您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)SQL SERVER Temporal Table 及相關(guān)怪異的故障怎么解決,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
SQL SERVER 2016 有一個(gè)新功能,Temporal table,他主要的功能是保留一份完整的數(shù)據(jù)表的變化記錄,并允許通過這個(gè)表來進(jìn)行數(shù)據(jù)的變更性分析。
啟用CAMAIN 中temporal tables 會(huì)產(chǎn)生一個(gè)新的表在原表的名稱前,增加后綴history。
主要的功能:
審核所有數(shù)據(jù)更改,并在必要時(shí)執(zhí)行數(shù)據(jù)取證
與過去任何時(shí)候一樣重建數(shù)據(jù)的狀態(tài)
計(jì)算隨時(shí)間的趨勢(shì)
為決策支持應(yīng)用程序維護(hù)一個(gè)緩慢變化的維度
從意外的數(shù)據(jù)更改和應(yīng)用程序錯(cuò)誤中恢復(fù)
我們下面來一個(gè)例子看一下 temporal 是怎么做的,我們?cè)谝粋€(gè)開啟了 temporal 的表中進(jìn)行 DML 操作,更改其中一行的數(shù)據(jù)。
可以看到歷史表中的數(shù)據(jù)已經(jīng)開始記錄修改數(shù)據(jù)之前的所有這行的原始數(shù)據(jù)
然后我們?cè)诖烁臄?shù)據(jù)
然后在查詢歷史表,這次還是一樣記錄更改前的記錄狀態(tài)
在插入數(shù)據(jù)的時(shí)候,會(huì)在原表中的字段,進(jìn)行記錄,而在歷史表中并不會(huì)有任何記錄,這點(diǎn)是要知道的。而更新記錄,刪除記錄,都會(huì)對(duì)這些操作進(jìn)行記錄。同時(shí)還有一種MERGE 的方式也是將操作拆分成 DELETE ,UPDATE, INSERT 的方式來進(jìn)行對(duì)應(yīng)行的記錄。
這么先進(jìn)的東西,從2016開始的新功能,其實(shí)深究起來,也是有問題的。
上面的問題,在HOT table 中反應(yīng)的比較多,在MICORSOFT 官方的 TECH在中,有提到,并且也有一些人提出了解決方法,當(dāng)然微軟并沒有認(rèn)為這一個(gè)BUG。
產(chǎn)生這個(gè)問題的原因是這樣的,我們現(xiàn)在進(jìn)行一個(gè)模擬,我們有兩個(gè)SESSION A and B ,我們都要對(duì)其中一個(gè)表 CACONTRACT ,進(jìn)行操作
而不幸的是, A 中的語句是這樣寫的。
UPDATE CACONTRACT SET NUM = 2 WHERE ID IN (select NUM FROM CAMAIN where num = 3)
看似沒有問題,但我們可以將他看成一個(gè)事務(wù),如果這樣的處理時(shí)間是需要0.2毫秒, 但B SESSION 更快,例如他處理 UPDATE CACONTRACT SET BC = 2 WHERE ID = '000003DJKHJ'
看似兩個(gè)操作其實(shí)不會(huì)影響,但B 操作由于快于 A 操作,則例如 ID 000003DJKHJ 在 表中的 SysStartTime 標(biāo)記為 10點(diǎn)15分 .27997 微妙
而 A SESSION 在操作完畢后, 也需要在 sysstarttime 中寫上我的處理
SysStartTime 進(jìn)行一個(gè)更改的操作,將 SysStartTime 更改為 10:1527987 ,這已經(jīng)明顯不符合邏輯了,一個(gè)記錄SysStartTime 再次更新要比當(dāng)前的時(shí)間 要早,這在邏輯上走不通,所以,這個(gè)操作 A 就被forbidden. 尤其在特別熱的表上。
光說不練假把式,來我們來模擬一下上述的情況吧
Follow me
1 在你的測(cè)試系統(tǒng)上建立一個(gè)測(cè)試表
REATE TABLE dbo.Orders
(
[OrderId] INT NOT NULL PRIMARY KEY CLUSTERED
, [OrderValue] DECIMAL(19,4)
, [ValidFrom] DATETIME2 (2) GENERATED ALWAYS AS ROW START
, [ValidTo] DATETIME2 (2) GENERATED ALWAYS AS ROW END
, PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.OrdersHistory));
GO
2 請(qǐng)?jiān)试S以下腳本
BEGIN TRAN
WAITFOR DELAY '00:00:15';
UPDATE dbo.Orders
SET [OrderValue] = [OrderValue] + 1;
COMMIT TRAN
3 請(qǐng)?jiān)诹硪粋€(gè) 查詢窗口執(zhí)行如下語句
INSERT dbo.Orders ([OrderId], [OrderValue])
VALUES (1, 9.99), (2, 9.99);
GO
SELECT * FROM dbo.Orders;
GO
這就是插入數(shù)據(jù)在后,但卻先插入,而要更新時(shí)在前,實(shí)際操作在后。這個(gè)時(shí)序性的系統(tǒng)自然就吃不消了。
解決這樣的問題:
1 讓關(guān)于報(bào)錯(cuò)表的 DML 操作足夠的快,避免這樣的事情發(fā)生(不過在很復(fù)雜的系統(tǒng)中,這很難)
2 在某些操作中,你想使用 holdlock 操作(其實(shí)是人為降低系統(tǒng)的處理性能)
3 在非常熱的表中,停止使用這項(xiàng)微軟的新功能,并等待微軟能在新的版本中更新這個(gè)BUG。
關(guān)于SQL SERVER Temporal Table 及相關(guān)怪異的故障怎么解決就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。