如果要在一個特定的時間分析數據庫中的數據,你會怎么做?例如,你想要分析晚上12點的數據,你會采取什么樣的措施?最經常用到的方法,創(chuàng)建一個計劃任務,在晚上12點的時候執(zhí)行備份,將當前數據庫以一個新的名字備份到服務器上,然后再開始分析這個備份數據庫中的數據。這樣做的問題就在于,如果這個數據庫很大,那么備份它就需要花費大量的時間和磁盤空間。如果你需要在數據訪問高峰期做備份的話,它花費的資源足以讓你的服務器宕機。然而,在SQL Server2005中,有一項新的功能,名為數據庫快照,可以讓你很方便的處理類似的問題。
除了上面提到的優(yōu)點,使用數據庫快照還有很多其它的好處,本文將集中討論數據庫快照的優(yōu)點。數據庫快照是一項不太起眼的功能,這意味著,許多DBA和開發(fā)者都沒有注意到它的存在。
數據庫快照是什么
數據庫快照是當前數據庫的只讀靜態(tài)視圖,不包括那些還沒有提交的事務。沒有提交的事務被回滾了,這樣才能保證數據庫的事務一致性。計算機培訓http://www.computerpx.com/
工作原理
通常,我們使用一項功能的時候并不需要知道它的工作原理。然而,知道其工作原理將會給我們的工作帶來大大的好處。
一旦你創(chuàng)建數據庫快照,快照數據庫將被分配到一個空閑文件中。當原始數據頁發(fā)生變化的時候,該頁就會被移動到這個空閑文件。當你訪問數據庫快照的時候,你會訪問到空閑文件,以及原始數據庫上那些沒有發(fā)生變化的數據頁。我們可以從下圖看出數據庫快照是如何工作的。
圖一(來源:SQL Server 2005 在線手冊)
使用數據庫快照
首先,你需要創(chuàng)建一個數據庫快照。有兩種方法可以創(chuàng)建數據庫快照。
CREATEDATABASEssAdventureWorks_dbss2230ON鄭州北大青鳥http://www.hnbenet.com/
(NAME=AdventureWorks_Data,FILENAME=
'C:ProgramFilesMicrosoftSQLServerMSSQL.1MSSQLDataAdventureWorks_data_2230.ss')
ASSNAPSHOTOFAdventureWorks;
GO
在上面的例子中,AdventureWork_data_2230.ss是一個空閑文件。擴展名cc是一個任意值,不是默認也不是必須的。
訪問數據庫快照的方法和訪問一般的數據庫一樣:
SELECT*
FROM[ssAdventureWorks_dbss2230].dbo.Employees
像訪問數據庫一樣,我么也可以像刪除一個一般數據庫一樣刪除數據庫快照。
DROP DATABASE [ssAdventureWorks_dbss2230]
你可以選擇將數據庫快照存儲在當前數據庫上,這樣的話,數據庫快照就成為了當前數據庫的一個備份。
RESTOREDATABASEAdventureWorksfrom
DATABASE_SNAPSHOT='ssAdventureWorks_dbss2230';
GO
對于數據庫快照,只有唯一的選項可用,這也就意味著,我們不可以對一個數據庫快照進行備份或者將它們存儲于數據庫快照之上。
定時數據庫快照
定時進行數據庫快照非常重要,但在SQL Server管理工具中,數據庫快照節(jié)點上是沒有這個直接選項的。然而,我們可以利用SQL Server代理作業(yè)新建一個定時作業(yè),用來創(chuàng)建一個數據庫快照。
以下的腳本將分為兩步來創(chuàng)建一個定時作業(yè)。第一步是刪除數據庫快照而第二步是重新創(chuàng)建一個數據庫快照。這項作業(yè)將每隔一個小時創(chuàng)建一個數據庫快照。
USE [msdb]
GO
/****** Object: Job [Database snapshot] Script Date: 01/29/2008 16:39:31 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object: JobCategory [[Uncategorized (Local)]]] Script Date: 01/29/2008 16:39:31 ******/
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'Database snapshot',
@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'Dinesh-Mobdinesh', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [drop database snapshot] Script Date: 01/29/2008 16:39:32 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'drop database snapshot',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=3,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'DROP DATABASE [ssAdventureWork_dbss2230]',
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [Create Snapshot] Script Date: 01/29/2008 16:39:32 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Create Snapshot',
@step_id=2,
@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'CREATE DATABASE ssAdventureWorks_dbss2230 ON
( NAME = AdventureWorks_Data, FILENAME =
''C:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLDataAdventureWorks_data_2230.ss'' )
AS SNAPSHOT OF AdventureWorks;
',
@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 = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Schedule',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=8,
@freq_subday_interval=1,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=20080129,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959
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:
其它信息
很多時候我們都知道,可以從sys.databases的系統視圖中看到數據庫的清單列表。數據庫快照也在這個清單中。在這個視圖中,有兩列與數據庫快照相關。一列是source_database_id,它將指名源數據庫ID或者快照的源數據庫。另一列是is_read_only,當一個快照數據庫是一個只讀數據庫時,該列的值為1.
SELECTNAME,
database_id,
source_database_id,
is_read_only
FROMsys.databases
優(yōu)點
1.數據庫快照最大的優(yōu)點就在于它可以作為一個報告數據庫。因為數據庫快照是主數據庫的一個只讀副本,對一個數據庫快照執(zhí)行報告能夠大大的減少加載時間。
2.數據庫快照只需要幾個特征值就可以恢復源數據庫。
缺點
1.數據庫快照最主要的缺點就是它只能在SQL Server企業(yè)版上使用。我們都知道,企業(yè)版的成本很好,因此不是每一個人都能夠使用這一項功能。
2.數據庫快照是依附于主數據庫,因此不能單獨使用。
3.數據庫快照中不支持全文檢索。
結論
數據庫快照是SQL Server企業(yè)版中一個非常方便的功能。然而,需要強調的是,數據庫快照不能替代數據庫備份。如果你想很好的利用這項有用的功能,可以在數據報告中多使用它。