CodeGym /Các khóa học /SQL SELF /PostgreSQL lưu dữ liệu như thế nào: cấu trúc database và ...

PostgreSQL lưu dữ liệu như thế nào: cấu trúc database và transaction log (WAL)

SQL SELF
Mức độ , Bài học
Có sẵn

Khi bạn làm việc với database, mọi thứ nhìn có vẻ đơn giản lắm: thêm dòng, update record, xoá khách hàng. Nhưng đằng sau sự đơn giản đó là một cơ chế cực kỳ phức tạp và thông minh. Thực ra thì dữ liệu này nằm ở đâu? Làm sao PostgreSQL không bị mất gì, kể cả khi server bị tắt đột ngột?

Để hiểu rõ, cần nắm hai thứ chính: dữ liệu (bảng, index, info hệ thống) thực sự nằm ở đâu trên ổ cứng, và cơ chế bảo vệ dữ liệu hoạt động thế nào — transaction log, hay còn gọi là WAL (Write-Ahead Logging).

Toàn bộ database PostgreSQL được lưu thành một loạt file trong một thư mục đặc biệt — data_directory. Thường nó nằm ở đây:

/var/lib/postgresql/17/main

Trong folder này là trái tim của database: bảng, index, meta info, config. WAL log cũng nằm ở đây — cơ chế đầu tiên nhận mọi thay đổi. Trước khi dữ liệu được ghi vào bảng trên ổ cứng, nó sẽ được ghi vào WAL trước. Kiểu như bản nháp, database ghi lại từng bước, để nếu có sự cố thì vẫn khôi phục được mọi thứ đến tận thao tác cuối cùng.

Nhờ cách này, PostgreSQL đảm bảo độ tin cậy và ổn định, kể cả trong điều kiện "lởm" nhất.

Bảng (Table)

Mỗi bảng thực chất là một file riêng biệt hoặc một nhóm file. Các file này nằm trong subfolder base/. Cấu trúc kiểu như này:

$PGDATA/base/
├── 16384/
│   ├── 12345   ← bảng
│   ├── 12346   ← index
│   └── ...
  • 16384 — là ID nội bộ của database (OID).
  • 12345 — là ID của bảng cụ thể.

Nếu bảng to, PostgreSQL sẽ chia nó thành các segment mỗi cái 1GB:

12345
12345.1
12345.2
...

Các file này không chứa "dòng" như CSV text đâu — nó là dạng "trang nhị phân" 8KB một trang.

WAL: Write-Ahead Logging — không chỉ là "log" bình thường

Giờ đến một phần cực kỳ quan trọng và hay bị hiểu nhầm trong PostgreSQL — WAL, hay Write-Ahead Logging. Dù tên có chữ log, WAL không phải là file log text bình thường như error log hay query log đâu. Đây là cơ chế sống còn để đảm bảo đồng nhất và phục hồi dữ liệu, hoạt động ở tầng thấp nhất của file system.

WAL không phải là báo cáo sự kiện, mà là ghi trước mọi thay đổi mà PostgreSQL sẽ thực hiện với dữ liệu. Việc ghi này diễn ra trước khi bảng thực sự bị sửa trên ổ cứng. Đó là lý do gọi là write-ahead — "ghi trước".

Khi bạn, ví dụ, insert một dòng mới vào bảng, PostgreSQL sẽ:

  1. KHÔNG update bảng trên ổ cứng ngay — làm vậy vừa chậm vừa nguy hiểm.
  2. Ghi vào WAL trước, rằng dòng này sẽ được thêm vào.
  3. Sau đó, khi tiện (ví dụ background process), dữ liệu mới thực sự được ghi vào bảng.

Nó giống như ký séc ở ngân hàng: bạn ký séc (WAL), rồi ngân hàng mới update tài khoản (bảng). Nếu có gì trục trặc — séc vẫn còn, làm lại thao tác được.

Định dạng và cấu trúc WAL

  • WAL file lưu ở dạng nhị phân.
  • Mỗi file là dòng các thao tác được sắp xếp chặt chẽ, mô tả thay đổi bên trong của các trang dữ liệu, cấu trúc index, commit, v.v.
  • Một WAL file có size cố định — mặc định là 16MB.

Lưu ý: WAL không chứa "SQL command" hay "dòng bảng" như bạn quen. Nó chứa instruction cho engine PostgreSQL để tái hiện lại thay đổi, từng trang một.

Nếu bị crash thì sao?

