Oracle core02_数据块

数据更改


oracle core完成了oracle的核心功能,recovery,读一致性等。
深入的了解oracle的机制,就从一个最简单的更新开始。
对于oracle来说,最大的一个特性就是写了两次数据:

  1. 写数据到数据文件中

  2. 写数据的变更日志到日志文件中

对于最常见的数据更新来说,oracle主要做了一下动作:

  1. 创建数据块变更的日志记录即 redo change vector

  2. 创建数据块的映像即undo record

  3. 创建undo数据块变更的日志记录

  4. 更新数据块

下面就以update为例:记录变更的过程。
实验环境:Oracle Database 10g Enterprise Edition Release
10.2.0.1.0

oracle对于update,会依次做以下变更:

  1. 创建插入undo record的undo变更redo change vector

  2. 创建数据块变更的redo change vector

  3. 组合redo change vector为record写入log buffer

  4. undo record插入到undo块中

  5. 更新数据块

这里可以看到,对于oracle来说,所有的数据块的变更都是日志先行。

  1. 准备数据:

    


SYS/SYS@ORCL>create table test(id number, name varchar2(100));
Table created.
SYS/SYS@ORCL>insert into test values(1,‘xpchild_1‘);
1 row created.
SYS/SYS@ORCL>insert into test values(2,‘xpchild_2‘);
1 row created.
SYS/SYS@ORCL>insert into test values(3,‘xpchild_3‘);
1 row created.
SYS/SYS@ORCL>commit;
Commit complete.

  2.dump 当前数据块


SYS/SYS@ORCL>select owner, segment_name, tablespace_name, HEADER_FILE, HEADER_BLOCK , blocks
from dba_segments where segment_name=‘TEST‘ AND OWNER=‘XPCHILD‘;

OWNER SEGMENT_NAME TABLESPACE_NAME HEADER_FILE HEADER_BLOCK BLOCKS
-------------------- -------------------- -------------------- ----------- ------------ ----------
XPCHILD TEST USERS 4 475 8

SYS/SYS@ORCL>select owner, segment_name, tablespace_name, file_id, block_id,blocks
from dba_extents where owner=‘XPCHILD‘ and segment_name=‘TEST‘;

OWNER SEGMENT_NAME TABLESPACE_NAME FILE_ID BLOCK_ID BLOCKS
-------------------- -------------------- -------------------- ---------- ---------- ----------
XPCHILD TEST USERS 4 473 8

上面的两个数据字典的查询,可以得出,test表在users表空间中,file_id为4。一共分配了一个extents,包括8个block。

  

SYS/SYS@ORCL>alter system dump datafile 4 block 473,474,475,476;

System altered.

block 473,474分别是first level bitmap block,second level bitmap
block。主要记录块的空闲情况。
如:

--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x010001d9 Length: 8 Offset: 0

0:Metadata 1:Metadata 2:Metadata 3:75-100% free
4:75-100% free 5:75-100% free 6:75-100% free 7:75-100% free

block 475为pagetable segment header。

block 480为存放真正数据的块,这也是堆管理的方式所决定,如下dump信息所示:


 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01 0x0001.01e.000000f4 0x008000aa.00f0.14 --U- 3 fsc 0x0000.000d61e9
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f78
0x16:pri[2] offs=0x1f68
block_row_dump:
tab 0, row 0, @0x1f88
tl: 16 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 9] 78 70 63 68 69 6c 64 5f 31
tab 0, row 1, @0x1f78
tl: 16 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [ 9] 78 70 63 68 69 6c 64 5f 32
tab 0, row 2, @0x1f68
tl: 16 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 04
col 1: [ 9] 78 70 63 68 69 6c 64 5f 33

2, 更新数据

  


SYS/SYS@ORCL>SYS/SYS@ORCL>update test set name=‘it is  beyond the current length‘ where id=2;
Session altered.
SYS/SYS@ORCL>alter system dump datafile 4 block 480;
System altered.
-------------------------------------------------------
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0001.01e.000000f4 0x008000aa.00f0.14 C--- 0 scn 0x0000.000d61e9
0x02 0x0001.018.000000f4 0x008000aa.00f0.26 --U- 1 fsc 0x0000.000d6475
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f41
0x16:pri[2] offs=0x1f68
block_row_dump:
tab 0, row 0, @0x1f88
tl: 16 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 9] 78 70 63 68 69 6c 64 5f 31
tab 0, row 1, @0x1f41
tl: 39 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 03
col 1: [32]
69 74 20 69 73 20 20 62 65 79 6f 6e 64 20 74 68 65 20 63 75 72 72 65 6e 74
20 6c 65 6e 67 74 68
tab 0, row 2, @0x1f68
tl: 16 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 9] 78 70 63 68 69 6c 64 5f 33

