How to resolve ksvcreate: Process(m000) creation failed

在一套10.2.0.1.0的一主一备dataguard测试环境中,physical standby database的告警日志文件里,经常报出下述错误信息:

Thu Dec  1 08:47:59 2011
alter database open
Thu Dec  1 08:48:00 2011
SMON: enabling cache recovery
Thu Dec  1 08:48:06 2011
Physical standby database opened for read only access.
Completed: alter database open
Thu Dec  1 08:48:11 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:48:38 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:49:38 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:50:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:51:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:52:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:53:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:54:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:55:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:56:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:57:39 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:58:40 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 08:59:40 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 09:00:40 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 09:01:41 2011
ksvcreate: Process(m000) creation failed
Thu Dec  1 09:02:41 2011
ksvcreate: Process(m000) creation failed

后经查找MetaLink:
‘Ksvcreate: Process(m000) creation failed’ after Standby Database Open Read Only Multiple Times [ID 418553.1]

Applies to:

Oracle Server – Enterprise Edition – Version: 10.2.0.1 to 10.2.0.1 – Release: 10.2 to 10.2
Information in this document applies to any platform.
***Checked for relevance on 15-APR-2011***
Symptoms

Switching a Physical Standby Database multiple to READ ONLY Mode will report the following Errors in the ALERT.LOG:

ksvcreate: Process(m000) creation failed

Changes

Switch Physical Standby from READ ONLY to apply and back to READ ONLY.
Cause

The Cause of this Problem has been identified in Bug 5583049.
Solution

There are two Workarounds available:
Restart the Instance..
or
Disable ADDM – Should be re-enabled if Standby takes up the Primary Role
* Set SGA_TARGET=0 and set shared_pool_size, db_cache_size, etc if using
Automatic SGA Memory Management (ASMM)

* Set STATISTICS_LEVEL=BASIC to disable statistics gathering
References

BUG:5583049 – ‘KSVCREATE: PROCESS(M000) CREATION FAILED’ AFTER STANDBY OPEN RO MULTIPLE TIMES

原来是oracle在10g上的bug,原因是physical standby database在没有完全关闭的情况下多次以read only方式打开。照着Oracle给出的解决方案1,重启Physical standby实例,暂且规避了该错误信息

umount误操作引发数据库宕机

在开发数据库上,执行完其它测试工作后,随手执行命令卸载光盘,图省事,执行了下述命令:

[root@OEL511gR2 ~]# umount -all

然后,然后,就导致了一则不大不小的数据库宕机!!!
因为,我的开发库文件系统信息如下:

[root@OEL511gR2 ~]# df -Th
Filesystem    Type    Size  Used Avail Use% Mounted on
/dev/sda1     ext3    9.7G  7.9G  1.3G  87% /
tmpfs        tmpfs    502M     0  502M   0% /dev/shm
/dev/sdb1     ext4     67G   57G  6.5G  90% /u02/rimis_data
172.16.1.100:/backup
               nfs    466G  105G  361G  23% /backup
[root@OEL511gR2 ~]#

而数据库的数据文件信息如下:

[oracle@OEL511gR2 ~]$ rlwrap sqlplus / as sysdba
SQL*Plus: Release 10.2.0.5.0 - Production on Thu Nov 24 17:09:59 2011
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u01/app/oradata/RIMISDB/system01.dbf
/u01/app/oradata/RIMISDB/undotbs01.dbf
/u01/app/oradata/RIMISDB/sysaux01.dbf
/u01/app/oradata/RIMISDB/users01.dbf
/u02/rimis_data/css_ott.dbf
/u02/rimis_data/css_ltt_bk.dbf
/u02/rimis_data/css_lti_bl.dbf
/u02/rimis_data/css_oti.dbf
/u02/rimis_data/css_ltt_rp.dbf
/u02/rimis_data/css_cdi.dbf
/u02/rimis_data/css_lti_ob.dbf
NAME
--------------------------------------------------------------------------------
/u02/rimis_data/css_ltt_eh.dbf
/u02/rimis_data/css_blt.dbf
/u02/rimis_data/css_ltt_bl.dbf
/u02/rimis_data/css_eci.dbf
/u02/rimis_data/css_ect.dbf
/u02/rimis_data/css_lti_ec.dbf
/u02/rimis_data/css_lti.dbf
/u02/rimis_data/css_ltt_gw.dbf
/u02/rimis_data/css_ltt.dbf
/u02/rimis_data/css_ltt_tr.dbf
/u02/rimis_data/css_lti_rp.dbf
NAME
--------------------------------------------------------------------------------
/u02/rimis_data/css_lti_bk.dbf
/u02/rimis_data/css_gwi.dbf
/u02/rimis_data/css_bli.dbf
/u02/rimis_data/css_lti_tr.dbf
/u02/rimis_data/css_ltt_ec.dbf
/u02/rimis_data/css_gwt.dbf
/u02/rimis_data/css_lti_gw.dbf
/u02/rimis_data/css_cdt.dbf
/u02/rimis_data/css_ltt_ob.dbf
/u02/rimis_data/css_lti_eh.dbf
32 rows selected.
SQL>

接着,邮箱就瞬间收到了来自开发项目组发出的数据库不可用的邮件!
最后,重新挂载磁盘,重启数据库。
一个小插曲,启完数据库后,忘记了启监听,就电话通知开发部门数据库可用。
又接着还是一通反应数据库不可用,罪过啊,手工启监听,手工注册服务!
写在这里,给自己提个醒,在服务器上操作时,记得千万千万要谨慎!!!好在,本次故障中,硬盘没损坏!不然就KO了!

如何从逻辑备份的dumpfile文件里获取头部详细信息?

在上一篇日志里,我们了解了 如何从逻辑备份的dumpfile文件里获取DDL脚本? 在本篇里,我们参照 MetaLink文档ID 462488.1】来了解如何从dumpfile里获取更为详细的头部信息。

所有的dumpfile文件都是包含大小为4KB的头部数据区,该区域记录dumpfile文件的详细信息。从Oracle 10.2.0.1.0开始,可以调用系统包DBMS_DATAPUMP.GET_DUMPFILE_INFO来获取dumpfile的头部信息。

1   参照 MetaLink文档ID 462488.1】我们可以创建一个SHOW_DUMPFILE_INFO存储过程,通过调用该过程可以获取dumpfile的详细信息,该过程的源代码如下:

CONNECT sys/manager as sysdba;

CREATE PROCEDURE show_dumpfile_info(
p_dir  VARCHAR2 DEFAULT 'DATA_PUMP_DIR',
p_file VARCHAR2 DEFAULT 'EXPDAT.DMP')
AS
-- p_dir         = directory object where dumpfile can be found
-- p_file        = simple filename of export dumpfile (case-sensitive)
v_separator   VARCHAR2(80) := '--------------------------------------' ||
'--------------------------------------';
v_path        all_directories.directory_path%type := '?';
v_filetype    NUMBER;                 -- 0=unknown 1=expdp 2=exp
v_fileversion VARCHAR2(15);           -- 0.1=10gR1 1.1=10gR2 2.1=11g
v_info_table  sys.ku$_dumpfile_info;  -- PL/SQL table with file info
type valtype  IS VARRAY(22) OF VARCHAR2(2048);
var_values    valtype := valtype();
no_file_found EXCEPTION;
PRAGMA        exception_init(no_file_found, -39211);

BEGIN

-- Show generic info:
-- ==================

dbms_output.put_line(v_separator);
dbms_output.put_line('Purpose..: Obtain details about export ' ||
'dumpfile.        Version: 19-MAR-2008');
dbms_output.put_line('Required.: RDBMS version: 10.2.0.1.0 or higher');
dbms_output.put_line('.          ' ||
'Export dumpfile version: 7.3.4.0.0 or higher');
dbms_output.put_line('.          ' ||
'Export Data Pump dumpfile version: 10.1.0.1.0 or higher');
dbms_output.put_line('Usage....: ' ||
'execute show_dumfile_info(''DIRECTORY'', ''DUMPFILE'');');
dbms_output.put_line('Example..: ' ||
'exec show_dumfile_info(''MY_DIR'', ''expdp_s.dmp'')');
dbms_output.put_line(v_separator);
dbms_output.put_line('Filename.: ' || p_file);
dbms_output.put_line('Directory: ' || p_dir);

-- Retrieve Export dumpfile details:
-- =================================

SELECT directory_path INTO v_path FROM all_directories
WHERE directory_name = p_dir
OR directory_name = UPPER(p_dir);

dbms_datapump.get_dumpfile_info(
filename   => p_file,       directory => UPPER(p_dir),
info_table => v_info_table, filetype  => v_filetype);

var_values.EXTEND(22);
FOR i in 1 .. 22 LOOP
BEGIN
SELECT value INTO var_values(i) FROM TABLE(v_info_table)
WHERE item_code = i;
EXCEPTION WHEN OTHERS THEN var_values(i) := '';
END;
END LOOP;

