PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL Streaming Replication - Deep Dive

Kiến thức về sao chép là điều bắt buộc đối với bất kỳ ai quản lý cơ sở dữ liệu. Đó là một chủ đề mà có lẽ bạn đã xem đi xem lại nhưng không bao giờ cũ. Trong blog này, chúng tôi sẽ xem xét một chút lịch sử của các tính năng sao chép tích hợp sẵn của PostgreSQL và đi sâu vào cách hoạt động của tính năng sao chép trực tuyến.

Khi nói về nhân rộng, chúng ta sẽ nói nhiều về WALs. Vì vậy, hãy nhanh chóng xem xét một chút về nhật ký viết trước.

Ghi nhật ký phía trước (WAL)

Write-Ahead Log là một phương pháp tiêu chuẩn để đảm bảo tính toàn vẹn của dữ liệu và nó được bật tự động theo mặc định.

WAL là nhật ký REDO trong PostgreSQL. Nhưng chính xác thì nhật ký REDO là gì?

Nhật ký REDO chứa tất cả các thay đổi được thực hiện trong cơ sở dữ liệu và chúng được sử dụng để sao chép, khôi phục, sao lưu trực tuyến và khôi phục tại thời điểm (PITR). Bất kỳ thay đổi nào chưa được áp dụng cho các trang dữ liệu có thể được thực hiện lại từ nhật ký REDO.

Sử dụng WAL giúp giảm đáng kể số lần ghi vào đĩa vì chỉ tệp nhật ký cần được chuyển vào đĩa để đảm bảo rằng một giao dịch được cam kết, thay vì mọi tệp dữ liệu được thay đổi bởi giao dịch.

Một bản ghi WAL sẽ chỉ định các thay đổi được thực hiện đối với dữ liệu, từng chút một. Mỗi bản ghi WAL sẽ được nối vào một tệp WAL. Vị trí chèn là Số thứ tự nhật ký (LSN), một byte bù đắp vào nhật ký, tăng dần theo mỗi bản ghi mới.

WAL được lưu trữ trong thư mục pg_wal (hoặc pg_xlog trong các phiên bản PostgreSQL <10) trong thư mục dữ liệu. Các tệp này có kích thước mặc định là 16MB (bạn có thể thay đổi kích thước bằng cách thay đổi tùy chọn cấu hình --with-wal-segsize khi xây dựng máy chủ). Chúng có một tên tăng dần duy nhất ở định dạng sau:"00000001 00000000 00000000".

Số lượng tệp WAL có trong pg_wal sẽ phụ thuộc vào giá trị được gán cho tham số checkpoint_searies (hoặc min_wal_size và max_wal_size, tùy thuộc vào phiên bản) trong tệp cấu hình postgresql.conf.

Một tham số mà bạn cần thiết lập khi định cấu hình tất cả các cài đặt PostgreSQL của mình là wal_level. Wal_level xác định lượng thông tin được ghi vào WAL. Giá trị mặc định là tối thiểu, chỉ ghi thông tin cần thiết để khôi phục sau sự cố hoặc tắt máy ngay lập tức. Lưu trữ thêm ghi nhật ký cần thiết để lưu trữ WAL; hot_standby bổ sung thêm thông tin cần thiết để chạy các truy vấn chỉ đọc trên máy chủ dự phòng; lôgic bổ sung thông tin cần thiết để hỗ trợ giải mã lôgic. Thông số này yêu cầu khởi động lại, do đó, có thể khó thay đổi khi chạy cơ sở dữ liệu sản xuất nếu bạn quên điều đó.

Để biết thêm thông tin, bạn có thể kiểm tra tài liệu chính thức tại đây hoặc tại đây. Bây giờ chúng ta đã đề cập đến WAL, hãy xem lại lịch sử sao chép trong PostgreSQL.

Lịch sử sao chép trong PostgreSQL

Phương pháp sao chép đầu tiên (chế độ chờ ấm) mà PostgreSQL đã triển khai (phiên bản 8.2, trở lại năm 2006) dựa trên phương thức vận chuyển nhật ký.

