Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

In un lontano futuro, la rimozione automatica dei dati non necessari sarà uno dei compiti importanti del DBMS [1]. Nel frattempo, noi stessi dobbiamo occuparci di eliminare o spostare i dati non necessari su sistemi di archiviazione meno costosi. Supponiamo che tu decida di eliminare alcuni milioni di righe. Un compito abbastanza semplice, soprattutto se la condizione è nota e c'è un indice adatto. "DELETE FROM table1 WHERE col1 = :value" - cosa potrebbe essere più semplice, giusto?

Video:

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

  • Faccio parte del comitato del programma Highload dal primo anno, cioè dal 2007.

  • E sono in Postgres dal 2005. Usato in molti progetti.

  • Gruppo con RuPostges anche dal 2007.

  • Siamo cresciuti fino a oltre 2100 partecipanti a Meetup. È la seconda al mondo dopo New York, per lungo tempo superata da San Francisco.

  • Vivo in California da diversi anni. Mi occupo di più delle aziende americane, anche di grandi dimensioni. Sono utenti attivi di Postgres. E ci sono tutti i tipi di cose interessanti.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://postgres.ai/ è la mia compagnia Ci occupiamo di automatizzare le attività che eliminano i rallentamenti dello sviluppo.

Se stai facendo qualcosa, a volte ci sono delle spine intorno a Postgres. Diciamo che devi aspettare che l'amministratore crei un banco di prova per te, oppure devi aspettare che il DBA ti risponda. E troviamo tali colli di bottiglia nel processo di sviluppo, test e amministrazione e proviamo a eliminarli con l'aiuto dell'automazione e di nuovi approcci.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf

Di recente sono stato al VLDB di Los Angeles. Questa è la più grande conferenza sui database. E c'era un rapporto secondo cui in futuro DBMS non solo memorizzerà, ma eliminerà anche automaticamente i dati. Questo è un nuovo argomento.

Ci sono sempre più dati nel mondo degli zettabyte, ovvero 1 di petabyte. E ora si stima già che abbiamo più di 000 zettabyte di dati archiviati nel mondo. E ce ne sono sempre di più.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://vldb2019.github.io/files/VLDB19-keynote-2-slides.pdf

E cosa farne? Ovviamente è da rimuovere. Ecco un link a questo interessante rapporto. Ma finora questo non è stato implementato nel DBMS.

Chi sa contare i soldi vuole due cose. Vogliono che cancelliamo, quindi tecnicamente dovremmo essere in grado di farlo.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Quello che racconterò dopo è una situazione astratta che include un mucchio di situazioni reali, cioè una sorta di raccolta di ciò che è realmente accaduto a me e ai database circostanti molte volte, molti anni. I rastrelli sono ovunque e tutti li calpestano continuamente.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Diciamo che abbiamo una o più basi in crescita. E alcuni dischi sono ovviamente spazzatura. Ad esempio, l'utente ha iniziato a fare qualcosa lì, ma non l'ha finito. E dopo qualche tempo sappiamo che questo incompiuto non può più essere conservato. Cioè, vorremmo pulire alcune cose spazzatura per risparmiare spazio, migliorare le prestazioni, ecc.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

In generale, il compito è automatizzare la rimozione di cose specifiche, righe specifiche in qualche tabella.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

E abbiamo una richiesta del genere, di cui parleremo oggi, cioè della rimozione dei rifiuti.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Abbiamo chiesto a uno sviluppatore esperto di farlo. Ha accettato questa richiesta, l'ha verificata di persona: tutto funziona. Testato sulla messa in scena: va tutto bene. Implementato: tutto funziona. Lo eseguiamo una volta al giorno: va tutto bene.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Il database cresce e cresce. Il DELETE giornaliero inizia a funzionare un po' più lentamente.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Quindi capiamo che ora abbiamo una società di marketing e il traffico sarà molte volte maggiore, quindi decidiamo di sospendere temporaneamente le cose non necessarie. E dimentica di tornare.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Pochi mesi dopo si sono ricordati. E quello sviluppatore si è licenziato o è impegnato con qualcos'altro, ha incaricato un altro di restituirlo.

Ha controllato lo sviluppo, la messa in scena: va tutto bene. Naturalmente, devi ancora ripulire ciò che si è accumulato. Ha controllato che tutto funzioni.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Cosa succede dopo? Poi tutto crolla per noi. Cade così che a un certo punto tutto crolla. Tutti sono sotto shock, nessuno capisce cosa sta succedendo. E poi si scopre che la questione era in questo DELETE.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Qualcosa è andato storto? Ecco un elenco di ciò che potrebbe essere andato storto. Quale di questi è il più importante?

  • Ad esempio, non c'è stata alcuna revisione, ad es. l'esperto DBA non l'ha esaminata. Troverebbe immediatamente il problema con un occhio esperto e inoltre ha accesso a prod, dove si sono accumulati diversi milioni di linee.

  • Forse hanno controllato qualcosa di sbagliato.

  • Forse l'hardware è obsoleto ed è necessario aggiornare questa base.

  • Oppure c'è qualcosa che non va nel database stesso e dobbiamo passare da Postgres a MySQL.

  • O forse c'è qualcosa che non va nell'operazione.

  • Forse ci sono degli errori nell'organizzazione del lavoro e devi licenziare qualcuno e assumere le persone migliori?

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Non è stato effettuato alcun controllo DBA. Se ci fosse un DBA, vedrebbe questi diversi milioni di righe e anche senza alcun esperimento direbbe: "Non lo fanno". Supponiamo che se questo codice fosse in GitLab, GitHub e ci fosse un processo di revisione del codice e non esistesse una cosa del genere che senza l'approvazione del DBA questa operazione avrebbe avuto luogo su prod, quindi ovviamente il DBA direbbe: "Questo non può essere fatto .”

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

E direbbe che avrai problemi con l'IO del disco e tutti i processi impazziranno, potrebbero esserci dei blocchi e inoltre bloccherai l'autovacuum per un mucchio di minuti, quindi non va bene.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

http://bit.ly/nancy-hl2018-2

Il secondo errore: hanno controllato nel posto sbagliato. Abbiamo visto dopo il fatto che molti dati spazzatura si sono accumulati su prod, ma lo sviluppatore non aveva accumulato dati in questo database e nessuno ha creato questa spazzatura durante la messa in scena. Di conseguenza, c'erano 1 righe che hanno funzionato rapidamente.

Comprendiamo che i nostri test sono deboli, ad es. il processo costruito non rileva problemi. Non è stato eseguito un esperimento DB adeguato.

Un esperimento ideale viene preferibilmente eseguito sulla stessa apparecchiatura. Non è sempre possibile farlo sulla stessa attrezzatura, ma è molto importante che sia una copia a grandezza naturale del database. Questo è ciò che predico ormai da diversi anni. E un anno fa ne ho parlato, puoi guardarlo tutto su YouTube.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Forse la nostra attrezzatura è difettosa? Se guardi, la latenza è aumentata. Abbiamo visto che l'utilizzo è del 100%. Ovviamente, se si trattasse di moderne unità NVMe, probabilmente sarebbe molto più semplice per noi. E forse non ci saremmo sdraiati.

Se disponi di cloud, l'aggiornamento viene eseguito facilmente lì. Aumentate nuove repliche sul nuovo hardware. passaggio. E tutto va bene. Molto facile.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

È possibile in qualche modo toccare i dischi più piccoli? E qui, proprio con l'aiuto di DBA, ci immergiamo in un certo argomento chiamato messa a punto del checkpoint. Si scopre che non avevamo la messa a punto del checkpoint.

Cos'è il punto di controllo? È in qualsiasi DBMS. Quando si hanno dati in memoria che cambiano, non vengono scritti immediatamente su disco. Le informazioni che i dati sono stati modificati vengono prima scritte nel registro write-ahead. E a un certo punto, il DBMS decide che è il momento di scaricare le pagine reali su disco, in modo che, in caso di errore, possiamo fare meno REDO. È come un giocattolo. Se veniamo uccisi, inizieremo il gioco dall'ultimo checkpoint. E tutti i DBMS lo implementano.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Le impostazioni in Postgres sono in ritardo. Sono progettati per volumi di dati e transazioni di 10-15 anni. E il checkpoint non fa eccezione.

Ecco le informazioni dal nostro rapporto di controllo Postgres, ovvero il controllo automatico dello stato di salute. Ed ecco un database di diversi terabyte. E si vede bene che posti di blocco forzati in quasi il 90% dei casi.

Cosa significa? Ci sono due impostazioni lì. Il checkpoint può arrivare per timeout, ad esempio, a 10 minuti. Oppure può arrivare quando sono stati riempiti molti dati.

E per impostazione predefinita max_wal_saze è impostato su 1 gigabyte. In effetti, questo accade davvero in Postgres dopo 300-400 megabyte. Hai modificato così tanti dati e il tuo checkpoint si verifica.

E se nessuno lo ha sintonizzato e il servizio è cresciuto e l'azienda guadagna molti soldi, ha molte transazioni, il checkpoint arriva una volta al minuto, a volte ogni 30 secondi e talvolta si sovrappone. Questo è abbastanza brutto.

E dobbiamo assicurarci che arrivi meno spesso. Cioè, possiamo aumentare max_wal_size. E arriverà meno frequentemente.

Ma abbiamo sviluppato un'intera metodologia su come farlo in modo più corretto, ovvero come prendere una decisione sulla scelta delle impostazioni, chiaramente basata su dati specifici.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Di conseguenza, stiamo facendo due serie di esperimenti sui database.

La prima serie: cambiamo max_wal_size. E stiamo facendo un'operazione massiccia. Innanzitutto, lo facciamo con l'impostazione predefinita di 1 gigabyte. E facciamo una massiccia DELETE di molti milioni di righe.

Puoi vedere quanto è difficile per noi. Vediamo che l'IO del disco è pessimo. Guardiamo quanti WAL abbiamo generato, perché questo è molto importante. Vediamo quante volte si è verificato il checkpoint. E vediamo che non va bene.

