月归档:八月 2012

extundelete恢复Linux被删除文件

今天群中有个朋友的客户闲着没事rm掉了数据文件,然后讨论到使用extundelete进行了恢复,抢救了部分未被覆盖的数据文件。该软件官方地址:http://extundelete.sourceforge.net/
安装extundelete

[root@xifenfei tmp]# bunzip2 extundelete-0.2.0.tar.bz2
[root@xifenfei tmp]# tar xvf extundelete-0.2.0.tar
extundelete-0.2.0/
extundelete-0.2.0/README
extundelete-0.2.0/acinclude.m4
extundelete-0.2.0/configure.ac
extundelete-0.2.0/aclocal.m4
extundelete-0.2.0/Makefile.am
extundelete-0.2.0/Makefile.in
extundelete-0.2.0/config.h.in
extundelete-0.2.0/configure
extundelete-0.2.0/compile
extundelete-0.2.0/depcomp
extundelete-0.2.0/install-sh
extundelete-0.2.0/missing
extundelete-0.2.0/LICENSE
extundelete-0.2.0/autogen.sh
extundelete-0.2.0/src/
extundelete-0.2.0/src/Makefile.am
extundelete-0.2.0/src/Makefile.in
extundelete-0.2.0/src/extundelete.cc
extundelete-0.2.0/src/block.c
extundelete-0.2.0/src/insertionops.cc
extundelete-0.2.0/src/block.h
extundelete-0.2.0/src/extundelete.h
extundelete-0.2.0/src/extundelete-priv.h
extundelete-0.2.0/src/jfs_compat.h
extundelete-0.2.0/src/kernel-jbd.h
[root@xifenfei tmp]# cd extundelete-0.2.0
[root@xifenfei extundelete-0.2.0]#  ./configure
Configuring extundelete 0.2.0
Writing generated files to disk
[root@xifenfei extundelete-0.2.0]# make && make install
make -s all-recursive
Making all in src
Making install in src
  /usr/bin/install -c 'extundelete' '/usr/local/bin/extundelete'

恢复操作命令

--umount或者read only 分区(如果umount不成功,可以通过fuser -km /www类似方法找出来占用进程)
 umount /dev/partition
 mount -o remount,ro /dev/partition

--恢复文件
extundelete /dev/partition --restore-all
extundelete /dev/partition --restore-directory /backup/gnutool-delete
extundelete /dev/partition --restore-files /etc/passwd 

测试恢复

--基于目录恢复
[root@xifenfei tmp]#extundelete /dev/sdb1  --restore-directory /u01/xifenfei
Loading filesystem metadata ... 160 groups loaded.
Loading journal descriptors ... 23 descriptors loaded.
Writing output to directory RECOVERED_FILES/
Failed to restore file /u01/xifenfei
Could not find correct inode number past inode 2.
[root@xifenfei tmp]# cd RECOVERED_FILES/
[root@xifenfei RECOVERED_FILES]# ll
total 0
--未成功

--基于磁盘恢复
[root@xifenfei RECOVERED_FILES]#extundelete /dev/sdb1  --restore-all
Loading filesystem metadata ... 160 groups loaded.
Loading journal descriptors ... 23 descriptors loaded.
Writing output to directory RECOVERED_FILES/
Searching for recoverable inodes in directory / ... 
4 recoverable inodes found.
Looking through the directory structure for deleted files ... 
Failed to restore inode 1966081 to file RECOVERED_FILES/xifenfei:Inode does not correspond to a regular file.
Restored inode 1966082 to file RECOVERED_FILES/xifenfei/xff.txt
Failed to restore inode 1966083 to file RECOVERED_FILES/xifenfei/xff:Inode does not correspond to a regular file.
Restored inode 1966084 to file RECOVERED_FILES/xifenfei/xff/xff.txt132
0 recoverable inodes still lost.
[root@xifenfei RECOVERED_FILES]# ll
total 4
drwxr-xr-x 3 root root 4096 Aug 31 21:36 RECOVERED_FILES
[root@xifenfei RECOVERED_FILES]# cd RECOVERED_FILES/
[root@xifenfei RECOVERED_FILES]# ll
total 4
drwxr-xr-x 3 root root 4096 Aug 31 21:36 xifenfei
[root@xifenfei RECOVERED_FILES]# cd xifenfei/
[root@xifenfei xifenfei]# ll
total 20
drwxr-xr-x 2 root root  4096 Aug 31 21:36 xff
-rw-r--r-- 1 root root 13231 Aug 31 21:36 xff.txt
[root@xifenfei xifenfei]# cd xff
[root@xifenfei xff]# ll
total 16
-rw-r--r-- 1 root root 13231 Aug 31 21:36 xff.txt132
--恢复成功

