PostgreSQL là một hệ thống quản lý cơ sở dữ liệu quan hệ (RDBMS) mạnh mẽ và giàu tính năng. Hệ thống này miễn phí và mã nguồn mở, đã được phát triển từ năm 1996. Postgres cung cấp nhiều cách lưu trữ và sao chép dữ liệu khác nhau, một trong số đó là sao chép luồng. Ở chế độ này, một phiên bản chính (master) xử lý cơ sở dữ liệu đang hoạt động chính và thực hiện các hoạt động. Phiên bản phụ (slave) sao chép tất cả các thay đổi từ phiên bản chính, duy trì một bản sao giống hệt của cơ sở dữ liệu đang hoạt động. Máy chủ phụ cũng có thể chấp nhận các truy vấn chỉ đọc. Nếu phiên bản chính bị lỗi, máy chủ phụ có thể thoát khỏi chế độ chờ và hoạt động như máy chủ chính mới (đây được gọi là chuyển đổi dự phòng).
Sao chép PostgreSQL thường dựa vào ghi nhật ký ghi trước (WAL), quy trình ghi nhật ký các thay đổi dữ liệu trước khi ghi chúng vào đĩa. Sau đó, các bản ghi WAL này được sao chép sang một nút thứ hai dưới dạng tệp (vận chuyển nhật ký dựa trên tệp) hoặc được truyền trực tiếp giữa các nút (sao chép luồng). Trong hầu hết các trường hợp, cái sau sẽ giảm độ trễ để các thay đổi trên nút chính được nút dự phòng nhận.
Vấn đề khi sử dụng sao chép luồng mà không có vận chuyển nhật ký dựa trên tệp là máy chủ phụ có thể bỏ lỡ một số bản ghi WAL nếu máy chủ chính loại bỏ chúng quá sớm. Một số tham số cấu hình có thể giảm rủi ro này nhưng thường đi kèm với chi phí lưu trữ không cần thiết. Giải pháp là các khe sao chép, một tính năng do Postgres cung cấp để đảm bảo máy chủ chính chỉ hủy các bản ghi WAL sau khi chúng được nút dự phòng nhận.
Chúng tôi sẽ thiết lập sao chép phát trực tuyến với các khe sao chép trên hai nút Debian 10.
Cài đặt Postgres trên cả hai nút và đảm bảo PostgreSQL được bật và đang chạy:
LƯU Ý: Khi cập nhật PostgreSQL, cập nhật chế độ chờ trước là tùy chọn an toàn hơn theo tài liệu của họ.
Tìm dòng sau:
Đổi thành:
Nếu cả hai nút chia sẻ cùng một mạng cục bộ, bạn có thể sử dụng địa chỉ riêng cho node_ip_address, mặc dù Postgres sẽ không thể truy cập internet. Nếu không, hãy sử dụng địa chỉ công khai.
Lưu thay đổi rồi khởi động lại cả hai phiên bản:
Mở thiết bị đầu cuối Postgres:
Nút dự phòng sẽ sử dụng người dùng để kết nối với máy chủ chính. Tạo nút này:
Sau đó tạo một khe sao chép và thoát:
Để đơn giản, vai trò sao chép và khe cắm đều được đặt tên là "replicator", mặc dù chúng không nhất thiết phải giống hệt nhau.
Tiếp theo, tạo một mục trong pg_hba.conf để cho phép người dùng sao chép kết nối từ chế độ chờ đến máy chủ chính. Mở nó:
Thêm dòng sau vào cuối:
Khởi động lại phiên bản chính:
Đầu tiên, dừng Postgres trên nút phụ:
Sao lưu thư mục dữ liệu cũ:
Sử dụng lệnh sau để sao chép thư mục dữ liệu của máy chủ chính sang máy chủ phụ:
Bạn sẽ được nhắc nhập mật khẩu. Nhập mật khẩu bạn đã chọn cho vai trò replicator trong quá trình tạo trên máy chủ chính. Sau khi quá trình chuyển hoàn tất, hãy cấp quyền sở hữu thư mục dữ liệu cho người dùng postgres:
Bật chế độ chờ nóng trong postgresql.conf:
Tìm và bỏ chú thích cho dòng sau:
Tạo tệp recovery.conf trong thư mục dữ liệu Postgres:
Bật chế độ chờ:
Đặt các tham số kết nối sao chép bằng thông tin xác thực được tạo trên máy chủ chính:
Đặt tên cho khe sao chép mà bạn đã tạo trên máy chủ chính:
Đặt đường dẫn đến tệp kích hoạt chuyển đổi dự phòng:
Nếu tham số trigger_file được đặt, Postgres sẽ thoát khỏi chế độ chờ và bắt đầu hoạt động bình thường như một máy chủ chính khi tệp kích hoạt này được tạo. Tham số này không bắt buộc.
Sau khi tạo recovery.conf, hãy cấp quyền sở hữu cho người dùng postgres:
Bây giờ bạn có thể khởi động Postgres:
Bây giờ nó đang ở chế độ chờ và sẽ sao chép bất kỳ giao dịch mới nào.
Chờ vài giây rồi liệt kê các cơ sở dữ liệu trên máy chủ phụ:
Bạn sẽ thấy rằng cơ sở dữ liệu replitest thực sự đã được sao chép bởi máy chủ dự phòng:
Vì Postgres đang ở chế độ dự phòng, bạn sẽ không thể thực hiện bất kỳ thao tác ghi nào trên nút phụ trước khi chuyển đổi dự phòng. Ví dụ, thực hiện lệnh sau:
Lệnh này sẽ không thành công:
Để báo hiệu chuyển đổi dự phòng, hãy tạo tệp kích hoạt được chỉ định trong recovery.conf
Chờ vài giây, sau đó thử thực hiện thao tác ghi. Ví dụ:
Vì Postgres không còn hoạt động ở chế độ chờ nữa nên thao tác này sẽ thành công. Postgres cũng sẽ đổi tên tệp recovery.conf của bạn thành recovery.done và sẽ xóa tệp kích hoạt.
Để quay lại chế độ chờ, hãy dừng Postgres trên nút phụ (trước đây):
Đặt lại thư mục dữ liệu:
Và tạo lại recovery.conf:
Cuối cùng, khởi động lại Postgres:
Phiên bản thứ cấp hiện đã trở lại chế độ chờ. Bạn có thể muốn kiểm tra lại quá trình sao chép tại thời điểm này.
Và xóa các thư mục dữ liệu cũ trên nút chờ của bạn:
Sao chép PostgreSQL thường dựa vào ghi nhật ký ghi trước (WAL), quy trình ghi nhật ký các thay đổi dữ liệu trước khi ghi chúng vào đĩa. Sau đó, các bản ghi WAL này được sao chép sang một nút thứ hai dưới dạng tệp (vận chuyển nhật ký dựa trên tệp) hoặc được truyền trực tiếp giữa các nút (sao chép luồng). Trong hầu hết các trường hợp, cái sau sẽ giảm độ trễ để các thay đổi trên nút chính được nút dự phòng nhận.
Vấn đề khi sử dụng sao chép luồng mà không có vận chuyển nhật ký dựa trên tệp là máy chủ phụ có thể bỏ lỡ một số bản ghi WAL nếu máy chủ chính loại bỏ chúng quá sớm. Một số tham số cấu hình có thể giảm rủi ro này nhưng thường đi kèm với chi phí lưu trữ không cần thiết. Giải pháp là các khe sao chép, một tính năng do Postgres cung cấp để đảm bảo máy chủ chính chỉ hủy các bản ghi WAL sau khi chúng được nút dự phòng nhận.
Chúng tôi sẽ thiết lập sao chép phát trực tuyến với các khe sao chép trên hai nút Debian 10.
Yêu cầu
- Hai phiên bản Debian 10 giống hệt nhau.
- Quyền truy cập gốc vào cả hai phiên bản.
- Biến môi trường $EDITOR phải được đặt trên cả hai phiên bản.
Bước 1: Cài đặt PostgreSQL
Cập nhật và khởi động lại cả hai nút:
Mã:
apt updateapt upgrade -yreboot
Mã:
apt install -y postgresqlsystemctl enable --now [emailprotected]
Bước 2: Cấu hình ban đầu
Theo mặc định, PostgreSQL chỉ lắng nghe trên giao diện vòng lặp và không thể truy cập bên ngoài. Thay đổi địa chỉ lắng nghe trên cả hai nút bằng cách chỉnh sửa postgresql.conf:
Mã:
$EDITOR /etc/postgresql/11/main/postgresql.conf
Mã:
#listen_addresses = 'localhost'
Mã:
listen_addresses = 'node_ip_address,127.0.0.1'
Lưu thay đổi rồi khởi động lại cả hai phiên bản:
Mã:
systemctl restart [emailprotected]
Bước 3: Cấu hình máy chủ chính
Bước này chỉ áp dụng cho máy chủ chính/máy chủ chính.Mở thiết bị đầu cuối Postgres:
Mã:
sudo -u postgres psql
Mã:
postgres=# CREATE ROLE replicator LOGIN REPLICATION ENCRYPTED PASSWORD 'replicator_password';
Mã:
postgres=# SELECT * FROM pg_create_physical_replication_slot('replicator');postgres=# \q
Tiếp theo, tạo một mục trong pg_hba.conf để cho phép người dùng sao chép kết nối từ chế độ chờ đến máy chủ chính. Mở nó:
Mã:
$EDITOR /etc/postgresql/11/main/pg_hba.conf
Mã:
host replication replicator standby_ip_address/32 md5
Mã:
systemctl restart [emailprotected]
Bước 4: Sao lưu cơ sở
Các lệnh trong bước này phải được thực thi trên máy chủ phụ/phụ.Đầu tiên, dừng Postgres trên nút phụ:
Mã:
systemctl stop [emailprotected]
Mã:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak
Mã:
pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator
Mã:
chown -R postgres:postgres /var/lib/postgresql/11/main
Bước 5: Cấu hình chế độ chờ
Bước này chỉ áp dụng cho máy chủ phụ/phụ.Bật chế độ chờ nóng trong postgresql.conf:
Mã:
$EDITOR /etc/postgresql/11/main/postgresql.conf
Mã:
#hot_standby = on
Mã:
$EDITOR /var/lib/postgresql/11/main/recovery.conf
Mã:
standby_mode = 'on'
Mã:
primary_conninfo = 'host=master_ip_address port=5432 user=replicator password=replicator_password'
Mã:
primary_slot_name = 'replicator'
Mã:
trigger_file = '/var/lib/postgresql/11/main/failover.trigger'
Sau khi tạo recovery.conf, hãy cấp quyền sở hữu cho người dùng postgres:
Mã:
chown postgres:postgres /var/lib/postgresql/11/main/recovery.conf
Mã:
systemctl start [emailprotected]
Đang thử nghiệm
Đang thử nghiệm Sao chép
Để kiểm tra sao chép, hãy thực hiện bất kỳ hành động ghi nào trên máy chủ chính. Ví dụ, tạo một cơ sở dữ liệu mới trên máy chủ chính:
Mã:
sudo -u postgres psql -c "CREATE DATABASE replitest"
Mã:
sudo -u postgres psql -c "\l"
Mã:
Danh sách cơ sở dữ liệu Tên | Chủ sở hữu | Mã hóa | Đối chiếu | Kiểu C | Quyền truy cập-----------+----------+----------+-------------+-------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | replitest | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres(4 hàng)
Kiểm tra chuyển đổi dự phòng
LƯU Ý: Kiểm tra chuyển đổi dự phòng như được hiển thị ở đây sẽ yêu cầu đặt lại máy chủ dự phòng sau khi chuyển đổi dự phòng.Vì Postgres đang ở chế độ dự phòng, bạn sẽ không thể thực hiện bất kỳ thao tác ghi nào trên nút phụ trước khi chuyển đổi dự phòng. Ví dụ, thực hiện lệnh sau:
Mã:
sudo -u postgres psql -c "CREATE DATABASE test"
Mã:
ERROR: cannot execute CREATE DATABASE in a read-only transaction
Mã:
touch /var/lib/postgresql/11/main/failover.trigger
Mã:
sudo -u postgres psql -c "CREATE DATABASE test2"
Để quay lại chế độ chờ, hãy dừng Postgres trên nút phụ (trước đây):
Mã:
systemctl stop [emailprotected]
Mã:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.2.bakpg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicatorchown -R postgres:postgres /var/lib/postgresql/11/main
Mã:
cp /var/lib/postgresql/11/main.2.bak/recovery.done /var/lib/postgresql/11/main/recovery.conf
Mã:
systemctl start [emailprotected]
Hoàn tất
Xóa mọi cơ sở dữ liệu không cần thiết trên nút chính, ví dụ:
Mã:
sudo -u postgres psqlpostgres=# DROP DATABASE replitest;
Mã:
rm /var/lib/postgresql/11/main.bak -rrm /var/lib/postgresql/11/main.2.bak -r