【引言】
今天有同事问了一个问题,在Oracle 11g下,为啥exp方式导出一个用户的数据表,在imp后却发现有些表并没有迁移过来。经查阅官方文档,发现和Oracle11g及12c +版本相对于10g,有一个新特性deferred_segment_creation(延迟段创建)造成的。
该参数的作用为:
oracle 11g中,当创建的表无数据时,不进行segment分配,以节省存储空间。
为了理解啥原理,这里再复习下Oracle的几个概念:
1. tablespace: 一个数据库划分为一个或多个逻辑单位,该逻辑单位成为表空间;每一个表空间可能包含一个或多个Segment;
2. Segments: Segment指在tablespace中为特定逻辑存储结构分配的空间。每一个段是由一个或多个extent组成。包括数据段、索引段、回滚段和临时段。
3. Extents: 一个 extent 由一系列连续的 Oracle blocks 组成。通过extent 来给segment分配空间。
4. Data Blocks:Oracle 最小I/O存储单位,一个 data block 对应一个或多个分配给data file的操作系统块;默认为8KB,此参数在创建实例时可以修改,如做数仓库一般修改为64KB以上,为的是一次能从存储中多读取一些数据进内存,提升处理速度。
来张图更直观:
Oracle10g之前的版本,table 创建时,默认创建了一个data segment,这个data segment含有min extents 指定的extents 数,每个extent 据表空间的存储参数分配一定数量的blocks。
Oracle11g及12c以后版本,有了一个新特性参数deferred_segment_creation(延迟段创建),默认为true;该参数表示:创建表时,如为空没有数据插入则不分配segment,如果为false,则在创建表示创建一个data segment;
注意sys用户除外,它会自动分配空间,普通用户不会自动创建。
了解了如上deferred_segment_creation特性;
有同学会说:把deferred_segment_creation修改为flase不就行了。
注意:
deferred_segment_creation修改为flase后,只对新建的空表起作用,之前空表依旧无法正常导出,除非把之前的所有空表做一次segment段分配处理。
怎么做?
把所有的空表做segment create 处理,通过sql手动方法实现。
步骤如下:
步骤1:--查询所有的空表
select table_name from user_tables where NUM_ROWS=0;
步骤2:--拼接sql,批量生成修改语句
select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0;
步骤3:--利用exp/imp命令重新执行导出和导入操作即可。
步骤4:--修改deferred_segment_creation修改为flase,规避后续再次出现此类问题。
这里注意,步骤2会出现一种现象:
步骤2查出来的有些空表,在视图user_tables中的num_rows不等于0(原因:表中以前有数据,删除后oracle没有统计,视图user_tables中数据没有更新),故通过步骤2的sql并不能为所有的空表分配数据段。
怎么办?
执行一遍统计信息搜集即可。
select 'analyze table '||table_name||' compute statistics;' from user_tables;
analyze table tablename compute statistics;
等同于 analyze table tablename compute statistics for table for all indexes for all columns;
for table的统计信息存在于视图:user_tables 、all_tables、dba_tables
for all indexes的统计信息存在于视图:user_indexes 、all_indexes、dba_indexes
for all columns的统计信息存在于视图:user_tab_columns、all_tab_columns、dba_tab_columns
执行完后,视图user_tables中的num_rows值会做更新,此时再执行步骤2,能够给所有空表分配数据段
然而,在执行 analyze table tablename compute statistics 时,oracle会报object statictis are locked (这些表的统计被锁了),通过如下方式解锁:
select 'exec dbms_stats.unlock_table_stats('||'''OWNNAME'''||','''||table_name||''');' from user_tables where table_block=’DISABLED’;
以下是UNLOCK_TABLE_STATS Procedure介绍
This procedure unlocks the statistics on the table.
Syntax
DBMS_STATS.UNLOCK_TABLE_STATS (
ownname VARCHAR2,
tabname VARCHAR2);
Parameters
Table 141-98 UNLOCK_TABLE_STATS Procedure Parameters
Parameter | Description |
ownname | The name of the schema |
tabname | The name of the table |
Usage Notes
When statistics on a table is locked, all the statistics depending on the table, including table statistics, column statistics, histograms and statistics on all dependent indexes, are considered to be locked.
The SET_*, DELETE_*, IMPORT_*, GATHER_* procedures that modify statistics in the dictionary of an individual table, index or column will raise an error if statistics of the object is locked.
Procedures that operates on multiple objects (such as GATHER_SCHEMA_STATS) will skip modifying the statistics of an object if it is locked. Many procedures have force argument to override the lock.
欢迎关注个人微信公众号“一森咖记”
近期热文
你可能也会对以下话题感兴趣。点击链接便可查看。
Oracle ADG同步技术,DBA必备的一种“后悔药”
OpenJDK和Oracle JDK有什么区别和联系?
神技_如何快捷下载Oracle补丁的方法?!
趋势篇:oracle 11g,12c,18c,19c之support lifetime
Configuring Kernel Parameters about SHMMAX on HP
对recursive calls的深刻理解
Centos能不能替换RHEL?
RAC1 服务器要重启,喂:RAC2你先顶一下,咋搞?!
对recursive calls的深刻理解
OpenJDK和Oracle JDK有什么区别和联系?
Centos能不能替换RHEL?
PLSQL Developer中控制结果集表格自动提交
alter table T1 add column新增字段执行时间超长,咋回事?
Oracle 11g 异机rman恢复报错ORA-27302:failure occurred at: sskgpcreates
年末总结_聊一聊数据库行业的“继往开来”
Materialized view物化视图的一个简单应用场景
干货:RHEL7.2生产环境下双节点12c RAC搭建实操
【干货篇】在国内外数据库百家争鸣的时代,DBA们该何去何从?
LINUX环境:MySQL和Oracle开机自启动,咋搞?Logminer:oracle人为误操作之恢复神器
What:ASM自动脱落了
实操:12C RAC环境下的ADG同步库搭建
“神器”:Oracle日志采集分析工具——TFA
Oracle Rac:关闭透明大页的原因及方法
实操篇:Oracle 19c的安装部署
浅谈MySQL三种锁:全局锁、表锁和行锁
Oracle如何访问MySql:透明网关