对于大于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。我们来看一个简单的例子:
USE master
GO -- Create a new database
CREATE DATABASE VersionStoreRestrictions
GO -- Enable RCSI
ALTER DATABASE VersionStoreRestrictions SET READ_COMMITTED_SNAPSHOT ON
GO -- Use it
USE VersionStoreRestrictions
GO -- Create a table where each record is 8047 bytes large
CREATE TABLE TableB
(
Column1 CHAR(40),
Column2 CHAR(8000)
)
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条记录看看:
-- Insert a initial row
INSERT INTO TableB VALUES (REPLICATE('A', 40), REPLICATE('A', 8000))
GO
现在当你尝试去更新这个记录(SQL Server尝试在TempDb里对这条记录进行版本控制),SQL Server会报下列错误:
UPDATE TableB
SET Column1 = REPLICATE('B', 40)
GO
这个错误信息非常有意义,因为数据库上下文信息是错误的(SSMS显示你还在master数据库)。但是当你在UPDATE语句加上表架构时,你就能拿回实际的错误信息:
UPDATE VersionStoreRestrictions.dbo.TableB
SET Column1 = REPLICATE('B', 40)
GO
哇噢,这是个内部错误,因为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内部架构和内部如何存储数据是多么重要!!
参考文章:
https://www.sqlpassion.at/archive/2011/05/06/rcsisi-doesnt-work-with-rows-larger-than-8046-bytes/
对于大于8046 bytes的行,RCSI/SI事务隔离级别无效的更多相关文章
- 设置SQLServer的行版本控制隔离级别
1.--查询数据库状态 select name,user_access,user_access_desc,snapshot_isolation_state,snapshot_isolation_sta ...
- 【转修正】sql server行版本控制的隔离级别
在SQL Server标准的已提交读(READ COMMITTED)隔离级别下,一个读操作会和一个写操作相互阻塞.未提交读(READ UNCOMMITTED)虽然不会有这种阻塞,但是读操作可能会读到脏 ...
- SQL Server-聚焦SNAPSHOT基于行版本隔离级别详解(三十)
前言 上一篇SQL Server详细讲解了隔离级别,但是对基于行版本中的SNAPSHOT隔离级别仍未完全理解,本节再详细讲解下,若有疑义或不同见解请在评论中提出,一起探讨. SNAPSHOT行版本隔离 ...
- 关于ORACLE的串行化隔离级别--来自ORACLE概念手册
为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被 称为串行化处理(serializability)的事务隔离模型(transaction isolation model).当所有 ...
- sqlserver快照,启用基于行版本控制的隔离级别
在sqlserver标准的已提交读(read committed)隔离级别下,读写操作相互阻塞.未提交读(read uncommitted)虽然不会有这种阻塞,但是读操作可能会读到脏数据,这是大部分用 ...
- DataGridView 行数据验证:当输入数据无效时不出现红色感叹号的Bug
private void dgvView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e){ if ...
- securityCRT mongoDB 命令行删除(backspace/delete)无效问题
1.MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无法修改输入 ...
- python 面试真题
0.Python是什么? Python是一种解释型语言.但是跟C和C的衍生语言不同,Python代码在运行之前不需要编译.其他解释型语言还包括PHP和Ruby. Python是动态类型语言,指的是在声 ...
- sqlserver事务隔离小结
SQL Server通过在锁资源上使用不同类型的锁来隔离事务.为了开发安全的事务,定义事务内容以及应在何种情况下回滚至关重要,定义如何以及在多长时间内在事务中保持锁定也同等重要.这由隔离级别决定.应用 ...
随机推荐
- 了解 JavaScript (4)– 第一个 Web 应用程序
在下面的例子中,我们将要构建一个 Bingo 卡片游戏,每个示例演示 JavaScript 的不同方面,通过每次的改进将会得到最终有效的 Bingo 卡片. Bingo 卡片的内容 美国 Bingo ...
- [salesforce] URLFOR function finally
While developing your Visualforce pages you may need to be able to obtain the URL of certain actions ...
- windows 2012 试用180天
windows server 2012 官方下载,可以使用180天, 快到期的时候执行以下命令 slmgr.vbs -rearm
- 如何判断平台工具集去做条件编译(VC++目录、预处理器定义、$(PlatformToolsetVersion))
作者:zyl910 从VS2010开始,提供了一个平台工作集(Platform ToolSet)选项用于配制vc编译版本.到了VS2012,更是因为默认平台工具集不支持WindowsXP,导致经常需要 ...
- 奇怪吸引子---WimolBanlue
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- Mysql自动备份工具1.0(2013年11月15日更新)
Mysql自动备份工具1.0 下载地址 2013-11-15 1.解决日历控件在Windows7/8/8.1环境下遮挡按钮问题:2.解决按月备份当月没有该日期问题: 2013-11-13 1.Mysq ...
- Scala 深入浅出实战经典 第68讲:Scala并发编程原生线程Actor、Cass Class下的消息传递和偏函数实战解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- 前端测试回顾及我们为什么选择Karma
前端测试,或者UI测试一直是业界一大难题.最近Q.js使用Karma作为测试任务管理工具,本文在回顾前端测试方案的同时,也分析下为什么Q.js选用Karma而不是其他测试框架. 像素级全站对比 曾今有 ...
- android 常用类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...
- 调用axis2开发的接口遇到的问题
第1个异常 [org.apache.struts.actions.DispatchAction] – Dispatch[/myservice/NgCallServiceInfo] to method ...