【问题标题】:Oracle not reuse deleted blocksOracle 不重用已删除的块
【发布时间】:2019-10-22 07:39:28
【问题描述】:

我正在尝试将数据从 PURCHASE_HIST_D 插入到 PURCHASE_HIST

(不同服务器中的不同架构,使用 DBLINK)。

目标表有很多被删除的数据块。

这就是我检查段与使用的块的方式:

-- result : 199.8743480481207370758056640625 GB
select (AVG_ROW_LEN*NUM_ROWS)/1024/1024/1024 from DBA_TABLES where TABLE_NAME='PURCHASE_HIST'; 

-- result: 250.7939453125 GB
select SUM(BYTES)/1024/1024/1024 from DBA_SEGMENTS where SEGMENT_NAME='PURCHASE_HIST'; 

这意味着有 50 GB 的已用块可重复用于新数据。

我对源表的查询相同:

-- result: 21.8079682849347591400146484375
select (AVG_ROW_LEN*NUM_ROWS)/1024/1024/1024 from DBA_TABLES where TABLE_NAME='PURCHASE_HIST_D'; 

-- result: 27.447265625
select SUM(BYTES)/1024/1024/1024 from DBA_SEGMENTS where SEGMENT_NAME='PURCHASE_HIST_D'; 

源只有 27 GB,所以看起来我不需要为表空间添加更多空间。

这是空闲表空间信息:

-- result: 1889477 (Used MB)    4923 (Free MB)  1894400 (Total MB)
select
   fs.tablespace_name                          "Tablespace",
   (df.totalspace - fs.freespace)              "Used MB",
   fs.freespace                                "Free MB",
   df.totalspace                               "Total MB",
   round(100 * (fs.freespace / df.totalspace)) "Pct. Free"
from
   (select
      tablespace_name,
      round(sum(bytes) / 1048576) TotalSpace
   from
      dba_data_files
   group by
      tablespace_name
   ) df,
   (select
      tablespace_name,
      round(sum(bytes) / 1048576) FreeSpace
   from
      dba_free_space
   group by
      tablespace_name
   ) fs
WHERE
   DF.TABLESPACE_NAME = FS.TABLESPACE_NAME
   and df.TABLESPACE_NAME = 'TS_DWHDATA';

那么为什么当我执行插入时(即使有 NOAPPEND 提示)我会收到一个错误,即表空间中没有足够的空间?

-- examole of the Insert
INSERT
        /*+ monitor NOAPPEND  parallel(64)  statement_queuing */
INTO    DWH.PURCHASE_HIST            
SELECT  *
FROM    DWH_MIG.PURCHASE_HIST_D@DWH_MIG ;

例外:

ORA-01653: unable to extend table DWH.PURCHASE_HIST by 8192 in tablespace TS_DWHDATA

【问题讨论】:

  • 什么版本的Oracle?如果您使用并行查询,我相信许多/大多数人会在高水位线之上插入,这样多个线程就不会相互竞争。但这可能是版本相关的行为。
  • 11g。你有什么参考吗?
  • 这是一个参考oracle-randolf.blogspot.com/2011/02/… 如果您进行串行插入,我希望它使用高水位线以下的块。
  • 这是来自您发送的文章:“正如您从上面的测试用例输出中看到的那样,直接路径(串行或并行)加载不会重复使用现有的任何可用空间块。它将始终“附加”在当前的高水位线之上,使该段增长”。由于附加,它与串行和并行负载有关。但是,如果我有 NOAPPEND 提示,我会排除空闲块将在使用中,在高水位线下。
  • 直接路径插入做几件事,其中之一是在高水位线上方插入。 NOAPPEND 应该强制它执行常规路径插入(取决于您拥有的 11g 的特定版本和您的配置),因此您将获得完整的重做生成,但我相信在某些情况下常规路径并行加载将写入 HWM 之上。

标签: oracle insert storage dblink tablespace


【解决方案1】:

您正在从表中获取可用空间(使用查询),但高水位线仍处于您无法在其下方插入数据的位置。

您需要使用以下方法回收该空间:

alter table your_table enable row movement;

alter table your_table shrink space cascade;

此外,您需要在这样的操作后重建表的索引。

请参考Oracle documentation 回收废旧空间。

干杯!!

【讨论】:

  • 但是当我们使用 noappend 时,目的是数据库会搜索已删除的块并在其中插入新行....如果我们需要收缩表 - append 和有什么区别并且没有附加??
猜你喜欢
  • 2022-07-22
  • 2012-12-02
  • 1970-01-01
  • 2016-02-21
  • 2021-08-29
  • 1970-01-01
  • 2013-03-17
  • 2014-06-13
  • 2018-01-18
相关资源
最近更新 更多