Điều này có nghĩa là các bản ghi WAL được chuyển trực tiếp từ máy chủ cơ sở dữ liệu này sang máy chủ cơ sở dữ liệu khác để được áp dụng. Có thể nói đó là PITR liên tục.

PostgreSQL triển khai vận chuyển nhật ký dựa trên tệp bằng cách chuyển các bản ghi WAL một tệp (phân đoạn WAL) tại một thời điểm.

Việc triển khai nhân rộng này có nhược điểm:nếu có lỗi lớn trên các máy chủ chính, các giao dịch chưa được vận chuyển sẽ bị mất. Vì vậy, có một cửa sổ cho việc mất dữ liệu (bạn có thể điều chỉnh điều này bằng cách sử dụng tham số archive_timeout, có thể được đặt ở mức thấp nhất là vài giây. Tuy nhiên, cài đặt thấp như vậy sẽ làm tăng đáng kể băng thông cần thiết để vận chuyển tệp).

Chúng tôi có thể trình bày phương thức vận chuyển nhật ký dựa trên tệp này bằng hình ảnh bên dưới:

Gửi nhật ký dựa trên tệp PostgreSQL

Sau đó, trong phiên bản 9.0 (trở lại năm 2010 ), nhân rộng phát trực tuyến đã được giới thiệu.

Tính năng sao chép truyền trực tuyến cho phép bạn luôn cập nhật nhiều hơn những gì có thể với việc vận chuyển nhật ký dựa trên tệp. Điều này hoạt động bằng cách chuyển trực tiếp các bản ghi WAL (tệp WAL bao gồm các bản ghi WAL) (vận chuyển nhật ký dựa trên bản ghi) giữa máy chủ chính và một hoặc một số máy chủ dự phòng mà không cần đợi tệp WAL được lấp đầy.

Trong thực tế, một quá trình được gọi là bộ thu WAL, chạy trên máy chủ dự phòng, sẽ kết nối với máy chủ chính bằng kết nối TCP / IP. Trong máy chủ chính, tồn tại một quy trình khác, có tên là người gửi WAL và chịu trách nhiệm gửi các đăng ký WAL đến máy chủ dự phòng khi chúng xảy ra.

Sơ đồ sau biểu thị sao chép trực tuyến:

PostgreSQL Streaming replication

Nhìn vào sơ đồ trên, bạn có thể tự hỏi, điều gì sẽ xảy ra khi giao tiếp giữa người gửi WAL và người nhận WAL không thành công?

Khi định cấu hình sao chép trực tuyến, bạn có tùy chọn bật lưu trữ WAL.

Bước này không bắt buộc nhưng cực kỳ quan trọng để thiết lập sao chép mạnh mẽ. Cần tránh trường hợp máy chủ chính tái chế các tệp WAL cũ chưa được áp dụng cho máy chủ dự phòng. Nếu điều này xảy ra, bạn sẽ cần tạo lại bản sao từ đầu.

Khi định cấu hình sao chép với tính năng lưu trữ liên tục, nó bắt đầu từ một bản sao lưu. Để đạt được trạng thái đồng bộ với chính, nó cần áp dụng tất cả các thay đổi được lưu trữ trong WAL đã xảy ra sau khi sao lưu. Trong quá trình này, chế độ chờ trước tiên sẽ khôi phục tất cả WAL có sẵn trong vị trí lưu trữ (được thực hiện bằng cách gọi lệnh restore_command). Lệnh khôi phục sẽ không thành công khi nó đạt đến bản ghi WAL được lưu trữ cuối cùng, vì vậy sau đó, chế độ chờ sẽ xem xét thư mục pg_wal để xem liệu thay đổi có tồn tại ở đó hay không (điều này hoạt động để tránh mất dữ liệu khi máy chủ chính gặp sự cố và một số thay đổi đã được di chuyển và áp dụng cho bản sao chưa được lưu trữ).

Nếu không thành công và bản ghi được yêu cầu không tồn tại ở đó, nó sẽ bắt đầu giao tiếp với máy chủ chính thông qua sao chép trực tuyến.

Bất cứ khi nào quá trình sao chép trực tuyến không thành công, nó sẽ quay lại bước 1 và khôi phục lại các bản ghi từ kho lưu trữ. Vòng lặp thử lại này từ kho lưu trữ, pg_wal và thông qua sao chép trực tuyến tiếp tục cho đến khi máy chủ dừng hoặc chuyển đổi dự phòng được kích hoạt bởi một tệp trình kích hoạt.

Sơ đồ sau thể hiện cấu hình sao chép trực tuyến với lưu trữ liên tục:

Sao chép phát trực tuyến PostgreSQL với lưu trữ liên tục

Sao chép truyền trực tuyến là không đồng bộ theo mặc định, vì vậy bất kỳ thời điểm nào, bạn có thể có một số giao dịch có thể được cam kết với máy chủ chính và chưa được sao chép sang máy chủ dự phòng. Điều này ngụ ý một số khả năng mất dữ liệu.

Tuy nhiên, độ trễ này giữa cam kết và tác động của các thay đổi trong bản sao được cho là thực sự nhỏ (vài mili giây), tất nhiên giả sử rằng máy chủ bản sao đủ mạnh để theo kịp tải.

Đối với những trường hợp không chấp nhận được nguy cơ mất mát dữ liệu nhỏ, phiên bản 9.1 đã giới thiệu tính năng sao chép đồng bộ.

Trong sao chép đồng bộ, mỗi cam kết của một giao dịch ghi sẽ đợi cho đến khi nhận được xác nhận rằng cam kết được ghi vào nhật ký ghi trước trên đĩa của cả máy chủ chính và máy chủ dự phòng.

Phương pháp này giảm thiểu khả năng mất dữ liệu; để điều đó xảy ra, bạn sẽ cần cả thiết bị chính và dự phòng đồng thời không hoạt động.

Nhược điểm rõ ràng của cấu hình này là thời gian phản hồi cho mỗi giao dịch ghi tăng lên, vì nó cần phải đợi cho đến khi tất cả các bên đã phản hồi. Vì vậy, thời gian cho một lần cam kết, tối thiểu là chu kỳ quay vòng giữa bản chính và bản sao. Giao dịch chỉ đọc sẽ không bị ảnh hưởng bởi điều này.

Để thiết lập sao chép đồng bộ, bạn cần chỉ định tên_ ứng dụng trong chính_conninfo của bản khôi phục cho mỗi tệp server.conf dự phòng:primary_conninfo ='... aplication_name =standbyX'.

Bạn cũng cần chỉ định danh sách các máy chủ dự phòng sẽ tham gia vào quá trình sao chép đồng bộ:sync_standby_name ='standbyX, standbyY'.

Bạn có thể thiết lập một hoặc một số máy chủ đồng bộ và tham số này cũng chỉ định phương pháp nào (ĐẦU TIÊN và BẤT KỲ) để chọn các dự phòng đồng bộ từ các máy chủ được liệt kê. Để biết thêm thông tin về cách thiết lập chế độ sao chép đồng bộ, hãy xem blog này. Cũng có thể thiết lập nhân rộng đồng bộ khi triển khai qua ClusterControl.

Sau khi bạn đã định cấu hình bản sao của mình và nó bắt đầu hoạt động, bạn sẽ cần triển khai giám sát

Giám sát sao chép PostgreSQL

Chế độ xem pg_stat_replication trên máy chủ chính có nhiều thông tin liên quan:

postgres=# SELECT * FROM pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 756
usesysid         | 16385
usename          | cmon_replication
application_name | pgsql_0_node_0
client_addr      | 10.10.10.137
client_hostname  |
client_port      | 36684
backend_start    | 2022-04-13 17:45:56.517518+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/400001C0
write_lsn        | 0/400001C0
flush_lsn        | 0/400001C0
replay_lsn       | 0/400001C0
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2022-04-13 17:53:03.454864+00

