pub enum MetadataEntry {
Show 21 variants
CatalogDdl {
payload: Vec<u8>,
},
CatalogDdlAudited {
payload: Vec<u8>,
auth_user_id: String,
auth_user_name: String,
sql_text: String,
},
Batch {
entries: Vec<MetadataEntry>,
},
DdlPrepared {
token: u64,
entry: Box<MetadataEntry>,
},
DdlPrepareAcquire {
token: u64,
},
DdlPrepareRelease {
token: u64,
},
TopologyChange(TopologyChange),
RoutingChange(RoutingChange),
ClusterVersionBump {
from: u16,
to: u16,
},
DescriptorLeaseGrant(DescriptorLease),
DescriptorLeaseRelease {
node_id: u64,
descriptor_ids: Vec<DescriptorId>,
},
DescriptorDrainStart {
descriptor_id: DescriptorId,
up_to_version: u64,
expires_at: Hlc,
},
DescriptorDrainEnd {
descriptor_id: DescriptorId,
},
CaTrustChange {
add_ca_cert: Option<Vec<u8>>,
remove_ca_fingerprint: Option<[u8; 32]>,
},
SyncProducerRegister {
lite_id: String,
producer_id: u64,
tenant_id: u64,
epoch: u64,
created_ms: i64,
},
SyncProducerFence {
lite_id: String,
new_epoch: u64,
},
SurrogateAlloc {
hwm: u32,
},
SurrogateReserve {
node_id: u64,
request_id: u64,
batch_size: u32,
},
JoinTokenTransition {
token_hash: [u8; 32],
transition: JoinTokenTransitionKind,
ts_ms: u64,
},
MigrationCheckpoint {
migration_id: String,
phase: MigrationPhaseTag,
attempt: u32,
payload: MigrationCheckpointPayload,
crc32c: u32,
ts_ms: u64,
},
MigrationAbort {
migration_id: String,
reason: String,
compensations: Vec<Compensation>,
},
}Expand description
An entry in the replicated metadata log.
Every mutation to cluster-wide state — DDL, topology, routing,
descriptor leases, cluster version bumps — is encoded as one of
these variants, proposed against the metadata Raft group, and
applied on every node by a
crate::metadata_group::applier::MetadataApplier.
The CatalogDdl variant is the single wire shape for every DDL
mutation. Its payload is an opaque, host-serialized
nodedb::control::catalog_entry::CatalogEntry value — the
nodedb-cluster crate is deliberately ignorant of the host’s
per-DDL-object struct shapes. This keeps the cluster crate
layering-clean and makes adding new DDL object types on the
host side a zero-wire-change operation.
Variants§
CatalogDdl
Single generic DDL entry carrying an opaque host-side payload.
Produced by every pgwire DDL handler via
nodedb::control::metadata_proposer::propose_catalog_entry.
CatalogDdlAudited
DDL entry with attached audit context. Produced by pgwire DDL
handlers that have the authenticated identity + raw statement
text bound at the call site (every CREATE, ALTER, DROP,
GRANT, REVOKE path). Applied identically to CatalogDdl
on every node; additionally, the production applier fsync-
appends an audit record to the audit segment WAL with the
authenticated user, HLC at commit, descriptor versions before
- after, and the raw SQL — exactly what J.4 requires.
Carries its own payload so legacy proposers (internal lease
and descriptor-drain flows that have no SQL text) can keep
using the plain CatalogDdl variant without synthesizing
fake audit context.
Fields
Batch
Atomic batch of metadata entries proposed by a transactional
DDL session (BEGIN; CREATE ...; CREATE ...; COMMIT;). The
applier unpacks and applies each sub-entry in order at a
single raft log index, so either all commit or none do.
Fields
entries: Vec<MetadataEntry>DdlPrepared
A catalog DDL proposal fenced by the replicated preparation owner.
Appliers execute entry only while token is the current owner;
superseded proposals are deterministic no-ops so they cannot wedge the
Raft apply watermark.
DdlPrepareAcquire
Acquire the replicated global descriptor-preparation lease. The first unexpired owner wins; contenders observe the winner after this entry is applied and retry after its matching release or expiry.
DdlPrepareRelease
Release the descriptor-preparation lease iff token still owns it.
TopologyChange(TopologyChange)
RoutingChange(RoutingChange)
ClusterVersionBump
DescriptorLeaseGrant(DescriptorLease)
DescriptorLeaseRelease
DescriptorDrainStart
Begin draining leases on a descriptor. While a drain entry
is active, any acquire_descriptor_lease at
version <= up_to_version must be rejected cluster-wide so
the in-flight DDL that bumps the version can make progress.
expires_at is the HLC at which this drain entry is
considered stale and ignored by is_draining checks on
read. Acts as a TTL that prevents a crashed proposer from
leaving an orphaned drain that blocks the cluster forever.
DescriptorDrainEnd
End draining on a descriptor. Emitted explicitly on drain
timeout so the cluster can make progress. On the happy
path (successful Put* apply), the host-side applier
clears drain implicitly — this variant is the escape
hatch for the failure path.
Fields
descriptor_id: DescriptorIdCaTrustChange
Cluster-wide CA trust mutation (L.4). Proposed by
nodedb rotate-ca --stage (to add a new CA) and
nodedb rotate-ca --finalize --remove <fp> (to drop an old
CA). Applied on every node by MetadataCommitApplier: writes
or deletes data_dir/tls/ca.d/<fp_hex>.crt and triggers a
live rebuild of the rustls server + client configs so the
new trust set takes effect without restart.
add_ca_cert and remove_ca_fingerprint are independent:
the --stage form sets add_ca_cert = Some(new_ca_der) +
remove_ca_fingerprint = None; --finalize flips both. A
single entry carrying both performs the cutover atomically
once the operator has confirmed every node has reissued.
Fields
SyncProducerRegister
Replicate a new Lite client registration to every node.
On apply every node writes the same registration row verbatim and
advances its producer-id allocator HWM to at least producer_id, so
a future leader never reissues the same id after a failover. The
producer_id and initial epoch are assigned by the leader before
proposing, so all replicas store identical state.
Applied host-side only; the cluster cache tracks the applied index.
SyncProducerFence
Replicate a fencing epoch advance to every node.
Applied with max-wins semantics: each node sets
current_epoch = max(stored_epoch, new_epoch) so out-of-order
or duplicate delivery cannot roll the epoch backwards. A fence
entry with no prior register row is a no-op on that node
(tolerated for reordering/missing idempotency).
Applied host-side only; the cluster cache tracks the applied index.
SurrogateAlloc
Advance the cluster-wide surrogate high-watermark to hwm.
Proposed by the metadata-group leader whenever the local
SurrogateRegistry flush threshold trips (every 1024
allocations or 200 ms, whichever comes first). Applied on
every node by the host-side MetadataCommitApplier which
calls SurrogateRegistry::restore_hwm(hwm) — idempotent and
monotonic, so out-of-order replay or duplicate delivery are
both safe. Followers must never allocate surrogates locally;
they only advance their in-memory HWM via these log entries.
SurrogateReserve
Reserve a disjoint batch of surrogates for one node (HiLo).
The carved [start, end) range is not carried in the entry:
it is computed AT APPLY by advancing the cluster-wide surrogate
global watermark on every node. Because every node applies the
metadata log in the same order against an identical watermark,
all nodes deterministically agree on which range this reservation
carves — guaranteeing globally-unique, disjoint surrogate batches
without any node ever minting a value another node also minted.
node_id + request_id identify the requesting node and the
specific in-flight reservation so the owning node’s host-side
applier can (a) install the carved batch locally and (b) fire the
completion signal that unblocks the waiting allocation path. Only
the owning node installs the batch; every other node merely
advances the watermark so future reservations stay disjoint.
JoinTokenTransition
Join-token lifecycle transition (L.4). Proposed by the bootstrap-listener handler on every state change so that all Raft peers can enforce single-use token semantics even after a crash-restart cycle.
token_hash is the SHA-256 of the token hex string — the raw
token is never stored in the log. transition encodes the
direction: Register for first issuance, BeginInFlight when
a joiner presents the token, MarkConsumed when the bundle is
delivered, RevertInFlight when the dead-man timer fires, and
MarkExpired / MarkAborted for the terminal states.
Fields
transition: JoinTokenTransitionKindMigrationCheckpoint
Crash-safe migration phase checkpoint. Persisted on every phase
transition; on coordinator restart, recovery scans the
MigrationStateTable and resumes from the latest committed
checkpoint. Apply is idempotent on (migration_id, phase, attempt)
— duplicate delivery is a no-op. CRC32C mismatch is fatal.
MigrationAbort
Replicated migration abort with ordered compensations. Each
compensation is applied in order; any failure is fatal (no
warn-and-continue). On success, the migration’s row in
MigrationStateTable is deleted.
Trait Implementations§
Source§impl Clone for MetadataEntry
impl Clone for MetadataEntry
Source§fn clone(&self) -> MetadataEntry
fn clone(&self) -> MetadataEntry
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for MetadataEntry
impl Debug for MetadataEntry
Source§impl<'de> Deserialize<'de> for MetadataEntry
impl<'de> Deserialize<'de> for MetadataEntry
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for MetadataEntry
Source§impl<'__msgpack_de> FromMessagePack<'__msgpack_de> for MetadataEntry
impl<'__msgpack_de> FromMessagePack<'__msgpack_de> for MetadataEntry
Source§impl PartialEq for MetadataEntry
impl PartialEq for MetadataEntry
Source§impl Serialize for MetadataEntry
impl Serialize for MetadataEntry
impl StructuralPartialEq for MetadataEntry
Auto Trait Implementations§
impl Freeze for MetadataEntry
impl RefUnwindSafe for MetadataEntry
impl Send for MetadataEntry
impl Sync for MetadataEntry
impl Unpin for MetadataEntry
impl UnsafeUnpin for MetadataEntry
impl UnwindSafe for MetadataEntry
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
impl<T> FromMessagePackOwned for Twhere
T: for<'a> FromMessagePack<'a>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.