mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-13 15:29:12 +01:00
iceberg: create missing metadata parent directories exclusively
saveMetadataBlob created each missing directory on the way to the metadata directory with a plain CreateEntry after a lookup. A table directory another create had made and written its record onto since the lookup was replaced by a bare directory, erasing that record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
712af663d1
commit
03e2dbb40e
2 files changed
+23
-1
No files matched your search
@@ -940,6 +940,26 @@ func TestFinalizeCreateOnCommitLosesToTableWithoutLocation(t *testing.T) {
|
||||
e.assertWinnerRecord("", winnerUUID)
|
||||
}
|
||||
|
||||
// A table directory another create made and wrote its record onto after this
|
||||
// writer's lookup missed it keeps that record when a metadata file is staged.
|
||||
func TestSaveMetadataBlobKeepsATableDirectoryCreatedSinceTheLookup(t *testing.T) {
|
||||
e := newConflictEnv(t)
|
||||
namespaceDir := path.Join(s3tables.TablesPath, conflictBucket, conflictNamespace)
|
||||
record := `{"Name":"` + conflictTable + `"}`
|
||||
e.hooks.beforeCreate = func(req *filer_pb.CreateEntryRequest) {
|
||||
if req.Directory == namespaceDir && req.Entry.Name == conflictTable {
|
||||
e.hooks.beforeCreate = nil
|
||||
e.filer.Put(namespaceDir, conflictTable, map[string][]byte{s3tables.ExtendedKeyMetadata: []byte(record)})
|
||||
}
|
||||
}
|
||||
if err := e.server.saveMetadataBlob(t.Context(), conflictBucket, path.Join(conflictNamespace, conflictTable), "v1.metadata.json", []byte("{}"), "application/json", true, nil); err != nil {
|
||||
t.Fatalf("save metadata: %v", err)
|
||||
}
|
||||
if got := e.filer.Get(namespaceDir, conflictTable); got == nil || string(got.Extended[s3tables.ExtendedKeyMetadata]) != record {
|
||||
t.Errorf("table record replaced by the 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) {
|
||||
|
||||
@@ -68,9 +68,11 @@ func (s *Server) saveMetadataBlob(ctx context.Context, bucketName, tablePath, me
|
||||
return fmt.Errorf("lookup %s failed: %w", errorContext, err)
|
||||
}
|
||||
|
||||
// If lookup fails with ErrNotFound, try to create the directory.
|
||||
// Exclusive, so a directory created since the lookup keeps the
|
||||
// record a table create may have written onto it.
|
||||
resp, createErr := client.CreateEntry(opCtx, &filer_pb.CreateEntryRequest{
|
||||
Directory: parent,
|
||||
OExcl: true,
|
||||
Entry: &filer_pb.Entry{
|
||||
Name: name,
|
||||
IsDirectory: true,
|
||||
|
||||
Reference in new issue
Block a user