Hãy xem chi tiết điều này:

  • pid:Id quy trình của tiến trình walsender.

  • useysid:OID của người dùng được sử dụng để sao chép trực tuyến.

  • usename:Tên người dùng được sử dụng để sao chép trực tuyến.

  • application_name:Tên ứng dụng được kết nối với chính.

  • client_addr:Địa chỉ của bản sao ở chế độ chờ / phát trực tuyến.

  • client_hostname:Tên máy chủ của chế độ chờ.

  • client_port:Số cổng TCP giao tiếp ở chế độ chờ với người gửi WAL.

  • backend_start:Thời gian bắt đầu khi SR kết nối với Chính.

  • trạng thái:Trạng thái người gửi WAL hiện tại, tức là đang phát trực tuyến.

  • sent_lsn:Vị trí giao dịch cuối cùng được gửi đến chế độ chờ.

  • write_lsn:Giao dịch cuối cùng được ghi trên đĩa ở chế độ chờ.

  • flush_lsn:Giao dịch cuối cùng được xóa trên đĩa ở chế độ chờ.

  • replay_lsn:Giao dịch cuối cùng được xóa trên đĩa ở chế độ chờ.

  • sync_priasty:Mức độ ưu tiên của máy chủ dự phòng được chọn làm chế độ chờ đồng bộ.

  • sync_state:Đồng bộ hóa ở trạng thái chờ (không đồng bộ hay đồng bộ).

Bạn cũng có thể thấy quá trình người gửi / người nhận WAL đang chạy trên máy chủ.

Người gửi (Nút chính):

[[email protected] ~]# ps aux |grep postgres
postgres     727  0.0  2.2 917060 47936 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres     732  0.0  0.2 351904  5280 ?        Ss   17:45   0:00 postgres: 14/main: logger
postgres     734  0.0  0.5 917188 10560 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
postgres     735  0.0  0.4 917208  9908 ?        Ss   17:45   0:00 postgres: 14/main: background writer
postgres     736  0.0  1.0 917060 22928 ?        Ss   17:45   0:00 postgres: 14/main: walwriter
postgres     737  0.0  0.4 917748  9128 ?        Ss   17:45   0:00 postgres: 14/main: autovacuum launcher
postgres     738  0.0  0.3 917060  6320 ?        Ss   17:45   0:00 postgres: 14/main: archiver last was 00000001000000000000003F
postgres     739  0.0  0.2 354160  5340 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
postgres     740  0.0  0.3 917632  6892 ?        Ss   17:45   0:00 postgres: 14/main: logical replication launcher
postgres     756  0.0  0.6 918252 13124 ?        Ss   17:45   0:00 postgres: 14/main: walsender cmon_replication 10.10.10.137(36684) streaming 0/400001C0

Bộ thu (Nút chờ):

[[email protected] ~]# ps aux |grep postgres
postgres     727  0.0  2.2 917060 47576 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres     732  0.0  0.2 351904  5396 ?        Ss   17:45   0:00 postgres: 14/main: logger
postgres     733  0.0  0.3 917196  6360 ?        Ss   17:45   0:00 postgres: 14/main: startup recovering 000000010000000000000040
postgres     734  0.0  0.4 917060 10056 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
postgres     735  0.0  0.3 917060  6304 ?        Ss   17:45   0:00 postgres: 14/main: background writer
postgres     736  0.0  0.2 354160  5456 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
postgres     737  0.0  0.6 924532 12948 ?        Ss   17:45   0:00 postgres: 14/main: walreceiver streaming 0/400001C0

Một cách để kiểm tra tính cập nhật của bản sao của bạn là bằng cách kiểm tra số lượng bản ghi WAL được tạo trong máy chủ chính, nhưng chưa được áp dụng trong máy chủ dự phòng.

Chính:

postgres=# SELECT pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 0/400001C0
(1 row)

Chế độ chờ:

postgres=# SELECT pg_last_wal_receive_lsn();
 pg_last_wal_receive_lsn
-------------------------
 0/400001C0
(1 row)
postgres=# SELECT pg_last_wal_replay_lsn();
 pg_last_wal_replay_lsn
------------------------
 0/400001C0
(1 row)

Bạn có thể sử dụng truy vấn sau trong nút chờ để lấy độ trễ trong vài giây:

postgres=# SELECT CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()
THEN 0
ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())
END AS log_delay;
 log_delay
-----------
         0
(1 row)

Và bạn cũng có thể xem tin nhắn cuối cùng nhận được:

