Snapshot takes compression and compaction options

This commit is contained in:
Louis Dureuil 2025-04-07 08:31:39 +02:00
parent c3c5a928e4
commit 7115b29a8c
No known key found for this signature in database
13 changed files with 267 additions and 66 deletions

215
Cargo.lock generated
View File

@ -27,7 +27,7 @@ checksum = "f9e772b3bcafe335042b5db010ab7c09013dad6eac4915c91d8d50902769f331"
dependencies = [ dependencies = [
"actix-utils", "actix-utils",
"actix-web", "actix-web",
"derive_more", "derive_more 0.99.17",
"futures-util", "futures-util",
"log", "log",
"once_cell", "once_cell",
@ -36,24 +36,24 @@ dependencies = [
[[package]] [[package]]
name = "actix-http" name = "actix-http"
version = "3.9.0" version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" checksum = "0fa882656b67966045e4152c634051e70346939fced7117d5f0b52146a7c74c9"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-rt", "actix-rt",
"actix-service", "actix-service",
"actix-tls", "actix-tls",
"actix-utils", "actix-utils",
"ahash 0.8.11",
"base64 0.22.1", "base64 0.22.1",
"bitflags 2.9.0", "bitflags 2.9.0",
"brotli", "brotli 7.0.0",
"bytes", "bytes",
"bytestring", "bytestring",
"derive_more", "derive_more 2.0.1",
"encoding_rs", "encoding_rs",
"flate2", "flate2",
"foldhash",
"futures-core", "futures-core",
"h2 0.3.26", "h2 0.3.26",
"http 0.2.11", "http 0.2.11",
@ -65,7 +65,7 @@ dependencies = [
"mime", "mime",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rand", "rand 0.9.0",
"sha1", "sha1",
"smallvec", "smallvec",
"tokio", "tokio",
@ -168,9 +168,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-web" name = "actix-web"
version = "4.9.0" version = "4.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" checksum = "92a9ac2e5a0d74d27551b65d10e2ed5c04e9935308c6b07c5f1325223dedfd00"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -182,13 +182,13 @@ dependencies = [
"actix-tls", "actix-tls",
"actix-utils", "actix-utils",
"actix-web-codegen", "actix-web-codegen",
"ahash 0.8.11",
"bytes", "bytes",
"bytestring", "bytestring",
"cfg-if", "cfg-if",
"cookie", "cookie",
"derive_more", "derive_more 2.0.1",
"encoding_rs", "encoding_rs",
"foldhash",
"futures-core", "futures-core",
"futures-util", "futures-util",
"impl-more", "impl-more",
@ -205,6 +205,7 @@ dependencies = [
"smallvec", "smallvec",
"socket2 0.5.5", "socket2 0.5.5",
"time", "time",
"tracing",
"url", "url",
] ]
@ -258,7 +259,7 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"once_cell", "once_cell",
"version_check", "version_check",
] ]
@ -271,10 +272,10 @@ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"const-random", "const-random",
"getrandom", "getrandom 0.2.15",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy", "zerocopy 0.7.32",
] ]
[[package]] [[package]]
@ -405,7 +406,7 @@ dependencies = [
"nohash", "nohash",
"ordered-float", "ordered-float",
"page_size", "page_size",
"rand", "rand 0.8.5",
"rayon", "rayon",
"roaring", "roaring",
"tempfile", "tempfile",
@ -498,8 +499,8 @@ dependencies = [
"memmap2", "memmap2",
"milli", "milli",
"mimalloc", "mimalloc",
"rand", "rand 0.8.5",
"rand_chacha", "rand_chacha 0.3.1",
"reqwest", "reqwest",
"roaring", "roaring",
"serde_json", "serde_json",
@ -654,6 +655,17 @@ dependencies = [
"brotli-decompressor", "brotli-decompressor",
] ]
[[package]]
name = "brotli"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
"brotli-decompressor",
]
[[package]] [[package]]
name = "brotli-decompressor" name = "brotli-decompressor"
version = "4.0.1" version = "4.0.1"
@ -832,7 +844,7 @@ dependencies = [
"memmap2", "memmap2",
"num-traits", "num-traits",
"num_cpus", "num_cpus",
"rand", "rand 0.8.5",
"rand_distr", "rand_distr",
"rayon", "rayon",
"safetensors", "safetensors",
@ -878,7 +890,7 @@ dependencies = [
"candle-nn", "candle-nn",
"fancy-regex", "fancy-regex",
"num-traits", "num-traits",
"rand", "rand 0.8.5",
"rayon", "rayon",
"serde", "serde",
"serde_json", "serde_json",
@ -1143,7 +1155,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"once_cell", "once_cell",
"tiny-keccak", "tiny-keccak",
] ]
@ -1544,6 +1556,27 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "derive_more"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"unicode-xid",
]
[[package]] [[package]]
name = "deserr" name = "deserr"
version = "0.6.3" version = "0.6.3"
@ -2216,10 +2249,22 @@ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
"libc", "libc",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "getrandom"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.27.3" version = "0.27.3"
@ -2312,7 +2357,7 @@ dependencies = [
"cfg-if", "cfg-if",
"crunchy", "crunchy",
"num-traits", "num-traits",
"rand", "rand 0.8.5",
"rand_distr", "rand_distr",
] ]
@ -2442,7 +2487,7 @@ dependencies = [
"http 1.2.0", "http 1.2.0",
"indicatif", "indicatif",
"log", "log",
"rand", "rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 1.0.69", "thiserror 1.0.69",
@ -3578,7 +3623,7 @@ dependencies = [
"actix-web", "actix-web",
"anyhow", "anyhow",
"async-trait", "async-trait",
"brotli", "brotli 6.0.0",
"bstr", "bstr",
"build-info", "build-info",
"byte-unit", "byte-unit",
@ -3619,7 +3664,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"platform-dirs", "platform-dirs",
"prometheus", "prometheus",
"rand", "rand 0.8.5",
"rayon", "rayon",
"regex", "regex",
"reqwest", "reqwest",
@ -3668,7 +3713,7 @@ dependencies = [
"hmac", "hmac",
"maplit", "maplit",
"meilisearch-types", "meilisearch-types",
"rand", "rand 0.8.5",
"roaring", "roaring",
"serde", "serde",
"serde_json", "serde_json",
@ -3798,7 +3843,7 @@ dependencies = [
"obkv", "obkv",
"once_cell", "once_cell",
"ordered-float", "ordered-float",
"rand", "rand 0.8.5",
"rayon", "rayon",
"rayon-par-bridge", "rayon-par-bridge",
"rhai", "rhai",
@ -3882,7 +3927,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -3893,7 +3938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -4338,7 +4383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [ dependencies = [
"phf_shared", "phf_shared",
"rand", "rand 0.8.5",
] ]
[[package]] [[package]]
@ -4605,7 +4650,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
dependencies = [ dependencies = [
"bytes", "bytes",
"rand", "rand 0.8.5",
"ring", "ring",
"rustc-hash 2.1.0", "rustc-hash 2.1.0",
"rustls", "rustls",
@ -4637,6 +4682,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]] [[package]]
name = "radium" name = "radium"
version = "0.7.0" version = "0.7.0"
@ -4650,8 +4701,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha", "rand_chacha 0.3.1",
"rand_core", "rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"zerocopy 0.8.24",
] ]
[[package]] [[package]]
@ -4661,7 +4723,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
] ]
[[package]] [[package]]
@ -4670,7 +4742,16 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.2",
] ]
[[package]] [[package]]
@ -4680,7 +4761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [ dependencies = [
"num-traits", "num-traits",
"rand", "rand 0.8.5",
] ]
[[package]] [[package]]
@ -4762,7 +4843,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"redox_syscall 0.2.16", "redox_syscall 0.2.16",
"thiserror 1.0.69", "thiserror 1.0.69",
] ]
@ -4892,7 +4973,7 @@ checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
"getrandom", "getrandom 0.2.15",
"libc", "libc",
"untrusted", "untrusted",
"windows-sys 0.52.0", "windows-sys 0.52.0",
@ -4960,7 +5041,7 @@ dependencies = [
"borsh", "borsh",
"bytes", "bytes",
"num-traits", "num-traits",
"rand", "rand 0.8.5",
"rkyv", "rkyv",
"serde", "serde",
"serde_json", "serde_json",
@ -5576,7 +5657,7 @@ checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"getrandom", "getrandom 0.2.15",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.52.0", "windows-sys 0.52.0",
@ -5751,7 +5832,7 @@ dependencies = [
"aho-corasick", "aho-corasick",
"derive_builder 0.12.0", "derive_builder 0.12.0",
"esaxx-rs", "esaxx-rs",
"getrandom", "getrandom 0.2.15",
"itertools 0.12.1", "itertools 0.12.1",
"lazy_static", "lazy_static",
"log", "log",
@ -5759,7 +5840,7 @@ dependencies = [
"monostate", "monostate",
"onig", "onig",
"paste", "paste",
"rand", "rand 0.8.5",
"rayon", "rayon",
"rayon-cond", "rayon-cond",
"regex", "regex",
@ -6122,6 +6203,12 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]] [[package]]
name = "unicode_categories" name = "unicode_categories"
version = "0.1.1" version = "0.1.1"
@ -6238,7 +6325,7 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"serde", "serde",
] ]
@ -6334,6 +6421,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.92" version = "0.2.92"
@ -6803,6 +6899,15 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.0",
]
[[package]] [[package]]
name = "write16" name = "write16"
version = "1.0.0" version = "1.0.0"
@ -6905,7 +7010,16 @@ version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive 0.7.32",
]
[[package]]
name = "zerocopy"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
"zerocopy-derive 0.8.24",
] ]
[[package]] [[package]]
@ -6919,6 +7033,17 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "zerocopy-derive"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "zerofrom" name = "zerofrom"
version = "0.1.3" version = "0.1.3"
@ -7017,7 +7142,7 @@ dependencies = [
"lzma-rs", "lzma-rs",
"memchr", "memchr",
"pbkdf2", "pbkdf2",
"rand", "rand 0.8.5",
"sha1", "sha1",
"thiserror 2.0.9", "thiserror 2.0.9",
"time", "time",

View File

@ -213,6 +213,7 @@ impl From<KindWithContent> for KindDump {
KindDump::DumpCreation { keys, instance_uid } KindDump::DumpCreation { keys, instance_uid }
} }
KindWithContent::SnapshotCreation => KindDump::SnapshotCreation, KindWithContent::SnapshotCreation => KindDump::SnapshotCreation,
KindWithContent::SnapshotCreationWithParams { .. } => KindDump::SnapshotCreation,
KindWithContent::UpgradeDatabase { from: version } => { KindWithContent::UpgradeDatabase { from: version } => {
KindDump::UpgradeDatabase { from: version } KindDump::UpgradeDatabase { from: version }
} }

