GH-maggio commented on issue #11108:
URL: https://github.com/apache/gravitino/issues/11108#issuecomment-5804317004

   Additionally, this closes a silent data-loss window for Lance writers on 
S3-compatible gateways, ie versitygw.
   
   ### The dependency today
   
   With `namespace-backend: gravitino`, Lance clients resolve tables through the
   namespace but commit through the object store. For an `s3://` location,
   `commit_handler_from_url` selects `ConditionalPutCommitHandler`
   unconditionally — no capability probe, no fallback — and that handler's
   `put_opts(..., PutMode::Create)` (`If-None-Match: *`) is the **sole** 
arbiter of
   who wins a version. `AlreadyExists`/`Precondition` becomes `CommitConflict`;
   anything else is treated as a successful commit.
   
   So correctness rests entirely on the object store enforcing put-if-absent.
   
   ### Where that breaks
   
   Not all S3 gateways enforce it across gateway processes. See
   [versity/versitygw#2359](https://github.com/versity/versitygw/pull/2359),
   "make conditional publish lock modes explicit" (merged 2026-09-11, not yet 
in a
   release; v1.8.0 is current). Its premise:
   
   > A successful flock call does not prove that property: some clustered
   > filesystem configurations accept flock but scope it to one node, silently
   > leaving cross-gateway check-and-publish races open.
   
   Measured this on an clustered fileset backing a
   multi-replica versitygw deployment, using pods pinned to different nodes:
   
   | Primitive | Same node | Cross node | Result |
   | --- | --- | --- | --- |
   | `flock` | denied | **acquired** (both directions) | not cluster-coherent |
   | `fcntl` byte-range | denied | denied (`EAGAIN`, both directions) | 
cluster-coherent |
   
   Controls: both pods verified to address the same inode, and an attempt from 
the
   holder's own node was denied on every round, so the lock was genuinely held 
and
   the harness was sound.
   
   Consequence for Lance: with a gateway that uses node-scoped locking, two
   concurrent writers to the same dataset can both pass the existence check and
   both publish the same manifest version. The later silently wins. Both clients
   report a successful commit and no conflict is raised — there is nothing to
   alert on. Lance already special-cases Tencent COS
   (`TencentCosCommitHandler`) for the same class of problem, but there is no 
way
   to detect it for a self-hosted gateway from the URI or storage options.
   
   ### Why this feature fixes it
   
   `CreateTableVersion` documents `put_if_not_exists` semantics with 409 
Conflict,
   which moves commit arbitration from the object store into the catalog. Once
   that path is used, gateway lock coherence stops mattering — the same reason
   Iceberg-on-JDBC is unaffected in the same deployment.
   
   The client side already appears complete: `namespace_manifest.rs` maps
   `put`/`get`/`get_latest_version` onto
   `create_table_version`/`describe_table_version`/`list_table_versions`, and
   `DatasetBuilder::from_namespace` installs `ExternalManifestCommitHandler` 
when
   `managed_versioning == Some(true)`. On the Gravitino side (1.3.0), the Lance
   REST server exposes `/v1/namespace` and `/v1/table/{id}` only, and
   `managed_versioning` appears solely in the generated client DTOs — so the
   remaining gap looks like the five version operations plus setting that flag 
in
   `describe_table`/`declare_table`.
   
   AI generated.


-- 
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]

Reply via email to