星期二, 三月 01, 2011

ORA-8104/ORA-8106的处理

ORA-8104/ORA-8106的处理
【分类信息】 故障处理

在生产环境下重建索引是十分危险的,一旦出现故障,将十分麻烦。所以老白很少在生产时间重建较大的索引。一旦ALTER INDEX ... REBUILD ONLINE失败,那么就可能碰到一个十分严重的问题。重新做索引重建会报ORA-8104/8106错误,导致无法重建索引。直到SMON清理了上回失败的现场才能进行重建。在10.2版本里,Oracle提供了一个 dbms_repair.online_index_clean来解决这个问题。对于9.2版本,BUG3805539曾经提出为9.2版本出一个补丁的请求,不过Oracle拒绝了这个补丁请求。所以在9.2里,只能采取下列方法来处理:

停应用,重启数据库,在SMON完成清理前不要启动应用。

有一个手工的方法有可能不需要停库,不过这个方法不是100%成功的,如果日志表比较忙就无法处理了。首先我们要了解REBUILD ONLINE失败后哪些地方受到了影响,首先ind$中这个索引的FLAGS被加上了512,另外会在这个用户下产生一张日志表sys_journal_<object_id>。我们要做的工作就是清除这两个部分。

sql>update ind$ set flags=flags-512 where obj#=<object id>; /* 首先要确认flags>512如果不是,说明这个标志是正常的*/

sql>drop table <owner>.sys_journal_<object_id>; /*这个步骤可能会报资源忙,因为有大量的日志正在插入,可以反复重试一下 */

在9.2.0.8下的HP-UX PA-RISC(64 BIT)和SUN SPARC环境下,是有一个补丁包,可以实现类似10.2的功能的,补丁包是7362402,这个补丁包是一个MLR,包含了bug 5597450 bug 6338480 ,其中6338480就是针对ORA-8104/8106的。安装了这个补丁包后就可以执行那个存储过程来清理了。如果那个存储过程不存在,可以通过下面的方法:

SQL> oradebug setmypid

SQL> oradebug call kdic_ext_cleanup object_id wait_for_lock

.

其中

object_id : 0 : cleanup 所有的

> 0 : cleanup 某个OBJECT_ID

wait_for_lock : 1 : 无法获得DML锁的时候进行重试,直到达到内部限制才失败

0 : 不重试,马上失败


星期三, 四月 28, 2010

Integrate EM Console Startup/Shutdown into Clusterware Control

When installing a RAC clusterware is responsible for starting and stopping required resources automatically and in required order. Under normal circumstances every resource is integrated with one exception: EM Control.

So this is a short guide on how to integrate EM Console startup/shutdown into Clusterware resource control.

First of all you need a startup/shutdown script:

#!/bin/sh
 case $1 in
 'start')
 /u01/app/oracle/product/11.2.0/db_1/bin/emctl start dbconsole
 RET=$?
 ;;
 'stop')
 /u01/app/oracle/product/11.2.0/db_1/bin/emctl stop dbconsole
 RET=$?
 ;;
 'check')
 /u01/app/oracle/product/11.2.0/db_1/bin/emctl status dbconsole
 RET=$?
 ;;
 esac
 exit $RET

After creating the script and placing is under /scripts you need to add the resource:

#crsctl add resource crs_dbconsole type cluster_resource -attr " ACTION SCRIPT= '/scripts/crs_dbconsole.sh' ,
PLACEMENT= 'restricted' , HOSTING_MEMBERS= 'node1' , CHECK_INTERVAL='30' ,
START_DEPENDENICES= 'hard(appsvip)' ,STOP_DEPENDENCIES= 'hard(appsvip)' , RESTART_ATTEMPTS='2' "

星期六, 七月 04, 2009

查找某一行索引位于那个块并dump , 修改该块模拟ORA-600(原创)

创建表和索引
create table temp as select rownum rn,owner username,created dt from all_objects where rownum<500;
alter table temp add constraint pk_temp primary key (rn);

10046查看到增加约束与删除经束时的一些与con$相关的语句.
select con# from con$ where owner#=58 and name='PK_TEMP';

STAT #2 id=1 cnt=0 pid=0 pos=1 obj=28 op='TABLE ACCESS BY INDEX ROWID CON$ (cr=2 pr=0 pw=0 time=896 us)'
STAT #2 id=2 cnt=0 pid=1 pos=1 obj=48 op='INDEX UNIQUE SCAN I_CON1 (cr=2 pr=0 pw=0 time=846 us)'

update con$ set con#='_NEXT_CONSTRAINT' where owner#=8581 and name=0

