rman在归档与非归档时备份数据库的简单示例

oracle10g

如果数据库是非归档模式只有数据库在mount状态下才能进行备份

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 6442450944 bytes
Fixed Size                  2030368 bytes
Variable Size            1090520288 bytes
Database Buffers         5335154688 bytes
Redo Buffers               14745600 bytes

在nomount状态下是不能备份的

RMAN> backup database;

Starting backup at 31-OCT-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=154 devtype=DISK
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of backup command at 10/31/2012 14:22:22
ORA-01507: database not mounted

在mount状态下能进行备份

SQL> alter database mount;

Database altered.

RMAN> backup database;

Starting backup at 31-OCT-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=156 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00005 name=/u01/app/oracle/oradata/jytest/hygeia.dbf
input datafile fno=00003 name=/u01/app/oracle/oradata/jytest/sysaux01.dbf
input datafile fno=00002 name=/u01/app/oracle/oradata/jytest/undotbs01.dbf
input datafile fno=00001 name=/u01/app/oracle/oradata/jytest/system01.dbf
input datafile fno=00004 name=/u01/app/oracle/oradata/jytest/users01.dbf
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_nnndf_TAG20121031T142300_891jy4yv_.bkp tag=TAG20121031T142300 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:05:25
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_ncsnf_TAG20121031T142300_891k8co4_.bkp tag=TAG20121031T142300 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 31-OCT-12

如果数据库是归档模式数据库能在open和mount状态下能进行备份

SQL> startup
ORACLE instance started.

Total System Global Area 6442450944 bytes
Fixed Size                  2030368 bytes
Variable Size            1090520288 bytes
Database Buffers         5335154688 bytes
Redo Buffers               14745600 bytes
Database mounted.
Database opened.

RMAN> backup database;

Starting backup at 31-OCT-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=156 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00005 name=/u01/app/oracle/oradata/jytest/hygeia.dbf
input datafile fno=00003 name=/u01/app/oracle/oradata/jytest/sysaux01.dbf
input datafile fno=00002 name=/u01/app/oracle/oradata/jytest/undotbs01.dbf
input datafile fno=00001 name=/u01/app/oracle/oradata/jytest/system01.dbf
input datafile fno=00004 name=/u01/app/oracle/oradata/jytest/users01.dbf
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_nnndf_TAG20121031T142300_892jy4yv_.bkp tag=TAG20121031T142301 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:05:25
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_ncsnf_TAG20121031T142300_891k8co4_.bkp tag=TAG20121031T142300 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 31-OCT-12

SQL> startup mount
ORACLE instance started.

Total System Global Area 6442450944 bytes
Fixed Size                  2030368 bytes
Variable Size            1090520288 bytes
Database Buffers         5335154688 bytes
Redo Buffers               14745600 bytes
Database mounted.


RMAN> backup database;

Starting backup at 31-OCT-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=156 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00005 name=/u01/app/oracle/oradata/jytest/hygeia.dbf
input datafile fno=00003 name=/u01/app/oracle/oradata/jytest/sysaux01.dbf
input datafile fno=00002 name=/u01/app/oracle/oradata/jytest/undotbs01.dbf
input datafile fno=00001 name=/u01/app/oracle/oradata/jytest/system01.dbf
input datafile fno=00004 name=/u01/app/oracle/oradata/jytest/users01.dbf
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_nnndf_TAG20121031T142300_893jy4yv_.bkp tag=TAG20121031T142302 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:05:25
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: starting piece 1 at 31-OCT-12
channel ORA_DISK_1: finished piece 1 at 31-OCT-12
piece handle=/u01/app/oracle/flash_recovery_area/JYTEST/backupset/2012_10_31/o1_mf_ncsnf_TAG20121031T142300_891k8co4_.bkp tag=TAG20121031T142300 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 31-OCT-12

oracle bbed修改数据块的例子

比如我要修改SQL_TEXT=’8.0.0.0.0’为’9.0.0.0.0′

SQL> select     rowid,
  2  dbms_rowid.rowid_relative_fno(rowid)rel_fno,
  3  dbms_rowid.rowid_block_number(rowid)blockno,
  4  dbms_rowid.rowid_row_number(rowid) rowno,
  5  a.*
  6  from bootstrap$ a where rownum<2;

ROWID              REL_FNO  BLOCKNO    ROWNO  LINE#     OBJ#  SQL_TEXT
------------------ -------  ---------- ------ --------- ----- -----------
AAAAA4AABAAAAF6AAA   1        378       0       -1       -1    8.0.0.0.0

一般使用bbed,都是将一些配置信息写入到一个参数文本里,在调用bbed时,指定该参数文件。如:
$bbed parfile=bbed.par
先获取datafile 的信息
将datafile 的信息写入一个文件,格式为:文件编号 文件名字 文件大小。可以通过如下SQL 获取:

SQL>select file#||' '||name||' '||bytes from v$datafile ;

FILE#||''||NAME||''||BYTES
------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/jytest/system01.dbf 524288000
2 /u01/app/oracle/oradata/jytest/undotbs01.dbf 193986560
3 /u01/app/oracle/oradata/jytest/sysaux01.dbf 2149580800
4 /u01/app/oracle/oradata/jytest/users01.dbf 5242880
5 /u01/app/oracle/oradata/jytest/hygeia.dbf 21474836480

注意这里的file id。 我们这里的file id 和 oracle 系统内部的file id 相同。 当然这个id 我们也可以自己指定。 当我们在bbed 里设置file id 时,就是根据这个参数文件中的的设置来的。 最好设置为相同,不然以后可能会混淆。

将上面查询出来的datafile信息保存到文本里。

[oracle@weblogic28 lib]$ cat /u01/filelist.txt
1 /u01/app/oracle/oradata/jytest/system01.dbf 524288000
2 /u01/app/oracle/oradata/jytest/undotbs01.dbf 193986560
3 /u01/app/oracle/oradata/jytest/sysaux01.dbf 2149580800
4 /u01/app/oracle/oradata/jytest/users01.dbf 5242880
5 /u01/app/oracle/oradata/jytest/hygeia.dbf 21474836480

创建parameter file:

[oracle@weblogic28 lib]$ cat /u01/bbed.par
blocksize=8192
listfile=/u01/filelist.txt
mode=edit

使用parameter file 连接bbed:

[oracle@weblogic28 lib]$ ./bbed parfile=/u01/bbed.par
Password:

BBED: Release 2.0.0.0.0 - Limited Production on Wed Oct 31 14:39:28 2012

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

************* !!! For Oracle Internal Use only !!! ***************

BBED> set dba 1,378 offset 0
        DBA             0x0040017a (4194682 1,378)
        OFFSET          0

find 在指定的block中查找指定的字符串,结果是显示出字符串,及其偏移量–offset,偏移量就是在block中的字节数
查找关键字8.0.0.0.0,确定其在block中的偏移量offset。

BBED> find /c 8.0.0.0.0
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378              Offsets: 8181 to 8191           Dba:0x0040017a
------------------------------------------------------------------------
 302e302e 302e3001 065d01

 <32 bytes per line>

dump 查看具体内容:

BBED> dump /v dba 1,378 offset 8181 count 11
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378     Offsets: 8181 to 8191  Dba:0x0040017a
-------------------------------------------------------
 302e302e 302e3001 065d01            l 0.0.0.0..].

 <16 bytes per line>

从上面看到’8.’这两个字节没显示出来所示8.0.0.0.0的偏移量是从8179开始
count是指查看多少个字节的内容

BBED> dump /v dba 1,378 offset 8179 count 11
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378     Offsets: 8179 to 8189  Dba:0x0040017a
-------------------------------------------------------
 382e302e 302e302e 300106            l 8.0.0.0.0..

 <16 bytes per line>

modify 修改指定block的指定偏移量的值,可以在线修改。
由上可知偏移量8179就是’8’现将8修改成9

BBED> modify /c '9' dba 1,378 offset 8179
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378              Offsets: 8179 to 8189           Dba:0x0040017a
------------------------------------------------------------------------
 392e302e 302e302e 300106

 <32 bytes per line>

BBED> dump /v dba 1,378 offset 8179 count 11
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378     Offsets: 8179 to 8189  Dba:0x0040017a
-------------------------------------------------------
 392e302e 302e302e 300106            l 9.0.0.0.0..

 <16 bytes per line>

应用变更

BBED> sum dba 1,378
Check value for File 1, Block 378:
current = 0x13d5, required = 0x12d5
此时 current checksum 是0x13d5,requiredchecksum 是0x12d5
BBED> sum dba 1,378 apply
Check value for File 1, Block 378:
current = 0x12d5, required = 0x12d5

加上apply参数,使checksum一致。即之前的修改生效。

这时关闭数据库后打开数据库报错

SQL> startup
ORACLE instance started.

Total System Global Area 6442450944 bytes
Fixed Size                  2030368 bytes
Variable Size            1090520288 bytes
Database Buffers         5335154688 bytes
Redo Buffers               14745600 bytes
Database mounted.
ORA-01092: ORACLE instance terminated. Disconnection forced

错误信息如下(alertsid.log)

Errors in file /u01/app/oracle/admin/jytest/udump/jytest_ora_6148.trc:
ORA-00704: bootstrap process failure
ORA-00702: bootstrap verison '9.0.0.0.0' inconsistent with version '8.0.0.0.0'
Wed Oct 31 14:46:52 2012
Error 704 happened during db open, shutting down database
USER: terminating instance due to error 704
Instance terminated by USER, pid = 6148
ORA-1092 signalled during: ALTER DATABASE OPEN...
 bootstrap verison '9.0.0.0.0' inconsistent with version '8.0.0.0.0'
 

说明原来的值是’8.0.0.0.0’现在却是’9.0.0.0.0’所以数据库打不开

现在又将8.0.0.0.0修改成9.0.0.0.0

BBED> modify /c '8' dba 1,378 offset 8179
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378              Offsets: 8179 to 8189           Dba:0x0040017a
------------------------------------------------------------------------
 382e302e 302e302e 300106

 <32 bytes per line>

BBED> dump /v dba 1,378 offset 8179 count 11
 File: /u01/app/oracle/oradata/jytest/system01.dbf (1)
 Block: 378     Offsets: 8179 to 8189  Dba:0x0040017a
-------------------------------------------------------
 382e302e 302e302e 300106            l 8.0.0.0.0..

 <16 bytes per line>

BBED> sum dba 1,378
Check value for File 1, Block 378:
current = 0x12d5, required = 0x13d5

BBED> sum dba 1,378 apply
Check value for File 1, Block 378:
current = 0x13d5, required = 0x13d5
SQL> startup
ORACLE instance started.

Total System Global Area 6442450944 bytes
Fixed Size                  2030368 bytes
Variable Size            1090520288 bytes
Database Buffers         5335154688 bytes
Redo Buffers               14745600 bytes
Database mounted.
Database opened.

当把9.0.0.0.0修改成8.0.0.0.0时数据库就能正常打开了

Oracle dump函数的与utl_raw

函数式:

DUMP(expr[,return_fmt[,start_position][,length]])

基本参数时4个,最少可以填的参数是0个。当完全没有参数时,直接返回null。另外3个参数也都有各自的默认值:
expr:这个参数是要进行分析的表达式(数字或字符串等,可以是各个类型的值)
return_fmt:指返回参数的格式,有5种用法:
1)8:以8进制返回结果的值
2)10:以10进制返回结果的值(默认)
3)16:以16进制返回结果的值
4)17:以单字符的形式返回结果的值
5)1000:以上4种加上1000,表示在返回值中加上当前字符集
start_position:开始进行返回的字符位置
length:需要返回的字符长度

示例

sql> select dump('abc') from dual;

DUMP('ABC')
----------------------
Typ=96 Len=3: 97,98,99

sql> select dump('abc',16) from dual;

DUMP('ABC',16)
----------------------
Typ=96 Len=3: 61,62,63

sql> select dump('abc',1016) from dual;

DUMP('ABC',1016)
--------------------------------------------
Typ=96 Len=3 CharacterSet=ZHS16GBK: 61,62,63

sql> select dump('abc',17,2,2) from dual;

DUMP('ABC',17,2,2
-----------------
Typ=96 Len=3: b,c

结果的格式一般都是类似:Typ=96 Len=3 [CharacterSet=ZHS16GBK]: 61,62,63

type

typ表示当前的expr值的类型。如:2表示NUMBER,96表示CHAR。

CODE TYP
----- ------------------------------
1     VARCHAR2
2     NUMBER
8     LONG
12    DATE
23    RAW
24    LONG RAW
69    ROWID
96    CHAR
112   CLOB
113   BLOB
114   BFILE
180   TIMESTAMP
181   TIMESTAMP WITH TIMEZONE
182   INTERVAL YEAR TO MONTH
183   INTERVAL DAY TO SECOND
208   UROWID
231   TIMESTAMP WITH LOCAL TIMEZONE

len
len表示该值所占用的字节数。
对于汉字,ZHS16GBK编码一个汉字需要2个字节,UTF8需要3个字节。

Value
具体的存储值。返回的数值就是Oracle在自己内部对前面的这个expr值得存储形式。对于非汉字的普通字符串,可以理解为就是它的ASCII码。

SQL>  select to_number('3230','xxxx')from dual;

TO_NUMBER('3230','XXXX')
------------------------
                   12848
SQL>   select to_number('3430','xxxx')from dual;

TO_NUMBER('3430','XXXX')
------------------------
                   13360
SQL>      select to_number('3036','xxxx')from dual;

TO_NUMBER('3036','XXXX')
------------------------
                   12342

SQL>
SQL>      select chr(12848)from dual;

CHR(12848)
----------
20
SQL>       select chr(13360)from dual;

CHR(13360)
----------
40
SQL>      select chr(12342)from dual;

CHR(12342)
----------
06

将CHR(12848)+CHR(13360)+CHR(12342)=204006

utl_raw.cast_to_xxx()作为dump的逆函数

sql>select dump('201201',16) from dual;
dump('201201',16)
---------------------------------------------------------
Typ=96 Len=6: 32,30,31,32,30,31

sql>select utl_raw.cast_to_varchar2('323031323031') value from dual
201201

Oracle 数据类型CHAR, NCHAR, VARCHAR2, NVARCHAR2

CHAR与VARCHAR2

字符数据通常是以单字节存储在数据库字符集中:
CHAR
–固定长度的字符串最长可达2000个字节
–内部代码:96
VARCHAR@
–可变长的字符串最长可达4000个字节
–内部代码:1

CHAR
在一个类型为char的列中,所有空字节都会用空格来补充(字符32)
它的长度是固定的

SQL> select gr03,dump(gr03) from wb02 where gr03< '4307050000000097';

GR03             DUMP(GR03)
---------------- ---------------------------------------------------------------
4307050000000091 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,49
4307050000000092 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,50
430705000000093  Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,51
4307050000000094 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,52
43070500000095   Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,53

从上面的输出typ=96,len=16,可以看出char的内部代码是96,长度是16

varchar2
在一个类型为varchar2的列中,oracle不会使用空格来进行补位
它的长度是可变的

SQL> select dw02,dump(dw02) from wb01 where dw01< '0012';

DW02                       DUMP(DW02)
-------------------------- --------------------------------------------------------------------------------
灵活人员                   Typ=1 Len=8: 193,233,187,238,200,203,212,177
灵活就业人员               Typ=1 Len=12: 193,233,187,238,190,205,210,181,200,203,212,177
西湖区委、区管委           Typ=1 Len=16: 206,247,186,254,199,248,206,175,161,162,199,248,185,220,206,175
西湖区委、区管委办公室     Typ=1 Len=22: 206,247,186,254,199,248,206,175,161,162,199,248,185,220,206,175,17
西湖管理区政治部           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,213,254,214,206,178,191
西湖管理区监察局           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,188,224,178,236,190,214
西湖管理区财政局           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,178,198,213,254,190,214

从上面的输出typ=1可以看出varchar2的内部代码是1,它的长度不是固定的

nchar与nvarchar2
字符数据也可以存储在国际(多字节)字符集中
nchar
--固定长度的字符串最大可达2000个字节
--内部代码:96

nvarchar2
--可变长度的字符串最大可达4000个字节
--内部代码:1

nchar
在一个类型为nchar的列中,所有空字节都会用空格来补充(字符32)
它的长度是固定的

SQL> desc wb02_jy
Name Type      Nullable Default Comments
---- --------- -------- ------- --------
GR03 NCHAR(18) Y

SQL> select gr03,dump(gr03) from wb02_jy;

GR03                                 DUMP(GR03)
----------------------------- --------------------------------------------------------------------------------
4307050000000091              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000092              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000093              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000094              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000095              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,

如上输出一样gr03定义为nchar(18),但是它是双字节所以长度len=36是18的2倍,内部代码还是与char一样96

nvarchar2
在一个类型为nvarchar2的列中,oracle不会使用空格来进行补位
它的长度是可变的

SQL> select dw02,dump(dw02) from wb01_jy;

DW02                            DUMP(DW02)
----------------------------- --------------------------------------------------------------------------------
灵活人员                      Typ=1 Len=8: 112,117,109,59,78,186,84,88
灵活就业人员                  Typ=1 Len=12: 112,117,109,59,92,49,78,26,78,186,84,88
西湖区委、区管委              Typ=1 Len=16: 137,127,110,86,83,58,89,212,48,1,83,58,123,161,89,212
西湖区委、区管委办公室        Typ=1 Len=22: 137,127,110,86,83,58,89,212,48,1,83,58,123,161,89,212,82,158,81,10
西湖管理区政治部              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,101,63,108,187,144,232
西湖管理区监察局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,118,209,91,223,92,64
西湖管理区财政局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,141,34,101,63,92,64
西湖管理区劳动保障局          Typ=1 Len=20: 137,127,110,86,123,161,116,6,83,58,82,179,82,168,79,221,150,156,92
西湖管理区农村经济开发局      Typ=1 Len=24: 137,127,110,86,123,161,116,6,83,58,81,156,103,81,126,207,109,78,95
西湖管理区卫生局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,83,107,117,31,92,64
西湖管理区国土局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,86,253,87,31,92,64
西湖管理区移民开发局          Typ=1 Len=20: 137,127,110,86,123,161,116,6,83,58,121,251,108,17,95,0,83,209,92,6
西湖管理区经贸局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,126,207,141,56,92,64

从上面的输出typ=1可以看出nvarchar2的内部代码是1,它的长度不是固定的

ora-02085

ra-02085:的注解是:

database link name connects to name
cause: The database link attempted to connect to a database with a different name.
The name of the database link must be the same name as the name of the database.
Action: Create a database link with same name as the database to which it connects.
意思是:If u set the parameter 'global_names' to true,the db link name connected to this server must equal db_name + db_domain.

很多时候我们只是让dblink的名字等于了db_name,所以创建出错
把服务器上的global_names修改了

索引的可选择性

索引的“可选择性”是指在该索引列里存储不同值的数目和记录数的比。比如某个表的记录数是

1000条,而该表的索引列的值只有900个不同的值(有100个是相同或是空)。这样索引的可选
择性为900/1000为0.9 。这样当然效果就不好,最好的索引可选择性(如主键索引)是1.0 。索
引的可选择性是衡量索引的利用率的方法,比如在极端的情况下,一个表记录数是1000,而
索引列的值只有5个不同的值,则索引的可选择性很差(只有0.005)。这样的情形使用全表扫
描要比采用索引还好。
测量索引的可选择性
方法1:
可以采用命令方式来测量某个索引的可选择性值,例如COMPAY表的city 列和state列是被建立
成索引,则:
COMPAY 表的city和state 列的不同值的数目为:

Select count( distinct ||%||state) from COMPAY;
用下面语句查出COMPAY表的记录数:
select count(*) from COMPAY;

按照前面的方法进行比可得到该索引的可选择性值。
方法2:
用analyze 对表进行统计,对表进行分析后,系统同样对索引进行了分析。在查询结果。

ANALYZE TABLE compay compute statistics;

一旦表及其索引被分析过,就可以查询USER_INDEXES数据字典中的数据:
查询不同索引的列值:

select distinct_keys from user_indexes where table_name=’COMPAY’;

查询表中的记录数:

select num_rows from user_tables where table_name =’COMPAY’;

索引可选择性= distinct_keys / num_rows

SQL*Net more data to client 等待事件造成的性能问题

客户在升级程序时死机.原因是因为

select  *  from  application_versions

是查询这个语句时死机,因为在 application_versions表中存储了几十个更新程序的文件是以blob类型来存储的,当客户登录系统时会检查更新并下载这些程序文件.

下面是执行升级时所执行语句的跟踪信息

TKPROF: Release 11.2.0.3.0 - Development on Thu Oct 11 11:56:47 2012

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

Trace file: /database/diag/rdbms/xxdyb/xxdyb1/trace/xxdyb1_ora_802824_Jy_Trace_20121011.trc
Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

SQL ID: cf06fwacdmgfk Plan Hash: 1546270724

select 'x'
from
 dual


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          0          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.00       0.00          0          0          0           1

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 85  (INSUR_TEST)
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  FAST DUAL  (cr=0 pr=0 pw=0 time=3 us cost=2 size=0 card=1)


Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT   MODE: ALL_ROWS
      1   FAST DUAL


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       2        0.00          0.00
  SQL*Net message from client                     2        0.01          0.01
********************************************************************************

SQL ID: fdjxawa50ppb3 Plan Hash: 2249315794

select *
from
 application_version


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch      100      0.52    1137.37          0      18010          1          99
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      102      0.52    1137.37          0      18010          1          99

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 85  (INSUR_TEST)
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
        99         99         99  TABLE ACCESS FULL APPLICATION_VERSION (cr=9409 pr=0 pw=0 time=710 us cost=2495 size=4512 card=96)


Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT   MODE: ALL_ROWS
     99   TABLE ACCESS   MODE: ANALYZED (FULL) OF 'APPLICATION_VERSION'
              (TABLE)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                     101        0.00          0.00
  SQL*Net message from client                   101       10.60        184.38
  SQL*Net more data to client                 34094       10.73       1136.87
********************************************************************************

但在通过应用程序程序上传这个程序文件并保存在application_versions表中是速度很快.
SQL*Net more data to client 这个等待事件是指示数据库在不断地发送数据到客户端时的网络问题.
后经地检查发送是华为交换机的问题,但上传更新程序到数据库中网络没有问题,但是下载时网络出问题.

windows主机访问虚拟机linux中的oracle实例的安装方法

在学习oracle时一般都会在windows中安装虚拟机,在虚拟机安装linux系统并[安装oracle.
下面是自己的在windows中安装虚拟机并让windows主机能访问虚拟机中oracle实例的安装方法写的不好请大家多多包涵.
一.准备安装所需要的软件:

1.VMware虚拟机的下载和安装在我的博客中已经提到,这里就不再详细阐述。

2.先推荐一个redhat的下载地址,RedHat Linux 5企业版:content.gougou.com/content,
这个比较全面,但是也比较大(2.68G),如果自己有合适的linux安装版本,可以不使用这个。

二.在VMware虚拟机为RedHat Linux创建新的虚拟机就不详述了

三.在新建的虚拟机里安装RedHat Linux就不详述了

四.在linux系统中安装oracle
为了创建一个新的oracle用户输入和以下相似的命令:

# /usr/sbin/useradd -g oinstall -G dba[,oper] oracle
给oralce用户设置密码
# passwd oracle
修改内核参数编辑/etc/sysctl.conf文件
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 262144
net.core.rmem_max = 262144
net.core.wmem_default = 262144
net.core.wmem_max = 262144

当在/etc/sysctl.conf文件中指定这些内核参数后你要重启系统
也可以执行以下命令让内核参数生效

/sbin/sysctl -p

给oracle用户设置shell限制
为了提高数据库软件在linux系统中的性能你必须给oracle用户增加以下shell限制:

shell limit item in limits.confg hard limit

能打开文件的最大数量 nofile 65536
单个用户可用的最大进程数 nproc 16384

在/etc/security/limits.conf文件中增加以下限制:

oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536

在/ect/pam.d/login文件如果下面显示的参数没有就增加到该文件中

session required pam_limits.so

根据oracle用户的默认shell,对默认的shell启动文件进行以下更改:
对于Bourne, Bash, or Korn shell在/etc/profile文件中增加下面的代码

if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
fi

对C shell(csh or tcsh)在/etc/csh.login文件中增加以下代码

if ( $USER == "oracle" ) then
limit maxproc 16384
limit descriptors 65536
endif

创建oracle根目录可以输入以下相似的命令:

# mkdir -p /mount_point/app/oracle_sw_owner
# chown -R oracleinstall /mount_point/app/oracle_sw_owner
# chmod -R 775 /mount_point/app/oracle_sw_owner

如果oracle根目录的加载点是/u01并且oracle软件使用者用户为oracle那么oracle根目录的路径为:
/u01/app/oracle

[root@weblogic28 ~]# mkdir -p /u01/app/oracle
[root@weblogic28 ~]# chown -R oracleinstall /u01/app/oracle
[root@weblogic28 ~]# chmod -R 775 /u01/app/oracle

当你配置oracle用户环境变量时设置ORACLE_BASE时就将oracle根目录的路径赋给ORACLE_BASE

创建存储数据库文件和数据库恢复文件的目录
创建存储数据库文件的目录的命令如下:

# mkdir /mount_point/oradata
# chown oracleinstall /mount_point/oradata
# chmod 775 /mount_point/oradata

将存放数据库文件的目录创建在oracle根目录下/u01/app/oracle/oradata

[root@weblogic28 ~]# mkdir /u01/app/oracle/oradata
[root@weblogic28 ~]# chown oracleinstall /u01/app/oracle/oradata
[root@weblogic28 ~]# chmod 775 /u01/app/oracle/oradata

创建oracle Home目录/u01/app/oracle/10.2.0/db

[root@weblogic28 ~]# mkdir /u01/app/oracle/10.2.0/db
[root@weblogic28 ~]# chown oracleinstall /u01/app/oracle/10.2.0/db
[root@weblogic28 ~]# chmod 775 /u01/app/oracle/10.2.0/db

创建存储数据库恢复文件的目录的命令如下:

# mkdir /mount_point/flash_recovery_area
# chown oracleinstall /mount_point/flash_recovery_area
# chmod 775 /mount_point/flash_recovery_area

将存放数据库恢复文件的目录创建在oracle根目录下/u01/app/oracle

[root@weblogic28 ~]# mkdir /u01/app/oracle/flash_recovery_area
[root@weblogic28 ~]# chown oracleinstall /u01/app/oracle/flash_recovery_area
[root@weblogic28 ~]# chmod 775 /u01/app/oracle/flash_recovery_area

创建一个/tmp目录

[root@weblogic28 ~]# mkdir /u01/tmp
[root@weblogic28 ~]# chmod a+wr /u01/tmp

切换到oracle用户来设置环境变量

[oracle@weblogic28 ~]$
ls -a

查看.bash_profile文件

vi .bash_profile

TEMP=/u01/tmp
TMPDIR=/u01/tmp
export TEMP TMPDIR
export LD_ASSUME_KERNEL=2.6.9
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/10.2.0/db
export ORACLE_SID=jycs
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH
export PATH=$PATH:$ORACLE_HOME/bin
CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
CLASSPATH=$CLASSPATH:$ORACLE_HOME/network/jlib
export CLASSPATH

[oracle@weblogic28 tmp]$# umask
0022

umask命令将会显示22,022或0022

[oracle@weblogic28 tmp]$# env | more
REMOTEHOST=10.138.135.242
HOSTNAME=weblogic28
SHELL=/bin/bash
TERM=ansi
HISTSIZE=1000
TMPDIR=/u01/tmp
KDE_NO_IPV6=1
QTDIR=/usr/lib64/qt-3.3
QTINC=/usr/lib64/qt-3.3/include
USER=root
TEMP=/u01/tmp
LS_COLORS=no=00:fi=00:di=01;34:ln=01;36i=40;33:so=01;35:bd=40;33;01:cd=40;33;0
1r=01;05;37;41:mi=01;05;37;41:ex=01;32:.cmd=01;32:.exe=01;32:.com=01;32:.b
tm=01;32:.bat=01;32:.sh=01;32:.csh=01;32:.tar=01;31:.tgz=01;31:.arj=01;31:
.taz=01;31:.lzh=01;31:.zip=01;31:.z=01;31:.Z=01;31:.gz=01;31:.bz2=01;31:
.bz=01;31:.tz=01;31:.rpm=01;31:.cpio=01;31:.jpg=01;35:.gif=01;35:.bmp=01;3
5:.xbm=01;35:.xpm=01;35:.png=01;35:.tif=01;35:
ORACLE_SID=jycs
ORACLE_BASE=/u01/app/oracle
KDEDIR=/usr
MAIL=/var/spool/mail/root
PATH=/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:
/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
INPUTRC=/etc/inputrc

上面显示了你所设置的环境变量

也可以用下面的命令来查看环境变量

[oracle@weblogic28 tmp]$ echo $ORACLE_HOME[$ORACLE_SID,$ORACLE_BASE]

将数据库软件包拷贝到linux系统中
然后解压文件

$ gunzip filename.cpio.gz
[oracle@weblogic28 tmp]$ gunzip 10201_database_linux_x86_64.cpio.gz

执行上面的命令后会出现在 10201_database_linux_x86_64.cpio文件包
再执行如下命令解压文件

$ cpio -idmv < filename.cpio
[oracle@weblogic28 tmp]$ cpio -idmv <10201_database_linux_x86_64.cpio
database/stage/prereq/db/refhost_Custom.xml
database/stage/prereq/db/refhost.xml
database/stage/prereq/db/db_prereq.xml
database/stage/prereq/db/dbprereq.jar
database/stage/prereq/db
database/stage/prereq/oui/knowledgesrc.xml
database/stage/prereq/oui/rulemap.xml
database/stage/prereq/oui/OraPrereqChecks.jar
database/stage/prereq/oui
database/stage/prereq/common/rulemap.xml
database/stage/prereq/common
......

会出现以上信息

如果是远程安装可以使用VNC远程连接到linux服务器上来执行界面安装
1、配置并开启vnc服务

[oracle@localhost ~]$ vncserver
You will require a password to access your desktops.
Password: ---这里要求输入vnc客户端登录的密码并重复
Verify:
New 'localhost.localdomain:2 (oracle)' desktop is localhost.localdomain:2
Creating default startup script. /home/oracle/.vnc/xstartup
Starting applications specified in /home/oracle/.vnc/xstartup
Log file is /home/oracle/.vnc/localhost.localdomain:2.log

—-如上告诉你vnc终端已经创建好,用的是第二个终端
2、在创建vnc服务的用户目录下会生成一个.vnc的隐藏目录

[oracle@localhost ~]$ ls -a
. .bash_profile Disk1 .gconfd .gstreamer-0.10 .metacity README.htm .viminfo
.. .bashrc .eggcups .gnome .gtkrc-1.2-gnome2 .mozilla .redhat .vnc
.bash_history .chewing .emacs .gnome2 .ICEauthority .nautilus .scim .Xauthority
.bash_logout Desktop .gconf .gnome2_private .kde p8202632_10205_Linux-x86-64.zip .Trash .zshrc

3、进入.vnc目录,找到xstartup可执行文件,用vi 编辑器打开

[oracle@localhost ~]$ cd .vnc/
[oracle@localhost .vnc]$ ls
localhost.localdomain:2.log localhost.localdomain:2.pid passwd xstartup
[oracle@localhost .vnc]$ vi xstartup
#!/bin/sh
# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
exec /etc/X11/xinit/xinitrc ---去掉前面的#号即可 --保存退出
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
twm &
~
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
"xstartup" 12L, 333C 已写入
[oracle@localhost .vnc]$ vncserver
New 'localhost.localdomain:3 (oracle)' desktop is localhost.localdomain:3
Starting applications specified in /home/oracle/.vnc/xstartup
Log file is /home/oracle/.vnc/localhost.localdomain:3.log

4、清除刚才创建的vnc虚拟终端

[oracle@localhost .vnc]$ vncserver -kill :1
Can't find file /home/oracle/.vnc/localhost.localdomain:1.pid
You'll have to kill the Xvnc process manually
[oracle@localhost .vnc]$ vncserver -kill :2
Killing Xvnc process ID 11889
[oracle@localhost .vnc]$ vncserver -kill :3
Killing Xvnc process ID 11945
[oracle@localhost .vnc]$ vncserver -kill :4
Can't find file /home/oracle/.vnc/localhost.localdomain:4.pid
You'll have to kill the Xvnc process manually

5、重新建立新的vnc虚拟终端

[oracle@localhost .vnc]$ vncserver
New 'localhost.localdomain:2 (oracle)' desktop is localhost.localdomain:2
Starting applications specified in /home/oracle/.vnc/xstartup
Log file is /home/oracle/.vnc/localhost.localdomain:2.log --该终端号为 :2

6、在windows客户端用RealVNC软件中的Run VNC Viewer客户端连接。
7、在Run VNC Viewer 只需输入linux服务器的地址和刚才生成的终端号:2
格式:192.168.1.56:2
8、输入刚才配置vnc服务的时候配的即可登录linux服务器图形界面。

如果是本地安装的话执行下面的步骤
用root用户登录
[root@weblogic28 ~]#xhost + 让任何用户都是启用图形界面
切换到oracle用户

[root@weblogic28 ~]su - oracle
[oracle@localhost ~]$ cd /database
[oracle@weblogic28 database]$./runInstaller

设置虚拟机的IP地址让主机可以访问虚拟机
1、 NAT方式
1.1 右键单击主机任务栏上的网络连接图标,选择打开网络连接页面
1.2 启动”VMware Network Adapter VMnet8” 和 “VMware Network Adapter VMnet1”这两个连接
1.3 右键单击“本地连接”,选择属性,打开”本地连接属性”对话框,选择”高级”标签,打开高级标签页面,选中选项”允许其它网络用户通过此计算机的internet连接来连接”,然后在”家庭网络连接”下拉列表中选择VMware Network Adapter VMnet8。
1.4 在虚拟机上右键单击你要设置的虚拟机选“setting”(因为有的不止虚拟一台),打开”Hardware”标签页,单击”device”下的ethernet,此时在右边选中NAT:Used to share the host’s IP address. 然后点击确定。
1.5 打开虚拟机上的Edit菜单,选择virtual network settings打开virtual network editor页面,先打开automatic bridging标签页,关闭automagic bridging,点击应用;再打开DHCP标签页,启动DHCP服务,然后点击应用;最后打开NAT标签页,启动NAT服务,然后点击应用;点击确定后退出
1.9 启动虚拟机中的系统。
1.10 设置虚拟机中的系统的IP地址为192.168.100.200,默认网关为192.168.100.1 (VMware Network Adapter VMnet8的IP地址),DNS服务器设置和主机中的DNS服务器一致。
1.11 重新加载网络参数或者重新启动虚拟机中的系统。
1.12设置静态IP地址.
(1).命令行设置(该方式只是临时设置,系统重启后失效)
[1].设置IP和掩码
ifconfig 接口名(如eth0) IP地址 netmask 子网掩码
[2].设置网关
route add default gw 默认网关
[3].设置DNS服务器地址
echo “nameserver DNS服务器地址”>/etc/resolv.conf
实例:假设设置eth0的IP:192.168.1.100,DNS:192.168.1.12
ifconfig eth0 192.168.100.200 netmask 255.255.255.0
route add default gw 192.168.100.1
echo “nameserver=192.168.1.12″>/etc/resolv.conf
(2).修改文件来实现配置网络(需要重启网络接口重启后IP不会改变)
[1].修改IP地址,文件:/etc/sysconfig/network-scripts/ifcfg-接口名
这里假设网络接口名为eth0.
vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 (注:这里填的是网络接口名)
BOOTPROTO=static
NBOOT=yes (注:是否随系统启动)
IPADDR=192.168.100.200(注:这里填写的是IP地址)
PREFIX=24 (注:这里填写的是掩码的长度)
NETMASK=255.255.255.0
GATEWAY=192.168.100.1( 注:这里写的是网关)就是VMware Network Adapter VMnet8的IP地址

[2].修改DNS
echo “nameserver DNS服务器地址”>/etc/resolv.conf
[3].重启网络接口(假设为eth0)
ifup eth0(注:这里写的是接口名)

关闭linux防火墙
(1) 重启后永久性生效:
开启:chkconfig iptables on
关闭:chkconfig iptables off
(2) 即时生效,重启后失效:
开启:service iptables start
关闭:service iptables stop

linux下Oracle自动启动与停止
1.修改Oracle系统配置文件/etc/oratab
/etc/oratab 格式为: SID:ORACLE_HOME:AUTO
把AUTO域设置为Y(大写),只有这样,oracle 自带的dbstart和dbshut才能够发挥作用。我的为:
$ORACLE_SID:$ORACLE_HOME:Y
这儿的ORACLE_SID和ORACLE_HOME是oracle用户下的环境变量,在不同的电脑上有不同的值.当你打开/etc/oratab的时候,修改一下就行了.
2.编写服务脚本
在/etc/rc.d/init.d目录下创建oracle文件作为启动脚本,内容如下:容如下:

#!/bin/sh
#chkconfig: 2345
#descriptionracle_orcl
#
# /etc/rc.d/init.d/oracle_orcl
# auto start database orcl instance
#set oracle env
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/oracle/product/10.2.0/db_1
export PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_SID=orcl
ORACLE_USER=oracle

#start or stop script
case $1 in
start)
su - "$ORACLE_USER"< 
在oracle用户下输入如上的内容,然后保存退出,由于是启动脚本,需要执行权限;执行命令chmod a+x oracle授予oracle执行权限.
3.建立服务连接
ln -s /etc/rc.d/init.d/oracle /etc/rc.d/rc2.d/S99oracle
ln -s /etc/rc.d/init.d/oracle /etc/rc.d/rc3.d/S99oracle
ln -s /etc/rc.d/init.d/oracle /etc/rc.d/rc5.d/S99oracle
ln -s /etc/rc.d/init.d/oracle /etc/rc.d/rc0.d/K01oracle
ln -s /etc/rc.d/init.d/oracle /etc/rc.d/rc6.d/K01oracle

或可以通过执行以下命令来实现
chkconfig –add oracle
chkconfig命令运行成功后,在rc2.d,rc3.d,rc4.d,rc5.d下面建立了S99oracle 连接文件,可以在系统启动的时候,运行脚本启动数据库。在rc0.d、rc1.d和rc6.d目录下面建立了K99oracle文件,用于在系统关闭的时候自动运行脚本关闭数据库。可以使用 chkconfig –list oracle 命令查看服务配置,关于chkconfig更多的用法,可以通过man chkconfig查看

4.测试
启动,运行命令:./oracle_linuxdb start
关闭,执行命令:./oracle_linuxdb stop
可以用sqlplus user/passward@tnsname来测试启动和关闭数据库是否成功。现在重新启动linux主机,看数据库是否自动启动了.

这样主机就能访问虚拟机中的oracle数据库了

create table as select * from xx是否会生成redo

redo

重做日志文件(redo log file)对Oracle数据库来说至关重要,它们是数据库的事务日志。Oracle维护着两类重做日志文件:
在线(online)重做日志文件和归档(archived)重做日志文件。这两类重做日志文件都用于恢复;其主要目的是,
万一实例失败或介质失败,它们就能派上用场。
如果数据库所在主机掉电,导致实例失败,Oracle会使用在线重做日志将系统恰好恢复到掉电之前的那个时间点。
如果磁盘驱动器出现故障(这是一个介质失败),Oracle会使用归档重做日志以及在线重做日志将该驱动器上的
数据备份恢复到适当的时间点。

归档重做日志文件实际上就是已填满的”旧”在线重做日志文件的副本。系统将日志文件填满时,
ARCH进程会在另一个位置建立在线重做日志文件的一个副本,也可以在本地和远程位置上建立多个另外的副本.
如果由于磁盘驱动器损坏或者其他物理故障而导致失败,就会用这些归档重做日志文件来执行介质恢复.
Oracle拿到这些归档重做日志文件,并把它们应用于数据文件的备份,使这些数据文件能与数据库的其余部分保持一至.
归档重做日志文件是数据库的事务历史。

测量redo
redo管理是数据库中的一个串行点.任何Oracle实例都有一个LGWR,最终所有事务都会归于LGWR,要求这个进程管理它们的redo,
并COMMIT其事务,LGWR工作越忙,系统就会越慢.通过查看一个操作会生成多少redo,并对一个问题的多种解决方法进行测试,
可以从中找出最佳的方法。

与redo有关的视图
V$MYSTAT,其中有会话的提交信息
V$STATNAME,这个视图能告诉我们V$MYSTAT中的每一行表示什么(查看的统计名)。

查询redo大小的语句

SELECT a.NAME,
b.VALUE cur_size_byte,
round(b.VALUE / 1024, 3) || 'KB' cur_size_kb
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic#
AND lower(a.NAME) LIKE '%' || lower('redo size') || '%'

数据库归档模式
数据库归档用来保存redo的日志文件副本,一般安装时默认未开启数据库的归档模式。
在NOARCHIVELOG模式的数据库中,除了数据字典的修改外,CREATE TABLE不会记录日志.
如果你想在NOARCHIVELOG模式的数据库上看到差别,可以把对表T的DROP TABLE和CREATE TABLE换成DROP INDEX和CREATE INDEX。
默认情况下,不论数据库以何种模式运行,这些操作都会生成日志。
因为不同的模式可能导致不同的行为。你的生产系统可能采用ARCHIVELOG模式运行.
倘若你执行的大量操作在ARCHIVELOG模式下会生成redo,而在NOARCHIVELOG模式下不会生成redo,
你肯定想在测试时就发现这一点,而不要等到系统交付给用户时才暴露出来!
查看是否归档
查看数据库是否开启归档

select name,log_mode from v$database;

启用归档

startup mount
alter database archivelog;
alter database open;

禁止归档

shutdown immediate
startup mount
alter database noarchivelog
alter database open

force logging(强制日志)模式:
如果数据库强制日志模式开启后,则Oracle无论什么操作都进行redo的写入。
查看强制日志模式
通过

select force_logging from v$database

可以看到当前数据库是否开启了强制日志模式状态
开启强制日志模式
如果未开启数据库强制日志模式(默认未开启),则可以通过

alter database force logging

开启,之后Oracle无论什么操作都进行redo的写入,不依赖于数据库的归档模式等其他因素.
关闭强制日志模式
如果已经开启了数据库强制日志模式,则可以通过

alter database no force logging

关闭强制日志模式。
使数据库恢复先前的设置,数据库是否写入redo由数据库的归档模式等其他因素决定

disable_logging
那么在Oracle内部还存在一个内部参数:_disable_logging 默认是false
通过更改为true可以让Oracle在修改表中的记录的时候完全不记录redo,这个参数要甚用,平时,我们只作为性能测试用。
查看:

show parameter disa /disable/_disable_logging

开启:

alter system set "_disable_logging"=true scope=both;

禁用:

alter system set "_disable_logging"=false

表的归档模式
查看表的logging模式
查看表是否是logging状态用如下SQL:

select table_name,logging from dba_tables where table_name=’tablename’;

修改表的logging模式
修改表的logging状态sql:

alter table table_name nologging/logging

减少redo写入
本节所讲的都是当数据库未开启强制日志模式时的操作。
对象的操作在执行时会产生重做日志,采用某种方式,生成的redo会比平常(即不使用NOLOGGING子句时)少得多.
注意,这里说”redo”少得多,而不是”完全没有redo”.所有操作都会生成一些redo,不论数据库的日志模式是什么,
所有数据字典操作都会计入日志。

如何减少redo
create table时减少redo的方法
创建表时crate table as加入nolongging选项减少redo,格式如下
create table [table_name] nologging as [select表达式]。
insert into减少redo的方法
insert 大批量数据时加入/*+append */选项减少redo写入,格式如下
insert /*+append */ into [table_name] [select表达式]

数据库归档模式下生成redo规则
create table时nologging效果
归档模式下创建的表,默认为logging模式。
创建表时crate table as加入nolongging选项减少redo写入明显
验证
下面比较以下两种create table as时产生的redo size量。

SELECT a.NAME,
b.VALUE cur_size_byte,
round(b.VALUE / 1024, 3) || 'KB' cur_size_kb
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic#
AND lower(a.NAME) LIKE '%' || lower('redo size') || '%'

查询当前的重做日志大小记录下来

create table test_1 as select * from test;
SELECT a.NAME,
b.VALUE cur_size_byte,
round(b.VALUE / 1024, 3) || 'KB' cur_size_kb
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic#
AND lower(a.NAME) LIKE '%' || lower('redo size') || '%'

查询当前的重做日志大小减去前面记录下来的值计算刚才这个操作产生的redo大小标记为redo_1

SELECT a.NAME,
b.VALUE cur_size_byte,
round(b.VALUE / 1024, 3) || 'KB' cur_size_kb
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic#
AND lower(a.NAME) LIKE '%' || lower('redo size') || '%'

查询当前的重做日志大小记录下来

create table test_2 nologging as select * from test;
SELECT a.NAME,
b.VALUE cur_size_byte,
round(b.VALUE / 1024, 3) || 'KB' cur_size_kb
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic#
AND lower(a.NAME) LIKE '%' || lower('redo size') || '%'

查询当前的重做日志大小减去前面记录下来的值计算刚才这个操作产生的redo大小标记为redo_2
比较redo_1和redo_2的大小就知道crate table as加入nolongging或不加nologging选项的区别了

insert into时加入append效果
表模式logging
当表模式为logging状态时,无论是append模式还是no append模式,redo都会生成,即加入append选项无法生效。
验证
下面比较以下两种insert时产生的redo size量,可以看出redo量是差不多的。
计算重做大小的方法与上面的一样就不说了

1、insert /*+append */ into test_1 select * from test;
commit;
2、insert  into  test_1 select * from test;
commit;

表模式nologging
当表模式为nologging状态时,只有加入append模式会明显减少生成redo。
验证

1、insert /*+append */ into test_1 select * from test;
commit;
2、insert  into  test_1 select * from test;
commit;

数据库非归档模式生成redo规则
create table 使用nologging对产生redo的影响
非归档模式下创建的表,默认为nologging模式。
在NOARCHIVELOG模式的数据库中,除了数据字典的修改外,CREATE TABLE不会记录日志。
因此创建表时(crate table as)加入nologging选项减少redo写入不明显,即nologging选项加不加都差不多
验证
下面比较以下两种create table as时产生的redo size量。

create table test_1 as select * from test;
create table test_2 nologging as select * from test;

insert into时append效果
表模式logging
当表模式为logging状态时,加入append模式明显减少生成redo,而no append模式下不会减少生成。
验证

insert /*+append */ into test_1 select * from test;
commit;
insert  into  test_1 select * from test;
commit;

表模式nologging
当表模式为nologging状态时,append的模式会减少生成redo,而no append模式不会减少生成。
验证

insert /*+append */ into test_1 select * from test;
commit;
insert  into  test_1 select * from test;
commit;

其实就是直截加载与传统加载的区别

直接加载优势
直接加载比传统加载效率要高
不扫描原来的空数据块
不需要sql解析,减少系统的负载
不经过SGA
不走DBWR进程,走自己的专属进程,所以速度快

直接加载限制
不能加载簇表
锁定整个表,在表上有活动事务的时候不能加载

直接加载特点
直接加载是在所有数据块后面加载新数据块,修改高水位线,不扫描原来的空数据块。
直接加载只产生一点点的管理redo,因为要修改数据字典(也可以讲不产生redo)。
回滚,如果加载失败把新分配数据块抹掉就行了。
无需SGA,无需SQL解析,无需DBWR进程

实验

现在我们已经定义了test;

SQL> select count(*) from test;    现在表里没有记录数
  COUNT(*)
----------
         0

SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST'; 现在分配了1个区

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     0      65536

[oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log    传统方式加载数据
LS@LEO> select count(*) from test;                   已经成功加载了100万条数据
  COUNT(*)
----------
   1000000

SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST'; 100万条数据占用28个区

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                      0      65536
TEST                                                                                      1      65536
TEST                                                                                      2      65536
TEST                                                                                      3      65536
TEST                                                                                      4      65536
TEST                                                                                      5      65536
TEST                                                                                      6      65536
TEST                                                                                      7      65536
TEST                                                                                      8      65536
TEST                                                                                      9      65536
TEST                                                                                     10      65536
TEST                                                                                     11      65536
TEST                                                                                     12      65536
TEST                                                                                     13      65536
TEST                                                                                     14      65536
TEST                                                                                     15      65536
TEST                                                                                     16    1048576
TEST                                                                                     17    1048576
TEST                                                                                     18    1048576
TEST                                                                                     19    1048576

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     20    1048576
TEST                                                                                     21    1048576
TEST                                                                                     22    1048576
TEST                                                                                     23    1048576
TEST                                                                                     24    1048576
TEST                                                                                     25    1048576
TEST                                                                                     26    1048576
TEST                                                                                     27    1048576

28 rows selected
SQL> delete from test;                     删除100万条数据
1000000 rows deleted.
SQL> commit;                                           提交
Commit complete.
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST';

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                      0      65536
TEST                                                                                      1      65536
TEST                                                                                      2      65536
TEST                                                                                      3      65536
TEST                                                                                      4      65536
TEST                                                                                      5      65536
TEST                                                                                      6      65536
TEST                                                                                      7      65536
TEST                                                                                      8      65536
TEST                                                                                      9      65536
TEST                                                                                     10      65536
TEST                                                                                     11      65536
TEST                                                                                     12      65536
TEST                                                                                     13      65536
TEST                                                                                     14      65536
TEST                                                                                     15      65536
TEST                                                                                     16    1048576
TEST                                                                                     17    1048576
TEST                                                                                     18    1048576
TEST                                                                                     19    1048576

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     20    1048576
TEST                                                                                     21    1048576
TEST                                                                                     22    1048576
TEST                                                                                     23    1048576
TEST                                                                                     24    1048576
TEST                                                                                     25    1048576
TEST                                                                                     26    1048576
TEST                                                                                     27    1048576

28 rows selected

把数据都删除了还占用空间,oracle的delete操作不回收空间,只是把自己的记录标记为删除,实际呢还占用的空间不释放

[oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log    第二次传统方式加载数据

SQL> select count(*) from test;                   已经成功加载了100万条数据
  COUNT(*)
----------
   1000000
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST';

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                      0      65536
TEST                                                                                      1      65536
TEST                                                                                      2      65536
TEST                                                                                      3      65536
TEST                                                                                      4      65536
TEST                                                                                      5      65536
TEST                                                                                      6      65536
TEST                                                                                      7      65536
TEST                                                                                      8      65536
TEST                                                                                      9      65536
TEST                                                                                     10      65536
TEST                                                                                     11      65536
TEST                                                                                     12      65536
TEST                                                                                     13      65536
TEST                                                                                     14      65536
TEST                                                                                     15      65536
TEST                                                                                     16    1048576
TEST                                                                                     17    1048576
TEST                                                                                     18    1048576
TEST                                                                                     19    1048576

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     20    1048576
TEST                                                                                     21    1048576
TEST                                                                                     22    1048576
TEST                                                                                     23    1048576
TEST                                                                                     24    1048576
TEST                                                                                     25    1048576
TEST                                                                                     26    1048576
TEST                                                                                     27    1048576

28 rows selected

使用传统方式加载数据,会扫描原来的空数据块,会把新加载的数据插入到空数据块内,看我们还是使用原来的28个区

SQL> delete from test;                     这是第二次删除100万条数据
1000000 rows deleted.
SQL> commit;                                           提交
Commit complete.
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST';

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                      0      65536
TEST                                                                                      1      65536
TEST                                                                                      2      65536
TEST                                                                                      3      65536
TEST                                                                                      4      65536
TEST                                                                                      5      65536
TEST                                                                                      6      65536
TEST                                                                                      7      65536
TEST                                                                                      8      65536
TEST                                                                                      9      65536
TEST                                                                                     10      65536
TEST                                                                                     11      65536
TEST                                                                                     12      65536
TEST                                                                                     13      65536
TEST                                                                                     14      65536
TEST                                                                                     15      65536
TEST                                                                                     16    1048576
TEST                                                                                     17    1048576
TEST                                                                                     18    1048576
TEST                                                                                     19    1048576

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     20    1048576
TEST                                                                                     21    1048576
TEST                                                                                     22    1048576
TEST                                                                                     23    1048576
TEST                                                                                     24    1048576
TEST                                                                                     25    1048576
TEST                                                                                     26    1048576
TEST                                                                                     27    1048576

28 rows selected

delete还是不回收空间,我们依然占用着28个区

[oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true    直接方式加载数据

SQL> select segment_name,extent_id,bytes from user_extents where segment_name='TEST';

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                      0      65536
TEST                                                                                      1      65536
TEST                                                                                      2      65536
TEST                                                                                      3      65536
TEST                                                                                      4      65536
TEST                                                                                      5      65536
TEST                                                                                      6      65536
TEST                                                                                      7      65536
TEST                                                                                      8      65536
TEST                                                                                      9      65536
TEST                                                                                     10      65536
TEST                                                                                     11      65536
TEST                                                                                     12      65536
TEST                                                                                     13      65536
TEST                                                                                     14      65536
TEST                                                                                     15      65536
TEST                                                                                     16    1048576
TEST                                                                                     17    1048576
TEST                                                                                     18    1048576
TEST                                                                                     19    1048576

SEGMENT_NAME                                                                      EXTENT_ID      BYTES
-------------------------------------------------------------------------------- ---------- ----------
TEST                                                                                     20    1048576
TEST                                                                                     21    1048576
TEST                                                                                     22    1048576
TEST                                                                                     23    1048576
TEST                                                                                     24    1048576
TEST                                                                                     25    1048576
TEST                                                                                     26    1048576
TEST                                                                                     27    1048576
TEST                                                                                     28    1048576
TEST                                                                                     29    1048576
TEST                                                                                     30    1048576
TEST                                                                                     31    1048576
TEST                                                                                     32    1048576
TEST                                                                                     33    1048576
TEST                                                                                     34    1048576
TEST                                                                                     35    1048576
TEST                                                                                     36    1048576
TEST                                                                                     37    1048576
TEST                                                                                     38    1048576
TEST                                                                                     39    1048576
TEST                                                                                     40    1048576
TEST                                                                                     41    1048576
TEST                                                                                     42    1048576
TEST                                                                                     43    1048576
TEST                                                                                     44    1048576
TEST                                                                                     45    1048576
TEST                                                                                     46    1048576
TEST                                                                                     47    1048576

48 rows selected

发现同样的100万条记录,竟然占用了48个区,传统加载只用了28个,而我们使用直接加载到多了20个数据块,
对了直接加载不扫描原来的空数据块,会在所有数据块之后加载新的数据块插入数据修改高水位线HWM,
当提交事务之后,把高水位线移到新数据之后,其他的用户就可以看见了。

比较直接加载使用conventional 和direct方式产生的redo大小(可以通过/*+ append */模拟直接加载)。
明确:直接加载与logging配合下并不能显著的减少redo日志量
直接加载与nologging配合下可以大幅度的减少redo日志量

SQL> create table leo_t1 as select * from test where 1=2;          创建leo_t1表
Table created.
SQL> alter table leo_t1 logging;                                               设置leo_t1表logging模式
Table altered.
SQL> set autotrace  traceonly;
SQL> insert into leo_t1 select * from leo_test_sqlload where rownum < = 20000;  采用传统方式加载2万条记录
20000 rows created.

Statistics   统计信息
----------------------------------------------------------
       1071  recursive calls
       2668  db block gets
       1860  consistent gets
        386  physical reads
    1680404  redo size                                                这是产生的日志量1680404
        680  bytes sent via SQL*Net to client
        603  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
      20000  rows processed
SQL> rollback;                                                     回滚操作,使用undo表空间
Rollback complete.
SQL> insert /*+ append */ into leo_t1 select * from leo_test_sqlload where rownum < = 20000; 使用直接加载方式插入2万条记录
20000 rows created.

Statistics
----------------------------------------------------------
         94  recursive calls
        268  db block gets
       1294  consistent gets
        202  physical reads
    1627260  redo size                                当leo_t1为logging属性时,直接加载和传统加载产生redo日志差不多
        664  bytes sent via SQL*Net to client
        617  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      20000  rows processed

小结:这是因为在logging模式下,所有的数据块的改变都会产生redo日志,为以后恢复做准备,这时候直接加载没有多大的优势。
直接加载与nologging配合下可以大幅度的减少redo日志量
重大前提
如果你的数据库开启了force_logging=yes模式,那么不管你是传统加载还是直接加载都不会减少redo产生量
所以要想大幅度减少redo日志就必须满足3个条件
(1)关闭force_logging选项

alter database no force logging;

启动

alter database force logging;

(2)数据对象级别nologging模式

 alter table leo_t1 nologging;

(3)直接加载

insert /*+ append */ into

数据库归档与redo日志量关系
数据库处于归档模式
当表模式为logging状态时,无论是否使用append模式,都会生成redo.当表模式为nologging状态时,只有append模式,不会生成redo。
数据库处于非归档模式
无论是在logging还是nologing的模式下,append的模式都不会生成redo,而no append模式下都会生成redo。

SQL> alter database no force logging;
SQL> select force_logging from v$database;                       已经关闭force_logging选项
FOR
---
NO
SQL> alter table leo_t1 nologging;                                       设置leo_t1表nologging模式
Table altered.
SQL> select logging from user_tables where table_name='LEO_T1';
LOG
---
NO
SQL> select count(*) from leo_t1;                                       0条记录
  COUNT(*)
----------
         0
SQL> select index_name from user_indexes where table_name='LEO_T1';   表上没有索引
no rows selected

SQL> insert /*+ append */ into leo_t1 select * from leo_test_sqlload where rownum < = 20000;    直接加载
20000 rows created.

Statistics
----------------------------------------------------------
       1443  recursive calls
        649  db block gets
       1702  consistent gets
       1519  physical reads
      44900  redo size                                    直接加载产生的redo日志非常少
        658  bytes sent via SQL*Net to client
        617  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          9  sorts (memory)
          0  sorts (disk)
      20000  rows processed
SQL> rollback;
Rollback complete.
LS@LEO> insert into leo_t1 select * from leo_test_sqlload where rownum < = 20000;       传统加载
20000 rows created.

Statistics
----------------------------------------------------------
          4  recursive calls
       2207  db block gets
       1534  consistent gets
        441  physical reads
    1634064  redo size                                      传统加载产生的redo日志非常非常的多
        673  bytes sent via SQL*Net to client
        603  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      20000  rows processed

小结:直接加载与nologging配合下可以大幅度的减少redo日志量,因为插入的数据不产生redo日志,
所以在插入后要做备份操作,一旦数据损坏,就要使用备份来恢复,不能使用redo来恢复。注意要关闭force_logging选项