原文作者:Mike Dietrich
原文地址:https://mikedietrichde.com/2024/09/23/cleanup-datapatch-patching-files-in-your-database/
不久前,我写过关于数据补丁存储在数据库中回滚补丁文件的情况,以及如果你频繁打补丁,它可能随时间消耗的空间量。我完全意识到这可能需要更长的时间,但终于在几个月后,有了缓解措施。现在,你可以清理数据库中的数据补丁文件,并回收空间。
快速回顾
在我2024年1月的博客文章中,我分享了一些查询,用于检查数据库中以前补丁所消耗的空间。简而言之,为了允许在多租户环境中无缝回滚补丁,特别是在你拔出/插入PDBs时,但也出于其他原因,数据库以压缩的zip格式存储了每次补丁运行的回滚脚本。这是好的且有用的,但不幸的是,它发生在每次补丁运行时——并且它保留了所有以前的zip文件。
由于这一发现,我们提交了一个跟踪错误,错误编号为34674756——如果不必要,从数据补丁库存中清除旧补丁元数据zip,数据补丁团队修复了它——这并不像人们想象的那么简单。
修复方案现已可用
目前,这个修复方案作为19.24.0版本的一次性补丁已经可用。它原本计划包含在19.25.0版本更新中,但由于一个性能问题而被撤回。现在它计划包含在下一个定期更新(RU)中。这意味着,如果你想在19.24.0版本上应用这个修复,你可以直接从MOS(MetaLink Online Support)下载。如果这个修复方案在你期望的版本更新中不可用,你需要提交一个服务请求(SR),并请求为你的RU版本提供针对错误编号34674756的回溯修复。请确保在提交SR时附上你的“opatch lsinventory”信息。
性能问题已经在错误编号37055793中得到修复,并预计将很快包含在内。
如何应用补丁
如果你想知道如何使用这个修复方案,这个过程非常简单直接。你只需将修复方案应用到你的数据库上,以我为例,是应用在19.24.0版本的定期更新(RU)之上,然后打开所有的PDBs。一旦你执行了datapatch -verbose命令,相关的脚本就会运行,一旦修复方案的脚本执行完毕,清理工作就会开始。
请准备好,根据数据库的大小,这个过程可能需要一些时间。但因为你的数据库在应用修复方案时已经可以打开并访问,所以这本身不应该是一个大问题。
在我的例子中,所有的容器中,sys.registrysqlpatch_ru_info(RUs)和sys.registrysqlpatch(一次性补丁)中的zip文件几乎占用了1GB的空间。
在datapatch完成其任务后,清理工作也完成了。在sys.registrysqlpatch_ru_info中只剩下一个单独的ZIP文件——所有其他行仍然存在,但没有了zip文件,因此不再占用任何空间。在sys.registrysqlpatch中,由于当前环境中甚至不再存在这些补丁,所有空间都被释放了。
只是运行时可能需要一些改进——但我知道我们已经在努力了。
用于检查数据库内补丁消耗情况的脚本
我在这里再次分享我之前博客文章中的脚本:https://mikedietrichde.com/2024/01/17/datapatch-stores-rollback-patching-files-in-the-database/
发布更新和补丁包
column patch_id format 9999999999
column ru_version format a15
column lob_size_md format 9999
COLUMN ru_build_ts FORMAT A20
set linesize 100
set pagesize 300
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'MM/DD/YY HH24:MI';
ALTER SESSION SET "_EXCLUDE_SEED_CDB_VIEW" = FALSE;
SELECT
patch_id,
ru_version,
TO_CHAR(ru_build_timestamp, 'MM/DD/YYYY HH24:MI:SS') AS ru_build_ts,
round(dbms_lob.getlength(patch_directory) / 1024 / 1024) lob_size_mb
FROM
sys.registry$sqlpatch_ru_info;
SELECT
con_id, round(sum(dbms_lob.getlength(patch_directory) / 1024 / 1024)) total_lob_size_mba
FROM
containers(sys.registry$sqlpatch_ru_info)
GROUP BY
con_id
ORDER BY
con_id;
复制
一次性补丁
column patch_id format 9999999999
column lob_size_md format 9999
COLUMN SUBSTR(description,1,40) FORMAT A40
set linesize 100
set pagesize 300
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'MM/DD/YY HH24:MI';
ALTER SESSION SET "_EXCLUDE_SEED_CDB_VIEW" = FALSE;
SELECT
patch_id,
SUBSTR(description,1,40) PATCH_DESCRIPTION,
TO_CHAR(source_build_timestamp, 'MM/DD/YYYY HH24:MI:SS') AS patch_build_ts,
round(dbms_lob.getlength(patch_directory) / 1024 / 1024) lob_size_mb
FROM
sys.registry$sqlpatch
WHERE
patch_type<>'RU';
SELECT
con_id, round(sum(dbms_lob.getlength(patch_directory) / 1024 / 1024)) total_lob_size_mba
FROM
containers(sys.registry$sqlpatch)
GROUP BY
con_id
ORDER BY
con_id;
复制