insert into con$(owner#,name,con#)values(58,'PK_TEMP',8580);

drop 的过程
select name from con$ where con#=8580;

delete from con$ where owner#=58 and name='PK_TEMP';

确认查找约束时会用到索引I_CON1,确认索引用到的列.

INDEX_NAME COLUMN_NAME
---------- --------------------
I_CON2 CON#
I_CON1 OWNER#
I_CON1 NAME

select rowid from con$ where name='PK_TEMP';
AAAAAcAABAAAN4nABt

将rowid转换成file,block,然后dump block,再用
select dump(58,16),dump('PK_TEMP',16) from dual;

得出的结果到trace file中寻找相对应的记录.

tab 0, row 109, @0xa6a
tl: 18 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 3b
col 1: [ 7] 50 4b 5f 54 45 4d 50
col 2: [ 3] c2 56 52

现在开始寻找index 记录所在的块
首先dump index.

sys@TONY> select object_id from dba_objects where object_name='I_CON1';

OBJECT_ID
----------
48

sys@TONY> alter session set events 'immediate trace name treedump level 48';
trace file 结果如下
branch: 0x40013a 4194618 (0: nrow: 32, level: 1)
leaf: 0x40013b 4194619 (-1: nrow: 247 rrow: 246)
leaf: 0x401cba 4201658 (0: nrow: 171 rrow: 170)
leaf: 0x401cbb 4201659 (1: nrow: 118 rrow: 109)
leaf: 0x401cbe 4201662 (2: nrow: 71 rrow: 70)
leaf: 0x401cbf 4201663 (3: nrow: 166 rrow: 166)

做tree dump后你可以得到root接点的DBA,转换为file,block,再dump这个block


begin
dbms_output.put_line(dbms_utility.data_block_address_file(dba=>4194618) );
dbms_output.put_line(dbms_utility.data_block_address_block(dba=>4194618));
end;
结果 1 314

alter system dump datafile 1 block 314;

SQL> select owner#,name from con$ where rowid='AAAAAcAABAAAN4nABt';

OWNER# NAME
---------- ------------------------------------------------------------
58 PK_TEMP
SQL> select dump(58,16),dump('PK_TEMP',16) from dual;

DUMP(58,16)
------------------------------------
DUMP('PK_TEMP',16)
--------------------------------------------------------------------
Typ=2 Len=2: c1,3b
Typ=96 Len=7: 50,4b,5f,54,45,4d,50

然后看刚才dump出来的文件,查找接近c1 3b的记录
row#28[7592] dba: 4251168=0x40de20
col 0; len 2; (2): c1 34
col 1; len 10; (10): 53 59 53 5f 43 30 30 35 30 34
row#29[7577] dba: 4256825=0x40f439
col 0; len 2; (2): c1 3f
col 1; len 7; (7): 53 54 41 54 53 24 4c

这里是 dba: 4251168=0x40de20
然后转化为文件和块号
begin
dbms_output.put_line(dbms_utility.data_block_address_file(dba=>4251168) );
dbms_output.put_line(dbms_utility.data_block_address_block(dba=>4251168));
end;
用结果
alter system dump datafile 1 block 56864;

查看trace 文件找到

row#139[1930] flag: ------, lock: 2, len=19, data:(6): 00 40 de 27 00 6d
col 0; len 2; (2): c1 3b
col 1; len 7; (7): 50 4b 5f 54 45 4d 50


可以确认到index 在 datafile 1 block 56864 . 记录在块中的地址为
1930+44+24*ITL数 即 1930+44+48=2022

用bbed查看

set file 1
set block 56884
dump offset 2022

00000040 de27006d 02c13b07

可以观察到00 40 de 27 00 6d 这个指向表块的rowid
如果要模拟
alter table tony.temp drop primary key
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [atbdro4], [], [], [], [], [], [], []

可以这样
m /x 03 offset 2029 (这样就将006d 修改为0003)
sum apply

存盘退出,并重启DB,执行上面的命令即可产生上述的错误.


windows 2k3 + 10G RAC 安装的一些注意事项

hosts的配置

127.0.0.1 localhost.com localhost
# Public
1x1.33.14.3 w2k3rac1.com w2k3rac1
1x1.33.14.4 w2k3rac2.com w2k3rac2
#Private
10.255.235.13 w2k3rac1-priv.com w2k3rac1-priv
10.255.235.14 w2k3rac2-priv.com w2k3rac2-priv
#Virtual
1x1.33.14.7 w2k3rac1-vip.com w2k3rac1-vip
1x1.33.14.11 w2k3rac2-vip.com w2k3rac2-vip

运行
runcluvfy.bat stage -pre crsinst -n rac01,rac02 -verbose
检查安装条件
如果报
找不到用于 VIP 的合适接口集。
有两个原因:
public 网卡不能是 10*,192*,172*; public网卡一定要设置一个gateway


要注意的地方(两台机都要做):
1. 查看是否有多余的网卡,有时vmware会冒出另一个网卡.
set devmgr_show_nonpresent_devices=12
set devmgr_show_nonpresent_devices=1
devmgmt.msc

用view--->show hidden devices 查看

2. 打开网络连接页面,在高级设置那将public 网卡设为第一个.

3.在cmd下 ,打入 diskpart
然后输入 automount enable
(注意在这里是查看共享磁盘的,你可以在两台机上都用list volume查看一下结果是否一致,要保持一致)

4. ocr 和 voting 磁盘一定要放两份,否则会遇到
安装crs时,安装到配置助手这一步时,就不能进行下去了。
这是因为bug:5027463

5.时间同步

升级10.2.0.4 的crs 要注意
安装完后,然后停止所有的oracle 服务,然后下载一个listdlls.exe 查看ons.exe 的pid
然后用
ntsd -c q -p pid 来停止ons.exe
再运行
C:oracleproduct10.2.0crsinstallpatch102.bat
否则这个运行不了的.

RAC运行在Windows平台,并且用ASM来管理存储, 在某一节点运行ASMCMD会遇到以下错误
===========================
ORA-01031: insufficient privileges (DBD ERROR: OCISessionBegin)
===========================
solution
1.设定环境变量
set oracle_home=C:oracleproduct10.2.0db_1
set oracle_sid=+AMS2

2.将当前OS帐号加入到ORA_DBA这个组中.通常在非运行安装程序节点中,没有将OS帐号加入到ORA_DBA组中.

进行ASMCMD命令行
C:>%oracle_home%binasmcmd

srvctl add service -d rac -s write -r rac1 -a rac2
srvctl add service -d rac -s read -r rac2 -a rac1

RAC1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = w2k3rac2-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac)
(INSTANCE_NAME = rac1)
)
)


appread =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = w2k3rac1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = w2k3rac2-vip)(PORT = 1521))
(LOAD_BALANCE = NO)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = read)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
(BACKUP = rac1)
)
))

应用服务器连接串 写成这样试下

(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = NODE1_VIP)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = NODE2_VIP)(PORT = 1521))
(SOURCE_ROUTE = yes) ***这个的作用是让其按照上面列出的地址一个一个连接*********
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = RACDB)
)
)


星期四, 二月 26, 2009

ASM 磁盘操作手册

向已有的ASM 磁盘组增加磁盘的方法:

