sqlserverlatch
具體問題具體分析,舉例來說明為什麼磁碟IO成瓶頸資料庫的性能急速下降了。
為什麼當磁碟IO成瓶頸之後, 資料庫的性能不是達到飽和的平衡狀態,而是急劇下降。為什麼資料庫的性能有非常明顯的分界點,原因是什麼?
相信大部分做資料庫運維的朋友,都遇到這種情況。 資料庫在前一天性能表現的相當穩定,資料庫的響應時間也很正常,但就在今天,在業務人員反饋業務流量沒有任何上升的情況下,資料庫的變得不穩定了,有時候一個最簡單的insert操作, 需要幾十秒,但99%的insert卻又可以在幾毫秒完成,這又是為什麼了?
dba此時心中有無限的疑惑,到底是什麼原因呢? 磁碟IO性能變差了?還是業務運維人員反饋的流量壓根就不對? 還是資料庫內部出問題?昨天不是還好好的嗎?
當資料庫出現響應時間不穩定的時候,我們在操作系統上會看到磁碟的利用率會比較高,如果觀察仔細一點,還可以看到,存在一些讀的IO. 資料庫伺服器如果存在大量的寫IO,性能一般都是正常跟穩定的,但只要存在少量的讀IO,則性能開始出現抖動,存在大量的讀IO時(排除配備非常高速磁碟的機器),對於在線交易的資料庫系統來說,大概性能就雪崩了。為什麼操作系統上看到的磁碟讀IO跟寫IO所帶來的性能差距這么大呢?
如果親之前沒有注意到上述的現象,親對上述的結論也是懷疑。但請看下面的分解。
在寫這個文章之前,作者閱讀了大量跟的IO相關的代碼,如非同步IO線程的相關的,innodb_buffer池相關的,以及跟讀數據塊最相關的核心函數buf_page_get_gen函數以及其調用的相關子函數。為了將文章寫得通俗點,看起來不那麼累,因此不再一行一行的將代碼解析寫出來。
咱們先來提問題。buf_page_get_gen函數的作用是從Buffer bool裡面讀數據頁,可能存在以下幾種情況。
提問. 數據頁不在buffer bool 裡面該怎麼辦?
回答:去讀文件,將文件中的數據頁載入到buffer pool裡面。下面是函數buffer_read_page的函數,作用是將物理數據頁載入到buffer pool, 圖片中顯示
buffer_read_page函數棧的頂層是pread64(),調用了操作系統的讀函數。
通過解析buf_wait_for_read函數的下層函數,我們知道其實通過首先自旋加鎖pin的方式,超過設定的自旋次數之後,進入等待,等待IO完成被喚醒。這樣節省不停自旋pin時消耗的cpu,但需要付出被喚起時的開銷。
再繼續擴展問題: 如果會話線程A 經過物理IO將數據頁1001讀入buffer之後,他需要修改這個頁,而在會話線程A之後的其他的同樣需要訪問數據頁1001的會話線程,即使在數據頁1001被入讀buffer pool之後,將仍然處於等待中。因為在數據頁上讀取或者更新的時候,同樣需要上鎖,這樣才能保證數據頁並發讀取/更新的一致性。
由此可見,當一個高並發的系統,出現了熱點數據頁需要從磁碟上載入到buffer pool中時,造成的延遲,是難以想像的。因此排在等待熱點頁隊列最後的會話線程最後才得到需要的頁,響應時間也就越長,這就是造成了一個簡單的sql需要執行幾十秒的原因。
再回頭來看上面的問題,mysql資料庫出現性能下降時,可以看到操作系統有讀IO。 原因是,在資料庫對數據頁的更改,是在內存中的,然後通過檢查點線程進行非同步寫盤,這個非同步的寫操作是不堵塞執行sql的會話線程的。所以,即使看到操作系統上有大量的寫IO,資料庫的性能也是很平穩的。但當用戶線程需要查找的數據頁不在buffer pool中時,則會從磁碟上讀取,在一個熱點數據頁不是非常多的情況下,我們設置足夠大的innodb_buffer_pool的size, 基本可以緩存所有的數據頁,因此一般都不會出現缺頁的情況,也就是在操作系統上基本看不到讀的IO。 當出現讀的IO時,原因時在執行buf_read_page_low函數,從磁碟上讀取數據頁到buffer pool, 則資料庫的性能則開始下降,當出現大量的讀IO,資料庫的性能會非常差。
⑵ 資料庫性能優化有哪些措施
1、調整數據結構的設計。這一部分在開發信息系統之前完成,程序員需要考慮是否使用ORACLE資料庫的分區功能,對於經常訪問的資料庫表是否需要建立索引等。
2、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什麼樣的體系結構,是使用傳統的Client/Server兩層體系結構,還是使用Browser/Web/Database的三層體系結構。不同的應用程序體系結構要求的資料庫資源是不同的。
3、調整資料庫SQL語句。應用程序的執行最終將歸結為資料庫中的SQL語句執行,因此SQL語句的執行效率最終決定了ORACLE資料庫的性能。ORACLE公司推薦使用ORACLE語句優化器(Oracle Optimizer)和行鎖管理器(row-level manager)來調整優化SQL語句。
4、調整伺服器內存分配。內存分配是在信息系統運行過程中優化配置的,資料庫管理員可以根據資料庫運行狀況調整資料庫系統全局區(SGA區)的數據緩沖區、日誌緩沖區和共享池的大小;還可以調整程序全局區(PGA區)的大小。需要注意的是,SGA區不是越大越好,SGA區過大會佔用操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5、調整硬碟I/O,這一步是在信息系統開發之前完成的。資料庫管理員可以將組成同一個表空間的數據文件放在不同的硬碟上,做到硬碟之間I/O負載均衡。
6、調整操作系統參數,例如:運行在UNIX操作系統上的ORACLE資料庫,可以調整UNIX數據緩沖池的大小,每個進程所能使用的內存大小等參數。
資料庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,它產生於距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以後,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。資料庫有很多種類型,從最簡單的存儲有各種數據的表格到能夠進行海量數據存儲的大型資料庫系統都在各個方面得到了廣泛的應用。
在信息化社會,充分有效地管理和利用各類信息資源,是進行科學研究和決策管理的前提條件。資料庫技術是管理信息系統、辦公自動化系統、決策支持系統等各類信息系統的核心部分,是進行科學研究和決策管理的重要技術手段。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的「倉庫」,並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
(2)sqlserverlatch擴展閱讀
資料庫,簡單來說是本身可視為電子化的文件櫃--存儲電子文件的處所,用戶可以對文件中的數據進行新增、截取、更新、刪除等操作。
資料庫指的是以一定方式儲存在一起、能為多個用戶共享、具有盡可能小的冗餘度的特點、是與應用程序彼此獨立的數據集合。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的"倉庫",並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
⑶ 如何判斷資料庫IO是否慢
我們可能經常會遇到SQLServer資料庫頻繁關閉的情況。在分析了內存和CPU使用情況後,我們需要繼續調查根源是否在I/O。我們應該如何識別SQLServer是否有I/O相關的瓶頸?
解決:
當數據頁經常從緩沖池中移進移出的時候,I/O子系統就會成為SQLServer性能問題的關鍵因素之一。事務日誌和tempdb同樣也會產生重大的I/O壓力。因此,你必須確保你的I/O子系統能按照預期運行。否則你將會成為響應時間增長和頻繁超時的受害者。在這篇文章中,將描述如何使用內置工具識別I/O相關瓶頸,並提供一些磁碟配置的方法:
性能計數器(Performance Monitor):
可以使用性能計數器來檢查I/O子系統的負荷。下面的計數器可用於檢查磁碟性能:
PhysicalDisk Object:Avg.DiskQueue
Length:計算從物理磁碟中的平均讀和寫的請求隊列。過高的值代表磁碟操作處於等待狀態。當這個值在SQLServer峰值時長期超過2,證明需要注意了。如果有多個硬碟,就需要把這些數值除以2。比如,有4個硬碟,且隊列為10,那麼平均值就是10/4=2.5,雖然也證明需要關注,但不能使用10這個值。
Avg.Disk Sec/Read和Avg.Disk
Sec/Write:顯示從磁碟讀或者寫入磁碟的平均時間。10ms內是很好的表現,20以下還算能接受。高於此值證明存在問題。
Physical Disk:%Disk
Time:在磁碟忙於讀或者寫請求的時候持續時間的比率。根據拇指定律,此值應該小於50%。
Disk Reads/Sec和Disk
Writes/Sec計數器顯示出在磁碟中讀寫操作的速率。這兩個值應該小於磁碟能力的85%。當超過此值,磁碟的訪問時間將以指數方式增長。
可以通過以下方式來計算逐漸增長的負載的能力。一種方法是使用SQLIO。你應該找到吞吐量比較穩定,但緩慢增長。
可以使用以下公式來計算RAID配置:
Raid 0: I/O per disk = (reads + writes) / number
ofdisks
Raid 1: I/O per disk = [reads + (writes*2)] /
2
Raid 5: I/O per disk = [reads + (writes*4)] / number of
disks
Raid
10: I/O per disk = [reads +
(writes*2)] / number of disks
比如:對於RAID 1,如果得到下面的計數器:
Disk Reads/sec = 90
Disk
Writes/sec =75
根據公式:[reads + (writes*2)] / 2 or [90 + (75*2)] /
2 = 120I/Os每個磁碟。
動態管理視圖(DMVs):
有很多游泳的DMVs可以用於檢查I/O瓶頸:
當一個頁面被用於讀或者寫訪問且頁面在緩沖池中不存在或不可用時,會引發一個I/O閂鎖等待(I/O
latch),它會在PAGEIOLATCH_EX/PAGEIOLATCH_SH(具體根據請求類型而定)。這些等待表明一個I/O瓶頸。可以使用sys.dm_os_wait_stats找到閂鎖等待的信息。如果你保存了SQLServer正常運行下的waiting_task_counts和wait_time_ms值,並且於此次的值做對比,可以識別出I/O問題:
select *
from sys.dm_os_wait_stats
where wait_type like
'PAGEIOLATCH%'
order by wait_type asc
掛起的I/O請求可以在下面查詢中查到,並且用於識別那個磁碟負責的這個瓶頸:
select database_id,
file_id,
io_stall,
io_pending_ms_ticks,
scheler_address
from sys.dm_io_virtual_file_stats(NULL, NULL) iovfs,
sys.dm_io_pending_io_requests as iopior
where iovfs.file_handle = iopior.io_handle
磁碟碎片(Disk Fragmentation):
建議你檢查磁碟碎片和配置用於SQLServer實例的磁碟。在NTFS文件系統中的碎片會產生嚴重的性能影響。磁碟需要經常整理碎片並且指定整理碎片計劃。研究表明,一些情況下SAN在整理碎片後性能更差。因此,SAN必須根據實際情況對待。
NTFS上的索引碎片同樣能引起高I/O好用。但是這和在SANs中的效果是不一樣的。
磁碟配置/最佳實踐:
常規情況,你應該把日誌文件和數據文件分開存放以獲得更好的性能。對於重負載的數據文件(包括tempdb)的I/O特性是隨機讀取。對於日誌文件,是順序訪問的,除非事務需要回滾。
對於內置磁碟僅僅可以用於資料庫日誌文件,因為它們對順序I/O有很好的性能,但是對隨機I/O性能低下。
資料庫的數據和日誌文件應該放在對應專用的磁碟中。確保良好的性能。建議日誌文件放在兩個內置磁碟,並配置為RAID
1。數據文件駐留在僅用於給SQLServer訪問的SAN系統中,並只被查詢和報表控制。特殊訪問應該被禁止。
寫緩沖在可能的情況下應該被允許,並保證斷電也能使用。
為了盡可能保證對於OLTP系統的I/O瓶頸影響最小化,不應該把OLAP和OLTP環境混合。並且保證你的代碼優化及有合適的索引來避免不必要的I/O。