使用create database命令来为数据库创建快照,当创建一个快照时必须在create database命令中包含源数据库中的每一个数据文件。包括原来的逻辑名称和一个新的物理名称。不能够指定其它的文件属性,也没有使用日志文件。
这是为Archive数据库创建一个快照的操作如下:
1.首先查看Archive数据库中的数据文件的逻辑名称
C:\Users\Administrator>sqlcmd -S WINS7-2014DITHH\JY 1> use Archive 2> GO 已将数据库上下文更改为 'Archive'。 1> select name,physical_name from sys.database_files; 2> GO name physical_name ------------------------------------------------ ------------------------------------------------------------------------- Arch1 C:\Program Files\Microsoft SQLServer\MSSQL.1\MSSQL\Data\archdat1.mdf Archlog1 C:\Program Files\Microsoft SQLServer\MSSQL.1\MSSQL\Data\archlog1.ldf Arch2 C:\Program Files\Microsoft SQLServer\MSSQL.1\MSSQL\Data\archdat2.ndf (3 行受影响)
2.创建数据库快照Archive_snapshot
1> create database Archive_snapshot on 2> ( 3> name='Arch1',--数据文件的逻辑名称 4> filename='C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Archive_snapshot_1.mdf' --快照文件 5> ), 6> ( 7> name='Arch2', 8> filename='C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Archive_snapshot_2.mdf' 9> ) 10> as snapshot of Archive; 11> GO
下面在源数据库中向表t1插入一行记录
1.先查看表t1中的记录
1>use Archive; 2>GO 已将数据库上下文更改为 'Archive'。 1>select * from t1; 2>GO t_id t_date ----------- -------------------- 1 2019-04-25 (1 行受影响)
2.向表t1中插入一行记录
1>insert into t1 values(2,'2019-04-26'); 2>GO; (1 行受影响)
3.再次查询表t1中的记录
1>select * from t1; 2>GO t_id t_date ----------- -------------------- 1 2019-04-25 2 2019-04-26 (2 行受影响)
在快照数据库中查询表t1的记录
1>use Archive_snapshot; 2>GO 已将数据库上下文更改为 'Archive_snapshot'。 1>select * from t1; 2>GO t_id t_date ----------- -------------------- 1 2019-04-25 (1 行受影响)
可以看到快照数据库中的t1的记录仍然只有一条,快照数据库只包含快照创建时源数据库中已有的数据。
快照中的每一个文件都被创建为稀疏文件,这是NTFS文件系统的一个特性。开始时,一个稀疏文件不包含用户数据,也没有分配到用来存储用户数据的磁盘空间。当数据被写入稀疏文件时,NTFS逐渐地为其分配磁盘空间。一个稀疏文件有可能增长得很大。稀疏文件以64KB为单位增量增长,因此磁盘上的稀疏文件的大小总是64KB的倍数。
快照文件只包含源数据库中发生了变化的数据。对每一个文件,SQL Server创建了一个保存在高速缓存中的比特图,文件的每一个页面对应一个比特位,表示那个页面是否已经被复制到快照中。每次当源数据库中有一个页面被更新时,SQL Server会查看比特图来检查该页面是否已经被复制了,如果还没有被复制,那么马上将其复制到快照中。这种操作被称为写入时复制操作。
前面提到,比特图保存在调整缓存里,而不是文件自身,所以它总是可供随时使用。当SQL Server关闭或数据库关闭时,比特图会丢失并且需要在数据库启动时进行重建军。当SQL Server被访问时它会判断读每一个页面是否存在稀疏文件中,然后将这些信息保存在比物图中供将业使用。
快照反映了发出create database命令的时间点—也就是在创建操作开始的那一刻。SQL Server对源数据库进行检查点操作并将一个同步日志序列号(Log Sequence Number,LSN)记录在源数据库的日志文件里。LSN是一种确定数据库中某一特定时间点的方式。SQL Server然后在源数据库上运行恢复,以便任何未提交事务能够在快照中被回滚。所以虽然快照的稀疏文件开始时是空白的,但是那并不能维护很久。如果当快照被创建时有事务正在进行,恢复进程将会在数据库快照可用前撤消未提交的事务,所以该快照将会包含修改后数据的源数据库所有页面的原始版本。
快照只能在NTFS格式的卷上创建,因为该格式是唯一支持稀疏文件技术的文件格式。如果我们尝试在FAT或FAT32卷上创建一个快照,那么会收到如下类似的错误:
Msg 1823, Level 16, State 2, Line 1 A database snapshot cannot be created because it failed to start. Msg 5119, Level 16, State 1, Line 1 Cannot make the file "E:\AW_snapshot.MDF" a sparse file. Make sure the file system supports sparse files.
第一个错误基本上是一个普通的错误信息,第二个错误信提供了关于该操作为什么失败的更详细信息。
可以通过查看动态管理函数sys.dm_io_virtual_file_stats来发现数据库快照的每个稀疏文件中正在使用的磁盘上的字节数据是多少,该函数通过size_on_disk_bytes列来返回一个文件中的当前字节数据。该函数将database_id和file_id作为参数。快照数据库的数据库id和每一个稀疏文件的文件ID被显示在目录视图sys.master_files中。还可以通过Windows资源管理器来查看其大小。
1>select name,database_id from sys.databases; 2>GO name database_id ---------------------- ----------- master 1 tempdb 2 model 3 msdb 4 AdventureWorksDW 5 AdventureWorks 6 resource_COPY 7 Archive 8 Archive_snapshot 9 (9 行受影响) 1>select database_id,file_id,name,physical_name from sys.master_files; 2>GO database_id file_id name physical_name ----------- ----------- ------------------------- ----------------------------------------------------------------------------------------- 1 1 master C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf 1 2 mastlog C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\mastlog.ldf 2 1 tempdev C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\tempdb.mdf 2 2 templog C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\templog.ldf 3 1 modeldev C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\model.mdf 3 2 modellog C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\modellog.ldf 4 1 MSDBData C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBData.mdf 4 2 MSDBLog C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBLog.ldf 5 1 AdventureWorksDW_Data C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorksDW_Data.mdf 5 2 AdventureWorksDW_Log C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorksDW_Log.ldf 6 1 AdventureWorks_Data C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks_Data.mdf 6 2 AdventureWorks_Log C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks_Log.ldf 7 1 data C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\mssqlsystemresource_copy.mdf 7 2 log C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\mssqlsystemresource_copy.ldf 8 1 Arch1 C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\archdat1.mdf 8 2 Archlog1 C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\archlog1.ldf 8 3 Arch2 C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\archdat2.ndf 9 1 Arch1 C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Archive_snapshot_1.mdf 9 3 Arch2 C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Archive_snapshot_2.mdf (19 行受影响) 1>select * from sys.dm_io_virtual_file_stats (9,NULL) AS vfs; 2>GO database_id file_id sample_ms num_of_reads num_of_bytes_read io_stall_read_ms num_of_writes num_of_bytes_written io_stall_write_ms io_stall size_on_disk_bytes file_handle ----------- ------- ----------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- ------------------ 9 1 1902593092 60 491520 133 5 40960 4 137 262144 0x000000000000080C 9 3 1902593092 4 32768 11 1 8192 0 11 65536 0x0000000000000840 (2 行受影响)
因为同一个数据库有可能拥有多个快照,所以我们必须确保有足够的可用磁盘空间。快照开始时会相对较小,当随着源数据库的更新,每个快照都会增长。稀疏文件的空间按照称为区域的片断进行分配,单位为64KB。当一个区域被分配时,除了已经更改过的一个页面,所有的页面都会被清零。这时该区域中还供7个更改过的页面使用的空间,并且在这7个页面空间被使用完之前,不会分配新的区域。
有可能会过度申请存储空间。这意味着在通常情况下,我们能够拥有的是实际物理存储空间很多倍的多个快照,但一旦快照增长,物理卷就会被耗尽(当运行在线dbcc checkdb命令或相关命令时有可能会发生这种情况,因为我们无法控制这些命令所使用的内部快照存放的物理位置—它会被存放在父数据库文件所在的同一个郑上。dbcc在这种情况下检查将会失败)。一旦物理卷空间耗尽,对源数据库的写操作就无法将写之前的页面图像复制到稀疏文件。无法写入页面的快照会被记为置疑(suspect)并且无法使用,但是源数据库仍然可以继续运行。不可能修复一个被置疑的快照,必须将这种快照数据库删除。
管理快照
如果一个源数据库中存在快照,那么就无法删除,分离或还原该源数据库。如果把握一个数据库切换到离线(offline)状态,那么快照将会被自动删除。另外,我们基本上可以通过将源数据回复(Revert)到快照创建时的状态,并把源数据库替换为它的一个快照。命令如下:
1> use master; 2> GO 已将数据库上下文更改为 'master'。 1> restore database Archive from database_snapshot='Archive_snapshot'; 2> GO 1> use Archive; 2> GO 已将数据库上下文更改为 'Archive'。 1> select * from t1; 2> GO t_id t_date ----------- -------------------- 1 2019-04-25 (1 行受影响)
在将源数据库Archive回复到快照创建时的状态后,表t1中只有一条记录。
在回复(Revert)操作期间,快照和源数据库是可用的并会被标记为“还原中”。如果在回复操作期间出现错误,该操作将会在数据库重新启动时尝试完成回复操作。当存在多个快照时是不能回复到其中任何一个快照的,所以首先我们应该把除了希望回复的快照以外的所有快照删除。删除一个快照的操作与drop database操作非常相似。在删除快照的同时,所有的NTFS稀疏文件也都被删除了。
需要注意下面的这些与数据库快照有关的附加注意事项:
.不能在model,master和tempdb数据库上创建快照(SQL Server内部可以为了对master数据库运行在线DBCC检查而为其创建一些快照,但是这些快照是不能显式创建的)。
1> drop database Archive_snapshot; 2> GO
.一个快照会从它的源数据库中继承安全约束,且由于快照是只读的,所以我们无法改变其权限。
.如果从源数据库中删除一个用户,该用户会继续留在快照中。
.不能备份或还原快照,但是能够正常备份源数据库;它并不受数据库快照的影响。
.不能附加或分离快照。
.数据库快照并不支持全文索引,全文目录不会从源数据库传播到快照中。