From 0cbef6292c63bc83c40d8e30520ce984a5d70cc8 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Sat, 7 Dec 2024 15:46:59 +0800 Subject: [PATCH 01/14] purge Signed-off-by: Calvin Neo --- components/engine_panic/Cargo.toml | 2 +- components/engine_rocks/Cargo.toml | 2 +- components/engine_traits/Cargo.toml | 2 +- components/hybrid_engine/Cargo.toml | 26 ++++++------ components/in_memory_engine/Cargo.toml | 42 +++++++++---------- components/raft_log_engine/Cargo.toml | 2 +- .../proxy_ffi/src/jemalloc_utils.rs | 2 +- .../proxy_server/src/status_server/mod.rs | 9 ++++ .../src/status_server/vendored_utils.rs | 20 ++++++++- 9 files changed, 67 insertions(+), 40 deletions(-) diff --git a/components/engine_panic/Cargo.toml b/components/engine_panic/Cargo.toml index 3ee5d82ad14..c125ef7ccf2 100644 --- a/components/engine_panic/Cargo.toml +++ b/components/engine_panic/Cargo.toml @@ -10,9 +10,9 @@ license = "Apache-2.0" testexport = [] [dependencies] +encryption = { workspace = true } engine_traits = { workspace = true } kvproto = { workspace = true } -encryption = { workspace = true } raft = { workspace = true } tracker = { workspace = true } txn_types = { workspace = true } diff --git a/components/engine_rocks/Cargo.toml b/components/engine_rocks/Cargo.toml index d3893da020a..26ca70e1606 100644 --- a/components/engine_rocks/Cargo.toml +++ b/components/engine_rocks/Cargo.toml @@ -61,6 +61,6 @@ package = "rocksdb" features = ["encryption"] [dev-dependencies] +proptest = "1.0.0" rand = "0.8" toml = "0.5" -proptest = "1.0.0" diff --git a/components/engine_traits/Cargo.toml b/components/engine_traits/Cargo.toml index 2e86822ceac..85b8337ef0d 100644 --- a/components/engine_traits/Cargo.toml +++ b/components/engine_traits/Cargo.toml @@ -11,6 +11,7 @@ testexport = [] [dependencies] collections = { workspace = true } +encryption = { workspace = true } error_code = { workspace = true } fail = "0.5" file_system = { workspace = true } @@ -19,7 +20,6 @@ kvproto = { workspace = true } log_wrappers = { workspace = true } protobuf = "2" raft = { workspace = true } -encryption = { workspace = true } serde = "1.0" slog = { workspace = true } slog-global = { workspace = true } diff --git a/components/hybrid_engine/Cargo.toml b/components/hybrid_engine/Cargo.toml index 3a23f9927da..2938a329f97 100644 --- a/components/hybrid_engine/Cargo.toml +++ b/components/hybrid_engine/Cargo.toml @@ -6,27 +6,27 @@ publish = false license = "Apache-2.0" [dependencies] -engine_traits = { workspace = true } -txn_types = { workspace = true } -tikv_util = { workspace = true } +crossbeam = { workspace = true } engine_rocks = { workspace = true } -online_config = { workspace = true } +engine_traits = { workspace = true } in_memory_engine = { workspace = true } -slog = { workspace = true } -slog-global = { workspace = true } -tempfile = "3.0" +keys = { workspace = true } +kvproto = { workspace = true } +lazy_static = "1.4.0" +online_config = { workspace = true } prometheus = { version = "0.13", default-features = false, features = [ "nightly", ] } prometheus-static-metric = "0.5" -lazy_static = "1.4.0" -crossbeam = { workspace = true } -raftstore = { workspace = true } raft = { workspace = true } -kvproto = { workspace = true } -keys = { workspace = true } +raftstore = { workspace = true } +slog = { workspace = true } +slog-global = { workspace = true } +tempfile = "3.0" +tikv_util = { workspace = true } +txn_types = { workspace = true } [dev-dependencies] +fail = { version = "0.5", features = ["failpoints"] } tempfile = "3.0" test_util = { workspace = true } -fail = { version = "0.5", features = ["failpoints"] } diff --git a/components/in_memory_engine/Cargo.toml b/components/in_memory_engine/Cargo.toml index a29ad0d6daf..00052d4542d 100644 --- a/components/in_memory_engine/Cargo.toml +++ b/components/in_memory_engine/Cargo.toml @@ -20,44 +20,44 @@ path = "benches/load_region.rs" harness = false [dependencies] -engine_traits = { workspace = true } -collections = { workspace = true } -crossbeam-skiplist = { workspace = true } bytes = "1.0" +collections = { workspace = true } crossbeam = { workspace = true } +crossbeam-skiplist = { workspace = true } +dashmap = "5.1" +engine_rocks = { workspace = true } +engine_traits = { workspace = true } +fail = "0.5" futures = { version = "0.3", features = ["compat"] } -tikv_util = { workspace = true } -txn_types = { workspace = true } +hex = "0.4" +keys = { workspace = true } kvproto = { workspace = true } +lazy_static = "1.4.0" +libc = "0.2" log_wrappers = { workspace = true } +online_config = { workspace = true } +parking_lot = "0.12" pd_client = { workspace = true } +prometheus = { version = "0.13", default-features = false, features = ["nightly"] } +prometheus-static-metric = "0.5" raftstore = { workspace = true } -dashmap = "5.1" +rand = "0.8" security = { workspace = true } serde = "1.0" serde_json = "1.0" -slog-global = { workspace = true } slog = { workspace = true } +slog-global = { workspace = true } +smallvec = "1.4" strum = { version = "0.20", features = ["derive"] } -engine_rocks = { workspace = true } -fail = "0.5" -yatp = { workspace = true } -parking_lot = "0.12" -keys = { workspace = true } -prometheus = { version = "0.13", default-features = false, features = ["nightly"] } -prometheus-static-metric = "0.5" -lazy_static = "1.4.0" -hex = "0.4" thiserror = "1.0" -online_config = { workspace = true } -libc = "0.2" -rand = "0.8" +tikv_util = { workspace = true } tokio = { version = "1.5", features = ["rt-multi-thread"] } -smallvec = "1.4" +txn_types = { workspace = true } +yatp = { workspace = true } [dev-dependencies] criterion = "0.3" +proptest = "1.0.0" tempfile = "3.0" test_pd = { workspace = true } test_util = { workspace = true } -proptest = "1.0.0" diff --git a/components/raft_log_engine/Cargo.toml b/components/raft_log_engine/Cargo.toml index c1c48988f44..15f2388b460 100644 --- a/components/raft_log_engine/Cargo.toml +++ b/components/raft_log_engine/Cargo.toml @@ -9,9 +9,9 @@ license = "Apache-2.0" failpoints = ["raft-engine/failpoints"] [dependencies] +codec = { workspace = true } encryption = { workspace = true } engine_traits = { workspace = true } -codec = { workspace = true } file_system = { workspace = true } kvproto = { workspace = true } raft = { workspace = true } diff --git a/proxy_components/proxy_ffi/src/jemalloc_utils.rs b/proxy_components/proxy_ffi/src/jemalloc_utils.rs index 763669fffd5..a37f53f0c8b 100644 --- a/proxy_components/proxy_ffi/src/jemalloc_utils.rs +++ b/proxy_components/proxy_ffi/src/jemalloc_utils.rs @@ -80,7 +80,7 @@ pub fn issue_mallctl_args( #[allow(unused_variables)] #[allow(unused_mut)] #[allow(unused_unsafe)] -fn issue_mallctl(command: &str) -> u64 { +pub fn issue_mallctl(command: &str) -> u64 { type PtrUnderlying = u64; let mut ptr: PtrUnderlying = 0; let mut size = std::mem::size_of::() as u64; diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index fc0f7f6afde..a492daff731 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -63,6 +63,7 @@ use tokio::{ sync::oneshot::{self, Receiver, Sender}, }; use tokio_openssl::SslStream; +use vendored_utils::jeprof_purge_arena; use crate::status_server::profile::set_prof_active; @@ -243,6 +244,11 @@ where } } + async fn arena_purge(_: Request) -> hyper::Result> { + jeprof_purge_arena(); + Ok(make_response(StatusCode::OK, "purge OK")) + } + #[allow(dead_code)] async fn dump_heap_prof_to_resp(req: Request) -> hyper::Result> { let query = req.uri().query().unwrap_or(""); @@ -796,6 +802,9 @@ where (Method::GET, "/debug/pprof/heap") => { Self::dump_heap_prof_to_resp(req).await } + (Method::GET, "/debug/pprof/arena_purge") => { + Self::arena_purge(req).await + } (Method::GET, "/config") => { Self::get_config(req, &cfg_controller, engine_store_server_helper) .await diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index 14362abd665..556582f40fa 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -1,6 +1,6 @@ // Copyright 2024 TiKV Project Authors. Licensed under Apache-2.0. -use proxy_ffi::jemalloc_utils::issue_mallctl_args; +use proxy_ffi::jemalloc_utils::{issue_mallctl, issue_mallctl_args}; use tikv_alloc::error::ProfResult; pub fn activate_prof() -> ProfResult<()> { @@ -107,3 +107,21 @@ pub fn adhoc_dump(path: &str) -> tikv_alloc::error::ProfResult<()> { } Ok(()) } + +pub fn jeprof_purge_arena() { + let narenas = issue_mallctl("arenas.narenas"); + info!("jeprof_purge_arena purge {} arenas", narenas); + for i in 0..narenas { + let a_string = format!("arena.{}.purge", i); + let r = issue_mallctl_args( + &a_string, + std::ptr::null_mut(), + std::ptr::null_mut(), + std::ptr::null_mut(), + 0, + ); + if r != 0 { + info!("jeprof_purge_arena purge {} return {}", a_string, r); + } + } +} From 3afbfc7dcc38f4833ac5b3a96fbcace4f7501520 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Mon, 9 Dec 2024 15:18:49 +0800 Subject: [PATCH 02/14] Update proxy_components/proxy_server/src/status_server/vendored_utils.rs Co-authored-by: JaySon --- .../proxy_server/src/status_server/vendored_utils.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index 556582f40fa..932ae2111c2 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -124,4 +124,5 @@ pub fn jeprof_purge_arena() { info!("jeprof_purge_arena purge {} return {}", a_string, r); } } + info!("jeprof_purge_arena purge {} arenas done", narenas); } From 4d6e7c76b909cf99ac40bfb9eec94531d8d822f8 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Mon, 9 Dec 2024 15:23:07 +0800 Subject: [PATCH 03/14] using warn Signed-off-by: Calvin Neo --- .../proxy_server/src/status_server/vendored_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index 556582f40fa..c19d7fd2743 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -121,7 +121,7 @@ pub fn jeprof_purge_arena() { 0, ); if r != 0 { - info!("jeprof_purge_arena purge {} return {}", a_string, r); + warn!("jeprof_purge_arena purge {} return {}", a_string, r); } } } From da7e90c74336c6e3245f9264545acfe902675393 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Mon, 9 Dec 2024 16:44:52 +0800 Subject: [PATCH 04/14] fmt Signed-off-by: Calvin Neo --- .../proxy_server/src/status_server/vendored_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index 05b27e18b53..dac7d6489f7 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -124,5 +124,5 @@ pub fn jeprof_purge_arena() { warn!("jeprof_purge_arena purge {} return {}", a_string, r); } } - info!("jeprof_purge_arena purge {} arenas done", narenas); + info!("jeprof_purge_arena purge {} arenas done", narenas); } From 2dcda8a7bd9df74df70befe56bd4ed3d84025a5e Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Mon, 9 Dec 2024 18:39:40 +0800 Subject: [PATCH 05/14] add memory status Signed-off-by: Calvin Neo --- .../proxy_ffi/src/jemalloc_utils.rs | 96 +++++++++++++++++++ .../proxy_server/src/status_server/mod.rs | 10 +- .../src/status_server/vendored_utils.rs | 6 +- 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/proxy_components/proxy_ffi/src/jemalloc_utils.rs b/proxy_components/proxy_ffi/src/jemalloc_utils.rs index a37f53f0c8b..dbfe17dca52 100644 --- a/proxy_components/proxy_ffi/src/jemalloc_utils.rs +++ b/proxy_components/proxy_ffi/src/jemalloc_utils.rs @@ -1,4 +1,5 @@ // Copyright 2024 TiKV Project Authors. Licensed under Apache-2.0. +use std::sync::Mutex; extern "C" { // External jemalloc @@ -18,6 +19,12 @@ extern "C" { newp: *mut ::std::os::raw::c_void, newlen: u64, ) -> ::std::os::raw::c_int; + + pub fn malloc_stats_print( + write_cb: Option, + cbopaque: *mut c_void, + opts: *const i8, + ); } #[allow(unused_variables)] @@ -109,3 +116,92 @@ pub fn get_allocate() -> u64 { pub fn get_deallocate() -> u64 { issue_mallctl("thread.deallocated") } + +use std::{ + ffi::{c_char, c_void, CStr}, + ptr, +}; +struct CaptureContext { + buffer: Mutex, +} + +extern "C" fn write_to_string(ctx: *mut c_void, message: *const c_char) { + if ctx.is_null() || message.is_null() { + return; + } + + let context = unsafe { &*(ctx as *mut CaptureContext) }; + + let c_str = unsafe { CStr::from_ptr(message) }; + if let Ok(str_slice) = c_str.to_str() { + let mut buffer = context.buffer.lock().unwrap(); + buffer.push_str(str_slice); + } +} + +pub fn get_malloc_stats() -> String { + let context = CaptureContext { + buffer: Mutex::new(String::new()), + }; + + unsafe { + // See unprefixed_malloc_on_supported_platforms in tikv-jemalloc-sys. + #[cfg(any(test, feature = "testexport"))] + { + // Test part + #[cfg(feature = "jemalloc")] + { + // See NO_UNPREFIXED_MALLOC + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "macos"))] + _rjem_malloc_stats_print( + Some(write_to_string), + &context as *const _ as *mut c_void, + ptr::null(), + ); + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "macos" + )))] + malloc_stats_print( + Some(write_to_string), + &context as *const _ as *mut c_void, + ptr::null(), + ); + } + } + + #[cfg(not(any(test, feature = "testexport")))] + { + // No test part + #[cfg(feature = "external-jemalloc")] + { + // Must linked to tiflash. + malloc_stats_print( + Some(write_to_string), + &context as *const _ as *mut c_void, + ptr::null(), + ); + } + #[cfg(not(feature = "external-jemalloc"))] + { + // Happens only with `raftstore-proxy-main` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "macos" + )))] + { + malloc_stats_print( + Some(write_to_string), + &context as *const _ as *mut c_void, + ptr::null(), + ); + } + } + } + } + + let buffer = context.buffer.lock().unwrap(); + buffer.clone() +} diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index a492daff731..036960127e9 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -63,7 +63,7 @@ use tokio::{ sync::oneshot::{self, Receiver, Sender}, }; use tokio_openssl::SslStream; -use vendored_utils::jeprof_purge_arena; +use vendored_utils::{jeprof_memory_status, jeprof_purge_arena}; use crate::status_server::profile::set_prof_active; @@ -249,6 +249,11 @@ where Ok(make_response(StatusCode::OK, "purge OK")) } + async fn memory_status(_: Request) -> hyper::Result> { + let s = jeprof_memory_status(); + Ok(make_response(StatusCode::OK, s)) + } + #[allow(dead_code)] async fn dump_heap_prof_to_resp(req: Request) -> hyper::Result> { let query = req.uri().query().unwrap_or(""); @@ -805,6 +810,9 @@ where (Method::GET, "/debug/pprof/arena_purge") => { Self::arena_purge(req).await } + (Method::GET, "/debug/pprof/memory_status") => { + Self::memory_status(req).await + } (Method::GET, "/config") => { Self::get_config(req, &cfg_controller, engine_store_server_helper) .await diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index dac7d6489f7..55850fb18f0 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -1,6 +1,6 @@ // Copyright 2024 TiKV Project Authors. Licensed under Apache-2.0. -use proxy_ffi::jemalloc_utils::{issue_mallctl, issue_mallctl_args}; +use proxy_ffi::jemalloc_utils::{get_malloc_stats, issue_mallctl, issue_mallctl_args}; use tikv_alloc::error::ProfResult; pub fn activate_prof() -> ProfResult<()> { @@ -126,3 +126,7 @@ pub fn jeprof_purge_arena() { } info!("jeprof_purge_arena purge {} arenas done", narenas); } + +pub fn jeprof_memory_status() -> String { + return get_malloc_stats(); +} From 561478d61a66c35baf0bb167f70487f843904bb7 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Tue, 10 Dec 2024 11:20:16 +0800 Subject: [PATCH 06/14] make compiler happy Signed-off-by: Calvin Neo --- proxy_components/proxy_ffi/src/jemalloc_utils.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/proxy_components/proxy_ffi/src/jemalloc_utils.rs b/proxy_components/proxy_ffi/src/jemalloc_utils.rs index dbfe17dca52..76ce93b3b4d 100644 --- a/proxy_components/proxy_ffi/src/jemalloc_utils.rs +++ b/proxy_components/proxy_ffi/src/jemalloc_utils.rs @@ -119,12 +119,12 @@ pub fn get_deallocate() -> u64 { use std::{ ffi::{c_char, c_void, CStr}, - ptr, }; struct CaptureContext { buffer: Mutex, } +#[allow(dead_code)] extern "C" fn write_to_string(ctx: *mut c_void, message: *const c_char) { if ctx.is_null() || message.is_null() { return; @@ -139,6 +139,9 @@ extern "C" fn write_to_string(ctx: *mut c_void, message: *const c_char) { } } +#[allow(unused_variables)] +#[allow(unused_mut)] +#[allow(unused_unsafe)] pub fn get_malloc_stats() -> String { let context = CaptureContext { buffer: Mutex::new(String::new()), @@ -156,7 +159,7 @@ pub fn get_malloc_stats() -> String { _rjem_malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - ptr::null(), + std::ptr::null(), ); #[cfg(not(any( target_os = "android", @@ -166,7 +169,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - ptr::null(), + std::ptr::null(), ); } } @@ -180,7 +183,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - ptr::null(), + std::ptr::null(), ); } #[cfg(not(feature = "external-jemalloc"))] @@ -195,7 +198,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - ptr::null(), + std::ptr::null(), ); } } From e004e939f06bd1f3500ed0c7f0fa9b5ed630c269 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Tue, 10 Dec 2024 19:26:12 +0800 Subject: [PATCH 07/14] format Signed-off-by: Calvin Neo --- proxy_components/proxy_ffi/src/jemalloc_utils.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/proxy_components/proxy_ffi/src/jemalloc_utils.rs b/proxy_components/proxy_ffi/src/jemalloc_utils.rs index 76ce93b3b4d..3fca85ef2a1 100644 --- a/proxy_components/proxy_ffi/src/jemalloc_utils.rs +++ b/proxy_components/proxy_ffi/src/jemalloc_utils.rs @@ -117,9 +117,7 @@ pub fn get_deallocate() -> u64 { issue_mallctl("thread.deallocated") } -use std::{ - ffi::{c_char, c_void, CStr}, -}; +use std::ffi::{c_char, c_void, CStr}; struct CaptureContext { buffer: Mutex, } From 833906cb78d4b1b247e8ebd95d7633cea461c2ca Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Tue, 10 Dec 2024 19:47:12 +0800 Subject: [PATCH 08/14] clippy Signed-off-by: Calvin Neo --- .../proxy_server/src/status_server/vendored_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy_components/proxy_server/src/status_server/vendored_utils.rs b/proxy_components/proxy_server/src/status_server/vendored_utils.rs index 55850fb18f0..d298a0dc3f2 100644 --- a/proxy_components/proxy_server/src/status_server/vendored_utils.rs +++ b/proxy_components/proxy_server/src/status_server/vendored_utils.rs @@ -128,5 +128,5 @@ pub fn jeprof_purge_arena() { } pub fn jeprof_memory_status() -> String { - return get_malloc_stats(); + get_malloc_stats() } From a1f16b8c18452bf6eaa099ea16c704430eeb455b Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Wed, 11 Dec 2024 14:57:00 +0800 Subject: [PATCH 09/14] f Signed-off-by: Calvin Neo --- proxy_components/proxy_ffi/src/jemalloc_utils.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/proxy_components/proxy_ffi/src/jemalloc_utils.rs b/proxy_components/proxy_ffi/src/jemalloc_utils.rs index 3fca85ef2a1..ce07031fef3 100644 --- a/proxy_components/proxy_ffi/src/jemalloc_utils.rs +++ b/proxy_components/proxy_ffi/src/jemalloc_utils.rs @@ -145,6 +145,10 @@ pub fn get_malloc_stats() -> String { buffer: Mutex::new(String::new()), }; + // Use Json format. + let c_str = std::ffi::CString::new("J").unwrap(); + let ops_str = c_str.as_ptr() as *const std::os::raw::c_char; + unsafe { // See unprefixed_malloc_on_supported_platforms in tikv-jemalloc-sys. #[cfg(any(test, feature = "testexport"))] @@ -157,7 +161,7 @@ pub fn get_malloc_stats() -> String { _rjem_malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - std::ptr::null(), + ops_str, ); #[cfg(not(any( target_os = "android", @@ -167,7 +171,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - std::ptr::null(), + ops_str, ); } } @@ -181,7 +185,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - std::ptr::null(), + ops_str, ); } #[cfg(not(feature = "external-jemalloc"))] @@ -196,7 +200,7 @@ pub fn get_malloc_stats() -> String { malloc_stats_print( Some(write_to_string), &context as *const _ as *mut c_void, - std::ptr::null(), + ops_str, ); } } From db21bb8ea043f50b5ccc018e9a2d310e1875a8b1 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Fri, 13 Dec 2024 14:22:17 +0800 Subject: [PATCH 10/14] z Signed-off-by: Calvin Neo --- .../proxy_server/src/status_server/mod.rs | 35 +++---------------- .../proxy_server/src/status_server/profile.rs | 16 +++++++++ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index 036960127e9..a48c3b089d3 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -42,8 +42,8 @@ use openssl::{ }; use pin_project::pin_project; use profile::{ - activate_heap_profile, deactivate_heap_profile, jeprof_heap_profile, list_heap_profiles, - read_file, start_one_cpu_profile, start_one_heap_profile, + activate_heap_profile, deactivate_heap_profile, dump_one_heap_profile, jeprof_heap_profile, + list_heap_profiles, read_file, start_one_cpu_profile, start_one_heap_profile, }; use raftstore::store::{transport::CasualRouter, CasualMessage}; use regex::Regex; @@ -259,7 +259,6 @@ where let query = req.uri().query().unwrap_or(""); let query_pairs: HashMap<_, _> = url::form_urlencoded::parse(query.as_bytes()).collect(); - let use_jeprof = query_pairs.get("jeprof").map(|x| x.as_ref()) == Some("true"); let output_format = match query_pairs.get("text").map(|x| x.as_ref()) { None => "--svg", Some("svg") => "--svg", @@ -270,29 +269,7 @@ where } .to_string(); - let result = if let Some(name) = query_pairs.get("name") { - if use_jeprof { - jeprof_heap_profile(name, output_format) - } else { - read_file(name) - } - } else { - let mut seconds = 10; - if let Some(s) = query_pairs.get("seconds") { - match s.parse() { - Ok(val) => seconds = val, - Err(_) => { - let errmsg = "request should have seconds argument".to_owned(); - return Ok(make_response(StatusCode::BAD_REQUEST, errmsg)); - } - } - } - let timer = GLOBAL_TIMER_HANDLE.delay(Instant::now() + Duration::from_secs(seconds)); - let end = Compat01As03::new(timer) - .map_err(|_| TIMER_CANCELED.to_owned()) - .into_future(); - start_one_heap_profile(end, use_jeprof, output_format).await - }; + let result = dump_one_heap_profile(true, output_format); match result { Ok(body) => { @@ -301,11 +278,7 @@ where .header("X-Content-Type-Options", "nosniff") .header("Content-Disposition", "attachment; filename=\"profile\"") .header("Content-Length", body.len()); - response = if use_jeprof { - response.header("Content-Type", mime::IMAGE_SVG.to_string()) - } else { - response.header("Content-Type", mime::APPLICATION_OCTET_STREAM.to_string()) - }; + response = response.header("Content-Type", mime::IMAGE_SVG.to_string()); Ok(response.body(body.into()).unwrap()) } Err(e) => { diff --git a/proxy_components/proxy_server/src/status_server/profile.rs b/proxy_components/proxy_server/src/status_server/profile.rs index 2459fa499c4..96abdcc2410 100644 --- a/proxy_components/proxy_server/src/status_server/profile.rs +++ b/proxy_components/proxy_server/src/status_server/profile.rs @@ -132,6 +132,22 @@ where ProfileGuard::new(on_start, on_end, end.boxed())?.await } +/// Trigger a heap profie and return the content. +#[allow(dead_code)] +pub fn dump_one_heap_profile(use_jeprof: bool, output_format: String) -> Result, String> { + info!("dump_one_heap_profile"; "use_jeprof" => use_jeprof, "output_format" => &output_format); + let f = NamedTempFile::new().map_err(|e| format!("create tmp file fail: {}", e))?; + let path = f.path().to_str().unwrap(); + dump_prof(path).map_err(|e| format!("dump_prof: {}", e))?; + if use_jeprof { + // Use jeprof to transform heap file into svg/raw/collapsed... + jeprof_heap_profile(path, output_format) + } else { + // Juse return the heap file. + read_file(path) + } +} + pub fn set_prof_active(val: bool) -> Result<(), String> { let activate = has_activate_prof(); if activate == val { From 939f2cbfe8505697c4f27e20e53858620cca03f1 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Fri, 13 Dec 2024 18:42:49 +0800 Subject: [PATCH 11/14] f Signed-off-by: Calvin Neo --- proxy_components/proxy_server/src/status_server/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index a48c3b089d3..565c8cd8d9f 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -269,7 +269,7 @@ where } .to_string(); - let result = dump_one_heap_profile(true, output_format); + let result = dump_one_heap_profile(false, output_format); match result { Ok(body) => { From e057b0c4ef8ee308937c199e8f7dbadc587e73ae Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Fri, 13 Dec 2024 19:37:11 +0800 Subject: [PATCH 12/14] re Signed-off-by: Calvin Neo --- proxy_components/proxy_server/src/status_server/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index 565c8cd8d9f..fb8c7e4493e 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -42,8 +42,8 @@ use openssl::{ }; use pin_project::pin_project; use profile::{ - activate_heap_profile, deactivate_heap_profile, dump_one_heap_profile, jeprof_heap_profile, - list_heap_profiles, read_file, start_one_cpu_profile, start_one_heap_profile, + activate_heap_profile, deactivate_heap_profile, dump_one_heap_profile, + list_heap_profiles, start_one_cpu_profile, }; use raftstore::store::{transport::CasualRouter, CasualMessage}; use regex::Regex; @@ -259,6 +259,7 @@ where let query = req.uri().query().unwrap_or(""); let query_pairs: HashMap<_, _> = url::form_urlencoded::parse(query.as_bytes()).collect(); + let use_jeprof = query_pairs.get("jeprof").map(|x| x.as_ref()) == Some("true"); let output_format = match query_pairs.get("text").map(|x| x.as_ref()) { None => "--svg", Some("svg") => "--svg", @@ -269,7 +270,7 @@ where } .to_string(); - let result = dump_one_heap_profile(false, output_format); + let result = dump_one_heap_profile(use_jeprof, output_format); match result { Ok(body) => { From 02ee1a4145f555ddc11e47b0d53a1921e4f547c4 Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Fri, 13 Dec 2024 19:39:01 +0800 Subject: [PATCH 13/14] re Signed-off-by: Calvin Neo --- proxy_components/proxy_server/src/status_server/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index fb8c7e4493e..66cff03638a 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -279,7 +279,11 @@ where .header("X-Content-Type-Options", "nosniff") .header("Content-Disposition", "attachment; filename=\"profile\"") .header("Content-Length", body.len()); - response = response.header("Content-Type", mime::IMAGE_SVG.to_string()); + response = if use_jeprof && output_format == "--svg" { + response.header("Content-Type", mime::IMAGE_SVG.to_string()) + } else { + response.header("Content-Type", mime::APPLICATION_OCTET_STREAM.to_string()) + }; Ok(response.body(body.into()).unwrap()) } Err(e) => { From 033029693111b028a9a12359c51c33f9d77ef76c Mon Sep 17 00:00:00 2001 From: Calvin Neo Date: Mon, 16 Dec 2024 10:23:18 +0800 Subject: [PATCH 14/14] a Signed-off-by: Calvin Neo --- proxy_components/proxy_server/src/status_server/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proxy_components/proxy_server/src/status_server/mod.rs b/proxy_components/proxy_server/src/status_server/mod.rs index 66cff03638a..f38f951f862 100644 --- a/proxy_components/proxy_server/src/status_server/mod.rs +++ b/proxy_components/proxy_server/src/status_server/mod.rs @@ -42,8 +42,8 @@ use openssl::{ }; use pin_project::pin_project; use profile::{ - activate_heap_profile, deactivate_heap_profile, dump_one_heap_profile, - list_heap_profiles, start_one_cpu_profile, + activate_heap_profile, deactivate_heap_profile, dump_one_heap_profile, list_heap_profiles, + start_one_cpu_profile, }; use raftstore::store::{transport::CasualRouter, CasualMessage}; use regex::Regex; @@ -270,7 +270,7 @@ where } .to_string(); - let result = dump_one_heap_profile(use_jeprof, output_format); + let result = dump_one_heap_profile(use_jeprof, output_format.clone()); match result { Ok(body) => {