-- Show dumpfile details:
-- ======================
-- For Oracle10g Release 2 and higher:
--    dbms_datapump.KU$_DFHDR_FILE_VERSION        CONSTANT NUMBER := 1;
--    dbms_datapump.KU$_DFHDR_MASTER_PRESENT      CONSTANT NUMBER := 2;
--    dbms_datapump.KU$_DFHDR_GUID                CONSTANT NUMBER := 3;
--    dbms_datapump.KU$_DFHDR_FILE_NUMBER         CONSTANT NUMBER := 4;
--    dbms_datapump.KU$_DFHDR_CHARSET_ID          CONSTANT NUMBER := 5;
--    dbms_datapump.KU$_DFHDR_CREATION_DATE       CONSTANT NUMBER := 6;
--    dbms_datapump.KU$_DFHDR_FLAGS               CONSTANT NUMBER := 7;
--    dbms_datapump.KU$_DFHDR_JOB_NAME            CONSTANT NUMBER := 8;
--    dbms_datapump.KU$_DFHDR_PLATFORM            CONSTANT NUMBER := 9;
--    dbms_datapump.KU$_DFHDR_INSTANCE            CONSTANT NUMBER := 10;
--    dbms_datapump.KU$_DFHDR_LANGUAGE            CONSTANT NUMBER := 11;
--    dbms_datapump.KU$_DFHDR_BLOCKSIZE           CONSTANT NUMBER := 12;
--    dbms_datapump.KU$_DFHDR_DIRPATH             CONSTANT NUMBER := 13;
--    dbms_datapump.KU$_DFHDR_METADATA_COMPRESSED CONSTANT NUMBER := 14;
--    dbms_datapump.KU$_DFHDR_DB_VERSION          CONSTANT NUMBER := 15;
-- For Oracle11gR1:
--    dbms_datapump.KU$_DFHDR_MASTER_PIECE_COUNT  CONSTANT NUMBER := 16;
--    dbms_datapump.KU$_DFHDR_MASTER_PIECE_NUMBER CONSTANT NUMBER := 17;
--    dbms_datapump.KU$_DFHDR_DATA_COMPRESSED     CONSTANT NUMBER := 18;
--    dbms_datapump.KU$_DFHDR_METADATA_ENCRYPTED  CONSTANT NUMBER := 19;
--    dbms_datapump.KU$_DFHDR_DATA_ENCRYPTED      CONSTANT NUMBER := 20;
-- For Oracle11gR2:
--    dbms_datapump.KU$_DFHDR_COLUMNS_ENCRYPTED   CONSTANT NUMBER := 21;
--    dbms_datapump.KU$_DFHDR_ENCPWD_MODE         CONSTANT NUMBER := 22;

-- For Oracle10gR2: KU$_DFHDR_MAX_ITEM_CODE       CONSTANT NUMBER := 15;
-- For Oracle11gR1: KU$_DFHDR_MAX_ITEM_CODE       CONSTANT NUMBER := 20;
-- For Oracle11gR2: KU$_DFHDR_MAX_ITEM_CODE       CONSTANT NUMBER := 22;

dbms_output.put_line('Disk Path: ' || v_path);

IF v_filetype = 1 OR v_filetype = 2 THEN
-- Get characterset name:
BEGIN
SELECT var_values(5) || ' (' || nls_charset_name(var_values(5)) ||
')' INTO var_values(5) FROM dual;
EXCEPTION WHEN OTHERS THEN null;
END;
IF v_filetype = 2 THEN
dbms_output.put_line(
'Filetype.: ' || v_filetype || ' (Original Export dumpfile)');
dbms_output.put_line(v_separator);
SELECT DECODE(var_values(13), '0', '0 (Conventional Path)',
'1', '1 (Direct Path)', var_values(13))
INTO var_values(13) FROM dual;
dbms_output.put_line('...Characterset ID.: ' || var_values(5));
dbms_output.put_line('...Direct Path.....: ' || var_values(13));
dbms_output.put_line('...Export Version..: ' || var_values(15));
ELSIF v_filetype = 1 THEN
dbms_output.put_line(
'Filetype.: ' || v_filetype || ' (Export Data Pump dumpfile)');
dbms_output.put_line(v_separator);
SELECT SUBSTR(var_values(1), 1, 15) INTO v_fileversion FROM dual;
SELECT DECODE(var_values(1),
'0.1', '0.1 (Oracle10g Release 1: 10.1.0.x)',
'1.1', '1.1 (Oracle10g Release 2: 10.2.0.x)',
'2.1', '2.1 (Oracle11g Release 1: 11.1.0.x)',
'3.1', '3.1 (Oracle11g Release 2: 11.2.0.x)',
var_values(1)) INTO var_values(1) FROM dual;
SELECT DECODE(var_values(2), '0', '0 (No)', '1', '1 (Yes)',
var_values(2)) INTO var_values(2) FROM dual;
SELECT DECODE(var_values(14), '0', '0 (No)', '1', '1 (Yes)',
var_values(14)) INTO var_values(14) FROM dual;
SELECT DECODE(var_values(18), '0', '0 (No)', '1', '1 (Yes)',
var_values(18)) INTO var_values(18) FROM dual;
SELECT DECODE(var_values(19), '0', '0 (No)', '1', '1 (Yes)',
var_values(19)) INTO var_values(19) FROM dual;
SELECT DECODE(var_values(20), '0', '0 (No)', '1', '1 (Yes)',
var_values(20)) INTO var_values(20) FROM dual;
SELECT DECODE(var_values(21), '0', '0 (No)', '1', '1 (Yes)',
var_values(21)) INTO var_values(21) FROM dual;
SELECT DECODE(var_values(22),
'1', '1 (Unknown)',
'2', '2 (None)',
'3', '3 (Password)',
'4', '4 (Dual)',
'5', '5 (Transparent)',
var_values(22)) INTO var_values(22) FROM dual;

