Log--事务日志

由于日志是顺序写入,而修改数据分散在数据库各个页面,属于随机写入,而磁盘顺序写入速度远高于随机写入,因此主流数据库都采用预写日志的方式来确保数据完整性

1.日志记录的是数据的变化而不是引发数据的操作
2.每条记录都有唯一的编号:LSN,并且记录了它属于的事务号。
3.日志记录的行数和实际修改的数据量有关
4.日志记录了事务发生的时间,但不记录发起者的程序名称和客户端信息
5.日志记录数据修改前和修改后的数据


虚拟日志文件的状态:
1.活动(ACTIVE),在VLF上有任一条LSN是活动的
2.可恢复(RECOVERABLE),VLF上的LSN不活动的,但尚未被截断(truncated),该片区域的日志将可能被用于备份/镜像/复制等
3.可重用(REUSED),VLF上无活动的LSN,且已经被截断,该空间可以被再次使用
4.未使用(UNUSED),VLF是不活动的,且空间从未被使用过

(PS: DBCC LOGINFO 中Status=0表示可重用或未使用,Status=2表示活动或可恢复)


数据增长大小与VLF增长数量
1-64M:4个VLF
64M-1G:8个VLF
1G以上:16个VLF

截断(Truncated)是将VLF从Recoberable 状态转变成 reused 状态

In sample recovery model,Every checkpiont will check is there any vlf could be truncated, truncated the recoverable lsn and move the min lsn


在简单恢复模式下,日志仅用于事务回滚和数据库崩溃时的恢复。


在完整恢复模式下,只有经过日志备份过的日志才可以被截断

从完整恢复模式切换到大容量日志恢复模式并不会破坏日志链条,因此可以在可能产生大量日志的操作(SELECT INTO/INSERT INTO SELECT /REBUILD INDEX/CREATE INDEX)等之前将恢复模式转换成大容量日志模式,操作结束后在换回完整模式,这样不会破坏现在的备份策略同时有效避免此操作生成大量日志和日志文件急速增长


引发Log 读的操作

1. Transcation rollback
2. crash recovery
3. create a database snapshot
4. running dbcc checkdb
5. transaction log backup
6. database full backup or differential backup
7. transcation replication
8. change data capture
9. database mirroring
10. a checkpoint in the simple recovery mode
11. processing a DML trigger(on sql server 2000)
12. manually looking in the log(dbcc log or fn_log)


由于单个事务会产生多天事务日志记录,如果每条事务日志记录都写一次磁盘,会造成严重的瓶颈,并且严重延迟事务执行时间,因此SQL SERVER 将事务日志先存放在Log Buffer中,在满足以下条件时将日志记录写入磁盘:
1>事务提交或回滚
2>有超过60KB的日志没有刷新写入磁盘

在log flush时,会将log buffer中所有日志记录都写入磁盘,无论该日志所属的事务是否提交。

由于每个事务提交或回滚都会造成一次log flush,每次事务提交需等待日志被写入磁盘才算成功,因此日志写入磁盘延迟直接影响事务的执行时间。

SQL SERVER限制log flush的并发数最大为32,因此,在同一时间点,只能有32个事务被提交


解决日志写等待的问题
1>减少日志的写入量
2>提高事务日志的写入速度


提高事务日志的写入速度
1>如果日志所在磁盘较慢,可以将日志移动到较快的磁盘上
2>如果日志所在磁盘已经足够快的情况下,有大量并发的小事务操作,可拆分为多个数据库来解决

原文地址:https://www.cnblogs.com/TeyGao/p/3522937.html