Oracle 11g及12c+版本下为啥有些表不能exp导出?

【引言】

今天有同事问了一个问题,在Oracle 11g下,为啥exp方式导出一个用户的数据表,在imp后却发现有些表并没有迁移过来。经查阅官方文档,发现和Oracle11g及12c +版本相对于10g,有一个新特性deferred_segment_creation(延迟段创建)造成的。

该参数的作用为:

oracle11g中当创建的表无数据时,不进行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介绍
在这里插入图片描述

欢迎关注个人微信公众号“一森咖记”
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/db_murphy/article/details/108225756
今日推荐