Cumu avemu usatu Lazy Replication per a Recuperazione di Disastru cù PostgreSQL

Cumu avemu usatu Lazy Replication per a Recuperazione di Disastru cù PostgreSQL
A replicazione ùn hè micca una copia di salvezza. O micca ? Eccu cumu avemu usatu a replicazione pigra per a ricuperazione eliminendu accidentalmente i shortcuts.

specialisti in infrastruttura GitLab hè rispunsevule per u travagliu GitLab.com - a più grande istanza di GitLab in natura. Cù 3 milioni d'utilizatori è quasi 7 milioni di prughjetti, hè unu di i più grandi siti SaaS open source cù una architettura dedicata. Senza u sistema di basa di dati PostgreSQL, l'infrastruttura GitLab.com ùn andarà micca luntanu, è ciò chì ùn facemu micca solu per a tolleranza di difetti in casu di fallimenti quandu pudete perde dati. Hè improbabile chì una tale catastrofa accadirà, ma avemu preparatu bè è furnitu cù diversi mecanismi di salvezza è replicazione.

A replicazione ùn hè micca u vostru strumentu di salvezza di basa di dati (vede quì sottu). Ma avà vedemu cumu ricuperà rapidamente dati sguassati accidentalmente usendu a replicazione lazy: on GitLab.com l 'utilizatori scurciatoia eliminata per u prugettu gitlab-ce è cunnessioni persu cù richieste di fusione è compiti.

Cù replica ritardata, avemu recuperatu dati in solu 1,5 ore. Vede cumu era.

Recuperazione puntuale cù PostgreSQL

PostgreSQL hà una funzione integrata chì restaurà u statu di una basa di dati à un puntu specificu in u tempu. Hè chjamatu Recuperazione puntuale (PITR) è usa i stessi miccanismi chì mantenenu una replica up-to-date: cuminciendu cù una snapshot affidabile di tuttu u cluster di basa di dati (backup di basa), applichemu una seria di cambiamenti statali finu à un certu puntu in u tempu.

Per utilizà sta funzione per una copia di salvezza à freddo, facemu regularmente una copia di salvezza di basa di basa è a guarda in un archiviu (l'archivi GitLab vivenu in Google cloud storage). Monitoremu ancu i cambiamenti di u statu di a basa di dati archiviendu un logu di scrittura anticipata (scrivite u logu avanti, WAL). È cù tuttu questu, pudemu fà PITR per a ricuperazione di disastru: cuminciamu cù una snapshot presa prima di l'errore è applicà i cambiamenti da l'archiviu WAL finu à u crash.

Cosa hè a replicazione ritardata?

A replicazione ritardata hè l'applicazione di cambiamenti da WAL cù un ritardu. Questu hè, a transazzione hè accaduta à l'ora X, ma apparirà in a replica cun un ritardu d in una ora X + d.

Ci hè 2 modi per stabilisce una replica di basa di dati fisica in PostgreSQL: restaurazione di l'archiviu è replicazione streaming. Restaurazione da un archiviu, Funziona essenzialmente cum'è PITR, ma continuamente: simu constantemente estratti cambiamenti da l'archiviu WAL è l'applicà à a replica. A replicazione in streaming recupera u flussu WAL direttamente da l'ospite di basa di dati upstream. Preferimu restaurà da un archiviu - hè più faciule di gestisce è hà un rendimentu normale, chì ùn hè micca in ritardu di un cluster di produzzione.

Cumu stabilisce a ricuperazione di salvezza ritardata

Opzioni di ricuperazione descrittu in u schedariu recovery.conf. Un esempiu:

standby_mode = 'on'
restore_command = '/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-fetch -p 4 "%f" "%p"'
recovery_min_apply_delay = '8h'
recovery_target_timeline = 'latest'

Cù questi paràmetri, avemu cunfiguratu una replica ritardata cù restaurazione di l'archiviu. Adupratu quì wal-e per estrarre i segmenti WAL (restore_command) da l'archiviu, è i cambiamenti seranu applicati dopu à ottu ore (recovery_min_apply_delay). A replica guarderà i cambiamenti di cronologia in l'archiviu, cum'è per via di un failover di cluster (recovery_target_timeline).

С recovery_min_apply_delay pudete cunfigurà a replicazione in streaming di latenza, ma ci sò un paru di trappule assuciati cù slots di replicazione, feedback hot spare, è cusì. L'archiviu WAL li evita.

Parameter recovery_min_apply_delay apparsu solu in PostgreSQL 9.3. In e versioni precedenti, a replicazione ritardata richiede una cumminazione di funzioni di gestione di ricuperazione (pg_xlog_replay_pause(), pg_xlog_replay_resume()) o mantene i segmenti WAL in l'archiviu per a durata di u ritardu.

Cumu fà PostgreSQL?

Hè interessante per vede cumu PostgreSQL implementa a restaurazione lazy. Fighjemu recoveryApplyDelay(XlogReaderState). Hè chjamatu da ripetizione di u ciclu principale per ogni entrata da WAL.

static bool
recoveryApplyDelay(XLogReaderState *record)
{
    uint8       xact_info;
    TimestampTz xtime;
    long        secs;
    int         microsecs;

    /* nothing to do if no delay configured */
    if (recovery_min_apply_delay <= 0)
        return false;

    /* no delay is applied on a database not yet consistent */
    if (!reachedConsistency)
        return false;

    /*
     * Is it a COMMIT record?
     *
     * We deliberately choose not to delay aborts since they have no effect on
     * MVCC. We already allow replay of records that don't have a timestamp,
     * so there is already opportunity for issues caused by early conflicts on
     * standbys.
     */
    if (XLogRecGetRmid(record) != RM_XACT_ID)
        return false;

    xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;

    if (xact_info != XLOG_XACT_COMMIT &&
        xact_info != XLOG_XACT_COMMIT_PREPARED)
        return false;

    if (!getRecordTimestamp(record, &xtime))
        return false;

    recoveryDelayUntilTime =
        TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);

    /*
     * Exit without arming the latch if it's already past time to apply this
     * record
     */
    TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
                        &secs, &microsecs);
    if (secs <= 0 && microsecs <= 0)
        return false;

    while (true)
    {
        // Shortened:
        // Use WaitLatch until we reached recoveryDelayUntilTime
        // and then
        break;
    }
    return true;
}

U fondu hè chì u ritardu hè basatu annantu à u tempu fisicu registratu in u timestamp di a transazzione impegnata (xtime). Comu pudete vede, u ritardu s'applica solu à l'impegni è ùn affetta micca l'altri registri - tutti i cambiamenti sò appiicati direttamente, è l'impegnu hè ritardatu, cusì vedemu i cambiamenti solu dopu à u ritardu cunfiguratu.

Cumu aduprà a replica lazy per a ricuperazione di dati

Diciamu chì avemu un cluster di basa di dati in pruduzzione è una replica cù un ritardu di ottu ore. Andemu vede cumu a ritruvà dati cù un esempiu eliminazione accidentale di i shortcuts.

Quandu avemu diventatu cuscenti di u prublema, avemu a ricuperazione di salvezza in pausa per a replica ritardata:

SELECT pg_xlog_replay_pause();

Cù una pausa, ùn avemu avutu risicu chì a replica ripetissi a dumanda DELETE. Cosa utile si avete bisognu di tempu per capisce tuttu.

U fondu hè chì a replica ritardata deve ghjunghje à u mumentu prima di a dumanda DELETE. Sapemu circa u tempu fisicu di rimuzione. Avemu cacciatu recovery_min_apply_delay è aghjustatu recovery_target_time в recovery.conf. Allora a replica ghjunghje à u mumentu ghjustu senza ritardu:

recovery_target_time = '2018-10-12 09:25:00+00'

Cù timestamps, hè megliu per riduce l'eccessu per ùn mancà. True, più grande a diminuzione, più dati perdemu. Di novu, se saltamu a dumanda DELETE, tuttu serà sguassatu di novu è avete da ricumincià (o ancu piglià una copia di salvezza fridda per PITR).

Avemu riavviatu l'istanza di Postgres ritardata è i segmenti WAL sò stati ripetuti finu à l'ora specificata. Pudete seguità u prugressu in questa tappa dumandendu:

