SQL Server 2008存储体系结构(二)

2014-11-24 15:47:52 · 作者: · 浏览: 4
L Server配置事务日志的内部结构时,它会尽量把虚拟事务日志的数量控制到最少。如果日志配置为自动增长,应将增量设置得较大些,这样可避免会导致创建多个小虚拟日志的微量重复性增长。
事务
  所有数据修改都在事务中发生并记录在事务日志中,事务是一个可控的完整数据操作单元,因此事务中的所有修改要么发生,要么都不发生。SQL Server有三种执行的事务方式:隐士事务、显示事务和自动提交事务。隐式事务和自动提交事务是互斥的。
  自动提交事务:默认情况下,SQL Server链接使用自动提交事务,任何单独执行或批量执行的INSERT,UPDATE或DELTE语句都将被自动应用于数据库
UPDATE CheckingAccount
SET Balance=Balance+500
WHERE AccountID='123456789-CK'
UPDATE SavingAccount
SET Balance=Balance-500
WHERE AccountID='123456789-SV'
  这个例子中的两个操作都是事务,在低通提交模式下,他们将彼此独立地应用到数据库。如果第一个成功,第二个失败,银行损失500元,没有办法回滚更改;同样,第一个失败,第二个成功,客户失去500,为了避免依赖性数据更改错误引起的数据问题,应使用事务。
  隐士事务:结构化查询语言的ANSI标准规定除非有显式提交,否则不能更改数据。SQL Server通过一个名为IMPLICIT_TRANSACTIONS的连接来支持这项规定。当IMPLICIT_TRANSACTIONS设置为ON时,任何数据修改都将隐式开始一个事务,但不会关闭事务。该事务将保持开启状态,直至被显示提交或回滚,如:
www.2cto.com
SET IMPLICIT_TRANSACTIONS ON
BEGIN TRY
UPDATE CheckingAccount
SET Balance=Balance+500
WHERE AccountID='123456789-CK'
UPDATE SavingAccount
SET Balance=Balance-500
WHERE AccountID='123456789-SV'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
RAISEERROR('Account Transfer Failed',14,1)
END CATCH
  此例中,如果在修改数据时有任何错误发生,则将调用CATCH块来回滚事务。如果没有发生错误,则提交。
  显式事务:显示事务需要用BEGIN TRANSACTION来开始事务,用显示的COMMIT TRANSACTION或者ROLLBACK TRANSACTION来关闭事务:
BEGIN TRY
www.2cto.com
BEGIN TRANSACTION
UPDATE CheckingAccount
SET Balance=Balance+500
WHERE AccountID='123456789-CK'
UPDATE SavingAccount
SET Balance=Balance-500
WHERE AccountID='123456789-SV'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
RAISEERROR('Account Transfer Failed',14,1)
END CATCH
记录事务
  直接对数据库中的数据文件进行修改是不可能的,当一个应用程序发送修改时,SQL Server会在缓冲区缓存中查找包含该数据的数据页,或者在插入的情况下,查找有足够空间容纳数据的页。如果该页不再缓存中,SQL Server会从磁盘读取页,然后将它放置在缓存中,并且在缓存中进行修改。同时,SQL Server把数据修改记录在磁盘的事务日志中。当页最初读入缓存时,他是一个干净的页,一旦事务修改了页,它就变脏了。
  SQL Server会定期发出一个名为CHECKPOINT的事件,当这个事件发出时,缓存中的所有脏页都被写入到磁盘上的数据文件中。检查点的目的是为了减少存储在缓存中的页,最小化SQL Server从失败中恢复的时间:
www.2cto.com
BEGIN TRANSACTION 1
UPDATE...
INSERT...
UPDATE...
COMMIT TRANSACTION 1
BEGIN TRANSACTION 2
INSERT...
UPDATE...
***CHECKPINT***
BEGIN TRANSACTION 3
DELETE...
UPDATE...
COMMIT TRANSACTION 3
BEGIN TRANSACTION 4
UPDATE...
***Server Power failure***
  当SQL Server在电力故障重启时,它会读取事务日志查找最后一次发出的CHECKPOINT。从最后一个CHECKPOINT到日志开始的所有内容都已经安全写入磁盘。但是,CHECKPOINT之后的数据修改只记录在事务日志中。因为事务3成功提交,调用应用程序会被通知成功,并且希望看到所有提交的修改,因此,SQL Server会回滚整个事务3,将更改提交到磁盘。事务4也没有成功提交,也没有被写入磁盘,事务4的诗句修改将从事务日志中删除。
事务日志物理特征 www.2cto.com
  事务日志是一种串行化的、顺序的、回绕的日志。当把数据修改写入日志时,他们会得到一个日志序列号LSN,由于事务日志记录越来越多,最终会被填满。如果已将事务日志设置为自动增长,那么SQL Server将分配额外的文件空间已容纳记录日志,直到达到事务日志的最大容量或者磁盘被填满。如果事务日志被填满,那么数据库将不会允许数据修改。
  为了避免事务日志被填满,必须定期清理日志中的旧事务,首选的清除方式是备份事务日志。默认情况下,一旦事务日志成功备份,SQL Server会清楚事务日志的不活动部分,这个不活动的部分包括最早打开的LSN到最新的LSN。可以手动清除不活动的部分,但是不推荐,因为这样会删除上次数据库备份以来的所有数据修改记录。
  因此,事务日志是一个回绕文件,一旦到达了物理日志的末尾,SQL Server将绕回并在物理日志的开头继续写当前逻辑日志。