跳转到内容
搜索文档

删除数据

最后更新 查看 MarkdownAgent 设置

从 R2 Data Catalog 或任何 Apache Iceberg catalog 删除数据时,必须通过 catalog 本身以事务方式执行操作。直接手动删除元数据或数据文件可能导致数据 catalog 损坏。

自动表维护

R2 Data Catalog 可以自动管理快照过期和压缩等表维护操作。这些持续运行的操作有助于降低延迟和存储成本。

  • 快照过期:自动删除旧快照及相应的未引用数据文件。这同时减少了元数据开销和存储成本。
  • 压缩:将小型数据文件合并为更大的文件。这优化了读取性能,并减少了查询期间读取的文件数量。

如果不启用自动维护,则需要手动处理这些操作。

表维护文档中了解更多信息。

在 R2 Data Catalog 中启用自动表维护的示例

# Enable automatic snapshot expiration for entire catalog
npx wrangler r2 bucket catalog snapshot-expiration enable my-bucket \
	--older-than-days 30 \
	--retain-last 5

# Enable automatic compaction for entire catalog
npx wrangler r2 bucket catalog compaction enable my-bucket \
	--target-size 256

请参阅管理 catalog文档中的更多示例。

手动删除和移除数据

在以下情况下需要手动删除数据:

  • 遵守 GDPR 或 CCPA 等数据保留政策。
  • 使用条件逻辑进行选择性删除。
  • 移除 R2 Data Catalog 未管理的陈旧或未引用文件。

以下示例使用 PySpark,但也可以使用其他兼容 Iceberg 的引擎执行类似操作。要配置 PySpark,请参阅我们的示例或官方 PySpark 文档

从表中删除行

# Creates new snapshots and marks old files for cleanup
spark.sql("""
	DELETE FROM r2dc.namespace.table_name
	WHERE column_name = 'value'
""")

# The following is effectively a TRUNCATE operation
spark.sql("DELETE FROM r2dc.namespace.table_name")

# For large deletes, use partitioned tables and delete entire partitions for faster performance:
spark.sql("""
    DELETE FROM r2dc.namespace.table_name
    WHERE date_partition < '2024-01-01'
""")

删除表和 namespace

# Removes table from catalog but keeps data files in R2 storage
spark.sql("DROP TABLE r2dc.namespace.table_name")

# ⚠️  DANGER: Permanently deletes all data files from R2
# This operation cannot be undone
spark.sql("DROP TABLE r2dc.namespace.table_name PURGE")

# Use CASCADE to drop all tables within the namespace
spark.sql("DROP NAMESPACE r2dc.namespace_name CASCADE")

# You will need to PURGE the tables before running CASCADE to permanently delete data files
# This can be done with a loop over all tables in the namespace
tables = spark.sql("SHOW TABLES IN r2dc.namespace_name").collect()
for row in tables:
	table_name = row['tableName']
  spark.sql(f"DROP TABLE r2dc.namespace_name.{table_name} PURGE")
spark.sql("DROP NAMESPACE r2dc.namespace_name CASCADE")

手动维护操作

# Remove old metadata and data files marked for deletion
# The following retains the last 5 snapshots and deletes files older than Nov 28, 2024
spark.sql("""
	CALL r2dc.system.expire_snapshots(
    table => 'r2dc.namespace_name.table_name',
    older_than => TIMESTAMP '2024-11-28 00:00:00',
     retain_last => 5
  )
""")

# Removes unreferenced data files from R2 storage (orphan files)
spark.sql("""
  CALL r2dc.system.remove_orphan_files(
    table => 'namespace.table_name'
  )
""")

# Rewrite data files with a target file size (e.g., 512 MB)
spark.sql("""
  CALL r2dc.system.rewrite_data_files(
    table => 'r2dc.namespace_name.table_name',
    options => map('target-file-size-bytes', '536870912')
  )
""")

关于 Apache Iceberg 元数据

Apache Iceberg 使用分层元数据结构来高效管理表数据。以下是关键组件和文件结构:

  • metadata.json:指向当前快照的顶层 JSON 文件
  • snapshot-*:给定时间点的不可变表状态
  • manifest-list-*.avro:列出给定快照所有 manifest 文件的 Avro 文件
  • manifest-file-*.avro:跟踪数据文件及其统计信息的 Avro 文件
  • data-*.parquet:包含实际表数据的 Parquet 文件
  • 注意:未更改的 manifest 文件会在快照之间复用
  • metadata.json Metadata File - Points to current snapshot
    • Table Schema
    • Partition Spec
    • Sort Order
    • Snapshots
      • snapshot-3051729675574597004.avro Snapshot 1 (Historical)
        • manifest-list-abc123.avro Manifest List
          • manifest-file-001.avro Manifest File
            • data-00001.parquet (10 MB, 50K rows)
            • data-00002.parquet (12 MB, 60K rows)
            • data-00003.parquet (11 MB, 55K rows)
          • manifest-file-002.avro
            • data-00004.parquet (9 MB, 45K rows)
            • data-00005.parquet (10 MB, 50K rows)
      • snapshot-3051729675574597005.avro Snapshot 2 (Current)
        • manifest-list-def456.avro Manifest List
          • manifest-file-001.avro (reused from Snapshot 1)
            • data-00001.parquet
            • data-00002.parquet
            • data-00003.parquet
          • manifest-file-003.avro (new)
            • data-00006.parquet (11 MB, 53K rows)
            • data-00007.parquet (10 MB, 51K rows)
            • data-00008.parquet (12 MB, 58K rows)

删除过程中会发生什么

Apache Iceberg 支持两种删除模式:Copy-on-Write (COW)Merge-on-Read (MOR)。两者都会创建新快照并将旧文件标记为待清理,但处理删除的方式不同:

方面 Copy-on-Write (COW) Merge-on-Read (MOR)
删除方式 重写不含已删除行的数据文件 创建 delete 文件标记要跳过的行
查询性能 快(无需合并) 较慢(需要读取时合并)
写入性能 较慢(重写数据文件) 快(仅写入 delete 标记)
存储影响 立即创建新数据文件 随时间累积 delete 文件
维护需求 快照过期 快照过期 + 压缩(rewrite_data_files
适用场景 读密集型工作负载 频繁小变更的写密集型工作负载

常见删除操作

这些操作对 COW 和 MOR 表的工作方式相同:

操作 作用 数据已删除? 可撤销?
DELETE FROM 删除符合条件的行 否(标记为待清理) 通过时间旅行1
DROP TABLE 从 catalog 中移除表 是(如果数据文件仍存在)
DROP TABLE ... PURGE 移除表并删除数据
expire_snapshots 清理旧快照/文件
remove_orphan_files 移除未引用的文件

MOR 特定操作

对于 Merge-on-Read 表,可能需要手动应用删除以提升性能:

操作 作用 使用时机
rewrite_data_files (compaction) 应用删除并合并文件 当大量 delete 文件导致查询性能下降时

相关资源

Footnotes

  1. 时间旅行功能在调用 expire_snapshots 之前可用

这篇文档对您有帮助吗?