Nếu server PostgreSQL bị tắt đột ngột — ví dụ mất điện — thì cũng không mất hết đâu. Khi khởi động lại, database không hoảng loạn, mà sẽ load từ ổ cứng phiên bản dữ liệu "ổn định" cuối cùng. Sau đó nó lấy transaction log (WAL), trong đó còn lưu mọi thay đổi mới nhất, và từ từ "apply" chúng — thực hiện nốt những gì chưa kịp ghi vào file chính. Kết quả là database phục hồi về trạng thái đồng nhất hoàn toàn, như chưa có gì xảy ra.

WAL còn làm được gì nữa?

Point-In-Time Recovery (PITR). Lưu WAL file cho phép phục hồi database đến bất kỳ thời điểm nào giữa hai lần backup đầy đủ.

Streaming replication. PostgreSQL có thể gửi WAL record sang server khác real-time. Nhờ đó có thể duy trì hot replica — bản sao database luôn đồng bộ với bản chính.

Incremental recovery. Kết hợp với backup đầy đủ, WAL cho phép phục hồi chỉ những thay đổi, không cần copy lại toàn bộ database.

Tạo backup nhị phân: pg_basebackup

Nếu bạn đã quen với pg_dump rồi thì biết nó rất hợp để tạo backup logic (tức là copy cấu trúc và dữ liệu database thành SQL query). Nhưng nếu bạn cần backup vật lý thì sao? Ví dụ, copy nguyên xi toàn bộ file database? Lúc này dùng tool pg_basebackup nhé.

pg_basebackup là utility giúp tạo bản sao vật lý của dữ liệu PostgreSQL. Nó cực kỳ hữu ích cho database lớn, khi cần quản lý quá trình phục hồi hiệu quả. Ưu điểm lớn nhất của pg_basebackup là nó làm việc này rất nhanh.

Cú pháp cơ bản của lệnh pg_basebackup

Làm việc với pg_basebackup bắt đầu từ việc hiểu lệnh của nó. Bạn chạy trên terminal, cú pháp cơ bản như sau:

pg_basebackup -D /backup_directory -F tar -z -P

Giải thích từng phần nhé:

  • -D /backup_directory — chỉ định folder sẽ lưu file backup của bạn.
  • -F tar — định dạng dữ liệu. Option tar tạo file archive dạng .tar. Bạn cũng có thể dùng plain để tạo cấu trúc file database.
  • -z — nén backup lại, giúp tiết kiệm dung lượng ổ cứng. Backup nhẹ nhàng ai mà chả thích!
  • -P — hiện tiến trình real-time. Nhìn thấy process chạy, yên tâm là server không "đơ".

Ví dụ sử dụng:

pg_basebackup -D /backups/university_backup -F tar -z -P

Sau khi chạy lệnh, trong folder /backups/university_backup sẽ có bản backup dạng .tar.

Ưu điểm khi dùng pg_basebackup

Hiệu quả: backup incremental giúp không lặp lại dữ liệu không đổi, tiết kiệm cả thời gian lẫn dung lượng.

Dễ dùng: tool pg_basebackup tự động xử lý mọi chi tiết, kể cả WAL file.

Đáng tin cậy: nhờ tích hợp với cơ chế PostgreSQL, pg_basebackup tạo bản sao chính xác toàn bộ database, phục hồi cực dễ.

Ví dụ sử dụng

Giờ đến phần thực hành. Dưới đây là ví dụ thực tế về cách dùng pg_basebackup để backup database PostgreSQL. Sẽ chỉ cách backup cơ bản, cách thêm nén, và cách bật archive WAL để phục hồi "đến từng thời điểm". Các lệnh này hợp cho cả newbie lẫn ai muốn nâng cao.

Tạo backup cơ bản

pg_basebackup -D /backups/full_backup -F tar -z -P

Kết quả: backup đầy đủ database trong file .tar.

Cấu hình nén và định dạng

Tạo backup dữ liệu với mức nén cao nhất:

pg_basebackup -D /backups/full_backup -F tar -z -Z 9 -P

Ở đây -Z 9 là mức nén (max là 9).

Archive WAL

Nếu bật archive WAL, database có thể phục hồi đến bất kỳ thời điểm nào. Lệnh để backup WAL:

pg_basebackup -D /backups/incremental_backup -F tar -z -P --wal-method=archive
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Giới thiệu về sao lưu
Giới thiệu về sao lưu
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION