PostgreSQL là một dự án tuyệt vời và nó phát triển với tốc độ đáng kinh ngạc. Chúng tôi sẽ tập trung vào sự phát triển của khả năng chịu lỗi trong PostgreSQL trong suốt các phiên bản của nó với một loạt bài đăng trên blog. Đây là bài thứ tư của loạt bài này và chúng ta sẽ nói về cam kết đồng bộ và tác động của nó đối với khả năng chịu lỗi và độ tin cậy của PostgreSQL.
Nếu bạn muốn chứng kiến quá trình phát triển ngay từ đầu, vui lòng kiểm tra ba bài đăng blog đầu tiên của loạt bài dưới đây. Mỗi bài đăng là độc lập, vì vậy bạn thực sự không cần phải đọc bài đăng này để hiểu bài đăng khác.
- Sự phát triển của khả năng chịu lỗi trong PostgreSQL
- Sự phát triển của khả năng chịu lỗi trong PostgreSQL:Giai đoạn tái tạo
- Sự phát triển của khả năng chịu lỗi trong PostgreSQL:Du hành thời gian
Cam kết đồng bộ
Theo mặc định, PostgreSQL thực hiện sao chép không đồng bộ, nơi dữ liệu được truyền trực tuyến bất cứ khi nào thuận tiện cho máy chủ. Điều này có thể có nghĩa là mất dữ liệu trong trường hợp chuyển đổi dự phòng. Có thể yêu cầu Postgres yêu cầu một (hoặc nhiều) standby để xác nhận sao chép dữ liệu trước khi cam kết, điều này được gọi là sao chép đồng bộ ( cam kết đồng bộ ) .
Với nhân rộng đồng bộ, sự chậm trễ nhân rộng trực tiếp ảnh hưởng đến thời gian trôi qua của các giao dịch trên bản chính. Với sao chép không đồng bộ, bản chính có thể tiếp tục ở tốc độ tối đa.
Sao chép đồng bộ đảm bảo rằng dữ liệu được ghi vào ít nhất hai nút trước khi người dùng hoặc ứng dụng được thông báo rằng một giao dịch đã được cam kết.
Người dùng có thể chọn chế độ cam kết của mỗi giao dịch , để có thể có cả giao dịch cam kết đồng bộ và không đồng bộ chạy đồng thời.
Điều này cho phép đánh đổi linh hoạt giữa hiệu suất và độ chắc chắn về độ bền của giao dịch.
Định cấu hình cam kết đồng bộ
Để thiết lập sao chép đồng bộ trong Postgres, chúng ta cần định cấu hình synchronous_commit
tham số trong postgresql.conf.
Tham số chỉ định liệu cam kết giao dịch có đợi các bản ghi WAL được ghi vào đĩa hay không trước khi lệnh trả về thành công chỉ dẫn cho khách hàng. Các giá trị hợp lệ là trên , remote_apply , remote_write , cục bộ và giảm . Chúng ta sẽ thảo luận về cách mọi thứ hoạt động về mặt sao chép đồng bộ khi chúng ta thiết lập synchronous_commit
với mỗi giá trị đã xác định.
Hãy bắt đầu với tài liệu Postgres (9.6):
Ở đây chúng tôi hiểu khái niệm về cam kết đồng bộ, giống như chúng tôi đã mô tả ở phần giới thiệu của bài đăng, bạn có thể tự do thiết lập sao chép đồng bộ nhưng nếu không, bạn luôn có nguy cơ mất dữ liệu. Nhưng không có nguy cơ tạo ra sự không nhất quán của cơ sở dữ liệu, không giống như tắt fsync off
- tuy nhiên đó là một chủ đề cho một bài đăng khác -. Cuối cùng, chúng tôi kết luận rằng nếu chúng tôi không muốn mất bất kỳ dữ liệu nào giữa các lần trì hoãn sao chép và muốn chắc chắn rằng dữ liệu được ghi vào ít nhất hai nút trước khi người dùng / ứng dụng được thông báo giao dịch đã cam kết , chúng tôi cần phải chấp nhận mất một số hiệu suất.
Hãy xem các cài đặt khác nhau hoạt động như thế nào đối với các mức độ đồng bộ hóa khác nhau. Trước khi bắt đầu, chúng ta hãy nói về cách xử lý cam kết bằng bản sao PostgreSQL. Máy khách thực hiện các truy vấn trên nút chính, các thay đổi được ghi vào nhật ký giao dịch (WAL) và được sao chép qua mạng sang WAL trên nút chờ. Sau đó, quá trình khôi phục trên nút chờ sẽ đọc các thay đổi từ WAL và áp dụng chúng cho các tệp dữ liệu giống như trong quá trình khôi phục sự cố. Nếu chế độ chờ ở chế độ chờ nóng , máy khách có thể đưa ra các truy vấn chỉ đọc trên nút trong khi điều này đang xảy ra. Để biết thêm chi tiết về cách hoạt động của tính năng sao chép, bạn có thể xem bài đăng trên blog về nhân bản trong loạt bài này.
Hình 1 Cách hoạt động của tính năng sao chép
sync_commit =off
Khi chúng tôi đặt sychronous_commit = off,
COMMIT
không đợi bản ghi giao dịch được chuyển vào đĩa. Điều này được đánh dấu trong Hình 2 bên dưới.
Hình 2 sync_commit =off
sync_commit =local
Khi chúng tôi đặt synchronous_commit = local,
COMMIT
đợi cho đến khi bản ghi giao dịch được chuyển vào đĩa cục bộ. Điều này được đánh dấu trong Hình 3 bên dưới.
Hình 3 sync_commit =local
sync_commit =on (mặc định)
Khi chúng tôi đặt synchronous_commit = on,
COMMIT
sẽ đợi cho đến khi (các) máy chủ được chỉ định bởi synchronous_standby_names
xác nhận rằng bản ghi giao dịch đã được ghi vào đĩa một cách an toàn. Điều này được đánh dấu trong Hình 4 bên dưới.
Lưu ý: Khi synchronous_standby_names
trống, cài đặt này hoạt động giống như synchronous_commit = local
.
Hình 4 sync_commit =on
sync_commit =remote_write
Khi chúng tôi đặt synchronous_commit = remote_write,
COMMIT
sẽ đợi cho đến khi (các) máy chủ được chỉ định bởi synchronous_standby_names
xác nhận ghi bản ghi giao dịch vào hệ điều hành nhưng không nhất thiết phải vào đĩa. Điều này được đánh dấu trong Hình 5 bên dưới.
Hình 5 sync_commit =remote_write
sync_commit =remote_apply
Khi chúng tôi đặt synchronous_commit = remote_apply,
COMMIT
sẽ đợi cho đến khi (các) máy chủ được chỉ định bởi synchronous_standby_names
xác nhận rằng bản ghi giao dịch đã được áp dụng cho cơ sở dữ liệu. Điều này được đánh dấu trong Hình 6 bên dưới.
Hình 6 sync_commit =remote_apply
Bây giờ, hãy xem sychronous_standby_names
thông số chi tiết, được đề cập ở trên khi cài đặt synchronous_commit
dưới dạng on
, remote_apply
hoặc remote_write
.
sync_standby_names =‘standby_name [,…]’
Cam kết đồng bộ sẽ đợi trả lời từ một trong các dự phòng được liệt kê theo thứ tự ưu tiên. Điều này có nghĩa là nếu chế độ chờ đầu tiên được kết nối và phát trực tuyến, cam kết đồng bộ sẽ luôn đợi phản hồi từ nó ngay cả khi chế độ chờ thứ hai đã được trả lời. Giá trị đặc biệt của *
có thể được sử dụng như stanby_name
sẽ phù hợp với bất kỳ chế độ chờ được kết nối nào.
sync_standby_names =‘num (standby_name [,…])’
Cam kết đồng bộ sẽ đợi trả lời từ ít nhất num
số lượng dự phòng được liệt kê theo thứ tự ưu tiên. Các quy tắc tương tự như trên được áp dụng. Vì vậy, ví dụ:đặt synchronous_standby_names = '2 (*)'
sẽ thực hiện cam kết đồng bộ chờ trả lời từ bất kỳ 2 máy chủ dự phòng nào.
sync_standby_names trống
Nếu thông số này trống như được hiển thị, nó sẽ thay đổi hành vi cài đặt synchronous_commit
thành on
, remote_write
hoặc remote_apply
hoạt động giống như local
(tức là, COMMIT
sẽ chỉ đợi xả vào đĩa cục bộ).
Kết luận
Trong bài đăng trên blog này, chúng tôi đã thảo luận về nhân rộng đồng bộ và mô tả các cấp độ bảo vệ khác nhau có sẵn trong Postgres. Chúng tôi sẽ tiếp tục sao chép hợp lý trong bài đăng blog tiếp theo.
Tài liệu tham khảo
Đặc biệt cảm ơn đồng nghiệp Petr Jelinek đã cho tôi ý tưởng về các bức tranh minh họa.
Tài liệu PostgreSQL
Sách nấu ăn quản trị PostgreSQL 9 - Phiên bản thứ hai