Exemple #1
0
int nisam_is_changed(N_INFO *info)
{
  int result;
  DBUG_ENTER("nisam_is_changed");
#ifndef NO_LOCKING
  if (_nisam_readinfo(info,F_RDLCK,1)) DBUG_RETURN(-1);
  VOID(_nisam_writeinfo(info,0));
#endif
  result=(int) info->data_changed;
  info->data_changed=0;
  DBUG_PRINT("exit",("result: %d",result));
  DBUG_RETURN(result);
}
Exemple #2
0
int nisam_info(N_INFO *info, register N_ISAMINFO *x, int flag)
{
  struct stat state;
  ISAM_SHARE *share=info->s;
  DBUG_ENTER("nisam_info");

  x->recpos  = info->lastpos;
  if (flag & (HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE |
	      HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK))
  {
#ifndef NO_LOCKING
    if (!(flag & HA_STATUS_NO_LOCK))
    {
      pthread_mutex_lock(&share->intern_lock);
      VOID(_nisam_readinfo(info,F_RDLCK,0));
      VOID(_nisam_writeinfo(info,0));
      pthread_mutex_unlock(&share->intern_lock);
    }
#endif
    x->records	 = share->state.records;
    x->deleted	 = share->state.del;
    x->delete_length= share->state.empty;
    x->keys	 = share->state.keys;
    x->reclength = share->base.reclength;
    x->mean_reclength= share->state.records ?
      (share->state.data_file_length-share->state.empty)/share->state.records :
      share->min_pack_length;
    x->data_file_length=share->state.data_file_length;
    x->max_data_file_length=share->base.max_data_file_length;
    x->index_file_length=share->state.key_file_length;
    x->max_index_file_length=share->base.max_key_file_length;
    x->filenr	 = info->dfile;
    x->errkey	 = info->errkey;
    x->dupp_key_pos= info->dupp_key_pos;
    x->options	 = share->base.options;
    x->create_time=share->base.create_time;
    x->isamchk_time=share->base.isamchk_time;
    x->rec_per_key=share->base.rec_per_key;
    if ((flag & HA_STATUS_TIME) && !fstat(info->dfile,&state))
      x->update_time=state.st_mtime;
    else
      x->update_time=0;
    x->sortkey= -1;				/* No clustering */
  }
  DBUG_RETURN(0);
} /* nisam_info */
Exemple #3
0
int nisam_rprev(N_INFO *info, byte *buf, int inx)
{
  int error,changed;
  register uint flag;
  DBUG_ENTER("nisam_rprev");

  if ((inx = _nisam_check_index(info,inx)) < 0)
    DBUG_RETURN(-1);
  flag=SEARCH_SMALLER;				/* Read previous */
  if (info->lastpos == NI_POS_ERROR && info->update & HA_STATE_NEXT_FOUND)
    flag=0;					/* Read last */

#ifndef NO_LOCKING
  if (_nisam_readinfo(info,F_RDLCK,1)) DBUG_RETURN(-1);
#endif
  changed=_nisam_test_if_changed(info);
  if (!flag)
    error=_nisam_search_last(info,info->s->keyinfo+inx,info->s->state.key_root[inx]);
  else if (!changed)
    error=_nisam_search_next(info,info->s->keyinfo+inx,info->lastkey,flag,
			  info->s->state.key_root[inx]);
  else
    error=_nisam_search(info,info->s->keyinfo+inx,info->lastkey,0,flag,
		     info->s->state.key_root[inx]);

  info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED |
		  HA_STATE_BUFF_SAVED);
  info->update|= HA_STATE_PREV_FOUND;
  if (error && my_errno == HA_ERR_KEY_NOT_FOUND)
    my_errno=HA_ERR_END_OF_FILE;
  if ((*info->read_record)(info,info->lastpos,buf) >=0)
  {
    info->update|= HA_STATE_AKTIV;		/* Record is read */
    DBUG_RETURN(0);
  }
  DBUG_RETURN(-1);
} /* nisam_rprev */
Exemple #4
0
int nisam_panic(enum ha_panic_function flag)
{
  int error=0;
  LIST *list_element,*next_open;
  N_INFO *info;
  DBUG_ENTER("nisam_panic");

  pthread_mutex_lock(&THR_LOCK_isam);
  for (list_element=nisam_open_list ; list_element ; list_element=next_open)
  {
    next_open=list_element->next;		/* Save if close */
    info=(N_INFO*) list_element->data;
    switch (flag) {
    case HA_PANIC_CLOSE:
      pthread_mutex_unlock(&THR_LOCK_isam);	/* Not exactly right... */
      if (nisam_close(info))
	error=my_errno;
      pthread_mutex_lock(&THR_LOCK_isam);
      break;
    case HA_PANIC_WRITE:		/* Do this to free databases */
#ifdef CANT_OPEN_FILES_TWICE
      if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
	break;
#endif
      if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
	error=my_errno;
      if (info->opt_flag & WRITE_CACHE_USED)
	if (flush_io_cache(&info->rec_cache))
	  error=my_errno;
      if (info->opt_flag & READ_CACHE_USED)
      {
	if (flush_io_cache(&info->rec_cache))
	  error=my_errno;
	reinit_io_cache(&info->rec_cache,READ_CACHE,0,
		       (pbool) (info->lock_type != F_UNLCK),1);
      }
#ifndef NO_LOCKING
      if (info->lock_type != F_UNLCK && ! info->was_locked)
      {
	info->was_locked=info->lock_type;
	if (nisam_lock_database(info,F_UNLCK))
	  error=my_errno;
      }
#else
      {
	int save_status=info->s->w_locks;	/* Only w_locks! */
	info->s->w_locks=0;
	if (_nisam_writeinfo(info, test(info->update & HA_STATE_CHANGED)))
	  error=my_errno;
	info->s->w_locks=save_status;
	info->update&= ~HA_STATE_CHANGED;	/* Not changed */
      }
#endif					/* NO_LOCKING */
#ifdef CANT_OPEN_FILES_TWICE
      if (info->s->kfile >= 0 && my_close(info->s->kfile,MYF(0)))
	error = my_errno;
      if (info->dfile >= 0 && my_close(info->dfile,MYF(0)))
	error = my_errno;
      info->s->kfile=info->dfile= -1;	/* Files aren't open anymore */
      break;
#endif
    case HA_PANIC_READ:			/* Restore to before WRITE */
#ifdef CANT_OPEN_FILES_TWICE
      {					/* Open closed files */
	char name_buff[FN_REFLEN];
	if (info->s->kfile < 0)
	  if ((info->s->kfile= my_open(fn_format(name_buff,info->filename,"",
					      N_NAME_IEXT,4),info->mode,
				    MYF(MY_WME))) < 0)
	    error = my_errno;
	if (info->dfile < 0)
	{
	  if ((info->dfile= my_open(fn_format(name_buff,info->filename,"",
					      N_NAME_DEXT,4),info->mode,
				    MYF(MY_WME))) < 0)
	    error = my_errno;
	  info->rec_cache.file=info->dfile;
	}
      }
#endif
#ifndef NO_LOCKING
      if (info->was_locked)
      {
	if (nisam_lock_database(info, info->was_locked))
	  error=my_errno;
	info->was_locked=0;
      }
#else
      {
	int lock_type,w_locks;
	lock_type=info->lock_type ; w_locks=info->s->w_locks;
	info->lock_type=0; info->s->w_locks=0;
	if (_nisam_readinfo(info,0,1))	/* Read changed data */
	  error=my_errno;
	info->lock_type=lock_type; info->s->w_locks=w_locks;
      }
      /* Don't use buffer when doing next */
      info->update|=HA_STATE_WRITTEN;
#endif					/* NO_LOCKING */
      break;
    }
  }
  if (flag == HA_PANIC_CLOSE)
    VOID(nisam_log(0));				/* Close log if neaded */
  pthread_mutex_unlock(&THR_LOCK_isam);
  if (!error) DBUG_RETURN(0);
  my_errno=error;
  DBUG_RETURN(-1);
} /* nisam_panic */
Exemple #5
0
int nisam_update(register N_INFO *info, const byte *oldrec, const byte *newrec)
{
  int flag,key_changed,save_errno;
  reg3 ulong pos;
  uint i,length;
  uchar old_key[N_MAX_KEY_BUFF],*new_key;
  DBUG_ENTER("nisam_update");

  LINT_INIT(save_errno);
  if (!(info->update & HA_STATE_AKTIV))
  {
    my_errno=HA_ERR_KEY_NOT_FOUND;
    DBUG_RETURN(-1);
  }
  if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
  {
    my_errno=EACCES;
    DBUG_RETURN(-1);
  }
  pos=info->lastpos;
#ifndef NO_LOCKING
  if (_nisam_readinfo(info,F_WRLCK,1)) DBUG_RETURN(-1);
#endif
  if ((*info->s->compare_record)(info,oldrec))
  {
    save_errno=my_errno;
    goto err_end;			/* Record has changed */
  }
  if (info->s->state.key_file_length >=
      info->s->base.max_key_file_length -
      info->s->blocksize* INDEX_BLOCK_MARGIN *info->s->state.keys)
  {
    save_errno=HA_ERR_INDEX_FILE_FULL;
    goto err_end;
  }

	/* Flyttar de element i isamfilen som m}ste flyttas */

  new_key=info->lastkey+info->s->base.max_key_length;
  key_changed=HA_STATE_KEY_CHANGED;	/* We changed current database */
					/* Remove key that didn't change */
  for (i=0 ; i < info->s->state.keys ; i++)
  {
    length=_nisam_make_key(info,i,new_key,newrec,pos);
    if (length != _nisam_make_key(info,i,old_key,oldrec,pos) ||
	memcmp((byte*) old_key,(byte*) new_key,length))
    {
      if ((int) i == info->lastinx)
	key_changed|=HA_STATE_WRITTEN;		/* Mark that keyfile changed */
      if (_nisam_ck_delete(info,i,old_key)) goto err;
      if (_nisam_ck_write(info,i,new_key)) goto err;
    }
  }

  if ((*info->s->update_record)(info,pos,newrec))
    goto err;

  info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
		 key_changed);
  nisam_log_record(LOG_UPDATE,info,newrec,info->lastpos,0);
  VOID(_nisam_writeinfo(info,test(key_changed)));
  allow_break();				/* Allow SIGHUP & SIGINT */
  DBUG_RETURN(0);

err:
  DBUG_PRINT("error",("key: %d  errno: %d",i,my_errno));
  save_errno=my_errno;
  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
  {
    info->errkey= (int) i;
    flag=0;
    do
    {
      length=_nisam_make_key(info,i,new_key,newrec,pos);
      if (length != _nisam_make_key(info,i,old_key,oldrec,pos) ||
	  memcmp((byte*) old_key,(byte*) new_key,length))
      {
	if ((flag++ && _nisam_ck_delete(info,i,new_key)) ||
	    _nisam_ck_write(info,i,old_key))
	  break;
      }
    } while (i-- != 0);
  }
  info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
		 key_changed);
 err_end:
  nisam_log_record(LOG_UPDATE,info,newrec,info->lastpos,save_errno);
  VOID(_nisam_writeinfo(info,1));
  allow_break();				/* Allow SIGHUP & SIGINT */
  my_errno=(save_errno == HA_ERR_KEY_NOT_FOUND) ? HA_ERR_CRASHED : save_errno;
  DBUG_RETURN(-1);
} /* nisam_update */
Exemple #6
0
int nisam_write(N_INFO *info, const byte *record)
{
  uint i;
  ulong filepos;
  uchar *buff;
  DBUG_ENTER("nisam_write");
  DBUG_PRINT("enter",("isam: %d  data: %d",info->s->kfile,info->dfile));

  if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
  {
    my_errno=EACCES;
    DBUG_RETURN(-1);
  }
#ifndef NO_LOCKING
  if (_nisam_readinfo(info,F_WRLCK,1)) DBUG_RETURN(-1);
#endif
  dont_break();				/* Dont allow SIGHUP or SIGINT */
#if !defined(NO_LOCKING) && defined(USE_RECORD_LOCK)
  if (!info->locked && my_lock(info->dfile,F_WRLCK,0L,F_TO_EOF,
			       MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
    goto err;
#endif
  filepos= ((info->s->state.dellink != NI_POS_ERROR) ?
	    info->s->state.dellink :
	    info->s->state.data_file_length);

  if (info->s->base.reloc == 1L && info->s->base.records == 1L &&
      info->s->state.records == 1L)
  {						/* System file */
    my_errno=HA_ERR_RECORD_FILE_FULL;
    goto err2;
  }
  if (info->s->state.key_file_length >=
      info->s->base.max_key_file_length -
      info->s->blocksize* INDEX_BLOCK_MARGIN *info->s->state.keys)
  {
    my_errno=HA_ERR_INDEX_FILE_FULL;
    goto err2;
  }

	/* Write all keys to indextree */
  buff=info->lastkey+info->s->base.max_key_length;
  for (i=0 ; i < info->s->state.keys ; i++)
  {
    VOID(_nisam_make_key(info,i,buff,record,filepos));
    if (_nisam_ck_write(info,i,buff)) goto err;
  }

  if ((*info->s->write_record)(info,record))
    goto err;

  info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED |HA_STATE_AKTIV |
		 HA_STATE_WRITTEN);
  info->s->state.records++;
  info->lastpos=filepos;
  nisam_log_record(LOG_WRITE,info,record,filepos,0);
  VOID(_nisam_writeinfo(info,1));
  allow_break();				/* Allow SIGHUP & SIGINT */
  DBUG_RETURN(0);

err:
  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
  {
    info->errkey= (int) i;
    while ( i-- > 0)
    {
      VOID(_nisam_make_key(info,i,buff,record,filepos));
      if (_nisam_ck_delete(info,i,buff))
	break;
    }
  }
  info->update=(HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_WRITTEN);
err2:
  nisam_log_record(LOG_WRITE,info,record,filepos,my_errno);
  VOID(_nisam_writeinfo(info,1));
  allow_break();			/* Allow SIGHUP & SIGINT */
  DBUG_RETURN(-1);
} /* nisam_write */
Exemple #7
0
int _nisam_read_rnd_static_record(N_INFO *info, byte *buf,
				  register ulong filepos,
				  int skipp_deleted_blocks)
{
  int locked,error,cache_read;
  uint cache_length;
  ISAM_SHARE *share=info->s;
  DBUG_ENTER("_nisam_read_rnd_static_record");

  cache_read=0;
  LINT_INIT(cache_length);
  if (info->opt_flag & WRITE_CACHE_USED &&
      (info->rec_cache.pos_in_file <= filepos || skipp_deleted_blocks) &&
      flush_io_cache(&info->rec_cache))
    DBUG_RETURN(-1);
  if (info->opt_flag & READ_CACHE_USED)
  {						/* Cash in use */
    if (filepos == my_b_tell(&info->rec_cache) &&
	(skipp_deleted_blocks || !filepos))
    {
      cache_read=1;				/* Read record using cache */
      cache_length=(uint) (info->rec_cache.rc_end - info->rec_cache.rc_pos);
    }
    else
      info->rec_cache.seek_not_done=1;		/* Filepos is changed */
  }
#ifndef NO_LOCKING
  locked=0;
  if (info->lock_type == F_UNLCK)
  {
    if (filepos >= share->state.data_file_length)
    {						/* Test if new records */
      if (_nisam_readinfo(info,F_RDLCK,0))
	DBUG_RETURN(-1);
      locked=1;
    }
    else
    {						/* We don't nead new info */
#ifndef UNSAFE_LOCKING
      if ((! cache_read || share->base.reclength > cache_length) &&
	  share->r_locks == 0 && share->w_locks == 0)
      {						/* record not in cache */
	if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
		    MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
	  DBUG_RETURN(-1);
	locked=1;
      }
#else
      info->tmp_lock_type=F_RDLCK;
#endif
    }
  }
#endif
  if (filepos >= share->state.data_file_length)
  {
#ifndef NO_LOCKING
    DBUG_PRINT("test",("filepos: %ld (%ld)  records: %ld  del: %ld",
		       filepos/share->base.reclength,filepos,
		       share->state.records, share->state.del));
    VOID(_nisam_writeinfo(info,0));
#endif
    my_errno=HA_ERR_END_OF_FILE;
    DBUG_RETURN(-1);
  }
  info->lastpos= filepos;
  info->nextpos= filepos+share->base.reclength;

  if (! cache_read)			/* No cacheing */
  {
    error=_nisam_read_static_record(info,filepos,buf);
    if (error > 0)
      my_errno=HA_ERR_RECORD_DELETED;
    DBUG_RETURN(error);
  }

	/* Read record with cacheing */
  error=my_b_read(&info->rec_cache,(byte*) buf,share->base.reclength);

#ifndef NO_LOCKING
  if (locked)
    VOID(_nisam_writeinfo(info,0));		/* Unlock keyfile */
#endif
  if (!error)
  {
    if (!buf[0])
    {						/* Record is removed */
      my_errno=HA_ERR_RECORD_DELETED;
      DBUG_RETURN(1);
    }
						/* Found and may be updated */
    info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
    DBUG_RETURN(0);
  }
  if (info->rec_cache.error != -1 || my_errno == 0)
    my_errno=HA_ERR_WRONG_IN_RECORD;
  DBUG_RETURN(-1);				/* Something wrong (EOF?) */
}