ื›ื™ืฆื“ ื”ืฉืชืžืฉื ื• ื‘ืฉื›ืคื•ืœ ืขืฆืœืŸ ืœื”ืชืื•ืฉืฉื•ืช ืžืืกื•ืŸ ืขื PostgreSQL

ื›ื™ืฆื“ ื”ืฉืชืžืฉื ื• ื‘ืฉื›ืคื•ืœ ืขืฆืœืŸ ืœื”ืชืื•ืฉืฉื•ืช ืžืืกื•ืŸ ืขื PostgreSQL
ืฉื›ืคื•ืœ ืื™ื ื• ื’ื™ื‘ื•ื™. ืื• ืฉืœื? ื›ืš ื”ืฉืชืžืฉื ื• ื‘ืฉื›ืคื•ืœ ื“ื—ื•ื™ ื›ื“ื™ ืœื”ืชืื•ืฉืฉ ืžืžื—ื™ืงืช ืงื™ืฆื•ืจื™ ื“ืจืš ื‘ื˜ืขื•ืช.

ืžื•ืžื—ื™ ืชืฉืชื™ื•ืช GitLab ืื—ืจืื™ืช ืขืœ ื”ืขื‘ื•ื“ื” GitLab.com - ืžื•ืคืข GitLab ื”ื’ื“ื•ืœ ื‘ื™ื•ืชืจ ื‘ื˜ื‘ืข. ืขื 3 ืžื™ืœื™ื•ืŸ ืžืฉืชืžืฉื™ื ื•ื›ืžืขื˜ 7 ืžื™ืœื™ื•ืŸ ืคืจื•ื™ืงื˜ื™ื, ื–ื”ื• ืื—ื“ ืžืืชืจื™ ื”-SaaS ื”ื’ื“ื•ืœื™ื ื‘ืงื•ื“ ืคืชื•ื— ืขื ืืจื›ื™ื˜ืงื˜ื•ืจื” ื™ื™ืขื•ื“ื™ืช. ืœืœื ืžืขืจื›ืช ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL, ืชืฉืชื™ืช GitLab.com ืœื ืชื’ื™ืข ืจื—ื•ืง, ื•ืžื” ืื ื—ื ื• ืขื•ืฉื™ื ื›ื“ื™ ืœื”ื‘ื˜ื™ื— ืกื•ื‘ืœื ื•ืช ืœืชืงืœื•ืช ื‘ืžืงืจื” ืฉืœ ืชืงืœื•ืช ื›ืœืฉื”ืŸ ื›ืืฉืจ ื ืชื•ื ื™ื ื™ื›ื•ืœื™ื ืœืœื›ืช ืœืื™ื‘ื•ื“. ืœื ืกื‘ื™ืจ ืฉื™ืงืจื” ืืกื•ืŸ ื›ื–ื”, ืื‘ืœ ืื ื—ื ื• ืขืจื•ื›ื™ื ื”ื™ื˜ื‘ ื•ืžืฆื•ื™ื“ื™ื ื‘ืžื ื’ื ื•ื ื™ ื’ื™ื‘ื•ื™ ื•ืฉื›ืคื•ืœ ืฉื•ื ื™ื.

ืฉื›ืคื•ืœ ืื™ื ื• ืืžืฆืขื™ ืœื’ื™ื‘ื•ื™ ืžืกื“ื™ ื ืชื•ื ื™ื (ืจืื” ืœื”ืœืŸ). ืื‘ืœ ืขื›ืฉื™ื• ื ืจืื” ื›ื™ืฆื“ ืœืฉื—ื–ืจ ื‘ืžื”ื™ืจื•ืช ื ืชื•ื ื™ื ืฉื ืžื—ืงื• ื‘ื˜ืขื•ืช ื‘ืืžืฆืขื•ืช ืฉื›ืคื•ืœ ืขืฆืœืŸ: ืขืœ GitLab.com ืžืฉืชืžืฉ ืžื—ืง ืืช ืงื™ืฆื•ืจ ื”ื“ืจืš ืœืคืจื•ื™ืงื˜ gitlab-ce ื•ืื™ื‘ื“ื• ืงืฉืจื™ื ืขื ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื•ืžืฉื™ืžื•ืช.

