在PostgreSQL中 pg_start_backup 做了什么?


# 在PostgreSQL中 pg_start_backup 做了什么?
HM 2019-07-30

## pg_start_backup
做一個備份開始標記,還做了一些其他的操作,下面進行探尋。

* 函數定義:
```
postgres=# \df pg_start_backup
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+-----------------+------------------+------------------------------------------------------------------------+------
pg_catalog | pg_start_backup | pg_lsn | label text, fast
boolean DEFAULT false, exclusive boolean DEFAULT true | func
(1 row)

```

* 參數介紹:
```
第一個參數:開始記錄備份的標簽;
第二個參數:設置是否為快速執行,默認為false,將會做一個schedule checkpoint,把臟數據刷到磁盤。這里會等待其他checkpoint結束,有時候會等一下;如果設置為true,會盡快執行checkpoint,可能會產生大量的IO,拖慢正在執行的SQL;
第三個參數:是否是exclusive模式,既是否為獨占模式;默認為true,如果設置為false,則在調用pg_stop_back時,需要指定獨占模式為false,且將返回備份標簽文件里面的內容。

那么exclusive模式和no-exclusive模式的內在區別在哪里?
```

* 那么pg_start_backup將會執行下面幾件事情:
```
1.如果設置為獨占模式(默認是),將會把開始備份的LSN和checkpoint信息記錄到標簽
文件。同時,如果有表空間鏈接,也會記錄一個tablespace_map。如果是no-exclusive
模式,則不會記錄,這些信息會在執行pg_stop_back時返回。

那么他會不會switch一個新的wal文件呢?會不會把歸檔日志做完歸檔呢?有沒有必要,
沒有必要。

在此時拷貝數據庫data文件進行恢復可能會失敗,因為備份的數據可能不是在一致性下,
數據文件的刷盤不可能同時完成。單純恢復到checkpoint點應該可以,但是,只有一個備
份文件是無法這樣回退恢復的。

因此,還需要獲取到從startbackup到stopbackup之間的wal日志,以拷貝的data目錄
+這段wal日志進行恢復,即可恢復成功。

這也是pg_basebackup的邏輯。

2.將wal日志設置為forcepagewrites,即使沒有把full_page_writes設為on,保證在
startbackup期間,對數據庫的寫是可以完全回放的。

如果不這樣做,在從checkpoint點恢復時,從新的環境的對應block進行數據回放,塊的
初始數據不一樣,恢復后的結果就可能是錯的。這點可以參考full_page_writes的功能。

3.根據第二個fast參數的值,選擇執行哪種checkpoint。
```
## pg_stop_backup:
pg_stop_backup則是將日志模式恢復正常,刪除data目錄下的備份日志文件,返回結束的
LSN或者備份標記信息。

* 函數定義:
```
postgres=# \df pg_stop_backup
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+----------------+------------------+-------------------------------------------------------------------------------------------------------------------+------
pg_catalog | pg_stop_backup | pg_lsn | | func
pg_catalog | pg_stop_backup | SETOF record | exclusive boolean,
wait_for_archive boolean DEFAULT true, OUT lsn pg_lsn, OUT labelfile text,
OUT spcmapfile text | func
(2 rows)
```

 

