mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Partial fix for Bug#11764622 57480: MEMORY LEAK WHEN HAVING 256+ TABLES
Port vasil.dimov@oracle.com-20111205082831-7v1qu50hvd9hjr3g from mysql-trunk
This commit is contained in:
@ -52,12 +52,13 @@ btr_pcur_create_for_mysql(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Frees the memory for a persistent cursor object. */
|
Resets a persistent cursor object, freeing ::old_rec_buf if it is
|
||||||
|
allocated and resetting the other members to their initial values. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
btr_pcur_free_for_mysql(
|
btr_pcur_reset(
|
||||||
/*====================*/
|
/*===========*/
|
||||||
btr_pcur_t* cursor) /*!< in, own: persistent cursor */
|
btr_pcur_t* cursor) /*!< in, out: persistent cursor */
|
||||||
{
|
{
|
||||||
if (cursor->old_rec_buf != NULL) {
|
if (cursor->old_rec_buf != NULL) {
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ btr_pcur_free_for_mysql(
|
|||||||
cursor->old_rec_buf = NULL;
|
cursor->old_rec_buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor->btr_cur.index = NULL;
|
||||||
cursor->btr_cur.page_cur.rec = NULL;
|
cursor->btr_cur.page_cur.rec = NULL;
|
||||||
cursor->old_rec = NULL;
|
cursor->old_rec = NULL;
|
||||||
cursor->old_n_fields = 0;
|
cursor->old_n_fields = 0;
|
||||||
@ -73,7 +75,17 @@ btr_pcur_free_for_mysql(
|
|||||||
|
|
||||||
cursor->latch_mode = BTR_NO_LATCHES;
|
cursor->latch_mode = BTR_NO_LATCHES;
|
||||||
cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
|
cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************//**
|
||||||
|
Frees the memory for a persistent cursor object. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
btr_pcur_free_for_mysql(
|
||||||
|
/*====================*/
|
||||||
|
btr_pcur_t* cursor) /*!< in, own: persistent cursor */
|
||||||
|
{
|
||||||
|
btr_pcur_reset(cursor);
|
||||||
mem_free(cursor);
|
mem_free(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,16 @@ UNIV_INTERN
|
|||||||
btr_pcur_t*
|
btr_pcur_t*
|
||||||
btr_pcur_create_for_mysql(void);
|
btr_pcur_create_for_mysql(void);
|
||||||
/*============================*/
|
/*============================*/
|
||||||
|
|
||||||
|
/**************************************************************//**
|
||||||
|
Resets a persistent cursor object, freeing ::old_rec_buf if it is
|
||||||
|
allocated and resetting the other members to their initial values. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
btr_pcur_reset(
|
||||||
|
/*===========*/
|
||||||
|
btr_pcur_t* cursor);/*!< in, out: persistent cursor */
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Frees the memory for a persistent cursor object. */
|
Frees the memory for a persistent cursor object. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@ -674,9 +674,9 @@ struct row_prebuilt_struct {
|
|||||||
in inserts */
|
in inserts */
|
||||||
que_fork_t* upd_graph; /*!< Innobase SQL query graph used
|
que_fork_t* upd_graph; /*!< Innobase SQL query graph used
|
||||||
in updates or deletes */
|
in updates or deletes */
|
||||||
btr_pcur_t* pcur; /*!< persistent cursor used in selects
|
btr_pcur_t pcur; /*!< persistent cursor used in selects
|
||||||
and updates */
|
and updates */
|
||||||
btr_pcur_t* clust_pcur; /*!< persistent cursor used in
|
btr_pcur_t clust_pcur; /*!< persistent cursor used in
|
||||||
some selects and updates */
|
some selects and updates */
|
||||||
que_fork_t* sel_graph; /*!< dummy query graph used in
|
que_fork_t* sel_graph; /*!< dummy query graph used in
|
||||||
selects */
|
selects */
|
||||||
|
@ -730,8 +730,8 @@ row_create_prebuilt(
|
|||||||
prebuilt->sql_stat_start = TRUE;
|
prebuilt->sql_stat_start = TRUE;
|
||||||
prebuilt->heap = heap;
|
prebuilt->heap = heap;
|
||||||
|
|
||||||
prebuilt->pcur = btr_pcur_create_for_mysql();
|
btr_pcur_reset(&prebuilt->pcur);
|
||||||
prebuilt->clust_pcur = btr_pcur_create_for_mysql();
|
btr_pcur_reset(&prebuilt->clust_pcur);
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_NONE;
|
prebuilt->select_lock_type = LOCK_NONE;
|
||||||
prebuilt->stored_select_lock_type = 99999999;
|
prebuilt->stored_select_lock_type = 99999999;
|
||||||
@ -792,8 +792,8 @@ row_prebuilt_free(
|
|||||||
prebuilt->magic_n = ROW_PREBUILT_FREED;
|
prebuilt->magic_n = ROW_PREBUILT_FREED;
|
||||||
prebuilt->magic_n2 = ROW_PREBUILT_FREED;
|
prebuilt->magic_n2 = ROW_PREBUILT_FREED;
|
||||||
|
|
||||||
btr_pcur_free_for_mysql(prebuilt->pcur);
|
btr_pcur_reset(&prebuilt->pcur);
|
||||||
btr_pcur_free_for_mysql(prebuilt->clust_pcur);
|
btr_pcur_reset(&prebuilt->clust_pcur);
|
||||||
|
|
||||||
if (prebuilt->mysql_template) {
|
if (prebuilt->mysql_template) {
|
||||||
mem_free(prebuilt->mysql_template);
|
mem_free(prebuilt->mysql_template);
|
||||||
@ -1453,11 +1453,11 @@ row_update_for_mysql(
|
|||||||
|
|
||||||
clust_index = dict_table_get_first_index(table);
|
clust_index = dict_table_get_first_index(table);
|
||||||
|
|
||||||
if (prebuilt->pcur->btr_cur.index == clust_index) {
|
if (prebuilt->pcur.btr_cur.index == clust_index) {
|
||||||
btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur);
|
btr_pcur_copy_stored_position(node->pcur, &prebuilt->pcur);
|
||||||
} else {
|
} else {
|
||||||
btr_pcur_copy_stored_position(node->pcur,
|
btr_pcur_copy_stored_position(node->pcur,
|
||||||
prebuilt->clust_pcur);
|
&prebuilt->clust_pcur);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
|
ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
|
||||||
@ -1561,8 +1561,8 @@ row_unlock_for_mysql(
|
|||||||
clust_pcur, and we do not need
|
clust_pcur, and we do not need
|
||||||
to reposition the cursors. */
|
to reposition the cursors. */
|
||||||
{
|
{
|
||||||
btr_pcur_t* pcur = prebuilt->pcur;
|
btr_pcur_t* pcur = &prebuilt->pcur;
|
||||||
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
|
btr_pcur_t* clust_pcur = &prebuilt->clust_pcur;
|
||||||
trx_t* trx = prebuilt->trx;
|
trx_t* trx = prebuilt->trx;
|
||||||
|
|
||||||
ut_ad(prebuilt && trx);
|
ut_ad(prebuilt && trx);
|
||||||
|
@ -2915,17 +2915,17 @@ row_sel_get_clust_rec_for_mysql(
|
|||||||
|
|
||||||
btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref,
|
btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref,
|
||||||
PAGE_CUR_LE, BTR_SEARCH_LEAF,
|
PAGE_CUR_LE, BTR_SEARCH_LEAF,
|
||||||
prebuilt->clust_pcur, 0, mtr);
|
&prebuilt->clust_pcur, 0, mtr);
|
||||||
|
|
||||||
clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur);
|
clust_rec = btr_pcur_get_rec(&prebuilt->clust_pcur);
|
||||||
|
|
||||||
prebuilt->clust_pcur->trx_if_known = trx;
|
prebuilt->clust_pcur.trx_if_known = trx;
|
||||||
|
|
||||||
/* Note: only if the search ends up on a non-infimum record is the
|
/* Note: only if the search ends up on a non-infimum record is the
|
||||||
low_match value the real match to the search tuple */
|
low_match value the real match to the search tuple */
|
||||||
|
|
||||||
if (!page_rec_is_user_rec(clust_rec)
|
if (!page_rec_is_user_rec(clust_rec)
|
||||||
|| btr_pcur_get_low_match(prebuilt->clust_pcur)
|
|| btr_pcur_get_low_match(&prebuilt->clust_pcur)
|
||||||
< dict_index_get_n_unique(clust_index)) {
|
< dict_index_get_n_unique(clust_index)) {
|
||||||
|
|
||||||
/* In a rare case it is possible that no clust rec is found
|
/* In a rare case it is possible that no clust rec is found
|
||||||
@ -2974,7 +2974,7 @@ row_sel_get_clust_rec_for_mysql(
|
|||||||
we set a LOCK_REC_NOT_GAP type lock */
|
we set a LOCK_REC_NOT_GAP type lock */
|
||||||
|
|
||||||
err = lock_clust_rec_read_check_and_lock(
|
err = lock_clust_rec_read_check_and_lock(
|
||||||
0, btr_pcur_get_block(prebuilt->clust_pcur),
|
0, btr_pcur_get_block(&prebuilt->clust_pcur),
|
||||||
clust_rec, clust_index, *offsets,
|
clust_rec, clust_index, *offsets,
|
||||||
prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
|
prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
@ -3052,7 +3052,7 @@ func_exit:
|
|||||||
/* We may use the cursor in update or in unlock_row():
|
/* We may use the cursor in update or in unlock_row():
|
||||||
store its position */
|
store its position */
|
||||||
|
|
||||||
btr_pcur_store_position(prebuilt->clust_pcur, mtr);
|
btr_pcur_store_position(&prebuilt->clust_pcur, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
@ -3300,7 +3300,7 @@ row_sel_try_search_shortcut_for_mysql(
|
|||||||
{
|
{
|
||||||
dict_index_t* index = prebuilt->index;
|
dict_index_t* index = prebuilt->index;
|
||||||
const dtuple_t* search_tuple = prebuilt->search_tuple;
|
const dtuple_t* search_tuple = prebuilt->search_tuple;
|
||||||
btr_pcur_t* pcur = prebuilt->pcur;
|
btr_pcur_t* pcur = &prebuilt->pcur;
|
||||||
trx_t* trx = prebuilt->trx;
|
trx_t* trx = prebuilt->trx;
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
|
|
||||||
@ -3389,7 +3389,7 @@ row_search_for_mysql(
|
|||||||
dict_index_t* index = prebuilt->index;
|
dict_index_t* index = prebuilt->index;
|
||||||
ibool comp = dict_table_is_comp(index->table);
|
ibool comp = dict_table_is_comp(index->table);
|
||||||
const dtuple_t* search_tuple = prebuilt->search_tuple;
|
const dtuple_t* search_tuple = prebuilt->search_tuple;
|
||||||
btr_pcur_t* pcur = prebuilt->pcur;
|
btr_pcur_t* pcur = &prebuilt->pcur;
|
||||||
trx_t* trx = prebuilt->trx;
|
trx_t* trx = prebuilt->trx;
|
||||||
dict_index_t* clust_index;
|
dict_index_t* clust_index;
|
||||||
que_thr_t* thr;
|
que_thr_t* thr;
|
||||||
|
Reference in New Issue
Block a user