mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-01-24 04:07:30 +01:00
Merge #5264
5264: Dumpless upgrade r=dureuill a=irevoire # Pull Request Usage: https://meilisearch.notion.site/Dumpless-upgrade-fff4b06b651f81f1acafe24d4687b3f7?pvs=74 ## Related issue Fixes https://github.com/meilisearch/meilisearch/issues/5162 ## What does this PR do? - Implement the dumpless upgrade with multiple hooks: - In meilisearch directly before the task queue has been opened - In the index-scheduler while processing the task - In milli while upgrading the indexes - There is no hook at search/query time to handle the old version of a database. That's left to the next person upgrading a database - A new special type of task (`upgradeDatabase`) that can be retried has been introduced - A new experimental cli flag has been introduced - The version has been upgraded to the v1.13.0 in this PR otherwise it was a lot of useless work to test the dumpless upgrade - Multiple tests have been introduced ## PR checklist Please check if your PR fulfills the following requirements: - [ ] Update the issue template we use for features, mentioning what we should do in case of a database upgrade - [ ] The experimental feature discussion should be opened and updated in the PR - [ ] Update the PRD - [ ] Add the new error codes - [ ] Add the task details - [ ] Add the telemetry ## Notes The new tests introduced are not _that_ slow ![image](https://github.com/user-attachments/assets/c5884540-482f-41eb-97ef-fc995c62d666) Co-authored-by: Tamo <tamo@meilisearch.com>
This commit is contained in:
commit
1f54f07f72
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3776,6 +3776,7 @@ dependencies = [
|
|||||||
"candle-transformers",
|
"candle-transformers",
|
||||||
"charabia",
|
"charabia",
|
||||||
"concat-arrays",
|
"concat-arrays",
|
||||||
|
"convert_case 0.6.0",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"csv",
|
"csv",
|
||||||
"deserr",
|
"deserr",
|
||||||
|
@ -38,7 +38,7 @@ fn setup_index() -> Index {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
options.max_readers(100);
|
options.max_readers(100);
|
||||||
Index::new(options, path).unwrap()
|
Index::new(options, path, true).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_settings<'t>(
|
fn setup_settings<'t>(
|
||||||
|
@ -68,7 +68,7 @@ pub fn base_setup(conf: &Conf) -> Index {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
options.max_readers(100);
|
options.max_readers(100);
|
||||||
let index = Index::new(options, conf.database_name).unwrap();
|
let index = Index::new(options, conf.database_name, true).unwrap();
|
||||||
|
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
|
@ -141,6 +141,9 @@ pub enum KindDump {
|
|||||||
instance_uid: Option<InstanceUid>,
|
instance_uid: Option<InstanceUid>,
|
||||||
},
|
},
|
||||||
SnapshotCreation,
|
SnapshotCreation,
|
||||||
|
UpgradeDatabase {
|
||||||
|
from: (u32, u32, u32),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Task> for TaskDump {
|
impl From<Task> for TaskDump {
|
||||||
@ -210,6 +213,9 @@ impl From<KindWithContent> for KindDump {
|
|||||||
KindDump::DumpCreation { keys, instance_uid }
|
KindDump::DumpCreation { keys, instance_uid }
|
||||||
}
|
}
|
||||||
KindWithContent::SnapshotCreation => KindDump::SnapshotCreation,
|
KindWithContent::SnapshotCreation => KindDump::SnapshotCreation,
|
||||||
|
KindWithContent::UpgradeDatabase { from: version } => {
|
||||||
|
KindDump::UpgradeDatabase { from: version }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ fn main() {
|
|||||||
Some(path) => TempDir::new_in(path).unwrap(),
|
Some(path) => TempDir::new_in(path).unwrap(),
|
||||||
None => TempDir::new().unwrap(),
|
None => TempDir::new().unwrap(),
|
||||||
};
|
};
|
||||||
let index = Index::new(options, tempdir.path()).unwrap();
|
let index = Index::new(options, tempdir.path(), true).unwrap();
|
||||||
let indexer_config = IndexerConfig::default();
|
let indexer_config = IndexerConfig::default();
|
||||||
|
|
||||||
std::thread::scope(|s| {
|
std::thread::scope(|s| {
|
||||||
|
@ -144,6 +144,7 @@ impl<'a> Dump<'a> {
|
|||||||
KindWithContent::DumpCreation { keys, instance_uid }
|
KindWithContent::DumpCreation { keys, instance_uid }
|
||||||
}
|
}
|
||||||
KindDump::SnapshotCreation => KindWithContent::SnapshotCreation,
|
KindDump::SnapshotCreation => KindWithContent::SnapshotCreation,
|
||||||
|
KindDump::UpgradeDatabase { from } => KindWithContent::UpgradeDatabase { from },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,7 +147,9 @@ pub enum Error {
|
|||||||
#[error("Corrupted task queue.")]
|
#[error("Corrupted task queue.")]
|
||||||
CorruptedTaskQueue,
|
CorruptedTaskQueue,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
TaskDatabaseUpdate(Box<Self>),
|
DatabaseUpgrade(Box<Self>),
|
||||||
|
#[error(transparent)]
|
||||||
|
UnrecoverableError(Box<Self>),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
HeedTransaction(heed::Error),
|
HeedTransaction(heed::Error),
|
||||||
|
|
||||||
@ -202,7 +204,8 @@ impl Error {
|
|||||||
| Error::Anyhow(_) => true,
|
| Error::Anyhow(_) => true,
|
||||||
Error::CreateBatch(_)
|
Error::CreateBatch(_)
|
||||||
| Error::CorruptedTaskQueue
|
| Error::CorruptedTaskQueue
|
||||||
| Error::TaskDatabaseUpdate(_)
|
| Error::DatabaseUpgrade(_)
|
||||||
|
| Error::UnrecoverableError(_)
|
||||||
| Error::HeedTransaction(_) => false,
|
| Error::HeedTransaction(_) => false,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
Error::PlannedFailure => false,
|
Error::PlannedFailure => false,
|
||||||
@ -266,7 +269,8 @@ impl ErrorCode for Error {
|
|||||||
Error::Anyhow(_) => Code::Internal,
|
Error::Anyhow(_) => Code::Internal,
|
||||||
Error::CorruptedTaskQueue => Code::Internal,
|
Error::CorruptedTaskQueue => Code::Internal,
|
||||||
Error::CorruptedDump => Code::Internal,
|
Error::CorruptedDump => Code::Internal,
|
||||||
Error::TaskDatabaseUpdate(_) => Code::Internal,
|
Error::DatabaseUpgrade(_) => Code::Internal,
|
||||||
|
Error::UnrecoverableError(_) => Code::Internal,
|
||||||
Error::CreateBatch(_) => Code::Internal,
|
Error::CreateBatch(_) => Code::Internal,
|
||||||
|
|
||||||
// This one should never be seen by the end user
|
// This one should never be seen by the end user
|
||||||
|
@ -7,7 +7,12 @@ use meilisearch_types::heed::{Database, Env, RwTxn};
|
|||||||
use crate::error::FeatureNotEnabledError;
|
use crate::error::FeatureNotEnabledError;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
const EXPERIMENTAL_FEATURES: &str = "experimental-features";
|
/// The number of database used by features
|
||||||
|
const NUMBER_OF_DATABASES: u32 = 1;
|
||||||
|
/// Database const names for the `FeatureData`.
|
||||||
|
mod db_name {
|
||||||
|
pub const EXPERIMENTAL_FEATURES: &str = "experimental-features";
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct FeatureData {
|
pub(crate) struct FeatureData {
|
||||||
@ -84,14 +89,20 @@ impl RoFeatures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FeatureData {
|
impl FeatureData {
|
||||||
pub fn new(env: &Env, instance_features: InstanceTogglableFeatures) -> Result<Self> {
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
let mut wtxn = env.write_txn()?;
|
NUMBER_OF_DATABASES
|
||||||
let runtime_features_db = env.create_database(&mut wtxn, Some(EXPERIMENTAL_FEATURES))?;
|
}
|
||||||
wtxn.commit()?;
|
|
||||||
|
pub fn new(
|
||||||
|
env: &Env,
|
||||||
|
wtxn: &mut RwTxn,
|
||||||
|
instance_features: InstanceTogglableFeatures,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let runtime_features_db =
|
||||||
|
env.create_database(wtxn, Some(db_name::EXPERIMENTAL_FEATURES))?;
|
||||||
|
|
||||||
let txn = env.read_txn()?;
|
|
||||||
let persisted_features: RuntimeTogglableFeatures =
|
let persisted_features: RuntimeTogglableFeatures =
|
||||||
runtime_features_db.get(&txn, EXPERIMENTAL_FEATURES)?.unwrap_or_default();
|
runtime_features_db.get(wtxn, db_name::EXPERIMENTAL_FEATURES)?.unwrap_or_default();
|
||||||
let InstanceTogglableFeatures { metrics, logs_route, contains_filter } = instance_features;
|
let InstanceTogglableFeatures { metrics, logs_route, contains_filter } = instance_features;
|
||||||
let runtime = Arc::new(RwLock::new(RuntimeTogglableFeatures {
|
let runtime = Arc::new(RwLock::new(RuntimeTogglableFeatures {
|
||||||
metrics: metrics || persisted_features.metrics,
|
metrics: metrics || persisted_features.metrics,
|
||||||
@ -108,7 +119,7 @@ impl FeatureData {
|
|||||||
mut wtxn: RwTxn,
|
mut wtxn: RwTxn,
|
||||||
features: RuntimeTogglableFeatures,
|
features: RuntimeTogglableFeatures,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.persisted.put(&mut wtxn, EXPERIMENTAL_FEATURES, &features)?;
|
self.persisted.put(&mut wtxn, db_name::EXPERIMENTAL_FEATURES, &features)?;
|
||||||
wtxn.commit()?;
|
wtxn.commit()?;
|
||||||
|
|
||||||
// safe to unwrap, the lock will only fail if:
|
// safe to unwrap, the lock will only fail if:
|
||||||
|
@ -102,7 +102,7 @@ impl ReopenableIndex {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
map.unavailable.remove(&self.uuid);
|
map.unavailable.remove(&self.uuid);
|
||||||
map.create(&self.uuid, path, None, self.enable_mdb_writemap, self.map_size)?;
|
map.create(&self.uuid, path, None, self.enable_mdb_writemap, self.map_size, false)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -171,11 +171,12 @@ impl IndexMap {
|
|||||||
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
||||||
enable_mdb_writemap: bool,
|
enable_mdb_writemap: bool,
|
||||||
map_size: usize,
|
map_size: usize,
|
||||||
|
creation: bool,
|
||||||
) -> Result<Index> {
|
) -> Result<Index> {
|
||||||
if !matches!(self.get_unavailable(uuid), Missing) {
|
if !matches!(self.get_unavailable(uuid), Missing) {
|
||||||
panic!("Attempt to open an index that was unavailable");
|
panic!("Attempt to open an index that was unavailable");
|
||||||
}
|
}
|
||||||
let index = create_or_open_index(path, date, enable_mdb_writemap, map_size)?;
|
let index = create_or_open_index(path, date, enable_mdb_writemap, map_size, creation)?;
|
||||||
match self.available.insert(*uuid, index.clone()) {
|
match self.available.insert(*uuid, index.clone()) {
|
||||||
InsertionOutcome::InsertedNew => (),
|
InsertionOutcome::InsertedNew => (),
|
||||||
InsertionOutcome::Evicted(evicted_uuid, evicted_index) => {
|
InsertionOutcome::Evicted(evicted_uuid, evicted_index) => {
|
||||||
@ -299,6 +300,7 @@ fn create_or_open_index(
|
|||||||
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
||||||
enable_mdb_writemap: bool,
|
enable_mdb_writemap: bool,
|
||||||
map_size: usize,
|
map_size: usize,
|
||||||
|
creation: bool,
|
||||||
) -> Result<Index> {
|
) -> Result<Index> {
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(clamp_to_page_size(map_size));
|
options.map_size(clamp_to_page_size(map_size));
|
||||||
@ -308,9 +310,9 @@ fn create_or_open_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((created, updated)) = date {
|
if let Some((created, updated)) = date {
|
||||||
Ok(Index::new_with_creation_dates(options, path, created, updated)?)
|
Ok(Index::new_with_creation_dates(options, path, created, updated, creation)?)
|
||||||
} else {
|
} else {
|
||||||
Ok(Index::new(options, path)?)
|
Ok(Index::new(options, path, creation)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,13 @@ use crate::{Error, IndexBudget, IndexSchedulerOptions, Result};
|
|||||||
|
|
||||||
mod index_map;
|
mod index_map;
|
||||||
|
|
||||||
const INDEX_MAPPING: &str = "index-mapping";
|
/// The number of database used by index mapper
|
||||||
const INDEX_STATS: &str = "index-stats";
|
const NUMBER_OF_DATABASES: u32 = 2;
|
||||||
|
/// Database const names for the `IndexMapper`.
|
||||||
|
mod db_name {
|
||||||
|
pub const INDEX_MAPPING: &str = "index-mapping";
|
||||||
|
pub const INDEX_STATS: &str = "index-stats";
|
||||||
|
}
|
||||||
|
|
||||||
/// Structure managing meilisearch's indexes.
|
/// Structure managing meilisearch's indexes.
|
||||||
///
|
///
|
||||||
@ -138,6 +143,10 @@ impl IndexStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IndexMapper {
|
impl IndexMapper {
|
||||||
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
NUMBER_OF_DATABASES
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
env: &Env,
|
env: &Env,
|
||||||
wtxn: &mut RwTxn,
|
wtxn: &mut RwTxn,
|
||||||
@ -146,8 +155,8 @@ impl IndexMapper {
|
|||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
index_map: Arc::new(RwLock::new(IndexMap::new(budget.index_count))),
|
index_map: Arc::new(RwLock::new(IndexMap::new(budget.index_count))),
|
||||||
index_mapping: env.create_database(wtxn, Some(INDEX_MAPPING))?,
|
index_mapping: env.create_database(wtxn, Some(db_name::INDEX_MAPPING))?,
|
||||||
index_stats: env.create_database(wtxn, Some(INDEX_STATS))?,
|
index_stats: env.create_database(wtxn, Some(db_name::INDEX_STATS))?,
|
||||||
base_path: options.indexes_path.clone(),
|
base_path: options.indexes_path.clone(),
|
||||||
index_base_map_size: budget.map_size,
|
index_base_map_size: budget.map_size,
|
||||||
index_growth_amount: options.index_growth_amount,
|
index_growth_amount: options.index_growth_amount,
|
||||||
@ -189,6 +198,7 @@ impl IndexMapper {
|
|||||||
date,
|
date,
|
||||||
self.enable_mdb_writemap,
|
self.enable_mdb_writemap,
|
||||||
self.index_base_map_size,
|
self.index_base_map_size,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
.map_err(|e| Error::from_milli(e, Some(uuid.to_string())))?;
|
.map_err(|e| Error::from_milli(e, Some(uuid.to_string())))?;
|
||||||
let index_rtxn = index.read_txn()?;
|
let index_rtxn = index.read_txn()?;
|
||||||
@ -387,6 +397,7 @@ impl IndexMapper {
|
|||||||
None,
|
None,
|
||||||
self.enable_mdb_writemap,
|
self.enable_mdb_writemap,
|
||||||
self.index_base_map_size,
|
self.index_base_map_size,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.map_err(|e| Error::from_milli(e, Some(uuid.to_string())))?;
|
.map_err(|e| Error::from_milli(e, Some(uuid.to_string())))?;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use meilisearch_types::heed::types::{SerdeBincode, SerdeJson, Str};
|
|||||||
use meilisearch_types::heed::{Database, RoTxn};
|
use meilisearch_types::heed::{Database, RoTxn};
|
||||||
use meilisearch_types::milli::{CboRoaringBitmapCodec, RoaringBitmapCodec, BEU32};
|
use meilisearch_types::milli::{CboRoaringBitmapCodec, RoaringBitmapCodec, BEU32};
|
||||||
use meilisearch_types::tasks::{Details, Kind, Status, Task};
|
use meilisearch_types::tasks::{Details, Kind, Status, Task};
|
||||||
|
use meilisearch_types::versioning;
|
||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use crate::index_mapper::IndexMapper;
|
use crate::index_mapper::IndexMapper;
|
||||||
@ -21,6 +22,7 @@ pub fn snapshot_index_scheduler(scheduler: &IndexScheduler) -> String {
|
|||||||
cleanup_enabled: _,
|
cleanup_enabled: _,
|
||||||
processing_tasks,
|
processing_tasks,
|
||||||
env,
|
env,
|
||||||
|
version,
|
||||||
queue,
|
queue,
|
||||||
scheduler,
|
scheduler,
|
||||||
|
|
||||||
@ -38,6 +40,16 @@ pub fn snapshot_index_scheduler(scheduler: &IndexScheduler) -> String {
|
|||||||
|
|
||||||
let mut snap = String::new();
|
let mut snap = String::new();
|
||||||
|
|
||||||
|
let indx_sched_version = version.get_version(&rtxn).unwrap();
|
||||||
|
let latest_version = (
|
||||||
|
versioning::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_MINOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_PATCH.parse().unwrap(),
|
||||||
|
);
|
||||||
|
if indx_sched_version != Some(latest_version) {
|
||||||
|
snap.push_str(&format!("index scheduler running on version {indx_sched_version:?}\n"));
|
||||||
|
}
|
||||||
|
|
||||||
let processing = processing_tasks.read().unwrap().clone();
|
let processing = processing_tasks.read().unwrap().clone();
|
||||||
snap.push_str(&format!("### Autobatching Enabled = {}\n", scheduler.autobatching_enabled));
|
snap.push_str(&format!("### Autobatching Enabled = {}\n", scheduler.autobatching_enabled));
|
||||||
snap.push_str(&format!(
|
snap.push_str(&format!(
|
||||||
@ -279,6 +291,9 @@ fn snapshot_details(d: &Details) -> String {
|
|||||||
Details::IndexSwap { swaps } => {
|
Details::IndexSwap { swaps } => {
|
||||||
format!("{{ swaps: {swaps:?} }}")
|
format!("{{ swaps: {swaps:?} }}")
|
||||||
}
|
}
|
||||||
|
Details::UpgradeDatabase { from, to } => {
|
||||||
|
format!("{{ from: {from:?}, to: {to:?} }}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,10 @@ mod queue;
|
|||||||
mod scheduler;
|
mod scheduler;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_utils;
|
mod test_utils;
|
||||||
|
pub mod upgrade;
|
||||||
mod utils;
|
mod utils;
|
||||||
pub mod uuid_codec;
|
pub mod uuid_codec;
|
||||||
|
mod versioning;
|
||||||
|
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
pub type TaskId = u32;
|
pub type TaskId = u32;
|
||||||
@ -65,6 +67,7 @@ use queue::Queue;
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
use scheduler::Scheduler;
|
use scheduler::Scheduler;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
use versioning::Versioning;
|
||||||
|
|
||||||
use crate::index_mapper::IndexMapper;
|
use crate::index_mapper::IndexMapper;
|
||||||
use crate::utils::clamp_to_page_size;
|
use crate::utils::clamp_to_page_size;
|
||||||
@ -120,6 +123,8 @@ pub struct IndexSchedulerOptions {
|
|||||||
pub batched_tasks_size_limit: u64,
|
pub batched_tasks_size_limit: u64,
|
||||||
/// The experimental features enabled for this instance.
|
/// The experimental features enabled for this instance.
|
||||||
pub instance_features: InstanceTogglableFeatures,
|
pub instance_features: InstanceTogglableFeatures,
|
||||||
|
/// The experimental features enabled for this instance.
|
||||||
|
pub auto_upgrade: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure which holds meilisearch's indexes and schedules the tasks
|
/// Structure which holds meilisearch's indexes and schedules the tasks
|
||||||
@ -131,17 +136,18 @@ pub struct IndexScheduler {
|
|||||||
/// The list of tasks currently processing
|
/// The list of tasks currently processing
|
||||||
pub(crate) processing_tasks: Arc<RwLock<ProcessingTasks>>,
|
pub(crate) processing_tasks: Arc<RwLock<ProcessingTasks>>,
|
||||||
|
|
||||||
|
/// A database containing only the version of the index-scheduler
|
||||||
|
pub version: versioning::Versioning,
|
||||||
/// The queue containing both the tasks and the batches.
|
/// The queue containing both the tasks and the batches.
|
||||||
pub queue: queue::Queue,
|
pub queue: queue::Queue,
|
||||||
|
|
||||||
pub scheduler: scheduler::Scheduler,
|
|
||||||
|
|
||||||
/// In charge of creating, opening, storing and returning indexes.
|
/// In charge of creating, opening, storing and returning indexes.
|
||||||
pub(crate) index_mapper: IndexMapper,
|
pub(crate) index_mapper: IndexMapper,
|
||||||
|
|
||||||
/// In charge of fetching and setting the status of experimental features.
|
/// In charge of fetching and setting the status of experimental features.
|
||||||
features: features::FeatureData,
|
features: features::FeatureData,
|
||||||
|
|
||||||
|
/// Everything related to the processing of the tasks
|
||||||
|
pub scheduler: scheduler::Scheduler,
|
||||||
|
|
||||||
/// Whether we should automatically cleanup the task queue or not.
|
/// Whether we should automatically cleanup the task queue or not.
|
||||||
pub(crate) cleanup_enabled: bool,
|
pub(crate) cleanup_enabled: bool,
|
||||||
|
|
||||||
@ -176,6 +182,7 @@ impl IndexScheduler {
|
|||||||
IndexScheduler {
|
IndexScheduler {
|
||||||
env: self.env.clone(),
|
env: self.env.clone(),
|
||||||
processing_tasks: self.processing_tasks.clone(),
|
processing_tasks: self.processing_tasks.clone(),
|
||||||
|
version: self.version.clone(),
|
||||||
queue: self.queue.private_clone(),
|
queue: self.queue.private_clone(),
|
||||||
scheduler: self.scheduler.private_clone(),
|
scheduler: self.scheduler.private_clone(),
|
||||||
|
|
||||||
@ -194,10 +201,15 @@ impl IndexScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
Versioning::nb_db() + Queue::nb_db() + IndexMapper::nb_db() + features::FeatureData::nb_db()
|
||||||
|
}
|
||||||
|
|
||||||
/// Create an index scheduler and start its run loop.
|
/// Create an index scheduler and start its run loop.
|
||||||
#[allow(private_interfaces)] // because test_utils is private
|
#[allow(private_interfaces)] // because test_utils is private
|
||||||
pub fn new(
|
pub fn new(
|
||||||
options: IndexSchedulerOptions,
|
options: IndexSchedulerOptions,
|
||||||
|
from_db_version: (u32, u32, u32),
|
||||||
#[cfg(test)] test_breakpoint_sdr: crossbeam_channel::Sender<(test_utils::Breakpoint, bool)>,
|
#[cfg(test)] test_breakpoint_sdr: crossbeam_channel::Sender<(test_utils::Breakpoint, bool)>,
|
||||||
#[cfg(test)] planned_failures: Vec<(usize, test_utils::FailureLocation)>,
|
#[cfg(test)] planned_failures: Vec<(usize, test_utils::FailureLocation)>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
@ -229,14 +241,16 @@ impl IndexScheduler {
|
|||||||
|
|
||||||
let env = unsafe {
|
let env = unsafe {
|
||||||
heed::EnvOpenOptions::new()
|
heed::EnvOpenOptions::new()
|
||||||
.max_dbs(19)
|
.max_dbs(Self::nb_db())
|
||||||
.map_size(budget.task_db_size)
|
.map_size(budget.task_db_size)
|
||||||
.open(&options.tasks_path)
|
.open(&options.tasks_path)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let features = features::FeatureData::new(&env, options.instance_features)?;
|
// We **must** starts by upgrading the version because it'll also upgrade the required database before we can open them
|
||||||
|
let version = versioning::Versioning::new(&env, from_db_version)?;
|
||||||
|
|
||||||
let mut wtxn = env.write_txn()?;
|
let mut wtxn = env.write_txn()?;
|
||||||
|
let features = features::FeatureData::new(&env, &mut wtxn, options.instance_features)?;
|
||||||
let queue = Queue::new(&env, &mut wtxn, &options)?;
|
let queue = Queue::new(&env, &mut wtxn, &options)?;
|
||||||
let index_mapper = IndexMapper::new(&env, &mut wtxn, &options, budget)?;
|
let index_mapper = IndexMapper::new(&env, &mut wtxn, &options, budget)?;
|
||||||
wtxn.commit()?;
|
wtxn.commit()?;
|
||||||
@ -244,6 +258,7 @@ impl IndexScheduler {
|
|||||||
// allow unreachable_code to get rids of the warning in the case of a test build.
|
// allow unreachable_code to get rids of the warning in the case of a test build.
|
||||||
let this = Self {
|
let this = Self {
|
||||||
processing_tasks: Arc::new(RwLock::new(ProcessingTasks::new())),
|
processing_tasks: Arc::new(RwLock::new(ProcessingTasks::new())),
|
||||||
|
version,
|
||||||
queue,
|
queue,
|
||||||
scheduler: Scheduler::new(&options),
|
scheduler: Scheduler::new(&options),
|
||||||
|
|
||||||
@ -366,6 +381,7 @@ impl IndexScheduler {
|
|||||||
match ret {
|
match ret {
|
||||||
Ok(Ok(TickOutcome::TickAgain(_))) => (),
|
Ok(Ok(TickOutcome::TickAgain(_))) => (),
|
||||||
Ok(Ok(TickOutcome::WaitForSignal)) => run.scheduler.wake_up.wait(),
|
Ok(Ok(TickOutcome::WaitForSignal)) => run.scheduler.wake_up.wait(),
|
||||||
|
Ok(Ok(TickOutcome::StopProcessingForever)) => break,
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
tracing::error!("{e}");
|
tracing::error!("{e}");
|
||||||
// Wait one second when an irrecoverable error occurs.
|
// Wait one second when an irrecoverable error occurs.
|
||||||
@ -813,6 +829,8 @@ pub enum TickOutcome {
|
|||||||
TickAgain(u64),
|
TickAgain(u64),
|
||||||
/// The scheduler should wait for an external signal before attempting another `tick`.
|
/// The scheduler should wait for an external signal before attempting another `tick`.
|
||||||
WaitForSignal,
|
WaitForSignal,
|
||||||
|
/// The scheduler exits the run-loop and will never process tasks again
|
||||||
|
StopProcessingForever,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How many indexes we can afford to have open simultaneously.
|
/// How many indexes we can afford to have open simultaneously.
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use std::borrow::Cow;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use enum_iterator::Sequence;
|
use meilisearch_types::milli::progress::{AtomicSubStep, NamedStep, Progress, ProgressView};
|
||||||
use meilisearch_types::milli::progress::{AtomicSubStep, NamedStep, Progress, ProgressView, Step};
|
|
||||||
use meilisearch_types::milli::{make_atomic_progress, make_enum_progress};
|
use meilisearch_types::milli::{make_atomic_progress, make_enum_progress};
|
||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
@ -173,32 +171,6 @@ make_atomic_progress!(Document alias AtomicDocumentStep => "document" );
|
|||||||
make_atomic_progress!(Batch alias AtomicBatchStep => "batch" );
|
make_atomic_progress!(Batch alias AtomicBatchStep => "batch" );
|
||||||
make_atomic_progress!(UpdateFile alias AtomicUpdateFileStep => "update file" );
|
make_atomic_progress!(UpdateFile alias AtomicUpdateFileStep => "update file" );
|
||||||
|
|
||||||
pub struct VariableNameStep {
|
|
||||||
name: String,
|
|
||||||
current: u32,
|
|
||||||
total: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VariableNameStep {
|
|
||||||
pub fn new(name: impl Into<String>, current: u32, total: u32) -> Self {
|
|
||||||
Self { name: name.into(), current, total }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Step for VariableNameStep {
|
|
||||||
fn name(&self) -> Cow<'static, str> {
|
|
||||||
self.name.clone().into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current(&self) -> u32 {
|
|
||||||
self.current
|
|
||||||
}
|
|
||||||
|
|
||||||
fn total(&self) -> u32 {
|
|
||||||
self.total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
use std::ops::{Bound, RangeBounds};
|
use std::ops::{Bound, RangeBounds};
|
||||||
|
|
||||||
use meilisearch_types::batches::{Batch, BatchId};
|
use meilisearch_types::batches::{Batch, BatchId};
|
||||||
@ -10,9 +11,14 @@ use time::OffsetDateTime;
|
|||||||
|
|
||||||
use super::{Query, Queue};
|
use super::{Query, Queue};
|
||||||
use crate::processing::ProcessingTasks;
|
use crate::processing::ProcessingTasks;
|
||||||
use crate::utils::{insert_task_datetime, keep_ids_within_datetimes, map_bound, ProcessingBatch};
|
use crate::utils::{
|
||||||
|
insert_task_datetime, keep_ids_within_datetimes, map_bound, remove_task_datetime,
|
||||||
|
ProcessingBatch,
|
||||||
|
};
|
||||||
use crate::{Error, Result, BEI128};
|
use crate::{Error, Result, BEI128};
|
||||||
|
|
||||||
|
/// The number of database used by the batch queue
|
||||||
|
const NUMBER_OF_DATABASES: u32 = 7;
|
||||||
/// Database const names for the `IndexScheduler`.
|
/// Database const names for the `IndexScheduler`.
|
||||||
mod db_name {
|
mod db_name {
|
||||||
pub const ALL_BATCHES: &str = "all-batches";
|
pub const ALL_BATCHES: &str = "all-batches";
|
||||||
@ -56,6 +62,10 @@ impl BatchQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
NUMBER_OF_DATABASES
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn new(env: &Env, wtxn: &mut RwTxn) -> Result<Self> {
|
pub(super) fn new(env: &Env, wtxn: &mut RwTxn) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
all_batches: env.create_database(wtxn, Some(db_name::ALL_BATCHES))?,
|
all_batches: env.create_database(wtxn, Some(db_name::ALL_BATCHES))?,
|
||||||
@ -159,6 +169,8 @@ impl BatchQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write_batch(&self, wtxn: &mut RwTxn, batch: ProcessingBatch) -> Result<()> {
|
pub(crate) fn write_batch(&self, wtxn: &mut RwTxn, batch: ProcessingBatch) -> Result<()> {
|
||||||
|
let old_batch = self.all_batches.get(wtxn, &batch.uid)?;
|
||||||
|
|
||||||
self.all_batches.put(
|
self.all_batches.put(
|
||||||
wtxn,
|
wtxn,
|
||||||
&batch.uid,
|
&batch.uid,
|
||||||
@ -172,30 +184,92 @@ impl BatchQueue {
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Update the statuses
|
||||||
|
if let Some(ref old_batch) = old_batch {
|
||||||
|
for status in old_batch.stats.status.keys() {
|
||||||
|
self.update_status(wtxn, *status, |bitmap| {
|
||||||
|
bitmap.remove(batch.uid);
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
for status in batch.statuses {
|
for status in batch.statuses {
|
||||||
self.update_status(wtxn, status, |bitmap| {
|
self.update_status(wtxn, status, |bitmap| {
|
||||||
bitmap.insert(batch.uid);
|
bitmap.insert(batch.uid);
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the kinds / types
|
||||||
|
if let Some(ref old_batch) = old_batch {
|
||||||
|
let kinds: HashSet<_> = old_batch.stats.types.keys().cloned().collect();
|
||||||
|
for kind in kinds.difference(&batch.kinds) {
|
||||||
|
self.update_kind(wtxn, *kind, |bitmap| {
|
||||||
|
bitmap.remove(batch.uid);
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
for kind in batch.kinds {
|
for kind in batch.kinds {
|
||||||
self.update_kind(wtxn, kind, |bitmap| {
|
self.update_kind(wtxn, kind, |bitmap| {
|
||||||
bitmap.insert(batch.uid);
|
bitmap.insert(batch.uid);
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the indexes
|
||||||
|
if let Some(ref old_batch) = old_batch {
|
||||||
|
let indexes: HashSet<_> = old_batch.stats.index_uids.keys().cloned().collect();
|
||||||
|
for index in indexes.difference(&batch.indexes) {
|
||||||
|
self.update_index(wtxn, index, |bitmap| {
|
||||||
|
bitmap.remove(batch.uid);
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
for index in batch.indexes {
|
for index in batch.indexes {
|
||||||
self.update_index(wtxn, &index, |bitmap| {
|
self.update_index(wtxn, &index, |bitmap| {
|
||||||
bitmap.insert(batch.uid);
|
bitmap.insert(batch.uid);
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the enqueued_at: we cannot retrieve the previous enqueued at from the previous batch, and
|
||||||
|
// must instead go through the db looking for it. We cannot look at the task contained in this batch either
|
||||||
|
// because they may have been removed.
|
||||||
|
// What we know, though, is that the task date is from before the enqueued_at, and max two timestamps have been written
|
||||||
|
// to the DB per batches.
|
||||||
|
if let Some(ref old_batch) = old_batch {
|
||||||
|
let started_at = old_batch.started_at.unix_timestamp_nanos();
|
||||||
|
|
||||||
|
// We have either one or two enqueued at to remove
|
||||||
|
let mut exit = old_batch.stats.total_nb_tasks.clamp(0, 2);
|
||||||
|
let mut iterator = self.enqueued_at.rev_iter_mut(wtxn)?;
|
||||||
|
while let Some(entry) = iterator.next() {
|
||||||
|
let (key, mut value) = entry?;
|
||||||
|
if key > started_at {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if value.remove(old_batch.uid) {
|
||||||
|
exit = exit.saturating_sub(1);
|
||||||
|
// Safe because the key and value are owned
|
||||||
|
unsafe {
|
||||||
|
iterator.put_current(&key, &value)?;
|
||||||
|
}
|
||||||
|
if exit == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some(enqueued_at) = batch.oldest_enqueued_at {
|
if let Some(enqueued_at) = batch.oldest_enqueued_at {
|
||||||
insert_task_datetime(wtxn, self.enqueued_at, enqueued_at, batch.uid)?;
|
insert_task_datetime(wtxn, self.enqueued_at, enqueued_at, batch.uid)?;
|
||||||
}
|
}
|
||||||
if let Some(enqueued_at) = batch.earliest_enqueued_at {
|
if let Some(enqueued_at) = batch.earliest_enqueued_at {
|
||||||
insert_task_datetime(wtxn, self.enqueued_at, enqueued_at, batch.uid)?;
|
insert_task_datetime(wtxn, self.enqueued_at, enqueued_at, batch.uid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the started at and finished at
|
||||||
|
if let Some(ref old_batch) = old_batch {
|
||||||
|
remove_task_datetime(wtxn, self.started_at, old_batch.started_at, old_batch.uid)?;
|
||||||
|
if let Some(finished_at) = old_batch.finished_at {
|
||||||
|
remove_task_datetime(wtxn, self.finished_at, finished_at, old_batch.uid)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
insert_task_datetime(wtxn, self.started_at, batch.started_at, batch.uid)?;
|
insert_task_datetime(wtxn, self.started_at, batch.started_at, batch.uid)?;
|
||||||
insert_task_datetime(wtxn, self.finished_at, batch.finished_at.unwrap(), batch.uid)?;
|
insert_task_datetime(wtxn, self.finished_at, batch.finished_at.unwrap(), batch.uid)?;
|
||||||
|
|
||||||
|
@ -20,14 +20,16 @@ use time::format_description::well_known::Rfc3339;
|
|||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use self::batches::BatchQueue;
|
pub(crate) use self::batches::BatchQueue;
|
||||||
use self::tasks::TaskQueue;
|
pub(crate) use self::tasks::TaskQueue;
|
||||||
use crate::processing::ProcessingTasks;
|
use crate::processing::ProcessingTasks;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
check_index_swap_validity, filter_out_references_to_newer_tasks, ProcessingBatch,
|
check_index_swap_validity, filter_out_references_to_newer_tasks, ProcessingBatch,
|
||||||
};
|
};
|
||||||
use crate::{Error, IndexSchedulerOptions, Result, TaskId};
|
use crate::{Error, IndexSchedulerOptions, Result, TaskId};
|
||||||
|
|
||||||
|
/// The number of database used by queue itself
|
||||||
|
const NUMBER_OF_DATABASES: u32 = 1;
|
||||||
/// Database const names for the `IndexScheduler`.
|
/// Database const names for the `IndexScheduler`.
|
||||||
mod db_name {
|
mod db_name {
|
||||||
pub const BATCH_TO_TASKS_MAPPING: &str = "batch-to-tasks-mapping";
|
pub const BATCH_TO_TASKS_MAPPING: &str = "batch-to-tasks-mapping";
|
||||||
@ -148,6 +150,10 @@ impl Queue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
tasks::TaskQueue::nb_db() + batches::BatchQueue::nb_db() + NUMBER_OF_DATABASES
|
||||||
|
}
|
||||||
|
|
||||||
/// Create an index scheduler and start its run loop.
|
/// Create an index scheduler and start its run loop.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
env: &Env,
|
env: &Env,
|
||||||
|
@ -9,12 +9,17 @@ use time::OffsetDateTime;
|
|||||||
|
|
||||||
use super::{Query, Queue};
|
use super::{Query, Queue};
|
||||||
use crate::processing::ProcessingTasks;
|
use crate::processing::ProcessingTasks;
|
||||||
use crate::utils::{self, insert_task_datetime, keep_ids_within_datetimes, map_bound};
|
use crate::utils::{
|
||||||
|
self, insert_task_datetime, keep_ids_within_datetimes, map_bound, remove_task_datetime,
|
||||||
|
};
|
||||||
use crate::{Error, Result, TaskId, BEI128};
|
use crate::{Error, Result, TaskId, BEI128};
|
||||||
|
|
||||||
|
/// The number of database used by the task queue
|
||||||
|
const NUMBER_OF_DATABASES: u32 = 8;
|
||||||
/// Database const names for the `IndexScheduler`.
|
/// Database const names for the `IndexScheduler`.
|
||||||
mod db_name {
|
mod db_name {
|
||||||
pub const ALL_TASKS: &str = "all-tasks";
|
pub const ALL_TASKS: &str = "all-tasks";
|
||||||
|
|
||||||
pub const STATUS: &str = "status";
|
pub const STATUS: &str = "status";
|
||||||
pub const KIND: &str = "kind";
|
pub const KIND: &str = "kind";
|
||||||
pub const INDEX_TASKS: &str = "index-tasks";
|
pub const INDEX_TASKS: &str = "index-tasks";
|
||||||
@ -59,7 +64,11 @@ impl TaskQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn new(env: &Env, wtxn: &mut RwTxn) -> Result<Self> {
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
NUMBER_OF_DATABASES
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn new(env: &Env, wtxn: &mut RwTxn) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
all_tasks: env.create_database(wtxn, Some(db_name::ALL_TASKS))?,
|
all_tasks: env.create_database(wtxn, Some(db_name::ALL_TASKS))?,
|
||||||
status: env.create_database(wtxn, Some(db_name::STATUS))?,
|
status: env.create_database(wtxn, Some(db_name::STATUS))?,
|
||||||
@ -90,12 +99,14 @@ impl TaskQueue {
|
|||||||
|
|
||||||
pub(crate) fn update_task(&self, wtxn: &mut RwTxn, task: &Task) -> Result<()> {
|
pub(crate) fn update_task(&self, wtxn: &mut RwTxn, task: &Task) -> Result<()> {
|
||||||
let old_task = self.get_task(wtxn, task.uid)?.ok_or(Error::CorruptedTaskQueue)?;
|
let old_task = self.get_task(wtxn, task.uid)?.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
|
let reprocessing = old_task.status != Status::Enqueued;
|
||||||
|
|
||||||
debug_assert!(old_task != *task);
|
debug_assert!(old_task != *task);
|
||||||
debug_assert_eq!(old_task.uid, task.uid);
|
debug_assert_eq!(old_task.uid, task.uid);
|
||||||
debug_assert!(old_task.batch_uid.is_none() && task.batch_uid.is_some());
|
|
||||||
|
// If we're processing a task that failed it may already contains a batch_uid
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
old_task.batch_uid.is_none() && task.batch_uid.is_some(),
|
reprocessing || (old_task.batch_uid.is_none() && task.batch_uid.is_some()),
|
||||||
"\n==> old: {old_task:?}\n==> new: {task:?}"
|
"\n==> old: {old_task:?}\n==> new: {task:?}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -122,13 +133,25 @@ impl TaskQueue {
|
|||||||
"Cannot update a task's enqueued_at time"
|
"Cannot update a task's enqueued_at time"
|
||||||
);
|
);
|
||||||
if old_task.started_at != task.started_at {
|
if old_task.started_at != task.started_at {
|
||||||
assert!(old_task.started_at.is_none(), "Cannot update a task's started_at time");
|
assert!(
|
||||||
|
reprocessing || old_task.started_at.is_none(),
|
||||||
|
"Cannot update a task's started_at time"
|
||||||
|
);
|
||||||
|
if let Some(started_at) = old_task.started_at {
|
||||||
|
remove_task_datetime(wtxn, self.started_at, started_at, task.uid)?;
|
||||||
|
}
|
||||||
if let Some(started_at) = task.started_at {
|
if let Some(started_at) = task.started_at {
|
||||||
insert_task_datetime(wtxn, self.started_at, started_at, task.uid)?;
|
insert_task_datetime(wtxn, self.started_at, started_at, task.uid)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if old_task.finished_at != task.finished_at {
|
if old_task.finished_at != task.finished_at {
|
||||||
assert!(old_task.finished_at.is_none(), "Cannot update a task's finished_at time");
|
assert!(
|
||||||
|
reprocessing || old_task.finished_at.is_none(),
|
||||||
|
"Cannot update a task's finished_at time"
|
||||||
|
);
|
||||||
|
if let Some(finished_at) = old_task.finished_at {
|
||||||
|
remove_task_datetime(wtxn, self.finished_at, finished_at, task.uid)?;
|
||||||
|
}
|
||||||
if let Some(finished_at) = task.finished_at {
|
if let Some(finished_at) = task.finished_at {
|
||||||
insert_task_datetime(wtxn, self.finished_at, finished_at, task.uid)?;
|
insert_task_datetime(wtxn, self.finished_at, finished_at, task.uid)?;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ fn test_disable_auto_deletion_of_tasks() {
|
|||||||
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
||||||
config.cleanup_enabled = false;
|
config.cleanup_enabled = false;
|
||||||
config.max_number_of_tasks = 2;
|
config.max_number_of_tasks = 2;
|
||||||
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
index_scheduler
|
index_scheduler
|
||||||
@ -228,6 +229,7 @@ fn test_disable_auto_deletion_of_tasks() {
|
|||||||
fn test_auto_deletion_of_tasks() {
|
fn test_auto_deletion_of_tasks() {
|
||||||
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
||||||
config.max_number_of_tasks = 2;
|
config.max_number_of_tasks = 2;
|
||||||
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
index_scheduler
|
index_scheduler
|
||||||
@ -325,6 +327,7 @@ fn test_task_queue_is_full() {
|
|||||||
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
let (index_scheduler, mut handle) = IndexScheduler::test_with_custom_config(vec![], |config| {
|
||||||
// that's the minimum map size possible
|
// that's the minimum map size possible
|
||||||
config.task_db_size = 1048576;
|
config.task_db_size = 1048576;
|
||||||
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
index_scheduler
|
index_scheduler
|
||||||
|
@ -85,6 +85,7 @@ impl From<KindWithContent> for AutobatchKind {
|
|||||||
KindWithContent::TaskCancelation { .. }
|
KindWithContent::TaskCancelation { .. }
|
||||||
| KindWithContent::TaskDeletion { .. }
|
| KindWithContent::TaskDeletion { .. }
|
||||||
| KindWithContent::DumpCreation { .. }
|
| KindWithContent::DumpCreation { .. }
|
||||||
|
| KindWithContent::UpgradeDatabase { .. }
|
||||||
| KindWithContent::SnapshotCreation => {
|
| KindWithContent::SnapshotCreation => {
|
||||||
panic!("The autobatcher should never be called with tasks that don't apply to an index.")
|
panic!("The autobatcher should never be called with tasks that don't apply to an index.")
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,9 @@ pub(crate) enum Batch {
|
|||||||
IndexSwap {
|
IndexSwap {
|
||||||
task: Task,
|
task: Task,
|
||||||
},
|
},
|
||||||
|
UpgradeDatabase {
|
||||||
|
tasks: Vec<Task>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -105,6 +108,7 @@ impl Batch {
|
|||||||
}
|
}
|
||||||
Batch::SnapshotCreation(tasks)
|
Batch::SnapshotCreation(tasks)
|
||||||
| Batch::TaskDeletions(tasks)
|
| Batch::TaskDeletions(tasks)
|
||||||
|
| Batch::UpgradeDatabase { tasks }
|
||||||
| Batch::IndexDeletion { tasks, .. } => {
|
| Batch::IndexDeletion { tasks, .. } => {
|
||||||
RoaringBitmap::from_iter(tasks.iter().map(|task| task.uid))
|
RoaringBitmap::from_iter(tasks.iter().map(|task| task.uid))
|
||||||
}
|
}
|
||||||
@ -138,6 +142,7 @@ impl Batch {
|
|||||||
| TaskDeletions(_)
|
| TaskDeletions(_)
|
||||||
| SnapshotCreation(_)
|
| SnapshotCreation(_)
|
||||||
| Dump(_)
|
| Dump(_)
|
||||||
|
| UpgradeDatabase { .. }
|
||||||
| IndexSwap { .. } => None,
|
| IndexSwap { .. } => None,
|
||||||
IndexOperation { op, .. } => Some(op.index_uid()),
|
IndexOperation { op, .. } => Some(op.index_uid()),
|
||||||
IndexCreation { index_uid, .. }
|
IndexCreation { index_uid, .. }
|
||||||
@ -162,6 +167,7 @@ impl fmt::Display for Batch {
|
|||||||
Batch::IndexUpdate { .. } => f.write_str("IndexUpdate")?,
|
Batch::IndexUpdate { .. } => f.write_str("IndexUpdate")?,
|
||||||
Batch::IndexDeletion { .. } => f.write_str("IndexDeletion")?,
|
Batch::IndexDeletion { .. } => f.write_str("IndexDeletion")?,
|
||||||
Batch::IndexSwap { .. } => f.write_str("IndexSwap")?,
|
Batch::IndexSwap { .. } => f.write_str("IndexSwap")?,
|
||||||
|
Batch::UpgradeDatabase { .. } => f.write_str("UpgradeDatabase")?,
|
||||||
};
|
};
|
||||||
match index_uid {
|
match index_uid {
|
||||||
Some(name) => f.write_fmt(format_args!(" on {name:?} from tasks: {tasks:?}")),
|
Some(name) => f.write_fmt(format_args!(" on {name:?} from tasks: {tasks:?}")),
|
||||||
@ -427,9 +433,24 @@ impl IndexScheduler {
|
|||||||
let mut current_batch = ProcessingBatch::new(batch_id);
|
let mut current_batch = ProcessingBatch::new(batch_id);
|
||||||
|
|
||||||
let enqueued = &self.queue.tasks.get_status(rtxn, Status::Enqueued)?;
|
let enqueued = &self.queue.tasks.get_status(rtxn, Status::Enqueued)?;
|
||||||
let to_cancel = self.queue.tasks.get_kind(rtxn, Kind::TaskCancelation)? & enqueued;
|
let failed = &self.queue.tasks.get_status(rtxn, Status::Failed)?;
|
||||||
|
|
||||||
|
// 0. The priority over everything is to upgrade the instance
|
||||||
|
// There shouldn't be multiple upgrade tasks but just in case we're going to batch all of them at the same time
|
||||||
|
let upgrade = self.queue.tasks.get_kind(rtxn, Kind::UpgradeDatabase)? & (enqueued | failed);
|
||||||
|
if !upgrade.is_empty() {
|
||||||
|
let mut tasks = self.queue.tasks.get_existing_tasks(rtxn, upgrade)?;
|
||||||
|
// In the case of an upgrade database batch, we want to find back the original batch that tried processing it
|
||||||
|
// and re-use its id
|
||||||
|
if let Some(batch_uid) = tasks.last().unwrap().batch_uid {
|
||||||
|
current_batch.uid = batch_uid;
|
||||||
|
}
|
||||||
|
current_batch.processing(&mut tasks);
|
||||||
|
return Ok(Some((Batch::UpgradeDatabase { tasks }, current_batch)));
|
||||||
|
}
|
||||||
|
|
||||||
// 1. we get the last task to cancel.
|
// 1. we get the last task to cancel.
|
||||||
|
let to_cancel = self.queue.tasks.get_kind(rtxn, Kind::TaskCancelation)? & enqueued;
|
||||||
if let Some(task_id) = to_cancel.max() {
|
if let Some(task_id) = to_cancel.max() {
|
||||||
let mut task =
|
let mut task =
|
||||||
self.queue.tasks.get_task(rtxn, task_id)?.ok_or(Error::CorruptedTaskQueue)?;
|
self.queue.tasks.get_task(rtxn, task_id)?.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
|
@ -6,6 +6,7 @@ mod process_batch;
|
|||||||
mod process_dump_creation;
|
mod process_dump_creation;
|
||||||
mod process_index_operation;
|
mod process_index_operation;
|
||||||
mod process_snapshot_creation;
|
mod process_snapshot_creation;
|
||||||
|
mod process_upgrade;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -183,6 +184,7 @@ impl IndexScheduler {
|
|||||||
|
|
||||||
progress.update_progress(BatchProgress::WritingTasksToDisk);
|
progress.update_progress(BatchProgress::WritingTasksToDisk);
|
||||||
processing_batch.finished();
|
processing_batch.finished();
|
||||||
|
let mut stop_scheduler_forever = false;
|
||||||
let mut wtxn = self.env.write_txn().map_err(Error::HeedTransaction)?;
|
let mut wtxn = self.env.write_txn().map_err(Error::HeedTransaction)?;
|
||||||
let mut canceled = RoaringBitmap::new();
|
let mut canceled = RoaringBitmap::new();
|
||||||
|
|
||||||
@ -221,7 +223,7 @@ impl IndexScheduler {
|
|||||||
self.queue
|
self.queue
|
||||||
.tasks
|
.tasks
|
||||||
.update_task(&mut wtxn, &task)
|
.update_task(&mut wtxn, &task)
|
||||||
.map_err(|e| Error::TaskDatabaseUpdate(Box::new(e)))?;
|
.map_err(|e| Error::UnrecoverableError(Box::new(e)))?;
|
||||||
}
|
}
|
||||||
if let Some(canceled_by) = canceled_by {
|
if let Some(canceled_by) = canceled_by {
|
||||||
self.queue.tasks.canceled_by.put(&mut wtxn, &canceled_by, &canceled)?;
|
self.queue.tasks.canceled_by.put(&mut wtxn, &canceled_by, &canceled)?;
|
||||||
@ -272,6 +274,12 @@ impl IndexScheduler {
|
|||||||
let (task_progress, task_progress_obj) = AtomicTaskStep::new(ids.len() as u32);
|
let (task_progress, task_progress_obj) = AtomicTaskStep::new(ids.len() as u32);
|
||||||
progress.update_progress(task_progress_obj);
|
progress.update_progress(task_progress_obj);
|
||||||
|
|
||||||
|
if matches!(err, Error::DatabaseUpgrade(_)) {
|
||||||
|
tracing::error!(
|
||||||
|
"Upgrade task failed, tasks won't be processed until the following issue is fixed: {err}"
|
||||||
|
);
|
||||||
|
stop_scheduler_forever = true;
|
||||||
|
}
|
||||||
let error: ResponseError = err.into();
|
let error: ResponseError = err.into();
|
||||||
for id in ids.iter() {
|
for id in ids.iter() {
|
||||||
task_progress.fetch_add(1, Ordering::Relaxed);
|
task_progress.fetch_add(1, Ordering::Relaxed);
|
||||||
@ -279,7 +287,7 @@ impl IndexScheduler {
|
|||||||
.queue
|
.queue
|
||||||
.tasks
|
.tasks
|
||||||
.get_task(&wtxn, id)
|
.get_task(&wtxn, id)
|
||||||
.map_err(|e| Error::TaskDatabaseUpdate(Box::new(e)))?
|
.map_err(|e| Error::UnrecoverableError(Box::new(e)))?
|
||||||
.ok_or(Error::CorruptedTaskQueue)?;
|
.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
task.status = Status::Failed;
|
task.status = Status::Failed;
|
||||||
task.error = Some(error.clone());
|
task.error = Some(error.clone());
|
||||||
@ -296,7 +304,7 @@ impl IndexScheduler {
|
|||||||
self.queue
|
self.queue
|
||||||
.tasks
|
.tasks
|
||||||
.update_task(&mut wtxn, &task)
|
.update_task(&mut wtxn, &task)
|
||||||
.map_err(|e| Error::TaskDatabaseUpdate(Box::new(e)))?;
|
.map_err(|e| Error::UnrecoverableError(Box::new(e)))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,7 +334,7 @@ impl IndexScheduler {
|
|||||||
.queue
|
.queue
|
||||||
.tasks
|
.tasks
|
||||||
.get_task(&rtxn, id)
|
.get_task(&rtxn, id)
|
||||||
.map_err(|e| Error::TaskDatabaseUpdate(Box::new(e)))?
|
.map_err(|e| Error::UnrecoverableError(Box::new(e)))?
|
||||||
.ok_or(Error::CorruptedTaskQueue)?;
|
.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
if let Err(e) = self.queue.delete_persisted_task_data(&task) {
|
if let Err(e) = self.queue.delete_persisted_task_data(&task) {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
@ -344,6 +352,10 @@ impl IndexScheduler {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
self.breakpoint(crate::test_utils::Breakpoint::AfterProcessing);
|
self.breakpoint(crate::test_utils::Breakpoint::AfterProcessing);
|
||||||
|
|
||||||
Ok(TickOutcome::TickAgain(processed_tasks))
|
if stop_scheduler_forever {
|
||||||
|
Ok(TickOutcome::StopProcessingForever)
|
||||||
|
} else {
|
||||||
|
Ok(TickOutcome::TickAgain(processed_tasks))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||||
|
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use meilisearch_types::batches::BatchId;
|
use meilisearch_types::batches::BatchId;
|
||||||
use meilisearch_types::heed::{RoTxn, RwTxn};
|
use meilisearch_types::heed::{RoTxn, RwTxn};
|
||||||
use meilisearch_types::milli::progress::Progress;
|
use meilisearch_types::milli::progress::{Progress, VariableNameStep};
|
||||||
use meilisearch_types::milli::{self};
|
use meilisearch_types::milli::{self};
|
||||||
use meilisearch_types::tasks::{Details, IndexSwap, KindWithContent, Status, Task};
|
use meilisearch_types::tasks::{Details, IndexSwap, KindWithContent, Status, Task};
|
||||||
use milli::update::Settings as MilliSettings;
|
use milli::update::Settings as MilliSettings;
|
||||||
@ -13,7 +14,7 @@ use super::create_batch::Batch;
|
|||||||
use crate::processing::{
|
use crate::processing::{
|
||||||
AtomicBatchStep, AtomicTaskStep, CreateIndexProgress, DeleteIndexProgress,
|
AtomicBatchStep, AtomicTaskStep, CreateIndexProgress, DeleteIndexProgress,
|
||||||
InnerSwappingTwoIndexes, SwappingTheIndexes, TaskCancelationProgress, TaskDeletionProgress,
|
InnerSwappingTwoIndexes, SwappingTheIndexes, TaskCancelationProgress, TaskDeletionProgress,
|
||||||
UpdateIndexProgress, VariableNameStep,
|
UpdateIndexProgress,
|
||||||
};
|
};
|
||||||
use crate::utils::{self, swap_index_uid_in_task, ProcessingBatch};
|
use crate::utils::{self, swap_index_uid_in_task, ProcessingBatch};
|
||||||
use crate::{Error, IndexScheduler, Result, TaskId};
|
use crate::{Error, IndexScheduler, Result, TaskId};
|
||||||
@ -297,7 +298,7 @@ impl IndexScheduler {
|
|||||||
}
|
}
|
||||||
progress.update_progress(SwappingTheIndexes::SwappingTheIndexes);
|
progress.update_progress(SwappingTheIndexes::SwappingTheIndexes);
|
||||||
for (step, swap) in swaps.iter().enumerate() {
|
for (step, swap) in swaps.iter().enumerate() {
|
||||||
progress.update_progress(VariableNameStep::new(
|
progress.update_progress(VariableNameStep::<SwappingTheIndexes>::new(
|
||||||
format!("swapping index {} and {}", swap.indexes.0, swap.indexes.1),
|
format!("swapping index {} and {}", swap.indexes.0, swap.indexes.1),
|
||||||
step as u32,
|
step as u32,
|
||||||
swaps.len() as u32,
|
swaps.len() as u32,
|
||||||
@ -314,6 +315,27 @@ impl IndexScheduler {
|
|||||||
task.status = Status::Succeeded;
|
task.status = Status::Succeeded;
|
||||||
Ok(vec![task])
|
Ok(vec![task])
|
||||||
}
|
}
|
||||||
|
Batch::UpgradeDatabase { mut tasks } => {
|
||||||
|
let KindWithContent::UpgradeDatabase { from } = tasks.last().unwrap().kind else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
let ret = catch_unwind(AssertUnwindSafe(|| self.process_upgrade(from, progress)));
|
||||||
|
match ret {
|
||||||
|
Ok(Ok(())) => (),
|
||||||
|
Ok(Err(e)) => return Err(Error::DatabaseUpgrade(Box::new(e))),
|
||||||
|
Err(_e) => {
|
||||||
|
return Err(Error::DatabaseUpgrade(Box::new(Error::ProcessBatchPanicked)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for task in tasks.iter_mut() {
|
||||||
|
task.status = Status::Succeeded;
|
||||||
|
// Since this task can be retried we must reset its error status
|
||||||
|
task.error = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(tasks)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,16 +4,14 @@ use std::sync::atomic::Ordering;
|
|||||||
|
|
||||||
use dump::IndexMetadata;
|
use dump::IndexMetadata;
|
||||||
use meilisearch_types::milli::constants::RESERVED_VECTORS_FIELD_NAME;
|
use meilisearch_types::milli::constants::RESERVED_VECTORS_FIELD_NAME;
|
||||||
use meilisearch_types::milli::progress::Progress;
|
use meilisearch_types::milli::progress::{Progress, VariableNameStep};
|
||||||
use meilisearch_types::milli::vector::parsed_vectors::{ExplicitVectors, VectorOrArrayOfVectors};
|
use meilisearch_types::milli::vector::parsed_vectors::{ExplicitVectors, VectorOrArrayOfVectors};
|
||||||
use meilisearch_types::milli::{self};
|
use meilisearch_types::milli::{self};
|
||||||
use meilisearch_types::tasks::{Details, KindWithContent, Status, Task};
|
use meilisearch_types::tasks::{Details, KindWithContent, Status, Task};
|
||||||
use time::macros::format_description;
|
use time::macros::format_description;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
use crate::processing::{
|
use crate::processing::{AtomicDocumentStep, AtomicTaskStep, DumpCreationProgress};
|
||||||
AtomicDocumentStep, AtomicTaskStep, DumpCreationProgress, VariableNameStep,
|
|
||||||
};
|
|
||||||
use crate::{Error, IndexScheduler, Result};
|
use crate::{Error, IndexScheduler, Result};
|
||||||
|
|
||||||
impl IndexScheduler {
|
impl IndexScheduler {
|
||||||
@ -109,7 +107,11 @@ impl IndexScheduler {
|
|||||||
let nb_indexes = self.index_mapper.index_mapping.len(&rtxn)? as u32;
|
let nb_indexes = self.index_mapper.index_mapping.len(&rtxn)? as u32;
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let () = self.index_mapper.try_for_each_index(&rtxn, |uid, index| -> Result<()> {
|
let () = self.index_mapper.try_for_each_index(&rtxn, |uid, index| -> Result<()> {
|
||||||
progress.update_progress(VariableNameStep::new(uid.to_string(), count, nb_indexes));
|
progress.update_progress(VariableNameStep::<DumpCreationProgress>::new(
|
||||||
|
uid.to_string(),
|
||||||
|
count,
|
||||||
|
nb_indexes,
|
||||||
|
));
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
let rtxn = index.read_txn()?;
|
let rtxn = index.read_txn()?;
|
||||||
|
@ -3,12 +3,12 @@ use std::fs;
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use meilisearch_types::heed::CompactionOption;
|
use meilisearch_types::heed::CompactionOption;
|
||||||
use meilisearch_types::milli::progress::Progress;
|
use meilisearch_types::milli::progress::{Progress, VariableNameStep};
|
||||||
use meilisearch_types::milli::{self};
|
use meilisearch_types::milli::{self};
|
||||||
use meilisearch_types::tasks::{Status, Task};
|
use meilisearch_types::tasks::{Status, Task};
|
||||||
use meilisearch_types::{compression, VERSION_FILE_NAME};
|
use meilisearch_types::{compression, VERSION_FILE_NAME};
|
||||||
|
|
||||||
use crate::processing::{AtomicUpdateFileStep, SnapshotCreationProgress, VariableNameStep};
|
use crate::processing::{AtomicUpdateFileStep, SnapshotCreationProgress};
|
||||||
use crate::{Error, IndexScheduler, Result};
|
use crate::{Error, IndexScheduler, Result};
|
||||||
|
|
||||||
impl IndexScheduler {
|
impl IndexScheduler {
|
||||||
@ -74,7 +74,9 @@ impl IndexScheduler {
|
|||||||
|
|
||||||
for (i, result) in index_mapping.iter(&rtxn)?.enumerate() {
|
for (i, result) in index_mapping.iter(&rtxn)?.enumerate() {
|
||||||
let (name, uuid) = result?;
|
let (name, uuid) = result?;
|
||||||
progress.update_progress(VariableNameStep::new(name, i as u32, nb_indexes));
|
progress.update_progress(VariableNameStep::<SnapshotCreationProgress>::new(
|
||||||
|
name, i as u32, nb_indexes,
|
||||||
|
));
|
||||||
let index = self.index_mapper.index(&rtxn, name)?;
|
let index = self.index_mapper.index(&rtxn, name)?;
|
||||||
let dst = temp_snapshot_dir.path().join("indexes").join(uuid.to_string());
|
let dst = temp_snapshot_dir.path().join("indexes").join(uuid.to_string());
|
||||||
fs::create_dir_all(&dst)?;
|
fs::create_dir_all(&dst)?;
|
||||||
|
49
crates/index-scheduler/src/scheduler/process_upgrade/mod.rs
Normal file
49
crates/index-scheduler/src/scheduler/process_upgrade/mod.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use meilisearch_types::milli;
|
||||||
|
use meilisearch_types::milli::progress::{Progress, VariableNameStep};
|
||||||
|
|
||||||
|
use crate::{Error, IndexScheduler, Result};
|
||||||
|
|
||||||
|
impl IndexScheduler {
|
||||||
|
pub(super) fn process_upgrade(
|
||||||
|
&self,
|
||||||
|
db_version: (u32, u32, u32),
|
||||||
|
progress: Progress,
|
||||||
|
) -> Result<()> {
|
||||||
|
#[cfg(test)]
|
||||||
|
self.maybe_fail(crate::test_utils::FailureLocation::ProcessUpgrade)?;
|
||||||
|
|
||||||
|
enum UpgradeIndex {}
|
||||||
|
let indexes = self.index_names()?;
|
||||||
|
|
||||||
|
for (i, uid) in indexes.iter().enumerate() {
|
||||||
|
progress.update_progress(VariableNameStep::<UpgradeIndex>::new(
|
||||||
|
format!("Upgrading index `{uid}`"),
|
||||||
|
i as u32,
|
||||||
|
indexes.len() as u32,
|
||||||
|
));
|
||||||
|
let index = self.index(uid)?;
|
||||||
|
let mut index_wtxn = index.write_txn()?;
|
||||||
|
let regen_stats = milli::update::upgrade::upgrade(
|
||||||
|
&mut index_wtxn,
|
||||||
|
&index,
|
||||||
|
db_version,
|
||||||
|
progress.clone(),
|
||||||
|
)
|
||||||
|
.map_err(|e| Error::from_milli(e, Some(uid.to_string())))?;
|
||||||
|
if regen_stats {
|
||||||
|
let stats = crate::index_mapper::IndexStats::new(&index, &index_wtxn)
|
||||||
|
.map_err(|e| Error::from_milli(e, Some(uid.to_string())))?;
|
||||||
|
index_wtxn.commit()?;
|
||||||
|
|
||||||
|
// Release wtxn as soon as possible because it stops us from registering tasks
|
||||||
|
let mut index_schd_wtxn = self.env.write_txn()?;
|
||||||
|
self.index_mapper.store_stats_of(&mut index_schd_wtxn, uid, &stats)?;
|
||||||
|
index_schd_wtxn.commit()?;
|
||||||
|
} else {
|
||||||
|
index_wtxn.commit()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, batch_uid: 0, status: succeeded, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
1 {uid: 1, batch_uid: 1, status: succeeded, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
2 {uid: 2, batch_uid: 2, status: succeeded, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
3 {uid: 3, batch_uid: 3, status: failed, error: ResponseError { code: 200, message: "Index `doggo` already exists.", error_code: "index_already_exists", error_type: "invalid_request", error_link: "https://docs.meilisearch.com/errors#index_already_exists" }, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
4 {uid: 4, batch_uid: 4, status: succeeded, details: { primary_key: Some("leaves") }, kind: IndexCreation { index_uid: "girafo", primary_key: Some("leaves") }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued []
|
||||||
|
succeeded [0,1,2,4,]
|
||||||
|
failed [3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,2,3,4,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,3,]
|
||||||
|
girafo [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
catto: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
doggo: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
girafo: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
0 {uid: 0, details: {"upgradeFrom":"v1.12.0","upgradeTo":"v1.13.0"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"upgradeDatabase":1},"indexUids":{}}, }
|
||||||
|
1 {uid: 1, details: {"primaryKey":"mouse"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"catto":1}}, }
|
||||||
|
2 {uid: 2, details: {"primaryKey":"bone"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"doggo":1}}, }
|
||||||
|
3 {uid: 3, details: {"primaryKey":"bone"}, stats: {"totalNbTasks":1,"status":{"failed":1},"types":{"indexCreation":1},"indexUids":{"doggo":1}}, }
|
||||||
|
4 {uid: 4, details: {"primaryKey":"leaves"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"girafo":1}}, }
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
0 [0,]
|
||||||
|
1 [1,]
|
||||||
|
2 [2,]
|
||||||
|
3 [3,]
|
||||||
|
4 [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
succeeded [0,1,2,4,]
|
||||||
|
failed [3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
"indexCreation" [1,2,3,4,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,3,]
|
||||||
|
girafo [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
1 {uid: 1, batch_uid: 1, status: succeeded, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
2 {uid: 2, batch_uid: 2, status: succeeded, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
3 {uid: 3, batch_uid: 3, status: failed, error: ResponseError { code: 200, message: "Index `doggo` already exists.", error_code: "index_already_exists", error_type: "invalid_request", error_link: "https://docs.meilisearch.com/errors#index_already_exists" }, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
4 {uid: 4, batch_uid: 4, status: succeeded, details: { primary_key: Some("leaves") }, kind: IndexCreation { index_uid: "girafo", primary_key: Some("leaves") }}
|
||||||
|
5 {uid: 5, batch_uid: 5, status: succeeded, details: { matched_tasks: 1, deleted_tasks: Some(1), original_filter: "types=upgradeDatabase" }, kind: TaskDeletion { query: "types=upgradeDatabase", tasks: RoaringBitmap<[0]> }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued []
|
||||||
|
succeeded [1,2,4,5,]
|
||||||
|
failed [3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,2,3,4,]
|
||||||
|
"taskDeletion" [5,]
|
||||||
|
"upgradeDatabase" []
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,3,]
|
||||||
|
girafo [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
catto: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
doggo: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
girafo: { number_of_documents: 0, field_distribution: {} }
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
1 {uid: 1, details: {"primaryKey":"mouse"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"catto":1}}, }
|
||||||
|
2 {uid: 2, details: {"primaryKey":"bone"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"doggo":1}}, }
|
||||||
|
3 {uid: 3, details: {"primaryKey":"bone"}, stats: {"totalNbTasks":1,"status":{"failed":1},"types":{"indexCreation":1},"indexUids":{"doggo":1}}, }
|
||||||
|
4 {uid: 4, details: {"primaryKey":"leaves"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"indexCreation":1},"indexUids":{"girafo":1}}, }
|
||||||
|
5 {uid: 5, details: {"matchedTasks":1,"deletedTasks":1,"originalFilter":"types=upgradeDatabase"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"taskDeletion":1},"indexUids":{}}, }
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
1 [1,]
|
||||||
|
2 [2,]
|
||||||
|
3 [3,]
|
||||||
|
4 [4,]
|
||||||
|
5 [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
succeeded [1,2,4,5,]
|
||||||
|
failed [3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
"indexCreation" [1,2,3,4,]
|
||||||
|
"taskDeletion" [5,]
|
||||||
|
"upgradeDatabase" []
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,3,]
|
||||||
|
girafo [4,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
[timestamp] [4,]
|
||||||
|
[timestamp] [5,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, status: enqueued, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, status: enqueued, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
1 {uid: 1, status: enqueued, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued [0,1,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, batch_uid: 0, status: failed, error: ResponseError { code: 200, message: "Planned failure for tests.", error_code: "internal", error_type: "internal", error_link: "https://docs.meilisearch.com/errors#internal" }, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
1 {uid: 1, status: enqueued, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued [1,]
|
||||||
|
failed [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
0 {uid: 0, details: {"upgradeFrom":"v1.12.0","upgradeTo":"v1.13.0"}, stats: {"totalNbTasks":1,"status":{"failed":1},"types":{"upgradeDatabase":1},"indexUids":{}}, }
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
0 [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
failed [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, batch_uid: 0, status: failed, error: ResponseError { code: 200, message: "Planned failure for tests.", error_code: "internal", error_type: "internal", error_link: "https://docs.meilisearch.com/errors#internal" }, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
1 {uid: 1, status: enqueued, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
2 {uid: 2, status: enqueued, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued [1,2,]
|
||||||
|
failed [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,2,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
0 {uid: 0, details: {"upgradeFrom":"v1.12.0","upgradeTo":"v1.13.0"}, stats: {"totalNbTasks":1,"status":{"failed":1},"types":{"upgradeDatabase":1},"indexUids":{}}, }
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
0 [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
failed [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
source: crates/index-scheduler/src/scheduler/test_failure.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
### Autobatching Enabled = true
|
||||||
|
### Processing batch None:
|
||||||
|
[]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Tasks:
|
||||||
|
0 {uid: 0, batch_uid: 0, status: succeeded, details: { from: (1, 12, 0), to: (1, 13, 0) }, kind: UpgradeDatabase { from: (1, 12, 0) }}
|
||||||
|
1 {uid: 1, status: enqueued, details: { primary_key: Some("mouse") }, kind: IndexCreation { index_uid: "catto", primary_key: Some("mouse") }}
|
||||||
|
2 {uid: 2, status: enqueued, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
3 {uid: 3, status: enqueued, details: { primary_key: Some("bone") }, kind: IndexCreation { index_uid: "doggo", primary_key: Some("bone") }}
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Status:
|
||||||
|
enqueued [1,2,3,]
|
||||||
|
succeeded [0,]
|
||||||
|
failed []
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Kind:
|
||||||
|
"indexCreation" [1,2,3,]
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Tasks:
|
||||||
|
catto [1,]
|
||||||
|
doggo [2,3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Index Mapper:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Canceled By:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
[timestamp] [1,]
|
||||||
|
[timestamp] [2,]
|
||||||
|
[timestamp] [3,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### All Batches:
|
||||||
|
0 {uid: 0, details: {"upgradeFrom":"v1.12.0","upgradeTo":"v1.13.0"}, stats: {"totalNbTasks":1,"status":{"succeeded":1},"types":{"upgradeDatabase":1},"indexUids":{}}, }
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batch to tasks mapping:
|
||||||
|
0 [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Status:
|
||||||
|
succeeded [0,]
|
||||||
|
failed []
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Kind:
|
||||||
|
"upgradeDatabase" [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Index Tasks:
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Enqueued At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Started At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### Batches Finished At:
|
||||||
|
[timestamp] [0,]
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
### File Store:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
@ -713,68 +713,70 @@ fn basic_get_stats() {
|
|||||||
let kind = index_creation_task("whalo", "fish");
|
let kind = index_creation_task("whalo", "fish");
|
||||||
let _task = index_scheduler.register(kind, None, false).unwrap();
|
let _task = index_scheduler.register(kind, None, false).unwrap();
|
||||||
|
|
||||||
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r###"
|
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r#"
|
||||||
{
|
{
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"catto": 1,
|
"catto": 1,
|
||||||
"doggo": 1,
|
"doggo": 1,
|
||||||
"whalo": 1
|
"whalo": 1
|
||||||
},
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"canceled": 0,
|
"canceled": 0,
|
||||||
"enqueued": 3,
|
"enqueued": 3,
|
||||||
"failed": 0,
|
"failed": 0,
|
||||||
"processing": 0,
|
"processing": 0,
|
||||||
"succeeded": 0
|
"succeeded": 0
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"documentAdditionOrUpdate": 0,
|
"documentAdditionOrUpdate": 0,
|
||||||
"documentDeletion": 0,
|
"documentDeletion": 0,
|
||||||
"documentEdition": 0,
|
"documentEdition": 0,
|
||||||
"dumpCreation": 0,
|
"dumpCreation": 0,
|
||||||
"indexCreation": 3,
|
"indexCreation": 3,
|
||||||
"indexDeletion": 0,
|
"indexDeletion": 0,
|
||||||
"indexSwap": 0,
|
"indexSwap": 0,
|
||||||
"indexUpdate": 0,
|
"indexUpdate": 0,
|
||||||
"settingsUpdate": 0,
|
"settingsUpdate": 0,
|
||||||
"snapshotCreation": 0,
|
"snapshotCreation": 0,
|
||||||
"taskCancelation": 0,
|
"taskCancelation": 0,
|
||||||
"taskDeletion": 0
|
"taskDeletion": 0,
|
||||||
}
|
"upgradeDatabase": 0
|
||||||
}
|
}
|
||||||
"###);
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
handle.advance_till([Start, BatchCreated]);
|
handle.advance_till([Start, BatchCreated]);
|
||||||
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r###"
|
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r#"
|
||||||
{
|
{
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"catto": 1,
|
"catto": 1,
|
||||||
"doggo": 1,
|
"doggo": 1,
|
||||||
"whalo": 1
|
"whalo": 1
|
||||||
},
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"canceled": 0,
|
"canceled": 0,
|
||||||
"enqueued": 2,
|
"enqueued": 2,
|
||||||
"failed": 0,
|
"failed": 0,
|
||||||
"processing": 1,
|
"processing": 1,
|
||||||
"succeeded": 0
|
"succeeded": 0
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"documentAdditionOrUpdate": 0,
|
"documentAdditionOrUpdate": 0,
|
||||||
"documentDeletion": 0,
|
"documentDeletion": 0,
|
||||||
"documentEdition": 0,
|
"documentEdition": 0,
|
||||||
"dumpCreation": 0,
|
"dumpCreation": 0,
|
||||||
"indexCreation": 3,
|
"indexCreation": 3,
|
||||||
"indexDeletion": 0,
|
"indexDeletion": 0,
|
||||||
"indexSwap": 0,
|
"indexSwap": 0,
|
||||||
"indexUpdate": 0,
|
"indexUpdate": 0,
|
||||||
"settingsUpdate": 0,
|
"settingsUpdate": 0,
|
||||||
"snapshotCreation": 0,
|
"snapshotCreation": 0,
|
||||||
"taskCancelation": 0,
|
"taskCancelation": 0,
|
||||||
"taskDeletion": 0
|
"taskDeletion": 0,
|
||||||
}
|
"upgradeDatabase": 0
|
||||||
}
|
}
|
||||||
"###);
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
handle.advance_till([
|
handle.advance_till([
|
||||||
InsideProcessBatch,
|
InsideProcessBatch,
|
||||||
@ -784,36 +786,37 @@ fn basic_get_stats() {
|
|||||||
Start,
|
Start,
|
||||||
BatchCreated,
|
BatchCreated,
|
||||||
]);
|
]);
|
||||||
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r###"
|
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r#"
|
||||||
{
|
{
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"catto": 1,
|
"catto": 1,
|
||||||
"doggo": 1,
|
"doggo": 1,
|
||||||
"whalo": 1
|
"whalo": 1
|
||||||
},
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"canceled": 0,
|
"canceled": 0,
|
||||||
"enqueued": 1,
|
"enqueued": 1,
|
||||||
"failed": 0,
|
"failed": 0,
|
||||||
"processing": 1,
|
"processing": 1,
|
||||||
"succeeded": 1
|
"succeeded": 1
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"documentAdditionOrUpdate": 0,
|
"documentAdditionOrUpdate": 0,
|
||||||
"documentDeletion": 0,
|
"documentDeletion": 0,
|
||||||
"documentEdition": 0,
|
"documentEdition": 0,
|
||||||
"dumpCreation": 0,
|
"dumpCreation": 0,
|
||||||
"indexCreation": 3,
|
"indexCreation": 3,
|
||||||
"indexDeletion": 0,
|
"indexDeletion": 0,
|
||||||
"indexSwap": 0,
|
"indexSwap": 0,
|
||||||
"indexUpdate": 0,
|
"indexUpdate": 0,
|
||||||
"settingsUpdate": 0,
|
"settingsUpdate": 0,
|
||||||
"snapshotCreation": 0,
|
"snapshotCreation": 0,
|
||||||
"taskCancelation": 0,
|
"taskCancelation": 0,
|
||||||
"taskDeletion": 0
|
"taskDeletion": 0,
|
||||||
}
|
"upgradeDatabase": 0
|
||||||
}
|
}
|
||||||
"###);
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
// now we make one more batch, the started_at field of the new tasks will be past `second_start_time`
|
// now we make one more batch, the started_at field of the new tasks will be past `second_start_time`
|
||||||
handle.advance_till([
|
handle.advance_till([
|
||||||
@ -824,36 +827,37 @@ fn basic_get_stats() {
|
|||||||
Start,
|
Start,
|
||||||
BatchCreated,
|
BatchCreated,
|
||||||
]);
|
]);
|
||||||
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r###"
|
snapshot!(json_string!(index_scheduler.get_stats().unwrap()), @r#"
|
||||||
{
|
{
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"catto": 1,
|
"catto": 1,
|
||||||
"doggo": 1,
|
"doggo": 1,
|
||||||
"whalo": 1
|
"whalo": 1
|
||||||
},
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"canceled": 0,
|
"canceled": 0,
|
||||||
"enqueued": 0,
|
"enqueued": 0,
|
||||||
"failed": 0,
|
"failed": 0,
|
||||||
"processing": 1,
|
"processing": 1,
|
||||||
"succeeded": 2
|
"succeeded": 2
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"documentAdditionOrUpdate": 0,
|
"documentAdditionOrUpdate": 0,
|
||||||
"documentDeletion": 0,
|
"documentDeletion": 0,
|
||||||
"documentEdition": 0,
|
"documentEdition": 0,
|
||||||
"dumpCreation": 0,
|
"dumpCreation": 0,
|
||||||
"indexCreation": 3,
|
"indexCreation": 3,
|
||||||
"indexDeletion": 0,
|
"indexDeletion": 0,
|
||||||
"indexSwap": 0,
|
"indexSwap": 0,
|
||||||
"indexUpdate": 0,
|
"indexUpdate": 0,
|
||||||
"settingsUpdate": 0,
|
"settingsUpdate": 0,
|
||||||
"snapshotCreation": 0,
|
"snapshotCreation": 0,
|
||||||
"taskCancelation": 0,
|
"taskCancelation": 0,
|
||||||
"taskDeletion": 0
|
"taskDeletion": 0,
|
||||||
}
|
"upgradeDatabase": 0
|
||||||
}
|
}
|
||||||
"###);
|
}
|
||||||
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -899,7 +903,7 @@ fn create_and_list_index() {
|
|||||||
|
|
||||||
index_scheduler.index("kefir").unwrap();
|
index_scheduler.index("kefir").unwrap();
|
||||||
let list = index_scheduler.get_paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap();
|
let list = index_scheduler.get_paginated_indexes_stats(&AuthFilter::default(), 0, 20).unwrap();
|
||||||
snapshot!(json_string!(list, { "[1][0][1].created_at" => "[date]", "[1][0][1].updated_at" => "[date]" }), @r#"
|
snapshot!(json_string!(list, { "[1][0][1].created_at" => "[date]", "[1][0][1].updated_at" => "[date]", "[1][0][1].used_database_size" => "[bytes]", "[1][0][1].database_size" => "[bytes]" }), @r#"
|
||||||
[
|
[
|
||||||
1,
|
1,
|
||||||
[
|
[
|
||||||
@ -907,8 +911,8 @@ fn create_and_list_index() {
|
|||||||
"kefir",
|
"kefir",
|
||||||
{
|
{
|
||||||
"number_of_documents": 0,
|
"number_of_documents": 0,
|
||||||
"database_size": 24576,
|
"database_size": "[bytes]",
|
||||||
"used_database_size": 8192,
|
"used_database_size": "[bytes]",
|
||||||
"primary_key": null,
|
"primary_key": null,
|
||||||
"field_distribution": {},
|
"field_distribution": {},
|
||||||
"created_at": "[date]",
|
"created_at": "[date]",
|
||||||
|
@ -6,6 +6,7 @@ use meili_snap::snapshot;
|
|||||||
use meilisearch_types::milli::obkv_to_json;
|
use meilisearch_types::milli::obkv_to_json;
|
||||||
use meilisearch_types::milli::update::IndexDocumentsMethod::*;
|
use meilisearch_types::milli::update::IndexDocumentsMethod::*;
|
||||||
use meilisearch_types::milli::update::Setting;
|
use meilisearch_types::milli::update::Setting;
|
||||||
|
use meilisearch_types::tasks::Kind;
|
||||||
use meilisearch_types::tasks::KindWithContent;
|
use meilisearch_types::tasks::KindWithContent;
|
||||||
|
|
||||||
use crate::insta_snapshot::snapshot_index_scheduler;
|
use crate::insta_snapshot::snapshot_index_scheduler;
|
||||||
@ -249,3 +250,78 @@ fn panic_in_process_batch_for_index_creation() {
|
|||||||
// No matter what happens in process_batch, the index_scheduler should be internally consistent
|
// No matter what happens in process_batch, the index_scheduler should be internally consistent
|
||||||
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "index_creation_failed");
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "index_creation_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn upgrade_failure() {
|
||||||
|
// By starting the index-scheduler at the v1.12.0 an upgrade task should be automatically enqueued
|
||||||
|
let (index_scheduler, mut handle) =
|
||||||
|
IndexScheduler::test_with_custom_config(vec![(1, FailureLocation::ProcessUpgrade)], |_| {
|
||||||
|
Some((1, 12, 0))
|
||||||
|
});
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "register_automatic_upgrade_task");
|
||||||
|
|
||||||
|
let kind = index_creation_task("catto", "mouse");
|
||||||
|
let _task = index_scheduler.register(kind, None, false).unwrap();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "registered_a_task_while_the_upgrade_task_is_enqueued");
|
||||||
|
|
||||||
|
handle.advance_one_failed_batch();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "upgrade_task_failed");
|
||||||
|
|
||||||
|
// We can still register tasks
|
||||||
|
let kind = index_creation_task("doggo", "bone");
|
||||||
|
let _task = index_scheduler.register(kind, None, false).unwrap();
|
||||||
|
|
||||||
|
// But the scheduler is down and won't process anything ever again
|
||||||
|
handle.scheduler_is_down();
|
||||||
|
|
||||||
|
// =====> After a restart is it still working as expected?
|
||||||
|
let (index_scheduler, mut handle) =
|
||||||
|
handle.restart(index_scheduler, true, vec![(1, FailureLocation::ProcessUpgrade)], |_| {
|
||||||
|
Some((1, 12, 0)) // the upgrade task should be rerun automatically and nothing else should be enqueued
|
||||||
|
});
|
||||||
|
|
||||||
|
handle.advance_one_failed_batch();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "upgrade_task_failed_again");
|
||||||
|
// We can still register tasks
|
||||||
|
let kind = index_creation_task("doggo", "bone");
|
||||||
|
let _task = index_scheduler.register(kind, None, false).unwrap();
|
||||||
|
// And the scheduler is still down and won't process anything ever again
|
||||||
|
handle.scheduler_is_down();
|
||||||
|
|
||||||
|
// =====> After a rerestart and without failure can we upgrade the indexes and process the tasks
|
||||||
|
let (index_scheduler, mut handle) =
|
||||||
|
handle.restart(index_scheduler, true, vec![], |_| Some((1, 12, 0)));
|
||||||
|
|
||||||
|
handle.advance_one_successful_batch();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "upgrade_task_succeeded");
|
||||||
|
// We can still register tasks
|
||||||
|
let kind = index_creation_task("girafo", "leaves");
|
||||||
|
let _task = index_scheduler.register(kind, None, false).unwrap();
|
||||||
|
// The scheduler is up and running
|
||||||
|
handle.advance_one_successful_batch();
|
||||||
|
handle.advance_one_successful_batch();
|
||||||
|
handle.advance_one_failed_batch(); // doggo already exists
|
||||||
|
handle.advance_one_successful_batch();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "after_processing_everything");
|
||||||
|
|
||||||
|
let (upgrade_tasks_ids, _) = index_scheduler
|
||||||
|
.get_task_ids_from_authorized_indexes(
|
||||||
|
&crate::Query { types: Some(vec![Kind::UpgradeDatabase]), ..Default::default() },
|
||||||
|
&Default::default(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
// When deleting the single upgrade task it should remove the associated batch
|
||||||
|
let _task = index_scheduler
|
||||||
|
.register(
|
||||||
|
KindWithContent::TaskDeletion {
|
||||||
|
query: String::from("types=upgradeDatabase"),
|
||||||
|
tasks: upgrade_tasks_ids,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
handle.advance_one_successful_batch();
|
||||||
|
snapshot!(snapshot_index_scheduler(&index_scheduler), name: "after_removing_the_upgrade_tasks");
|
||||||
|
}
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use big_s::S;
|
||||||
|
use crossbeam_channel::RecvTimeoutError;
|
||||||
use file_store::File;
|
use file_store::File;
|
||||||
use meilisearch_types::document_formats::DocumentFormatError;
|
use meilisearch_types::document_formats::DocumentFormatError;
|
||||||
use meilisearch_types::milli::update::IndexDocumentsMethod::ReplaceDocuments;
|
use meilisearch_types::milli::update::IndexDocumentsMethod::ReplaceDocuments;
|
||||||
|
use meilisearch_types::milli::update::IndexerConfig;
|
||||||
|
use meilisearch_types::tasks::KindWithContent;
|
||||||
|
use meilisearch_types::{versioning, VERSION_FILE_NAME};
|
||||||
|
use tempfile::{NamedTempFile, TempDir};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use Breakpoint::*;
|
||||||
|
|
||||||
use crate::insta_snapshot::snapshot_index_scheduler;
|
use crate::insta_snapshot::snapshot_index_scheduler;
|
||||||
use crate::{Error, IndexScheduler, IndexSchedulerOptions};
|
use crate::{Error, IndexScheduler, IndexSchedulerOptions};
|
||||||
@ -28,20 +36,13 @@ pub(crate) enum FailureLocation {
|
|||||||
InsideCreateBatch,
|
InsideCreateBatch,
|
||||||
InsideProcessBatch,
|
InsideProcessBatch,
|
||||||
PanicInsideProcessBatch,
|
PanicInsideProcessBatch,
|
||||||
|
ProcessUpgrade,
|
||||||
AcquiringWtxn,
|
AcquiringWtxn,
|
||||||
UpdatingTaskAfterProcessBatchSuccess { task_uid: u32 },
|
UpdatingTaskAfterProcessBatchSuccess { task_uid: u32 },
|
||||||
UpdatingTaskAfterProcessBatchFailure,
|
UpdatingTaskAfterProcessBatchFailure,
|
||||||
CommittingWtxn,
|
CommittingWtxn,
|
||||||
}
|
}
|
||||||
|
|
||||||
use big_s::S;
|
|
||||||
use crossbeam_channel::RecvTimeoutError;
|
|
||||||
use meilisearch_types::milli::update::IndexerConfig;
|
|
||||||
use meilisearch_types::tasks::KindWithContent;
|
|
||||||
use meilisearch_types::VERSION_FILE_NAME;
|
|
||||||
use tempfile::{NamedTempFile, TempDir};
|
|
||||||
use Breakpoint::*;
|
|
||||||
|
|
||||||
impl IndexScheduler {
|
impl IndexScheduler {
|
||||||
/// Blocks the thread until the test handle asks to progress to/through this breakpoint.
|
/// Blocks the thread until the test handle asks to progress to/through this breakpoint.
|
||||||
///
|
///
|
||||||
@ -55,7 +56,6 @@ impl IndexScheduler {
|
|||||||
/// As soon as we find it, the index scheduler is unblocked but then wait again on the call to
|
/// As soon as we find it, the index scheduler is unblocked but then wait again on the call to
|
||||||
/// `test_breakpoint_sdr.send(b, true)`. This message will only be able to send once the
|
/// `test_breakpoint_sdr.send(b, true)`. This message will only be able to send once the
|
||||||
/// test asks to progress to the next `(b2, false)`.
|
/// test asks to progress to the next `(b2, false)`.
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) fn breakpoint(&self, b: Breakpoint) {
|
pub(crate) fn breakpoint(&self, b: Breakpoint) {
|
||||||
// We send two messages. The first one will sync with the call
|
// We send two messages. The first one will sync with the call
|
||||||
// to `handle.wait_until(b)`. The second one will block until the
|
// to `handle.wait_until(b)`. The second one will block until the
|
||||||
@ -75,12 +75,13 @@ impl IndexScheduler {
|
|||||||
) -> (Self, IndexSchedulerHandle) {
|
) -> (Self, IndexSchedulerHandle) {
|
||||||
Self::test_with_custom_config(planned_failures, |config| {
|
Self::test_with_custom_config(planned_failures, |config| {
|
||||||
config.autobatching_enabled = autobatching_enabled;
|
config.autobatching_enabled = autobatching_enabled;
|
||||||
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn test_with_custom_config(
|
pub(crate) fn test_with_custom_config(
|
||||||
planned_failures: Vec<(usize, FailureLocation)>,
|
planned_failures: Vec<(usize, FailureLocation)>,
|
||||||
configuration: impl Fn(&mut IndexSchedulerOptions),
|
configuration: impl Fn(&mut IndexSchedulerOptions) -> Option<(u32, u32, u32)>,
|
||||||
) -> (Self, IndexSchedulerHandle) {
|
) -> (Self, IndexSchedulerHandle) {
|
||||||
let tempdir = TempDir::new().unwrap();
|
let tempdir = TempDir::new().unwrap();
|
||||||
let (sender, receiver) = crossbeam_channel::bounded(0);
|
let (sender, receiver) = crossbeam_channel::bounded(0);
|
||||||
@ -109,10 +110,17 @@ impl IndexScheduler {
|
|||||||
max_number_of_batched_tasks: usize::MAX,
|
max_number_of_batched_tasks: usize::MAX,
|
||||||
batched_tasks_size_limit: u64::MAX,
|
batched_tasks_size_limit: u64::MAX,
|
||||||
instance_features: Default::default(),
|
instance_features: Default::default(),
|
||||||
|
auto_upgrade: true, // Don't cost much and will ensure the happy path works
|
||||||
};
|
};
|
||||||
configuration(&mut options);
|
let version = configuration(&mut options).unwrap_or_else(|| {
|
||||||
|
(
|
||||||
|
versioning::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_MINOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_PATCH.parse().unwrap(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let index_scheduler = Self::new(options, sender, planned_failures).unwrap();
|
let index_scheduler = Self::new(options, version, sender, planned_failures).unwrap();
|
||||||
|
|
||||||
// To be 100% consistent between all test we're going to start the scheduler right now
|
// To be 100% consistent between all test we're going to start the scheduler right now
|
||||||
// and ensure it's in the expected starting state.
|
// and ensure it's in the expected starting state.
|
||||||
@ -224,6 +232,55 @@ pub struct IndexSchedulerHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IndexSchedulerHandle {
|
impl IndexSchedulerHandle {
|
||||||
|
/// Restarts the index-scheduler on the same database.
|
||||||
|
/// To use this function you must give back the index-scheduler that was given to you when
|
||||||
|
/// creating the handle the first time.
|
||||||
|
/// If the index-scheduler has been cloned in the meantime you must drop all copy otherwise
|
||||||
|
/// the function will panic.
|
||||||
|
pub(crate) fn restart(
|
||||||
|
self,
|
||||||
|
index_scheduler: IndexScheduler,
|
||||||
|
autobatching_enabled: bool,
|
||||||
|
planned_failures: Vec<(usize, FailureLocation)>,
|
||||||
|
configuration: impl Fn(&mut IndexSchedulerOptions) -> Option<(u32, u32, u32)>,
|
||||||
|
) -> (IndexScheduler, Self) {
|
||||||
|
drop(index_scheduler);
|
||||||
|
let Self { _tempdir: tempdir, index_scheduler, test_breakpoint_rcv, last_breakpoint: _ } =
|
||||||
|
self;
|
||||||
|
let env = index_scheduler.env.clone();
|
||||||
|
drop(index_scheduler);
|
||||||
|
|
||||||
|
// We must ensure that the `run` function has stopped running before restarting the index scheduler
|
||||||
|
loop {
|
||||||
|
match test_breakpoint_rcv.recv_timeout(Duration::from_secs(5)) {
|
||||||
|
Ok((_, true)) => continue,
|
||||||
|
Ok((b, false)) => {
|
||||||
|
panic!("Scheduler is not stopped and passed {b:?}")
|
||||||
|
}
|
||||||
|
Err(RecvTimeoutError::Timeout) => panic!("The indexing loop is stuck somewhere"),
|
||||||
|
Err(RecvTimeoutError::Disconnected) => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let closed = env.prepare_for_closing().wait_timeout(Duration::from_secs(5));
|
||||||
|
assert!(closed, "The index scheduler couldn't close itself, it seems like someone else is holding the env somewhere");
|
||||||
|
|
||||||
|
let (scheduler, mut handle) =
|
||||||
|
IndexScheduler::test_with_custom_config(planned_failures, |config| {
|
||||||
|
let version = configuration(config);
|
||||||
|
config.autobatching_enabled = autobatching_enabled;
|
||||||
|
config.version_file_path = tempdir.path().join(VERSION_FILE_NAME);
|
||||||
|
config.auth_path = tempdir.path().join("auth");
|
||||||
|
config.tasks_path = tempdir.path().join("db_path");
|
||||||
|
config.update_file_path = tempdir.path().join("file_store");
|
||||||
|
config.indexes_path = tempdir.path().join("indexes");
|
||||||
|
config.snapshots_path = tempdir.path().join("snapshots");
|
||||||
|
config.dumps_path = tempdir.path().join("dumps");
|
||||||
|
version
|
||||||
|
});
|
||||||
|
handle._tempdir = tempdir;
|
||||||
|
(scheduler, handle)
|
||||||
|
}
|
||||||
|
|
||||||
/// Advance the scheduler to the next tick.
|
/// Advance the scheduler to the next tick.
|
||||||
/// Panic
|
/// Panic
|
||||||
/// * If the scheduler is waiting for a task to be registered.
|
/// * If the scheduler is waiting for a task to be registered.
|
||||||
@ -349,4 +406,18 @@ impl IndexSchedulerHandle {
|
|||||||
}
|
}
|
||||||
self.advance_till([AfterProcessing]);
|
self.advance_till([AfterProcessing]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for one failed batch.
|
||||||
|
#[track_caller]
|
||||||
|
pub(crate) fn scheduler_is_down(&mut self) {
|
||||||
|
loop {
|
||||||
|
match self
|
||||||
|
.test_breakpoint_rcv
|
||||||
|
.recv_timeout(std::time::Duration::from_secs(1)) {
|
||||||
|
Ok((_, true)) => continue,
|
||||||
|
Ok((b, false)) => panic!("The scheduler was supposed to be down but successfully moved to the next breakpoint: {b:?}"),
|
||||||
|
Err(RecvTimeoutError::Timeout | RecvTimeoutError::Disconnected) => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
108
crates/index-scheduler/src/upgrade/mod.rs
Normal file
108
crates/index-scheduler/src/upgrade/mod.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
use anyhow::bail;
|
||||||
|
use meilisearch_types::heed::{Env, RwTxn};
|
||||||
|
use meilisearch_types::tasks::{Details, KindWithContent, Status, Task};
|
||||||
|
use meilisearch_types::versioning::{VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH};
|
||||||
|
use time::OffsetDateTime;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
use crate::queue::TaskQueue;
|
||||||
|
use crate::versioning::Versioning;
|
||||||
|
|
||||||
|
trait UpgradeIndexScheduler {
|
||||||
|
fn upgrade(&self, env: &Env, wtxn: &mut RwTxn, original: (u32, u32, u32))
|
||||||
|
-> anyhow::Result<()>;
|
||||||
|
fn target_version(&self) -> (u32, u32, u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upgrade_index_scheduler(
|
||||||
|
env: &Env,
|
||||||
|
versioning: &Versioning,
|
||||||
|
from: (u32, u32, u32),
|
||||||
|
to: (u32, u32, u32),
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let current_major = to.0;
|
||||||
|
let current_minor = to.1;
|
||||||
|
let current_patch = to.2;
|
||||||
|
|
||||||
|
let upgrade_functions: &[&dyn UpgradeIndexScheduler] = &[&V1_12_ToCurrent {}];
|
||||||
|
|
||||||
|
let start = match from {
|
||||||
|
(1, 12, _) => 0,
|
||||||
|
(major, minor, patch) => {
|
||||||
|
if major > current_major
|
||||||
|
|| (major == current_major && minor > current_minor)
|
||||||
|
|| (major == current_major && minor == current_minor && patch > current_patch)
|
||||||
|
{
|
||||||
|
bail!(
|
||||||
|
"Database version {major}.{minor}.{patch} is higher than the Meilisearch version {current_major}.{current_minor}.{current_patch}. Downgrade is not supported",
|
||||||
|
);
|
||||||
|
} else if major < 1 || (major == current_major && minor < 12) {
|
||||||
|
bail!(
|
||||||
|
"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{current_major}.{current_minor}.{current_patch}",
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
bail!("Unknown database version: v{major}.{minor}.{patch}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut current_version = from;
|
||||||
|
|
||||||
|
info!("Upgrading the task queue");
|
||||||
|
for upgrade in upgrade_functions[start..].iter() {
|
||||||
|
let target = upgrade.target_version();
|
||||||
|
info!(
|
||||||
|
"Upgrading from v{}.{}.{} to v{}.{}.{}",
|
||||||
|
from.0, from.1, from.2, current_version.0, current_version.1, current_version.2
|
||||||
|
);
|
||||||
|
let mut wtxn = env.write_txn()?;
|
||||||
|
upgrade.upgrade(env, &mut wtxn, from)?;
|
||||||
|
versioning.set_version(&mut wtxn, target)?;
|
||||||
|
wtxn.commit()?;
|
||||||
|
current_version = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut wtxn = env.write_txn()?;
|
||||||
|
let queue = TaskQueue::new(env, &mut wtxn)?;
|
||||||
|
let uid = queue.next_task_id(&wtxn)?;
|
||||||
|
queue.register(
|
||||||
|
&mut wtxn,
|
||||||
|
&Task {
|
||||||
|
uid,
|
||||||
|
batch_uid: None,
|
||||||
|
enqueued_at: OffsetDateTime::now_utc(),
|
||||||
|
started_at: None,
|
||||||
|
finished_at: None,
|
||||||
|
error: None,
|
||||||
|
canceled_by: None,
|
||||||
|
details: Some(Details::UpgradeDatabase { from, to }),
|
||||||
|
status: Status::Enqueued,
|
||||||
|
kind: KindWithContent::UpgradeDatabase { from },
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
wtxn.commit()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct V1_12_ToCurrent {}
|
||||||
|
|
||||||
|
impl UpgradeIndexScheduler for V1_12_ToCurrent {
|
||||||
|
fn upgrade(
|
||||||
|
&self,
|
||||||
|
_env: &Env,
|
||||||
|
_wtxn: &mut RwTxn,
|
||||||
|
_original: (u32, u32, u32),
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn target_version(&self) -> (u32, u32, u32) {
|
||||||
|
(
|
||||||
|
VERSION_MAJOR.parse().unwrap(),
|
||||||
|
VERSION_MINOR.parse().unwrap(),
|
||||||
|
VERSION_PATCH.parse().unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -234,6 +234,7 @@ pub fn swap_index_uid_in_task(task: &mut Task, swap: (&str, &str)) {
|
|||||||
K::TaskCancelation { .. }
|
K::TaskCancelation { .. }
|
||||||
| K::TaskDeletion { .. }
|
| K::TaskDeletion { .. }
|
||||||
| K::DumpCreation { .. }
|
| K::DumpCreation { .. }
|
||||||
|
| K::UpgradeDatabase { .. }
|
||||||
| K::SnapshotCreation => (),
|
| K::SnapshotCreation => (),
|
||||||
};
|
};
|
||||||
if let Some(Details::IndexSwap { swaps }) = &mut task.details {
|
if let Some(Details::IndexSwap { swaps }) = &mut task.details {
|
||||||
@ -547,6 +548,9 @@ impl crate::IndexScheduler {
|
|||||||
Details::Dump { dump_uid: _ } => {
|
Details::Dump { dump_uid: _ } => {
|
||||||
assert_eq!(kind.as_kind(), Kind::DumpCreation);
|
assert_eq!(kind.as_kind(), Kind::DumpCreation);
|
||||||
}
|
}
|
||||||
|
Details::UpgradeDatabase { from: _, to: _ } => {
|
||||||
|
assert_eq!(kind.as_kind(), Kind::UpgradeDatabase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
crates/index-scheduler/src/versioning.rs
Normal file
75
crates/index-scheduler/src/versioning.rs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
use crate::{upgrade::upgrade_index_scheduler, Result};
|
||||||
|
use meilisearch_types::{
|
||||||
|
heed::{types::Str, Database, Env, RoTxn, RwTxn},
|
||||||
|
milli::heed_codec::version::VersionCodec,
|
||||||
|
versioning,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The number of database used by queue itself
|
||||||
|
const NUMBER_OF_DATABASES: u32 = 1;
|
||||||
|
/// Database const names for the `IndexScheduler`.
|
||||||
|
mod db_name {
|
||||||
|
pub const VERSION: &str = "version";
|
||||||
|
}
|
||||||
|
mod entry_name {
|
||||||
|
pub const MAIN: &str = "main";
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Versioning {
|
||||||
|
pub version: Database<Str, VersionCodec>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Versioning {
|
||||||
|
pub(crate) const fn nb_db() -> u32 {
|
||||||
|
NUMBER_OF_DATABASES
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_version(&self, rtxn: &RoTxn) -> Result<Option<(u32, u32, u32)>> {
|
||||||
|
Ok(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_current_version(&self, wtxn: &mut RwTxn) -> Result<()> {
|
||||||
|
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.
|
||||||
|
pub(crate) fn new(env: &Env, db_version: (u32, u32, u32)) -> Result<Self> {
|
||||||
|
let mut wtxn = env.write_txn()?;
|
||||||
|
let version = env.create_database(&mut wtxn, Some(db_name::VERSION))?;
|
||||||
|
let this = Self { version };
|
||||||
|
let from = match this.get_version(&wtxn)? {
|
||||||
|
Some(version) => version,
|
||||||
|
// fresh DB: use the db version
|
||||||
|
None => {
|
||||||
|
this.set_version(&mut wtxn, db_version)?;
|
||||||
|
db_version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wtxn.commit()?;
|
||||||
|
|
||||||
|
let bin_major: u32 = versioning::VERSION_MAJOR.parse().unwrap();
|
||||||
|
let bin_minor: u32 = versioning::VERSION_MINOR.parse().unwrap();
|
||||||
|
let bin_patch: u32 = versioning::VERSION_PATCH.parse().unwrap();
|
||||||
|
let to = (bin_major, bin_minor, bin_patch);
|
||||||
|
|
||||||
|
if from != to {
|
||||||
|
upgrade_index_scheduler(env, &this, from, to)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we reach this point it means the upgrade process, if there was one is entirely finished
|
||||||
|
// we can safely say we reached the latest version of the index scheduler
|
||||||
|
let mut wtxn = env.write_txn()?;
|
||||||
|
this.set_current_version(&mut wtxn)?;
|
||||||
|
wtxn.commit()?;
|
||||||
|
|
||||||
|
Ok(this)
|
||||||
|
}
|
||||||
|
}
|
@ -371,7 +371,8 @@ VectorEmbeddingError , InvalidRequest , BAD_REQUEST ;
|
|||||||
NotFoundSimilarId , InvalidRequest , BAD_REQUEST ;
|
NotFoundSimilarId , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidDocumentEditionContext , InvalidRequest , BAD_REQUEST ;
|
InvalidDocumentEditionContext , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidDocumentEditionFunctionFilter , InvalidRequest , BAD_REQUEST ;
|
InvalidDocumentEditionFunctionFilter , InvalidRequest , BAD_REQUEST ;
|
||||||
EditDocumentsByFunctionError , InvalidRequest , BAD_REQUEST
|
EditDocumentsByFunctionError , InvalidRequest , BAD_REQUEST ;
|
||||||
|
CouldNotUpgrade , InvalidRequest , BAD_REQUEST
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCode for JoinError {
|
impl ErrorCode for JoinError {
|
||||||
|
@ -114,6 +114,10 @@ pub struct DetailsView {
|
|||||||
pub settings: Option<Box<Settings<Unchecked>>>,
|
pub settings: Option<Box<Settings<Unchecked>>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub swaps: Option<Vec<IndexSwap>>,
|
pub swaps: Option<Vec<IndexSwap>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub upgrade_from: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub upgrade_to: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DetailsView {
|
impl DetailsView {
|
||||||
@ -234,6 +238,18 @@ impl DetailsView {
|
|||||||
Some(left)
|
Some(left)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// We want the earliest version
|
||||||
|
upgrade_from: match (self.upgrade_from.clone(), other.upgrade_from.clone()) {
|
||||||
|
(None, None) => None,
|
||||||
|
(None, Some(from)) | (Some(from), None) => Some(from),
|
||||||
|
(Some(from), Some(_)) => Some(from),
|
||||||
|
},
|
||||||
|
// And the latest
|
||||||
|
upgrade_to: match (self.upgrade_to.clone(), other.upgrade_to.clone()) {
|
||||||
|
(None, None) => None,
|
||||||
|
(None, Some(to)) | (Some(to), None) => Some(to),
|
||||||
|
(Some(_), Some(to)) => Some(to),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,6 +327,11 @@ impl From<Details> for DetailsView {
|
|||||||
Details::IndexSwap { swaps } => {
|
Details::IndexSwap { swaps } => {
|
||||||
DetailsView { swaps: Some(swaps), ..Default::default() }
|
DetailsView { swaps: Some(swaps), ..Default::default() }
|
||||||
}
|
}
|
||||||
|
Details::UpgradeDatabase { from, to } => DetailsView {
|
||||||
|
upgrade_from: Some(format!("v{}.{}.{}", from.0, from.1, from.2)),
|
||||||
|
upgrade_to: Some(format!("v{}.{}.{}", to.0, to.1, to.2)),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use crate::batches::BatchId;
|
|||||||
use crate::error::ResponseError;
|
use crate::error::ResponseError;
|
||||||
use crate::keys::Key;
|
use crate::keys::Key;
|
||||||
use crate::settings::{Settings, Unchecked};
|
use crate::settings::{Settings, Unchecked};
|
||||||
use crate::InstanceUid;
|
use crate::{versioning, InstanceUid};
|
||||||
|
|
||||||
pub type TaskId = u32;
|
pub type TaskId = u32;
|
||||||
|
|
||||||
@ -50,6 +50,7 @@ impl Task {
|
|||||||
| SnapshotCreation
|
| SnapshotCreation
|
||||||
| TaskCancelation { .. }
|
| TaskCancelation { .. }
|
||||||
| TaskDeletion { .. }
|
| TaskDeletion { .. }
|
||||||
|
| UpgradeDatabase { .. }
|
||||||
| IndexSwap { .. } => None,
|
| IndexSwap { .. } => None,
|
||||||
DocumentAdditionOrUpdate { index_uid, .. }
|
DocumentAdditionOrUpdate { index_uid, .. }
|
||||||
| DocumentEdition { index_uid, .. }
|
| DocumentEdition { index_uid, .. }
|
||||||
@ -84,7 +85,8 @@ impl Task {
|
|||||||
| KindWithContent::TaskCancelation { .. }
|
| KindWithContent::TaskCancelation { .. }
|
||||||
| KindWithContent::TaskDeletion { .. }
|
| KindWithContent::TaskDeletion { .. }
|
||||||
| KindWithContent::DumpCreation { .. }
|
| KindWithContent::DumpCreation { .. }
|
||||||
| KindWithContent::SnapshotCreation => None,
|
| KindWithContent::SnapshotCreation
|
||||||
|
| KindWithContent::UpgradeDatabase { .. } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,6 +152,9 @@ pub enum KindWithContent {
|
|||||||
instance_uid: Option<InstanceUid>,
|
instance_uid: Option<InstanceUid>,
|
||||||
},
|
},
|
||||||
SnapshotCreation,
|
SnapshotCreation,
|
||||||
|
UpgradeDatabase {
|
||||||
|
from: (u32, u32, u32),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
||||||
@ -175,6 +180,7 @@ impl KindWithContent {
|
|||||||
KindWithContent::TaskDeletion { .. } => Kind::TaskDeletion,
|
KindWithContent::TaskDeletion { .. } => Kind::TaskDeletion,
|
||||||
KindWithContent::DumpCreation { .. } => Kind::DumpCreation,
|
KindWithContent::DumpCreation { .. } => Kind::DumpCreation,
|
||||||
KindWithContent::SnapshotCreation => Kind::SnapshotCreation,
|
KindWithContent::SnapshotCreation => Kind::SnapshotCreation,
|
||||||
|
KindWithContent::UpgradeDatabase { .. } => Kind::UpgradeDatabase,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +191,8 @@ impl KindWithContent {
|
|||||||
DumpCreation { .. }
|
DumpCreation { .. }
|
||||||
| SnapshotCreation
|
| SnapshotCreation
|
||||||
| TaskCancelation { .. }
|
| TaskCancelation { .. }
|
||||||
| TaskDeletion { .. } => vec![],
|
| TaskDeletion { .. }
|
||||||
|
| UpgradeDatabase { .. } => vec![],
|
||||||
DocumentAdditionOrUpdate { index_uid, .. }
|
DocumentAdditionOrUpdate { index_uid, .. }
|
||||||
| DocumentEdition { index_uid, .. }
|
| DocumentEdition { index_uid, .. }
|
||||||
| DocumentDeletion { index_uid, .. }
|
| DocumentDeletion { index_uid, .. }
|
||||||
@ -262,6 +269,14 @@ impl KindWithContent {
|
|||||||
}),
|
}),
|
||||||
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
||||||
KindWithContent::SnapshotCreation => None,
|
KindWithContent::SnapshotCreation => None,
|
||||||
|
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
|
||||||
|
from: (from.0, from.1, from.2),
|
||||||
|
to: (
|
||||||
|
versioning::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_MINOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_PATCH.parse().unwrap(),
|
||||||
|
),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +335,14 @@ impl KindWithContent {
|
|||||||
}),
|
}),
|
||||||
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
||||||
KindWithContent::SnapshotCreation => None,
|
KindWithContent::SnapshotCreation => None,
|
||||||
|
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
|
||||||
|
from: *from,
|
||||||
|
to: (
|
||||||
|
versioning::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_MINOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_PATCH.parse().unwrap(),
|
||||||
|
),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,6 +383,14 @@ impl From<&KindWithContent> for Option<Details> {
|
|||||||
}),
|
}),
|
||||||
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
|
||||||
KindWithContent::SnapshotCreation => None,
|
KindWithContent::SnapshotCreation => None,
|
||||||
|
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
|
||||||
|
from: *from,
|
||||||
|
to: (
|
||||||
|
versioning::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_MINOR.parse().unwrap(),
|
||||||
|
versioning::VERSION_PATCH.parse().unwrap(),
|
||||||
|
),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,6 +499,7 @@ pub enum Kind {
|
|||||||
TaskDeletion,
|
TaskDeletion,
|
||||||
DumpCreation,
|
DumpCreation,
|
||||||
SnapshotCreation,
|
SnapshotCreation,
|
||||||
|
UpgradeDatabase,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kind {
|
impl Kind {
|
||||||
@ -484,6 +516,7 @@ impl Kind {
|
|||||||
| Kind::TaskCancelation
|
| Kind::TaskCancelation
|
||||||
| Kind::TaskDeletion
|
| Kind::TaskDeletion
|
||||||
| Kind::DumpCreation
|
| Kind::DumpCreation
|
||||||
|
| Kind::UpgradeDatabase
|
||||||
| Kind::SnapshotCreation => false,
|
| Kind::SnapshotCreation => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,6 +536,7 @@ impl Display for Kind {
|
|||||||
Kind::TaskDeletion => write!(f, "taskDeletion"),
|
Kind::TaskDeletion => write!(f, "taskDeletion"),
|
||||||
Kind::DumpCreation => write!(f, "dumpCreation"),
|
Kind::DumpCreation => write!(f, "dumpCreation"),
|
||||||
Kind::SnapshotCreation => write!(f, "snapshotCreation"),
|
Kind::SnapshotCreation => write!(f, "snapshotCreation"),
|
||||||
|
Kind::UpgradeDatabase => write!(f, "upgradeDatabase"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,6 +568,8 @@ impl FromStr for Kind {
|
|||||||
Ok(Kind::DumpCreation)
|
Ok(Kind::DumpCreation)
|
||||||
} else if kind.eq_ignore_ascii_case("snapshotCreation") {
|
} else if kind.eq_ignore_ascii_case("snapshotCreation") {
|
||||||
Ok(Kind::SnapshotCreation)
|
Ok(Kind::SnapshotCreation)
|
||||||
|
} else if kind.eq_ignore_ascii_case("upgradeDatabase") {
|
||||||
|
Ok(Kind::UpgradeDatabase)
|
||||||
} else {
|
} else {
|
||||||
Err(ParseTaskKindError(kind.to_owned()))
|
Err(ParseTaskKindError(kind.to_owned()))
|
||||||
}
|
}
|
||||||
@ -607,6 +643,10 @@ pub enum Details {
|
|||||||
IndexSwap {
|
IndexSwap {
|
||||||
swaps: Vec<IndexSwap>,
|
swaps: Vec<IndexSwap>,
|
||||||
},
|
},
|
||||||
|
UpgradeDatabase {
|
||||||
|
from: (u32, u32, u32),
|
||||||
|
to: (u32, u32, u32),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Details {
|
impl Details {
|
||||||
@ -627,6 +667,7 @@ impl Details {
|
|||||||
Self::SettingsUpdate { .. }
|
Self::SettingsUpdate { .. }
|
||||||
| Self::IndexInfo { .. }
|
| Self::IndexInfo { .. }
|
||||||
| Self::Dump { .. }
|
| Self::Dump { .. }
|
||||||
|
| Self::UpgradeDatabase { .. }
|
||||||
| Self::IndexSwap { .. } => (),
|
| Self::IndexSwap { .. } => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +728,9 @@ pub fn serialize_duration<S: Serializer>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Details;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use super::{Details, Kind};
|
||||||
use crate::heed::types::SerdeJson;
|
use crate::heed::types::SerdeJson;
|
||||||
use crate::heed::{BytesDecode, BytesEncode};
|
use crate::heed::{BytesDecode, BytesEncode};
|
||||||
|
|
||||||
@ -703,4 +746,13 @@ mod tests {
|
|||||||
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
|
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
|
||||||
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
|
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn all_kind_can_be_from_str() {
|
||||||
|
for kind in enum_iterator::all::<Kind>() {
|
||||||
|
let s = kind.to_string();
|
||||||
|
let k = Kind::from_str(&s).map_err(|e| format!("Could not from_str {s}: {e}")).unwrap();
|
||||||
|
assert_eq!(kind, k, "{kind}.to_string() returned {s} which was parsed as {k}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,39 @@ use std::path::Path;
|
|||||||
/// The name of the file that contains the version of the database.
|
/// The name of the file that contains the version of the database.
|
||||||
pub const VERSION_FILE_NAME: &str = "VERSION";
|
pub const VERSION_FILE_NAME: &str = "VERSION";
|
||||||
|
|
||||||
static VERSION_MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
|
pub static VERSION_MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
|
||||||
static VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");
|
pub static VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");
|
||||||
static VERSION_PATCH: &str = env!("CARGO_PKG_VERSION_PATCH");
|
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
|
/// 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) -> io::Result<()> {
|
||||||
@ -24,18 +54,7 @@ pub fn create_version_file(
|
|||||||
fs::write(version_path, format!("{}.{}.{}", major, minor, patch))
|
fs::write(version_path, format!("{}.{}.{}", major, minor, patch))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures Meilisearch version is compatible with the database, returns an error versions mismatch.
|
pub fn get_version(db_path: &Path) -> Result<(u32, u32, u32), VersionFileError> {
|
||||||
pub fn check_version_file(db_path: &Path) -> anyhow::Result<()> {
|
|
||||||
let (major, minor, patch) = get_version(db_path)?;
|
|
||||||
|
|
||||||
if major != VERSION_MAJOR || minor != VERSION_MINOR {
|
|
||||||
return Err(VersionFileError::VersionMismatch { major, minor, patch }.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_version(db_path: &Path) -> Result<(String, String, String), VersionFileError> {
|
|
||||||
let version_path = db_path.join(VERSION_FILE_NAME);
|
let version_path = db_path.join(VERSION_FILE_NAME);
|
||||||
|
|
||||||
match fs::read_to_string(version_path) {
|
match fs::read_to_string(version_path) {
|
||||||
@ -47,11 +66,28 @@ pub fn get_version(db_path: &Path) -> Result<(String, String, String), VersionFi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_version(version: &str) -> Result<(String, String, String), VersionFileError> {
|
pub fn parse_version(version: &str) -> Result<(u32, u32, u32), VersionFileError> {
|
||||||
let version_components = version.split('.').collect::<Vec<_>>();
|
let version_components = version.trim().split('.').collect::<Vec<_>>();
|
||||||
let (major, minor, patch) = match &version_components[..] {
|
let (major, minor, patch) = match &version_components[..] {
|
||||||
[major, minor, patch] => (major.to_string(), minor.to_string(), patch.to_string()),
|
[major, minor, patch] => (
|
||||||
_ => return Err(VersionFileError::MalformedVersionFile),
|
major.parse().map_err(|e| VersionFileError::MalformedVersionFile {
|
||||||
|
context: format!("Could not parse the major: {e}"),
|
||||||
|
})?,
|
||||||
|
minor.parse().map_err(|e| VersionFileError::MalformedVersionFile {
|
||||||
|
context: format!("Could not parse the minor: {e}"),
|
||||||
|
})?,
|
||||||
|
patch.parse().map_err(|e| VersionFileError::MalformedVersionFile {
|
||||||
|
context: format!("Could not parse the patch: {e}"),
|
||||||
|
})?,
|
||||||
|
),
|
||||||
|
_ => {
|
||||||
|
return Err(VersionFileError::MalformedVersionFile {
|
||||||
|
context: format!(
|
||||||
|
"The version contains {} parts instead of 3 (major, minor and patch)",
|
||||||
|
version_components.len()
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok((major, minor, patch))
|
Ok((major, minor, patch))
|
||||||
}
|
}
|
||||||
@ -64,14 +100,18 @@ pub enum VersionFileError {
|
|||||||
env!("CARGO_PKG_VERSION").to_string()
|
env!("CARGO_PKG_VERSION").to_string()
|
||||||
)]
|
)]
|
||||||
MissingVersionFile,
|
MissingVersionFile,
|
||||||
#[error("Version file is corrupted and thus Meilisearch is unable to determine the version of the database.")]
|
#[error("Version file is corrupted and thus Meilisearch is unable to determine the version of the database. {context}")]
|
||||||
MalformedVersionFile,
|
MalformedVersionFile { context: String },
|
||||||
#[error(
|
#[error(
|
||||||
"Your database version ({major}.{minor}.{patch}) is incompatible with your current engine version ({}).\n\
|
"Your database version ({major}.{minor}.{patch}) is incompatible with your current engine version ({}).\n\
|
||||||
To migrate data between Meilisearch versions, please follow our guide on https://www.meilisearch.com/docs/learn/update_and_migration/updating.",
|
To migrate data between Meilisearch versions, please follow our guide on https://www.meilisearch.com/docs/learn/update_and_migration/updating.",
|
||||||
env!("CARGO_PKG_VERSION").to_string()
|
env!("CARGO_PKG_VERSION").to_string()
|
||||||
)]
|
)]
|
||||||
VersionMismatch { major: String, minor: String, patch: String },
|
VersionMismatch { major: u32, minor: u32, patch: u32 },
|
||||||
|
#[error("Database version {major}.{minor}.{patch} is higher than the Meilisearch version {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_PATCH}. Downgrade is not supported")]
|
||||||
|
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(transparent)]
|
#[error(transparent)]
|
||||||
IoError(#[from] std::io::Error),
|
IoError(#[from] std::io::Error),
|
||||||
|
@ -189,6 +189,7 @@ struct Infos {
|
|||||||
experimental_drop_search_after: usize,
|
experimental_drop_search_after: usize,
|
||||||
experimental_nb_searches_per_core: usize,
|
experimental_nb_searches_per_core: usize,
|
||||||
experimental_logs_mode: LogMode,
|
experimental_logs_mode: LogMode,
|
||||||
|
experimental_dumpless_upgrade: bool,
|
||||||
experimental_replication_parameters: bool,
|
experimental_replication_parameters: bool,
|
||||||
experimental_enable_logs_route: bool,
|
experimental_enable_logs_route: bool,
|
||||||
experimental_reduce_indexing_memory_usage: bool,
|
experimental_reduce_indexing_memory_usage: bool,
|
||||||
@ -235,6 +236,7 @@ impl Infos {
|
|||||||
experimental_drop_search_after,
|
experimental_drop_search_after,
|
||||||
experimental_nb_searches_per_core,
|
experimental_nb_searches_per_core,
|
||||||
experimental_logs_mode,
|
experimental_logs_mode,
|
||||||
|
experimental_dumpless_upgrade,
|
||||||
experimental_replication_parameters,
|
experimental_replication_parameters,
|
||||||
experimental_enable_logs_route,
|
experimental_enable_logs_route,
|
||||||
experimental_reduce_indexing_memory_usage,
|
experimental_reduce_indexing_memory_usage,
|
||||||
@ -296,6 +298,7 @@ impl Infos {
|
|||||||
experimental_drop_search_after: experimental_drop_search_after.into(),
|
experimental_drop_search_after: experimental_drop_search_after.into(),
|
||||||
experimental_nb_searches_per_core: experimental_nb_searches_per_core.into(),
|
experimental_nb_searches_per_core: experimental_nb_searches_per_core.into(),
|
||||||
experimental_logs_mode,
|
experimental_logs_mode,
|
||||||
|
experimental_dumpless_upgrade,
|
||||||
experimental_replication_parameters,
|
experimental_replication_parameters,
|
||||||
experimental_enable_logs_route: experimental_enable_logs_route | logs_route,
|
experimental_enable_logs_route: experimental_enable_logs_route | logs_route,
|
||||||
experimental_reduce_indexing_memory_usage,
|
experimental_reduce_indexing_memory_usage,
|
||||||
|
@ -34,11 +34,15 @@ use error::PayloadError;
|
|||||||
use extractors::payload::PayloadConfig;
|
use extractors::payload::PayloadConfig;
|
||||||
use index_scheduler::{IndexScheduler, IndexSchedulerOptions};
|
use index_scheduler::{IndexScheduler, IndexSchedulerOptions};
|
||||||
use meilisearch_auth::AuthController;
|
use meilisearch_auth::AuthController;
|
||||||
|
use meilisearch_types::milli::constants::VERSION_MAJOR;
|
||||||
use meilisearch_types::milli::documents::{DocumentsBatchBuilder, DocumentsBatchReader};
|
use meilisearch_types::milli::documents::{DocumentsBatchBuilder, DocumentsBatchReader};
|
||||||
use meilisearch_types::milli::update::{IndexDocumentsConfig, IndexDocumentsMethod};
|
use meilisearch_types::milli::update::{IndexDocumentsConfig, IndexDocumentsMethod};
|
||||||
use meilisearch_types::settings::apply_settings_to_builder;
|
use meilisearch_types::settings::apply_settings_to_builder;
|
||||||
use meilisearch_types::tasks::KindWithContent;
|
use meilisearch_types::tasks::KindWithContent;
|
||||||
use meilisearch_types::versioning::{check_version_file, create_current_version_file};
|
use meilisearch_types::versioning::{
|
||||||
|
create_current_version_file, get_version, update_version_file_for_dumpless_upgrade,
|
||||||
|
VersionFileError, VERSION_MINOR, VERSION_PATCH,
|
||||||
|
};
|
||||||
use meilisearch_types::{compression, milli, VERSION_FILE_NAME};
|
use meilisearch_types::{compression, milli, VERSION_FILE_NAME};
|
||||||
pub use option::Opt;
|
pub use option::Opt;
|
||||||
use option::ScheduleSnapshot;
|
use option::ScheduleSnapshot;
|
||||||
@ -206,13 +210,47 @@ enum OnFailure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<AuthController>)> {
|
pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<AuthController>)> {
|
||||||
|
let index_scheduler_opt = IndexSchedulerOptions {
|
||||||
|
version_file_path: opt.db_path.join(VERSION_FILE_NAME),
|
||||||
|
auth_path: opt.db_path.join("auth"),
|
||||||
|
tasks_path: opt.db_path.join("tasks"),
|
||||||
|
update_file_path: opt.db_path.join("update_files"),
|
||||||
|
indexes_path: opt.db_path.join("indexes"),
|
||||||
|
snapshots_path: opt.snapshot_dir.clone(),
|
||||||
|
dumps_path: opt.dump_dir.clone(),
|
||||||
|
webhook_url: opt.task_webhook_url.as_ref().map(|url| url.to_string()),
|
||||||
|
webhook_authorization_header: opt.task_webhook_authorization_header.clone(),
|
||||||
|
task_db_size: opt.max_task_db_size.as_u64() as usize,
|
||||||
|
index_base_map_size: opt.max_index_size.as_u64() as usize,
|
||||||
|
enable_mdb_writemap: opt.experimental_reduce_indexing_memory_usage,
|
||||||
|
indexer_config: Arc::new((&opt.indexer_options).try_into()?),
|
||||||
|
autobatching_enabled: true,
|
||||||
|
cleanup_enabled: !opt.experimental_replication_parameters,
|
||||||
|
max_number_of_tasks: 1_000_000,
|
||||||
|
max_number_of_batched_tasks: opt.experimental_max_number_of_batched_tasks,
|
||||||
|
batched_tasks_size_limit: opt.experimental_limit_batched_tasks_total_size,
|
||||||
|
index_growth_amount: byte_unit::Byte::from_str("10GiB").unwrap().as_u64() as usize,
|
||||||
|
index_count: DEFAULT_INDEX_COUNT,
|
||||||
|
instance_features: opt.to_instance_features(),
|
||||||
|
auto_upgrade: opt.experimental_dumpless_upgrade,
|
||||||
|
};
|
||||||
|
let bin_major: u32 = VERSION_MAJOR.parse().unwrap();
|
||||||
|
let bin_minor: u32 = VERSION_MINOR.parse().unwrap();
|
||||||
|
let bin_patch: u32 = VERSION_PATCH.parse().unwrap();
|
||||||
|
let binary_version = (bin_major, bin_minor, bin_patch);
|
||||||
|
|
||||||
let empty_db = is_empty_db(&opt.db_path);
|
let empty_db = is_empty_db(&opt.db_path);
|
||||||
let (index_scheduler, auth_controller) = if let Some(ref snapshot_path) = opt.import_snapshot {
|
let (index_scheduler, auth_controller) = if let Some(ref snapshot_path) = opt.import_snapshot {
|
||||||
let snapshot_path_exists = snapshot_path.exists();
|
let snapshot_path_exists = snapshot_path.exists();
|
||||||
// the db is empty and the snapshot exists, import it
|
// the db is empty and the snapshot exists, import it
|
||||||
if empty_db && snapshot_path_exists {
|
if empty_db && snapshot_path_exists {
|
||||||
match compression::from_tar_gz(snapshot_path, &opt.db_path) {
|
match compression::from_tar_gz(snapshot_path, &opt.db_path) {
|
||||||
Ok(()) => open_or_create_database_unchecked(opt, OnFailure::RemoveDb)?,
|
Ok(()) => open_or_create_database_unchecked(
|
||||||
|
opt,
|
||||||
|
index_scheduler_opt,
|
||||||
|
OnFailure::RemoveDb,
|
||||||
|
binary_version, // the db is empty
|
||||||
|
)?,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
std::fs::remove_dir_all(&opt.db_path)?;
|
std::fs::remove_dir_all(&opt.db_path)?;
|
||||||
return Err(e);
|
return Err(e);
|
||||||
@ -229,14 +267,18 @@ pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<
|
|||||||
bail!("snapshot doesn't exist at {}", snapshot_path.display())
|
bail!("snapshot doesn't exist at {}", snapshot_path.display())
|
||||||
// the snapshot and the db exist, and we can ignore the snapshot because of the ignore_snapshot_if_db_exists flag
|
// the snapshot and the db exist, and we can ignore the snapshot because of the ignore_snapshot_if_db_exists flag
|
||||||
} else {
|
} else {
|
||||||
open_or_create_database(opt, empty_db)?
|
open_or_create_database(opt, index_scheduler_opt, empty_db, binary_version)?
|
||||||
}
|
}
|
||||||
} else if let Some(ref path) = opt.import_dump {
|
} else if let Some(ref path) = opt.import_dump {
|
||||||
let src_path_exists = path.exists();
|
let src_path_exists = path.exists();
|
||||||
// the db is empty and the dump exists, import it
|
// the db is empty and the dump exists, import it
|
||||||
if empty_db && src_path_exists {
|
if empty_db && src_path_exists {
|
||||||
let (mut index_scheduler, mut auth_controller) =
|
let (mut index_scheduler, mut auth_controller) = open_or_create_database_unchecked(
|
||||||
open_or_create_database_unchecked(opt, OnFailure::RemoveDb)?;
|
opt,
|
||||||
|
index_scheduler_opt,
|
||||||
|
OnFailure::RemoveDb,
|
||||||
|
binary_version, // the db is empty
|
||||||
|
)?;
|
||||||
match import_dump(&opt.db_path, path, &mut index_scheduler, &mut auth_controller) {
|
match import_dump(&opt.db_path, path, &mut index_scheduler, &mut auth_controller) {
|
||||||
Ok(()) => (index_scheduler, auth_controller),
|
Ok(()) => (index_scheduler, auth_controller),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -256,10 +298,10 @@ pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<
|
|||||||
// the dump and the db exist and we can ignore the dump because of the ignore_dump_if_db_exists flag
|
// the dump and the db exist and we can ignore the dump because of the ignore_dump_if_db_exists flag
|
||||||
// or, the dump is missing but we can ignore that because of the ignore_missing_dump flag
|
// or, the dump is missing but we can ignore that because of the ignore_missing_dump flag
|
||||||
} else {
|
} else {
|
||||||
open_or_create_database(opt, empty_db)?
|
open_or_create_database(opt, index_scheduler_opt, empty_db, binary_version)?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
open_or_create_database(opt, empty_db)?
|
open_or_create_database(opt, index_scheduler_opt, empty_db, binary_version)?
|
||||||
};
|
};
|
||||||
|
|
||||||
// We create a loop in a thread that registers snapshotCreation tasks
|
// We create a loop in a thread that registers snapshotCreation tasks
|
||||||
@ -287,37 +329,15 @@ pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<
|
|||||||
/// Try to start the IndexScheduler and AuthController without checking the VERSION file or anything.
|
/// Try to start the IndexScheduler and AuthController without checking the VERSION file or anything.
|
||||||
fn open_or_create_database_unchecked(
|
fn open_or_create_database_unchecked(
|
||||||
opt: &Opt,
|
opt: &Opt,
|
||||||
|
index_scheduler_opt: IndexSchedulerOptions,
|
||||||
on_failure: OnFailure,
|
on_failure: OnFailure,
|
||||||
|
version: (u32, u32, u32),
|
||||||
) -> anyhow::Result<(IndexScheduler, AuthController)> {
|
) -> anyhow::Result<(IndexScheduler, AuthController)> {
|
||||||
// we don't want to create anything in the data.ms yet, thus we
|
// we don't want to create anything in the data.ms yet, thus we
|
||||||
// wrap our two builders in a closure that'll be executed later.
|
// wrap our two builders in a closure that'll be executed later.
|
||||||
let auth_controller = AuthController::new(&opt.db_path, &opt.master_key);
|
let auth_controller = AuthController::new(&opt.db_path, &opt.master_key);
|
||||||
let instance_features = opt.to_instance_features();
|
let index_scheduler_builder =
|
||||||
let index_scheduler_builder = || -> anyhow::Result<_> {
|
|| -> anyhow::Result<_> { Ok(IndexScheduler::new(index_scheduler_opt, version)?) };
|
||||||
Ok(IndexScheduler::new(IndexSchedulerOptions {
|
|
||||||
version_file_path: opt.db_path.join(VERSION_FILE_NAME),
|
|
||||||
auth_path: opt.db_path.join("auth"),
|
|
||||||
tasks_path: opt.db_path.join("tasks"),
|
|
||||||
update_file_path: opt.db_path.join("update_files"),
|
|
||||||
indexes_path: opt.db_path.join("indexes"),
|
|
||||||
snapshots_path: opt.snapshot_dir.clone(),
|
|
||||||
dumps_path: opt.dump_dir.clone(),
|
|
||||||
webhook_url: opt.task_webhook_url.as_ref().map(|url| url.to_string()),
|
|
||||||
webhook_authorization_header: opt.task_webhook_authorization_header.clone(),
|
|
||||||
task_db_size: opt.max_task_db_size.as_u64() as usize,
|
|
||||||
index_base_map_size: opt.max_index_size.as_u64() as usize,
|
|
||||||
enable_mdb_writemap: opt.experimental_reduce_indexing_memory_usage,
|
|
||||||
indexer_config: Arc::new((&opt.indexer_options).try_into()?),
|
|
||||||
autobatching_enabled: true,
|
|
||||||
cleanup_enabled: !opt.experimental_replication_parameters,
|
|
||||||
max_number_of_tasks: 1_000_000,
|
|
||||||
max_number_of_batched_tasks: opt.experimental_max_number_of_batched_tasks,
|
|
||||||
batched_tasks_size_limit: opt.experimental_limit_batched_tasks_total_size,
|
|
||||||
index_growth_amount: byte_unit::Byte::from_str("10GiB").unwrap().as_u64() as usize,
|
|
||||||
index_count: DEFAULT_INDEX_COUNT,
|
|
||||||
instance_features,
|
|
||||||
})?)
|
|
||||||
};
|
|
||||||
|
|
||||||
match (
|
match (
|
||||||
index_scheduler_builder(),
|
index_scheduler_builder(),
|
||||||
@ -334,16 +354,42 @@ 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)> {
|
||||||
|
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,
|
||||||
|
(db_major, db_minor, db_patch),
|
||||||
|
(bin_major, bin_minor, bin_patch),
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
return Err(VersionFileError::VersionMismatch {
|
||||||
|
major: db_major,
|
||||||
|
minor: db_minor,
|
||||||
|
patch: db_patch,
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((db_major, db_minor, db_patch))
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensure you're in a valid state and open the IndexScheduler + AuthController for you.
|
/// Ensure you're in a valid state and open the IndexScheduler + AuthController for you.
|
||||||
fn open_or_create_database(
|
fn open_or_create_database(
|
||||||
opt: &Opt,
|
opt: &Opt,
|
||||||
|
index_scheduler_opt: IndexSchedulerOptions,
|
||||||
empty_db: bool,
|
empty_db: bool,
|
||||||
|
binary_version: (u32, u32, u32),
|
||||||
) -> anyhow::Result<(IndexScheduler, AuthController)> {
|
) -> anyhow::Result<(IndexScheduler, AuthController)> {
|
||||||
if !empty_db {
|
let version = if !empty_db { check_version(opt, binary_version)? } else { binary_version };
|
||||||
check_version_file(&opt.db_path)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
open_or_create_database_unchecked(opt, OnFailure::KeepDb)
|
open_or_create_database_unchecked(opt, index_scheduler_opt, OnFailure::KeepDb, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_dump(
|
fn import_dump(
|
||||||
|
@ -49,6 +49,7 @@ const MEILI_IGNORE_DUMP_IF_DB_EXISTS: &str = "MEILI_IGNORE_DUMP_IF_DB_EXISTS";
|
|||||||
const MEILI_DUMP_DIR: &str = "MEILI_DUMP_DIR";
|
const MEILI_DUMP_DIR: &str = "MEILI_DUMP_DIR";
|
||||||
const MEILI_LOG_LEVEL: &str = "MEILI_LOG_LEVEL";
|
const MEILI_LOG_LEVEL: &str = "MEILI_LOG_LEVEL";
|
||||||
const MEILI_EXPERIMENTAL_LOGS_MODE: &str = "MEILI_EXPERIMENTAL_LOGS_MODE";
|
const MEILI_EXPERIMENTAL_LOGS_MODE: &str = "MEILI_EXPERIMENTAL_LOGS_MODE";
|
||||||
|
const MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE: &str = "MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE";
|
||||||
const MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS: &str = "MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS";
|
const MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS: &str = "MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS";
|
||||||
const MEILI_EXPERIMENTAL_ENABLE_LOGS_ROUTE: &str = "MEILI_EXPERIMENTAL_ENABLE_LOGS_ROUTE";
|
const MEILI_EXPERIMENTAL_ENABLE_LOGS_ROUTE: &str = "MEILI_EXPERIMENTAL_ENABLE_LOGS_ROUTE";
|
||||||
const MEILI_EXPERIMENTAL_CONTAINS_FILTER: &str = "MEILI_EXPERIMENTAL_CONTAINS_FILTER";
|
const MEILI_EXPERIMENTAL_CONTAINS_FILTER: &str = "MEILI_EXPERIMENTAL_CONTAINS_FILTER";
|
||||||
@ -400,6 +401,13 @@ pub struct Opt {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub experimental_logs_mode: LogMode,
|
pub experimental_logs_mode: LogMode,
|
||||||
|
|
||||||
|
/// Experimental dumpless upgrade. For more information, see: <https://github.com/orgs/meilisearch/discussions/804>
|
||||||
|
///
|
||||||
|
/// When set, Meilisearch will auto-update its database without using a dump.
|
||||||
|
#[clap(long, env = MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE, default_value_t)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub experimental_dumpless_upgrade: bool,
|
||||||
|
|
||||||
/// Experimental logs route feature. For more information,
|
/// Experimental logs route feature. For more information,
|
||||||
/// see: <https://github.com/orgs/meilisearch/discussions/721>
|
/// see: <https://github.com/orgs/meilisearch/discussions/721>
|
||||||
///
|
///
|
||||||
@ -535,6 +543,7 @@ impl Opt {
|
|||||||
experimental_drop_search_after,
|
experimental_drop_search_after,
|
||||||
experimental_nb_searches_per_core,
|
experimental_nb_searches_per_core,
|
||||||
experimental_logs_mode,
|
experimental_logs_mode,
|
||||||
|
experimental_dumpless_upgrade,
|
||||||
experimental_enable_logs_route,
|
experimental_enable_logs_route,
|
||||||
experimental_replication_parameters,
|
experimental_replication_parameters,
|
||||||
experimental_reduce_indexing_memory_usage,
|
experimental_reduce_indexing_memory_usage,
|
||||||
@ -608,6 +617,10 @@ impl Opt {
|
|||||||
MEILI_EXPERIMENTAL_LOGS_MODE,
|
MEILI_EXPERIMENTAL_LOGS_MODE,
|
||||||
experimental_logs_mode.to_string(),
|
experimental_logs_mode.to_string(),
|
||||||
);
|
);
|
||||||
|
export_to_env_if_not_present(
|
||||||
|
MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE,
|
||||||
|
experimental_dumpless_upgrade.to_string(),
|
||||||
|
);
|
||||||
export_to_env_if_not_present(
|
export_to_env_if_not_present(
|
||||||
MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS,
|
MEILI_EXPERIMENTAL_REPLICATION_PARAMETERS,
|
||||||
experimental_replication_parameters.to_string(),
|
experimental_replication_parameters.to_string(),
|
||||||
|
@ -912,14 +912,14 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let params = "types=createIndex";
|
let params = "types=createIndex";
|
||||||
let err = deserr_query_params::<TaskDeletionOrCancelationQuery>(params).unwrap_err();
|
let err = deserr_query_params::<TaskDeletionOrCancelationQuery>(params).unwrap_err();
|
||||||
snapshot!(meili_snap::json_string!(err), @r###"
|
snapshot!(meili_snap::json_string!(err), @r#"
|
||||||
{
|
{
|
||||||
"message": "Invalid value in parameter `types`: `createIndex` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
|
"message": "Invalid value in parameter `types`: `createIndex` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`, `upgradeDatabase`.",
|
||||||
"code": "invalid_task_types",
|
"code": "invalid_task_types",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
||||||
}
|
}
|
||||||
"###);
|
"#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
1
crates/meilisearch/src/upgrade/mod.rs
Normal file
1
crates/meilisearch/src/upgrade/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -42,7 +42,7 @@ async fn batch_bad_types() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(json_string!(response), @r#"
|
snapshot!(json_string!(response), @r#"
|
||||||
{
|
{
|
||||||
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
|
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`, `upgradeDatabase`.",
|
||||||
"code": "invalid_task_types",
|
"code": "invalid_task_types",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
||||||
|
@ -14,6 +14,7 @@ mod snapshot;
|
|||||||
mod stats;
|
mod stats;
|
||||||
mod swap_indexes;
|
mod swap_indexes;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
|
mod upgrade;
|
||||||
mod vector;
|
mod vector;
|
||||||
|
|
||||||
// Tests are isolated by features in different modules to allow better readability, test
|
// Tests are isolated by features in different modules to allow better readability, test
|
||||||
|
@ -95,36 +95,36 @@ async fn task_bad_types() {
|
|||||||
|
|
||||||
let (response, code) = server.tasks_filter("types=doggo").await;
|
let (response, code) = server.tasks_filter("types=doggo").await;
|
||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(json_string!(response), @r###"
|
snapshot!(json_string!(response), @r#"
|
||||||
{
|
{
|
||||||
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
|
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`, `upgradeDatabase`.",
|
||||||
"code": "invalid_task_types",
|
"code": "invalid_task_types",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
||||||
}
|
}
|
||||||
"###);
|
"#);
|
||||||
|
|
||||||
let (response, code) = server.cancel_tasks("types=doggo").await;
|
let (response, code) = server.cancel_tasks("types=doggo").await;
|
||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(json_string!(response), @r###"
|
snapshot!(json_string!(response), @r#"
|
||||||
{
|
{
|
||||||
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
|
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`, `upgradeDatabase`.",
|
||||||
"code": "invalid_task_types",
|
"code": "invalid_task_types",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
||||||
}
|
}
|
||||||
"###);
|
"#);
|
||||||
|
|
||||||
let (response, code) = server.delete_tasks("types=doggo").await;
|
let (response, code) = server.delete_tasks("types=doggo").await;
|
||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(json_string!(response), @r###"
|
snapshot!(json_string!(response), @r#"
|
||||||
{
|
{
|
||||||
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
|
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentEdition`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`, `upgradeDatabase`.",
|
||||||
"code": "invalid_task_types",
|
"code": "invalid_task_types",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
|
||||||
}
|
}
|
||||||
"###);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
87
crates/meilisearch/tests/upgrade/mod.rs
Normal file
87
crates/meilisearch/tests/upgrade/mod.rs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
mod v1_12;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
use std::{fs, io};
|
||||||
|
|
||||||
|
use meili_snap::snapshot;
|
||||||
|
use meilisearch::Opt;
|
||||||
|
|
||||||
|
use crate::common::{default_settings, Server};
|
||||||
|
|
||||||
|
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||||
|
fs::create_dir_all(&dst)?;
|
||||||
|
for entry in fs::read_dir(src)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let ty = entry.file_type()?;
|
||||||
|
if ty.is_dir() {
|
||||||
|
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||||
|
} else {
|
||||||
|
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn malformed_version_file() {
|
||||||
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
let default_settings = default_settings(temp.path());
|
||||||
|
let db_path = default_settings.db_path.clone();
|
||||||
|
std::fs::create_dir_all(&db_path).unwrap();
|
||||||
|
std::fs::write(db_path.join("VERSION"), "kefir").unwrap();
|
||||||
|
let options = Opt { experimental_dumpless_upgrade: true, ..default_settings };
|
||||||
|
let err = Server::new_with_options(options).await.map(|_| ()).unwrap_err();
|
||||||
|
snapshot!(err, @"Version file is corrupted and thus Meilisearch is unable to determine the version of the database. The version contains 1 parts instead of 3 (major, minor and patch)");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn version_too_old() {
|
||||||
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
let default_settings = default_settings(temp.path());
|
||||||
|
let db_path = default_settings.db_path.clone();
|
||||||
|
std::fs::create_dir_all(&db_path).unwrap();
|
||||||
|
std::fs::write(db_path.join("VERSION"), "1.11.9999").unwrap();
|
||||||
|
let options = Opt { experimental_dumpless_upgrade: true, ..default_settings };
|
||||||
|
let err = Server::new_with_options(options).await.map(|_| ()).unwrap_err();
|
||||||
|
snapshot!(err, @"Database version 1.11.9999 is too old for the experimental dumpless upgrade feature. Please generate a dump using the v1.11.9999 and import it in the v1.13.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn version_requires_downgrade() {
|
||||||
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
let default_settings = default_settings(temp.path());
|
||||||
|
let db_path = default_settings.db_path.clone();
|
||||||
|
std::fs::create_dir_all(&db_path).unwrap();
|
||||||
|
let major = meilisearch_types::versioning::VERSION_MAJOR;
|
||||||
|
let minor = meilisearch_types::versioning::VERSION_MINOR;
|
||||||
|
let patch = meilisearch_types::versioning::VERSION_PATCH.parse::<u32>().unwrap() + 1;
|
||||||
|
std::fs::write(db_path.join("VERSION"), format!("{major}.{minor}.{patch}")).unwrap();
|
||||||
|
let options = Opt { experimental_dumpless_upgrade: true, ..default_settings };
|
||||||
|
let err = Server::new_with_options(options).await.map(|_| ()).unwrap_err();
|
||||||
|
snapshot!(err, @"Database version 1.13.1 is higher than the Meilisearch version 1.13.0. Downgrade is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn upgrade_to_the_current_version() {
|
||||||
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
let server = Server::new_with_options(default_settings(temp.path())).await.unwrap();
|
||||||
|
drop(server);
|
||||||
|
|
||||||
|
let server = Server::new_with_options(Opt {
|
||||||
|
experimental_dumpless_upgrade: true,
|
||||||
|
..default_settings(temp.path())
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
// The upgrade tasks should NOT be spawned => task queue is empty
|
||||||
|
let (tasks, _status) = server.tasks().await;
|
||||||
|
snapshot!(tasks, @r#"
|
||||||
|
{
|
||||||
|
"results": [],
|
||||||
|
"total": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"from": null,
|
||||||
|
"next": null
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
1
crates/meilisearch/tests/upgrade/v1_12/mod.rs
Normal file
1
crates/meilisearch/tests/upgrade/v1_12/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
mod v1_12_0;
|
@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"displayedAttributes": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"searchableAttributes": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"filterableAttributes": [
|
||||||
|
"age",
|
||||||
|
"surname"
|
||||||
|
],
|
||||||
|
"sortableAttributes": [
|
||||||
|
"age"
|
||||||
|
],
|
||||||
|
"rankingRules": [
|
||||||
|
"words",
|
||||||
|
"typo",
|
||||||
|
"proximity",
|
||||||
|
"attribute",
|
||||||
|
"sort",
|
||||||
|
"exactness"
|
||||||
|
],
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
],
|
||||||
|
"nonSeparatorTokens": [],
|
||||||
|
"separatorTokens": [],
|
||||||
|
"dictionary": [],
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"distinctAttribute": null,
|
||||||
|
"proximityPrecision": "byWord",
|
||||||
|
"typoTolerance": {
|
||||||
|
"enabled": true,
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4,
|
||||||
|
"twoTypos": 9
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99,
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
},
|
||||||
|
"embedders": {},
|
||||||
|
"searchCutoffMs": 8000,
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fra"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"facetSearch": true,
|
||||||
|
"prefixSearch": "indexingTime"
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"hits": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "kefir",
|
||||||
|
"surname": [
|
||||||
|
"kef",
|
||||||
|
"kefkef",
|
||||||
|
"kefirounet",
|
||||||
|
"boubou"
|
||||||
|
],
|
||||||
|
"age": 1.4,
|
||||||
|
"description": "kefir est un petit chien blanc très mignon"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "",
|
||||||
|
"processingTimeMs": "[duration]",
|
||||||
|
"limit": 20,
|
||||||
|
"offset": 0,
|
||||||
|
"estimatedTotalHits": 1
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [],
|
||||||
|
"total": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"from": null,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,505 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"upgradeDatabase": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 5,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.016307263S",
|
||||||
|
"startedAt": "2025-01-16T16:53:19.913351957Z",
|
||||||
|
"finishedAt": "2025-01-16T16:53:19.92965922Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 23,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 24,
|
||||||
|
"next": 4
|
||||||
|
}
|
@ -0,0 +1,505 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"upgradeDatabase": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 5,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.016307263S",
|
||||||
|
"startedAt": "2025-01-16T16:53:19.913351957Z",
|
||||||
|
"finishedAt": "2025-01-16T16:53:19.92965922Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 23,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 24,
|
||||||
|
"next": 4
|
||||||
|
}
|
@ -0,0 +1,505 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"upgradeDatabase": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 5,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.016307263S",
|
||||||
|
"startedAt": "2025-01-16T16:53:19.913351957Z",
|
||||||
|
"finishedAt": "2025-01-16T16:53:19.92965922Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 23,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 24,
|
||||||
|
"next": 4
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 10,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 18,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 18,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 10,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [],
|
||||||
|
"total": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"from": null,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,397 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 25,
|
||||||
|
"batchUid": 24,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "upgradeDatabase",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"batchUid": 23,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:38:57.000009177Z",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"batchUid": 22,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:22.53917994Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"batchUid": 21,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Document doesn't have a `id` attribute: `{\"age\":1.4}`.",
|
||||||
|
"code": "missing_document_id",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#missing_document_id"
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:04.115475071Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"batchUid": 20,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "The primary key inference failed as the engine did not find any field ending with `id` in its name. Please specify the primary key manually using the `primaryKey` query parameter.",
|
||||||
|
"code": "index_primary_key_no_candidate_found",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#index_primary_key_no_candidate_found"
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:35:53.625718309Z",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"batchUid": 19,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:50:52.862223877Z",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.618121963Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.596815611Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"batchUid": 17,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:53.498618093Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"batchUid": 16,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:48.426597451Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"batchUid": 15,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:42.414346511Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"batchUid": 14,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:03.079292487Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"batchUid": 13,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:18:43.280901282Z",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"batchUid": 12,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:02:52.527382964Z",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"batchUid": 11,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:01:14.100316617Z",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:29.188815062Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"batchUid": 9,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:15.759501709Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"batchUid": 8,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:59:42.727292501Z",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"batchUid": 7,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:58:41.203145044Z",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"batchUid": 6,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:54:51.927866243Z",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 24,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 25,
|
||||||
|
"next": 5
|
||||||
|
}
|
@ -0,0 +1,397 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 25,
|
||||||
|
"batchUid": 24,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "upgradeDatabase",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"batchUid": 23,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:38:57.000009177Z",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"batchUid": 22,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:22.53917994Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"batchUid": 21,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Document doesn't have a `id` attribute: `{\"age\":1.4}`.",
|
||||||
|
"code": "missing_document_id",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#missing_document_id"
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:04.115475071Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"batchUid": 20,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "The primary key inference failed as the engine did not find any field ending with `id` in its name. Please specify the primary key manually using the `primaryKey` query parameter.",
|
||||||
|
"code": "index_primary_key_no_candidate_found",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#index_primary_key_no_candidate_found"
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:35:53.625718309Z",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"batchUid": 19,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:50:52.862223877Z",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.618121963Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.596815611Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"batchUid": 17,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:53.498618093Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"batchUid": 16,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:48.426597451Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"batchUid": 15,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:42.414346511Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"batchUid": 14,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:03.079292487Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"batchUid": 13,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:18:43.280901282Z",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"batchUid": 12,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:02:52.527382964Z",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"batchUid": 11,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:01:14.100316617Z",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:29.188815062Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"batchUid": 9,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:15.759501709Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"batchUid": 8,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:59:42.727292501Z",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"batchUid": 7,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:58:41.203145044Z",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"batchUid": 6,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:54:51.927866243Z",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 24,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 25,
|
||||||
|
"next": 5
|
||||||
|
}
|
@ -0,0 +1,397 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 25,
|
||||||
|
"batchUid": 24,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "upgradeDatabase",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"batchUid": 23,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:38:57.000009177Z",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"batchUid": 22,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:22.53917994Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"batchUid": 21,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Document doesn't have a `id` attribute: `{\"age\":1.4}`.",
|
||||||
|
"code": "missing_document_id",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#missing_document_id"
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:04.115475071Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"batchUid": 20,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "The primary key inference failed as the engine did not find any field ending with `id` in its name. Please specify the primary key manually using the `primaryKey` query parameter.",
|
||||||
|
"code": "index_primary_key_no_candidate_found",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#index_primary_key_no_candidate_found"
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:35:53.625718309Z",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"batchUid": 19,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:50:52.862223877Z",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.618121963Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.596815611Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"batchUid": 17,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:53.498618093Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"batchUid": 16,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:48.426597451Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"batchUid": 15,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:42.414346511Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"batchUid": 14,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:03.079292487Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"batchUid": 13,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:18:43.280901282Z",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"batchUid": 12,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:02:52.527382964Z",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"batchUid": 11,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:01:14.100316617Z",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:29.188815062Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"batchUid": 9,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:15.759501709Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"batchUid": 8,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:59:42.727292501Z",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"batchUid": 7,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:58:41.203145044Z",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"batchUid": 6,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:54:51.927866243Z",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 24,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 25,
|
||||||
|
"next": 5
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 10,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"batchUid": 1,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"batchUid": 0,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:45:16.003570092Z",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"batchUid": 1,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"batchUid": 0,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:45:16.003570092Z",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"batchUid": 1,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"batchUid": 0,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:45:16.003570092Z",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 2,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 1,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 18,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 18,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1,
|
||||||
|
"limit": 20,
|
||||||
|
"from": 10,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,624 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"upgradeDatabase": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"failed": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"indexDeletion": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0,
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 2,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1,
|
||||||
|
"canceled": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1,
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"taskCancelation": 1
|
||||||
|
},
|
||||||
|
"indexUids": {}
|
||||||
|
},
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"mieli": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 5,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.016307263S",
|
||||||
|
"startedAt": "2025-01-16T16:53:19.913351957Z",
|
||||||
|
"finishedAt": "2025-01-16T16:53:19.92965922Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 4,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.087655941S",
|
||||||
|
"startedAt": "2025-01-16T16:52:32.631145531Z",
|
||||||
|
"finishedAt": "2025-01-16T16:52:32.718801472Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 3,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"sortableAttributes": [
|
||||||
|
"age"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.007593573S",
|
||||||
|
"startedAt": "2025-01-16T16:47:53.677901409Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:53.685494982Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 2,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"filterableAttributes": [
|
||||||
|
"age",
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"settingsUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.017769760S",
|
||||||
|
"startedAt": "2025-01-16T16:47:41.211587682Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:41.229357442Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.066095506S",
|
||||||
|
"startedAt": "2025-01-16T16:47:10.217299609Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:10.283395115Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"progress": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"totalNbTasks": 1,
|
||||||
|
"status": {
|
||||||
|
"succeeded": 1
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"documentAdditionOrUpdate": 1
|
||||||
|
},
|
||||||
|
"indexUids": {
|
||||||
|
"kefir": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 25,
|
||||||
|
"limit": 1000,
|
||||||
|
"from": 24,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,505 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": 25,
|
||||||
|
"batchUid": 24,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "upgradeDatabase",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"upgradeFrom": "v1.12.0",
|
||||||
|
"upgradeTo": "v1.13.0"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 24,
|
||||||
|
"batchUid": 23,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.004146631S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:38:57.000009177Z",
|
||||||
|
"startedAt": "2025-01-23T11:38:57.012591321Z",
|
||||||
|
"finishedAt": "2025-01-23T11:38:57.016737952Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 23,
|
||||||
|
"batchUid": 22,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.102738497S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:22.53917994Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:22.551906856Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:22.654645353Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 22,
|
||||||
|
"batchUid": 21,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Document doesn't have a `id` attribute: `{\"age\":1.4}`.",
|
||||||
|
"code": "missing_document_id",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#missing_document_id"
|
||||||
|
},
|
||||||
|
"duration": "PT0.005108474S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:36:04.115475071Z",
|
||||||
|
"startedAt": "2025-01-23T11:36:04.132670526Z",
|
||||||
|
"finishedAt": "2025-01-23T11:36:04.137779Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 21,
|
||||||
|
"batchUid": 20,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "The primary key inference failed as the engine did not find any field ending with `id` in its name. Please specify the primary key manually using the `primaryKey` query parameter.",
|
||||||
|
"code": "index_primary_key_no_candidate_found",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#index_primary_key_no_candidate_found"
|
||||||
|
},
|
||||||
|
"duration": "PT0.027954894S",
|
||||||
|
"enqueuedAt": "2025-01-23T11:35:53.625718309Z",
|
||||||
|
"startedAt": "2025-01-23T11:35:53.631082795Z",
|
||||||
|
"finishedAt": "2025-01-23T11:35:53.659037689Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 20,
|
||||||
|
"batchUid": 19,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "indexDeletion",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"deletedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.006903297S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:50:52.862223877Z",
|
||||||
|
"startedAt": "2025-01-20T11:50:52.874106134Z",
|
||||||
|
"finishedAt": "2025-01-20T11:50:52.881009431Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 19,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 1,
|
||||||
|
"canceledTasks": 1,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.618121963Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 18,
|
||||||
|
"batchUid": 18,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "canceled",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": 19,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 0
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000481257S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:48:04.596815611Z",
|
||||||
|
"startedAt": "2025-01-20T11:48:04.92820416Z",
|
||||||
|
"finishedAt": "2025-01-20T11:48:04.928685417Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 17,
|
||||||
|
"batchUid": 17,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000407005S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:53.498618093Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:53.509403957Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:53.509810962Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 16,
|
||||||
|
"batchUid": 16,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing%2Cenqueued"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000403716S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:48.426597451Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:48.430653005Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:48.431056721Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 15,
|
||||||
|
"batchUid": 15,
|
||||||
|
"indexUid": null,
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "taskCancelation",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"matchedTasks": 0,
|
||||||
|
"canceledTasks": 0,
|
||||||
|
"originalFilter": "?statuses=processing"
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.000417016S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:42.414346511Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:42.429678617Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:42.430095633Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 14,
|
||||||
|
"batchUid": 14,
|
||||||
|
"indexUid": "mieli",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 19547,
|
||||||
|
"indexedDocuments": 19546
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT12.086284842S",
|
||||||
|
"enqueuedAt": "2025-01-20T11:47:03.079292487Z",
|
||||||
|
"startedAt": "2025-01-20T11:47:03.092181576Z",
|
||||||
|
"finishedAt": "2025-01-20T11:47:15.178466418Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 13,
|
||||||
|
"batchUid": 13,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"localizedAttributes": [
|
||||||
|
{
|
||||||
|
"attributePatterns": [
|
||||||
|
"description"
|
||||||
|
],
|
||||||
|
"locales": [
|
||||||
|
"fr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.011506614S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:18:43.280901282Z",
|
||||||
|
"startedAt": "2025-01-16T17:18:43.29334923Z",
|
||||||
|
"finishedAt": "2025-01-16T17:18:43.304855844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 12,
|
||||||
|
"batchUid": 12,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"sortFacetValuesBy": {
|
||||||
|
"*": "alpha",
|
||||||
|
"age": "count"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007640163S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:02:52.527382964Z",
|
||||||
|
"startedAt": "2025-01-16T17:02:52.539749853Z",
|
||||||
|
"finishedAt": "2025-01-16T17:02:52.547390016Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 11,
|
||||||
|
"batchUid": 11,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"searchCutoffMs": 8000
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007307840S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:01:14.100316617Z",
|
||||||
|
"startedAt": "2025-01-16T17:01:14.112756687Z",
|
||||||
|
"finishedAt": "2025-01-16T17:01:14.120064527Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 10,
|
||||||
|
"batchUid": 10,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 99
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007391353S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:29.188815062Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:29.201180268Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:29.208571621Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 9,
|
||||||
|
"batchUid": 9,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"faceting": {
|
||||||
|
"maxValuesPerFacet": 100
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"maxTotalHits": 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007445825S",
|
||||||
|
"enqueuedAt": "2025-01-16T17:00:15.759501709Z",
|
||||||
|
"startedAt": "2025-01-16T17:00:15.77629445Z",
|
||||||
|
"finishedAt": "2025-01-16T17:00:15.783740275Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 8,
|
||||||
|
"batchUid": 8,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
},
|
||||||
|
"disableOnWords": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"disableOnAttributes": [
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.012020083S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:59:42.727292501Z",
|
||||||
|
"startedAt": "2025-01-16T16:59:42.744086671Z",
|
||||||
|
"finishedAt": "2025-01-16T16:59:42.756106754Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 7,
|
||||||
|
"batchUid": 7,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"typoTolerance": {
|
||||||
|
"minWordSizeForTypos": {
|
||||||
|
"oneTypo": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007440092S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:58:41.203145044Z",
|
||||||
|
"startedAt": "2025-01-16T16:58:41.2155771Z",
|
||||||
|
"finishedAt": "2025-01-16T16:58:41.223017192Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 6,
|
||||||
|
"batchUid": 6,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"synonyms": {
|
||||||
|
"boubou": [
|
||||||
|
"kefir"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007565161S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:54:51.927866243Z",
|
||||||
|
"startedAt": "2025-01-16T16:54:51.940332781Z",
|
||||||
|
"finishedAt": "2025-01-16T16:54:51.947897942Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 5,
|
||||||
|
"batchUid": 5,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"stopWords": [
|
||||||
|
"le",
|
||||||
|
"un"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.016307263S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:53:19.900781991Z",
|
||||||
|
"startedAt": "2025-01-16T16:53:19.913351957Z",
|
||||||
|
"finishedAt": "2025-01-16T16:53:19.92965922Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 4,
|
||||||
|
"batchUid": 4,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.087655941S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:52:32.618659861Z",
|
||||||
|
"startedAt": "2025-01-16T16:52:32.631145531Z",
|
||||||
|
"finishedAt": "2025-01-16T16:52:32.718801472Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 3,
|
||||||
|
"batchUid": 3,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"sortableAttributes": [
|
||||||
|
"age"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.007593573S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:47:53.665616298Z",
|
||||||
|
"startedAt": "2025-01-16T16:47:53.677901409Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:53.685494982Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 2,
|
||||||
|
"batchUid": 2,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"filterableAttributes": [
|
||||||
|
"age",
|
||||||
|
"surname"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.017769760S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:47:41.194872913Z",
|
||||||
|
"startedAt": "2025-01-16T16:47:41.211587682Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:41.229357442Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 1,
|
||||||
|
"batchUid": 1,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.066095506S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:47:10.200537203Z",
|
||||||
|
"startedAt": "2025-01-16T16:47:10.217299609Z",
|
||||||
|
"finishedAt": "2025-01-16T16:47:10.283395115Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": 0,
|
||||||
|
"batchUid": 0,
|
||||||
|
"indexUid": "kefir",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "documentAdditionOrUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"receivedDocuments": 1,
|
||||||
|
"indexedDocuments": 1
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "PT0.111055654S",
|
||||||
|
"enqueuedAt": "2025-01-16T16:45:16.003570092Z",
|
||||||
|
"startedAt": "2025-01-16T16:45:16.020248085Z",
|
||||||
|
"finishedAt": "2025-01-16T16:45:16.131303739Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 26,
|
||||||
|
"limit": 1000,
|
||||||
|
"from": 25,
|
||||||
|
"next": null
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "Kefir",
|
||||||
|
"description": "My little kefirino key",
|
||||||
|
"key": "760c6345918b5ab1d251c1a3e8f9666547628a710d91f6b1d558ba944ef15746",
|
||||||
|
"uid": "9a77a636-e4e2-4f1a-93ac-978c368fd596",
|
||||||
|
"actions": [
|
||||||
|
"stats.get",
|
||||||
|
"documents.*"
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"expiresAt": null,
|
||||||
|
"createdAt": "2025-01-16T14:43:20.863318893Z",
|
||||||
|
"updatedAt": "[date]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Default Search API Key",
|
||||||
|
"description": "Use it to search from the frontend",
|
||||||
|
"key": "4d9376547ed779a05dde416148e7e98bd47530e28c500be674c9e60b2accb814",
|
||||||
|
"uid": "dc699ff0-a053-4956-a46a-912e51b3316b",
|
||||||
|
"actions": [
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"expiresAt": null,
|
||||||
|
"createdAt": "2025-01-16T14:24:46.264041777Z",
|
||||||
|
"updatedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offset": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"total": 2
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
source: crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "kefir",
|
||||||
|
"description": "the patou",
|
||||||
|
"key": "4d9376547ed779a05dde416148e7e98bd47530e28c500be674c9e60b2accb814",
|
||||||
|
"uid": "dc699ff0-a053-4956-a46a-912e51b3316b",
|
||||||
|
"actions": [
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"expiresAt": null,
|
||||||
|
"createdAt": "2025-01-16T14:24:46.264041777Z",
|
||||||
|
"updatedAt": "[date]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offset": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"total": 1
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
1.12.0
|
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/auth/data.mdb
Normal file
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/auth/data.mdb
Normal file
Binary file not shown.
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/auth/lock.mdb
Normal file
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/auth/lock.mdb
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
34ebe3d9-306d-4ead-885d-65d33b4bd60a
|
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/tasks/data.mdb
Normal file
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/tasks/data.mdb
Normal file
Binary file not shown.
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/tasks/lock.mdb
Normal file
BIN
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.ms/tasks/lock.mdb
Normal file
Binary file not shown.
268
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
Normal file
268
crates/meilisearch/tests/upgrade/v1_12/v1_12_0.rs
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
// This test is the first test of the dumpless upgrade.
|
||||||
|
// It must test pretty much all the features of meilisearch because the other tests will only tests
|
||||||
|
// the new features they introduced.
|
||||||
|
|
||||||
|
use manifest_dir_macros::exist_relative_path;
|
||||||
|
use meili_snap::{json_string, snapshot};
|
||||||
|
use meilisearch::Opt;
|
||||||
|
|
||||||
|
use crate::common::{default_settings, Server, Value};
|
||||||
|
use crate::json;
|
||||||
|
use crate::upgrade::copy_dir_all;
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn import_v1_12_0() {
|
||||||
|
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();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We must ensure that the keys database is still working:
|
||||||
|
/// 1. Check its content
|
||||||
|
/// 2. Ensure we can still query the keys
|
||||||
|
/// 3. Ensure we can still update the keys
|
||||||
|
async fn check_the_keys(server: &Server) {
|
||||||
|
// All the api keys are still present
|
||||||
|
let (keys, _) = server.list_api_keys("").await;
|
||||||
|
snapshot!(json_string!(keys, { ".results[].updatedAt" => "[date]" }), name: "list_all_keys");
|
||||||
|
|
||||||
|
// We can still query the keys
|
||||||
|
let (by_uid, _) = server.get_api_key("9a77a636-e4e2-4f1a-93ac-978c368fd596").await;
|
||||||
|
let (by_key, _) = server
|
||||||
|
.get_api_key("760c6345918b5ab1d251c1a3e8f9666547628a710d91f6b1d558ba944ef15746")
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(by_uid, by_key);
|
||||||
|
snapshot!(json_string!(by_uid, { ".updatedAt" => "[date]" }), @r#"
|
||||||
|
{
|
||||||
|
"name": "Kefir",
|
||||||
|
"description": "My little kefirino key",
|
||||||
|
"key": "760c6345918b5ab1d251c1a3e8f9666547628a710d91f6b1d558ba944ef15746",
|
||||||
|
"uid": "9a77a636-e4e2-4f1a-93ac-978c368fd596",
|
||||||
|
"actions": [
|
||||||
|
"stats.get",
|
||||||
|
"documents.*"
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"kefir"
|
||||||
|
],
|
||||||
|
"expiresAt": null,
|
||||||
|
"createdAt": "2025-01-16T14:43:20.863318893Z",
|
||||||
|
"updatedAt": "[date]"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Remove a key
|
||||||
|
let (_value, status) = server.delete_api_key("9a77a636-e4e2-4f1a-93ac-978c368fd596").await;
|
||||||
|
snapshot!(status, @"204 No Content");
|
||||||
|
|
||||||
|
// Update a key
|
||||||
|
let (value, _) = server
|
||||||
|
.patch_api_key(
|
||||||
|
"dc699ff0-a053-4956-a46a-912e51b3316b",
|
||||||
|
json!({ "name": "kefir", "description": "the patou" }),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
snapshot!(json_string!(value, { ".updatedAt" => "[date]" }), @r#"
|
||||||
|
{
|
||||||
|
"name": "kefir",
|
||||||
|
"description": "the patou",
|
||||||
|
"key": "4d9376547ed779a05dde416148e7e98bd47530e28c500be674c9e60b2accb814",
|
||||||
|
"uid": "dc699ff0-a053-4956-a46a-912e51b3316b",
|
||||||
|
"actions": [
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"expiresAt": null,
|
||||||
|
"createdAt": "2025-01-16T14:24:46.264041777Z",
|
||||||
|
"updatedAt": "[date]"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Everything worked
|
||||||
|
let (keys, _) = server.list_api_keys("").await;
|
||||||
|
snapshot!(json_string!(keys, { ".results[].updatedAt" => "[date]" }), name: "list_all_keys_after_removing_kefir");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We must ensure the index-scheduler database is still working:
|
||||||
|
/// 1. We can query the indexes and their metadata
|
||||||
|
/// 2. The upgrade task has been spawned and has been processed (wait for it to finish or it'll be flaky)
|
||||||
|
/// 3. Snapshot the whole queue, the tasks and batches should always be the same after update
|
||||||
|
/// 4. Query the batches and tasks on all filters => the databases should still works
|
||||||
|
/// 5. Ensure we can still update the queue
|
||||||
|
/// 5.1. Delete tasks until a batch is removed
|
||||||
|
/// 5.2. Enqueue a new task
|
||||||
|
/// 5.3. Create an index
|
||||||
|
async fn check_the_index_scheduler(server: &Server) {
|
||||||
|
// All the indexes are still present
|
||||||
|
let (indexes, _) = server.list_indexes(None, None).await;
|
||||||
|
snapshot!(indexes, @r#"
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"uid": "kefir",
|
||||||
|
"createdAt": "2025-01-16T16:45:16.020663157Z",
|
||||||
|
"updatedAt": "2025-01-23T11:36:22.634859166Z",
|
||||||
|
"primaryKey": "id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offset": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"total": 1
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
// And their metadata are still right
|
||||||
|
let (stats, _) = server.stats().await;
|
||||||
|
snapshot!(stats, @r#"
|
||||||
|
{
|
||||||
|
"databaseSize": 438272,
|
||||||
|
"lastUpdate": "2025-01-23T11:36:22.634859166Z",
|
||||||
|
"indexes": {
|
||||||
|
"kefir": {
|
||||||
|
"numberOfDocuments": 1,
|
||||||
|
"isIndexing": false,
|
||||||
|
"fieldDistribution": {
|
||||||
|
"age": 1,
|
||||||
|
"description": 1,
|
||||||
|
"id": 1,
|
||||||
|
"name": 1,
|
||||||
|
"surname": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Wait until the upgrade has been applied to all indexes to avoid flakyness
|
||||||
|
let (tasks, _) = server.tasks_filter("types=upgradeDatabase&limit=1").await;
|
||||||
|
server.wait_task(Value(tasks["results"][0].clone()).uid()).await.succeeded();
|
||||||
|
|
||||||
|
// Tasks and batches should still work
|
||||||
|
// We rewrite the first task for all calls because it may be the upgrade database with unknown dates and duration.
|
||||||
|
// The other tasks should NOT change
|
||||||
|
let (tasks, _) = server.tasks_filter("limit=1000").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "the_whole_task_queue_once_everything_has_been_processed");
|
||||||
|
let (batches, _) = server.batches_filter("limit=1000").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "the_whole_batch_queue_once_everything_has_been_processed");
|
||||||
|
|
||||||
|
// Tests all the tasks query parameters
|
||||||
|
let (tasks, _) = server.tasks_filter("uids=10").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_uids_equal_10");
|
||||||
|
let (tasks, _) = server.tasks_filter("batchUids=10").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_batchUids_equal_10");
|
||||||
|
let (tasks, _) = server.tasks_filter("statuses=canceled").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_statuses_equal_canceled");
|
||||||
|
// types has already been tested above to retrieve the upgrade database
|
||||||
|
let (tasks, _) = server.tasks_filter("canceledBy=19").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_canceledBy_equal_19");
|
||||||
|
let (tasks, _) = server.tasks_filter("beforeEnqueuedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_beforeEnqueuedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (tasks, _) = server.tasks_filter("afterEnqueuedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_afterEnqueuedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (tasks, _) = server.tasks_filter("beforeStartedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_beforeStartedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (tasks, _) = server.tasks_filter("afterStartedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_afterStartedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (tasks, _) = server.tasks_filter("beforeFinishedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_beforeFinishedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (tasks, _) = server.tasks_filter("afterFinishedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(tasks, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "tasks_filter_afterFinishedAt_equal_2025-01-16T16_47_41");
|
||||||
|
|
||||||
|
// Tests all the batches query parameters
|
||||||
|
let (batches, _) = server.batches_filter("uids=10").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_uids_equal_10");
|
||||||
|
let (batches, _) = server.batches_filter("batchUids=10").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_batchUids_equal_10");
|
||||||
|
let (batches, _) = server.batches_filter("statuses=canceled").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_statuses_equal_canceled");
|
||||||
|
// types has already been tested above to retrieve the upgrade database
|
||||||
|
let (batches, _) = server.batches_filter("canceledBy=19").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_canceledBy_equal_19");
|
||||||
|
let (batches, _) = server.batches_filter("beforeEnqueuedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_beforeEnqueuedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (batches, _) = server.batches_filter("afterEnqueuedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_afterEnqueuedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (batches, _) = server.batches_filter("beforeStartedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_beforeStartedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (batches, _) = server.batches_filter("afterStartedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_afterStartedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (batches, _) = server.batches_filter("beforeFinishedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_beforeFinishedAt_equal_2025-01-16T16_47_41");
|
||||||
|
let (batches, _) = server.batches_filter("afterFinishedAt=2025-01-16T16:47:41Z").await;
|
||||||
|
snapshot!(json_string!(batches, { ".results[0].duration" => "[duration]", ".results[0].enqueuedAt" => "[date]", ".results[0].startedAt" => "[date]", ".results[0].finishedAt" => "[date]" }), name: "batches_filter_afterFinishedAt_equal_2025-01-16T16_47_41");
|
||||||
|
|
||||||
|
let (stats, _) = server.stats().await;
|
||||||
|
snapshot!(stats, @r#"
|
||||||
|
{
|
||||||
|
"databaseSize": 438272,
|
||||||
|
"lastUpdate": "2025-01-23T11:36:22.634859166Z",
|
||||||
|
"indexes": {
|
||||||
|
"kefir": {
|
||||||
|
"numberOfDocuments": 1,
|
||||||
|
"isIndexing": false,
|
||||||
|
"fieldDistribution": {
|
||||||
|
"age": 1,
|
||||||
|
"description": 1,
|
||||||
|
"id": 1,
|
||||||
|
"name": 1,
|
||||||
|
"surname": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
let index = server.index("kefir");
|
||||||
|
let (stats, _) = index.stats().await;
|
||||||
|
snapshot!(stats, @r#"
|
||||||
|
{
|
||||||
|
"numberOfDocuments": 1,
|
||||||
|
"isIndexing": false,
|
||||||
|
"fieldDistribution": {
|
||||||
|
"age": 1,
|
||||||
|
"description": 1,
|
||||||
|
"id": 1,
|
||||||
|
"name": 1,
|
||||||
|
"surname": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Delete all the tasks of a specific batch
|
||||||
|
let (task, _) = server.delete_tasks("batchUids=10").await;
|
||||||
|
server.wait_task(task.uid()).await.succeeded();
|
||||||
|
|
||||||
|
let (tasks, _) = server.tasks_filter("batchUids=10").await;
|
||||||
|
snapshot!(tasks, name: "task_by_batchUids_after_deletion");
|
||||||
|
let (tasks, _) = server.batches_filter("batchUids=10").await;
|
||||||
|
snapshot!(tasks, name: "batch_by_batchUids_after_deletion");
|
||||||
|
|
||||||
|
let index = server.index("kefirausaurus");
|
||||||
|
let (task, _) = index.create(Some("kefid")).await;
|
||||||
|
server.wait_task(task.uid()).await.succeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensuring the index roughly works with filter and sort.
|
||||||
|
/// More specific test will be made for the next versions everytime they updates a feature
|
||||||
|
async fn check_the_index_features(server: &Server) {
|
||||||
|
let kefir = server.index("kefir");
|
||||||
|
|
||||||
|
let (settings, _) = kefir.settings().await;
|
||||||
|
snapshot!(settings, name: "kefir_settings");
|
||||||
|
|
||||||
|
let (results, _status) =
|
||||||
|
kefir.search_post(json!({ "sort": ["age:asc"], "filter": "surname = kefirounet" })).await;
|
||||||
|
snapshot!(results, name: "search_with_sort_and_filter");
|
||||||
|
}
|
@ -187,7 +187,7 @@ fn export_a_dump(
|
|||||||
db_path: PathBuf,
|
db_path: PathBuf,
|
||||||
dump_dir: PathBuf,
|
dump_dir: PathBuf,
|
||||||
skip_enqueued_tasks: bool,
|
skip_enqueued_tasks: bool,
|
||||||
detected_version: (String, String, String),
|
detected_version: (u32, u32, u32),
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
let started_at = OffsetDateTime::now_utc();
|
let started_at = OffsetDateTime::now_utc();
|
||||||
|
|
||||||
@ -253,12 +253,7 @@ fn export_a_dump(
|
|||||||
if status == Status::Enqueued {
|
if status == Status::Enqueued {
|
||||||
let content_file = file_store.get_update(content_file_uuid)?;
|
let content_file = file_store.get_update(content_file_uuid)?;
|
||||||
|
|
||||||
if (
|
if (detected_version.0, detected_version.1, detected_version.2) < (1, 12, 0) {
|
||||||
detected_version.0.as_str(),
|
|
||||||
detected_version.1.as_str(),
|
|
||||||
detected_version.2.as_str(),
|
|
||||||
) < ("1", "12", "0")
|
|
||||||
{
|
|
||||||
eprintln!("Dumping the enqueued tasks reading them in obkv format...");
|
eprintln!("Dumping the enqueued tasks reading them in obkv format...");
|
||||||
let reader =
|
let reader =
|
||||||
DocumentsBatchReader::from_reader(content_file).with_context(|| {
|
DocumentsBatchReader::from_reader(content_file).with_context(|| {
|
||||||
@ -303,7 +298,7 @@ fn export_a_dump(
|
|||||||
for result in index_mapping.iter(&rtxn)? {
|
for result in index_mapping.iter(&rtxn)? {
|
||||||
let (uid, uuid) = result?;
|
let (uid, uuid) = result?;
|
||||||
let index_path = db_path.join("indexes").join(uuid.to_string());
|
let index_path = db_path.join("indexes").join(uuid.to_string());
|
||||||
let index = Index::new(EnvOpenOptions::new(), &index_path).with_context(|| {
|
let index = Index::new(EnvOpenOptions::new(), &index_path, false).with_context(|| {
|
||||||
format!("While trying to open the index at path {:?}", index_path.display())
|
format!("While trying to open the index at path {:?}", index_path.display())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ use crate::upgrade::v1_11::v1_10_to_v1_11;
|
|||||||
|
|
||||||
pub struct OfflineUpgrade {
|
pub struct OfflineUpgrade {
|
||||||
pub db_path: PathBuf,
|
pub db_path: PathBuf,
|
||||||
pub current_version: (String, String, String),
|
pub current_version: (u32, u32, u32),
|
||||||
pub target_version: (String, String, String),
|
pub target_version: (u32, u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OfflineUpgrade {
|
impl OfflineUpgrade {
|
||||||
@ -50,7 +50,7 @@ impl OfflineUpgrade {
|
|||||||
|
|
||||||
let upgrade_list = [
|
let upgrade_list = [
|
||||||
(
|
(
|
||||||
v1_9_to_v1_10 as fn(&Path, &str, &str, &str) -> Result<(), anyhow::Error>,
|
v1_9_to_v1_10 as fn(&Path, u32, u32, u32) -> Result<(), anyhow::Error>,
|
||||||
"1",
|
"1",
|
||||||
"10",
|
"10",
|
||||||
"0",
|
"0",
|
||||||
@ -62,18 +62,14 @@ impl OfflineUpgrade {
|
|||||||
|
|
||||||
let no_upgrade: usize = upgrade_list.len();
|
let no_upgrade: usize = upgrade_list.len();
|
||||||
|
|
||||||
let (current_major, current_minor, current_patch) = &self.current_version;
|
let (current_major, current_minor, current_patch) = self.current_version;
|
||||||
|
|
||||||
let start_at = match (
|
let start_at = match (current_major, current_minor, current_patch) {
|
||||||
current_major.as_str(),
|
(1, 9, _) => 0,
|
||||||
current_minor.as_str(),
|
(1, 10, _) => 1,
|
||||||
current_patch.as_str(),
|
(1, 11, _) => 2,
|
||||||
) {
|
(1, 12, 0..=2) => 3,
|
||||||
("1", "9", _) => 0,
|
(1, 12, 3..=5) => no_upgrade,
|
||||||
("1", "10", _) => 1,
|
|
||||||
("1", "11", _) => 2,
|
|
||||||
("1", "12", "0" | "1" | "2") => 3,
|
|
||||||
("1", "12", "3" | "4" | "5") => no_upgrade,
|
|
||||||
_ => {
|
_ => {
|
||||||
bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from versions in range [{}-{}]",
|
bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from versions in range [{}-{}]",
|
||||||
FIRST_SUPPORTED_UPGRADE_FROM_VERSION,
|
FIRST_SUPPORTED_UPGRADE_FROM_VERSION,
|
||||||
@ -81,16 +77,13 @@ impl OfflineUpgrade {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (target_major, target_minor, target_patch) = &self.target_version;
|
let (target_major, target_minor, target_patch) = self.target_version;
|
||||||
|
|
||||||
let ends_at = match (target_major.as_str(), target_minor.as_str(), target_patch.as_str()) {
|
let ends_at = match (target_major, target_minor, target_patch) {
|
||||||
("1", "10", _) => 0,
|
(1, 10, _) => 0,
|
||||||
("1", "11", _) => 1,
|
(1, 11, _) => 1,
|
||||||
("1", "12", "0" | "1" | "2") => 2,
|
(1, 12, x) if x == 0 || x == 1 || x == 2 => 2,
|
||||||
("1", "12", "3" | "4" | "5") => 3,
|
(1, 12, 3..=5) => 3,
|
||||||
(major, _, _) if major.starts_with('v') => {
|
|
||||||
bail!("Target version must not starts with a `v`. Instead of writing `v1.9.0` write `1.9.0` for example.")
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to versions in range [{}-{}]",
|
bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to versions in range [{}-{}]",
|
||||||
FIRST_SUPPORTED_UPGRADE_TO_VERSION,
|
FIRST_SUPPORTED_UPGRADE_TO_VERSION,
|
||||||
@ -102,8 +95,13 @@ impl OfflineUpgrade {
|
|||||||
|
|
||||||
if start_at == no_upgrade {
|
if start_at == no_upgrade {
|
||||||
println!("No upgrade operation to perform, writing VERSION file");
|
println!("No upgrade operation to perform, writing VERSION file");
|
||||||
create_version_file(&self.db_path, target_major, target_minor, target_patch)
|
create_version_file(
|
||||||
.context("while writing VERSION file after the upgrade")?;
|
&self.db_path,
|
||||||
|
&target_major.to_string(),
|
||||||
|
&target_minor.to_string(),
|
||||||
|
&target_patch.to_string(),
|
||||||
|
)
|
||||||
|
.context("while writing VERSION file after the upgrade")?;
|
||||||
println!("Success");
|
println!("Success");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -153,9 +153,9 @@ fn date_round_trip(
|
|||||||
|
|
||||||
pub fn v1_9_to_v1_10(
|
pub fn v1_9_to_v1_10(
|
||||||
db_path: &Path,
|
db_path: &Path,
|
||||||
_origin_major: &str,
|
_origin_major: u32,
|
||||||
_origin_minor: &str,
|
_origin_minor: u32,
|
||||||
_origin_patch: &str,
|
_origin_patch: u32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
println!("Upgrading from v1.9.0 to v1.10.0");
|
println!("Upgrading from v1.9.0 to v1.10.0");
|
||||||
// 2 changes here
|
// 2 changes here
|
||||||
|
@ -16,9 +16,9 @@ use crate::{try_opening_database, try_opening_poly_database};
|
|||||||
|
|
||||||
pub fn v1_10_to_v1_11(
|
pub fn v1_10_to_v1_11(
|
||||||
db_path: &Path,
|
db_path: &Path,
|
||||||
_origin_major: &str,
|
_origin_major: u32,
|
||||||
_origin_minor: &str,
|
_origin_minor: u32,
|
||||||
_origin_patch: &str,
|
_origin_patch: u32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
println!("Upgrading from v1.10.0 to v1.11.0");
|
println!("Upgrading from v1.10.0 to v1.11.0");
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ use crate::uuid_codec::UuidCodec;
|
|||||||
|
|
||||||
pub fn v1_11_to_v1_12(
|
pub fn v1_11_to_v1_12(
|
||||||
db_path: &Path,
|
db_path: &Path,
|
||||||
_origin_major: &str,
|
_origin_major: u32,
|
||||||
_origin_minor: &str,
|
_origin_minor: u32,
|
||||||
_origin_patch: &str,
|
_origin_patch: u32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
println!("Upgrading from v1.11.0 to v1.12.0");
|
println!("Upgrading from v1.11.0 to v1.12.0");
|
||||||
|
|
||||||
@ -38,13 +38,13 @@ pub fn v1_11_to_v1_12(
|
|||||||
|
|
||||||
pub fn v1_12_to_v1_12_3(
|
pub fn v1_12_to_v1_12_3(
|
||||||
db_path: &Path,
|
db_path: &Path,
|
||||||
origin_major: &str,
|
origin_major: u32,
|
||||||
origin_minor: &str,
|
origin_minor: u32,
|
||||||
origin_patch: &str,
|
origin_patch: u32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
println!("Upgrading from v1.12.{{0, 1, 2}} to v1.12.3");
|
println!("Upgrading from v1.12.{{0, 1, 2}} to v1.12.3");
|
||||||
|
|
||||||
if origin_minor == "12" {
|
if origin_minor == 12 {
|
||||||
rebuild_field_distribution(db_path)?;
|
rebuild_field_distribution(db_path)?;
|
||||||
} else {
|
} else {
|
||||||
println!("Not rebuilding field distribution as it wasn't corrupted coming from v{origin_major}.{origin_minor}.{origin_patch}");
|
println!("Not rebuilding field distribution as it wasn't corrupted coming from v{origin_major}.{origin_minor}.{origin_patch}");
|
||||||
@ -173,10 +173,11 @@ fn rebuild_field_distribution(db_path: &Path) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
println!("\t- Rebuilding field distribution");
|
println!("\t- Rebuilding field distribution");
|
||||||
|
|
||||||
let index = meilisearch_types::milli::Index::new(EnvOpenOptions::new(), &index_path)
|
let index =
|
||||||
.with_context(|| {
|
meilisearch_types::milli::Index::new(EnvOpenOptions::new(), &index_path, false)
|
||||||
format!("while opening index {uid} at '{}'", index_path.display())
|
.with_context(|| {
|
||||||
})?;
|
format!("while opening index {uid} at '{}'", index_path.display())
|
||||||
|
})?;
|
||||||
|
|
||||||
let mut index_txn = index.write_txn()?;
|
let mut index_txn = index.write_txn()?;
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ bytemuck = { version = "1.21.0", features = ["extern_crate_alloc"] }
|
|||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
charabia = { version = "0.9.2", default-features = false }
|
charabia = { version = "0.9.2", default-features = false }
|
||||||
concat-arrays = "0.1.2"
|
concat-arrays = "0.1.2"
|
||||||
|
convert_case = "0.6.0"
|
||||||
crossbeam-channel = "0.5.14"
|
crossbeam-channel = "0.5.14"
|
||||||
deserr = "0.6.3"
|
deserr = "0.6.3"
|
||||||
either = { version = "1.13.0", features = ["serde"] }
|
either = { version = "1.13.0", features = ["serde"] }
|
||||||
|
@ -1,2 +1,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");
|
||||||
|
|
||||||
pub const RESERVED_VECTORS_FIELD_NAME: &str = "_vectors";
|
pub const RESERVED_VECTORS_FIELD_NAME: &str = "_vectors";
|
||||||
pub const RESERVED_GEO_FIELD_NAME: &str = "_geo";
|
pub const RESERVED_GEO_FIELD_NAME: &str = "_geo";
|
||||||
|
@ -74,6 +74,8 @@ pub enum InternalError {
|
|||||||
AbortedIndexation,
|
AbortedIndexation,
|
||||||
#[error("The matching words list contains at least one invalid member")]
|
#[error("The matching words list contains at least one invalid member")]
|
||||||
InvalidMatchingWords,
|
InvalidMatchingWords,
|
||||||
|
#[error("Cannot upgrade to the following version: v{0}.{1}.{2}.")]
|
||||||
|
CannotUpgradeToVersion(u32, u32, u32),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ArroyError(#[from] arroy::Error),
|
ArroyError(#[from] arroy::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -10,6 +10,7 @@ mod roaring_bitmap_length;
|
|||||||
mod str_beu32_codec;
|
mod str_beu32_codec;
|
||||||
mod str_ref;
|
mod str_ref;
|
||||||
mod str_str_u8_codec;
|
mod str_str_u8_codec;
|
||||||
|
pub mod version;
|
||||||
|
|
||||||
pub use byte_slice_ref::BytesRefCodec;
|
pub use byte_slice_ref::BytesRefCodec;
|
||||||
use heed::BoxedError;
|
use heed::BoxedError;
|
||||||
|
43
crates/milli/src/heed_codec/version.rs
Normal file
43
crates/milli/src/heed_codec/version.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
use std::mem::{size_of, size_of_val};
|
||||||
|
|
||||||
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
|
use heed::{BoxedError, BytesDecode, BytesEncode};
|
||||||
|
|
||||||
|
const VERSION_SIZE: usize = std::mem::size_of::<u32>() * 3;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error(
|
||||||
|
"Could not decode the version: Expected {VERSION_SIZE} bytes but instead received {0} bytes"
|
||||||
|
)]
|
||||||
|
pub struct DecodeVersionError(usize);
|
||||||
|
|
||||||
|
pub struct VersionCodec;
|
||||||
|
impl<'a> BytesEncode<'a> for VersionCodec {
|
||||||
|
type EItem = (u32, u32, u32);
|
||||||
|
|
||||||
|
fn bytes_encode(item: &'a Self::EItem) -> Result<Cow<'a, [u8]>, BoxedError> {
|
||||||
|
let mut ret = Vec::with_capacity(size_of::<u32>() * 3);
|
||||||
|
ret.extend(&item.0.to_be_bytes());
|
||||||
|
ret.extend(&item.1.to_be_bytes());
|
||||||
|
ret.extend(&item.2.to_be_bytes());
|
||||||
|
Ok(Cow::Owned(ret))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a> BytesDecode<'a> for VersionCodec {
|
||||||
|
type DItem = (u32, u32, u32);
|
||||||
|
|
||||||
|
fn bytes_decode(bytes: &'a [u8]) -> Result<Self::DItem, BoxedError> {
|
||||||
|
if bytes.len() != VERSION_SIZE {
|
||||||
|
Err(Box::new(DecodeVersionError(bytes.len())))
|
||||||
|
} else {
|
||||||
|
let major = BigEndian::read_u32(bytes);
|
||||||
|
let bytes = &bytes[size_of_val(&major)..];
|
||||||
|
let minor = BigEndian::read_u32(bytes);
|
||||||
|
let bytes = &bytes[size_of_val(&major)..];
|
||||||
|
let patch = BigEndian::read_u32(bytes);
|
||||||
|
|
||||||
|
Ok((major, minor, patch))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ use roaring::RoaringBitmap;
|
|||||||
use rstar::RTree;
|
use rstar::RTree;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::constants::RESERVED_VECTORS_FIELD_NAME;
|
use crate::constants::{self, RESERVED_VECTORS_FIELD_NAME};
|
||||||
use crate::documents::PrimaryKey;
|
use crate::documents::PrimaryKey;
|
||||||
use crate::error::{InternalError, UserError};
|
use crate::error::{InternalError, UserError};
|
||||||
use crate::fields_ids_map::FieldsIdsMap;
|
use crate::fields_ids_map::FieldsIdsMap;
|
||||||
@ -18,6 +18,7 @@ use crate::heed_codec::facet::{
|
|||||||
FacetGroupKeyCodec, FacetGroupValueCodec, FieldDocIdFacetF64Codec, FieldDocIdFacetStringCodec,
|
FacetGroupKeyCodec, FacetGroupValueCodec, FieldDocIdFacetF64Codec, FieldDocIdFacetStringCodec,
|
||||||
FieldIdCodec, OrderedF64Codec,
|
FieldIdCodec, OrderedF64Codec,
|
||||||
};
|
};
|
||||||
|
use crate::heed_codec::version::VersionCodec;
|
||||||
use crate::heed_codec::{BEU16StrCodec, FstSetCodec, StrBEU16Codec, StrRefCodec};
|
use crate::heed_codec::{BEU16StrCodec, FstSetCodec, StrBEU16Codec, StrRefCodec};
|
||||||
use crate::order_by_map::OrderByMap;
|
use crate::order_by_map::OrderByMap;
|
||||||
use crate::proximity::ProximityPrecision;
|
use crate::proximity::ProximityPrecision;
|
||||||
@ -33,6 +34,7 @@ pub const DEFAULT_MIN_WORD_LEN_ONE_TYPO: u8 = 5;
|
|||||||
pub const DEFAULT_MIN_WORD_LEN_TWO_TYPOS: u8 = 9;
|
pub const DEFAULT_MIN_WORD_LEN_TWO_TYPOS: u8 = 9;
|
||||||
|
|
||||||
pub mod main_key {
|
pub mod main_key {
|
||||||
|
pub const VERSION_KEY: &str = "version";
|
||||||
pub const CRITERIA_KEY: &str = "criteria";
|
pub const CRITERIA_KEY: &str = "criteria";
|
||||||
pub const DISPLAYED_FIELDS_KEY: &str = "displayed-fields";
|
pub const DISPLAYED_FIELDS_KEY: &str = "displayed-fields";
|
||||||
pub const DISTINCT_FIELD_KEY: &str = "distinct-field-key";
|
pub const DISTINCT_FIELD_KEY: &str = "distinct-field-key";
|
||||||
@ -176,6 +178,7 @@ impl Index {
|
|||||||
path: P,
|
path: P,
|
||||||
created_at: time::OffsetDateTime,
|
created_at: time::OffsetDateTime,
|
||||||
updated_at: time::OffsetDateTime,
|
updated_at: time::OffsetDateTime,
|
||||||
|
creation: bool,
|
||||||
) -> Result<Index> {
|
) -> Result<Index> {
|
||||||
use db_name::*;
|
use db_name::*;
|
||||||
|
|
||||||
@ -223,12 +226,9 @@ impl Index {
|
|||||||
let vector_arroy = env.create_database(&mut wtxn, Some(VECTOR_ARROY))?;
|
let vector_arroy = env.create_database(&mut wtxn, Some(VECTOR_ARROY))?;
|
||||||
|
|
||||||
let documents = env.create_database(&mut wtxn, Some(DOCUMENTS))?;
|
let documents = env.create_database(&mut wtxn, Some(DOCUMENTS))?;
|
||||||
wtxn.commit()?;
|
|
||||||
|
|
||||||
Index::set_creation_dates(&env, main, created_at, updated_at)?;
|
let this = Index {
|
||||||
|
env: env.clone(),
|
||||||
Ok(Index {
|
|
||||||
env,
|
|
||||||
main,
|
main,
|
||||||
external_documents_ids,
|
external_documents_ids,
|
||||||
word_docids,
|
word_docids,
|
||||||
@ -253,12 +253,31 @@ impl Index {
|
|||||||
vector_arroy,
|
vector_arroy,
|
||||||
embedder_category_id,
|
embedder_category_id,
|
||||||
documents,
|
documents,
|
||||||
})
|
};
|
||||||
|
if this.get_version(&wtxn)?.is_none() && creation {
|
||||||
|
this.put_version(
|
||||||
|
&mut wtxn,
|
||||||
|
(
|
||||||
|
constants::VERSION_MAJOR.parse().unwrap(),
|
||||||
|
constants::VERSION_MINOR.parse().unwrap(),
|
||||||
|
constants::VERSION_PATCH.parse().unwrap(),
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
wtxn.commit()?;
|
||||||
|
|
||||||
|
Index::set_creation_dates(&this.env, this.main, created_at, updated_at)?;
|
||||||
|
|
||||||
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<P: AsRef<Path>>(options: heed::EnvOpenOptions, path: P) -> Result<Index> {
|
pub fn new<P: AsRef<Path>>(
|
||||||
|
options: heed::EnvOpenOptions,
|
||||||
|
path: P,
|
||||||
|
creation: bool,
|
||||||
|
) -> Result<Index> {
|
||||||
let now = time::OffsetDateTime::now_utc();
|
let now = time::OffsetDateTime::now_utc();
|
||||||
Self::new_with_creation_dates(options, path, now, now)
|
Self::new_with_creation_dates(options, path, now, now, creation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_creation_dates(
|
fn set_creation_dates(
|
||||||
@ -331,6 +350,26 @@ impl Index {
|
|||||||
self.env.prepare_for_closing()
|
self.env.prepare_for_closing()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* version */
|
||||||
|
|
||||||
|
/// Writes the version of the database.
|
||||||
|
pub(crate) fn put_version(
|
||||||
|
&self,
|
||||||
|
wtxn: &mut RwTxn<'_>,
|
||||||
|
(major, minor, patch): (u32, u32, u32),
|
||||||
|
) -> heed::Result<()> {
|
||||||
|
self.main.remap_types::<Str, VersionCodec>().put(
|
||||||
|
wtxn,
|
||||||
|
main_key::VERSION_KEY,
|
||||||
|
&(major, minor, patch),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the version of the database. `None` if it was never set.
|
||||||
|
pub(crate) fn get_version(&self, rtxn: &RoTxn<'_>) -> heed::Result<Option<(u32, u32, u32)>> {
|
||||||
|
self.main.remap_types::<Str, VersionCodec>().get(rtxn, main_key::VERSION_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
/* documents ids */
|
/* documents ids */
|
||||||
|
|
||||||
/// Writes the documents ids that corresponds to the user-ids-documents-ids FST.
|
/// Writes the documents ids that corresponds to the user-ids-documents-ids FST.
|
||||||
@ -1768,7 +1807,7 @@ pub(crate) mod tests {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(size);
|
options.map_size(size);
|
||||||
let _tempdir = TempDir::new_in(".").unwrap();
|
let _tempdir = TempDir::new_in(".").unwrap();
|
||||||
let inner = Index::new(options, _tempdir.path()).unwrap();
|
let inner = Index::new(options, _tempdir.path(), true).unwrap();
|
||||||
let indexer_config = IndexerConfig::default();
|
let indexer_config = IndexerConfig::default();
|
||||||
let index_documents_config = IndexDocumentsConfig::default();
|
let index_documents_config = IndexDocumentsConfig::default();
|
||||||
Self { inner, indexer_config, index_documents_config, _tempdir }
|
Self { inner, indexer_config, index_documents_config, _tempdir }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
@ -88,19 +89,24 @@ impl<Name: NamedStep> Step for AtomicSubStep<Name> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use convert_case as _private_convert_case;
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use enum_iterator as _private_enum_iterator;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! make_enum_progress {
|
macro_rules! make_enum_progress {
|
||||||
($visibility:vis enum $name:ident { $($variant:ident,)+ }) => {
|
($visibility:vis enum $name:ident { $($variant:ident,)+ }) => {
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Sequence)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, $crate::progress::_private_enum_iterator::Sequence)]
|
||||||
#[allow(clippy::enum_variant_names)]
|
#[allow(clippy::enum_variant_names)]
|
||||||
$visibility enum $name {
|
$visibility enum $name {
|
||||||
$($variant),+
|
$($variant),+
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step for $name {
|
impl $crate::progress::Step for $name {
|
||||||
fn name(&self) -> Cow<'static, str> {
|
fn name(&self) -> std::borrow::Cow<'static, str> {
|
||||||
use convert_case::Casing;
|
use $crate::progress::_private_convert_case::Casing;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
@ -114,6 +120,7 @@ macro_rules! make_enum_progress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn total(&self) -> u32 {
|
fn total(&self) -> u32 {
|
||||||
|
use $crate::progress::_private_enum_iterator::Sequence;
|
||||||
Self::CARDINALITY as u32
|
Self::CARDINALITY as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,3 +160,41 @@ pub struct ProgressStepView {
|
|||||||
pub finished: u32,
|
pub finished: u32,
|
||||||
pub total: u32,
|
pub total: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used when the name can change but it's still the same step.
|
||||||
|
/// To avoid conflicts on the `TypeId`, create a unique type every time you use this step:
|
||||||
|
/// ```text
|
||||||
|
/// enum UpgradeVersion {}
|
||||||
|
///
|
||||||
|
/// progress.update_progress(VariableNameStep::<UpgradeVersion>::new(
|
||||||
|
/// "v1 to v2",
|
||||||
|
/// 0,
|
||||||
|
/// 10,
|
||||||
|
/// ));
|
||||||
|
/// ```
|
||||||
|
pub struct VariableNameStep<U: Send + Sync + 'static> {
|
||||||
|
name: String,
|
||||||
|
current: u32,
|
||||||
|
total: u32,
|
||||||
|
phantom: PhantomData<U>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: Send + Sync + 'static> VariableNameStep<U> {
|
||||||
|
pub fn new(name: impl Into<String>, current: u32, total: u32) -> Self {
|
||||||
|
Self { name: name.into(), current, total, phantom: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: Send + Sync + 'static> Step for VariableNameStep<U> {
|
||||||
|
fn name(&self) -> Cow<'static, str> {
|
||||||
|
self.name.clone().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current(&self) -> u32 {
|
||||||
|
self.current
|
||||||
|
}
|
||||||
|
|
||||||
|
fn total(&self) -> u32 {
|
||||||
|
self.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user