dbms_output.put_line('...File Version....: ' || var_values(1));
dbms_output.put_line('...Master Present..: ' || var_values(2));
dbms_output.put_line('...GUID............: ' || var_values(3));
dbms_output.put_line('...File Number.....: ' || var_values(4));
dbms_output.put_line('...Characterset ID.: ' || var_values(5));
dbms_output.put_line('...Creation Date...: ' || var_values(6));
dbms_output.put_line('...Flags...........: ' || var_values(7));
dbms_output.put_line('...Job Name........: ' || var_values(8));
dbms_output.put_line('...Platform........: ' || var_values(9));
IF v_fileversion >= '2.1' THEN
dbms_output.put_line('...Instance........: ' || var_values(10));
END IF;
dbms_output.put_line('...Language........: ' || var_values(11));
dbms_output.put_line('...Block size......: ' || var_values(12));
dbms_output.put_line('...Metadata Compres: ' || var_values(14));
IF dbms_datapump.KU$_DFHDR_MAX_ITEM_CODE > 15 THEN
dbms_output.put_line('...Data Compressed.: ' || var_values(18));
dbms_output.put_line('...Metadata Encrypt: ' || var_values(19));
dbms_output.put_line('...Data Encrypted..: ' || var_values(20));
dbms_output.put_line('...Column Encrypted: ' || var_values(21));
dbms_output.put_line('...Encrypt.pwd. mod: ' || var_values(22));
IF v_fileversion = '2.1' or v_fileversion = '3.1' THEN
dbms_output.put_line('...Master Piece Cnt: ' || var_values(16));
dbms_output.put_line('...Master Piece Num: ' || var_values(17));
END IF;
END IF;
IF v_fileversion >= '1.1' THEN
dbms_output.put_line('...Job Version.....: ' || var_values(15));
END IF;
dbms_output.put_line('...Max Items Code..: ' ||
dbms_datapump.KU$_DFHDR_MAX_ITEM_CODE);
END IF;
ELSE
dbms_output.put_line('Filetype.: ' || v_filetype);
dbms_output.put_line(v_separator);
dbms_output.put_line('ERROR....: Not an export dumpfile.');
END IF;
dbms_output.put_line(v_separator);

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('Disk Path: ?');
dbms_output.put_line('Filetype.: ?');
dbms_output.put_line(v_separator);
dbms_output.put_line('ERROR....: Directory Object does not exist.');
dbms_output.put_line(v_separator);
WHEN no_file_found THEN
dbms_output.put_line('Disk Path: ' || v_path);
dbms_output.put_line('Filetype.: ?');
dbms_output.put_line(v_separator);
dbms_output.put_line('ERROR....: File does not exist.');
dbms_output.put_line(v_separator);
END;
/

2  接下来,我们还以上篇博文里提到的使用EXPDP导出的dumpfile为例,其具体调用方法如下:

SQL> show user;
USER is "SYS"
SQL> select * from dba_directories where directory_name like 'MIG%';
OWNE DIRECTORY_NAME  DIRECTORY_PATH
---- --------------- --------------------------------------------------
SYS  MIG_DIR         /u01/app/oracle/mig_dir
SQL> !ls -l /u01/app/oracle/mig_dir
total 24360
-rw-r----- 1 oracle asmadmin 24797184 Nov 21 17:19 expdp_hr.dmp
-rw-r--r-- 1 oracle asmadmin     3299 Nov 21 17:19 expdp_hr.log
-rw-r--r-- 1 oracle asmadmin   103892 Nov 21 17:23 hr_ddl.sql
-rw-r--r-- 1 oracle asmadmin     1672 Nov 21 17:23 impdp_hr.log
SQL> exec show_dumpfile_info(p_dir=>'mig_dir',p_file=>'expdp_hr.dmp');
----------------------------------------------------------------------------
Purpose..: Obtain details about export dumpfile.        Version: 19-MAR-2008
Required.: RDBMS version: 10.2.0.1.0 or higher
.          Export dumpfile version: 7.3.4.0.0 or higher
.          Export Data Pump dumpfile version: 10.1.0.1.0 or higher
Usage....: execute show_dumfile_info('DIRECTORY', 'DUMPFILE');
Example..: exec show_dumfile_info('MY_DIR', 'expdp_s.dmp')
----------------------------------------------------------------------------
Filename.: expdp_hr.dmp
Directory: mig_dir
Disk Path: /u01/app/oracle/mig_dir
Filetype.: 1 (Export Data Pump dumpfile)
----------------------------------------------------------------------------
...File Version....: 3.1 (Oracle11g Release 2: 11.2.0.x)
...Master Present..: 1 (Yes)
...GUID............: B23C2582426C247EE04010ACBF00579A
...File Number.....: 1
...Characterset ID.: 873 (AL32UTF8)
...Creation Date...: Mon Nov 21 17:19:48 2011
...Flags...........: 2
...Job Name........: "HR"."SYS_EXPORT_SCHEMA_01"
...Platform........: x86_64/Linux 2.4.xx
...Instance........: rac1.localdomain:devdb1
...Language........: AL32UTF8
...Block size......: 4096
...Metadata Compres: 1 (Yes)
...Data Compressed.: 0 (No)
...Metadata Encrypt: 0 (No)
...Data Encrypted..: 0 (No)
...Column Encrypted: 0 (No)
...Encrypt.pwd. mod: 2 (None)
...Master Piece Cnt: 1
...Master Piece Num: 1
...Job Version.....: 11.02.00.00.00
...Max Items Code..: 22
----------------------------------------------------------------------------
PL/SQL procedure successfully completed.
SQL>

可以看到较为详细的信息,其中的Block size 4096表示dumpfile的header为4K。

3   如果,想把该过程的执行权限给普通用户:

GRANT execute ON show_dumpfile_info TO username;

4   如果,想要删除改过程:

DROP PROCEDURE show_dumpfile_info;

5  对于UNIX平台,我们还可以借助操作系统的命令来简单获取一些简单的信息:

rac1-> pwd
/home/oracle
rac1-> ls -l
total 23688
drwxrwxr-x 17 root   root         4096 May 26 21:20 12419321
-rw-r--r--  1 oracle oinstall    15626 Aug 31 14:28 db.rsp
-rw-r--r--  1 oracle oinstall 24166400 Nov 21 16:51 exp_hr.dmp
-rw-r--r--  1 oracle oinstall     2493 Nov 21 16:51 exp_hr.log
drwxr-x---  3 oracle oinstall     4096 Aug 31 15:03 oradiag_oracle
-rw-r--r--  1 oracle oinstall    28766 Nov 21 17:03 show_ddl.log
rac1-> cat exp_hr.dmp |head|strings
iEXPORT:V11.02.00
RUSERS
8192
Mon Nov 21 16:50:25 2011exp_hr.dmp
#G#G
rac1->

结合,上一篇,我们算是对如何从dumpfile里获取DDL脚本以及如何获取dumpfile的header deatail information有了一个初步认识。希望这两篇文章可以对网友在学习Oracle数据库逻辑备份带去帮助!

如何从逻辑备份的dumpfile文件里获取DDL脚本?

在数据库的管理工作中,难免会遇到使用Export/Import或者是EXPort Data Pump/IMPort Data Pump工具来执行逻辑备份、恢复的场景。在有些时候,我们可能会对产生的dumpfile的内容感兴趣。本文就这两种工具产生的逻辑备份文件分别描述如何获取数据定义语句(Data Definition Language)的脚本?

1 先来看,如何从传统的Export工具产生的dumpfile里获取DDL语句?

首先,导出HR用户的所有对象:

rac1-> id

uid=1101(oracle) gid=1000(oinstall) groups=1000(oinstall),1201(asmdba),1300(dba),1301(oper)

rac1-> pwd

/home/oracle

rac1-> ls -l

total 24

drwxrwxr-x 17 root   root      4096 May 26 21:20 12419321

-rw-r--r--  1 oracle oinstall 15626 Aug 31 14:28 db.rsp

drwxr-x---  3 oracle oinstall  4096 Aug 31 15:03 oradiag_oracle

rac1-> exp hr/hr file=exp_hr.dmp log=exp_hr.log owner=hr

Export: Release 11.2.0.1.0 - Production on Mon Nov 21 16:50:22 2011

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

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,

Data Mining and Real Application Tes

Export done in AL32UTF8 character set and AL16UTF16 NCHAR character set

. exporting pre-schema procedural objects and actions

. exporting foreign function library names for user HR

. exporting PUBLIC type synonyms

. exporting private type synonyms

. exporting object type definitions for user HR

About to export HR's objects ...

. exporting database links

. exporting sequence numbers

.....

.....

. exporting statistics

Export terminated successfully without warnings.

rac1-> ls -l

total 23656

drwxrwxr-x 17 root   root         4096 May 26 21:20 12419321

-rw-r--r--  1 oracle oinstall    15626 Aug 31 14:28 db.rsp

-rw-r--r--  1 oracle oinstall 24166400 Nov 21 16:51 exp_hr.dmp

-rw-r--r--  1 oracle oinstall     2493 Nov 21 16:51 exp_hr.log

drwxr-x---  3 oracle oinstall     4096 Aug 31 15:03 oradiag_oracle

rac1->

我们已经顺利导出了一份exp_hr.dmp的dumpfile,那么该如何从该文件里获取DDL语句呢?

我们可以利用传统的导入工具Import附带SHOW=y选项来获取:

rac1-> imp hr/hr file=exp_hr.dmp log=show_ddl.log  show=y

Import: Release 11.2.0.1.0 - Production on Mon Nov 21 17:03:26 2011

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

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,

Data Mining and Real Application Tes

Export file created by EXPORT:V11.02.00 via conventional path

import done in AL32UTF8 character set and AL16UTF16 NCHAR character set

. importing HR's objects into HR

"BEGIN  "

...

...

Import terminated successfully without warnings.

rac1->

rac1-> ls -l

total 23688

drwxrwxr-x 17 root   root         4096 May 26 21:20 12419321

-rw-r--r--  1 oracle oinstall    15626 Aug 31 14:28 db.rsp

-rw-r--r--  1 oracle oinstall 24166400 Nov 21 16:51 exp_hr.dmp

-rw-r--r--  1 oracle oinstall     2493 Nov 21 16:51 exp_hr.log

drwxr-x---  3 oracle oinstall     4096 Aug 31 15:03 oradiag_oracle

-rw-r--r--  1 oracle oinstall    28766 Nov 21 17:03 show_ddl.log

rac1-> head -30 show_ddl.log

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,

Data Mining and Real Application Tes

Export file created by EXPORT:V11.02.00 via conventional path

import done in AL32UTF8 character set and AL16UTF16 NCHAR character set

. importing HR's objects into HR

"BEGIN  "

"sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','"

"CURRENT_SCHEMA'), export_db_name=>'DEVDB', inst_scn=>'41155490');"

"COMMIT; END;"

"CREATE TYPE "MY_TEST_TYPE" TIMESTAMP '2011-10-12:09:59:12' OID 'AF115DDE620"

"59E4AE04010ACBF000672'   as object(id number,name varchar2(10));"

"CREATE SEQUENCE "LOCATIONS_SEQ" MINVALUE 1 MAXVALUE 9900 INCREMENT BY 100 S"

"TART WITH 3300 NOCACHE NOORDER NOCYCLE"

"CREATE SEQUENCE "DEPARTMENTS_SEQ" MINVALUE 1 MAXVALUE 9990 INCREMENT BY 10 "

"START WITH 280 NOCACHE NOORDER NOCYCLE"

"CREATE SEQUENCE "EMPLOYEES_SEQ" MINVALUE 1 MAXVALUE 99999999999999999999999"

"99999 INCREMENT BY 1 START WITH 207 NOCACHE NOORDER NOCYCLE"

"CREATE CLUSTER "DEPT_EMP_CLUSTER" ("DEPARTMENT_ID" NUMBER(4, 0))  PCTFREE 1"

"0 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 262144 NEXT 1048576 MI"

"NEXTENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "U"

"SERS""

"CREATE INDEX "IDX_DEPT_EMP_CLUSTER" ON CLUSTER "DEPT_EMP_CLUSTER" PCTFREE 1"

"0 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 F"

"REELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS""

"CREATE TABLE "BIGFILE_TAB" ("ID" NUMBER, "NAME" VARCHAR2(10))  PCTFREE 10 P"

"CTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXT"

"ENTS 1 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "BIG_T"

rac1->

从上,我们可以看到,我们在IMPORT命令行上带上SHOW=Y的选项时,IMPORT工具并没有真正的执行数据导入,而是生成了一份含有DDL语句的日志文件,我们可以直接编辑该日志文件,以获取我们所需的脚本。

2 那么,对于EXPDP产生的dumpfile,又该如何获取DDL语句呢?

先以EXPDP导出dumpfile:

rac1-> pwd

/u01/app/oracle/mig_dir

rac1-> ls -l

total 0

rac1-> expdp hr/hr directory=mig_dir dumpfile=expdp_hr.dmp logfile=expdp_hr.log schemas=hr

Export: Release 11.2.0.1.0 - Production on Mon Nov 21 17:16:45 2011

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

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,

Data Mining and Real Application Testing options

...

Job "HR"."SYS_EXPORT_SCHEMA_01" successfully completed at 17:19:48

rac1-> ls -l

total 24248

-rw-r----- 1 oracle asmadmin 24797184 Nov 21 17:19 expdp_hr.dmp

-rw-r--r-- 1 oracle asmadmin     3299 Nov 21 17:19 expdp_hr.log

rac1->

该如何从expdp_hr.dmp文件里获取DDL语句呢?IMPDP工具给我们提供了SQLFILE的命令行选项,同样是只获取DDL语句,并未真正的执行数据导入。

rac1-> impdp hr/hr directory=mig_dir dumpfile=expdp_hr.dmp logfile=impdp_hr.log schemas=hr sqlfile=hr_ddl.sql

Import: Release 11.2.0.1.0 - Production on Mon Nov 21 17:23:23 2011

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

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,

Data Mining and Real Application Testing options

Master table "HR"."SYS_SQL_FILE_SCHEMA_01" successfully loaded/unloaded

...

...

Job "HR"."SYS_SQL_FILE_SCHEMA_01" successfully completed at 17:23:47

rac1-> ls -l

total 24360

-rw-r----- 1 oracle asmadmin 24797184 Nov 21 17:19 expdp_hr.dmp

-rw-r--r-- 1 oracle asmadmin     3299 Nov 21 17:19 expdp_hr.log

-rw-r--r-- 1 oracle asmadmin   103892 Nov 21 17:23 hr_ddl.sql

-rw-r--r-- 1 oracle asmadmin     1672 Nov 21 17:23 impdp_hr.log

rac1-> head -30 hr_ddl.sql

-- CONNECT HR

ALTER SESSION SET EVENTS '10150 TRACE NAME CONTEXT FOREVER, LEVEL 1';

ALTER SESSION SET EVENTS '10904 TRACE NAME CONTEXT FOREVER, LEVEL 1';

ALTER SESSION SET EVENTS '25475 TRACE NAME CONTEXT FOREVER, LEVEL 1';

ALTER SESSION SET EVENTS '10407 TRACE NAME CONTEXT FOREVER, LEVEL 1';

ALTER SESSION SET EVENTS '10851 TRACE NAME CONTEXT FOREVER, LEVEL 1';

ALTER SESSION SET EVENTS '22830 TRACE NAME CONTEXT FOREVER, LEVEL 192 ';

-- new object type path: SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA

BEGIN

sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'DEVDB', inst_scn=>'41161309');

COMMIT;

END;

/

-- new object type path: SCHEMA_EXPORT/TYPE/TYPE_SPEC

CREATE TYPE "HR"."MY_TEST_TYPE"