Successivamente aumentiamo max_wal_size. Noi ripetiamo. Aumentiamo, ripetiamo. E così tante volte. In linea di principio, 10 punti vanno bene, dove 1, 2, 4, 8 gigabyte. E guardiamo al comportamento di un particolare sistema. È chiaro che qui l'attrezzatura dovrebbe essere come su prod. Devi avere gli stessi dischi, la stessa quantità di memoria e le stesse impostazioni di Postgres.

E in questo modo scambieremo il nostro sistema, e sappiamo come si comporterà il DBMS in caso di una cattiva DELETE di massa, come farà il checkpoint.

I checkpoint in russo sono checkpoint.

Esempio: ELIMINA diversi milioni di righe per indice, le righe sono "sparse" tra le pagine.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Ecco un esempio. Questa è una base. E con l'impostazione predefinita di 1 gigabyte per max_wal_size, è molto chiaro che i nostri dischi vanno sullo scaffale per la registrazione. Questa immagine è un sintomo tipico di un paziente molto malato, cioè si sentiva davvero male. E c'era una singola operazione, c'era solo un DELETE di diversi milioni di righe.

Se un'operazione del genere è consentita in prod, allora ci sdraieremo semplicemente, perché è chiaro che un DELETE ci uccide sullo scaffale.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Inoltre, dove 16 gigabyte, è chiaro che i denti sono già andati. I denti stanno già meglio, cioè stiamo bussando al soffitto, ma non così male. C'era un po' di libertà lì. A destra c'è il record. E il numero di operazioni: il secondo grafico. Ed è chiaro che respiriamo già un po 'più facilmente quando 16 gigabyte.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

E dove si possono vedere 64 gigabyte che è diventato completamente migliore. Già i denti sono pronunciati, ci sono più opportunità per sopravvivere ad altre operazioni e fare qualcosa con il disco.

Perché è così?

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Mi immergerò un po 'nei dettagli, ma questo argomento, come condurre la messa a punto del checkpoint, può portare a un intero rapporto, quindi non caricherò molto, ma delineerò un po' quali difficoltà ci sono.

Se il checkpoint si verifica troppo spesso e aggiorniamo le nostre righe non in sequenza, ma troviamo per indice, il che è positivo, perché non cancelliamo l'intera tabella, allora può succedere che prima abbiamo toccato la prima pagina, poi la millesima, e poi tornato al primo . E se tra queste visite alla prima pagina, checkpoint l'ha già salvata su disco, la salverà di nuovo, perché l'abbiamo sporcata una seconda volta.

E forzeremo il checkpoint per salvarlo molte volte. Come ci sarebbero operazioni ridondanti per lui.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Ma non è tutto. Le pagine sono 8 kilobyte in Postgres e 4 kilobyte in Linux. E c'è un'impostazione full_page_writes. Si è abilitata di default. E questo è corretto, perché se lo disattiviamo, c'è il pericolo che solo metà della pagina venga salvata in caso di arresto anomalo.

Il comportamento della scrittura nel WAL del log di inoltro è tale che quando abbiamo un checkpoint e cambiamo la pagina per la prima volta, l'intera pagina, cioè tutti gli 8 kilobyte, entra nel log di inoltro, anche se abbiamo cambiato solo il line, che pesa 100 byte . E dobbiamo scrivere l'intera pagina.

Nelle modifiche successive ci sarà solo una tupla specifica, ma per la prima volta scriviamo tutto.

E, di conseguenza, se il checkpoint si è verificato di nuovo, dobbiamo ricominciare tutto da capo e spingere l'intera pagina. Con checkpoint frequenti, quando percorriamo le stesse pagine, full_page_writes = on sarà più di quanto potrebbe essere, ovvero generiamo più WAL. Altro viene inviato alle repliche, all'archivio, al disco.

E, di conseguenza, abbiamo due licenziamenti.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Se aumentiamo max_wal_size, si scopre che rendiamo le cose più facili sia per checkpoint che per wal writer. E questo è fantastico.

Mettiamoci dentro un terabyte e conviviamoci. Cosa c'è di male? Questo è un male, perché in caso di guasto scaleremo per ore, perché il checkpoint era molto tempo fa e molto è già cambiato. E dobbiamo fare tutto questo REDO. E così facciamo la seconda serie di esperimenti.

Facciamo un'operazione e vediamo quando il checkpoint sta per essere completato, uccidiamo di proposito -9 Postgres.

E dopo lo riavviamo e vediamo per quanto tempo salirà su questa attrezzatura, ad es. quanto RIFARE in questa brutta situazione.

Per due volte noterò che la situazione è brutta. Innanzitutto, ci siamo schiantati poco prima che il checkpoint finisse, quindi abbiamo molto da perdere. E in secondo luogo, abbiamo avuto un'operazione massiccia. E se i checkpoint fossero in timeout, molto probabilmente verrebbe generato meno WAL dall'ultimo checkpoint. Cioè, è un doppio perdente.

Misuriamo una situazione del genere per diverse dimensioni max_wal_size e comprendiamo che se max_wal_size è 64 gigabyte, nel doppio caso peggiore saliremo per 10 minuti. E pensiamo se ci va bene o no. Questa è una domanda di lavoro. Dobbiamo mostrare questa immagine ai responsabili delle decisioni aziendali e chiedere: “Quanto tempo possiamo sdraiarci al massimo in caso di problemi? Possiamo sdraiarci nella situazione peggiore per 3-5 minuti? E tu prendi una decisione.

Ed ecco un punto interessante. Abbiamo un paio di rapporti su Patroni alla conferenza. E forse lo stai usando. Questo è un failover automatico per Postgres. GitLab e Data Egret ne hanno parlato.

E se hai un failover automatico che arriva in 30 secondi, allora forse possiamo sdraiarci per 10 minuti? Perché a questo punto passeremo alla replica e andrà tutto bene. Questo è un punto controverso. Non conosco una risposta chiara. Sento solo che questo argomento non riguarda solo il recupero da crash.

Se abbiamo un lungo recupero dopo un fallimento, allora ci sentiremo a disagio in molte altre situazioni. Ad esempio, negli stessi esperimenti, quando facciamo qualcosa e talvolta dobbiamo aspettare 10 minuti.

Non andrei ancora troppo lontano, anche se avessimo un failover automatico. Di norma, valori come 64, 100 gigabyte sono buoni valori. A volte vale anche la pena scegliere di meno. In generale, questa è una scienza sottile.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Per eseguire iterazioni, ad esempio max_wal_size =1, 8, è necessario ripetere l'operazione di massa molte volte. L'hai fatta. E sulla stessa base vuoi rifarlo, ma hai già cancellato tutto. Cosa fare?

Parlerò più avanti della nostra soluzione, di cosa facciamo per iterare in tali situazioni. E questo è l'approccio più corretto.

Ma in questo caso siamo stati fortunati. Se, come dice qui "BEGIN, DELETE, ROLLBACK", allora possiamo ripetere DELETE. Cioè, se lo annulliamo noi stessi, possiamo ripeterlo. E fisicamente a te i dati si troveranno nello stesso posto. Non ti gonfi nemmeno. Puoi iterare su tali DELETE.

Questo DELETE con ROLLBACK è ideale per l'ottimizzazione del checkpoint, anche se non si dispone di laboratori di database distribuiti correttamente.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Abbiamo realizzato un piatto con una colonna "i". Postgres ha colonne di utilità. Sono invisibili se non espressamente richiesti. Questi sono: ctid, xmid, xmax.

Ctid è un indirizzo fisico. Pagina zero, la prima tupla nella pagina.

Si può vedere che dopo ROOLBACK la tupla è rimasta nello stesso posto. Cioè, possiamo riprovare, si comporterà allo stesso modo. Questa è la cosa principale.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Xmax è l'ora di morte della tupla. È stato contrassegnato, ma Postgres sa che la transazione è stata ripristinata, quindi non importa se è 0 o è una transazione ripristinata. Ciò suggerisce che è possibile eseguire iterazioni su DELETE e controllare le operazioni di massa del comportamento del sistema. Puoi creare laboratori di database per i poveri.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Si tratta di programmatori. Anche a proposito di DBA rimproverano sempre i programmatori per questo: "Perché fai operazioni così lunghe e difficili?". Questo è un argomento perpendicolare completamente diverso. Prima c'era l'amministrazione e ora ci sarà lo sviluppo.

Ovviamente non ci siamo fatti a pezzi. È chiaro. È impossibile non spezzare tale DELETE per un mucchio di milioni di righe in parti. Sarà fatto per 20 minuti e tutto si sdraierà. Ma, sfortunatamente, anche gli sviluppatori esperti commettono errori, anche in aziende molto grandi.

Perché è importante rompere?

  • Se vediamo che il disco è duro, rallentiamolo. E se siamo rotti, allora possiamo aggiungere pause, possiamo rallentare il throttling.

  • E non bloccheremo gli altri per molto tempo. In alcuni casi non importa, se stai eliminando spazzatura reale su cui nessuno sta lavorando, molto probabilmente non bloccherai nessuno tranne il lavoro di autovacuum, perché attenderà il completamento della transazione. Ma se rimuovi qualcosa che qualcun altro può richiedere, verrà bloccato, ci sarà una sorta di reazione a catena. Le transazioni lunghe dovrebbero essere evitate su siti Web e applicazioni mobili.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://postgres.ai/products/joe/

Questo è interessante. Vedo spesso che gli sviluppatori chiedono: "Quale dimensione del pacchetto dovrei scegliere?".

È chiaro che maggiore è la dimensione del pacchetto, minore è l'overhead della transazione, ovvero l'overhead aggiuntivo delle transazioni. Ma allo stesso tempo, il tempo per questa transazione aumenta.

Ho una regola molto semplice: prendi più che puoi, ma non superare gli eseguibili al secondo.

