Modifica tabella su database di produzione live


24

In che modo il sistema di database più "popolare" (MySQL, Postgres ...) gestisce le tabelle di modifica sui database di produzione live (come l'aggiunta, l'eliminazione o la modifica del tipo di colonne)?

So che il modo corretto è quello di eseguire il backup di tutti i tempi di inattività pianificati e quindi fare le modifiche.

Ma ... qualsiasi sistema di database corrente supporta queste operazioni "on-line" senza interrompere nulla? (forse solo ritardando le query che fanno riferimento a una colonna che è appena stata modificata / eliminata)

E cosa succede quando faccio un ALTER TABLE...database in esecuzione dal vivo? Tutto si ferma quando questo accade? I dati possono essere danneggiati? eccetera.

Ancora una volta, mi riferisco principalmente a Postgres o MySQL poiché questi sono ciò che incontro.

(E, sì, ogni volta che dovevo farlo prima di farlo "nel modo giusto", eseguendo il backup di cose, programmando downtine ecc ... ma voglio solo sapere se è possibile fare questo tipo e le cose "velocemente e dirty "o se esiste un sistema DB che supporta effettivamente modifiche dello schema" veloci, attive e sporche ")


Qualcuno ha appena suggerito il cambio di schema online per MySQL dallo script di Facebook (con un tutorial qui e fonte qui ) ... sembra un bel modo per automatizzare una serie di modi "hacky" per farlo ... qualcuno lo ha mai usato qualcosa somiglia alla produzione?


3
Nota: il "modo corretto" specificato è relativo a MySQL e non a PostgreSQL. Il "modo corretto" in PostgreSQL è in genere molto semplice, sebbene possa essere coinvolto. L'uso di pg_reorgpuò aiutare con gli scenari più difficili.
Sean,

Mi sarebbe piaciuto avere un video dettagliato su questo, con qualcuno che spiegasse quante più strategie possibili.
Sandeepan Nath,

Risposte:


22

Quando si emette un ALTER TABLEPostgreSQL , ci vorrà un ACCESS EXCLUSIVEblocco che blocca tutto compresoSELECT . Tuttavia, questo blocco può essere molto brevi se la tabella non richiede ri-scrittura, non nuovi UNIQUE, CHECKo FOREIGN KEYvincoli hanno bisogno di costose scansioni full-tabella per verificare, etc.

In caso di dubbio, in genere puoi semplicemente provarlo! Tutto il DDL in PostgreSQL è transazionale, quindi è bene annullare un ALTER TABLEse impiega troppo tempo e inizia a trattenere altre query. I livelli di blocco richiesti da vari comandi sono documentati nella pagina di blocco .

Alcune operazioni normalmente lente possono essere accelerate per essere sicure da eseguire senza tempi di inattività. Ad esempio, se si dispone di una tabella te si desidera modificare la colonna customercode integer NOT NULLin textperché il cliente ha deciso che tutti i codici cliente devono ora iniziare con un X, è possibile scrivere:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... ma ciò bloccherebbe l'intera tabella per la riscrittura. Quindi l'aggiunta di una colonna con a DEFAULT. Può essere fatto in un paio di passaggi per evitare il blocco lungo, ma le applicazioni devono essere in grado di far fronte alla duplicazione temporanea:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Questo consentirà di evitare solo le scritture a tdurante il processo; il nome del lucchetto EXCLUSIVEè in qualche modo ingannevole in quanto esclude tutto tranneSELECT ; la ACCESS EXCLUSIVEmodalità è l'unica che esclude assolutamente tutto. Vedi le modalità di blocco . Esiste il rischio che questa operazione possa eseguire il rollback del deadlock a causa dell'aggiornamento del blocco richiesto da ALTER TABLE, ma nella peggiore delle ipotesi dovrai rifarlo.

Si può anche evitare che il blocco e fare il tutto in diretta con la creazione di una funzione di trigger su tche ogni volta che una INSERTo UPDATEviene in, inserisce automaticamente customercode_newda customercode.

Ci sono anche strumenti integrati come CREATE INDEX CONCURRENTLYe che ALTER TABLE ... ADD table_constraint_using_indexsono progettati per consentire ai DBA di ridurre le durate di blocco esclusive facendo un lavoro più lentamente in un modo concorrenziale.

Lo pg_reorgstrumento o il suo successore pg_repackpossono essere utilizzati anche per alcune operazioni di ristrutturazione dei tavoli.


1
La cosa chiave in ciò che ha detto @Craig è stata "se non è necessario riscrivere". L'uso di ALTER TABLE t ADD COLUMN i INTè un'operazione rapida (in genere <1 ms) una volta acquisito il blocco. L'acquisizione del blocco può tuttavia mettere in coda le connessioni, quindi non è "gratuito" ... sebbene sia il mondo migliore di quello che devi fare in MySQL. Aggiungere un NOT NULLvincolo è più difficile e non per il finto cuore.
Sean,

Sembra essere il consenso che pg_repackè il successore migliorato di pg_reorg.
Erwin Brandstetter,

Una buona risposta, per quanto riguarda l'aggiunta di una colonna con un valore predefinito (o calcolato) in modo meno "bloccante" è quella di creare un'intera nuova tabella, bloccare la vecchia tabella per inserire / aggiornare / eliminare ma consentendo di selezionare e popolare la nuova. Infine emetti un breve blocco esclusivo sulla vecchia tabella per selezionare, eliminalo e rinomina da vecchio a vecchio. A seconda del tuo scenario puoi persino iniziare a popolare il nuovo senza bloccare gli inserti nel vecchio e rilasciare quel blocco esclusivo solo mentre risolvi il diff (speriamo solo inserendo alcuni nuovi record)
Jean

7

