summaryrefslogtreecommitdiff
path: root/sql/ha_ndbcluster.cc
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2008-02-04 15:40:04 +0100
committerunknown <tomas@poseidon.ndb.mysql.com>2008-02-04 15:40:04 +0100
commit0fe17ab3c0a941124cce1ccc2bcd16c3d93425aa (patch)
tree685cab89cfbd1464962488743c3c68ed5734a6f4 /sql/ha_ndbcluster.cc
parent0d2be94e60a0778fe559effe84a5ad34b4065704 (diff)
downloadmariadb-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.cc83
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);
}