说到Sql Server2000的事务日志恐怕稍微对数据库技术有些了解的人都会知道,事务日志是储存用户对Sql Server 2000的数据操作。我们首先来看一下Sql Server 2000的事务日志逻辑架构以及它能够干些什么:
事务日志逻辑构架
Microsoft® SQL Server™ 2000 事务日志按逻辑运行,就好象是一串连续的日志记录一样。每条日志记录由一个日志序号 (LSN) 标识。每条新日志记录用一个比以前记录的 LSN 更高的 LSN 写入日志的逻辑末端。
数据修改的日志记录或者记录所执行的逻辑操作,或者记录已修改数据的前像和后像。前像是操作执行前的数据复本;后像是操作执行后的数据复本。操作的恢复步骤取决于日志记录的类型:
- 记录的逻辑操作:
- 若要前滚逻辑操作,请再次执行它。
- 若要回滚逻辑操作,请执行相反的逻辑操作。
- 记录的前像和后像:
- 若要前滚操作,请应用后像。
- 若要回滚操作,请应用前像。
事务日志内记录许多类型的操作,包括:
- 每个事务的起点和终点。
- 每次数据修改(插入、更新或删除)。这包括系统存储过程或数据定义语言 (DDL) 语句对系统表所做的更改。
- 每次分配或释放扩展盘区。
- 表或索引的创建或除去。
日志记录按创建时的串行序列存储。每条日志记录由所属的事务的 ID 标记。对于每个事务,使用可提高事务回滚速度的向后指针,在链内单向链接与事务相关联的所有日志记录。
回滚语句也将记入日志。每个事务都在事务日志上保留空间,以确保在遇到错误时有足够的日志空间支持回滚操作。当事务完成后,将释放该保留空间。保留的空间量取决于在事务中执行的操作,但通常等于用于记录每项操作的空间量。
以上Sql Server2000联机丛书中对事务日志文件的描述,如果大家还想要知道更多有关事务日志的信息,请参考联机丛书,再来看看事务日志的作用:
事务恢复
每个 Microsoft® SQL Server™ 2000 数据库都有一个事务日志记录数据库内的数据修改。日志记录每个事务的开始和结束并将每个修改与一个事务相关联。SQL Server 实例在日志中存储足够的信息以恢复(前滚)或撤消(回滚)构成事务的数据修改。日志中的每条记录都由一个唯一的日志序号 (LSN) 标识。事务的所有日志记录都链接在一起。
SQL Server 实例在事务日志中记录多种不同类型的信息。SQL Server 2000 实例主要将所执行的逻辑操作记入日志。重新应用操作将前滚修改,反向执行逻辑操作将回滚修改。
每个 SQL Server 实例都控制将修改从其数据缓冲区写入磁盘的时间。SQL Server 实例可以将修改在缓冲区内高速缓存一段时间以优化磁盘写入。包含尚未写入磁盘的修改的缓冲区页称为。将脏缓冲区页写入磁盘称为刷新页。对修改进行高速缓存时,务必注意确保在将相应的日志映像写入日志文件之前没有刷新任何数据修改。否则将产生不能在需要时进行回滚的修改。为确保能恢复所有修改,SQL Server 实例使用预写日志,这意味着所有日志映像都在相应的数据修改前写入磁盘。
提交操作将事务的所有日志记录强行写入日志文件,以使事务可以完全恢复,即使服务器已经关闭。只要所有日志记录都已刷新到磁盘,提交操作便不必将所有修改的数据页都强行刷新到磁盘。系统恢复可以只使用日志记录前滚或回滚事务。
SQL Server 实例定期确保刷新所有脏日志和数据页。这称为检查点。检查点减少了重新启动 SQL Server 实例时恢复所需的时间和资源。
回滚个别事务
如果在事务执行过程中出现任何错误,SQL Server 实例将使用日志文件中的信息回滚事务。这个回滚不影响同时在数据库内工作的任何其它用户的工作。通常情况下,错误被返回给应用程序,如果错误表明事务可能有问题,则应用程序发出 ROLLBACK 语句。一些错误(如 1205 号死锁错误)会自动回滚事务。如果在事务活动时由于任何原因中断了客户端和SQL Server 实例之间的通讯,SQL Server 实例将在收到网络或操作系统发出的中断通知时自动回滚事务。如果客户端应用程序终止,客户端计算机关闭或重新启动,或者如果客户端网络连接中断,可能会发生这种情况。在所有这些错误情况下,将回滚任何未完成的事务以保护数据库的完整性。
启动时恢复所有未完成的事务
SQL Server 实例有时可能停止处理(例如,如果操作员在用户正与数据库连接并进行工作时重新启动服务器)。这可能造成两个问题:
- 可能有未知数目的 SQL Server 事务在实例停止时只部分完成。需要回滚这些未完成的事务。
- 可能有未知数目的数据修改记录在 SQL Server 数据库日志文件中,但被修改的相应的数据页在服务器停止前没有刷新到数据文件。必须前滚任何已提交的修改。
每次启动 SQL Server 实例时,它都必须找出是否存在这些情况并加以解决。实例中的每个 SQL Server 数据库都采用下列步骤:
- 与最小恢复 LSN 一起从数据库引导块读取上一个检查点的 LSN。
- 从事务日志的最小恢复 LSN 扫描到日志的末端。通过重做日志记录中记录的逻辑操作前滚所有提交的脏页。
- SQL Server 实例然后通过反向应用日志记录中记录的逻辑操作,向后扫描日志文件以回滚所有未完成的事务。
除非用户指定 NORECOVERY 选项,否则 RESTORE 语句也使用这种恢复类型。还原数据库序列、差异备份或日志备份以将数据库恢复到某个故障点时,在所有 RESTORE 语句上指定 NORECOVERY,但还原上次日志备份时除外。还原序列中的最后一次备份时,RESTORE 语句还必须确保回滚所有未完成的事务。在该 RESTORE 语句上指定 RECOVERY 选项,在这种情况下,该语句使用与启动恢复进程相同的逻辑回滚在最后一个日志的结尾处仍标记为未完成的所有事务。
看到了吧,就和上面的Sql Server2000联机丛书中的文章说得一样事务日志的主要作用是用来进行数据恢复,它能够保证在数据库出问题的情况下把数据还原到最近一次的更新状态。好了以上是事务日志的一个优点,但是如果事务日志运用不好,也会给数据库性能带来负面的影响,现在我们来看一些联机丛书上没有的东西。
首先,事务日志文件是需要存储空间的,而且它和数据库文件一样,都是定期增长的,并且要设置增长值,这里就要说一下增长值和为事务日志文件分配空间的问题,在分配事务日志文件的时候,你一定要估算出数据库更新的频率,并且给定一个比较合适的空间,如果没有办法估算,那么这里有一个经验,就是在存储空间足够的情况下应该给定尽可能大的空间,这样做的主要目的是减少事务日志分页的频率,要知道如果给定的空间不够,那么事务日志就会增长,增量取决于你的设置,如果不让它增长,那么在事务日志空间用尽之后数据库就会报错,并且无法访问数据库;作为一个数据库管理人员应当知道,事务日志的分页将要耗用一定的CPU和I/O资源,数据分页往往发生在你对数据进行操作的时候,如果事务日志能够成功增长,那么数据访问就不会受到影响,反之,数据访问就会终止。
在什么情况下数据库分页会失败呢?造成这种结果的原因有很多,但基本上都和磁盘子系统有关,如果你没有一个健壮的磁盘子系统,那么在设置增量的时候就要非常小心,打个比方,如果你使用10%的增量,那么当事务日志为100MB的时候,增加值仅为1MB,可如果数据库是10G呢?增量就是1G,这就要问问你的磁盘系统是否吃得消了,如果吃不消,那么在数据库日志中将会产生大量的分页失败信息,最糟糕的是,Sql Server2000在一次分页失败之后还会在间隔一段时间之后继续重试,很容易造成连续失败,如果你维护的数据库是一个访问量比较大的网站的后台数据库,那结果将是用户访问网站的速度明显变慢,数据库的当前进程中出现大量的锁定和阻塞进程,这种情况会一直继续下去,直到事务日志文件增长成功。
在上诉的情况下,采用按照MB增长数据事务日志的方法就要好得多,限制一个比较合适的值,普通IDE硬盘20MB,SCSI硬盘50MB左右,这样就能够保证事务日志的增长和数据库的访问不互相冲突,从而取得良好的数据库性能。
同时,当事务日志占用的空间过大的时候,就要对事务日志进行清理了,这里要说明的是,在清理事务日志的时候,是没有办法反问相应的数据库的,具体操作方法如下:在企业管理器中选择要清理事务日志的数据库,点击分离数据库,在清理掉连接之后,点击确定,数据库就从企业管理器中消失了,然后找到事务日志文件的物理位置,进行删除,在回到企业管理器中附加数据库,这时Sql Server2000会提示你重新建立一个事务日志文件,这样一来数据库事务日志文件就被清除掉了。不过应当注意的是,任何敏感操作之前,都应当备份数据库。
还有一种做法是收缩事务日志,具体方法是使用DBCC SHRINKFILE语句,关于这个语句的使用请大家参看Sql Server2000联机丛书,但是无论你采用那种方法,都会造成数据库短暂的无法访问。
这里,我们只是针对事务日志与数据库性能影响进行了简单的讨论,当然,关于数据库和事务日志文件的部署还有很深的学问,而且,针对不同的数据库还要采用不同的优化方式,这里只作简述,以供大家解决常见问题之用。