yuqi1129 opened a new issue, #13313:
URL: https://github.com/apache/gravitino/issues/13313

   ### Describe the proposal
   
   For non-managed catalogs (JDBC, Hive, Iceberg, Kafka, …) the underlying 
source is the source of truth and Gravitino keeps only a registration row per 
schema/table/view/topic/fileset to attach owners, tags, policies, audit 
information and properties. Registrations are kept in sync only on Gravitino's 
own write path. When an object is created, renamed or dropped directly in the 
source, nothing reconciles the registration:
   
   - A dropped schema stays live in `schema_meta`. `listSchemas` (store ∪ 
source) still returns it, `loadSchema` returns 404, and every consumer that 
walks the catalog (dashboard metrics, lineage, search sync) fails on it. See 
#13279 for the drop-side symptom ("a schema dropped in the source leaves a 
stale record that makes its whole catalog uncounted").
   - `TableOperationDispatcher` and `SchemaOperationDispatcher` deliberately 
preserve a registration when the source drop reports `false`, because a `false` 
is ambiguous between "renamed" and "dropped out of band" (see the comments in 
`dropTable`/`purgeTable`/`dropSchema`). A true out-of-band drop therefore 
always leaves a stale row.
   - The only cleanup that exists is best-effort and local to a drop call: 
`SchemaEntityCleaner.deleteOrphanedSchemaEntities` and an explicit 
`dropSchema(cascade = true)`.
   
   Consumers are starting to work around this individually (e.g. a metrics 
collector probing the source and deleting the row through 
`EntityStore.delete`). Such ad-hoc deletes bypass the dispatcher chain, so they 
skip secret cleanup, authorization-plugin privilege removal, `Drop*Event` 
emission (search index, audit, webhooks) and orphan cleanup, and when run from 
another process they race with concurrent creates because tree locks are per 
JVM.
   
   This epic is to design and build one reconciliation mechanism in the server:
   
   1. Define what "stale" means per entity type and how to confirm absence 
(explicit existence probe, never a listing alone, since listings can omit 
objects for permission reasons; distinguish source-unreachable from absent).
   2. Decide the trigger: a periodic server-side job, an on-demand 
`reconcile`/`sync` API per catalog or schema, or both; and the policy (report 
only, or report and remove).
   3. Perform removal through the dispatcher chain under the server's tree lock 
so events, secret cleanup, authorization plugins and orphan cleanup behave 
exactly as an explicit drop.
   4. Surface stale objects to users (API/UI) so an administrator can see and 
fix them before or instead of automatic removal.
   5. Make `list*` for non-managed catalogs stop reporting registrations that 
no longer exist in the source, or mark them, so list and load agree.
   
   ### Task list
   
   - [ ] Design doc: stale-registration semantics, absence confirmation, and 
trigger/policy options
   - [ ] Server-side reconcile for schemas (through `SchemaDispatcher`, with 
events and cleanup)
   - [ ] Extend reconcile to tables, views, topics and filesets
   - [ ] Expose stale registrations via API and surface them in the UI
   - [ ] Align `list*` behaviour for non-managed catalogs with reconcile results
   - [ ] #13279 `dropSchema(cascade = true)` reports `dropped: true` when it 
removes a stale registration
   


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