feat(snix/{castore,store}): Upgrade all redb file formats

In version 2.6.0 of redb a new file format was released. It will end up
being the only supported format in version 3.0.0. With this change we
prepare for v3 by migrating all databases to the new format.

Change-Id: I297a7d70e00e872d9354d1fc7acb277c83d76c71
Reviewed-on: https://cl.snix.dev/c/snix/+/30661
Autosubmit: Ilan Joselevich <personal@ilanjoselevich.com>
Tested-by: besadii
Reviewed-by: Florian Klink <flokli@flokli.de>
This commit is contained in:
Ilan Joselevich 2025-08-05 23:40:16 +02:00 committed by clbot
parent bd4c4bb5f0
commit 189cb17e34
3 changed files with 32 additions and 8 deletions

View file

@ -3,7 +3,7 @@ use prost::Message;
use redb::{Database, TableDefinition};
use std::{path::PathBuf, sync::Arc};
use tonic::async_trait;
use tracing::{instrument, warn};
use tracing::{info, instrument, warn};
use super::{
Directory, DirectoryGraph, DirectoryPutter, DirectoryService, LeavesToRootValidator,
@ -41,7 +41,15 @@ impl RedbDirectoryService {
}
let db = tokio::task::spawn_blocking(|| -> Result<_, redb::Error> {
let db = redb::Database::create(path)?;
let mut db = redb::Database::builder()
.create_with_file_format_v3(true)
.create(path)?;
// Upgrade redb database file format.
if db.upgrade()? {
info!("Upgraded database format");
};
create_schema(&db)?;
Ok(db)
})
@ -55,8 +63,9 @@ impl RedbDirectoryService {
/// Constructs a new instance using the in-memory backend.
pub fn new_temporary() -> Result<Self, Error> {
let db =
redb::Database::builder().create_with_backend(redb::backends::InMemoryBackend::new())?;
let db = redb::Database::builder()
.create_with_file_format_v3(true)
.create_with_backend(redb::backends::InMemoryBackend::new())?;
create_schema(&db)?;

View file

@ -125,6 +125,12 @@ impl From<redb::CommitError> for Error {
}
}
impl From<redb::UpgradeError> for Error {
fn from(value: redb::UpgradeError) -> Self {
Error::StorageError(value.to_string())
}
}
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
if value.kind() == std::io::ErrorKind::InvalidInput {

View file

@ -11,7 +11,7 @@ use snix_castore::{
use std::{path::PathBuf, sync::Arc};
use tokio_stream::wrappers::ReceiverStream;
use tonic::async_trait;
use tracing::{instrument, warn};
use tracing::{info, instrument, warn};
const PATHINFO_TABLE: TableDefinition<[u8; 20], Vec<u8>> = TableDefinition::new("pathinfo");
@ -40,7 +40,15 @@ impl RedbPathInfoService {
}
let db = tokio::task::spawn_blocking(|| -> Result<_, redb::Error> {
let db = redb::Database::create(path)?;
let mut db = redb::Database::builder()
.create_with_file_format_v3(true)
.create(path)?;
// Upgrade redb database file format.
if db.upgrade()? {
info!("Upgraded database format");
};
create_schema(&db)?;
Ok(db)
})
@ -54,8 +62,9 @@ impl RedbPathInfoService {
/// Constructs a new instance using the in-memory backend.
pub fn new_temporary(instance_name: String) -> Result<Self, Error> {
let db =
redb::Database::builder().create_with_backend(redb::backends::InMemoryBackend::new())?;
let db = redb::Database::builder()
.create_with_file_format_v3(true)
.create_with_backend(redb::backends::InMemoryBackend::new())?;
create_schema(&db)?;