Perché un secondo? La spiegazione è molto semplice e comprensibile a tutti, anche ai non tecnici. Vediamo una reazione. Prendiamo 50 millisecondi. Se qualcosa è cambiato, il nostro occhio reagirà. Se meno, allora più difficile. Se qualcosa risponde dopo 100 millisecondi, ad esempio, hai fatto clic con il mouse e ti ha risposto dopo 100 millisecondi, senti già questo leggero ritardo. Un secondo è già percepito come freni.

Di conseguenza, se interrompiamo le nostre operazioni di massa in sequenze di 10 secondi, corriamo il rischio di bloccare qualcuno. E funzionerà per alcuni secondi e le persone lo noteranno già. Pertanto, preferisco non fare più di un secondo. Ma allo stesso tempo, non suddividerlo molto finemente, perché il sovraccarico della transazione sarà evidente. La base sarà più dura e potrebbero sorgere altri problemi.

Scegliamo la dimensione della confezione. In ogni caso, possiamo farlo in modo diverso. Può essere automatizzato. E siamo convinti dell'efficienza della lavorazione di un pacco. Cioè, eliminiamo un pacchetto o lo AGGIORNIAMO.

A proposito, tutto ciò di cui parlo non riguarda solo DELETE. Come hai intuito, si tratta di operazioni in blocco sui dati.

E vediamo che il piano è eccellente. Puoi vedere la scansione dell'indice, la scansione solo dell'indice è ancora migliore. E abbiamo una piccola quantità di dati coinvolti. E meno di un secondo soddisfa. Super.

E dobbiamo ancora assicurarci che non ci sia degrado. Succede che i primi pacchetti si risolvano rapidamente e poi peggiora, peggiora e peggiora. Il processo è tale che devi testare molto. Questo è esattamente lo scopo dei laboratori di database.

E dobbiamo ancora preparare qualcosa in modo che ci permetta di seguirlo correttamente nella produzione. Ad esempio, possiamo scrivere l'ora nel registro, possiamo scrivere dove siamo ora e chi abbiamo ora cancellato. E questo ci permetterà di capire cosa sta succedendo in seguito. E nel caso qualcosa vada storto, trova rapidamente il problema.

Se dobbiamo verificare l'efficienza delle richieste e dobbiamo iterare molte volte, allora esiste un collega bot. È già pronto. Viene utilizzato quotidianamente da dozzine di sviluppatori. E sa come fornire un enorme database di terabyte su richiesta in 30 secondi, la tua copia. E puoi eliminare qualcosa lì e dire RESET ed eliminarlo di nuovo. Puoi sperimentarlo in questo modo. Vedo un futuro per questa cosa. E lo stiamo già facendo.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://docs.gitlab.com/ee/development/background_migrations.html

Cosa sono le strategie di partizionamento? Vedo 3 diverse strategie di partizionamento utilizzate dagli sviluppatori del pacchetto.

Il primo è molto semplice. Abbiamo un ID numerico. E suddividiamolo in diversi intervalli e lavoriamo con quello. Il rovescio della medaglia è chiaro. Nel primo segmento, potremmo avere 100 righe di vera spazzatura, nelle seconde 5 righe o per niente, o tutte le 1 righe risulteranno spazzatura. Lavoro molto irregolare, ma è facile da rompere. Hanno preso l'ID massimo e l'hanno distrutto. Questo è un approccio ingenuo.

La seconda strategia è un approccio equilibrato. È usato in Gitlab. Hanno preso e scansionato il tavolo. Abbiamo trovato i confini dei pacchetti ID in modo che ogni pacchetto contenesse esattamente 10 record. E metterli in coda. E poi elaboriamo. Puoi farlo in più thread.

Anche nella prima strategia, tra l'altro, puoi farlo in diversi thread. Non è difficile.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

https://medium.com/@samokhvalov/how-partial-indexes-affect-update-performance-in-postgres-d05e0052abc

Ma c'è un approccio più interessante e migliore. Questa è la terza strategia. E quando possibile, è meglio sceglierlo. Lo facciamo sulla base di un indice speciale. In questo caso, molto probabilmente sarà un indice in base alla nostra condizione di immondizia e ID. Includeremo l'ID in modo che sia solo una scansione dell'indice in modo da non andare nell'heap.

Generalmente, la scansione solo indice è più veloce della scansione indice.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

E troviamo rapidamente i nostri ID che vogliamo eliminare. BATCH_SIZE selezioniamo in anticipo. E non solo li prendiamo, li prendiamo in un modo speciale e li hackeriamo immediatamente. Ma stiamo bloccando in modo che se sono già bloccati, non li blocchiamo, ma andiamo avanti e prendiamo quelli successivi. Questo è per l'aggiornamento salta bloccato. Questa super funzionalità di Postgres ci consente di lavorare su più thread, se lo desideriamo. È possibile in un flusso. E qui c'è un CTE: questa è una richiesta. E abbiamo una vera cancellazione in corso al secondo piano di questo CTE... returning *. Puoi restituire l'ID, ma è meglio *se non hai molti dati su ogni riga.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Perchè ne abbiamo bisogno? Questo è ciò che dobbiamo riferire. Ora abbiamo cancellato così tante righe in effetti. E abbiamo confini per ID o per created_at in questo modo. Puoi fare min, max. Si può fare qualcos'altro. Puoi farcire molto qui. Ed è molto conveniente per il monitoraggio.

