Oracle 11g 空表不导出处理方法

在数据库运维的世界里,Oracle数据库一直以其强大的功能和稳定性受到众多企业的青睐。然而,即使是经验丰富的运维人员,在面对 Oracle 11g的某些特性时,也可能会遇到一些小困惑。今天,我们就来聊聊一个让不少初学者头疼的问题——Oracle 11g 空表不导出。

在Oracle 11g的11.2.0.2版本中,出现了一个新特性:表创建时不分配空间,而是在第一次数据插入时才分配空间。这就导致了一个有趣的现象——使用传统的exp工具导出数据库时,那些没有分配空间的空表是不会被导出的。

想象一下,你辛辛苦苦创建了一个表,结果在导出数据库时却发现它不见了,是不是会有点抓狂?别担心,这并不是你的操作有问题,而是Oracle数据库的一个新特性在“作祟”。

关键知识点:deferred_segment_creation 参数

Oracle 11g新增了一个参数——deferred_segment_creation,它的含义是段延迟创建。默认情况下,这个参数的值是true。也就是说,当你新建一个表但没有向其中插入数据时,这个表不会立即分配extent(扩展),也就是不占用数据空间。只有当你插入数据后,才会分配空间。这样做的好处是可以节省少量的空间。

不过,这里有个小例外。如果你是在系统用户(sys用户)下创建表,那么这个参数的影响就会被忽略。无论参数值如何,系统用户下的表在创建时都会分配空间。

解决方法

方法一:修改deferred_segment_creation参数

如果你希望无论是空表还是非空表,都分配segment,那么可以将deferred_segment_creation参数设置为FALSE。具体操作如下:


ALTER 
SYSTEM 
SET deferred_segment_creation=
FALSE;

查看参数是否修改成功:


show parameter deferred_segment_creation;

或者:


SELECT 
nameTYPEVALUE, isses_modifiable, issys_modifiable 

FROM v$parameter 
WHERE  name  LIKE  'defer%';

需要注意的是,修改这个参数后,它只对后面新增的表产生作用,对之前已经建立的空表是不起作用的。而且,通常情况下,还需要重新启动数据库,让参数真正生效。

方法二:在创建表时指定段创建方式

如果你不想修改系统参数,也可以在创建表的时候直接指定是否创建段。如果你想在创建表的同时创建段,可以使用以下语法:


create 
table 
test(
id 
number(
10)) 
SEGMENT 
CREATION 
IMMEDIATE;

相反,如果你想在创建表时不创建段(非sys用户),可以使用:


create 
table 
test(
id 
number(
10)) 
SEGMENT 
CREATION 
DEFERRED;

方法三:手动为表分配段

如果你已经创建了空表,并且希望为它们分配段,可以使用以下方法:


BEGIN 

 DBMS_SPACE_ADMIN.materialize_deferred_segments ( 
 schema_name =>  'SCOTT',  
 table_name =>  'TEST' 
 ); 
END
/

或者:


ALTER 
TABLE TableName 
ALLOCATE 
EXTENT;

如果是分区表,可以使用:


ALTER 
TABLE TableName 
modify 
partition partition_name 
ALLOCATE 
EXTENT;

方法四:删除空表的段

如果你想要将空表的段删除,可以执行以下操作:


BEGIN 

 DBMS_SPACE_ADMIN.drop_empty_segments; 
END
/

方法五:构建对空表分配空间的SQL命令

如果你想批量为当前用户下的所有空表分配空间,可以按照以下步骤操作:

首先,查询当前用户下的所有空表:


SELECT table_name 

FROM user_tables 
WHERE NUM_ROWS =  0;

然后,构建针对空表分配空间的命令语句:


set echo 
off feed 
off pages 
0

spool temp.sql 

SELECT 'alter table ' || table_name ||  ' allocate extent;'
FROM user_tables 
WHERE num_rows =  0 AND partitioned =  'NO'

SELECT 'alter table '
|| table_name 
||  ' modify partition '
|| partition_name 
||  ' allocate extent;'
FROM USER_TAB_PARTITIONS 
WHERE num_rows =  0
spool off 
set echo  on feed  on
@ temp.sql

Oracle 11g的空表不导出问题,其实是数据库为了优化空间使用而设计的一个特性。通过了解deferred_segment_creation参数的作用,以及掌握相应的解决方法,你可以轻松应对这个问题。


请使用浏览器的分享功能分享到微信等