PostgreSQL WAL

PostgreSQL WAL

Trong bài này chúng ta sẽ cùng đi tìm hiểu cơ chế hoạt động của WAL trong Postgres – thành phần đảm bảo tính toàn vẹn dữ liệu.

1. WAL là gì?

Về cơ bản khi có một action nào đó thay đổi trạng thái của dữ liệu trên shared buffer pool, thì sự thay đổi đó sẽ được log lại. Khi hệ thống xảy ra sự cố thì Postgres sẽ xem xét lại các log chưa được xử lý và xử lý nó để đảm bảo dữ liệu được nguyên vẹn. Việc ghi log này gọi là WAL.

Sử dụng WAL sẽ giảm đi đáng kể số lần ghi data vào disk, vì chỉ cần ghi log vào các log file để đảm bảo các transaction này đã được commit thay vì phải ghi toàn bộ data changes vào disk sau mỗi transaction. Log sẽ được ghi vào các log file một cách tuần tự(tuyến tính) nên chi phí của nó sẽ ít hơn rất nhiều so với việc ghi vào các data page.

Không những thế WAL còn hỗ trợ cho việc on-line backup và point-in-time recovery. Bằng việc lưu trữ WAL data chúng ta có thể dễ dàng recover data tại bất kỳ thời điểm nào khi mà những thay đổi trên những data đó đã được cover bởi WAL data.

2. Tầm quan trọng và cách hoạt động.

Trong phần này chúng ta sẽ lướt qua một vài ví dụ để các bạn có thế thấy được tầm quan trọng và cách hoạt động của WAL trong Postgres.

Nhưng trước khi đi vào các ví dụ cụ thể chúng ta sẽ cần phải biết một vài keyword và concept liên quan đến physical storage trong Postgres, nếu bạn chưa biết về những keyword đó thì có thể bạn sẽ cần ghé qua đây một xíu để có thể nắm rõ chúng hơn.

2.1. Insert data khi không có WAL.

Trong phần này chúng ta sẽ insert một vài data tuple vào TABLE_A trong Postgres không có implement WAL.

Insert operations without WAL

1. Khi thực hiện lệnh insert đầu tiên, Postgres load page của TABLE_A từ database cluster lên shared buffer pool, sau đó insert tuple vào page. Page này không được ghi vào database cluster liền mà nó chỉ được lưu lại trên shared buffer pool.

2. Sau đó ta thực hiện lệnh insert thứ hai, Postgres insert một tuple mới vào page trong shared buffer pool. Tương tự page này cũng chưa được ghi vào database cluster.

3. Đến lúc này, hệ thống gặp trục trặc như cúp điện chẳng hạn và toàn bộ data đã insert đều bị mất hết vì nó vẫn còn nằm trên shared buffer pool.

=> Nếu database không implement WAL thì data rất dễ bị tổn thương khi mà system gặp vấn đề.

2.2 Insert data khi có WAL.

Trong phần này, chúng ta sẽ cùng xem cách mà WAL trong Postgres giải quyết vấn đề trên. Nhưng trước hết sẽ có thêm một vài keyword cần biết:

  • XLOG record(s) hoặc WAL data: là history data ghi lại sự thay đổi của data.
  • WAL buffer: được lưu trên RAM, dùng để lưu trữ XLOG record sau khi có sự thay đổi data do các câu lệnh insert, update, delete gây ra.
  • WAL segment file được lưu trên disk, dùng để lưu trữ XLOG record sau khi transaction được commit hoặc aborts
  • ***LSN (Log Sequence Number)***: là unique id của record, là vị trí nơi mà XLOG record được ghi vào trong transaction log.
  • Checkpointer: Là background process, mỗi lần chạy sẽ ghi một XLOG record, record này được gọi là checkpoint record, checkpoint record sẽ chứa REDO point.
  • REDO point: Khi recover data thì Postgres sẽ bắt đầu recover từ REDO point. REDO point lưu lại vị trí XLOG record được ghi ngay tại thời điểm checkpointer cuối cùng được chạy
Insert operation with WAL

1. Checkpointer được gọi, nó thực hiện việc ghi một checkpoint record vào WAL segment file. Record này chứa REDO point.

2. Với lệnh insert đầu tiên, Postgres load page của TABLE_A lên shared buffer pool rồi insert tuple vào trong page trên shared buffer pool. Sau đó tạo và ghi lại XLOG record của câu lệnh insert vào WAL buffer tại vị trí LSN_1, rồi update LSN trên header của TABLE_A từ LSN_0 thành LSN_1.

3. Ngay khi transaction được commit, Postgres tạo và ghi lại XLOG record của hành động commit vào WAL buffer, sau đó nó ghi là flush record này vào WAL segment file từ vị trí LSN_1.

4. Với lệnh insert thứ hai, Postgres insert một tuple mới vào page trên buffer pool, sau đó tạo và ghi XLOG record vào WAL buffer tại vị trí LSN_2 và update lại LSN của TABLE_A thành LSN_2.

5. Khi transaction này được commit thì Postgres thực hiện các bước tương tự bước 3.

6. Giả sử đến lúc này system gặp sự cố, Mặc dù toàn bộ data của shared buffer pool bị mất hết, nhưng toàn bộ thay đổi trên page đã được lưu lại trong WAL segment file nên chúng ta vẫn có thể recover lại data dựa trên những thông tin đã có trong segment file. Ở phần tiếp theo chúng ta sẽ cùng xem cách mà Postgres recover lại data.

2.3 Postgres recover data sử dụng WAL.

Database recovery using WAL

1. Postgres đọc XLOG record của câu lệnh insert đầu tiên trong WAL segment file, load TABLE_A từ database cluster lên shared buffer pool.

2. Postgres so sánh LSN của record với LSN của TABLE_A. Nếu LSN của XLOG record lớn hơn LSN của TABLE_A thì XLOG record đó sẽ được insert vào TABLE_A sau đó update LSN của TABLE_A bằng LSN của XLOG record. Nếu LSN của XLOG record bé hơn LSN của TABLE_A thì nó sẽ bỏ qua và đọc tiếp WAL segment file tiếp theo.

3. Những XLOG record khác cũng được xử lý tương tự.

3. References.

Sau bài viết vừa rồi, mình hy vọng mọi người sẽ có cái nhìn tổng quan về WAL trong Postgres, nắm được tầm quan trọng và cách hoạt động của nó.

Bài viết trên được tham khảo từ các nguồn dưới đây:

Nguồn : http://grokking.org