當前位置:首頁 >  站長 >  數(shù)據(jù)庫 >  正文

PostgreSQL 恢復誤刪數(shù)據(jù)的操作

 2021-06-04 17:20  來源: 腳本之家   我來投稿 撤稿糾錯

  域名預訂/競價,好“米”不錯過

在Oracle中;刪除表或者誤刪表記錄;有個閃回特性,不需要停機操作,可以完美找回記錄。當然也有一些其他的恢復工具;例如odu工具,gdul工具。都可以找回數(shù)據(jù)。而PostgreSQL目前沒有閃回特性。如何在不停機情況下恢復誤刪數(shù)據(jù)。還好是有完整的熱備份。

本文描述的方法是:利用熱備份在另一臺服務器進行數(shù)據(jù)恢復;再導入正式環(huán)境;這樣不影響數(shù)據(jù)庫操作。這方法也適用在Oracle恢復。必須滿足幾個條件

1、有完整的基礎數(shù)據(jù)文件備份和歸檔文件備份.所以備份是很重要的。

2、有一臺裝好同款Postgres軟件的服務器

實例模擬講解

過程模擬誤刪表tbl_lottu_drop后;后續(xù)進行dml/ddl操作;表明正式數(shù)據(jù)庫還是進行正常工作。在另外一臺數(shù)據(jù)庫基于數(shù)據(jù)庫PITR恢復。恢復表tbl_lottu_drop的數(shù)據(jù)。

1、創(chuàng)建一個有效的備份

Postgres201 : 線上數(shù)據(jù)庫服務器
Postgres202 : 操作服務器
postgres=# select pg_start_backup(now()::text);
 pg_start_backup
-----------------
 0/F000060
(1 row)
[postgres@Postgres201 ~]$ rsync -acvz -L --exclude "pg_xlog" --exclude "pg_log" $PGDATA /data/backup/20180428
postgres=# select pg_stop_backup();
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
 pg_stop_backup
----------------
 0/F000168
(1 row)

 

2、模擬誤操作

2.1 創(chuàng)建一個需要恢復對象表tbl_lottu_drop。并插入1000記錄。也保證數(shù)據(jù)從數(shù)據(jù)緩存寫入磁盤中。

lottu=> create table tbl_lottu_drop (id int);
CREATE TABLE
lottu=> insert into tbl_lottu_drop select generate_series(1,1000);
INSERT 0 1000
lottu=> \c lottu postgres
You are now connected to database "lottu" as user "postgres".

 

2.2 這個獲取一個時間:用于后面基于數(shù)據(jù)庫PITR恢復(當然現(xiàn)實操作后只能記住一個大概的時間;還往往是不準;可能記住的時間是誤操作之后。后面有講解如何獲取需要恢復到那個時間點)

lottu=# select now();
    now   
-------------------------------
 2018-04-28 20:47:31.617808+08
(1 row)
lottu=# checkpoint;
CHECKPOINT
lottu=# select pg_xlogfile_name(pg_switch_xlog());
  pg_xlogfile_name 
--------------------------
 000000030000000000000010
(1 row)

 

2.3 進行drop表

lottu=# drop table tbl_lottu_drop;
DROP TABLE

 

2.4 后續(xù)進行dml/ddl操作;表明正式數(shù)據(jù)庫還是進行正常工作

lottu=# create table tbl_lottu_log (id int);
CREATE TABLE
lottu=# insert into tbl_lottu_log values (1),(2);
INSERT 0 2
lottu=# checkpoint;
CHECKPOINT
lottu=# select pg_xlogfile_name(pg_switch_xlog());
  pg_xlogfile_name 
--------------------------
 000000030000000000000011
(1 row)

 

3、恢復操作

3.1 將備份拷貝到Postgres202數(shù)據(jù)庫上

[postgres@Postgres201 20180428]$ cd /data/backup/20180428
[postgres@Postgres201 20180428]$ ll
total 4
drwx------. 18 postgres postgres 4096 Apr 28 20:42 data
[postgres@Postgres201 20180428]$ rsync -acvz -L data postgres@192.168.1.202:/data/postgres
  

 

3.2 刪除不必要的文件

[postgres@Postgres202 data]$ cd $PGDATA
[postgres@Postgres202 data]$ rm backup_label.old postmaster.pid tablespace_map.old

 

3.3 還原備份表空間軟鏈接

[postgres@Postgres202 data]$ cat tablespace_map
16385 /data/pg_data/lottu
[postgres@Postgres202 data]$ mkdir -p /data/pg_data
[postgres@Postgres202 data]$ cd pg_tblspc/
[postgres@Postgres202 pg_tblspc]$ mv 16385/ /data/pg_data/lottu
[postgres@Postgres202 pg_tblspc]$ ln -s /data/pg_data/lottu ./16385
[postgres@Postgres202 pg_tblspc]$ ll
total 0
lrwxrwxrwx. 1 postgres postgres 19 Apr 28 23:12 16385 -> /data/pg_data/lottu

 

3.4 將wal日志拷貝到Postgres202數(shù)據(jù)庫上pg_xlog目錄下;從哪個日志開始拷貝?

[postgres@Postgres202 data]$ mkdir -p pg_xlog/archive_status
[postgres@Postgres202 data]$ cat backup_label
START WAL LOCATION: 0/F000060 (file 00000003000000000000000F)
CHECKPOINT LOCATION: 0/F000098
BACKUP METHOD: pg_start_backup
BACKUP FROM: master
START TIME: 2018-04-28 20:42:15 CST
LABEL: 2018-04-28 20:42:13.244358+08

 

查看backup_label;知道00000003000000000000000F開始到正在寫入的wal日志。

[postgres@Postgres202 pg_xlog]$ ll
total 65540
-rw-------. 1 postgres postgres 16777216 Apr 28 20:42 00000003000000000000000F
-rw-------. 1 postgres postgres  313 Apr 28 20:42 00000003000000000000000F.00000060.backup
-rw-------. 1 postgres postgres 16777216 Apr 28 20:48 000000030000000000000010
-rw-------. 1 postgres postgres 16777216 Apr 28 20:50 000000030000000000000011
-rw-------. 1 postgres postgres 16777216 Apr 28 20:55 000000030000000000000012

 

3.5 編輯recovery.conf文件

[postgres@Postgres202 data]$ vi recovery.conf
restore_command = 'cp /data/arch/%f %p'   # e.g. 'cp /mnt/server/archivedir/%f %p'
recovery_target_time = '2018-04-28 20:47:31.617808+08'
recovery_target_inclusive = false
recovery_target_timeline = 'latest'

 

3.6 啟動數(shù)據(jù)庫;并驗證數(shù)據(jù)

[postgres@Postgres202 data]$ pg_start
server starting
[postgres@Postgres202 data]$ ps -ef | grep postgres
root  1098 1083 0 22:32 pts/0 00:00:00 su - postgres
postgres 1099 1098 0 22:32 pts/0 00:00:00 -bash
root  1210 1195 0 22:55 pts/1 00:00:00 su - postgres
postgres 1211 1210 0 22:55 pts/1 00:00:00 -bash
postgres 1442  1 1 23:16 pts/0 00:00:00 /opt/pgsql96/bin/postgres
postgres 1450 1442 0 23:16 ?  00:00:00 postgres: checkpointer process
postgres 1451 1442 0 23:16 ?  00:00:00 postgres: writer process
postgres 1459 1442 0 23:16 ?  00:00:00 postgres: wal writer process
postgres 1460 1442 0 23:16 ?  00:00:00 postgres: autovacuum launcher process
postgres 1461 1442 0 23:16 ?  00:00:00 postgres: archiver process last was 00000005.history
postgres 1462 1442 0 23:16 ?  00:00:00 postgres: stats collector process
postgres 1464 1099 0 23:16 pts/0 00:00:00 ps -ef
postgres 1465 1099 0 23:16 pts/0 00:00:00 grep postgres
[postgres@Postgres202 data]$ psql
psql (9.6.0)
Type "help" for help.
postgres=# \c lottu lottu
You are now connected to database "lottu" as user "lottu".
lottu=> \dt
   List of relations
 Schema |  Name  | Type | Owner
--------+----------------+-------+-------
 public | pitr_test  | table | lottu
 public | tbl_lottu_drop | table | lottu
 
 lottu=> select count(1) from tbl_lottu_drop;
 count
-------
 1000
(1 row)

 

lottu=> select count(1) from tbl_lottu_drop; count------- 1000(1 row)

從這看數(shù)據(jù)是恢復了;copy到線上數(shù)據(jù)庫操作略。

延伸點

下面講解下如何找到誤操作的時間。即recovery_target_time = '2018-04-28 20:47:31.617808+08'的時間點。上文是前面已經(jīng)獲取的;

1. 用pg_xlogdump解析這段日志。

[postgres@Postgres201 pg_xlog]$ pg_xlogdump -b 00000003000000000000000F 000000030000000000000012 > lottu.log
pg_xlogdump: FATAL: error in WAL record at 0/12000648: invalid record length at 0/12000680: wanted 24, got 0

 

2. 從lottu.log中可以找到這段日志

rmgr: Transaction len (rec/tot):  8/ 34, tx:  1689, lsn: 0/100244A0, prev 0/10024460, desc: COMMIT 2018-04-28 20:45:49.736013 CST
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/100244C8, prev 0/100244A0, desc: RUNNING_XACTS nextXid 1690 latestCompletedXid 1689 oldestRunningXid 1690
rmgr: Heap  len (rec/tot):  3/ 3130, tx:  1690, lsn: 0/10024500, prev 0/100244C8, desc: INSERT off 9
 blkref #0: rel 16385/16386/2619 fork main blk 15 (FPW); hole: offset: 60, length: 5116
rmgr: Btree  len (rec/tot):  2/ 7793, tx:  1690, lsn: 0/10025140, prev 0/10024500, desc: INSERT_LEAF off 385
 blkref #0: rel 16385/16386/2696 fork main blk 1 (FPW); hole: offset: 1564, length: 452
rmgr: Heap  len (rec/tot):  2/ 184, tx:  1690, lsn: 0/10026FD0, prev 0/10025140, desc: INPLACE off 16
 blkref #0: rel 16385/16386/1259 fork main blk 0
rmgr: Transaction len (rec/tot):  88/ 114, tx:  1690, lsn: 0/10027088, prev 0/10026FD0, desc: COMMIT 2018-04-28 20:46:37.718442 CST; inval msgs: catcache 49 catcache 45 catcache 44 relcache 32784
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/10027100, prev 0/10027088, desc: RUNNING_XACTS nextXid 1691 latestCompletedXid 1690 oldestRunningXid 1691
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/10027138, prev 0/10027100, desc: RUNNING_XACTS nextXid 1691 latestCompletedXid 1690 oldestRunningXid 1691
rmgr: XLOG  len (rec/tot):  80/ 106, tx:   0, lsn: 0/10027170, prev 0/10027138, desc: CHECKPOINT_ONLINE redo 0/10027138; tli 3; prev tli 3; fpw true; xid 0:1691; oid 40976; multi 1; offset 0; oldest xid 1668 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 1691; online
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/100271E0, prev 0/10027170, desc: RUNNING_XACTS nextXid 1691 latestCompletedXid 1690 oldestRunningXid 1691
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/10027218, prev 0/100271E0, desc: RUNNING_XACTS nextXid 1691 latestCompletedXid 1690 oldestRunningXid 1691
rmgr: XLOG  len (rec/tot):  80/ 106, tx:   0, lsn: 0/10027250, prev 0/10027218, desc: CHECKPOINT_ONLINE redo 0/10027218; tli 3; prev tli 3; fpw true; xid 0:1691; oid 40976; multi 1; offset 0; oldest xid 1668 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 1691; online
rmgr: XLOG  len (rec/tot):  0/ 24, tx:   0, lsn: 0/100272C0, prev 0/10027250, desc: SWITCH
rmgr: Standby  len (rec/tot):  24/ 50, tx:   0, lsn: 0/11000028, prev 0/100272C0, desc: RUNNING_XACTS nextXid 1691 latestCompletedXid 1690 oldestRunningXid 1691
rmgr: Standby  len (rec/tot):  16/ 42, tx:  1691, lsn: 0/11000060, prev 0/11000028, desc: LOCK xid 1691 db 16386 rel 32784
rmgr: Heap  len (rec/tot):  8/ 2963, tx:  1691, lsn: 0/11000090, prev 0/11000060, desc: DELETE off 16 KEYS_UPDATED
 blkref #0: rel 16385/16386/1247 fork main blk 8 (FPW); hole: offset: 88, length: 5288

 

根據(jù)“32784”日志可以看到是表tbl_lottu_drop在2018-04-28 20:46:37.718442插入1000條記錄(所以恢復時間點選2018-04-28 20:47:31.617808+08沒毛病);即也是在事務id為1690操作的。并在事務id為1691進行刪除操作。

所以上面的recovery.conf 也可以改寫為:

restore_command = 'cp /data/arch/%f %p'   # e.g. 'cp /mnt/server/archivedir/%f %p'
recovery_target_xid = '1690'
recovery_target_inclusive = false
recovery_target_timeline = 'latest'

 

補充:PostgreSQL多種恢復實例分析

Postgresql歸檔恢復實例分析(時間線機制)

這篇文章根據(jù)實例介紹Postgresql歸檔恢復的方法,時間線的含義。

1 參數(shù)配置

sed -ir "s/#*max_wal_senders.*/max_wal_senders = 10/" $PGDATA/postgresql.conf
sed -ir "s/#*wal_level.*/wal_level = replica/" $PGDATA/postgresql.conf
sed -ir "s/#*archive_mode.*/archive_mode = on/" $PGDATA/postgresql.conf
sed -ir "s/#*archive_command.*/archive_command = 'test ! -f \${PGHOME}\/archive\/%f \&\& cp %p \${PGHOME}\/archive\/%f'/" $PGDATA/postgresql.conf

 

2 數(shù)據(jù)操作

date;psql -c "create table test00 (id int primary key, info text)"
Sat Apr 1 10:09:55 CST 2017
date;psql -c "insert into test00 values(generate_series(1,50000), repeat(md5(random()::text), 1000))"
Sat Apr 1 10:10:10 CST 2017
date;psql -c "create table test01 (id int primary key, info text)"
Sat Apr 1 10:10:48 CST 2017
date;psql -c "insert into test01 values(generate_series(1,50000), repeat(md5(random()::text), 1000))"
Sat Apr 1 10:10:53 CST 2017

 

3 制作基礎備份

1sed -ir "s/#*max_wal_senders.*/max_wal_senders = 10/" $PGDATA/postgresql.conf

配置pg_hba.conf通道

1pg_basebackup -Fp -P -x -D ~/bin/data/pg_root21 -l basebackup21

4 數(shù)據(jù)庫上繼續(xù)進行業(yè)務操作(模擬在基礎備份后,業(yè)務繼續(xù)下發(fā),然后發(fā)生故障)

date;psql -c "create table test02 (id int primary key, info text)"
Sat Apr 1 10:15:59 CST 2017
date;psql -c "insert into test02 values(generate_series(1,100000), repeat(md5(random()::text), 1000))"
Sat Apr 1 10:16:09 CST 2017

 

時間軸(第三行的縮寫代表Create Insert)

-10:09:55----10:10:10-----10:10:48-----10:10:53------10:15:59----10:16:09--
----|-----------|------------|------------|-------------|-----------|------
C test00-----I test00-----C test01-----I test01-----C test01-----I test01--

 

情況1

沒有設置archive_timeout,整個數(shù)據(jù)目錄被刪除

5 數(shù)據(jù)目錄被rm -rf掉了(模擬誤操作)

1rm -rf pg_root20/

6 歸檔恢復

1cp -r pg_root21 pg_root20

修改pg_hba.conf阻止用戶連接

cp $PGHOME/share/recovery.conf.sample ./recovery.conf
sed -ir "s/#*restore_command.*/restore_command = 'cp \${PGHOME}\/archive\/%f %p'/" $PGDATA/recovery.conf
 

 

7 恢復結果

test02存在,但是其中的數(shù)據(jù)被認為是未提交事務,表為空(最后一個xlog文件的內(nèi)容全部遺失了)。

情況2

設置archive_timeout,整個數(shù)據(jù)目錄被刪除,歸檔timeout為60s,在test02表數(shù)據(jù)灌入之后,xlog自動切換并歸檔

1(sed -ir "s/#*archive_timeout.*/archive_timeout = 60/" $PGDATA/postgresql.conf)

5 數(shù)據(jù)目錄被rm -rf掉了(模擬誤操作)

1rm -rf pg_root20/

6 歸檔恢復

1cp -r pg_root21 pg_root20

修改pg_hba.conf阻止用戶連接

cp $PGHOME/share/recovery.conf.sample ./recovery.conf
sed -ir "s/#*restore_command.*/restore_command = 'cp \${PGHOME}\/archive\/%f %p'/" $PGDATA/recovery.conf
 

 

7 恢復結果

test02存在,數(shù)據(jù)也存在(由于歸檔設置了超時切換,最后一個xlog會被歸檔)。

情況3(重要)

設置archive_timeout,根據(jù)估計時間點嘗試多次恢復,不能確定想恢復到具體哪個時間點,歸檔timeout為60s

1(sed -ir "s/#*archive_timeout.*/archive_timeout = 60/" $PGDATA/postgresql.conf)

5 數(shù)據(jù)目錄被rm -rf掉了(模擬誤操作)

1rm -rf pg_root20/

6 歸檔恢復

1cp -r pg_root21 pg_root20

修改pg_hba.conf阻止用戶連接

cp $PGHOME/share/recovery.conf.sample ./recovery.conf
sed -ir "s/#*restore_command.*/restore_command = 'cp \${PGHOME}\/archive\/%f %p'/" $PGDATA/recovery.conf
 

 

(1) recovery_target_time = ‘2017-4-1 10:09:47' (基礎備份時間之前)

這里------------------------------------------------------------------------
-10:09:55----10:10:10-----10:10:48-----10:10:53------10:15:59----10:16:09--
----|-----------|------------|------------|---basebackup---|--------|------
C test00-----I test00-----C test01-----I test01-----C test02-----I test02--

 

結果:

恢復時間定到了基礎備份之前,所以這里會恢復到最早時間點:基礎備份點。

1LOG: recovery stopping before commit of transaction 1175, time 2017-04-01 10:15:59.597495+08

注意:無法恢復到基礎備份之前的點,所以再做基礎備份時,請保證數(shù)據(jù)一致性。

(2) recovery_target_time = ‘2017-4-1 10:10:00' (基礎備份時間之前)

---------這里---------------------------------------------------------------
-10:09:55----10:10:10-----10:10:48-----10:10:53------10:15:59----10:16:09--
----|-----------|------------|------------|---basebackup---|--------|------
C test00-----I test00-----C test01-----I test01-----C test02-----I test02--

 

結果:

恢復時間定到了基礎備份之前,所以這里會恢復到最早時間點:基礎備份點。

1LOG: recovery stopping before commit of transaction 1175, time 2017-04-01 10:15:59.597495+08

注意:無法恢復到基礎備份之前的點,所以再做基礎備份時,請保證數(shù)據(jù)一致性。

(3) recovery_target_time = ‘2017-4-1 10:16:00'

-------------------------------------------------------------這里-----------
-10:09:55----10:10:10-----10:10:48-----10:10:53------10:15:59----10:16:09--
----|-----------|------------|------------|---basebackup---|--------|------
C test00-----I test00-----C test01-----I test01-----C test02-----I test02--

 

結果:

表test02存在,但沒有數(shù)據(jù)。說明如果時間在基礎備份點之后,可以恢復到任意時間點。恢復后會創(chuàng)建新時間線。

1LOG: last completed transaction was at log time 2017-04-01 10:15:59.597495+08

(3.1) 在(3)的基礎上繼續(xù)進行恢復:recovery_target_time = ‘2017-4-1 10:17:00'

------------------------------------------------------------------------這里
-10:09:55----10:10:10-----10:10:48-----10:10:53------10:15:59----10:16:09--
----|-----------|------------|------------|---basebackup---|--------|------
C test00-----I test00-----C test01-----I test01-----C test02-----I test02--

 

結果:

同3,這次恢復創(chuàng)建了一條新的時間線3,這條時間線上面進行恢復的話,數(shù)據(jù)庫會去archive里面去找時間線2的xlog,但是歸檔目錄中的日志應該都是時間線1的,所以會報錯找不到xlog。

1cp: cannot stat pathto/archive/00000002000000000000000A': No such file or directory

注意: 根據(jù)上述結論,請在每次恢復時都使用原始歸檔文件,即如果嘗試再次恢復,請重新使用基礎備份進行恢復,不要在前一次恢復的基礎上繼續(xù)進行,否則由于時間線切換,會找不到歸檔文件。

其他

壓縮的歸檔日志

sed -ir "s/#*archive_command.*/archive_command = 'gzip -c %p > \${PGHOME}\/archive\/%f.gz'/" $PGDATA/postgresql.conf
sed -ir "s/#*restore_command.*/restore_command = 'gzip -d -c \${PGHOME}\/archive\/%f.gz > %p'/" $PGDATA/recovery.conf
 

 

1、recovery.conf(幾個重要參數(shù))

Postgresql9.6手冊(彭煜瑋翻譯)

restore_command (string)用于獲取 WAL 文件系列的一個已歸檔段的本地 shell 命令。這個參數(shù)是歸檔恢復所必需的,但是對于流復制是可選的。在該字符串中的任何%f會被替換為從歸檔中獲得的文件的名字,并且任何%p會被在服務器上的復制目標路徑名替換(該路徑名是相對于當前工作目錄的,即集簇的數(shù)據(jù)目錄)。任何%r會被包含上一個可用重啟點的文件的名字所替換。在那些必須被保留用于使得一次恢復變成可重啟的文件中,這個文件是其中最早的一個,因此這個信息可以被用來把歸檔截斷為支持從當前恢復重啟所需的最小值。%r通常只被溫備配置(見Section 26.2)所使用。要嵌入一個真正的%字符,需要寫成%%。很重要的一點是,該命令只有在成功時才返回一個為零的退出狀態(tài)。該命令將會被詢問不存在于歸檔中的文件名,當這樣被詢問時它必須返回非零。

recovery_target_time (timestamp)這個參數(shù)指定恢復將進入的時間戳。

recovery_target_xid (string)這個參數(shù)指定恢復將進入的事務 ID。記住雖然事務 ID 是在事務開始時順序分配的,但是事務可能以不同的數(shù)字順序完成。那些在指定事務之前(也可以包括該事務)提交的事務將被恢復。精確的停止點也受到recovery_target_inclusive的影響。

