MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:ingo Date:June 28 2006 4:55pm
Subject:bk commit into 4.0 tree (ingo:1.2182) BUG#14400
View as plain text  
Below is the list of changes that have just been committed into a local
4.0 repository of mydev. When mydev 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.2182 06/06/28 18:55:30 ingo@stripped +2 -0
  Bug#14400 - Query joins wrong rows from table which is subject of "concurrent insert"
  
  It was possible that fetching a record by an exact key value 
  (including the record pointer) could return a record with a 
  different key value. This happened only if a concurrent insert 
  added a record with the searched key value after the fetching 
  statement locked the table for read.
  
  The search succeded on the key value, but the record was
  rejected as it was past the file length that was remembered
  at start of the fetching statement. With other words it was 
  rejected as being a concurrently inserted record.
  
  The action to recover from this problem was to fetch the 
  record that is pointed at by the next key of the index. 
  This was repeated until a record below the file length was 
  found.
  
  I do now avoid this loop if an exact match was searched. 
  If this match is beyond the file length, it is now treated 
  as "key not found". There cannot be another key with the 
  same record pointer.

  sql/sql_class.cc
    1.114 06/06/28 18:55:18 ingo@stripped +3 -3
    Bug#14400 - Query joins wrong rows from table which is subject of "concurrent insert"
    Fixed some DBUG_ENTER strings.

  myisam/mi_rkey.c
    1.15 06/06/28 18:55:18 ingo@stripped +14 -2
    Bug#14400 - Query joins wrong rows from table which is subject of "concurrent insert"
    Added a check for exact key match before searching for
    the next key that was not concurrently inserted. If an
    exact key match finds a concurrently inserted row, this
    must be treated as "key not found".

# 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:	ingo
# Host:	chilla.local
# Root:	/home/mydev/mysql-4.0-bug14400

--- 1.14/myisam/mi_rkey.c	2005-09-23 10:15:08 +02:00
+++ 1.15/myisam/mi_rkey.c	2006-06-28 18:55:18 +02:00
@@ -66,6 +66,7 @@ int mi_rkey(MI_INFO *info, byte *buf, in
 
   if (fast_mi_readinfo(info))
     goto err;
+
   if (share->concurrent_insert)
     rw_rdlock(&share->key_root_lock[inx]);
 
@@ -77,14 +78,24 @@ int mi_rkey(MI_INFO *info, byte *buf, in
   if (!_mi_search(info,keyinfo, key_buff, use_key_length,
 		  myisam_read_vec[search_flag], info->s->state.key_root[inx]))
   {
-    while (info->lastpos >= info->state->data_file_length)
+    /*
+      If we are searching for an exact key (including the data pointer)
+      and this was added by an concurrent insert,
+      then the result is "key not found".
+    */
+    if ((search_flag == HA_READ_KEY_EXACT) &&
+        (info->lastpos >= info->state->data_file_length))
+    {
+      my_errno= HA_ERR_KEY_NOT_FOUND;
+      info->lastpos= HA_OFFSET_ERROR;
+    }
+    else while (info->lastpos >= info->state->data_file_length)
     {
       /*
 	Skip rows that are inserted by other threads since we got a lock
 	Note that this can only happen if we are not searching after an
 	exact key, because the keys are sorted according to position
       */
-
       if  (_mi_search_next(info, keyinfo, info->lastkey,
 			   info->lastkey_length,
 			   myisam_readnext_vec[search_flag],
@@ -92,6 +103,7 @@ int mi_rkey(MI_INFO *info, byte *buf, in
 	break;
     }
   }
+
   if (share->concurrent_insert)
     rw_unlock(&share->key_root_lock[inx]);
 

--- 1.113/sql/sql_class.cc	2005-11-03 18:24:00 +01:00
+++ 1.114/sql/sql_class.cc	2006-06-28 18:55:18 +02:00
@@ -477,7 +477,7 @@ bool select_send::send_data(List<Item> &
 {
   List_iterator_fast<Item> li(items);
   String *packet= &thd->packet;
-  DBUG_ENTER("send_data");
+  DBUG_ENTER("select_send::send_data");
 
 #ifdef HAVE_INNOBASE_DB
   /* We may be passing the control from mysqld to the client: release the
@@ -611,7 +611,7 @@ select_export::prepare(List<Item> &list)
 bool select_export::send_data(List<Item> &items)
 {
 
-  DBUG_ENTER("send_data");
+  DBUG_ENTER("select_export::send_data");
   char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
   bool space_inited=0;
   String tmp(buff,sizeof(buff)),*res;
@@ -828,7 +828,7 @@ bool select_dump::send_data(List<Item> &
   String tmp(buff,sizeof(buff)),*res;
   tmp.length(0);
   Item *item;
-  DBUG_ENTER("send_data");
+  DBUG_ENTER("select_dump::send_data");
 
   if (thd->offset_limit)
   {						// using limit offset,count
Thread
bk commit into 4.0 tree (ingo:1.2182) BUG#14400ingo28 Jun