一、UNDO的产生
10年积累的网站制作、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计后付款的网站建设流程,更有新乡免费网站建设让你可以放心的选择与我们合作。
dml操作会产生undo的数据块。
update时, server process会在 databuffer中找到该记录的记录块,没有就从datafile中找并读入 data buffer。在修改之前,先放到undo段 active状态,并在数据块头记录undo段中该数据块的位置,读写这个块时会占用事务槽,会将该事务号记录在数据块的头部。然后进行 update,并将该块放到 dirty list检查点队列,等待dbwr进行写操作。
二、UNDO的作用
还原段的引入,主要是为了解决三个问题。
1 事务恢复:在进行DML操作时,insert、update、delete操作时,undo段记录事务的反向操作并且redo日志也记录undo段的操作,既redo保护undo段的信息。当实例关闭或意外崩溃后,再次open时实例需要对没有commit的事务进行回滚,完成事务的恢复。
2 事务回滚:用户进行DML操作后没有进行commit,需要修改前的数据。只要该操作在undo段保护的时间内,此时执行rollback操作可以回滚到最近记录点或上一次commit操作后的状态,恢复到数据修改前的状态。
3 读一致性:当进行DML操作时,undo段会记录数据变更前的状态(通过构造原数据的一致性数据块)。如果用户还没有进行commit操作,其他人查询此条数据会看到数据变更前的状态。因为其他用户读到的数据是undo段中原数据块中的数据,保证没有commit的数据读取的一致性。
4 倒叙查询:flashback query、 flashback table
10G后增加了新特性一一闪回。利用undo已经提交的块,闪回数据库和表。已经提交的块 inactive数据是不能提交的,但可以倒回到某个时间点。
SQL>select name, flashback_on from v$database;
我们常常会忽略对它的监控,这会导致UNDO表空间可能出现以下问题:
1).空间使用率100%,导致DML操作无法进行。
2).告警日志中出现大量的ORA-01555告警错误。
3).实例恢复失败,数据库无法正常打开。
三、undo参数解析
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
1 初始化参数undo_management
该初始化参数用于指定UNDO数据的管理方式.如果要使用自动管理模式,为AUTO;如果使用手工管理模式,为MANUAL。
使用自动管理模式时,oracle会使用undo表空间管理undo管理;使用手工管理模式时,oracle会使用回滚段管理undo数据。
如果使用自动管理模式时,如果没有配置初始化参数UNDO_TABLESPACE。Oracle会自动选择第一个可用的UNDO表空间存放UNDO数据,如果没有可用的UNDO表空间,oracle会使用SYSTEM回滚段存放UNDO记录,并在ALTER文件中记载警告
2 undo_retention
该参数是一个时间值。说明当还原段中的事务在提交后继续保留的时间,为flashback等工具进行如闪回数据等操作,该参数默认值为900秒,可以动态修改。
当保留时间超过undo_retention所指定的时间以后,该undo块才能够被其他事务覆盖。当我们使用AUM的时候,并且设置了undo_retention以后,undo块的状态就会存在如下4种情况:
active:活跃的,表示正在使用该数据块的事务还没有提交或回滚。
inactive:不活跃的,表示该数据块上没有活动的事务,该状态的数据块可以被其他事务覆盖。
expired:达到时间上限的,表示该数据块持续inactive的时间已经超过了undo_retention所指定的时间,如果没有freed、
freed:已经释放的,表示该数据块是空的,从来没有使用过。
查看Oracle自动调整undo_retention的值可以通过以下查询获得:
select to_char(begin_time,'mm/dd/yyyy hh34:mi:ss') begin_tiem,TUNED_UNDORETENTION from v$undostat;
undo表空间获取空间的申请顺序
freed=>expired=>自动拓展(必须该参数为yes状态才可以)=>inactive(下面详细解释此种状态的覆盖)=>ORA-30036
而且在使用数据块时尽量使用相对更短的连续extent,如不足时才使用更连续的extent。这样能够减少碎片的产生。并且尽量不去覆盖inactive状态的数据块,如果空间足够会最大限度的保存此种状态的数据块包含的信息。
数据查询出现ORA-1555的原因,和如何避免出现?
ORA-1555错误的出现,共有两种原因。
首先解释一下Oracle在数据变更后,如何保证原始数据能够在变更数据不提交的情况下如何得到保护。
原始数据已经被update、delete等DML操作,但变更数据还未进行commit,此时Oracle通过UNDO段构造与原数据相同的一致性数据块,保证其他用户数据不会出现脏读。但在commit后该事务占用的回滚段事务状态会被标记为不活跃的(inactive),回滚段中此区段可以被覆盖重用。
a、回滚段数据被覆盖
出现原因:如果一个查询需要使用已经变更为inactive并且被覆盖的回滚段一致性读块内的数据,想实现一致性读,那么此时就会出现Oracle著名的ORA-01555错误。原因有SQL语句执行时间太长、UNDO表空间过小、事务量过大,提交过于频繁,导致执行SQL过程中进行一致性读时,修改的原数据(UNDO数据)在UNDO表空间中已经被覆盖,不能构造一致性读块。
避免出现的方法:尽量加大回滚段的容量,尽量将undo_retention参数内的提交后保留时间设置更大一些。如果需要保证原数据在retention保留时间内绝对能够查找,那么在保证回滚段容量足够用的前提下可以将表空间参数中加入
retention
guarantee以保证原数据的不被任何情况的覆盖。优化出错的SQL和尽量将大事务分割成小事务,并且不进行频繁的提交。
出现原因:相比第一种,这种出现的几率11g会低很多。不做深入。
设置undo_retention参数
SQL> alter system set undo_retention=1500;
再次查询
SQL> show parameter undo_retention;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 1500
3 UNDO表空间guarantee属性
SQL> SELECT tablespace_name, retention FROM dba_tablespaces where tablespace_name='UNDOTBS1';
TABLESPACE_NAME RETENTION
------------------------------ -----------
UNDOTBS1 NOGUARANTEE
修改RETENTION
SQL> alter tablespace undotbs1 retention guarantee;
再次查询
SQL> SELECT tablespace_name, retention FROM dba_tablespaces where tablespace_name='UNDOTBS1';
TABLESPACE_NAME RETENTION
------------------------------ -----------
UNDOTBS1
GUARANTEE
四、创建、维护undo表空间
1 创建
SQL> create undo tablespace undotab1 datafile '/ooradata/lxtab/test_undotab1.dbf' size 200m autoextend on;
--查询
SQL> select tablespace_name,extent_management,contents,logging,status from dba_tablespaces where tablespace_name='UNDOTAB1';
TABLESPACE_NAME EXTENT_MAN CONTENTS LOGGING STATUS
------------------------------ ---------- --------- --------- ---------
UNDOTAB1 LOCAL UNDO LOGGING ONLINE
--查询
SQL> col FILE_NAME for a50
select file_name,file_id,bytes/(1024*1024) M,autoextensible from dba_data_files where tablespace_name='UNDOTAB1';
FILE_NAME FILE_ID M AUT
-------------------------------------------------- ---------- ---------- ---
/ooradata/lxtab/test_undotab1.dbf 7 200 YES
具体语法看之前表空间语法部分,创建了一个200MB的undo表空间已经联机,管理方式为本地管理,已经受到日志保护,并且空间不足时自动增长空间。
2 undo表空间重命名
--先查看undo有哪些表空间
SQL> select tablespace_name,status,contents from dba_tablespaces where CONTENTS='UNDO';
TABLESPACE_NAME STATUS CONTENTS
------------------------------ --------- ---------
UNDOTBS1 ONLINE UNDO
UNDOTBS2 ONLINE UNDO
UNDOTBS ONLINE UNDO
UNDOTAB1 ONLINE UNDO
UNDOTAB2 ONLINE UNDO
--查询默认undo表空间
SQL> show parameter undo_tablespace;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1
a) 修改非系统默认UNDO表空间名
SQL> alter tablespace UNDOTAB1 rename to UNDOTAB_one;
验证
SQL> select tablespace_name,status,contents from dba_tablespaces where TABLESPACE_NAME='UNDOTAB_ONE';
TABLESPACE_NAME STATUS CONTENTS
------------------------------ --------- ---------
UNDOTAB_ONE ONLINE UNDO
非系统默认UNDO表空间修改后立即生效
b)修改系统默认undo表空间名
SQL> alter tablespace UNDOTBS1 rename to UNDOTBS_ONE;
验证
SQL> show parameter undo_tablespace;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS1
SQL> shutdown immediate;
SQL> startup
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 1500
undo_tablespace string UNDOTBS_ONE
3 向undo表空间添加数据文件
a)查询 UNDOTAB_ONE表空间大小
SQL> select tablespace_name,file_name,bytes/1024/1024 m,autoextensible from dba_data_files where tablespace_name='UNDOTAB_ONE';
TABLESPACE_NAME FILE_NAME M AUT
------------------------------ ---------------------------------------- ---------- ---
UNDOTAB_ONE /ooradata/lxtab/test_undotab1.dbf 200 YES
b) 添加数据文件
SQL> alter tablespace UNDOTAB_ONE add datafile'/ooradata/lxtab/test_undo_tab1.dbf' size 20m;
再次查询
SQL> select
tablespace_name,file_name,bytes/1024/1024 m,autoextensible from
dba_data_files where tablespace_name='UNDOTAB_ONE';
TABLESPACE_NAME FILE_NAME M AUT
------------------------------ ---------------------------------------- ---------- ---
UNDOTAB_ONE /ooradata/lxtab/test_undotab1.dbf 200 YES
UNDOTAB_ONE /ooradata/lxtab/test_undo_tab2.dbf 10 NO
把数据文件改为自动拓展
SQL> alter database datafile '/ooradata/lxtab/test_undo_tab2.dbf' autoextend on;
Database altered.
4 切换当前默认UNDO表空间
在实际生产中,如还原表空间的磁盘空间受限,还原表空间所在的磁盘过于繁忙(有其他进程争用),为了减少与其他进程争用带来的高I/O或者避免磁盘空间受限的限制。需要通过切换还原表空间来提高数据库的磁盘性能。
--
首先查看当前默认undo表空间
SQL> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTBS_ONE
--切换为UNDOTAB2
SQL> alter system set undo_tablespace=UNDOTAB2;
--再次查询
SQL> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDOTAB2
五、undo表空间使用情况
1 UNDOTAB2表空间总大小
SQL> select tablespace_name,sum(bytes/1024/1024) M from dba_data_files where tablespace_name='UNDOTAB2' group by tablespace_name;
TABLESPACE_NAME M
------------------------------ ----------
UNDOTAB2 200
2 UNDOTAB2表空间使用情况
SQL> select owner,segment_name,bytes/1024 k from dba_segments where tablespace_name='UNDOTAB2';
OWNER SEGMENT_NAME K
------------------------------ ------------------------- ----------
SYS _SYSSMU41_3529217193$ 128
SYS _SYSSMU42_3691377120$ 128
SYS _SYSSMU43_2276363185$ 128
SYS _SYSSMU44_2801918226$ 128
SYS _SYSSMU45_3144470353$ 128
SYS _SYSSMU46_163396642$ 128
SYS _SYSSMU47_813829394$ 128
SYS _SYSSMU48_3430728809$ 128
SYS _SYSSMU49_2193813215$ 128
SYS _SYSSMU50_858471824$ 128
10 rows selected.
SQL> select segment_name, v.rssize/1024 k From dba_rollback_segs r, v$rollstat v Where r.segment_id = v.usn(+) order by segment_name ;
SEGMENT_NAME K
------------------------- ----------
_SYSSMU3_1723003836$
_SYSSMU40_3968832332$
_SYSSMU41_3529217193$ 120
_SYSSMU42_3691377120$ 120
_SYSSMU43_2276363185$ 120
_SYSSMU44_2801918226$ 120
_SYSSMU45_3144470353$ 120
_SYSSMU46_163396642$ 120
_SYSSMU47_813829394$ 120
_SYSSMU48_3430728809$ 120
_SYSSMU49_2193813215$ 120
通过上面的两个查询可以看出,两个视图查询的值几乎一致,
通常在巡检的时候,我们习惯查询dba_segments视图来确定UNDO表空间的使用情况,但查询V$ROLLSTAT数据更加准确。
3 删除表空间
SQL> drop tablespace UNDOTAB2 including contents and datafiles;
五、闪回
1 闪回需要开归档
a)查看归档状态
SQL> show parameter recovery;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest
string
db_recovery_file_dest_size big integer 0
recovery_parallelism integer 0
b)建立归档路径,并改变授权
ORACLE>mkdir /flash
ORACLE>chown oracle:oinstall /flash
c)设置大小和归档路径--一定要先制定大小
SQL> alter system set DB_RECOVERY_FILE_DEST_SIZE=4g scope=both;
SQL> alter system set db_recovery_file_dest='/flash' scope=both;
d)关闭数据库,启动到mount状态
shutdown immediate
startup mount
e)开启归档
SQL> alter database flashback on;
f)启动数据库
alter database open;
验证
SQL> show parameter recovery;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /flash
db_recovery_file_dest_size big integer 4G
recovery_parallelism integer 0
SQL> select name,flashback_on from v$database;
NAME FLASHBACK_ON
--------- ------------------
TEST YES
关闭闪回:需要重复步骤d,e步骤是SQL>alter database flashback off; 再进行步骤f
注意 :步骤c也可以使用修改参数的方式
ORACLE>cd $ORACLE_HOME/dbs
vi intitest.ora
2 闪回的作用
查询闪回文件大小
SQL> select name,bytes/1048576 m from v$sgastat where pool='shared pool' and name like '%flash%';
后续再细讲