
想学会更多实用技巧,欢迎加入青学会MOP技术社区(实名社区)。
加入方法:公众号后台回复关键字“加入”获取小助手微信,添加后登记入会。

同时欢迎大家在评论区留言互动交流!社区会不定期举行相关的抽奖、公开分享活动。
如果你有想了解的知识点希望我们发文可以后台私信。
最近联合几个 Oracle ACE技术专家 开通了一个付费微信群,都是具有10多年金融、医疗、制造业10年以上的一线专家,坑位费399/人,无限期,目前群内近165人。加群后会有一些福利(分享各类技术文档,干货资源,问题解答等等),更有特邀嘉宾会定期在群内直播,解读AWR,快问快答等!有问题我们尽量都解答,毕竟399不能都解决所有问题。有兴趣联系微:ywu0613
内部知识库正在筹建中,不止有oracle!
正文开始
在数据库运维的世界里,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 name, TYPE, VALUE, 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 = 0AND 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参数的作用,以及掌握相应的解决方法,你可以轻松应对这个问题。
在数据库运维的道路上,我们会遇到各种各样的挑战。但只要我们不断学习、积累经验,就能像游戏打怪升级一样,一步步攻克这些难题。希望这篇文章能帮助你更好地理解和解决Oracle 11g空表不导出的问题。如果你还有其他疑问,欢迎随时交流探讨!
往期文章回顾
MOP社区新闻
金仓专栏
告别繁琐!KingbaseES v9数据库一键安装-青学会&金仓专栏(1)
KingbaseES v9数据库Docker安装-青学会&金仓专栏(2)
DBA实战小技巧
实战:记一次RAC故障排查
DBA实战运维小技巧安装篇(一)Oracle 主流版本不同架构下的静默安装指南
DBA实战运维小技巧存储篇(一)根目录满了如何处理
DBA实战运维小技巧存储篇(二)打包迁移单机数据库至新存储
MOP社区投稿-内核开发
简单解析 IvorySQL 增强 Oracle xml 兼容能力的原理
简单讨论 PostgreSQL C语言拓展函数返回数据表的方式
简单分析 pg_config 程序的作用与原理
Redis 日志机制简介(一):SlowLog
Redis 日志机制简介(二):AOF 日志
Redis 日志机制简介(三):RDB 日志
pg_cron插件使用介绍
Redis 的指令表实现机制简介
pg几款源码工具介绍
Redis 事务功能简介




