SQL Server数据库引擎在内部将每一物理日志文件分成多个虚拟日志文件,这样日志管理系统可以轻松的跟踪那些部分是可以被重用的。事务日志文件根据下面的公式决定生成多少个VLFs,不管是自动增长还是手动增长: Up to 1MB
2 VLFs, each roughly 1/2 of the total size 1MB to 64MB
4 VLFs, each roughly 1/4 of the total size 64MB to 1GB
8 VLFs, each roughly 1/8 of the total size More than 1GB
16 VLFs, each roughly 1/16 of the total size
举个例子,如果创建一个8GB的事务日志文件,那么会得到16个VLF,每个大约512MB.如果日志一次性增长4GB,那么我们会得到另外16个VLF,每个大约256MB,整个文件具有32个VLF.
一般最好的做法是设置日志的自动增长而不是默认的10%,这样你可以更好控制日志由于zero-initializing操作导致的暂停。比方说,你创建一个256MB的事务日志,并设置自动增长到32MB,然后将日志增长到16GB的稳态大小。根据上述公式,这将导致你的交易记录有4000多的VLF。
这许多的VLF很可能会对需要事务日志的操作(如崩溃恢复,清除日志,日志备份,事务复制,数据库恢复)产生性能问题。这种情况被称为有VLF碎片。一般来说任何数量的VLF超过一千元左右将是有问题的,需要加以解决(我曾经听说过的最多的是154万的VLF在超过1TB的大小事务日志!)。
太多的VLFs可能会导致一些操作在处理日志的时候遇到性能问题(比如崩溃恢复,清除日志,日志备份,事务复制,数据库恢复)。这种情况被称为VLF碎片。一般来说超过1000的VLF是有问题的,需要加以解决(我曾经听说过的1TB的事务日志文件有超过154W的VLF).
查询VLFs的数量可以使用undocumented(绝对安全)的DBCC LOGINFO命令。输出的行数就是VLF在事务日志中的数量。如果你觉得VLF太多,可以用下面的方式减少:
1.清除日志(比如通过日志备份等等截断日志)
2.手动收缩日志文件
3.重复步骤1和2,直到日志达到小尺寸(在繁忙的生产系统可能会比较麻烦)
4.手动将日志增长到期望的大小,比如8GB这样VLFS单个VLF不超过0.5GB.
你可以阅读更多有关VLF碎片问题并且如何解决:
· Microsoft KB article that advises reducing VLF numbers
· Can log files growth affect DML?
· 8 steps to better transaction log throughput Tempdb