diff options
author | unknown <pem@mysql.com> | 2003-12-01 16:14:40 +0100 |
---|---|---|
committer | unknown <pem@mysql.com> | 2003-12-01 16:14:40 +0100 |
commit | 38f853d291075a8eaa9d408a23626b09aa7ac1d2 (patch) | |
tree | 024f2d18e3cf9f65db53f9f8c2d5413859781e16 /myisam/mi_check.c | |
parent | 6573b851e36de43d4cfa39d5eba0b740c3226521 (diff) | |
parent | 91de6fdbce2a5c545532acf1124f35378a75ea0c (diff) | |
download | mariadb-git-38f853d291075a8eaa9d408a23626b09aa7ac1d2.tar.gz |
Merge 4.1 to 5.0
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
configure.in:
Auto merged
client/mysql.cc:
Auto merged
client/mysqltest.c:
Auto merged
include/my_global.h:
Auto merged
include/my_pthread.h:
Auto merged
include/mysql_com.h:
Auto merged
libmysql/libmysql.c:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/myisamchk.c:
Auto merged
myisam/myisamdef.h:
Auto merged
myisam/sort.c:
Auto merged
mysql-test/install_test_db.sh:
Auto merged
mysql-test/r/subselect.result:
Auto merged
mysql-test/r/symlink.result:
Auto merged
mysql-test/t/subselect.test:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/handler.h:
Auto merged
sql/item.cc:
Auto merged
sql/item.h:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_func.cc:
Auto merged
sql/log.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/protocol.cc:
Auto merged
sql/protocol.h:
Auto merged
sql/protocol_cursor.cc:
Auto merged
sql/repl_failsafe.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_db.cc:
Auto merged
sql/sql_derived.cc:
Auto merged
sql/sql_error.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_list.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_select.h:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_test.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
Diffstat (limited to 'myisam/mi_check.c')
-rw-r--r-- | myisam/mi_check.c | 172 |
1 files changed, 101 insertions, 71 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 4f8fc9b981a..c077e267dde 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -77,6 +77,7 @@ void myisamchk_init(MI_CHECK *param) param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL; param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL); param->start_check_pos=0; + param->max_record_length= LONGLONG_MAX; param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE; } @@ -242,7 +243,7 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) if (next_link > info->state->key_file_length || next_link & (info->s->blocksize-1)) DBUG_RETURN(1); - if (!(buff=key_cache_read(*info->s->key_cache, + 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))) @@ -262,7 +263,7 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) } /* check_k_link */ - /* Kontrollerar storleken p} filerna */ + /* Check sizes of files */ int chk_size(MI_CHECK *param, register MI_INFO *info) { @@ -273,8 +274,9 @@ int chk_size(MI_CHECK *param, register MI_INFO *info) if (!(param->testflag & T_SILENT)) puts("- check file-size"); - flush_key_blocks(*info->s->key_cache, - info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */ + /* The following is needed if called externally (not from myisamchk) */ + flush_key_blocks(info->s->key_cache, + info->s->kfile, FLUSH_FORCE_WRITE); size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); if ((skr=(my_off_t) info->state->key_file_length) != size) @@ -502,7 +504,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) param->record_checksum=old_record_checksum-init_checksum; /* Remove delete links */ else param->record_checksum=0; - DBUG_RETURN(0); + DBUG_RETURN(result); } /* chk_key */ @@ -522,7 +524,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length))) { - mi_check_print_error(param,"Not Enough memory"); + mi_check_print_error(param,"Not enough memory for keyblock"); DBUG_RETURN(-1); } @@ -711,7 +713,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) if (!(record= (byte*) my_malloc(info->s->base.pack_reclength,MYF(0)))) { - mi_check_print_error(param,"Not Enough memory"); + mi_check_print_error(param,"Not enough memory for record"); DBUG_RETURN(-1); } records=del_blocks=0; @@ -814,16 +816,17 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) goto next; } mi_check_print_error(param,"Wrong bytesec: %d-%d-%d at linkstart: %s", - block_info.header[0],block_info.header[1], - block_info.header[2], - llstr(start_block,llbuff)); + block_info.header[0],block_info.header[1], + block_info.header[2], + llstr(start_block,llbuff)); goto err2; } if (info->state->data_file_length < block_info.filepos+ block_info.block_len) { - mi_check_print_error(param,"Recordlink that points outside datafile at %s", - llstr(pos,llbuff)); + mi_check_print_error(param, + "Recordlink that points outside datafile at %s", + llstr(pos,llbuff)); got_error=1; break; } @@ -834,9 +837,9 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) pos=block_info.filepos+block_info.block_len; if (block_info.rec_len > (uint) info->s->base.max_pack_length) { - mi_check_print_error(param,"Found too long record (%d) at %s", - block_info.rec_len, - llstr(start_recpos,llbuff)); + mi_check_print_error(param,"Found too long record (%lu) at %s", + (ulong) block_info.rec_len, + llstr(start_recpos,llbuff)); got_error=1; break; } @@ -845,8 +848,10 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) if (!(to= mi_alloc_rec_buff(info, block_info.rec_len, &info->rec_buff))) { - mi_check_print_error(param,"Not enough memory for blob at %s", - llstr(start_recpos,llbuff)); + mi_check_print_error(param, + "Not enough memory (%lu) for blob at %s", + (ulong) block_info.rec_len, + llstr(start_recpos,llbuff)); got_error=1; break; } @@ -857,9 +862,11 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) } if (left_length < block_info.data_len) { - mi_check_print_error(param,"Found too long record at %s", - llstr(start_recpos,llbuff)); - got_error=1; break; + mi_check_print_error(param,"Found too long record (%lu) at %s", + (ulong) block_info.data_len, + llstr(start_recpos,llbuff)); + got_error=1; + break; } if (_mi_read_cache(¶m->read_cache,(byte*) to,block_info.filepos, (uint) block_info.data_len, @@ -1142,9 +1149,12 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + if (!param->using_global_keycache) - VOID(init_key_cache(dflt_keycache, param->key_cache_block_size, - param->use_buffers, &dflt_key_cache_var)); + VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size, + param->use_buffers, 0, 0)); if (init_io_cache(¶m->read_cache,info->dfile, (uint) param->read_buffer_length, @@ -1163,7 +1173,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, MYF(0))) || !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff)) { - mi_check_print_error(param,"Not enough memory for extra record"); + mi_check_print_error(param, "Not enough memory for extra record"); goto err; } @@ -1355,6 +1365,7 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks, MYF(MY_WME))); + info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */ } mi_mark_crashed_on_repair(info); } @@ -1365,7 +1376,7 @@ err: VOID(end_io_cache(¶m->read_cache)); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); VOID(end_io_cache(&info->rec_cache)); - got_error|=flush_blocks(param, *share->key_cache, share->kfile); + got_error|=flush_blocks(param, share->key_cache, share->kfile); if (!got_error && param->testflag & T_UNPACK) { share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD; @@ -1501,7 +1512,7 @@ void lock_memory(MI_CHECK *param __attribute__((unused))) /* Flush all changed blocks to disk */ -int flush_blocks(MI_CHECK *param, KEY_CACHE_HANDLE key_cache, File file) +int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file) { if (flush_key_blocks(key_cache, file, FLUSH_RELEASE)) { @@ -1564,7 +1575,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) } /* Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); share->state.version=(ulong) time((time_t*) 0); old_state= share->state; /* save state if not stored */ @@ -1625,7 +1636,7 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length))) { - mi_check_print_error(param,"Not Enough memory"); + mi_check_print_error(param,"Not enough memory for key block"); DBUG_RETURN(-1); } if (!_mi_fetch_keypage(info,keyinfo,pagepos,DFLT_INIT_HITS,buff,0)) @@ -1811,6 +1822,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + bzero((char*)&sort_info,sizeof(sort_info)); bzero((char *)&sort_param, sizeof(sort_param)); if (!(sort_info.key_block= @@ -1834,7 +1848,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, MYF(0))) || !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff)) { - mi_check_print_error(param,"Not enough memory for extra record"); + mi_check_print_error(param, "Not enough memory for extra record"); goto err; } if (!rep_quick) @@ -1874,7 +1888,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) share->state.key_root[i]= HA_OFFSET_ERROR; @@ -1884,7 +1898,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, } else { - if (flush_key_blocks(*share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) + if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) goto err; key_map= ~key_map; /* Create the missing keys */ } @@ -2076,7 +2090,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, memcpy( &share->state.state, info->state, sizeof(*info->state)); err: - got_error|= flush_blocks(param, *share->key_cache, share->kfile); + got_error|= flush_blocks(param, share->key_cache, share->kfile); VOID(end_io_cache(&info->rec_cache)); if (!got_error) { @@ -2182,6 +2196,9 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ + if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) + param->testflag|=T_CALC_CHECKSUM; + bzero((char*)&sort_info,sizeof(sort_info)); if (!(sort_info.key_block= alloc_key_blocks(param, @@ -2237,7 +2254,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, Flush key cache for this file if we are calling this outside myisamchk */ - flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); + flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED); /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) share->state.key_root[i]= HA_OFFSET_ERROR; @@ -2247,7 +2264,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, } else { - if (flush_key_blocks(*share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) + if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE)) goto err; key_map= ~key_map; /* Create the missing keys */ } @@ -2267,17 +2284,19 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, rec_length=share->base.min_block_length; else rec_length=share->base.pack_reclength; + /* + +1 below is required hack for parallel repair mode. + The info->state->records value, that is compared later + to sort_info.max_records and cannot exceed it, is + increased in sort_key_write. In mi_repair_by_sort, sort_key_write + is called after sort_key_read, where the comparison is performed, + but in parallel mode master thread can call sort_key_write + before some other repair thread calls sort_key_read. + Furthermore I'm not even sure +1 would be enough. + May be sort_info.max_records shold be always set to max value in + parallel mode. + */ sort_info.max_records= - /* +1 below is required hack for parallel repair mode. - The info->state->records value, that is compared later - to sort_info.max_records and cannot exceed it, is - increased in sort_key_write. In mi_repair_by_sort, sort_key_write - is called after sort_key_read, where the comparison is performed, - but in parallel mode master thread can call sort_key_write - before some other repair thread calls sort_key_read. - Furthermore I'm not even sure +1 would be enough. - May be sort_info.max_records shold be always set to max value in - parallel mode. */ ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records + 1: (ha_rows) (sort_info.filelength/rec_length+1)); @@ -2291,7 +2310,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, (sizeof(MI_SORT_PARAM) + share->base.pack_reclength), MYF(MY_ZEROFILL)))) { - mi_check_print_error(param,"Not enough memory!"); + mi_check_print_error(param,"Not enough memory for key!"); goto err; } total_key_length=0; @@ -2483,7 +2502,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, memcpy(&share->state.state, info->state, sizeof(*info->state)); err: - got_error|= flush_blocks(param, *share->key_cache, share->kfile); + got_error|= flush_blocks(param, share->key_cache, share->kfile); VOID(end_io_cache(&info->rec_cache)); if (!got_error) { @@ -2847,9 +2866,20 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) if (!(to=mi_alloc_rec_buff(info,block_info.rec_len, &(sort_param->rec_buff)))) { - mi_check_print_error(param,"Not enough memory for blob at %s", - llstr(sort_param->start_recpos,llbuff)); - DBUG_RETURN(1); + if (param->max_record_length >= block_info.rec_len) + { + mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)", + llstr(sort_param->start_recpos,llbuff), + (ulong) block_info.rec_len); + DBUG_RETURN(1); + } + else + { + mi_check_print_info(param,"Not enough memory for blob at %s (need %lu); Row skipped", + llstr(sort_param->start_recpos,llbuff), + (ulong) block_info.rec_len); + goto try_next; + } } } else @@ -2857,14 +2887,16 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) } if (left_length < block_info.data_len || ! block_info.data_len) { - mi_check_print_info(param,"Found block with too small length at %s; Skipped", + mi_check_print_info(param, + "Found block with too small length at %s; Skipped", llstr(sort_param->start_recpos,llbuff)); goto try_next; } if (block_info.filepos + block_info.data_len > sort_param->read_cache.end_of_file) { - mi_check_print_info(param,"Found block that points outside data file at %s", + mi_check_print_info(param, + "Found block that points outside data file at %s", llstr(sort_param->start_recpos,llbuff)); goto try_next; } @@ -3269,30 +3301,28 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a) ft_buf->buf=0; return error; } - else - { - /* flushing buffer */ - if ((error=sort_ft_buf_flush(sort_param))) - return error; -word_init_ft_buf: - a_len+=val_len; - memcpy(ft_buf->lastkey, a, a_len); - ft_buf->buf=ft_buf->lastkey+a_len; - ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32); - /* 32 is just a safety margin here - (at least max(val_len, sizeof(nod_flag)) should be there). - May be better performance could be achieved if we'd put - (sort_info->keyinfo->block_length-32)/XXX - instead. - TODO: benchmark the best value for XXX. - */ + /* flushing buffer */ + if ((error=sort_ft_buf_flush(sort_param))) + return error; - return 0; - } - return -1; /* impossible */ +word_init_ft_buf: + a_len+=val_len; + memcpy(ft_buf->lastkey, a, a_len); + ft_buf->buf=ft_buf->lastkey+a_len; + /* + 32 is just a safety margin here + (at least max(val_len, sizeof(nod_flag)) should be there). + May be better performance could be achieved if we'd put + (sort_info->keyinfo->block_length-32)/XXX + instead. + TODO: benchmark the best value for XXX. + */ + ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32); + return 0; } /* sort_ft_key_write */ + /* get pointer to record from a key */ static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo, @@ -3499,7 +3529,7 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks, buffer_length+IO_SIZE)*blocks, MYF(0)))) { - mi_check_print_error(param,"Not Enough memory for sort-key-blocks"); + mi_check_print_error(param,"Not enough memory for sort-key-blocks"); return(0); } for (i=0 ; i < blocks ; i++) |