这里主要说明两点:

  1. @0x1f78变为@0x1f41,这里是代表的这一行的真正的行内偏移地址,因为update更新一个比当前大的值,需要一个更大的连续空间,所以在块内部行进行了迁移,即偏移量发生了变化,rowid指向的是slot的地址,所以update仅仅是更新了slot中存放的块内偏移量,rowid保持不变。

  2. 开始事务时,lock byte lb:变为了0x2。关联的事务标示为itl(interested transaction list)。

redo change vector

  

接下来看下redo change vector的内容:

  


SYS/SYS@ORCL>alter system switch logfile;
System altered.
SYS/SYS@ORCL>update test set name=‘ssssssss‘ where id=2;
1 row updated.
SYS/SYS@ORCL>commit;
Commit complete.
SYS/SYS@ORCL>alter system switch logfile;
System altered.

SYS/SYS@ORCL>select * from v$Log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARCHIV STATUS FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- -------------------
1 1 5 52428800 1 NO CURRENT 879223 2012-01-11 17:11:00
2 1 4 52428800 1 YES ACTIVE 879196 2012-01-11 17:09:52
3 1 3 52428800 1 YES ACTIVE 879176 2012-01-11 17:08:57
SYS/SYS@ORCL>select SEQUENCE# , name from v$archived_log;
SEQUENCE# NAME
---------- -----------------------------------------------------------------------------------
1 /opt/oracle/flash_recovery_area/ORCL/archivelog/2012_01_11/o1_mf_1_1_7jvkvdfo_.arc
2 /opt/oracle/flash_recovery_area/ORCL/archivelog/2012_01_11/o1_mf_1_2_7jw23sfk_.arc
3 /opt/oracle/flash_recovery_area/ORCL/archivelog/2012_01_11/o1_mf_1_3_7jw25j8o_.arc
4 /opt/oracle/flash_recovery_area/ORCL/archivelog/2012_01_11/o1_mf_1_4_7jw27nhp_.arc

23 rows selected.

SYS/SYS@ORCL>alter system dump logfile
‘/opt/oracle/flash_recovery_area/ORCL/archivelog/2012_01_11/o1_mf_1_4_7jw27nhp_.arc‘;

System altered.

KTB Redo
op: 0x11 ver: 0x01
op: F xid: 0x0004.013.000000fb uba: 0x00800054.0110.05
Block cleanout record, scn: 0x0000.000d6a6c ver: 0x01 opt: 0x02, entries follow...
itli: 1 flg: 2 scn: 0x0000.000d6a12
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010001e0 hdba: 0x010001db
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 2 ckix: 10
ncol: 2 nnew: 1 size: 1
col 1: [ 8] 73 73 73 73 73 73 73 73

这一部分代表的是更新数据库的redo。bdba代表更新的块,hdba代表segment header。


SYS/SYS@ORCL>select ubafil,ubablk,start_ubablk,used_ublk from v$transaction;

UBAFIL UBABLK START_UBABLK USED_UBLK
---------- ---------- ------------ ----------
2 155 155 1

1 row selected.
SYS/SYS@ORCL>alter system dump datafile 2 block 155;
System altered.  

对于更新的事务,根据v$transaction可以查询到这个事务使用的undo块的信息,然后dump这个块的情况:

  


*-----------------------------
* Rec #0x5 slt: 0x0f objn: 52634(0x0000cd9a) objd: 52634 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x0080009b.00f2.03 ctl max scn: 0x0000.000d56ca prv tx scn: 0x0000.000d56e5
txn start scn: scn: 0x0000.000d6dec logon user: 0
prev brb: 8389342 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0004.013.000000fb uba: 0x00800054.0110.05
flg: C--- lkc: 0 scn: 0x0000.000d6a70
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010001e0 hdba: 0x010001db
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 12
ncol: 2 nnew: 1 size: -1
col 1: [ 7] 78 70 63 68 69 6c 64

这便是undo块的dump信息,这里也可以看到,undo的信息也仅仅只保留了被改变的那一部分信息,而不是整个块的原始镜像。


txn start scn:  0x0000.000d6a12  logon user: 0  prev brb: 8388689  prev bcl: 0 KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0001.018.000000f4 uba: 0x008000aa.00f0.26
flg: C--- lkc: 0 scn: 0x0000.000d6475
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010001e0 hdba: 0x010001db
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 10
ncol: 2 nnew: 1 size: -1
col 1: [ 7] 78 70 63 68 69 6c 64

  

这一部分代表undo的redo日志,因为oracle对所有对数据块的变更都写两份,一份是数据变更,一份是日志,这一部分就是

对undo 块变更的重做日志。

Oracle core02_数据块,码迷,mamicode.com

时间: 2024-11-08 22:09:19

Oracle core02_数据块的相关文章

oracle 数据块介绍 1

