1 --TempDB上的PAGELATCH
2
3
4 --分清楚數據庫裏面的數據頁面和系統頁面
5
6 --須要解釋的是,SQL不只在數據頁修改的時候加latch,在數據文件的系統頁面上,例如
7 --SGAM、PFS、GAM頁面發生修改的時候,也會加latch。這些latch在某些狀況下也有可能
8 --成爲系統瓶頸
9
10 --例如:當數據庫建立一張新表的時候,SQL要爲這張表分配存儲頁面,同時SQL也要
11 --修改SGAM、PFS、GAM頁面,把已經分配出去的頁面標誌成已使用。因此每建立一張
12 --新表,SGAM、PFS、GAM頁面都會有修改動做
13
14 --這種行爲對通常用戶數據庫不會有問題,由於正常的應用不會折騰着不停地建表,刪表
15 --可是tempdb就不一樣了。若是一個存儲過程使用了臨時表,而這個存儲過程被併發用戶
16 --普遍使用,那很天然地就會有不少併發用戶在tempdb裏同時建立表,作完了之後又
17 --刪除表。這時候在一個時間點,會有不少任務要修改SGAM、PFS、GAM頁面。他們
18 --上面的latch就會成爲系統瓶頸。因此這類問題,一般會發生在tempdb上
19
20
21 --數據頁面上的「HOT」 能夠經過調整表格設計來緩解,系統頁面的瓶頸怎麼解決呢?
22 --其實解決方法很簡單。讓咱們想一想,在任何一個時間點,最多能有多少個任務在
23 --併發處理tempdb?假設服務器的全部CPU都在跑這些任務,最大任務數也不會超過
24 --服務器邏輯CPU的數目。DBA能夠爲tempdb創建和CPU數目同樣多的數據文件,他們的
25 --大小又都同樣。這樣,SQL的任務就會平均地分不到這些數據文件上。在每一個時間點
26 --只有一個任務在修改同一個數據文件上的系統分配頁面,PAGELATCH瓶頸就不會出現
27
28
29 -------------------------再小結一下 解決方法要點--------------------------------------------
30 --(1)SQL使用幾顆CPU在運行,就爲TEMPDB建立幾個數據文件
31 --(2)這些文件的大小必須同樣大
32 --(3)要嚴格防止tempdb數據空間用盡,引起數據文件自動增加。由於自動增加只會增加
33 --其中一個文件,形成只有一個文件有空閒空間,全部的任務就會集中在他的身上,他
34 --就又變成瓶頸了
35
36
37
38
39 --如今來看一個真實案例,看看tempdb的瓶頸是如何產生的:
40
41 --一個用戶反映,他的SQL會在某一段時間裏,忽然變得很是慢。最後他不得不重啓SQL服務。
42 --重啓之後,問題消失了。客戶在出現問題的那段時間裏,收集了主要的系統DVM,以及
43 --性能監視器裏和SQL有關的那些計數器。順便說一句,這臺服務器有16顆邏輯CPU
44
45 SELECT * FROM sys.[dm_exec_requests]
46 --從上面的結果來看,問題比較明顯,有不少任務在爭搶頁面2:18:331608上的PAGELATCH_X資源
47 --tempdb上的瓶頸是當時最大的問題
48
49 --可是2:18:331608這個值使人有點疑惑。第一,文件ID18意味着這個tempdb上至少有18個文件。
50 --除去一個日誌文件,這個tempdb至少有17個數據文件。而這臺服務器只有16顆CPU,爲什麼
51 --你們別的數據文件都不用,非要槍這個第18號文件呢?這是很奇怪的地方。第二,SGAM、PFS、GAM
52 --頁面都在數據文件的開頭。只有當數據文件變得比較大之後,文件頭的那幾個頁面已經不夠用了
53 --,SQL纔會在後面再分配新的系統頁面。因此331608意味着這個18號文件當時已經比較大了
54
55 --帶着這些疑惑,筆者又讓客戶收集了一個tempdb上的sp_helpfile結果(但這時問題已經消失)
56 --這個結果回答了疑惑
57
58 --像前面猜想那樣,這個tempdb上果真有17個數據文件。可是這些文件的配置是不同的。前16個
59 --文件的初始大小是256MB,最大大小是512MB。而最後一個數據文件,也就是出問題的18號,初始大小
60 --是2GB,沒有上限。用戶這樣設置,顯示是爲了防止tempdb在P盤上使用太多的空間
61
62 --若是tempdb可以同時使用這17個數據文件,tempdb數據文件應該是多大呢?假使前16個小的
63 --數據文件都自動增加到了最大值,並且最後一個數據文件沒有增加,大小應該是
64 --(0.5*16+2)=10GB。那出問題的時候,tempdb到底用了多大的數據文件呢?
65
66 --這個信息用戶沒有收集,不過在性能監視器的計數器裏,有一個計數器
67 --SQLSERVER:DataBase\DataFile(s) Size(KB)這時候可以派上用場。打開一看,
68 --發現當時的值在21GB。也就是說,前面的16個小的數據文件已經用完。SQL只好使用
69 --第18號數據文件,由於他沒有上限,就讓他不斷自動增加。全部壓力都集中在了
70 --一個數據文件上,難怪這個數據文件成爲了瓶頸
71
72 --防止問題再次出現的建議:就是增大前16個數據文件的初始大小。既然此次SQL會用到
73 --21GB,不如每一個數據文件的初始大小都設置爲2GB。這樣就不容易用完了。若是P盤
74 --沒有那麼多空間,能夠把這些數據文件都移到G盤上。固然,監視tempdb的使用狀況
75 --搞清楚是誰在tempdb裏佔用這麼多空間也是很重要的。監視方法和腳本第一章裏有
76 --介紹數據庫