summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-08-21 11:54:16 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-08-21 11:54:16 +0300
commitd98ccbe1e1a8190d295fe91942ba739a12d9e245 (patch)
treec500d0b5be023530260ffaf1f85c51580b766403
parentf2739e2a96d6e73922577cd2dc8611aab81e6024 (diff)
downloadmariadb-git-d98ccbe1e1a8190d295fe91942ba739a12d9e245.tar.gz
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.
-rw-r--r--storage/innobase/include/log0log.h5
-rw-r--r--storage/innobase/include/log0recv.h2
-rw-r--r--storage/innobase/log/log0log.cc11
-rw-r--r--storage/innobase/log/log0recv.cc76
-rw-r--r--storage/innobase/srv/srv0srv.cc12
5 files changed, 55 insertions, 51 deletions
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 8a4953d7533..9eae5369d48 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -480,6 +480,11 @@ public:
bool writes_are_durable() const noexcept;
dberr_t write(os_offset_t offset, span<const byte> buf) noexcept;
dberr_t flush() noexcept;
+ void free()
+ {
+ m_path.clear();
+ m_path.shrink_to_fit();
+ }
private:
std::unique_ptr<file_io> m_file;
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index fe36b3a5c83..b8d7e40246c 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -302,7 +302,7 @@ public:
void read(os_offset_t offset, span<byte> buf);
inline size_t files_size();
- void close_files() { files.clear(); }
+ void close_files() { files.clear(); files.shrink_to_fit(); }
private:
/** Attempt to initialize a page based on redo log records.
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 62de68790ed..3e2a64a3902 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -823,11 +823,12 @@ void log_t::file::flush()
void log_t::file::close_file()
{
- if (!fd.is_opened())
- return;
-
- if (const dberr_t err= fd.close())
- ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
+ if (fd.is_opened())
+ {
+ if (const dberr_t err= fd.close())
+ ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
+ }
+ fd.free(); // Free path
}
/** Initialize the redo log. */
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 791e13e014e..46830db1323 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -907,37 +907,34 @@ fil_name_process(char* name, ulint len, ulint space_id, bool deleted)
/** Clean up after recv_sys_t::create() */
void recv_sys_t::close()
{
- ut_ad(this == &recv_sys);
- ut_ad(!recv_writer_thread_active);
-
- if (is_initialised()) {
- dblwr.pages.clear();
- ut_d(mutex_enter(&mutex));
- clear();
- ut_d(mutex_exit(&mutex));
+ ut_ad(this == &recv_sys);
+ ut_ad(!recv_writer_thread_active);
- if (flush_start) {
- os_event_destroy(flush_start);
- }
+ if (is_initialised())
+ {
+ dblwr.pages.clear();
+ ut_d(mutex_enter(&mutex));
+ clear();
+ ut_d(mutex_exit(&mutex));
- if (flush_end) {
- os_event_destroy(flush_end);
- }
+ os_event_destroy(flush_start);
+ os_event_destroy(flush_end);
- if (buf) {
- ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
- buf = NULL;
- }
+ if (buf)
+ {
+ ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
+ buf= nullptr;
+ }
- last_stored_lsn = 0;
- mutex_free(&writer_mutex);
- mutex_free(&mutex);
- }
+ last_stored_lsn= 0;
+ mutex_free(&writer_mutex);
+ mutex_free(&mutex);
+ }
- recv_spaces.clear();
- mlog_init.clear();
+ recv_spaces.clear();
+ mlog_init.clear();
- files.clear();
+ close_files();
}
/******************************************************************//**
@@ -1060,24 +1057,25 @@ inline void recv_sys_t::clear()
/** Free most recovery data structures. */
void recv_sys_t::debug_free()
{
- ut_ad(this == &recv_sys);
- ut_ad(is_initialised());
- mutex_enter(&mutex);
+ ut_ad(this == &recv_sys);
+ ut_ad(is_initialised());
+ mutex_enter(&mutex);
- pages.clear();
- ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
+ pages.clear();
+ ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
- buf = NULL;
+ buf= nullptr;
- /* wake page cleaner up to progress */
- if (!srv_read_only_mode) {
- ut_ad(!recv_recovery_is_on());
- ut_ad(!recv_writer_thread_active);
- os_event_reset(buf_flush_event);
- os_event_set(flush_start);
- }
+ /* wake page cleaner up to progress */
+ if (!srv_read_only_mode)
+ {
+ ut_ad(!recv_recovery_is_on());
+ ut_ad(!recv_writer_thread_active);
+ 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)
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index aa8a5ea2d14..ceb9245f659 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -73,7 +73,7 @@ Created 10/8/1995 Heikki Tuuri
#include "fil0crypt.h"
#include "fil0pagecompress.h"
#include "trx0types.h"
-
+#include <list>
#include <my_service_manager.h>
/* 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)
}
-static std::queue<THD*> purge_thds;
+static std::list<THD*> purge_thds;
static std::mutex purge_thd_mutex;
extern void* thd_attach_thd(THD*);
extern void thd_detach_thd(void *);
@@ -2120,11 +2120,11 @@ THD* acquire_thd(void **ctx)
std::unique_lock<std::mutex> lk(purge_thd_mutex);
if (purge_thds.empty()) {
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);
}
THD* thd = purge_thds.front();
- purge_thds.pop();
+ purge_thds.pop_front();
lk.unlock();
/* Set current thd, and thd->mysys_var as well,
@@ -2137,7 +2137,7 @@ void release_thd(THD *thd, void *ctx)
{
thd_detach_thd(ctx);
std::unique_lock<std::mutex> lk(purge_thd_mutex);
- purge_thds.push(thd);
+ purge_thds.push_back(thd);
lk.unlock();
set_current_thd(0);
}
@@ -2236,7 +2236,7 @@ static void srv_shutdown_purge_tasks()
while (!purge_thds.empty())
{
innobase_destroy_background_thd(purge_thds.front());
- purge_thds.pop();
+ purge_thds.pop_front();
}
}