ืขื ื”ืขืชืง ื“ื—ื•ื™, ืฉื—ื–ืจื ื• ื ืชื•ื ื™ื ืชื•ืš 1,5 ืฉืขื•ืช ื‘ืœื‘ื“. ืชืจืื” ืื™ืš ื–ื” ืงืจื”.

ื”ืชืื•ืฉืฉื•ืช ื‘ื ืงื•ื“ืช ื–ืžืŸ ืขื PostgreSQL

ืœ-PostgreSQL ืคื•ื ืงืฆื™ื” ืžื•ื‘ื ื™ืช ื”ืžืฉื—ื–ืจืช ืืช ืžืฆื‘ ืžืกื“ ื”ื ืชื•ื ื™ื ืœื ืงื•ื“ืช ื–ืžืŸ ืžืกื•ื™ืžืช. ื–ื” ื ืงืจื ืฉื—ื–ื•ืจ ื ืงื•ื“ืช ื–ืžืŸ (PITR) ื•ืžืฉืชืžืฉ ื‘ืื•ืชื ืžื ื’ื ื•ื ื™ื ืฉืžืขื“ื›ื ื™ื ืืช ื”ืขืชืง: ื”ื—ืœ ืžืชืžื•ื ืช ืžืฆื‘ ืืžื™ื ื” ืฉืœ ื›ืœ ืืฉื›ื•ืœ ืžืกื“ ื”ื ืชื•ื ื™ื (ื’ื™ื‘ื•ื™ ื‘ืกื™ืก), ืื ื• ืžื™ื™ืฉืžื™ื ืกื“ืจื” ืฉืœ ืฉื™ื ื•ื™ื™ ืžืฆื‘ ืขื“ ืœื ืงื•ื“ืช ื–ืžืŸ ืžืกื•ื™ืžืช.

ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ืชื›ื•ื ื” ื–ื• ืœื’ื™ื‘ื•ื™ ืงืจ, ืื ื• ืขื•ืจื›ื™ื ื‘ืื•ืคืŸ ืงื‘ื•ืข ื’ื™ื‘ื•ื™ ื‘ืกื™ืกื™ ืฉืœ ืžืกื“ ื ืชื•ื ื™ื ื•ืžืื—ืกื ื™ื ืื•ืชื• ื‘ืืจื›ื™ื•ืŸ (ืืจื›ื™ื•ืŸ GitLab ืคืขื™ืœ ื‘ ืื—ืกื•ืŸ ื‘ืขื ืŸ ืฉืœ ื’ื•ื’ืœ). ืื ื• ื’ื ืขื•ืงื‘ื™ื ืื—ืจ ืฉื™ื ื•ื™ื™ื ื‘ืžืฆื‘ ืžืกื“ ื”ื ืชื•ื ื™ื ืขืœ ื™ื“ื™ ืืจื›ื™ื•ืŸ ื™ื•ืžืŸ ื”ื›ืชื™ื‘ื” ืงื“ื™ืžื” (ื™ื•ืžืŸ ื›ืชื™ื‘ื” ืงื“ื™ืžื”, WAL). ื•ืขื ื›ืœ ื–ื” ื‘ืžืงื•ื, ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืขืฉื•ืช PITR ืœื”ืชืื•ืฉืฉื•ืช ืžืืกื•ืŸ: ื”ื—ืœ ืžืชืžื•ื ืช ื”ืžืฆื‘ ืฉืฆื•ืœืžื” ืœืคื ื™ ื”ื›ื™ืฉืœื•ืŸ, ื•ื”ื—ืœืช ื”ืฉื™ื ื•ื™ื™ื ืžืืจื›ื™ื•ืŸ WAL ืขื“ ื”ืชืงืœื”.

ืžื”ื• ืฉื›ืคื•ืœ ื“ื—ื•ื™?

