diff options
-rw-r--r-- | Docs/manual.texi | 3 | ||||
-rw-r--r-- | innobase/os/os0file.c | 33 | ||||
-rw-r--r-- | myisam/mi_check.c | 48 | ||||
-rw-r--r-- | myisam/mi_dynrec.c | 12 | ||||
-rw-r--r-- | myisam/myisamdef.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 19 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | tests/myisam-big-rows.tst | 72 |
8 files changed, 141 insertions, 50 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index b361e5dd984..49fc7a649ee 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46167,6 +46167,9 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item +Changed @code{SELECT ... IN SHARE MODE} to +@code{SELECT .. LOCK IN SHARE MODE} (as in MySQL 3.23). +@item A new query cache to cache results from identical @code{SELECT} queries. @item Fixed core dump bug on 64 bit machines when it got a wrong communication diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 9fecf2c04fd..a7cd31af2ee 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -457,14 +457,13 @@ os_file_get_size( offs = lseek(file, 0, SEEK_END); - if (sizeof(off_t) > 4) { - *size = (ulint)(offs & 0xFFFFFFFF); - *size_high = (ulint)(offs >> 32); - } else { - *size = (ulint) offs; - *size_high = 0; - } - +#if SIZEOF_OFF_T > 4 + *size = (ulint)(offs & 0xFFFFFFFF); + *size_high = (ulint)(offs >> 32); +#else + *size = (ulint) offs; + *size_high = 0; +#endif return(TRUE); #endif } @@ -614,18 +613,16 @@ os_file_pread( /* If off_t is > 4 bytes in size, then we assume we can pass a 64-bit address */ - if (sizeof(off_t) > 4) { - offs = (off_t)offset + (((off_t)offset_high) << 32); - - } else { - offs = (off_t)offset; +#if SIZEOF_OFF_T > 4 + offs = (off_t)offset + (((off_t)offset_high) << 32); +#else + offs = (off_t)offset; - if (offset_high > 0) { - fprintf(stderr, - "InnoDB: Error: file read at offset > 4 GB\n"); - } + if (offset_high > 0) { + fprintf(stderr, + "InnoDB: Error: file read at offset > 4 GB\n"); } - +#endif os_n_file_reads++; #ifdef HAVE_PREAD diff --git a/myisam/mi_check.c b/myisam/mi_check.c index ad095c8e546..7839de20bb8 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1288,8 +1288,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, my_close(info->dfile,MYF(0)); info->dfile=new_file; info->state->data_file_length=sort_info->filepos; - /* Only whole records */ - share->state.split=info->state->records+info->state->del; share->state.version=(ulong) time((time_t*) 0); /* Force reopen */ } else @@ -1962,7 +1960,6 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, share->state.state.data_file_length = info->state->data_file_length = sort_info->filepos; /* Only whole records */ - share->state.split=info->state->records+info->state->del; share->state.version=(ulong) time((time_t*) 0); my_close(info->dfile,MYF(0)); info->dfile=new_file; @@ -2183,9 +2180,11 @@ static int sort_get_next_record(SORT_INFO *sort_info) } sort_info->start_recpos=sort_info->pos; if (!sort_info->fix_datafile) + { sort_info->filepos=sort_info->pos; + share->state.split++; + } sort_info->max_pos=(sort_info->pos+=share->base.pack_reclength); - share->state.split++; if (*sort_info->record) { if (param->calc_checksum) @@ -2356,7 +2355,8 @@ static int sort_get_next_record(SORT_INFO *sort_info) continue; } - share->state.split++; + if (!sort_info->fix_datafile && (b_type & BLOCK_DELETED)) + share->state.split++; if (! found_record++) { sort_info->find_length=left_length=block_info.rec_len; @@ -2494,10 +2494,12 @@ static int sort_get_next_record(SORT_INFO *sort_info) } info->checksum=mi_checksum(info,sort_info->record); if (!sort_info->fix_datafile) + { sort_info->filepos=sort_info->pos; + share->state.split++; + } sort_info->max_pos=(sort_info->pos=block_info.filepos+ block_info.rec_len); - share->state.split++; info->packed_length=block_info.rec_len; if (param->calc_checksum) param->glob_crc+= info->checksum; @@ -2535,6 +2537,7 @@ int sort_write_record(SORT_INFO *sort_info) DBUG_RETURN(1); } sort_info->filepos+=share->base.pack_reclength; + info->s->state.split++; /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */ break; case DYNAMIC_RECORD: @@ -2559,20 +2562,28 @@ int sort_write_record(SORT_INFO *sort_info) } info->checksum=mi_checksum(info,sort_info->record); reclength=_mi_rec_pack(info,from,sort_info->record); - /* sort_info->param->glob_crc+=info->checksum; */ - block_length=reclength+ 3 + test(reclength >= (65520-3)); - if (block_length < share->base.min_block_length) - block_length=share->base.min_block_length; flag=0; - info->update|=HA_STATE_WRITE_AT_END; - block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE); - if (_mi_write_part_record(info,0L,block_length,HA_OFFSET_ERROR, - &from,&reclength,&flag)) + /* sort_info->param->glob_crc+=info->checksum; */ + + do { - mi_check_print_error(param,"%d when writing to datafile",my_errno); - DBUG_RETURN(1); - } - sort_info->filepos+=block_length; + block_length=reclength+ 3 + test(reclength >= (65520-3)); + if (block_length < share->base.min_block_length) + block_length=share->base.min_block_length; + info->update|=HA_STATE_WRITE_AT_END; + block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE); + if (block_length > MI_MAX_BLOCK_LENGTH) + block_length=MI_MAX_BLOCK_LENGTH; + if (_mi_write_part_record(info,0L,block_length, + sort_info->filepos+block_length, + &from,&reclength,&flag)) + { + mi_check_print_error(param,"%d when writing to datafile",my_errno); + DBUG_RETURN(1); + } + sort_info->filepos+=block_length; + info->s->state.split++; + } while (reclength); /* sort_info->param->glob_crc+=info->checksum; */ break; case COMPRESSED_RECORD: @@ -2588,6 +2599,7 @@ int sort_write_record(SORT_INFO *sort_info) } /* sort_info->param->glob_crc+=info->checksum; */ sort_info->filepos+=reclength+length; + info->s->state.split++; break; } } diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index dfe1b7053de..b5f5ca7fd33 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -64,11 +64,13 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record) MI_DYN_DELETE_BLOCK_HEADER+1; reclength=info->s->base.pack_reclength+ _my_calc_total_blob_length(info,record)+ extra; +#ifdef NOT_USED /* We now support big rows */ if (reclength > MI_DYN_MAX_ROW_LENGTH) { my_errno=HA_ERR_TO_BIG_ROW; return -1; } +#endif if (!(rec_buff=(byte*) my_alloca(reclength))) { my_errno=ENOMEM; @@ -93,11 +95,13 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record) MI_DYN_DELETE_BLOCK_HEADER; reclength=info->s->base.pack_reclength+ _my_calc_total_blob_length(info,record)+ extra; +#ifdef NOT_USED /* We now support big rows */ if (reclength > MI_DYN_MAX_ROW_LENGTH) { my_errno=HA_ERR_TO_BIG_ROW; return -1; } +#endif if (!(rec_buff=(byte*) my_alloca(reclength))) { my_errno=ENOMEM; @@ -130,14 +134,14 @@ static int write_dynamic_record(MI_INFO *info, const byte *record, DBUG_ENTER("write_dynamic_record"); flag=0; - while (reclength) + do { if (_mi_find_writepos(info,reclength,&filepos,&length)) goto err; if (_mi_write_part_record(info,filepos,length,info->s->state.dellink, (byte**) &record,&reclength,&flag)) goto err; - } + } while (reclength); DBUG_RETURN(0); err: @@ -377,7 +381,7 @@ int _mi_write_part_record(MI_INFO *info, head_length= 16; temp[0]=13; mi_int4store(temp+1,*reclength); - mi_int3store(temp+4,length-head_length); + mi_int3store(temp+5,length-head_length); mi_sizestore((byte*) temp+8,next_filepos); } else @@ -1441,7 +1445,7 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos) DBUG_DUMP("header",(byte*) header,MI_BLOCK_INFO_HEADER_LENGTH); if (info->second_read) { - if (info->header[0] <= 6) + if (info->header[0] <= 6 || info->header[0] == 13) return_val=BLOCK_SYNC_ERROR; } else diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 203101a2f48..e9d3461fe9a 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -359,7 +359,7 @@ struct st_myisam_info { #define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH) #define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */ #define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */ -#define MI_MAX_BLOCK_LENGTH (((ulong) 1 << 24)-1) +#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1))) #define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cfc40bdfdc3..c168ce775fc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -480,7 +480,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, (thd->select_limit == HA_POS_ERROR || (join.select_options & OPTION_FOUND_ROWS) || order && - !(skip_sort_order=test_if_skip_sort_order(&join.join_tab[join.const_tables], order, thd->select_limit,1)))) + !(skip_sort_order= + test_if_skip_sort_order(&join.join_tab[join.const_tables], + order, thd->select_limit,1)))) { if ((group=create_distinct_group(order,fields))) { @@ -5272,13 +5274,6 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys) } -/***************************************************************************** -** If not selecting by given key, create an index how records should be read -** return: 0 ok -** -1 some fatal error -** 1 no records -*****************************************************************************/ - /* Return 1 if we don't have to do file sorting */ static bool @@ -5391,6 +5386,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, DBUG_RETURN(0); // Can't use index. } + +/***************************************************************************** + If not selecting by given key, create an index how records should be read + return: 0 ok + -1 some fatal error + 1 no records +*****************************************************************************/ + static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ca8421aeaa2..a6b42cdf50b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1394,7 +1394,7 @@ select_lock_type: /* empty */ | FOR_SYM UPDATE_SYM { Lex->lock_option= TL_WRITE; current_thd->safe_to_cache_query=0; } - | IN_SYM SHARE_SYM MODE_SYM + | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; } select_item_list: diff --git a/tests/myisam-big-rows.tst b/tests/myisam-big-rows.tst new file mode 100644 index 00000000000..56c06f4820f --- /dev/null +++ b/tests/myisam-big-rows.tst @@ -0,0 +1,72 @@ +# +# Test rows with length above > 16M +# Note that for this to work, you should start mysqld with +# -O max_allowed_packet=32M +# + +drop table if exists t1; +create table t1 (a tinyint not null auto_increment, b longblob not null, primary key (a)) checksum=1; + +insert into t1 (b) values(repeat(char(65),10)); +insert into t1 (b) values(repeat(char(66),10)); +insert into t1 (b) values(repeat(char(67),10)); +update t1 set b=repeat(char(68),16777216) where a=1; +check table t1; +update t1 set b=repeat(char(69),16777000) where a=2; +update t1 set b=repeat(char(70),167) where a=3; +update t1 set b=repeat(char(71),16778000) where a=1; +update t1 set b=repeat(char(72),16778000) where a=3; +select a,length(b) from t1; +set @a=1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +update t1 set b=('A') where a=5; +delete from t1 where a=7; +set @a=@a+1; +insert into t1 (b) values (repeat(char(73+@a),16777200+@a)); +update t1 set b=repeat(char(73+@a+1),17000000+@a) where a=last_insert_id(); + +select a,mid(b,1,5),length(b) from t1; +check table t1; +repair table t1; +check table t1; +select a from table where b<>repeat(mid(b,1,1),length(b)); +delete from t1 where (a & 1); +select a from table where b<>repeat(mid(b,1,1),length(b)); +check table t1; +repair table t1; +check table t1; +drop table t1; |