SQL Server中STATISTICS IO物理讀和邏輯讀的誤區


SQL Server中STATISTICS IO物理讀和邏輯讀的誤區

 

大家知道,SQL Server中可以利用下面命令查看某個語句讀寫IO的情況

SET STATISTICS IO ON

那么這個命令的結果顯示的物理讀、邏輯讀的IO單位大小是多少,比如結果顯示有

物理讀取 1

是代表 對硬盤做了1次物理IO嗎?


在回答這個問題之前,需要先普及幾個常識

在一般默認情況下

Windows的內存分頁大小單位是4KB

數據庫的最小讀寫單位是 8K頁面

Windows操作系統的NTFS文件系統最小讀寫單位(分配單元/簇)是 4KB

機械硬盤的邏輯扇區:512字節,整個硬盤暴露給操作系統的扇區,一般跟物理扇區的大小是一樣的,保持對齊,操作系統將分配單元的讀寫請求划分為多個512字節大小,為了適應邏輯扇區的大小

機械硬盤的物理扇區:512字節 ,舊磁盤是512字節,也就是硬盤里面每個磁碟真正的讀寫扇區,新磁盤(固態硬盤的物理扇區和邏輯扇區都是為了兼容機械硬盤模擬出來的,固態硬盤實際用的是塊/頁)是4KB

機械硬盤的原生512 native對齊:邏輯扇區、物理扇區的大小都是一樣的,也叫512n,如果邏輯扇區和物理扇區是不一樣的,那么就是512e,如果是固態硬盤的native對齊就是4Kn

高級格式化:操作系統對文件系統盤符進行格式化,規划每分配單元/簇大小,默認4KB

低級格式化:存儲廠家對物理存儲硬件做的低級格式化,例如機械硬盤,規划每扇區大小,通常512字節

 

前提:本文闡述的所有場景都是針對《機械硬盤的原生512 native對齊》的前提下,並且是非虛擬化環境下,虛擬化環境會多了一層VMFS bloc更加復雜,敬請注意!

 

為什么存在磁盤塊/簇/分配單元?

讀取方便:由於扇區的數量比較小,數目眾多在尋址時比較困難,所以操作系統就將相鄰的扇區組合在一起,形成一個塊,再對塊進行整體的操作,

分離對底層的依賴,操作系統忽略對底層物理存儲結構的設計,通過虛擬出來磁盤塊的概念,文件系統就是操作系統的一部分,所以文件系統操作文件的最小單位是塊/簇/分配單元

這個磁盤塊在Linux的ext4文件系統中稱為block,在Windows的NTFS文件系統中稱為分配單元或簇

 

什么是內存分頁?

操作系統經常與內存和硬盤這兩種存儲設備進行通信,類似於“塊”的概念,都需要一種虛擬的基本單位。所以,與內存操作,是虛擬一個頁的概念來作為最小單位。與硬盤打交道,就是以塊為最小單位

固態硬盤因為沒有扇區概念,用的是塊/頁,一個塊/頁一般是4KB,so固態硬盤暫且不討論

 

先說結論,實際上STATISTICS IO 中物理讀和邏輯讀的統計對象自始至終都是數據庫8K頁面,比如,邏輯讀1次, 物理讀1次,實際上都是按8KB頁為單位,是SQL Server這個軟件的統計方式

這樣就會造成誤解,產生疑問

如果物理讀為1次,那么數據庫對磁盤是做了一次讀寫操作一次IO,對嗎?

如果邏輯讀為1次,那么數據庫在內存中是讀寫了一個內存頁一次IO,對嗎?

 

實際情況是怎樣的呢?

對於物理讀情況

SQL Server是運行在Windows系統上的一個軟件,那么這個軟件在文件系統上存儲數據依然按照NTFS文件系統的規則,存儲一個8K的頁面需要占用2個分配單元

可以用winhex這個軟件,按8K大小查看數據庫的mdf文件可以查看到完整的一個數據庫頁面數據

對於文件系統,讀寫一個數據庫8KB頁面需要讀寫2個分配單元 也就是2個文件系統IO

在機械硬盤里面,文件系統的一個4KB分配單元寫入到機械硬盤里,需要讀寫8個扇區,也就是8個硬盤IO,而1個數據庫8KB頁面寫入到機械硬盤里,就需要讀寫16個扇區,也就是實際寫入一個數據庫頁面需要16個硬盤IO

然后這里會出現一些問題,如果系統故障或硬件故障,就有可能出現一個數據庫頁面寫入存儲硬件不完整情況,比如16個硬盤IO才能寫入完整一個8KB頁面,而如果在寫入第10個IO的時候發生系統崩潰或硬件崩潰,只寫入了5KB頁面數據到硬盤,這時候數據庫數據就已經不完整了,然后各家數據庫廠商才開發【頁面寫入完整性檢測機制】,例如

MySQL InnoDB的Double Write機制(innodb_doublewrite = 1) + page checksum

MSSQL的PAGE校驗機制

注意:即使是用固態硬盤,也請不要關閉頁面完整性檢測功能!

只有在數據庫頁面、文件系統分配單元、機械硬盤扇區的大小一致的情況下

就是說,數據庫文件系統存儲設備的最小讀寫單位大小一樣的情況下,也就是所謂的【對齊】,更嚴謹的應該是數據庫、文件系統、(存儲設備的邏輯扇區、存儲設備的物理扇區,512n或4Kn)的最小讀寫單位大小一樣

才能關閉頁面完整性檢測功能,這個時候可以獲得最大性能

某些文件系統、存儲設備所謂的聲稱支持【原子寫】,請各位擦亮眼睛^_^,檢查是否真的完整支持,對於某些情況,確實是支持真正原子寫,例如

1、數據庫使用裸設備,這樣就不需要文件系統

2、以寶存PCIE閃存為例子,其Nand Flash的最小寫單位是page,目前Nand Flash 的page大小是32kb,這個基本上都是大於大部分數據庫通用的block size或page size,32kb可以存放4個MSSQL頁面(非廣告)

 


對於邏輯讀情況

Windows的內存分頁大小單位是4KB,一個數據庫頁面8KB,那么讀寫一個內存中的數據庫頁面實際上需要讀寫2個內存分頁

在內存里,讀寫一個數據庫8KB頁面需要讀寫2個內存分頁, 也就是2個內存IO

然后內存中8KB數據庫頁跟文件系統中的8KB數據庫頁是一一對應的,不然的話,利用B+樹索引結構和二分查找法查找數據也無從談起


總結

對於文件系統,讀寫一個數據庫8KB頁面需要讀寫2個分配單元 也就是2個文件系統IO

對於機械硬盤,讀寫一個數據庫8KB頁面需要讀寫16個硬盤扇區 也就是16個硬盤IO

對於內存,讀寫一個數據庫8KB頁面需要讀寫2個內存分頁 也就是2個內存IO

 


SQL Server只是跑在Windows操作系統上的一個軟件,它無法知道也不需知道它所在文件系統的最小讀寫單位,也無法知道也不需知道存儲設備的最小讀寫單位,

實際上操作系統從文件系統中讀取8KB頁面數據喂給數據庫,數據庫收到之后STATISTICS IO 就統計物理讀為 1,至於邏輯讀也是同理

最最后,放一張圖,做的比較丑

 

 

 

參考文章
http://www.dostor.com/article/111637957.html
https://blog.csdn.net/qq_34228570/article/details/80209748

 

 

本文版權歸作者所有,未經作者同意不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM