-
Notifications
You must be signed in to change notification settings - Fork 465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adapter: Switch from GlobalId
to CatalogItemId
#30189
adapter: Switch from GlobalId
to CatalogItemId
#30189
Conversation
af814eb
to
64bad48
Compare
MitigationsCompleting required mitigations increases Resilience Coverage.
Risk Summary:The pull request has a high-risk score of 83, driven by predictors such as the average line count in files and executable lines within files. Historically, PRs with these predictors are 157% more likely to cause a bug compared to the repo baseline. Additionally, 10 files modified in this PR are recent bug hotspots. Note: The risk score is not based on semantic analysis but on historical predictors of bug occurrence in the repository. The attributes above were deemed the strongest predictors based on that history. Predictors and the score may change as the PR evolves in code, time, and review activity. Bug Hotspots:
|
Nightly run triggered: https://buildkite.com/materialize/nightly/builds/10190 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm about 8 commits deep, but thought I'd leave my comments so far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not done, I have 3-4 commits left, but here's another batch of comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I made it through all the commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the term "Global ID" a user facing concept? If so we should consider updating the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe so! Excluding developer design docs, there isn't any mention of global ids in our documentation
@jkosh44 Responded to most of the comments, planning to take a second pass and push up more changes, will let you know when the PR is ready for a second look! |
@jkosh44 this should be ready for a second look, just the two most recent commits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
b9a86a0
to
c78ef44
Compare
* Updates the memory/objects.rs types to fully use CatalogItemId * Update the durable Catalog Transaction type, and its methods to use CatalogItemId * Changes the User and System ID allocators to return both a CatalogItemId and a GlobalId in-memory objects 5
* Update Catalog Transaction APIs to support builtin objects * Update builtin items migration to use CatalogItemId * Update open/startup paths to use CatalogItemId
* Updates name resolution to track a BTreeMap<CatalogItemId, BTreeSet<GlobalId>> * Update callsites to access resolved IDs via methods instead of reaching into the ResolvedIds newtype
* Add a map of GlobalId to CatalogItemId to CatalogState * refactor try_get_item(...) and get_item(...) Catalog APIs to use CatalogItemId * add try_get_item_by_global_id(...) and get_item_by_global_id(...) APIs * add CatalogCollectionItem trait, move desc(...) -> RelationDesc method from CatalogItem to this new trait
* update the APIs on the OptimizerCatalog to support both CatalogItemIds and GlobalIds
* For Views, MaterializedViews, and ContinualTasks track a set of dependencies, which is separate from resolved_ids * Used for the CatalogEntry::uses(...) method
* use the new Catalog APIs and update the Coordintator's startup/bootstrap code path
* Update Create plans for Source, View, MaterializedView, ContinualTask, Sink, Table, and Connection to use CatalogItemId and include a GlobalId
* update plans and sequencing for COPY and INSERT plans
* update plans for Dropping objects * update Catalog Transactions
* update planning and sequencing for Alter* plans * update Catalog transaction handling for Alter* plans
* small changes to support COMMENT ON and Webhook sources
* update planning and sequencing for Peeks and Subscribes * update timestamp and timedomain logic
* update planning and sequencing for EXPLAIN plans
* this is a bit of a grab-bag commit, but is everything to do with cluster routing, scheduling, and caught up detection
* Updates List, Map, and Record variants of ScalarType to reference CatalogItemId
* updates all pack_* methods to use CatalogItemId
* fixup a legit bug when bootstrapping storage collections * refactor some codepaths * fix clippy
* make Catalog timeline APIs use CatalogItemId instead of GlobalId * update comment describing TODO * remove use<'_> until we rebase the PR
* mostly making changes after the removal of the global write lock * small changes here and there
* previously I refactored the timeline context methods in the Catalog to use CatalogItemId, some of them need to use GlobalId because they're called with Transient dataflows, e.g. Peeks
…'t know any better'
1788883
to
6458a38
Compare
`buf` is a bit aggressive in what it considers breaking. Some changes I merged in #30189 were not wire breaking but `buf` thought they were. To prevent needing a force push to main I marked them as temporarily ignored for breaking changes, this PR unignores them. ### Motivation Re-enable protobuf linting on temporarily ignored files. ### Checklist - [x] This PR has adequate test coverage / QA involvement has been duly considered. ([trigger-ci for additional test/nightly runs](https://trigger-ci.dev.materialize.com/)) - [x] This PR has an associated up-to-date [design doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md), is a design doc ([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)), or is sufficiently small to not require a design. <!-- Reference the design in the description. --> - [x] If this PR evolves [an existing `$T ⇔ Proto$T` mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md) (possibly in a backwards-incompatible way), then it is tagged with a `T-proto` label. - [x] If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label ([example](MaterializeInc/cloud#5021)). <!-- Ask in #team-cloud on Slack if you need help preparing the cloud PR. --> - [x] If this PR includes major [user-facing behavior changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note), I have pinged the relevant PM to schedule a changelog post.
This PR switches the Adapter/Catalog from referencing items with a
GlobalId
, to aCatalogItemId
.Internally the compute and storage layers of Materialize will still reference objects by their
GlobalId
, but conceptually aGlobalId
refers to a "collection of data", while aCatalogItemId
refers to the database object. This switch allows us to associate multipleGlobalId
s (aka "collections of data") with a single Catalog object. The primary motivator for this is supporting live schema migrations, orALTER TABLE ... ADD COLUMN ...
.When adding a new column to a table we'll create a new
GlobalId
, this ensures that the schema (akaRelationDesc
) associated with aGlobalId
never changes.Design
The durable Catalog migration to add
CatalogItemId
took place in #30163.What took a bit of thought is where to place the associated
GlobalId
s for each object, we have the following requirements:Table
: multipleGlobalId
sSource
: singleGlobalId
(maybe eventually multiple?)Log
: singleGlobalId
View
: singleGlobalId
MaterializedView
: singleGlobalId
ContinualTask
: singleGlobalId
Sink
: singleGlobalId
Index
: singleGlobalId
Type
: noGlobalId
sFunc
: noGlobalId
sSecret
: noGlobalId
sConnection
: noGlobalId
sType
,Func
,Secret
, andConnection
are never referenced by the compute and storage layer so they don't need aGlobalId
. MeanwhileTable
s can be evolved so they need to support multipleGlobalId
s. What complicates this a bit is how we use thecreate_sql
for an object as our durable record, while we could come up with some syntax likeCREATE TABLE [<name> WITH u1 u2 u3] ...
as a way to associate multipleGlobalId
s with an object, this didn't feel great.What I landed on was persisting a single
GlobalId
for all objects, and then including anextra_versions: BTreeMap<Version, GlobalId>
at the durable layer. While not all types need aGlobalId
, associating a singleGlobalId
for each object makes things easier to reason about. And while I would like to "design away invalid states", trying to associate multipleGlobalId
s with only tables added a bunch of boilerplate which I didn't think was worth it.But at the in-memory layer is where we enforce only
Table
s can have multipleGlobalId
s. Instead of sticking aglobal_id: GlobalId
field on CatalogEntry, which might feel natural, I put them on the innerenum CatalogItem
variants. If a caller has just aCatalogEntry
, they're forced to reason about their item possibly having multipleGlobalId
s associated with it. But if they match on the innerCatalogItem
they can get the inner object and generally get the singleGlobalId
, or if it's a table, reason about whichGlobalId
to use.Motivation
Implements the approach described in: #30019
Progress towards: https://github.com/MaterializeInc/database-issues/issues/8233
Tips for reviewer
I tried splitting up this PR into multiple smaller ones, but the amount of shimming required to convert back and forth between
GlobalId
andCatalogItemId
made the changes very noisy. As such, I split this single PR into multiple commits where each commit migrates a single logical code path.Commits that require the most attention are annotated with a ⭐, and tagged by the teams most directly impacted.
Connection
s andSecret
s to useCatalogItemId
. This doesn't require much attention, it's largely just a find and replace since these objects are only ever referenced by the Catalog.GlobalId
per-object, forTable
s we store multipleGlobalId
s. To review this commit I would start by looking atsrc/catalog/src/memory/objects.rs
to get an understanding of whereGlobalId
s live and how the individual objects were updated. It also updates our durable Catalog transactions to remove the shims introduced in alter_table: Durable Catalog Migration #30163. What's subtle here is we also change theallocate_user_item_ids(...)
API to return both aCatalogItemId
andGlobalId
with the same inner value. This ensures that that string representation of aCatalogItemId
for an object will always be the same as theGlobalId
, this allows us to sidestep the issue for now of updating builtin tables to map betweenCatalogItemId
andGlobalId
CatalogItemId
and aGlobalId
with a builtin object. Builtin objects are handled separately from normal objects, hence having to migrate the separate code path.CatalogItemId
. It also changes theResolvedIds
newtype from aBTreeSet<GlobalId>
to aBTreeMap<CatalogItemId, BTreeSet<GlobalId>>
. This way after name resolution we not only know what objects a statement refers to, but also their underlying collections. This also makes the inner field ofResolvedIds
private and migrates its callsites.GlobalId
, and adds a new trait calledCatalogCollectionItem
. I would start reviewing this commit by looking atsrc/sql/src/catalog.rs
to get an idea of the API surface.CatalogCollectionItem
is really only necessary to supportALTER TABLE
and isn't strictly necessary for this change, but I found that it adds context to the change. Thedesc(...)
method is removed fromtrait CatalogItem
and moved totrait CatalogCollectionItem
. You can only get aCatalogCollectionItem
(and thusRelationDesc
) if you have aGlobalId
or aCatalogItemId
+Version
.trait OptimizerCatalog
to allow getting an item by aCatalogItemId
, and updates implementations to use new Catalog APIs. This commit is small and only needs to be skimmed.DependencyIds
field on some Catalog items.ResolvedIds
are derived from name resolution, meanwhileDependencyIds
are derived from theHirRelationExpr
created after planning.CatalogEntry::uses
method wants to return a list ofCatalogItemId
s, but theHirRelationExpr
only knows aboutGlobalId
s. We could map fromGlobalId
->CatalogItemId
when calling the method, but this was a decent refactor on it's own, so I opted to cache these dependencies during planning on the few types of objects that need them.entry.id()
tomat_view.global_id()
.PlanCreate*
) to associate aGlobalId
with each item.COPY
andINSERT
to useCatalogItemId
instead ofGlobalId
, since we also want to insert into collections at their latest version. This commit is largely a find and replace and can be skimmed.PlanDrop*
) to useCatalogItemId
, this is pretty much a find and replace and can be skimmed.PlanAlter*
) to useCatalogItemId
, this is pretty much a find and replace and can be skimmed.COMMENT ON
and Webhook Sources to useCatalogItemId
. This is a fairly small commit and can definitely be skimmed.CatalogItemId
. This commit is interesting and could use some extra thought since it's where we map from a catalog item to it's collection, and is one of the primary motivators of this work.SHOW
andINSPECT
plans to useCatalogItemId
. This commit is quite small and can be skimmed.PlanValidity
to useCatalogItemId
. This commit is quite small and can be skimmed.EXPLAIN
plans to use the newGlobalId
-based Catalog APIs. It's pretty straight forward and probably doesn't require too much attention.mz_catalog_server
, cluster scheduling, and "caught up" checks to map betweenCatalogItemId
andGlobalId
. It could use a bit of extra attention.ScalarType
s to useCatalogItemId
instead ofGlobalId
.ScalarType
s in the Persist schema registry. This change should be okay though since the protobuf type ofCatalogItemId
is exactly the same asGlobalId
(minus theExplain
variant) so it is wire compatible.pack_*
method) to use
CatalogItemId`.GlobalId::to_item_id
andCatalogItemId::to_global_id
shim methods.Checklist
$T ⇔ Proto$T
mapping (possibly in a backwards-incompatible way), then it is tagged with aT-proto
label.