当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的。你只要确保每个数据库都有正确的备份。当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时。这系列文章会告诉你每个DBA应该知道的具体细节。
?
这篇文章会列出导致事务日志过度增长的常见的问题和错误管理形式,包括:
?
在完整恢复模式里,没有进行日志备份
?
进行索引维护
?
长时间运行或未提交的事务阻止事务日志里空间重用
?
当然,如果增长没检查,日志文件会扩展直到吞没所有可用磁盘空间或日志文件的最大大小,在这个时候你会收到该死的9002错误(事务日志已满),数据库会变成只读。这篇文章会谈到处理日志不断增长和9002错误的正确方法,还会解释下通常建议截断或收缩事务日志为什么是危险的。
?
最后,我们会谈下保证你日志文件是平稳和可预见增长的措施,还有日志碎片的最小化问题。在忙碌的数据库里,大型的事务日志会是一个简单的生活事实,如果管理妥当的话,这并不是件坏事,即使大部分时间日志文件空间不可用。
?
日志大小和增长
任何时候日志文件需要增长,额外的空间被分配,这个空间平均分到VLS里,基于被分配空间数。
?
例如,日志文件默认会有2MB的初始大小,10%的自动增长率(来自model数据库的配置)。这就是说,日志文件开始至少会很小的增长,因此会有大量的小VLF。
?
当我们在很大的块上分配额外空间时,例如当一次操作初始16GB的大小,结果事务日志会有很小数量的VLF。
?
太高数量的小VLF,这样的情况称为日志文件碎片,会影响到性能,尤其在故障恢复,还原和备份,特别是日志备份。换句话说,它会影响读取日志文件的操作性能。我们会在第8篇详细讨论这个问题。
?
事务日志VLF——太多还是太少?
?
SQL Server MVP的Kimberly Tripp在他的文章里讨论了VLF大小的影响,并提供了如何恰当管理VLF大小的指导——事务日志VLF—太多还是太少?
?
相反,如果日志文件只有几个很大的VLF,我们有长时间占用大块日志的风险。每个VLF都有很大数量的日志记录,SQL Server不能截断VLF直到它没有包含活动日志。这个情况下截断会因某些原因延迟(在缺少日志空间重用部分会详细谈到),这会导致日志的快速增长。例如,我们假设每个VLF是1GB大小且日志满了。你进行了一次日志备份,但是所有的VLF包含活动日志的一部分,SQL Server不能截断日志。它没有别的选择只能增加更多VLF,如果日志的增长率设置为同等大小,那么日志增长会很快,直到有VLF变成可截断。
?
因此,正确设置日志初始大小非常重要,那它的增长才会是合适的大小步骤,最小化日志碎片也避免了过快增长。
?
正确设置初始大小且可控制它的增长的第2个原因是:对于日志文件,每个增长是相对昂贵的操作。数据和日志文件增长超时是正常的。SQL Server可以优化增加新数据文件和扩展现有数据文件的过程,通过即时文件初始化(instant file initialization)(在SQL Server 2005引入,允许在磁盘上分配空间给数据文件,而不需要进行填零)。遗憾的是,对于日志文件是不一样的,对于日志文件创建或增长的空间分配,还是需要初始化且填零。
?
为什么事务日志不能使用即时初始化?
?
进一步关注事务日志填零,看下Paul Randal的文章:http://sqlskills.com/BLOGS/PAUL/post/Search-Engine-QA-24-Why-cant-the-transaction-log-use-instant-initialization.aspx
?
事务日志不断增长的诊断
?
如果你经历事务日志的不可控增长,它由于要么是活动日志频率太高,要么是有因素阻止日志文件里的空间重用,或者两者都有。
?
如果增长的主要原因是活动日志过多,你要检查下是否可以避免这个活动,例如调整处理大容量数据和索引维护的数据库模式,这样的话这些操作不会完整记录(例如针对这些操作使用大容量日志恢复模式)。但是,如果日志备份里包含有任何的最小化日志操作,大容量操作会立即阻止数据库到时间点的恢复(可以阅读下第6篇文章来获得更多详细信息)。如果这是不可接受的,你必须直接接受大日志的事实,根据具体情况计划它的增长和管理(例如日志备份频率),在接下来的妥当的日志管理会介绍。
?
如果增长原因是缺少日志空间的重用,你要找出什么阻止这个重用并采取措施来修正这个问题。
?
日志过度增长:索引维护操作
?
索引维护操作是个很常见的导致事务日志使用率过度和增长的原因,尤其数据库运行在完整恢复模式里。进行索引维护需要日志空间量取决于下列因素:
?
重建还是重组——通常索引重建在日志里会使用更多的空间
?
恢复模式——如果时间点恢复的风险已理解且可接受的,那么索引重建可以临时通过切换到大容量恢复模式里的最小化日志。但索引重组始终是完整记录的。
?
索引重建
?
当重建索引时,不管在线还是离线,使用ALTER INDEX REBUILD,或是已经废弃的SQL Server 2000里的DBCC DBREINDEX,SQL Server新创建一个索引的副本,然后一旦重建完整,删除老的副本(这是为什么你至少需要数据文件里索引大小一样的可用空间)
?
日志记录和在线索引重建
?
在SQL Server 2008和后续版本,在线索引重建是完整日志操作,在SQL Server 2005里是最小化日志。因此,在后续SQL Server版本上进行这样的操作本质上需要更多的事务日志空间,可以看下:https://support.microsoft.com/zh-cn/kb/2407439 还有Kalen Delaney的日志,对于完整和大容量日志2个恢复模式,验证下在在线和离线索引重建期间的日志记录。
?
在完整恢复模式里,索引重建可以是非常占资源的操作,需要事务日志里的很多空间。在简单或大容量日志恢复模式里,重建索引是最小化日志操作,这意味着只有分配被记录,实际的页并没改变,因此通过这个操作减少了日志空间量。
?
如果你切换到简单模式进行索引重建,LSN链会立即中断。你只能恢复你的数据库到刚才事务日志备份里的包含的时间点。为了重新开始日志链,你需要切换回完整恢复模式并立即进行一次完整或差异数据库备份。
?
如果你切换到大容量日志模式(看下第6篇),LSN链还是连续的,但还会影响到进行时间点的恢复,因为包含最小化日志操作的日志备份不能用来恢复到时间点。如果能恢复到时间点的要求是至高无上的,那么索引重建或任何最小化日志操作不要使用大容量日志恢复模式。除非在数据库里没有同时发生的用户活动,你可以使用。不然的话,在可能的情况下考虑在完整恢复模式里进行索引重建。
?
如果使用的是大容量日志模式,尽可能使时间点恢复的时间最小,这样可以最小化暴露数据丢失风险。为了做到这一