SQLSERVER2005 参数设置二(转sql2005技术内幕)
上一篇 / 下一篇 2009-02-11 11:08:57 / 个人分类:性能测试
离线|在线|紧急
我们可以使用这三个选项来描述一个数据库的状态。这些选项是互相排斥的。一个数据库默认是ONLINE的。与用户访问选项一样,当我们使用ALTER DATABASE来将数据库设置为这些模式之一时,不需要为其指定一个ON或者OFF值——我们只需要使用该选项的名字即可。当一个数据库被设置为离线(OFFLINE)时,它会被正常地关闭并被标记为离线,数据的所有快照也都会被自动删除。当一个数据库在离线状态时它是不能被修改的。当一个数据库中有任何连接时,它是不能被设置为离线的。在这种情况下SQLServer是等待其他连接终止还是产生一条错误信息取决于指定的结束(TERMINATION)选项。
下面的示例代码显示了如何将一个数据库的状态值设置为OFFLINE和如何确定一个数据库的状态:
ALTER DATABASE AdventureWorks SET OFFLINE;
SELECT state_desc from sys.databases
WHERE name = 'AdventureWorks';
一个数据库能够显式地设置为紧急(EMERGENCY)模式,并且在讨论一些不能设置的数据库状态值之后将会解释为什么我们可能希望那样做。
前面的查询所示,我们可以通过检查sys.databases视图的state_desc列来确定一个数据库的当前状态。此列可以返回除OFFLINE、ONLINE和EMERGENRCY以外的状态值,但是那些值不能通过ALTER DATABASE命令直接进行设置。一个数据库处于从备份还原的过程中时会具有还原中(RESTORING)状态值。在SQL Server重新启动期间数据库会具有恢复中(RECOVERING)状态值。还原进程一次只能在一个数据库上进行,并且一个数据库会保持恢复中(RECOVERING)状态值直到SQL Server完成该数据库的还原。如果由于某种原因,恢复进程无法完成(很有可能是由于数据库的一个或多个日志文件不可用或不可读),SQL Server会给该数据库一个恢复中断(RECOVERY_PENDING)的状态值。如果SQL Server在回滚恢复过程中用完了日志或数据空间,或者如果SQL Server在启动过程的某个部分用完了锁或内存,数据库也会被置为恢复中断(RECOVERY_PENDING)模式。我们会在第5章中对回滚恢复和启动恢复的不同进行更多讨论51Testing软件测试网!D&te$x2`.G i2X
如果所有需要的资源包括日志文件都可获得,但是在恢复期间探测到了故障,数据库可能会被设置为置疑(SUSPECT)状态。这时我们可以通过查看sys.dataselect*fromsys.databaseswherename='oscartest'
bases视图的state_desc列来确定数据库的状态值。当一个数据库处于置疑(SUSPECT)状态时它是完全不可用的,并且即使我们运行sp_helpdb,也无法看到该数据库。然而,我们可以查看一个置疑数据库的数据库属性(DATABASEPROPERTY)的值,并从sys.databases视图来查看其状态值。在很多情况下,可以通过将一个置疑的数据库设置到紧急(EMERGERCY)模式来使得该数据库能够进行只读操作。如果确实丢失了一个数据库的一个或多个日志文件,紧急模式允许我们在将数据复制到一个新的位置之后访问数据。当我们将一个数据库从恢复中断(RECOVERY_PENDING)模式转换到紧急模式时,SQL Server关闭该数据库,然后使用一个允许它跳过恢复过程的特殊的标志位重新启动该数据库。跳过恢复过程意味着会出现一些在逻辑上或物理上不一致的数据——丢失索引行、损坏的页面链接或不正确的元数据指针。我们虽然承认数据也许是不一致的,但是不管怎样还是希望在访问数据库的情况下,可以通过专门将数据库设置到紧急模式来读取数据。51Testing软件测试网 E `(sz@(y2`M
紧急模式修复
我们可以在紧急模式下运行DBCC CHECKDB命令,并且当指定REPAIR_ALLOW_ DATA_LOSS选项时,SQL Server能够在数据库上进行一些专门的修复,这有可能使通常无法恢复的数据库变得在物理上一致,并且能够重新上线。这些修复应该作为我们最后的手段,在无法从备份中还原数据库时才考虑使用。
当数据库被设置为紧急模式时,该数据库被内部地设置为只读(READ_ONLY),日志被禁用了,并且对该数据库的访问也仅限于sysadmin角色的成员。然而,我们从sys.databases系统表中看到的数据库的属性不会反映这些限制。
当数据库处于紧急模式并且运行带REPAIR_ALLOW_DATALOSS从句的DBCC CHECKDB时,会进行下面的操作:
%R)M [9A ~0为了增加数据恢复的概率,DBCC CHECKDB会使用由于I/O或校验和(checksum)错误已经被标为无法访问的页面,就好像这些错误还没有发生一样。
n DBCC CHECKDB会尝试使用常规的基于日志的恢复技术来恢复数据库。
n 如果数据库恢复没有成功,会重建事务日志。重建事务日志也许会导致事务一致性被破坏。
如果DBCC CHECKDB命令成功了,那么这个数据库会处于物理上一致的状态,并且这个数据库的状态会被设置为ONLINE。然而,该数据库也许含有一个或更多事务的或逻辑的不连续处。这时我们可以考虑运行DBCC CHECKCONSTRAINTS来找出所有的业务逻辑方面的错误,并且马上备份该数据库。
如果DBCC CHECKDB命令失败了,那么该数据库就无法修复了。
在某些情况下,紧急模式是不可能的,特别是当与空间分配有关的一些元数据(数据库启动时需要这些数据时)丢失或损坏的时候。
我们可以尝试将一个紧急模式下的数据库设置为在线(ONLINE)模式(例如,当丢失的文件已经重新可用时),SQL Server将会试图在该数据库上运行恢复。如果到在线(ONLINE)模式的转变无法完成,那么数据库或者停留在恢复中断(RECOVERY_ PENDING)状态,或者停留在置疑(SUSPECT)状态,就像我们首次启动SQL Server实例并尝试恢复数据库时一样。再次强调一下,我们可以通过将处于恢复中断(RECOVERY_PENDING)状态的数据库切换到紧急模式来使得数据能够被读取。
在一台测试服务器上测试一个数据库的紧急状态值相对容易。我们可以使用三个单词的命令CREATE DATABASE TESTDB来创建一个简单的数据库,然后停止SQL Server实例并重新命名(或删除)日志文件。当我们重新启动该实例时,检查该新数据库的状态:
SELECT name, database_id, user_access_desc, state_desc
FROM sys.databases
WHERE name = 'testdb';
state_desc列应该会显示RECOVERY_PENDING,这时我们可以将它切换到紧急(EMERGENCY)模式:
ALTER DATABASE testdb SET EMERGENCY;
虽然这时并没有事务日志,但是数据库将允许读取数据。无论我们使用何种方式来尝试更新数据,都会收到下面的错误:
Msg 3908, Level 16, State 1, Line 1
Could not run BEGIN TRANSACTION in database 'testdb' because the database is in bypass
recovery mode.