Commit d98ccbe1 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent f2739e2a
...@@ -480,6 +480,11 @@ class log_file_t ...@@ -480,6 +480,11 @@ class log_file_t
bool writes_are_durable() const noexcept; bool writes_are_durable() const noexcept;
dberr_t write(os_offset_t offset, span<const byte> buf) noexcept; dberr_t write(os_offset_t offset, span<const byte> buf) noexcept;
dberr_t flush() noexcept; dberr_t flush() noexcept;
void free()
{
m_path.clear();
m_path.shrink_to_fit();
}
private: private:
std::unique_ptr<file_io> m_file; std::unique_ptr<file_io> m_file;
......
...@@ -302,7 +302,7 @@ struct recv_sys_t ...@@ -302,7 +302,7 @@ struct recv_sys_t
void read(os_offset_t offset, span<byte> buf); void read(os_offset_t offset, span<byte> buf);
inline size_t files_size(); inline size_t files_size();
void close_files() { files.clear(); } void close_files() { files.clear(); files.shrink_to_fit(); }
private: private:
/** Attempt to initialize a page based on redo log records. /** Attempt to initialize a page based on redo log records.
......
...@@ -823,11 +823,12 @@ void log_t::file::flush() ...@@ -823,11 +823,12 @@ void log_t::file::flush()
void log_t::file::close_file() void log_t::file::close_file()
{ {
if (!fd.is_opened()) if (fd.is_opened())
return; {
if (const dberr_t err= fd.close())
if (const dberr_t err= fd.close()) ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
ib::fatal() << "close(" << fd.get_path() << ") returned " << err; }
fd.free(); // Free path
} }
/** Initialize the redo log. */ /** Initialize the redo log. */
......
...@@ -907,37 +907,34 @@ fil_name_process(char* name, ulint len, ulint space_id, bool deleted) ...@@ -907,37 +907,34 @@ fil_name_process(char* name, ulint len, ulint space_id, bool deleted)
/** Clean up after recv_sys_t::create() */ /** Clean up after recv_sys_t::create() */
void recv_sys_t::close() void recv_sys_t::close()
{ {
ut_ad(this == &recv_sys); ut_ad(this == &recv_sys);
ut_ad(!recv_writer_thread_active); ut_ad(!recv_writer_thread_active);
if (is_initialised()) {
dblwr.pages.clear();
ut_d(mutex_enter(&mutex));
clear();
ut_d(mutex_exit(&mutex));
if (flush_start) { if (is_initialised())
os_event_destroy(flush_start); {
} dblwr.pages.clear();
ut_d(mutex_enter(&mutex));
clear();
ut_d(mutex_exit(&mutex));
if (flush_end) { os_event_destroy(flush_start);
os_event_destroy(flush_end); os_event_destroy(flush_end);
}
if (buf) { if (buf)
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE); {
buf = NULL; ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
} buf= nullptr;
}
last_stored_lsn = 0; last_stored_lsn= 0;
mutex_free(&writer_mutex); mutex_free(&writer_mutex);
mutex_free(&mutex); mutex_free(&mutex);
} }
recv_spaces.clear(); recv_spaces.clear();
mlog_init.clear(); mlog_init.clear();
files.clear(); close_files();
} }
/******************************************************************//** /******************************************************************//**
...@@ -1060,24 +1057,25 @@ inline void recv_sys_t::clear() ...@@ -1060,24 +1057,25 @@ inline void recv_sys_t::clear()
/** Free most recovery data structures. */ /** Free most recovery data structures. */
void recv_sys_t::debug_free() void recv_sys_t::debug_free()
{ {
ut_ad(this == &recv_sys); ut_ad(this == &recv_sys);
ut_ad(is_initialised()); ut_ad(is_initialised());
mutex_enter(&mutex); mutex_enter(&mutex);
pages.clear(); pages.clear();
ut_free_dodump(buf, RECV_PARSING_BUF_SIZE); ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
buf = NULL; buf= nullptr;
/* wake page cleaner up to progress */ /* wake page cleaner up to progress */
if (!srv_read_only_mode) { if (!srv_read_only_mode)
ut_ad(!recv_recovery_is_on()); {
ut_ad(!recv_writer_thread_active); ut_ad(!recv_recovery_is_on());
os_event_reset(buf_flush_event); ut_ad(!recv_writer_thread_active);
os_event_set(flush_start); os_event_reset(buf_flush_event);
} os_event_set(flush_start);
}
mutex_exit(&mutex); mutex_exit(&mutex);
} }
inline void *recv_sys_t::alloc(size_t len) inline void *recv_sys_t::alloc(size_t len)
......
...@@ -73,7 +73,7 @@ Created 10/8/1995 Heikki Tuuri ...@@ -73,7 +73,7 @@ Created 10/8/1995 Heikki Tuuri
#include "fil0crypt.h" #include "fil0crypt.h"
#include "fil0pagecompress.h" #include "fil0pagecompress.h"
#include "trx0types.h" #include "trx0types.h"
#include <list>
#include <my_service_manager.h> #include <my_service_manager.h>
/* The following is the maximum allowed duration of a lock wait. */ /* 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) ...@@ -2110,7 +2110,7 @@ static uint32_t srv_do_purge(ulint* n_total_purged)
} }
static std::queue<THD*> purge_thds; static std::list<THD*> purge_thds;
static std::mutex purge_thd_mutex; static std::mutex purge_thd_mutex;
extern void* thd_attach_thd(THD*); extern void* thd_attach_thd(THD*);
extern void thd_detach_thd(void *); extern void thd_detach_thd(void *);
...@@ -2120,11 +2120,11 @@ THD* acquire_thd(void **ctx) ...@@ -2120,11 +2120,11 @@ THD* acquire_thd(void **ctx)
std::unique_lock<std::mutex> lk(purge_thd_mutex); std::unique_lock<std::mutex> lk(purge_thd_mutex);
if (purge_thds.empty()) { if (purge_thds.empty()) {
THD* thd = current_thd; THD* thd = current_thd;
purge_thds.push(innobase_create_background_thd("InnoDB purge worker")); purge_thds.push_back(innobase_create_background_thd("InnoDB purge worker"));
set_current_thd(thd); set_current_thd(thd);
} }
THD* thd = purge_thds.front(); THD* thd = purge_thds.front();
purge_thds.pop(); purge_thds.pop_front();
lk.unlock(); lk.unlock();
/* Set current thd, and thd->mysys_var as well, /* Set current thd, and thd->mysys_var as well,
...@@ -2137,7 +2137,7 @@ void release_thd(THD *thd, void *ctx) ...@@ -2137,7 +2137,7 @@ void release_thd(THD *thd, void *ctx)
{ {
thd_detach_thd(ctx); thd_detach_thd(ctx);
std::unique_lock<std::mutex> lk(purge_thd_mutex); std::unique_lock<std::mutex> lk(purge_thd_mutex);
purge_thds.push(thd); purge_thds.push_back(thd);
lk.unlock(); lk.unlock();
set_current_thd(0); set_current_thd(0);
} }
...@@ -2236,7 +2236,7 @@ static void srv_shutdown_purge_tasks() ...@@ -2236,7 +2236,7 @@ static void srv_shutdown_purge_tasks()
while (!purge_thds.empty()) while (!purge_thds.empty())
{ {
innobase_destroy_background_thd(purge_thds.front()); innobase_destroy_background_thd(purge_thds.front());
purge_thds.pop(); purge_thds.pop_front();
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment