{"id":81089,"date":"2020-05-11T01:42:24","date_gmt":"2020-05-10T23:42:24","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov"},"modified":"2020-05-11T01:42:24","modified_gmt":"2020-05-10T23:42:24","slug":"tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal'nikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Ti invitiamo a prendere visione della trascrizione della relazione di inizio 2016 di Andrey Sal'nikov \"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL\"<\/strong><\/p>\n<p><\/p>\n<p>In questa relazione analizzer\u00f2 gli errori principali nelle applicazioni che si verificano durante la fase di progettazione e scrittura del codice dell'applicazione. Prender\u00f2 in considerazione solo quegli errori che portano al bloat in Postgresql. Di norma, questo segna l'inizio della fine delle prestazioni del sistema nel suo complesso, anche se inizialmente non si vedevano presupposti evidenti.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/a9e199bfe2e01c76966b32868790f8f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Sono felice di dare il benvenuto a tutti! Questa relazione non \u00e8 cos\u00ec tecnica come quella precedente del mio collega. \u00c8 principalmente rivolta agli sviluppatori di sistemi backend, poich\u00e9 abbiamo un numero abbastanza elevato di clienti. E tutti loro commettono gli stessi errori. Di questi vi parler\u00f2. Spiegher\u00f2 a cosa portano questi errori fatali e dannosi. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Perch\u00e9 si commettono errori? Ci sono due motivi: per caso, magari andr\u00e0 bene e per ignoranza di alcuni meccanismi che avvengono a livello tra il database e l'applicazione, e anche all'interno del database stesso. <\/p>\n<p><\/p>\n<p>Vi presenter\u00f2 tre esempi con orribili immagini di come tutto \u00e8 andato male. Vi parler\u00f2 brevemente del meccanismo che accade. E di come affrontarli quando si sono verificati, e quali metodi preventivi utilizzare per evitare questi errori. Vi parler\u00f2 di strumenti ausiliari e vi fornir\u00f2 link utili. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ho utilizzato un database di test, dove avevo due tabelle. Una tabella con le fatture dei clienti, l'altra con le operazioni su queste fatture. E con una certa periodicit\u00e0 aggiorniamo i saldi su queste fatture.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I dati della tabella iniziale: \u00e8 abbastanza piccola, 2 MB. Il tempo di risposta del database e specificamente per la tabella \u00e8 anch'esso molto buono. E un carico piuttosto buono \u2013 2.000 operazioni al secondo sulla tabella.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E attraverso questa relazione vi mostrer\u00f2 grafici, per rendere chiaro cosa sta succedendo. Ci saranno sempre 2 diapositive con grafici. La prima diapositiva mostrer\u00e0 cosa succede in generale sul server. <\/p>\n<p><\/p>\n<p>E in questa situazione vediamo che in effetti la nostra tabella \u00e8 di piccole dimensioni. L'indice \u00e8 piccolo, di 2 MB. Questo \u00e8 il primo grafico a sinistra. <\/p>\n<p><\/p>\n<p>Il tempo medio di risposta del server \u00e8 anch'esso stabile e ridotto. Questo \u00e8 il grafico in alto a destra. <\/p>\n<p><\/p>\n<p>Il grafico in basso a sinistra rappresenta le transazioni pi\u00f9 lunghe. Vediamo che le transazioni vengono completate rapidamente. E l'auto-vacuum qui non funziona ancora, perch\u00e9 era un test di avvio. Successivamente, funzioner\u00e0 e sar\u00e0 utile per noi.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il secondo slide sar\u00e0 sempre dedicato alla tabella in esame. In questa situazione, aggiorniamo costantemente i saldi nei conti del cliente. E vediamo che il tempo medio di risposta per l'operazione di aggiornamento \u00e8 piuttosto buono, meno di un millisecondo. Possiamo notare che le risorse della CPU (questo \u00e8 il grafico in alto a destra) vengono utilizzate in modo uniforme e con un quantitativo piuttosto ridotto. <\/p>\n<p><\/p>\n<p>Il grafico in basso a destra mostra quanta memoria operativa e di disco stiamo esplorando alla ricerca della riga necessaria, prima di aggiornarla. E il numero di operazioni sulla tabella \u00e8 di 2000 al secondo, come ho detto all'inizio. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E ora abbiamo una tragedia. Per qualche motivo si verifica una transazione dimenticata di lunga durata. Le cause sono solitamente tutte banali: <\/p>\n<p><\/p>\n<ul>\n<li>Una delle pi\u00f9 comuni \u00e8 che nel codice dell'applicazione abbiamo iniziato a chiamare un servizio esterno. E quel servizio non ci risponde. Cio\u00e8, abbiamo aperto una transazione, effettuato una modifica nel database e poi siamo andati a controllare la posta o ad utilizzare un altro servizio all'interno della nostra infrastruttura, e per qualche motivo non ci risponde. E ci troviamo con una sessione bloccata che \u00e8 in uno stato - non si sa quando si risolver\u00e0.<\/li>\n<li>La seconda situazione si verifica quando nel codice per qualche motivo abbiamo avuto un exception. E non abbiamo gestito la chiusura della transazione nell'exception. E ci troviamo con una sessione bloccata con una transazione aperta. <\/li>\n<li>E infine \u2013 questo \u00e8 un altro caso abbastanza comune. \u00c8 un codice di bassa qualit\u00e0. Alcuni framework aprono una transazione. Essa rimane bloccata, e potresti non sapere nell'applicazione che \u00e8 bloccata. <\/li>\n<\/ul>\n<p><\/p>\n<p>A cosa portano queste cose? <\/p>\n<p><\/p>\n<p>A fatto che le tabelle e gli indici cominciano a gonfiarsi rapidamente. Questo \u00e8 proprio l'effetto bloat. Per il database, si tradurr\u00e0 in un aumento drastico del tempo di risposta del database, e ci sar\u00e0 un aumento del carico sul server del database. E come conseguenza, l'applicazione ne risentir\u00e0. Perch\u00e9 se nel codice impiegavi 10 millisecondi per una query al database, 10 millisecondi per la tua logica, la tua funzione impiegava 20 millisecondi. Ma ora ti trovi in una situazione davvero triste. <\/p>\n<p><\/p>\n<p>E vediamo cosa sta succedendo. Il grafico in basso a sinistra mostra che abbiamo una transazione lunga. E se guardiamo il grafico in alto a sinistra, vediamo che la dimensione della tabella \u00e8 passata da due megabyte a 300 megabyte. Tuttavia, la quantit\u00e0 di dati nella tabella non \u00e8 cambiata, cio\u00e8 c'\u00e8 una grande quantit\u00e0 di spazzatura.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La situazione generale per il tempo medio di risposta del server \u00e8 cambiata di diversi ordini di grandezza. Cio\u00e8, tutte le richieste al server hanno iniziato a rallentare drasticamente. Inoltre, sono stati attivati processi interni di Postgres come l\u2019autovacuum, che stanno cercando di fare qualcosa e consumano risorse.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cosa succede alla nostra tabella? Anche qui. Il tempo medio di risposta per la tabella \u00e8 aumentato di diversi ordini di grandezza. In particolare, per quanto riguarda le risorse consumate, vediamo che il carico della CPU \u00e8 aumentato notevolmente. Questo \u00e8 il grafico in alto a destra. \u00c8 aumentato perch\u00e9 la CPU deve esaminare un gran numero di righe inutili alla ricerca di una riga utile. Questo \u00e8 il grafico in basso a destra. E come risultato, il numero di chiamate al secondo ha iniziato a diminuire drasticamente, perch\u00e9 il database non riesce a gestire il numero di richieste. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dobbiamo tornare alla normalit\u00e0. Andiamo su internet e scopriamo che le transazioni lunghe causano problemi. Troviamo e cancelliamo questa transazione. E tutto torna alla normalit\u00e0. Tutto funziona come dovrebbe. <\/p>\n<p><\/p>\n<p>Ci siamo calmati, ma dopo un po' iniziamo a notare che l'applicazione non funziona come prima dell'incidente. Le richieste vengono comunque elaborate pi\u00f9 lentamente, e in modo significativo pi\u00f9 lentamente. Un'ottima volta e mezzo pi\u00f9 lentamente nel mio esempio specifico. Il carico sul server \u00e8 anche pi\u00f9 alto di quanto fosse prima dell'incidente. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E la domanda \u00e8: \"Cosa succede al database in quel momento?\". Nel database si verifica la seguente situazione. Nel grafico delle transazioni si vede che \u00e8 fermo e non ci sono davvero transazioni lunghe. Ma le dimensioni della tabella durante l'incidente sono aumentate drammaticamente. E da allora non sono diminuite. Il tempo medio del database si \u00e8 stabilizzato. E le risposte sembrano viaggiare a una velocit\u00e0 accettabile per noi. L'autovacuum \u00e8 diventato pi\u00f9 attivo e ha iniziato a fare qualcosa con la tabella, perch\u00e9 deve rielaborare un numero maggiore di dati. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Con riferimento alla tabella dei conti in cui stiamo modificando i saldi: il tempo di risposta della richiesta sembra essere tornato alla normalit\u00e0. Ma in realt\u00e0 \u00e8 un'altra volta e mezzo pi\u00f9 alto.<\/p>\n<p><\/p>\n<p>E per quanto riguarda il carico sulla CPU, vediamo che il carico non \u00e8 tornato ai valori necessari prima dell'incidente. Le cause si trovano proprio nel grafico in basso a destra. \u00c8 evidente che si sta verificando una sovraccumulazione di qualche quantit\u00e0 di memoria. Cio\u00e8, per cercare la riga necessaria stiamo consumando risorse del server database durante una scansione di dati inutili. Il numero di transazioni al secondo si \u00e8 stabilizzato. <\/p>\n<p><\/p>\n<p>In generale sta andando bene, ma la situazione \u00e8 peggiore di prima. C'\u00e8 un evidente degrado del database a causa della nostra applicazione che lavora con questo database. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E per capire cosa stia accadendo, se non eravate alla presentazione precedente, faremo ora un po' di teoria. Teoria sul processo interno. A cosa serve l'autovacuum e cosa fa?<\/p>\n<p><\/p>\n<p>In breve, per una migliore comprensione. A un certo punto abbiamo una tabella. Nella tabella ci sono delle righe. Queste righe possono essere attive, vive, necessarie ora. Nella figura sono contrassegnate in verde. E ci sono righe morte, che sono gi\u00e0 state elaborate, sono state aggiornate e su di esse sono state create nuove registrazioni. E sono contrassegnate come non pi\u00f9 interessanti per il database. Ma rimangono nella tabella a causa delle peculiarit\u00e0 di Postgres.<\/p>\n<p><\/p>\n<p>A cosa serve l'autovacuum? A un certo punto, l'autovacuum si presenta, si rivolge al database e gli chiede: \u00abPer favore, dammi l'id della transazione pi\u00f9 vecchia che \u00e8 attualmente aperta nel database\u00bb. Il database restituisce questo id. E l'autovacuum, facendo riferimento ad esso, scorre le righe nella tabella. E se vede che alcune righe sono state modificate da transazioni decisamente pi\u00f9 vecchie, ha il diritto di contrassegnarle come righe che possiamo riutilizzare in futuro, scrivendo nuovi dati. \u00c8 un processo in background.<\/p>\n<p><\/p>\n<p>Nel frattempo continuiamo a lavorare con il database, continuiamo a fare modifiche nella tabella. E per queste righe che possiamo riutilizzare, scriviamo nuovi dati. In questo modo otteniamo un ricircolo, cio\u00e8 emergono costantemente vecchie righe morte e al loro posto scriviamo nuove righe che ci servono. E questo \u00e8 uno stato normale per il funzionamento di PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cosa \u00e8 successo durante l'incidente? Come \u00e8 avvenuto questo processo?<\/p>\n<p><\/p>\n<p>Avevamo una tabella in qualche stato, alcune righe vive, alcune morte. \u00c8 arrivato l'autovacuum. Ha chiesto al database qual \u00e8 la nostra transazione pi\u00f9 antica e qual \u00e8 il suo id. Ha ottenuto questo id, che pu\u00f2 risalire a molte ore fa o a dieci minuti fa. Questo dipende da quanto \u00e8 forte il carico nel tuo database. E ha cominciato a cercare le righe che pu\u00f2 segnare come riutilizzabili. E non ha trovato tali righe nella nostra tabella. <\/p>\n<p><\/p>\n<p>Ma noi nel frattempo continuiamo a lavorare con la tabella. Facciamo qualcosa in essa, aggiorniamo, cambiamo i dati. E cosa pu\u00f2 fare il database nel frattempo? Non pu\u00f2 fare altro che aggiungere nuove righe alla fine della tabella esistente. E cos\u00ec, la dimensione della tabella inizia ad aumentare. <\/p>\n<p><\/p>\n<p>In realt\u00e0, abbiamo bisogno delle righe verdi per lavorare. Ma durante un problema del genere, il nostro percentuale di righe verdi risulta estremamente bassa rispetto all'intero volume della tabella. <\/p>\n<p><\/p>\n<p>Quando eseguiamo una query, il database deve esaminare tutte le righe: sia rosse che verdi, per trovare la riga necessaria. E l'effetto dell'aumento della tabella con dati inutili si chiama \"bloat\", che consuma anche il nostro spazio su disco. Ricordate, erano 2 MB, sono diventati 300 MB? Ora cambiate megabyte in gigabyte e perderete rapidamente tutte le vostre risorse disco.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quali possono essere le conseguenze per noi? <\/p>\n<p><\/p>\n<ul>\n<li>Nel mio esempio, la tabella e l'indice sono cresciuti di 150 volte. Alcuni dei nostri clienti hanno sperimentato casi pi\u00f9 fatali, con il semplice spazio su disco che cominciava a finire. <\/li>\n<li>La dimensione delle tabelle di per s\u00e9 non diminuir\u00e0 mai. L'autovacuum in alcuni casi pu\u00f2 tagliare la parte finale della tabella, se ci sono solo righe morte. Ma poich\u00e9 si verifica una rotazione costante, una riga verde pu\u00f2 rimanere in fondo e non aggiornarsi, mentre tutte le altre saranno registrate all'inizio della tabella. Ma \u00e8 un evento cos\u00ec improbabile che non dovresti contare su un diminuzione della dimensione della tua tabella. <\/li>\n<li>Il database deve filtrare tutta questa montagna di righe inutili. E noi stiamo sprecando risorse disco, sprecando risorse CPU e energia elettrica. <\/li>\n<li>E questo influisce direttamente sulla nostra applicazione, perch\u00e9 se all'inizio impiegavamo 10 millisecondi per la richiesta, 10 millisecondi per il nostro codice, durante il guasto siamo passati a impiegare un secondo per la richiesta e 10 millisecondi per il codice, cio\u00e8 la performance dell'applicazione \u00e8 diminuita di un ordine di grandezza. E quando abbiamo risolto il guasto, abbiamo cominciato a impiegare 20 millisecondi per la richiesta e 10 millisecondi per il codice. Questo significa che siamo comunque scesi a un rendimento di un italiano e mezzo. E tutto questo a causa di una transazione che \u00e8 rimasta bloccata, probabilmente per nostra colpa. <\/li>\n<li>E la domanda \u00e8: \u00abCome possiamo riportare tutto come prima?\u00bb, affinch\u00e9 le nostre richieste tornino ad essere rapide come prima del guasto. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Per questo esiste un ciclo di lavori specifico che viene svolto. <\/p>\n<p><\/p>\n<p>Innanzitutto dobbiamo identificare le tabelle problematiche che si sono gonfiate. Ci rendiamo conto che per alcune tabelle la scrittura avviene in modo pi\u00f9 attivo, per altre meno attivo. E per questo si utilizza l'estensione <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. Installando questa estensione, puoi scrivere interrogazioni che ti aiuteranno a trovare le tabelle che si sono gonfiate abbastanza. <\/p>\n<p><\/p>\n<p>Dopo aver trovato queste tabelle, \u00e8 necessario compattarle. A questo scopo ci sono gi\u00e0 degli strumenti. Nella nostra azienda utilizziamo tre strumenti. Il primo \u00e8 il VACUUM FULL integrato. \u00c8 brutale, severo e spietato, ma a volte \u00e8 molto utile. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> sono utility di terze parti per la compressione delle tabelle. E sono pi\u00f9 rispettosi nei confronti del database. <\/p>\n<p><\/p>\n<p>Vengono utilizzati a seconda di quello che ti risulta pi\u00f9 comodo. Ma di questo parler\u00f2 alla fine. L'importante \u00e8 che ci sono tre strumenti. Hai da dove scegliere. <\/p>\n<p><\/p>\n<p>Dopo aver sistemato tutto e averci assicurato che tutto funzionasse correttamente, dobbiamo sapere come prevenire questa situazione in futuro:<\/p>\n<p><\/p>\n<ul>\n<li>Pu\u00f2 essere prevenuta piuttosto facilmente. \u00c8 importante monitorare la durata delle sessioni sul Server Master. <strong>Sessioni particolarmente pericolose in stato di idle in transazione<\/strong>. Sono quelle che hanno aperto una transazione, hanno fatto qualcosa e poi se ne sono andate, oppure sono semplicemente rimaste appese, perse nel codice. <\/li>\n<li>E per voi, come per sviluppatori, \u00e8 importante testare il codice nel momento in cui si verificano queste situazioni. Non \u00e8 difficile farlo. Sar\u00e0 un controllo utile. Eviterete un gran numero di problemi 'infantili' legati a transazioni lunghe. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In questi grafici volevo mostrarti come \u00e8 cambiata la tabella e il comportamento del database dopo aver eseguito un VACUUM FULL sulla tabella. Questo non \u00e8 un ambiente di produzione per me.<\/p>\n<p><\/p>\n<p>La dimensione della tabella \u00e8 tornata subito a uno stato di lavoro normale, di qualche megabyte. Sul tempo medio di risposta del server, questo non ha avuto un grande impatto. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ma specificamente sulla nostra tabella di prova, dove abbiamo aggiornato i saldi, vediamo che il tempo medio di risposta per la richiesta di aggiornamento dei dati nella tabella \u00e8 sceso a livelli pre-allerta. Anche le risorse consumate dal processore per eseguire questa richiesta sono diminuite a livelli pre-allerta. E il grafico in basso a destra mostra che ora troviamo esattamente la riga di cui abbiamo bisogno immediatamente, senza dover scorrere un mucchio di righe morte che c'erano prima della compressione della tabella. E il tempo medio delle richieste \u00e8 rimasto all'incirca sullo stesso livello. Ma qui credo sia pi\u00f9 un errore del mio hardware.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Questa \u00e8 la prima storia, ed \u00e8 la pi\u00f9 comune. Accade a tutti, indipendentemente dall'esperienza del cliente, anche se gli sviluppatori sono qualificati. Prima o poi succede. <\/p>\n<p><\/p>\n<p>La seconda storia, in cui distribuiamo il carico e ottimizziamo le risorse del server.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Siamo gi\u00e0 cresciuti e siamo diventati ragazzi seri. E capiamo che abbiamo una replica e sarebbe bene bilanciare il carico: scrivere sul Master e leggere dalla replica. Questa situazione di solito si presenta quando vogliamo preparare dei report o delle operazioni ETL. E il business ne \u00e8 molto contento. Vuole report vari con un sacco di analisi complesse. <\/li>\n<li>I report richiedono ore, perch\u00e9 un'analisi complessa non pu\u00f2 essere calcolata in millisecondi. Noi, come dei bravi ragazzi, scriviamo codice. Effettuiamo inserimenti nell'applicazione, registriamo sul Master e eseguiamo i report sulla replica. <\/li>\n<li>Distribuiamo il carico. <\/li>\n<li>Tutto funziona alla grande. Siamo bravi. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E come appare questa situazione? Nello specifico, in questi grafici ho aggiunto anche la durata delle transazioni dalla replica. Tutti gli altri grafici si riferiscono solo al server Master. <\/p>\n<p><\/p>\n<p>La tabella con i report \u00e8 cresciuta fino a questo punto. Sono diventati di pi\u00f9. Vediamo che il tempo medio di risposta del server \u00e8 stabile. Vediamo che nella replica abbiamo una transazione lunga che dura 2 ore. Vediamo un funzionamento tranquillo dell\u2019autovacuum, che gestisce le righe morte. E tutto va bene. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specificamente per la tabella in esame, continuiamo ad aggiornare i saldi sui conti. Anche noi abbiamo un tempo di risposta stabile per la richiesta, un consumo di risorse stabile. Tutto va bene. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Va bene finch\u00e9 non iniziamo a vedere questi report sparire a causa di conflitti con la replicazione. E scompaiono con una certa regolarit\u00e0. <\/p>\n<p><\/p>\n<p>Ci connettiamo a Internet e iniziamo a leggere perch\u00e9 questo sta succedendo. E troviamo una soluzione. <\/p>\n<p><\/p>\n<p>La prima soluzione \u00e8 aumentare il ritardo della replicazione. Sappiamo che il nostro report impiega 3 ore. Impostiamo il ritardo della replicazione a 3 ore. Avviamo tutto, ma continuiamo ad avere problemi con i report che a volte scompaiono. <\/p>\n<p><\/p>\n<p>Vogliamo che tutto sia perfetto. Ci spingiamo oltre. E troviamo su Internet una fantastica impostazione \u2013 hot_standby_feedback. La attiviamo. Hot_standby_feedback ci consente di mantenere il lavoro dell\u2019autovacuum sul Master. In questo modo ci liberiamo completamente dai conflitti di replicazione. E tutto funziona bene con i report.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E cosa succede nel frattempo al server Master? Al server Master stiamo vivendo un disastro totale. Ora stiamo osservando i grafici da quando ho attivato entrambe queste impostazioni. E vediamo che la sessione sulla replica in qualche modo ha iniziato a influenzare la situazione sul server Master. Influisce davvero, perch\u00e9 ha sospeso l\u2019autovacuum che ripulisce le righe morte. Le dimensioni della tabella sono nuovamente schizzate in alto. Anche il tempo medio di esecuzione delle query su tutto il database \u00e8 aumentato. Gli autovacuum sono un po' sotto pressione. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specificamente per la nostra tabella vediamo che anche l'aggiornamento dei dati \u00e8 schizzato in alto. Anche il consumo di risorse della CPU \u00e8 aumentato notevolmente. Stiamo di nuovo elaborando un gran numero di righe morte inutili. E il tempo di risposta per questa tabella, il numero di transazioni \u00e8 diminuito. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Come apparir\u00e0 se non sappiamo di cosa stavo parlando prima?<\/p>\n<p><\/p>\n<ul>\n<li>Iniziamo a cercare problemi. Se abbiamo riscontrato problemi nella prima parte, sappiamo che potrebbe essere dovuto a una lunga transazione e andiamo su Master. Il problema \u00e8 su Master. \u00c8 instabile. Si surriscalda, ha un Load Average vicino a cento. <\/li>\n<li>Le richieste l\u00ec sono lente, ma non vediamo transazioni prolungate. E non capiamo di cosa si tratti. Non capiamo dove cercare. <\/li>\n<li>Controlliamo l'hardware del server. Forse il nostro raid \u00e8 andato in panne. Magari uno stick di memoria \u00e8 bruciato. Pu\u00f2 succedere di tutto. Ma no, i server sono nuovi, tutto funziona perfettamente. <\/li>\n<li>Correndo qua e l\u00e0: amministratori, sviluppatori e direttore. Nulla sembra funzionare. <\/li>\n<li>E a un certo punto tutto inizia improvvisamente a sistemarsi da solo. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sulla replica, nel frattempo, la richiesta \u00e8 stata elaborata e ha terminato. Abbiamo ricevuto un rapporto. Il business \u00e8 ancora soddisfatto. Come vediamo, la tabella \u00e8 nuovamente cresciuta e non sembra voler diminuire. Sul grafico delle sessioni ho lasciato un pezzo di questa lunga transazione dalla replica, cos\u00ec potete valutare quanto tempo passa finch\u00e9 la situazione si stabilizza. <\/p>\n<p><\/p>\n<p>La sessione \u00e8 terminata. Solo dopo un po' il server inizia a tornare a un certo ordine. E il tempo medio di risposta per le richieste sul server Master torna alla normalit\u00e0. Perch\u00e9, finalmente, l'autovacuum ha avuto la possibilit\u00e0 di pulire e contrassegnare queste righe morte. E ha iniziato a fare il suo lavoro. E tanto velocemente quanto lo fa, tanto velocemente torneremo in ordine.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sulla tabella oggetto di prova, dove aggiorniamo i saldi, vediamo lo stesso scenario. Anche il tempo medio di aggiornamento del saldo si normalizza gradualmente. Le risorse consume dal processore stanno diminuendo, e anche il numero di transazioni al secondo torna alla normalit\u00e0. Ma, di nuovo, non alla normalit\u00e0 che avevamo prima dell'incidente. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Riceviamo comunque una flessione delle prestazioni, proprio come nel primo caso, da un'ora e mezza a due volte, a volte anche di pi\u00f9. <\/p>\n<p><\/p>\n<p>Sembra che abbiamo fatto tutto correttamente. Abbiamo distribuito il carico. L'hardware non \u00e8 fermo. Abbiamo suddiviso le richieste in modo intelligente, ma alla fine \u00e8 andata male. <\/p>\n<p><\/p>\n<ul>\n<li>Non attivare hot_standby_feedback? S\u00ec, non \u00e8 consigliato attivarlo senza motivi particolari. Questo perch\u00e9 questa impostazione influisce direttamente sul server master e sospende il funzionamento dell'autovacuum l\u00ec. Attivandolo su una replica e dimenticandosene, potresti compromettere il master e avere grandi problemi con l'applicazione. <\/li>\n<li>Aumentare max_standby_streaming_delay? S\u00ec, per i report \u00e8 cos\u00ec. Se hai un report di tre ore e non vuoi che cada a causa dei conflitti di replica, aumenta semplicemente il ritardo. Un report lungo non richiede mai dati che sono appena arrivati nel database. Se \u00e8 di tre ore, significa che lo esegui su un vecchio periodo di dati. E per te, che sia tre ore di ritardo o sei ore, non far\u00e0 alcuna differenza, ma in questo modo riceverai report in modo stabile senza problemi di caduta. <\/li>\n<li>Naturalmente, \u00e8 necessario monitorare le sessioni prolungate sulle repliche, soprattutto se hai deciso di attivare hot_standby_feedback sulla replica. Perch\u00e9 pu\u00f2 succedere di tutto. Hai dato questa replica a uno sviluppatore per testare le query. Ha scritto una query folle. L'ha eseguita e se ne \u00e8 andato a bere un t\u00e8, mentre noi abbiamo ottenuto un master bloccato. Oppure abbiamo fatto girare un'applicazione sbagliata. Le situazioni sono varie. Le sessioni sulle repliche devono essere monitorate con la stessa attenzione di quelle sul master. <\/li>\n<li>E se hai query rapide e lunghe sulle repliche, in questo caso \u00e8 meglio suddividerle per distribuire il carico. Questo \u00e8 un riferimento a streaming_delay. Per le query rapide usa una replica con un piccolo ritardo nella replica. Per le query reportistiche lunghe, utilizza una replica che pu\u00f2 avere un ritardo di 6 ore o un giorno. \u00c8 una situazione del tutto normale. <\/li>\n<\/ul>\n<p><\/p>\n<p>Eliminiamo le conseguenze nello stesso modo:<\/p>\n<p><\/p>\n<ul>\n<li>Troviamo le tabelle sovradimensionate.<\/li>\n<li>E le comprimiamo con lo strumento pi\u00f9 adatto a noi. <\/li>\n<\/ul>\n<p><\/p>\n<p>La seconda storia \u00e8 finita qui. Passiamo alla terza storia. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Anche questa \u00e8 abbastanza comune per noi, in cui facciamo una migrazione. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Qualsiasi prodotto software cresce. Cambiano le richieste verso di esso. Vogliamo sempre progredire. E a volte \u00e8 necessario aggiornare i dati in una tabella, eseguendo un aggiornamento nell'ambito della nostra migrazione verso una nuova funzionalit\u00e0 che stiamo implementando nel nostro percorso di sviluppo. <\/li>\n<li>Il vecchio formato dei dati non va bene. Supponiamo che ora ci rivolgiamo alla seconda tabella, dove ho le operazioni su questi conti. E, supponiamo, che fossero in rubli, e abbiamo deciso di aumentare la precisione e operare in kopeck. Per questo dobbiamo eseguire un aggiornamento: moltiplicare il campo con l'importo dell'operazione per cento. <\/li>\n<li>Nel mondo moderno utilizziamo strumenti automatizzati per il controllo delle versioni delle basi di dati. Supponiamo, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>. Scriviamo l\u00ec la nostra migrazione. La testiamo sulla nostra base dati di prova. Tutto perfetto. L'aggiornamento va a buon fine. Blocca le operazioni per un certo periodo, ma cos\u00ec otteniamo dati aggiornati. E possiamo avviare nuove funzionalit\u00e0 su questo. Abbiamo testato tutto, controllato. Tutto confermato. <\/li>\n<li>Abbiamo eseguito lavori programmati, abbiamo effettuato la migrazione. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ecco la migrazione con l'aggiornamento presentata davanti a voi. Poich\u00e9 queste sono operazioni sui conti, la tabella era di 15 GB. E poich\u00e9 aggiorniamo ogni riga, con l'aggiornamento abbiamo raddoppiato la dimensione della tabella perch\u00e9 abbiamo riscritto ogni riga. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Durante la migrazione non potevamo fare nulla con questa tabella, poich\u00e9 tutte le richieste a essa si sono messe in coda e hanno atteso il termine di questo aggiornamento. Ma qui voglio attirare la vostra attenzione sui numeri sull'asse verticale. Cio\u00e8, abbiamo un tempo medio di richiesta prima della migrazione di circa 5 millisecondi e un carico sulla CPU, il numero di operazioni bloccanti di lettura dalla memoria del disco inferiore a 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Abbiamo effettuato la migrazione e abbiamo nuovamente riscontrato problemi. <\/p>\n<p><\/p>\n<p>La migrazione \u00e8 riuscita, ma:<\/p>\n<p><\/p>\n<ul>\n<li>La funzionalit\u00e0 precedente \u00e8 diventata pi\u00f9 lenta. <\/li>\n<li>La tabella \u00e8 nuovamente cresciuta in dimensioni. <\/li>\n<li>Il carico sul server \u00e8 di nuovo aumentato rispetto a prima. <\/li>\n<li>E, naturalmente, mentre stiamo ancora lavorando su quella funzionalit\u00e0 che funzionava bene, l'abbiamo leggermente migliorata. <\/li>\n<\/ul>\n<p><\/p>\n<p>E questo \u00e8 di nuovo bloat che ci complica la vita. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Qui dimostro che la tabella, come nei due casi precedenti, non ha intenzione di tornare alle dimensioni precedenti. Il carico medio sul server sembra essere adeguato. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se ci rivolgiamo alla tabella dei conti, vediamo che il tempo medio di richiesta \u00e8 raddoppiato rispetto a questa tabella. Il carico sulla CPU e il numero di righe elaborate in memoria sono saliti oltre 7,5, mentre prima erano inferiori. E nel caso dei processori \u00e8 raddoppiato, mentre nel caso delle operazioni a blocchi \u00e8 aumentato di 1,5 volte, cio\u00e8 abbiamo avuto una degradazione delle prestazioni del server. Di conseguenza, anche le prestazioni della nostra applicazione sono peggiorate. Tuttavia, il numero di chiamate \u00e8 rimasto pi\u00f9 o meno lo stesso. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E qui \u00e8 fondamentale capire come eseguire correttamente queste migrazioni. E sono necessarie. Eseguiamo queste migrazioni in modo piuttosto costante.<\/p>\n<p><\/p>\n<ul>\n<li>Tali grandi migrazioni non vengono effettuate automaticamente. Devono sempre essere controllate. <\/li>\n<li>\u00c8 necessaria la supervisione da parte di una persona esperta. Se hai un DBA nel team, dovrebbe occuparsene lui. Questo \u00e8 il suo compito. Se no, la persona pi\u00f9 esperta dovrebbe farlo, quella che sa come lavorare con i database. <\/li>\n<li>Uno schema di database nuovo, anche nel caso in cui aggiorniamo una sola colonna, deve sempre essere preparato a tappe, cio\u00e8 in anticipo rispetto al rilascio di una nuova versione dell'applicazione:<\/li>\n<li>Vengono aggiunti nuovi campi in cui scriveremo i dati aggiornati. <\/li>\n<li>Trasferiamo i dati dal campo vecchio al campo nuovo in piccole porzioni. Perch\u00e9 facciamo questo? Innanzitutto, monitoriamo sempre il processo. Sappiamo che abbiamo gi\u00e0 trasferito un certo numero di batch e ci rimane ancora questa quantit\u00e0. <\/li>\n<li>Un secondo effetto positivo \u00e8 che tra ogni batch chiudiamo la transazione, ne apriamo una nuova e questo consente al vacuum automatico di lavorare sulla tabella, segnando le righe inutilizzate per il riutilizzo. <\/li>\n<li>Per le righe che appariranno durante il funzionamento dell'applicazione (abbiamo ancora l'applicazione vecchia funzionante) aggiungiamo un trigger che scrive i nuovi valori nei nuovi campi. Nel nostro caso, \u00e8 il valore vecchio moltiplicato per cento. <\/li>\n<li>Se siamo testardi e vogliamo usare lo stesso campo, allora alla conclusione di tutte le migrazioni e prima del rilascio della nuova versione dell'applicazione, semplicemente rinominiamo i campi. I vecchi con un nome inventato e i nuovi campi vengono rinominati nei vecchi. <\/li>\n<li>E solo dopo lanciamo la nuova versione dell'applicazione. <\/li>\n<\/ul>\n<p><\/p>\n<p>E in questo modo non avremo bloat e non avremo un calo delle prestazioni. <\/p>\n<p><\/p>\n<p>Questa \u00e8 la fine della terza storia. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/2afab2906b5ccd30e4c8772248818057.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>E ora parler\u00f2 un po' pi\u00f9 dettagliatamente degli strumenti che ho menzionato nella prima storia. <\/p>\n<p><\/p>\n<p>Prima di cercare il bloat, \u00e8 necessario installare l'estensione. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Per non dover inventare le query, noi nel nostro lavoro abbiamo gi\u00e0 scritto queste query. Puoi usarle. Qui sono presentate due query. <\/p>\n<p><\/p>\n<ul>\n<li>La prima funziona piuttosto a lungo, ma ti mostrer\u00e0 valori esatti del bloat per la tabella. <\/li>\n<li>La seconda funziona pi\u00f9 velocemente ed \u00e8 molto efficace quando \u00e8 necessario valutare rapidamente se c'\u00e8 o meno bloat nella tabella. E devi anche capire che il bloat nelle tabelle Postgres \u00e8 sempre presente. Questa \u00e8 una caratteristica del suo modello MVCC. <\/li>\n<li>E il 20% di bloat \u00e8 normale per le tabelle nella maggior parte dei casi. Cio\u00e8, non dovresti preoccuparti e comprimere questa tabella. <\/li>\n<\/ul>\n<p><\/p>\n<p>Abbiamo capito come identificare le tabelle che si sono gonfiate, e anche quando si sono gonfiate a causa di dati inutili. <\/p>\n<p><\/p>\n<p>Ora parliamo di come correggere il bloat:<\/p>\n<p><\/p>\n<ul>\n<li>Se abbiamo una piccola tabella e dischi buoni, cio\u00e8 se la tabella \u00e8 di dimensioni inferiori a un gigabyte, \u00e8 assolutamente possibile utilizzare VACUUM FULL. Ti prender\u00e0 un blocco esclusivo sulla tabella per alcuni secondi e poi sar\u00e0 tutto a posto, ma far\u00e0 tutto velocemente e in modo rigoroso. Cosa fa VACUUM FULL? Prende un blocco esclusivo sulla tabella e riscrive le righe vive da tabelle pi\u00f9 vecchie in una nuova tabella. Alla fine sostituisce i dati. Elimina i file vecchi, sostituisce con quelli nuovi. Ma durante il suo funzionamento prende un blocco esclusivo sulla tabella. Questo significa che non potrai fare nulla con questa tabella: n\u00e9 scrivere, n\u00e9 leggere, n\u00e9 modificarla. E VACUUM FULL richiede spazio aggiuntivo su disco per scrivere i dati.<\/li>\n<li>Lo strumento successivo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. Per principio \u00e8 molto simile a VACUUM FULL, perch\u00e9 anche lui riscrive i dati dai file pi\u00f9 vecchi in quelli nuovi e li sostituisce nella tabella. Tuttavia, non prende un blocco esclusivo sulla tabella all'inizio del suo funzionamento, ma lo prende solo nel momento in cui ha dati pronti per sostituire i file. I requisiti per le risorse di disco sono simili a quelli di VACUUM FULL. Hai bisogno di spazio aggiuntivo su disco, e questo pu\u00f2 essere critico se hai tabelle da un terabyte. Inoltre, \u00e8 piuttosto affamato di CPU, poich\u00e9 effettua operazioni attive di input-output. <\/li>\n<li>Il terzo strumento \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>. \u00c8 pi\u00f9 attenta alle risorse, poich\u00e9 opera su principi leggermente diversi. La sostanza principale di pgcompacttable \u00e8 che durante gli aggiornamenti sposta tutte le righe attive all'inizio della tabella. E poi avvia un'operazione di vacuum su questa tabella, perch\u00e9 sappiamo che all'inizio abbiamo righe attive e alla fine righe non pi\u00f9 attive. Inoltre, il vacuum stesso taglia questa parte finale, cio\u00e8 non richiede molto spazio su disco. E, in aggiunta, \u00e8 possibile ottimizzarlo ulteriormente per le risorse. <\/li>\n<\/ul>\n<p><\/p>\n<p>Con gli strumenti \u00e8 tutto. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Errori comuni nelle applicazioni che portano a bloat in PostgreSQL. Andrei Sal&#039;nikov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se vi interessa approfondire il tema del bloat, ecco alcuni link utili:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres\">https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres<\/a><\/noindex> \u2013 \u00e8 una relazione del mio collega. \u00c8 generale e parla di dove va a finire lo spazio in Postgres durante il suo funzionamento e la sua vita. Contiene anche una parte tecnica molto ampia e dettagliata per gli amministratori di database sul bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\">https:\/\/github.com\/dataegret\/pg-utils<\/a><\/noindex> \u2013 \u00e8 un link al nostro repository, dove conserviamo una serie di script utili per controllare lo stato del database. Qui puoi trovare script per la ricerca di bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Terzo<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">quarta<\/a><\/noindex> link agli strumenti che ti aiuteranno a ottimizzare le tabelle. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html\">http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html<\/a><\/noindex> \u2013 \u00e8 un post del mio collega. Qui analizza in modo piuttosto serio e dettagliato il bloat a un livello vicino a quello degli amministratori. <\/li>\n<\/ul>\n<p><\/p>\n<p>Ho cercato di presentare una sorta di allerta per i programmatori, poich\u00e9 sono i nostri clienti diretti e devono capire le conseguenze delle proprie azioni. Spero di esserci riuscito. Grazie per l'attenzione!<\/p>\n<p><\/p>\n<p>Domande<\/p>\n<p><\/p>\n<p><em>Grazie per la relazione! Hai parlato di come identificare i problemi. Come si possono prevenire? Cio\u00e8, ho avuto una situazione in cui le query erano bloccate non solo a causa di chiamate a servizi esterni. C'erano anche join piuttosto complessi. C'erano piccole query innocue che rimanevano bloccate per un giorno e poi iniziavano a fare disastri. Cio\u00e8, sembra molto simile a ci\u00f2 che hai descritto. Come si pu\u00f2 monitorare ci\u00f2? Devo stare seduto e controllare costantemente quale query \u00e8 bloccata? Come posso prevenirlo?<\/em><\/p>\n<p><\/p>\n<p>In questo caso, \u00e8 un compito per gli amministratori della tua azienda, non necessariamente per il DBA.<\/p>\n<p><\/p>\n<p><em>Io sono un amministratore.<\/em><\/p>\n<p><\/p>\n<p>In PostgreSQL esiste una vista chiamata pg_stat_activity, che mostra le query bloccate. Puoi vedere da quanto tempo sono bloccate.<\/p>\n<p><\/p>\n<p><em>Devo entrare ogni 5 minuti per controllare?<\/em><\/p>\n<p><\/p>\n<p>Imposta cron e controlla. Se hai una richiesta lunga, invia una email e basta. Cio\u00e8, non devi controllare a occhio, puoi automatizzarlo. Riceverai un\u2019email e reagirai di conseguenza. Oppure puoi automatizzare il processo.<\/p>\n<p><\/p>\n<p><em>Ci sono motivi evidenti per cui questo sta accadendo?<\/em><\/p>\n<p><\/p>\n<p>Ne ho elencati alcuni. Altri sono esempi pi\u00f9 complessi. E l\u00ec la conversazione potrebbe durare a lungo.<\/p>\n<p><\/p>\n<p><em>Grazie per la presentazione! Volevo chiarire riguardo all'utility pg_repack. Se non fa un blocco esclusivo, allora\u2026<\/em><\/p>\n<p><\/p>\n<p>Fa un blocco esclusivo. <\/p>\n<p><\/p>\n<p>\u2026 <em>quindi potenzialmente posso perdere dati. La mia applicazione non dovrebbe scrivere nulla in quel momento?<\/em><\/p>\n<p><\/p>\n<p>No, funziona tranquillamente con la tabella, cio\u00e8 pg_repack prima sposta tutte le righe attive. Naturalmente, si verifica una certa scrittura nella tabella. Aggiunge semplicemente questo residuo. <\/p>\n<p><\/p>\n<p><em>Cio\u00e8, alla fine lo fa comunque?<\/em><\/p>\n<p><\/p>\n<p>Alla fine prende un blocco esclusivo per sostituire questi file. <\/p>\n<p><\/p>\n<p><em>Sar\u00e0 pi\u00f9 veloce di VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, appena avviato, prende subito un blocco esclusivo. E fino a quando non ha terminato, non lo rilascia. Pg_repack prende il blocco esclusivo solo al momento della sostituzione dei file. In quel momento non puoi scrivere, ma i dati non andranno persi, tutto sar\u00e0 a posto. <\/p>\n<p><\/p>\n<p><em>Salve! Hai parlato del funzionamento dell'autovacuum. C'era un grafico con celle rosse, gialle e verdi. Cio\u00e8, le gialle sono state contrassegnate come eliminate. E di conseguenza, \u00e8 possibile scrivere qualcosa di nuovo in esse?<\/em><\/p>\n<p><\/p>\n<p>S\u00ec. Postgres non elimina le righe. Ha questa specificit\u00e0. Se aggiorniamo una riga, contrassegniamo quella vecchia come eliminata. Entra l'id della transazione che ha modificato quella riga e scriviamo la nuova riga. Abbiamo sessioni che possono leggerle. A un certo punto, diventano gi\u00e0 molto vecchie. E il lavoro dell'autovacuum \u00e8 quello di scorrere queste righe e contrassegnarle come non necessarie. E puoi riscrivere i dati l\u00ec. <\/p>\n<p><\/p>\n<p><em>Ho capito. Ma la domanda \u00e8 un po' diversa. Non ho finito. Supponiamo di avere una tabella. Ha campi di dimensione variabile. E se provo a inserire qualcosa di nuovo, potrebbe semplicemente non entrarci nella vecchia cella.<\/em> <\/p>\n<p><\/p>\n<p>No, in ogni caso l'intera riga viene aggiornata. In Postgres ci sono due modelli di memorizzazione dei dati. Viene scelto in base al tipo di dato. Ci sono dati che vengono memorizzati direttamente nella tabella e ci sono anche dati tos. Si tratta di grandi volumi di dati: testo, json. Questi vengono memorizzati in tabelle separate. E su queste tabelle si verifica la stessa storia con il bloat, cio\u00e8 esattamente la stessa cosa. Sono semplicemente separati. <\/p>\n<p><\/p>\n<p><em>Grazie per la presentazione! Quanto \u00e8 accettabile usare il timeout di dichiarazione per limitare la durata delle richieste?<\/em><\/p>\n<p><\/p>\n<p>Molto accettabile. Lo usiamo ovunque. E poich\u00e9 non abbiamo i nostri servizi, forniamo supporto remoto, abbiamo clienti piuttosto diversi. E tutti sono abbastanza soddisfatti. Cio\u00e8, abbiamo lavori in cron che effettuano controlli. Semplicemente viene concordata con il cliente la durata delle sessioni, prima della quale non intervieniamo. Pu\u00f2 essere un minuto, pu\u00f2 essere 10 minuti. Dipende dal carico sulla base e dal suo obiettivo. Ma per tutti utilizziamo pg_stat_activity.<\/p>\n<p><\/p>\n<p><em>Grazie per la presentazione! Sto cercando di adattare la vostra presentazione alle mie applicazioni. E sembra che noi iniziamo sempre una transazione, la concludiamo esplicitamente ovunque. Se c'\u00e8 qualche eccezione, comunque si verifica un rollback. E qui ho iniziato a riflettere. Infatti, una transazione potrebbe avviarsi non esplicitamente. Questo \u00e8 un suggerimento per la ragazza, probabilmente. Se faccio semplicemente un aggiornamento di un record, la transazione si avvier\u00e0 in PostgreSQL e si concluder\u00e0 solo quando avviene la disconnessione della connessione?<\/em><\/p>\n<p><\/p>\n<p>Se parliamo ora del livello dell'applicazione, dipende dal driver che stai usando, dall'ORM che viene utilizzato. Ci sono molte impostazioni. Se hai attivato l'auto commit, allora la transazione si avvia e si chiude immediatamente.<\/p>\n<p><\/p>\n<p><em>Cio\u00e8, si chiude immediatamente dopo l'aggiornamento?<\/em><\/p>\n<p><\/p>\n<p>Dipende dalle impostazioni. Ho menzionato una impostazione. \u00c8 l'auto commit attivato. \u00c8 abbastanza comune. Se \u00e8 attivato, la transazione si apre e si chiude. Se non hai detto esplicitamente \"start transaction\" e \"end transaction\", ma hai semplicemente lanciato la richiesta nella sessione. <\/p>\n<p><\/p>\n<p><em>Buongiorno! Grazie per la presentazione! Immagina di avere un database che cresce e cresce e qui sul server finisce lo spazio. Ci sono strumenti per risolvere questa situazione?<\/em> <\/p>\n<p><\/p>\n<p>Lo spazio sul server dovrebbe essere monitorato adeguatamente. <\/p>\n<p><\/p>\n<p><em>Ad esempio, il DBA \u00e8 andato a bere un caff\u00e8, era in vacanza, ecc.<\/em><\/p>\n<p><\/p>\n<p>Quando viene creata una filesystem, viene riservato almeno uno spazio, dove non vengono scritti dati. <\/p>\n<p><\/p>\n<p><em>E se completamente a zero?<\/em><\/p>\n<p><\/p>\n<p>Si chiama proprio reserved space, cio\u00e8 pu\u00f2 essere liberato e, a seconda di quanto grande \u00e8 stato creato, hai uno spazio libero. Di default non so quanto ci sia. In un altro caso, bisogna inviare dischi per avere spazio per effettuare l'operazione di ripristino. Puoi eliminare una tabella che sai per certo non ti serve. <\/p>\n<p><\/p>\n<p><em>Non ci sono altri strumenti?<\/em><\/p>\n<p><\/p>\n<p>\u00c8 sempre un lavoro manuale. E sul posto si determina meglio cosa fare, poich\u00e9 ci sono dati critici e non critici. E per ogni database e applicazione che ci lavora, dipende dal business. Si decide sempre sul posto. <\/p>\n<p><\/p>\n<p><em>Grazie per la presentazione! Ho due domande. In primo luogo, hai mostrato diapositive in cui si evidenziava che in caso di transazioni bloccate, sia il volume dello spazio tabellare che le dimensioni degli indici aumentano. E poi nella presentazione c'erano molte utility che compattano la tabella. E per l'indice?<\/em><\/p>\n<p><\/p>\n<p>Anche loro la compattano. <\/p>\n<p><\/p>\n<p><em>Ma il vacuum non tocca l'indice?<\/em><\/p>\n<p><\/p>\n<p>Alcuni lavorano con l'indice. Ad esempio, pg_rapack, pgcompacttable. Il vacuum ricrea gli indici, li tocca. Con VACUUM FULL, l'essenza \u00e8 che si riscrive tutto, cio\u00e8 lavora con tutti. <\/p>\n<p><\/p>\n<p><em>E la seconda domanda. Non ho capito perch\u00e9 i report sulle repliche dipendono cos\u00ec tanto dalla replica stessa. Mi sembrava che i report fossero lettura e la replica fosse scrittura.<\/em> <\/p>\n<p><\/p>\n<p>Qual \u00e8 il conflitto nella replica? Abbiamo un Master, dove avvengono i processi. Abbiamo un autovacuum. Cosa fa di fatto l'autovacuum? Rimuove alcune righe vecchie. Se in quel momento nella replica c'\u00e8 una richiesta che legge queste righe vecchie, e nel Master succede una situazione in cui l'autovacuum ha contrassegnato queste righe come possibili da sovrascrivere, allora le sovrascriveremo. E ci \u00e8 arrivato un pacchetto di dati in cui dobbiamo sovrascrivere quelle righe necessarie per la richiesta nella replica, quindi il processo di replica aspetter\u00e0 il timeout che hai impostato. E poi PostgreSQL decider\u00e0 cosa \u00e8 pi\u00f9 importante per lui. E la replica \u00e8 pi\u00f9 importante della richiesta, quindi annuller\u00e0 la richiesta per eseguire queste modifiche nella replica. <\/p>\n<p><\/p>\n<p><em>Andrej, ho una domanda. Queste meravigliose grafico che hai mostrato durante la presentazione, sono il risultato di qualche tuo strumento? Come sono stati creati i grafici?<\/em><\/p>\n<p><\/p>\n<p>\u00c8 un servizio <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>\u00c8 un prodotto commerciale?<\/em><\/p>\n<p><\/p>\n<p>S\u00ec. \u00c8 un prodotto commerciale.<\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/501040\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":81090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-81089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Errori comuni nelle applicazioni che portano a bloat in postgresql. Andrej Sal'nikov | ProHoster","description":"Ti propongo di dare un'occhiata alla trascrizione della relazione di inizio 2016 di Andrej Sal'nikov \"Errori comuni nelle applicazioni che portano a bloat in postgresql\" In questa relazione analizzer\u00f2 i punti principali.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-10T23:42:24+00:00","article:modified_time":"2020-05-10T23:42:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"81089","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:05:22","updated":"2022-09-27 16:01:50","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}