mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-10 00:07:44 +02:00
s3: commit a versioned PutObject and its latest pointer in one transaction (#9756)
* s3: commit a versioned PutObject and its latest pointer in one transaction A versioned PutObject wrote the version file and flipped the .versions latest pointer in two separate routed transactions. Fold the RECOMPUTE_LATEST into the version file's PUT so both commit atomically under the object's per-path lock: the recompute, applied after the PUT in the same transaction, scans the directory and sees the new version. A crash can no longer leave the version present with a stale pointer. putToFiler now takes a putFinalize describing the finalize step — routed mutations folded into the PUT, or an afterCreate run under the object write lock off the ring. Suspended-versioning keeps its afterCreate-only form; multipart, copy, and delete-marker finalizes are unchanged. * s3: trim verbose finalize comments
This commit is contained in:
1 parent
d806778757
commit
6b06fe5ec4
4 files changed
+127
-52
No files matched your search
@@ -158,19 +158,25 @@ func (s3a *S3ApiServer) objectTxnOnFiler(owner pb.ServerAddress, req *filer_pb.O
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// routedPut writes an object entry as a one-mutation ObjectTransaction on the
|
||||
// owner filer. lock_key is the object's full path so the transaction shares the
|
||||
// per-path lock with a concurrent create or delete of the same key.
|
||||
func (s3a *S3ApiServer) routedPut(owner pb.ServerAddress, routeKey, filePath string, entry *filer_pb.Entry, cond *filer_pb.WriteCondition) (*filer_pb.ObjectTransactionResponse, error) {
|
||||
// routedPut writes an entry as a PUT, optionally followed by finalize mutations,
|
||||
// as one ObjectTransaction applied in order under lockKey on the owner filer.
|
||||
// lockKey is normally the entry's own path; a versioned add instead passes the
|
||||
// object path plus a RECOMPUTE_LATEST finalize, so the version's PUT and its
|
||||
// .versions pointer flip commit atomically (the recompute scans .versions/ after
|
||||
// the PUT and sees the new version).
|
||||
func (s3a *S3ApiServer) routedPut(owner pb.ServerAddress, routeKey, lockKey, filePath string, entry *filer_pb.Entry, cond *filer_pb.WriteCondition, finalize []*filer_pb.ObjectMutation) (*filer_pb.ObjectTransactionResponse, error) {
|
||||
mutations := make([]*filer_pb.ObjectMutation, 0, 1+len(finalize))
|
||||
mutations = append(mutations, &filer_pb.ObjectMutation{
|
||||
Type: filer_pb.ObjectMutation_PUT,
|
||||
Directory: path.Dir(filePath),
|
||||
Entry: entry,
|
||||
})
|
||||
mutations = append(mutations, finalize...)
|
||||
return s3a.objectTxnOnFiler(owner, &filer_pb.ObjectTransactionRequest{
|
||||
LockKey: filePath,
|
||||
LockKey: lockKey,
|
||||
RouteKey: routeKey,
|
||||
Condition: cond,
|
||||
Mutations: []*filer_pb.ObjectMutation{{
|
||||
Type: filer_pb.ObjectMutation_PUT,
|
||||
Directory: path.Dir(filePath),
|
||||
Entry: entry,
|
||||
}},
|
||||
Mutations: mutations,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -193,7 +199,8 @@ func (s3a *S3ApiServer) routedMkFile(owner pb.ServerAddress, routeKey, parentDir
|
||||
if fn != nil {
|
||||
fn(entry)
|
||||
}
|
||||
resp, err := s3a.routedPut(owner, routeKey, parentDir+"/"+name, entry, nil)
|
||||
filePath := parentDir + "/" + name
|
||||
resp, err := s3a.routedPut(owner, routeKey, filePath, filePath, entry, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user