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]