C'è un'altra nota sull'indice. Se decidiamo di aver bisogno di un indice speciale per questa attività, dobbiamo assicurarci che non rovini solo gli aggiornamenti delle tuple dell'heap. Cioè, Postgres ha tali statistiche. Questo può essere visto in pg_stat_user_tables per la tua tabella. Puoi vedere se gli aggiornamenti a caldo vengono utilizzati o meno.

Ci sono situazioni in cui il tuo nuovo indice può semplicemente tagliarli. E hai tutti gli altri aggiornamenti che stanno già funzionando, rallenta. Non solo perché è apparso l'indice (ogni indice rallenta un po 'gli aggiornamenti, ma un po'), ma qui lo rovina ancora. Ed è impossibile effettuare un'ottimizzazione speciale per questa tabella. Questo succede a volte. Questa è una tale sottigliezza che poche persone ricordano. E questo rastrello è facile da calpestare. A volte capita che sia necessario trovare un approccio dall'altra parte e continuare a fare a meno di questo nuovo indice, o creare un altro indice, o in qualche altro modo, ad esempio, è possibile utilizzare il secondo metodo.

Ma questa è la strategia ottimale, come dividere in lotti e sparare a lotti con una richiesta, eliminare un po', ecc.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Transazioni lunghe https://gitlab.com/snippets/1890447

Autovuoto bloccato - https://gitlab.com/snippets/1889668

problema di blocco - https://gitlab.com/snippets/1890428

L'errore n. 5 è grave. Nikolai di Okmeter ha parlato del monitoraggio di Postgres. Il monitoraggio ideale di Postgres, sfortunatamente, non esiste. Alcuni sono più vicini, altri più lontani. Okmeter è abbastanza vicino alla perfezione, ma manca molto e deve essere aggiunto. Devi essere pronto per questo.

Ad esempio, le tuple morte vengono monitorate meglio. Se hai un sacco di cose morte nel tavolo, allora c'è qualcosa che non va. È meglio reagire ora, altrimenti potrebbe esserci un degrado e possiamo sdraiarci. Succede.

Se c'è un grande IO, allora è chiaro che questo non va bene.

Anche transazioni lunghe. Le transazioni lunghe non dovrebbero essere consentite su OLTP. Ed ecco un collegamento a uno snippet che ti consente di prendere questo snippet e di eseguire già un monitoraggio delle transazioni lunghe.

Perché le transazioni lunghe sono negative? Perché tutte le serrature verranno rilasciate solo alla fine. E freghiamo tutti. Inoltre, blocchiamo l'autovacuum per tutti i tavoli. Non va affatto bene. Anche se hai abilitato l'hot standby sulla replica, è comunque negativo. In generale, da nessuna parte è meglio evitare lunghe transazioni.

Se abbiamo molti tavoli che non vengono aspirati, allora dobbiamo avere un avviso. Qui una situazione del genere è possibile. Possiamo influenzare indirettamente il funzionamento dell'autovacuum. Questo è un frammento di Avito, che ho leggermente migliorato. E si è rivelato uno strumento interessante per vedere cosa abbiamo con l'autovacuum. Ad esempio, alcuni tavoli stanno aspettando lì e non aspetteranno il loro turno. Devi anche metterlo in monitoraggio e avere un avviso.

E rilascia blocchi. Foresta di alberi di blocco. Mi piace prendere qualcosa da qualcuno e migliorarlo. Qui ho preso un bel CTE ricorsivo da Data Egret che mostra una foresta di lock tree. Questo è un buon strumento diagnostico. E sulla sua base, puoi anche costruire il monitoraggio. Ma questo deve essere fatto con attenzione. Devi fare un piccolo statement_timeout per te stesso. E lock_timeout è desiderabile.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

A volte tutti questi errori si verificano in somma.

Secondo me, l'errore principale qui è organizzativo. È organizzativo, perché la tecnica non tira. Questo è il numero 2: hanno controllato nel posto sbagliato.

Abbiamo controllato nel posto sbagliato, perché non avevamo un clone di produzione, che è facile da controllare. Uno sviluppatore potrebbe non avere affatto accesso alla produzione.

E non abbiamo controllato lì. Se avessimo controllato lì, l'avremmo visto noi stessi. Lo sviluppatore ha visto tutto anche senza un DBA se lo ha controllato in un buon ambiente, dove c'è la stessa quantità di dati e una posizione identica. Avrebbe visto tutto questo degrado e se ne sarebbe vergognato.

Maggiori informazioni sull'autovuoto. Dopo aver effettuato un'enorme scansione di diversi milioni di righe, dobbiamo ancora eseguire REPACK. Ciò è particolarmente importante per gli indici. Si sentiranno male dopo che avremo pulito tutto lì.

