[MDEV-6212] TokuDB: memory leak in external_lock Created: 2014-05-06  Updated: 2022-09-08

Status: Open
Project: MariaDB Server
Component/s: None
Affects Version/s: 5.5.37, 10.0.10
Fix Version/s: 5.5

Type: Bug Priority: Minor
Reporter: Sergey Vojtovich Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: tokudb, upstream

Issue Links:
Relates
relates to MDEV-6083 Assertion `! (&(&LOCK_open)->m_mutex)... Closed

 Description   

A split from MDEV-6083. Please note that 5.5 is also affected, just comment out assertion in intern_sys_var_ptr().

# It's not necessary to install TokuDB at runtime, 
# instead the server can be run with --plugin-load=ha_tokudb
 
INSTALL SONAME 'ha_tokudb';
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT) ENGINE=TokuDB;
INSERT INTO t1 VALUES (1),(2);
UNINSTALL SONAME 'ha_tokudb';
 
# Let server to shutdown (with MTR, it happens on its own)

==2806== 212 bytes in 1 blocks are still reachable in loss record 9 of 10
==2806==    at 0x4C28CCE: malloc (vg_replace_malloc.c:292)
==2806==    by 0xE3853F: sf_malloc (safemalloc.c:115)
==2806==    by 0xE276A6: my_malloc (my_malloc.c:100)
==2806==    by 0xD63B40C: ???
==2806==    by 0xD63EEA2: ???
==2806==    by 0xD64F7DE: ???
==2806==    by 0x869CC7: handler::ha_external_lock(THD*, int) (handler.cc:5843)
==2806==    by 0x93F723: lock_external(THD*, TABLE**, unsigned int) (lock.cc:357)
==2806==    by 0x93F4A3: mysql_lock_tables(THD*, st_mysql_lock*, unsigned int) (lock.cc:309)
==2806==    by 0x93F3B4: mysql_lock_tables(THD*, TABLE**, unsigned int, unsigned int) (lock.cc:276)
==2806==    by 0x61937F: lock_tables(THD*, TABLE_LIST*, unsigned int, unsigned int) (sql_base.cc:5310)
==2806==    by 0x618B3A: open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int, Prelocking_strategy*) (sql_base.cc:5081)
==2806==    by 0x60D1E2: open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int) (sql_base.h:485)
==2806==    by 0x655BE1: mysql_insert(THD*, TABLE_LIST*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) (sql_insert.cc:722)
==2806==    by 0x676262: mysql_execute_command(THD*) (sql_parse.cc:3471)
==2806==    by 0x67E48E: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6452)



 Comments   
Comment by Rich Prohaska [ 2014-05-06 ]

client runs the insert statement.

tokudb::external lock sets thd->ha_data[tokudb_hton->slot] = malloced tokudb_trx_data.

client uninstalls the tokudb plugin. the tokudb_hton->close_connection function does not get called, so the tokudb trx data does not get freed.

valgrind proclaims a leak.

IMO, the uninstall of the plugin should call the close_connection function for all THD's that have used the plugin. this is not happening.

Comment by Sergey Vojtovich [ 2014-05-06 ]

Hi Rich,

there is an API which should be used to set/get ha_data, which TokuDB doesn't seem to follow. For details please see the following revision:

revno: 2661.599.1
revision-id: svoj@sun.com-20100414095359-0sca2h1203eeybar
parent: sergey.glukhov@sun.com-20100329134249-03wyhzp5k92dzhcb
committer: Sergey Vojtovich <svoj@sun.com>
branch nick: mysql-5.1-bugteam-bug39053
timestamp: Wed 2010-04-14 13:53:59 +0400
message:
  BUG#39053 - UNISTALL PLUGIN does not allow the storage engine
              to cleanup open connections
 
  It was possible to UNINSTALL storage engine plugin when binding
  between THD object and storage engine is still active (e.g. in
  the middle of transaction).
 
  To avoid unclean deactivation (uninstall) of storage engine plugin
  in the middle of transaction, additional storage engine plugin
  lock is acquired by thd_set_ha_data().
 
  If ha_data is not null and storage engine plugin was not locked
  by thd_set_ha_data() in this connection before, storage engine
  plugin gets locked.
 
  If ha_data is null and storage engine plugin was locked by
  thd_set_ha_data() in this connection before, storage engine
  plugin lock gets released.
 
  If handlerton::close_connection() didn't reset ha_data, server does
  it immediately after calling handlerton::close_connection().
 
  Note that this is just a framework fix, storage engines must switch
  to thd_set_ha_data() from thd_ha_data() if they want to see fit.

Comment by Rich Prohaska [ 2014-05-06 ]

after using thd_set/ha_data and thd_ha_data, the memory leak still exists. in addition, this is now in the error log:

140506 14:48:10 [ERROR] Plugin 'TokuDB' has ref_count=1 after shutdown.

so, there is another problem. what event other than close_connection would get rid of the plugin reference?

Comment by Sergey Vojtovich [ 2014-05-06 ]

Could you share your patch? I can't remember at glance extra requirements, but this error in the log looks like a sign that we're on a right way.

Comment by Sergey Vojtovich [ 2014-05-07 ]

Rich,

fwics TokuDB doesn't reset ha_data thus this error and memory leak. It should call thd_set_ha_data(thd, hton, NULL) whenever ha_data is not needed anymore. I suppose in case of TokuDB it is transaction commit/rollback/cancel/abort/whatever.

Generated at Thu Feb 08 07:10:11 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.