Skip to content

Fix leftover S3 files when deleting native ClickHouse backups - #1590

Merged
Slach merged 5 commits into
Altinity:masterfrom
cryptoque:fix/native-backup-json-cleanup
Oct 7, 2026
Merged

Slach merged 5 commits into
Altinity:masterfrom
cryptoque:fix/native-backup-json-cleanup

Conversation

@cryptoque

@cryptoque cryptoque commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Deleting a backup made with use_embedded_backup_restore and an S3 backup disk can report success while native backup files remain in S3. Files such as serialization.json were skipped, and remote deletion could choose the wrong cleanup path after the local backup was removed.

This change selects cleanup from the backup’s recorded type, includes native JSON files, and reads object references inside compressed data archives. It skips the tool’s own catalog, saved users, server settings, and named collections, which are ordinary files rather than references to native data. Native backups made on local disks keep their ordinary-file cleanup path.

The unit tests cover local deletion and remote deletion with uncompressed, tar, and gzip files. The new integration test creates a real serialization.json, records the native data objects named by the backup, and checks both deletion orders. Those objects must remain while either the local or remote copy is kept, and all must disappear after both copies are deleted. The existing clustered backup and restore scenarios remain unchanged.

ClickHouse 23.3 has a separate backup-creation bug that can leave files no longer named by any backup, fixed in ClickHouse/ClickHouse#51299. The integration test checks the files actually named by the backup instead of requiring deletion of those unrelated leftovers.

Validation:

  • go test ./pkg/backup ./pkg/storage/object_disk -count=1 -v and go vet ./pkg/backup ./pkg/storage/object_disk passed for the deletion changes.
  • Local Docker checks with ClickHouse 26.4.3 passed for uncompressed, tar, and gzip backups, including saved users, server settings, and named collections. Both deletion orders removed the old objects, preserved a separate retained backup, and restored exactly 10,003 rows on another ClickHouse instance.
  • Local TestEmbeddedS3 and TestEmbeddedS3Cleanup runs passed on ClickHouse 23.3 and 23.8. These ran the upstream test setup with local services and dummy credentials; the test runner was compiled for macOS ARM64 and the Linux backup binary included race checks and coverage.
  • Reintroducing the JSON-file exclusion in a separate local test build makes TestEmbeddedS3Cleanup/remote_first fail specifically because its real serialization.json object remains after deletion.

@Slach

Slach commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

thanks for contribution, will review later

@Slach Slach added this to the 2.8.2 milestone Oct 2, 2026
cryptoque and others added 4 commits October 1, 2026 23:55
Retention inside upload calls cleanEmbeddedAndObjectDiskRemoteIfSameLocalNotPresent
for older remote backups; assigning b.isEmbedded there leaked the tags of the
last deleted backup into the following local retention (hasObjectDisksLocal),
so use a local variable instead.

Read the backups_s3 object prefix from the {cluster}/{shard} macros in
TestEmbeddedS3Cleanup instead of hardcoding cluster/0, and add a ChangeLog entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Slach
Slach merged commit be67bcc into Altinity:master Oct 7, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants