diff options
author | unknown <svoj@april.(none)> | 2006-04-19 15:13:50 +0500 |
---|---|---|
committer | unknown <svoj@april.(none)> | 2006-04-19 15:13:50 +0500 |
commit | 4441e34e38acc430a229844a85756891221068a4 (patch) | |
tree | 5bb95b29ccad280aca995617952fa4dd8c747dc3 | |
parent | 8077c693a60bc9b5d0d0fee19712e9dcda5cc5ff (diff) | |
download | mariadb-git-4441e34e38acc430a229844a85756891221068a4.tar.gz |
BUG#18160 - Memory-/HEAP Table endless growing indexes
Updating data in HEAP table with BTREE index results in wrong index_length
counter value, which keeps growing after each update.
When inserting new record into tree counter is incremented by:
sizeof(TREE_ELEMENT) + key_size + tree->size_of_element
But when deleting element from tree it doesn't decrement counter by key_size:
sizeof(TREE_ELEMENT) + tree->size_of_element
This fix makes accurate allocated memory counter for tree. That is
decrease counter by key_size when deleting tree element.
heap/hp_delete.c:
Added size of the key to tree_delete() for accurate allocated memory counter.
include/my_tree.h:
Added size of the key to tree_delete() for accurate allocated memory counter.
myisam/myisamlog.c:
Added size of the key to tree_delete() for accurate allocated memory counter.
mysql-test/r/heap_btree.result:
Testcase for BUG#18160.
mysql-test/t/heap_btree.test:
Testcase for BUG#18160.
mysys/tree.c:
Added size of the key to tree_delete() for accurate allocated memory counter.
Note that this size is optional. If one doesn't need precise counter it is safe
to pass 0 as key_size.
-rw-r--r-- | heap/hp_delete.c | 3 | ||||
-rw-r--r-- | include/my_tree.h | 2 | ||||
-rw-r--r-- | myisam/myisamlog.c | 2 | ||||
-rw-r--r-- | mysql-test/r/heap_btree.result | 10 | ||||
-rw-r--r-- | mysql-test/t/heap_btree.test | 10 | ||||
-rw-r--r-- | mysys/tree.c | 5 |
6 files changed, 26 insertions, 6 deletions
diff --git a/heap/hp_delete.c b/heap/hp_delete.c index 2d94418a1bf..f37db2588f3 100644 --- a/heap/hp_delete.c +++ b/heap/hp_delete.c @@ -79,7 +79,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); custom_arg.search_flag= SEARCH_SAME; old_allocated= keyinfo->rb_tree.allocated; - res= tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg); + res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length, + &custom_arg); info->s->index_length-= (old_allocated - keyinfo->rb_tree.allocated); return res; } diff --git a/include/my_tree.h b/include/my_tree.h index 14d8593b6dc..03dc9d5c829 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -84,7 +84,7 @@ TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size, void *tree_search(TREE *tree, void *key, void *custom_arg); int tree_walk(TREE *tree,tree_walk_action action, void *argument, TREE_WALK visit); -int tree_delete(TREE *tree, void *key, void *custom_arg); +int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg); void *tree_search_key(TREE *tree, const void *key, TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos, enum ha_rkey_function flag, void *custom_arg); diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c index de55b86252c..17af4ab34a2 100644 --- a/myisam/myisamlog.c +++ b/myisam/myisamlog.c @@ -475,7 +475,7 @@ static int examine_log(my_string file_name, char **table_names) { if (!curr_file_info->closed) files_open--; - VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg)); + VOID(tree_delete(&tree, (gptr) curr_file_info, 0, tree.custom_arg)); } break; case MI_LOG_EXTRA: diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 374d2c63632..b63eaf7e48c 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -246,3 +246,13 @@ DELETE from t1 where a < 100; SELECT * from t1; a DROP TABLE t1; +CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; +INSERT INTO t1 VALUES(0); +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +INDEX_LENGTH +21 +UPDATE t1 SET val=1; +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +INDEX_LENGTH +21 +DROP TABLE t1; diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 5e493c2643b..eadb1fec8ae 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -164,4 +164,14 @@ DELETE from t1 where a < 100; SELECT * from t1; DROP TABLE t1; +# +# BUG#18160 - Memory-/HEAP Table endless growing indexes +# +CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; +INSERT INTO t1 VALUES(0); +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +UPDATE t1 SET val=1; +SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysys/tree.c b/mysys/tree.c index 1780913961e..0c9c04919b0 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -271,7 +271,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, return element; } -int tree_delete(TREE *tree, void *key, void *custom_arg) +int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg) { int cmp,remove_colour; TREE_ELEMENT *element,***parent, ***org_parent, *nod; @@ -326,8 +326,7 @@ int tree_delete(TREE *tree, void *key, void *custom_arg) rb_delete_fixup(tree,parent); if (tree->free) (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg); - /* This doesn't include key_size, but better than nothing */ - tree->allocated-= sizeof(TREE_ELEMENT)+tree->size_of_element; + tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size; my_free((gptr) element,MYF(0)); tree->elements_in_tree--; return 0; |