1. 加硬盘,分区,用fdisk -l 查看分区表
2. 在root用户下
/etc/init.d/oracleasm listdisks
/etc/init.d/oracleasm createdisk VOL4 /dev/sde1

 查看全文

星期四, 十一月 06, 2008

Linux性能优化的两个重要参数(参考)

vfs_cache_pressure:
该文件表示内核回收用于directory和inode cache内存的倾向;缺省值100表示内核将根据pagecache和swapcache,把directory和inode cache保持在一个合理的百分比;降低该值低于100,将导致内核倾向于保留directory和inode cache;增加该值超过100,将导致内核倾向于回收directory和inode cache。
缺省设置:100

min_free_kbytes:
该文件表示强制Linux VM最低保留多少空闲内存(Kbytes)。
缺省设置:724(512M物理内存)

改变命令:
sysctl -w vm.vfs_cache_pressure=200
sysctl -w vm.min_free_kbytes=1024

参见:
http://bbs.chinaunix.net/viewthread.php?tid=849389
http://blog.sina.com.cn/s/blog_4b4de658010006m7.html


星期三, 七月 16, 2008

Linux性能监控之IO篇(转)

IO系统是整个系统中最慢的部分,因为它需要真正的物理操作磁盘的转动和检索。比起内存来要差几个数量级。Linux内核将硬盘IO分页,每一页的大小默认为4K。这时,内存和磁盘的读写以页为单位进行,这些页叫做内存页。用time命令可以检查页的大小:

# /usr/bin/time -v date

<snip>

Page size (bytes): 4096

<snip>

主要页错误(Major Page Faults)和次要页错误(Minor Page Faults):

MPFMajor Page Faults)表示进程需要的数据并不在内存中,需要从磁盘读取。

一旦内存页读入到内存的缓冲区中,程序就在内存中读取或写入数据,叫做MnPFMinor Page Faults)。MnPF通过重复使用内存页而缩短了内核时间。Time命令可以显示一个进程中MPFMnPF的数量,在evolution程序第一次启动的时候会有很多MPF

# /usr/bin/time -v evolution

<snip>

Major (requiring I/O) page faults: 163

Minor (reclaiming a frame) page faults: 5918

<snip>

如果再次启动evolution程序,我们就看到MPF消失了,因为此时进程需要的数据已经全部在内存中了:

# /usr/bin/time -v evolution

<snip>

Major (requiring I/O) page faults: 0

Minor (reclaiming a frame) page faults: 5581

<snip>

当进程不断的进行IO操作的时候,系统会将这些数据缓存到内存中。所以我们会看到系统的FreeMemory越来越少,而Cache越来越大。如下:

# cat /proc/meminfo

MemTotal: 2075672 kB

MemFree: 52528 kB

Buffers: 24596 kB

Cached: 1766844 kB

有些人为系统的可用内存太少而担心,而事实不是这样,这种情况恰恰证明系统正在高效的利用cache,进而减少MPF,增加MnPF。但从这个输出我们无法断定内存是否为系统瓶颈。

前面讲了内存页的定义,接下来我们说说内存页的分类:

1. Read Pages-这些页通过MPF从磁盘读入,并且是只读的。这些页存在与cache中包括不能修改的静态文件,二进制文件,库文件。内核在需要的时候会将他们读入内存,当内存资源紧张时,内核会释一些放此类的内存页,当程序在此需要的时候,就只能通过MPF重新读入。

2. Dirty Pages-这些页是内核在内存中修改过的页面。这些页面需要同步回磁盘上。Pdflush负责将他们写回磁盘。当内存不够时,kswapd就会触发pdflush将页面写回磁盘以释放内存。

3. Anonymous Pages-这些页属于某个进程,但是没有任何磁盘文件与之相关。他们不能和磁盘同步。当内存不够时,kswapd会将他们写入swap分区。

应用程序可以用系统调用fsync()sync()Dirty Page立即写回磁盘。如果应用程序没有调用此类函数,pdflush进程会定期与磁盘进行同步。

接下来我们分析一些具体的情况,在这些情况下I/O会成为系统的瓶颈。我们会用到工具topvmstatiostatsar等。每一个工具的输出都从不同的方面反映除系统的性能情况。

情况1:同一时间进行大量的I/O操作

在这种情况时我们会发现CPUwa时间百分比会上升,证明系统的idle时间大部分都是在等待I/O操作。

# vmstat 1

procs -----memory----- ---swap---io---- --system--cpu----

r b swpd free buff cache si so bi bo in cs us sy id wa

3 2 0 55452 9236 1739020 0 0 9352 0 2580 8771 20 24 0 57

2 3 0 53888 9232 1740836 0 0 14860 0 2642 8954 23 25 0 52

2 2 0 51856 9212 1742928 0 0 12688 0 2636 8487 23 25 0 52

从这个输出我们可以看到CPU50%的时间都在等待I/O操作,我们还可以看到系统的bi值很大,证明系统有大量的I/O请求将磁盘内容读入内存。

没有很好的工具能看到到底是哪个进程在进行I/O读写。但我们可以通过top命令的输出来猜测

# top -d 1

top - 19:45:07 up 1:40, 3 users, load average: 6.36, 5.87, 4.40

Tasks: 119 total, 3 running, 116 sleeping, 0 stopped, 0 zombie

Cpu(s): 5.9% us, 87.1% sy, 0.0% ni, 0.0% id, 5.9% wa, 1.0% hi, 0.0% si

Mem: 2075672k total, 2022668k used, 53004k free, 7156k buffers

Swap: 2031608k total, 132k used, 2031476k free, 1709372k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ nFLT COMMAND

3069 root 5 -10 450m 303m 280m S 61.5 15.0 10:56.68 4562 vmware-vmx

3016 root 5 -10 447m 300m 280m S 21.8 14.8 12:22.83 3978 vmware-vmx

3494 root 5 -10 402m 255m 251m S 3.0 12.6 1:08.65 3829 vmware-vmx

3624 root 5 -10 401m 256m 251m S 1.0 12.6 0:29.92 3747 vmware-vmx

top的输出通过faults进行排序。我们可以看到vmware产生最多的page faults。也就是说它进行了大量的IO操作。

情况2:管道太小

任何I/O操作都需要一定的时间,而且这些时间对于硬盘来说是确定的,它包含磁盘旋转的延时RDrotation delay)和磁头搜索时间DSdisk seek)。RD由磁盘转速(RPM)决定。RD是磁盘旋转一周所需时间的一半。如RPM10000.

RPS=RPM/60=166

1/166=0.0006=6ms 磁盘旋转一周要6毫秒

RD=6ms/2=3ms

磁盘平均搜索时间是3ms,数据传输的平均延时是2ms,这样一次I/O操作的平均时间是:

3ms+3ms+2ms=8ms

IOPS=1000/8=125 这块磁盘的每秒IO数(IOPS)为125。所以对于10000RPM的磁盘来说它所能承受的IO操作在IOPS120150之间。如果系统的I/O请求超过这个值,就会使磁盘成为系统的瓶颈。

对与系统而言有两种不同种类的I/O压力,连续I/O和随机I/O

连续I/O常常出现在企业级数据库这样的应用中,需要连续的读取大量数据。这种系统的性能依靠它读取和移动数据的大小和快慢。我们用iostat来监控,会发现rKB/s,wKB/s会很高。

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util

/dev/sda 0.00 12891.43 0.00 105.71 0.00 106080.00 0.00 53040.00 1003.46 1099.43 3442.43 26.49 280.00

从输出我们看到w/s=105,wKB/s=53040.所以53040/105=505KB per I/O.

对于随机I/O的系统来说性能的关注点不在搜传输数据的大小和速度,而是在磁盘的IOPS。这类系统的I/O请求比较小但是数量很大,如Web服务器和Mail服务器。他们的性能主要依赖每秒钟可处理的请求数:

# iostat -x 1

avg-cpu: %user %nice %sys %idle

2.04 0.00 97.96 0.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util

/dev/sda 0.00 633.67 3.06 102.31 24.49 5281.63 12.24 2640.82 288.89 73.67 113.89 27.22 50.00

从输出我们看到w/s=102,wKB/s=2640.所以2640/102=23KB per I/O.

因此对于连续I/O系统来说我们要关注系统读取大量数据的能力即KB per request.对于随机I/O系统我们注重IOPS值.


星期二, 五月 27, 2008

重定义表的几种方法(转帖)

在一个高可用系统中,如果需要改变一个表的定义是一件比较棘手的问题,尤其是对于7×24系统。Oracle提供的基本语法基本可以满足一般性修改,但是对于把普通堆表改为分区表,把索引组织表修改为堆表等操作就无法完成了。而且,对于被大量DML语句访问的表,幸运的是,Oracle从9i版本开始提供了在线重定义表功能,通过调用DBMS_REDEFINITION包,可以在修改表结构的同时允许DML操作。

在线重定义表具有以下功能:

修改表的存储参数;

可以将表转移到其他表空间;

增加并行查询选项;

增加或删除分区;

重建表以减少碎片;

将堆表改为索引组织表或相反的操作;

增加或删除一个列。

调用DBMS_REDEFINITION包需要EXECUTE_CATALOG_ROLE角色,除此之外,还需要CREATE ANY TABLE、ALTER ANY TABLE、DROP ANY TABLE、LOCK ANY TABLE和SELECT ANY TABLE的权限。

在线重定义表的步骤如下:

1.选择一种重定义方法

存在两种重定义方法,一种是基于主键、另一种是基于ROWID。ROWID的方式不能用于索引组织表,而且重定义后会存在隐藏列M_ROW $ $。默认采用主键的方式。

2.调用DBMS_REDEFINITION.CAN_REDEF_TABLE()过程,如果表不满足重定义的条件,将会报错并给出原因。

3.在用一个方案中建立一个空的中间表,根据重定义后你期望得到的结构建立中间表。比如:采用分区表,增加了COLUMN等。

4.调用DBMS_REDEFINITION.START_REDEF_TABLE()过程,并提供下列参数:被重定义的表的名称、中间表的名称、列的映射规则、重定义方法。

如果映射方法没有提供,则认为所有包括在中间表中的列用于表的重定义。如果给出了映射方法,则只考虑映射方法中给出的列。如果没有给出重定义方法,则认为使用主键方式。

5.在中间表上建立触发器、索引和约束,并进行相应的授权。任何包含中间表的完整性约束应将状态置为disabled。

当重定义完成时,中间表上建立的触发器、索引、约束和授权将替换重定义表上的触发器、索引、约束和授权。中间表上disabled的约束将在重定义表上enable。

6.(可选)如果在执行DBMS_REDEFINITION.START_REDEF_TABLE()过程和执行DBMS_REDEFINITION.FINISH_REDEF_TABLE()过程直接在重定义表上执行了大量的DML操作,那么可以选择执行一次或多次的SYNC_INTERIM_TABLE()过程,以减少最后一步执行FINISH_REDEF_TABLE()过程时的锁定时间。

7.执行DBMS_REDEFINITION.FINISH_REDEF_TABLE()过程完成表的重定义。这个过程中,原始表会被独占模式锁定一小段时间,具体时间和表的数据量有关。

执行完FINISH_REDEF_TABLE()过程后,原始表重定义后具有了中间表的属性、索引、约束、授权和触发器。中间表上disabled的约束在原始表上处于enabled状态。

8.(可选)可以重命名索引、触发器和约束。对于采用了ROWID方式重定义的表,包括了一个隐含列M_ROW $ $。推荐使用下列语句经隐含列置为UNUSED状态或删除。

ALTER TABLE TABLE_NAME SET UNUSED (M_ROW $ $);

ALTER TABLE TABLE_NAME DROP UNUSED COLUMNS;

下面是进行重定义操作后的结果:

原始表根据中间表的属性和特性进行重定义;

START_REDEF_TABLE()和FINISH_REDEF_TABLE()操作之间在中间表上建立的触发器、索引、约束和授权,现在定义在原始表上。中间表上disabled的约束在原始表上处于enabled状态。

原始表上定义的触发器、索引、约束和授权建立在中间表上,并会在删除中间表时删除。原始表上原来enabled状态的索引,建立在中间表上,并处于disabled状态。

任何定义在原始表上的存储过程和游标都会变为INVALID,当下次调用时后自动进行编译。

如果执行过程中出现错误或者人为选择退出的话,可以执行DBMS_REDEFINITION.ABORT_REDEF_TABLE()过程。

其中UNAME 参数是指用户;

Oracle的普通表没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,下面介绍三种效率比较高的方法,并说明它们各自的特点

方法一:利用原表重建分区表

步骤:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;

已创建6264行。

SQL> COMMIT;

提交完成。

SQL> CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)

2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),

3 PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),

4 PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),

5 PARTITION P4 VALUES LESS THAN (MAXVALUE))

6 AS SELECT ID, TIME FROM T;

表已创建。

SQL> RENAME T TO T_OLD;

表已重命名。

SQL> RENAME T_NEW TO T;

表已重命名。

SQL> SELECT COUNT(*) FROM T;

COUNT(*)

----------

6264

SQL> SELECT COUNT(*) FROM T PARTITION (P1);

COUNT(*)

----------

0

SQL> SELECT COUNT(*) FROM T PARTITION (P2);

COUNT(*)

----------

6246

SQL> SELECT COUNT(*) FROM T PARTITION (P3);

COUNT(*)

----------

18

优点:

方法简单易用,由于采用DDL语句,不会产生UNDO,且只产生少量REDO,效率相对较高,而且建表完成后数据已经在分布到各个分区中了。

不足:

对于数据的一致性方面还需要额外的考虑。由于几乎没有办法通过手工锁定T表的方式保证一致性,在执行CREATE TABLE语句和RENAME T_NEW TO T语句直接的修改可能会丢失,如果要保证一致性,需要在执行完语句后对数据进行检查,而这个代价是比较大的。另外在执行两个RENAME语句之间执行的对T的访问会失败。

适用于修改不频繁的表,在闲时进行操作,表的数据量不宜太大。

方法二:使用交换分区的方法

步骤:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;

已创建6264行。

SQL> COMMIT;

提交完成。

SQL> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)

2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),

3 PARTITION P2 VALUES LESS THAN (MAXVALUE));

表已创建。

SQL> ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;

表已更改。

SQL> RENAME T TO T_OLD;

表已重命名。

SQL> RENAME T_NEW TO T;

表已重命名。

SQL> SELECT COUNT(*) FROM T;

COUNT(*)

----------

6264

优点:

只是对数据字典中分区和表的定义进行了修改,没有数据的修改或复制,效率最高。如果对数据在分区中的分布没有进一步要求的话,实现比较简单。在执行完RENAME操作后,可以检查T_OLD中是否存在数据,如果存在的话,直接将这些数据插入到T中,可以保证对T插入的操作不会丢失。

不足:

仍然存在一致性问题,交换分区之后RENAME T_NEW TO T之前,查询、更新和删除会出现错误或访问不到数据。如果要求数据分布到多个分区中,则需要进行分区的SPLIT操作,会增加操作的复杂度,效率也会降低。

适用于包含大数据量的表转到分区表中的一个分区的操作。应尽量在闲时进行操作。

方法三:Oracle9i以上版本,利用在线重定义功能

步骤:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS;

已创建6264行。

SQL> COMMIT;

提交完成。

SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER’, 'T', DBMS_REDEFINITION.CONS_USE_PK);

PL/SQL 过程已成功完成。

SQL> CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)

2 (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),

3 PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),

4 PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),

5 PARTITION P4 VALUES LESS THAN (MAXVALUE));

表已创建。

SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(‘USER’, 'T', 'T_NEW', -

> 'ID ID, TIME TIME', DBMS_REDEFINITION.CONS_USE_PK);

可以改为:

SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(‘USER’, 'T', 'T_NEW')

PL/SQL 过程已成功完成。

SQL> EXEC dbms_redefinition.sync_interim_table(‘USER’, 'T', 'T_NEW')

现在,将中间表与原始表同步。(仅当要对表 T 进行更新时才需要执行该操作。)

SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER’, 'T', 'T_NEW');

PL/SQL 过程已成功完成。

如果重组织失败,那么你就必须采取特殊的步骤来让它重新开始。由于重定义过程需要创建表格的快照,因此为了重新开始这一过程,你必须调用DBMS_REDEFINITION.ABORT_REDEF_TABLE来释放快照。  

DBMS_REDEFINITION.ABORT_REDEF_TABLE过程有三个参数,即用户(schema)、原始表格(original table name)名称以及持有表格名称(holding table name)。它“出栈”并允许你开始重组织表格。

SQL> SELECT COUNT(*) FROM T;

SQL> SELECT COUNT(*) FROM T PARTITION (P2);

SQL> SELECT COUNT(*) FROM T PARTITION (P3);

需要说明的是完成后,原表和中间表的结构也同时进行了交换,并且中间表里面有原表的数据备份。

优点:

保证数据的一致性,在大部分时间内,表T都可以正常进行DML操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性,对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约束,可以做到切换完成后不再需要任何额外的管理操作。

不足:实现上比上面两种略显复杂,适用于各种情况。

然而,在线表格重定义也不是完美无缺的。下面列出了Oracle9i重定义过程的部分限制:

你必须有足以维护两份表格拷贝的空间。   

你不能更改主键栏。   

表格必须有主键。   

必须在同一个大纲中进行表格重定义。   

在重定义操作完成之前,你不能对新加栏加以NOT NULL约束。   

表格不能包含LONG、BFILE以及用户类型(UDT)。   

不能重定义链表(clustered tables)。   

不能在SYS和SYSTEM大纲中重定义表格。   

