diff options
author | unknown <tomas@poseidon.ndb.mysql.com> | 2008-02-04 15:40:04 +0100 |
---|---|---|
committer | unknown <tomas@poseidon.ndb.mysql.com> | 2008-02-04 15:40:04 +0100 |
commit | 0fe17ab3c0a941124cce1ccc2bcd16c3d93425aa (patch) | |
tree | 685cab89cfbd1464962488743c3c68ed5734a6f4 /sql/ha_ndbcluster.cc | |
parent | 0d2be94e60a0778fe559effe84a5ad34b4065704 (diff) | |
download | mariadb-git-0fe17ab3c0a941124cce1ccc2bcd16c3d93425aa.tar.gz |
Bug #34275 mysqld leak if doing multiple statements within same transaction (or wo/ trans)
- in autocommit do not allocate statistics share, but instead use one directly on the handler
Diffstat (limited to 'sql/ha_ndbcluster.cc')
-rw-r--r-- | sql/ha_ndbcluster.cc | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b4bf8e15902..b8e6ff32d37 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -313,6 +313,10 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans, /* Place holder for ha_ndbcluster thread specific data */ +typedef struct st_thd_ndb_share { + const void *key; + struct Ndb_local_table_statistics stat; +} THD_NDB_SHARE; static uchar *thd_ndb_share_get_key(THD_NDB_SHARE *thd_ndb_share, size_t *length, my_bool not_used __attribute__((unused))) @@ -369,41 +373,6 @@ Thd_ndb::init_open_tables() my_hash_reset(&open_tables); } -THD_NDB_SHARE * -Thd_ndb::get_open_table(THD *thd, const void *key) -{ - DBUG_ENTER("Thd_ndb::get_open_table"); - HASH_SEARCH_STATE state; - THD_NDB_SHARE *thd_ndb_share= - (THD_NDB_SHARE*)hash_first(&open_tables, (uchar *)&key, sizeof(key), &state); - while (thd_ndb_share && thd_ndb_share->key != key) - thd_ndb_share= (THD_NDB_SHARE*)hash_next(&open_tables, (uchar *)&key, sizeof(key), &state); - if (thd_ndb_share == 0) - { - thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root, - sizeof(THD_NDB_SHARE)); - if (!thd_ndb_share) - { - mem_alloc_error(sizeof(THD_NDB_SHARE)); - DBUG_RETURN(NULL); - } - thd_ndb_share->key= key; - thd_ndb_share->stat.last_count= count; - thd_ndb_share->stat.no_uncommitted_rows_count= 0; - thd_ndb_share->stat.records= ~(ha_rows)0; - my_hash_insert(&open_tables, (uchar *)thd_ndb_share); - } - else if (thd_ndb_share->stat.last_count != count) - { - thd_ndb_share->stat.last_count= count; - thd_ndb_share->stat.no_uncommitted_rows_count= 0; - thd_ndb_share->stat.records= ~(ha_rows)0; - } - DBUG_PRINT("exit", ("thd_ndb_share: 0x%lx key: 0x%lx", - (long) thd_ndb_share, (long) key)); - DBUG_RETURN(thd_ndb_share); -} - inline Ndb *ha_ndbcluster::get_ndb() { @@ -4554,12 +4523,48 @@ int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb) thd_ndb->trans_options|= TNTO_INJECTED_APPLY_STATUS; } #endif - // TODO remove double pointers... - if (!(m_thd_ndb_share= thd_ndb->get_open_table(thd, m_table))) + + if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { - DBUG_RETURN(1); + const void *key= m_table; + HASH_SEARCH_STATE state; + THD_NDB_SHARE *thd_ndb_share= + (THD_NDB_SHARE*)hash_first(&thd_ndb->open_tables, (uchar *)&key, sizeof(key), &state); + while (thd_ndb_share && thd_ndb_share->key != key) + thd_ndb_share= (THD_NDB_SHARE*)hash_next(&thd_ndb->open_tables, (uchar *)&key, sizeof(key), &state); + if (thd_ndb_share == 0) + { + thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root, + sizeof(THD_NDB_SHARE)); + if (!thd_ndb_share) + { + mem_alloc_error(sizeof(THD_NDB_SHARE)); + DBUG_RETURN(1); + } + thd_ndb_share->key= key; + thd_ndb_share->stat.last_count= thd_ndb->count; + thd_ndb_share->stat.no_uncommitted_rows_count= 0; + thd_ndb_share->stat.records= ~(ha_rows)0; + my_hash_insert(&thd_ndb->open_tables, (uchar *)thd_ndb_share); + } + else if (thd_ndb_share->stat.last_count != thd_ndb->count) + { + thd_ndb_share->stat.last_count= thd_ndb->count; + thd_ndb_share->stat.no_uncommitted_rows_count= 0; + thd_ndb_share->stat.records= ~(ha_rows)0; + } + DBUG_PRINT("exit", ("thd_ndb_share: 0x%lx key: 0x%lx", + (long) thd_ndb_share, (long) key)); + m_table_info= &thd_ndb_share->stat; + } + else + { + struct Ndb_local_table_statistics &stat= m_table_info_instance; + stat.last_count= thd_ndb->count; + stat.no_uncommitted_rows_count= 0; + stat.records= ~(ha_rows)0; + m_table_info= &stat; } - m_table_info= &m_thd_ndb_share->stat; DBUG_RETURN(0); } |