在SQL Server中,利用日志的WAL來保證關系數據庫的持久性,但由於硬盤的特性,不可能使得每生成一條日志,就直接向磁盤寫一次,因此日志會被緩存起來,到一定數據量才會寫入磁盤。這部分已經生成的,卻沒有寫入磁盤的日志,就是所謂的In-Flight日志。
在SQL Server中,In-Flight的日志的大小取決於兩個因素,根據Paul Randal的說法,In-Flight日志不能超過60K,因此In-Flight的日志最大是60K,此外,如果In-Flight日志沒有到60K,如果發生了Commit或Rollback,那么直接會寫入磁盤。因此日志最小為512字節,最大為60K,以512字節為單位進行增長。下面我們來看一個例子。
我們首先建立一個簡單的表,循環向其中插入10W的數據,該語句會生成大量的日志,如代碼清單1所示:
BEGIN TRAN DECLARE @i INTEGER SET @i = 0 WHILE ( @i < 100000 ) BEGIN INSERT INTO Number VALUES ( @i ) SET @i = @i + 1 END CHECKPOINT COMMIT
代碼清單1.生成大量日志的語句
數據庫我以5M日志為起點,以5M遞增,上面的語句導致日志自動增長,如圖1所示。
圖1.對應的6次日志增長
我們再來觀察SQL Server進程對於日志文件的操作,如圖2所示:
圖2.SQL Server進程對於日志文件的寫
圖2中的圖片我只截取了一小部分,但是可以看到沒有超過60K的log block,只有在日志文件填零增長時,才出現5M的塊。因此我對於微軟亞太數據庫支持組的博文:http://blogs.msdn.com/b/apgcdsd/archive/2013/06/17/sql-server-log-write.aspx中說到會出現超過60K的log write產生一些疑問,畢竟日志填零增長和logWrite不是一回事。
因此,得知這一點之后,對於日志所在的LUN,分配單元64K應該是對於性能來說最優的。