How to recover data with DUL after datafile offline

系统情况如下:
1. Oracle版本是10.2.0.3,操作系统是HP-UX PA RISC 64
2. 数据文件存储在裸设备上
3. 需要恢复的表是分区表
4. 在调整存储硬件的时候没有关闭数据库,由于某些不可预知的故障导致某些用户表空间的数据文件write error,然后自动offline了
5. 数据库确实是归档模式,但是有一个每小时删除一次归档的crontab,删除了重新online数据文件需要的所有归档
6. 保留了之前建表时的create脚本

恢复过程如下:
1. DUL使用的init.dul内容:

CONTROL_FILE = control.dul
DB_BLOCK_SIZE = 16384

2. DUL使用的control.dul文件内容

0 1 /somepath/rsystem_01_8g blocks 524161
22 128 /somepath/r_data07_01_32g blocks 2096641
22 134 /somepath/r_data07_02_32g blocks 2096641 
22 141 /somepath/r_data07_03_32g blocks 2096641
22 147 /somepath/r_data07_04_32g blocks 2096641
22 153 /somepath/r_data07_05_32g blocks 2096641
22 159 /somepath/r_data07_06_32g blocks 2096641
22 165 /somepath/r_data07_07_32g blocks 2096641
22 171 /somepath/r_data07_08_32g blocks 2096641
22 177 /somepath/r_data07_09_32g blocks 2096641
22 183 /somepath/r_data07_10_32g blocks 2096641

在HP-UX PA RISC中,虽然数据文件是存储在裸设备中的,但是仍然不需要设置需要跳过的字节,跟AIX中DUL相比较,缺少了第4位的4096。

3. 登录DUL

DUL> bootstrap;
DUL> unload table user_name.table_name;

由于system表空间正常,数据字典都存在,因此unload table的过程很简单,并且对于分区表(复合分区表)DUL也是完全胜任的,只需要指定table name,就会自动unload出该表的所有分区以及子分区的数据。

这次DUL大概花了4个小时,unload出120G左右的数据。数据库字符集为ZHS16GBK,字段内容包含中文内容,DUL可以unload出正确的字符。

4. 重新创建表结构,将DUL卸载出的数据再sqlldr到表中。
此步操作在处理位于offline表空间中的表分区时碰到了ORA-14117错误,详细参看How to resolve ORA-14117: partition resides in offlined tablespace文章。

Something about PGA allocation

1. 在设置了PGA_AGGREGATE_TARGET初始化参数的数据库中,表示使用PGA自动管理,所有其它的*_AREA_SIZE参数都将被忽略。PGA_AGGREGATE_TARGET参数值的范围是:10MB 到 4096GB–1个字节之间。

2. Oracle数据库会按照每个session的需要为其分配PGA,同时会尽量维持整个PGA的内存总和不超过PGA_AGGREGATE_TARGET参数所定义的值。

3. 在PGA中对于性能影响最大的是SQL Work Area(SQL工作区)
Oracle将所分配的SQL工作区大小分成三种类型:
Optimal:SQL语句能够完全在所分配的SQL工作区内完成所有的操作。这时性能最佳。
Onepass:SQL语句需要与磁盘上的临时表空间交互一次才能够在所分配的SQL工作区中完成所有的操作。
Multipass:由于SQL工作区过小,从而导致SQL语句需要与磁盘上的临时表空间交互多次才能完成所有的操作。这时性能将急剧下降。

SQL> select swh.MULTIPASSES_EXECUTIONS,swh.LOW_OPTIMAL_SIZE,swh.HIGH_OPTIMAL_SIZE
  2  from v$sql_workarea_histogram swh
  3  where swh.MULTIPASSES_EXECUTIONS>0
  4  order by 1 desc;

通过以上SQL可以知道所有被分配了Multipass尺寸的会话需要多大的内存才能够成为Optimal操作。

4. 单个会话使用PGA的期望尺寸(也可以认为是实际分配的最大尺寸)计算公式是: min(5%*pga_aggregate_target,50%*_pga_max_size,_smm_max_size)

5. 每次修改pga_aggregate_target值,Oracle都会自动重新计算_smm_max_size值。
如果_pga_max_size > 5%*pga_aggregate_target,则_smm_max_size为5%*pga_aggregate_target。
如果_pga_max_size <= 5%*pga_aggregate_target,则_smm_max_size为50%*_pga_max_size。 实际上最终决定会话PGA使用量的隐含参数是_smm_max_size。 我们通过在会话级别修改_pga_max_size或者_smm_max_size,可以达到微调单个会话PGA使用效率的目的。 注:_smm_max_size单位是K。在已知版本中,_pga_max_size的初始大小200M是硬编码在Oracle Source中的,因此在默认情况下,即使设置了很大的pga_aggregate_target,实际上每个会话能够使用的workarea size也只能最大是100M。所以在大内存的机器上,请注意手工设置_smm_max_size和_smm_px_max_size。

Listener Password in Oracle 10g

在Google上搜索“监听 安全 oracle”,一堆《实例讲解Oracle监听口令及监听器安全》的文章,都是copy+paste自eygle的这篇《Oracle的监听口令及监听器安全》,eygle的测试环境是本地的10.2.0.3客户端加远程9.2.0.4数据库。

如果服务器端数据库版本在Oracle9i以后,设置监听密码的情况则有一些变化。

Metalink Note 260986.1中,可以看到:

In Oracle 10, the TNSListener is secure out of the box and there should not be a need to set a listener password as in older versions of the Oracle listener.

Oracle10g以后,设置Listener密码已经不是安全检查的必要条件了,因为默认在10g里面除了启动监听的用户之外,其它用户都无法停止Listener(还有另外一些lsnrctl的命令也同样被禁止了,比如trace, reload等),即使Listener没有设置密码。

在默认情况下,启动Listener或者使用lsnrctl status命令查看监听状态,可以看到:

Security                  ON: Password or Local OS Authentication

这表明Listener的安全机制使用了Password方式或者Local OS Authentication方式,在这种状态下,即使是设置了监听密码,对于启动监听的user来说,也仍然是不需要任何密码就可以停止监听的。

如果我们想去除自Oracle10g之后的这种新安全机制,那么需要在listener.ora文件中添加:

LOCAL_OS_AUTHENTICATION_[listener name] = OFF

重新启动Listener之后,将会只看到:

Security                  ON: Password

这就又回复到了Oracle9i时的状态,只要有密码存在,无论是谁尝试停止监听都会被要求set password。

D:\Temp>lsnrctl

LSNRCTL for 32-bit Windows: Version 11.1.0.7.0 - Production on 20-MAY-2009 11:15:41

Copyright (c) 1991, 2008, Oracle.  All rights reserved.

Welcome to LSNRCTL, type "help" for information.

LSNRCTL> status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521)))
TNS-01169: The listener has not recognized the password
LSNRCTL> stop
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521)))
TNS-01169: The listener has not recognized the password
LSNRCTL> set password
Password:
The command completed successfully
LSNRCTL> status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for 32-bit Windows: Version 11.1.0.7.0 - Production
Start Date                20-MAY-2009 11:14:22
Uptime                    0 days 0 hr. 1 min. 34 sec
Trace Level               off
Security                  ON: Password
SNMP                      OFF
Listener Parameter File   D:\oracle\product\11.1.0\db_1\network\admin\listener.ora
Listener Log File         d:\oracle\diag\tnslsnr\kamus-laptop\listener\alert\log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=kamus-laptop)(PORT=1521)))
Services Summary...
Service "orcl11g" has 1 instance(s).
  Instance "orcl11g", status READY, has 1 handler(s) for this service...
Service "orcl11g_XPT" has 1 instance(s).
  Instance "orcl11g", status READY, has 1 handler(s) for this service...
The command completed successfully
LSNRCTL> stop
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=kamus-laptop)(PORT=1521)))
The command completed successfully
LSNRCTL>