OID 'AF115DDE62059E4AE04010ACBF000672' as object(id number,name varchar2(10));

/

ALTER TYPE "HR"."MY_TEST_TYPE"

COMPILE SPECIFICATION

PLSQL_OPTIMIZE_LEVEL=  2

PLSQL_CODE_TYPE=  INTERPRETED

PLSQL_DEBUG=  FALSE    PLSCOPE_SETTINGS=  'IDENTIFIERS:NONE'

/

-- new object type path: SCHEMA_EXPORT/SEQUENCE/SEQUENCE

CREATE SEQUENCE  "HR"."LOCATIONS_SEQ"  MINVALUE 1 MAXVALUE 9900 INCREMENT BY 100 START WITH 3300 NOCACHE  NOORDER  NOCYCLE ;

rac1->

最后,简单一句话总结:

对于使用传统工具EXPORT导出的dumpfile,我们可以使用IMPORT加上SHOW=Y的选项获取DDL

对于使用数据泵EXPDP导出的dumpfile,我们可以使用IMPDP加上SQLFILE的选项获取DDL

ORA-39142 IMPDP跨版本导入数据报错解决

前几天,公司某项目组搭建一套演示应用系统,需要将后台的Oracle数据从一台服务器迁移到另外一套系统。在执行IMPDP导入的过程遭遇下述错误,后经查找Metalink给出解决方法。

-bash-3.2$ impdp directory=mig_dir dumpfile=dms_expdp.dmp logfile=impdp.log schemas=dms
Import: Release 10.2.0.5.0 - 64bit Production on Thursday, 10 November, 2011 3:12:56
Copyright (c) 2003, 2007, Oracle.  All rights reserved.
Username: sys/oracle as sysdba
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-39142: incompatible version number 3.1 in dump file "/home/oracle/mig_dir/dms_expdp.dmp"
[oracle@OEL511gR2 mig_dir]$ oerr ora 39142
39142, 00000, "incompatible version number %s in dump file \"%s\""
// *Cause:  A dump file was specified for an import operation whose version
//          number is incompatible with the dump file version of the
//          Data Pump product currently running on the system. Usually this
//          message indicates that the dump file was produced by a newer
//          version of the Data Pump export utility.
// *Action: Import this dump file using the Data Pump import utility with
//          the same version as the export which created the file.
[oracle@OEL511gR2 mig_dir]$

ORA-39142的错误是指要导入的dump file中记录的数据库版本与要导入的数据库版本不一致。果不其然,这份导出的dump file是其他同事从一套11.1.0.6.0数据库上EXPDP 导出的,而这套要导入演示系统的数据库版本是10.2.0.5.0。将11g数据库中导出的dump file导入到10g数据库的过程中,就报这个错误了,Metalink ID 553337.1给出了详细的解决方法。

我这里的解决方法是在源库,即11g的数据库上重新以EXPDP加上version=10.2.0.5.0参数重新执行导出,然后在目标库上重新执行上述导入命令,OK!

需要注意的是,经过测试:直接在目标库(10.2.0.5.0)上以IMPDP附带version=11.1.0.6.0参数导入第一份dump file文件是行不通的,依旧会报上述ORA-39142的错!
那么,dump file里包含的数据库版本信息及其它详细信息应该怎么获取呢?我们将在下一篇介绍。

Oracle 数据逻辑恢复及权限控制一例

近日,应公司内部东南亚Regional Integrated Management Information System项目组需求,完成下述测试环境的搭建:

1 在现有开发库中,创建一个新的名为RIMISADMIN的schema,将现有RIMIS这个schema下的所有数据逻辑备份出来并导入到新建的RIMISADMIN这个schema下;

2 另外创建一个新的测试schema 名为RIMISTEST,该测试schema与RIMISADMIN公用一份数据,并限制其权限仅可以执行DML语句,对数据表有增删改查功能,不允许执行DDL语句,同时不允许对如下表执行DML语句操作:
cd_menu;cd_functionpoint;cd_menu_function;cd_office_fmenu;cd_role_fmenu;cd_office_biz_config;
cd_serial_no;cd_codedict;cd_codetype;edi_code_table;edi_code_type;pr_report_config;
上述内容是公司同事发给我的一封邮件,当然是我与需求同事沟通确认后,整理出来的需求信息。

我的解决思路:
1 在现有RAC数据库中将RIMIS schema用户下的所有数据用EXPDP按照schema模式全部逻辑导出;

2 准备使用IMPDP工具附带remap_schema=rimis:rimisadmin参数全部导入,在这一步执行之前确认RAC数据库的存储信息时,发现ASM磁盘组的总空间为236G,剩余空间只有区区的30G左右。而原有RIMIS schema下的所有数据在数据库中占用将近55G的空间,看来不能直接在这台RAC数据库上搭建这个测试环境,除非先给ASM磁盘组添加磁盘,而开发库又需要给各个项目组使用,不好直接停服务加磁盘,怕影响其他项目组进度。只好选择一种迂回的方案,先将测试环境搭建到另外一套数据库中,等有机会的话,再停RAC数据库,然后添加存储之后另作处理。

3 在新的测试环境上执行逻辑导入,导入之前,在新环境下创建必要的表空间,表空间名需要与原环境下RIMIS用户对象所在表空间名相同,否则,在导入时就得指定REMAP_TABLESPACE选项了,不然,就不可能顺利导入。具体的导入的命令如下:

impdp directory=mig_dir dumpfile=expdp_rimis_20111114.dmp logfile=impdp_rimis.log  remap_schema=rimis:rimisadmin exclude=table_statistics

4 导入之后,发现有些对象编译失效,图省事,执行下述命令直接编译RIMISADMIN schema下的所有对象:

SQL> exec dbms_utility.compile_schema('RIMISADMIN');

5 以SYS用户登录数据库,修改RIMISADMIN schema的口令,并确认RIMISADMIN 可以正常访问数据库;

[oracle@OEL511gR2 mig_dir]$ rlwrap sqlplus / as sysdba
SQL*Plus: Release 10.2.0.5.0 - Production on Wed Nov 16 16:10:42 2011
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> conn / as sysdba
Connected.
SQL> alter user rimisadmin identified by fjxm;
User altered.
SQL> conn rimisadmin/fjxm;
Connected.
SQL>

6 新环境下创建RIMIS schema,原来需求是创建RIMISTEST,又经更改需求要命名为RIMIS,并只给RIMIS用户赋予最小CREATE SESSION的权限及CREATE SYNONYM(见第8步,具体用处)的权限:

SQL> conn / as sysdba
Connected.
SQL> create user rimis identified by rimis;
User created.
SQL> grant create session to rimis;
Grant succeeded.
SQL> conn rimis/rimis
Connected.
SQL>

7 给RIMIS用户赋予可以对RIMISADMIN对象的增删改查的权限,见下述SQL:

SQL> conn rimisadmin/fjxm
Connected.
SQL> spool /home/oracle/privs.sql
SQL> select 'grant select,insert,update,delete on '||table_name||' to rimis;' from user_tables;
SQL> spool off;

简单修改/home/oracle/privs.sql后,由RIMISADMIN用户执行/home/oracle/privs.sql赋权脚本。

8 RIMIS用户创建一系列的同义词:
RIMISADMIN先生成创建同义词的脚本:

SQL> conn rimisadmin/fjxm
Connected.
SQL> spool /home/oracle/create_synonym.sql
SQL> select 'create synonym '||table_name||' for rimisadmin.'||table_name||';' from user_tables;
SQL> spool off;

然后交由RIMIS用户执行上述创建同义词的脚本;
至此,RIMIS用户就可以正常访问RIMISADMIN用户下的对象。只是,还有一个特殊的上述那些表的权限控制,不能执行DML操作。

9 移除对特定表的增删改的权限:

SQL> conn rimisadmin/fjxm
Connected.
SQL> select 'revoke insert,update,delete on '||table_name||' from rimis;'
   2 from user_tables
   3 where lower(table_name) in ('cd_menu','cd_functionpoint','cd_menu_function',
   4 'cd_office_fmenu','cd_role_fmenu','cd_office_biz_config','cd_serial_no',
   5 'cd_codedict','cd_codetype','edi_code_table','edi_code_type','pr_report_config');

至此,完成RIMIS项目组的数据逻辑恢复、及相关权限的控制。以前,在数据库日常管理中,很少有遇到权限比较细化的场景,所以简单做一记录。
在发布本博文前,收到同事的邮件,说权限已经控制OK!

《Oracle DBA手记》“享受”中

《Oracle DBA手记》新书到手,正在“啃食”中!感谢邹先生(banping)赠送此书与我。同样要感谢其他几位作者,感谢Oracle高手前辈写出如此好的技术性书籍,给我等newbie指点学习的方向和解决问题的方法。 2010.1.30下午在厦门市湖滨南路中山医院门口初见邹先生,特别高兴,也很欣慰,不单是他赠送此书给我,更为重要的是认识一位Oracle从业前辈。两个陌生的北方男人认识在南方的厦门,完全是因为Oracle。初次拿到书的时候感觉封面很凝重,随后慢慢翻阅学习的时候,才发觉内容是如此之精华!得知他母亲身体不好在医院治疗,他也一直忙着照顾老人。在此,祝福老人家,早日康复,祝福邹先生合家团圆,家人平安快乐!

user_tab_modifications

USER_TAB_MODIFICATIONS describes modifications to all tables owned by the
current user that have been modified since the last time statistics were gathered on the

USER_TAB_MODIFICATIONS describes modifications to all tables owned by the current user that have been modified since the last time statistics were gathered on the tables. 使用User_tab_modifications来获取数据表的DML过程: 1,SQL> select * from USER_TAB_MODIFICATIONS ; no rows selected 2,  SQL>insert into test values(1,'Asher'); one row inserted 3, SQL>select * from USER_TAB_MODIFICATIONS ; no rows selected Why? just waiting for a moment,or after I've executed the procedure【dbms_stats.flush_database_monitoring_info()】,we will get the expected result. 4, SQL> exec dbms_stats.flush_database_monitoring_info(); PL/SQL procedure successfully completed. 5,SQL> select * from USER_TAB_MODIFICATIONS ; The correct result will appears.