mercoledì 3 luglio 2013

Due feature interessanti di PostgreSQL 9.3

Una delle nuove funzionalita' disponibile con l'imminente usicta di PostgreSQL 9.3 e' il controllo contro la corruzione delle pagine dati.
Nell'era degli hard disk dalle dimensioni enormi, dei dispositivi di memorizzazione portatile e, soprattutto, dei sistemi di reivisione che includono hash crittografici, il controllo contro la corruzione dei dati persistenti e' fondamentale. Non e' un problema di se si rompera' il disco quanto di quando si rompera'.
Simon Riggs, con l'aiuto di altri sviluppatori, ha introdotto un controllo sulle pagine dati mediante un CRC a 16 bit. Sostanzialmente ogni volta che una pagina viene flushata dal memory buffer al disco ne viene calcolato un checksum. Quando la pagina viene ricaricata in memoria il checksum viene controllato.
Cosa succede se il checksum non corrisponde?
Ci sono due alternative: la prima consiste nell'ignorare l'errore e procedere ugualmente, e questa e' ovviamente quella sconsigliata. La seconda prevede che la pagina non sia caricata, ovvero che le tuple non siano accessibili, con conseguente errore di I/O sulla transazione. In sostanza PostgreSQL non e' in grado di prendere alcuna decisione e quindi indica l'errore, lasciando la scelta su cosa fare (accedere i dati forzatamente) al DBA.

Il controllo di coerenza sulla pagina dati deve essere abilitato all'atto di inizializzazione del cluster (ossia initdb) e ovviamente richiedera' un certo ammontare di CPU, che si traduce in un leggero calo di performance (non si puo' avere tutto!). Inoltre sara' disponibile anche un GUC (ossia un parametro di configurazione) per impostare la decisione circa il comportamento in caso di errore.


Un'altra funzione veramente molto interessante e' la presenza di WAL log human readable. La funzione permettera' una analisi dei record contenuti nei WAL e, da una veloce analisi del codice sorgente, il cuore e' rappresentato dal seguente frammento:

static void
XLogDumpDisplayRecord(XLogReaderState *state, XLogRecord *record)
{
...
 printf("xlog record: rmgr: %-11s, record_len: %6u, tot_len: 
         %6u, tx: %10u, lsn: %X/%08X, prev 
         %X/%08X, bkp: %u%u%u%u, desc:",
         desc->rm_name,
         record->xl_len, record->xl_tot_len,
         record->xl_xid,
         (uint32) (state->ReadRecPtr >> 32), 
         (uint32) state->ReadRecPtr,
         (uint32) (record->xl_prev >> 32), 
         (uint32) record->xl_prev,
         !!(XLR_BKP_BLOCK(0) & record->xl_info),
         !!(XLR_BKP_BLOCK(1) & record->xl_info),
         !!(XLR_BKP_BLOCK(2) & record->xl_info),
         !!(XLR_BKP_BLOCK(3) & record->xl_info));

La funzione era gia' stata annunciata al precedente PGDay.IT 2012, e pone le basi per la multi-master replication.

Nessun commento: