Skip to main content

Built-in expire snapshots job

Overview​

The builtin-iceberg-expire-snapshots job template removes old Iceberg snapshots and their associated metadata files. Without periodic expiration, snapshot JSON files and manifest lists accumulate indefinitely, slowing table operations and wasting storage.

This job executes Iceberg's expire_snapshots stored procedure via Spark SQL.

Job template​

PropertyValue
Namebuiltin-iceberg-expire-snapshots
TypeSpark
Versionv1
Main classorg.apache.gravitino.maintenance.jobs.iceberg.IcebergExpireSnapshotsJob

Parameters​

Required​

KeyDescriptionExample
catalog_nameIceberg catalog name registered in Sparkrest_catalog
table_identifierFully qualified table namedb.sample

Optional​

KeyDescriptionDefault
older_thanExpire snapshots older than this timestamp (yyyy-MM-dd HH:mm:ss)5 days ago (Iceberg default)
retain_lastMinimum number of most recent snapshots to keep1
stream_resultsFlag: presence enables streaming of intermediate delete resultsdisabled
spark_confJSON map of custom Spark configurationsnone

Usage​

Direct job submission via REST​

Submit an expire snapshots job
curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-d '{
"jobTemplateName": "builtin-iceberg-expire-snapshots",
"jobConf": {
"catalog_name": "rest_catalog",
"table_identifier": "db.t1",
"older_than": "2024-01-01 00:00:00",
"retain_last": "3",
"spark_master": "local[2]",
"spark_executor_instances": "1",
"spark_executor_cores": "1",
"spark_executor_memory": "1g",
"spark_driver_memory": "1g",
"catalog_type": "rest",
"catalog_uri": "http://localhost:9001/iceberg",
"warehouse_location": ""
}
}' \
http://localhost:8090/api/metalakes/test/jobs

Expire with only retain_last​

Keep only the last five snapshots
curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-d '{
"jobTemplateName": "builtin-iceberg-expire-snapshots",
"jobConf": {
"catalog_name": "rest_catalog",
"table_identifier": "db.t1",
"retain_last": "5",
"spark_master": "local[2]",
"spark_executor_instances": "1",
"spark_executor_cores": "1",
"spark_executor_memory": "1g",
"spark_driver_memory": "1g",
"catalog_type": "rest",
"catalog_uri": "http://localhost:9001/iceberg",
"warehouse_location": ""
}
}' \
http://localhost:8090/api/metalakes/test/jobs

Check job status​

Check job status
curl -sS "http://localhost:8090/api/metalakes/test/jobs/{job_id}" | jq

Generated SQL​

The job builds and executes a Spark SQL statement:

Generated Spark SQL
CALL `rest_catalog`.system.expire_snapshots(
table => 'db.t1',
older_than => TIMESTAMP '2024-01-01 00:00:00',
retain_last => 3,
stream_results => true
)

Only non-empty optional parameters are included. The catalog identifier is backtick-quoted for safety.

Output​

On success, the job logs:

Example job log output
Expire Snapshots Results:
Deleted data files: 12
Deleted manifest files: 8
Deleted manifest lists: 3

Verification​

Verify the job result
# Verify job completed
curl -sS "http://localhost:8090/api/metalakes/test/jobs/{job_id}" | jq '.job.state'
# Expected: "SUCCEEDED"

# Check staging logs
cat /tmp/gravitino/jobs/staging/test/builtin-iceberg-expire-snapshots/{job_id}/stdout.log

Relationship to other jobs​

JobPurpose
builtin-iceberg-rewrite-data-filesCompacts small data files
builtin-iceberg-update-statsCollects file statistics and metrics
builtin-iceberg-expire-snapshotsRemoves old snapshot metadata

These jobs are complementary. A typical maintenance workflow runs update-stats first, then compaction, then expire-snapshots to clean up the snapshot history created by compaction.