diff --git a/.gitignore b/.gitignore index 8ef20bb2944..9d6bddfb6de 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ out/ # Vscode files .vscode/** +.devcontainer/ target dist diff --git a/Cargo.lock b/Cargo.lock index d48e3ea81dd..61e2e9edb42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,16 +36,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c80b57a86234ee3e9238f5f2d33d37f8fd5c7ff168c07f2d5147d410e86db33" dependencies = [ "home", - "libc 0.2.151", + "libc 0.2.176", "rustc_version 0.4.0", "xdg", ] [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.11", "once_cell", @@ -94,7 +94,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -207,16 +207,16 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" dependencies = [ - "concurrent-queue", - "event-listener", + "concurrent-queue 1.2.2", + "event-listener 2.5.1", "futures-core", ] [[package]] name = "async-compression" -version = "0.4.12" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" +checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" dependencies = [ "futures-core", "futures-io", @@ -229,11 +229,13 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.7.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "event-listener", + "event-listener 5.4.1", + "event-listener-strategy", + "pin-project-lite", ] [[package]] @@ -277,7 +279,7 @@ checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -295,7 +297,7 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -341,7 +343,7 @@ dependencies = [ "prometheus", "slog", "slog-global", - "thiserror", + "thiserror 1.0.40", "tikv_util", "tokio", "tokio-util", @@ -368,7 +370,7 @@ dependencies = [ "bytes", "fastrand 2.0.1", "http 0.2.12", - "time 0.3.20", + "time 0.3.41", "tokio", "tracing", "url", @@ -463,7 +465,7 @@ dependencies = [ "once_cell", "percent-encoding", "regex-lite", - "sha2 0.10.8", + "sha2", "tracing", "url", ] @@ -510,8 +512,8 @@ dependencies = [ "http 1.1.0", "once_cell", "percent-encoding", - "sha2 0.10.8", - "time 0.3.20", + "sha2", + "time 0.3.41", "tracing", ] @@ -543,7 +545,7 @@ dependencies = [ "md-5", "pin-project-lite", "sha1", - "sha2 0.10.8", + "sha2", "tracing", ] @@ -604,7 +606,7 @@ dependencies = [ "regex-lite", "roxmltree", "serde_json", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -679,13 +681,14 @@ dependencies = [ "http-body 0.4.5", "http-body 1.0.0", "http-body-util", + "hyper", "itoa 1.0.1", "num-integer", "pin-project-lite", "pin-utils", "ryu", "serde", - "time 0.3.20", + "time 0.3.41", "tokio", "tokio-util", ] @@ -735,7 +738,7 @@ dependencies = [ "slog", "slog-global", "tikv_util", - "time 0.3.20", + "time 0.3.41", "tokio", "url", "uuid 1.7.0", @@ -743,105 +746,123 @@ dependencies = [ [[package]] name = "azure_core" -version = "0.12.0" -source = "git+https://github.com/tikv/azure-sdk-for-rust?branch=release-7.5-fips#e3dc3e02573e60e70f00418255c417aa80b8e26b" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6218987c374650fdad0b476bfc675729762c28dfb35f58608a38a2b1ea337dd" dependencies = [ "async-trait", - "base64 0.21.0", + "base64 0.21.7", "bytes", "dyn-clone", "futures 0.3.15", "getrandom 0.2.11", "http-types", "log", + "once_cell", + "openssl", "paste", "pin-project", - "quick-xml 0.29.0", + "quick-xml 0.31.0", "rand 0.8.5", "reqwest", "rustc_version 0.4.0", "serde", "serde_json", - "time 0.3.20", + "time 0.3.41", "url", "uuid 1.7.0", ] [[package]] name = "azure_identity" -version = "0.12.0" -source = "git+https://github.com/tikv/azure-sdk-for-rust?branch=release-7.5-fips#e3dc3e02573e60e70f00418255c417aa80b8e26b" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1eacc4f7fb2a73d57c39139d0fc3aed78435606055779ddaef4b43cdf919a8" dependencies = [ "async-lock", "async-trait", "azure_core", - "fix-hidden-lifetime-bug", "futures 0.3.15", "log", "oauth2", "pin-project", "serde", - "serde_json", - "time 0.3.20", + "time 0.3.41", + "tz-rs", "url", "uuid 1.7.0", ] [[package]] name = "azure_security_keyvault" -version = "0.12.0" -source = "git+https://github.com/tikv/azure-sdk-for-rust?branch=release-7.5-fips#e3dc3e02573e60e70f00418255c417aa80b8e26b" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7b31bc2b045f0fe1fe377960df975fcf578a22277268c1565fb2b239d9a7ffa" dependencies = [ "async-trait", "azure_core", - "const_format", "futures 0.3.15", "serde", "serde_json", - "time 0.3.20", - "url", + "time 0.3.41", ] [[package]] name = "azure_storage" -version = "0.12.0" -source = "git+https://github.com/tikv/azure-sdk-for-rust?branch=release-7.5-fips#e3dc3e02573e60e70f00418255c417aa80b8e26b" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade8f2653e408de88b9eafec9f48c3c26b94026375e88adbd34523a7dd9795a1" dependencies = [ "RustyXML", + "async-lock", "async-trait", "azure_core", "bytes", - "futures 0.3.15", "log", - "once_cell", - "openssl", "serde", "serde_derive", - "serde_json", - "time 0.3.20", + "time 0.3.41", "url", "uuid 1.7.0", ] [[package]] name = "azure_storage_blobs" -version = "0.12.0" -source = "git+https://github.com/tikv/azure-sdk-for-rust?branch=release-7.5-fips#e3dc3e02573e60e70f00418255c417aa80b8e26b" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "025701c7cc5b523100f0f3b2b01723564ec5a86c03236521c06826337047e872" dependencies = [ "RustyXML", "azure_core", "azure_storage", + "azure_svc_blobstorage", "bytes", "futures 0.3.15", "log", "serde", "serde_derive", "serde_json", - "time 0.3.20", + "time 0.3.41", "url", "uuid 1.7.0", ] +[[package]] +name = "azure_svc_blobstorage" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76051e5bb67cea1055abe5e530a0878feac7e0ab4cbbcb4a6adc953a58993389" +dependencies = [ + "azure_core", + "bytes", + "futures 0.3.15", + "log", + "once_cell", + "serde", + "serde_json", + "time 0.3.41", +] + [[package]] name = "backtrace" version = "0.3.61" @@ -850,7 +871,7 @@ dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "miniz_oxide 0.4.4", "object", "rustc-demangle", @@ -890,7 +911,7 @@ dependencies = [ "slog", "slog-global", "tempfile", - "thiserror", + "thiserror 1.0.40", "tikv", "tikv_alloc", "tikv_util", @@ -910,7 +931,7 @@ dependencies = [ "concurrency_manager", "crc64fast", "dashmap", - "derive_more", + "derive_more 0.99.3", "encryption", "encryption_export", "engine_panic", @@ -933,7 +954,7 @@ dependencies = [ "pin-project", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "rand 0.8.5", @@ -948,7 +969,7 @@ dependencies = [ "test_pd_client", "test_raftstore", "test_util", - "thiserror", + "thiserror 1.0.40", "tidb_query_datatype", "tikv", "tikv_kv", @@ -972,9 +993,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64-simd" @@ -993,7 +1014,7 @@ dependencies = [ "criterion 0.3.5", "crossbeam", "dashmap", - "derive_more", + "derive_more 0.99.3", "fail", "file_system", "kvproto", @@ -1018,9 +1039,9 @@ dependencies = [ "bcc-sys", "bitflags 1.3.2", "byteorder", - "libc 0.2.151", + "libc 0.2.176", "regex", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -1093,7 +1114,7 @@ dependencies = [ "regex", "rustc-hash", "shlex 1.3.0", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -1135,15 +1156,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -1221,7 +1233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" dependencies = [ "cc", - "libc 0.2.151", + "libc 0.2.176", "pkg-config", ] @@ -1247,7 +1259,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7f788eaf239475a3c1e1acf89951255a46c4b9b46cf3e866fc4d0707b4b9e36" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "valgrind_request", ] @@ -1294,7 +1306,7 @@ dependencies = [ "slog", "slog-global", "test_pd_client", - "thiserror", + "thiserror 1.0.40", "tikv_util", "tokio", "txn_types", @@ -1326,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "jobserver", - "libc 0.2.151", + "libc 0.2.176", "shlex 1.3.0", ] @@ -1355,7 +1367,7 @@ dependencies = [ "pd_client", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "resolved_ts", @@ -1366,7 +1378,7 @@ dependencies = [ "test_pd_client", "test_raftstore", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv", "tikv_kv", "tikv_util", @@ -1464,7 +1476,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f54d78e30b388d4815220c8dd03fea5656b6c6d32adb59e89061552a102f8da1" dependencies = [ "glob", - "libc 0.2.151", + "libc 0.2.176", "libloading", ] @@ -1500,7 +1512,7 @@ name = "cloud" version = "0.0.1" dependencies = [ "async-trait", - "derive_more", + "derive_more 0.99.3", "error_code", "futures 0.3.15", "futures-io", @@ -1508,8 +1520,8 @@ dependencies = [ "lazy_static", "pin-project", "prometheus", - "protobuf", - "thiserror", + "protobuf 2.8.0", + "thiserror 1.0.40", "tikv_util", "tokio", "url", @@ -1530,7 +1542,7 @@ version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71367d3385c716342014ad17e3d19f7788ae514885a1f4c24f500260fb365e1a" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "once_cell", "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", @@ -1543,12 +1555,12 @@ dependencies = [ "byteorder", "bytes", "error_code", - "libc 0.2.151", + "libc 0.2.176", "panic_hook", - "protobuf", + "protobuf 2.8.0", "rand 0.8.5", "static_assertions", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", ] @@ -1567,10 +1579,11 @@ dependencies = [ "async-compression", "bytes", "chrono", + "cloud", "codec", "crc64fast", "dashmap", - "derive_more", + "derive_more 0.99.3", "encryption", "engine_rocks", "engine_traits", @@ -1584,16 +1597,16 @@ dependencies = [ "kvproto", "lazy_static", "pin-project", - "pprof", + "pprof 0.15.0", "prometheus", - "protobuf", + "protobuf 2.8.0", "serde", "serde_json", "slog", "slog-global", "tempdir", "test_util", - "thiserror", + "thiserror 1.0.40", "tidb_query_datatype", "tikv_alloc", "tikv_util", @@ -1627,7 +1640,7 @@ dependencies = [ "serde", "slog", "slog-global", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", "tokio", @@ -1644,24 +1657,19 @@ dependencies = [ ] [[package]] -name = "const_format" -version = "0.2.30" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "const_format_proc_macros", + "crossbeam-utils", ] [[package]] -name = "const_format_proc_macros" -version = "0.2.29" +name = "const_fn" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" [[package]] name = "coprocessor_plugin_api" @@ -1679,7 +1687,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" dependencies = [ "core-foundation-sys", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -1690,9 +1698,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpp_demangle" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" dependencies = [ "cfg-if 1.0.0", ] @@ -1703,7 +1711,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e393a7668fe1fad3075085b86c781883000b4ede868f43627b34a87c8b7ded" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -1713,15 +1721,9 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] -[[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - [[package]] name = "crc32c" version = "0.6.8" @@ -1805,7 +1807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63aaaf47e457badbcb376c65a49d0f182c317ebd97dc6d1ced94c8e1d09c0f3a" dependencies = [ "criterion 0.3.5", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -2025,6 +2027,16 @@ dependencies = [ "uuid 1.7.0", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derivative" version = "2.2.0" @@ -2048,27 +2060,39 @@ dependencies = [ ] [[package]] -name = "diff" -version = "0.1.13" +name = "derive_more" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] [[package]] -name = "digest" -version = "0.9.0" +name = "derive_more-impl" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ - "generic-array", + "proc-macro2", + "quote", + "syn 2.0.101", + "unicode-xid", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", "subtle", ] @@ -2089,7 +2113,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "redox_users", "winapi 0.3.9", ] @@ -2102,7 +2126,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -2162,7 +2186,7 @@ dependencies = [ "online_config", "openssl", "prometheus", - "protobuf", + "protobuf 2.8.0", "rand 0.8.5", "serde", "serde_derive", @@ -2170,7 +2194,7 @@ dependencies = [ "slog-global", "tempfile", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv_util", "tokio", "toml", @@ -2188,7 +2212,7 @@ dependencies = [ "file_system", "gcp", "kvproto", - "protobuf", + "protobuf 2.8.0", "rust-ini", "slog", "slog-global", @@ -2215,7 +2239,7 @@ version = "0.0.1" dependencies = [ "api_version", "collections", - "derive_more", + "derive_more 0.99.3", "encryption", "engine_traits", "fail", @@ -2229,7 +2253,7 @@ dependencies = [ "prometheus", "prometheus-static-metric", "proptest", - "protobuf", + "protobuf 2.8.0", "raft", "rand 0.8.5", "regex", @@ -2307,7 +2331,7 @@ dependencies = [ "portable-atomic 0.3.20", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "proxy_ffi", "raft", "raft-proto", @@ -2322,7 +2346,7 @@ dependencies = [ "sst_importer", "tempfile", "test_sst_importer", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", "time 0.1.43", @@ -2352,7 +2376,7 @@ version = "0.0.1" dependencies = [ "api_version", "collections", - "derive_more", + "derive_more 0.99.3", "encryption", "engine_panic", "engine_rocks", @@ -2363,7 +2387,7 @@ dependencies = [ "keys", "kvproto", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log_wrappers", "num_cpus", "online_config", @@ -2371,7 +2395,7 @@ dependencies = [ "portable-atomic 0.3.20", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "proxy_ffi", "raft", "rand 0.8.5", @@ -2404,13 +2428,13 @@ dependencies = [ "keys", "kvproto", "log_wrappers", - "protobuf", + "protobuf 2.8.0", "raft", "rand 0.8.5", "serde", "slog", "slog-global", - "thiserror", + "thiserror 1.0.40", "tikv_util", "toml", "tracker", @@ -2484,7 +2508,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -2495,12 +2519,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "libc 0.2.151", - "windows-sys 0.52.0", + "libc 0.2.176", + "windows-sys 0.61.0", ] [[package]] @@ -2529,6 +2553,27 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue 2.5.0", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.1", + "pin-project-lite", +] + [[package]] name = "example_coprocessor_plugin" version = "0.1.0" @@ -2629,7 +2674,7 @@ dependencies = [ "fail", "fs2", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "online_config", "openssl", "parking_lot 0.12.1", @@ -2651,8 +2696,8 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed3d8a5e20435ff00469e51a0d82049bae66504b5c429920dadf9bb54d47b3f" dependencies = [ - "libc 0.2.151", - "thiserror", + "libc 0.2.176", + "thiserror 1.0.40", "winapi 0.3.9", ] @@ -2663,7 +2708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "redox_syscall 0.2.11", "winapi 0.3.9", ] @@ -2676,30 +2721,10 @@ checksum = "d691fdb3f817632d259d09220d4cf0991dbb2c9e59e044a02a59194bf6e14484" dependencies = [ "cc", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] -[[package]] -name = "fix-hidden-lifetime-bug" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ae9c2016a663983d4e40a9ff967d6dcac59819672f0b47f2b17574e99c33c8" -dependencies = [ - "fix-hidden-lifetime-bug-proc_macros", -] - -[[package]] -name = "fix-hidden-lifetime-bug-proc_macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c81935e123ab0741c4c4f0d9b8377e5fb21d3de7e062fa4b1263b1fbcba1ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] - [[package]] name = "flatbuffers" version = "2.1.2" @@ -2708,7 +2733,7 @@ checksum = "86b428b715fdbdd1c364b84573b5fdc0f84f8e423661b9f398735278bc7f2b6a" dependencies = [ "bitflags 1.3.2", "smallvec", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -2718,7 +2743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2adaffba6388640136149e18ed080b77a78611c1e1d6de75aedcdf78df5d4682" dependencies = [ "crc32fast", - "libc 0.2.151", + "libc 0.2.176", "libz-sys", "miniz_oxide 0.3.7", ] @@ -2770,7 +2795,7 @@ name = "fs2" version = "0.4.3" source = "git+https://github.com/tikv/fs2-rs?branch=tikv#cd503764a19a99d74c1ab424dd13d6bcd093fcae" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -2796,7 +2821,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -2899,7 +2924,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -3056,7 +3081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" dependencies = [ "cfg-if 0.1.10", - "libc 0.2.151", + "libc 0.2.176", "wasi 0.7.0", ] @@ -3068,7 +3093,7 @@ checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if 1.0.0", "js-sys", - "libc 0.2.151", + "libc 0.2.176", "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -3117,10 +3142,10 @@ dependencies = [ "futures-executor", "futures-util", "grpcio-sys", - "libc 0.2.151", + "libc 0.2.176", "log", "parking_lot 0.11.1", - "protobuf", + "protobuf 2.8.0", ] [[package]] @@ -3129,7 +3154,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed97a17310fd00ff4109357584a00244e2a785d05b7ee0ef4d1e8fb1d84266df" dependencies = [ - "protobuf", + "protobuf 2.8.0", ] [[package]] @@ -3142,7 +3167,7 @@ dependencies = [ "futures-util", "grpcio", "log", - "protobuf", + "protobuf 2.8.0", ] [[package]] @@ -3154,7 +3179,7 @@ dependencies = [ "bindgen 0.59.2", "cc", "cmake", - "libc 0.2.151", + "libc 0.2.176", "libz-sys", "openssl-sys", "pkg-config", @@ -3227,6 +3252,7 @@ dependencies = [ name = "health_controller" version = "0.1.0" dependencies = [ + "collections", "grpcio-health", "kvproto", "ordered-float", @@ -3276,7 +3302,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -3409,7 +3435,7 @@ dependencies = [ "online_config", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "slog", @@ -3613,7 +3639,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -3667,7 +3693,7 @@ dependencies = [ "keys", "kvproto", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log_wrappers", "online_config", "parking_lot 0.12.1", @@ -3687,7 +3713,7 @@ dependencies = [ "tempfile", "test_pd", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", "tokio", @@ -3734,7 +3760,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16d4bde3a7105e59c66a4104cfe9606453af1c7a0eac78cb7d5bc263eb762a70" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", "atty", "indexmap 1.6.2", "itoa 1.0.1", @@ -3754,7 +3780,7 @@ checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" dependencies = [ "bitflags 1.3.2", "inotify-sys", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -3763,7 +3789,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -3811,7 +3837,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -3856,15 +3882,16 @@ version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3895,7 +3922,7 @@ dependencies = [ "kvproto", "log_wrappers", "panic_hook", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", ] @@ -3903,11 +3930,12 @@ dependencies = [ [[package]] name = "kvproto" version = "0.0.2" -source = "git+https://github.com/pingcap/kvproto.git#e89bec5a53cc25bc13bc3d4b75af97c95cdedb3d" +source = "git+https://github.com/pingcap/kvproto.git#0503050094661a00e390e3c235966791d1c59eb0" dependencies = [ + "bytes", "futures 0.3.15", "grpcio", - "protobuf", + "protobuf 2.8.0", "protobuf-build", "raft-proto", ] @@ -3996,9 +4024,9 @@ checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libfuzzer-sys" @@ -4038,13 +4066,13 @@ dependencies = [ [[package]] name = "librocksdb_sys" version = "0.1.0" -source = "git+https://github.com/tikv/rust-rocksdb.git#489433e1cbaba553500c5c9145bf7290f58d9e73" +source = "git+https://github.com/tikv/rust-rocksdb.git#995b1f22af7a252ac35c2f90d007ddeee201aca6" dependencies = [ "bindgen 0.65.1", "bzip2-sys", "cc", "cmake", - "libc 0.2.151", + "libc 0.2.176", "libtitan_sys", "libz-sys", "lz4-sys", @@ -4057,12 +4085,12 @@ dependencies = [ [[package]] name = "libtitan_sys" version = "0.0.1" -source = "git+https://github.com/tikv/rust-rocksdb.git#489433e1cbaba553500c5c9145bf7290f58d9e73" +source = "git+https://github.com/tikv/rust-rocksdb.git#995b1f22af7a252ac35c2f90d007ddeee201aca6" dependencies = [ "bzip2-sys", "cc", "cmake", - "libc 0.2.151", + "libc 0.2.176", "libz-sys", "lz4-sys", "snappy-sys", @@ -4076,7 +4104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" dependencies = [ "cc", - "libc 0.2.151", + "libc 0.2.176", "pkg-config", "vcpkg", ] @@ -4130,7 +4158,7 @@ dependencies = [ "atomic", "hex 0.4.3", "online_config", - "protobuf", + "protobuf 2.8.0", "serde", "slog", "slog-term", @@ -4154,7 +4182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" dependencies = [ "cc", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -4170,11 +4198,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.8", + "regex-automata 0.4.3", ] [[package]] @@ -4190,7 +4218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if 1.0.0", - "digest 0.10.7", + "digest", ] [[package]] @@ -4211,7 +4239,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -4221,7 +4249,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -4301,7 +4329,7 @@ dependencies = [ "fuchsia-zircon-sys", "iovec", "kernel32-sys", - "libc 0.2.151", + "libc 0.2.176", "log", "miow", "net2", @@ -4315,7 +4343,7 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -4384,7 +4412,7 @@ dependencies = [ "log_wrappers", "openssl", "pd_client", - "protobuf", + "protobuf 2.8.0", "proxy_server", "raft", "raft_log_engine", @@ -4434,7 +4462,7 @@ dependencies = [ "cfg-if 1.0.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -4480,12 +4508,11 @@ checksum = "97af489e1e21b68de4c390ecca6703318bc1aa16e9733bcb62c089b73c6fbb1b" [[package]] name = "native-tls" -version = "0.2.7" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ - "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log", "openssl", "openssl-probe", @@ -4503,7 +4530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" dependencies = [ "cfg-if 0.1.10", - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -4516,7 +4543,7 @@ dependencies = [ "bitflags 1.3.2", "cc", "cfg-if 0.1.10", - "libc 0.2.151", + "libc 0.2.176", "void", ] @@ -4529,7 +4556,7 @@ dependencies = [ "bitflags 1.3.2", "cc", "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "memoffset 0.6.4", ] @@ -4541,7 +4568,7 @@ checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "memoffset 0.6.4", ] @@ -4553,7 +4580,7 @@ checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "memoffset 0.7.1", "pin-utils", "static_assertions", @@ -4612,7 +4639,7 @@ dependencies = [ "fsevent", "fsevent-sys", "inotify", - "libc 0.2.151", + "libc 0.2.176", "mio 0.6.23", "mio-extras", "walkdir", @@ -4630,12 +4657,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi 0.3.9", + "windows-sys 0.52.0", ] [[package]] @@ -4694,15 +4720,10 @@ dependencies = [ ] [[package]] -name = "num-derive" -version = "0.3.0" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8b15b261814f992e33760b1fca9fe8b693d8a65299f20c9901688636cfb746" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.103", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-derive" @@ -4712,7 +4733,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -4784,7 +4805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -4793,14 +4814,14 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] name = "oauth2" -version = "4.1.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e47cfc4c0a1a519d9a025ebfbac3a2439d1b5cdf397d72dcb79b11d9920dab" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" dependencies = [ "base64 0.13.0", "chrono", @@ -4810,8 +4831,8 @@ dependencies = [ "serde", "serde_json", "serde_path_to_error", - "sha2 0.9.1", - "thiserror", + "sha2", + "thiserror 1.0.40", "url", ] @@ -4855,22 +4876,16 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags 2.4.1", "cfg-if 1.0.0", "foreign-types", - "libc 0.2.151", + "libc 0.2.176", "once_cell", "openssl-macros", "openssl-sys", @@ -4878,13 +4893,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.101", ] [[package]] @@ -4895,21 +4910,21 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.25.0+1.1.1t" +version = "300.5.2+3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3173cd3626c43e3854b1b727422a276e568d9ec5fe8cec197822cf52cfb743d6" +checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.92" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", - "libc 0.2.151", + "libc 0.2.176", "openssl-src", "pkg-config", "vcpkg", @@ -4939,19 +4954,13 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "page_size" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] @@ -4994,7 +5003,7 @@ checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ "cfg-if 1.0.0", "instant", - "libc 0.2.151", + "libc 0.2.176", "redox_syscall 0.2.11", "smallvec", "winapi 0.3.9", @@ -5007,7 +5016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" dependencies = [ "cfg-if 1.0.0", - "libc 0.2.151", + "libc 0.2.176", "redox_syscall 0.2.11", "smallvec", "windows-sys 0.32.0", @@ -5048,7 +5057,7 @@ dependencies = [ "serde_derive", "slog", "slog-global", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", "tokio", @@ -5083,7 +5092,7 @@ checksum = "b8f94885300e262ef461aa9fd1afbf7df3caf9e84e271a74925d1c6c8b24830f" dependencies = [ "bitflags 1.3.2", "byteorder", - "libc 0.2.151", + "libc 0.2.176", "mmap", "nom 4.2.3", "phf", @@ -5216,7 +5225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d27361d7578b410d0eb5fe815c2b2105b01ab770a7c738cb9a231457a809fcc7" dependencies = [ "ipnetwork", - "libc 0.2.151", + "libc 0.2.176", "pnet_base", "pnet_sys", "winapi 0.2.8", @@ -5228,7 +5237,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82f881a6d75ac98c5541db6144682d1773bb14c6fc50c6ebac7086c8f7f23c29" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.2.8", "ws2_32-sys", ] @@ -5239,37 +5248,67 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e30165d31df606f5726b090ec7592c308a0eaf61721ff64c9a3018e344a8753e" dependencies = [ - "portable-atomic 1.11.0", + "portable-atomic 1.11.1", ] [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "pprof" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebbe2f8898beba44815fdc9e5a4ae9c929e21c5dc29b0c774a15555f7f58d6d0" +checksum = "afad4d4df7b31280028245f152d5a575083e2abb822d05736f5e47653e77689f" dependencies = [ "aligned-vec", "backtrace", "cfg-if 1.0.0", "findshlibs", "inferno", - "libc 0.2.151", + "libc 0.2.176", "log", "nix 0.26.2", "once_cell", - "parking_lot 0.12.1", - "protobuf", + "protobuf 2.8.0", "protobuf-codegen-pure", "smallvec", + "spin", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.40", +] + +[[package]] +name = "pprof" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a01da47675efa7673b032bf8efd8214f1917d89685e07e395ab125ea42b187" +dependencies = [ + "aligned-vec", + "backtrace", + "cfg-if 1.0.0", + "findshlibs", + "inferno", + "libc 0.2.176", + "log", + "nix 0.26.2", + "once_cell", + "protobuf 3.7.2", + "protobuf-codegen 3.7.2", + "smallvec", + "spin", + "symbolic-demangle", + "tempfile", + "thiserror 2.0.12", ] [[package]] @@ -5321,7 +5360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b69d39aab54d069e7f2fe8cb970493e7834601ca2d8c65fd7bbd183578080d1" dependencies = [ "proc-macro2", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -5360,9 +5399,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -5377,7 +5416,7 @@ dependencies = [ "byteorder", "hex 0.4.3", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -5386,7 +5425,7 @@ version = "0.4.2" source = "git+https://github.com/tikv/procinfo-rs?rev=6599eb9dca74229b2c1fcc44118bef7eff127128#6599eb9dca74229b2c1fcc44118bef7eff127128" dependencies = [ "byteorder", - "libc 0.2.151", + "libc 0.2.176", "nom 2.2.1", "rustc_version 0.2.3", ] @@ -5397,7 +5436,7 @@ version = "0.4.2" source = "git+https://github.com/tikv/procinfo-rs?rev=7693954bd1dd86eb1709572fd7b62fd5f7ff2ea1#7693954bd1dd86eb1709572fd7b62fd5f7ff2ea1" dependencies = [ "byteorder", - "libc 0.2.151", + "libc 0.2.176", "nom 2.2.1", "rustc_version 0.2.3", ] @@ -5421,12 +5460,12 @@ dependencies = [ "cfg-if 1.0.0", "fnv", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "memchr", "parking_lot 0.11.1", - "protobuf", + "protobuf 2.8.0", "reqwest", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -5455,7 +5494,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.0", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -5464,7 +5503,7 @@ dependencies = [ [[package]] name = "protobuf" version = "2.8.0" -source = "git+https://github.com/pingcap/rust-protobuf?branch=v2.8#6d445fe5ff4e99621a800be0f2c54dc96f056bac" +source = "git+https://github.com/pingcap/rust-protobuf?branch=v2.8#de31a47f395c2f46dbfea2545517ea1b27ad0096" dependencies = [ "atomic", "bytes", @@ -5472,6 +5511,17 @@ dependencies = [ "hex 0.3.2", ] +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror 1.0.40", +] + [[package]] name = "protobuf-build" version = "0.15.1" @@ -5480,8 +5530,8 @@ checksum = "c852d9625b912c3e50480cdc701f60f49890b5d7ad46198dd583600f15e7c6ec" dependencies = [ "bitflags 1.3.2", "grpcio-compiler", - "protobuf", - "protobuf-codegen", + "protobuf 2.8.0", + "protobuf-codegen 2.8.0", "protobuf-src", "regex", ] @@ -5489,10 +5539,25 @@ dependencies = [ [[package]] name = "protobuf-codegen" version = "2.8.0" -source = "git+https://github.com/pingcap/rust-protobuf?branch=v2.8#6d445fe5ff4e99621a800be0f2c54dc96f056bac" +source = "git+https://github.com/pingcap/rust-protobuf?branch=v2.8#de31a47f395c2f46dbfea2545517ea1b27ad0096" dependencies = [ "heck 0.3.1", - "protobuf", + "protobuf 2.8.0", +] + +[[package]] +name = "protobuf-codegen" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" +dependencies = [ + "anyhow", + "once_cell", + "protobuf 3.7.2", + "protobuf-parse", + "regex", + "tempfile", + "thiserror 1.0.40", ] [[package]] @@ -5501,8 +5566,24 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00993dc5fbbfcf9d8a005f6b6c29fd29fd6d86deba3ae3f41fd20c624c414616" dependencies = [ - "protobuf", - "protobuf-codegen", + "protobuf 2.8.0", + "protobuf-codegen 2.8.0", +] + +[[package]] +name = "protobuf-parse" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" +dependencies = [ + "anyhow", + "indexmap 2.0.1", + "log", + "protobuf 3.7.2", + "protobuf-support", + "tempfile", + "thiserror 1.0.40", + "which 4.2.4", ] [[package]] @@ -5514,6 +5595,15 @@ dependencies = [ "autotools", ] +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror 1.0.40", +] + [[package]] name = "proxy_ffi" version = "0.0.1" @@ -5532,7 +5622,7 @@ dependencies = [ "lazy_static", "openssl", "pd_client", - "protobuf", + "protobuf 2.8.0", "raftstore", "reqwest", "rocksdb", @@ -5583,7 +5673,7 @@ dependencies = [ "keys", "kvproto", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log", "log_wrappers", "mime", @@ -5592,9 +5682,9 @@ dependencies = [ "openssl", "pd_client", "pin-project", - "pprof", + "pprof 0.14.1", "prometheus", - "protobuf", + "protobuf 2.8.0", "proxy_ffi", "raft", "raft_log_engine", @@ -5664,7 +5754,7 @@ dependencies = [ "hyper", "keys", "kvproto", - "libc 0.2.151", + "libc 0.2.176", "log_wrappers", "mock-engine-store", "more-asserts", @@ -5675,7 +5765,7 @@ dependencies = [ "perfcnt", "procinfo 0.4.2 (git+https://github.com/tikv/procinfo-rs?rev=6599eb9dca74229b2c1fcc44118bef7eff127128)", "profiler", - "protobuf", + "protobuf 2.8.0", "proxy_ffi", "proxy_server", "raft", @@ -5735,9 +5825,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", "serde", @@ -5760,17 +5850,17 @@ dependencies = [ "bytes", "fxhash", "getset", - "protobuf", + "protobuf 2.8.0", "raft-proto", "rand 0.8.5", "slog", - "thiserror", + "thiserror 1.0.40", ] [[package]] name = "raft-engine" version = "0.4.2" -source = "git+https://github.com/tikv/raft-engine.git#de1ec937529e3a88e093db0cf0d403522565fe64" +source = "git+https://github.com/tikv/raft-engine.git#03f77d90c09793a6f79411ff5f88233715eb23da" dependencies = [ "byteorder", "crc32fast", @@ -5781,24 +5871,24 @@ dependencies = [ "hex 0.4.3", "if_chain", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log", "lz4-sys", "memmap2", "nix 0.26.2", - "num-derive 0.4.2", + "num-derive", "num-traits", "parking_lot 0.12.1", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "rayon", "rhai", "scopeguard", "serde", "serde_repr", "strum 0.26.3", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -5807,7 +5897,7 @@ version = "0.7.0" source = "git+https://github.com/tikv/raft-rs?branch=master#0d01b20312f74889a5e44ad4180aade5da2f16fa" dependencies = [ "bytes", - "protobuf", + "protobuf 2.8.0", "protobuf-build", ] @@ -5844,7 +5934,7 @@ dependencies = [ "concurrency_manager", "crc32fast", "crossbeam", - "derivative", + "derive_more 2.0.1", "encryption", "encryption_export", "engine_panic", @@ -5872,7 +5962,7 @@ dependencies = [ "pd_client", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "raft", "raft-proto", "rand 0.8.5", @@ -5889,7 +5979,7 @@ dependencies = [ "strum 0.20.0", "tempfile", "test_sst_importer", - "thiserror", + "thiserror 1.0.40", "tidb_query_datatype", "tikv_alloc", "tikv_util", @@ -5943,7 +6033,7 @@ dependencies = [ "parking_lot 0.12.1", "pd_client", "prometheus", - "protobuf", + "protobuf 2.8.0", "raft", "raft-proto", "raftstore", @@ -5957,7 +6047,7 @@ dependencies = [ "tempfile", "test_pd", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv_util", "time 0.1.43", "tracker", @@ -5973,7 +6063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" dependencies = [ "fuchsia-cprng", - "libc 0.2.151", + "libc 0.2.176", "rand_core 0.3.1", "rdrand", "winapi 0.3.9", @@ -5986,7 +6076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.12", - "libc 0.2.151", + "libc 0.2.176", "rand_chacha 0.2.1", "rand_core 0.5.1", "rand_hc", @@ -5998,7 +6088,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "rand_chacha 0.3.0", "rand_core 0.6.4", ] @@ -6162,7 +6252,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -6172,8 +6262,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" dependencies = [ "byteorder", - "regex-syntax 0.6.29", - "utf8-ranges", ] [[package]] @@ -6184,7 +6272,7 @@ checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -6193,12 +6281,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -6216,34 +6298,40 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.1" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.13.0", + "base64 0.21.7", "bytes", "encoding_rs 0.8.33", "futures-core", "futures-util", + "h2", "http 0.2.12", "http-body 0.4.5", "hyper", "hyper-tls", "ipnet", "js-sys", - "lazy_static", "log", "mime", "native-tls", + "once_cell", "percent-encoding", "pin-project-lite", "serde", + "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", + "tokio-util", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", "winreg", ] @@ -6265,7 +6353,7 @@ dependencies = [ "online_config", "pd_client", "prometheus", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "security", @@ -6275,7 +6363,7 @@ dependencies = [ "test_raftstore", "test_sst_importer", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv", "tikv_kv", "tikv_util", @@ -6300,7 +6388,7 @@ dependencies = [ "pd_client", "pin-project", "prometheus", - "protobuf", + "protobuf 2.8.0", "rand 0.8.5", "serde", "serde_json", @@ -6356,7 +6444,7 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f06953bb8b9e4307cb7ccc0d9d018e2ddd25a30d32831f631ce4fe8f17671f7" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", "bitflags 1.3.2", "instant", "num-traits", @@ -6379,9 +6467,9 @@ dependencies = [ [[package]] name = "rocksdb" version = "0.3.0" -source = "git+https://github.com/tikv/rust-rocksdb.git#489433e1cbaba553500c5c9145bf7290f58d9e73" +source = "git+https://github.com/tikv/rust-rocksdb.git#995b1f22af7a252ac35c2f90d007ddeee201aca6" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "librocksdb_sys", ] @@ -6453,7 +6541,7 @@ checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" dependencies = [ "bitflags 2.4.1", "errno", - "libc 0.2.151", + "libc 0.2.176", "linux-raw-sys", "windows-sys 0.48.0", ] @@ -6482,12 +6570,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" -[[package]] -name = "safemem" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" - [[package]] name = "same-file" version = "1.0.5" @@ -6499,12 +6581,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.16" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "lazy_static", - "winapi 0.3.9", + "windows-sys 0.61.0", ] [[package]] @@ -6545,7 +6626,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-foundation-sys", - "libc 0.2.151", + "libc 0.2.176", "security-framework-sys", ] @@ -6556,7 +6637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339" dependencies = [ "core-foundation-sys", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -6641,7 +6722,7 @@ checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -6682,7 +6763,7 @@ checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.40", ] [[package]] @@ -6698,12 +6779,12 @@ dependencies = [ [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 0.4.4", + "itoa 1.0.1", "ryu", "serde", ] @@ -6758,11 +6839,11 @@ dependencies = [ "in_memory_engine", "keys", "kvproto", - "libc 0.2.151", + "libc 0.2.176", "log_wrappers", "pd_client", "prometheus", - "protobuf", + "protobuf 2.8.0", "raft", "raft_log_engine", "raftstore", @@ -6802,20 +6883,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 0.1.10", - "cpuid-bool", - "digest 0.9.0", - "opaque-debug", + "digest", ] [[package]] @@ -6826,7 +6894,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -6856,7 +6924,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106428d9d96840ecdec5208c13ab8a4e28c38da1e0ccf2909fb44e41b992f897" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "nix 0.11.1", ] @@ -6866,7 +6934,7 @@ version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "signal-hook-registry", ] @@ -6876,16 +6944,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ - "libc 0.2.151", -] - -[[package]] -name = "simsimd" -version = "6.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56838e1a0aceaef39fc1327227033efa84a294f54a39b356eefa5c60c885e9f0" -dependencies = [ - "cc", + "libc 0.2.176", ] [[package]] @@ -6896,9 +6955,9 @@ checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" [[package]] name = "slab" -version = "0.4.2" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slog" @@ -7003,7 +7062,7 @@ dependencies = [ "slog", "slog-global", "tempfile", - "thiserror", + "thiserror 1.0.40", "tikv", "tikv_util", "tokio", @@ -7016,7 +7075,7 @@ version = "0.1.0" source = "git+https://github.com/tikv/rust-snappy.git?branch=static-link#8c12738bad811397600455d6982aff754ea2ac44" dependencies = [ "cmake", - "libc 0.2.151", + "libc 0.2.176", "pkg-config", ] @@ -7044,10 +7103,19 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +dependencies = [ + "lock_api", +] + [[package]] name = "sst_importer" version = "0.1.0" @@ -7064,6 +7132,7 @@ dependencies = [ "engine_traits", "error_code", "external_storage", + "fail", "file_system", "futures 0.3.15", "futures-util", @@ -7075,7 +7144,7 @@ dependencies = [ "online_config", "openssl", "prometheus", - "protobuf", + "protobuf 2.8.0", "rand 0.8.5", "serde", "serde_derive", @@ -7084,7 +7153,7 @@ dependencies = [ "tempfile", "test_sst_importer", "test_util", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", "tokio", @@ -7187,7 +7256,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -7232,9 +7301,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -7255,7 +7324,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -7265,13 +7334,34 @@ source = "git+https://github.com/tikv/sysinfo?branch=0.26-fix-cpu#5a1bcf08816979 dependencies = [ "cfg-if 1.0.0", "core-foundation-sys", - "libc 0.2.151", + "libc 0.2.176", "ntapi", "once_cell", "rayon", "winapi 0.3.9", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc 0.2.176", +] + [[package]] name = "take_mut" version = "0.2.2" @@ -7294,7 +7384,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "thiserror", + "thiserror 1.0.40", "url", ] @@ -7394,7 +7484,7 @@ dependencies = [ "futures-util", "grpcio", "kvproto", - "protobuf", + "protobuf 2.8.0", "raftstore", "rand 0.8.5", "test_raftstore", @@ -7414,7 +7504,7 @@ dependencies = [ "futures 0.3.15", "kvproto", "pd_client", - "protobuf", + "protobuf 2.8.0", "resource_metering", "test_storage", "tidb_query_common", @@ -7490,7 +7580,7 @@ dependencies = [ "lazy_static", "log_wrappers", "pd_client", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "rand 0.8.5", @@ -7532,7 +7622,7 @@ dependencies = [ "kvproto", "log_wrappers", "pd_client", - "protobuf", + "protobuf 2.8.0", "raft", "raftstore", "raftstore-v2", @@ -7662,7 +7752,7 @@ dependencies = [ "pd_client", "perfcnt", "profiler", - "protobuf", + "protobuf 2.8.0", "raft", "raft_log_engine", "raftstore", @@ -7725,7 +7815,16 @@ version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.40", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -7736,7 +7835,18 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] @@ -7780,8 +7890,9 @@ version = "0.0.1" dependencies = [ "anyhow", "api_version", + "async-trait", "byteorder", - "derive_more", + "derive_more 0.99.3", "error_code", "futures 0.3.15", "kvproto", @@ -7789,8 +7900,9 @@ dependencies = [ "log_wrappers", "prometheus", "prometheus-static-metric", + "raft", "serde_json", - "thiserror", + "thiserror 1.0.40", "tikv_util", "time 0.1.43", "yatp", @@ -7822,18 +7934,17 @@ dependencies = [ "match-template", "nom 7.1.3", "num 0.3.0", - "num-derive 0.3.0", + "num-derive", "num-traits", "ordered-float", - "protobuf", + "protobuf 2.8.0", "regex", "serde", "serde_json", - "simsimd", "slog", "slog-global", "static_assertions", - "thiserror", + "thiserror 1.0.40", "tidb_query_common", "tikv_alloc", "tikv_util", @@ -7855,7 +7966,7 @@ dependencies = [ "kvproto", "log_wrappers", "match-template", - "protobuf", + "protobuf 2.8.0", "slog", "slog-global", "smallvec", @@ -7867,6 +7978,7 @@ dependencies = [ "tikv_util", "tipb", "tipb_helper", + "txn_types", ] [[package]] @@ -7885,14 +7997,14 @@ dependencies = [ "hex 0.4.3", "log_wrappers", "match-template", + "memchr", "num 0.3.0", "num-traits", "openssl", "panic_hook", "profiler", - "protobuf", + "protobuf 2.8.0", "regex", - "safemem", "serde", "serde_json", "static_assertions", @@ -7903,13 +8015,12 @@ dependencies = [ "time 0.1.43", "tipb", "tipb_helper", - "twoway", "uuid 0.8.2", ] [[package]] name = "tikv" -version = "9.0.0-beta.1" +version = "9.0.0-beta.2" dependencies = [ "anyhow", "api_version", @@ -7958,7 +8069,7 @@ dependencies = [ "keys", "kvproto", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "libloading", "log", "log_wrappers", @@ -7978,10 +8089,10 @@ dependencies = [ "pd_client", "pin-project", "pnet_datalink", - "pprof", + "pprof 0.15.0", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "raft", "raft_log_engine", "raftstore", @@ -8009,7 +8120,7 @@ dependencies = [ "sysinfo", "tempfile", "test_util", - "thiserror", + "thiserror 1.0.40", "tidb_query_common", "tidb_query_datatype", "tidb_query_executors", @@ -8039,7 +8150,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e37706572f4b151dff7a0146e040804e9c26fe3a3118591112f05cf12a4216c1" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "paste", "tikv-jemalloc-sys", ] @@ -8052,7 +8163,7 @@ checksum = "aeab4310214fe0226df8bfeb893a291a58b19682e8a07e1e1d4483ad4200d315" dependencies = [ "cc", "fs_extra", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -8061,7 +8172,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20612db8a13a6c06d57ec83953694185a367e16945f66565e8028d2c0bd76979" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "tikv-jemalloc-sys", ] @@ -8071,7 +8182,7 @@ version = "0.1.0" dependencies = [ "fxhash", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "mimalloc", "snmalloc-rs", "tcmalloc", @@ -8107,7 +8218,7 @@ dependencies = [ "slog-global", "slog_derive", "tempfile", - "thiserror", + "thiserror 1.0.40", "tikv_util", "tracker", "txn_types", @@ -8127,7 +8238,7 @@ dependencies = [ "cpu-time", "crossbeam", "crossbeam-skiplist 0.1.3", - "derive_more", + "derive_more 0.99.3", "error_code", "fail", "fs2", @@ -8139,7 +8250,7 @@ dependencies = [ "http 0.2.12", "kvproto", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", "log", "log_wrappers", "nix 0.24.1", @@ -8154,7 +8265,7 @@ dependencies = [ "procinfo 0.4.2 (git+https://github.com/tikv/procinfo-rs?rev=7693954bd1dd86eb1709572fd7b62fd5f7ff2ea1)", "prometheus", "prometheus-static-metric", - "protobuf", + "protobuf 2.8.0", "rand 0.8.5", "regex", "serde", @@ -8167,7 +8278,7 @@ dependencies = [ "strum 0.20.0", "sysinfo", "tempfile", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "time 0.1.43", "tokio", @@ -8186,19 +8297,23 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "winapi 0.3.9", ] [[package]] name = "time" -version = "0.3.20" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ + "deranged", "itoa 1.0.1", - "libc 0.2.151", + "js-sys", + "libc 0.2.176", + "num-conv", "num_threads", + "powerfmt", "serde", "time-core", "time-macros", @@ -8206,16 +8321,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ + "num-conv", "time-core", ] @@ -8257,11 +8373,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tipb" version = "0.0.1" -source = "git+https://github.com/pingcap/tipb.git#cf70966bef25e205cb845c19265301542d1238d1" +source = "git+https://github.com/pingcap/tipb.git#85a019a5df23fa11f93c53ebf7fc05462813df1e" dependencies = [ "futures 0.3.15", "grpcio", - "protobuf", + "protobuf 2.8.0", "protobuf-build", ] @@ -8282,7 +8398,7 @@ checksum = "68722da18b0fc4a05fdc1120b302b82051265792a1e1b399086e9b204b10ad3d" dependencies = [ "backtrace", "bytes", - "libc 0.2.151", + "libc 0.2.176", "mio 0.8.11", "num_cpus", "parking_lot 0.12.1", @@ -8310,7 +8426,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -8384,9 +8500,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" [[package]] name = "toml_edit" @@ -8413,9 +8529,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -8438,20 +8554,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -8470,9 +8586,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -8480,14 +8596,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata 0.4.3", "serde", "serde_json", "sharded-slab", @@ -8519,16 +8635,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -[[package]] -name = "twoway" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "766345ed3891b291d01af307cd3ad2992a4261cb6c0c7e665cd3e01cf379dd24" -dependencies = [ - "memchr", - "unchecked-index", -] - [[package]] name = "twox-hash" version = "1.6.3" @@ -8555,7 +8661,7 @@ dependencies = [ "panic_hook", "rand 0.8.5", "slog", - "thiserror", + "thiserror 1.0.40", "tikv_alloc", "tikv_util", ] @@ -8566,6 +8672,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "tz-rs" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33851b15c848fad2cf4b105c6bb66eb9512b6f6c44a4b13f57c53c73c707e2b4" +dependencies = [ + "const_fn", +] + [[package]] name = "ucd-trie" version = "0.1.3" @@ -8578,12 +8693,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unchecked-index" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" - [[package]] name = "unicode-ident" version = "1.0.5" @@ -8632,12 +8741,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -8661,6 +8764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom 0.2.11", + "serde", ] [[package]] @@ -8717,7 +8821,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -8761,48 +8865,49 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if 1.0.0", - "serde", - "serde_json", + "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", - "lazy_static", "log", "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.101", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.20" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if 1.0.0", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8810,28 +8915,44 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.103", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -8843,7 +8964,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -8854,7 +8975,7 @@ checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" dependencies = [ "either", "lazy_static", - "libc 0.2.151", + "libc 0.2.176", ] [[package]] @@ -8909,6 +9030,12 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-sys" version = "0.32.0" @@ -8940,6 +9067,15 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -9095,11 +9231,12 @@ dependencies = [ [[package]] name = "winreg" -version = "0.7.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi 0.3.9", + "cfg-if 1.0.0", + "windows-sys 0.48.0", ] [[package]] @@ -9194,7 +9331,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", "synstructure", ] @@ -9215,7 +9352,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -9235,7 +9372,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", "synstructure", ] @@ -9264,7 +9401,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -9300,7 +9437,7 @@ version = "5.0.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" dependencies = [ - "libc 0.2.151", + "libc 0.2.176", "zstd-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 22781004153..8b24634fb09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tikv" -version = "9.0.0-beta.1" +version = "9.0.0-beta.2" authors = ["The TiKV Authors"] description = "A distributed transactional key-value database powered by Rust and Raft" license = "Apache-2.0" @@ -58,7 +58,7 @@ openssl-vendored = [ # for testing configure propegate to other crates # https://stackoverflow.com/questions/41700543/can-we-share-test-utilites-between-crates testing = [] -docker_test = [] # Feature flag for Docker-specific tests +docker_test = [] # Feature flag for Docker-specific tests [lib] name = "tikv" @@ -133,7 +133,7 @@ paste = "1.0" pd_client = { workspace = true } pin-project = "1.0" pnet_datalink = "0.23" -pprof = { version = "0.14", default-features = false, features = [ +pprof = { version = "0.15", default-features = false, features = [ "flamegraph", "protobuf-codec", ] } diff --git a/OWNERS b/OWNERS index af3aca17ee3..b3321b31e9f 100644 --- a/OWNERS +++ b/OWNERS @@ -1,14 +1,22 @@ -# See the OWNERS docs at https://go.k8s.io/owners +# See the OWNERS docs at https://www.kubernetes.dev/docs/guide/owners/#owners +# The members of 'sig-community-*' are synced from memberships defined in repository: https://github.com/tikv/community. approvers: - 5kbpers - AndreMouche + - BusyJay + - Connor1996 + - Little-Wallace + - LykxSassinator + - MyonKeminta + - NingLin-P + - SpadeA-Tang + - TennyZhuang + - YuJuncen - andylokandy - breezewish - brson - bufferflies - - BusyJay - cfzjywxk - - Connor1996 - coocood - crazycs520 - disksing @@ -22,30 +30,23 @@ approvers: - iosmanthus - jackysp - kennytm - - Little-Wallace - liuzix - lonng - - LykxSassinator - lysu - marsishandsome - - MyonKeminta - niedhui - - NingLin-P - nrc - overvenus - pingyu - skyzh - - SpadeA-Tang - sticnarf - sunxiaoguang - tabokie - - TennyZhuang - tonyxuqqi - v01dstar - yiwu-arbug - you06 - youjiali1995 - - YuJuncen - zhangjinpeng87 - zhongzc - zhouqiang-cl @@ -54,27 +55,27 @@ reviewers: - 3AceShowHand - 3pointer - CalvinNeo + - Fullstop000 + - HuSharp + - Jibbow + - JmPotato + - Leavrth + - Mossaka + - MrCroxx + - Rustin170506 + - Xuanwo - ethercflow - fredchenbj - - Fullstop000 - gozssky - haojinming - hbisheng - hhwyt - - HuSharp - jayzhan211 - - Jibbow - - JmPotato - - Leavrth - lhy1024 - longfangsong - lzmhhh123 - - Mossaka - - MrCroxx - nolouch - rleungx - - Rustin170506 - tier-cap - wjhuang2016 - wshwsh12 - - Xuanwo diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 49fdc25e4ee..0c2bb301242 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -1,4 +1,5 @@ -# Sort the member alphabetically. +# See the OWNERS docs at https://www.kubernetes.dev/docs/guide/owners/#owners_aliases +# The members of 'sig-community-*' are synced from memberships defined in repository: https://github.com/tikv/community. aliases: sig-critical-approvers-config-components: - BenMeadowcroft diff --git a/README.md b/README.md index 0e0203c9f57..dab1dc4c2b4 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,78 @@ To use this library, please follow the steps below: ## Contact +<<<<<<< HEAD [Rongzhen Luo](http://github.com/CalvinNeo) ([luorongzhen@pingcap.com](mailto:luorongzhen@pingcap.com)) +======= +4. Install TiKV Client(Python) and verify the deployment, required Python 3.5+. + +```bash +$ pip3 install -i https://test.pypi.org/simple/ tikv-client +``` + +```python +from tikv_client import RawClient + +client = RawClient.connect(["127.0.0.1:2379"]) + +client.put(b'foo', b'bar') +print(client.get(b'foo')) # b'bar' + +client.put(b'foo', b'baz') +print(client.get(b'foo')) # b'baz' +``` + +### Deploy a cluster with TiUP + +You can see [this manual](./doc/deploy.md) of production-like cluster deployment presented by @c4pt0r. + +### Build from source + +See [CONTRIBUTING.md](./CONTRIBUTING.md). + +## Client drivers + +- [Go](https://github.com/tikv/client-go) (The most stable and widely used) +- [Java](https://github.com/tikv/client-java) +- [Rust](https://github.com/tikv/client-rust) +- [C](https://github.com/tikv/client-c) + +If you want to try the Go client, see [Go Client](https://tikv.org/docs/4.0/reference/clients/go/). + +## Security + +### Security audit + +A third-party security auditing was performed by Cure53. See the full report [here](./security/Security-Audit.pdf). + +### Reporting Security Vulnerabilities + +To report a security vulnerability, please send an email to [TiKV-security](mailto:tikv-security@lists.cncf.io) group. + +See [Security](SECURITY.md) for the process and policy followed by the TiKV project. + +## Communication + +Communication within the TiKV community abides by [TiKV Code of Conduct](./CODE_OF_CONDUCT.md). Here is an excerpt: + +> In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +### Social Media + +- [Twitter](https://twitter.com/tikvproject) +- [Blog](https://tikv.org/blog/) +- [Reddit](https://www.reddit.com/r/TiKV) +- Post questions or help answer them on [Stack Overflow](https://stackoverflow.com/questions/tagged/tikv) + +### Slack + +Join the TiKV community on [Slack](https://slack.tidb.io/invite?team=tikv-wg&channel=general) - Sign up and join channels on TiKV topics that interest you. +>>>>>>> tikv/master ## License diff --git a/cmd/tikv-ctl/src/cmd.rs b/cmd/tikv-ctl/src/cmd.rs index a42e1781383..436c73176b5 100644 --- a/cmd/tikv-ctl/src/cmd.rs +++ b/cmd/tikv-ctl/src/cmd.rs @@ -1,9 +1,9 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -use std::{borrow::ToOwned, str, string::ToString, sync::LazyLock, u64}; +use std::{borrow::ToOwned, str, string::ToString, sync::LazyLock}; -use clap::{crate_authors, AppSettings}; -use engine_traits::{SstCompressionType, CF_DEFAULT}; +use clap::{AppSettings, crate_authors}; +use engine_traits::{CF_DEFAULT, SstCompressionType}; use raft_engine::ReadableSize; use structopt::StructOpt; @@ -705,6 +705,20 @@ pub enum Cmd { ) )] minimal_compaction_size: ReadableSize, + + #[structopt( + long, + default_value = "128", + help("specify the maximum count of running tasks to download a metadata") + )] + prefetch_running_count: u64, + + #[structopt( + long, + default_value = "1024", + help("specify the maximum count of spawning tasks to download a metadata") + )] + prefetch_buffer_count: u64, }, /// Get the state of a region's RegionReadProgress. GetRegionReadProgress { diff --git a/cmd/tikv-ctl/src/executor.rs b/cmd/tikv-ctl/src/executor.rs index 30d4aa192ac..adcfd5c0010 100644 --- a/cmd/tikv-ctl/src/executor.rs +++ b/cmd/tikv-ctl/src/executor.rs @@ -9,15 +9,15 @@ use api_version::{ApiV1, KvFormat}; use encryption_export::data_key_manager_from_config; use engine_rocks::util::{db_exist, new_engine_opt}; use engine_traits::{ - Engines, Error as EngineError, RaftEngine, TabletRegistry, ALL_CFS, CF_DEFAULT, CF_LOCK, - CF_WRITE, DATA_CFS, + ALL_CFS, CF_DEFAULT, CF_LOCK, CF_WRITE, DATA_CFS, Engines, Error as EngineError, RaftEngine, + TabletRegistry, }; use file_system::read_dir; use futures::{ + StreamExt, TryStreamExt, executor::block_on, future, stream::{self, BoxStream}, - StreamExt, TryStreamExt, }; use grpcio::{ChannelBuilder, Environment}; use kvproto::{ @@ -31,7 +31,7 @@ use pd_client::{Config as PdConfig, PdClient, RpcClient}; use protobuf::Message; use raft::eraftpb::{ConfChange, ConfChangeV2, Entry, EntryType}; use raft_log_engine::RaftLogEngine; -use raftstore::store::{util::build_key_range, INIT_EPOCH_CONF_VER}; +use raftstore::store::{INIT_EPOCH_CONF_VER, util::build_key_range}; use security::SecurityManager; use serde_json::json; use server::fatal; @@ -39,15 +39,15 @@ use slog_global::crit; use tikv::{ config::{ConfigController, TikvConfig}, server::{ + KvEngineFactoryBuilder, debug::{BottommostLevelCompaction, Debugger, DebuggerImpl, RegionInfo}, debug2::DebuggerImplV2, - KvEngineFactoryBuilder, }, storage::{ + Engine, config::EngineType, kv::MockEngine, lock_manager::{LockManager, MockLockManager}, - Engine, }, }; use tikv_util::escape; @@ -108,9 +108,15 @@ pub fn new_debug_executor( .build_shared_rocks_env(key_manager.clone(), None /* io_rate_limiter */) .unwrap(); - let factory = KvEngineFactoryBuilder::new(env.clone(), cfg, cache, key_manager.clone()) - .lite(true) - .build(); + let factory = KvEngineFactoryBuilder::new( + env.clone(), + cfg, + cache, + key_manager.clone(), + Default::default(), + ) + .lite(true) + .build(); let cfg_controller = ConfigController::default(); if !cfg.raft_engine.enable { @@ -223,7 +229,7 @@ pub trait DebugExecutor { let r = self.get_region_info(region_id); if skip_tombstone { let region_state = r.region_local_state.as_ref(); - if region_state.map_or(false, |s| s.get_state() == PeerState::Tombstone) { + if region_state.is_some_and(|s| s.get_state() == PeerState::Tombstone) { continue; } } @@ -386,21 +392,21 @@ pub trait DebugExecutor { println!("key: {}", escape(&key)); if cfs.contains(&CF_LOCK) && mvcc.has_lock() { let lock_info = mvcc.get_lock(); - if start_ts.map_or(true, |ts| lock_info.get_start_ts() == ts) { + if start_ts.is_none_or(|ts| lock_info.get_start_ts() == ts) { println!("\tlock cf value: {:?}", lock_info); } } if cfs.contains(&CF_DEFAULT) { for value_info in mvcc.get_values() { - if commit_ts.map_or(true, |ts| value_info.get_start_ts() == ts) { + if commit_ts.is_none_or(|ts| value_info.get_start_ts() == ts) { println!("\tdefault cf value: {:?}", value_info); } } } if cfs.contains(&CF_WRITE) { for write_info in mvcc.get_writes() { - if start_ts.map_or(true, |ts| write_info.get_start_ts() == ts) - && commit_ts.map_or(true, |ts| write_info.get_commit_ts() == ts) + if start_ts.is_none_or(|ts| write_info.get_start_ts() == ts) + && commit_ts.is_none_or(|ts| write_info.get_commit_ts() == ts) { println!("\t write cf value: {:?}", write_info); } diff --git a/cmd/tikv-ctl/src/fork_readonly_tikv.rs b/cmd/tikv-ctl/src/fork_readonly_tikv.rs index 934ef173a67..4d16f1e382f 100644 --- a/cmd/tikv-ctl/src/fork_readonly_tikv.rs +++ b/cmd/tikv-ctl/src/fork_readonly_tikv.rs @@ -8,7 +8,7 @@ use std::{ }; use encryption_export::data_key_manager_from_config; -use raft_engine::{env::DefaultFileSystem, Engine as RaftEngine}; +use raft_engine::{Engine as RaftEngine, env::DefaultFileSystem}; use regex::Regex; use tikv::config::TikvConfig; diff --git a/cmd/tikv-ctl/src/main.rs b/cmd/tikv-ctl/src/main.rs index bb73f55810a..8ddf98a9be5 100644 --- a/cmd/tikv-ctl/src/main.rs +++ b/cmd/tikv-ctl/src/main.rs @@ -1,6 +1,5 @@ // Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0. -#![feature(lazy_cell)] #![feature(let_chains)] #[macro_use] @@ -16,19 +15,19 @@ use std::{ sync::{Arc, Mutex, RwLock}, thread, time::Duration, - u64, }; use collections::HashMap; use compact_log_backup::{ + TraceResultExt, exec_hooks::{self as compact_log_hooks, skip_small_compaction::SkipSmallCompaction}, - execute as compact_log, TraceResultExt, + execute as compact_log, }; use crypto::fips; use encryption_export::{ - create_backend, data_key_manager_from_config, DataKeyManager, DecrypterReader, Iv, + DataKeyManager, DecrypterReader, Iv, create_backend, data_key_manager_from_config, }; -use engine_rocks::{get_env, util::new_engine_opt, RocksEngine}; +use engine_rocks::{RocksEngine, get_env, util::new_engine_opt}; use engine_traits::Peekable; use file_system::calc_crc32; use futures::{executor::block_on, future::try_join_all}; @@ -49,16 +48,16 @@ use raft_log_engine::ManagedFileSystem; use raftstore::store::util::build_key_range; use regex::Regex; use security::{SecurityConfig, SecurityManager}; -use structopt::{clap::ErrorKind, StructOpt}; +use structopt::{StructOpt, clap::ErrorKind}; use tempfile::TempDir; use tikv::{ config::TikvConfig, - server::{debug::BottommostLevelCompaction, KvEngineFactoryBuilder}, + server::{KvEngineFactoryBuilder, debug::BottommostLevelCompaction}, storage::config::EngineType, }; use tikv_util::{ escape, - logger::{get_log_level, Level}, + logger::{Level, get_log_level}, run_and_wait_child_process, sys::thread::StdThreadBuildWrapper, unescape, warn, @@ -407,6 +406,8 @@ fn main() { name, force_regenerate, minimal_compaction_size, + prefetch_running_count, + prefetch_buffer_count, } => { let tmp_engine = TemporaryRocks::new(&cfg).expect("failed to create temp engine for writing SSTs."); @@ -433,6 +434,8 @@ fn main() { let ccfg = compact_log::ExecutionConfig { from_ts, until_ts, + prefetch_running_count, + prefetch_buffer_count, compression, compression_level, }; @@ -1208,8 +1211,10 @@ impl TemporaryRocks { let tmp = TempDir::new().map_err(|v| format!("failed to create tmp dir: {}", v))?; let opt = build_rocks_opts(cfg); let cf_opts = cfg.rocksdb.build_cf_opts( - &cfg.rocksdb - .build_cf_resources(cfg.storage.block_cache.build_shared_cache()), + &cfg.rocksdb.build_cf_resources( + cfg.storage.block_cache.build_shared_cache(), + Default::default(), + ), None, cfg.storage.api_version(), None, @@ -1292,6 +1297,9 @@ fn print_bad_ssts(data_dir: &str, manifest: Option<&str>, pd_client: RpcClient, stderr_buf.read_to_end(&mut buffer).unwrap(); let corruptions = unsafe { String::from_utf8_unchecked(buffer) }; + let r = Regex::new(r"/\w*\.sst").unwrap(); + let column_r = Regex::new(r"--------------- (.*) --------------\n(.*)").unwrap(); + let sst_stat_r = Regex::new(r".*\n\d+:\d+\[\d+ .. \d+\]\['(\w*)' seq:\d+, type:\d+ .. '(\w*)' seq:\d+, type:\d+\] at level \d+").unwrap(); for line in corruptions.lines() { println!("--------------------------------------------------------"); // The corruption format may like this: @@ -1300,7 +1308,6 @@ fn print_bad_ssts(data_dir: &str, manifest: Option<&str>, pd_client: RpcClient, // ``` println!("corruption info:\n{}", line); - let r = Regex::new(r"/\w*\.sst").unwrap(); let sst_file_number = match r.captures(line) { None => { println!("skip bad line format"); @@ -1361,15 +1368,13 @@ fn print_bad_ssts(data_dir: &str, manifest: Option<&str>, pd_client: RpcClient, // --------------- Column family "write" (ID 2) -------------- // 63:132906243[3555338 .. 3555338]['7A311B40EFCC2CB4C5911ECF3937D728DED26AE53FA5E61BE04F23F2BE54EACC73' seq:3555338, type:1 .. '7A313030302E25CD5F57252E' seq:3555338, type:1] at level 0 // ``` - let column_r = Regex::new(r"--------------- (.*) --------------\n(.*)").unwrap(); if let Some(m) = column_r.captures(&output) { println!( "{} for {}", m.get(2).unwrap().as_str(), m.get(1).unwrap().as_str() ); - let r = Regex::new(r".*\n\d+:\d+\[\d+ .. \d+\]\['(\w*)' seq:\d+, type:\d+ .. '(\w*)' seq:\d+, type:\d+\] at level \d+").unwrap(); - let matches = match r.captures(&output) { + let matches = match sst_stat_r.captures(&output) { None => { println!("sst start key format is not correct: {}", output); continue; @@ -1487,10 +1492,11 @@ fn read_cluster_id(config: &TikvConfig) -> Result { .map(Arc::new); let env = get_env(key_manager.clone(), None /* io_rate_limiter */).unwrap(); let cache = config.storage.block_cache.build_shared_cache(); - let kv_engine = KvEngineFactoryBuilder::new(env, config, cache, key_manager) - .build() - .create_shared_db(&config.storage.data_dir) - .map_err(|e| format!("create_shared_db fail: {}", e))?; + let kv_engine = + KvEngineFactoryBuilder::new(env, config, cache, key_manager, Default::default()) + .build() + .create_shared_db(&config.storage.data_dir) + .map_err(|e| format!("create_shared_db fail: {}", e))?; let ident = kv_engine .get_msg::(keys::STORE_IDENT_KEY) .unwrap() diff --git a/cmd/tikv-ctl/src/util.rs b/cmd/tikv-ctl/src/util.rs index 90322b6000d..913df27675b 100644 --- a/cmd/tikv-ctl/src/util.rs +++ b/cmd/tikv-ctl/src/util.rs @@ -1,6 +1,6 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -use std::{borrow::ToOwned, error::Error, str, str::FromStr, u64}; +use std::{borrow::ToOwned, error::Error, str, str::FromStr}; use kvproto::kvrpcpb::KeyRange; use server::setup::initial_logger; diff --git a/cmd/tikv-server/Cargo.toml b/cmd/tikv-server/Cargo.toml index bdb8af9e4f5..521d26c7fea 100644 --- a/cmd/tikv-server/Cargo.toml +++ b/cmd/tikv-server/Cargo.toml @@ -40,7 +40,7 @@ tikv = { workspace = true } tikv_util = { workspace = true } toml = "0.5" tracing-active-tree = { workspace = true, optional = true } -tracing-subscriber = { version = "0.3.17", default-features = false, features = [ "registry", "smallvec" ], optional = true } +tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "registry", "smallvec" ], optional = true } [build-dependencies] cc = "1.0" diff --git a/cmd/tikv-server/src/main.rs b/cmd/tikv-server/src/main.rs index 9fe7f6986d0..e9f6fe8ab64 100644 --- a/cmd/tikv-server/src/main.rs +++ b/cmd/tikv-server/src/main.rs @@ -4,12 +4,12 @@ use std::{path::Path, process}; -use clap::{crate_authors, App, Arg}; +use clap::{App, Arg, crate_authors}; use crypto::fips; use serde_json::{Map, Value}; use server::setup::{ensure_no_unrecognized_config, validate_and_persist_config}; use tikv::{ - config::{to_flatten_config_info, TikvConfig}, + config::{TikvConfig, to_flatten_config_info}, storage::config::EngineType, }; diff --git a/components/api_version/src/api_v1ttl.rs b/components/api_version/src/api_v1ttl.rs index 2a2df6bfb33..bd66e0c4523 100644 --- a/components/api_version/src/api_v1ttl.rs +++ b/components/api_version/src/api_v1ttl.rs @@ -4,8 +4,8 @@ use engine_traits::Result; use tikv_util::{ box_err, codec::{ - number::{self, NumberEncoder}, Error, + number::{self, NumberEncoder}, }, }; diff --git a/components/api_version/src/api_v2.rs b/components/api_version/src/api_v2.rs index a56d5deac30..9096e8a18fa 100644 --- a/components/api_version/src/api_v2.rs +++ b/components/api_version/src/api_v2.rs @@ -3,9 +3,8 @@ use codec::byte::MemComparableByteCodec; use engine_traits::Result; use tikv_util::codec::{ - bytes, + Error, bytes, number::{self, NumberEncoder}, - Error, }; use txn_types::{Key, TimeStamp}; diff --git a/components/api_version/src/lib.rs b/components/api_version/src/lib.rs index 879751e7b62..18de8148228 100644 --- a/components/api_version/src/lib.rs +++ b/components/api_version/src/lib.rs @@ -259,7 +259,7 @@ impl> RawValue { #[inline] pub fn is_ttl_expired(&self, current_ts: u64) -> bool { self.expire_ts - .map_or(false, |expire_ts| expire_ts <= current_ts) + .is_some_and(|expire_ts| expire_ts <= current_ts) } } diff --git a/components/backup-stream/Cargo.toml b/components/backup-stream/Cargo.toml index 50262898e3b..42f658e8bed 100644 --- a/components/backup-stream/Cargo.toml +++ b/components/backup-stream/Cargo.toml @@ -26,7 +26,7 @@ test = true harness = true [dependencies] -async-compression = { version = "0.4.12", features = ["tokio", "zstd"] } +async-compression = { version = "0.4.27", features = ["tokio", "zstd"] } async-trait = { version = "0.1" } base64 = "0.13.0" chrono = { workspace = true } diff --git a/components/backup-stream/src/checkpoint_manager.rs b/components/backup-stream/src/checkpoint_manager.rs index 9896ea99b69..0e7addb32fe 100644 --- a/components/backup-stream/src/checkpoint_manager.rs +++ b/components/backup-stream/src/checkpoint_manager.rs @@ -3,9 +3,9 @@ use std::{cell::RefCell, collections::HashMap, sync::Arc, time::Duration}; use futures::{ + FutureExt, SinkExt, StreamExt, channel::mpsc::{self as async_mpsc, Receiver, Sender}, future::BoxFuture, - FutureExt, SinkExt, StreamExt, }; use grpcio::{RpcStatus, RpcStatusCode, WriteFlags}; use kvproto::{ @@ -20,13 +20,13 @@ use txn_types::TimeStamp; use uuid::Uuid; use crate::{ - annotate, + RegionCheckpointOperation, Task, annotate, errors::{Error, Result}, future, - metadata::{store::MetaStore, Checkpoint, CheckpointProvider, MetadataClient}, + metadata::{Checkpoint, CheckpointProvider, MetadataClient, store::MetaStore}, metrics, subscription_track::ResolveResult, - try_send, RegionCheckpointOperation, Task, + try_send, }; /// A manager for maintaining the last flush ts. @@ -66,6 +66,7 @@ impl SubscriptionManager { info!("subscription manager started!"); defer! { info!("subscription manager exit.") } while let Some(msg) = self.input.next().await { + metrics::ACTIVE_SUBSCRIPTION_NUMBER.set(self.subscribers.len() as _); match msg { SubscriptionOp::Add(sub) => { let uid = Uuid::new_v4(); @@ -609,7 +610,7 @@ pub mod tests { time::Duration, }; - use futures::{future::ok, Sink}; + use futures::{Sink, future::ok}; use grpcio::{RpcStatus, RpcStatusCode}; use kvproto::{logbackuppb::SubscribeFlushEventResponse, metapb::*}; use pd_client::{PdClient, PdFuture}; @@ -617,8 +618,8 @@ pub mod tests { use super::{BasicFlushObserver, FlushObserver, RegionIdWithVersion}; use crate::{ - subscription_track::{CheckpointType, ResolveResult}, GetCheckpointResult, + subscription_track::{CheckpointType, ResolveResult}, }; fn region(id: u64, version: u64, conf_version: u64) -> Region { diff --git a/components/backup-stream/src/endpoint.rs b/components/backup-stream/src/endpoint.rs index b81279ed186..f1110bc4334 100644 --- a/components/backup-stream/src/endpoint.rs +++ b/components/backup-stream/src/endpoint.rs @@ -15,7 +15,7 @@ use dashmap::DashMap; use encryption::BackupEncryptionManager; use engine_traits::KvEngine; use error_code::ErrorCodeExt; -use futures::{stream::AbortHandle, FutureExt, TryFutureExt}; +use futures::{FutureExt, TryFutureExt, stream::AbortHandle}; use kvproto::{ brpb::{StreamBackupError, StreamBackupTaskInfo}, metapb::{Region, RegionEpoch}, @@ -26,13 +26,13 @@ use raftstore::{ coprocessor::{CmdBatch, ObserveHandle, RegionInfoProvider}, router::CdcHandle, }; -use resolved_ts::{resolve_by_raft, LeadershipResolver}; +use resolved_ts::{LeadershipResolver, resolve_by_raft}; use tikv::{ config::{BackupStreamConfig, ResolvedTsConfig}, storage::txn::txn_status_cache::TxnStatusCache, }; use tikv_util::{ - box_err, + HandyRwLock, box_err, config::ReadableDuration, debug, defer, error, info, memory::MemoryQuota, @@ -40,12 +40,11 @@ use tikv_util::{ time::{Instant, Limiter}, warn, worker::{Runnable, Scheduler}, - HandyRwLock, }; use tokio::{ io::Result as TokioResult, runtime::{Handle, Runtime}, - sync::{mpsc::Sender, Semaphore}, + sync::{Semaphore, mpsc::Sender}, }; use tokio_stream::StreamExt; use tracing::instrument; @@ -62,7 +61,7 @@ use crate::{ errors::{Error, ReportableResult, Result}, event_loader::InitialDataLoader, future, - metadata::{store::MetaStore, MetadataClient, MetadataEvent, StreamTask}, + metadata::{MetadataClient, MetadataEvent, StreamTask, store::MetaStore}, metrics::{self, TaskStatus}, observer::BackupStreamObserver, router::{self, ApplyEvents, FlushContext, Router, TaskSelector, TaskSelectorRef}, @@ -186,7 +185,7 @@ where ), accessor.clone(), meta_client.clone(), - ((config.num_threads + 1) / 2).max(1), + (config.num_threads.div_ceil(2)).max(1), resolver, resolved_ts_config.advance_ts_interval.0, ); @@ -834,7 +833,7 @@ where router.unregister_task(task) } - fn prepare_min_ts(&self) -> future![TimeStamp] { + fn prepare_min_ts(&self) -> future![(TimeStamp, TimeStamp)] { let pd_cli = self.pd_client.clone(); let cm = self.concurrency_manager.clone(); async move { @@ -845,11 +844,16 @@ where .unwrap_or_default(); cm.update_max_ts(pd_tso, "backup-stream").unwrap(); let min_ts = cm.global_min_lock_ts().unwrap_or(TimeStamp::max()); - Ord::min(pd_tso, min_ts) + (Ord::min(pd_tso, min_ts), pd_tso) } } - fn do_flush(&self, task: String, resolved: ResolvedRegions) -> future![Result<()>] { + fn do_flush( + &self, + task: String, + resolved: ResolvedRegions, + flush_ts: TimeStamp, + ) -> future![Result<()>] { let router = self.range_router.clone(); let store_id = self.store_id; let mut flush_ob = self.flush_observer(); @@ -866,6 +870,7 @@ where store_id, resolved_regions: &resolved, resolved_ts: new_rts, + flush_ts, }; if let Some(rts) = router.do_flush(cx).await { info!("flushing and refreshing checkpoint ts."; @@ -900,7 +905,7 @@ where info!("Triggering force flush."; "selector" => ?task); let handlers = self.range_router.select_task_handler(task); for hnd in handlers { - let mts = self.prepare_min_ts().await; + let (mts, fts) = self.prepare_min_ts().await; let sched = self.scheduler.clone(); let sender = sender.clone(); self.subscribe_flush_done(&hnd.task.info.name, sender); @@ -910,7 +915,7 @@ where callback: Box::new(move |res| { try_send!( sched, - Task::ExecFlush(hnd.task.info.name.to_owned(), res) + Task::ExecFlush(hnd.task.info.name.to_owned(), res, fts) ); }), min_ts: mts, @@ -927,12 +932,12 @@ where pub fn on_flush(&self, task: String) { self.pool.block_on(async move { - let mts = self.prepare_min_ts().await; + let (mts, flush_ts) = self.prepare_min_ts().await; let sched = self.scheduler.clone(); - info!("min_ts prepared for flushing"; "min_ts" => %mts); + info!("min_ts prepared for flushing"; "min_ts" => %mts, "flush_ts" => %flush_ts); self.region_op(ObserveOp::ResolveRegions { callback: Box::new(move |res| { - try_send!(sched, Task::ExecFlush(task, res)); + try_send!(sched, Task::ExecFlush(task, res, flush_ts)); }), min_ts: mts, }) @@ -940,9 +945,9 @@ where }) } - fn on_exec_flush(&mut self, task: String, resolved: ResolvedRegions) { + fn on_exec_flush(&mut self, task: String, resolved: ResolvedRegions, flush_ts: TimeStamp) { self.checkpoint_mgr.freeze(); - let fut = self.do_flush(task.clone(), resolved); + let fut = self.do_flush(task.clone(), resolved, flush_ts); let sched = self.scheduler.clone(); self.pool.spawn(root!("flush"; async move { let res = fut.await; @@ -1096,7 +1101,7 @@ where } } Task::MarkFailover(t) => self.failover_time = Some(t), - Task::ExecFlush(task, min_ts) => self.on_exec_flush(task, min_ts), + Task::ExecFlush(task, min_ts, flush_ts) => self.on_exec_flush(task, min_ts, flush_ts), Task::RegionCheckpointsOp(s) => self.handle_region_checkpoints_op(s), Task::UpdateGlobalCheckpoint(task) => self.on_update_global_checkpoint(task), Task::Flushed(result) => self.on_flushed(result), @@ -1178,7 +1183,7 @@ where metrics::MISC_EVENTS.skip_resolve_no_subscription.inc(); return; } - let min_ts = self.pool.block_on(self.prepare_min_ts()); + let (min_ts, _) = self.pool.block_on(self.prepare_min_ts()); let start_time = Instant::now(); // We need to reschedule the `Resolve` task to queue, because the subscription // is asynchronous -- there may be transactions committed before @@ -1350,7 +1355,7 @@ pub enum Task { Flushed(FlushResult), /// Execute the flush with the calculated resolved result. /// This is an internal command only issued by the `Flush` task. - ExecFlush(String, ResolvedRegions), + ExecFlush(String, ResolvedRegions, TimeStamp), /// The command for getting region checkpoints. RegionCheckpointsOp(RegionCheckpointOperation), /// update global-checkpoint-ts to storage. @@ -1464,10 +1469,11 @@ impl fmt::Debug for Task { .debug_tuple("MarkFailover") .field(&format_args!("{:?} ago", t.saturating_elapsed())) .finish(), - Self::ExecFlush(arg0, arg1) => f + Self::ExecFlush(arg0, arg1, arg2) => f .debug_tuple("ExecFlush") .field(arg0) .field(&arg1.global_checkpoint()) + .field(&arg2) .finish(), Self::RegionCheckpointsOp(s) => f.debug_tuple("GetRegionCheckpoints").field(s).finish(), Self::UpdateGlobalCheckpoint(task) => { diff --git a/components/backup-stream/src/errors.rs b/components/backup-stream/src/errors.rs index 657fab840fa..f19016fcd38 100644 --- a/components/backup-stream/src/errors.rs +++ b/components/backup-stream/src/errors.rs @@ -79,7 +79,7 @@ impl ErrorCodeExt for Error { } } -impl<'a> ErrorCodeExt for &'a Error { +impl ErrorCodeExt for &Error { fn error_code(&self) -> error_code::ErrorCode { Error::error_code(*self) } @@ -198,7 +198,7 @@ impl Error { mod test { extern crate test; - use std::io::{self, ErrorKind}; + use std::io; use error_code::ErrorCodeExt; @@ -206,8 +206,7 @@ mod test { #[test] fn test_contextual_error() { - let err = Error::Io(io::Error::new( - ErrorKind::Other, + let err = Error::Io(io::Error::other( "the absence of error messages, is also a kind of error message", )); let result: Result<()> = Err(err); @@ -232,8 +231,7 @@ mod test { // 2,685 ns/iter (+/- 194) fn contextual_add_format_strings_directly(b: &mut test::Bencher) { b.iter(|| { - let err = Error::Io(io::Error::new( - ErrorKind::Other, + let err = Error::Io(io::Error::other( "basement, it is the fundamental basement.", )); let result: Result<()> = Err(err); @@ -253,8 +251,7 @@ mod test { // 1,922 ns/iter (+/- 273) fn contextual_add_format_strings(b: &mut test::Bencher) { b.iter(|| { - let err = Error::Io(io::Error::new( - ErrorKind::Other, + let err = Error::Io(io::Error::other( "basement, it is the fundamental basement.", )); let result: Result<()> = Err(err); @@ -274,8 +271,7 @@ mod test { // 1,988 ns/iter (+/- 89) fn contextual_add_closure(b: &mut test::Bencher) { b.iter(|| { - let err = Error::Io(io::Error::new( - ErrorKind::Other, + let err = Error::Io(io::Error::other( "basement, it is the fundamental basement.", )); let result: Result<()> = Err(err); @@ -296,8 +292,7 @@ mod test { // 773 ns/iter (+/- 8) fn baseline(b: &mut test::Bencher) { b.iter(|| { - let err = Error::Io(io::Error::new( - ErrorKind::Other, + let err = Error::Io(io::Error::other( "basement, it is the fundamental basement.", )); let result: Result<()> = Err(err); diff --git a/components/backup-stream/src/event_loader.rs b/components/backup-stream/src/event_loader.rs index a990ea2a82b..f7f18d18ea4 100644 --- a/components/backup-stream/src/event_loader.rs +++ b/components/backup-stream/src/event_loader.rs @@ -2,18 +2,18 @@ use std::{marker::PhantomData, sync::Arc, time::Duration}; -use engine_traits::{KvEngine, CF_DEFAULT, CF_WRITE}; +use engine_traits::{CF_DEFAULT, CF_WRITE, KvEngine}; use kvproto::{kvrpcpb::ExtraOp, metapb::Region, raft_cmdpb::CmdType}; use raftstore::{ coprocessor::ObserveHandle, router::CdcHandle, - store::{fsm::ChangeObserver, Callback}, + store::{Callback, fsm::ChangeObserver}, }; use tikv::storage::{ + Snapshot, Statistics, kv::StatisticsSummary, mvcc::{DeltaScanner, ScannerBuilder}, txn::{TxnEntry, TxnEntryScanner}, - Snapshot, Statistics, }; use tikv_util::{ box_err, @@ -27,12 +27,12 @@ use tracing_active_tree::frame; use txn_types::{Key, Lock, TimeStamp}; use crate::{ - annotate, debug, + Task, annotate, debug, errors::{ContextualResultExt, Error, Result}, metrics, router::{ApplyEvent, ApplyEvents, Router}, subscription_track::{Ref, RefMut, SubscriptionTracer, TwoPhaseResolver}, - utils, Task, + utils, }; const MAX_GET_SNAPSHOT_RETRY: usize = 5; @@ -484,8 +484,8 @@ mod tests { use futures::executor::block_on; use kvproto::metapb::*; use tikv::storage::{ - txn::{tests::*, txn_status_cache::TxnStatusCache}, TestEngineBuilder, + txn::{tests::*, txn_status_cache::TxnStatusCache}, }; use tikv_kv::SnapContext; use tikv_util::memory::{MemoryQuota, OwnedAllocated}; diff --git a/components/backup-stream/src/lib.rs b/components/backup-stream/src/lib.rs index 6d7afa334c9..97467fc169c 100644 --- a/components/backup-stream/src/lib.rs +++ b/components/backup-stream/src/lib.rs @@ -1,5 +1,4 @@ // Copyright 2022 TiKV Project Authors. Licensed under Apache-2.0. -#![feature(slice_group_by)] #![feature(trait_alias)] #![feature(result_flattening)] #![feature(assert_matches)] diff --git a/components/backup-stream/src/metadata/store/pd.rs b/components/backup-stream/src/metadata/store/pd.rs index 5b2e2b466e5..6ed5f693f2e 100644 --- a/components/backup-stream/src/metadata/store/pd.rs +++ b/components/backup-stream/src/metadata/store/pd.rs @@ -3,7 +3,7 @@ use std::{collections::VecDeque, fmt::Display, pin::Pin, task::ready}; use async_trait::async_trait; -use futures::{stream, Stream}; +use futures::{Stream, stream}; use kvproto::meta_storagepb::{self as mpb, WatchResponse}; use pd_client::meta_storage::{Get, MetaStorageClient, Put, Watch}; use pin_project::pin_project; @@ -200,10 +200,10 @@ mod tests { use futures::{Future, StreamExt}; use pd_client::{ - meta_storage::{Checked, Source, Sourced}, RpcClient, + meta_storage::{Checked, Source, Sourced}, }; - use test_pd::{mocker::MetaStorage, util::*, Server as PdServer}; + use test_pd::{Server as PdServer, mocker::MetaStorage, util::*}; use tikv_util::config::ReadableDuration; use super::PdStore; diff --git a/components/backup-stream/src/metadata/store/slash_etc.rs b/components/backup-stream/src/metadata/store/slash_etc.rs index a564d069d14..1afb387e596 100644 --- a/components/backup-stream/src/metadata/store/slash_etc.rs +++ b/components/backup-stream/src/metadata/store/slash_etc.rs @@ -9,8 +9,8 @@ use std::{ use async_trait::async_trait; use tokio::sync::{ - mpsc::{self, Sender}, Mutex, + mpsc::{self, Sender}, }; use tokio_stream::StreamExt; @@ -113,7 +113,7 @@ impl SlashEtc { .collect::>(); let kvs = mvccs .as_slice() - .group_by(|k1, k2| k1.0.0 == k2.0.0) + .chunk_by(|k1, k2| k1.0.0 == k2.0.0) .filter_map(|k| { let (k, v) = k.last()?; match v { diff --git a/components/backup-stream/src/metadata/test.rs b/components/backup-stream/src/metadata/test.rs index bb2b7fe1577..c7343e86754 100644 --- a/components/backup-stream/src/metadata/test.rs +++ b/components/backup-stream/src/metadata/test.rs @@ -3,17 +3,17 @@ #![cfg(test)] use std::{ - collections::{hash_map::RandomState, HashSet}, + collections::{HashSet, hash_map::RandomState}, iter::FromIterator, }; use kvproto::brpb::{Noop, StorageBackend}; use tokio_stream::StreamExt; -use super::{keys::MetaKey, MetadataClient, StreamTask}; +use super::{MetadataClient, StreamTask, keys::MetaKey}; use crate::{ errors::Result, - metadata::{store::SlashEtcStore, MetadataEvent}, + metadata::{MetadataEvent, store::SlashEtcStore}, }; pub fn test_meta_cli() -> MetadataClient { diff --git a/components/backup-stream/src/metrics.rs b/components/backup-stream/src/metrics.rs index 90296b3baf0..a096c9f6139 100644 --- a/components/backup-stream/src/metrics.rs +++ b/components/backup-stream/src/metrics.rs @@ -197,6 +197,21 @@ lazy_static! { "The duration of polling read temp file.", exponential_buckets(0.001, 2.0, 10).unwrap() ).unwrap(); + + pub static ref STORE_SMALLEST_CHECKPOINT_REGION_ID: IntGauge = register_int_gauge!( + "tikv_log_backup_store_last_checkpoint_region_id", + "ID of the region with the smallest checkpoint ts in the store." + ).unwrap(); + + pub static ref STORE_SMALLEST_CHECKPOINT_TS: IntGauge = register_int_gauge!( + "tikv_log_backup_store_last_checkpoint_ts", + "The smallest checkpoint ts in the store." + ).unwrap(); + + pub static ref ACTIVE_SUBSCRIPTION_NUMBER: IntGauge = register_int_gauge!( + "tikv_log_backup_active_subscription_number", + "The number of active subscriptions from advancer in the store." + ).unwrap(); } make_static_metric! { diff --git a/components/backup-stream/src/observer.rs b/components/backup-stream/src/observer.rs index f808e582e3c..ce6d8f130f8 100644 --- a/components/backup-stream/src/observer.rs +++ b/components/backup-stream/src/observer.rs @@ -6,7 +6,7 @@ use engine_traits::KvEngine; use kvproto::metapb::Region; use raft::StateRole; use raftstore::coprocessor::*; -use tikv_util::{worker::Scheduler, HandyRwLock}; +use tikv_util::{HandyRwLock, worker::Scheduler}; use crate::{ debug, @@ -185,7 +185,6 @@ impl RegionChangeObserver for BackupStreamObserver { } #[cfg(test)] - mod tests { use std::{assert_matches::assert_matches, sync::Arc, time::Duration}; @@ -198,7 +197,7 @@ mod tests { RegionChangeEvent, RegionChangeObserver, RegionChangeReason, RoleChange, RoleObserver, }; use tikv::storage::txn::txn_status_cache::TxnStatusCache; - use tikv_util::{worker::dummy_scheduler, HandyRwLock}; + use tikv_util::{HandyRwLock, worker::dummy_scheduler}; use super::BackupStreamObserver; use crate::{ diff --git a/components/backup-stream/src/router.rs b/components/backup-stream/src/router.rs index ed307871a46..523252b13aa 100644 --- a/components/backup-stream/src/router.rs +++ b/components/backup-stream/src/router.rs @@ -7,8 +7,8 @@ use std::{ path::{Path, PathBuf}, result, sync::{ - atomic::{AtomicBool, AtomicPtr, AtomicU64, AtomicUsize, Ordering}, Arc, RwLock as SyncRwLock, + atomic::{AtomicBool, AtomicPtr, AtomicU64, AtomicUsize, Ordering}, }, time::Duration, }; @@ -16,8 +16,8 @@ use std::{ use dashmap::DashMap; use encryption::{BackupEncryptionManager, EncrypterReader, Iv, MultiMasterKeyBackend}; use encryption_export::create_async_backend; -use engine_traits::{CfName, CF_DEFAULT, CF_LOCK, CF_WRITE}; -use external_storage::{create_storage, BackendConfig, ExternalStorage, UnpinReader}; +use engine_traits::{CF_DEFAULT, CF_LOCK, CF_WRITE, CfName}; +use external_storage::{BackendConfig, ExternalStorage, UnpinReader, create_storage}; use file_system::Sha256Reader; use futures::io::Cursor; use kvproto::{ @@ -36,14 +36,13 @@ use slog_global::debug; use tidb_query_datatype::codec::table::decode_table_id; use tikv::config::BackupStreamConfig; use tikv_util::{ - box_err, + Either, HandyRwLock, box_err, codec::stream_event::EventEncoder, config::ReadableSize, error, info, time::{Instant, Limiter}, warn, worker::Scheduler, - Either, HandyRwLock, }; use tokio::{ io::AsyncWriteExt, @@ -103,7 +102,7 @@ pub enum TaskSelectorRef<'a> { All, } -impl<'a> std::fmt::Debug for TaskSelectorRef<'a> { +impl std::fmt::Debug for TaskSelectorRef<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::ByName(name) => f.debug_tuple("ByName").field(name).finish(), @@ -121,7 +120,7 @@ impl<'a> std::fmt::Debug for TaskSelectorRef<'a> { } } -impl<'a> TaskSelectorRef<'a> { +impl TaskSelectorRef<'_> { fn matches<'c, 'd>( self, task_name: &str, @@ -160,6 +159,7 @@ pub struct FlushContext<'a> { pub store_id: u64, pub resolved_regions: &'a ResolvedRegions, pub resolved_ts: TimeStamp, + pub flush_ts: TimeStamp, } impl ApplyEvents { @@ -1150,7 +1150,6 @@ impl StreamTaskHandler { ) .await .into_iter() - .map(|r| r.map_err(Error::from)) .fold(Ok(()), Result::and)?; let mut metadata = MetadataInfo::with_capacity(w.len() + wm.len()); @@ -1182,8 +1181,8 @@ impl StreamTaskHandler { for f in fg.data_files_info.iter_mut() { if let Some((epoches, start_key, end_key)) = rmap.get(&(f.region_id as _)) { f.set_region_epoch(epoches.iter().copied().cloned().collect::>().into()); - f.set_region_start_key(start_key.to_vec()); - f.set_region_end_key(end_key.to_vec()); + f.set_region_start_key(start_key.to_vec().into()); + f.set_region_end_key(end_key.to_vec().into()); } } } @@ -1312,12 +1311,8 @@ impl StreamTaskHandler { } let min_ts = min_ts.unwrap_or_default(); let max_ts = max_ts.unwrap_or_default(); - merged_file_info.set_path(TempFileKey::file_name( - metadata.store_id, - min_ts, - max_ts, - is_meta, - )); + merged_file_info + .set_path(TempFileKey::file_name(metadata.store_id, min_ts, max_ts, is_meta).into()); merged_file_info.set_data_files_info(data_file_infos.into()); merged_file_info.set_length(stat_length); merged_file_info.set_max_ts(max_ts); @@ -1414,9 +1409,21 @@ impl StreamTaskHandler { } #[instrument(skip_all)] - pub async fn flush_backup_metadata(&self, metadata_info: MetadataInfo) -> Result<()> { + pub async fn flush_backup_metadata( + &self, + metadata_info: MetadataInfo, + flush_ts: TimeStamp, + ) -> Result<()> { if !metadata_info.file_groups.is_empty() { - let meta_path = metadata_info.path_to_meta(); + let mut min_begin_ts = u64::MAX; + for file_group in metadata_info.file_groups.as_slice() { + assert!(!file_group.data_files_info.is_empty()); + for d in file_group.data_files_info.as_slice() { + assert_ne!(d.min_begin_ts_in_default_cf, 0); + min_begin_ts = min_begin_ts.min(d.min_begin_ts_in_default_cf) + } + } + let meta_path = metadata_info.path_to_meta(min_begin_ts, flush_ts.into_inner()); let meta_buff = metadata_info.marshal_to()?; let buflen = meta_buff.len(); @@ -1483,7 +1490,8 @@ impl StreamTaskHandler { // flush meta file to storage. self.fill_region_info(cx, &mut backup_metadata); // flush backup metadata to external storage. - self.flush_backup_metadata(backup_metadata).await?; + self.flush_backup_metadata(backup_metadata, cx.flush_ts) + .await?; crate::metrics::FLUSH_DURATION .with_label_values(&["save_files"]) .observe(sw.lap().as_secs_f64()); @@ -1740,6 +1748,7 @@ pub struct MetadataInfo { // the field files is deprecated in v6.3.0 // pub files: Vec, pub file_groups: Vec, + // deprecated pub min_resolved_ts: Option, pub min_ts: Option, pub max_ts: Option, @@ -1787,11 +1796,13 @@ impl MetadataInfo { .map_err(|err| Error::Other(box_err!("failed to marshal proto: {}", err))) } - fn path_to_meta(&self) -> String { + fn path_to_meta(&self, min_begin_ts: u64, flush_ts: u64) -> String { format!( - "v1/backupmeta/{}-{}.meta", - self.min_resolved_ts.unwrap_or_default(), - uuid::Uuid::new_v4() + "v1/backupmeta/{:016X}-{:016X}-{:016X}-{:016X}.meta", + flush_ts, + min_begin_ts, + self.min_ts.unwrap_or_default(), + self.max_ts.unwrap_or_default(), ) } } @@ -1902,7 +1913,8 @@ impl DataFile { self.sha256 .finish() .map(|bytes| bytes.to_vec()) - .map_err(|err| Error::Other(box_err!("openssl hasher failed to init: {}", err)))?, + .map_err(|err| Error::Other(box_err!("openssl hasher failed to init: {}", err)))? + .into(), ); meta.set_crc64xor(self.crc64xor); meta.set_number_of_entries(self.number_of_entries as _); @@ -1913,13 +1925,13 @@ impl DataFile { self.min_begin_ts .map_or(self.min_ts.into_inner(), |ts| ts.into_inner()), ); - meta.set_start_key(std::mem::take(&mut self.start_key)); - meta.set_end_key(std::mem::take(&mut self.end_key)); + meta.set_start_key(std::mem::take(&mut self.start_key).into()); + meta.set_end_key(std::mem::take(&mut self.end_key).into()); meta.set_length(self.file_size as _); meta.set_is_meta(file_key.is_meta); meta.set_table_id(file_key.table_id); - meta.set_cf(file_key.cf.to_owned()); + meta.set_cf(file_key.cf.to_owned().into()); meta.set_region_id(file_key.region_id as i64); meta.set_type(file_key.get_file_type()); @@ -1940,9 +1952,6 @@ impl std::fmt::Debug for DataFile { } } -#[derive(Clone, Ord, PartialOrd, PartialEq, Eq, Debug)] -struct KeyRange(Vec); - #[derive(Clone, Debug)] #[allow(dead_code)] struct TaskRange { @@ -1957,7 +1966,7 @@ mod tests { use async_compression::tokio::bufread::ZstdDecoder; use encryption::{DecrypterReader, FileConfig, MasterKeyConfig, MultiMasterKeyBackend}; use external_storage::{BlobObject, ExternalData, NoopStorage}; - use futures::{future::LocalBoxFuture, stream::LocalBoxStream, AsyncReadExt}; + use futures::{AsyncReadExt, future::LocalBoxFuture, stream::LocalBoxStream}; use kvproto::{ brpb::{CipherInfo, Noop, StorageBackend, StreamBackupTaskInfo}, encryptionpb::EncryptionMethod, @@ -1971,7 +1980,7 @@ mod tests { stream_event::{EventIterator, Iterator}, }, config::ReadableDuration, - worker::{dummy_scheduler, ReceiverWrapper}, + worker::{ReceiverWrapper, dummy_scheduler}, }; use tokio::{fs::File, io::BufReader}; use txn_types::{Write, WriteType}; @@ -2254,7 +2263,10 @@ mod tests { } } - task_handler.flush_backup_metadata(meta).await.unwrap(); + task_handler + .flush_backup_metadata(meta, TimeStamp::new(1)) + .await + .unwrap(); task_handler.clear_flushing_files().await; drop(router); @@ -2267,10 +2279,34 @@ mod tests { let mut meta_count = 0; let mut log_count = 0; + for entry in walkdir::WalkDir::new(storage_path) { let entry = entry.unwrap(); - let filename = entry.file_name(); if entry.path().extension() == Some(OsStr::new("meta")) { + let filename = entry.path().file_stem().unwrap().to_os_string(); + let parts: Vec<&str> = filename.to_str().unwrap().split('-').collect(); + + assert!( + parts.len() >= 4, + "Invalid meta file name format: expected at least 4 parts, got {}, file: {:?}", + parts.len(), + entry.file_name(), + ); + + for (i, label) in ["flushTs", "minDefaultTs", "minTs", "maxTs"] + .iter() + .enumerate() + { + let val = u64::from_str_radix(parts[i], 16); + assert!( + val.is_ok(), + "Failed to parse '{}' as u64 (hex) for {} in file name: {:?}", + parts[i], + label, + entry.file_name(), + ); + } + meta_count += 1; } else if entry.path().extension() == Some(OsStr::new("log")) { log_count += 1; @@ -2278,7 +2314,7 @@ mod tests { assert!( f.len() > 10, "the log file {:?} is too small (size = {}B)", - filename, + entry.file_name(), f.len() ); } @@ -2334,6 +2370,7 @@ mod tests { store_id: 1, resolved_regions: &EMPTY_RESOLVE, resolved_ts: TimeStamp::new(1), + flush_ts: TimeStamp::new(1), }; task_handler.do_flush(cx).await.unwrap(); assert_eq!(task_handler.flush_failure_count(), 0); @@ -2358,8 +2395,7 @@ mod tests { let mut fst = first_time.lock().unwrap(); if *fst { *fst = false; - return Err(io::Error::new( - io::ErrorKind::Other, + return Err(io::Error::other( "the absence of the result, is also a kind of result", )); } @@ -2453,6 +2489,7 @@ mod tests { store_id: 42, resolved_regions: &EMPTY_RESOLVE, resolved_ts: TimeStamp::max(), + flush_ts: TimeStamp::max(), }; let (task, _path) = task_handler("error_prone".to_owned()).await?; must_register_table(router.as_ref(), task, 1).await; @@ -2509,6 +2546,7 @@ mod tests { store_id: 1, resolved_regions: &EMPTY_RESOLVE, resolved_ts: ts, + flush_ts: ts, }; let rts = router.do_flush(cx).await.unwrap(); assert_eq!(ts.into_inner(), rts); @@ -2593,6 +2631,7 @@ mod tests { store_id: 42, resolved_regions: &EMPTY_RESOLVE, resolved_ts: TimeStamp::zero(), + flush_ts: TimeStamp::new(1), }; for i in 0..=FLUSH_FAILURE_BECOME_FATAL_THRESHOLD { check_on_events_result(&router.on_events(build_kv_event((i * 10) as _, 10)).await); @@ -2787,8 +2826,7 @@ mod tests { if data_len == content_length { Ok(()) } else { - Err(io::Error::new( - io::ErrorKind::Other, + Err(io::Error::other( "the length of content in reader is not equal with content_length", )) } @@ -2985,6 +3023,7 @@ mod tests { store_id: 42, resolved_regions: &EMPTY_RESOLVE, resolved_ts: TimeStamp::max(), + flush_ts: TimeStamp::new(1), }; // set flush status to true, because we disabled the auto flush. t.set_flushing_status(true); @@ -3096,6 +3135,7 @@ mod tests { store_id: 1, resolved_regions: &EMPTY_RESOLVE, resolved_ts: TimeStamp::new(1), + flush_ts: TimeStamp::new(1), }; task_handler.do_flush(cx).await?; let duration = start.saturating_elapsed(); @@ -3167,7 +3207,22 @@ mod tests { for entry in walkdir::WalkDir::new(path) { let entry = entry.unwrap(); if entry.path().extension() == Some(OsStr::new("meta")) { - meta_files.push(entry.path().to_path_buf()); + if let Some(filename) = entry.path().file_stem().and_then(OsStr::to_str) { + // v1/backupmeta/{a}-{b}-{c}-{d}.meta + let parts: Vec<&str> = filename.split('-').collect(); + if parts.len() == 4 { + for p in parts { + assert!( + u64::from_str_radix(p, 16).is_ok(), + "Part '{}' is not a valid hex u64", + p + ); + } + meta_files.push(entry.path().to_path_buf()); + } else { + panic!("backup meta file format changed") + } + } } } meta_files diff --git a/components/backup-stream/src/service.rs b/components/backup-stream/src/service.rs index 3e1db6f1d0d..1dc38416468 100644 --- a/components/backup-stream/src/service.rs +++ b/components/backup-stream/src/service.rs @@ -8,10 +8,11 @@ use kvproto::{logbackuppb::*, metapb::Region}; use tikv_util::{info, warn, worker::Scheduler}; use crate::{ + Task, checkpoint_manager::{GetCheckpointResult, RegionIdWithVersion}, endpoint::{RegionCheckpointOperation, RegionSet}, router::TaskSelector, - try_send, Task, + try_send, }; #[derive(Clone)] diff --git a/components/backup-stream/src/subscription_manager.rs b/components/backup-stream/src/subscription_manager.rs index 4eae7b7ee11..fef9b7852e4 100644 --- a/components/backup-stream/src/subscription_manager.rs +++ b/components/backup-stream/src/subscription_manager.rs @@ -17,24 +17,23 @@ use tikv_util::{ box_err, debug, info, memory::MemoryQuota, sys::thread::ThreadBuildWrapper, time::Instant, warn, worker::Scheduler, }; -use tokio::sync::mpsc::{channel, error::SendError, Receiver, Sender, WeakSender}; +use tokio::sync::mpsc::{Receiver, Sender, WeakSender, channel, error::SendError}; use tracing::instrument; use tracing_active_tree::root; use txn_types::TimeStamp; use crate::{ - annotate, + Task, annotate, endpoint::{BackupStreamResolver, ObserveOp}, errors::{Error, ReportableResult, Result}, event_loader::InitialDataLoader, future, - metadata::{store::MetaStore, CheckpointProvider, MetadataClient}, + metadata::{CheckpointProvider, MetadataClient, store::MetaStore}, metrics, router::{Router, TaskSelector}, subscription_track::{CheckpointType, Ref, RefMut, ResolveResult, SubscriptionTracer}, try_send, utils::{self, FutureWaitGroup, Work}, - Task, }; type ScanPool = tokio::runtime::Runtime; @@ -236,7 +235,7 @@ async fn scan_executor_loop(init: impl InitialScan, mut cmds: Receiver) /// spawn the executors to some runtime. #[cfg(test)] fn spawn_executors_to( - init: impl InitialScan + Send + Sync + 'static, + init: impl InitialScan + 'static, handle: &tokio::runtime::Handle, ) -> ScanPoolHandle { let (tx, rx) = tokio::sync::mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -247,10 +246,7 @@ fn spawn_executors_to( } /// spawn the executors in the scan pool. -fn spawn_executors( - init: impl InitialScan + Send + Sync + 'static, - number: usize, -) -> ScanPoolHandle { +fn spawn_executors(init: impl InitialScan + 'static, number: usize) -> ScanPoolHandle { let (tx, rx) = tokio::sync::mpsc::channel(MESSAGE_BUFFER_SIZE); let pool = create_scan_pool(number); let handle = pool.handle().clone(); @@ -451,6 +447,10 @@ where // If there isn't any region observed, the `min_ts` can be used as resolved ts // safely. let rts = min_region.map(|rs| rs.checkpoint).unwrap_or(min_ts); + if let Some(mr) = min_region.as_ref() { + metrics::STORE_SMALLEST_CHECKPOINT_REGION_ID.set(mr.region.id as _); + metrics::STORE_SMALLEST_CHECKPOINT_TS.set(rts.into_inner() as _); + } if min_region .map(|mr| mr.checkpoint_type != CheckpointType::MinTs) .unwrap_or(false) @@ -819,8 +819,8 @@ mod test { use std::{ collections::HashMap, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, + atomic::{AtomicBool, Ordering}, }, time::Duration, }; @@ -833,27 +833,27 @@ mod test { metapb::{Region, RegionEpoch}, }; use raftstore::{ + RegionInfo, coprocessor::{ObserveHandle, RegionInfoCallback, RegionInfoProvider}, router::{CdcRaftRouter, ServerRaftStoreRouter}, - RegionInfo, }; use tikv::{ config::BackupStreamConfig, - storage::{txn::txn_status_cache::TxnStatusCache, Statistics}, + storage::{Statistics, txn::txn_status_cache::TxnStatusCache}, }; use tikv_util::{box_err, info, memory::MemoryQuota, worker::dummy_scheduler}; use tokio::{sync::mpsc::Sender, task::JoinHandle}; use txn_types::TimeStamp; - use super::{spawn_executors_to, InitialScan, RegionSubscriptionManager}; + use super::{InitialScan, RegionSubscriptionManager, spawn_executors_to}; use crate::{ + BackupStreamResolver, ObserveOp, Task, errors::Error, - metadata::{store::SlashEtcStore, MetadataClient, StreamTask}, + metadata::{MetadataClient, StreamTask, store::SlashEtcStore}, router::{Router, RouterInner}, subscription_manager::{OOM_BACKOFF_BASE, OOM_BACKOFF_JITTER_SECS}, subscription_track::{CheckpointType, SubscriptionTracer}, utils::FutureWaitGroup, - BackupStreamResolver, ObserveOp, Task, }; #[derive(Clone, Copy)] diff --git a/components/backup-stream/src/subscription_track.rs b/components/backup-stream/src/subscription_track.rs index e0b10418bd9..4e3f4622a23 100644 --- a/components/backup-stream/src/subscription_track.rs +++ b/components/backup-stream/src/subscription_track.rs @@ -3,8 +3,8 @@ use std::{collections::HashSet, result::Result, sync::Arc}; use dashmap::{ - mapref::{entry::Entry, one::RefMut as DashRefMut}, DashMap, + mapref::{entry::Entry, one::RefMut as DashRefMut}, }; use kvproto::metapb::Region; use raftstore::coprocessor::*; @@ -405,6 +405,7 @@ pub trait Ref { type Key; type Value; + #[allow(dead_code)] fn key(&self) -> &Self::Key; fn value(&self) -> &Self::Value; } @@ -413,7 +414,7 @@ pub trait RefMut: Ref { fn value_mut(&mut self) -> &mut ::Value; } -impl<'a> Ref for ActiveSubscriptionRef<'a> { +impl Ref for ActiveSubscriptionRef<'_> { type Key = u64; type Value = ActiveSubscription; @@ -426,7 +427,7 @@ impl<'a> Ref for ActiveSubscriptionRef<'a> { } } -impl<'a> RefMut for ActiveSubscriptionRef<'a> { +impl RefMut for ActiveSubscriptionRef<'_> { fn value_mut(&mut self) -> &mut ::Value { self.sub_mut() } @@ -605,7 +606,7 @@ impl TwoPhaseResolver { txn_status_cache: Arc, ) -> Self { // TODO: limit the memory usage of the resolver. - let memory_quota = Arc::new(MemoryQuota::new(std::usize::MAX)); + let memory_quota = Arc::new(MemoryQuota::new(usize::MAX)); Self { resolver: Resolver::new(region_id, memory_quota, txn_status_cache), future_locks: Default::default(), diff --git a/components/backup-stream/src/tempfiles.rs b/components/backup-stream/src/tempfiles.rs index 612ba4f9e5f..a8d6d330e8f 100644 --- a/components/backup-stream/src/tempfiles.rs +++ b/components/backup-stream/src/tempfiles.rs @@ -22,10 +22,10 @@ use std::{ path::{Path, PathBuf}, pin::Pin, sync::{ - atomic::{AtomicU8, AtomicUsize, Ordering}, Arc, Mutex as BlockMutex, + atomic::{AtomicU8, AtomicUsize, Ordering}, }, - task::{ready, Context, Poll}, + task::{Context, Poll, ready}, time::Instant, }; @@ -234,8 +234,7 @@ impl TempFilePool { } }); if f.reader_count.load(Ordering::SeqCst) > 0 { - return Err(Error::new( - ErrorKind::Other, + return Err(Error::other( "open_for_write isn't allowed when there are concurrent reading.", )); } @@ -288,8 +287,7 @@ impl TempFilePool { // like cursors to allow the reader be able to access consistent // File snapshot even there are writers appending contents // to the file. But that isn't needed for now. - return Err(IoErr::new( - ErrorKind::Other, + return Err(IoErr::other( format!( "open_for_read isn't allowed when there are concurrent writing (there are still {} reads for file {}.).", refc, @@ -339,11 +337,11 @@ impl TempFilePool { fn create_relative(&self, p: &Path) -> std::io::Result { let abs_path = self.cfg.swap_files.join(p); #[cfg(test)] - match &self.override_swapout { - Some(f) => return Ok(SwappedOut::Dynamic(f(&abs_path))), - None => {} + if let Some(f) = &self.override_swapout { + return Ok(SwappedOut::Dynamic(f(&abs_path))); } - let file = OsFile::from_std(SyncOsFile::create(&abs_path)?); + let mut file = OsFile::from_std(SyncOsFile::create(&abs_path)?); + file.set_max_buf_size(self.config().write_buffer_size); let pfile = match &self.backup_encryption_manager.opt_data_key_manager() { Some(enc) => SwappedOut::Encrypted( @@ -788,15 +786,15 @@ mod test { path::Path, pin::Pin, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, + atomic::{AtomicUsize, Ordering}, }, }; use async_compression::tokio::bufread::ZstdDecoder; use encryption::{BackupEncryptionManager, DataKeyManager, MultiMasterKeyBackend}; use kvproto::{brpb::CompressionType, encryptionpb::EncryptionMethod}; - use tempfile::{tempdir, TempDir}; + use tempfile::{TempDir, tempdir}; use test_util::new_test_key_manager; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader}; use walkdir::WalkDir; diff --git a/components/backup-stream/src/utils.rs b/components/backup-stream/src/utils.rs index 051a3be033c..343c341c1bb 100644 --- a/components/backup-stream/src/utils.rs +++ b/components/backup-stream/src/utils.rs @@ -4,21 +4,21 @@ use core::pin::Pin; use std::{ borrow::Borrow, cell::RefCell, - collections::{hash_map::RandomState, BTreeMap, HashMap}, + collections::{BTreeMap, HashMap, hash_map::RandomState}, future::Future, ops::{Bound, RangeBounds}, path::Path, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, + atomic::{AtomicUsize, Ordering}, }, task::{Context, Waker}, time::Duration, }; -use async_compression::{tokio::write::ZstdEncoder, Level}; +use async_compression::{Level, tokio::write::ZstdEncoder}; use engine_rocks::ReadPerfInstant; -use engine_traits::{CfName, CF_DEFAULT, CF_LOCK, CF_RAFT, CF_WRITE}; +use engine_traits::{CF_DEFAULT, CF_LOCK, CF_RAFT, CF_WRITE, CfName}; use futures::{ready, task::Poll}; use kvproto::{ brpb::CompressionType, @@ -27,13 +27,12 @@ use kvproto::{ }; use tikv::storage::CfStatistics; use tikv_util::{ - box_err, + Either, box_err, sys::inspector::{ - self_thread_inspector, IoStat, ThreadInspector, ThreadInspectorImpl as OsInspector, + IoStat, ThreadInspector, ThreadInspectorImpl as OsInspector, self_thread_inspector, }, time::Instant, worker::Scheduler, - Either, }; use tokio::{ fs::File, @@ -43,9 +42,9 @@ use tokio::{ use txn_types::{Key, Lock, LockType}; use crate::{ + Task, errors::{Error, Result}, router::TaskSelector, - Task, }; /// wrap a user key with encoded data key. @@ -105,7 +104,7 @@ pub type SlotMap = RwLock, S>>; /// to DSTs. struct RangeToInclusiveRef<'a, T: ?Sized>(&'a T); -impl<'a, T: ?Sized> RangeBounds for RangeToInclusiveRef<'a, T> { +impl RangeBounds for RangeToInclusiveRef<'_, T> { fn start_bound(&self) -> Bound<&T> { Bound::Unbounded } @@ -117,7 +116,7 @@ impl<'a, T: ?Sized> RangeBounds for RangeToInclusiveRef<'a, T> { struct RangeToExclusiveRef<'a, T: ?Sized>(&'a T); -impl<'a, T: ?Sized> RangeBounds for RangeToExclusiveRef<'a, T> { +impl RangeBounds for RangeToExclusiveRef<'_, T> { fn start_bound(&self) -> Bound<&T> { Bound::Unbounded } @@ -394,7 +393,7 @@ impl Drop for Work { pub struct WaitAll<'a>(&'a FutureWaitGroup); -impl<'a> Future for WaitAll<'a> { +impl Future for WaitAll<'_> { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { @@ -706,7 +705,7 @@ pub fn debug_key_range<'ret, 'a: 'ret, 'b: 'ret>( struct DebugKeyRange<'start, 'end>(&'start [u8], &'end [u8]); -impl<'start, 'end> std::fmt::Debug for DebugKeyRange<'start, 'end> { +impl std::fmt::Debug for DebugKeyRange<'_, '_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let end_key = if self.1.is_empty() { Either::Left("inf") @@ -735,7 +734,7 @@ pub fn debug_region(r: &Region) -> impl std::fmt::Debug + '_ { struct DebugRegion<'a>(&'a Region); -impl<'a> std::fmt::Debug for DebugRegion<'a> { +impl std::fmt::Debug for DebugRegion<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let r = self.0; f.debug_struct("Region") @@ -756,7 +755,7 @@ impl<'a> std::fmt::Debug for DebugRegion<'a> { struct SlogRegion<'a>(&'a Region); -impl<'a> slog::KV for SlogRegion<'a> { +impl slog::KV for SlogRegion<'_> { fn serialize( &self, _record: &slog::Record<'_>, @@ -812,8 +811,8 @@ impl> std::fmt::Debug for DebugIter s, Err(e) => { - error!(?e; "backup snapshot failed"); + warn!("backup snapshot failed"; "err" => ?e, "ctx" => ?ctx); return Err(e.into()); } }; @@ -417,7 +418,7 @@ impl BackupRange { RescheduleChecker::new(tokio::task::yield_now, TASK_YIELD_DURATION); loop { if let Err(e) = scanner.scan_entries(&mut batch) { - error!(?e; "backup scan entries failed"); + warn!("backup scan entries failed"; "err" => ?e, "ctx" => ?ctx); return Err(e.into()); }; if batch.is_empty() { @@ -458,7 +459,7 @@ impl BackupRange { // Build sst files. if let Err(e) = writer.write(entries, true) { - error_unknown!(?e; "backup build sst failed"); + warn!("backup build sst failed"; "err" => ?e, "ctx" => ?ctx); return Err(e); } if resource_limiter.is_some() { @@ -583,7 +584,7 @@ impl BackupRange { ) { Ok(w) => w, Err(e) => { - error_unknown!(?e; "backup writer failed"); + warn!("backup writer failed"; "err" => ?e, "region" => ?self.region); return Err(e); } }; @@ -600,7 +601,7 @@ impl BackupRange { let engine_snapshot = match engine.snapshot(snap_ctx) { Ok(s) => s, Err(e) => { - error!(?e; "backup raw kv snapshot failed"); + warn!("backup raw kv snapshot failed"; "err" => ?e, "ctx" => ?ctx); return Err(e.into()); } }; @@ -862,7 +863,6 @@ impl Progress { }), ); if let Err(e) = res { - // TODO: handle error. error!(?e; "backup seek region failed"); } @@ -970,7 +970,8 @@ impl Endpoint { loop { // when get the guard, release it until we finish scanning a batch, // because if we were suspended during scanning, - // the region info have higher possibility to change (then we must compensate that by the fine-grained backup). + // the region info have higher possibility to change (then we must compensate + // that by the fine-grained backup). let guard = soft_limit_keeper.guard().await; if let Err(e) = guard { warn!("failed to retrieve limit guard, omitting."; "err" => %e); @@ -980,14 +981,16 @@ impl Endpoint { // It is critical to speed up backup, otherwise workers are // blocked by each other. // - // If we use [tokio::sync::Mutex] here, until we give back the control flow to the scheduler - // or tasks waiting for the lock won't be waked up due to the characteristic of the runtime... + // If we use [tokio::sync::Mutex] here, until we give back the control flow to + // the scheduler or tasks waiting for the lock won't be + // waked up due to the characteristic of the runtime... // // The worst case is when using `noop` backend: - // the task seems never yielding and in fact the backup would executing sequentially. + // the task seems never yielding and in fact the backup would executing + // sequentially. // - // Anyway, even tokio itself doesn't recommend to use it unless the lock guard needs to be `Send`. - // (See https://tokio.rs/tokio/tutorial/shared-state) + // Anyway, even tokio itself doesn't recommend to use it unless the lock guard + // needs to be `Send`. (See https://tokio.rs/tokio/tutorial/shared-state) // Use &mut and mark the type for making rust-analyzer happy. let progress: &mut Progress<_> = &mut prs.lock().unwrap(); match progress.forward(batch_size, request.replica_read) { @@ -997,8 +1000,9 @@ impl Endpoint { }; for brange in batch { - // wake up the scheduler for each loop for awaking tasks waiting for some lock or channels. - // because the softlimit permit is held by current task, there isn't risk of being suspended for long time. + // wake up the scheduler for each loop for awaking tasks waiting for some lock + // or channels. because the softlimit permit is held by + // current task, there isn't risk of being suspended for long time. tokio::task::yield_now().await; let engine = engine.clone(); if request.cancel.load(Ordering::SeqCst) { @@ -1007,7 +1011,8 @@ impl Endpoint { } // TODO: make file_name unique and short let key = brange.start_key.clone().and_then(|k| { - // use start_key sha256 instead of start_key to avoid file name too long os error + // use start_key sha256 instead of start_key to avoid file name too long os + // error let input = brange.codec.decode_backup_key(Some(k)).unwrap_or_default(); file_system::sha256(&input).ok().map(hex::encode) }); @@ -1046,7 +1051,8 @@ impl Endpoint { sst_max_size, request.cipher.clone(), ); - with_resource_limiter(brange.backup( + with_resource_limiter( + brange.backup( writer_builder, engine, concurrency_manager.clone(), @@ -1057,15 +1063,17 @@ impl Endpoint { saver_tx.clone(), _backend.name(), resource_limiter.clone(), - ), resource_limiter.clone()) - .await + ), + resource_limiter.clone(), + ) + .await }; match stat { Err(err) => { - error_unknown!(%err; "error during backup"; "region" => ?brange.region,); + warn!("error during backup"; "region" => ?brange.region, "err" => %err); let mut resp = BackupResponse::new(); resp.set_error(err.into()); - if let Err(err) = resp_tx.unbounded_send(resp) { + if let Err(err) = resp_tx.unbounded_send(resp) { warn!("failed to send response"; "err" => ?err) } } @@ -1339,7 +1347,7 @@ pub mod tests { time::Duration, }; - use api_version::{api_v2::RAW_KEY_PREFIX, dispatch_api_version, KvFormat, RawValue}; + use api_version::{KvFormat, RawValue, api_v2::RAW_KEY_PREFIX, dispatch_api_version}; use collections::HashSet; use engine_rocks::RocksSstReader; use engine_traits::{IterOptions, Iterator, MiscExt, RefIterable, SstReader}; @@ -1354,9 +1362,9 @@ pub mod tests { use tikv::{ coprocessor::checksum_crc64_xor, storage::{ + RocksEngine, TestEngineBuilder, kv::LocalTablets, txn::tests::{must_commit, must_prewrite_put}, - RocksEngine, TestEngineBuilder, }, }; use tikv_util::{config::ReadableSize, info, store::new_peer}; diff --git a/components/backup/src/lib.rs b/components/backup/src/lib.rs index 30345665369..54be9e5256a 100644 --- a/components/backup/src/lib.rs +++ b/components/backup/src/lib.rs @@ -14,7 +14,7 @@ mod softlimit; mod utils; mod writer; -pub use endpoint::{backup_file_name, Endpoint, Task}; +pub use endpoint::{Endpoint, Task, backup_file_name}; pub use errors::{Error, Result}; pub use service::Service; pub use writer::{BackupRawKvWriter, BackupWriter}; diff --git a/components/backup/src/service.rs b/components/backup/src/service.rs index 7e38093df53..2e8cf44dd81 100644 --- a/components/backup/src/service.rs +++ b/components/backup/src/service.rs @@ -1,8 +1,8 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -use std::sync::{atomic::*, Arc, Mutex}; +use std::sync::{Arc, Mutex, atomic::*}; -use futures::{channel::mpsc, FutureExt, SinkExt, StreamExt, TryFutureExt}; +use futures::{FutureExt, SinkExt, StreamExt, TryFutureExt, channel::mpsc}; use futures_util::stream::AbortHandle; use grpcio::{self, *}; use kvproto::brpb::*; @@ -139,10 +139,10 @@ where /// Generally there will be some steps for the client to do: /// 1. Establish a `prepare_snapshot_backup` connection. /// 2. Send a initial `UpdateLease`. And we should update the lease - /// periodically. + /// periodically. /// 3. Send `WaitApply` to each leader peer in this store. /// 4. Once `WaitApply` for all regions have done, we can take disk - /// snapshot. + /// snapshot. /// 5. Once all snapshots have been taken, send `Finalize` to stop. fn prepare_snapshot_backup( &mut self, @@ -180,7 +180,7 @@ mod tests { use external_storage::make_local_backend; use tikv::storage::txn::tests::{must_commit, must_prewrite_put}; - use tikv_util::worker::{dummy_scheduler, ReceiverWrapper}; + use tikv_util::worker::{ReceiverWrapper, dummy_scheduler}; use txn_types::TimeStamp; use super::*; diff --git a/components/backup/src/softlimit.rs b/components/backup/src/softlimit.rs index a3de91bb403..42d5accb042 100644 --- a/components/backup/src/softlimit.rs +++ b/components/backup/src/softlimit.rs @@ -3,8 +3,8 @@ use std::{ cmp::Ordering as CmpOrder, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, + atomic::{AtomicUsize, Ordering}, }, }; @@ -181,8 +181,8 @@ impl SoftLimitByCpu { mod softlimit_test { use std::{ sync::{ - atomic::{AtomicU8, Ordering}, Arc, + atomic::{AtomicU8, Ordering}, }, time::Duration, }; diff --git a/components/backup/src/utils.rs b/components/backup/src/utils.rs index b13e51466f9..358a61e65b0 100644 --- a/components/backup/src/utils.rs +++ b/components/backup/src/utils.rs @@ -1,6 +1,6 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. -use api_version::{dispatch_api_version, ApiV2, KeyMode, KvFormat}; +use api_version::{ApiV2, KeyMode, KvFormat, dispatch_api_version}; use file_system::IoType; use kvproto::kvrpcpb::ApiVersion; use tikv_util::{error, sys::thread::ThreadBuildWrapper}; diff --git a/components/backup/src/writer.rs b/components/backup/src/writer.rs index 4e77f20350d..9e2e3301015 100644 --- a/components/backup/src/writer.rs +++ b/components/backup/src/writer.rs @@ -4,8 +4,8 @@ use std::{fmt::Display, io::Read}; use encryption::{EncrypterReader, Iv}; use engine_traits::{ - CfName, ExternalSstFileInfo, KvEngine, SstCompressionType, SstExt, SstWriter, SstWriterBuilder, - CF_DEFAULT, CF_WRITE, + CF_DEFAULT, CF_WRITE, CfName, ExternalSstFileInfo, KvEngine, SstCompressionType, SstExt, + SstWriter, SstWriterBuilder, }; use external_storage::{ExternalStorage, UnpinReader}; use file_system::Sha256Reader; @@ -21,7 +21,7 @@ use tikv_util::{ }; use txn_types::KvPair; -use crate::{backup_file_name, metrics::*, utils::KeyValueCodec, Error, Result}; +use crate::{Error, Result, backup_file_name, metrics::*, utils::KeyValueCodec}; #[derive(Debug, Clone, Copy)] /// CfNameWrap wraps the CfName type. @@ -467,7 +467,7 @@ mod tests { .unwrap(); assert_eq!(map.len(), kv.len(), "{} {:?} {:?}", cf, map, kv); for (k, v) in *kv { - assert_eq!(&v.to_vec(), map.get(&k.to_vec()).unwrap()); + assert_eq!(&v.to_vec(), map.get(*k).unwrap()); } } } @@ -542,10 +542,7 @@ mod tests { engine_traits::CF_WRITE, &temp.path().join(files[0].get_name()), )], - &[( - engine_traits::CF_WRITE, - &[(&keys::data_key(&[b'a']), &[b'a'])], - )], + &[(engine_traits::CF_WRITE, &[(&keys::data_key(b"a"), b"a")])], ); // Test write and default. @@ -595,16 +592,10 @@ mod tests { ), ], &[ - ( - engine_traits::CF_DEFAULT, - &[(&keys::data_key(&[b'a']), &[b'a'])], - ), + (engine_traits::CF_DEFAULT, &[(&keys::data_key(b"a"), b"a")]), ( engine_traits::CF_WRITE, - &[ - (&keys::data_key(&[b'a']), &[b'a']), - (&keys::data_key(&[b'b']), &[]), - ], + &[(&keys::data_key(b"a"), b"a"), (&keys::data_key(b"b"), &[])], ), ], ); diff --git a/components/batch-system/benches/batch-system.rs b/components/batch-system/benches/batch-system.rs index 9edf72f0ff9..d849d2460dc 100644 --- a/components/batch-system/benches/batch-system.rs +++ b/components/batch-system/benches/batch-system.rs @@ -2,7 +2,7 @@ #![feature(test)] -use std::sync::{atomic::*, Arc}; +use std::sync::{Arc, atomic::*}; use batch_system::{test_runner::*, *}; use criterion::*; diff --git a/components/batch-system/src/batch.rs b/components/batch-system/src/batch.rs index 0b7f9f45489..4791d2d02aa 100644 --- a/components/batch-system/src/batch.rs +++ b/components/batch-system/src/batch.rs @@ -10,16 +10,16 @@ use std::{ borrow::Cow, ops::{Deref, DerefMut}, - sync::{atomic::AtomicUsize, Arc, Mutex}, - thread::{self, current, JoinHandle, ThreadId}, + sync::{Arc, Mutex, atomic::AtomicUsize}, + thread::{self, JoinHandle, ThreadId, current}, time::Duration, }; use fail::fail_point; -use file_system::{set_io_type, IoType}; +use file_system::{IoType, set_io_type}; use resource_control::{ - channel::{unbounded, Receiver, Sender}, ResourceController, + channel::{Receiver, Sender, unbounded}, }; use tikv_util::{ debug, error, info, mpsc, safe_panic, sys::thread::StdThreadBuildWrapper, thd_name, diff --git a/components/batch-system/src/fsm.rs b/components/batch-system/src/fsm.rs index 9002e16e0a2..427e37e1015 100644 --- a/components/batch-system/src/fsm.rs +++ b/components/batch-system/src/fsm.rs @@ -4,10 +4,9 @@ use std::{ borrow::Cow, ptr, sync::{ - atomic::{AtomicPtr, AtomicUsize, Ordering}, Arc, + atomic::{AtomicPtr, AtomicUsize, Ordering}, }, - usize, }; use resource_control::ResourceMetered; diff --git a/components/batch-system/src/lib.rs b/components/batch-system/src/lib.rs index 1a45f2c5cdf..1f6f3ba4a60 100644 --- a/components/batch-system/src/lib.rs +++ b/components/batch-system/src/lib.rs @@ -13,8 +13,8 @@ pub mod test_runner; pub use self::{ batch::{ - create_system, BatchRouter, BatchSystem, FsmTypes, HandleResult, HandlerBuilder, - PollHandler, Poller, PoolState, + BatchRouter, BatchSystem, FsmTypes, HandleResult, HandlerBuilder, PollHandler, Poller, + PoolState, create_system, }, config::Config, fsm::{Fsm, FsmScheduler, Priority}, diff --git a/components/batch-system/src/mailbox.rs b/components/batch-system/src/mailbox.rs index 869031392af..024a275cd49 100644 --- a/components/batch-system/src/mailbox.rs +++ b/components/batch-system/src/mailbox.rs @@ -3,7 +3,7 @@ // #[PerformanceCriticalPath] use std::{ borrow::Cow, - sync::{atomic::AtomicUsize, Arc}, + sync::{Arc, atomic::AtomicUsize}, }; use crossbeam::channel::{SendError, TrySendError}; diff --git a/components/batch-system/src/router.rs b/components/batch-system/src/router.rs index 4f886fe3b3d..5c1cb92d7ca 100644 --- a/components/batch-system/src/router.rs +++ b/components/batch-system/src/router.rs @@ -2,13 +2,13 @@ // #[PerformanceCriticalPath] use std::sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }; use crossbeam::channel::{SendError, TrySendError}; use dashmap::DashMap; -use tikv_util::{debug, info, time::Instant, Either}; +use tikv_util::{Either, debug, info, time::Instant}; use crate::{ fsm::{Fsm, FsmScheduler}, @@ -102,7 +102,7 @@ where where F: FnMut(&BasicMailbox) -> Option, { - let mailbox = match self.normals.get_mut(&addr) { + let mailbox = match self.normals.get(&addr) { Some(mailbox) => mailbox, None => { return CheckDoResult::NotExist; diff --git a/components/batch-system/src/scheduler.rs b/components/batch-system/src/scheduler.rs index 12db92b8fa7..a9289cfbd34 100644 --- a/components/batch-system/src/scheduler.rs +++ b/components/batch-system/src/scheduler.rs @@ -5,8 +5,8 @@ use resource_control::channel::Sender; use tikv_util::{time::Instant, warn}; use crate::{ - fsm::{Fsm, FsmScheduler, Priority}, FsmTypes, + fsm::{Fsm, FsmScheduler, Priority}, }; pub struct NormalScheduler { pub(crate) sender: Sender>, diff --git a/components/batch-system/src/test_runner.rs b/components/batch-system/src/test_runner.rs index 7723fa88882..bcbdfbc2a27 100644 --- a/components/batch-system/src/test_runner.rs +++ b/components/batch-system/src/test_runner.rs @@ -6,8 +6,8 @@ use std::{ borrow::Cow, ops::DerefMut, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, Mutex, + atomic::{AtomicUsize, Ordering}, }, }; diff --git a/components/batch-system/tests/cases/batch.rs b/components/batch-system/tests/cases/batch.rs index dc13affc363..9246edffe0f 100644 --- a/components/batch-system/tests/cases/batch.rs +++ b/components/batch-system/tests/cases/batch.rs @@ -1,7 +1,7 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. use std::{ - sync::{atomic::AtomicUsize, Arc}, + sync::{Arc, atomic::AtomicUsize}, thread::sleep, time::Duration, }; diff --git a/components/batch-system/tests/cases/router.rs b/components/batch-system/tests/cases/router.rs index 66d0770d544..b5dc0688d77 100644 --- a/components/batch-system/tests/cases/router.rs +++ b/components/batch-system/tests/cases/router.rs @@ -1,7 +1,7 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. use std::{ - sync::{atomic::*, Arc}, + sync::{Arc, atomic::*}, time::Duration, }; diff --git a/components/causal_ts/src/lib.rs b/components/causal_ts/src/lib.rs index ab57fbf734f..fa34b032f14 100644 --- a/components/causal_ts/src/lib.rs +++ b/components/causal_ts/src/lib.rs @@ -1,7 +1,5 @@ // Copyright 2022 TiKV Project Authors. Licensed under Apache-2.0. -#![feature(div_duration)] - #[macro_use] extern crate tikv_util; @@ -42,8 +40,8 @@ pub enum CausalTsProviderImpl { pub mod tests { use std::sync::{ - atomic::{AtomicU64, Ordering}, Arc, + atomic::{AtomicU64, Ordering}, }; use super::*; diff --git a/components/causal_ts/src/tso.rs b/components/causal_ts/src/tso.rs index 51f1824f7a6..b4527bd95b7 100644 --- a/components/causal_ts/src/tso.rs +++ b/components/causal_ts/src/tso.rs @@ -2,8 +2,8 @@ //! ## The algorithm to make the TSO cache tolerate failure of TSO service //! -//! 1. The expected total size (in duration) of TSO cache is specified by -//! config item `causal-ts.alloc-ahead-buffer`. +//! 1. The expected total size (in duration) of TSO cache is specified by config +//! item `causal-ts.alloc-ahead-buffer`. //! //! 2. Count usage of TSO on every renew interval. //! @@ -11,10 +11,10 @@ //! causal-ts.renew-interval`. //! //! 4. Then `tso_usage x cache_multiplier` is the expected number of TSO should -//! be cached. +//! be cached. //! //! 5. And `tso_usage x cache_multiplier - tso_remain` is the expected number of -//! TSO to be requested from TSO service (if it's not a flush). +//! TSO to be requested from TSO service (if it's not a flush). //! //! Others: //! * `cache_multiplier` is also used as capacity of TSO batch list, as we @@ -25,8 +25,8 @@ use std::{ collections::BTreeMap, error, result, sync::{ - atomic::{AtomicI32, AtomicU32, AtomicU64, Ordering}, Arc, + atomic::{AtomicI32, AtomicU32, AtomicU64, Ordering}, }, }; @@ -47,9 +47,9 @@ use tokio::sync::{ use txn_types::TimeStamp; use crate::{ + CausalTsProvider, errors::{Error, Result}, metrics::*, - CausalTsProvider, }; /// Renew on every 100ms, to adjust batch size rapidly enough. @@ -131,11 +131,11 @@ impl TsoBatch { /// `TsoBatchList` is a ordered list of `TsoBatch`. It aims to: /// /// 1. Cache more number of TSO to improve high availability. See issue #12794. -/// `TsoBatch` can only cache at most 262144 TSO as logical clock is 18 bits. +/// `TsoBatch` can only cache at most 262144 TSO as logical clock is 18 bits. /// /// 2. Fully utilize cached TSO when some regions require latest TSO (e.g. in -/// the scenario of leader transfer). Other regions without the requirement can -/// still use older TSO cache. +/// the scenario of leader transfer). Other regions without the requirement +/// can still use older TSO cache. #[derive(Default, Debug)] pub struct TsoBatchList { inner: RwLock, @@ -157,11 +157,11 @@ pub struct TsoBatchList { /// The reasons why `crossbeam_skiplist::SkipMap` is not chosen: /// /// 1. In `flush()` procedure, a reader of `SkipMap` can still acquire a batch -/// after the it is removed, which would violate the causality requirement. -/// The `RwLock` avoid this scenario by lock synchronization. +/// after the it is removed, which would violate the causality requirement. +/// The `RwLock` avoid this scenario by lock synchronization. /// /// 2. It is a scenario with much more reads than writes. The `RwLock` would not -/// be less efficient than lock free implementation. +/// be less efficient than lock free implementation. type TsoBatchListInner = BTreeMap; impl TsoBatchList { @@ -423,11 +423,10 @@ impl BatchTsoProvider { Ok(ts) => { tso_batch_list .push(new_batch_size, ts, need_flush) - .map_err(|e| { + .inspect_err(|_e| { if need_flush { tso_batch_list.flush(); } - e })?; debug!("BatchTsoProvider::renew_tso_batch"; "tso_batch_list.remain" => tso_batch_list.remain(), "ts" => ?ts); diff --git a/components/cdc/benches/cdc_event.rs b/components/cdc/benches/cdc_event.rs index 1ea57f5c703..c23852149b1 100644 --- a/components/cdc/benches/cdc_event.rs +++ b/components/cdc/benches/cdc_event.rs @@ -1,7 +1,7 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. use cdc::CdcEvent; -use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; +use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main}; use kvproto::cdcpb::ResolvedTs; use protobuf::Message; diff --git a/components/cdc/src/channel.rs b/components/cdc/src/channel.rs index 98520dc7b02..521fb90527b 100644 --- a/components/cdc/src/channel.rs +++ b/components/cdc/src/channel.rs @@ -3,19 +3,20 @@ use std::{ fmt, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, time::Duration, }; use futures::{ + SinkExt, Stream, StreamExt, channel::mpsc::{ - channel as bounded, unbounded, Receiver, SendError as FuturesSendError, Sender, - TrySendError, UnboundedReceiver, UnboundedSender, + Receiver, SendError as FuturesSendError, Sender, TrySendError, UnboundedReceiver, + UnboundedSender, channel as bounded, unbounded, }, executor::block_on, - stream, SinkExt, Stream, StreamExt, + stream, }; use grpcio::WriteFlags; use kvproto::cdcpb::{ChangeDataEvent, Event, ResolvedTs}; @@ -386,8 +387,13 @@ impl<'a> Drain { }) } - // Forwards contents to the sink, simulates StreamExt::forward. - pub async fn forward(&'a mut self, sink: &mut S) -> Result<(), E> + // Forwards contents to the sink with time tracking, simulates + // StreamExt::forward. + pub async fn forward( + &'a mut self, + sink: &mut S, + last_flush_time: Option<&crossbeam::atomic::AtomicCell>, + ) -> Result<(), E> where S: futures::Sink<(ChangeDataEvent, WriteFlags), Error = E> + Unpin, { @@ -415,6 +421,12 @@ impl<'a> Drain { sink.feed((e, write_flags)).await?; } sink.flush().await?; + #[cfg(feature = "failpoints")] + sleep_after_sink_flush().await; + // Update last flush time if provided + if let Some(time_tracker) = last_flush_time { + time_tracker.store(std::time::Instant::now()); + } total_event_bytes.inc_by(event_bytes as u64); total_resolved_ts_bytes.inc_by(resolved_ts_bytes as u64); } @@ -422,6 +434,21 @@ impl<'a> Drain { } } +#[cfg(feature = "failpoints")] +async fn sleep_after_sink_flush() { + let should_sleep = || { + fail::fail_point!("cdc_sleep_after_sink_flush", |_| true); + false + }; + if !should_sleep() { + return; + } + info!("inside sleep_after_sink_flush failpoint, sleep 30 seconds!"); + let dur = Duration::from_secs(30); + let timer = tikv_util::timer::GLOBAL_TIMER_HANDLE.delay(std::time::Instant::now() + dur); + let _ = futures::compat::Compat01As03::new(timer).await; +} + impl Drop for Drain { fn drop(&mut self) { self.bounded_receiver.close(); @@ -459,13 +486,13 @@ where mod tests { use std::{ assert_matches::assert_matches, - sync::{mpsc, Arc}, + sync::{Arc, mpsc}, time::Duration, }; use futures::executor::block_on; use kvproto::cdcpb::{ - ChangeDataEvent, Event, EventEntries, EventRow, Event_oneof_event, ResolvedTs, + ChangeDataEvent, Event, Event_oneof_event, EventEntries, EventRow, ResolvedTs, }; use super::*; @@ -567,7 +594,7 @@ mod tests { let (mut tx, mut rx) = unbounded(); let runtime = tokio::runtime::Runtime::new().unwrap(); runtime.spawn(async move { - drain.forward(&mut tx).await.unwrap(); + drain.forward(&mut tx, None).await.unwrap(); }); let timeout = Duration::from_millis(100); assert!(recv_timeout(&mut rx, timeout).unwrap().is_some()); diff --git a/components/cdc/src/delegate.rs b/components/cdc/src/delegate.rs index db5d67f5887..d0bc075d525 100644 --- a/components/cdc/src/delegate.rs +++ b/components/cdc/src/delegate.rs @@ -7,8 +7,8 @@ use std::{ result::Result as StdResult, string::String, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, time::Duration, }; @@ -18,21 +18,21 @@ use collections::HashMap; use crossbeam::atomic::AtomicCell; use kvproto::{ cdcpb::{ - ChangeDataRequestKvApi, Error as EventError, Event, EventEntries, EventLogType, EventRow, - EventRowOpType, Event_oneof_event, + ChangeDataRequestKvApi, Error as EventError, Event, Event_oneof_event, EventEntries, + EventLogType, EventRow, EventRowOpType, }, kvrpcpb::ExtraOp as TxnExtraOp, metapb::{Region, RegionEpoch}, raft_cmdpb::{AdminCmdType, AdminRequest, AdminResponse, CmdType, PutRequest, Request}, }; use raftstore::{ + Error as RaftStoreError, coprocessor::{Cmd, CmdBatch, ObserveHandle}, store::util::compare_region_epoch, - Error as RaftStoreError, }; -use tikv::storage::{txn::TxnEntry, Statistics}; +use tikv::storage::{Statistics, txn::TxnEntry}; use tikv_util::{ - debug, info, + debug, error, info, memory::{HeapSize, MemoryQuota}, time::Instant, warn, @@ -40,14 +40,14 @@ use tikv_util::{ use txn_types::{Key, Lock, LockType, TimeStamp, WriteBatchFlags, WriteRef, WriteType}; use crate::{ - channel::{CdcEvent, SendError, Sink, CDC_EVENT_MAX_BYTES}, + Error, Result, + channel::{CDC_EVENT_MAX_BYTES, CdcEvent, SendError, Sink}, endpoint::Advance, initializer::KvEntry, metrics::*, old_value::{OldValueCache, OldValueCallback}, service::{Conn, ConnId, FeatureGate, RequestId}, txn_source::TxnSource, - Error, Result, }; static DOWNSTREAM_ID_ALLOC: AtomicUsize = AtomicUsize::new(0); @@ -369,10 +369,25 @@ impl Delegate { CDC_PENDING_BYTES_GAUGE.add(bytes as _); locks.push(PendingLock::Track { key, start_ts }); } - LockTracker::Prepared { locks, .. } => match locks.entry(key) { + LockTracker::Prepared { locks, .. } => match locks.entry(key.clone()) { BTreeMapEntry::Occupied(mut x) => { - assert_eq!(x.get().ts, start_ts.ts); + if x.get().ts != start_ts.ts { + error!("[for debug] cdc push_lock found lock with same key but different start_ts"; + "old_generation" => ?x.get().generation, + "new_generation" => ?start_ts.generation, + "old_start_ts" => ?x.get().ts, + "new_start_ts" => ?start_ts.ts, + "key" => ?key, + "region_id" => self.region_id, + ); + } + // There could be stale locks in the lock_tracker due to scenarios such as the + // overlapped write/rollback issue (#18498). We can safely + // ignore such stale locks, while keeping the invariant of + // monotonically increasing start_ts and generation. + assert!(x.get().ts <= start_ts.ts); assert!(x.get().generation <= start_ts.generation); + x.get_mut().ts = start_ts.ts; x.get_mut().generation = start_ts.generation; } BTreeMapEntry::Vacant(x) => { @@ -397,13 +412,21 @@ impl Delegate { locks.push(PendingLock::Untrack { key, start_ts }); } LockTracker::Prepared { locks, .. } => { - if let BTreeMapEntry::Occupied(x) = locks.entry(key) { + if let BTreeMapEntry::Occupied(x) = locks.entry(key.clone()) { if x.get().ts == start_ts { let (key, _) = x.remove_entry(); let bytes = key.approximate_heap_size(); self.memory_quota.free(bytes); CDC_PENDING_BYTES_GAUGE.sub(bytes as _); lock_count_modify = -1; + } else { + info!("[for debug] cdc pop_lock found lock with same key but different start_ts"; + "generation" => ?x.get().generation, + "old_start_ts" => ?x.get().ts, + "new_start_ts" => ?start_ts, + "key" => ?key, + "region_id" => self.region_id, + ); } } } @@ -437,9 +460,11 @@ impl Delegate { BTreeMapEntry::Vacant(x) => { x.insert(start_ts); } - BTreeMapEntry::Occupied(x) => { - assert_eq!(x.get().ts, start_ts.ts); + BTreeMapEntry::Occupied(mut x) => { + assert!(x.get().ts <= start_ts.ts); assert!(x.get().generation <= start_ts.generation); + x.get_mut().ts = start_ts.ts; + x.get_mut().generation = start_ts.generation; } }, PendingLock::Untrack { key, start_ts } => { @@ -1742,7 +1767,7 @@ mod tests { let (mut tx, mut rx) = futures::channel::mpsc::unbounded(); let runtime = tokio::runtime::Runtime::new().unwrap(); runtime.spawn(async move { - drain.forward(&mut tx).await.unwrap(); + drain.forward(&mut tx, None).await.unwrap(); }); let (e, _) = recv_timeout(&mut rx, std::time::Duration::from_secs(5)) .unwrap() @@ -1809,7 +1834,7 @@ mod tests { let (mut tx, mut rx) = futures::channel::mpsc::unbounded(); let runtime = tokio::runtime::Runtime::new().unwrap(); runtime.spawn(async move { - drain.forward(&mut tx).await.unwrap(); + drain.forward(&mut tx, None).await.unwrap(); }); let (e, _) = recv_timeout(&mut rx, std::time::Duration::from_secs(5)) .unwrap() diff --git a/components/cdc/src/endpoint.rs b/components/cdc/src/endpoint.rs index 0100fd1e35c..07878aab667 100644 --- a/components/cdc/src/endpoint.rs +++ b/components/cdc/src/endpoint.rs @@ -5,8 +5,8 @@ use std::{ collections::{BTreeMap, BinaryHeap}, fmt, sync::{ - atomic::{AtomicBool, AtomicIsize, Ordering}, Arc, Mutex as StdMutex, + atomic::{AtomicBool, AtomicIsize, Ordering}, }, time::Duration, }; @@ -35,11 +35,11 @@ use raftstore::{ router::CdcHandle, store::fsm::store::StoreRegionMeta, }; -use resolved_ts::{resolve_by_raft, LeadershipResolver}; +use resolved_ts::{LeadershipResolver, resolve_by_raft}; use security::SecurityManager; use tikv::{ config::{CdcConfig, ResolvedTsConfig}, - storage::{kv::LocalTablets, Statistics}, + storage::{Statistics, kv::LocalTablets}, }; use tikv_util::{ debug, defer, error, impl_display_as_debug, info, @@ -59,13 +59,13 @@ use tokio::{ use txn_types::{Key, TimeStamp, TxnExtra, TxnExtraScheduler}; use crate::{ + CdcObserver, Error, channel::{CdcEvent, SendError}, - delegate::{on_init_downstream, Delegate, Downstream, DownstreamId, DownstreamState, MiniLock}, + delegate::{Delegate, Downstream, DownstreamId, DownstreamState, MiniLock, on_init_downstream}, initializer::Initializer, metrics::*, old_value::{OldValueCache, OldValueCallback}, - service::{validate_kv_api, Conn, ConnId, FeatureGate, RequestId}, - CdcObserver, Error, + service::{Conn, ConnId, FeatureGate, RequestId, validate_kv_api}, }; const FEATURE_RESOLVED_TS_STORE: Feature = Feature::require(5, 0, 0); @@ -640,25 +640,25 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint 0 { self.config.incremental_scan_speed_limit.0 as f64 } else { @@ -667,7 +667,7 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint 0 { self.config.incremental_fetch_speed_limit.0 as f64 } else { @@ -714,19 +714,26 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint { - let conn = self.connections.remove(&conn_id).unwrap(); - conn.iter_downstreams(|_, region_id, downstream_id, _| { - self.deregister_downstream(region_id, downstream_id, None); - }); + if let Some(conn) = self.connections.remove(&conn_id) { + conn.iter_downstreams(|_, region_id, downstream_id, _| { + self.deregister_downstream(region_id, downstream_id, None); + }); + } else { + info!("cdc connection already deregistered"; "conn_id" => ?conn_id); + } } Deregister::Request { conn_id, request_id, } => { - let conn = self.connections.get_mut(&conn_id).unwrap(); - for (region_id, downstream) in conn.unsubscribe_request(request_id) { - let err = Some(Error::Other("region not found".into())); - self.deregister_downstream(region_id, downstream, err); + if let Some(conn) = self.connections.get_mut(&conn_id) { + for (region_id, downstream) in conn.unsubscribe_request(request_id) { + let err = Some(Error::Other("region not found".into())); + self.deregister_downstream(region_id, downstream, err); + } + } else { + info!("cdc connection already deregistered for request deregister"; + "request_id" => ?request_id, "conn_id" => ?conn_id); } } Deregister::Region { @@ -734,10 +741,14 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint { - let conn = self.connections.get_mut(&conn_id).unwrap(); - if let Some(downstream) = conn.unsubscribe(request_id, region_id) { - let err = Some(Error::Other("region not found".into())); - self.deregister_downstream(region_id, downstream, err); + if let Some(conn) = self.connections.get_mut(&conn_id) { + if let Some(downstream) = conn.unsubscribe(request_id, region_id) { + let err = Some(Error::Other("region not found".into())); + self.deregister_downstream(region_id, downstream, err); + } + } else { + info!("cdc connection already deregistered for region deregister"; + "request_id" => ?request_id, "region_id" => region_id, "conn_id" => ?conn_id); } } Deregister::Downstream { @@ -863,7 +874,7 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint reader.txn_extra_op.clone(), None => { - error!("cdc register for a not found region"; "region_id" => region_id); + warn!("cdc register for a not found region"; "region_id" => region_id); let mut err_event = EventError::default(); err_event.mut_region_not_found().region_id = region_id; let _ = downstream.sink_error_event(region_id, err_event); @@ -974,7 +985,7 @@ impl, E: KvEngine, S: StoreRegionMeta> Endpoint { CDC_SCAN_TASKS.with_label_values(&["abort"]).inc(); - error!( + warn!( "cdc initialize fail: {}", e; "region_id" => region_id, "conn_id" => ?init.conn_id, "request_id" => ?init.request_id, ); @@ -1256,7 +1267,7 @@ impl, E: KvEngine, S: StoreRegionMeta + Send> Runnable _ => return, } if let Err(e) = sink.unbounded_send(incremental_scan_barrier, true) { - error!("cdc failed to schedule barrier for delta before delta scan"; + warn!("cdc failed to schedule barrier for delta before delta scan"; "region_id" => region_id, "observe_id" => ?observe_id, "downstream_id" => ?downstream_id, @@ -1383,23 +1394,23 @@ mod tests { use raftstore::{ errors::{DiscardReason, Error as RaftStoreError}, router::{CdcRaftRouter, RaftStoreRouter}, - store::{fsm::StoreMeta, msg::CasualMessage, PeerMsg, ReadDelegate}, + store::{PeerMsg, ReadDelegate, fsm::StoreMeta, msg::CasualMessage}, }; use test_pd_client::TestPdClient; use test_raftstore::MockRaftStoreRouter; use tikv::{ server::DEFAULT_CLUSTER_ID, - storage::{kv::Engine, TestEngineBuilder}, + storage::{TestEngineBuilder, kv::Engine}, }; use tikv_util::{ config::{ReadableDuration, ReadableSize}, - worker::{dummy_scheduler, ReceiverWrapper}, + worker::{ReceiverWrapper, dummy_scheduler}, }; use super::*; use crate::{ channel, - delegate::{post_init_downstream, ObservedRange}, + delegate::{ObservedRange, post_init_downstream}, recv_timeout, }; diff --git a/components/cdc/src/initializer.rs b/components/cdc/src/initializer.rs index 7017cf36ba3..f575ef3fab4 100644 --- a/components/cdc/src/initializer.rs +++ b/components/cdc/src/initializer.rs @@ -2,18 +2,19 @@ use std::{ collections::BTreeMap, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, time::Duration, }; use api_version::ApiV2; use crossbeam::atomic::AtomicCell; -use engine_rocks::{ReadPerfContext, ReadPerfInstant, PROP_MAX_TS}; +use engine_rocks::{PROP_MAX_TS, ReadPerfContext, ReadPerfInstant}; use engine_traits::{ - IterOptions, KvEngine, Range, Snapshot as EngineSnapshot, TablePropertiesCollection, - TablePropertiesExt, UserCollectedProperties, CF_DEFAULT, CF_WRITE, DATA_KEY_PREFIX_LEN, + CF_DEFAULT, CF_WRITE, DATA_KEY_PREFIX_LEN, IterOptions, KvEngine, Range, + Snapshot as EngineSnapshot, TableProperties, TablePropertiesCollection, + UserCollectedProperties, }; use fail::fail_point; use keys::{data_end_key, data_key}; @@ -31,36 +32,35 @@ use raftstore::{ }, }; use tikv::storage::{ + Statistics, kv::Snapshot, mvcc::{DeltaScanner, MvccReader, ScannerBuilder}, raw::raw_mvcc::{RawMvccIterator, RawMvccSnapshot}, txn::{TxnEntry, TxnEntryScanner}, - Statistics, }; use tikv_kv::{Iterator, ScanMode}; use tikv_util::{ - box_err, + Either, box_err, codec::number, debug, defer, error, info, - sys::inspector::{self_thread_inspector, ThreadInspector}, - time::{duration_to_sec, Instant, Limiter}, + sys::inspector::{ThreadInspector, self_thread_inspector}, + time::{Instant, Limiter, duration_to_sec}, warn, worker::Scheduler, - Either, }; use tokio::sync::Semaphore; use txn_types::{Key, KvPair, LockType, OldValue, TimeStamp}; use crate::{ + Error, Result, Task, channel::CdcEvent, delegate::{ - post_init_downstream, Delegate, DownstreamId, DownstreamState, MiniLock, ObservedRange, + Delegate, DownstreamId, DownstreamState, MiniLock, ObservedRange, post_init_downstream, }, endpoint::Deregister, metrics::*, - old_value::{near_seek_old_value, OldValueCursors}, + old_value::{OldValueCursors, near_seek_old_value}, service::{ConnId, RequestId}, - Error, Result, Task, }; #[derive(Copy, Clone, Debug, Default)] @@ -523,7 +523,7 @@ impl Initializer { .send_all(events, self.scan_truncated.clone()) .await { - error!("cdc send scan event failed"; "req_id" => ?self.request_id); + warn!("cdc send scan event failed"; "err" => ?e, "req_id" => ?self.request_id); return Err(Error::Sink(e)); } @@ -606,12 +606,16 @@ impl Initializer { let hint_min_ts = self.checkpoint_ts.into_inner(); let (mut total_count, mut filtered_count, mut tables) = (0, 0, 0); - collection.iter_user_collected_properties(|prop| { + collection.iter_table_properties(|table_prop| { + let prop = table_prop.get_user_collected_properties(); tables += 1; if let Some((_, keys)) = prop.approximate_size_and_keys(&start_key, &end_key) { total_count += keys; - if Self::parse_u64_prop(prop, PROP_MAX_TS) - .map_or(false, |max_ts| max_ts < hint_min_ts) + + if prop + .get(PROP_MAX_TS.as_bytes()) + .and_then(|mut x| number::decode_u64(&mut x).ok()) + .is_some_and(|max_ts| max_ts < hint_min_ts) { filtered_count += keys; } @@ -629,14 +633,6 @@ impl Initializer { "tables" => tables); use_ts_filter } - - fn parse_u64_prop( - prop: &<::TablePropertiesCollection as TablePropertiesCollection>::UserCollectedProperties, - field: &str, - ) -> Option { - prop.get(field.as_bytes()) - .and_then(|mut x| number::decode_u64(&mut x).ok()) - } } #[cfg(test)] @@ -645,18 +641,18 @@ mod tests { collections::BTreeMap, fmt::Display, sync::{ - atomic::AtomicBool, - mpsc::{channel, sync_channel, Receiver, RecvTimeoutError, Sender}, Arc, + atomic::AtomicBool, + mpsc::{Receiver, RecvTimeoutError, Sender, channel, sync_channel}, }, time::Duration, }; use engine_rocks::{BlobRunMode, RocksEngine}; - use engine_traits::{MiscExt, CF_WRITE}; - use futures::{executor::block_on, StreamExt}; + use engine_traits::{CF_WRITE, MiscExt}; + use futures::{StreamExt, executor::block_on}; use kvproto::{ - cdcpb::{EventLogType, Event_oneof_event}, + cdcpb::{Event_oneof_event, EventLogType}, errorpb::Error as ErrorHeader, }; use raftstore::{coprocessor::ObserveHandle, router::CdcRaftRouter}; @@ -664,12 +660,12 @@ mod tests { use tikv::{ config::DbConfig, storage::{ + TestEngineBuilder, kv::Engine, txn::tests::{ must_acquire_pessimistic_lock, must_commit, must_prewrite_delete, must_prewrite_put, must_prewrite_put_with_txn_soucre, }, - TestEngineBuilder, }, }; use tikv_util::{ diff --git a/components/cdc/src/lib.rs b/components/cdc/src/lib.rs index 64f110f5c45..3498fbdba00 100644 --- a/components/cdc/src/lib.rs +++ b/components/cdc/src/lib.rs @@ -15,7 +15,7 @@ mod old_value; mod service; mod txn_source; -pub use channel::{recv_timeout, CdcEvent}; +pub use channel::{CdcEvent, recv_timeout}; pub use config::CdcConfigManager; pub use delegate::Delegate; pub use endpoint::{CdcTxnExtraScheduler, Endpoint, Task, Validate}; diff --git a/components/cdc/src/metrics.rs b/components/cdc/src/metrics.rs index de13f29fa44..49df95533dc 100644 --- a/components/cdc/src/metrics.rs +++ b/components/cdc/src/metrics.rs @@ -236,6 +236,11 @@ lazy_static! { exponential_buckets(0.01, 2.0, 17).unwrap(), ) .unwrap(); + + pub static ref CDC_ABORTED_CONNECTIONS: IntCounter = register_int_counter!( + "tikv_cdc_aborted_connections", + "Total number of aborted connections" + ).unwrap(); } thread_local! { diff --git a/components/cdc/src/observer.rs b/components/cdc/src/observer.rs index de898a8ae72..7a3e0d63685 100644 --- a/components/cdc/src/observer.rs +++ b/components/cdc/src/observer.rs @@ -7,14 +7,14 @@ use engine_traits::KvEngine; use fail::fail_point; use kvproto::metapb::{Peer, Region}; use raft::StateRole; -use raftstore::{coprocessor::*, store::RegionSnapshot, Error as RaftStoreError}; +use raftstore::{Error as RaftStoreError, coprocessor::*, store::RegionSnapshot}; use tikv::storage::Statistics; use tikv_util::{error, memory::MemoryQuota, warn, worker::Scheduler}; use crate::{ + Error as CdcError, endpoint::{Deregister, Task}, old_value::{self, OldValueCache}, - Error as CdcError, }; /// An Observer for CDC. diff --git a/components/cdc/src/old_value.rs b/components/cdc/src/old_value.rs index 1ab5a3a7510..bbb5de229a6 100644 --- a/components/cdc/src/old_value.rs +++ b/components/cdc/src/old_value.rs @@ -2,22 +2,22 @@ use std::ops::{Bound, Deref}; -use engine_traits::{ReadOptions, CF_DEFAULT, CF_WRITE}; +use engine_traits::{CF_DEFAULT, CF_WRITE, ReadOptions}; use getset::CopyGetters; use tikv::storage::{ - mvcc::near_load_data_by_write, Cursor, CursorBuilder, ScanMode, Snapshot as EngineSnapshot, - Statistics, + Cursor, CursorBuilder, ScanMode, Snapshot as EngineSnapshot, Statistics, + mvcc::near_load_data_by_write, }; use tikv_kv::Snapshot; use tikv_util::{ + Either, config::ReadableSize, lru::{LruCache, SizePolicy}, time::Instant, - Either, }; use txn_types::{Key, MutationType, OldValue, TimeStamp, Value, WriteRef, WriteType}; -use crate::{metrics::*, Result}; +use crate::{Result, metrics::*}; pub(crate) type OldValueCallback = Box< dyn Fn(Key, TimeStamp, &mut OldValueCache, &mut Statistics) -> Result>> + Send, @@ -534,7 +534,10 @@ mod tests { let mut default_cursor = new_old_value_cursor(&snapshot, CF_DEFAULT); let mut load_default = |use_default_cursor: bool| { if use_default_cursor { - let x = unsafe { std::mem::transmute::<_, &'static mut _>(&mut default_cursor) }; + let x = unsafe { + #[allow(clippy::missing_transmute_annotations)] + std::mem::transmute::<_, &'static mut _>(&mut default_cursor) + }; Either::Right(x) } else { Either::Left(&snapshot) @@ -548,7 +551,7 @@ mod tests { let key = Key::from_raw(&raw_key).append_ts(150.into()); let ld = load_default(use_default_cursor); let v = near_seek_old_value(&key, &mut cursor, ld, &mut stats).unwrap(); - assert!(v.map_or(false, |x| x == value())); + assert!(v.is_some_and(|x| x == value())); } assert_eq!(stats.write.seek, 1); assert_eq!(stats.write.next, 58); @@ -567,7 +570,7 @@ mod tests { let key = Key::from_raw(&raw_key).append_ts(150.into()); let ld = load_default(use_default_cursor); let v = near_seek_old_value(&key, &mut cursor, ld, &mut stats).unwrap(); - assert!(v.map_or(false, |x| x == value())); + assert!(v.is_some_and(|x| x == value())); } assert_eq!(stats.write.seek, 2); assert_eq!(stats.write.next, 144); diff --git a/components/cdc/src/service.rs b/components/cdc/src/service.rs index 6f1a7c08d08..c41c30c51a7 100644 --- a/components/cdc/src/service.rs +++ b/components/cdc/src/service.rs @@ -1,31 +1,44 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. -use std::sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, +use std::{ + sync::{ + Arc, + atomic::{AtomicUsize, Ordering}, + }, + time::{Duration, Instant}, }; use collections::{HashMap, HashMapEntry}; use crossbeam::atomic::AtomicCell; -use futures::stream::TryStreamExt; +use futures::{ + compat::Stream01CompatExt, + stream::{StreamExt, TryStreamExt}, +}; use grpcio::{DuplexSink, RequestStream, RpcContext, RpcStatus, RpcStatusCode}; use kvproto::{ cdcpb::{ - ChangeData, ChangeDataEvent, ChangeDataRequest, ChangeDataRequestKvApi, - ChangeDataRequest_oneof_request, + ChangeData, ChangeDataEvent, ChangeDataRequest, ChangeDataRequest_oneof_request, + ChangeDataRequestKvApi, }, kvrpcpb::ApiVersion, }; -use tikv_util::{error, info, memory::MemoryQuota, warn, worker::*}; +use tikv_util::{error, info, memory::MemoryQuota, timer::GLOBAL_TIMER_HANDLE, warn, worker::*}; use crate::{ - channel::{channel, Sink, CDC_CHANNLE_CAPACITY}, + channel::{CDC_CHANNLE_CAPACITY, Sink, channel}, delegate::{Downstream, DownstreamId, DownstreamState, ObservedRange}, endpoint::{Deregister, Task}, + metrics::CDC_ABORTED_CONNECTIONS, }; static CONNECTION_ID_ALLOC: AtomicUsize = AtomicUsize::new(0); +// CDC connection monitoring constants in seconds +const CDC_WATCHDOG_CHECK_INTERVAL_SECS: u64 = 2; +const CDC_IDLE_WARNING_THRESHOLD_SECS: u64 = 60; +const CDC_IDLE_DEREGISTER_THRESHOLD_SECS: u64 = 60 * 20; // 20 minutes +const CDC_MEMORY_QUOTA_ABORT_THRESHOLD: f64 = 0.999; + pub fn validate_kv_api(kv_api: ChangeDataRequestKvApi, api_version: ApiVersion) -> bool { kv_api == ChangeDataRequestKvApi::TiDb || (kv_api == ChangeDataRequestKvApi::RawKv && api_version == ApiVersion::V2) @@ -248,16 +261,22 @@ impl EventFeedHeaders { pub struct Service { scheduler: Scheduler, memory_quota: Arc, + pool: Arc, } impl Service { /// Create a ChangeData service. /// /// It requires a scheduler of an `Endpoint` in order to schedule tasks. - pub fn new(scheduler: Scheduler, memory_quota: Arc) -> Service { + pub fn new( + scheduler: Scheduler, + memory_quota: Arc, + pool: Arc, + ) -> Service { Service { scheduler, memory_quota, + pool, } } @@ -428,7 +447,8 @@ impl Service { }; explicit_features = headers.features; } - info!("cdc connection created"; "downstream" => ctx.peer(), "features" => ?explicit_features); + info!("cdc connection created"; "downstream" => ctx.peer(), + "conn_id" => ?conn_id,"features" => ?explicit_features); if let Err(e) = self.scheduler.schedule(Task::OpenConn { conn }) { let peer = ctx.peer(); @@ -473,14 +493,125 @@ impl Service { } }); + let last_flush_time = Arc::new(AtomicCell::new(Instant::now())); + let last_flush_time_for_forward = last_flush_time.clone(); + let last_flush_time_for_watchdog = last_flush_time.clone(); + let peer_for_watchdog = ctx.peer().to_string(); + let peer = ctx.peer(); + let (cancel_tx, mut cancel_rx) = tokio::sync::oneshot::channel::<()>(); + + // Create cancelCh for eventDrain.forward exit signal + let (forward_exit_tx, forward_exit_rx) = tokio::sync::oneshot::channel::<()>(); + ctx.spawn(async move { #[cfg(feature = "failpoints")] sleep_before_drain_change_event().await; - if let Err(e) = event_drain.forward(&mut sink).await { - warn!("cdc send failed"; "error" => ?e, "downstream" => peer, "conn_id" => ?conn_id); - } else { - info!("cdc send closed"; "downstream" => peer, "conn_id" => ?conn_id); + tokio::select! { + _ = &mut cancel_rx => { + warn!("cdc send cancelled"; "downstream" => peer, "conn_id" => ?conn_id); + let status = RpcStatus::with_message(RpcStatusCode::UNKNOWN, "connection cancelled".to_string()); + let _ = sink.fail(status).await; + CDC_ABORTED_CONNECTIONS.inc(); + } + result = event_drain.forward(&mut sink, Some(&last_flush_time_for_forward)) => { + if let Err(e) = result { + warn!("cdc send failed"; "error" => ?e, "downstream" => peer, "conn_id" => ?conn_id); + } else { + info!("cdc send closed"; "downstream" => peer, "conn_id" => ?conn_id); + } + // Send signal when eventDrain.forward exits + let _ = forward_exit_tx.send(()); + } + } + }); + + // Start watchdog to monitor connection activity + Self::start_connection_watchdog( + self.pool.clone(), + last_flush_time_for_watchdog.clone(), + peer_for_watchdog.clone(), + conn_id, + cancel_tx, + forward_exit_rx, + self.memory_quota.clone(), + ); + } + + /// Start a watchdog to monitor CDC connection activity. + /// + /// This function creates a background task that periodically checks if the + /// connection has been idle for too long and takes appropriate action + /// (warning or aborting). + fn start_connection_watchdog( + pool: Arc, + last_flush_time: Arc>, + peer: String, + conn_id: ConnId, + cancel_tx: tokio::sync::oneshot::Sender<()>, + mut forward_exit_rx: tokio::sync::oneshot::Receiver<()>, + memory_quota: Arc, + ) { + let last_flush_time_clone = last_flush_time.clone(); + let peer_clone = peer.clone(); + + // Create a custom interval task that can be stopped + let _ = pool.pool().spawn(async move { + let mut interval = GLOBAL_TIMER_HANDLE + .interval( + Instant::now(), + Duration::from_secs(CDC_WATCHDOG_CHECK_INTERVAL_SECS), + ) + .compat(); + + loop { + tokio::select! { + _ = &mut forward_exit_rx => { + info!("cdc connection forward exit signal received, stopping watchdog"); + break; + } + _ = interval.next() => { + let elapsed = last_flush_time_clone.load().elapsed(); + + // Check if last flush was more than the warning threshold + if elapsed > Duration::from_secs(CDC_IDLE_WARNING_THRESHOLD_SECS) { + warn!("cdc connection idle too long"; + "downstream" => peer_clone.clone(), + "conn_id" => ?conn_id, + "seconds_since_last_flush" => elapsed.as_secs()); + } + + let _idle_threshold = CDC_IDLE_DEREGISTER_THRESHOLD_SECS; + + #[cfg(feature = "failpoints")] + let _idle_threshold = { + let should_adjust = || { + fail::fail_point!("cdc_idle_deregister_threshold", |_| true); + false + }; + if should_adjust() { + 5 + } else { + CDC_IDLE_DEREGISTER_THRESHOLD_SECS + } + }; + + // Check if last flush was more than the deregister threshold + // To prevent the case that the connection idle since there are a lot of + // incremental scan tasks queueing so won't send events, also check on the + // memory usage, if the memory quota is almost used up, we abort the connection. + if elapsed > Duration::from_secs(_idle_threshold) + && memory_quota.used_ratio() >= CDC_MEMORY_QUOTA_ABORT_THRESHOLD { + error!("cdc connection idle for too long, aborting connection"; + "downstream" => peer_clone.clone(), + "conn_id" => ?conn_id, + "seconds_since_last_flush" => elapsed.as_secs()); + // Cancel the gRPC connection + let _ = cancel_tx.send(()); + break; + } + } + } } }); } @@ -526,18 +657,19 @@ async fn sleep_before_drain_change_event() { mod tests { use std::{sync::Arc, time::Duration}; - use futures::{executor::block_on, SinkExt}; + use futures::{SinkExt, executor::block_on}; use grpcio::{self, ChannelBuilder, EnvBuilder, Server, ServerBuilder, WriteFlags}; - use kvproto::cdcpb::{create_change_data, ChangeDataClient, ResolvedTs}; + use kvproto::cdcpb::{ChangeDataClient, ResolvedTs, create_change_data}; use tikv_util::future::block_on_timeout; use super::*; - use crate::channel::{recv_timeout, CdcEvent}; + use crate::channel::{CdcEvent, recv_timeout}; fn new_rpc_suite(capacity: usize) -> (Server, ChangeDataClient, ReceiverWrapper) { let memory_quota = Arc::new(MemoryQuota::new(capacity)); + let pool = Arc::new(Builder::new("cdc-watchdog-test").thread_count(1).create()); let (scheduler, rx) = dummy_scheduler(); - let cdc_service = Service::new(scheduler, memory_quota); + let cdc_service = Service::new(scheduler, memory_quota, pool); let env = Arc::new(EnvBuilder::new().build()); let builder = ServerBuilder::new(env.clone()).register_service(create_change_data(cdc_service)); diff --git a/components/cdc/tests/failpoints/test_endpoint.rs b/components/cdc/tests/failpoints/test_endpoint.rs index 018946fd89b..84c4b0b56cc 100644 --- a/components/cdc/tests/failpoints/test_endpoint.rs +++ b/components/cdc/tests/failpoints/test_endpoint.rs @@ -1,23 +1,23 @@ // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. use std::{ - sync::{mpsc, Arc}, + sync::{Arc, mpsc}, thread, time::{Duration, Instant}, }; -use api_version::{test_kv_format_impl, KvFormat}; +use api_version::{KvFormat, test_kv_format_impl}; use causal_ts::CausalTsProvider; -use cdc::{recv_timeout, Delegate, OldValueCache, Task, Validate}; +use cdc::{Delegate, OldValueCache, Task, Validate, recv_timeout}; use futures::{executor::block_on, sink::SinkExt}; use grpcio::{ChannelBuilder, Environment, WriteFlags}; use kvproto::{cdcpb::*, kvrpcpb::*, tikvpb_grpc::TikvClient}; use pd_client::PdClient; use test_raftstore::*; -use tikv_util::{debug, worker::Scheduler, HandyRwLock}; +use tikv_util::{HandyRwLock, debug, worker::Scheduler}; use txn_types::{Key, TimeStamp}; -use crate::{new_event_feed, new_event_feed_v2, ClientReceiver, TestSuite, TestSuiteBuilder}; +use crate::{ClientReceiver, TestSuite, TestSuiteBuilder, new_event_feed, new_event_feed_v2}; #[test] fn test_cdc_double_scan_deregister() { @@ -811,3 +811,94 @@ fn test_cdc_unresolved_region_count_before_finish_scan_lock() { } suite.stop(); } + +#[test] +fn test_cdc_watchdog_idle_timeout() { + let cluster = new_server_cluster(0, 1); + cluster.pd_client.disable_default_operator(); + let mut suite = TestSuiteBuilder::new().cluster(cluster).build(); + let region = suite.cluster.get_region(b""); + + // Enable failpoints to control the watchdog behavior + // cdc_idle_deregister_threshold will make the threshold 20 seconds instead of + // 20 minutes cdc_sleep_after_sink_flush will make the sink sleep for 30 + // seconds after each flush + fail::cfg("cdc_idle_deregister_threshold", "return(true)").unwrap(); + fail::cfg("cdc_sleep_after_sink_flush", "return(true)").unwrap(); // Remove the "1*" to make it trigger continuously + + // Create event feed connection + let (mut req_tx, event_feed, _) = new_event_feed(suite.get_region_cdc_client(region.id)); + let mut req = suite.new_changedata_request(region.id); + req.mut_header().set_ticdc_version("7.5.0".into()); + block_on(req_tx.send((req, WriteFlags::default()))).unwrap(); + + // Wait for the connection to be established and initialized + thread::sleep(Duration::from_millis(1000)); + + debug!("Starting watchdog test - waiting for connection to be cancelled"); + + // Wait for the watchdog to trigger and cancel the connection + // The watchdog should trigger after 5 seconds due to + // cdc_idle_deregister_threshold failpoint and cdc_sleep_after_sink_flush + // failpoint will make the sink sleep for 6 seconds + thread::sleep(Duration::from_secs(6)); + + debug!("Finished waiting, now checking if connection was cancelled"); + + // Try to detect if the connection was cancelled by watchdog + // We can do this by trying to receive from the underlying receiver + // If the connection is closed, recv_timeout should return an error + let mut connection_cancelled = false; + let start_time = Instant::now(); + + // Try to detect connection closure for up to 5 seconds (shorter timeout for + // testing) + while start_time.elapsed() < Duration::from_secs(5) { + // Get the underlying receiver + let mut rx = event_feed.replace(None).unwrap(); + + // Try to receive with a short timeout + match recv_timeout(&mut rx, Duration::from_millis(100)) { + Ok(Some(Ok(_))) => { + // Still receiving data, connection is alive + debug!("Connection still alive, received data"); + // Put the receiver back + event_feed.replace(Some(rx)); + } + Ok(Some(Err(_))) => { + // Received an error, connection was cancelled + debug!("Connection cancelled with error"); + connection_cancelled = true; + break; + } + Ok(None) => { + // No data available, but connection might still be alive + debug!("No data available, connection might still be alive"); + // Put the receiver back + event_feed.replace(Some(rx)); + } + Err(_) => { + // Connection is closed + debug!("Connection closed"); + connection_cancelled = true; + break; + } + } + + // Small delay before next check + thread::sleep(Duration::from_millis(100)); + } + + // Verify that the connection was cancelled due to watchdog timeout + assert!( + connection_cancelled, + "Connection should have been cancelled by watchdog after idle timeout" + ); + + // Clean up + fail::remove("cdc_idle_deregister_threshold"); + fail::remove("cdc_sleep_after_sink_flush"); + + drop(event_feed); + suite.stop(); +} diff --git a/components/cdc/tests/failpoints/test_memory_quota.rs b/components/cdc/tests/failpoints/test_memory_quota.rs index 3d331deda3d..07184993336 100644 --- a/components/cdc/tests/failpoints/test_memory_quota.rs +++ b/components/cdc/tests/failpoints/test_memory_quota.rs @@ -3,13 +3,13 @@ use std::{sync::*, time::Duration}; use cdc::{Task, Validate}; -use futures::{executor::block_on, SinkExt}; +use futures::{SinkExt, executor::block_on}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*}; use pd_client::PdClient; use test_raftstore::*; -use crate::{new_event_feed, TestSuiteBuilder}; +use crate::{TestSuiteBuilder, new_event_feed}; #[test] fn test_resolver_track_lock_memory_quota_exceeded() { diff --git a/components/cdc/tests/failpoints/test_observe.rs b/components/cdc/tests/failpoints/test_observe.rs index 4a34185de76..1b350fe3493 100644 --- a/components/cdc/tests/failpoints/test_observe.rs +++ b/components/cdc/tests/failpoints/test_observe.rs @@ -2,22 +2,23 @@ use std::{ sync::{ + Arc, atomic::{AtomicBool, Ordering}, - mpsc, Arc, + mpsc, }, time::Duration, }; -use api_version::{test_kv_format_impl, KvFormat}; +use api_version::{KvFormat, test_kv_format_impl}; use futures::{executor::block_on, sink::SinkExt}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*, raft_serverpb::RaftMessage}; use pd_client::PdClient; use raft::eraftpb::MessageType; use test_raftstore::*; -use tikv_util::{config::ReadableDuration, HandyRwLock}; +use tikv_util::{HandyRwLock, config::ReadableDuration}; -use crate::{new_event_feed, TestSuite, TestSuiteBuilder}; +use crate::{TestSuite, TestSuiteBuilder, new_event_feed}; #[test] fn test_observe_duplicate_cmd() { diff --git a/components/cdc/tests/failpoints/test_register.rs b/components/cdc/tests/failpoints/test_register.rs index 2128dff08e1..0ad85de1a6b 100644 --- a/components/cdc/tests/failpoints/test_register.rs +++ b/components/cdc/tests/failpoints/test_register.rs @@ -1,7 +1,7 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. use std::{thread, time::Duration}; -use api_version::{test_kv_format_impl, KvFormat}; +use api_version::{KvFormat, test_kv_format_impl}; use futures::{executor::block_on, sink::SinkExt}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*, metapb::RegionEpoch}; @@ -10,7 +10,7 @@ use raft::StateRole; use raftstore::coprocessor::{ObserverContext, RoleChange, RoleObserver}; use test_raftstore::sleep_ms; -use crate::{new_event_feed, TestSuite}; +use crate::{TestSuite, new_event_feed}; #[test] fn test_failed_pending_batch() { diff --git a/components/cdc/tests/failpoints/test_resolve.rs b/components/cdc/tests/failpoints/test_resolve.rs index 560eb68ba44..6f1e63f2d6c 100644 --- a/components/cdc/tests/failpoints/test_resolve.rs +++ b/components/cdc/tests/failpoints/test_resolve.rs @@ -1,7 +1,7 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. use std::time::Duration; -use api_version::{test_kv_format_impl, KvFormat}; +use api_version::{KvFormat, test_kv_format_impl}; use futures::{executor::block_on, sink::SinkExt}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*}; @@ -10,7 +10,7 @@ use raft::eraftpb::ConfChangeType; use test_raftstore::*; use tikv_util::config::*; -use crate::{new_event_feed, TestSuite, TestSuiteBuilder}; +use crate::{TestSuite, TestSuiteBuilder, new_event_feed}; #[test] fn test_stale_resolver() { diff --git a/components/cdc/tests/integrations/test_cdc.rs b/components/cdc/tests/integrations/test_cdc.rs index c89bdcbb55a..942c41ce3e4 100644 --- a/components/cdc/tests/integrations/test_cdc.rs +++ b/components/cdc/tests/integrations/test_cdc.rs @@ -2,20 +2,20 @@ use std::{sync::*, time::Duration}; -use api_version::{test_kv_format_impl, KvFormat}; -use cdc::{metrics::CDC_RESOLVED_TS_ADVANCE_METHOD, Task, Validate}; +use api_version::{KvFormat, test_kv_format_impl}; +use cdc::{Task, Validate, metrics::CDC_RESOLVED_TS_ADVANCE_METHOD}; use concurrency_manager::ConcurrencyManager; -use futures::{executor::block_on, SinkExt}; +use futures::{SinkExt, executor::block_on}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*}; use pd_client::PdClient; use raft::eraftpb::MessageType; use test_raftstore::*; use tikv::server::DEFAULT_CLUSTER_ID; -use tikv_util::{config::ReadableDuration, HandyRwLock}; +use tikv_util::{HandyRwLock, config::ReadableDuration, debug, error}; use txn_types::{Key, Lock, LockType, TimeStamp}; -use crate::{new_event_feed, new_event_feed_v2, TestSuite, TestSuiteBuilder}; +use crate::{TestSuite, TestSuiteBuilder, new_event_feed, new_event_feed_v2}; #[test] fn test_cdc_basic() { @@ -2906,3 +2906,313 @@ fn test_cdc_pessimistic_lock_unlock() { suite.must_release_pessimistic_lock(rid, k.clone(), start_tso, for_update_tso); std::thread::sleep(Duration::from_millis(500)); } + +#[test] +fn test_cdc_overlapped_write_bug() { + // This test is to verify the overlapped write bug (#18498). + let cluster = new_server_cluster(1, 1); + let mut suite = TestSuiteBuilder::new().cluster(cluster).build(); + let region = suite.cluster.get_region(&[]); + let region_id = region.get_id(); + + debug!("region:"; "region_id" => region_id); + + let test_key = b"test_key"; + let primary_key_t2 = b"t2_primary"; // t2's primary (different from test_key) + let value1 = b"value1"; + let value2 = b"value2"; + let value3 = b"value3"; + + // Phase 1: t1 prewrites and commits test_key + // CRITICAL: We need t2's start_ts to equal t1's commit_ts for overlapped write + // detection! + let t1_start_ts = block_on(suite.cluster.pd_client.get_tso()).unwrap(); + debug!("t1:"; "start_ts" => t1_start_ts); + + let mut mutation1 = Mutation::default(); + mutation1.set_op(Op::Put); + mutation1.set_key(test_key.to_vec()); + mutation1.set_value(value1.to_vec()); + + suite.must_kv_prewrite(region_id, vec![mutation1], test_key.to_vec(), t1_start_ts); + // t1: Prewrite completed + + // Get t1's commit_ts, which will become t2's start_ts + let t1_commit_ts = block_on(suite.cluster.pd_client.get_tso()).unwrap(); + let mut commit_req = CommitRequest::default(); + commit_req.set_context(suite.get_context(region_id)); + commit_req.set_start_version(t1_start_ts.into_inner()); + commit_req.set_keys(vec![test_key.to_vec()].into()); + commit_req.set_commit_version(t1_commit_ts.into_inner()); + + suite + .get_tikv_client(region_id) + .kv_commit(&commit_req) + .unwrap(); + debug!("t1:"; "commit_ts" => t1_commit_ts); + // CF_WRITE now has t1's committed write + + // Set up CDC AFTER t1 commits + let req = suite.new_changedata_request(region_id); + let (mut req_tx, event_feed_wrap, receive_event) = + new_event_feed(suite.get_region_cdc_client(region_id)); + block_on(req_tx.send((req.clone(), WriteFlags::default()))).unwrap(); + + let events = receive_event(false).events.to_vec(); + debug!("cdc: initialized with "; "events" => events.len()); + + // Wait for stream to be registered + let scheduler = suite.endpoints.values().next().unwrap().scheduler(); + let (tx, rx) = mpsc::channel(); + scheduler + .schedule(Task::Validate(Validate::Region( + region_id, + Box::new(move |delegate| { + if let Some(d) = delegate { + assert_eq!(d.downstreams().len(), 1); + } + tx.send(()).unwrap(); + }), + ))) + .unwrap(); + rx.recv_timeout(Duration::from_secs(1)).unwrap(); + + // Phase 2: t2 prewrites test_key as a SECONDARY key + // CRITICAL: Use t1's commit_ts as t2's start_ts to trigger overlapped write! + let t2_start_ts = t1_commit_ts; // This is the key: start_ts == commit_ts of t1! + debug!("t2: start_ts is the same as t1's commit_ts!"; "start_ts" => t2_start_ts); + // t2: primary_key is different from the test_key + + // Prewrite both primary and secondary + let mut mutation_t2_primary = Mutation::default(); + mutation_t2_primary.set_op(Op::Put); + mutation_t2_primary.set_key(primary_key_t2.to_vec()); + mutation_t2_primary.set_value(value2.to_vec()); + + let mut mutation_t2_secondary = Mutation::default(); + mutation_t2_secondary.set_op(Op::Put); + mutation_t2_secondary.set_key(test_key.to_vec()); + mutation_t2_secondary.set_value(value2.to_vec()); + + // Prewrite with primary_key_t2 as primary + suite.must_kv_prewrite( + region_id, + vec![mutation_t2_primary, mutation_t2_secondary], + primary_key_t2.to_vec(), + t2_start_ts, + ); + // t2: Prewrite completed + debug!("cf_lock now has t2's lock"; "test_key" => t2_start_ts); + debug!("cdc should call push_lock for t2"); + + // Wait for t2 prewrite events to be received + let mut t2_prewrite_received = false; + for _ in 0..5 { + let events = receive_event(true).events.to_vec(); + for event in events { + if let Some(Event_oneof_event::Entries(entries)) = event.event { + for entry in &entries.entries { + if entry.get_type() == EventLogType::Prewrite + && entry.start_ts == t2_start_ts.into_inner() + { + t2_prewrite_received = true; + break; + } + } + } + } + if t2_prewrite_received { + break; + } + } + + // Phase 3: t2 rolls back ONLY the secondary key (test_key) + let ctx = suite.get_context(region_id); + let tikv_client = suite.get_tikv_client(region_id); + + let mut rollback_req = BatchRollbackRequest::default(); + rollback_req.set_context(ctx.clone()); + rollback_req.set_keys(vec![test_key.to_vec()].into()); // Only rollback test_key + rollback_req.set_start_version(t2_start_ts.into_inner()); + + tikv_client.kv_batch_rollback(&rollback_req).unwrap(); + // t2: Rollback completed on test_key (secondary) + debug!("get_txn_commit_record finds t1's write where"; "commit_ts" => t1_commit_ts, "== t2's start_ts" => t2_start_ts); + // get_txn_commit_record returns overlapped_write! + // test_key is NOT t2's primary → protected=false + // make_rollback(protected=false, overlapped_write=Some) returns None + // NO CF_WRITE ENTRY! + // Only DELETE from CF_LOCK (CDC ignores this) + // CDC's lock_tracker still has t2's lock (stale) + + // Phase 4: t3 prewrites test_key + // This will trigger resolve_lock to clean up t2's stale lock + let t3_start_ts = block_on(suite.cluster.pd_client.get_tso()).unwrap(); + debug!("t3:"; "start_ts" => t3_start_ts); + debug!("note:"; "t2's start_ts" => t2_start_ts, "t3's start_ts" => t3_start_ts); + + let mut mutation3 = Mutation::default(); + mutation3.set_op(Op::Put); + mutation3.set_key(test_key.to_vec()); + mutation3.set_value(value3.to_vec()); + + // t3: Attempting prewrite... + // Will encounter t2's stale lock in CF_LOCK + // Triggers resolve_lock_lite to clean it up + // resolve_lock removes lock from CF_LOCK (no CDC notification) + // CDC processes t3's prewrite + debug!("cdc calls push_lock(test_key)"; "start_ts" => t3_start_ts); + debug!("cdc finds t2's stale lock in the lock_tracker"; "start_ts" => t2_start_ts); + // EXPECTED: Assertion failure or warning! + + suite.must_kv_prewrite(region_id, vec![mutation3], test_key.to_vec(), t3_start_ts); + // t3: Prewrite completed + + // Phase 5: Wait for CDC to process t3 prewrite event + let mut t3_prewrite_received = false; + for _ in 0..10 { + let events_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + receive_event(true).events.to_vec() + })); + + if let Ok(events) = events_result { + for event in events { + if let Some(Event_oneof_event::Entries(entries)) = event.event { + for entry in &entries.entries { + if entry.get_type() == EventLogType::Prewrite + && entry.start_ts == t3_start_ts.into_inner() + { + t3_prewrite_received = true; + break; + } + } + } + } + if t3_prewrite_received { + break; + } + } else { + // If panic occurred, break to handle it below + break; + } + } + + // Try to receive events (will panic if assertion fails) + let events = receive_event(true).events.to_vec(); + debug!("cdc:"; "received" => events.len()); + for (i, event) in events.iter().enumerate() { + debug!("event"; "index" => i, "event" => ?event); + } + + // Check delegate status + let scheduler = suite.endpoints.values().next().unwrap().scheduler(); + let (tx, rx) = mpsc::channel(); + scheduler + .schedule(Task::Validate(Validate::Region( + region_id, + Box::new(move |delegate| { + let status = match delegate { + Some(d) => { + if d.has_failed() { + "FAILED".to_string() + } else { + "ACTIVE".to_string() + } + } + None => "REMOVED".to_string(), + }; + tx.send(status).unwrap(); + }), + ))) + .unwrap(); + + match rx.recv_timeout(Duration::from_secs(1)) { + Ok(status) => { + assert_eq!(status, "ACTIVE"); + } + Err(e) => { + error!("Failed to check delegate status"; "error" => ?e); + panic!("Failed to check delegate status"); + } + } + + event_feed_wrap.replace(None); + suite.stop(); +} + +#[test] +fn test_verify_overlapped_write_skips_cf_write() { + // This is a simpler test to verify that rollback indeed skips CF_WRITE + // when there's an overlapped write and the key is not primary + // CRITICAL: Overlapped write requires t2.start_ts == t1.commit_ts + + let cluster = new_server_cluster(1, 1); + let mut suite = TestSuiteBuilder::new().cluster(cluster).build(); + let region = suite.cluster.get_region(&[]); + let region_id = region.get_id(); + + let test_key = b"test_key"; + let primary_key = b"primary_key"; + let value1 = b"value1"; + let value2 = b"value2"; + + // t1: Commit a write + let t1_start_ts = block_on(suite.cluster.pd_client.get_tso()).unwrap(); + let mut mutation1 = Mutation::default(); + mutation1.set_op(Op::Put); + mutation1.set_key(test_key.to_vec()); + mutation1.set_value(value1.to_vec()); + suite.must_kv_prewrite(region_id, vec![mutation1], test_key.to_vec(), t1_start_ts); + + let t1_commit_ts = block_on(suite.cluster.pd_client.get_tso()).unwrap(); + let mut commit_req = CommitRequest::default(); + commit_req.set_context(suite.get_context(region_id)); + commit_req.set_start_version(t1_start_ts.into_inner()); + commit_req.set_keys(vec![test_key.to_vec()].into()); + commit_req.set_commit_version(t1_commit_ts.into_inner()); + suite + .get_tikv_client(region_id) + .kv_commit(&commit_req) + .unwrap(); + + // t2: Prewrite with test_key as SECONDARY (primary is different) + // CRITICAL: Use t1's commit_ts as t2's start_ts! + let t2_start_ts = t1_commit_ts; + let mut mutation_primary = Mutation::default(); + mutation_primary.set_op(Op::Put); + mutation_primary.set_key(primary_key.to_vec()); + mutation_primary.set_value(value2.to_vec()); + + let mut mutation_secondary = Mutation::default(); + mutation_secondary.set_op(Op::Put); + mutation_secondary.set_key(test_key.to_vec()); + mutation_secondary.set_value(value2.to_vec()); + + suite.must_kv_prewrite( + region_id, + vec![mutation_primary, mutation_secondary], + primary_key.to_vec(), + t2_start_ts, + ); + + // t2: Rollback the secondary key + let ctx = suite.get_context(region_id); + let tikv_client = suite.get_tikv_client(region_id); + let mut rollback_req = BatchRollbackRequest::default(); + rollback_req.set_context(ctx); + rollback_req.set_keys(vec![test_key.to_vec()].into()); + rollback_req.set_start_version(t2_start_ts.into_inner()); + + tikv_client.kv_batch_rollback(&rollback_req).unwrap(); + + // t2: Rolled back test_key (secondary) + // Expected behavior: + // - get_txn_commit_record finds: commit_ts={t1_commit_ts} == + // start_ts={t2_start_ts} + // - Overlapped write detected! + // - test_key is NOT primary → protected=false + // - make_rollback(protected=false, overlapped_write=Some) returns None + // - NO CF_WRITE entry created + // If this test passes, the overlapped write behavior is confirmed + suite.stop(); +} diff --git a/components/cdc/tests/integrations/test_flow_control.rs b/components/cdc/tests/integrations/test_flow_control.rs index 77edbcc7e2d..854f4e82ea8 100644 --- a/components/cdc/tests/integrations/test_flow_control.rs +++ b/components/cdc/tests/integrations/test_flow_control.rs @@ -3,13 +3,13 @@ use std::{sync::*, time::Duration}; use cdc::{Task, Validate}; -use futures::{executor::block_on, SinkExt}; +use futures::{SinkExt, executor::block_on}; use grpcio::WriteFlags; use kvproto::{cdcpb::*, kvrpcpb::*}; use pd_client::PdClient; use test_raftstore::*; -use crate::{new_event_feed, TestSuiteBuilder}; +use crate::{TestSuiteBuilder, new_event_feed}; #[test] fn test_cdc_congest() { diff --git a/components/cdc/tests/mod.rs b/components/cdc/tests/mod.rs index 56fa39720ab..e264f52a6be 100644 --- a/components/cdc/tests/mod.rs +++ b/components/cdc/tests/mod.rs @@ -6,7 +6,7 @@ use std::{ }; use causal_ts::CausalTsProvider; -use cdc::{recv_timeout, CdcObserver, Delegate, FeatureGate, Task, Validate}; +use cdc::{CdcObserver, Delegate, FeatureGate, Task, Validate, recv_timeout}; use collections::HashMap; use concurrency_manager::ConcurrencyManager; use engine_rocks::RocksEngine; @@ -16,7 +16,7 @@ use grpcio::{ Environment, MetadataBuilder, }; use kvproto::{ - cdcpb::{create_change_data, ChangeDataClient, ChangeDataEvent, ChangeDataRequest}, + cdcpb::{ChangeDataClient, ChangeDataEvent, ChangeDataRequest, create_change_data}, kvrpcpb::{PrewriteRequestPessimisticAction::*, *}, tikvpb::TikvClient, }; @@ -29,10 +29,10 @@ use tikv::{ storage::kv::LocalTablets, }; use tikv_util::{ + HandyRwLock, config::ReadableDuration, memory::MemoryQuota, - worker::{LazyWorker, Runnable}, - HandyRwLock, + worker::{Builder, LazyWorker, Runnable}, }; use txn_types::TimeStamp; static INIT: Once = Once::new(); @@ -185,11 +185,16 @@ impl TestSuiteBuilder { let memory_quota = Arc::new(MemoryQuota::new(memory_quota)); let memory_quota_ = memory_quota.clone(); let scheduler = worker.scheduler(); + let pool = Arc::new(Builder::new("cdc-watchdog-test").thread_count(1).create()); sim.pending_services .entry(id) .or_default() .push(Box::new(move || { - create_change_data(cdc::Service::new(scheduler.clone(), memory_quota_.clone())) + create_change_data(cdc::Service::new( + scheduler.clone(), + memory_quota_.clone(), + pool.clone(), + )) })); sim.txn_extra_schedulers.insert( id, diff --git a/components/cloud/aws/Cargo.toml b/components/cloud/aws/Cargo.toml index ce7e15d13c4..e985ea50d3d 100644 --- a/components/cloud/aws/Cargo.toml +++ b/components/cloud/aws/Cargo.toml @@ -50,6 +50,7 @@ uuid = { version = "0.8", features = ["v4"] } [dev-dependencies] aws-smithy-runtime = { version = "1.4.0", features = ["test-util", "client"] } +aws-smithy-types = { version = "1", features = ["hyper-0-14-x", "http-body-0-4-x"] } base64 = "0.13" futures = "0.3" tokio = { version = "1.5", features = ["macros"] } diff --git a/components/cloud/aws/src/kms.rs b/components/cloud/aws/src/kms.rs index f877d159778..08bfe67aa81 100644 --- a/components/cloud/aws/src/kms.rs +++ b/components/cloud/aws/src/kms.rs @@ -4,12 +4,12 @@ use std::ops::Deref; use async_trait::async_trait; use aws_config::BehaviorVersion; -use aws_credential_types::provider::{error::CredentialsError, ProvideCredentials}; +use aws_credential_types::provider::{ProvideCredentials, error::CredentialsError}; use aws_sdk_kms::{ + Client, operation::{decrypt::DecryptError, generate_data_key::GenerateDataKeyError}, primitives::Blob, types::DataKeySpec, - Client, }; use aws_sdk_s3::config::HttpClient; use cloud::{ @@ -18,7 +18,7 @@ use cloud::{ }; use futures::executor::block_on; -use crate::util::{self, is_retryable, SdkError}; +use crate::util::{self, SdkError, is_retryable}; const AWS_KMS_DATA_KEY_SPEC: DataKeySpec = DataKeySpec::Aes256; @@ -352,8 +352,8 @@ mod tests { client.assert_requests_match(&[]); } + #[ignore = "no available aws ksm backend for the test env."] #[tokio::test] - #[cfg(FALSE)] // FIXME: enable this (or move this to an integration test) async fn test_aws_kms_localstack() { let config = Config { @@ -365,6 +365,7 @@ mod tests { }, azure: None, gcp: None, + aws: None, }; let creds = diff --git a/components/cloud/aws/src/s3.rs b/components/cloud/aws/src/s3.rs index 0c2092bc2bc..706057df14e 100644 --- a/components/cloud/aws/src/s3.rs +++ b/components/cloud/aws/src/s3.rs @@ -7,41 +7,41 @@ use std::{ }; use async_trait::async_trait; -use aws_config::{sts::AssumeRoleProvider, BehaviorVersion, Region, SdkConfig}; -use aws_credential_types::{provider::ProvideCredentials, Credentials}; +use aws_config::{BehaviorVersion, Region, SdkConfig, sts::AssumeRoleProvider}; +use aws_credential_types::{Credentials, provider::ProvideCredentials}; use aws_sdk_s3::{ - config::HttpClient, + Client, + config::{HttpClient, StalledStreamProtectionConfig}, operation::get_object::GetObjectError, types::{CompletedMultipartUpload, CompletedPart}, - Client, }; use bytes::Bytes; use cloud::{ blob::{ - none_to_empty, BlobConfig, BlobObject, BlobStorage, BucketConf, DeletableStorage, - IterableStorage, PutResource, StringNonEmpty, + BlobConfig, BlobObject, BlobStorage, BucketConf, DeletableStorage, IterableStorage, + PutResource, StringNonEmpty, none_to_empty, }, metrics::CLOUD_REQUEST_HISTOGRAM_VEC, }; use fail::fail_point; use futures::{executor::block_on, stream::Stream}; use futures_util::{ + StreamExt, future::{FutureExt, LocalBoxFuture}, io::{AsyncRead, AsyncReadExt}, stream::TryStreamExt, - StreamExt, }; pub use kvproto::brpb::S3 as InputConfig; use thiserror::Error; use tikv_util::{ debug, - stream::{error_stream, RetryError}, + stream::{RetryError, error_stream}, time::Instant, }; use tokio::time::{sleep, timeout}; use tokio_util::io::ReaderStream; -use crate::util::{self, retry_and_count, SdkError}; +use crate::util::{self, SdkError, retry_and_count}; const CONNECTION_TIMEOUT: Duration = Duration::from_secs(900); pub const STORAGE_VENDOR_NAME_AWS: &str = "aws"; @@ -143,12 +143,9 @@ impl BlobConfig for Config { } fn url(&self) -> io::Result { - self.bucket.url("s3").map_err(|s| { - io::Error::new( - io::ErrorKind::Other, - format!("error creating bucket url: {}", s), - ) - }) + self.bucket + .url("s3") + .map_err(|s| io::Error::other(format!("error creating bucket url: {}", s))) } } @@ -255,8 +252,9 @@ impl S3Storage { let bucket_region = none_to_empty(config.bucket.region.clone()); let bucket_endpoint = none_to_empty(config.bucket.endpoint.clone()); - let mut loader = - aws_config::defaults(BehaviorVersion::latest()).credentials_provider(creds); + let mut loader = aws_config::defaults(BehaviorVersion::latest()) + .stalled_stream_protection(StalledStreamProtectionConfig::disabled()) + .credentials_provider(creds); loader = util::configure_region(loader, &bucket_region)?; loader = util::configure_endpoint(loader, &bucket_endpoint); @@ -775,10 +773,7 @@ impl DeletableStorage for S3Storage { .observe(now.saturating_elapsed().as_secs_f64()); match res { Ok(_) => Ok(()), - Err(e) => Err(io::Error::new( - io::ErrorKind::Other, - format!("failed to delete object {}", e), - )), + Err(e) => Err(io::Error::other(format!("failed to delete object {}", e))), } } .boxed_local() @@ -819,10 +814,7 @@ impl IterableStorage for S3Storage { .unwrap_or_else(|| futures::stream::empty().right_stream()) }) .map_err(|err| { - io::Error::new( - io::ErrorKind::Other, - format!("sdk encounters an unexpected error: {:?}", err), - ) + io::Error::other(format!("sdk encounters an unexpected error: {:?}", err)) }) .try_flatten() .boxed_local() @@ -1145,8 +1137,62 @@ mod tests { client.assert_requests_match(&[]); } + /// Ensures that stalled stream protection does not kick in to kill a + /// rate-limited connection. + /// + /// This test simulates a GetObject response with 7s delay, which will cause + /// a StreamingError(ThroughputBelowMinimum) error if stalled stream + /// protection is enabled. + #[tokio::test] + async fn test_s3_storage_without_stalled_stream_protection() { + let bucket_name = StringNonEmpty::required("mybucket".to_string()).unwrap(); + let mut bucket = BucketConf::default(bucket_name); + bucket.region = StringNonEmpty::opt("ap-southeast-2".to_string()); + bucket.prefix = StringNonEmpty::opt("myprefix".to_string()); + let config = Config::default(bucket); + + let (mut delayed_response_sender, delayed_response_body) = hyper::body::Body::channel(); + let client = StaticReplayClient::new(vec![ + ReplayEvent::new( + http::Request::builder() + .method("GET") + .uri(Uri::from_static( + "https://mybucket.s3.ap-southeast-2.amazonaws.com/myprefix/mykey?x-id=GetObject", + )) + .body(SdkBody::empty()) + .unwrap(), + http::Response::builder() + .status(200) + .body(delayed_response_body.into()) + .unwrap(), + ), + ]); + + let creds = Credentials::from_keys("abc".to_string(), "xyz".to_string(), None); + let s = S3Storage::new_with_creds_client(config.clone(), client.clone(), creds).unwrap(); + + let mut reader = s.get("mykey"); + let mut buf = Vec::new(); + let send_delayed_response_task = tokio::spawn(async move { + // The sleep cannot be less than 6s. We need to ensure the throughput is 0 B/s + // for over 6s to trigger stalled stream protection. + tokio::time::sleep(Duration::from_secs(7)).await; + delayed_response_sender + .send_data("abcd".into()) + .await + .unwrap(); + }); + + let ret = reader.read_to_end(&mut buf).await.unwrap(); + send_delayed_response_task.await.unwrap(); + assert_eq!(ret, 4); + assert_eq!(buf, b"abcd"); + + client.assert_requests_match(&[]); + } + + #[ignore = "s3 test env is unavailable"] #[tokio::test] - #[cfg(FALSE)] // FIXME: enable this (or move this to an integration test) if we've got a // reliable way to test s3 (aws test_util requires custom logic to verify the // body stream which itself can have bug) diff --git a/components/cloud/aws/src/util.rs b/components/cloud/aws/src/util.rs index 8938cdf607b..eb3ff93bb6e 100644 --- a/components/cloud/aws/src/util.rs +++ b/components/cloud/aws/src/util.rs @@ -3,14 +3,14 @@ use std::{error::Error as StdError, io}; use ::aws_smithy_runtime_api::client::orchestrator::HttpResponse; use aws_config::{ + ConfigLoader, Region, default_provider::credentials::DefaultCredentialsChain, environment::EnvironmentVariableRegionProvider, meta::region::{self, ProvideRegion, RegionProviderChain}, profile::ProfileFileRegionProvider, provider_config::ProviderConfig, - ConfigLoader, Region, }; -use aws_credential_types::provider::{error::CredentialsError, ProvideCredentials}; +use aws_credential_types::provider::{ProvideCredentials, error::CredentialsError}; use aws_sdk_kms::config::SharedHttpClient; use aws_sdk_s3::config::HttpClient; use aws_smithy_runtime::client::http::hyper_014::HyperClientBuilder; @@ -19,12 +19,10 @@ use futures::{Future, TryFutureExt}; use hyper::Client; use hyper_tls::HttpsConnector; use tikv_util::{ - stream::{block_on_external_io, retry_ext, RetryError, RetryExt}, + stream::{RetryError, RetryExt, block_on_external_io, retry_ext}, warn, }; -const READ_BUF_SIZE: usize = 1024 * 1024 * 2; - const DEFAULT_REGION: &str = "us-east-1"; pub(crate) type SdkError = @@ -52,8 +50,7 @@ impl RetryError for CredentialsErrorWrapper { } pub fn new_http_client() -> SharedHttpClient { - let mut hyper_builder = Client::builder(); - hyper_builder.http1_read_buf_exact_size(READ_BUF_SIZE); + let hyper_builder = Client::builder(); HyperClientBuilder::new() .hyper_builder(hyper_builder) diff --git a/components/cloud/azure/Cargo.toml b/components/cloud/azure/Cargo.toml index a9aaf2244c6..910c62f17fe 100644 --- a/components/cloud/azure/Cargo.toml +++ b/components/cloud/azure/Cargo.toml @@ -7,19 +7,17 @@ license = "Apache-2.0" [dependencies] async-trait = "0.1" -# TODO: The azure sdk with the newest version needs the rustc v1.70, but current version of rustc in TiKV is v1.67. -# Therefore use the patch to update sdk to support fips 140. -azure_core = { git = "https://github.com/tikv/azure-sdk-for-rust", branch = "release-7.5-fips" } -azure_identity = { git = "https://github.com/tikv/azure-sdk-for-rust", branch = "release-7.5-fips" } -azure_security_keyvault = { git = "https://github.com/tikv/azure-sdk-for-rust", branch = "release-7.5-fips", default-features = false } -azure_storage = { git = "https://github.com/tikv/azure-sdk-for-rust", branch = "release-7.5-fips", default-features = false } -azure_storage_blobs = { git = "https://github.com/tikv/azure-sdk-for-rust", branch = "release-7.5-fips" } +azure_core = { version = "0.18", default-features = false, features = ["hmac_openssl"]} +azure_identity = "0.18" +azure_security_keyvault = { version = "0.18", default-features = false } +azure_storage = { version = "0.18", default-features = false } +azure_storage_blobs = { version = "0.18", default-features = false } base64 = "0.13" cloud = { workspace = true } futures = "0.3" futures-util = { version = "0.3", default-features = false, features = ["io"] } kvproto = { workspace = true } -oauth2 = { version = "4.0.0", default-features = false } +oauth2 = { version = "4.4", default-features = false } openssl = { workspace = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/components/cloud/azure/src/azblob.rs b/components/cloud/azure/src/azblob.rs index 04398c935e1..39b5b152492 100644 --- a/components/cloud/azure/src/azblob.rs +++ b/components/cloud/azure/src/azblob.rs @@ -7,36 +7,30 @@ use std::{ }; use async_trait::async_trait; -use azure_core::{ - auth::{TokenCredential, TokenResponse}, - new_http_client, -}; -use azure_identity::{ - AutoRefreshingTokenCredential, ClientSecretCredential, DefaultAzureCredential, - TokenCredentialOptions, -}; -use azure_storage::{prelude::*, ConnectionString, ConnectionStringBuilder}; +use azure_core::auth::{AccessToken, TokenCredential}; +use azure_identity::{ClientSecretCredential, DefaultAzureCredential}; +use azure_storage::{ConnectionString, ConnectionStringBuilder, prelude::*}; use azure_storage_blobs::{blob::operations::PutBlockBlobBuilder, prelude::*}; use cloud::{ blob::{ - none_to_empty, read_to_end, unimplemented, BlobConfig, BlobObject, BlobStorage, BucketConf, - DeletableStorage, IterableStorage, PutResource, StringNonEmpty, + BlobConfig, BlobObject, BlobStorage, BucketConf, DeletableStorage, IterableStorage, + PutResource, StringNonEmpty, none_to_empty, read_to_end, unimplemented, }, metrics::AZBLOB_UPLOAD_DURATION, }; use futures::TryFutureExt; -use futures_util::{future::FutureExt, io::AsyncRead, stream, stream::StreamExt, TryStreamExt}; +use futures_util::{TryStreamExt, future::FutureExt, io::AsyncRead, stream, stream::StreamExt}; pub use kvproto::brpb::{AzureBlobStorage as InputConfig, AzureCustomerKey}; use oauth2::{ClientId, ClientSecret}; use tikv_util::{ debug, defer, - stream::{retry, RetryError}, + stream::{RetryError, retry}, time::Instant, }; use time::OffsetDateTime; use tokio::{ sync::Mutex, - time::{timeout, Duration}, + time::{Duration, timeout}, }; const ENV_CLIENT_ID: &str = "AZURE_CLIENT_ID"; @@ -239,12 +233,9 @@ impl BlobConfig for Config { } fn url(&self) -> io::Result { - self.bucket.url("azure").map_err(|s| { - io::Error::new( - io::ErrorKind::Other, - format!("error creating bucket url: {}", s), - ) - }) + self.bucket + .url("azure") + .map_err(|s| io::Error::other(format!("error creating bucket url: {}", s))) } } @@ -391,14 +382,14 @@ trait ContainerBuilder: 'static + Send + Sync { /// Also see [`DefaultAzureCredential`]. struct DefaultContainerBuilder { config: Config, - cred: AutoRefreshingTokenCredential, + cred: Arc, } impl DefaultContainerBuilder { fn new(config: Config) -> Self { Self { config, - cred: AutoRefreshingTokenCredential::new(Arc::::default()), + cred: Arc::::default(), } } } @@ -410,9 +401,10 @@ impl ContainerBuilder for DefaultContainerBuilder { let bucket = (*self.config.bucket.bucket).to_owned(); let token_resource = format!("https://{}.blob.core.windows.net", &account_name); + let scopes = vec![&token_resource as &str]; let token = self .cred - .get_token(&token_resource) + .get_token(&scopes) .await .map_err(|e| { io::Error::new( @@ -424,7 +416,7 @@ impl ContainerBuilder for DefaultContainerBuilder { let client = BlobServiceClient::new( account_name, - StorageCredentials::bearer_token(token.secret()), + StorageCredentials::bearer_token(token.secret().to_string()), ) .container_client(bucket); Ok(Arc::new(client)) @@ -442,7 +434,7 @@ impl ContainerBuilder for SharedKeyContainerBuilder { } } -type TokenCacheType = Arc)>>>; +type TokenCacheType = Arc)>>>; struct TokenCredContainerBuilder { account_name: String, container_name: String, @@ -528,14 +520,14 @@ impl ContainerBuilder for TokenCredContainerBuilder { } // release read lock, the thread still have modify lock, // so no other threads can write the token_cache, so read lock is not blocked. - let token = self - .token_cred - .get_token(&self.token_resource) - .await - .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, format!("{:?}", &e)))?; + let scopes = vec![&self.token_resource as &str]; + let token = + self.token_cred.get_token(&scopes).await.map_err(|e| { + io::Error::new(io::ErrorKind::InvalidInput, format!("{:?}", &e)) + })?; let blob_service = BlobServiceClient::new( self.account_name.clone(), - StorageCredentials::BearerToken(token.token.secret().into()), + StorageCredentials::bearer_token(token.token.secret().to_string()), ); let storage_client = Arc::new(blob_service.container_client(self.container_name.clone())); @@ -640,11 +632,11 @@ impl AzureStorage { } else if let Some(credential_info) = config.credential_info.as_ref() { let token_resource = format!("https://{}.blob.core.windows.net", &account_name); let cred = ClientSecretCredential::new( - new_http_client(), - credential_info.tenant_id.clone(), + azure_core::new_http_client(), credential_info.client_id.to_string(), credential_info.client_secret.secret().clone(), - TokenCredentialOptions::default(), + credential_info.tenant_id.clone(), + Default::default(), ); let client_builder = Arc::new(TokenCredContainerBuilder::new( @@ -818,6 +810,8 @@ impl DeletableStorage for AzureStorage { #[cfg(test)] mod tests { + use futures::AsyncReadExt; + use super::*; #[test] @@ -895,8 +889,8 @@ mod tests { env::remove_var(ENV_CLIENT_SECRET); } + #[ignore = "no available azure cloud service for the test env."] #[tokio::test] - #[cfg(feature = "azurite")] // test in Azurite emulator async fn test_azblob_storage() { use futures_util::stream; diff --git a/components/cloud/azure/src/kms.rs b/components/cloud/azure/src/kms.rs index a7d72c2afa4..e0e9fd850d8 100644 --- a/components/cloud/azure/src/kms.rs +++ b/components/cloud/azure/src/kms.rs @@ -3,11 +3,9 @@ use std::{ops::Deref, sync::Arc}; use async_trait::async_trait; -use azure_core::{auth::TokenCredential, new_http_client, Error as AzureError}; -use azure_identity::{ - AutoRefreshingTokenCredential, ClientSecretCredential, TokenCredentialOptions, -}; -use azure_security_keyvault::{prelude::*, KeyClient}; +use azure_core::{Error as AzureError, auth::TokenCredential}; +use azure_identity::ClientSecretCredential; +use azure_security_keyvault::{KeyClient, prelude::*}; use cloud::{ error::{Error as CloudError, KmsError, OtherError, Result}, kms::{Config, CryptographyType, DataKeyPair, EncryptedKey, KeyId, KmsProvider, PlainKey}, @@ -123,18 +121,18 @@ impl AzureKms { // Client secret to access KeyVault. let (keyvault_credential, hsm_credential) = ( ClientSecretCredential::new( - new_http_client(), - azure_cfg.tenant_id.clone(), + azure_core::new_http_client(), azure_cfg.client_id.clone(), client_secret.clone(), - TokenCredentialOptions::default(), + azure_cfg.tenant_id.clone(), + Default::default(), ), ClientSecretCredential::new( - new_http_client(), - azure_cfg.tenant_id.clone(), + azure_core::new_http_client(), azure_cfg.client_id, client_secret, - TokenCredentialOptions::default(), + azure_cfg.tenant_id.clone(), + Default::default(), ), ); Self::new_with_credentials(config, keyvault_credential, hsm_credential) @@ -190,7 +188,7 @@ impl KmsProvider for AzureKms { ), }; self.client - .encrypt(&self.current_key_id.clone().into_inner(), encrypt_params) + .encrypt(self.current_key_id.clone().into_inner(), encrypt_params) .await .map_err(convert_azure_error) .and_then(|response| { @@ -237,10 +235,7 @@ fn convert_azure_error(err: AzureError) -> CloudError { let err_msg = if let Ok(e) = err.into_inner() { e } else { - Box::new(std::io::Error::new( - std::io::ErrorKind::Other, - "unknown error", - )) + Box::new(std::io::Error::other("unknown error")) }; CloudError::KmsError(KmsError::Other(OtherError::from_box(err_msg))) } @@ -250,11 +245,7 @@ fn new_key_client(url: &str, credentials: Creds) -> Result where Creds: TokenCredential + Send + Sync + 'static, { - KeyClient::new( - url, - Arc::new(AutoRefreshingTokenCredential::new(Arc::new(credentials))), - ) - .map_err(|e| CloudError::Other(Box::new(e))) + KeyClient::new(url, Arc::new(credentials)).map_err(|e| CloudError::Other(Box::new(e))) } #[cfg(test)] diff --git a/components/cloud/azure/src/token_credentials/certificate_credentials.rs b/components/cloud/azure/src/token_credentials/certificate_credentials.rs index af39e7be5fa..24e960ca610 100644 --- a/components/cloud/azure/src/token_credentials/certificate_credentials.rs +++ b/components/cloud/azure/src/token_credentials/certificate_credentials.rs @@ -3,15 +3,15 @@ use std::{str, sync::Arc, time::Duration}; use azure_core::{ - auth::{AccessToken, TokenCredential, TokenResponse}, + HttpClient, Method, Request, + auth::{AccessToken, TokenCredential}, base64, content_type, error::{Error, ErrorKind}, - headers, new_http_client, HttpClient, Method, Request, + headers, new_http_client, }; -use azure_identity::authority_hosts::AZURE_PUBLIC_CLOUD; use openssl::{ error::ErrorStack, - hash::{hash, DigestBytes, MessageDigest}, + hash::{DigestBytes, MessageDigest, hash}, pkcs12::Pkcs12, pkey::{PKey, Private}, sign::Signer, @@ -19,7 +19,7 @@ use openssl::{ }; use serde::Deserialize; use time::OffsetDateTime; -use url::{form_urlencoded, Url}; +use url::{Url, form_urlencoded}; /// Refresh time to use in seconds const DEFAULT_REFRESH_TIME: i64 = 300; @@ -35,7 +35,7 @@ struct CertificateCredentialOptions { impl Default for CertificateCredentialOptions { fn default() -> Self { Self { - authority_host: AZURE_PUBLIC_CLOUD.to_owned(), + authority_host: "https://login.microsoftonline.com/".to_owned(), send_certificate_chain: true, } } @@ -66,6 +66,7 @@ struct AadTokenResponse { /// TODO: make `ClientCertificateCredentialExt` directly extended from /// `ClientCertificateCredential` if `ClientCertificateCredential` is nightly /// released. +#[derive(Debug)] pub struct ClientCertificateCredentialExt { http_client: Arc, @@ -150,11 +151,14 @@ fn openssl_error(err: ErrorStack) -> azure_core::error::Error { #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] impl TokenCredential for ClientCertificateCredentialExt { + async fn clear_cache(&self) -> azure_core::Result<()> { + Ok(()) + } // As previous [TODO] shows, following operations in `get_token` is just // extended from `ClientCertificateCredential::get_token()` as a special // version with caching feature and stable feature. // Reference of the REST API: https://learn.microsoft.com/en-us/azure/key-vault/general/common-parameters-and-headers. - async fn get_token(&self, resource: &str) -> azure_core::Result { + async fn get_token(&self, scopes: &[&str]) -> azure_core::Result { let options = self.options(); let url = &format!( "{}/{}/oauth2/v2.0/token", @@ -231,7 +235,7 @@ impl TokenCredential for ClientCertificateCredentialExt { let mut encoded = &mut form_urlencoded::Serializer::new(String::new()); encoded = encoded .append_pair("client_id", self.client_id.as_str()) - .append_pair("scope", format!("{}/.default", resource).as_str()) + .append_pair("scope", &scopes.join(" ")) .append_pair( "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", @@ -258,8 +262,8 @@ impl TokenCredential for ClientCertificateCredentialExt { } let response: AadTokenResponse = serde_json::from_slice(&rsp_body)?; - let token = TokenResponse::new( - AccessToken::new(response.access_token.to_string()), + let token = AccessToken::new( + response.access_token.to_string(), OffsetDateTime::now_utc() + Duration::from_secs(response.expires_in), ); Ok(token) diff --git a/components/cloud/gcp/src/client.rs b/components/cloud/gcp/src/client.rs index 7dc99c0e1f2..b6bca3529a0 100644 --- a/components/cloud/gcp/src/client.rs +++ b/components/cloud/gcp/src/client.rs @@ -8,13 +8,13 @@ use std::{ sync::Arc, }; -use hyper::{client::HttpConnector, Body, Client, Request, Response, StatusCode}; +use hyper::{Body, Client, Request, Response, StatusCode, client::HttpConnector}; use hyper_tls::HttpsConnector; use serde::Deserialize; use tame_oauth::gcp::{ - end_user::EndUserCredentialsInner, service_account::ServiceAccountProviderInner, EndUserCredentialsInfo, ServiceAccountInfo, TokenOrRequest, TokenProvider, - TokenProviderWrapper, TokenProviderWrapperInner, + TokenProviderWrapper, TokenProviderWrapperInner, end_user::EndUserCredentialsInner, + service_account::ServiceAccountProviderInner, }; use tikv_util::stream::RetryError; @@ -166,6 +166,7 @@ trait ResultExt { // Maps the error of this result as an `std::io::Error` with `Other` error // kind. + #[allow(dead_code)] fn or_io_error(self, msg: D) -> io::Result; // Maps the error of this result as an `std::io::Error` with `InvalidInput` @@ -176,7 +177,7 @@ trait ResultExt { impl ResultExt for StdResult { type Ok = T; fn or_io_error(self, msg: D) -> io::Result { - self.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{}: {}", msg, e))) + self.map_err(|e| io::Error::other(format!("{}: {}", msg, e))) } fn or_invalid_input(self, msg: D) -> io::Result { self.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, format!("{}: {}", msg, e))) diff --git a/components/cloud/gcp/src/gcs.rs b/components/cloud/gcp/src/gcs.rs index 794367e43e7..13b56e77efa 100644 --- a/components/cloud/gcp/src/gcs.rs +++ b/components/cloud/gcp/src/gcs.rs @@ -4,8 +4,8 @@ use std::{fmt::Display, io}; use async_trait::async_trait; use cloud::{ blob::{ - none_to_empty, read_to_end, BlobConfig, BlobObject, BlobStorage, BucketConf, - DeletableStorage, IterableStorage, PutResource, StringNonEmpty, + BlobConfig, BlobObject, BlobStorage, BucketConf, DeletableStorage, IterableStorage, + PutResource, StringNonEmpty, none_to_empty, read_to_end, }, metrics, }; @@ -24,12 +24,12 @@ use tame_gcs::{ }; use tame_oauth::gcp::ServiceAccountInfo; use tikv_util::{ - stream::{error_stream, AsyncReadAsSyncStreamOfBytes}, + stream::{AsyncReadAsSyncStreamOfBytes, error_stream}, time::Instant, }; use crate::{ - client::{status_code_error, GcpClient, RequestError}, + client::{GcpClient, RequestError, status_code_error}, utils::{self, retry}, }; @@ -100,12 +100,9 @@ impl BlobConfig for Config { } fn url(&self) -> io::Result { - self.bucket.url("gcs").map_err(|s| { - io::Error::new( - io::ErrorKind::Other, - format!("error creating bucket url: {}", s), - ) - }) + self.bucket + .url("gcs") + .map_err(|s| io::Error::other(format!("error creating bucket url: {}", s))) } } @@ -131,7 +128,7 @@ pub trait ResultExt { impl ResultExt for Result { type Ok = T; fn or_io_error(self, msg: D) -> io::Result { - self.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{}: {}", msg, e))) + self.map_err(|e| io::Error::other(format!("{}: {}", msg, e))) } fn or_invalid_input(self, msg: D) -> io::Result { self.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, format!("{}: {}", msg, e))) @@ -415,7 +412,7 @@ struct GcsPrefixIter<'cli> { finished: bool, } -impl<'cli> GcsPrefixIter<'cli> { +impl GcsPrefixIter<'_> { async fn one_page(&mut self) -> io::Result>> { if self.finished { return Ok(None); @@ -438,7 +435,7 @@ impl<'cli> GcsPrefixIter<'cli> { .cli .make_request(req.map(|_e| Body::empty()), tame_gcs::Scopes::ReadOnly) .await - .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + .map_err(|err| io::Error::other(err))?; let resp = utils::read_from_http_body::(res).await?; metrics::CLOUD_REQUEST_HISTOGRAM_VEC .with_label_values(&["gcp", "list"]) diff --git a/components/cloud/gcp/src/kms.rs b/components/cloud/gcp/src/kms.rs index 3d4c84d06a1..9a83851e411 100644 --- a/components/cloud/gcp/src/kms.rs +++ b/components/cloud/gcp/src/kms.rs @@ -4,9 +4,10 @@ use std::{fmt, result::Result as StdResult}; use async_trait::async_trait; use cloud::{ + KeyId, error::{Error as CloudError, KmsError, Result}, kms::{Config, CryptographyType, DataKeyPair, EncryptedKey, KmsProvider, PlainKey}, - metrics, KeyId, + metrics, }; use futures_util::stream::StreamExt; use http::Method; @@ -18,8 +19,8 @@ use tame_gcs::error::HttpStatusError; use tikv_util::{box_err, stream::RetryError, time::Instant}; use crate::{ - client::{GcpClient, RequestError}, STORAGE_VENDOR_NAME_GCP, + client::{GcpClient, RequestError}, }; // generated random encryption data key length. diff --git a/components/cloud/gcp/src/lib.rs b/components/cloud/gcp/src/lib.rs index 81ab327f724..69ebc4bd32c 100644 --- a/components/cloud/gcp/src/lib.rs +++ b/components/cloud/gcp/src/lib.rs @@ -16,9 +16,9 @@ pub mod utils { use std::{future::Future, io}; use cloud::metrics; - use hyper::{body::Bytes, Body}; + use hyper::{Body, body::Bytes}; use tame_gcs::ApiResponse; - use tikv_util::stream::{retry_ext, RetryError, RetryExt}; + use tikv_util::stream::{RetryError, RetryExt, retry_ext}; pub async fn retry(action: G, name: &'static str) -> Result where G: FnMut() -> F, diff --git a/components/cloud/src/blob.rs b/components/cloud/src/blob.rs index 18c7c81a594..dd86f8ac996 100644 --- a/components/cloud/src/blob.rs +++ b/components/cloud/src/blob.rs @@ -21,7 +21,7 @@ pub struct PutResource<'a>(pub Box); pub type BlobStream<'a> = Box; -impl<'a> AsyncRead for PutResource<'a> { +impl AsyncRead for PutResource<'_> { fn poll_read( self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, diff --git a/components/cloud/src/error.rs b/components/cloud/src/error.rs index 8fd1dda3e8e..ea400d95466 100644 --- a/components/cloud/src/error.rs +++ b/components/cloud/src/error.rs @@ -3,7 +3,7 @@ use std::{ error, fmt::{self, Debug, Display}, - io::{Error as IoError, ErrorKind}, + io::Error as IoError, result, }; @@ -59,7 +59,7 @@ impl From for IoError { fn from(err: Error) -> IoError { match err { Error::Io(e) => e, - other => IoError::new(ErrorKind::Other, format!("{}", other)), + other => IoError::other(format!("{}", other)), } } } diff --git a/components/cloud/src/lib.rs b/components/cloud/src/lib.rs index 28debed51b9..978a1558a3e 100644 --- a/components/cloud/src/lib.rs +++ b/components/cloud/src/lib.rs @@ -13,6 +13,6 @@ pub mod kms; pub use kms::{Config, DataKeyPair, EncryptedKey, KeyId, KmsProvider, PlainKey, SubConfigAzure}; pub mod blob; -pub use blob::{none_to_empty, BucketConf, StringNonEmpty}; +pub use blob::{BucketConf, StringNonEmpty, none_to_empty}; pub mod metrics; diff --git a/components/codec/src/buffer.rs b/components/codec/src/buffer.rs index f40ee1fae4f..e47249e05ae 100644 --- a/components/codec/src/buffer.rs +++ b/components/codec/src/buffer.rs @@ -65,7 +65,7 @@ impl> BufferReader for std::io::Cursor { } } -impl<'a> BufferReader for &'a [u8] { +impl BufferReader for &[u8] { #[inline] fn bytes(&self) -> &[u8] { self @@ -86,7 +86,7 @@ impl<'a> BufferReader for &'a [u8] { } } -impl<'a, T: BufferReader + ?Sized> BufferReader for &'a mut T { +impl BufferReader for &mut T { #[inline] fn bytes(&self) -> &[u8] { (**self).bytes() @@ -204,7 +204,7 @@ impl> BufferWriter for std::io::Cursor { } } -impl<'a> BufferWriter for &'a mut [u8] { +impl BufferWriter for &mut [u8] { #[inline] unsafe fn bytes_mut(&mut self, _size: usize) -> &mut [u8] { self @@ -252,7 +252,7 @@ impl BufferWriter for Vec { } } -impl<'a, T: BufferWriter + ?Sized> BufferWriter for &'a mut T { +impl BufferWriter for &mut T { #[inline] unsafe fn bytes_mut(&mut self, size: usize) -> &mut [u8] { (**self).bytes_mut(size) @@ -635,7 +635,7 @@ mod tests { // Re-allocate the vector space and ensure that the address is changed. vec.reserve(::std::cmp::max(payload_len * 3, 32)); - if vec_ptr == vec.as_ptr() { + if std::ptr::eq(vec_ptr, vec.as_ptr()) { in_place_reallocs += 1; } diff --git a/components/codec/src/byte.rs b/components/codec/src/byte.rs index 8b5fd928edf..5489002dfac 100644 --- a/components/codec/src/byte.rs +++ b/components/codec/src/byte.rs @@ -3,9 +3,9 @@ use std::{intrinsics::unlikely, io::Read}; use crate::{ + ErrorInner, Result, buffer::BufferReader, number::{self, NumberCodec, NumberDecoder, NumberEncoder}, - ErrorInner, Result, }; const MEMCMP_GROUP_SIZE: usize = 8; @@ -1374,6 +1374,9 @@ mod benches { } if desc { + // SEE: https://github.com/rust-lang/rust-clippy/issues/14685 + // We can remove this after upgrading to a newer toolchain. + #[allow(clippy::manual_slice_fill)] for k in &mut key { *k = !*k; } diff --git a/components/codec/src/number.rs b/components/codec/src/number.rs index af47905334d..7422573588f 100644 --- a/components/codec/src/number.rs +++ b/components/codec/src/number.rs @@ -1,12 +1,15 @@ // Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0. -use std::intrinsics::{likely, unlikely}; +use std::{ + intrinsics::{likely, unlikely}, + ptr, +}; use byteorder::{BigEndian, ByteOrder, LittleEndian}; use crate::{ - buffer::{BufferReader, BufferWriter}, ErrorInner, Result, + buffer::{BufferReader, BufferWriter}, }; pub const MAX_VARINT64_LENGTH: usize = 10; @@ -466,12 +469,12 @@ impl NumberCodec { let ptr_end = buf.as_ptr().add(len); // Slow path let mut shift = 0; - while ptr != ptr_end && *ptr >= 0x80 { + while !ptr::eq(ptr, ptr_end) && *ptr >= 0x80 { val |= ((*ptr & 0x7f) as u64) << shift; shift += 7; ptr = ptr.add(1); } - if unlikely(ptr == ptr_end) { + if unlikely(ptr::eq(ptr, ptr_end)) { return Err(ErrorInner::eof().into()); } val |= (*ptr as u64) << shift; @@ -541,7 +544,7 @@ impl NumberCodec { } else { let ptr_end = buf.as_ptr().add(len); // Slow path - while ptr != ptr_end && *ptr >= 0x80 { + while !ptr::eq(ptr, ptr_end) && *ptr >= 0x80 { ptr = ptr.add(1); } // When we got here, we are either `ptr == ptr_end`, or `*ptr < 0x80`. @@ -549,7 +552,7 @@ impl NumberCodec { // but meet EOF, so only `len` is returned. // For `*ptr < 0x80` case, it means currently it is pointing to the last byte // of the VarInt, so we return `delta + 1` as length. - if unlikely(ptr == ptr_end) { + if unlikely(ptr::eq(ptr, ptr_end)) { return len; } ptr.offset_from(buf.as_ptr()) as usize + 1 diff --git a/components/compact-log-backup/Cargo.toml b/components/compact-log-backup/Cargo.toml index 8f3bf8f1445..ca181e407ee 100644 --- a/components/compact-log-backup/Cargo.toml +++ b/components/compact-log-backup/Cargo.toml @@ -8,13 +8,14 @@ edition = "2021" failpoints = ["fail/failpoints"] [dependencies] -async-compression = { version = "0.4.12", features = [ +async-compression = { version = "0.4.27", features = [ "tokio", "futures-io", "zstd", ] } bytes = "1" chrono = { workspace = true } +cloud = { workspace = true } codec = { workspace = true } crc64fast = "0.1" dashmap = "5" @@ -62,7 +63,7 @@ uuid = { version = "0.8", features = ["v4", "serde"] } zstd = "0.11" [dev-dependencies] -pprof = { version = "0.14", default-features = false, features = [ +pprof = { version = "0.15", default-features = false, features = [ "flamegraph", "protobuf-codec", ] } diff --git a/components/compact-log-backup/src/compaction/collector.rs b/components/compact-log-backup/src/compaction/collector.rs index 6113a82bccd..4b4f514fbdf 100644 --- a/components/compact-log-backup/src/compaction/collector.rs +++ b/components/compact-log-backup/src/compaction/collector.rs @@ -12,7 +12,7 @@ use crate::{ }; /// A collecting subcompaction. - +/// /// Collecting a stream of [`LogFile`], and generate a stream of compactions. #[pin_project::pin_project] pub struct CollectSubcompaction>> { @@ -163,9 +163,11 @@ impl>> Stream for CollectSubcompaction { mod test { use std::sync::Arc; + use bytes::Bytes; use engine_traits::CF_WRITE; use futures::stream::{self, StreamExt, TryStreamExt}; use kvproto::brpb; + use protobuf::Chars; use super::{CollectSubcompaction, CollectSubcompactionConfig, SubcompactionCollectKey}; use crate::{ @@ -177,7 +179,7 @@ mod test { fn log_file(name: &str, len: u64, key: SubcompactionCollectKey) -> LogFile { LogFile { id: LogFileId { - name: Arc::from(name.to_owned().into_boxed_str()), + name: Chars::from(name), offset: 0, length: len, }, @@ -187,8 +189,8 @@ mod test { file_real_size: len, min_ts: 0, max_ts: 0, - min_key: Arc::from([]), - max_key: Arc::from([]), + min_key: Bytes::new(), + max_key: Bytes::new(), is_meta: key.is_meta, region_id: key.region_id, cf: key.cf, @@ -196,7 +198,7 @@ mod test { min_start_ts: 0, table_id: 0, resolved_ts: 0, - sha256: Arc::from([]), + sha256: Bytes::new(), region_start_key: None, region_end_key: None, region_epoches: None, diff --git a/components/compact-log-backup/src/compaction/exec.rs b/components/compact-log-backup/src/compaction/exec.rs index 481c2340048..a4ff62a1812 100644 --- a/components/compact-log-backup/src/compaction/exec.rs +++ b/components/compact-log-backup/src/compaction/exec.rs @@ -6,8 +6,8 @@ use std::{ use engine_rocks::RocksEngine; use engine_traits::{ - ExternalSstFileInfo, SstCompressionType, SstExt, SstWriter, SstWriterBuilder, - DATA_KEY_PREFIX_LEN, + DATA_KEY_PREFIX_LEN, ExternalSstFileInfo, SstCompressionType, SstExt, SstWriter, + SstWriterBuilder, }; use external_storage::{ExternalStorage, UnpinReader}; use file_system::Sha256Reader; @@ -22,7 +22,7 @@ use crate::{ compaction::SST_OUT_REL, errors::{OtherErrExt, Result, TraceResultExt}, source::{Record, Source}, - statistic::{prom::*, LoadStatistic, SubcompactStatistic}, + statistic::{LoadStatistic, SubcompactStatistic, prom::*}, storage::DEFAULT_COMPACTION_OUT_PREFIX, util::{self, Cooperate, ExecuteAllExt}, }; @@ -410,7 +410,7 @@ mod test { compaction::Subcompaction, storage::{Epoch, MetaFile}, test_util::{ - gen_step, save_many_log_files, CompactInMem, KvGen, LogFileBuilder, TmpStorage, + CompactInMem, KvGen, LogFileBuilder, TmpStorage, gen_step, save_many_log_files, }, }; diff --git a/components/compact-log-backup/src/compaction/meta.rs b/components/compact-log-backup/src/compaction/meta.rs index a54c35e70d1..18e602817eb 100644 --- a/components/compact-log-backup/src/compaction/meta.rs +++ b/components/compact-log-backup/src/compaction/meta.rs @@ -7,10 +7,11 @@ use std::{ use external_storage::ExternalStorage; use futures::stream::TryStreamExt; use kvproto::brpb::{self, DeleteSpansOfFile}; +use protobuf::Chars; use super::{ - collector::CollectSubcompactionConfig, EpochHint, Subcompaction, SubcompactionCollectKey, - SubcompactionResult, UnformedSubcompaction, + EpochHint, Subcompaction, SubcompactionCollectKey, SubcompactionResult, UnformedSubcompaction, + collector::CollectSubcompactionConfig, }; use crate::{ errors::Result, @@ -164,7 +165,7 @@ impl Ord for SortByOffset { /// Finally, it calculates which files can be deleted. #[derive(Debug)] pub struct CompactionRunInfoBuilder { - files: HashMap, BTreeSet>, + files: HashMap>, compaction: brpb::LogFileCompaction, } @@ -182,14 +183,18 @@ impl Default for CompactionRunInfoBuilder { /// A set of deletable log files from the same metadata. pub struct ExpiringFilesOfMeta { meta_path: Arc, - logs: Vec>, + logs: Vec, /// Whether the log file is still needed. /// /// When we are going to delete every log files recoreded in a log file, the /// logfile itself can also be removed. destruct_self: bool, + + // Whether the data kv files has been compcated before. so we can skip it quickly. + // Since we are not handle meta kv files. the destruct_self may not work here. + all_data_files_compacted: bool, /// The logical log files that can be removed. - spans_of_file: HashMap, (Vec, /* physical file size */ u64)>, + spans_of_file: HashMap, /* physical file size */ u64)>, } impl ExpiringFilesOfMeta { @@ -199,13 +204,17 @@ impl ExpiringFilesOfMeta { meta_path: Arc::clone(path), logs: vec![], destruct_self: false, + all_data_files_compacted: false, spans_of_file: Default::default(), } } /// Whether we are going to delete nothing. pub fn is_empty(&self) -> bool { - self.logs.is_empty() && self.spans_of_file.is_empty() && !self.destruct_self + self.logs.is_empty() + && self.spans_of_file.is_empty() + && !self.destruct_self + && !self.all_data_files_compacted } /// Get the list of physical files that can be deleted. @@ -232,8 +241,7 @@ impl CompactionRunInfoBuilder { pub fn add_subcompaction(&mut self, c: &SubcompactionResult) { for file in &c.origin.inputs { if !self.files.contains_key(&file.id.name) { - self.files - .insert(Arc::clone(&file.id.name), Default::default()); + self.files.insert(file.id.name.clone(), Default::default()); } self.files .get_mut(&file.id.name) @@ -249,9 +257,9 @@ impl CompactionRunInfoBuilder { &mut self.compaction } - pub async fn write_migration(&self, s: &dyn ExternalStorage) -> Result<()> { - let migration = self.migration_of(self.find_expiring_files(s).await?); - let wrapped_storage = MigrationStorageWrapper::new(s); + pub async fn write_migration(&self, s: Arc) -> Result<()> { + let migration = self.migration_of(self.find_expiring_files(s.clone()).await?); + let wrapped_storage = MigrationStorageWrapper::new(s.as_ref()); wrapped_storage.write(migration.into()).await?; Ok(()) } @@ -268,6 +276,7 @@ impl CompactionRunInfoBuilder { medit.delete_logical_files.push(span) } medit.destruct_self = files.destruct_self; + medit.all_data_files_compacted = files.all_data_files_compacted; migration.edit_meta.push(medit); } migration.mut_compactions().push(self.compaction.clone()); @@ -276,10 +285,10 @@ impl CompactionRunInfoBuilder { async fn find_expiring_files( &self, - s: &dyn ExternalStorage, + s: Arc, ) -> Result> { let ext = LoadFromExt::default(); - let mut storage = StreamMetaStorage::load_from_ext(s, ext).await?; + let mut storage = StreamMetaStorage::load_from_ext(&s, ext).await?; let mut result = vec![]; while let Some(item) = storage.try_next().await? { @@ -317,26 +326,34 @@ impl CompactionRunInfoBuilder { fn expiring(&self, file: &MetaFile) -> ExpiringFilesOfMeta { let mut result = ExpiringFilesOfMeta::of(&file.name); let mut all_full_covers = true; + let mut all_data_files_compacted = true; for p in &file.physical_files { let full_covers = self.full_covers(p); if full_covers { - result.logs.push(Arc::clone(&p.name)) + result.logs.push(p.name.clone()); } else { if let Some(vs) = self.files.get(&p.name) { let segs = result .spans_of_file - .entry(Arc::clone(&p.name)) + .entry(p.name.clone()) .or_insert_with(|| (vec![], p.size)); for f in vs { segs.0.push(f.0.span()); } } all_full_covers = false; + + // Meta KV files and data KV files belong to different physical files. + // Therefore, only if this physical file contains no `is_meta` entries + // should `all_data_files_full_covers` be set to false. + if p.files.iter().any(|f| !f.is_meta) { + all_data_files_compacted = false; + } } } - if all_full_covers { - result.destruct_self = true; - } + result.destruct_self = all_full_covers; + result.all_data_files_compacted = all_data_files_compacted; + result } } @@ -353,21 +370,85 @@ impl EpochHint { #[cfg(test)] mod test { + use std::sync::Arc; + use external_storage::ExternalStorage; use kvproto::brpb; use super::CompactionRunInfoBuilder; use crate::{ - compaction::{exec::SubcompactionExec, Subcompaction, SubcompactionResult}, - test_util::{gen_min_max, KvGen, LogFileBuilder, TmpStorage}, + compaction::{Subcompaction, SubcompactionResult, exec::SubcompactionExec}, + test_util::{KvGen, LogFileBuilder, TmpStorage, gen_min_max}, }; impl CompactionRunInfoBuilder { - async fn mig(&self, s: &dyn ExternalStorage) -> crate::Result { + async fn mig(&self, s: Arc) -> crate::Result { Ok(self.migration_of(self.find_expiring_files(s).await?)) } } + #[tokio::test] + async fn test_ignore_small_files() { + let const_val = |_| b"fiolvit".to_vec(); + let g11 = + LogFileBuilder::from_iter(KvGen::new(gen_min_max(1, 1, 2, 10, 20), const_val), |_| {}); + let g12 = + LogFileBuilder::from_iter(KvGen::new(gen_min_max(1, 3, 4, 15, 25), const_val), |_| {}); + let g21 = + LogFileBuilder::from_iter(KvGen::new(gen_min_max(3, 5, 6, 30, 40), const_val), |_| {}); + let g22 = + LogFileBuilder::from_iter(KvGen::new(gen_min_max(4, 7, 8, 45, 55), const_val), |_| {}); + let st = TmpStorage::create(); + let m = st + .build_flush_logs("v1/1", "v1/backupmeta/1.meta", [[g11, g12], [g21, g22]]) + .await; + + let mut coll1 = CompactionRunInfoBuilder::default(); + let cr = SubcompactionExec::default_config(st.storage().clone()); + let subc = Subcompaction::singleton(m.physical_files[0].files[0].clone()); + let res = cr.run(subc, Default::default()).await.unwrap(); + coll1.add_subcompaction(&res); + let mig = coll1.mig(st.storage().clone()).await.unwrap(); + assert_eq!(mig.edit_meta.len(), 1); + assert!(!mig.edit_meta[0].destruct_self); + assert!(!mig.edit_meta[0].all_data_files_compacted); + assert_eq!(mig.edit_meta[0].delete_physical_files.len(), 0); + assert_eq!(mig.edit_meta[0].delete_logical_files.len(), 1); + + let subc = Subcompaction::singleton(m.physical_files[0].files[1].clone()); + let cr = SubcompactionExec::default_config(st.storage().clone()); + let res2 = cr.run(subc, Default::default()).await.unwrap(); + coll1.add_subcompaction(&res2); + let mig = coll1.mig(st.storage().clone()).await.unwrap(); + assert_eq!(mig.edit_meta.len(), 1); + assert!(!mig.edit_meta[0].destruct_self); + assert!(!mig.edit_meta[0].all_data_files_compacted); + assert_eq!(mig.edit_meta[0].delete_physical_files.len(), 1); + assert_eq!(mig.edit_meta[0].delete_logical_files.len(), 0); + + let subc = Subcompaction::singleton(m.physical_files[1].files[0].clone()); + let cr = SubcompactionExec::default_config(st.storage().clone()); + let res3 = cr.run(subc, Default::default()).await.unwrap(); + coll1.add_subcompaction(&res3); + let mig = coll1.mig(st.storage().clone()).await.unwrap(); + assert_eq!(mig.edit_meta.len(), 1); + assert!(!mig.edit_meta[0].destruct_self); + assert!(!mig.edit_meta[0].all_data_files_compacted); + assert_eq!(mig.edit_meta[0].delete_physical_files.len(), 1); + assert_eq!(mig.edit_meta[0].delete_logical_files.len(), 1); + + let subc = Subcompaction::singleton(m.physical_files[1].files[1].clone()); + let cr = SubcompactionExec::default_config(st.storage().clone()); + let res4 = cr.run(subc, Default::default()).await.unwrap(); + coll1.add_subcompaction(&res4); + let mig = coll1.mig(st.storage().clone()).await.unwrap(); + assert_eq!(mig.edit_meta.len(), 1); + assert!(mig.edit_meta[0].destruct_self); + assert!(mig.edit_meta[0].all_data_files_compacted); + assert_eq!(mig.edit_meta[0].delete_physical_files.len(), 2); + assert_eq!(mig.edit_meta[0].delete_logical_files.len(), 0); + } + #[tokio::test] async fn test_collect_single() { let const_val = |_| b"fiolvit".to_vec(); @@ -385,14 +466,14 @@ mod test { let subc = Subcompaction::singleton(m.physical_files[0].files[0].clone()); let res = cr.run(subc, Default::default()).await.unwrap(); coll.add_subcompaction(&res); - let mig = coll.mig(st.storage().as_ref()).await.unwrap(); + let mig = coll.mig(st.storage().clone()).await.unwrap(); assert_eq!(mig.edit_meta.len(), 1); assert!(!mig.edit_meta[0].destruct_self); let mut coll = CompactionRunInfoBuilder::default(); let subc = Subcompaction::of_many(m.physical_files[0].files.iter().cloned()); coll.add_subcompaction(&SubcompactionResult::of(subc)); - let mig = coll.mig(st.storage().as_ref()).await.unwrap(); + let mig = coll.mig(st.storage().clone()).await.unwrap(); assert_eq!(mig.edit_meta.len(), 1); assert!(mig.edit_meta[0].destruct_self); @@ -412,6 +493,15 @@ mod test { |v| v.region_id = region as u64, ) }; + let of_region_meta = |region, is_meta| { + LogFileBuilder::from_iter( + KvGen::new(gen_min_max(region, 1, 2, 10, 20), const_val), + |v| { + v.region_id = region as u64; + v.is_meta = is_meta; + }, + ) + }; let f1 = st .build_flush( "1.log", @@ -420,10 +510,11 @@ mod test { ) .await; let f2 = st - .build_flush( + .build_flush_with_meta( "2.log", "v1/backupmeta/2.meta", [of_region(1), of_region(2), of_region(3)], + Some([of_region_meta(4, true)]), ) .await; @@ -441,16 +532,21 @@ mod test { coll.add_subcompaction(&SubcompactionResult::of(subc1)); coll.add_subcompaction(&SubcompactionResult::of(subc2)); coll.add_subcompaction(&SubcompactionResult::of(subc3)); - let mig = coll.mig(st.storage().as_ref()).await.unwrap(); + let mig = coll.mig(st.storage().clone()).await.unwrap(); assert_eq!(mig.edit_meta.len(), 2); let check = |me: &brpb::MetaEdit| match me.get_path() { "v1/backupmeta/1.meta" => { assert!(!me.destruct_self); + // file 3 not compacted + assert!(!me.all_data_files_compacted); assert_eq!(me.delete_logical_files.len(), 1); assert_eq!(me.delete_logical_files[0].spans.len(), 2); } "v1/backupmeta/2.meta" => { - assert!(me.destruct_self); + // file 4 not compacted + assert!(!me.destruct_self); + // but file 4 is meta kv file + assert!(me.all_data_files_compacted); assert_eq!(me.delete_physical_files.len(), 1, "{:?}", me); assert_eq!(me.delete_logical_files.len(), 0, "{:?}", me); } diff --git a/components/compact-log-backup/src/compaction/mod.rs b/components/compact-log-backup/src/compaction/mod.rs index 3365fb0499f..9588d7b9d6b 100644 --- a/components/compact-log-backup/src/compaction/mod.rs +++ b/components/compact-log-backup/src/compaction/mod.rs @@ -1,6 +1,7 @@ // Copyright 2024 TiKV Project Authors. Licensed under Apache-2.0. -use std::{collections::HashSet, ops::Deref, sync::Arc}; +use std::{collections::HashSet, ops::Deref}; +use bytes::Bytes; use derive_more::Display; use kvproto::brpb::{self, FileType}; @@ -53,15 +54,15 @@ pub struct Subcompaction { pub input_min_ts: u64, pub compact_from_ts: u64, pub compact_to_ts: u64, - pub min_key: Arc<[u8]>, - pub max_key: Arc<[u8]>, + pub min_key: Bytes, + pub max_key: Bytes, pub epoch_hints: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EpochHint { - pub start_key: Arc<[u8]>, - pub end_key: Arc<[u8]>, + pub start_key: Bytes, + pub end_key: Bytes, pub region_epoch: Epoch, } @@ -112,8 +113,8 @@ struct UnformedSubcompaction { inputs: Vec, min_ts: u64, max_ts: u64, - min_key: Arc<[u8]>, - max_key: Arc<[u8]>, + min_key: Bytes, + max_key: Bytes, epoch_hints: HashSet, } @@ -143,8 +144,8 @@ impl UnformedSubcompaction { size: self.size, input_min_ts: self.min_ts, input_max_ts: self.max_ts, - min_key: self.min_key.clone(), - max_key: self.max_key.clone(), + min_key: self.min_key, + max_key: self.max_key, compact_from_ts: cfg.compact_from_ts, compact_to_ts: cfg.compact_to_ts, subc_key: *key, diff --git a/components/compact-log-backup/src/exec_hooks/checkpoint.rs b/components/compact-log-backup/src/exec_hooks/checkpoint.rs index 6bbfe42422b..ff1e85c3b61 100644 --- a/components/compact-log-backup/src/exec_hooks/checkpoint.rs +++ b/components/compact-log-backup/src/exec_hooks/checkpoint.rs @@ -7,9 +7,9 @@ use futures::stream::TryStreamExt; use tikv_util::{info, time::Instant, warn}; use crate::{ + ErrorKind, OtherErrExt, Result, TraceResultExt, compaction::META_OUT_REL, execute::hooking::{BeforeStartCtx, CId, ExecHooks, SubcompactionStartCtx}, - ErrorKind, OtherErrExt, Result, TraceResultExt, }; #[derive(Default)] diff --git a/components/compact-log-backup/src/exec_hooks/consistency.rs b/components/compact-log-backup/src/exec_hooks/consistency.rs index c22a49c9719..3b3cef912bf 100644 --- a/components/compact-log-backup/src/exec_hooks/consistency.rs +++ b/components/compact-log-backup/src/exec_hooks/consistency.rs @@ -1,16 +1,16 @@ // Copyright 2024 TiKV Project Authors. Licensed under Apache-2.0. pub use engine_traits::SstCompressionType; -use external_storage::{locking::RemoteLock, ExternalStorage}; +use external_storage::{ExternalStorage, locking::RemoteLock}; use futures::{io::AsyncReadExt, stream::TryStreamExt}; use tikv_util::warn; use crate::{ + ErrorKind, TraceResultExt, errors::Result, execute::hooking::{AbortedCtx, AfterFinishCtx, BeforeStartCtx, ExecHooks}, storage::LOCK_PREFIX, util::storage_url, - ErrorKind, TraceResultExt, }; #[derive(Default)] @@ -39,7 +39,9 @@ async fn load_storage_checkpoint(storage: &dyn ExternalStorage) -> Result