iceberg: create missing stage-create marker directories exclusively

The marker path starts at the table bucket directory, which carries the bucket
record; a plain create after a missed lookup replaces a directory another writer
made in between, with whatever it carries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris LuandClaude Opus 5.5 committed 2026-11-12 20:19:40 -08:00
1 parent 03e2dbb40e
commit 477e42fcc1
2 files changed
+21

No files matched your search

@@ -960,6 +960,26 @@ func TestSaveMetadataBlobKeepsATableDirectoryCreatedSinceTheLookup(t *testing.T)
}
}
// A stage-create marker write keeps the attributes of a directory on its path
// that another writer created after the marker's lookup missed it.
func TestStageCreateMarkerKeepsADirectoryCreatedSinceTheLookup(t *testing.T) {
e := newConflictEnv(t)
bucketDir := path.Join(s3tables.TablesPath, conflictBucket)
attrs := map[string][]byte{"probe": []byte("kept")}
e.hooks.beforeCreate = func(req *filer_pb.CreateEntryRequest) {
if req.Directory == bucketDir && req.Entry.Name == stageCreateMarkerDirName {
e.hooks.beforeCreate = nil
e.filer.Put(bucketDir, stageCreateMarkerDirName, attrs)
}
}
if err := e.server.writeStageCreateMarker(t.Context(), conflictBucket, []string{conflictNamespace}, conflictTable, uuid.New(), conflictLocation, ""); err != nil {
t.Fatalf("write stage-create marker: %v", err)
}
if got := e.filer.Get(bucketDir, stageCreateMarkerDirName); got == nil || string(got.Extended["probe"]) != "kept" {
t.Errorf("directory replaced by the marker's directory create: %+v", got)
}
}
// Two stage-create commits for one name: one creates the table and the other is
// told it lost, and the file the catalog points at belongs to the winner.
func TestConcurrentFinalizeCreateOnCommitHasOneWinner(t *testing.T) {
+1
View File
@@ -191,6 +191,7 @@ func (s *Server) writeStageCreateMarker(ctx context.Context, bucketName string,
resp, createErr := client.CreateEntry(opCtx, &filer_pb.CreateEntryRequest{
Directory: parent,
OExcl: true,
Entry: &filer_pb.Entry{
Name: name,
IsDirectory: true,