Replikasi bukan sandaran. Atau tidak? Begini cara kami menggunakan replikasi malas untuk pemulihan dengan memadamkan pintasan secara tidak sengaja.
Replikasi bukan alat sandaran pangkalan data anda (gitlab-ce
Dengan replika tertunda, kami memulihkan data dalam masa 1,5 jam sahaja. Lihat bagaimana keadaannya.
Pemulihan titik dalam masa dengan PostgreSQL
PostgreSQL mempunyai fungsi terbina dalam yang memulihkan keadaan pangkalan data ke titik masa tertentu. Ia dikenali sebagai
Untuk menggunakan ciri ini untuk sandaran sejuk, kami kerap membuat sandaran pangkalan data asas dan menyimpannya dalam arkib (arkib GitLab hidup dalam
Apakah replikasi tertunda?
Replikasi tertunda ialah permohonan perubahan daripada WAL dengan kelewatan. Iaitu, transaksi berlaku pada jam tersebut X
, tetapi ia akan muncul dalam replika dengan kelewatan d
dalam masa sejam X + d
.
Terdapat 2 cara untuk menyediakan replika pangkalan data fizikal dalam PostgreSQL: pemulihan arkib dan replikasi penstriman.
Bagaimana untuk menyediakan pemulihan sandaran tertunda
recovery.conf
. Contoh:
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'
Dengan tetapan ini, kami telah mengkonfigurasi replika tertunda dengan pemulihan arkib. Digunakan di sini restore_command
) daripada arkib, dan perubahan akan digunakan selepas lapan jam (recovery_min_apply_delay
). Replika akan melihat perubahan garis masa dalam arkib, seperti disebabkan kegagalan kelompok (recovery_target_timeline
).
Π‘ recovery_min_apply_delay
anda boleh menyediakan replikasi penstriman kependaman, tetapi terdapat beberapa masalah yang berkaitan dengan slot replikasi, maklum balas ganti panas dan sebagainya. Arkib WAL mengelakkan mereka.
Parameter recovery_min_apply_delay
muncul hanya dalam PostgreSQL 9.3. Dalam versi sebelumnya, replikasi tertunda memerlukan gabungan pg_xlog_replay_pause(), pg_xlog_replay_resume()
) atau tahan segmen WAL dalam arkib untuk tempoh kelewatan.
Bagaimanakah PostgreSQL melakukannya?
Sangat menarik untuk melihat bagaimana PostgreSQL melaksanakan pemulihan malas. Jom tengok 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;
}
Intinya ialah kelewatan adalah berdasarkan masa fizikal yang direkodkan dalam cap waktu komit transaksi (xtime
). Seperti yang anda lihat, kelewatan hanya terpakai pada komit dan tidak menjejaskan rekod lain - semua perubahan digunakan secara langsung dan komit ditangguhkan, jadi kami akan melihat perubahan hanya selepas kelewatan yang dikonfigurasikan.
Cara menggunakan replika malas untuk pemulihan data
Katakan kita mempunyai kluster pangkalan data dalam pengeluaran dan replika dengan kelewatan lapan jam. Mari lihat cara memulihkan data menggunakan contoh
Apabila kita menyedari masalah itu, kita
SELECT pg_xlog_replay_pause();
Dengan jeda, kami tidak mempunyai risiko bahawa replika itu akan mengulangi permintaan itu DELETE
. Perkara yang berguna jika anda memerlukan masa untuk memikirkan segala-galanya.
Intinya ialah replika yang ditangguhkan mesti mencapai masa sebelum permintaan DELETE
. Kami kira-kira tahu masa fizikal penyingkiran. Kami mengeluarkan recovery_min_apply_delay
dan ditambah recovery_target_time
Π² recovery.conf
. Jadi replika mencapai masa yang tepat tanpa berlengah-lengah:
recovery_target_time = '2018-10-12 09:25:00+00'
Dengan cap masa, lebih baik kurangkan lebihan supaya tidak terlepas. Benar, semakin besar penurunan, semakin banyak data yang kita hilang. Sekali lagi, jika kita melangkau permintaan DELETE
, semuanya akan dipadamkan sekali lagi dan anda perlu memulakan semula (atau mengambil sandaran sejuk untuk PITR).
Kami memulakan semula kejadian Postgres yang tertunda dan segmen WAL diulang sehingga masa yang ditentukan. Anda boleh menjejaki kemajuan pada peringkat ini dengan bertanya:
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;
Jika cap masa tidak lagi berubah, pemulihan selesai. Anda boleh menyesuaikan tindakan recovery_target_action
Pangkalan data datang ke negeri ini sebelum permintaan malang itu. Kini anda boleh, sebagai contoh, mengeksport data. Kami telah mengeksport data label jauh dan semua pautan kepada isu dan permintaan gabungan dan memindahkannya ke pangkalan data pengeluaran. Jika kerugian besar, anda boleh mempromosikan replika dan menggunakannya sebagai yang utama. Tetapi kemudian semua perubahan akan hilang selepas masa kami pulih.
Adalah lebih baik untuk menggunakan ID transaksi dan bukannya cap masa. Adalah berguna untuk merekodkan ID ini, contohnya, untuk pernyataan DDL (seperti DROP TABLE
), dengan menggunakan log_statements = 'ddl'
. Jika kami mempunyai ID transaksi, kami akan mengambil recovery_target_xid
dan menjalankan segala-galanya ke urus niaga sebelum permintaan DELETE
.
Kembali ke tempat kerja adalah sangat mudah: alih keluar semua perubahan daripada recovery.conf
dan mulakan semula postgres. Tidak lama lagi isyarat akan mengalami kelewatan selama lapan jam, dan kami bersedia untuk menghadapi masalah pada masa hadapan.
Faedah Pemulihan
Dengan replika tertunda, bukannya sandaran sejuk, anda tidak perlu menghabiskan berjam-jam memulihkan keseluruhan gambar daripada arkib. Sebagai contoh, kita memerlukan lima jam untuk mendapatkan keseluruhan sandaran asas 2 TB. Dan kemudian anda masih perlu menggunakan keseluruhan WAL harian untuk pulih ke keadaan yang diingini (dalam kes yang paling teruk).
Replika tertunda adalah lebih baik daripada sandaran sejuk dalam dua cara:
- Anda tidak perlu mendapatkan keseluruhan sandaran asas daripada arkib.
- Terdapat tetingkap tetap lapan jam bagi segmen WAL yang mesti diulang.
Selain itu, kami sentiasa menyemak untuk melihat sama ada WAL boleh PITRed, dan kami akan segera melihat rasuah atau masalah lain dengan arkib WAL dengan memantau tunggakan replika yang tertangguh.
Dalam contoh ini, kami mengambil masa 50 minit untuk memulihkan, iaitu, kelajuan adalah 110 GB data WAL sejam (arkib masih dihidupkan
Ringkasan: apabila replika tertunda berguna (dan jika tidak)
Gunakan replikasi tertunda sebagai pertolongan cemas jika anda kehilangan data secara tidak sengaja dan menyedari bencana ini dalam kelewatan yang dikonfigurasikan.
Tetapi perlu diingat: replikasi bukan sandaran.
Sandaran dan replikasi mempunyai tujuan yang berbeza. Sandaran sejuk akan berguna jika anda membuat secara tidak sengaja DELETE
atau DROP TABLE
. Kami membuat sandaran daripada storan sejuk dan memulihkan keadaan jadual sebelumnya atau keseluruhan pangkalan data. Tetapi pada masa yang sama permintaan DROP TABLE
hampir serta-merta diterbitkan semula dalam semua replika pada kelompok kerja, jadi replikasi biasa tidak akan disimpan di sini. Replikasi itu sendiri memastikan pangkalan data tersedia apabila pelayan individu dipajak dan mengagihkan beban.
Walaupun dengan replika yang tertunda, kadangkala kami benar-benar memerlukan sandaran sejuk di tempat yang selamat, jika tiba-tiba terdapat kegagalan pusat data, kerosakan tersembunyi atau peristiwa lain yang anda tidak perasan dengan segera. Di sini dari satu replikasi tidak ada makna.
Nota. Pada
Sumber: www.habr.com