From 288eee140541e4c053489b6ca0b23ee3472a98a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Wed, 10 Apr 2024 12:19:17 +0200 Subject: [PATCH 1/3] Add 'prof_accum' to jemalloc defaults Activate cumulative object/byte counts in profile dumps. This mode increments memory consumption, but it also increases the chances of detection of small and consistent leaks. It also enables extra accumulative memory metrics, e.g: jeprof 'alloc_space'. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index aaac09822c..700272f29a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -409,7 +409,7 @@ static volatile int load_; //#else //const char *malloc_conf = "xmalloc:true,lg_tcache_max:16,purge:decay"; #ifndef __FreeBSD__ -const char *malloc_conf = "xmalloc:true,lg_tcache_max:16,prof:true,prof_leak:true,lg_prof_sample:20,lg_prof_interval:30,prof_active:false"; +const char *malloc_conf = "xmalloc:true,lg_tcache_max:16,prof:true,prof_accum:true,prof_leak:true,lg_prof_sample:20,lg_prof_interval:30,prof_active:false"; #endif //#endif /* DEBUG */ //const char *malloc_conf = "prof_leak:true,lg_prof_sample:0,prof_final:true,xmalloc:true,lg_tcache_max:16"; From 0a38bd435d5e3ba27b9492200d5fc066d83e9490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Wed, 10 Apr 2024 15:55:39 +0200 Subject: [PATCH 2/3] Print jemalloc default config on startup Since jemalloc config can be changed via 'MALLOC_CONF' env variable, printing on startup ensures that we can check in the error log if the default config has been overridden. --- src/Makefile | 9 ++++++++- src/main.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 0d2e577cf2..40480140b9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -149,11 +149,18 @@ ifeq ($(TEST_WITHASAN),1) WASAN += -DTEST_WITHASAN endif +NOJEMALLOC := $(shell echo $(NOJEMALLOC)) +ifeq ($(NOJEMALLOC),1) +NOJEM=-DNOJEM +else +NOJEM= +endif + MYCXXFLAGS := $(STDCPP) ifeq ($(CXX),clang++) MYCXXFLAGS += -fuse-ld=lld endif -MYCXXFLAGS += $(IDIRS) $(OPTZ) $(DEBUG) $(PSQLCH) -DGITVERSION=\"$(GIT_VERSION)\" $(WGCOV) $(WASAN) +MYCXXFLAGS += $(IDIRS) $(OPTZ) $(DEBUG) $(PSQLCH) -DGITVERSION=\"$(GIT_VERSION)\" $(NOJEM) $(WGCOV) $(WASAN) STATICMYLIBS := -Wl,-Bstatic -lconfig -lproxysql -ldaemon -lconfig++ -lre2 -lpcrecpp -lpcre -lmariadbclient -lhttpserver -lmicrohttpd -linjection -lcurl -lssl -lcrypto -lev diff --git a/src/main.cpp b/src/main.cpp index 700272f29a..34f6f12e79 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1902,7 +1902,61 @@ void handleProcessRestart() { } while (pid > 0); } +#ifndef NOJEM +int print_jemalloc_conf() { + int rc = 0; + + bool xmalloc = 0; + bool prof_accum = 0; + bool prof_leak = 0; + + size_t lg_cache_max = 0; + size_t lg_prof_sample = 0; + size_t lg_prof_interval = 0; + + size_t bool_sz = sizeof(bool); + size_t size_sz = sizeof(size_t); + size_t ssize_sz = sizeof(ssize_t); + + rc = mallctl("config.xmalloc", &xmalloc, &bool_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'config.xmalloc' with error %d", rc); return rc; } + + rc = mallctl("opt.lg_tcache_max", &lg_cache_max, &size_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'opt.lg_tcache_max' with error %d", rc); return rc; } + + rc = mallctl("opt.prof_accum", &prof_accum, &bool_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'opt.prof_accum' with error %d", rc); return rc; } + + rc = mallctl("opt.prof_leak", &prof_leak, &bool_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'opt.prof_leak' with error %d", rc); return rc; } + + rc = mallctl("opt.lg_prof_sample", &lg_prof_sample, &size_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'opt.lg_prof_sample' with error %d", rc); return rc; } + + rc = mallctl("opt.lg_prof_interval", &lg_prof_interval, &ssize_sz, NULL, 0); + if (rc) { proxy_error("Failed to fetch 'opt.lg_prof_interval' with error %d", rc); return rc; } + + proxy_info( + "Using jemalloc with MALLOC_CONF:" + " config.xmalloc:%d, lg_tcache_max:%lu, opt.prof_accum:%d, opt.prof_leak:%d," + " opt.lg_prof_sample:%lu, opt.lg_prof_interval:%lu, rc:%d\n", + xmalloc, lg_cache_max, prof_accum, prof_leak, lg_prof_sample, lg_prof_interval, rc + ); + + return 0; +} +#else +int print_jemalloc_conf() { + return 0; +} +#endif + int main(int argc, const char * argv[]) { + // Output current jemalloc conf; no action taken when disabled + { + int rc = print_jemalloc_conf(); + if (rc) { exit(EXIT_FAILURE); } + } { MYSQL *my = mysql_init(NULL); From 9894621db1938f462490bf1480b83a9c2b3bfd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Wed, 10 Apr 2024 16:00:40 +0200 Subject: [PATCH 3/3] Fix GCC type mismatch warning on 'proxy_info' --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 34f6f12e79..0e1335d04d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1859,7 +1859,7 @@ void handleProcessRestart() { // Calculate wait time using exponential backoff int waitTime = 1 << restartAttempts; parent_open_error_log(); - proxy_info("ProxySQL exited after only %d seconds , below the %d seconds threshold. Restarting attempt %d\n", elapsed_seconds, EXECUTION_THRESHOLD, restartAttempts); + proxy_info("ProxySQL exited after only %ld seconds , below the %d seconds threshold. Restarting attempt %d\n", elapsed_seconds, EXECUTION_THRESHOLD, restartAttempts); proxy_info("Angel process is waiting %d seconds before starting a new ProxySQL process\n", waitTime); parent_close_error_log();