Skip to content

Commit d98ccbe

Browse files
committed
MDEV-23526 InnoDB leaks memory for some static objects
Leaks of some members of statically allocated objects are not being reported by AddressSanitizer or Valgrind, but they can be reported by implementing SAFEMALLOC instrumentation. These leaks were identified and original fixes provided by Michael Widenius and Vicențiu Ciorbaru.
1 parent f2739e2 commit d98ccbe

File tree

5 files changed

+55
-51
lines changed

5 files changed

+55
-51
lines changed

storage/innobase/include/log0log.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ class log_file_t
480480
bool writes_are_durable() const noexcept;
481481
dberr_t write(os_offset_t offset, span<const byte> buf) noexcept;
482482
dberr_t flush() noexcept;
483+
void free()
484+
{
485+
m_path.clear();
486+
m_path.shrink_to_fit();
487+
}
483488

484489
private:
485490
std::unique_ptr<file_io> m_file;

storage/innobase/include/log0recv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ struct recv_sys_t
302302

303303
void read(os_offset_t offset, span<byte> buf);
304304
inline size_t files_size();
305-
void close_files() { files.clear(); }
305+
void close_files() { files.clear(); files.shrink_to_fit(); }
306306

307307
private:
308308
/** Attempt to initialize a page based on redo log records.

storage/innobase/log/log0log.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -823,11 +823,12 @@ void log_t::file::flush()
823823

824824
void log_t::file::close_file()
825825
{
826-
if (!fd.is_opened())
827-
return;
828-
829-
if (const dberr_t err= fd.close())
830-
ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
826+
if (fd.is_opened())
827+
{
828+
if (const dberr_t err= fd.close())
829+
ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
830+
}
831+
fd.free(); // Free path
831832
}
832833

833834
/** Initialize the redo log. */

storage/innobase/log/log0recv.cc

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -907,37 +907,34 @@ fil_name_process(char* name, ulint len, ulint space_id, bool deleted)
907907
/** Clean up after recv_sys_t::create() */
908908
void recv_sys_t::close()
909909
{
910-
ut_ad(this == &recv_sys);
911-
ut_ad(!recv_writer_thread_active);
912-
913-
if (is_initialised()) {
914-
dblwr.pages.clear();
915-
ut_d(mutex_enter(&mutex));
916-
clear();
917-
ut_d(mutex_exit(&mutex));
910+
ut_ad(this == &recv_sys);
911+
ut_ad(!recv_writer_thread_active);
918912

919-
if (flush_start) {
920-
os_event_destroy(flush_start);
921-
}
913+
if (is_initialised())
914+
{
915+
dblwr.pages.clear();
916+
ut_d(mutex_enter(&mutex));
917+
clear();
918+
ut_d(mutex_exit(&mutex));
922919

923-
if (flush_end) {
924-
os_event_destroy(flush_end);
925-
}
920+
os_event_destroy(flush_start);
921+
os_event_destroy(flush_end);
926922

927-
if (buf) {
928-
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
929-
buf = NULL;
930-
}
923+
if (buf)
924+
{
925+
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
926+
buf= nullptr;
927+
}
931928

932-
last_stored_lsn = 0;
933-
mutex_free(&writer_mutex);
934-
mutex_free(&mutex);
935-
}
929+
last_stored_lsn= 0;
930+
mutex_free(&writer_mutex);
931+
mutex_free(&mutex);
932+
}
936933

937-
recv_spaces.clear();
938-
mlog_init.clear();
934+
recv_spaces.clear();
935+
mlog_init.clear();
939936

940-
files.clear();
937+
close_files();
941938
}
942939

943940
/******************************************************************//**
@@ -1060,24 +1057,25 @@ inline void recv_sys_t::clear()
10601057
/** Free most recovery data structures. */
10611058
void recv_sys_t::debug_free()
10621059
{
1063-
ut_ad(this == &recv_sys);
1064-
ut_ad(is_initialised());
1065-
mutex_enter(&mutex);
1060+
ut_ad(this == &recv_sys);
1061+
ut_ad(is_initialised());
1062+
mutex_enter(&mutex);
10661063

1067-
pages.clear();
1068-
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
1064+
pages.clear();
1065+
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
10691066

1070-
buf = NULL;
1067+
buf= nullptr;
10711068

1072-
/* wake page cleaner up to progress */
1073-
if (!srv_read_only_mode) {
1074-
ut_ad(!recv_recovery_is_on());
1075-
ut_ad(!recv_writer_thread_active);
1076-
os_event_reset(buf_flush_event);
1077-
os_event_set(flush_start);
1078-
}
1069+
/* wake page cleaner up to progress */
1070+
if (!srv_read_only_mode)
1071+
{
1072+
ut_ad(!recv_recovery_is_on());
1073+
ut_ad(!recv_writer_thread_active);
1074+
os_event_reset(buf_flush_event);
1075+
os_event_set(flush_start);
1076+
}
10791077

1080-
mutex_exit(&mutex);
1078+
mutex_exit(&mutex);
10811079
}
10821080

10831081
inline void *recv_sys_t::alloc(size_t len)

storage/innobase/srv/srv0srv.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Created 10/8/1995 Heikki Tuuri
7373
#include "fil0crypt.h"
7474
#include "fil0pagecompress.h"
7575
#include "trx0types.h"
76-
76+
#include <list>
7777

7878
#include <my_service_manager.h>
7979
/* The following is the maximum allowed duration of a lock wait. */
@@ -2110,7 +2110,7 @@ static uint32_t srv_do_purge(ulint* n_total_purged)
21102110
}
21112111

21122112

2113-
static std::queue<THD*> purge_thds;
2113+
static std::list<THD*> purge_thds;
21142114
static std::mutex purge_thd_mutex;
21152115
extern void* thd_attach_thd(THD*);
21162116
extern void thd_detach_thd(void *);
@@ -2120,11 +2120,11 @@ THD* acquire_thd(void **ctx)
21202120
std::unique_lock<std::mutex> lk(purge_thd_mutex);
21212121
if (purge_thds.empty()) {
21222122
THD* thd = current_thd;
2123-
purge_thds.push(innobase_create_background_thd("InnoDB purge worker"));
2123+
purge_thds.push_back(innobase_create_background_thd("InnoDB purge worker"));
21242124
set_current_thd(thd);
21252125
}
21262126
THD* thd = purge_thds.front();
2127-
purge_thds.pop();
2127+
purge_thds.pop_front();
21282128
lk.unlock();
21292129

21302130
/* Set current thd, and thd->mysys_var as well,
@@ -2137,7 +2137,7 @@ void release_thd(THD *thd, void *ctx)
21372137
{
21382138
thd_detach_thd(ctx);
21392139
std::unique_lock<std::mutex> lk(purge_thd_mutex);
2140-
purge_thds.push(thd);
2140+
purge_thds.push_back(thd);
21412141
lk.unlock();
21422142
set_current_thd(0);
21432143
}
@@ -2236,7 +2236,7 @@ static void srv_shutdown_purge_tasks()
22362236
while (!purge_thds.empty())
22372237
{
22382238
innobase_destroy_background_thd(purge_thds.front());
2239-
purge_thds.pop();
2239+
purge_thds.pop_front();
22402240
}
22412241
}
22422242

0 commit comments

Comments
 (0)