List:Internals« Previous MessageNext Message »
From:Jay Pipes Date:July 16 2007 6:55pm
Subject:Question on where exactly locks are set on MyISAM data files...
View as plain text  
Hi!

I've been doing a bit of digging around for an article I'm writing on 
the MyISAM concurrent insert functionality and have run into a 
frustrating lack of understanding on *when* exactly file locks are 
placed on the .MYD data file during connection thread execution.

For the purposes of this inquiry, assume a fixed MyISAM record format, 
so we'd be talking about the _mi_write_static_record() function (as tied 
to the MYISAM_SHARE.write_record function pointer).  If you take a look 
at this stripped-down version of that function:

int _mi_write_static_record(MI_INFO *info, const uchar *record)
{
<snip>
   if (info->s->state.dellink != HA_OFFSET_ERROR &&
       !info->append_insert_at_end)
   {
     my_off_t filepos=info->s->state.dellink;
     info->rec_cache.seek_not_done=1;		/* We have done a seek */
     if (info->s->file_read(info,(char*) 
&temp[0],info->s->base.rec_reflength,
		info->s->state.dellink+1,
		 MYF(MY_NABP)))
       goto err;
     info->s->state.dellink= _mi_rec_pos(info->s,temp);
     info->state->del--;
     info->state->empty-=info->s->base.pack_reclength;
     if (info->s->file_write(info, (char*) record, info->s->base.reclength,
		  filepos,
		  MYF(MY_NABP)))
       goto err;
   }
   else
   {
<snip>
       info->rec_cache.seek_not_done=1; /* We have done a seek */
       if (info->s->file_write(info,(char*) record,info->s->base.reclength,
		    info->state->data_file_length,
		    info->s->write_flag))
         goto err;
       if (info->s->base.pack_reclength != info->s->base.reclength)
       {
	uint length=info->s->base.pack_reclength - info->s->base.reclength;
	bzero((char*) temp,length);
	if (info->s->file_write(info, (uchar*) temp,length,
		      info->state->data_file_length+
		      info->s->base.reclength,
		      info->s->write_flag))
     goto err;
       }
     }
     info->state->data_file_length+=info->s->base.pack_reclength;
     info->s->state.split++;
   }
   return 0;
  err:
   return 1;
}

I have the following questions:

1) I notice that if the append_insert_at_end property of the share's 
info struct is not set, then both a file_read() *and* a file_write() are 
called when writing the data -- presumably because a seek is needed to 
find the first deleted record slot...

If append_insert_at_end *is* set, then only a file_write() at the end of 
the file (an append) is issued.

Is this the reason why a lock is needed when concurrent inserts aren't 
enabled?  In other words, does the file_read() actually lock the file 
descriptor or the file in the place seeked to?

2) If file locking doesn't happen in either file_read() nor file_write() 
(which I could not find any evidence that in a PREAD environment they 
do...) when exactly does the file locking occur?  I see that in 
mi_lock_database() (in /storage/myisam/mi_locking.c) there are calls to 
my_lock(), but only for the share->kfile, which I thought was just the 
.frm file?

Where does the .MYD file get locked during non-concurrent inserts/writes?

Your insight would be GREATLY appreciated, as my eyesight is beginning 
to blur as I grep my way through countless function pointer redirections 
and redefines in /storage/myisam and /mysys

Cheers!

jay
Thread
Question on where exactly locks are set on MyISAM data files...Jay Pipes16 Jul
  • Re: Question on where exactly locks are set on MyISAM data files...Ingo Strüwing17 Jul
    • Re: Question on where exactly locks are set on MyISAM data files...Jay Pipes18 Jul
      • Re: Question on where exactly locks are set on MyISAM data files...Ingo Strüwing18 Jul
        • Re: Question on where exactly locks are set on MyISAM data files...Jay Pipes18 Jul
  • Re: Question on where exactly locks are set on MyISAM data files...Sergei Golubchik17 Jul