From 626afa7e5a0936fad899d509864c7e24bb64ce89 Mon Sep 17 00:00:00 2001 From: "acurtis/antony@xiphis.org/ltamd64.xiphis.org" <> Date: Tue, 24 Oct 2006 16:41:13 -0700 Subject: [PATCH 1/6] Bug#22694 "function plugin_foreach_with_mask() uses an uninitialized pointer" Fix uninitialized memory. --- sql/sql_plugin.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 34fb447792e..3b9fb1b249f 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -944,29 +944,28 @@ my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, state_mask= ~state_mask; // do it only once rw_rdlock(&THR_LOCK_plugin); + total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements + : plugin_hash[type].records; + /* + Do the alloca out here in case we do have a working alloca: + leaving the nested stack frame invalidates alloca allocation. + */ + plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); if (type == MYSQL_ANY_PLUGIN) { - total=plugin_array.elements; - plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); for (idx= 0; idx < total; idx++) { plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); - if (plugin->state & state_mask) - continue; - plugins[idx]= plugin; + plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; } } else { - HASH *hash= &plugin_hash[type]; - total=hash->records; - plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); + HASH *hash= plugin_hash + type; for (idx= 0; idx < total; idx++) { plugin= (struct st_plugin_int *) hash_element(hash, idx); - if (plugin->state & state_mask) - continue; - plugins[idx]= plugin; + plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; } } rw_unlock(&THR_LOCK_plugin); From cdb8358503e38d3f6bc4aca624c9da1e0211a42e Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/april.(none)" <> Date: Wed, 25 Oct 2006 15:40:10 +0500 Subject: [PATCH 2/6] BUG#22053 - REPAIR table can crash server for some really damaged MyISAM tables When unpacking a blob column from broken row server crash could happen. This could rather happen when trying to repair a table using either REPAIR TABLE or myisamchk, though it also could happend when trying to access broken row using other SQL statements like SELECT if table is not marked as crashed. Fixed ulong overflow when trying to extract blob from broken row. Affects MyISAM only. --- myisam/mi_dynrec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 4dec3055fa1..727f44341b1 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -992,9 +992,11 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from, { uint size_length=rec_length- mi_portable_sizeof_char_ptr; ulong blob_length=_mi_calc_blob_length(size_length,from); - if ((ulong) (from_end-from) - size_length < blob_length || - min_pack_length > (uint) (from_end -(from+size_length+blob_length))) - goto err; + ulong from_left= (ulong) (from_end - from); + if (from_left < size_length || + from_left - size_length < blob_length || + from_left - size_length - blob_length < min_pack_length) + goto err; memcpy((byte*) to,(byte*) from,(size_t) size_length); from+=size_length; memcpy_fixed((byte*) to+size_length,(byte*) &from,sizeof(char*)); From 7dc7af51e03dde227861e3338a6113edd0d740f4 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Wed, 25 Oct 2006 13:39:40 +0200 Subject: [PATCH 3/6] Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk When compiling with a default key block size greater than the smallest key block size used in a table, checking that table failed with bogus errors. The table was marked corrupt. This affected myisamchk and the server. The problem was that the default key block size was used at some places where sizes less or equal to the block size of the index in check was required. We do now use the key block size of the particular index when checking. A test case is available for later versions only. --- myisam/mi_check.c | 88 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index b07c9904247..3a7817b7f03 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -251,11 +251,12 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) my_off_t next_link; uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH; ha_rows records; - char llbuff[21],*buff; + char llbuff[21], llbuff2[21], *buff; DBUG_ENTER("check_k_link"); + DBUG_PRINT("enter", ("block_size: %u", block_size)); if (param->testflag & T_VERBOSE) - printf("block_size %4d:",block_size); + printf("block_size %4u:", block_size); /* purecov: tested */ next_link=info->s->state.key_del[nr]; records= (ha_rows) (info->state->key_file_length / block_size); @@ -265,14 +266,46 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) DBUG_RETURN(1); if (param->testflag & T_VERBOSE) printf("%16s",llstr(next_link,llbuff)); - if (next_link > info->state->key_file_length || - next_link & (info->s->blocksize-1)) + + /* Key blocks must lay within the key file length entirely. */ + if (next_link + block_size > info->state->key_file_length) + { + /* purecov: begin tested */ + mi_check_print_error(param, "Invalid key block position: %s " + "key block size: %u file_length: %s", + llstr(next_link, llbuff), block_size, + llstr(info->state->key_file_length, llbuff2)); DBUG_RETURN(1); + /* purecov: end */ + } + + /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */ + if (next_link & (MI_MIN_KEY_BLOCK_LENGTH - 1)) + { + /* purecov: begin tested */ + mi_check_print_error(param, "Mis-aligned key block: %s " + "minimum key block length: %u", + llstr(next_link, llbuff), MI_MIN_KEY_BLOCK_LENGTH); + DBUG_RETURN(1); + /* purecov: end */ + } + + /* + Read the key block with MI_MIN_KEY_BLOCK_LENGTH to find next link. + If the key cache block size is smaller than block_size, we can so + avoid unecessary eviction of cache block. + */ if (!(buff=key_cache_read(info->s->key_cache, info->s->kfile, next_link, DFLT_INIT_HITS, - (byte*) info->buff, - myisam_block_size, block_size, 1))) + (byte*) info->buff, MI_MIN_KEY_BLOCK_LENGTH, + MI_MIN_KEY_BLOCK_LENGTH, 1))) + { + /* purecov: begin tested */ + mi_check_print_error(param, "key cache read error for block: %s", + llstr(next_link,llbuff)); DBUG_RETURN(1); + /* purecov: end */ + } next_link=mi_sizekorr(buff); records--; param->key_file_blocks+=block_size; @@ -555,17 +588,37 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, ha_checksum *key_checksum, uint level) { char llbuff[22],llbuff2[22]; - if (page > info->state->key_file_length || (page & (info->s->blocksize -1))) - { - my_off_t max_length=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); - mi_check_print_error(param,"Wrong pagepointer: %s at page: %s", - llstr(page,llbuff),llstr(page,llbuff2)); + DBUG_ENTER("chk_index_down"); - if (page+info->s->blocksize > max_length) + /* Key blocks must lay within the key file length entirely. */ + if (page + keyinfo->block_length > info->state->key_file_length) + { + /* purecov: begin tested */ + /* Give it a chance to fit in the real file size. */ + my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(0)); + mi_check_print_error(param, "Invalid key block position: %s " + "key block size: %u file_length: %s", + llstr(page, llbuff), keyinfo->block_length, + llstr(info->state->key_file_length, llbuff2)); + if (page + keyinfo->block_length > max_length) goto err; - info->state->key_file_length=(max_length & - ~ (my_off_t) (info->s->blocksize-1)); + /* Fix the remebered key file length. */ + info->state->key_file_length= (max_length & + ~ (my_off_t) (keyinfo->block_length - 1)); + /* purecov: end */ } + + /* Key blocks must be aligned at MI_MIN_KEY_BLOCK_LENGTH. */ + if (page & (MI_MIN_KEY_BLOCK_LENGTH - 1)) + { + /* purecov: begin tested */ + mi_check_print_error(param, "Mis-aligned key block: %s " + "minimum key block length: %u", + llstr(page, llbuff), MI_MIN_KEY_BLOCK_LENGTH); + goto err; + /* purecov: end */ + } + if (!_mi_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0)) { mi_check_print_error(param,"Can't read key from filepos: %s", @@ -576,9 +629,12 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level)) goto err; - return 0; + DBUG_RETURN(0); + + /* purecov: begin tested */ err: - return 1; + DBUG_RETURN(1); + /* purecov: end */ } From 931f7dbc892530c6977d795d3d59c5dc1e6015f2 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Wed, 25 Oct 2006 17:23:32 +0200 Subject: [PATCH 4/6] Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk Added the promised test case. --- mysql-test/r/myisam.result | 45 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/myisam.test | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 69069825588..66a8e51c4d2 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1757,4 +1757,49 @@ create table t1 (a int not null, key key_block_size=1024 (a)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1 create table t1 (a int not null, key `a` key_block_size=1024 (a)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key_block_size=1024 (a))' at line 1 +CREATE TABLE t1 ( +c1 INT, +c2 VARCHAR(300), +KEY (c1) KEY_BLOCK_SIZE 1024, +KEY (c2) KEY_BLOCK_SIZE 8192 +); +INSERT INTO t1 VALUES (10, REPEAT('a', CEIL(RAND(10) * 300))), +(11, REPEAT('b', CEIL(RAND() * 300))), +(12, REPEAT('c', CEIL(RAND() * 300))), +(13, REPEAT('d', CEIL(RAND() * 300))), +(14, REPEAT('e', CEIL(RAND() * 300))), +(15, REPEAT('f', CEIL(RAND() * 300))), +(16, REPEAT('g', CEIL(RAND() * 300))), +(17, REPEAT('h', CEIL(RAND() * 300))), +(18, REPEAT('i', CEIL(RAND() * 300))), +(19, REPEAT('j', CEIL(RAND() * 300))), +(20, REPEAT('k', CEIL(RAND() * 300))), +(21, REPEAT('l', CEIL(RAND() * 300))), +(22, REPEAT('m', CEIL(RAND() * 300))), +(23, REPEAT('n', CEIL(RAND() * 300))), +(24, REPEAT('o', CEIL(RAND() * 300))), +(25, REPEAT('p', CEIL(RAND() * 300))), +(26, REPEAT('q', CEIL(RAND() * 300))), +(27, REPEAT('r', CEIL(RAND() * 300))), +(28, REPEAT('s', CEIL(RAND() * 300))), +(29, REPEAT('t', CEIL(RAND() * 300))), +(30, REPEAT('u', CEIL(RAND() * 300))), +(31, REPEAT('v', CEIL(RAND() * 300))), +(32, REPEAT('w', CEIL(RAND() * 300))), +(33, REPEAT('x', CEIL(RAND() * 300))), +(34, REPEAT('y', CEIL(RAND() * 300))), +(35, REPEAT('z', CEIL(RAND() * 300))); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +DELETE FROM t1 WHERE c1 >= 10; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 5a663718878..b40938b96a6 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1054,4 +1054,47 @@ create table t1 (a int not null, key key_block_size=1024 (a)); --error 1064 create table t1 (a int not null, key `a` key_block_size=1024 (a)); +# +# Bug#22119 - Changing MI_KEY_BLOCK_LENGTH makes a wrong myisamchk +# +CREATE TABLE t1 ( + c1 INT, + c2 VARCHAR(300), + KEY (c1) KEY_BLOCK_SIZE 1024, + KEY (c2) KEY_BLOCK_SIZE 8192 + ); +INSERT INTO t1 VALUES (10, REPEAT('a', CEIL(RAND(10) * 300))), + (11, REPEAT('b', CEIL(RAND() * 300))), + (12, REPEAT('c', CEIL(RAND() * 300))), + (13, REPEAT('d', CEIL(RAND() * 300))), + (14, REPEAT('e', CEIL(RAND() * 300))), + (15, REPEAT('f', CEIL(RAND() * 300))), + (16, REPEAT('g', CEIL(RAND() * 300))), + (17, REPEAT('h', CEIL(RAND() * 300))), + (18, REPEAT('i', CEIL(RAND() * 300))), + (19, REPEAT('j', CEIL(RAND() * 300))), + (20, REPEAT('k', CEIL(RAND() * 300))), + (21, REPEAT('l', CEIL(RAND() * 300))), + (22, REPEAT('m', CEIL(RAND() * 300))), + (23, REPEAT('n', CEIL(RAND() * 300))), + (24, REPEAT('o', CEIL(RAND() * 300))), + (25, REPEAT('p', CEIL(RAND() * 300))), + (26, REPEAT('q', CEIL(RAND() * 300))), + (27, REPEAT('r', CEIL(RAND() * 300))), + (28, REPEAT('s', CEIL(RAND() * 300))), + (29, REPEAT('t', CEIL(RAND() * 300))), + (30, REPEAT('u', CEIL(RAND() * 300))), + (31, REPEAT('v', CEIL(RAND() * 300))), + (32, REPEAT('w', CEIL(RAND() * 300))), + (33, REPEAT('x', CEIL(RAND() * 300))), + (34, REPEAT('y', CEIL(RAND() * 300))), + (35, REPEAT('z', CEIL(RAND() * 300))); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +CHECK TABLE t1; +REPAIR TABLE t1; +DELETE FROM t1 WHERE c1 >= 10; +CHECK TABLE t1; +DROP TABLE t1; + --echo End of 5.1 tests From a8ff7bafb4ee760afed9c13e9c2d7197c9b57159 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Fri, 27 Oct 2006 17:40:06 +0200 Subject: [PATCH 5/6] Enterprise numbers, only --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 7c2d3e77b27..4e9ab05a176 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.29) +AM_INIT_AUTOMAKE(mysql, 5.0.30) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=29 +NDB_VERSION_BUILD=30 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From c71395ce256d058f47639768c0f3b3b6b3764158 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/april.(none)" <> Date: Thu, 2 Nov 2006 00:05:02 +0400 Subject: [PATCH 6/6] BUG#23312 - server hangs 'closing tables' with insert delayed,flush tables,alter table Deadlock could happen if there are delayed insert + flush tables + alter table running concurrently. This is fixed by removing a redundant mutex lock when killing a delayed thread. --- sql/sql_insert.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 283fe571d53..2887d97bd8f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1181,8 +1181,6 @@ void kill_delayed_threads(void) delayed_insert *tmp; while ((tmp=it++)) { - /* Ensure that the thread doesn't kill itself while we are looking at it */ - pthread_mutex_lock(&tmp->mutex); tmp->thd.killed=1; if (tmp->thd.mysys_var) { @@ -1201,7 +1199,6 @@ void kill_delayed_threads(void) } pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); } - pthread_mutex_unlock(&tmp->mutex); } VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list }