--基于文件恢复
[root@xifenfei xff]# extundelete /dev/sdb1  --restore-files /u01/xifenfei/xff.txt
Loading filesystem metadata ... 160 groups loaded.
Loading journal descriptors ... 23 descriptors loaded.
Writing output to directory RECOVERED_FILES/
[root@xifenfei xff]# cd RECOVERED_FILES/
[root@xifenfei RECOVERED_FILES]# ll
total 0
--未成功

通过上述实验证明extundelete还是有很大的不完整性,基于整个磁盘的恢复功能较为强大,基于目录和文件的恢复还不够强大.不过该软件在很多时候还是有救火的功能,特别是当蛋筒的人员删除了数据库的部分文件之时.

发表在 Linux | 3 条评论

何种情况下imp的fromuser/touser改变tablespace失效

exp/imp是大家在数据库迁移中最常见的工具,但是该工具对于表空间的转换不是很智能(最少没有datapump方便),使得很多人在导入数据的时候,吃够了表空间不存在的苦.这里有个细节:fromuser和touser在哪些情况下会失效.这里通过试验,简单证明了对于常见的lob对象和分区表对象的时候fromuser和touser修改表空间会失效.
exp/imp支持表空间变化

--创建测试用户
SQL> create user chf identified by xifenfei;  

User created.

SQL> grant dba to chf;

Grant succeeded.

SQL> conn chf/xifenfei
Connected.

--创建测试对象
SQL> create table t_xifenfei01 tablespace users
  2  as
  3  select * from dba_objects;

Table created.

SQL> create index in_t_xifenfei01 on t_xifenfei01(object_id) tablespace xifenfei;

Index created.

SQL> create table t_xifenfei02 tablespace xifenfei
  2  as
  3  select * from dba_objects;

Table created.

SQL> create index in_t_xifenfei02 on t_xifenfei02(object_id) tablespace users;

Index created.

--查询测试对象分布表空间情况
SQL> select OWNER,table_name,TABLESPACE_NAME from dba_tables where table_name like 'T_XIFENFEI%';

OWNER                          TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
CHF                            T_XIFENFEI01                   USERS
CHF                            T_XIFENFEI02                   XIFENFEI

SQL> SELECT OWNER,INDEX_NAME,TABLESPACE_NAME FROM DBA_INDEXES WHERE INDEX_NAME LIKE 'IN_T_XIFENFEI%';

OWNER                          INDEX_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
CHF                            IN_T_XIFENFEI01                XIFENFEI
CHF                            IN_T_XIFENFEI02                USERS

--导出测试对象
[oracle@xifenfei ~]$ exp chf/xifenfei tables=t_xifenfei01,t_xifenfei02 file=/tmp/xifenfei.dmp log=/tmp/xifenfei.log

Export: Release 10.2.0.4.0 - Production on Thu Dec 15 07:33:27 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table                   T_XIFENFEI01      50053 rows exported
. . exporting table                   T_XIFENFEI02      50055 rows exported
Export terminated successfully without warnings.

--为了试验证实,离线该表涉及表空间
SQL> alter tablespace xifenfei read only;

Tablespace altered.

SQL> alter tablespace users read only;

Tablespace altered.

--创建新用户
SQL> create user chf1 identified by xifenfei;

User created.

SQL> grant dba to chf1;

Grant succeeded.

--创建新表空间
SQL> create tablespace xifenfei1 datafile '/u01/oracle/oradata/XFF/xifenfei02.dbf' size 10m autoextend on 
  2  next 10m maxsize 10g;

Tablespace created.

SQL> alter user chf1 default tablespace xifenfei1;

User altered.

--两个测试用户分别默认表空间
SQL> select username,default_tablespace from dba_users where username like 'CHF%';

USERNAME                       DEFAULT_TABLESPACE
------------------------------ ------------------------------
CHF                            USERS
CHF1                           XIFENFEI1

--导入测试数据
[oracle@xifenfei ~]$ imp chf1/xifenfei fromuser=chf touser=chf1 file=/tmp/xifenfei.dmp log=/tmp/xifenfei.log

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 07:37:54 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
. . importing table                 "T_XIFENFEI01"      50053 rows imported
. . importing table                 "T_XIFENFEI02"      50055 rows imported
Import terminated successfully without warnings.

--查询导入结果
SQL> SELECT OWNER,INDEX_NAME,TABLESPACE_NAME FROM DBA_INDEXES WHERE INDEX_NAME LIKE 'IN_T_XIFENFEI%' 
  2  and owner='CHF1';

OWNER                          INDEX_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
CHF1                           IN_T_XIFENFEI01                XIFENFEI1
CHF1                           IN_T_XIFENFEI02                XIFENFEI1

SQL> select OWNER,table_name,TABLESPACE_NAME from dba_tables where table_name like 'T_XIFENFEI%'
  2  AND OWNER='CHF1';

OWNER                          TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
CHF1                           T_XIFENFEI01                   XIFENFEI1
CHF1                           T_XIFENFEI02                   XIFENFEI1

通过这里的试验证明:对于无lob对象的普通表和普通index使用fromuser和touser可以实现表空间完美变化

含LOB对象测试

--read write相关表空间
SQL> alter tablespace users read write;

Tablespace altered.

SQL> alter tablespace xifenfei read write;

Tablespace altered.

SQL> create tablespace xifenfei2 datafile '/u01/oracle/oradata/XFF/xifenfei03.dbf' size 10m;

Tablespace created.

SQL> conn chf/xifenfei
Connected.

--创建表,lob分别属于不同空间(数据导入到另外表空间)
SQL> create table t_lob 
  2  (id number,clob1 clob,blob1 blob) tablespace users 
  3   LOB ("CLOB1") STORE AS (   TABLESPACE xifenfei)
  4   LOB ("BLOB1") STORE AS (   TABLESPACE xifenfei1 );

Table created.

SQL> select table_name,COLUMN_NAME,TABLESPACE_NAME from user_lobs;

TABLE_NAME                     COLUMN_NAME     TABLESPACE_NAME
------------------------------ --------------- ------------------------------
T_LOB                          CLOB1           XIFENFEI
T_LOB                          BLOB1           XIFENFEI1

SQL> select tablespace_name from user_tables where table_name='T_LOB';

TABLESPACE_NAME
------------------------------
USERS

--创建表和lob属于一个表空间(数据导入到另外表空间)
SQL>  create table t_lob_n
  2  (id number,clob1 clob) tablespace users;

Table created.

SQL> select segment_name,segment_type,tablespace_name  from user_segments where SEGMENT_NAME not like '%XIFENFEI%';

SEGMENT_NAME                                                                      SEGMENT_TYPE       TABLESPACE_NAME
--------------------------------------------------------------------------------- ------------------ ----------------
SYS_IL0000051858C00002$$                                                          LOBINDEX           USERS
SYS_LOB0000051858C00002$$                                                         LOBSEGMENT         USERS
T_LOB_N                                                                           TABLE              USERS
T_LOB                                                                             TABLE              USERS
SYS_IL0000051851C00002$$                                                          LOBINDEX           XIFENFEI
SYS_LOB0000051851C00002$$                                                         LOBSEGMENT         XIFENFEI
SYS_IL0000051851C00003$$                                                          LOBINDEX           XIFENFEI1
SYS_LOB0000051851C00003$$                                                         LOBSEGMENT         XIFENFEI1

--表和lob不同表空间(数据导入到lob对应表空间)
SQL>  create table t_lob2
  2  (id number,clob1 clob) tablespace users 
  3  LOB ("CLOB1") STORE AS (   TABLESPACE xifenfei2);

Table created.

SQL> select table_name,COLUMN_NAME,TABLESPACE_NAME from user_lobs;

TABLE_NAME                     COLUMN_NAME     TABLESPACE_NAME
------------------------------ --------------- ------------------------------
T_LOB_N                        CLOB1           USERS
T_LOB                          CLOB1           XIFENFEI
T_LOB                          BLOB1           XIFENFEI1
T_LOB2                         CLOB1           XIFENFEI2

SQL>  select segment_name,segment_type,tablespace_name  from user_segments where SEGMENT_NAME not like '%XIFENFEI%';

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE_NAME
------------------------------ ------------------ ------------------------------
T_LOB2                         TABLE              USERS
SYS_IL0000051858C00002$$       LOBINDEX           USERS
SYS_LOB0000051858C00002$$      LOBSEGMENT         USERS
T_LOB_N                        TABLE              USERS
T_LOB                          TABLE              USERS
SYS_IL0000051851C00002$$       LOBINDEX           XIFENFEI
SYS_LOB0000051851C00002$$      LOBSEGMENT         XIFENFEI
SYS_IL0000051851C00003$$       LOBINDEX           XIFENFEI1
SYS_LOB0000051851C00003$$      LOBSEGMENT         XIFENFEI1
SYS_IL0000051863C00002$$       LOBINDEX           XIFENFEI2
SYS_LOB0000051863C00002$$      LOBSEGMENT         XIFENFEI2

11 rows selected.

SQL> select table_name,COLUMN_NAME,TABLESPACE_NAME,SEGMENT_NAME from user_lobs;

TABLE_NAME                     COLUMN_NAME     TABLESPACE_NAME                SEGMENT_NAME
------------------------------ --------------- ------------------------------ ------------------------------
T_LOB                          BLOB1           XIFENFEI1                      SYS_LOB0000051851C00003$$
T_LOB                          CLOB1           XIFENFEI                       SYS_LOB0000051851C00002$$
T_LOB_N                        CLOB1           USERS                          SYS_LOB0000051858C00002$$
T_LOB2                         CLOB1           XIFENFEI2                      SYS_LOB0000051863C00002$$
--得到在默认情况下LOBINDEX和LOBSEGMENT在同一个表空间

--导出三种情况下lob表
[oracle@xifenfei ~]$ exp chf/xifenfei tables=t_lob_n file=/tmp/lob1.dmp log=/tmp/xifenfei.log indexes=y

Export: Release 10.2.0.4.0 - Production on Thu Dec 15 08:57:38 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table                        T_LOB_N          0 rows exported
Export terminated successfully without warnings.

[oracle@xifenfei ~]$ exp chf/xifenfei tables=t_lob file=/tmp/lob.dmp log=/tmp/xifenfei.log indexes=y

Export: Release 10.2.0.4.0 - Production on Thu Dec 15 08:31:25 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table                          T_LOB          0 rows exported
Export terminated successfully without warnings.

[oracle@xifenfei ~]$ exp chf/xifenfei tables=t_lob2 file=/tmp/lob2.dmp log=/tmp/xifenfei.log

Export: Release 10.2.0.4.0 - Production on Thu Dec 15 16:23:18 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table                         T_LOB2          0 rows exported
Export terminated successfully without warnings.

--修改default tablespace 和 read only相关表空间
SQL> alter user chf1 default tablespace xifenfei2;

User altered.

SQL> alter tablespace users read only;

Tablespace altered.

SQL> alter tablespace xifenfei read only;

Tablespace altered.

SQL> alter tablespace xifenfei1 read only;

Tablespace altered.

--导入lob表
[oracle@xifenfei ~]$ imp chf1/xifenfei tables=t_lob_n file=/tmp/lob1.dmp log=/tmp/xifenfei.log fromuser=chf touser=chf1

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 08:58:12 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
IMP-00017: following statement failed with ORACLE error 1647:
 "CREATE TABLE "T_LOB_N" ("ID" NUMBER, "CLOB1" CLOB)  PCTFREE 10 PCTUSED 40 I"
 "NITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 "
 "BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS LOB ("CLOB1") ST"
 "ORE AS  (TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION NOCA"
 "CHE LOGGING  STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POO"
 "L DEFAULT))"