ืฉื›ืคื•ืœ ืขืฆืœืŸ ื”ื•ื ื™ื™ืฉื•ื ืฉืœ ืฉื™ื ื•ื™ื™ื ืž-WAL ื‘ืื™ื—ื•ืจ. ื›ืœื•ืžืจ, ื”ืขืกืงื” ื”ืชืจื—ืฉื” ืชื•ืš ืฉืขื” X, ืืš ื”ื•ื ื™ื•ืคื™ืข ื‘ื”ืขืชืง ื‘ืื™ื—ื•ืจ d ืชื•ืš ืฉืขื” X + d.

ืœ-PostgreSQL ื™ืฉ 2 ื“ืจื›ื™ื ืœื”ื’ื“ื™ืจ ืขื•ืชืง ืฉืœ ืžืกื“ ื ืชื•ื ื™ื ืคื™ื–ื™: ืฉื—ื–ื•ืจ ื’ื™ื‘ื•ื™ ื•ืฉื›ืคื•ืœ ืกื˜ืจื™ืžื™ื ื’. ืžืฉื—ื–ืจ ืžืืจื›ื™ื•ืŸ, ืขื•ื‘ื“ ื‘ืขืฆื ื›ืžื• PITR, ืื‘ืœ ื‘ืจืฆื™ืคื•ืช: ืื ื—ื ื• ื›ืœ ื”ื–ืžืŸ ืฉื•ืื‘ื™ื ืฉื™ื ื•ื™ื™ื ืžืืจื›ื™ื•ืŸ WAL ื•ืžื—ื™ืœื™ื ืื•ืชื ืขืœ ื”ืขืชืง. ื ืฉื›ืคื•ืœ ืกื˜ืจื™ืžื™ื ื’ ืžืื—ื–ืจ ื™ืฉื™ืจื•ืช ืืช ื–ืจื ื”-WAL ืžืžืืจื— โ€‹โ€‹ืžืกื“ ื”ื ืชื•ื ื™ื ื‘ืžืขืœื” ื”ื–ืจื. ืื ื—ื ื• ืžืขื“ื™ืคื™ื ืฉื—ื–ื•ืจ ืืจื›ื™ื•ืŸ - ื–ื” ืงืœ ื™ื•ืชืจ ืœื ื™ื”ื•ืœ ื•ื‘ืขืœ ื‘ื™ืฆื•ืขื™ื ืจื’ื™ืœื™ื ืฉืขื•ืžื“ื™ื ื‘ืงืฆื‘ ืฉืœ ืืฉื›ื•ืœ ื”ื™ื™ืฆื•ืจ.

ื›ื™ืฆื“ ืœื”ื’ื“ื™ืจ ื”ืชืื•ืฉืฉื•ืช ืžื•ืฉื”ื™ืช ืžืืจื›ื™ื•ืŸ

ืืคืฉืจื•ื™ื•ืช ืฉื—ื–ื•ืจ ื”ืžืชื•ืืจ ื‘ืงื•ื‘ืฅ recovery.conf. ื“ื•ื’ืžื:

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'

ืขื ืคืจืžื˜ืจื™ื ืืœื”, ื”ื’ื“ืจื ื• ืขื•ืชืง ื“ื—ื•ื™ ืขื ืฉื—ื–ื•ืจ ื’ื™ื‘ื•ื™. ื›ืืŸ ื–ื” ืžืฉืžืฉ wal-e ืœื—ืœืฅ ืžืงื˜ืขื™ WAL (restore_command) ืžื”ืืจื›ื™ื•ืŸ, ื•ื”ืฉื™ื ื•ื™ื™ื ื™ื—ื•ืœื• ืœืื—ืจ ืฉืžื•ื ื” ืฉืขื•ืช (recovery_min_apply_delay). ื”ืขืชืง ื™ืฆืคื” ื‘ืฉื™ื ื•ื™ื™ื ื‘ืฆื™ืจ ื”ื–ืžืŸ ื‘ืืจื›ื™ื•ืŸ, ืœืžืฉืœ ืขืงื‘ ื›ืฉืœ ื‘ืืฉื›ื•ืœ (recovery_target_timeline).

