feat(lsm): move catch-up activation to an explicit API

This commit is contained in:
XYZhan
2026-08-10 09:09:39 -04:00
parent f75279b69f
commit 41e0161067
2 changed files with 54 additions and 4 deletions
+25
View File
@@ -662,6 +662,15 @@ pub trait BaseTable: std::fmt::Display + std::fmt::Debug + Send + Sync {
message: "set_lsm_write_spec is not supported on this table type".into(),
})
}
/// Switch this table to required index catch-up, one way.
///
/// The default implementation returns `NotSupported`. Implementations
/// that support the MemWAL LSM write path must override this.
async fn require_mem_wal_index_catchup(&self) -> Result<()> {
Err(Error::NotSupported {
message: "require_mem_wal_index_catchup is not supported on this table type".into(),
})
}
/// Remove the [`LsmWriteSpec`] from this table.
///
/// This is a no-op if no spec is currently set.
@@ -1697,6 +1706,18 @@ impl Table {
self.inner.set_lsm_write_spec(spec).await
}
/// Switch this table to required index catch-up, one way.
///
/// Separate from [`Self::set_lsm_write_spec`] on purpose: a table carrying
/// the bit retains its SSTables until an index records that it holds the
/// compacted rows, so turn it on only once something can repair coverage.
///
/// Errors if no spec is set, or if the table already records SSTable
/// compaction progress from before this protocol.
pub async fn require_mem_wal_index_catchup(&self) -> Result<()> {
self.inner.require_mem_wal_index_catchup().await
}
/// Remove the [`LsmWriteSpec`] from this table, reverting to the standard
/// `merge_insert` write path.
///
@@ -3147,6 +3168,10 @@ impl BaseTable for NativeTable {
merge::lsm::set_lsm_write_spec(self, spec).await
}
async fn require_mem_wal_index_catchup(&self) -> Result<()> {
merge::lsm::require_mem_wal_index_catchup(self).await
}
async fn unset_lsm_write_spec(&self) -> Result<()> {
merge::lsm::unset_lsm_write_spec(self).await
}
+29 -4
View File
@@ -114,10 +114,35 @@ pub(crate) async fn set_lsm_write_spec(table: &NativeTable, spec: LsmWriteSpec)
builder = builder.add_writer_config_default(key, value);
}
builder.execute().await?;
// Require recorded index catch-up from the moment WAL is turned on, while
// the table is provably clean: no SSTable has been compacted, so there is
// no unvalidated progress to inherit, and the migration never has to be run
// against a table already in flight.
table.dataset.update(dataset);
Ok(())
}
// =============================================================================
// require_mem_wal_index_catchup
// =============================================================================
/// Switch this table to required index catch-up, one way.
///
/// Deliberately **not** part of installing the write spec. Until something can
/// actually repair coverage, a table carrying the bit reports every index as
/// not known to hold the compacted rows, so its SSTables are retained
/// indefinitely -- and the WAL pod trims on the legacy rule meanwhile, leaving
/// readers pointed at files that are gone. Turn this on only once remote
/// maintenance owns the merge and the repair for the table.
///
/// Lance refuses the activation if the table already records SSTable
/// compaction progress: those numbers predate this protocol and cannot be
/// validated, so such a table must be drained rather than activated.
#[allow(clippy::redundant_pub_crate)]
pub(crate) async fn require_mem_wal_index_catchup(table: &NativeTable) -> Result<()> {
table.dataset.ensure_mutable()?;
let mut dataset = (*table.dataset.get().await?).clone();
if dataset.mem_wal_index_details().await?.is_none() {
return Err(Error::InvalidInput {
message: "require_mem_wal_index_catchup: no LSM write spec is set on this table".into(),
});
}
dataset.require_mem_wal_index_catchup().await?;
table.dataset.update(dataset);
Ok(())