E se vuoi riportare il lavoro di pulizia quotidiano, suggerirei di farlo più spesso, ma più piccolo. Può essere una volta al minuto o anche più spesso un po'. E devi monitorare due cose: che questa cosa non abbia errori e che non sia in ritardo. Il trucco che ho mostrato risolverà solo questo.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Quello che facciamo è open source. È pubblicato su GitLab. E lo facciamo in modo che le persone possano controllare anche senza un DBA. Stiamo realizzando un laboratorio di database, ovvero chiamiamo il componente di base su cui Joe sta attualmente lavorando. E puoi prendere una copia della produzione. Ora c'è un'implementazione di Joe per slack, puoi dire lì: "spiega questa e quella richiesta" e ottieni immediatamente il risultato per la tua copia del database. Puoi persino CANCELLARE lì e nessuno se ne accorgerà.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Diciamo che hai 10 terabyte, creiamo database lab anche 10 terabyte. E con database simultanei da 10 terabyte, 10 sviluppatori possono lavorare contemporaneamente. Ognuno può fare quello che vuole. Può eliminare, rilasciare, ecc. È una tale fantasia. Di questo parleremo domani.

Caro ELIMINA. Nikolaj Samokhvalov (Postgres.ai)

Questo si chiama thin provisioning. Questo è un approvvigionamento sottile. Questa è una sorta di fantasia che rimuove notevolmente i ritardi nello sviluppo, nei test e rende il mondo un posto migliore in questo senso. Cioè, ti consente solo di evitare problemi con le operazioni di massa.

Esempio: database da 5 terabyte, ottenendo una copia in meno di 30 secondi. E non dipende nemmeno dalla dimensione, cioè non importa quanti terabyte.

Oggi puoi andare a postgres.ai e scavare nei nostri strumenti. Puoi registrarti per vedere cosa c'è. Puoi installare questo bot. È gratis. Scrivere.

domande

Molto spesso in situazioni reali si scopre che i dati che dovrebbero rimanere nella tabella sono molto meno di quelli che devono essere cancellati. Cioè, in una situazione del genere, è spesso più facile implementare un tale approccio, quando è più facile creare un nuovo oggetto, copiare lì solo i dati necessari ed eseguire il trunking della vecchia tabella. È chiaro che in questo momento è necessario un approccio programmatico, mentre cambierete. Com'è questo approccio?

Questo è un ottimo approccio e un ottimo compito. È molto simile a ciò che fa pg_repack, è molto simile a ciò che devi fare quando crei ID 4 byte. Molti framework lo hanno fatto alcuni anni fa, e solo le lastre sono cresciute e devono essere convertite in 8 byte.

Questo compito è abbastanza difficile. Ce l'abbiamo fatta. E devi stare molto attento. Ci sono serrature, ecc. Ma si sta facendo. Cioè, l'approccio standard è andare con pg_repack. Dichiari una tale etichetta. E prima di iniziare a caricare i dati dell'istantanea, dichiari anche una lastra che tiene traccia di tutte le modifiche. C'è un trucco che potresti non tenere nemmeno traccia di alcune modifiche. Ci sono sottigliezze. E poi cambi facendo rotolare le modifiche. Ci sarà una breve pausa quando chiuderemo tutti, ma in generale questo è stato fatto.

Se guardi pg_repack su GitHub, allora lì, quando c'era un'attività per convertire un ID da int 4 a int 8, allora c'era l'idea di usare pg_repack stesso. Anche questo è possibile, ma è un po' un trucco, ma funzionerà anche per questo. Puoi intervenire nel trigger utilizzato da pg_repack e dire lì: "Non abbiamo bisogno di questi dati", ovvero trasferiamo solo ciò di cui abbiamo bisogno. E poi cambia e basta.

Con questo approccio, otteniamo comunque una seconda copia della tabella, in cui i dati sono già indicizzati e impilati in modo molto uniforme con bellissimi indici.

Bloat non è presente, è un buon approccio. Ma so che ci sono tentativi di sviluppare un'automazione per questo, ad es. per creare una soluzione universale. Posso metterti in contatto con questa automazione. È scritto in Python, il che è una buona cosa.

Vengo solo un po' dal mondo di MySQL, quindi sono venuto ad ascoltare. E usiamo questo approccio.

Ma è solo se abbiamo il 90%. Se abbiamo il 5%, non è molto utile usarlo.

Grazie per la segnalazione! Se non ci sono risorse per creare una copia completa di prod, esiste un algoritmo o una formula per calcolare il carico o le dimensioni?

Buona domanda. Finora, siamo in grado di trovare database multi-terabyte. Anche se l'hardware non è lo stesso, ad esempio, meno memoria, meno processore e dischi non sono esattamente gli stessi, ma lo facciamo comunque. Se non c'è assolutamente da nessuna parte, allora devi pensare. Fammi pensare fino a domani, sei venuto, parleremo, questa è una buona domanda.

Grazie per la segnalazione! Hai iniziato parlando del fatto che esiste un fantastico Postgres, che ha questi e quei limiti, ma si sta sviluppando. E questa è tutta una stampella in generale. Tutto questo non è in conflitto con lo sviluppo di Postgres stesso, in cui appariranno alcuni deferenti DELETE o qualcos'altro che dovrebbe mantenere a un livello basso ciò che stiamo cercando di imbrattare con alcuni dei nostri strani mezzi qui?

