国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

對于大于8046 bytes的行,RCSI/SI事務隔離級別無效

2024-07-21 02:46:42
字體:
來源:轉載
供稿:網友
對于大于8046 bytes的行,RCSI/SI事務隔離級別無效

自SQL Server 2005起,我們有了READ COMMITTED SNAPSHOT ISOLATION level (RCSI) 和SNAPSHOT ISOLATION level (SI)兩個事務隔離級別。當你使用這些事務隔離級別時,讀操作(SELECT語句)在讀的時候不需要S鎖(共享鎖),寫操作(UPDATE,DELETE語句)會對記錄進行版本控制,這些改變會寫入TempDb。它們就會生成一個版本鏈,記錄的最新版本(存在數據庫里的數據頁里)指向存在TempDb里的頁,下圖可以幫助我們理解這個情況。

為了使這個機制有效,SQL Server需要在數據庫內部的數據頁上的每條記錄,增加14 bytes長的指針。這就是說,每條記錄增加了14 bytes的長度。或許你已經知道,當你使用定長數據類型時,SQL Server內部的記錄長度不能超過8060 bytes。這就意味著,當你啟用RCSI/SI隔離級別時,會導致記錄超過現有的8060 bytes。我們來看一個簡單的例子:

 1 USE master 2 GO 3  4 -- Create a new database 5 CREATE DATABASE VersionStoreRestrictions 6 GO 7  8 -- Enable RCSI 9 ALTER DATABASE VersionStoreRestrictions SET READ_COMMITTED_SNAPSHOT ON10 GO11 12 -- Use it13 USE VersionStoreRestrictions14 GO15 16 -- Create a table where each record is 8047 bytes large17 CREATE TABLE TableB18 (19    Column1 CHAR(40),20    Column2 CHAR(8000)21 )22 GO

從代碼里我們可以看到,這里我創建了帶2個CHAR列,總長為8040 bytes的表。SQL Server為每條記錄內部需要至少7 bytes的開銷。這里數據頁上的1條記錄需要8047 bytes。因為我們在數據庫級別啟用了RCSI數據隔離級別,SQL Server需要增加額外的14 bytes作為行版本指針(Row Version Pointe),這就把表里的每條記錄長度擴展到8061 bytes。對于SQL Server來說,這就意味著每條記錄太長了(多出1 byte)。我們在表里插入1條記錄看看:

1 -- Insert a initial row2 INSERT INTO TableB VALUES (REPLICATE('A', 40), REPLICATE('A', 8000))3 GO

現在當你嘗試去更新這個記錄(SQL Server嘗試在TempDb里對這條記錄進行版本控制),SQL Server會報下列錯誤:

1 UPDATE TableB2 SET Column1 = REPLICATE('B', 40)3 GO

這個錯誤信息非常有意義,因為數據庫上下文信息是錯誤的(SSMS顯示你還在master數據庫)。但是當你在UPDATE語句加上表架構時,你就能拿回實際的錯誤信息:

1 UPDATE VersionStoreRestrictions.dbo.TableB2 SET Column1 = REPLICATE('B', 40)3 GO4  

哇噢,這是個內部錯誤,因為SQL Server使用的緩存只有8060 bytes 大,現在我們嘗試在那個緩存里保存8061 bytes——瞧!這在SQL Server內部是個bug!你可以在自SQL SERVER 2005以后的版本里驗證這個BUG,也就說,這個BUG已經存在好幾年了(SQL Server 2012已經修正這個BUG,但在頁里面的確存儲了預期的8061 bytes,我測試的版本是SQL Server 2008R2)。

當你對數據庫啟用RCSI/SI數據隔離級別時,你就要留意這個BUG了,因為這意味這RCSI/SI在任何情況下都無效了。當在你的數據庫里有1個表超過8046 bytes限制,那你真的是有麻煩了!通過這個危險的BUG(nasty bug),你也會理解,知道SQL Serve內部架構和內部如何存儲數據是多么重要!!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永宁县| 郸城县| 金湖县| 乌拉特后旗| 沿河| 龙陵县| 宜城市| 秀山| 黄石市| 潍坊市| 和平区| 樟树市| 泸水县| 高碑店市| 常宁市| 韶关市| 绵阳市| 江北区| 临洮县| 梁平县| 西充县| 嫩江县| 乌拉特后旗| 庐江县| 新疆| 黔东| 朝阳市| 电白县| 黄梅县| 米林县| 抚顺县| 嘉鱼县| 夏津县| 安庆市| 莱芜市| 运城市| 北安市| 奉化市| 周至县| 禄丰县| 兴国县|