代码之家  ›  专栏  ›  技术社区  ›  Tom

oracle如何避免写撤销/重做日志

  •  1
  • Tom  · 技术社区  · 15 年前

    我有一个oracle pl/sql脚本。它处理大约5100万个寄存器,并将结果写入5个不同的表。

    问题是我昨晚让进程继续运行,而且很明显undo日志中有溢出。

    特别是,我们对回滚这个脚本不感兴趣,如果它失败了,我们可以再次运行它。

    是否有任何方法可以优化撤消/重做日志的使用?避免写或尽量减少那些写?

    据我所知,除了使用append insert之外,设置输出表的nologging属性也会有帮助(如前所述 here )

    5 回复  |  直到 7 年前
        1
  •  2
  •   Kosi2801    15 年前

    不能一批处理5100万个寄存器。例如,试着把它分成几千个小块。如果在每个较小的批处理之后执行提交(不管怎样,您都会这样做,因为您不会回滚),那么重做/撤消日志的使用将仅用于未提交的部分,并且您将避免溢出。

        2
  •  1
  •   David Aldridge    15 年前

    这真的是一个问题或减少你正在做的工作量。

    直接路径插入上的表撤消总是很小,因为系统只需记录应该从段中删除某些范围的块。不过,索引仍需要大量撤销。在直接路径插入上取消记录可以最小化表重做。

        3
  •  1
  •   Dinesh Bhat    15 年前

    此外,禁用约束和索引也可能加快插入速度。您可以使用nologging重新生成索引。

        4
  •  0
  •   Gary Myers    15 年前

    “特别是,我们对回滚此脚本不感兴趣,如果失败,我们可以再次运行它。”

    一个问题是,为了再次运行脚本,是否需要并准备好返回到以前的备份? 也就是说,如果进程在1000万行之后失败,那么只需重新运行脚本就可以插入6100万行,或者跳过/忽略1000万行,或者更新1000万行,插入4100万行。

    另外,如果您执行nologgin插入,则可能需要在作业完成后立即进行新的备份。在脚本运行期间,您将无法将时间点恢复到某个时间,因此还需要考虑脚本运行时数据库上正在发生的其他活动。

    根据编写pl/sql脚本的方式,您可能会发现使用大型sql而不是逐行处理可以减少撤消(例如通过最小化对已处理块的重新访问)。

    除非您真正理解减少undo或提交以允许重用undo的影响,否则我的第一个建议将只是增加undo表空间的大小。当然,这样做的缺点是,如果生成了大量的undo bucket,那么回滚失败将需要很长时间。

        5
  •  0
  •   Oscar Caraballo    8 年前

    您还可以使用隐藏参数disable_logging=true来减少重做,但请注意,生成的导入将是不可恢复的。