Pengantar
Pengiriman Log Transaksi adalah teknologi yang sangat terkenal yang digunakan di SQL Server untuk memelihara salinan database langsung di Situs Pemulihan Bencana. Teknologi ini bergantung pada tiga pekerjaan utama:Backup Job, Copy Job, dan Restore Job. Sementara pekerjaan Cadangan berjalan di Server Utama, pekerjaan Salin dan Pulihkan berjalan di Server Sekunder. Pada dasarnya proses ini melibatkan pencadangan log transaksi berkala ke bagian dari mana Pekerjaan Penyalinan bergerak sama ke Server Sekunder; selanjutnya, Pekerjaan Pemulihan menerapkan cadangan log ke server sekunder. Sebelum semua ini dimulai, Database Sekunder harus diinisialisasi dengan cadangan penuh dari server Primer yang dipulihkan dengan opsi NORECOVERY.
Microsoft menyediakan serangkaian prosedur tersimpan yang dapat digunakan untuk mengonfigurasi Pengiriman Log ujung ke ujung serta setara GUI mulai dari item properti setiap database yang mungkin ingin Anda konfigurasikan Pengiriman Log. Perlu dicatat bahwa Database Sekunder dapat dikonfigurasi dalam mode NORECOVERY atau dalam mode STANDBY. Dalam mode NORECOVERY database tidak pernah tersedia untuk kueri tetapi dalam mode STANDBY, database Sekunder dapat ditanyakan ketika tidak ada operasi pemulihan log Transaksi yang sedang berlangsung.
Menyiapkan Lingkungan
Untuk menjalankannya, kami membuat dua instans SQL Server di AWS dengan image Amazon EC2 yang identik. Instans Amazon EC2 ini menjalankan SQL Server 2017 RTM-CU5 di Windows Server 2016. Kemudian kami memulihkan salinan database WideWorldImporters menggunakan set cadangan yang diperoleh dari GitHub ke instans pertama, Instans Utama kami. Kami menggunakan set cadangan yang sama untuk membuat dua database identik bernama BranchDB dan CorporateDB.
Gbr. 1 Versi SQL Server
Gbr. 2 BranchDB dan CorporateDB pada Instans Utama (Kosongkan Instance Sekunder)
Daftar 1:Memulihkan Basis Data Contoh 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
Kami sekarang memiliki dua instans, Instans Utama yang menghosting dua basis data Utama (BranchDB dan CorporateDB dan instans Sekunder tanpa basis data pengguna. Kami melanjutkan dengan mengonfigurasi Pengiriman Log Transaksi pada kedua basis data tetapi membedakannya dengan menerapkan penundaan pada konfigurasi pemulihan dari database pertama. Ingatlah bahwa database sebenarnya identik dalam hal data yang dikandungnya. Grafik berikut menunjukkan opsi utama yang dipilih dalam Konfigurasi Pengiriman Log.
Gbr. 3 Pengaturan Cadangan untuk BranchDB
Gbr. 4 Salin Pengaturan untuk BranchDB
Gbr. 5 Pulihkan Pengaturan untuk BranchDB
Setiap pekerjaan Pengiriman Log dikonfigurasi untuk dijalankan setiap lima menit. Untuk proses “Delay Restoring Backups”, kita harus menggunakan mode Standby Recovery pada konfigurasi Log Shipping. Ini logis karena memiliki Database Sekunder dalam mode siaga dan menunjukkan bahwa kita dapat menanyakan Database Sekunder setiap kali Pemulihan Log Transaksi tidak berlangsung. Nilai yang kami tentukan dalam opsi ini (30 menit dalam kasus ini) memberi kami jendela yang baik di mana kami dapat menjalankan laporan dari Database Sekunder terlepas dari persyaratan inti artikel ini yang mampu memulihkan dari kesalahan pengguna.
Juga, kami harus menyebutkan bahwa pemulihan cadangan log transaksi sebenarnya sedang tertunda. Stempel waktunya lebih lambat dari nilai penundaan. Ini berarti bahwa semua cadangan log transaksi akan disalin ke server sekunder, yang didasarkan pada jadwal dan ditentukan dalam Pekerjaan Salin. Sebenarnya, Pekerjaan Pemulihan akan tetap berjalan sesuai jadwal tetapi cadangan log transaksi (yang tidak sampai 30 menit) tidak akan dipulihkan. Intinya, database Standby BranchDB adalah 30 menit di belakang database utama BranchDB. Untuk mendemonstrasikan kelambatan ini, di bagian selanjutnya, kita akan membuat tabel di kedua database dan membuat pekerjaan yang menyisipkan catatan setiap menit. Kami akan memeriksa tabel ini di Database Sekunder.
Pengaturan untuk Database CorporateDB sama seperti pada Gambar. 3 hingga 5, kecuali untuk Pekerjaan Pemulihan yang TIDAK disetel untuk menunda pencadangan log transaksi.
Gbr. 6 Pulihkan Pengaturan untuk CorporateDB
Memverifikasi Konfigurasi
Setelah konfigurasi selesai, kami dapat memverifikasi bahwa konfigurasi tersebut OK dan mulai dengan mengamati pekerjaannya. Laporan Pengiriman Log Transaksi menunjukkan kepada kita bahwa DB Cabang memang tertinggal dari CorporateDB dalam hal pemulihan:
Gbr. 7a Laporan Pengiriman Log Transaksi di Server Utama
Gbr. 7b Laporan Pengiriman Log Transaksi di Server Sekunder
Selain itu, Anda akan melihat pesan di bawah ini di riwayat Restore Job untuk BranchDB:
Gbr. 8 Pemulihan Log Transaksi yang Dilewati di Server Sekunder
Kita dapat melangkah lebih jauh dengan verifikasi ini dengan membuat tabel dan menggunakan tugas untuk mengisi tabel ini dengan baris setiap menit. Pekerjaan adalah cara sederhana untuk mensimulasikan apa yang mungkin dilakukan aplikasi ke tabel pengguna. Ini dapat menunjukkan kepada kita bahwa kelambatan ini jelas ditunjukkan dalam data pengguna.
Daftar 2 – Buat Tabel Pelacak Log
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)
Daftar 3 – Buat Pekerjaan untuk Mengisi Tabel Pelacak Log
/* ==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
Saat kami menanyakan tabel di Database Utama masing-masing, kami dapat mengonfirmasi (dengan menggunakan kolom RecordTime) bahwa baris cocok di BranchDB dan CorporateDB. Saat kami memeriksa tabel di Database Sekunder, dengan cara yang sama, kami melihat dengan jelas bahwa kami memiliki jeda 30 menit antara BranchDB dan CorporateDB.
Daftar 4 – Membuat Kueri Tabel Pelacak Log
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
Gbr. 9 Tabel Pelacak Log yang Cocok di Basis Data Utama
Gbr. 10 Tabel Pelacak Log Memiliki Kesenjangan ~30 Menit di Database Sekunder
Memulihkan dari Kesalahan Pengguna
Sekarang mari kita bicara tentang manfaat utama dari penundaan ini. Dalam skenario, di mana pengguna secara tidak sengaja menjatuhkan tabel, kami dapat memulihkan data dengan cepat dari Database Sekunder selama periode Penundaan belum berlalu. Dalam contoh ini, kami menghapus tabel Sales.Orderlines di database KEDUA dan memverifikasi bahwa tabel tidak lagi ada di database KEDUA.
Daftar 5 – Menjatuhkan Tabel Pesanan
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
Gbr. 11 Penjualan Tabel Dropping.Orderlines
Ketika kami mencari tabel di Server Sekunder, kami menemukan bahwa tabel tersebut masih tersedia di database KEDUA. Jadi, untuk CorporateDB kami memiliki waktu kurang dari lima menit untuk memulihkan data. (Gbr. 12). Tetapi begitu Siklus pemulihan berikutnya dijalankan, kami kehilangan tabel di database DB Perusahaan. Untuk memulihkan tabel ini, kita perlu melakukan pemulihan point-in-time menggunakan cadangan penuh di lingkungan yang terpisah dan kemudian mengekstrak tabel khusus ini. Anda akan setuju bahwa itu akan memakan waktu. Untuk tabel BranchDB Orderlines, kami memiliki sedikit lebih banyak waktu dan kami dapat memulihkan tabel dengan satu Pernyataan SQL melalui Server Tertaut (lihat Daftar 6).
Gbr. 12 Hitung Mundur Lima Menit:Tabel Ada di Kedua Basis Data Sekunder
Gbr. 13 Tambahan 25 Menit untuk Memulihkan Tabel BranchDB
Daftar 6 – Pulihkan Tabel Pesanan
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
Gbr. 14 Pulihkan Tabel Sales.Orderlines BranchDB
Kemudian kami memverifikasi Server Utama (Database BranchDB) bahwa tabel telah dipulihkan.
Gbr. 15 Pulihkan Tabel Sales.Orderlines BranchDB
Kesimpulan
SQL Server menyediakan sejumlah cara untuk memulihkan dari kehilangan data dari berbagai penyebab utama – kegagalan disk, korupsi, kesalahan pengguna, dll. Pemulihan point-in-time dari cadangan mungkin adalah metode yang paling terkenal. Untuk kasus sederhana tertentu dari kesalahan pengguna atau kasus serupa, di mana satu atau dua objek hilang, penggunaan Pengiriman Log Transaksi dengan Pemulihan Tertunda adalah pendekatan yang baik untuk dipertimbangkan. Namun, perlu dicatat bahwa database sekunder, yang dikonfigurasi secara ketat untuk kebutuhan DR, harus dipilih untuk RPO yang lebih rendah.