## 實驗
```
postgres=# select pg_start_backup('test', true, true);
pg_start_backup
-----------------
0/2000060
(1 row)

postgres=# select pg_start_backup('test', true, true);
ERROR: a backup is already in progress
HINT: Run pg_stop_backup() and try again.
postgres=# ^Z
[1]+ Stopped psql
[postgres@localhost ~]$ cd $PGDATA
[postgres@localhost data]$ ls
backup_label global pg_dynshmem pg_logical pg_replslot
pg_stat pg_tblspc pg_wal postgresql.conf
base log pg_hba.conf pg_multixact pg_serial
pg_stat_tmp pg_twophase pg_xact postmaster.opts
current_logfiles pg_commit_ts pg_ident.conf pg_notify pg_snapshots
pg_subtrans PG_VERSION postgresql.auto.conf postmaster.pid
[postgres@localhost data]$ cat backup_label
START WAL LOCATION: 0/2000060 (file 000000010000000000000002)
CHECKPOINT LOCATION: 0/2000098
BACKUP METHOD: pg_start_backup
BACKUP FROM: master
START TIME: 2019-07-30 03:05:20 PDT
LABEL: test
START TIMELINE: 1
[postgres@localhost data]$ fg
psql (wd: ~)

postgres=# select pg_stop_backup();
NOTICE: WAL archiving is not enabled; you must ensure that all required
WAL segments are copied through other means to complete the backup
pg_stop_backup
----------------
0/2000168
(1 row)

postgres=# ^Z
[1]+ Stopped psql (wd: ~)
(wd now: /dbdata/pg11/data)
[postgres@localhost data]$ cat backup_label
cat: backup_label: No such file or directory
[postgres@localhost data]$ ls
base log pg_hba.conf pg_multixact pg_serial
pg_stat_tmp pg_twophase pg_xact postmaster.opts
current_logfiles pg_commit_ts pg_ident.conf pg_notify
pg_snapshots pg_subtrans PG_VERSION postgresql.auto.conf postmaster.pid
global pg_dynshmem pg_logical pg_replslot pg_stat pg_tblspc pg_wal postgresql.conf
[postgres@localhost data]$
postgres=# select pg_start_backup('test', true, false);
pg_start_backup
-----------------
0/4000028
(1 row)

postgres=# select pg_stop_backup();
ERROR: non-exclusive backup in progress
HINT: Did you mean to use pg_stop_backup('f')?
postgres=# select pg_stop_backup('f');
NOTICE: WAL archiving is not enabled; you must ensure that all
required WAL segments are copied through other means to complete
the backup
pg_stop_backup
---------------------------------------------------------------------------
(0/4000130,"START WAL LOCATION: 0/4000028 (file 000000010000000000000004)
+ CHECKPOINT LOCATION: 0/4000060
+ BACKUP METHOD: streamed
+ BACKUP FROM: master
+ START TIME: 2019-07-30 03:12:35 PDT
+ LABEL: test
+ START TIMELINE: 1
+ ","")
(1 row)

postgres=# ^Z
[1]+ Stopped psql (wd: ~)
(wd now: /dbdata/pg11/data)
[postgres@localhost data]$ ls
base log pg_hba.conf pg_multixact pg_serial pg_stat_tmp pg_twophase pg_xact postmaster.opts
current_logfiles pg_commit_ts pg_ident.conf pg_notify pg_snapshots pg_subtrans PG_VERSION postgresql.auto.conf postmaster.pid
global pg_dynshmem pg_logical pg_replslot pg_stat pg_tblspc pg_wal postgresql.conf
[postgres@localhost data]$ ls pg_wal/
000000010000000000000004 000000010000000000000005 archive_status
```
## 官方文檔
```
`pg_start_backup` accepts an arbitrary user-defined label for the backup.
(Typically this would be the name under which the backup dump file will be
stored.) When used in exclusive mode, the function writes a backup label
file (`backup_label`) and, if there are any links in the `pg_tblspc/`
directory, a tablespace map file (`tablespace_map`) into the database
cluster's data directory, performs a checkpoint, and then returns the
backup's starting write-ahead log location as text. The user can ignore
this result value, but it is provided in case it is useful. When used
in non-exclusive mode, the contents of these files are instead returned
by the `pg_stop_backup` function, and should be written to the backup
by the caller.

postgres=# select pg_start_backup('label_goes_here');
pg_start_backup
-----------------
0/D4445B8
(1 row)

There is an optional second parameter of type `boolean`. If `true`, it
specifies executing `pg_start_backup` as quickly as possible. This
forces an immediate checkpoint which will cause a spike in I/O operations,
slowing any concurrently executing queries.

In an exclusive backup, `pg_stop_backup` removes the label file and, if it exists, the `tablespace_map` file created by `pg_start_backup`. In
a non-exclusive backup, the contents of the `backup_label` and
`tablespace_map` are returned in the result of the function, and should
be written to files in the backup (and not in the data directory).
There is an optional second parameter of type `boolean`. If false, the
`pg_stop_backup` will return immediately after the backup is completed
without waiting for WAL to be archived. This behavior is only useful
for backup software which independently monitors WAL archiving.
Otherwise, WAL required to make the backup consistent might be missing
and make the backup useless. When this parameter is set to true,
`pg_stop_backup`will wait for WAL to be archived when archiving is
enabled; on the standby, this means that it will wait only when
`archive_mode = always`. If write activity on the primary is low, it
may be useful to run `pg_switch_wal` on the primary in order to trigger
an immediate segment switch.

When executed on a primary, the function also creates a backup history
file in the write-ahead log archive area. The history file includes the
label given to `pg_start_backup`, the starting and ending write-ahead
log locations for the backup, and the starting and ending times of the
backup. The return value is the backup's ending write-ahead log
location (which again can be ignored). After recording the ending
location, the current write-ahead log insertion point is automatically
advanced to the next write-ahead log file, so that the ending write-
ahead log file can be archived immediately to complete the backup.
```


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM