From 628119e31ecb3d140f47c63f39a4912e5ee68f4c Mon Sep 17 00:00:00 2001 From: Tamo Date: Wed, 5 Feb 2025 15:25:05 +0100 Subject: [PATCH 1/7] fix the dumpless upgrade potential corruption when upgrading from the v1.12 --- crates/index-scheduler/src/lib.rs | 2 +- crates/index-scheduler/src/versioning.rs | 28 ++++++--- crates/meilisearch-types/src/versioning.rs | 34 ++-------- crates/meilisearch/src/lib.rs | 72 ++++++++++++++++++++-- 4 files changed, 89 insertions(+), 47 deletions(-) diff --git a/crates/index-scheduler/src/lib.rs b/crates/index-scheduler/src/lib.rs index 0f8212470..3b61b5dc4 100644 --- a/crates/index-scheduler/src/lib.rs +++ b/crates/index-scheduler/src/lib.rs @@ -33,7 +33,7 @@ mod test_utils; pub mod upgrade; mod utils; pub mod uuid_codec; -mod versioning; +pub mod versioning; pub type Result = std::result::Result; pub type TaskId = u32; diff --git a/crates/index-scheduler/src/versioning.rs b/crates/index-scheduler/src/versioning.rs index f4c502b6f..aaf5224ff 100644 --- a/crates/index-scheduler/src/versioning.rs +++ b/crates/index-scheduler/src/versioning.rs @@ -1,6 +1,6 @@ use crate::{upgrade::upgrade_index_scheduler, Result}; use meilisearch_types::{ - heed::{types::Str, Database, Env, RoTxn, RwTxn}, + heed::{self, types::Str, Database, Env, RoTxn, RwTxn}, milli::heed_codec::version::VersionCodec, versioning, }; @@ -21,30 +21,38 @@ pub struct Versioning { } impl Versioning { - pub(crate) const fn nb_db() -> u32 { + pub const fn nb_db() -> u32 { NUMBER_OF_DATABASES } - pub fn get_version(&self, rtxn: &RoTxn) -> Result> { - Ok(self.version.get(rtxn, entry_name::MAIN)?) + pub fn get_version(&self, rtxn: &RoTxn) -> Result, heed::Error> { + self.version.get(rtxn, entry_name::MAIN) } - pub fn set_version(&self, wtxn: &mut RwTxn, version: (u32, u32, u32)) -> Result<()> { - Ok(self.version.put(wtxn, entry_name::MAIN, &version)?) + pub fn set_version( + &self, + wtxn: &mut RwTxn, + version: (u32, u32, u32), + ) -> Result<(), heed::Error> { + self.version.put(wtxn, entry_name::MAIN, &version) } - pub fn set_current_version(&self, wtxn: &mut RwTxn) -> Result<()> { + pub fn set_current_version(&self, wtxn: &mut RwTxn) -> Result<(), heed::Error> { let major = versioning::VERSION_MAJOR.parse().unwrap(); let minor = versioning::VERSION_MINOR.parse().unwrap(); let patch = versioning::VERSION_PATCH.parse().unwrap(); self.set_version(wtxn, (major, minor, patch)) } - /// Create an index scheduler and start its run loop. + /// Return `Self` without checking anything about the version + pub fn raw_new(env: &Env, wtxn: &mut RwTxn) -> Result { + let version = env.create_database(wtxn, Some(db_name::VERSION))?; + Ok(Self { version }) + } + pub(crate) fn new(env: &Env, db_version: (u32, u32, u32)) -> Result { let mut wtxn = env.write_txn()?; - let version = env.create_database(&mut wtxn, Some(db_name::VERSION))?; - let this = Self { version }; + let this = Self::raw_new(env, &mut wtxn)?; let from = match this.get_version(&wtxn)? { Some(version) => version, // fresh DB: use the db version diff --git a/crates/meilisearch-types/src/versioning.rs b/crates/meilisearch-types/src/versioning.rs index f009002d1..3e072a8e5 100644 --- a/crates/meilisearch-types/src/versioning.rs +++ b/crates/meilisearch-types/src/versioning.rs @@ -2,6 +2,8 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::Path; +use milli::heed; + /// The name of the file that contains the version of the database. pub const VERSION_FILE_NAME: &str = "VERSION"; @@ -9,36 +11,6 @@ pub static VERSION_MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR"); pub static VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR"); pub static VERSION_PATCH: &str = env!("CARGO_PKG_VERSION_PATCH"); -/// Persists the version of the current Meilisearch binary to a VERSION file -pub fn update_version_file_for_dumpless_upgrade( - db_path: &Path, - from: (u32, u32, u32), - to: (u32, u32, u32), -) -> Result<(), VersionFileError> { - let (from_major, from_minor, from_patch) = from; - let (to_major, to_minor, to_patch) = to; - - if from_major > to_major - || (from_major == to_major && from_minor > to_minor) - || (from_major == to_major && from_minor == to_minor && from_patch > to_patch) - { - Err(VersionFileError::DowngradeNotSupported { - major: from_major, - minor: from_minor, - patch: from_patch, - }) - } else if from_major < 1 || (from_major == to_major && from_minor < 12) { - Err(VersionFileError::TooOldForAutomaticUpgrade { - major: from_major, - minor: from_minor, - patch: from_patch, - }) - } else { - create_current_version_file(db_path)?; - Ok(()) - } -} - /// Persists the version of the current Meilisearch binary to a VERSION file pub fn create_current_version_file(db_path: &Path) -> io::Result<()> { create_version_file(db_path, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) @@ -112,6 +84,8 @@ pub enum VersionFileError { DowngradeNotSupported { major: u32, minor: u32, patch: u32 }, #[error("Database version {major}.{minor}.{patch} is too old for the experimental dumpless upgrade feature. Please generate a dump using the v{major}.{minor}.{patch} and import it in the v{VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_PATCH}")] TooOldForAutomaticUpgrade { major: u32, minor: u32, patch: u32 }, + #[error("Error while modifying the database: {0}")] + ErrorWhileModifyingTheDatabase(#[from] heed::Error), #[error(transparent)] IoError(#[from] std::io::Error), diff --git a/crates/meilisearch/src/lib.rs b/crates/meilisearch/src/lib.rs index cbd299f26..9b4ee25d6 100644 --- a/crates/meilisearch/src/lib.rs +++ b/crates/meilisearch/src/lib.rs @@ -32,6 +32,7 @@ use analytics::Analytics; use anyhow::bail; use error::PayloadError; use extractors::payload::PayloadConfig; +use index_scheduler::versioning::Versioning; use index_scheduler::{IndexScheduler, IndexSchedulerOptions}; use meilisearch_auth::AuthController; use meilisearch_types::milli::constants::VERSION_MAJOR; @@ -40,10 +41,9 @@ use meilisearch_types::milli::update::{IndexDocumentsConfig, IndexDocumentsMetho use meilisearch_types::settings::apply_settings_to_builder; use meilisearch_types::tasks::KindWithContent; use meilisearch_types::versioning::{ - create_current_version_file, get_version, update_version_file_for_dumpless_upgrade, - VersionFileError, VERSION_MINOR, VERSION_PATCH, + create_current_version_file, get_version, VersionFileError, VERSION_MINOR, VERSION_PATCH, }; -use meilisearch_types::{compression, milli, VERSION_FILE_NAME}; +use meilisearch_types::{compression, heed, milli, VERSION_FILE_NAME}; pub use option::Opt; use option::ScheduleSnapshot; use search_queue::SearchQueue; @@ -356,14 +356,19 @@ fn open_or_create_database_unchecked( /// Ensures Meilisearch version is compatible with the database, returns an error in case of version mismatch. /// Returns the version that was contained in the version file -fn check_version(opt: &Opt, binary_version: (u32, u32, u32)) -> anyhow::Result<(u32, u32, u32)> { +fn check_version( + opt: &Opt, + index_scheduler_opt: &IndexSchedulerOptions, + binary_version: (u32, u32, u32), +) -> anyhow::Result<(u32, u32, u32)> { let (bin_major, bin_minor, bin_patch) = binary_version; let (db_major, db_minor, db_patch) = get_version(&opt.db_path)?; if db_major != bin_major || db_minor != bin_minor || db_patch > bin_patch { if opt.experimental_dumpless_upgrade { update_version_file_for_dumpless_upgrade( - &opt.db_path, + opt, + index_scheduler_opt, (db_major, db_minor, db_patch), (bin_major, bin_minor, bin_patch), )?; @@ -380,6 +385,57 @@ fn check_version(opt: &Opt, binary_version: (u32, u32, u32)) -> anyhow::Result<( Ok((db_major, db_minor, db_patch)) } +/// Persists the version of the current Meilisearch binary to a VERSION file +pub fn update_version_file_for_dumpless_upgrade( + opt: &Opt, + index_scheduler_opt: &IndexSchedulerOptions, + from: (u32, u32, u32), + to: (u32, u32, u32), +) -> Result<(), VersionFileError> { + let (from_major, from_minor, from_patch) = from; + let (to_major, to_minor, to_patch) = to; + + // Early exit in case of error + if from_major > to_major + || (from_major == to_major && from_minor > to_minor) + || (from_major == to_major && from_minor == to_minor && from_patch > to_patch) + { + return Err(VersionFileError::DowngradeNotSupported { + major: from_major, + minor: from_minor, + patch: from_patch, + }); + } else if from_major < 1 || (from_major == to_major && from_minor < 12) { + return Err(VersionFileError::TooOldForAutomaticUpgrade { + major: from_major, + minor: from_minor, + patch: from_patch, + }); + } + + // In the case of v1.12, the index-scheduler didn't store its internal version at the time. + // => We must write it immediately **in the index-scheduler** otherwise we'll update the version file + // there is a risk of DB corruption if a restart happens after writing the version file but before + // writing the version in the index-scheduler. See + if from_major == 1 && from_minor == 12 { + let env = unsafe { + heed::EnvOpenOptions::new() + .max_dbs(Versioning::nb_db()) + .map_size(index_scheduler_opt.task_db_size) + .open(&index_scheduler_opt.tasks_path) + }?; + let mut wtxn = env.write_txn()?; + let versioning = Versioning::raw_new(&env, &mut wtxn)?; + versioning.set_version(&mut wtxn, (from_major, from_minor, from_patch))?; + wtxn.commit()?; + // Should be instant since we're the only one using the env + env.prepare_for_closing().wait(); + } + + create_current_version_file(&opt.db_path)?; + Ok(()) +} + /// Ensure you're in a valid state and open the IndexScheduler + AuthController for you. fn open_or_create_database( opt: &Opt, @@ -387,7 +443,11 @@ fn open_or_create_database( empty_db: bool, binary_version: (u32, u32, u32), ) -> anyhow::Result<(IndexScheduler, AuthController)> { - let version = if !empty_db { check_version(opt, binary_version)? } else { binary_version }; + let version = if !empty_db { + check_version(opt, &index_scheduler_opt, binary_version)? + } else { + binary_version + }; open_or_create_database_unchecked(opt, index_scheduler_opt, OnFailure::KeepDb, version) } From b63c64395d899c206a24f87d3c81c9dbb2fb124f Mon Sep 17 00:00:00 2001 From: Tamo Date: Wed, 5 Feb 2025 17:42:19 +0100 Subject: [PATCH 2/7] add a test ensuring the index-scheduler version is set when we cannot write the version file --- .../tests/upgrade/v1_12/v1_12_0.rs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs index 1d364d855..df495126c 100644 --- a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs +++ b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs @@ -2,9 +2,11 @@ // It must test pretty much all the features of meilisearch because the other tests will only tests // the new features they introduced. +use index_scheduler::versioning::Versioning; use manifest_dir_macros::exist_relative_path; use meili_snap::{json_string, snapshot}; use meilisearch::Opt; +use meilisearch_types::heed; use crate::common::{default_settings, Server, Value}; use crate::json; @@ -268,3 +270,55 @@ async fn check_the_index_features(server: &Server) { kefir.search_post(json!({ "sort": ["age:asc"], "filter": "surname = kefirounet" })).await; snapshot!(results, name: "search_with_sort_and_filter"); } + +#[actix_rt::test] +async fn import_v1_12_0_with_version_file_error() { + let temp = tempfile::tempdir().unwrap(); + let original_db_path = exist_relative_path!("tests/upgrade/v1_12/v1_12_0.ms"); + let options = Opt { + experimental_dumpless_upgrade: true, + master_key: Some("kefir".to_string()), + ..default_settings(temp.path()) + }; + copy_dir_all(original_db_path, &options.db_path).unwrap(); + + // We're going to drop the write permission on the VERSION file to force Meilisearch to fail its startup. + let version_path = options.db_path.join("VERSION"); + let metadata = std::fs::metadata(&version_path).unwrap(); + let mut permissions = metadata.permissions(); + permissions.set_readonly(true); + std::fs::set_permissions(&version_path, permissions.clone()).unwrap(); + + let err = Server::new_with_options(options.clone()).await.map(|_| ()).unwrap_err(); + snapshot!(err, @"Permission denied (os error 13)"); + + let env = unsafe { + heed::EnvOpenOptions::new() + .max_dbs(Versioning::nb_db()) + .map_size(1024 * 1024 * 1024) + .open(options.db_path.join("tasks")) + } + .unwrap(); + + // Even though the v1.12 don't have a version in its index-scheduler initially, after + // failing the startup the version should have been written before even trying to + // update the version file + let mut wtxn = env.write_txn().unwrap(); + let versioning = Versioning::raw_new(&env, &mut wtxn).unwrap(); + let version = versioning.get_version(&wtxn).unwrap().unwrap(); + snapshot!(format!("{version:?}"), @"(1, 12, 0)"); + drop(wtxn); + env.prepare_for_closing().wait(); + + // Finally we check that even after a first failure the engine can still start and work as expected + #[allow(clippy::permissions_set_readonly_false)] + permissions.set_readonly(false); + std::fs::set_permissions(&version_path, permissions).unwrap(); + + let mut server = Server::new_with_options(options).await.unwrap(); + server.use_api_key("kefir"); + + check_the_keys(&server).await; + check_the_index_scheduler(&server).await; + check_the_index_features(&server).await; +} From ae1d7f4d9bea564aaa1d2b2d53147b45be98f54f Mon Sep 17 00:00:00 2001 From: Tamo Date: Thu, 6 Feb 2025 10:53:29 +0100 Subject: [PATCH 3/7] Improve the test and disable it on windows and linux since they don't work on the CI --- .../tests/upgrade/v1_12/v1_12_0.rs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs index df495126c..b42e4e8f8 100644 --- a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs +++ b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs @@ -2,11 +2,9 @@ // It must test pretty much all the features of meilisearch because the other tests will only tests // the new features they introduced. -use index_scheduler::versioning::Versioning; use manifest_dir_macros::exist_relative_path; use meili_snap::{json_string, snapshot}; use meilisearch::Opt; -use meilisearch_types::heed; use crate::common::{default_settings, Server, Value}; use crate::json; @@ -272,7 +270,11 @@ async fn check_the_index_features(server: &Server) { } #[actix_rt::test] +#[cfg(target_os = "macos")] // The test should work everywhere but in the github CI it only works on macOS async fn import_v1_12_0_with_version_file_error() { + use index_scheduler::versioning::Versioning; + use meilisearch_types::heed; + let temp = tempfile::tempdir().unwrap(); let original_db_path = exist_relative_path!("tests/upgrade/v1_12/v1_12_0.ms"); let options = Opt { @@ -284,10 +286,13 @@ async fn import_v1_12_0_with_version_file_error() { // We're going to drop the write permission on the VERSION file to force Meilisearch to fail its startup. let version_path = options.db_path.join("VERSION"); - let metadata = std::fs::metadata(&version_path).unwrap(); - let mut permissions = metadata.permissions(); - permissions.set_readonly(true); - std::fs::set_permissions(&version_path, permissions.clone()).unwrap(); + + let file = std::fs::File::options().write(true).open(&version_path).unwrap(); + let mut perms = file.metadata().unwrap().permissions(); + perms.set_readonly(true); + file.set_permissions(perms).unwrap(); + file.sync_all().unwrap(); + drop(file); let err = Server::new_with_options(options.clone()).await.map(|_| ()).unwrap_err(); snapshot!(err, @"Permission denied (os error 13)"); @@ -311,9 +316,13 @@ async fn import_v1_12_0_with_version_file_error() { env.prepare_for_closing().wait(); // Finally we check that even after a first failure the engine can still start and work as expected + let file = std::fs::File::open(&version_path).unwrap(); + let mut perms = file.metadata().unwrap().permissions(); #[allow(clippy::permissions_set_readonly_false)] - permissions.set_readonly(false); - std::fs::set_permissions(&version_path, permissions).unwrap(); + perms.set_readonly(false); + file.set_permissions(perms).unwrap(); + file.sync_all().unwrap(); + drop(file); let mut server = Server::new_with_options(options).await.unwrap(); server.use_api_key("kefir"); From 8c5856007cd5c92b561c5257aea8c6efddafef16 Mon Sep 17 00:00:00 2001 From: Tamo Date: Thu, 6 Feb 2025 18:04:43 +0100 Subject: [PATCH 4/7] flush+sync the version file just in case --- crates/meilisearch-types/src/versioning.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/meilisearch-types/src/versioning.rs b/crates/meilisearch-types/src/versioning.rs index 3e072a8e5..b2e9fe724 100644 --- a/crates/meilisearch-types/src/versioning.rs +++ b/crates/meilisearch-types/src/versioning.rs @@ -1,5 +1,5 @@ -use std::fs; -use std::io::{self, ErrorKind}; +use std::fs::{self, File}; +use std::io::{self, ErrorKind, Write}; use std::path::Path; use milli::heed; @@ -23,7 +23,10 @@ pub fn create_version_file( patch: &str, ) -> io::Result<()> { let version_path = db_path.join(VERSION_FILE_NAME); - fs::write(version_path, format!("{}.{}.{}", major, minor, patch)) + let mut file = File::create(&version_path)?; + file.write_all(format!("{}.{}.{}", major, minor, patch).as_bytes())?; + file.flush()?; + file.sync_all() } pub fn get_version(db_path: &Path) -> Result<(u32, u32, u32), VersionFileError> { From 7f82d33597a18814a3d03d7d94a5ef986734a94c Mon Sep 17 00:00:00 2001 From: Tamo Date: Thu, 6 Feb 2025 18:23:28 +0100 Subject: [PATCH 5/7] update the version file atomically --- crates/meilisearch-types/src/versioning.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/meilisearch-types/src/versioning.rs b/crates/meilisearch-types/src/versioning.rs index b2e9fe724..07e42c2ce 100644 --- a/crates/meilisearch-types/src/versioning.rs +++ b/crates/meilisearch-types/src/versioning.rs @@ -1,8 +1,9 @@ -use std::fs::{self, File}; -use std::io::{self, ErrorKind, Write}; +use std::fs; +use std::io::{ErrorKind, Write}; use std::path::Path; use milli::heed; +use tempfile::NamedTempFile; /// The name of the file that contains the version of the database. pub const VERSION_FILE_NAME: &str = "VERSION"; @@ -12,7 +13,7 @@ pub static VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR"); pub static VERSION_PATCH: &str = env!("CARGO_PKG_VERSION_PATCH"); /// Persists the version of the current Meilisearch binary to a VERSION file -pub fn create_current_version_file(db_path: &Path) -> io::Result<()> { +pub fn create_current_version_file(db_path: &Path) -> anyhow::Result<()> { create_version_file(db_path, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) } @@ -21,12 +22,14 @@ pub fn create_version_file( major: &str, minor: &str, patch: &str, -) -> io::Result<()> { +) -> anyhow::Result<()> { let version_path = db_path.join(VERSION_FILE_NAME); - let mut file = File::create(&version_path)?; + // In order to persist the file later we must create it in the `data.ms` and not in `/tmp` + let mut file = NamedTempFile::new_in(db_path)?; file.write_all(format!("{}.{}.{}", major, minor, patch).as_bytes())?; file.flush()?; - file.sync_all() + file.persist(version_path)?; + Ok(()) } pub fn get_version(db_path: &Path) -> Result<(u32, u32, u32), VersionFileError> { @@ -36,7 +39,7 @@ pub fn get_version(db_path: &Path) -> Result<(u32, u32, u32), VersionFileError> Ok(version) => parse_version(&version), Err(error) => match error.kind() { ErrorKind::NotFound => Err(VersionFileError::MissingVersionFile), - _ => Err(error.into()), + _ => Err(anyhow::Error::from(error).into()), }, } } @@ -91,5 +94,5 @@ pub enum VersionFileError { ErrorWhileModifyingTheDatabase(#[from] heed::Error), #[error(transparent)] - IoError(#[from] std::io::Error), + AnyhowError(#[from] anyhow::Error), } From 35b6bca598e6f9fa81a87e42ee9e213459803212 Mon Sep 17 00:00:00 2001 From: Tamo Date: Mon, 10 Feb 2025 10:20:14 +0100 Subject: [PATCH 6/7] remove the failing test --- .../tests/upgrade/v1_12/v1_12_0.rs | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs index b42e4e8f8..50bd79e00 100644 --- a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs +++ b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs @@ -269,65 +269,3 @@ async fn check_the_index_features(server: &Server) { snapshot!(results, name: "search_with_sort_and_filter"); } -#[actix_rt::test] -#[cfg(target_os = "macos")] // The test should work everywhere but in the github CI it only works on macOS -async fn import_v1_12_0_with_version_file_error() { - use index_scheduler::versioning::Versioning; - use meilisearch_types::heed; - - let temp = tempfile::tempdir().unwrap(); - let original_db_path = exist_relative_path!("tests/upgrade/v1_12/v1_12_0.ms"); - let options = Opt { - experimental_dumpless_upgrade: true, - master_key: Some("kefir".to_string()), - ..default_settings(temp.path()) - }; - copy_dir_all(original_db_path, &options.db_path).unwrap(); - - // We're going to drop the write permission on the VERSION file to force Meilisearch to fail its startup. - let version_path = options.db_path.join("VERSION"); - - let file = std::fs::File::options().write(true).open(&version_path).unwrap(); - let mut perms = file.metadata().unwrap().permissions(); - perms.set_readonly(true); - file.set_permissions(perms).unwrap(); - file.sync_all().unwrap(); - drop(file); - - let err = Server::new_with_options(options.clone()).await.map(|_| ()).unwrap_err(); - snapshot!(err, @"Permission denied (os error 13)"); - - let env = unsafe { - heed::EnvOpenOptions::new() - .max_dbs(Versioning::nb_db()) - .map_size(1024 * 1024 * 1024) - .open(options.db_path.join("tasks")) - } - .unwrap(); - - // Even though the v1.12 don't have a version in its index-scheduler initially, after - // failing the startup the version should have been written before even trying to - // update the version file - let mut wtxn = env.write_txn().unwrap(); - let versioning = Versioning::raw_new(&env, &mut wtxn).unwrap(); - let version = versioning.get_version(&wtxn).unwrap().unwrap(); - snapshot!(format!("{version:?}"), @"(1, 12, 0)"); - drop(wtxn); - env.prepare_for_closing().wait(); - - // Finally we check that even after a first failure the engine can still start and work as expected - let file = std::fs::File::open(&version_path).unwrap(); - let mut perms = file.metadata().unwrap().permissions(); - #[allow(clippy::permissions_set_readonly_false)] - perms.set_readonly(false); - file.set_permissions(perms).unwrap(); - file.sync_all().unwrap(); - drop(file); - - let mut server = Server::new_with_options(options).await.unwrap(); - server.use_api_key("kefir"); - - check_the_keys(&server).await; - check_the_index_scheduler(&server).await; - check_the_index_features(&server).await; -} From 45f843ccb9c0c09010d94c6b9720418fd3883a50 Mon Sep 17 00:00:00 2001 From: Tamo Date: Mon, 10 Feb 2025 10:46:42 +0100 Subject: [PATCH 7/7] fmt --- .../index-scheduler/src/scheduler/test_failure.rs | 3 +-- crates/index-scheduler/src/versioning.rs | 13 +++++++------ crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs | 1 - crates/milli/src/update/new/indexer/mod.rs | 3 +-- crates/milli/src/update/upgrade/v1_12.rs | 3 +-- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/crates/index-scheduler/src/scheduler/test_failure.rs b/crates/index-scheduler/src/scheduler/test_failure.rs index 712fe01a5..5cdcb248b 100644 --- a/crates/index-scheduler/src/scheduler/test_failure.rs +++ b/crates/index-scheduler/src/scheduler/test_failure.rs @@ -6,8 +6,7 @@ use meili_snap::snapshot; use meilisearch_types::milli::obkv_to_json; use meilisearch_types::milli::update::IndexDocumentsMethod::*; use meilisearch_types::milli::update::Setting; -use meilisearch_types::tasks::Kind; -use meilisearch_types::tasks::KindWithContent; +use meilisearch_types::tasks::{Kind, KindWithContent}; use crate::insta_snapshot::snapshot_index_scheduler; use crate::test_utils::Breakpoint::*; diff --git a/crates/index-scheduler/src/versioning.rs b/crates/index-scheduler/src/versioning.rs index aaf5224ff..22132bf5f 100644 --- a/crates/index-scheduler/src/versioning.rs +++ b/crates/index-scheduler/src/versioning.rs @@ -1,9 +1,10 @@ -use crate::{upgrade::upgrade_index_scheduler, Result}; -use meilisearch_types::{ - heed::{self, types::Str, Database, Env, RoTxn, RwTxn}, - milli::heed_codec::version::VersionCodec, - versioning, -}; +use meilisearch_types::heed::types::Str; +use meilisearch_types::heed::{self, Database, Env, RoTxn, RwTxn}; +use meilisearch_types::milli::heed_codec::version::VersionCodec; +use meilisearch_types::versioning; + +use crate::upgrade::upgrade_index_scheduler; +use crate::Result; /// The number of database used by queue itself const NUMBER_OF_DATABASES: u32 = 1; diff --git a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs index 50bd79e00..1d364d855 100644 --- a/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs +++ b/crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs @@ -268,4 +268,3 @@ async fn check_the_index_features(server: &Server) { kefir.search_post(json!({ "sort": ["age:asc"], "filter": "surname = kefirounet" })).await; snapshot!(results, name: "search_with_sort_and_filter"); } - diff --git a/crates/milli/src/update/new/indexer/mod.rs b/crates/milli/src/update/new/indexer/mod.rs index 8b98bfba3..f3c96e6e5 100644 --- a/crates/milli/src/update/new/indexer/mod.rs +++ b/crates/milli/src/update/new/indexer/mod.rs @@ -1,5 +1,5 @@ use std::sync::atomic::AtomicBool; -use std::sync::RwLock; +use std::sync::{Once, RwLock}; use std::thread::{self, Builder}; use big_s::S; @@ -21,7 +21,6 @@ use crate::progress::Progress; use crate::update::GrenadParameters; use crate::vector::{ArroyWrapper, EmbeddingConfigs}; use crate::{FieldsIdsMap, GlobalFieldsIdsMap, Index, InternalError, Result, ThreadPoolNoAbort}; -use std::sync::Once; pub(crate) mod de; pub mod document_changes; diff --git a/crates/milli/src/update/upgrade/v1_12.rs b/crates/milli/src/update/upgrade/v1_12.rs index e48ecfe36..9086e920f 100644 --- a/crates/milli/src/update/upgrade/v1_12.rs +++ b/crates/milli/src/update/upgrade/v1_12.rs @@ -1,11 +1,10 @@ use heed::RwTxn; +use super::UpgradeIndex; use crate::constants::{VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH}; use crate::progress::Progress; use crate::{make_enum_progress, Index, Result}; -use super::UpgradeIndex; - #[allow(non_camel_case_types)] pub(super) struct V1_12_To_V1_12_3 {}