View File

@ -210,7 +210,10 @@ impl<'a> Dump<'a> {
KindDump::DumpCreation { keys, instance_uid } => { KindDump::DumpCreation { keys, instance_uid } => {
KindWithContent::DumpCreation { keys, instance_uid } KindWithContent::DumpCreation { keys, instance_uid }
} }
KindDump::SnapshotCreation => KindWithContent::SnapshotCreation, KindDump::SnapshotCreation => KindWithContent::SnapshotCreationWithParams {
compaction: false,
compression: true,
},
KindDump::UpgradeDatabase { from } => KindWithContent::UpgradeDatabase { from }, KindDump::UpgradeDatabase { from } => KindWithContent::UpgradeDatabase { from },
}, },
}; };

View File

@ -5,9 +5,10 @@ tasks affecting a single index into a [batch](crate::batch::Batch).
The main function of the autobatcher is [`next_autobatch`]. The main function of the autobatcher is [`next_autobatch`].
*/ */
use meilisearch_types::tasks::TaskId;
use std::ops::ControlFlow::{self, Break, Continue}; use std::ops::ControlFlow::{self, Break, Continue};
use meilisearch_types::tasks::TaskId;
use crate::KindWithContent; use crate::KindWithContent;
/// Succinctly describes a task's [`Kind`](meilisearch_types::tasks::Kind) /// Succinctly describes a task's [`Kind`](meilisearch_types::tasks::Kind)
@ -71,7 +72,8 @@ impl From<KindWithContent> for AutobatchKind {
| KindWithContent::TaskDeletion { .. } | KindWithContent::TaskDeletion { .. }
| KindWithContent::DumpCreation { .. } | KindWithContent::DumpCreation { .. }
| KindWithContent::UpgradeDatabase { .. } | KindWithContent::UpgradeDatabase { .. }
| KindWithContent::SnapshotCreation => { | KindWithContent::SnapshotCreation
| KindWithContent::SnapshotCreationWithParams { .. } => {
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.")
} }
} }

