Giới thiệu
Nhật ký giao dịch Vận chuyển là một công nghệ rất nổi tiếng được sử dụng trong SQL Server để duy trì một bản sao của cơ sở dữ liệu trực tiếp trong Trang khôi phục sau thảm họa. Công nghệ này phụ thuộc vào ba công việc chính:Công việc Sao lưu, Công việc Sao chép và Công việc Khôi phục. Trong khi công việc Sao lưu chạy trên Máy chủ chính, công việc Sao chép và Khôi phục chạy trên Máy chủ phụ. Về cơ bản, quá trình này liên quan đến việc sao lưu nhật ký giao dịch định kỳ vào một phần mà từ đó Công việc sao chép di chuyển tương tự đến Máy chủ phụ; sau đó, Công việc khôi phục áp dụng các bản sao lưu nhật ký cho máy chủ phụ. Trước khi tất cả điều này bắt đầu, Cơ sở dữ liệu phụ phải được khởi tạo bằng bản sao lưu đầy đủ từ máy chủ Chính được khôi phục với tùy chọn NORECOVERY.
Microsoft cung cấp một tập hợp các thủ tục được lưu trữ có thể được sử dụng để cấu hình Log Shipping end đến end cũng như GUI tương đương bắt đầu từ mục thuộc tính của mỗi cơ sở dữ liệu mà bạn có thể muốn định cấu hình Log Shipping. Cần lưu ý rằng Cơ sở dữ liệu phụ có thể được cấu hình ở chế độ NORECOVERY hoặc ở chế độ STANDBY. Ở chế độ NORECOVERY, cơ sở dữ liệu không bao giờ có sẵn cho các truy vấn nhưng ở chế độ STANDBY, Cơ sở dữ liệu phụ có thể được truy vấn khi không có hoạt động khôi phục Nhật ký giao dịch nào đang diễn ra.
Thiết lập Môi trường
Để hiểu quả bóng, chúng tôi tạo hai phiên bản SQL Server trên AWS với một hình ảnh Amazon EC2 giống hệt nhau. Phiên bản Amazon EC2 này đang chạy SQL Server 2017 RTM-CU5 trên Windows Server 2016. Sau đó, chúng tôi khôi phục bản sao của cơ sở dữ liệu WideWorldImporters bằng cách sử dụng bộ sao lưu có được từ GitHub cho phiên bản đầu tiên, Phiên bản chính của chúng tôi. Chúng tôi sử dụng cùng một bộ sao lưu để tạo hai cơ sở dữ liệu giống nhau có tên BranchDB và CorporateDB.
Hình. 1 Phiên bản Máy chủ SQL
Hình. 2 BranchDB và CorporateDB trên Bản chính (Bản trống thứ cấp)
Liệt kê 1:Khôi phục cơ sở dữ liệu mẫu WideWorldImporters
restore filelistonly from disk='WideWorldImporters-Full.bak' restore database CorporateDB from disk='WideWorldImporters-Full.bak' with stats=10,recovery, move 'WWI_Primary' to 'M:\MSSQL\Data\WWI_Primary.mdf' , move 'WWI_UserData' to 'M:\MSSQL\Data\WWI_UserData.ndf' , move 'WWI_Log' to 'N:\MSSQL\Log\WWI_Log.ldf', move 'WWI_InMemory_Data_1' to 'M:\MSSQL\Data\WWI_InMemory_Data_1.ndf' restore database BranchDB from disk='WideWorldImporters-Full.bak' with stats=10,recovery, move 'WWI_Primary' to 'M:\MSSQL\Data\WWI_Primary1.mdf' , move 'WWI_UserData' to 'M:\MSSQL\Data\WWI_UserData1.ndf' , move 'WWI_Log' to 'N:\MSSQL\Log\WWI_Log1.ldf', move 'WWI_InMemory_Data_1' to 'M:\MSSQL\Data\WWI_InMemory_Data_11.ndf
Bây giờ chúng ta có hai phiên bản, Phiên bản chính lưu trữ hai cơ sở dữ liệu Chính (BranchDB và CorporateDB và Phiên bản phụ không có cơ sở dữ liệu người dùng. Chúng tôi tiến hành định cấu hình Vận chuyển Nhật ký Giao dịch trên cả hai cơ sở dữ liệu nhưng phân biệt chúng bằng cách áp dụng độ trễ cho cấu hình khôi phục của cơ sở dữ liệu đầu tiên. Hãy nhớ lại rằng các cơ sở dữ liệu thực sự giống hệt nhau về dữ liệu mà chúng chứa. Đồ họa sau đây hiển thị các tùy chọn chính được chọn trong Cấu hình Vận chuyển Nhật ký.
Hình. 3 Cài đặt sao lưu cho BranchDB
Hình. 4 Sao chép Cài đặt cho BranchDB
Hình. 5 Khôi phục cài đặt cho BranchDB
Mỗi công việc Vận chuyển nhật ký được định cấu hình để chạy năm phút một lần. Để xử lý “Sao lưu khôi phục trì hoãn”, chúng tôi phải sử dụng chế độ Khôi phục ở chế độ chờ trong cấu hình Vận chuyển nhật ký. Nó hợp lý vì nó có Cơ sở dữ liệu thứ cấp ở chế độ chờ và chỉ ra rằng chúng ta có thể truy vấn Cơ sở dữ liệu thứ cấp bất cứ khi nào Khôi phục nhật ký giao dịch không diễn ra. Giá trị mà chúng tôi chỉ định trong tùy chọn này (30 phút trong trường hợp này) cung cấp cho chúng tôi một cửa sổ tốt trong đó chúng tôi có thể chạy báo cáo từ Cơ sở dữ liệu phụ ngoài yêu cầu cốt lõi của bài viết này là có thể khôi phục từ lỗi người dùng.
Ngoài ra, chúng ta nên đề cập rằng việc khôi phục các bản sao lưu nhật ký giao dịch thực sự đang bị trì hoãn. Dấu thời gian của nó trễ hơn giá trị trễ. Điều này có nghĩa là tất cả các bản sao lưu nhật ký giao dịch sẽ được sao chép sang máy chủ phụ, dựa trên lịch trình và được chỉ định trong Công việc sao chép. Trên thực tế, Công việc Khôi phục sẽ vẫn chạy theo lịch trình nhưng các bản sao lưu nhật ký giao dịch (không quá 30 phút) sẽ không được khôi phục. Về bản chất, cơ sở dữ liệu BranchDB Standby chậm hơn 30 phút so với cơ sở dữ liệu chính BranchDB. Để chứng minh độ trễ này, trong phần tiếp theo, chúng ta sẽ tạo một bảng trong cả hai cơ sở dữ liệu và tạo một công việc chèn một bản ghi mỗi phút. Chúng tôi sẽ kiểm tra bảng này trong Cơ sở dữ liệu phụ.
Cài đặt cho Cơ sở dữ liệu CorporateDB giống như trong Hình. 3 đến 5, ngoại trừ Công việc khôi phục KHÔNG được đặt để trì hoãn việc sao lưu nhật ký giao dịch.
Hình. 6 Khôi phục cài đặt cho CorporateDB
Xác minh cấu hình
Sau khi cấu hình xong, chúng tôi có thể xác minh rằng cấu hình là OK và bắt đầu với việc quan sát hoạt động của nó. Báo cáo Vận chuyển Nhật ký Giao dịch cho chúng ta thấy rằng Branch DB thực sự đang tụt hậu so với CorporateDB về khả năng khôi phục:
Hình. 7a Báo cáo vận chuyển nhật ký giao dịch trên máy chủ chính
Hình. 7b Báo cáo vận chuyển nhật ký giao dịch trên máy chủ phụ
Ngoài ra, bạn sẽ nhận thấy thông báo bên dưới trong Lịch sử công việc Khôi phục cho BranchDB:
Hình. 8 Nhật ký giao dịch bị bỏ qua khôi phục trên máy chủ phụ
Chúng tôi có thể tiến xa hơn với việc xác minh này bằng cách tạo một bảng và sử dụng công việc để điền vào bảng này các hàng mỗi phút. Công việc là một cách đơn giản để mô phỏng những gì một ứng dụng có thể đang làm với một bảng người dùng. Điều này có thể cho chúng ta thấy rằng độ trễ này chắc chắn được hiển thị trong dữ liệu người dùng.
Liệt kê 2 - Tạo Bảng theo dõi Nhật ký
use BranchDB go create table log_ship_tracker ( ID int identity (100,1) ,Database_Name sysname default db_name() ,RecordTime datetime default getdate() ,ServerName sysname default @@servername) use CorporateDB go create table log_ship_tracker ( ID int identity (100,1) ,Database_Name sysname default db_name() ,RecordTime datetime default getdate() ,ServerName sysname default @@servername)
Liệt kê 3 - Tạo công việc để điền bảng theo dõi nhật ký
/* ==Scripting Parameters== Source Server Version : SQL Server 2017 (14.0.3023) Source Database Engine Edition : Microsoft SQL Server Standard Edition Source Database Engine Type : Standalone SQL Server Target Server Version : SQL Server 2017 Target Database Engine Edition : Microsoft SQL Server Standard Edition Target Database Engine Type : Standalone SQL Server */ USE [msdb] GO /****** Object: Job [InsertRecords] Script Date: 7/2/2018 3:32:00 PM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 /****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 7/2/2018 3:32:00 PM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'InsertRecords', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, @delete_level=0, @description=N'No description available.', @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'kairos\kigiri', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [InsertRecords] Script Date: 7/2/2018 3:32:00 PM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'InsertRecords', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @on_success_step_id=0, @on_fail_action=2, @on_fail_step_id=0, @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'TSQL', @command=N'use BranchDB go insert into log_ship_tracker values (db_name(),getdate(),@@servername) use CorporateDB go insert into log_ship_tracker values (db_name(),getdate(),@@servername) GO', @database_name=N'master', @flags=0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @[email protected], @name=N'Schedule', @enabled=1, @freq_type=4, @freq_interval=1, @freq_subday_type=4, @freq_subday_interval=1, @freq_relative_interval=0, @freq_recurrence_factor=0, @active_start_date=20180702, @active_end_date=99991231, @active_start_time=0, @active_end_time=235959, @schedule_uid=N'03e5f1b2-2e0b-4b30-8d60-3643c84aa08d' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION EndSave: GO
Khi chúng tôi truy vấn bảng trên Cơ sở dữ liệu chính tương ứng, chúng tôi có thể xác nhận (bằng cách sử dụng cột RecordTime) rằng các hàng khớp trong BranchDB và CorporateDB. Khi chúng tôi kiểm tra bảng trong Cơ sở dữ liệu phụ, theo cách tương tự, chúng tôi thấy rõ ràng rằng chúng tôi có khoảng cách 30 phút giữa BranchDB và CorporateDB.
Liệt kê 4 - Truy vấn bảng theo dõi nhật ký
select top 10 @@servername [Current_Server],* from BranchDB.dbo.log_ship_tracker order by RecordTime desc select top 10 @@servername [Current_Server], * from CorporateDB.dbo.log_ship_tracker order by RecordTime desc
Hình. 9 Bảng theo dõi nhật ký Khớp trong Cơ sở dữ liệu Chính
Hình. 10 Bảng theo dõi nhật ký Có khoảng cách ~ 30 phút trong cơ sở dữ liệu phụ
Khôi phục từ lỗi người dùng
Bây giờ, hãy nói về lợi ích chính của việc trì hoãn này. Trong trường hợp người dùng vô tình làm rơi bảng, chúng tôi có thể khôi phục dữ liệu nhanh chóng từ Cơ sở dữ liệu phụ miễn là khoảng thời gian Trì hoãn chưa trôi qua. Trong ví dụ này, chúng tôi loại bỏ bảng Sales.Orderlines trên cả hai cơ sở dữ liệu và xác minh rằng bảng không còn tồn tại trong cả hai cơ sở dữ liệu.
Liệt kê 5 - Bảng đơn hàng giảm xuống
drop table BranchDB.Sales.Orderlines drop table CorporateDB.Sales.Orderlines GO use BranchDB go select @@servername [Current_Server] , db_name() [Database_Name] , name , schema_name(schema_id) [schema] , type_desc , create_date , modify_date from sys.tables where name='Orderlines' GO use CorporateDB go select @@servername [Current_Server] , db_name() [Database_Name] , name , schema_name(schema_id) [schema] , type_desc , create_date , modify_date from sys.tables where name='Orderlines' GO
Hình. 11 Bán hàng theo bảng giảm dần. Đơn hàng
Khi chúng tôi tìm kiếm bảng trên Máy chủ phụ, chúng tôi thấy rằng bảng vẫn có sẵn trong CẢ hai cơ sở dữ liệu. Vì vậy, đối với CorporateDB, chúng tôi có ít hơn năm phút để khôi phục dữ liệu. (Hình 12). Nhưng khi Chu kỳ khôi phục tiếp theo thực thi, chúng ta sẽ mất bảng trong cơ sở dữ liệu Corporate DB. Để khôi phục bảng này, chúng ta cần khôi phục tại chỗ bằng cách sử dụng bản sao lưu đầy đủ trong một môi trường riêng biệt và sau đó giải nén bảng cụ thể này. Bạn sẽ đồng ý rằng sẽ mất một thời gian. Đối với bảng BranchDB Orderlines, chúng tôi có thêm một chút thời gian và chúng tôi có thể khôi phục bảng bằng một Câu lệnh SQL duy nhất qua một Máy chủ được Liên kết (xem Liệt kê 6).
Hình. Đếm ngược 12 năm phút:Bảng tồn tại trong cả hai cơ sở dữ liệu phụ
Hình. 13 Thêm 25 phút để khôi phục bảng BranchDB
Liệt kê 6 - Khôi phục bảng đơn hàng
USE [master] GO /****** Object: LinkedServer [10.2.1.84] Script Date: 7/2/2018 4:14:59 PM ******/ EXEC master.dbo.sp_addlinkedserver @server = N'10.2.1.84', @srvproduct=N'SQL Server' /* For security reasons the linked server remote logins password is changed with ######## */ EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'10.2.1.84',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpasswo rd=NULL GO select * into BranchDB.Sales.Orderlines from [10.2.1.84].BranchDB.Sales.Orderlines
Hình. 14 Khôi phục bảng BranchDB Sales.Orderlines
Sau đó, chúng tôi xác minh Máy chủ chính (Cơ sở dữ liệu BranchDB) rằng bảng được khôi phục.
Hình. 15 Khôi phục bảng BranchDB Sales.Orderlines
Kết luận
SQL Server cung cấp một số cách khôi phục sau khi mất dữ liệu từ nhiều nguyên nhân gốc rễ - lỗi đĩa, hỏng, lỗi người dùng, v.v. Khôi phục tại chỗ từ các bản sao lưu có lẽ là phương pháp nổi tiếng nhất trong số các phương pháp này. Đối với một số trường hợp đơn giản do lỗi người dùng hoặc trường hợp tương tự, trong đó một hoặc hai đối tượng bị mất, việc sử dụng Vận chuyển nhật ký giao dịch với Khôi phục bị trì hoãn là một cách tiếp cận tốt để xem xét. Tuy nhiên, cần lưu ý rằng cơ sở dữ liệu thứ cấp, được định cấu hình nghiêm ngặt cho nhu cầu DR, phải được chọn cho RPO thấp hơn.