不能用具体化视图日志(materialized view logs)来重定义表格;不能重定义含有具体化视图的表格。   

不能在重定义过程中进行横向分集(horizontal subsetting)。


星期一, 五月 26, 2008

ORA-6512 During Full Export

在linux 中将oracle 10.2.0.1 升级到10.2.0.4 后.exp 出现

EXP-00008: ORACLE error 6550 encountered
ORA-06550: line 1, column 18:
PLS-00201: identifierSYS.DBMS_DEFER_IMPORT_INTERNALmust be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at “SYS.DBMS_SYS_SQL”, line 1204
ORA-06512: at “SYS.DBMS_SQL”, line 323
ORA-06512: at “SYS.DBMS_EXPORT_EXTENSION”, line 97
ORA-06512: at “SYS.DBMS_EXPORT_EXTENSION”, line 126
ORA-06512: at line 1

Metalink Note 464672.1 lists the problem as Bug 6392040 and provides a solution.

GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO <user_name>;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO <user_name>;

One important statement to consider from Metalink Note 464672.1:

“There is no fix in this bug because the export utility is no longer supported in 11g and should be replaced by the Data Pump Export.”

Additional References
Metalink Note 464862.1 - “EXP-00008 PLS-00201 When Performing Full Database Export After Applying CPUOCT2007″

Bug 6510213 - “INSTALLED CPUOCT2007; NOW EXP GETS THE ERRORS EXP-00008,ORA-06550,PLS-00201


星期四, 十二月 13, 2007

利用qwinsta和rwinsta察看连接到一个机器的连接数

字体大小:

平时我们可能会遇到这样的一种情况:需要对某台机器进行远程桌面连接,而验证完用户名和密码后提示这台机器的连接数已经达到最大值。这个时候就可以利用qwinsta和rwinsta察看连接到这个机器的连接以及断开某个连接。

察看连接:qwinsta

用法:
Display information about Terminal Sessions.

QUERY SESSION [sessionname | username | sessionid]
[/SERVER:servername] [/MODE] [/FLOW] [/CONNECT] [/COUNTER]

sessionname Identifies the session named sessionname.
username Identifies the session with user username.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server to be queried (default is current).
/MODE Display current line settings.
/FLOW Display current flow control settings.
/CONNECT Display current connect settings.
/COUNTER Display current Terminal Services counters information.

用法示例:qwinsta /server:test-machine
显示结果
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console 0 Conn wdcon
rdp-tcp 65536 Listen rdpwd
Gogboy 1 Disc rdpwd
Sunny 2 Disc rdpwd
这个结果显示有两个普通用户(Gogboy, Sunny)保留着对该机器(test-machine)的会话。可以通过下面的rwinsta段开

断开连接:rwinsta
用法:
Reset the session subsytem hardware and software to known initial values.

RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]

sessionname Identifies the session with name sessionname.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server containing the session (default is current).
/V Display additional information.

用法示例:rwinsta 2 /server:test-machine
这样就把上面用户Sunny的会话从该机器断开了。

可能描述上有些不太规范,只是随笔,记录以下,欢迎看到的朋友指正。


星期五, 十月 12, 2007

用ocfs创建数据库时一定要注意

要用
dbca -datafileDestination /opt/oracle/data_ocfs/rac 这个命令来运行

否则会报

stat for /opt/oracle/data_ocfs/rac/spfilerac.ora file failed

The filename "/opt/oracle/data_ocfs/rac/spfilerac.ora" entered for the
persistent initialization parameters file (spfile) is not a valid raw device.
Please enter a valid raw device name with its full path.

 查看全文

星期四, 十月 11, 2007

CRSCTL命令的用法举例(转帖)

主要内容:

. CRS 的组成

. CRSCTL命令的用法举例

. Start/Stop RAC Instance

 查看全文

星期三, 九月 12, 2007

在SQLPLUS里显示相对应的用户名和实例名

The following entries in either of these files sets the prompt to "user@database>"

define gname = 'not connected'
column global_name new_value gname
set termout off
select lower(user) || '@' || replace(global_name,'.WORLD',null) global_name
from global_name;
set termout on
set sqlprompt '&&gname> '

However, this is only run ONCE (when you login), so if you're the kind of person that issues "conn" or "connect" from within your SQL Plus session, you can then create two files

conn.sql
-----------
connect &1
@login

connect.sql
-----------
connect &1
@login

which will change your connection and then re-issue the prompt setting commands

scott@demo> @conn newuser/newpass
Connected.
newuser@demo>
我喜欢用这个

define gname = 'not connected'
column global_name new_value gname
set termout off
select lower(user) || '@' || utl_inaddr.get_host_address() || '@' || replace(global_name,'.WORLD',null) global_name
from global_name;
set termout on
set sqlprompt '&&gname> '
tong@19.200.1.33@OA>

星期二, 七月 17, 2007

在UNIX裸设备和文件系统之间移动ORACLE(ZT)

在UNIX裸设备和文件系统之间移动ORACLE(ZT)
在UNIX裸设备和文件系统之间移动ORACLE
作者:Rejoice999


在UNIX裸设备和文件系统之间移动ORACLE

一、关于裸设备

1.1 什么是裸设备(RAW DEVICE)

裸设备是指未创建文件系统的磁盘分区(raw partition)或逻辑卷(raw logical volume),应用程序直接通过一
个字符设备驱动程序对它进行访问。如何对设备上的数据读写决定于使用它的应用程序。由于对裸设备的操作不通过UNIX的缓冲区,数据在ORACLE的数据缓冲区(BUFFER CACHE)和磁盘之间直接传递,所以使用裸设备在一定程度上能够提高I/O性能,适合I/O量大的系统。另外OPS/RAC (Oracle Parallel Server/Real Application Cluster)环境下,多个节点同时访问同一个数据库,所以CONTROL FILE、DATA FILE、REDO LOG都必须建在RAW DEVICE上。

1.2 裸设备的可用空间

不同的UNIX对裸设备的管理不完全相同,特别要注意的是某些UNIX在每个裸设备的头部要保留一定的空间,应用程序在使用裸设备时不可以覆盖这一部分,否则会对裸设备造成损坏。所以一个裸设备的实际可用空间是分配给裸设备的空间再减去这部分操作系统保留空间。下面是常用UNIX的OS Reserved Size列表:

UNIXOS Reserved Size

----------------------------

SUN Solaris0

HP-UX0

IBM AIX4k

Tru64 UNIX64k

Linux0

1.3 dd命令

UNIX上读写裸设备不能使用cp, cpio, tar等命令,必须用dd,下面是几个dd常用参数的简单说明,更详细的信息请参考UNIX使用手册或用命令man dd。

dd [ operand=value ... ]

if=file 指定输入文件,缺省值是标准输入

of=file 指定输出文件,缺省值是标准输出

bs=n 设置输入和输出的块大小为n字节,也可以用“k”作单位

skip=n 在拷贝之前跳过n个输入块,缺省值是0

seek=n 在拷贝之前从输出文件首部跳过n块,缺省值是0

count=n 指定拷贝的块数,缺省拷贝到输入文件结束

1.4 对本文中示例的说明

a. 所有例子中ORACLE的DB_BLOCK_SIZE都是8k

b. /oradata是一文件系统目录

c. /dev/rlv_data,/dev/rlv_redo和/dev/rlv_ctrl是三个RAW DEVICE,大小均为8MB(8192k)

d. 在未提到操作系统时,默认是AIX,OS_RESERVED_SIZE=4K

二、移动数据文件(DATAFILE)

2.1 在裸设备上建立数据文件

用以下命令建立表空间:

SQL> CREATE TABLESPACE ts_test DATAFILE '/dev/rlv_data' SIZE 8180k;

SIZE指定的数值必须小于或等于8180k,否则语句将会失败:

ORA-01119: error in creating database file '/dev/rlv_data'

ORA-27042: not enough space on raw partition to fullfill request

这个最大值的计算方法如下:

8192k(RAW DEVICE SIZE) - 4k (OS_RESERVED_SIZE) - 8k (DB_BLOCK_SIZE) = 8180k

为什么还要减去一个DB_BLOCK_SIZE呢?这是因为ORACLE建立DATAFILE时,在命令中SIZE指定的大小之外,还要在文件头另加一个BLOCK,叫作“Oracle OS Header Block”,里面保存有这个文件的逻辑块大小和文件块数等信息。这一点并不是在RAW DEVICE上建DATAFILE特有的,如果你在文件系统上建一个DATAFILE,指定SIZE 1000k的话,你用ls -l或dir命令看到的文件大小将是1008k (DB_BLOCK_SIZE=8K)。

2.2 在文件系统和裸设备之间移动数据文件

2.2.1 从文件系统到裸设备

a. 在文件系统上建一个4M的DATAFILE

SQL> CREATE TABLESPACE test DATAFILE '/oradata/test.dbf' SIZE 4M;

b. 查看一下这个新建的DATAFILE的大小 (注:4202496 = 4M + 8K)

$ ls -l /oradata/test.dbf

-rw-r----- 1 oracle dba 4202496 Aug 29 15:01 /oradata/test.dbf

c. 按下表公式确定dd的参数

d. 在数据库没有OPEN的状态下,用dd进行拷贝,下面给出命令及输出

AIX$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=4k seek=1

1026+0 records in

1026+0 records out

Tru64$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=64k seek=1

64+1 records in

64+1 records out

Other$ dd if=/oradata/test.dbf of=/dev/rlv_data bs=1024k

4+1 records in

4+1 records out

2.2.2 从裸设备到文件系统

a. 确定数据文件实际大小file_size,用于下一步计算dd的参数count。如果count计算不对,拷贝出的数据文件无效,数据库无法打开。

SQL> SELECT bytes, blocks, bytes/blocks db_block_size, bytes+bytes/blocks file_size

FROM dba_data_files WHERE file_name='/dev/rlv_data';

BYTESBLOCKSDB_BLOCK_SIZEFILE_SIZE

---------- -------- ------------- ---------

419430451281924202496

b. 按下表公式确定dd的参数,min表示二者之中取较小的

c. 在数据库没有OPEN的状态下,用dd进行拷贝,下面给出命令及输出

AIX$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=4k skip=1 count=1026

1026+0 records in

1026+0 records out

Tru64$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=8k skip=8 count=513

513+0 records in

513+0 records out

Other$ dd if=/dev/rlv_data of=/oradata/test2.dbf bs=8k count=513

513+0 records in

513+0 records out

2.2.3 无论从FILE SYSTEM拷贝到RAW DEVICE还是反之,想让ORACLE以新的数据文件打开数据库,必须进行RENAME操作

SQL> STARTUP MOUNT;

SQL> ALTER DATABASE RENAME FILE 'oldfilename' TO 'newfilename';

SQL> ALTER DATABASE OPEN;

三、移动联机重作日志(ONLINE REDO LOG)

3.1 在裸设备上建ONLINE REDO LOG

用以下命令增加一组ONLINE REDO LOG:

SQL> ALTER DATABASE ADD LOGFILE GROUP 4 '/dev/rlv_redo' SIZE xxxxk;

在裸设备上建REDO LOG时也要计算SIZE子句可使用的最大值,方法类似于在2.1中建DATAFILE时的计算方法,唯一不同的是要把公式中的DB_BLOCK_SIZE换成REDO_BLOCK_SIZE(即REDO LOG的逻辑块大小)。这个REDO_BLOCK_SIZE在不同操作系统上取值不同,用以下两种方法均可得到这个值,同时还可计算出REDO LOG的实际文件大小file_size):

方法1:dump现有的REDO LOG FILE

SQL> ALTER SYSTEM DUMP LOGFILE '/oradata/redo01.log';

SQL> SHOW PARAMETER user_dump_dest

查看user_dump_dest目录下刚产生的trc文件:

FILE HEADER:

Software vsn=135294976=0x8107000, Compatibility Vsn=135290880=0x8106000

Db Id=3227187598=0xc05af98e, Db Name='V817'

Control Seq=12474=0x30ba, File size=8192=0x2000

File Number=5, Blksiz=512, File Type=2 LOG

方法2:用ORACLE提供的工具dbfsize,对文件系统和RAW DEVICE上的文件都适用

$ dbfsize /oradata/redo01.log

Database file: /oradata/redo01.log

Database file type: file system

Database file size: 8192 512 byte blocks

从以上两个输出都可得知REDO_BLOCK_SIZE=512,blocks=8192

file_size=(blocks + 1) * REDO_BLOCK_SIZE = (8192+1)*512=4194816

如果已知所在平台的REDO_BLOCK_SIZE,也可以通过查询数据字典来计算file_size:

SQL> SELECT b.member, b.bytes, b.bytes+512 file_size FROM v$logfile a, v$log b

WHERE a.group#=b.group# and a.member='/oradata/redo01.log ';

MEMBERBYTES FILE_SIZE

-------------------------------------

/oradata/redo01.log41943044194816

下表列出了常用OS上的ORACLE REDO_BLOCK_SIZE:

OSREDO_BLOCK_SIZE

----------------- ---------------

Windows512

SUN Solaris512

HP-UX1024

IBM AIX512

Compaq Tru64 UNIX1024

Linux512

3.2在文件系统和裸设备之间移动ONLINE REDO LOG

参见2.2拷贝DATAFILE的过程,唯一不同是要把DB_BLOCK_SIZE换成REDO_BLOCK_SIZE。另外,REDO LOG也可以不用dd进行拷贝,而采用删除重建的方法:

SQL> SELECT * FROM v$log; --be sure it's not current and archived

SQL> ALTER SYSTEM SWITCH LOGFILE; --if it’s current, force switch

SQL> ALTER DATABASE DROP LOGFILE GROUP n;

SQL> ALTER DATABASE ADD LOGFILE GROUP n 'newlogfilename' SIZE xxxxM;

四、移动控制文件(CONTROL FILE)

4.1在裸设备上建控制文件

ORACLE的控制文件是执行CREATE DATABASE或CREATE CONTROLFILE语句时生成的,其名字是由初始化参数文件init$ORACLE_SID.ora中的control_files参数指定。CONTROL FILE的大小不能显式指定,而且随着数据库的运行,它还会自动增长,所以为控制文件划分裸设备时要根据经验,留好足够的余量,以免不必要的麻烦。CONTROL FILE的逻辑块大小和DB_BLOCK_SIZE相同,而且文件头部也和DATAFILE一样有一块“Oracle OS Header Block”。

4.2在文件系统和裸设备之间移动控制文件

4.2.1 使用dd复制

拷贝CONTROL FILE的方法基本与2.2中拷贝DATAFILE相同,唯一不同是当由裸设备向文件系统拷贝时,如何确定CONTROL FILE的实际大小file_size (ORACLE数据字典里没有CONTROL FILE大小的数据)。下面介绍两个方法:

方法1:执行完下面的SQL语句,再到user_dump_dest目录查看刚产生的trc文件

SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME CONTROLF LEVEL 10';

FILE HEADER:

Software vsn=135266304=0x8100000, Compatibility Vsn=134217728=0x8000000

Db Id=1937054535=0x73751b47, Db Name='O817'

Control Seq=5838=0x16ce, File size=476=0x1dc

File Number=0, Blksiz=8192, File Type=1 CONTROL

方法2:用ORACLE提供的工具dbfsize

$ dbfsize /oradata/control01.ctl

Database file: /oradata/control01.ctl

Database file type: file system

Database file size: 476 8192 byte blocks

从以上两个方法的输出结果都可得到file_size=(476+1)*8192=3907584

4.2.2 使用SQL命令复制

相对于4.2.1介绍的用dd拷贝CONTROL FILE,下面用SQL语句进行复制的方法更为简洁:

SQL> STARTUP MOUNT

SQL> ALTER DATABASE BACKUP CONTROLFILE TO 'newcontrolfile';

语句中newcontrolfile既可以是文件系统文件,也可以是RAW DEVICE,所以在MOUNT状态下运行这个命令就可以生成一个与现有CONTROL FILE完全相同CONTROL FILE复件。

4.2.3 修改初始化参数文件(init$ORACLE_SID.ora)

无论用4.2.1还是4.2.2的方法产生了新的CONTROL FILE,为了让数据库使用新的CONTROL FILE,只要修改init$ORACLE_SID.ora里的control_files参数即可。

五、Recovery Manager (RMAN)

RMAN是ORACLE8开始提供的备份与恢复工具,它能自动正确地跳过裸设备头部的OS Reserved Block,通过使用RMAN的BACKUP和RESTORE功能,可以方便地达到把DATAFILE和CONTROL FILE在文件系统和裸设备之间移动的目的,具体操作过程在这里不再详述,请参见RMAN手册。

星期一, 四月 30, 2007

限定特定IP访问数据库

可以在$OREACLE_HOME/network/admin下直接修改sqlnet.ora文件,增加如下内容:

tcp.validnode_checking=yes

#允许访问的ip

tcp.invited_nodes=(ip1,ip2,……)

#不允许访问的ip

tcp.excluded_nodes=(ip1,ip2,……)

修改sqlnet.ora后,重新启动listener服务,改动就可以生效了。

如果有人从不允许的IP客户端连接过来,会出现以下错误:

ERROR: ORA-12537: TNS: 连接已关闭

这种在Oracle网络层实现客户端IP访问限制的方法在防火墙后面的局域网内部可以采用。

不允许访问IP地址的方法我觉得应用可能不大,因为IP地址是很容易修改的,但DBA完全可以采用允许IP地址访问的方法,把会使用的客户端IP写入、DBA自己的IP写入即可屏蔽掉其他可能非法访问的IP来源。