ะก recovery_min_apply_delay ืืชื” ื™ื›ื•ืœ ืœื”ื’ื“ื™ืจ ืฉื›ืคื•ืœ ืกื˜ืจื™ืžื™ื ื’ ื‘ืื™ื—ื•ืจ, ืื‘ืœ ื™ืฉ ื›ืืŸ ื›ืžื” ืžืœื›ื•ื“ื•ืช ืฉืงืฉื•ืจื•ืช ืœืžืฉื‘ืฆื•ืช ืฉื›ืคื•ืœ, ืžืฉื•ื‘ ื—ื ื‘ื”ืžืชื ื” ื•ื›ื•'. ืืจื›ื™ื•ืŸ WAL ืžืืคืฉืจ ืœืš ืœื”ื™ืžื ืข ืžื”ื.

ืคืจืžื˜ืจ recovery_min_apply_delay ื”ื•ืคื™ืข ืจืง ื‘-PostgreSQL 9.3. ื‘ื’ืจืกืื•ืช ืงื•ื“ืžื•ืช, ืขื‘ื•ืจ ืฉื›ืคื•ืœ ื“ื—ื•ื™ ืขืœื™ืš ืœื”ื’ื“ื™ืจ ืืช ื”ืฉื™ืœื•ื‘ ืคื•ื ืงืฆื™ื•ืช ื ื™ื”ื•ืœ ื”ืชืื•ืฉืฉื•ืช (pg_xlog_replay_pause(), pg_xlog_replay_resume()) ืื• ื”ื—ื–ืง ืงื˜ืขื™ WAL ื‘ืืจื›ื™ื•ืŸ ืœืžืฉืš ื”ื”ืฉื”ื™ื”.

ืื™ืš PostgreSQL ืขื•ืฉื” ื–ืืช?

ืžืขื ื™ื™ืŸ ืœืจืื•ืช ื›ื™ืฆื“ PostgreSQL ืžื™ื™ืฉืžืช ื”ืชืื•ืฉืฉื•ืช ืขืฆืœื ื™ืช. ื‘ื•ื ื ืกืชื›ืœ ืขืœ recoveryApplyDelay(XlogReaderState). ื–ื” ื ืงืจื ืž ืœื•ืœืื” ื—ื•ื–ืจืช ืจืืฉื™ืช ืขื‘ื•ืจ ื›ืœ ื›ื ื™ืกื” ืž-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;
}

ื”ืฉื•ืจื” ื”ืชื—ืชื•ื ื” ื”ื™ื ืฉื”ืขื™ื›ื•ื‘ ืžื‘ื•ืกืก ืขืœ ื”ื–ืžืŸ ื”ืคื™ื–ื™ ืฉื ืจืฉื ื‘ื—ื•ืชืžืช ื”ื–ืžืŸ ืฉืœ ื”ืชื—ื™ื™ื‘ื•ืช ื”ืขืกืงื” (xtime). ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช, ื”ื”ืฉื”ื™ื” ื—ืœื” ืจืง ืขืœ commits ื•ืื™ื ื” ืžืฉืคื™ืขื” ืขืœ ืขืจื›ื™ื ืื—ืจื™ื - ื›ืœ ื”ืฉื™ื ื•ื™ื™ื ืžื•ื—ืœื™ื ื™ืฉื™ืจื•ืช, ื•ื”-commit ืžืขื•ื›ื‘, ื›ืš ืฉื ืจืื” ืืช ื”ืฉื™ื ื•ื™ื™ื ืจืง ืœืื—ืจ ื”ื”ืฉื”ื™ื” ืฉื”ื•ื’ื“ืจื”.

ื›ื™ืฆื“ ืœื”ืฉืชืžืฉ ื‘ื”ืขืชืง ืžื•ืฉื”ื” ื›ื“ื™ ืœืฉื—ื–ืจ ื ืชื•ื ื™ื

