sodonnel commented on PR #10822:
URL: https://github.com/apache/ozone/pull/10822#issuecomment-5410939443

   An idea I had a long time back, is that a versioned bucket effectively gives 
you infinite snapshots.
   
   If you have the ability to read a bucket "as of" a given time and filter out 
all the future and past versions, then you can effectively get a consistent 
read on a bucket and it is almost exactly like a snapshot.
   
   I like in this design how the current key table and the versioned key tabled 
are separate. Keeping them as the same table with a row per version would 
result in a listing of the current state being slowed by all the old versions. 
Having a single row for all versions would result in large values which would 
be even more problematic. Having the version in the key is important too, as it 
allows versions we don't care about to be filtered out without deserializing 
the full value, which is slow.
   
   One thing I am trying to think through - if we wanted to have the ability to 
read the bucket as of some previous point in time how would that look and are 
there any changes we may want to make to this design to make that possible, or 
easier if we later add that?
   
   Lets say you wanted to "snapshot" a versioned bucket using this idea (not 
the current snapshot implementation). What would that mean?
   
   If we have a monotonically increasing version ID then all you need to so is 
store the last version_Id somewhere and give it a name:
   
   eg `snapshot versions_bucket_name, daily-backup-2026-08-01`
   
   Then anything that wants to use that snapshot has to use a special version 
of some list / read API (that does not exist right now) that filters out 
anything that happened later than version_x. This would just be a scan over the 
prefix and as we read each row take the latest version of any key which is 
before the version we care about, and skip any version which is later. Such a 
listing could be somewhat expensive, but it would be fairly simple to code and 
potentially quite useful.
   
   Even the snapshot itself isn't really needed it could just be a name 
attached to a specific version_id. If you have the ability to get the version 
of some key you wrote and want to see the state of things at that point in 
time, you just need to use the same list API to list out keys "as of" that 
version.
   
   If the version_Id is time based, as I saw discussed in some of the comments, 
there is a possibility to say "show me the state of this bucket as of 5pm 
yesterday" and it would just work, after adjusting for timezones etc.
   
   One small complication of this approach is that we would need to scan two 
tables and merge the results, which is slow and tricky code. Reading the table 
"as of version x" for any key, a version younger than X might be in the key 
table or the versioned key table.
   
   I feel this is a simpler problem if someone does a point lookup on key1-v123 
- where do we look for it? It may be in the current or the versioned table, as 
we don't know if its the most recent version or not.
   
   What if the design was modified to have the versioned table holding all 
versions of the key, even the current one? Would it make the point lookup on a 
version faster and easier (always just read from versioned table for point 
lookups that include a version). That would mean for a put we would do a double 
write, but wouldn't need to worry about migrating a record from current to 
versioned. Same for deletes I think - the tombstone would just go to both 
tables. One complication is moving a table from non-versioned with existing 
data to versioned. In that case, the versioned table would not have all the 
original data. This could be solved with a limitation on how the bucket get 
created. If you want to have the "list as of" feature, the bucket must have 
been versioned when it was created.
   
   One thing about using versioned tables in this way - we probably need to 
ability to prevent deletes of older versions so that the older versions are 
effectively immutable, except for some retention time. You would also not be 
able to suspend versioning are the history would be incomplete.
   
   Just to be clear, we don't need to add this sort of stuff to this design 
now. These are ideas that we might want, as if we can ensure the design now 
would support them without rework, then it would be nice.
   
   Would it make sense to ensure that the versioned table has all keys? I think 
it changes this design sightly, but I think the overhead is and complexity is 
largely the same - we are skipping a migration on new version write, but 
writing the same key twice to two tables instead.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to