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
This commit is contained in:
parent
0d2be94e60
commit
0fe17ab3c0
@ -313,6 +313,10 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans,
|
|||||||
/*
|
/*
|
||||||
Place holder for ha_ndbcluster thread specific data
|
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
|
static
|
||||||
uchar *thd_ndb_share_get_key(THD_NDB_SHARE *thd_ndb_share, size_t *length,
|
uchar *thd_ndb_share_get_key(THD_NDB_SHARE *thd_ndb_share, size_t *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
@ -369,41 +373,6 @@ Thd_ndb::init_open_tables()
|
|||||||
my_hash_reset(&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
|
inline
|
||||||
Ndb *ha_ndbcluster::get_ndb()
|
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;
|
thd_ndb->trans_options|= TNTO_INJECTED_APPLY_STATUS;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,11 +195,6 @@ struct Ndb_local_table_statistics {
|
|||||||
ha_rows records;
|
ha_rows records;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct st_thd_ndb_share {
|
|
||||||
const void *key;
|
|
||||||
struct Ndb_local_table_statistics stat;
|
|
||||||
} THD_NDB_SHARE;
|
|
||||||
|
|
||||||
class Thd_ndb
|
class Thd_ndb
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -207,7 +202,6 @@ class Thd_ndb
|
|||||||
~Thd_ndb();
|
~Thd_ndb();
|
||||||
|
|
||||||
void init_open_tables();
|
void init_open_tables();
|
||||||
THD_NDB_SHARE *get_open_table(THD *thd, const void *key);
|
|
||||||
|
|
||||||
Ndb *ndb;
|
Ndb *ndb;
|
||||||
ulong count;
|
ulong count;
|
||||||
@ -514,6 +508,7 @@ private:
|
|||||||
NdbScanOperation *m_active_cursor;
|
NdbScanOperation *m_active_cursor;
|
||||||
const NdbDictionary::Table *m_table;
|
const NdbDictionary::Table *m_table;
|
||||||
struct Ndb_local_table_statistics *m_table_info;
|
struct Ndb_local_table_statistics *m_table_info;
|
||||||
|
struct Ndb_local_table_statistics m_table_info_instance;
|
||||||
char m_dbname[FN_HEADLEN];
|
char m_dbname[FN_HEADLEN];
|
||||||
//char m_schemaname[FN_HEADLEN];
|
//char m_schemaname[FN_HEADLEN];
|
||||||
char m_tabname[FN_HEADLEN];
|
char m_tabname[FN_HEADLEN];
|
||||||
@ -522,7 +517,6 @@ private:
|
|||||||
bool m_lock_tuple;
|
bool m_lock_tuple;
|
||||||
NDB_SHARE *m_share;
|
NDB_SHARE *m_share;
|
||||||
NDB_INDEX_DATA m_index[MAX_KEY];
|
NDB_INDEX_DATA m_index[MAX_KEY];
|
||||||
THD_NDB_SHARE *m_thd_ndb_share;
|
|
||||||
// NdbRecAttr has no reference to blob
|
// NdbRecAttr has no reference to blob
|
||||||
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
|
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
|
||||||
uchar m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH];
|
uchar m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user