IMP-00003: ORACLE error 1647 encountered
ORA-01647: tablespace 'USERS' is read only, cannot allocate space in it
Import terminated successfully with warnings.
--使用fromuser和touser并未修改table segment初始化参数

[oracle@xifenfei ~]$ imp chf1/xifenfei tables=t_lob file=/tmp/lob.dmp log=/tmp/xifenfei.log fromuser=chf touser=chf1

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 08:35:05 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
IMP-00017: following statement failed with ORACLE error 1647:
 "CREATE TABLE "T_LOB" ("ID" NUMBER, "CLOB1" CLOB, "BLOB1" BLOB)  PCTFREE 10 "
 "PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELI"
 "ST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS LOB "
 "("CLOB1") STORE AS  (TABLESPACE "XIFENFEI" ENABLE STORAGE IN ROW CHUNK 8192"
 " RETENTION NOCACHE LOGGING  STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROU"
 "PS 1 BUFFER_POOL DEFAULT)) LOB ("BLOB1") STORE AS  (TABLESPACE "XIFENFEI1" "
 "ENABLE STORAGE IN ROW CHUNK 8192 RETENTION NOCACHE LOGGING  STORAGE(INITIAL"
 " 65536 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT))"
IMP-00003: ORACLE error 1647 encountered
ORA-01647: tablespace 'USERS' is read only, cannot allocate space in it
Import terminated successfully with warnings.
--结论同上

[oracle@xifenfei ~]$ imp chf1/xifenfei tables=t_lob2 file=/tmp/lob2.dmp log=/tmp/xifenfei.log fromuser=chf touser=chf1

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 16:24:03 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
IMP-00017: following statement failed with ORACLE error 1647:
 "CREATE TABLE "T_LOB2" ("ID" NUMBER, "CLOB1" CLOB)  PCTFREE 10 PCTUSED 40 IN"
 "ITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 B"
 "UFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS LOB ("CLOB1") STO"
 "RE AS  (TABLESPACE "XIFENFEI2" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION N"
 "OCACHE LOGGING  STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 BUFFER_"
 "POOL DEFAULT))"
IMP-00003: ORACLE error 1647 encountered
ORA-01647: tablespace 'USERS' is read only, cannot allocate space in it
Import terminated successfully with warnings.
--结论也同上

通过三种不同情况的table segment 和lob segment的分别表空间和导入表空间测试情况,可以判断出来在使用exp/imp迁移数据时候,如果遇到含lob字段表,不能通过fromuser和touser来实现修改,就算lob的表空间存在,或者lob和table segment是同一个表空间,而table segment的表空间不存在,依然会报错,导入不成功.

分区表测试

--read write 相关表空间
SQL> alter tablespace users read write;

Tablespace altered.

SQL> alter tablespace xifenfei read write;

Tablespace altered.

SQL> alter tablespace xifenfei1 read write;

Tablespace altered.

--创建分区表
SQL> conn chf/xifenfei
Connected.
SQL> create table tab_par
  2  (
  3    F_KJND VARCHAR2(4) default ' ' not null,
  4    F_CODE VARCHAR2(30) default ' ' not null,
  5    F_KMBH VARCHAR2(30) default ' ' not null,
  6    F_BKBH VARCHAR2(30) default ' ' not null,
  7    UNIT_ID VARCHAR2(30) 
  8  )
  9  partition by range (F_KJND)
 10  (partition TABL_NAME_PT_2009 values less than ('2010')tablespace users,
 11  partition TABL_NAME_PT_2010 values less than ('2011')tablespace xifenfei,
 12  partition TABL_NAME_PT_MAX values less than (MAXVALUE)  tablespace xifenfei1
 13  );

Table created.

--查询分区分布
SQL> select PARTITION_NAME,TABLESPACE_NAME from ALL_TAB_PARTITIONS where TABLE_NAME='TAB_PAR';

PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------
TABL_NAME_PT_2009              USERS
TABL_NAME_PT_2010              XIFENFEI
TABL_NAME_PT_MAX               XIFENFEI1

--导出分区表
[oracle@xifenfei ~]$ exp chf/xifenfei tables=tab_par file=/tmp/tab_par.dmp log=/tmp/xifenfei.log

Export: Release 10.2.0.4.0 - Production on Thu Dec 15 18:33:19 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table                        TAB_PAR
. . exporting partition              TABL_NAME_PT_2009          0 rows exported
. . exporting partition              TABL_NAME_PT_2010          0 rows exported
. . exporting partition               TABL_NAME_PT_MAX          0 rows exported
Export terminated successfully without warnings.

--导入分区表
[oracle@xifenfei ~]$ imp chf1/xifenfei tables=tab_par file=/tmp/tab_par.dmp log=/tmp/xifenfei.log fromuser=chf touser=chf1

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 18:33:52 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
. . importing partition  "TAB_PAR":"TABL_NAME_PT_2009"          0 rows imported
. . importing partition  "TAB_PAR":"TABL_NAME_PT_2010"          0 rows imported
. . importing partition   "TAB_PAR":"TABL_NAME_PT_MAX"          0 rows imported
Import terminated successfully without warnings.
--导入成功

--查看导入进入表空间
SQL> select PARTITION_NAME,TABLESPACE_NAME from ALL_TAB_PARTITIONS where TABLE_NAME='TAB_PAR' and TABLE_OWNER='CHF1';

PARTITION_NAME                 TABLESPACE_NAME
------------------------------ ------------------------------
TABL_NAME_PT_2009              USERS
TABL_NAME_PT_2010              XIFENFEI
TABL_NAME_PT_MAX               XIFENFEI1
--发现还是进入和以前相同的表空间,fromuser和touser未生效

SQL> DROP TABLE CHF1.TAB_PAR PURGE;

Table dropped.

--read only相关表空间测试
SQL> ALTER TABLESPACE USERS READ ONLY;

Tablespace altered.

SQL> ALTER TABLESPACE XIFENFEI READ ONLY;

Tablespace altered.

SQL> ALTER TABLESPACE XIFENFEI1 READ ONLY;

Tablespace altered.

--再次导入
[oracle@xifenfei ~]$ imp chf1/xifenfei tables=tab_par file=/tmp/tab_par.dmp log=/tmp/xifenfei.log fromuser=chf touser=chf1

Import: Release 10.2.0.4.0 - Production on Thu Dec 15 18:36:38 2011

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


Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

