存储引擎内幕:启动页校验和会丢弃页残损保护吗?
来源:互联网 发布:四川成都大学淘宝地址 编辑:程序博客网 时间:2024/05/22 06:32
存储引擎内幕:启动页校验和会丢弃页残损保护吗?
原文地址:http://www.sqlskills.com/BLOGS/PAUL/post/Inside-The-Storage-Engine-Does-turning-on-page-checksums-discard-any-torn-page-protection.aspx
(译者:本文想说的是当修改了数据库的页保护方式(由残损保护改为校验和保护),以前已存在的页的保护方式是不会失效的,而且直到下次写磁盘时才会改为新的保护方式的。这是因为:数据库的页保护方式记录在启动页(boot page,第9页)的dbi_status字段中,而页当前的保护方式记录在页头的m_flagBits字段中。)
译文:
在我现在教的微软认证架构师课堂上,有人提出了一个很有意思的问题:如果数据库原来是页残损保护,现在改成校验和保护了,那么是否所有已存在的页残损保护都会丢失呢?
这是一个很重要的问题,因为将数据库改成页校验和保护并不是立即将所有已分配页改为校验和保护(你要将页读取至缓存池中、修改它并将其写回到磁盘中,只有在这时页才会是校验和保护)。所以如果因为启动数据库页校验和保护而使所有已存在的页的残损保护都失效的话,那么在页改为校验和保护之前,这些页是不会得到任何保护的。是这样的吗?我不记得答案了,下面我做了个实验。
我的想法是:先创建一个页残损保护的数据库,然后创建一个用来模拟页残损保护的表,接着置数据库为页校验和保护,此时看看残损页是否还会报错。
-- 建立一个测试数据库
USE master;
GO
CREATE DATABASE ChecksumTest;
GO
USE ChecksumTest;
GO
-- 将数据库置为页残损保护
ALTER DATABASE ChecksumTest SET PAGE_VERIFY TORN_PAGE_DETECTION;
GO
-- 创建一个测试表,插入一行。
CREATE TABLE BrokenTable (c1 INT, c2 CHAR (1000));
INSERT INTO BrokenTable VALUES (1, 'a');
GO
-- 确保页写入磁盘,并从缓存池中删除。
CHECKPOINT;
GO
DBCC DROPCLEANBUFFERS;
GO
现在我们来检查一下页。在页头部有两个比特位用来说明页是残损保护还是校验和保护。具体地说就是:如果残损保护,那么字段m_flagBits会置上0x100;如果是校验和保护,那么m_flagBits会置上0x200,而且页并没有被修改(也就是说,校验和仍然有效)。因为当页被读取至缓存池中时,系统会去除m_flagBits字段上的残损保护编码的,所以你应当不会看到0x100被置上——当然前提是页不是真的残损,如果真是页残损的话,0x100肯定会被置上的。
sp_allocationmetadata'BrokenTable';
GO
DBCC TRACEON (3604);
GO
DBCC PAGE ('ChecksumTest', 1, 143, 3);
GO
<snip>
m_pageId=(1:143) m_headerVersion = 1 m_type = 1
m_typeFlagBits =0x4 m_level =0 m_flagBits = 0x8000
m_objId(AllocUnitId.idObj) = 67 m_indexId (AllocUnitId.idInd)= 256
Metadata: AllocUnitId =72057594042318848
Metadata: PartitionId =72057594038321152 Metadata: IndexId = 0
Metadata: ObjectId = 2073058421 m_prevPage =(0:0) m_nextPage = (0:0)
pminlen =1008 m_slotCnt = 2 m_freeCnt = 6070
m_freeData =2118 m_reservedCnt =0 m_lsn = (28:183:2)
m_xactReserved =0 m_xdesId =(0:0) m_ghostRecCnt = 0
m_tornBits = 770
<snip>
这时,页残损保护的编码(0x100)已经去除,而且数据页是好的。一旦将磁盘中的页破坏了,这时还可以用DBCC PAGE查看页。下面是我将页破坏了,由DBCC PAGE输出的内容(译注:正如上面所说,当页被破坏了,m_flagBits中0x100肯定会被置上):
m_pageId=(1:143) m_headerVersion =1 m_type = 1
m_typeFlagBits =0x4 m_level =0 m_flagBits = 0x8100
m_objId(AllocUnitId.idObj) = 67 m_indexId (AllocUnitId.idInd)= 256
Metadata: AllocUnitId =72057594042318848
Metadata: PartitionId =72057594038321152 Metadata: IndexId = 0
Metadata: ObjectId = 2073058421 m_prevPage =(0:0) m_nextPage = (0:0)
pminlen =1008 m_slotCnt =1 m_freeCnt = 7083
m_freeData =1107 m_reservedCnt =0 m_lsn = (28:81:20)
m_xactReserved =0 m_xdesId =(0:0) m_ghostRecCnt = 0
m_tornBits = 41949233
此时如果我再查询表,我会得到:
SELECT * FROM BrokenTable;
GO
Msg 824, Level 24, State 2, Line 1
SQL Server detected a logical consistency-based I/O error: torn page(expected signature: 0xaaaaaaaa; actual signature: 0xaaaaa82a). It occurred during a read of page (1:143) indatabase ID 8 at offset 0x0000000011e000 infile 'C:/Program Files/Microsoft SQLServer/MSSQL.1/MSSQL/DATA/ChecksumTest.mdf'. Additional messages in the SQLServer error log or system event log may provide more detail. This is a severeerror condition that threatens database integrity and must be correctedimmediately. Complete a full database consistency check (DBCC CHECKDB). Thiserror can be caused by many factors; for more information, see SQL Server BooksOnline.
现在问题的关键是:如果此时将数据库改为校验和保护,是否还报告页残损错误。我们来试试:
ALTER DATABASE checksumtest SET PAGE_VERIFY CHECKSUM;
GO
SELECT * FROM BrokenTable;
GO
Msg 824, Level 24, State 2, Line 1
SQL Server detected a logical consistency-based I/O error: torn page(expected signature: 0xaaaaaaaa; actual signature: 0xaaaaa82a). It occurred during a read of page (1:143) indatabase ID 8 at offset 0x0000000011e000 infile 'C:/Program Files/Microsoft SQLServer/MSSQL.1/MSSQL/DATA/ChecksumTest.mdf'. Additional messages in the SQLServer error log or system event log may provide more detail. This is a severeerror condition that threatens database integrity and must be correctedimmediately. Complete a full database consistency check (DBCC CHECKDB). Thiserror can be caused by many factors; for more information, see SQL Server BooksOnline.
酷!所以最终的答案是YES——残损页保护仍然有效。因为页头部的有两个比特位保存着页正在使用的保护算法。实际上,你就是关闭了数据库的校验和保护和残损保护(译注:将它置为NONE保护),数据页原来的保护还是有效的。
- 存储引擎内幕:启动页校验和会丢弃页残损保护吗?
- 存储引擎内幕:IAM页、IAM链及分配单元
- MySQL技术内幕--存储引擎
- 3.保护模式8-页式存储(启动分页机制)
- MySQL技术内幕:InnoDB存储引擎
- MySQL技术内幕InnoDB存储引擎
- MySQL技术内幕-InnoDB存储引擎 笔记
- MySQL技术内幕InnoDB存储引擎 读书笔记
- MySQL技术内幕:InnoDB存储引擎
- MySQL技术内幕 InnoDB存储引擎(一)
- MySQL 技术内幕:InnoDB存储引擎pdf
- 《MySQL技术内幕--InnoDB存储引擎》读书笔记
- 《MySQL技术内幕 InnoDB存储引擎》一书中用于查看数据页内容的python小工具
- 保护模式 页式存储
- 保护模式--页式存储
- 《SQL SERVER 2005技术内幕--存储引擎》学习笔记
- mysql技术内幕-innodb存储引擎读书笔记(下)
- mysql技术内幕-innodb存储引擎读书笔记(中)
- Terasoluna框架讲解(带小例子)
- JavaScript在IE和Firefox(火狐)的不兼容问题解决
- SQL SERVER:在SQL中分类合并数据行
- Windows 映射模式
- 编程网站
- 存储引擎内幕:启动页校验和会丢弃页残损保护吗?
- Flex与Java Socket的AMF3通信小示范
- 经典String str = new String("abc")内存分配问题
- 使用MFC开发ActiveX控件
- H.264句法和语法总结 句法元素的分层结构
- JQuery 框架中的选择器说明
- Symbian常用工具用法说明
- 搞编程有前途吗?
- 常用的js语句