summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-02-16 10:31:05 +0200
committerunknown <monty@mysql.com>2004-02-16 10:31:05 +0200
commitcad7f2a155c26fe2477a104284a4db59470ae694 (patch)
treee792af64f95eba198633387e3b36f50f096c3001 /myisam
parent571c901008730a10013d7e1ac84534e7d83914bc (diff)
parentebac2d25bcdcc74bf153a6a3568bfde5f1b17a8b (diff)
downloadmariadb-git-cad7f2a155c26fe2477a104284a4db59470ae694.tar.gz
Merge with public tree
client/mysqldump.c: Auto merged configure.in: Auto merged include/m_ctype.h: Auto merged include/m_string.h: Auto merged include/my_global.h: Auto merged mysql-test/r/ctype_utf8.result: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/t/fulltext.test: Auto merged mysql-test/t/grant.test: Auto merged mysql-test/t/subselect.test: Auto merged mysql-test/t/union.test: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/item.cc: Auto merged sql/item_func.cc: Auto merged sql/item_strfunc.cc: Auto merged sql/mysql_priv.h: Auto merged sql/set_var.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/share/english/errmsg.txt: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_string.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_yacc.yy: Auto merged strings/ctype-mb.c: Auto merged strings/ctype-simple.c: Auto merged mysql-test/r/warnings.result: Fix error numbers after merge sql/share/czech/errmsg.txt: Add missing ',' and fix typo sql/share/danish/errmsg.txt: Add missing ',' and fix typo sql/share/dutch/errmsg.txt: Add missing ',' and fix typo sql/share/estonian/errmsg.txt: Add missing ',' and fix typo sql/share/french/errmsg.txt: Add missing ',' and fix typo sql/share/german/errmsg.txt: Add missing ',' and fix typo sql/share/greek/errmsg.txt: Add missing ',' and fix typo sql/share/hungarian/errmsg.txt: Add missing ',' and fix typo sql/share/italian/errmsg.txt: Add missing ',' and fix typo sql/share/japanese/errmsg.txt: Add missing ',' and fix typo sql/share/korean/errmsg.txt: Add missing ',' and fix typo sql/share/norwegian-ny/errmsg.txt: Add missing ',' and fix typo sql/share/norwegian/errmsg.txt: Add missing ',' and fix typo sql/share/polish/errmsg.txt: Add missing ',' and fix typo sql/share/portuguese/errmsg.txt: Add missing ',' and fix typo sql/share/romanian/errmsg.txt: Add missing ',' and fix typo sql/share/russian/errmsg.txt: Add missing ',' and fix typo sql/share/slovak/errmsg.txt: Add missing ',' and fix typo sql/share/spanish/errmsg.txt: Add missing ',' and fix typo sql/share/swedish/errmsg.txt: Add missing ',' and fix typo sql/share/ukrainian/errmsg.txt: Add missing ',' and fix typo
Diffstat (limited to 'myisam')
-rw-r--r--myisam/Makefile.am6
-rw-r--r--myisam/mi_check.c10
-rw-r--r--myisam/mi_dynrec.c144
-rw-r--r--myisam/myisam_ftdump.c (renamed from myisam/ft_dump.c)0
-rw-r--r--myisam/myisamdef.h5
5 files changed, 118 insertions, 47 deletions
diff --git a/myisam/Makefile.am b/myisam/Makefile.am
index fdcfc6d0d41..5aa0740261e 100644
--- a/myisam/Makefile.am
+++ b/myisam/Makefile.am
@@ -21,18 +21,18 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a
pkglib_LIBRARIES = libmyisam.a
-bin_PROGRAMS = myisamchk myisamlog myisampack
+bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
myisamchk_DEPENDENCIES= $(LIBRARIES)
myisamlog_DEPENDENCIES= $(LIBRARIES)
myisampack_DEPENDENCIES=$(LIBRARIES)
-noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test ft_dump #ft_test1 ft_eval
+noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test2_DEPENDENCIES= $(LIBRARIES)
mi_test3_DEPENDENCIES= $(LIBRARIES)
#ft_test1_DEPENDENCIES= $(LIBRARIES)
#ft_eval_DEPENDENCIES= $(LIBRARIES)
-ft_dump_DEPENDENCIES= $(LIBRARIES)
+myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
rt_test_DEPENDENCIES= $(LIBRARIES)
sp_test_DEPENDENCIES= $(LIBRARIES)
libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 5687e7d48e3..4f6aa0b46d4 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -947,7 +947,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
info->checksum=mi_checksum(info,record);
if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
{
- if (_mi_rec_check(info,record, info->rec_buff))
+ if (_mi_rec_check(info,record, info->rec_buff,block_info.rec_len))
{
mi_check_print_error(param,"Found wrong packed record at %s",
llstr(start_recpos,llbuff));
@@ -2389,6 +2389,11 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
sort_param[i].record= (((char *)(sort_param+share->base.keys))+
(share->base.pack_reclength * i));
+ if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
+ {
+ mi_check_print_error(param,"Not enough memory!");
+ goto err;
+ }
sort_param[i].key_length=share->rec_reflength;
for (keyseg=sort_param[i].seg; keyseg->type != HA_KEYTYPE_END;
@@ -2966,7 +2971,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
info->checksum=mi_checksum(info,sort_param->record);
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
{
- if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff))
+ if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff,
+ sort_param->find_length))
{
mi_check_print_info(param,"Found wrong packed record at %s",
llstr(sort_param->start_recpos,llbuff));
diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c
index 079779bd0ef..30a4762abe0 100644
--- a/myisam/mi_dynrec.c
+++ b/myisam/mi_dynrec.c
@@ -14,7 +14,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- /* Functions to handle space-packed-records and blobs */
+/*
+ Functions to handle space-packed-records and blobs
+
+ A row may be stored in one or more linked blocks.
+ The block size is between MI_MIN_BLOCK_LENGTH and MI_MAX_BLOCK_LENGTH.
+ Each block is aligned on MI_DYN_ALIGN_SIZE.
+ The reson for the max block size is to not have too many different types
+ of blocks. For the differnet block types, look at _mi_get_block_info()
+*/
#include "myisamdef.h"
#include <assert.h>
@@ -148,7 +156,7 @@ static int write_dynamic_record(MI_INFO *info, const byte *record,
} while (reclength);
DBUG_RETURN(0);
- err:
+err:
DBUG_RETURN(1);
}
@@ -264,37 +272,62 @@ static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
DBUG_RETURN(0);
}
- /* Delete datarecord from database */
- /* info->rec_cache.seek_not_done is updated in cmp_record */
-static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
- uint second_read)
+/*
+ Add a backward link to delete block
+
+ SYNOPSIS
+ update_backward_delete_link()
+ info MyISAM handler
+ delete_block Position to delete block to update.
+ If this is 'HA_OFFSET_ERROR', nothing will be done
+ filepos Position to block that 'delete_block' should point to
+
+ RETURN
+ 0 ok
+ 1 error. In this case my_error is set.
+*/
+
+static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block,
+ my_off_t filepos)
{
- uint length,b_type;
- MI_BLOCK_INFO block_info,del_block;
- int error=0;
- my_bool remove_next_block;
- DBUG_ENTER("delete_dynamic_record");
+ MI_BLOCK_INFO block_info;
+ DBUG_ENTER("update_backward_delete_link");
- /* First add a link from the last block to the new one */
- if (info->s->state.dellink != HA_OFFSET_ERROR)
+ if (delete_block != HA_OFFSET_ERROR)
{
block_info.second_read=0;
- if (_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink)
+ if (_mi_get_block_info(&block_info,info->dfile,delete_block)
& BLOCK_DELETED)
{
char buff[8];
mi_sizestore(buff,filepos);
- if (my_pwrite(info->dfile,buff,8,info->s->state.dellink+12,
- MYF(MY_NABP)))
- error=1; /* Error on write */
+ if (my_pwrite(info->dfile,buff, 8, delete_block+12, MYF(MY_NABP)))
+ DBUG_RETURN(1); /* Error on write */
}
else
{
- error=1; /* Wrong delete link */
my_errno=HA_ERR_WRONG_IN_RECORD;
+ DBUG_RETURN(1); /* Wrong delete link */
}
}
+ return 0;
+}
+
+ /* Delete datarecord from database */
+ /* info->rec_cache.seek_not_done is updated in cmp_record */
+
+static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
+ uint second_read)
+{
+ uint length,b_type;
+ MI_BLOCK_INFO block_info,del_block;
+ int error;
+ my_bool remove_next_block;
+ DBUG_ENTER("delete_dynamic_record");
+
+ /* First add a link from the last block to the new one */
+ error= update_backward_delete_link(info, info->s->state.dellink, filepos);
block_info.second_read=second_read;
do
@@ -518,21 +551,11 @@ int _mi_write_part_record(MI_INFO *info,
*reclength-=(length-head_length);
*flag=6;
- if (del_length && next_delete_block != HA_OFFSET_ERROR)
+ if (del_length)
{
/* link the next delete block to this */
- MI_BLOCK_INFO del_block;
- del_block.second_read=0;
- if (!(_mi_get_block_info(&del_block,info->dfile,next_delete_block)
- & BLOCK_DELETED))
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- goto err;
- }
- mi_sizestore(del_block.header+12,info->s->state.dellink);
- if (my_pwrite(info->dfile,(char*) del_block.header+12,8,
- next_delete_block+12,
- MYF(MY_NABP)))
+ if (update_backward_delete_link(info, next_delete_block,
+ info->s->state.dellink))
goto err;
}
@@ -574,6 +597,8 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
{
uint tmp=MY_ALIGN(reclength - length + 3 +
test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+ tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
/* Check if we can extend this block */
if (block_info.filepos + block_info.block_len ==
info->state->data_file_length &&
@@ -588,9 +613,15 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
info->update|= HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK;
length+=tmp;
}
- else
+ else if (length < MI_MAX_BLOCK_LENGTH - MI_MIN_BLOCK_LENGTH)
{
- /* Check if next block is a deleted block */
+ /*
+ Check if next block is a deleted block
+ Above we have MI_MIN_BLOCK_LENGTH to avoid the problem where
+ the next block is so small it can't be splited which could
+ casue problems
+ */
+
MI_BLOCK_INFO del_block;
del_block.second_read=0;
if (_mi_get_block_info(&del_block,info->dfile,
@@ -601,7 +632,35 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
DBUG_PRINT("info",("Extending current block"));
if (unlink_deleted_block(info,&del_block))
goto err;
- length+=del_block.block_len;
+ if ((length+=del_block.block_len) > MI_MAX_BLOCK_LENGTH)
+ {
+ /*
+ New block was too big, link overflow part back to
+ delete list
+ */
+ my_off_t next_pos;
+ ulong rest_length= length-MI_MAX_BLOCK_LENGTH;
+ set_if_bigger(rest_length, MI_MIN_BLOCK_LENGTH);
+ next_pos= del_block.filepos+ del_block.block_len - rest_length;
+
+ if (update_backward_delete_link(info, info->s->state.dellink,
+ next_pos))
+ DBUG_RETURN(1);
+
+ /* create delete link for data that didn't fit into the page */
+ del_block.header[0]=0;
+ mi_int3store(del_block.header+1, rest_length);
+ mi_sizestore(del_block.header+4,info->s->state.dellink);
+ bfill(del_block.header+12,8,255);
+ if (my_pwrite(info->dfile,(byte*) del_block.header,20, next_pos,
+ MYF(MY_NABP)))
+ DBUG_RETURN(1);
+ info->s->state.dellink= next_pos;
+ info->s->state.split++;
+ info->state->del++;
+ info->state->empty+= rest_length;
+ length-= rest_length;
+ }
}
}
}
@@ -615,7 +674,10 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
&record,&reclength,&flag))
goto err;
if ((filepos=block_info.next_filepos) == HA_OFFSET_ERROR)
+ {
+ /* Start writing data on deleted blocks */
filepos=info->s->state.dellink;
+ }
}
if (block_info.next_filepos != HA_OFFSET_ERROR)
@@ -744,7 +806,8 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
Returns 0 if record is ok.
*/
-my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff)
+my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff,
+ ulong packed_length)
{
uint length,new_length,flag,bit,i;
char *pos,*end,*packpos,*to;
@@ -836,8 +899,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff)
to+=length;
}
}
- if (info->packed_length != (uint) (to - rec_buff)
- + test(info->s->calc_checksum) ||
+ if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
(bit != 1 && (flag & ~(bit - 1))))
goto err;
if (info->s->calc_checksum)
@@ -850,7 +912,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff)
}
DBUG_RETURN(0);
- err:
+err:
DBUG_RETURN(1);
}
@@ -966,8 +1028,8 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
if (info->s->calc_checksum)
from++;
if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
- DBUG_RETURN((info->packed_length=found_length));
- err:
+ DBUG_RETURN(found_length);
+err:
my_errno=HA_ERR_RECORD_DELETED;
DBUG_PRINT("error",("to_end: %lx -> %lx from_end: %lx -> %lx",
to,to_end,from,from_end));
@@ -1210,7 +1272,7 @@ int _mi_cmp_dynamic_record(register MI_INFO *info, register const byte *record)
}
}
my_errno=0;
- err:
+err:
if (buffer != info->rec_buff)
my_afree((gptr) buffer);
DBUG_RETURN(my_errno);
diff --git a/myisam/ft_dump.c b/myisam/myisam_ftdump.c
index 47134af71d6..47134af71d6 100644
--- a/myisam/ft_dump.c
+++ b/myisam/myisam_ftdump.c
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index c92d5a76815..f84d1c573d0 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -249,6 +249,8 @@ struct st_myisam_info {
my_off_t last_search_keypage; /* Last keypage when searching */
my_off_t dupp_key_pos;
ha_checksum checksum;
+ /* QQ: the folloing two xxx_length fields should be removed,
+ as they are not compatible with parallel repair */
ulong packed_length,blob_length; /* Length of found, packed record */
int dfile; /* The datafile */
uint opt_flag; /* Optim. for space/speed */
@@ -577,7 +579,8 @@ extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
ulong reclength);
-extern my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *packpos);
+extern my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *packpos,
+ ulong reclength);
extern int _mi_write_part_record(MI_INFO *info,my_off_t filepos,ulong length,
my_off_t next_filepos,byte **record,
ulong *reclength,int *flag);