Se in SQL abbiamo detto di eliminare o aggiornare molti record in una transazione, come può Postgres distribuirlo lì? Siamo fisicamente limitati nelle operazioni. Lo faremo ancora per molto tempo. E bloccheremo in questo momento, ecc.

Fatto con gli indici.

Posso presumere che la stessa messa a punto del checkpoint possa essere automatizzata. Un giorno potrebbe esserlo. Ma poi non capisco davvero la domanda.

La domanda è: esiste un tale vettore di sviluppo che va qua e là, e qui il tuo va in parallelo? Quelli. Non ci hanno ancora pensato?

Ho parlato dei principi che possono essere usati ora. C'è un altro robot Nancy, con questo puoi eseguire l'ottimizzazione automatica del checkpoint. Un giorno sarà in Postgres? Non lo so, non se ne è ancora parlato. Siamo ancora lontani da questo. Ma ci sono scienziati che creano nuovi sistemi. E ci spingono in indici automatici. Ci sono sviluppi. Ad esempio, puoi guardare l'autotuning. Seleziona i parametri automaticamente. Ma non eseguirà ancora la messa a punto del checkpoint per te. Cioè, riprenderà per prestazioni, buffer di shell, ecc.

E per l'ottimizzazione del checkpoint, puoi farlo: se hai mille cluster e hardware diverso, macchine virtuali diverse nel cloud, puoi usare il nostro bot Nancy fare automazione. E max_wal_size verrà selezionato automaticamente in base alle impostazioni di destinazione. Ma finora questo non è nemmeno vicino al nucleo, sfortunatamente.

Buon pomeriggio Hai parlato dei pericoli delle lunghe transazioni. Hai detto che l'autovacuum è bloccato in caso di cancellazioni. In quale altro modo ci danneggia? Perché stiamo parlando più di liberare spazio e poterlo usare. Cos'altro ci manca?

L'autovacuum forse non è il problema più grande qui. E il fatto che una lunga transazione possa bloccare altre transazioni, questa possibilità è più pericolosa. Potrebbe incontrarsi o meno. Se si è incontrata, allora può essere molto brutto. E con l'autovacuum, anche questo è un problema. Esistono due problemi con le transazioni lunghe in OLTP: i blocchi e l'autovacuum. E se hai abilitato il feedback hot standby sulla replica, riceverai comunque un blocco di autovacuum sul master, che arriverà dalla replica. Ma almeno non ci saranno serrature. E ci saranno blocchi. Stiamo parlando di modifiche ai dati, quindi i blocchi sono un punto importante qui. E se questo è tutto per molto, molto tempo, sempre più transazioni vengono bloccate. Possono rubare gli altri. E compaiono gli alberi lok. Ho fornito un collegamento allo snippet. E questo problema diventa più evidente più velocemente del problema con l'autovacuum, che può solo accumularsi.

Grazie per la segnalazione! Hai iniziato il tuo rapporto dicendo che hai testato in modo errato. Abbiamo continuato la nostra idea che dobbiamo prendere la stessa attrezzatura, con la base allo stesso modo. Diciamo che abbiamo dato allo sviluppatore una base. E ha ottemperato alla richiesta. E sembra che stia bene. Ma non controlla dal vivo, ma dal vivo, ad esempio, abbiamo un carico del 60-70%. E anche se usiamo questa messa a punto, non funziona molto bene.

È importante avere un esperto nel team e utilizzare esperti DBA in grado di prevedere cosa accadrà con un carico in background reale. Quando abbiamo appena guidato i nostri cambiamenti puliti, vediamo l'immagine. Ma un approccio più avanzato, quando abbiamo fatto di nuovo la stessa cosa, ma con un carico simulato con la produzione. È abbastanza bello. Fino ad allora, devi crescere. È come un adulto. Abbiamo solo esaminato ciò che abbiamo e anche verificato se disponiamo di risorse sufficienti. Questa è una bella domanda.

Quando stiamo già eseguendo una selezione spazzatura e abbiamo, ad esempio, un flag eliminato

Questo è ciò che fa automaticamente autovacuum in Postgres.

Ah, lo fa?

Autovacuum è il Garbage Collector.

Grazie!

Grazie per la segnalazione! Esiste un'opzione per progettare immediatamente un database con il partizionamento in modo tale che tutta la spazzatura si sporchi dalla tabella principale da qualche parte a lato?

Certamente.

È possibile quindi proteggersi se abbiamo bloccato un tavolo che non dovrebbe essere utilizzato?

Certo. Ma è come una domanda sull'uovo e la gallina. Se sappiamo tutti cosa accadrà in futuro, allora, ovviamente, faremo tutto bene. Ma il business sta cambiando, ci sono nuove rubriche, nuove richieste. E poi - oops, vogliamo rimuoverlo. Ma questa situazione ideale, nella vita si verifica, ma non sempre. Ma nel complesso è una buona idea. Basta troncare e basta.

Fonte: habr.com

Aggiungi un commento