今天AP人員跟我反應說他在truncate table時一直跑不出來,我上去看,發現truncate table被block,如下圖
當時心想,就是一個單純的block而己,很容易處理的。
然後我就去看block的源頭…………
意外的是,block的源頭竟是一個系統背景程序,而且這個背景程序在做「Create index..」
~~~~頓時一頭霧水~~~~
~~這到底是什麼啊,系統自己在create index!!!
然後我用dbcc inputbuffer想看看它在跑什麼指令,結果是空的,沒辦法查到它在跑的指令。
TupleMover
TupleMover是SQL 2014開始引進的一個背景程序,主要是定期將columnStore index的deltaStore中的資料,壓縮並寫入columnStore中。
columnStore
index其實包含了兩部份(columnStore 跟 deltaStore)。如果TABLE有columnStore index,當對這個TABLE做insert / update時,columnStore index不會立即被同步修改,這些資訊會先存到一個稱為deltaStore的地方。當使用者查詢時,columnStore及DeltaStore會被一併搜尋。
deltaStore可以理解為columnStore的暫存區,它由RowSet所組成,這些RowSet仍然是傳統的Row-Base index結構。當收集到足夠多的資料後,RowSet會關閉。
TupleMover這支背景程序,就是用來將deltaStore中的「已關閉」的RwoSet,壓縮並寫入columnStore,TupleMover預設每5分鐘會啟動一次,或者當有使用者手動執行alter index reorganize/rebuild時啟動。
TupleMover在執行期間,會在目標TABLE獲取S鎖,並在最後階段獲取SCH-M鎖,從sysprocess中看,它的cmd會是「CREATE INDEX」。
檢查
瞭解了這些後,再看truncate的目標TABLE,果然它有個columnStore index,如下圖
至此,總算是知道原因了,我詢問AP人員,他說在truncate之前有支JOB在做分批大量的insert的操作(約3億筆),由於空間不夠,AP人員把JOB中斷,然後要truncate table以清出空間。但由於已有大量的資料insert進去了,TupleMover需要較長的作業時間。
而truncate table需要獲取SCH-M鎖,此時TupleMover在該TABLE上已獲取了S鎖,所以truncate
table被blocked。
原因終於搞清楚了~~~
但這個問題,目前只能等,沒有其它方式。於是只能就跟AP人員說這必需要等到TupleMover執行完,再做truncate。
後記
我們可以使用 trace flag 634去關閉TupleMover,關閉之後系統將不會自動啟動TupleMover去處理deltaStore的資料,直到使用者執行alter index reorganize/rebuild。
很棒文章,加油
回覆刪除謝謝老師.
刪除