ื ื ื™ื— ืฉื™ืฉ ืœื ื• ืืฉื›ื•ืœ ืžืกื“ ื ืชื•ื ื™ื ื•ื”ืขืชืง ืขื ืขื™ื›ื•ื‘ ืฉืœ ืฉืžื•ื ื” ืฉืขื•ืช ื‘ื™ื™ืฆื•ืจ. ื‘ื•ืื• ื ืจืื” ื›ื™ืฆื“ ืœืฉื—ื–ืจ ื ืชื•ื ื™ื ื‘ืืžืฆืขื•ืช ื“ื•ื’ืžื” ืžื—ื™ืงืช ืงื™ืฆื•ืจื™ ื“ืจืš ื‘ื˜ืขื•ืช.

ื›ืืฉืจ ืœืžื“ื ื• ืขืœ ื”ื‘ืขื™ื”, ืื ื—ื ื• ืฉื—ื–ื•ืจ ื”ืืจื›ื™ื•ืŸ ื”ื•ืฉื”ื” ืขื‘ื•ืจ ื”ืขืชืง ื“ื—ื•ื™:

SELECT pg_xlog_replay_pause();

ืขื ื”ืคืกืงื”, ืœื ื”ื™ื” ืœื ื• ืกื™ื›ื•ืŸ ืฉื”ืขื•ืชืง ื™ื—ื–ื•ืจ ืขืœ ื”ื‘ืงืฉื” DELETE. ื“ื‘ืจ ืฉื™ืžื•ืฉื™ ืื ืืชื” ืฆืจื™ืš ื–ืžืŸ ืœื”ื‘ื™ืŸ ื”ื›ืœ.

ื”ืขื ื™ื™ืŸ ื”ื•ื ืฉื”ืขืชืง ื”ื ื“ื—ื” ื—ื™ื™ื‘ ืœื”ื’ื™ืข ืœืจื’ืข ืฉืœืคื ื™ ื”ื‘ืงืฉื” DELETE. ื™ื“ืขื ื• ื‘ืขืจืš ืืช ื”ื–ืžืŸ ื”ืคื™ื–ื™ ืฉืœ ื”ื”ืกืจื”. ืžื—ืงื ื• recovery_min_apply_delay ื•ื”ื•ืกื™ืฃ recovery_target_time ะฒ recovery.conf. ื›ืš ืžื’ื™ืข ื”ืขืชืง ืœืœื ื“ื™ื—ื•ื™ ืœืจื’ืข ื”ื ื›ื•ืŸ:

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

ืขื ื—ื•ืชืžื•ืช ื–ืžืŸ, ืขื“ื™ืฃ ืœื”ืคื—ื™ืช ืืช ื”ืขื•ื“ืฃ ื›ื“ื™ ืœื ืœืคืกืคืก. ื ื›ื•ืŸ, ื›ื›ืœ ืฉื”ื™ืจื™ื“ื” ื’ื“ื•ืœื” ื™ื•ืชืจ, ื›ืš ื ืื‘ื“ ื™ื•ืชืจ ื ืชื•ื ื™ื. ืฉื•ื‘, ืื ื ืคืกืคืก ืืช ื”ื‘ืงืฉื” DELETE, ื”ื›ืœ ื™ื™ืžื—ืง ืฉื•ื‘ ื•ืชืฆื˜ืจืš ืœื”ืชื—ื™ืœ ืžื—ื“ืฉ (ืื• ืืคื™ืœื• ืœืงื—ืช ื’ื™ื‘ื•ื™ ืงืจ ืขื‘ื•ืจ PITR).

ื”ืคืขืœื ื• ืžื—ื“ืฉ ืืช ื”ืžื•ืคืข ื”ื ื“ื—ื” ืฉืœ Postgres ื•ืงื˜ืขื™ WAL ื—ื–ืจื• ืขืœ ืขืฆืžื ืขื“ ืœื–ืžืŸ ืฉืฆื•ื™ืŸ. ืืชื” ื™ื›ื•ืœ ืœืขืงื•ื‘ ืื—ืจ ื”ื”ืชืงื“ืžื•ืช ื‘ืฉืœื‘ ื–ื” ืขืœ ื™ื“ื™ ืฉืืœืช:

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;

ืื ื—ื•ืชืžืช ื”ื–ืžืŸ ื›ื‘ืจ ืœื ืžืฉืชื ื”, ื”ืฉื—ื–ื•ืจ ื”ื•ืฉืœื. ื ื™ืชืŸ ืœื”ืชืื™ื ืืช ื”ืคืขื•ืœื” recovery_target_actionื›ื“ื™ ืœืกื’ื•ืจ, ืœืงื“ื ืื• ืœื”ืฉื”ื•ืช ืืช ื”ืžื•ืคืข ืœืื—ืจ ื ื™ืกื™ื•ืŸ ื—ื•ื–ืจ (ื”ื•ื ืžื•ืฉืขื” ื›ื‘ืจื™ืจืช ืžื—ื“ืœ).

ื”ืžืื’ืจ ื—ื–ืจ ืœืžืฆื‘ื• ืœืคื ื™ ืื•ืชื” ื‘ืงืฉื” ืžืฆืขืจืช. ื›ืขืช ืชื•ื›ืœ, ืœืžืฉืœ, ืœื™ื™ืฆื ื ืชื•ื ื™ื. ื™ื™ืฆืื ื• ืืช ื ืชื•ื ื™ ื”ืชื•ื•ื™ื•ืช ืฉื ืžื—ืงื• ื•ืืช ื›ืœ ื”ืงื™ืฉื•ืจื™ื ืœื‘ืขื™ื•ืช ื•ื‘ืงืฉื•ืช ืžื™ื–ื•ื’ ื•ื”ืขื‘ืจื ื• ืื•ืชื ืœืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ื™ื™ืฆื•ืจ. ืื ื”ื”ืคืกื“ื™ื ื”ื ื‘ืงื ื” ืžื™ื“ื” ื’ื“ื•ืœ, ืืชื” ื™ื›ื•ืœ ืคืฉื•ื˜ ืœืงื“ื ืืช ื”ืขืชืง ื•ืœื”ืฉืชืžืฉ ื‘ื• ื›ืขื™ืงืจื™. ืื‘ืœ ืื– ื›ืœ ื”ืฉื™ื ื•ื™ื™ื ืื—ืจื™ ื”ื ืงื•ื“ื” ืฉืืœื™ื” ื”ืชืื•ืฉืฉื ื• ื™ืื‘ื“ื•.

ื‘ืžืงื•ื ื—ื•ืชืžื•ืช ื–ืžืŸ, ืขื“ื™ืฃ ืœื”ืฉืชืžืฉ ื‘ืžื–ื”ื™ ืขืกืงื”. ื–ื” ืฉื™ืžื•ืฉื™ ืœืจืฉื•ื ืžื–ื”ื™ื ืืœื”, ืœืžืฉืœ, ืขื‘ื•ืจ ื”ืฆื”ืจื•ืช DDL (ื›ื’ื•ืŸ DROP TABLE), ืขืœ ื™ื“ื™ ืฉื™ืžื•ืฉ ื‘ log_statements = 'ddl'. ืื ื”ื™ื” ืœื ื• ืžื–ื”ื” ืขืกืงื”, ื”ื™ื™ื ื• ืœื•ืงื—ื™ื recovery_target_xid ื•ื”ืจื™ืฅ ื”ื›ืœ ืขื“ ืœืขืกืงื” ืœืคื ื™ ื”ื‘ืงืฉื” DELETE.

ื”ื—ื–ืจื” ืœืขื‘ื•ื“ื” ื”ื™ื ืคืฉื•ื˜ื” ืžืื•ื“: ื”ืกืจ ืืช ื›ืœ ื”ืฉื™ื ื•ื™ื™ื ืž recovery.conf ื•ื”ืคืขืœ ืžื—ื“ืฉ ืืช Postgres. ืœืขืชืง ืฉื•ื‘ ื™ื”ื™ื” ืขื™ื›ื•ื‘ ืฉืœ ืฉืžื•ื ื” ืฉืขื•ืช ื‘ืงืจื•ื‘, ื•ืื ื—ื ื• ืขืจื•ื›ื™ื ืœืฆืจื•ืช ืขืชื™ื“ื™ื•ืช.

ื™ืชืจื•ื ื•ืช ื”ืชืื•ืฉืฉื•ืช

ืขื ื”ืขืชืง ื“ื—ื•ื™ ื‘ืžืงื•ื ื’ื™ื‘ื•ื™ ืงืจ, ืืชื” ืœื ืฆืจื™ืš ืœื”ืฉืงื™ืข ืฉืขื•ืช ื‘ืฉื—ื–ื•ืจ ื›ืœ ื”ืชืžื•ื ื” ืžื”ืืจื›ื™ื•ืŸ. ืœื“ื•ื’ืžื”, ืœื•ืงื— ืœื ื• ื—ืžืฉ ืฉืขื•ืช ืœืงื‘ืœ ืืช ื›ืœ ื”ื’ื™ื‘ื•ื™ ื”ื‘ืกื™ืกื™ ืฉืœ 2 TB. ื•ืื– ืืชื” ืขื“ื™ื™ืŸ ืฆืจื™ืš ืœื™ื™ืฉื ืืช ื›ืœ ื”-WAL ื”ื™ื•ืžื™ ื›ื“ื™ ืœื”ืชืื•ืฉืฉ ืœืžืฆื‘ ื”ืจืฆื•ื™ (ื‘ืžืงืจื” ื”ื’ืจื•ืข).

ื”ืขืชืง ื“ื—ื•ื™ ืขื“ื™ืฃ ืขืœ ื’ื™ื‘ื•ื™ ืงืจ ื‘ืฉืชื™ ื“ืจื›ื™ื:

  1. ืื™ืŸ ืฆื•ืจืš ืœื”ืกื™ืจ ืืช ื›ืœ ื”ื’ื™ื‘ื•ื™ ื”ื‘ืกื™ืกื™ ืžื”ืืจื›ื™ื•ืŸ.
  2. ื™ืฉ ื—ืœื•ืŸ ืงื‘ื•ืข ืฉืœ ืฉืžื•ื ื” ืฉืขื•ืช ืฉืœ ืžืงื˜ืขื™ WAL ืฉื™ืฉ ืœื—ื–ื•ืจ ืขืœื™ื•.

ืื ื—ื ื• ื’ื ื‘ื•ื“ืงื™ื ื›ืœ ื”ื–ืžืŸ ืื ืืคืฉืจ ืœืขืฉื•ืช PITR ืž-WAL, ื•ื”ื™ื™ื ื• ืžื‘ื—ื™ื ื™ื ื‘ืžื”ื™ืจื•ืช ื‘ืฉื—ื™ืชื•ืช ืื• ื‘ืขื™ื•ืช ืื—ืจื•ืช ื‘ืืจื›ื™ื•ืŸ WAL ืขืœ ื™ื“ื™ ื ื™ื˜ื•ืจ ื”ืฉื”ื™ื™ื” ืฉืœ ื”ืขืชืง ื”ื ื“ื—ื”.

ื‘ื“ื•ื’ืžื” ื–ื•, ืœืงื— ืœื ื• 50 ื“ืงื•ืช ืœืฉื—ื–ืจ, ื›ืœื•ืžืจ ื”ืžื”ื™ืจื•ืช ื”ื™ื™ืชื” 110 GB ืฉืœ ื ืชื•ื ื™ WAL ืœืฉืขื” (ื”ืืจื›ื™ื•ืŸ ืขื“ื™ื™ืŸ ืคื•ืขืœ AWS S3). ื‘ืกืš ื”ื›ืœ ืคืชืจื ื• ืืช ื”ื‘ืขื™ื” ื•ืฉื—ื–ืจื ื• ืืช ื”ื ืชื•ื ื™ื ืชื•ืš 1,5 ืฉืขื•ืช.

ืชื•ืฆืื•ืช: ื”ื™ื›ืŸ ื”ืขืชืง ื“ื—ื•ื™ ืฉื™ืžื•ืฉื™ (ื•ื”ื™ื›ืŸ ืœื)