SELECT
  -- current location in WAL
  pg_last_xlog_replay_location(),
  -- current transaction timestamp (state of the replica)
  pg_last_xact_replay_timestamp(),
  -- current physical time
  now(),
  -- the amount of time still to be applied until recovery_target_time has been reached
  '2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;

Se u timestamp ùn cambia più, a restaurazione hè cumpleta. Pudete persunalizà l'azzione recovery_target_actionper chjude, prumove o mette in pausa l'istanza dopu un novu tentativu (si mette in pausa per difettu).

A basa di dati hè ghjunta à u statu prima di quella dumanda disgraziata. Avà pudete, per esempiu, esportà dati. Avemu esportatu i dati di l'etichetta remota è tutti i ligami per i prublemi è e richieste di fusione è i trasfirìu à a basa di dati di produzzione. Sì i perditi sò grande, pudete simpricimenti prumove a replica è l'utilizanu cum'è u principale. Ma tandu tutti i cambiamenti seranu persi dopu à u mumentu à quale avemu recuperatu.

Hè megliu aduprà ID di transazzione invece di timestamps. Hè utile per arregistrà questi ID, per esempiu, per e dichjarazioni DDL (cum'è DROP TABLE), usendu log_statements = 'ddl'. Se avemu avutu un ID di transazzione, avemu da piglià recovery_target_xid è corse tuttu finu à a transazzione prima di a dumanda DELETE.

Riturnà à u travagliu hè assai simplice: sguassate tutti i cambiamenti da recovery.conf è riavvia postgres. Prestu u cue averà di novu un ritardu di ottu ore, è simu pronti per i prublemi futuri.

Beneficii di ricuperazione

Cù una replica ritardata, invece di una copia di salvezza fridda, ùn avete micca da passà ore à restaurà tutta l'istantanea da l'archiviu. Per esempiu, avemu bisognu di cinque ore per uttene tutta a copia di salvezza di basa di 2 TB. E poi avete sempre à applicà tuttu u WAL di ogni ghjornu per ricuperà à u statu desideratu (in u peghju casu).

Una replica ritardata hè megliu cà una copia di salvezza fridda in dui modi:

  1. Ùn avete bisognu di piglià a copia di salvezza di basa sana da l'archiviu.
  2. Ci hè una finestra fissa di ottu ore di segmenti WAL chì deve esse ripetuta.

Inoltre, cuntrollemu in permanenza per vede s'ellu WAL pò esse PITRed, è notate rapidamente corruzzione o altri prublemi cù l'archiviu WAL monitorendu u backlog di a replica ritardata.

In questu esempiu, ci hà pigliatu 50 minuti per restaurà, vale à dì, a vitezza era 110 GB di dati WAL per ora (l'archiviu era sempre in AWS S3). In u tutale, avemu risoltu u prublema è restauratu i dati in 1,5 ore.

Riassuntu: induve una replica ritardata hè utile (è induve micca)

Aduprate a replicazione ritardata cum'è un primu aiutu se perde accidentalmente dati è nota stu disastru in u ritardu cunfiguratu.

Ma tenite in mente: a replicazione ùn hè micca una copia di salvezza.

A copia di salvezza è a replicazione anu scopi diversi. Una copia di salvezza di fretu serà utile s'ellu avete fattu accidentalmente DELETE o DROP TABLE. Facemu una copia di salvezza da u cold storage è restaurà u statu precedente di a tavula o a basa di dati sana. Ma à u listessu tempu a dumanda DROP TABLE riproduce quasi istantaneamente in tutte e repliche nantu à u cluster di travagliu, cusì a replicazione regulare ùn salverà micca quì. A replicazione stessu mantene a basa di dati dispunibule quandu i servitori individuali sò affittati è distribuisce a carica.

Ancu cù una replica ritardata, avemu qualchì volta veramente bisognu di una copia di salvezza fridda in un locu sicuru, se di colpu ci hè un fallimentu di u centru di dati, danni oculati, o altri avvenimenti chì ùn avete micca avvistu immediatamente. Quì da una replicazione ùn ci hè micca sensu.

Vita. Nantu à u GitLab.com Avemu attualmente prutegge solu da a perdita di dati à u livellu di u sistema è ùn restaurà micca dati à u livellu di l'utilizatori.

Source: www.habr.com

Add a comment