recovery_target_timeline (string)指定恢復到一個特定的時間線中。默認值是沿著基礎備份建立時的當前時間線恢復。將這個參數(shù)設置為latest會恢復到該歸檔中能找到的最新的時間線,這在一個后備服務器中有用。除此之外,你只需要在復雜的重恢復情況下設置這個參數(shù),在這種情況下你需要返回到一個狀態(tài),該狀態(tài)本身是在一次時間點恢復之后到達的。相關討論見Section25.3.5

2、關于時間線

Postgresql9.6手冊(彭煜瑋翻譯)

將數(shù)據(jù)庫恢復到一個之前的時間點的能力帶來了一些復雜性,這和有關時間旅行和平行宇宙的科幻小說有些相似。例如,在數(shù)據(jù)庫的最初歷史中,假設你在周二晚上5:15時丟棄了一個關鍵表,但是一直到周三中午才意識到你的錯誤。不用苦惱,你取出你的備份,恢復到周二晚上5:14的時間點,并上線運行。在數(shù)據(jù)庫宇宙的這個歷史中,你從沒有丟棄該表。但是假設你后來意識到這并非一個好主意,并且想回到最初歷史中周三早上的某個時間。你沒法這樣做,在你的數(shù)據(jù)庫在線運行期間,它重寫了某些WAL段文件,而這些文件本來可以將你引向你希望回到的時間。因此,為了避免出現(xiàn)這種狀況,你需要將完成時間點恢復后生成的WAL記錄序列與初始數(shù)據(jù)庫歷史中產(chǎn)生的WAL記錄序列區(qū)分開來。

要解決這個問題,PostgreSQL有一個時間線概念。無論何時當一次歸檔恢復完成,一個新的時間線被創(chuàng)建來標識恢復之后生成的WAL記錄序列。時間線ID號是WAL段文件名的一部分,因此一個新的時間線不會重寫由之前的時間線生成的WAL數(shù)據(jù)。實際上可以歸檔很多不同的時間線。雖然這可能看起來是一個無用的特性,但是它常常扮演救命稻草的角色??紤]到你不太確定需要恢復到哪個時間點的情況,你可能不得不做多次時間點恢復嘗試和錯誤,直到最終找到從舊歷史中分支出去的最佳位置。如果沒有時間線,該處理將會很快生成一堆不可管理的混亂。而有了時間線,你可以恢復到任何之前的狀態(tài),包括早先被你放棄的時間線分支中的狀態(tài)。

每次當一個新的時間線被創(chuàng)建,PostgreSQL會創(chuàng)建一個“時間線歷史”文件,它顯示了新時間線是什么時候從哪個時間線分支出來的。系統(tǒng)在從一個包含多個時間線的歸檔中恢復時,這些歷史文件對于允許系統(tǒng)選取正確的WAL段文件非常必要。因此,和WAL段文件相似,它們也要被歸檔到WAL歸檔區(qū)域。歷史文件是很小的文本文件,因此將它們無限期地保存起來的代價很小,而且也是很合適的(而段文件都很大)。如果你喜歡,你可以在一個歷史文件中增加注釋來記錄如何和為什么要創(chuàng)建該時間線。當你由于試驗的結果擁有了一大堆錯綜復雜的不同時間線時,這種注釋將會特別有價值。

恢復的默認行為是沿著相同的時間線進行恢復,該時間線是基礎備份創(chuàng)建時的當前時間線。如果你希望恢復到某個子女時間線(即,你希望回到在一次恢復嘗試后產(chǎn)生的某個狀態(tài)),你需要在recovery.conf中指定目標時間線ID。你不能恢復到早于該基礎備份之前分支出去的時間線。

文章來源:腳本之家

來源地址:https://www.jb51.net/article/204286.htm

申請創(chuàng)業(yè)報道,分享創(chuàng)業(yè)好點子。點擊此處,共同探討創(chuàng)業(yè)新機遇!

相關文章

熱門排行

信息推薦