ื”ืฉืชืžืฉ ื‘ืฉื›ืคื•ืœ ืžื•ืฉื”ื” ื›ืขื–ืจื” ืจืืฉื•ื ื” ืื ืื™ื‘ื“ืช ื‘ื˜ืขื•ืช ื ืชื•ื ื™ื ื•ื”ื‘ื—ื ืช ื‘ื‘ืขื™ื” ื–ื• ื‘ืชื•ืš ื”ืฉื”ื™ื” ืฉื”ื•ื’ื“ืจ.

ืื‘ืœ ื–ื›ื•ืจ: ืฉื›ืคื•ืœ ืื™ื ื• ื’ื™ื‘ื•ื™.

ืœื’ื™ื‘ื•ื™ ื•ืœืฉื›ืคื•ืœ ื™ืฉ ืžื˜ืจื•ืช ืฉื•ื ื•ืช. ื’ื™ื‘ื•ื™ ืงืจ ื™ื”ื™ื” ืฉื™ืžื•ืฉื™ ืื ืขืฉื™ืช ื‘ื˜ืขื•ืช DELETE ืื• DROP TABLE. ืื ื• ืขื•ืฉื™ื ื’ื™ื‘ื•ื™ ืžืื—ืกื•ืŸ ืงืจ ื•ืžืฉื—ื–ืจื™ื ืืช ื”ืžืฆื‘ ื”ืงื•ื“ื ืฉืœ ื”ื˜ื‘ืœื” ืื• ื›ืœ ืžืกื“ ื”ื ืชื•ื ื™ื. ืื‘ืœ ื‘ืžืงื‘ื™ืœ ื”ื‘ืงืฉื” DROP TABLE ืžืฉื•ื›ืคืœ ื›ืžืขื˜ ื‘ืื•ืคืŸ ืžื™ื™ื“ื™ ื‘ื›ืœ ื”ื”ืขืชืงื™ื ื‘ืืฉื›ื•ืœ ื”ืขื‘ื•ื“ื”, ื›ืš ืฉื›ืคื•ืœ ืจื’ื™ืœ ืœื ื™ืขื–ื•ืจ ื›ืืŸ. ื”ืฉื›ืคื•ืœ ืขืฆืžื• ืฉื•ืžืจ ืขืœ ืžืกื“ ื”ื ืชื•ื ื™ื ื–ืžื™ืŸ ื›ืืฉืจ ืฉืจืชื™ื ื‘ื•ื“ื“ื™ื ืžื•ืฉื›ืจื™ื ื•ืžื—ืœืง ืืช ื”ืขื•ืžืก.

ืืคื™ืœื• ืขื ื”ืขืชืง ื“ื—ื•ื™, ืœืคืขืžื™ื ืื ื—ื ื• ื‘ืืžืช ืฆืจื™ื›ื™ื ื’ื™ื‘ื•ื™ ืงืจ ื‘ืžืงื•ื ื‘ื˜ื•ื— ืื ืžืชืจื—ืฉื™ื ื›ืฉืœ ื‘ืžืจื›ื– ื”ื ืชื•ื ื™ื, ื ื–ืง ื ืกืชืจ ืื• ืื™ืจื•ืขื™ื ืื—ืจื™ื ืฉืื™ื ื ืžื•ืจื’ืฉื™ื ืžื™ื“. ืฉื›ืคื•ืœ ืœื‘ื“ื• ืื™ื ื• ืžื•ืขื™ืœ ื›ืืŸ.

ืฉื™ื ืœื‘. ืขืœ GitLab.com ื›ืจื’ืข ืื ื—ื ื• ืžื’ื ื™ื ืจืง ืžืคื ื™ ืื•ื‘ื“ืŸ ื ืชื•ื ื™ื ื‘ืจืžืช ื”ืžืขืจื›ืช ื•ืœื ืžืฉื—ื–ืจื™ื ื ืชื•ื ื™ื ื‘ืจืžืช ื”ืžืฉืชืžืฉ.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”