2019年3月7日 星期四

Truncate table 被系統背景程序 block


今天AP人員跟我反應說他在truncate table時一直跑不出來,我上去看,發現truncate tableblock,如下圖



當時心想,就是一個單純的block而己,很容易處理的。
然後我就去看block的源頭…………

意外的是,block的源頭竟是一個系統背景程序,而且這個背景程序在做「Create index..
~~~~頓時一頭霧水~~~~













~~這到底是什麼啊,系統自己在create index!!!


首先我先確認了這個session是系統的程序

剛開始搞不清楚,從沒聽過系統會自己建index。我試著kill看看,果然不行,系統程序不能kill














然後我用dbcc inputbuffer想看看它在跑什麼指令,結果是空的,沒辦法查到它在跑的指令。

再來我用dbcc opentran看看它的交易資訊,發現了一個關鍵字「TupleMover



















TupleMover
TupleMoverSQL 2014開始引進的一個背景程序,主要是定期將columnStore indexdeltaStore中的資料,壓縮並寫入columnStore中。

columnStore index其實包含了兩部份(columnStore deltaStore)。如果TABLEcolumnStore index,當對這個TABLEinsert / update時,columnStore index不會立即被同步修改,這些資訊會先存到一個稱為deltaStore的地方。當使用者查詢時,columnStoreDeltaStore會被一併搜尋。

deltaStore可以理解為columnStore的暫存區,它由RowSet所組成,這些RowSet仍然是傳統的Row-Base index結構。當收集到足夠多的資料後,RowSet會關閉。

TupleMover這支背景程序,就是用來將deltaStore中的「已關閉」的RwoSet,壓縮並寫入columnStoreTupleMover預設每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 tableblocked

原因終於搞清楚了~~~
但這個問題,目前只能等,沒有其它方式。於是只能就跟AP人員說這必需要等到TupleMover執行完,再做truncate

後記
我們可以使用 trace flag 634去關閉TupleMover,關閉之後系統將不會自動啟動TupleMover去處理deltaStore的資料,直到使用者執行alter index reorganize/rebuild


2 則留言: