Tiếp tục series các bài lab về Backup/Restore PostgreSQL được một bạn thành viên yêu cầu tại group “Kho tài liệu kiến thức về Database”.

Ở bài trước tôi đã hướng dẫn các bạn 1 cách restore database rồi, tuy nhiên với cách đó, dữ liệu chỉ khôi phục về đúng thời điểm backup mà thôi.

Đọc thêm  Restore database PostgreSQL ở chế độ No Archive mode

Trên thực tế, khi database gặp sự cố, người ta thường phải khôi phục dữ liệu về thời điểm gần lúc xảy ra sự cố nhất. Tuy nhiên, cũng có những tình huống, chúng ta lại muốn đưa database về 1 thời điểm nào đó trong quá khứ.

Ví dụ: Bạn lỡ tay cập nhật sai dữ liệu, hoặc drop một bảng quan trọng nào đó.

Để làm được điều đó, các bạn sử dụng kỹ thuật Point in time Recovery (PITR).

Bài viết này tôi sẽ hướng dẫn các bạn kỹ thuật PITR, thực hiện trên máy chủ CentOS 7, phiên bản PostgreSQL 13.

Ok, giả sử các bạn đã chuẩn bị đầy đủ điều kiện như trên, chúng ta sẽ bắt đầu công việc


   Các bước chuẩn bị

Đầu tiên, để thực hiện được kỹ thuật Point in time Recovery (PITR), điều kiện đầu tiên là database của bạn phải ở chế độ archive mode trước đã.

Để hiểu archive mode là gì và cách cấu hình nó ra sao, các bạn có thể theo dõi bài viết sau của tôi nhé:

Đọc thêm  Cấu hình chức năng archive mode trong PostgreSQL

Bạn kiểm tra xem database đã ở chế độ archive mode hay chưa, các bạn sử dụng lệnh sau:

$ psql 
psql (13.3)
Type "help" for help.

postgres=# show archive_mode ;
 archive_mode 
--------------
 on
(1 row)

postgres=# show archive_command ;
                     archive_command                      
----------------------------------------------------------
 test ! -f /backup/archive/%f && cp %p /backup/archive/%f
(1 row)

postgres=# show wal_level;
wal_level 
-----------
replica
(1 row)

(Nếu giá trị của tham số như trên là được)

Trong bài thực hành này, dữ liệu của tôi như sau:

Dữ liệu tại thời điểm 9:30 phút

postgres=# \c testdb
You are now connected to database "testdb" as user "postgres".
testdb=# select * from khach_hang;
 id |     name     
----+--------------
  1 | nguyen van a
  2 | pham van b
(2 rows)

   Backup database bằng pg_basebackup

Tiếp theo, bạn cần thực hiện backup lại database bằng công cụ pg_basebackup. Các bạn chú ý, bạn có thể backup database bằng pg_dump, pg_dumpall hay pg_basebackup. Tuy nhiên, để thực hiện được kỹ thuật PITR bạn cần phải thực hiên physical backup database như pg_basebackup

Đọc thêm  Backup database PostgreSQL bằng pg_basebackup

Câu lệnh thực hiện backup như sau:

pg_basebackup -D /var/lib/pgsql/13/backup -Ft -z -Xf -P
Đọc thêm  Backup database PostgreSQL bằng pg_basebackup

bản backup sẽ được đặt tại thư mục /var/lib/pgsql/13/backup

backup database

Insert thêm 1 vài dữ liệu nữa

-bash-4.2$ psql testdb
psql (13.3)
Type "help" for help.

testdb=# 
testdb=# insert into khach_hang values (3,'nguyen van c');
INSERT 0 1
testdb=# insert into khach_hang values (4,'nguyen van d');
INSERT 0 1

Thời điểm sau khi insert xong đang là 11h:00

Tại thời điểm 11h:30 tôi lỡ tay drop mất table khach_hang

testdb=# drop table khach_hang;

Như vậy là tôi đã giả lập tình huống database gặp trục trặc, phải khôi phục lại từ bản backup đến thời điểm 11h:00 nhé.


   Khôi phục lại database

Ý tưởng cơ bản như sau: Tôi sẽ stop PostgreSQL xuống, xóa hết data directory đi và restore lại data directory từ bản backup. Như vậy tôi đã có dữ liệu của database tại thời điểm 9h:30 (là lúc tôi thực hiện bản full backup). Sau đó, tôi sẽ áp dụng các archive log để cập nhật các thay đổi cho đến 11h, như vậy là tôi sẽ có dữ liệu lúc 11h.

Ok, cùng bắt tay thực hiện nào

   Stop và xóa data directory

Đầu tiên, tôi stop PostgreSQL và xóa thư mục data directory đi.

$ pg_ctl stop
waiting for server to shut down.... done
server stopped
$ rm -rf /var/lib/pgsql/13/data

Bây giờ khôi phục lại nhé:

   Restore lại từ bản backup

Tôi tạo lại thư mục data và gán lại các quyền thích hợp

$ mkdir /var/lib/pgsql/13/data
$ chmod 700 /var/lib/pgsql/13/data

Tiếp theo tôi khôi phục lại data directory từ bản full backup thực hiện lúc 9h30.

tar -xzf /var/lib/pgsql/13/backups/base.tar.gz -C /var/lib/pgsql/13/data

Như vậy, tôi đã có dữ liệu lúc 9h30 rồi. Bây giờ tôi cần sử dụng các archive log để kéo dữ liệu lên 11h.

   Chỉnh sửa lại tham số trong postgresql.conf

Tôi thêm các tham số sau vào file postgresql.conf

restore_command = 'cp /backup/archive/%f "%p"'
recovery_target_time = '2021-06-01 11:00:00'

Trong đó:

   Tham số restore_command sẽ copy các archive log từ đường dẫn /backup/archive vào thư mục lưu WAL file mặc định của PostgreSQL (pg_wal)

   Tham số recovery_target_time là thời gian mà tôi muốn restore database về (Ở đây là lúc 11h ngày 1/6/2021)

Sau đó, tôi xóa hết nội dung trong thư mục pg_wal đi (Vì đây là những WAL file của bản backup lúc 9h30)

Tạo file recovery.signal

touch recovery.signal

File này có nhiệm vụ thông báo cho PostgreSQL biết cần phải thực hiện các lệnh trong tham số restore_command khi khởi động.

   Khởi động PostgreSQL

Sau đó bạn khởi động lại PostgreSQL lên nhé

$ pg_ctl start
waiting for server to start....2021-06-01 15:50:21.571 +07 [27794] LOG:  redirecting log output to logging collector process
2021-06-01 15:50:21.571 +07 [27794] HINT:  Future log output will appear in directory "log".
. done
server started

Và kiểm tra lại dữ liệu:

-bash-4.2$ psql 
psql (13.3)
Type "help" for help.

postgres=# \c testdb
You are now connected to database "testdb" as user "postgres".
testdb=# select * from khach_hang
testdb-# ;
 id |     name     
----+--------------
  1 | nguyen van a
  2 | pham van b
  3 | nguyen van c 
  4 | nguyen van d
(4 rows)

Như vậy tôi đã khôi phục lại dữ liệu lúc 11h rồi. Chúc các bạn thành công.

Nguồn: https://dangxuanduy.com/

Xin cho tôi được biết, bạn cảm thấy bài viết này như thế nào? Ý kiến của bạn sẽ giúp tôi nâng cao chất lượng bài viết của mình.

    Hãy chia sẻ bài viết này nếu bạn thấy có ích nhé
    0 0 votes
    Article Rating
    Subscribe
    Notify of
    guest
    0 Comments
    Inline Feedbacks
    View all comments