离线|在线|紧急
6SL+@%hr1A
q~ f0我们可以使用这三个选项来描述一个数据库的状态。这些选项是互相排斥的。一个数据库默认是ONLINE的。与用户访问选项一样,当我们使用ALTER DATABASE来将数据库设置为这些模式之一时,不需要为其指定一个ON或者OFF值——我们只需要使用该选项的名字即可。当一个数据库被设置为离线(OFFLINE)时,它会被正常地关闭并被标记为离线,数据的所有快照也都会被自动删除。当一个数据库在离线状态时它是不能被修改的。当一个数据库中有任何连接时,它是不能被设置为离线的。在这种情况下SQLServer是等待其他连接终止还是产生一条错误信息取决于指定的结束(TERMINATION)选项。
Y"]dy'UkI-?UN0下面的示例代码显示了如何将一个数据库的状态值设置为OFFLINE和如何确定一个数据库的状态:51Testing软件测试网~kG} Y/@`7w6n4sI8@[
ALTER DATABASE AdventureWorks SET OFFLINE;51Testing软件测试网QThJWb`
SELECT state_desc from sys.databases51Testing软件测试网P%YY0DHb
Lcys
WHERE name = 'AdventureWorks';
@$t~s5Hf-eL0一个数据库能够显式地设置为紧急(EMERGENCY)模式,并且在讨论一些不能设置的数据库状态值之后将会解释为什么我们可能希望那样做。
+M-prwy8Z0前面的查询所示,我们可以通过检查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软件测试网/p.Ca] MCe U
如果所有需要的资源包括日志文件都可获得,但是在恢复期间探测到了故障,数据库可能会被设置为置疑(SUSPECT)状态。这时我们可以通过查看sys.dataselect*fromsys.databaseswherename='oscartest'
Ak(}0t%?U#B n0 bases视图的state_desc列来确定数据库的状态值。当一个数据库处于置疑(SUSPECT)状态时它是完全不可用的,并且即使我们运行sp_helpdb,也无法看到该数据库。然而,我们可以查看一个置疑数据库的数据库属性(DATABASEPROPERTY)的值,并从sys.databases视图来查看其状态值。在很多情况下,可以通过将一个置疑的数据库设置到紧急(EMERGERCY)模式来使得该数据库能够进行只读操作。如果确实丢失了一个数据库的一个或多个日志文件,紧急模式允许我们在将数据复制到一个新的位置之后访问数据。当我们将一个数据库从恢复中断(RECOVERY_PENDING)模式转换到紧急模式时,SQL Server关闭该数据库,然后使用一个允许它跳过恢复过程的特殊的标志位重新启动该数据库。跳过恢复过程意味着会出现一些在逻辑上或物理上不一致的数据——丢失索引行、损坏的页面链接或不正确的元数据指针。我们虽然承认数据也许是不一致的,但是不管怎样还是希望在访问数据库的情况下,可以通过专门将数据库设置到紧急模式来读取数据。
8g[L2W;M0
GS
pC}0紧急模式修复51Testing软件测试网A#^c0md
我们可以在紧急模式下运行DBCC CHECKDB命令,并且当指定REPAIR_ALLOW_ DATA_LOSS选项时,SQL Server能够在数据库上进行一些专门的修复,这有可能使通常无法恢复的数据库变得在物理上一致,并且能够重新上线。这些修复应该作为我们最后的手段,在无法从备份中还原数据库时才考虑使用。51Testing软件测试网$JD*Ad%yJc
当数据库被设置为紧急模式时,该数据库被内部地设置为只读(READ_ONLY),日志被禁用了,并且对该数据库的访问也仅限于sysadmin角色的成员。然而,我们从sys.databases系统表中看到的数据库的属性不会反映这些限制。
:L[wsTo!qA0当数据库处于紧急模式并且运行带REPAIR_ALLOW_DATALOSS从句的DBCC CHECKDB时,会进行下面的操作:
%BA:m#\i"F0为了增加数据恢复的概率,DBCC CHECKDB会使用由于I/O或校验和(checksum)错误已经被标为无法访问的页面,就好像这些错误还没有发生一样。51Testing软件测试网S&z&@
rG.?gw kGR
n DBCC CHECKDB会尝试使用常规的基于日志的恢复技术来恢复数据库。
"P!i+Y JE sD8a*L\0n 如果数据库恢复没有成功,会重建事务日志。重建事务日志也许会导致事务一致性被破坏。
;qU\+D
x0如果DBCC CHECKDB命令成功了,那么这个数据库会处于物理上一致的状态,并且这个数据库的状态会被设置为ONLINE。然而,该数据库也许含有一个或更多事务的或逻辑的不连续处。这时我们可以考虑运行DBCC CHECKCONSTRAINTS来找出所有的业务逻辑方面的错误,并且马上备份该数据库。
-ySg,Jp%z'm8J,d0如果DBCC CHECKDB命令失败了,那么该数据库就无法修复了。51Testing软件测试网cLM:T5Q-QoUDS
在某些情况下,紧急模式是不可能的,特别是当与空间分配有关的一些元数据(数据库启动时需要这些数据时)丢失或损坏的时候。51Testing软件测试网#d5n+J(e9r#xD)J T
我们可以尝试将一个紧急模式下的数据库设置为在线(ONLINE)模式(例如,当丢失的文件已经重新可用时),SQL Server将会试图在该数据库上运行恢复。如果到在线(ONLINE)模式的转变无法完成,那么数据库或者停留在恢复中断(RECOVERY_ PENDING)状态,或者停留在置疑(SUSPECT)状态,就像我们首次启动SQL Server实例并尝试恢复数据库时一样。再次强调一下,我们可以通过将处于恢复中断(RECOVERY_PENDING)状态的数据库切换到紧急模式来使得数据能够被读取。51Testing软件测试网4jjW;by2Hu
在一台测试服务器上测试一个数据库的紧急状态值相对容易。我们可以使用三个单词的命令CREATE DATABASE TESTDB来创建一个简单的数据库,然后停止SQL Server实例并重新命名(或删除)日志文件。当我们重新启动该实例时,检查该新数据库的状态:51Testing软件测试网 Gdf*R4`~
h8p
SELECT name, database_id, user_access_desc, state_desc
;\UZ0qlNx0FROM sys.databases
$D!NS"p-rK_*]y
?0WHERE name = 'testdb';51Testing软件测试网]!z P/I}
state_desc列应该会显示RECOVERY_PENDING,这时我们可以将它切换到紧急(EMERGENCY)模式:
)s,@\8u0K*lv!Ga0ALTER DATABASE testdb SET EMERGENCY;51Testing软件测试网V*J5[9tm@6?(l+g
E
虽然这时并没有事务日志,但是数据库将允许读取数据。无论我们使用何种方式来尝试更新数据,都会收到下面的错误:
w8k6y-?U
W6JS0Msg 3908, Level 16, State 1, Line 151Testing软件测试网U'qKoa$i5L
Could not run BEGIN TRANSACTION in database 'testdb' because the database is in bypass
P&uP
DFD$GAG0recovery mode.
0ff"qtU/D0The statement has been terminated.
&l*J o)~-O$k'z3?%_p0如果将数据库的状态切换回在线(ONLINE),我们会收到一个指出无法进行恢复的错误,并且数据库将被重新设置为恢复中断(RECOVERY_PENDING)模式。前面提到过,在紧急模式下运行带repair选项的DBCC CHECKDB命令能够使可以修复的数据库重新上线。51Testing软件测试网l
|+f6u7YA
只读|读写51Testing软件测试网IK8Hlv`"hR{
这些选项描述了一个数据库的可更新性。这些选项是互斥的。一个数据库在默认情况下是读写的(READ_WRITE)。与用户访问选项一样,当使用ALTER DATABASE命令将一个数据库设置为这些模式之一时,我们不用指定ON或OFF值,只需使用该选项的名字即可。当该数据库处于读写模式时,任何有着合适权限的用户都能够执行数据修改操作。在只读模式,不能执行插入(INSERT)、更新(UPDATE)和删除(DELETE)操作。另外,因为当一个数据库处于只读模式时不能进行任何修改操作,所以数据库重新启动时不会在该数据库上运行自动恢复,并且所有的SELECT操作中都不需要获得任何锁。在只读模式下收缩数据库是不可能的。51Testing软件测试网1PP0k-]Tr
当存在任何到一个数据库的连接时,该数据库是不可能设置为只读模式的。SQL Server是等待其他连接结束还是产生一条错误信息,取决于指定的结束(TERMINATION)选项。
/dqxd.X0下面的代码显示了如果将一个数据库的可更新性设置为只读(READ_ONLY)及如何确定一个数据库的可更新性:51Testing软件测试网P8A"P2F7~Lev
ALTER DATABASE AdventureWorks SET READ_ONLY;51Testing软件测试网Y7I!?9_ia
SELECT name, is_read_only FROM sys.databases
5JI%}"q'K2iN.P0Tq0WHERE name = 'AdventureWorks';51Testing软件测试网V3Nd,F']!~^
当数据库启用了只读选项,is_read_only列将会返回1;否则对一个读写的数据库,它会返回0。51Testing软件测试网:M(gL(Ho D M/Mo
结束(Termination)选项
`{B/q.r'ij
w+B;v#^p0刚刚提到过当一个数据库正在使用或正在被不合格的用户使用时,有几个状态选项无法设置。这时我们可以在ALTER DATABASE命令中使用一个结束(termination)选项指定SQL Server如何来处理这种情况。我们可以指定SQL Server等待情况发生变化,或者产生一条错误信息,或者结束不合格用户的连接。51Testing软件测试网|K`.[%P6m-[
结束(termination)选项决定了SQL Server在以下情况中的行为:51Testing软件测试网UXKt oF3N8y*W
n 当我们尝试切换一个数据库到单用户(SINGLE_USER)模式,但该数据库有多于一个的当前连接时。
tVV8e#[0n 当我们尝试切换一个数据库到限制用户(RESTRICTED_USER)模式,但该数据库当前有不合格的用户连接时。51Testing软件测试网7L9U0z
C^!K
n 当我们尝试切换数据库到离线(OFFLINE)状态,但是尚有当前连接时。51Testing软件测试网1~KkUC7kL~
n 当我们尝试切换数据库到只读(READ_ONLY)状态,但是尚有当前连接时。
9jv#W1fZV LX0SQL Server在这些情形下的默认行为是无限期等待。下面的TERMINATION选项会改变这种行为:
}pU't$m,\;X0n ROLLBACK AFTER integer [SECONDS] 这个选项会使SQL Server先等待指定的秒数,然后中断不合格的连接。不完整的事务会被回滚。当切换到单用户(SINGLE_USER)模式时,除了发出ALTER DATABASE语句的连接,所有的连接都被当作不合格的连接。当切换到限制用户(RESTRICT_USER)模式时,不合格的连接不仅包括那些非db_owner固定数据库角色成员的连接,还包括那些非dbcreator且非sysadmin固定服务器角色成员的连接。51Testing软件测试网$TIjMi A
alterdatabaseoscartestsetoffLINEwithrollbackafter3051Testing软件测试网9vb*~cIw
n ROLLBACK IMMEDIATE 这个选项马上就中断不合格的连接。所有尚未完成的事务都会被回滚。要注意的是也许连接被马上中断,回滚却需要一些时间来完成。事务所有的工作都必须被撤销,所以对某些特定的操作,例如一个对数百万行数据进行更新的批处理操作,或者对一个大型索引的重建操作,我们可能需要等待很久。这里的不合格连接与前面所描述的不合格连接相同。
F
n.nbt xG0alterdatabaseoscartestsetonLINEwithrollbackimmediate
2M.hSjwQ/P0n NO_WAIT 该选项会使得SQL Server在尝试改变数据库状态之前检查连接,并且当某些连接存在时该选项会导致ALTER DATABASE语句失败。如果数据库被设置为SINGLE_USER模式,当存在任何其他连接时ALTER DATABASE语句都会失败。如果是切换到限制用户模式,当存在任何不合格用户的连接时ALTER DATABASE语句都会失败。
}PNfN0E*det0下面的命令将AdventureWorks数据库的用户访问选项切换到单用户(SINGLE_USER)模式,并且当存在任何其他到AdventureWorks数据库的连接时都会产生一条错误信息:
h,C6Y fE*K;f6|0ALTER DATABASE AdventureWorks SET SINGLE_VSER WITH NO_WAIT;
#K/h$o&JJi0游标(CURSOR)选项
G+`w0KO!h@u0游标选项控制着服务器端游标的行为,服务器端游标的定义使用下面的用来定义和操纵游标的T-SQL命令:DECLARE、OPEN、FETCH、CLOSE和DEALLOCATE。T-SQL游标在《Microsoft SQL Server 2005技术内幕:T-SQL程序设计》一书中有详细讨论。51Testing软件测试网w8yD-UV6~tn
n CURSOR_CLOSE_ON_COMMIT{ON|OFF} 如果该选项设置为ON,那么当一个事务被提交或被回滚时所有打开的游标都会被关闭(遵守SQL-92标准)。如果OFF(默认值)被指定,那么在事务提交后游标仍然保持开放。回滚一个事务会关闭除了被定义为INSENSITIVE或STATIC之外的所有游标。
%a&Br0sL\
y&v1vj0n CURSOR_DEFAULT {LOCAL|GLOBAL} 当这个选项被设置为LOCAL且游标在创建时没有被指定为GLOBAL时,任何游标的作用域都是创建它的本地批处理、存储过程或触发器。游标名称只在它的作用域内才有效。游标可以被批处理、存储过程或触发器,或者一个存储过程的输出参数中的本地游标变量所引用。当这个选项被设置为GLOBAL且游标在创建时没有被指定为LOCAL时,游标的作用域就是整个连接。游标的名称能够被任何使用该连接执行的存储过程或批处理所引用。51Testing软件测试网,ITFY|