如何使用 Oracle 自治数据库比较两个对象存储桶中的文件?

How can I compare files in two object store buckets using an Oracle Autonomous Database?

我在 OCI 对象存储的不同区域中有两个存储桶。我想使用 Oracle Autonomous Database 比较两个存储桶中的文件,以检测丢失的文件并将它们复制过来并同步两个存储桶。我使用不同区域的两个存储桶在两个区域的服务 运行 之间复制一些配置元数据。

例如:

Oracle 自治数据库提供了 DBMS_CLOUD 包来访问对象存储文件。

DBMS_CLOUD 包有一个函数 LIST_OBJECTS,它提供对象存储位置(存储桶或子文件夹)中的文件列表。此函数提供对象名称、字节大小和校验和,可用于在 Oracle SQL FULL OUTER JOIN 和 WITH 子句的帮助下比较 2 个存储桶中的文件。

SQL 脚本:

define bucket1_uri='https://objectstorage.us-phoenix-1.oraclecloud.com/n/mynamespace/b/mybucket/o/folder1/'
define bucket2_uri='https://objectstorage.us-ashburn-1.oraclecloud.com/n/mynamespace/b/mybucket/o/folder2/'
define credname1='OCI$RESOURCE_PRINCIPAL'
define credname2='OCI$RESOURCE_PRINCIPAL'

set linesize 120
set pages 1000
col object_name_A format a30
col object_name_B format a30
col object_checksum_A format a10
col object_checksum_B format a10


-- Use SQL FULL OUTER JOIN and compare the checksum exclude matching rows
WITH bucket1 AS 
   (SELECT object_name, bytes, checksum FROM DBMS_CLOUD.LIST_OBJECTS('&credname1', '&bucket1_uri')
    ORDER BY object_name, bytes, checksum),
     bucket2 AS
   (SELECT object_name, bytes, checksum FROM DBMS_CLOUD.LIST_OBJECTS('&credname2', '&bucket2_uri')
    ORDER BY object_name, bytes, checksum)
SELECT rownum id, diff.* FROM
(SELECT a.object_name object_name_A, a.bytes object_size_A, a.checksum object_checksum_A,
        b.object_name object_name_B, b.bytes object_size_B, b.checksum object_checksum_B
  FROM bucket1 a FULL OUTER JOIN bucket2 b
    ON a.object_name = b.object_name) diff
WHERE diff.object_name_A IS NULL OR
      diff.object_name_B IS NULL OR
      (diff.object_name_A = diff.object_name_B AND
       diff.object_checksum_A != diff.object_checksum_B)
/

解释:

在上面的脚本中:

  1. 假设是提供 2 个对象存储 URL 和一个凭据名称。可以使用自治数据库中 OCI 对象存储的资源主体来避免指定密码。
  2. 使用 Oracle SQL WITH Clause,有 2 个内联视图在两个存储桶中提供来自 DBMS_CLOUD.LIST_OBJECTS 的 object_name、字节和校验和列。
  3. 该脚本使用文件校验和来比较两个存储桶中的文件,它由云对象存储提供商作为文件内容的哈希值提供。
  4. 使用SQLFull Outer Join,我们可以得到存在于bucket1中但不存在于bucket2中的对象,或者vice-versa,以及在两个bucket中具有相同名称但文件校验和不同的对象.
  5. 最后,上面的 SQL 不显示两个存储桶中具有相同名称和相同大小的对象。

用例:

DBMS_CLOUD包适用于Oracle OCI、AWS S3、Azure BLOB、GoogleCloud、Wasabi等多种对象存储,因此上述脚本可用于多种场景下的bucket比较比如-

  • 在 OCI 中比较同一区域中的桶
  • 比较 OCI 中不同区域的桶
  • 比较 OCI 对象存储中不同账户中的存储桶
  • 比较不同云提供商中的存储桶 - OCI 存储桶与 S3 存储桶

参考文献: