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

Khắc phục mất dữ liệu bằng Vận chuyển nhật ký với khôi phục bị trì hoãn

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Vui vẻ với nén (columnstore) trên một bảng rất lớn - phần 1

  2. 18 cơ sở dữ liệu NoSQL mã nguồn mở miễn phí và được sử dụng rộng rãi nhất

  3. Cách viết câu lệnh CASE trong SQL

  4. Thủ tục được lưu trữ chuyên dụng để có được trạng thái sao lưu cơ sở dữ liệu mới nhất

  5. Toán tử SQL IN cho người mới bắt đầu