Khe sao chép là gì?
Quay lại những ngày mà "Khe sao chép" chưa được giới thiệu, việc quản lý các phân đoạn WAL là một thách thức. Trong sao chép trực tuyến tiêu chuẩn, chủ nhân không có kiến thức về trạng thái nô lệ. Lấy ví dụ về một nút chính thực hiện một giao dịch lớn, trong khi một nút chờ ở chế độ bảo trì trong vài giờ (chẳng hạn như nâng cấp gói hệ thống, điều chỉnh bảo mật mạng, nâng cấp phần cứng, v.v.). Tại một số thời điểm, tổng thể loại bỏ nhật ký giao dịch của nó (các phân đoạn WAL) khi trạm kiểm soát đi qua. Một khi nô lệ không được bảo trì, nó có thể có độ trễ nô lệ rất lớn và phải bắt kịp với chủ. Cuối cùng, nô lệ sẽ gặp sự cố nghiêm trọng như sau:
LOG: started streaming WAL from primary at 0/73000000 on timeline 1
FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000000000073 has already been removed
Cách tiếp cận điển hình là chỉ định trong postgresql.conf của bạn một tập lệnh lưu trữ WAL sẽ sao chép các tệp WAL vào một hoặc nhiều vị trí lưu trữ lâu dài. Nếu bạn không có bất kỳ lỗi nào hoặc ứng dụng khách sao chép luồng khác, thì về cơ bản máy chủ có thể loại bỏ tệp WAL sau khi tập lệnh lưu trữ hoàn tất hoặc phản hồi OK. Nhưng bạn vẫn sẽ cần một số tệp WAL gần đây để khôi phục sự cố (dữ liệu từ các tệp WAL gần đây được phát lại trong quá trình khôi phục sự cố. Trong ví dụ của chúng tôi về nút chờ được đặt trong thời gian bảo trì dài, các vấn đề phát sinh khi nó trực tuyến trở lại và yêu cầu tệp chính cho tệp WAL mà tệp chính không còn nữa, thì quá trình sao chép không thành công.
Sự cố này đã được giải quyết trong PostgreSQL 9.4 thông qua "Replication Slots".
Nếu không sử dụng các khe sao chép, một cách phổ biến để giảm nguy cơ sao chép không thành công là đặt wal_keep_segment đủ cao để các tệp WAL có thể cần thiết sẽ không bị xoay hoặc tái chế. Nhược điểm của phương pháp này là khó xác định giá trị nào là tốt nhất cho thiết lập của bạn. Bạn sẽ không cần bảo trì hàng ngày hoặc bạn sẽ không cần phải giữ lại một đống lớn các tệp WAL sử dụng dung lượng lưu trữ trên đĩa của bạn. Mặc dù cách này hoạt động, nhưng đây không phải là giải pháp lý tưởng vì rủi ro về dung lượng đĩa trên máy chủ có thể khiến các giao dịch đến không thành công.
Các phương pháp thay thế để không sử dụng các khe sao chép là định cấu hình PostgreSQL với tính năng lưu trữ liên tục và cung cấp lệnh khôi phục để cấp cho bản sao quyền truy cập vào kho lưu trữ. Để tránh tích tụ WAL trên tệp chính, bạn có thể sử dụng ổ đĩa hoặc thiết bị lưu trữ riêng cho tệp WAL, ví dụ:SAN hoặc NFS. Một điều khác là với nhân rộng đồng bộ vì nó yêu cầu rằng chính phải đợi các nút dự phòng để thực hiện giao dịch. Điều này có nghĩa là, nó đảm bảo rằng các tệp WAL đã được áp dụng cho các nút dự phòng. Tuy nhiên, tốt nhất là bạn nên cung cấp các lệnh lưu trữ từ tệp chính để khi WAL được tái chế trong tệp chính, hãy yên tâm rằng bạn có các bản sao lưu WAL trong trường hợp khôi phục. Mặc dù trong một số tình huống, sao chép đồng bộ không phải là một giải pháp lý tưởng vì nó đi kèm với một số chi phí hiệu suất so với sao chép không đồng bộ.
Các loại Khe sao chép
Có hai loại khe sao chép. Đây là:
Vị trí sao chép vật lý
Có thể được sử dụng để nhân rộng luồng tiêu chuẩn. Họ sẽ đảm bảo rằng dữ liệu không được tái chế quá sớm.
Vị trí sao chép lôgic
Bản sao lôgic thực hiện điều tương tự như các khe sao chép vật lý và được sử dụng để sao chép lôgic. Tuy nhiên, chúng được sử dụng để giải mã logic. Ý tưởng đằng sau giải mã hợp lý là cung cấp cho người dùng cơ hội đính kèm vào nhật ký giao dịch và giải mã nó bằng một plugin. Nó cho phép trích xuất các thay đổi được thực hiện đối với cơ sở dữ liệu và do đó đối với nhật ký giao dịch ở bất kỳ định dạng nào và cho bất kỳ mục đích nào.
Trong blog này, chúng tôi sẽ sử dụng các vị trí sao chép vật lý và cách đạt được điều này bằng cách sử dụng ClusterControl.
Ưu điểm và Nhược điểm của việc Sử dụng Khe sao chép
Các vị trí sao chép chắc chắn có lợi khi được bật. Theo mặc định, "Khe sao chép" không được bật và phải được đặt theo cách thủ công. Trong số những lợi thế của việc sử dụng Replication Slots là
- Đảm bảo bản gốc giữ lại đủ phân đoạn WAL để tất cả các bản sao nhận được chúng
- Ngăn trang cái xóa các hàng có thể gây ra xung đột khôi phục trên các bản sao
- Bản chính chỉ có thể tái chế bản ghi giao dịch khi nó đã được sử dụng bởi tất cả các bản sao. Lợi thế ở đây là một nô lệ không bao giờ có thể bị tụt hậu đến mức cần phải đồng bộ hóa lại.
Khe sao chép cũng có một số lưu ý.
- Khe nhân bản mồ côi có thể khiến ổ đĩa phát triển không giới hạn do các tệp WAL chồng chất từ cái chính
- Các nút nô lệ được bảo trì trong thời gian dài (chẳng hạn như ngày hoặc tuần) và được liên kết với một khe sao chép sẽ có tốc độ phát triển đĩa không giới hạn do các tệp WAL được xếp chồng lên nhau từ cái chính
Bạn có thể giám sát điều này bằng cách truy vấn pg_replication_slots để xác định các vị trí không được sử dụng. Chúng tôi sẽ kiểm tra lại vấn đề này sau một chút.
Sử dụng Khe sao chép
Như đã nêu trước đó, có hai loại khe sao chép. Đối với blog này, chúng tôi sẽ sử dụng các khe sao chép vật lý để sao chép trực tuyến.
Tạo Vùng Sao chép
Tạo một bản sao rất đơn giản. Bạn cần gọi hàm hiện có pg_create_physical_replication_slot để thực hiện việc này và phải được chạy và tạo trong nút chính. Chức năng này rất đơn giản,
maximus_db=# \df pg_create_physical_replication_slot
Schema | pg_catalog
Name | pg_create_physical_replication_slot
Result data type | record
Argument data types | slot_name name, immediately_reserve boolean DEFAULT false, OUT slot_name name, OUT xlog_position pg_lsn
Type | normal
ví dụ:Tạo một vùng sao chép có tên slot1,
postgres=# SELECT pg_create_physical_replication_slot('slot1');
-[ RECORD 1 ]-----------------------+---------
pg_create_physical_replication_slot | (slot1,)
Tên vùng sao chép và cấu hình cơ bản của nó chỉ dành cho toàn hệ thống chứ không phải toàn cụm. Ví dụ:nếu bạn có nodeA (chính hiện tại), và các nút dự phòng là nodeB và nodeC, việc tạo vị trí trên một nút chínhA cụ thể là "slot1", thì dữ liệu sẽ không có sẵn cho nodeB và nodeC. Do đó, khi chuyển đổi dự phòng / chuyển đổi dự phòng sắp xảy ra, bạn cần tạo lại các vị trí mà bạn đã tạo.
Bỏ qua một vị trí sao chép
Các vị trí sao chép không sử dụng phải bị xóa hoặc xóa. Như đã nói trước đó, khi có các khe sao chép hoặc các khe sao chép không hợp lệ chưa được chỉ định cho bất kỳ ứng dụng khách hoặc nút dự phòng nào, nó có thể dẫn đến các vấn đề về dung lượng ổ đĩa vô hạn nếu vẫn chưa được khai thác. Vì vậy, điều rất quan trọng là chúng phải được loại bỏ khi nó không còn sử dụng. Để loại bỏ nó, chỉ cần gọi pg_drop_replication_slot. Hàm này có định nghĩa sau:
maximus_db=# \df pg_drop_replication_slot
Schema | pg_catalog
Name | pg_drop_replication_slot
Result data type | void
Argument data types | name
Type | normal
Việc loại bỏ nó rất đơn giản:
maximus_db=# select pg_drop_replication_slot('slot2');
-[ RECORD 1 ]------------+-
pg_drop_replication_slot |
Giám sát các Khe sao chép PostgreSQL của bạn
Giám sát các vị trí sao chép của bạn là điều bạn không muốn bỏ lỡ. Chỉ cần thu thập thông tin từ chế độ xem pg_replication_slots trong nút chính / nút chính như bên dưới:
postgres=# select * from pg_replication_slots;
-[ RECORD 1 ]-------+-----------
slot_name | main_slot
plugin |
slot_type | physical
datoid |
database |
active | t
active_pid | 16297
xmin |
catalog_xmin |
restart_lsn | 2/F4000108
confirmed_flush_lsn |
-[ RECORD 2 ]-------+-----------
slot_name | main_slot2
plugin |
slot_type | physical
datoid |
database |
active | f
active_pid |
xmin |
catalog_xmin |
restart_lsn |
confirmed_flush_lsn |
Kết quả trên cho thấy rằng main_slot đã được sử dụng, nhưng không phải main_slot2.
Một điều khác bạn có thể làm là theo dõi mức độ trễ so với các khe cắm mà bạn có. Để đạt được điều này, bạn chỉ cần sử dụng truy vấn dựa trên kết quả mẫu bên dưới:
postgres=# SELECT redo_lsn, slot_name,restart_lsn,
round((redo_lsn-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind
FROM pg_control_checkpoint(), pg_replication_slots;
redo_lsn | slot_name | restart_lsn | gb_behind
------------+-----------+-------------+-----------
1/8D400238 | slot1 | 0/9A000000 | 3.80
Nhưng redo_lsn không có trong 9.6, sẽ sử dụng redo_location, vì vậy trong 9.6,
imbd=# SELECT redo_location, slot_name,restart_lsn,
round((redo_location-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind
FROM pg_control_checkpoint(), pg_replication_slots;
-[ RECORD 1 ]-+-----------
redo_location | 2/F6008BE0
slot_name | main_slot
restart_lsn | 2/F6008CC0
gb_behind | 0.00
-[ RECORD 2 ]-+-----------
redo_location | 2/F6008BE0
slot_name | main_slot2
restart_lsn | 2/F6008CC0
gb_behind | 0.00
Yêu cầu về biến hệ thống
Việc triển khai các vị trí sao chép yêu cầu cài đặt thủ công. Có những biến mà bạn phải ghi nhớ yêu cầu thay đổi và được chỉ định trong postgresql.conf của bạn. Xem bên dưới:
- max_replication_slots - Nếu được đặt thành 0, điều này có nghĩa là các vị trí sao chép hoàn toàn bị vô hiệu hóa. Nếu bạn đang sử dụng phiên bản PostgreSQL <10, vị trí này phải được chỉ định khác 0 (mặc định). Kể từ PostgreSQL 10, mặc định là 10. Biến này chỉ định số lượng khe sao chép tối đa. Đặt nó thành giá trị thấp hơn số lượng vị trí sao chép hiện có sẽ ngăn máy chủ khởi động.
- wal_level - ít nhất phải là bản sao hoặc cao hơn (bản sao là mặc định). Đặt hot_standby hoặc kho lưu trữ sẽ ánh xạ thành bản sao. Đối với một khe sao chép vật lý, bản sao là đủ. Đối với các vị trí sao chép lôgic, lôgic được ưu tiên hơn.
- max_wal_senders - được đặt thành 10 theo mặc định, 0 trong phiên bản 9.6 có nghĩa là tính năng sao chép bị vô hiệu hóa. Chúng tôi khuyên bạn nên đặt giá trị này ít nhất là 16, đặc biệt là khi chạy với ClusterControl.
- hot_standby - trong các phiên bản <10, bạn cần đặt cài đặt này thành bật theo mặc định. Điều này rất quan trọng đối với các nút ở chế độ chờ, nghĩa là khi bật, bạn có thể kết nối và chạy các truy vấn trong quá trình khôi phục hoặc ở chế độ chờ.
- primary_slot_name - biến này được đặt thông qua recovery.conf trên nút chờ. Đây là vị trí được người nhận hoặc nút chờ sử dụng khi kết nối với người gửi (hoặc chính / chính).
Bạn phải lưu ý rằng các biến này chủ yếu yêu cầu khởi động lại dịch vụ cơ sở dữ liệu để tải lại các giá trị mới.
Sử dụng Khe sao chép trong Môi trường ClusterControl PostgreSQL
Bây giờ, hãy xem cách chúng ta có thể sử dụng các vị trí sao chép vật lý và triển khai chúng trong thiết lập Postgres do ClusterControl quản lý.
Triển khai các nút cơ sở dữ liệu PostgreSQL
Hãy bắt đầu triển khai Cụm PostgreSQL 3 nút bằng ClusterControl sử dụng phiên bản PostgreSQL 9.6 lần này.
ClusterControl sẽ triển khai các nút với các biến hệ thống sau được xác định tương ứng dựa trên giá trị mặc định của chúng hoặc điều chỉnh các giá trị. Trong:
postgres=# select name, setting from pg_settings where name in ('max_replication_slots', 'wal_level', 'max_wal_senders', 'hot_standby');
name | setting
-----------------------+---------
hot_standby | on
max_replication_slots | 0
max_wal_senders | 16
wal_level | replica
(4 rows)
Trong các phiên bản PostgreSQL> 9.6, giá trị mặc định max_replication_slots là 10 được bật theo mặc định nhưng không được bật trong các phiên bản 9.6 hoặc thấp hơn mà giá trị này bị tắt theo mặc định. Bạn cần chỉ định max_replication_slots cao hơn 0. Trong ví dụ này, tôi đặt max_replication_slots thành 5.
[email protected]:~# grep 'max_replication_slots' /etc/postgresql/9.6/main/postgresql.conf
# max_replication_slots = 0 # max number of replication slots
max_replication_slots = 5
và khởi động lại dịch vụ,
[email protected]:~# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
9.6 main 5432 online postgres /var/lib/postgresql/9.6/main pg_log/postgresql-%Y-%m-%d_%H%M%S.log
[email protected]:~# pg_ctlcluster 9.6 main restart
Đặt Khe sao chép cho Nút chính và Nút chờ
Không có tùy chọn nào trong ClusterControl để thực hiện việc này, vì vậy bạn phải tạo các vị trí của mình theo cách thủ công. Trong ví dụ này, tôi đã tạo các vị trí trong máy chủ chính trong máy chủ 192.168.30.100:
192.168.10.100:5432 [email protected]_db=# SELECT pg_create_physical_replication_slot('slot1'), pg_create_physical_replication_slot('slot2');
pg_create_physical_replication_slot | pg_create_physical_replication_slot
-------------------------------------+-------------------------------------
(slot1,) | (slot2,)
(1 row)
Kiểm tra những gì chúng tôi vừa tạo cho thấy,
192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;
slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn
-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------
slot1 | | physical | | | f | | | | |
slot2 | | physical | | | f | | | | |
(2 rows)
Bây giờ trong các nút dự phòng, chúng ta cần cập nhật recovery.conf và thêm biến primary_slot_name và thay đổi tên_dụng_dụng để việc xác định nút dễ dàng hơn. Đây là cách nó trông như thế nào trong máy chủ 192.168.30.110 recovery.conf:
[email protected]:/var/lib/postgresql/9.6/main/pg_log# cat ../recovery.conf
standby_mode = 'on'
primary_conninfo = 'application_name=node11 host=192.168.30.100 port=5432 user=cmon_replication password=m8rLmZxyn23Lc2Rk'
recovery_target_timeline = 'latest'
primary_slot_name = 'slot1'
trigger_file = '/tmp/failover_5432.trigger'
Làm điều tương tự như trong máy chủ 192.168.30.120 nhưng đã thay đổi application_name và đặt primary_slot_name ='slot2'.
Kiểm tra tình trạng vùng sao chép:
192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;
slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn
-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------
slot1 | | physical | | | t | 24252 | | | 0/CF0A4218 |
slot2 | | physical | | | t | 11635 | | | 0/CF0A4218 |
(2 rows)
Bạn Cần Gì Khác?
Vì ClusterControl không hỗ trợ Khe sao chép vào thời điểm này, nên có những điều bạn cần tính đến. Cái gì đây? Hãy đi vào chi tiết.
Quá trình chuyển đổi dự phòng / chuyển mạch
Khi thực hiện chuyển đổi dự phòng hoặc chuyển đổi tự động qua ClusterControl, các vị trí sẽ không được giữ lại từ nút chính và trên các nút dự phòng. Bạn cần phải tạo lại điều này theo cách thủ công, kiểm tra các biến nếu được đặt chính xác và sửa đổi recovery.conf cho phù hợp.
Xây dựng lại một nô lệ từ một Master
Khi xây dựng lại một nô lệ, recovery.conf sẽ không được giữ lại. Điều này có nghĩa là cài đặt recovery.conf của bạn có primary_slot_name sẽ bị xóa. Bạn cần chỉ định lại điều này theo cách thủ công và kiểm tra chế độ xem pg_replication_slots để xác định xem các vị trí có được sử dụng đúng cách hay không.
Nếu bạn muốn xây dựng lại nút phụ / nút dự phòng từ nút chính, bạn có thể phải xem xét việc chỉ định biến env PGAPPNAME giống như lệnh bên dưới:
$ export PGAPPNAME="app_repl_testnode15"; /usr/pgsql-9.6/bin/pg_basebackup -h 192.168.10.190 -U cmon_replication -D /var/lib/pgsql/9.6/data -p5434 -W -S main_slot -X s -R -P
Chỉ định tham số -R là rất quan trọng vì vậy nó sẽ tạo lại recovery.conf, trong khi -S sẽ chỉ định tên vùng nào sẽ sử dụng khi xây dựng lại nút dự phòng.
Kết luận
Việc triển khai Replication Slots trong PostgreSQL rất đơn giản nhưng có một số lưu ý nhất định mà bạn phải nhớ. Khi triển khai với ClusterControl, bạn sẽ cần cập nhật một số cài đặt trong quá trình chuyển đổi dự phòng hoặc xây dựng lại nô lệ.