postgres=# SELECT status, last_msg_receipt_time FROM pg_stat_wal_receiver;
  status   |    last_msg_receipt_time
-----------+------------------------------
 streaming | 2022-04-13 18:32:39.83118+00
(1 row)

Giám sát sao chép PostgreSQL với ClusterControl

Để giám sát cụm PostgreSQL của mình, bạn có thể sử dụng ClusterControl, cho phép bạn theo dõi và thực hiện một số tác vụ quản lý bổ sung như triển khai, sao lưu, mở rộng quy mô và hơn thế nữa.

Trong phần tổng quan, bạn sẽ có bức tranh toàn cảnh về cụm cơ sở dữ liệu của mình tình trạng hiện tại. Để xem thêm chi tiết, bạn có thể truy cập phần trang tổng quan, nơi bạn sẽ thấy nhiều thông tin hữu ích được phân tách thành các biểu đồ khác nhau.

Trong phần cấu trúc liên kết, bạn có thể thấy cấu trúc liên kết hiện tại của mình trong người dùng- theo cách thân thiện và bạn cũng có thể thực hiện các tác vụ khác nhau trên các nút bằng cách sử dụng nút Hành động nút.

Sao chép truyền trực tuyến dựa trên việc vận chuyển các bản ghi WAL và áp dụng chúng ở chế độ chờ máy chủ, nó ra lệnh thêm hoặc thay đổi những byte nào trong tệp nào. Do đó, máy chủ dự phòng thực sự là một bản sao từng bit của máy chủ chính. Tuy nhiên, có một số hạn chế nổi tiếng ở đây:

  • Bạn không thể sao chép thành một phiên bản hoặc kiến ​​trúc khác.

  • Bạn không thể thay đổi bất kỳ điều gì trên máy chủ dự phòng.

  • Bạn không có nhiều thông tin chi tiết về những gì bạn sao chép.

Vì vậy, để khắc phục những hạn chế này, PostgreSQL 10 đã thêm hỗ trợ sao chép hợp lý

Sao chép lôgic

Bản sao lôgic cũng sẽ sử dụng thông tin trong tệp WAL, nhưng nó sẽ giải mã nó thành các thay đổi lôgic. Thay vì biết byte nào đã thay đổi, nó sẽ biết chính xác dữ liệu nào đã được chèn vào bảng nào.

Nó dựa trên mô hình “xuất bản” và “đăng ký” với một hoặc nhiều người đăng ký đăng ký một hoặc nhiều ấn phẩm trên một nút nhà xuất bản trông giống như sau:

PostgreSQL Logical Replication

Kết thúc

Với tính năng sao chép trực tuyến, bạn có thể liên tục gửi và áp dụng các bản ghi WAL cho các máy chủ dự phòng của mình, đảm bảo rằng thông tin cập nhật trên máy chủ chính được chuyển sang máy chủ dự phòng trong thời gian thực, cho phép cả hai luôn đồng bộ hóa .

ClusterControl giúp việc thiết lập sao chép phát trực tuyến trở nên đơn giản và bạn có thể đánh giá nó miễn phí trong 30 ngày.

Nếu bạn muốn tìm hiểu thêm về sao chép lôgic trong PostgreSQL, hãy nhớ xem tổng quan về sao chép lôgic này và bài đăng này về các phương pháp hay nhất về sao chép PostgreSQL.

Để biết thêm các mẹo và phương pháp hay nhất để quản lý cơ sở dữ liệu dựa trên nguồn mở của bạn, hãy theo dõi chúng tôi trên Twitter và LinkedIn, đồng thời đăng ký nhận bản tin của chúng tôi để được cập nhật thường xuyên.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sắp xếp truy vấn chậm theo cột trong bảng đã nối

  2. Cách đóng lỗ hổng bảo mật trong PostgreSQL

  3. Làm cách nào để nối các cột trong một Postgres SELECT?

  4. Cách cbrt () hoạt động trong PostgreSQL

  5. Cốt lõi của Entity Framework - Chứa phân biệt chữ hoa chữ thường hay không phân biệt chữ hoa chữ thường?