View File

@ -23,7 +23,11 @@ pub(crate) enum Batch {
task: Task, task: Task,
}, },
TaskDeletions(Vec<Task>), TaskDeletions(Vec<Task>),
SnapshotCreation(Vec<Task>), SnapshotCreation {
tasks: Vec<Task>,
compression: bool,
compaction: bool,
},
Dump(Task), Dump(Task),
IndexOperation { IndexOperation {
op: IndexOperation, op: IndexOperation,
@ -106,7 +110,7 @@ impl Batch {
| Batch::IndexUpdate { task, .. } => { | Batch::IndexUpdate { task, .. } => {
RoaringBitmap::from_sorted_iter(std::iter::once(task.uid)).unwrap() RoaringBitmap::from_sorted_iter(std::iter::once(task.uid)).unwrap()
} }
Batch::SnapshotCreation(tasks) Batch::SnapshotCreation { tasks, .. }
| Batch::TaskDeletions(tasks) | Batch::TaskDeletions(tasks)
| Batch::UpgradeDatabase { tasks } | Batch::UpgradeDatabase { tasks }
| Batch::IndexDeletion { tasks, .. } => { | Batch::IndexDeletion { tasks, .. } => {
@ -140,7 +144,7 @@ impl Batch {
match self { match self {
TaskCancelation { .. } TaskCancelation { .. }
| TaskDeletions(_) | TaskDeletions(_)
| SnapshotCreation(_) | SnapshotCreation { .. }
| Dump(_) | Dump(_)
| UpgradeDatabase { .. } | UpgradeDatabase { .. }
| IndexSwap { .. } => None, | IndexSwap { .. } => None,
@ -160,7 +164,7 @@ impl fmt::Display for Batch {
match self { match self {
Batch::TaskCancelation { .. } => f.write_str("TaskCancelation")?, Batch::TaskCancelation { .. } => f.write_str("TaskCancelation")?,
Batch::TaskDeletions(_) => f.write_str("TaskDeletion")?, Batch::TaskDeletions(_) => f.write_str("TaskDeletion")?,
Batch::SnapshotCreation(_) => f.write_str("SnapshotCreation")?, Batch::SnapshotCreation { .. } => f.write_str("SnapshotCreation")?,
Batch::Dump(_) => f.write_str("Dump")?, Batch::Dump(_) => f.write_str("Dump")?,
Batch::IndexOperation { op, .. } => write!(f, "{op}")?, Batch::IndexOperation { op, .. } => write!(f, "{op}")?,
Batch::IndexCreation { .. } => f.write_str("IndexCreation")?, Batch::IndexCreation { .. } => f.write_str("IndexCreation")?,
@ -478,7 +482,17 @@ impl IndexScheduler {
if !to_snapshot.is_empty() { if !to_snapshot.is_empty() {
let mut tasks = self.queue.tasks.get_existing_tasks(rtxn, to_snapshot)?; let mut tasks = self.queue.tasks.get_existing_tasks(rtxn, to_snapshot)?;
current_batch.processing(&mut tasks); current_batch.processing(&mut tasks);
return Ok(Some((Batch::SnapshotCreation(tasks), current_batch))); let (compaction, compression) = match &tasks.last().unwrap().kind {
KindWithContent::SnapshotCreation => (false, true),
KindWithContent::SnapshotCreationWithParams { compaction, compression } => {
(*compaction, *compression)
}
_ => unreachable!(),
};
return Ok(Some((
Batch::SnapshotCreation { compaction, compression, tasks },
current_batch,
)));
} }
// 4. we batch the dumps. // 4. we batch the dumps.

View File

@ -117,9 +117,9 @@ impl IndexScheduler {
} }
Ok((tasks, None)) Ok((tasks, None))
} }
Batch::SnapshotCreation(tasks) => { Batch::SnapshotCreation { tasks, compression, compaction } => self
self.process_snapshot(progress, tasks).map(|tasks| (tasks, None)) .process_snapshot(progress, tasks, compaction, compression)
} .map(|tasks| (tasks, None)),
Batch::Dump(task) => { Batch::Dump(task) => {
self.process_dump_creation(progress, task).map(|tasks| (tasks, None)) self.process_dump_creation(progress, task).map(|tasks| (tasks, None))
} }

View File

@ -15,8 +15,13 @@ impl IndexScheduler {
&self, &self,
progress: Progress, progress: Progress,
mut tasks: Vec<Task>, mut tasks: Vec<Task>,
compaction: bool,
compression: bool,
) -> Result<Vec<Task>> { ) -> Result<Vec<Task>> {
tracing::debug!(compaction, compression, "process snapshot");
progress.update_progress(SnapshotCreationProgress::StartTheSnapshotCreation); progress.update_progress(SnapshotCreationProgress::StartTheSnapshotCreation);
let compaction =
if compaction { CompactionOption::Enabled } else { CompactionOption::Disabled };
fs::create_dir_all(&self.scheduler.snapshots_path)?; fs::create_dir_all(&self.scheduler.snapshots_path)?;
let temp_snapshot_dir = tempfile::tempdir()?; let temp_snapshot_dir = tempfile::tempdir()?;
@ -41,7 +46,7 @@ impl IndexScheduler {
progress.update_progress(SnapshotCreationProgress::SnapshotTheIndexScheduler); progress.update_progress(SnapshotCreationProgress::SnapshotTheIndexScheduler);
let dst = temp_snapshot_dir.path().join("tasks"); let dst = temp_snapshot_dir.path().join("tasks");
fs::create_dir_all(&dst)?; fs::create_dir_all(&dst)?;
self.env.copy_to_path(dst.join("data.mdb"), CompactionOption::Enabled)?; self.env.copy_to_path(dst.join("data.mdb"), compaction)?;
// 2.2 Create a read transaction on the index-scheduler // 2.2 Create a read transaction on the index-scheduler
let rtxn = self.env.read_txn()?; let rtxn = self.env.read_txn()?;
@ -80,7 +85,7 @@ impl IndexScheduler {
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)?;
index index
.copy_to_path(dst.join("data.mdb"), CompactionOption::Enabled) .copy_to_path(dst.join("data.mdb"), compaction)
.map_err(|e| Error::from_milli(e, Some(name.to_string())))?; .map_err(|e| Error::from_milli(e, Some(name.to_string())))?;
} }
@ -103,7 +108,7 @@ impl IndexScheduler {
// 5.2 Tarball the content of the snapshot in a tempfile with a .snapshot extension // 5.2 Tarball the content of the snapshot in a tempfile with a .snapshot extension
let snapshot_path = self.scheduler.snapshots_path.join(format!("{}.snapshot", db_name)); let snapshot_path = self.scheduler.snapshots_path.join(format!("{}.snapshot", db_name));
let temp_snapshot_file = tempfile::NamedTempFile::new_in(&self.scheduler.snapshots_path)?; let temp_snapshot_file = tempfile::NamedTempFile::new_in(&self.scheduler.snapshots_path)?;
compression::to_tar_gz(temp_snapshot_dir.path(), temp_snapshot_file.path())?; compression::to_tar_gz(temp_snapshot_dir.path(), temp_snapshot_file.path(), compression)?;
let file = temp_snapshot_file.persist(snapshot_path)?; let file = temp_snapshot_file.persist(snapshot_path)?;
// 5.3 Change the permission to make the snapshot readonly // 5.3 Change the permission to make the snapshot readonly

View File

@ -266,6 +266,7 @@ pub fn swap_index_uid_in_task(task: &mut Task, swap: (&str, &str)) {
| K::DumpCreation { .. } | K::DumpCreation { .. }
| K::UpgradeDatabase { .. } | K::UpgradeDatabase { .. }
| K::SnapshotCreation => (), | K::SnapshotCreation => (),
K::SnapshotCreationWithParams { .. } => (),
}; };
if let Some(Details::IndexSwap { swaps }) = &mut task.details { if let Some(Details::IndexSwap { swaps }) = &mut task.details {
for IndexSwap { indexes: (lhs, rhs) } in swaps.iter_mut() { for IndexSwap { indexes: (lhs, rhs) } in swaps.iter_mut() {

View File

@ -7,9 +7,14 @@ use flate2::write::GzEncoder;
use flate2::Compression; use flate2::Compression;
use tar::{Archive, Builder}; use tar::{Archive, Builder};
pub fn to_tar_gz(src: impl AsRef<Path>, dest: impl AsRef<Path>) -> anyhow::Result<()> { pub fn to_tar_gz(
src: impl AsRef<Path>,
dest: impl AsRef<Path>,
compression: bool,
) -> anyhow::Result<()> {
let compression = if compression { Compression::default() } else { Compression::none() };
let mut f = File::create(dest)?; let mut f = File::create(dest)?;
let gz_encoder = GzEncoder::new(&mut f, Compression::default()); let gz_encoder = GzEncoder::new(&mut f, compression);
let mut tar_encoder = Builder::new(gz_encoder); let mut tar_encoder = Builder::new(gz_encoder);
tar_encoder.append_dir_all(".", src)?; tar_encoder.append_dir_all(".", src)?;
let gz_encoder = tar_encoder.into_inner()?; let gz_encoder = tar_encoder.into_inner()?;

View File

@ -328,6 +328,7 @@ InvalidSettingsDictionary , InvalidRequest , BAD_REQUEST ;
InvalidSettingsSynonyms , InvalidRequest , BAD_REQUEST ; InvalidSettingsSynonyms , InvalidRequest , BAD_REQUEST ;
InvalidSettingsTypoTolerance , InvalidRequest , BAD_REQUEST ; InvalidSettingsTypoTolerance , InvalidRequest , BAD_REQUEST ;
InvalidSettingsLocalizedAttributes , InvalidRequest , BAD_REQUEST ; InvalidSettingsLocalizedAttributes , InvalidRequest , BAD_REQUEST ;
InvalidSnapshotOptions , InvalidRequest , BAD_REQUEST ;
InvalidState , Internal , INTERNAL_SERVER_ERROR ; InvalidState , Internal , INTERNAL_SERVER_ERROR ;
InvalidStoreFile , Internal , INTERNAL_SERVER_ERROR ; InvalidStoreFile , Internal , INTERNAL_SERVER_ERROR ;
InvalidSwapDuplicateIndexFound , InvalidRequest , BAD_REQUEST ; InvalidSwapDuplicateIndexFound , InvalidRequest , BAD_REQUEST ;

View File

@ -48,6 +48,7 @@ impl Task {
match &self.kind { match &self.kind {
DumpCreation { .. } DumpCreation { .. }
| SnapshotCreation | SnapshotCreation
| SnapshotCreationWithParams { .. }
| TaskCancelation { .. } | TaskCancelation { .. }
| TaskDeletion { .. } | TaskDeletion { .. }
| UpgradeDatabase { .. } | UpgradeDatabase { .. }
@ -86,6 +87,7 @@ impl Task {
| KindWithContent::TaskDeletion { .. } | KindWithContent::TaskDeletion { .. }
| KindWithContent::DumpCreation { .. } | KindWithContent::DumpCreation { .. }
| KindWithContent::SnapshotCreation | KindWithContent::SnapshotCreation
| KindWithContent::SnapshotCreationWithParams { .. }
| KindWithContent::UpgradeDatabase { .. } => None, | KindWithContent::UpgradeDatabase { .. } => None,
} }
} }
@ -152,6 +154,10 @@ pub enum KindWithContent {
instance_uid: Option<InstanceUid>, instance_uid: Option<InstanceUid>,
}, },
SnapshotCreation, SnapshotCreation,
SnapshotCreationWithParams {
compaction: bool,
compression: bool,
},
UpgradeDatabase { UpgradeDatabase {
from: (u32, u32, u32), from: (u32, u32, u32),
}, },
@ -180,6 +186,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::SnapshotCreationWithParams { .. } => Kind::SnapshotCreation,
KindWithContent::UpgradeDatabase { .. } => Kind::UpgradeDatabase, KindWithContent::UpgradeDatabase { .. } => Kind::UpgradeDatabase,
} }
} }
@ -190,6 +197,7 @@ impl KindWithContent {
match self { match self {
DumpCreation { .. } DumpCreation { .. }
| SnapshotCreation | SnapshotCreation
| SnapshotCreationWithParams { .. }
| TaskCancelation { .. } | TaskCancelation { .. }
| TaskDeletion { .. } | TaskDeletion { .. }
| UpgradeDatabase { .. } => vec![], | UpgradeDatabase { .. } => vec![],
@ -269,6 +277,7 @@ 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::SnapshotCreationWithParams { .. } => None,
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase { KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
from: (from.0, from.1, from.2), from: (from.0, from.1, from.2),
to: ( to: (
@ -335,6 +344,7 @@ 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::SnapshotCreationWithParams { .. } => None,
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase { KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
from: *from, from: *from,
to: ( to: (
@ -383,6 +393,7 @@ 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::SnapshotCreationWithParams { .. } => None,
KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase { KindWithContent::UpgradeDatabase { from } => Some(Details::UpgradeDatabase {
from: *from, from: *from,
to: ( to: (

View File

@ -315,9 +315,14 @@ pub fn setup_meilisearch(opt: &Opt) -> anyhow::Result<(Arc<IndexScheduler>, Arc<
.name(String::from("register-snapshot-tasks")) .name(String::from("register-snapshot-tasks"))
.spawn(move || loop { .spawn(move || loop {
thread::sleep(snapshot_delay); thread::sleep(snapshot_delay);
if let Err(e) = if let Err(e) = index_scheduler.register(
index_scheduler.register(KindWithContent::SnapshotCreation, None, false) KindWithContent::SnapshotCreationWithParams {
{ compaction: false,
compression: true,
},
None,
false,
) {
error!("Error while registering snapshot: {}", e); error!("Error while registering snapshot: {}", e);
} }
}) })

View File

@ -1,6 +1,8 @@
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{web, HttpRequest, HttpResponse}; use actix_web::{web, FromRequest, HttpRequest, HttpResponse};
use deserr::actix_web::AwebJson;
use index_scheduler::IndexScheduler; use index_scheduler::IndexScheduler;
use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::ResponseError; use meilisearch_types::error::ResponseError;
use meilisearch_types::tasks::KindWithContent; use meilisearch_types::tasks::KindWithContent;
use tracing::debug; use tracing::debug;
@ -42,6 +44,7 @@ crate::empty_analytics!(SnapshotAnalytics, "Snapshot Created");
path = "", path = "",
tag = "Snapshots", tag = "Snapshots",
security(("Bearer" = ["snapshots.create", "snapshots.*", "*"])), security(("Bearer" = ["snapshots.create", "snapshots.*", "*"])),
request_body = SnapshotOptions,
responses( responses(
(status = 202, description = "Snapshot is being created", body = SummarizedTaskView, content_type = "application/json", example = json!( (status = 202, description = "Snapshot is being created", body = SummarizedTaskView, content_type = "application/json", example = json!(
{ {
@ -64,13 +67,29 @@ crate::empty_analytics!(SnapshotAnalytics, "Snapshot Created");
)] )]
pub async fn create_snapshot( pub async fn create_snapshot(
index_scheduler: GuardedData<ActionPolicy<{ actions::SNAPSHOTS_CREATE }>, Data<IndexScheduler>>, index_scheduler: GuardedData<ActionPolicy<{ actions::SNAPSHOTS_CREATE }>, Data<IndexScheduler>>,
snapshot_options: Option<actix_web::web::Bytes>,
req: HttpRequest, req: HttpRequest,
opt: web::Data<Opt>, opt: web::Data<Opt>,
analytics: web::Data<Analytics>, analytics: web::Data<Analytics>,
) -> Result<HttpResponse, ResponseError> { ) -> Result<HttpResponse, ResponseError> {
analytics.publish(SnapshotAnalytics::default(), &req); analytics.publish(SnapshotAnalytics::default(), &req);
let task = KindWithContent::SnapshotCreation; let task = match snapshot_options {
Some(snapshot_options) if !snapshot_options.is_empty() => {
let mut payload = actix_web::dev::Payload::from(snapshot_options);
let snapshot_options: AwebJson<SnapshotOptions, DeserrJsonError> =
match AwebJson::from_request(&req, &mut payload).await {
Ok(snapshot_options) => snapshot_options,
Err(error) => {
return Err(ResponseError::from_msg(format!("{error}\n - note: POST /snapshots without a body to use default parameters"), meilisearch_types::error::Code::InvalidSnapshotOptions));
}
};
let SnapshotOptions { compaction, compression } = snapshot_options.into_inner();
KindWithContent::SnapshotCreationWithParams { compaction, compression }
}
_ => KindWithContent::SnapshotCreationWithParams { compaction: false, compression: true },
};
let uid = get_task_id(&req, &opt)?; let uid = get_task_id(&req, &opt)?;
let dry_run = is_dry_run(&req, &opt)?; let dry_run = is_dry_run(&req, &opt)?;
let task: SummarizedTaskView = let task: SummarizedTaskView =
@ -81,3 +100,12 @@ pub async fn create_snapshot(
debug!(returns = ?task, "Create snapshot"); debug!(returns = ?task, "Create snapshot");
Ok(HttpResponse::Accepted().json(task)) Ok(HttpResponse::Accepted().json(task))
} }
#[derive(Clone, Copy, deserr::Deserr, utoipa::ToSchema)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
struct SnapshotOptions {
#[deserr(default)]
compaction: bool,
#[deserr(default)]
compression: bool,
}