甲骨论36课图解剖析一个事务的操作流程
>selectxid,xudusn,xidslot,xidsgn,ubablk,ubafil from v$transaction; //查询事务的XID
事务表:undo段的第一个数据块放着一个事务表,每个回滚段最多可放47个事务表。
事务建立之后,先被分配一个XID。然后在undo表空间中找一个undo 段,在undo段的段头块的事务表里写入自己的信息(XID)。
回滚块、事务表、事务槽的概念:
事务表的分配:事务表被均匀的分在回滚段中,尽量一个事务表占一个回滚段。
>select header_block,header_file from dba_segments wheresegment_name=’_SYSSMU1$’; //查询段头块的地址
>alter system dump udo header ‘_SYSSMU1$’; //转储回滚段头
>alter system dump datafile 5 block 4308;//转储回滚段数据块
事务槽包括:xid(即是ID 又是地址)、uba(undoblock address回滚块,存回滚信息)
事务操作流程:
1) 在undo表空间找一个相对空闲的段,在回滚段的段头块的事务表中写入事务信息(xid ;uba)
2) 被分配一个undo块,同时将undo块的地址(uba)写入事务表中。
3) 在被修改的数据块的事务槽中写入事务信息(xid)。
4) 修改数据时先将原数据写入undo块,同时事务槽的xid批向分配的undo块。
xid包括事务使用:回滚段的段头块、事务表使用的行、覆盖次数。块号、行号及第几次覆盖可以唯一确定某一行。如果没有覆盖次数将不能唯一与事件对应。
5) 当有新的事务修改数据,数据的三个链接:
l rollback链接:则将两个undo块链起来(新指向旧),链接可以方便回滚。
l CR链接:xid与uid链接,使构造CR块不必访问段头的地址(一致性读)。
l 提交方式:xid链接到事务表。
甲骨论37课深入剖析事务槽及Oracle多种提交方式
>selectINI_TRANS,MAX_TRANS from dba_tables where table_name=’T2’ //查询事务槽相关信息
Oracle为减数据块的争用,尽量对事务槽的征用分布到多个块中。
dump出事务槽的方法:
l >select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid),idfrom t10;//查询进程ID号对应的段号和块号
l >select ubafil,ubablk,xidusn,xidslot,xidsgn,start_scnb from v$transaction;//从事务表查看uba的段号及块号、段号、槽位号、被覆盖次数。
l >select * from v$rollname; //查询段名字
l >alter system dump undo header ‘_SYSSMU8$’;//dump出段头
l >alter system dump datafile 2 block 4308;//dump出2号段头的4308号的回滚块
l >select spid from vsession where sid=(select sid from v$mystat where rownum=1));//查看当前会话的进程编号
l 从文件查看事务槽:
1) #cd $ORACLE/admin/数据库名/udump/;ls块号;
2) #vim 此文件,可以看到事务槽It1事务槽编号;Xid事务ID;Uba回滚块;Flag是否已提交;Lck锁定标记;Scn/Fsc提交时间点。
事务操作流程:
1) 回滚段事务表里找到一个事务槽,同时分配一个回滚块。事务表写入xid指向回滚块。
2) 修改块中的事务槽指向”回滚段事务表听xid”。
3) 修改块中的uba指向回滚块。
4) 修改数据行,数据行头部指向事务槽。(被改块的事务槽中有事务提交标志,不必查回滚段的段头)
5) 当需要的访问”行头指向的事务槽编号”时,此行有已提交和未提交两种情况,根据已提交标志作判断是否可使用。(事务信息既要写在回滚段段头又要写要被修改块的事务槽中共**2处的原因**)
1000个块的提交需要访问所有的块,以改变提交方式。可能有800个块已由DBwriter写入磁盘,变成干净块被覆盖,再访问时不存在。因此2处写事务信息虽然更新数据行高效,但是带来提交commit需要过多修改事务信息。
因而需要快速提交技术。当大量块提交时,只更新回滚段段头的事务信息,对于被修改块的事务信息不更新或少量更新。
当修改数据块,从而需要更新事务信息时,以”回滚段的段头事务信息”为准对”修改块的事务信息”更新。
行前加事务槽编号,相当于对该行数据加锁(行级锁概念)。对于sqlServer的块级锁,Oracle的并发性更好些。
不仅增删改产生redo,select查询也会操作redo。select会清除”行锁”。当有行锁,且查得被修改块的事务槽未提交,若再去查回滚段的事务槽已提交,则更新被修改块的事务槽并产生日志。若回滚段的事务槽也未提交(说明确实未提交),则根据锁找到事务槽,根据事务槽找到undo块。拷贝undo块到CR块供查询,保持数据一致性。
如果需要查询的数据块覆盖次数小于当前覆盖次数,则直接认为已提交。
甲骨论38课IMU及Redo Private Strands技术
传统oracle的undo机制:申请的回滚段的段头事务槽不在内存时,从磁盘读入。当构造CR块时,可能需要的回滚块已经被DBwriter写到磁盘上,再使用时需要从新读磁盘获取。
IMU技术:在shared pool分配个IMU buffer用于保存回滚块。实现快速构造CR块(从IMU buffer读回滚块而非undo表空间),实现读一致性。
一个事务分配一个IMUbuffer。IMU buffer中的日志在PrivateRedoAddress中产生,由LGWriter写回磁盘。IMU buffer写满时还是会被写回滚块UndoBlock中去。IMU由shared pool写到buffer cache的过程称为IMU flush。
IMU技术优点:事务获取undoBlock变快,CR读变快。
甲骨论39课读一致性(Ora-01555)错误机制分析及Undo表空间大小设置
通过回滚块构造CR块避免脏读(一个会话读到了另一个会话未提交的数据)。
读数据过程中表被修改,以开始读时的数据保持一致性。数据被修改时间不一致,则构造CR块读一致性时间相同的数据。若select执行时间太长、undo表空间压力很大(inactive被占用),导致undo表空间被覆盖,无法构造与”一致性时间”相同的CR块,报错snap shot too old(ora-01555 error)。由于select执行时间无法解决,只能增大undo表空间解决ora-01555错误。
图形界面EM-指导中心-还原管理-,可以根据”还原保留时间查询undo表空间大小。还原保留时间至少要大于最长select语句执行时间,闪回则需要保留更长的时间。
甲骨论40课字符集概述
字符集是字符和编码的对应表。
#locale –a;//显示Linux字符集
cmd:chcp //查看win字符集,中文的活动页代码936
字符集使用场合:
l 存储:固定长度字符char、可变长度字符varchar2、大对象clog、旧版大对象long等数据类型
l 存储:表名、列名、PL/SQL变量
l 存储PL/SQL程序单元
Oracle安装有数据库字符集和国家字符集。nchar、nvarchar2、nclog数据类型使用国家字符集。国家字符集作为数据库字符集的补充,用的较少。
常用字符集:
l US7ASCII英文
l ZHS16GBK中文
l UTF8万国码
l AL32UTF8适用于数据库字符集
l AF16UTF16适用于国家字符集
甲骨论41课字符集正确设置及相关操作
Linux+PTserver+RAC结构。UNIX性能和稳定性更好。Oracle从客户端的NLS_LANG参数获得编码方式。Oracle将接收数据先转码后存储。转码时字符集找不到存?出现字符丢失的问题。
NLS_LANG必需设置为客户端字符集:
l win:set NLS_LANG=american_america.zhs16gbk //客户端设置语言、地区、字符集。其中语言是提示信息的语言,地区影响日期格式、货币符号,字符集是客户端编码
NLS_LANG设置为与服务端编码方式,是个隐蔽的错误。虽然未转码,但是存储和访问都不会报错。错误设置前的存储显示出错,错误设置后的存储编码错误。
dump(列名,1016) //将列名以16进制显示,1008八进制,1010十进制。用来查询存储的编码方式。
字符集错误中,存储错误的字符编码是不可逆的,存储正确的字符编码只要改正NLS_LANG即可。