Percona ha messo a punto un proprio strumento per eseguire modifiche allo schema online

Lo strumento si chiama pt-online-schema-change

Implica i trigger, quindi leggi attentamente la documentazione.

Secondo la documentazione, le principali operazioni eseguite sono

  • Controlli di sanità mentale
  • chunking
  • Modifica dello schema online
    • Crea e modifica la tabella temporanea
    • Cattura le modifiche dalla tabella alla tabella temporanea
    • Copia le righe dalla tabella alla tabella temporanea
    • Sincronizza la tabella e la tabella temporanea
    • Scambia / rinomina la tabella e la tabella temporanea
    • Pulire

grazie, sembra una versione "soldified" dell'approccio di Facebook di cui potrei fidarmi di più ...
NeuronQ,

pt-online-schema-change è sicuramente il modo preferito per farlo se si esegue il proprio server MySQL. A partire da Percona Tools 2.2, (purtroppo) non supportano RDS / Aurora su AWS. pt-online-schema-change inserisce un trigger nella tabella di origine per copiare le righe (bassa priorità per MyISAM) nella destinazione table_temp ed esegue un singolo drop di blocco rapido e rinomina alla fine quando tutte le righe sono sincronizzate tra l'origine e la destinazione tabelle.
phpguru,

6

Arrestare il sistema e apportare tutte le modifiche contemporaneamente può essere molto rischioso. Se qualcosa va storto, e spesso lo fa, non è possibile tornare indietro.

Come sviluppatore Agile, a volte ho bisogno di refactoring delle tabelle senza tempi di inattività, poiché tali tabelle vengono modificate e lette.

L'approccio seguente presenta un rischio basso, poiché la modifica viene eseguita in diversi passaggi a basso rischio che sono molto facili da ripristinare:

  • Assicurarsi che tutti i moduli che accedono alla tabella siano ben coperti da test automatici.
  • Crea una nuova tabella. Modificare tutte le procedure che modificano la vecchia tabella, in modo che modifichino sia le vecchie che le nuove tabelle.
  • Migrare i dati esistenti in una nuova struttura. Fallo in batch di piccole dimensioni, in modo che non influisca seriamente sulle prestazioni complessive sul server.
  • Verificare che la migrazione dei dati sia riuscita.
  • Reindirizzare alcune delle procedure di selezione dalla vecchia tabella a quelle nuove. Utilizzare test automatici per assicurarsi che i moduli modificati siano ancora corretti. Assicurati che le loro prestazioni siano accettabili. Distribuire le procedure modificate.
  • Ripetere il passaggio precedente fino a quando tutti i report utilizzano la nuova tabella.
  • Modificare le procedure che modificano le tabelle, in modo che accedano solo alla nuova tabella.
  • Archivia la vecchia tabella e rimuovila dal sistema.

Abbiamo usato questo approccio molte volte per modificare grandi tabelle di produzione live senza tempi di inattività, senza alcun problema.


3
fantastico ... ma questo è esattamente il tipo di "dolore" che sto cercando di evitare :)
NeuronQ,

@NeuronQ " Non c'è modo semplice di tornare " - c'è in Postgres: metti semplicemente tutto in una transazione e rollbackse qualcosa va storto.
a_horse_with_no_name

2

Sì, molti database moderni ti permetteranno solo di aggiungere una colonna o modificare le caratteristiche di una colonna, come aggiungere o rimuovere nullable.

Se si rilascia una colonna, i dati andranno persi, ma non c'è molta paura della corruzione.



-1

Per rispondere alla domanda su cosa succede con ALTER TABLEun'affermazione, dipende dall'entità delle modifiche. In casi specifici, se si aggiunge una nuova colonna, almeno in MS SQL Server, il motore creerà una copia temporanea della tabella, mentre crea la nuova definizione della tabella e quindi inserisce nuovamente i dati. Per la durata della modifica, la tabella sarebbe quindi inaccessibile agli utenti.

Un esempio delle operazioni specifiche per il server MSSQL è qui: http://support.microsoft.com/kb/956176/en-us

Suppongo che altri RMDB abbiano metodi simili, anche se l'implementazione esatta sarebbe qualcosa che dovresti verificare con la documentazione del fornitore.


-1 Questo è completamente sbagliato per SQL Server: "Se aggiungi una nuova colonna, almeno in MS SQL Server, il motore creerà una copia temporanea della tabella, mentre crea la nuova definizione della tabella e quindi inserisce nuovamente i dati "
AK,

@AlexKuznetsov - Ho immaginato la riga precedente, così come il collegamento con alcuni dei casi elencati chiarirebbe che ciò non accade sempre. Ho modificato la frase per riflettere meglio questo.
SchmitzIT,

1
Stai citando il comportamento della GUI, SSMS, non il comportamento di SQL Server stesso. Seguendo il tuo link, il consiglio è di usare T-SQL direttamente per apportare modifiche al DDL. SSMS non è un ottimo strumento per cambiare DDL.
AK,

@AlexKuznetsov - Ho letto l'articolo dicendo che ci sono rischi, ma non come scoraggiamento. Comunque, non ho collegato l'articolo per il bit della GUI, ma come indicazione di alcune delle operazioni che portano a un'istruzione ALTER che porta alla creazione di una tabella temporanea a causa di cambiamenti nella struttura dei dati sottostanti. Non ho testato se la stessa cosa si applica quando si rilascia l'istruzione direttamente da T-SQL, ma penso che il processo sia abbastanza simile e che SL Server esegua il lavoro dietro le quinte.
SchmitzIT,

È possibile avviare Profiler, eseguire direttamente l'istruzione ALTER TABLE e vedere cosa sta succedendo. Quindi puoi modificare una tabella tramite una finestra di dialogo e vedere di persona i comandi in esecuzione.
AK,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.