Warning: the objects were exported by CHF, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing CHF's objects into CHF1
IMP-00017: following statement failed with ORACLE error 1647:
 "CREATE TABLE "TAB_PAR" ("F_KJND" VARCHAR2(4) NOT NULL ENABLE, "F_CODE" VARC"
 "HAR2(30) NOT NULL ENABLE, "F_KMBH" VARCHAR2(30) NOT NULL ENABLE, "F_BKBH" V"
 "ARCHAR2(30) NOT NULL ENABLE, "UNIT_ID" VARCHAR2(30))  PCTFREE 10 PCTUSED 40"
 " INITRANS 1 MAXTRANS 255 TABLESPACE "USERS" LOGGING PARTITION BY RANGE ("F_"
 "KJND" )  (PARTITION "TABL_NAME_PT_2009" VALUES LESS THAN ('2010')  PCTFREE "
 "10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FRE"
 "ELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS, "
 "PARTITION "TABL_NAME_PT_2010" VALUES LESS THAN ('2011')  PCTFREE 10 PCTUSED"
 " 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROU"
 "PS 1 BUFFER_POOL DEFAULT) TABLESPACE "XIFENFEI" LOGGING NOCOMPRESS, PARTITI"
 "ON "TABL_NAME_PT_MAX" VALUES LESS THAN (MAXVALUE)  PCTFREE 10 PCTUSED 40 IN"
 "ITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1 B"
 "UFFER_POOL DEFAULT) TABLESPACE "XIFENFEI1" LOGGING NOCOMPRESS )"
IMP-00003: ORACLE error 1647 encountered
ORA-01647: tablespace 'USERS' is read only, cannot allocate space in it
Import terminated successfully with warnings.
--进步一证明分区表在导入的时候fromuser和touser未能改变其对应表空间

通过对分区表的测试,证明exp/imp在操作分区表的时候fromuser和touser也不能实现表空间的转换

在使用imp和exp实现数据迁移的时候,遇到我们常见的lob和分区表时候fromuser和touser修改表空间会失效,数据还是会导入到原对象锁对应的表空间,所以在处理含这些对象的数据迁移时,一般方法有:1.创建好这些对象所属表空间;2.先导出来这些对象对应的创建脚本,创建好这些对象,然后使用IGNORE=Y导入

发表在 逻辑备份/恢复 | 评论关闭

数据库收集统计信息属于dml操作

今天群里面讨论DBMS_STATS和analyze是属于ddl操作还是dml操作,这里进行了一些测试和猜测
创建模拟环境

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Solaris: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> conn xifenfei/xifenfei
Connected.
SQL> create table t_xifenfei
  2  as
  3  select * from dba_objects;

Table created.

SQL> select object_name,TO_CHAR(last_ddl_time,'YYYY-MM-DD HH24:MI:SS')  
  2  from dba_objects where object_name='T_XIFENFEI';

OBJECT_NAME     TO_CHAR(LAST_DDL_TI
--------------- -------------------
T_XIFENFEI      2012-08-28 18:33:03

SQL> select owner,to_char(LAST_ANALYZED,'YYYY-MM-DD HH24:MI:SS') 
  2  from dba_tables where table_name='T_XIFENFEI';

OWNER                          TO_CHAR(LAST_ANALYZ
------------------------------ -------------------
XIFENFEI

DBMS_STATS测试

SQL> EXEC DBMS_STATS.gather_table_stats(user,'T_XIFENFEI');

PL/SQL procedure successfully completed.

SQL> select owner,to_char(LAST_ANALYZED,'YYYY-MM-DD HH24:MI:SS')  
   2 from dba_tables where table_name='T_XIFENFEI';

OWNER                          TO_CHAR(LAST_ANALYZ
------------------------------ -------------------
XIFENFEI                       2012-08-28 18:42:50

SQL> select object_name,TO_CHAR(last_ddl_time,'YYYY-MM-DD HH24:MI:SS')  
   2 from dba_objects where object_name='T_XIFENFEI';

OBJECT_NAME     TO_CHAR(LAST_DDL_TI
--------------- -------------------
T_XIFENFEI      2012-08-28 18:33:03

这里测试证明:DBMS_STATS包的只是收集了表的统计信息,并没有修改DBA_OBJECTS.last_ddl_time列的内容,也就是说这个操作不是ddl操作

analyze测试

SQL> analyze table t_xifenfei compute statistics;

Table analyzed.

SQL> select object_name,TO_CHAR(last_ddl_time,'YYYY-MM-DD HH24:MI:SS')  from dba_objects where object_name='T_XIFENFEI';

OBJECT_NAME     TO_CHAR(LAST_DDL_TI
--------------- -------------------
T_XIFENFEI      2012-08-28 18:33:03

SQL> select owner,to_char(LAST_ANALYZED,'YYYY-MM-DD HH24:MI:SS')  from dba_tables where table_name='T_XIFENFEI';

OWNER                          TO_CHAR(LAST_ANALYZ
------------------------------ -------------------
XIFENFEI                       2012-08-28 18:45:17

这里测试结果显示和DBMS_STATS相同

测试DBMS_STATS 类似DDL功能

--会话1
SQL> delete from t_xifenfei;

14292 rows deleted.

SQL> EXEC DBMS_STATS.gather_table_stats(user,'T_XIFENFEI');

PL/SQL procedure successfully completed.

--会话2
SQL> select count(*) from t_xifenfei;

  COUNT(*)
----------
         0
--执行DBMS_STATS后事务提交,类此如在

DBMS_STATS分析事务提交原因

SQL> conn / as sysdba
Connected.
SQL> oradebug setmypid
Statement processed.
SQL> oradebug EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12
Statement processed.
SQL> EXEC DBMS_STATS.gather_table_stats('XIFENFEI','T_XIFENFEI');

PL/SQL procedure successfully completed.

SQL> oradebug TRACEFILE_NAME
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_24022.trc
SQL> oradebug EVENT 10046 trace name context off
Statement processed.

--分析trace文件中头几条sql语句
BEGIN DBMS_STATS.gather_table_stats('XIFENFEI','T_XIFENFEI'); END;

SELECT SPARE4 FROM SYS.OPTSTAT_HIST_CONTROL$ WHERE SNAME = :B1 

COMMIT

SELECT P.VALCHAR FROM SYS.OPTSTAT_USER_PREFS$ P, OBJ$ O, USER$ U WHERE P.OBJ#=O.OBJ#
 AND U.USER#=O.OWNER# AND U.NAME=:B3 AND O.NAME=:B2 AND P.PNAME=:B1 

通过这里的分析,我们可以大概的知道,为什么执行DBMS_STATS包之后事务自动提交,是因为在该程序中有COMMIT直接提交事务.

通过第三方程序UNWRAP DBMS_STAT包

 PROCEDURE INIT_PARAM_DEFAULT IS
  PARAMS     PARARRAY;
  ISDEFAULT  SYS.OPTSTAT_HIST_CONTROL$.SPARE1%TYPE;
  PAREXIST   BOOLEAN;
  CUR_TIME   TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP;
  BEGIN

    FILL_IN_PARAMS(PARAMS);

    FOR I IN 1..PARAMS.COUNT LOOP
      DBMS_STATS_INTERNAL.GET_PARAM_PROP(PARAMS(I).PNAME,
        PAREXIST, ISDEFAULT);
      IF (PAREXIST = TRUE AND ISDEFAULT = 1) THEN
        DBMS_STATS_INTERNAL.SET_PARAM(PARAMS(I).PNAME,
          PARAMS(I).PVALNUM, PARAMS(I).PVALVCHAR,
          CUR_TIME, PARAMS(I).ISDEFAULT);
      ELSIF (PAREXIST = FALSE) THEN
        DBMS_STATS_INTERNAL.ADD_PARAM(PARAMS(I).PNAME,
          PARAMS(I).PVALNUM, PARAMS(I).PVALVCHAR,
          CUR_TIME, PARAMS(I).ISDEFAULT);
      END IF;
    END LOOP;
    COMMIT;

通过这里可以看到我们在使用DBMS_STAT收集统计信息时,在初始化默认参数的时候,会执行COMMIT操作.

测试 analyze 类似DDL功能

--session 1
SQL> insert into t_xifenfei select * from dba_objects where rownum<10;

9 rows created.

SQL> analyze table xifenfei.t_xifenfei compute statistics;

Table analyzed.

SQL> select count(*) from t_xifenfei;

  COUNT(*)
----------
         0

--session 2
SQL> select count(*) from t_xifenfei;

  COUNT(*)
----------
         9
--证明analyze隐式提交了会话,类此ddl功能

分析analyze事务提交原因

SQL> oradebug setmypid
Statement processed.
SQL> oradebug EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12
Statement processed.
SQL> analyze table xifenfei.t_xifenfei compute statistics;

Table analyzed.

SQL> oradebug TRACEFILE_NAME
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_27497.trc
SQL> oradebug EVENT 10046 trace name context off
Statement processed.

--分析trace主要操作如下
delete:sys.mon_mods$,sys.mon_mods_all$,superobj$,tab_stats$
update:tab$,hist_head$

从10046中未看到明显的commit,但是里面有不少delete和update的dml操作,那肯定有提交,可能在10046中没有显示出来.

总结说明
1.通过观察dba_objects.last_ddl_time列,发现收集统计信息未能是的该列发生变化,从而猜测收集统计信息是dml操作
2.通过DBMS_STATS和analyze事务的测试,证明这些操作可以提交事务
3.通过分析发现DBMS_STATS在设置默认值的时候,会显式commit
4.通过分析analyze发现其本质就是对一些数据的delete+update操作,并没有修改这些对象的结构,在提交这些记录的时候,隐式提交了以前事务
5.最终总结:数据库收集统计信息是dml操作

发表在 Oracle | 评论关闭