Skip to content

Commit 73b7d37

Browse files
committed
fix: fast append should not contain deleted file during retry process
1 parent ae29c3d commit 73b7d37

2 files changed

Lines changed: 38 additions & 8 deletions

File tree

src/iceberg/update/fast_append.cc

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "iceberg/manifest/manifest_entry.h"
2727
#include "iceberg/manifest/manifest_util_internal.h"
2828
#include "iceberg/snapshot.h"
29-
#include "iceberg/table.h"
29+
#include "iceberg/table.h" // IWYU pragma: keep
3030
#include "iceberg/table_metadata.h"
3131
#include "iceberg/table_properties.h"
3232
#include "iceberg/transaction.h"
@@ -58,7 +58,7 @@ FastAppend& FastAppend::AppendFile(const std::shared_ptr<DataFile>& file) {
5858
auto [iter, inserted] = data_files.insert(file);
5959
if (inserted) {
6060
has_new_files_ = true;
61-
ICEBERG_BUILDER_RETURN_IF_ERROR(summary_.AddedFile(*spec, *file));
61+
ICEBERG_BUILDER_RETURN_IF_ERROR(added_data_files_summary_.AddedFile(*spec, *file));
6262
}
6363

6464
return *this;
@@ -75,11 +75,13 @@ FastAppend& FastAppend::AppendManifest(const ManifestFile& manifest) {
7575
"Sequence number must be assigned during commit");
7676

7777
if (can_inherit_snapshot_id() && manifest.added_snapshot_id == kInvalidSnapshotId) {
78-
summary_.AddedManifest(manifest);
78+
appended_manifests_summary_.AddedManifest(manifest);
7979
append_manifests_.push_back(manifest);
8080
} else {
8181
// The manifest must be rewritten with this update's snapshot ID
82-
ICEBERG_BUILDER_ASSIGN_OR_RETURN(auto copied_manifest, CopyManifest(manifest));
82+
ICEBERG_BUILDER_ASSIGN_OR_RETURN(auto copied_manifest,
83+
CopyManifest(manifest, /*update_summary=*/true));
84+
append_manifests_to_copy_.push_back(manifest);
8385
rewritten_append_manifests_.push_back(std::move(copied_manifest));
8486
}
8587

@@ -93,6 +95,14 @@ Result<std::vector<ManifestFile>> FastAppend::Apply(
9395
std::vector<ManifestFile> manifests;
9496

9597
ICEBERG_ASSIGN_OR_RAISE(auto new_written_manifests, WriteNewManifests());
98+
if (rewritten_append_manifests_.empty() && !append_manifests_to_copy_.empty()) {
99+
for (const auto& manifest : append_manifests_to_copy_) {
100+
ICEBERG_ASSIGN_OR_RAISE(auto copied_manifest,
101+
CopyManifest(manifest, /*update_summary=*/false));
102+
rewritten_append_manifests_.push_back(std::move(copied_manifest));
103+
}
104+
}
105+
96106
manifests.reserve(new_written_manifests.size() + append_manifests_.size() +
97107
rewritten_append_manifests_.size());
98108
if (!new_written_manifests.empty()) {
@@ -126,11 +136,23 @@ Result<std::vector<ManifestFile>> FastAppend::Apply(
126136
}
127137

128138
std::unordered_map<std::string, std::string> FastAppend::Summary() {
139+
summary_.Clear();
129140
summary_.SetPartitionSummaryLimit(
130141
base().properties.Get(TableProperties::kWritePartitionSummaryLimit));
142+
summary_.Merge(added_data_files_summary_);
143+
summary_.Merge(appended_manifests_summary_);
144+
for (const auto& [property, value] : custom_summary_properties_) {
145+
summary_.Set(property, value);
146+
}
131147
return summary_.Build();
132148
}
133149

150+
void FastAppend::SetSummaryProperty(const std::string& property,
151+
const std::string& value) {
152+
custom_summary_properties_[property] = value;
153+
SnapshotUpdate::SetSummaryProperty(property, value);
154+
}
155+
134156
Status FastAppend::CleanUncommitted(const std::unordered_set<std::string>& committed) {
135157
// Clean up new manifests that were written but not committed
136158
if (!new_manifests_.empty()) {
@@ -151,6 +173,7 @@ Status FastAppend::CleanUncommitted(const std::unordered_set<std::string>& commi
151173
std::ignore = DeleteFile(manifest.manifest_path);
152174
}
153175
}
176+
rewritten_append_manifests_.clear();
154177
}
155178
return {};
156179
}
@@ -161,14 +184,15 @@ bool FastAppend::CleanupAfterCommit() const {
161184
// 1.) Appended manifests are never rewritten
162185
// 2.) Manifests which are written out as part of AppendFile are already cleaned
163186
// up between commit attempts in WriteNewManifests
164-
return !rewritten_append_manifests_.empty();
187+
return !rewritten_append_manifests_.empty() || !append_manifests_to_copy_.empty();
165188
}
166189

167190
Result<std::shared_ptr<PartitionSpec>> FastAppend::Spec(int32_t spec_id) {
168191
return base().PartitionSpecById(spec_id);
169192
}
170193

171-
Result<ManifestFile> FastAppend::CopyManifest(const ManifestFile& manifest) {
194+
Result<ManifestFile> FastAppend::CopyManifest(const ManifestFile& manifest,
195+
bool update_summary) {
172196
const TableMetadata& current = base();
173197
ICEBERG_ASSIGN_OR_RAISE(auto schema, current.Schema());
174198
ICEBERG_ASSIGN_OR_RAISE(auto spec,
@@ -180,7 +204,8 @@ Result<ManifestFile> FastAppend::CopyManifest(const ManifestFile& manifest) {
180204

181205
// Copy the manifest with the new snapshot ID.
182206
return CopyAppendManifest(manifest, ctx_->table->io(), schema, spec, snapshot_id,
183-
new_manifest_path, current.format_version, &summary_);
207+
new_manifest_path, current.format_version,
208+
update_summary ? &appended_manifests_summary_ : nullptr);
184209
}
185210

186211
Result<std::vector<ManifestFile>> FastAppend::WriteNewManifests() {

src/iceberg/update/fast_append.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class ICEBERG_EXPORT FastAppend : public SnapshotUpdate {
7272
const TableMetadata& metadata_to_update,
7373
const std::shared_ptr<Snapshot>& snapshot) override;
7474
std::unordered_map<std::string, std::string> Summary() override;
75+
void SetSummaryProperty(const std::string& property, const std::string& value) override;
7576
Status CleanUncommitted(const std::unordered_set<std::string>& committed) override;
7677
bool CleanupAfterCommit() const override;
7778

@@ -85,7 +86,7 @@ class ICEBERG_EXPORT FastAppend : public SnapshotUpdate {
8586
///
8687
/// \param manifest The manifest to copy
8788
/// \return The copied manifest file
88-
Result<ManifestFile> CopyManifest(const ManifestFile& manifest);
89+
Result<ManifestFile> CopyManifest(const ManifestFile& manifest, bool update_summary);
8990

9091
/// \brief Write new manifests for the accumulated data files.
9192
///
@@ -95,7 +96,11 @@ class ICEBERG_EXPORT FastAppend : public SnapshotUpdate {
9596
private:
9697
std::string table_name_;
9798
std::unordered_map<int32_t, DataFileSet> new_data_files_by_spec_;
99+
SnapshotSummaryBuilder added_data_files_summary_;
100+
SnapshotSummaryBuilder appended_manifests_summary_;
101+
std::unordered_map<std::string, std::string> custom_summary_properties_;
98102
std::vector<ManifestFile> append_manifests_;
103+
std::vector<ManifestFile> append_manifests_to_copy_;
99104
std::vector<ManifestFile> rewritten_append_manifests_;
100105
std::vector<ManifestFile> new_manifests_;
101106
bool has_new_files_{false};

0 commit comments

Comments
 (0)