MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:ramil Date:September 5 2005 11:31am
Subject:bk commit into 4.1 tree (ramil:1.2391) BUG#4214
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of ram. When ram does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2391 05/09/05 16:31:42 ramil@stripped +5 -0
  a fix (bug #4214: Table corruption with myisampack and large BLOB objects).

  myisam/myisampack.c
    1.41 05/09/05 16:31:35 ramil@stripped +7 -18
    a fix (bug #4214: Table corruption with myisampack and large BLOB objects).
    - code cleanup
    - pass version to the calc_pack_length() and save_pack_length()

  myisam/myisamdef.h
    1.79 05/09/05 16:31:35 ramil@stripped +4 -1
    a fix (bug #4214: Table corruption with myisampack and large BLOB objects).
    - packing version slot introduced (see MI_PACK)

  myisam/mi_static.c
    1.17 05/09/05 16:31:35 ramil@stripped +1 -1
    a fix (bug #4214: Table corruption with myisampack and large BLOB objects).
    - packing version set to 2

  myisam/mi_packrec.c
    1.27 05/09/05 16:31:35 ramil@stripped +53 -60
    a fix (bug #4214: Table corruption with myisampack and large BLOB objects).
    - code cleanup: read_pack_length() and calc_pack_length() introduced, 
                    save_pack_length() modified: now the behavior depends on packing version
    - save packing version in the share->pack.version
    - pass it to the read_pack_length()

  myisam/mi_check.c
    1.148 05/09/05 16:31:35 ramil@stripped +4 -2
    a fix (bug #4214: Table corruption with myisampack and large BLOB objects).
    - pass version to the save_pack_length().

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	ramil
# Host:	gw.mysql.r18.ru
# Root:	/usr/home/ram/work/4.1.b4214

--- 1.147/myisam/mi_check.c	2005-06-07 18:34:09 +05:00
+++ 1.148/myisam/mi_check.c	2005-09-05 16:31:35 +05:00
@@ -3189,9 +3189,11 @@
       break;
     case COMPRESSED_RECORD:
       reclength=info->packed_length;
-      length=save_pack_length(block_buff,reclength);
+      length= save_pack_length((uint) share->pack.version, block_buff,
+                               reclength);
       if (info->s->base.blobs)
-	length+=save_pack_length(block_buff+length,info->blob_length);
+	length+= save_pack_length((uint) share->pack.version,
+	                          block_buff + length, info->blob_length);
       if (my_b_write(&info->rec_cache,block_buff,length) ||
 	  my_b_write(&info->rec_cache,(byte*) sort_param->rec_buff,reclength))
       {

--- 1.26/myisam/mi_packrec.c	2005-01-24 18:48:16 +04:00
+++ 1.27/myisam/mi_packrec.c	2005-09-05 16:31:35 +05:00
@@ -149,11 +149,12 @@
       my_errno=HA_ERR_END_OF_FILE;
     goto err0;
   }
-  if (memcmp((byte*) header,(byte*) myisam_pack_file_magic,4))
+  if (memcmp((byte*) header, (byte*) myisam_pack_file_magic, 3))
   {
     my_errno=HA_ERR_WRONG_IN_RECORD;
     goto err0;
   }
+  share->pack.version= header[3];
   share->pack.header_length=	uint4korr(header+4);
   share->min_pack_length=(uint) uint4korr(header+8);
   share->max_pack_length=(uint) uint4korr(header+12);
@@ -1040,38 +1041,12 @@
       return BLOCK_FATAL_ERROR;
     DBUG_DUMP("header",(byte*) header,ref_length);
   }
-  if (header[0] < 254)
-  {
-    info->rec_len=header[0];
-    head_length=1;
-  }
-  else if (header[0] == 254)
-  {
-    info->rec_len=uint2korr(header+1);
-    head_length=3;
-  }
-  else
-  {
-    info->rec_len=uint3korr(header+1);
-    head_length=4;
-  }
+  head_length= read_pack_length((uint) myisam->s->pack.version, header,
+                                &info->rec_len);
   if (myisam->s->base.blobs)
   {
-    if (header[head_length] < 254)
-    {
-      info->blob_len=header[head_length];
-      head_length++;
-    }
-    else if (header[head_length] == 254)
-    {
-      info->blob_len=uint2korr(header+head_length+1);
-      head_length+=3;
-    }
-    else
-    {
-      info->blob_len=uint3korr(header+head_length+1);
-      head_length+=4;
-    }
+    head_length+= read_pack_length((uint) myisam->s->pack.version,
+                                   header + head_length, &info->blob_len);
     if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
 			    &myisam->rec_buff)))
       return BLOCK_FATAL_ERROR;			/* not enough memory */
@@ -1220,34 +1195,12 @@
 static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
 					 uchar *header)
 {
-  if (header[0] < 254)
-    info->rec_len= *header++;
-  else if (header[0] == 254)
-  {
-    info->rec_len=uint2korr(header+1);
-    header+=3;
-  }
-  else
-  {
-    info->rec_len=uint3korr(header+1);
-    header+=4;
-  }
+  header+= read_pack_length((uint) myisam->s->pack.version, header,
+                            &info->rec_len);
   if (myisam->s->base.blobs)
   {
-    if (header[0] < 254)
-    {
-      info->blob_len= *header++;
-    }
-    else if (header[0] == 254)
-    {
-      info->blob_len=uint2korr(header+1);
-      header+=3;
-    }
-    else
-    {
-      info->blob_len=uint3korr(header+1);
-      header+=4;
-    }
+    header+= read_pack_length((uint) myisam->s->pack.version, header,
+                              &info->blob_len);
     /* mi_alloc_rec_buff sets my_errno on error */
     if (!(mi_alloc_rec_buff(myisam, info->blob_len,
 			    &myisam->rec_buff)))
@@ -1319,7 +1272,7 @@
 
 	/* Save length of row */
 
-uint save_pack_length(byte *block_buff,ulong length)
+uint save_pack_length(uint version, byte *block_buff, ulong length)
 {
   if (length < 254)
   {
@@ -1333,6 +1286,46 @@
     return 3;
   }
   *(uchar*) block_buff=255;
-  int3store(block_buff+1,(ulong) length);
-  return 4;
+  if (version == 1) /* old format */
+  {
+    DBUG_ASSERT(length <= 0xFFFFFF);
+    int3store(block_buff + 1, (ulong) length);
+    return 4;
+  }
+  else
+  {
+    int4store(block_buff + 1, (ulong) length);
+    return 5;
+  }
+}
+
+
+uint read_pack_length(uint version, const uchar *buf, ulong *length)
+{
+  if (buf[0] < 254)
+  {
+    *length= buf[0];
+    return 1;
+  }
+  else if (buf[0] == 254)
+  {
+    *length= uint2korr(buf + 1);
+    return 3;
+  }
+  if (version == 1) /* old format */
+  {
+    *length= uint3korr(buf + 1);
+    return 4;
+  }
+  else
+  {
+    *length= uint4korr(buf + 1);
+    return 5;
+  }
+}
+
+
+uint calc_pack_length(uint version, ulong length)
+{
+  return (length < 254) ? 1 : (length < 65536) ? 3 : (version == 1) ? 4 : 5;
 }

--- 1.16/myisam/mi_static.c	2004-06-23 15:28:58 +05:00
+++ 1.17/myisam/mi_static.c	2005-09-05 16:31:35 +05:00
@@ -27,7 +27,7 @@
 uchar	NEAR myisam_file_magic[]=
 { (uchar) 254, (uchar) 254,'\007', '\001', };
 uchar	NEAR myisam_pack_file_magic[]=
-{ (uchar) 254, (uchar) 254,'\010', '\001', };
+{ (uchar) 254, (uchar) 254,'\010', '\002', };
 my_string myisam_log_filename=(char*) "myisam.log";
 File	myisam_log_file= -1;
 uint	myisam_quick_table_bits=9;

--- 1.78/myisam/myisamdef.h	2005-04-11 23:04:43 +05:00
+++ 1.79/myisam/myisamdef.h	2005-09-05 16:31:35 +05:00
@@ -149,6 +149,7 @@
 typedef struct st_mi_isam_pack {
   ulong header_length;
   uint ref_length;
+  uchar version;
 } MI_PACK;
 
 
@@ -669,7 +670,9 @@
 			      int result);
 extern my_bool _mi_memmap_file(MI_INFO *info);
 extern void _mi_unmap_file(MI_INFO *info);
-extern uint save_pack_length(byte *block_buff,ulong length);
+extern uint save_pack_length(uint version, byte *block_buff, ulong length);
+extern uint read_pack_length(uint version, const uchar *buf, ulong *length);
+extern uint calc_pack_length(uint version, ulong length);
 
 uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite);
 char *mi_state_info_read(char *ptr, MI_STATE_INFO *state);

--- 1.40/myisam/myisampack.c	2005-08-12 23:44:23 +05:00
+++ 1.41/myisam/myisampack.c	2005-09-05 16:31:35 +05:00
@@ -1666,6 +1666,7 @@
   HUFF_COUNTS *count,*end_count;
   HUFF_TREE *tree;
   MI_INFO *isam_file=mrg->file[0];
+  uint pack_version= (uint) isam_file->s->pack.version;
   DBUG_ENTER("compress_isam_file");
 
   if (!(record=(byte*) my_alloca(isam_file->s->base.reclength)))
@@ -1693,23 +1694,10 @@
 	  huff_counts[i].tree->height+huff_counts[i].length_bits;
   }
   max_calc_length/=8;
-  if (max_calc_length < 254)
-    pack_ref_length=1;
-  else if (max_calc_length <= 65535)
-    pack_ref_length=3;
-  else
-    pack_ref_length=4;
+  pack_ref_length= calc_pack_length(pack_version, max_calc_length);
   record_count=0;
-  pack_blob_length=0;
-  if (isam_file->s->base.blobs)
-  {
-    if (mrg->max_blob_length < 254)
-      pack_blob_length=1;
-    else if (mrg->max_blob_length <= 65535)
-      pack_blob_length=3;
-    else
-      pack_blob_length=4;
-  }
+  pack_blob_length= isam_file->s->base.blobs ?
+                    calc_pack_length(pack_version, mrg->max_blob_length) : 0;
   max_pack_length=pack_ref_length+pack_blob_length;
 
   mrg_reset(mrg);
@@ -1865,9 +1853,10 @@
       }
       flush_bits();
       length=(ulong) (file_buffer.pos-record_pos)-max_pack_length;
-      pack_length=save_pack_length(record_pos,length);
+      pack_length= save_pack_length(pack_version, record_pos, length);
       if (pack_blob_length)
-	pack_length+=save_pack_length(record_pos+pack_length,tot_blob_length);
+	pack_length+= save_pack_length(pack_version, record_pos + pack_length,
+	                               tot_blob_length);
 
       /* Correct file buffer if the header was smaller */
       if (pack_length != max_pack_length)
Thread
bk commit into 4.1 tree (ramil:1.2391) BUG#4214ramil5 Sep