ืฉืืคืื ืืื ื ืืืืื. ืื ืฉืื? ืื ืืฉืชืืฉื ื ืืฉืืคืื ืืืื ืืื ืืืชืืืฉืฉ ืืืืืงืช ืงืืฆืืจื ืืจื ืืืขืืช.
ืฉืืคืื ืืื ื ืืืฆืขื ืืืืืื ืืกืื ื ืชืื ืื (gitlab-ce
ืขื ืืขืชืง ืืืื, ืฉืืืจื ื ื ืชืื ืื ืชืื 1,5 ืฉืขืืช ืืืื. ืชืจืื ืืื ืื ืงืจื.
ืืชืืืฉืฉืืช ืื ืงืืืช ืืื ืขื PostgreSQL
ื-PostgreSQL ืคืื ืงืฆืื ืืืื ืืช ืืืฉืืืจืช ืืช ืืฆื ืืกื ืื ืชืื ืื ืื ืงืืืช ืืื ืืกืืืืช. ืื ื ืงืจื
ืืื ืืืฉืชืืฉ ืืชืืื ื ืื ืืืืืื ืงืจ, ืื ื ืขืืจืืื ืืืืคื ืงืืืข ืืืืื ืืกืืกื ืฉื ืืกื ื ืชืื ืื ืืืืืกื ืื ืืืชื ืืืจืืืื (ืืจืืืื GitLab ืคืขืื ื
ืืื ืฉืืคืื ืืืื?
ืฉืืคืื ืขืฆืื ืืื ืืืฉืื ืฉื ืฉืื ืืืื ื-WAL ืืืืืืจ. ืืืืืจ, ืืขืกืงื ืืชืจืืฉื ืชืื ืฉืขื X
, ืื ืืื ืืืคืืข ืืืขืชืง ืืืืืืจ d
ืชืื ืฉืขื X + d
.
ื-PostgreSQL ืืฉ 2 ืืจืืื ืืืืืืจ ืขืืชืง ืฉื ืืกื ื ืชืื ืื ืคืืื: ืฉืืืืจ ืืืืื ืืฉืืคืื ืกืืจืืืื ื.
ืืืฆื ืืืืืืจ ืืชืืืฉืฉืืช ืืืฉืืืช ืืืจืืืื
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'
ืขื ืคืจืืืจืื ืืื, ืืืืจื ื ืขืืชืง ืืืื ืขื ืฉืืืืจ ืืืืื. ืืื ืื ืืฉืืฉ 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)
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, µsecs);
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 ืืืืื ืืื ืืืชืืืฉืฉ ืืืฆื ืืจืฆืื (ืืืงืจื ืืืจืืข).
ืืขืชืง ืืืื ืขืืืฃ ืขื ืืืืื ืงืจ ืืฉืชื ืืจืืื:
- ืืื ืฆืืจื ืืืกืืจ ืืช ืื ืืืืืื ืืืกืืกื ืืืืจืืืื.
- ืืฉ ืืืื ืงืืืข ืฉื ืฉืืื ื ืฉืขืืช ืฉื ืืงืืขื WAL ืฉืืฉ ืืืืืจ ืขืืื.
ืื ืื ื ืื ืืืืงืื ืื ืืืื ืื ืืคืฉืจ ืืขืฉืืช PITR ื-WAL, ืืืืื ื ืืืืื ืื ืืืืืจืืช ืืฉืืืชืืช ืื ืืขืืืช ืืืจืืช ืืืจืืืื WAL ืขื ืืื ื ืืืืจ ืืฉืืืื ืฉื ืืขืชืง ืื ืืื.
ืืืืืื ืื, ืืงื ืื ื 50 ืืงืืช ืืฉืืืจ, ืืืืืจ ืืืืืจืืช ืืืืชื 110 GB ืฉื ื ืชืื ื WAL ืืฉืขื (ืืืจืืืื ืขืืืื ืคืืขื
ืชืืฆืืืช: ืืืื ืืขืชืง ืืืื ืฉืืืืฉื (ืืืืื ืื)
ืืฉืชืืฉ ืืฉืืคืื ืืืฉืื ืืขืืจื ืจืืฉืื ื ืื ืืืืืช ืืืขืืช ื ืชืื ืื ืืืืื ืช ืืืขืื ืื ืืชืื ืืฉืืื ืฉืืืืืจ.
ืืื ืืืืจ: ืฉืืคืื ืืื ื ืืืืื.
ืืืืืื ืืืฉืืคืื ืืฉ ืืืจืืช ืฉืื ืืช. ืืืืื ืงืจ ืืืื ืฉืืืืฉื ืื ืขืฉืืช ืืืขืืช DELETE
ืื DROP TABLE
. ืื ื ืขืืฉืื ืืืืื ืืืืกืื ืงืจ ืืืฉืืืจืื ืืช ืืืฆื ืืงืืื ืฉื ืืืืื ืื ืื ืืกื ืื ืชืื ืื. ืืื ืืืงืืื ืืืงืฉื DROP TABLE
ืืฉืืืคื ืืืขื ืืืืคื ืืืืื ืืื ืืืขืชืงืื ืืืฉืืื ืืขืืืื, ืื ืฉืืคืื ืจืืื ืื ืืขืืืจ ืืื. ืืฉืืคืื ืขืฆืื ืฉืืืจ ืขื ืืกื ืื ืชืื ืื ืืืื ืืืฉืจ ืฉืจืชืื ืืืืืื ืืืฉืืจืื ืืืืืง ืืช ืืขืืืก.
ืืคืืื ืขื ืืขืชืง ืืืื, ืืคืขืืื ืื ืื ื ืืืืช ืฆืจืืืื ืืืืื ืงืจ ืืืงืื ืืืื ืื ืืชืจืืฉืื ืืฉื ืืืจืื ืื ืชืื ืื, ื ืืง ื ืกืชืจ ืื ืืืจืืขืื ืืืจืื ืฉืืื ื ืืืจืืฉืื ืืื. ืฉืืคืื ืืืื ืืื ื ืืืขืื ืืื.
ืฉืื ืื. ืขื
ืืงืืจ: www.habr.com