ORACLE DATA BLOCK oracle data block是数据库管理数据文件的最小单元. 在物理层面,oracle data file保存在操作系统上,最小i/o单元是操作系统块,oracle data block是oracle db逻辑最小i/o单元,其结构和系统块不同,大小是系统块的整数倍,如图: DATA BLOCK SIZE oracle db都会配置db_block_size参数,在建库时确定oracle db的默认data block size的大小.建库后数据库默认数

Oracle数据块实现原理深入解读(转)

Oracle对数据库数据文件(datafile)中的存储空间进行管理的单位是数据块(data block).数据块是数据库中最小的(逻辑)数据单位.与数据块对应的,所有数据在操作系统级的最小物理存储单位是字节(byte).每种操作系统都有一个被称为块容量(block size)的参数.Oracle每次获取数据时,总是访问整数个(Oracle)数据块,而不是按照操作系统块的容量访问数据. 数据库中标准的数据块(data block)容量是由初始化参数 DB_BLOCK_SIZE指定的.除此之外,用

oracle -- 数据块(data Block)

基本关系:数据库---表空间---数据段---分区---数据块 数据块(data Block)一.数据块Block是Oracle存储数据信息的最小单位.这里说的是Oracle环境下的最小单位.Oracle也就是通过数据块来屏蔽不同操作系统存储结构的差异.无论是Windows环境,还是Unix/Linux环境,他们的操作系统存储结构和方式.甚至字符排列的方式都是不同的.Oracle利用数据块将这些差异加以屏蔽,全部数据操作采用对Oracle块的操作,相当于是一个层次的抽象. 二.Oracle所有对

对Oracle数据库坏块的理解

1.物理坏块和逻辑坏块 在数据库中有一个概念叫做数据块的一致性,Oracle的数据块的一致性包括了两个层次:物理一致性和逻辑一致性,如果一个数据块在这两个层次上存在不一致性,那就对应到了我们今天要要说的物理坏块和逻辑坏块. 在每一个数据块的头部有一个校验和字段,每当数据块要被写回磁盘前,Oracle都会重新计算 这个数据块的校验和,并记录到这个字段最终写会磁盘.下次数据块被读入内存,Oracle会重新 计算数据块的校验和,并和块头的字段相比较,如果有差异,Oracle就知道这个数据块有错误, 会

使用BBED理解和修改Oracle数据块

1.生成bbed list file文件: SQL> select file#||' '||name||' '||bytes from v$datafile; $ vim dbfile.txt 1 /u01/app/oradata/sydb/system01.dbf 754974720 2 /u01/app/oradata/sydb/sysaux01.dbf 587202560 3 /u01/app/oradata/sydb/undotbs01.dbf 429916160 4 /u01/app/

oracle数据块的大小

标准数据块用于临时表空间和系统表空间,同时也是一个表空间数据块的默认值.标准数据块的大小是在创建数据库时由参数DB_BLOCK_SIZE确定的.若要改变这一设置必须重建数据库. DB_CACHE_SIZE设置数据库高速缓存的大小.其最小尺寸为一个granule,高速缓存的数据块的大小必须等于标准数据块的大小,因为标准数据块是数据库输入输出的基本单位和最小单位,数据由数据文件加载进入内存的最小数据容量必须是一个标准块. 如果要在数据库中使用非标准数据块就必须定义DB_CACHE_SIZE 和DB_

oracle ora-01578 ORACLE 数据块损坏 (文件号 4, 块号 840339)

ORA-01578是 数据块物理坏块/损坏的一种,不同于逻辑损坏/坏块,一般 会伴随ORA-1110出现,一旦ORACLE读取到存在损坏的块就会报出Caused by: java.sql.SQLException: ORA-01578: ORACLE 数据块损坏 (文件号 4, 块号 840339)ORA-01110: 数据文件 4: 'E:\APP\ADMINISTRATOR\ORADATA\ORCL\USERS01.DBF' 解决方法如下:1.使用DBV检查数据文件,在cmd目录下直接输入d

5.oracle的dump理解五 数据块理论

5.oracle的dump理解五 数据块理论 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/51228514 前两篇描述了我们在操作层面看到的一些东西,但是没有理论指导,看到越多我们只会越迷糊.所以,蛤蟆从官方文档上摘取一些老少皆宜的内容来补脑. 块是数据块IO的最小单位. 1     数据块和操作系统块 从物理层面,数据库的块存储时候是由操作系统块组成.操作系统块是操作系统可以读写的最小数据单位.ORACLE块是一个逻辑存

Oracle 学习之RMAN(十三)恢复实战--数据块修复

在很多情况下,数据库只是某个数据文件的些许数据块发生损坏.这种情况,我们当然可是使用数据库恢复或者数据文件恢复的方式来解决问题.但是有点高射炮打蚊子的感觉.幸好RMAN提供了块级别的恢复.下面我们来演示一下. 1. 创建一个表空间,大小小一点. SQL> conn / as sysdba Connected. SQL> create tablespace tbs_blkerr datafile '/u01/app/oracle/oradata/devdb/blkerr01.dbf' size