RMAN> list backup of archivelog all;
列出所有archive log 备份
RMAN> list backup of archivelog from logseq 100 until logseq 120;
列出archive log 从100到120
RMAN> list backup of archivelog sequence between 100 and 110;
列出archive log 从100到120
–说明:between……and只能使用sequence,而不能使用logseq
RMAN> list backup of archivelog from logseq 100;
列出seq大于等于100的archive log
RMAN> list backup of archivelog low logseq 120;
列出seq大于等于120的archive log
RMAN> list backup of archivelog sequence 100;
列出seq为100的archive log
–说明:在对于rman中关于archivelog的操作中logseq与sequence作用相同,但是建议尽量使用sequence
RMAN> list backup of archivelog logseq 85;
列出seq为85的archive log
RMAN> list backup of archivelog until logseq 85;
列出seq小于等于85的archive log
RMAN> list backup of archivelog high logseq 40;
列出seq小于等于40的archive log
RMAN> list backup of archivelog from time ‘sysdate-7’;
列出7天以前的archive log
RMAN> run {
2> set archivelog destination to ‘/opt/oracle/oradata/test/newlog’;
3> restore archivelog low logseq 40;
4> }
从seq为40开始,恢复到/opt/oracle/oradata/test/newlog中
–说明:list backup of archivelog中限定日志的位置也适合restore archivelog
RMAN> backup archivelog sequence between 100 and 110 format ‘/tmp/text_test.rman’ delete input;
备份seq为100至110的archive log
–说明:list backup of archivelog中限定日志的位置也适合backup archivelog
RMAN>DELETE ARCHIVELOG ALL COMPLETED BEFORE ‘SYSDATE-7’;
删除7天前archive log
RMAN>DELETE ARCHIVELOG low logseq 40;
删除seq大于等于40的archive log
RMAN> crosscheck archivelog all;
RMAN> delete expired archivelog all;
删除无效archive log
–说明:DELETE ARCHIVELOG中限定日志的位置也适合restore archivelog
对/dev/shm认识
一、/dev/shm理论
/dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里。因此在linux下,就不需要大费周折去建ramdisk,直接使用/dev/shm/就可达到很好的优化效果。 /dev /shm/需要注意的一个是容量问题,在linux下,它默认最大为内存的一半大小,使用df -h命令可以看到。但它并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节;如果它最大为1G,里头放有 100M文件,那剩余的900M仍然可为其它应用程序所使用,但它所占用的100M内存,是绝不会被系统回收重新划分的,否则谁还敢往里头存文件呢?
默认系统就会加载/dev/shm ,它就是所谓的tmpfs,有人说跟ramdisk(虚拟磁盘),但不一样。象虚拟磁盘一样,tmpfs 可以使用您的 RAM,但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备,并需要一个 mkfs 之类的命令才能真正地使用它,tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。
tmpfs有以下优势:
1,动态文件系统的大小。
2,tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中,读写几乎可以是瞬间的。
3,tmpfs 数据在重新启动之后不会保留,因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载,绑定的操作。
二、修改/dev/shm大小
默认的最大一半内存大小在某些场合可能不够用,并且默认的inode数量很低一般都要调高些,这时可以用mount命令来管理它。
#mount -o size=1500M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm
在2G的机器上,将最大容量调到1.5G,并且inode数量调到1000000,这意味着大致可存入最多一百万个小文件。
如果需要永久修改/dev/shm的值,需要修改/etc/fstab
tmpfs /dev/shm tmpfs defaults,size=1.5G 0 0
#mount -o remount /dev/shm
三、/dev/shm应用
首先在/dev/shm建个tmp文件夹,然后与实际/tmp绑定
#mkdir /dev/shm/tmp
#chmod 1777 /dev/shm/tmp
#mount –bind /dev/shm/tmp /tmp(–bind )
在使用mount –bind olderdir newerdir命令来挂载一个目录到另一个目录后,newerdir的权限和所有者等所有信息会发生变化。挂载后的目录继承了被挂载目录的所有属性,除了名称。Oracle 11g的amm内存管理模式就是使用/dev/shm,所以有时候修改MEMORY_TARGET或者MEMORY_MAX_TARGET会出现ORA-00845的错误
升级到Oracle 10.2.0.4
一、单实例升级先决条件:
1.表空间需求
确保system表空间至少有10M空间可用
2.系统参数:
确保参数SHARED_POOL_SIZE 和 JAVA_POOL_SIZE大于150MB以上,为加快升级速度,在系统内存可用的情况下,可临时调大这2个参数
SQL> SHOW PARAMETER SHARED_POOL_SIZE
SQL> SHOW PARAMETER JAVA_POOL_SIZE
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE=’200M’ SCOPE=spfile;
SQL> ALTER SYSTEM SET JAVA_POOL_SIZE=’200M’ SCOPE=spfile;
二、实施升级
1.关闭需要升级的实例
停止实例
SQL> shutdown immediate
停止与该实例相关的所有后台进程
$ emctl stop dbconsole
$ isqlplusctl stop
$ lsnrctl stop
2.备份Oracle Home 目录及数据库
tar -cvf $ORACLE_BASE /orabak/ –确保Oracle相关的所有配置都位于$ORACLE_BASE目录,如监听等
cp *.dbf con*.ora redo*.log /orabak/ –对数据库实施冷备
3.升级软件
./runIstanller –>oracle 账户
root.sh –>root 账户
4.更新数据字典
SQL> startup upgrade
SQL> spool patch.log
SQL> @?/rdbms/admin/catupgrd.sql –注9i 使用catpatch.sql
SQL> spool off
SQL> !egrep “ORA-|Error” patch.log -i
5.重编译失效对象:
sql>shutdown immediate
sql>startup
SQL>@?/rdbms/admin/utlrp.sql
6.修改兼容性参数
SQL> alter system set compatible=’10.2.0.4.0′ scope=spfile;
7.如果使用了恢复目录,则执行下面的命令
$ rman catalog username/password@alias
RMAN> UPGRADE CATALOG;
8.如果升级回退:
SQL> STARTUP DOWNGRADE
SQL> SPOOL downgrade.log
SQL> @catdwgrd.sql(10.2.10运行的是这个,而10.1降级用的是d92000.sql,即dold_release.sql)
SQL>spool off
SQL>shutdown immediate
9.重新启动数据库:
SQL> SHUTDOWN
SQL> STARTUP
$ lsnrctl start
$ isqlplusctl start
$ emctl start dbconsole
10.检查升级后的情况
SQL> col comp_name for a35
SQL> col comp_name for a30
SQL> col version for a10
SQL> select comp_name,version,status from sys.dba_registry;
COMP_NAME VERSION STATUS
———————————– ———- ———————-
Oracle Database Catalog Views 10.2.0.4.0 VALID
Oracle Database Packages and Types 10.2.0.4.0 VALID
Oracle Workspace Manager 10.2.0.4.3 VALID
JServer JAVA Virtual Machine 10.2.0.4.0 VALID
Oracle XDK 10.2.0.4.0 VALID
Oracle Database Java Packages 10.2.0.4.0 VALID
Oracle Expression Filter 10.2.0.4.0 VALID
Oracle Data Mining 10.2.0.4.0 VALID
Oracle Text 10.2.0.4.0 VALID
Oracle XML Database 10.2.0.4.0 VALID
Oracle Rule Manager 10.2.0.4.0 VALID
COMP_NAME VERSION STATUS
———————————– ———- ———————-
Oracle interMedia 10.2.0.4.0 VALID
OLAP Analytic Workspace 10.2.0.4.0 VALID
Oracle OLAP API 10.2.0.4.0 VALID
OLAP Catalog 10.2.0.4.0 VALID
Spatial 10.2.0.4.0 VALID
Oracle Enterprise Manager 10.2.0.4.0 VALID
17 rows selected.
SQL> select * from utl_recomp_errors;
no rows selected
10g新增列方式指定HINT
在9i和以前的版本,索引提示的格式为/*+ index(table_alias) */或/*+ index(table_alias index_name) */,但是在10g中不仅可以通过索引名称来确定HINT的索引,还可以通过指定列名的方式,格式为/*+ index(table_alias (column_names)) */
SQL> create table test_hint 2 as 3 select * from dba_objects; Table created. SQL> create index ind_hint on test_hint(owner,object_type); Index created. SQL> exec dbms_stats.gather_table_stats(user, 'TEST_HINT', 2 method_opt => 'for all indexed columns size 100',cascade=>true); PL/SQL procedure successfully completed. SQL> set autot trace exp SQL> select * from test_hint where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 11101196 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 161 (1)| 00:00:02 | |* 1 | TABLE ACCESS FULL| TEST_HINT | 23272 | 2113K| 161 (1)| 00:00:02 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OWNER"='SYS') SQL> select /*+index(a)*/ * from test_hint a where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 890897193 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 1122 (1)| 00:00:14 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_HINT | 23272 | 2113K| 1122 (1)| 00:00:14 | |* 2 | INDEX RANGE SCAN | IND_HINT | 23272 | | 84 (0)| 00:00:02 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OWNER"='SYS') SQL> select /*+index(a ind_hint)*/ * from test_hint a where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 890897193 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 1122 (1)| 00:00:14 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_HINT | 23272 | 2113K| 1122 (1)| 00:00:14 | |* 2 | INDEX RANGE SCAN | IND_HINT | 23272 | | 84 (0)| 00:00:02 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OWNER"='SYS') SQL> select /*+index(a (owner,object_type))*/ * from test_hint a where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 890897193 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 1122 (1)| 00:00:14 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_HINT | 23272 | 2113K| 1122 (1)| 00:00:14 | |* 2 | INDEX RANGE SCAN | IND_HINT | 23272 | | 84 (0)| 00:00:02 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OWNER"='SYS') --指定和index完全一致的列,走index SQL> select /*+index(a (owner))*/ * from test_hint a where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 890897193 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 1122 (1)| 00:00:14 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_HINT | 23272 | 2113K| 1122 (1)| 00:00:14 | |* 2 | INDEX RANGE SCAN | IND_HINT | 23272 | | 84 (0)| 00:00:02 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OWNER"='SYS') --指定列和where条件一致,也可以使用该index SQL> select /*+index(a (object_id))*/ * from test_hint a where owner = 'SYS'; Execution Plan ---------------------------------------------------------- Plan hash value: 11101196 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 23272 | 2113K| 161 (1)| 00:00:02 | |* 1 | TABLE ACCESS FULL| TEST_HINT | 23272 | 2113K| 161 (1)| 00:00:02 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OWNER"='SYS') --虽然是index中的一个列,但是由于不是where条件中,所以不能被使用 SQL> select /*+index(a (owner))*/ * from test_hint a where object_type = 'TABLE'; Execution Plan ---------------------------------------------------------- Plan hash value: 1755360976 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1752 | 159K| 104 (0)| 00:00:02 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_HINT | 1752 | 159K| 104 (0)| 00:00:02 | |* 2 | INDEX SKIP SCAN | IND_HINT | 1752 | | 25 (0)| 00:00:01 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_TYPE"='TABLE') filter("OBJECT_TYPE"='TABLE') --指定index的第一列,虽然不在where中,但是还是会使用index --说明:使用/*+ index(table_alias (column_names)) */方式的hint,需要先测试,有可能不能达到预期效果
TOM的SHOW_SPACE过程使用
TOM写了个好工具SHOW_SPACE,这个工具对于Oracle来讲其实就是个存储过程,这个存储过程可以用来分析空间使用情况,有了此工具,就不用再通过写SQL语句来看每条记录或表占用表空间的大小了,使用起来很方便。
create or replace procedure show_space ( p_segname_1 in varchar2, p_owner_1 in varchar2 default user, p_type_1 in varchar2 default 'TABLE', p_space in varchar2 default 'AUTO', p_analyzed in varchar2 default 'Y' ) as p_segname varchar2(100); p_type varchar2(10); p_owner varchar2(30); l_unformatted_blocks number; l_unformatted_bytes number; l_fs1_blocks number; l_fs1_bytes number; l_fs2_blocks number; l_fs2_bytes number; l_fs3_blocks number; l_fs3_bytes number; l_fs4_blocks number; l_fs4_bytes number; l_full_blocks number; l_full_bytes number; l_free_blks number; l_total_blocks number; l_total_bytes number; l_unused_blocks number; l_unused_bytes number; l_LastUsedExtFileId number; l_LastUsedExtBlockId number; l_LAST_USED_BLOCK number; procedure p( p_label in varchar2, p_num in number ) is begin dbms_output.put_line( rpad(p_label,40,'.') || p_num ); end; begin p_segname := upper(p_segname_1); -- rainy changed p_owner := upper(p_owner_1); p_type := p_type_1; if (p_type_1 = 'i' or p_type_1 = 'I') then --rainy changed p_type := 'INDEX'; end if; if (p_type_1 = 't' or p_type_1 = 'T') then --rainy changed p_type := 'TABLE'; end if; if (p_type_1 = 'c' or p_type_1 = 'C') then --rainy changed p_type := 'CLUSTER'; end if; dbms_space.unused_space ( segment_owner => p_owner, segment_name => p_segname, segment_type => p_type, total_blocks => l_total_blocks, total_bytes => l_total_bytes, unused_blocks => l_unused_blocks, unused_bytes => l_unused_bytes, LAST_USED_EXTENT_FILE_ID => l_LastUsedExtFileId, LAST_USED_EXTENT_BLOCK_ID => l_LastUsedExtBlockId, LAST_USED_BLOCK => l_LAST_USED_BLOCK ); if p_space = 'MANUAL' or (p_space <> 'auto' and p_space <> 'AUTO') then dbms_space.free_blocks ( segment_owner => p_owner, segment_name => p_segname, segment_type => p_type, freelist_group_id => 0, free_blks => l_free_blks ); p( 'Free Blocks', l_free_blks ); end if; p( 'Total Blocks', l_total_blocks ); p( 'Total Bytes', l_total_bytes ); p( 'Unused Blocks', l_unused_blocks ); p( 'Unused Bytes', l_unused_bytes ); p( 'Last Used Ext FileId', l_LastUsedExtFileId ); p( 'Last Used Ext BlockId', l_LastUsedExtBlockId ); p( 'Last Used Block', l_LAST_USED_BLOCK ); /*IF the segment is analyzed */ if p_analyzed = 'Y' then dbms_space.space_usage(segment_owner => p_owner , segment_name => p_segname , segment_type => p_type , unformatted_blocks => l_unformatted_blocks , unformatted_bytes => l_unformatted_bytes, fs1_blocks => l_fs1_blocks, fs1_bytes => l_fs1_bytes , fs2_blocks => l_fs2_blocks, fs2_bytes => l_fs2_bytes, fs3_blocks => l_fs3_blocks , fs3_bytes => l_fs3_bytes, fs4_blocks => l_fs4_blocks, fs4_bytes => l_fs4_bytes, full_blocks => l_full_blocks, full_bytes => l_full_bytes); dbms_output.put_line(rpad(' ',50,'*')); dbms_output.put_line('The segment is analyzed'); p( '0% -- 25% free space blocks', l_fs1_blocks); p( '0% -- 25% free space bytes', l_fs1_bytes); p( '25% -- 50% free space blocks', l_fs2_blocks); p( '25% -- 50% free space bytes', l_fs2_bytes); p( '50% -- 75% free space blocks', l_fs3_blocks); p( '50% -- 75% free space bytes', l_fs3_bytes); p( '75% -- 100% free space blocks', l_fs4_blocks); p( '75% -- 100% free space bytes', l_fs4_bytes); p( 'Unused Blocks', l_unformatted_blocks ); p( 'Unused Bytes', l_unformatted_bytes ); p( 'Total Blocks', l_full_blocks); p( 'Total bytes', l_full_bytes); end if; end; /
用法
SQL> create table t 2 as 3 select * from dba_objects; Table created. SQL> set serverout on SQL> exec show_space('T','TEST'); Total Blocks............................768 Total Bytes.............................6291456 Unused Blocks...........................52 Unused Bytes............................425984 Last Used Ext FileId....................4 Last Used Ext BlockId...................1033 Last Used Block.........................76 ************************************************* The segment is analyzed 0% -- 25% free space blocks.............0 0% -- 25% free space bytes..............0 25% -- 50% free space blocks............0 25% -- 50% free space bytes.............0 50% -- 75% free space blocks............0 50% -- 75% free space bytes.............0 75% -- 100% free space blocks...........0 75% -- 100% free space bytes............0 Unused Blocks...........................0 Unused Bytes............................0 Total Blocks............................696 Total bytes.............................5701632 PL/SQL procedure successfully completed. SQL> delete from t; 50602 rows deleted. SQL> exec show_space('T','TEST'); Total Blocks............................768 Total Bytes.............................6291456 Unused Blocks...........................52 Unused Bytes............................425984 Last Used Ext FileId....................4 Last Used Ext BlockId...................1033 Last Used Block.........................76 ************************************************* The segment is analyzed 0% -- 25% free space blocks.............0 0% -- 25% free space bytes..............0 25% -- 50% free space blocks............0 25% -- 50% free space bytes.............0 50% -- 75% free space blocks............0 50% -- 75% free space bytes.............0 75% -- 100% free space blocks...........696 75% -- 100% free space bytes............5701632 Unused Blocks...........................0 Unused Bytes............................0 Total Blocks............................0 Total bytes.............................0 PL/SQL procedure successfully completed. SQL> alter table t move; Table altered. SQL> exec show_space('T','TEST'); Total Blocks............................8 Total Bytes.............................65536 Unused Blocks...........................5 Unused Bytes............................40960 Last Used Ext FileId....................4 Last Used Ext BlockId...................401 Last Used Block.........................3 ************************************************* The segment is analyzed 0% -- 25% free space blocks.............0 0% -- 25% free space bytes..............0 25% -- 50% free space blocks............0 25% -- 50% free space bytes.............0 50% -- 75% free space blocks............0 50% -- 75% free space bytes.............0 75% -- 100% free space blocks...........0 75% -- 100% free space bytes............0 Unused Blocks...........................0 Unused Bytes............................0 Total Blocks............................0 Total bytes.............................0 PL/SQL procedure successfully completed.
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
truncate清空一张表记录发现ORA-02266,进行模拟测试
SQL> truncate table p; truncate table p * ERROR at line 1: ORA-02266: unique/primary keys in table referenced by enabled foreign keys --错误原因 SQL> !oerr ora 02266 02266, 00000, "unique/primary keys in table referenced by enabled foreign keys" // *Cause: An attempt was made to truncate a table with unique or // primary keys referenced by foreign keys enabled in another table. // Other operations not allowed are dropping/truncating a partition of a // partitioned table or an ALTER TABLE EXCHANGE PARTITION. // *Action: Before performing the above operations the table, disable the // foreign key constraints in other tables. You can see what // constraints are referencing a table by issuing the following // command: // SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME = "tabnam"; --查询是否有主键或者唯一index SET SERVEROUTPUT ON SET LINESIZE 1000 SET FEEDBACK OFF SET LONG 999999 SET PAGESIZE 1000 EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false);--不显示存储信息 SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','P') FROM DUAL; DBMS_METADATA.GET_DDL('TABLE','P') -------------------------------------------------------------------------------- CREATE TABLE "CHF"."P" ( "X" NUMBER(*,0), PRIMARY KEY ("X") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 TABLESPACE "USERS" ENABLE ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "USERS --查询主外键关系 SQL> col 主键表名 for a20 SQL> col 主键列名 for a20 SQL> col 外键表名 for a20 SQL> col 外键列名 for a20 SQL> select b.table_name 主键表名, b.column_name 主键列名, a.table_name 外键表名, a.column_name 外键列名 from (select a.constraint_name, b.table_name, b.column_name, a.r_constraint_name from dba_constraints a, dba_cons_columns b WHERE a.constraint_type = 'R' and a.constraint_name = b.constraint_name) a, (select distinct a.r_constraint_name, b.table_name, b.column_name from dba_constraints a, dba_cons_columns b WHERE a.constraint_type = 'R' and a.r_constraint_name = b.constraint_name) b where a.r_constraint_name = b.r_constraint_name and b.table_name='P'; 主键表名 主键列名 外键表名 外键列名 -------------------- -------------------- -------------------- -------------------- P X C X 1 row selected. --处理方法一 SQL> alter table p disable primary key cascade; Table altered. SQL> truncate table p; Table truncated. SQL> alter table p enable primary key; Table altered. --处理方法二 SQL> delete from t; 1 row deleted. SQL> commit; Commit complete.
自治事件引起死锁
今天遇到一个比较特殊的死锁现象,记录下来
DEADLOCK DETECTED ( ORA-00060 ) [Transaction Deadlock] The following deadlock is not an ORACLE error. It is a deadlock due to user error in the design of an application or from issuing incorrect ad-hoc SQL. The following information may aid in determining the deadlock: Deadlock graph: ---------Blocker(s)-------- ---------Waiter(s)--------- Resource Name process session holds waits process session holds waits TX-00090022-000002ba 15 145 X 15 145 X session 145: DID 0001-000F-00000019 session 145: DID 0001-000F-00000019 Rows waited on: Session 145: obj - rowid = 0000E0A3 - AAAOCjAAFAAAAA8AAA (dictionary objn - 57507, file - 5, block - 60, slot - 0) Information on the OTHER waiting sessions: End of information on OTHER waiting sessions. Current SQL statement for this session: UPDATE T SET Y = Y WHERE X = :B1 ----- PL/SQL Call Stack ----- object line object handle number name 0x67987910 4 CHF.T ===================================================
问题原因:自治事件导致(重现)
drop table t; create table t ( x int, y int ); create or replace trigger t before update on t for each row declare pragma autonomous_transaction; begin update t set y = y where x = :new.x; commit; end; / insert into t values ( 1, 1 ); commit; update t set y = y where x = 1;
DUMPING ORACLE BLOCKS
我见识过的,讲的最好的关于dump相关的文章,这个里面关于dump block,dump index,dump controlfile说的比较详细,看了收获不小,现在贡献出来和大家分享
如何阅读oracle数据块的dump文件
http://www.xifenfei.com/wp-content/uploads/2011/09/read_oracle_dump.pdf
假坏块引起恐慌
alert文件出现如下日志
Fri Sep 16 02:58:25 2011
Hex dump of (file 19, block 1444767) in trace file /opt/oracle/admin/ora9i/udump/ora9i_ora_24702.trc
Corrupt block relative dba: 0x04d60b9f (file 19, block 1444767)
Fractured block found during backing up datafile
Data in bad block:
type: 6 format: 2 rdba: 0x04d60b9f
last change scn: 0x0abf.56961827 seq: 0x1 flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x7c340601
check value in block header: 0xba17
computed block checksum: 0x6413
Reread of blocknum=1444767, file=/opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf. found valid data
因为这个是我们比较重要的业务服务器,如果出现坏块,不能及时处理,后果将不堪设想,因此我马上检查
先查看是什么对象:(结果是一个分区表的index,担心减少一半,index大不了重建,无大事)
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME FROM DBA_EXTENTS A WHERE FILE_ID = &FILE_ID AND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;
然后检查是否真的坏块
方法一:dbv
[oracle@DB1 bdump]$ dbv file=/opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf blocksize=8192 DBVERIFY: Release 10.2.0.4.0 - Production on Fri Sep 16 09:15:11 2011 Copyright (c) 1982, 2007, Oracle. All rights reserved. DBVERIFY - Verification starting : FILE = /opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf DBVERIFY - Verification complete Total Pages Examined : 2207744 Total Pages Processed (Data) : 0 Total Pages Failing (Data) : 0 Total Pages Processed (Index): 2201581 Total Pages Failing (Index): 0 Total Pages Processed (Other): 3271 Total Pages Processed (Seg) : 0 Total Pages Failing (Seg) : 0 Total Pages Empty : 2892 Total Pages Marked Corrupt : 0 Total Pages Influx : 0 Highest block SCN : 1454468581 (2751.1454468581)
结论无坏块
方法二:bbed
[oracle@DB1 lib]$ bbed Password: BBED: Release 2.0.0.0.0 - Limited Production on Fri Sep 16 10:01:26 2011 Copyright (c) 1982, 2007, Oracle. All rights reserved. ************* !!! For Oracle Internal Use only !!! *************** BBED> set filename '/opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf' FILENAME /opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf BBED> set block 1444767 BLOCK# 1444767 BBED> VERIFY DBVERIFY - Verification starting FILE = /opt/oracle/oradata/ora9i/TS_INDX_Base.005.dbf BLOCK = 1444767 DBVERIFY - Verification complete Total Blocks Examined : 1 Total Blocks Processed (Data) : 0 Total Blocks Failing (Data) : 0 Total Blocks Processed (Index): 1 Total Blocks Failing (Index): 0 Total Blocks Empty : 0 Total Blocks Marked Corrupt : 0 Total Blocks Influx : 0
再次证明无坏块
方法三:rman
RMAN> backup validate datafile 19;
结果查询V$BACKUP_CORRUPTION也无坏块
方法四:使用index查询
结果也正常,没报错,alert中无错误记录
发现alert报错,但是实际没有错误,查询相关资料发现
从日志中可以看到,提示Corrupt的block对应的dba为0x04d60b9f (file 19, block 1444767),data block的类型为6(6为trans data,所有的data和index blocks都是该类型)。Oracle发现block有可能corrupt后,进行了reread,结果为found valid data,说明数据块未损坏。Fractured block found,表示rman发现这个数据块正在被使用,这时rman会进行重新读取,如果再次失败,才认为是坏块。如果第二次尝试读取时成功,则表示数据完好,不会产生影响。此类信息在IO负载较高的情况下进行rman备份时比较容易出现。
查询系统发现,正好该时间段是系统io负载最高的时候
ORA-00600 [ktbdchk1: bad dscn] 解决
启动数据库报错 SQL> startup ORACLE instance started. Total System Global Area 167772160 bytes Fixed Size 1260720 bytes Variable Size 150995792 bytes Database Buffers 8388608 bytes Redo Buffers 7127040 bytes Database mounted. ORA-01092: ORACLE instance terminated. Disconnection forced alert.log导错 Wed Aug 10 12:31:11 2011 Errors in file /u01/admin/xienfei/udump/xff_ora_8568.trc: ORA-00600: internal error code, arguments: [ktbdchk1: bad dscn], [], [], [], [], [], [], [] xff_ora_8568.trc内容 [ktbdchk] -- readers_dsz -- bad dscn scn: 0x0000.b1e60c00scn: 0x0000.0011fca1 *** 2011-08-10 12:31:11.998 ksedmp: internal or fatal error ORA-00600: internal error code, arguments: [ktbdchk1: bad dscn], [], [], [], [], [], [], [] Current SQL statement for this session: select ctime, mtime, stime from obj$ where obj# = :1 根据上面错误判断,错误的scn为b1e60c00,不是整个数据文件的scn错误 而应该是一个对象的scn错误,所以继续在xff_ora_8568.trc文件中查找b1e60c00 找到结果如下: Block header dump: 0x0040007a Object id on Block? Y seg/obj: 0x12 csc: 0x00.b1e60c00 itc: 1 flg: - typ: 1 - DATA fsl: 0 fnx: 0x0 ver: 0x01 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0008.02a.000001d9 0x00802341.01bb.04 ---- 1 fsc 0x0000.0011ae7c data_block_dump,data header at 0x20fd6044 =============== tsiz: 0x1fb8 hsiz: 0xea pbl: 0x20fd6044 bdba: 0x0040007a 76543210 flag=-------- ntab=1 nrow=108 frre=-1 fsbo=0xea fseo=0x453 avsp=0x369 tosp=0x369 0xe:pti[0] nrow=108 offs=0 根据这个提示,发现dba为:0040007a的对象异常,查找对应的file_id,block SQL> SELECT DBMS_UTILITY.data_block_address_file (TO_NUMBER ('40007a', 'XXXXXXXX')) file_id, 2 DBMS_UTILITY.data_block_address_block (TO_NUMBER ('40007a', 'XXXXXXXX')) block_id 3 FROM DUAL; FILE_ID BLOCK_ID ---------- ---------- 1 122 使用bbed查看file=1,block=122的scn情况 BBED> p ktbbh struct ktbbh, 48 bytes @20 ub1 ktbbhtyp @20 0x01 (KDDBTDATA) union ktbbhsid, 4 bytes @24 ub4 ktbbhsg1 @24 0x00000012 ub4 ktbbhod1 @24 0x00000012 struct ktbbhcsc, 8 bytes @28 ub4 kscnbas @28 0xb1e60c00 ub2 kscnwrp @32 0x0000 b2 ktbbhict @36 1 ub1 ktbbhflg @38 0x02 (NONE) ub1 ktbbhfsl @39 0x00 ub4 ktbbhfnx @40 0x00000000 struct ktbbhitl[0], 24 bytes @44 struct ktbitxid, 8 bytes @44 ub2 kxidusn @44 0x0008 ub2 kxidslt @46 0x002a ub4 kxidsqn @48 0x000001d9 struct ktbituba, 8 bytes @52 ub4 kubadba @52 0x00802341 ub2 kubaseq @56 0x01bb ub1 kubarec @58 0x04 ub2 ktbitflg @60 0x0001 (NONE) union _ktbitun, 2 bytes @62 b2 _ktbitfsc @62 0 ub2 _ktbitwrp @62 0x0000 ub4 ktbitbas @64 0x0011ae7c 果然发现scn为0xb1e60c00,现在把其修改为:0x00124ac6(注意规则,一般linux下都是倒序) BBED> set offset 28 OFFSET 28 BBED> m /x c64a1200 BBED-00209: invalid number (c64a1200) 小技巧,一次性修改报错,尝试一次修改一点 BBED> m /x c64a File: /u01/oradata/xienfei/system01.dbf (0) Block: 122 Offsets: 28 to 43 Dba:0x00000000 ------------------------------------------------------------------------ c64ae6b1 00000000 01000200 00000000 <32 bytes per line> BBED> set offset +2 OFFSET 30 BBED> m /x 1200 File: /u01/oradata/xienfei/system01.dbf (0) Block: 122 Offsets: 30 to 45 Dba:0x00000000 ------------------------------------------------------------------------ 12000000 00000100 02000000 00000800 <32 bytes per line> BBED> set offset -2 OFFSET 28 BBED> dump File: /u01/oradata/xienfei/system01.dbf (0) Block: 122 Offsets: 28 to 43 Dba:0x00000000 ------------------------------------------------------------------------ c64a1200 00000000 01000200 00000000 <32 bytes per line> BBED> sum apply Check value for File 0, Block 122: current = 0x3a4e, required = 0x3a4e SQL> startup ORACLE instance started. Total System Global Area 167772160 bytes Fixed Size 1260720 bytes Variable Size 150995792 bytes Database Buffers 8388608 bytes Redo Buffers 7127040 bytes Database mounted. Database opened.