Thực hiện Failover thủ công từ Primary sang Secondary
Bước này xác nhận tính khả dụng của Availability Group bằng cách chuyển đổi vai trò node thủ công. Thao tác này mô phỏng sự cố phần cứng hoặc mất điện của node chính.
Tại sao: Để đảm bảo Secondary node đã sẵn sàng nhận vai trò Primary và dữ liệu không bị mất mát (RPO = 0) trong kịch bản chuyển đổi.
Kết quả mong đợi: Node Secondary trở thành Primary mới, node cũ chuyển thành Secondary, và trạng thái Availability Group vẫn là "Synchronized".
Trước tiên, cần xác định tên Availability Group và tên Replica Secondary đích thông qua query kiểm tra trạng thái hiện tại.
SELECT name, role_desc, is_primary_replica FROM sys.dm_hadr_availability_replica_states;
Kết quả: Trả về danh sách các replica, chỉ ra node nào đang là PRIMARY và node nào là SECONDARY.
Thực hiện lệnh Failover thủ công. Lệnh này yêu cầu quyền SYSADMIN trên node Primary hiện tại. Tham số `WITH FAILURE` dùng để mô phỏng sự cố, trong khi `WITH SEVERE_FAILURE` dùng khi không thể liên lạc với Primary (ở đây dùng `WITH FAILURE` cho kiểm thử có kiểm soát).
ALTER AVAILABILITY GROUP [YourAGName] FAILOVER WITH FAILURE;
Thay thế `YourAGName` bằng tên Availability Group thực tế đã tạo ở Phần 4.
Kết quả: Lệnh thực thi thành công, hệ thống tự động chuyển trạng thái. Nếu Secondary chưa đồng bộ dữ liệu (Asynchronous), lệnh này sẽ bị từ chối. Hãy đảm bảo Secondary đã ở trạng thái "Synchronized" trước khi chạy lệnh này.
Verify kết quả Failover
Chạy lại query kiểm tra trạng thái trên node mới (đang là Primary) để xác nhận vai trò đã đổi.
SELECT name, role_desc, is_primary_replica FROM sys.dm_hadr_availability_replica_states;
Kết quả: Node trước đây là Secondary giờ hiển thị `role_desc` là `PRIMARY` và `is_primary_replica` là `1`.
Kiểm tra trạng thái kết nối ứng dụng sau khi Failover
Bước này xác minh khả năng tự động kết nối lại của ứng dụng client sử dụng Connection String với Listening Endpoint.
Tại sao: Trong môi trường Always On, ứng dụng không nên biết IP cụ thể của node. Việc kiểm tra này đảm bảo DNS và Endpoint Listener hoạt động đúng sau khi đổi Primary.
Kết quả mong đợi: Ứng dụng (hoặc lệnh SQL) kết nối thành công qua tên Listener mà không cần thay đổi cấu hình, dù backend đã thay đổi.
Sử dụng `sqlcmd` để kết nối qua tên Listener (ví dụ: `ListenerAG`). Connection String bắt buộc phải có tham số `MultiSubnetFailover=True` để giảm độ trễ khi phát hiện failover trên các subnet khác nhau (nếu có).
sqlcmd -S ListenerAG -U sa -P YourPassword -Q "SELECT @@SERVERNAME, @@SPID, sys.fn_hadr_is_primary_replica('YourAGName') AS IsPrimary;"
Thay `YourPassword` bằng mật khẩu thực tế. `YourAGName` là tên Availability Group.
Kết quả: Trả về tên server hiện tại của node đang là Primary. Cột `IsPrimary` trả về giá trị `1`.
Verify kết nối từ ứng dụng thực tế
Nếu có ứng dụng chạy trên server khác, hãy restart ứng dụng hoặc đợi timeout kết nối cũ hết hạn. Nếu ứng dụng không tự reconnect, kiểm tra log lỗi.
grep "Connection failed" /var/log/sqlserver.log
Kết quả: Không có lỗi liên quan đến kết nối listener, hoặc nếu có thì chỉ là lỗi transient trong vài giây đầu khi failover xảy ra.
Cấu hình Read-Only Secondary để phân phối tải đọc
Bước này kích hoạt khả năng đọc dữ liệu từ node Secondary để giảm tải cho node Primary, thường dùng cho báo cáo hoặc phân tích.
Tại sao: SQL Server mặc định chặn kết nối đọc trên Secondary nếu không cấu hình cụ thể. Cần thiết lập `ReadableSecondary` trong Availability Group.
Kết quả mong đợi: Có thể thực thi lệnh `SELECT` trên Secondary node thông qua Listener hoặc kết nối trực tiếp.
Trước tiên, cập nhật Availability Group để cho phép kết nối vào Secondary Replica. Lệnh này phải chạy trên node Primary hiện tại.
ALTER AVAILABILITY GROUP [YourAGName] MODIFY REPLICA N'NodeSecondaryName' WITH (READ_ONLY_ROUTING_URL = N'TCP://NodeSecondaryName:1433', READ_ONLY_ROUTING_LIST = (N'NodePrimaryName', N'NodeSecondaryName'));
Thay `NodeSecondaryName` và `NodePrimaryName` bằng hostname thực tế. `READ_ONLY_ROUTING_URL` là địa chỉ kết nối tới Secondary, `READ_ONLY_ROUTING_LIST` xác định thứ tự ưu tiên chuyển hướng đọc (từ Primary sang Secondary).
Kết quả: Cấu hình được cập nhật, hệ thống sẵn sàng định tuyến các yêu cầu đọc.
Kiểm tra trạng thái của Availability Group để đảm bảo nó cho phép đọc trên Secondary.
SELECT name, read_only_routing_url, is_read_only_routing_enabled FROM sys.availability_replicas WHERE role_desc = 'SECONDARY';
Kết quả: Cột `is_read_only_routing_enabled` trả về `1`.
Verify đọc từ Secondary
Thực hiện kết nối đọc trực tiếp vào Secondary hoặc qua Listener với tham số `ApplicationIntent=ReadOnly`.
sqlcmd -S ListenerAG -U sa -P YourPassword -Q "SET CONTEXT_INFO 'ReadOnlyTest'; SELECT COUNT(*) FROM YourDatabase.YourTable;"
Lưu ý: Nếu dùng `ApplicationIntent=ReadOnly`, SQL Server sẽ tự động chuyển hướng sang Secondary. Ở đây dùng Listener để test.
Kết quả: Query chạy thành công trên Secondary node, không bị lỗi "Database is not in readable state".
Đo lường thời gian Failover và độ trễ sao chép
Bước này định lượng hiệu năng của Always On: thời gian mất để hoàn tất Failover (RTO) và độ trễ dữ liệu giữa Primary và Secondary (RPO).
Tại sao: Để đảm bảo hệ thống đáp ứng SLA về thời gian phục hồi và mức độ mất dữ liệu cho phép.
Kết quả mong đợi: RTO dưới 30 giây (tùy cấu hình) và độ trễ sao chép (Log Send Delay) gần bằng 0 giây.
Sử dụng DMV `sys.dm_hadr_database_replica_states` để đo độ trễ sao chép (Log Send Queue và Redo Queue).
SELECT
drs.database_id,
DB_NAME(drs.database_id) AS DatabaseName,
drs.log_send_queue_size / 1024.0 AS LogSendKB,
drs.redo_queue_size / 1024.0 AS RedoKB,
DATEDIFF(MILLISECOND, drs.last_redo_time, GETDATE()) AS RedoDelayMs
FROM sys.dm_hadr_database_replica_states drs
WHERE drs.is_primary_replica = 0;
Kết quả: Trả về kích thước queue và độ trễ redo. Nếu `RedoDelayMs` nhỏ hơn 1000ms, dữ liệu gần như đồng bộ tức thời.
Để đo thời gian Failover (RTO), thực hiện Failover và đồng thời ghi log thời gian trên node Secondary.
SELECT GETDATE() AS FailoverStartTime;
-- Chờ Failover xảy ra
-- Sau đó chạy lệnh này ngay khi kết nối được
SELECT GETDATE() AS FailoverEndTime, DATEDIFF(MILLISECOND, '2023-10-27 10:00:00', GETDATE()) AS DurationMs;
Thay '2023-10-27 10:00:00' bằng thời điểm bắt đầu Failover thực tế (có thể lấy từ `sys.dm_os_performance_counters` hoặc log sự kiện Windows).
Cách chính xác hơn là dùng PowerShell hoặc script Bash để time lệnh Failover.
time sqlcmd -S PrimaryNode -U sa -P YourPassword -Q "ALTER AVAILABILITY GROUP [YourAGName] FAILOVER WITH FAILURE;"
Kết quả: Dòng output cuối cùng của lệnh `time` hiển thị `real`, `user`, `sys`. Giá trị `real` là thời gian Failover thực tế (RTO).
Verify hiệu năng
So sánh kết quả đo được với SLA dự kiến. Nếu RTO quá cao (>30s), kiểm tra kích thước database, tốc độ disk I/O, hoặc cấu hình CPU. Nếu độ trễ sao chép cao, kiểm tra mạng hoặc CPU Secondary.
SELECT
counter_name,
cntr_value
FROM sys.dm_os_performance_counters
WHERE counter_name LIKE '%Log Send Queue Size%'
OR counter_name LIKE '%Redo Queue Size%';
Kết quả: Giá trị `cntr_value` nên về 0 sau khi failover thành công và dữ liệu đã đồng bộ.
Điều hướng series:
Mục lục: Series: Triển khai Database SQL Server Always On với Ubuntu 24.04
« Phần 4: Tạo và cấu hình Always On Availability Group
Phần 6: Troubleshooting và bảo trì nâng cao cho SQL Server Always On »