int mi_delete_all_rows(MI_INFO *info) { uint i; MYISAM_SHARE *share=info->s; MI_STATE_INFO *state=&share->state; DBUG_ENTER("mi_delete_all_rows"); if (share->options & HA_OPTION_READ_ONLY_DATA) { DBUG_RETURN(my_errno=EACCES); } if (_mi_readinfo(info,F_WRLCK,1)) DBUG_RETURN(my_errno); if (_mi_mark_file_changed(info)) goto err; info->state->records=info->state->del=state->split=0; state->dellink = HA_OFFSET_ERROR; state->sortkey= (ushort) ~0; info->state->key_file_length=share->base.keystart; info->state->data_file_length=0; info->state->empty=info->state->key_empty=0; info->state->checksum=0; for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) state->key_del[i]= HA_OFFSET_ERROR; for (i=0 ; i < share->base.keys ; i++) state->key_root[i]= HA_OFFSET_ERROR; myisam_log_command(MI_LOG_DELETE_ALL,info,(uchar*) 0,0,0); /* If we are using delayed keys or if the user has done changes to the tables since it was locked then there may be key blocks in the key cache */ flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED); #ifdef HAVE_MMAP if (share->file_map) mi_munmap_file(info); #endif if (mysql_file_chsize(info->dfile, 0, 0, MYF(MY_WME)) || mysql_file_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME))) goto err; (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); #ifdef HAVE_MMAP /* Map again */ if (share->file_map) mi_dynmap_file(info, (my_off_t) 0); #endif allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); err: { int save_errno=my_errno; (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); info->update|=HA_STATE_WRITTEN; /* Buffer changed */ allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(my_errno=save_errno); } } /* mi_delete */
int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf, register my_off_t filepos, my_bool skip_deleted_blocks) { int locked,error,cache_read; uint cache_length; MYISAM_SHARE *share=info->s; DBUG_ENTER("_mi_read_rnd_static_record"); cache_read=0; cache_length=0; if (info->opt_flag & WRITE_CACHE_USED && (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) && flush_io_cache(&info->rec_cache)) DBUG_RETURN(my_errno); if (info->opt_flag & READ_CACHE_USED) { /* Cache in use */ if (filepos == my_b_tell(&info->rec_cache) && (skip_deleted_blocks || !filepos)) { cache_read=1; /* Read record using cache */ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos); } else info->rec_cache.seek_not_done=1; /* Filepos is changed */ } locked=0; if (info->lock_type == F_UNLCK) { if (filepos >= info->state->data_file_length) { /* Test if new records */ if (_mi_readinfo(info,F_RDLCK,0)) DBUG_RETURN(my_errno); locked=1; } else { /* We don't nead new info */ #ifndef UNSAFE_LOCKING if ((! cache_read || share->base.reclength > cache_length) && share->tot_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(my_errno); locked=1; } #else info->tmp_lock_type=F_RDLCK; #endif } } if (filepos >= info->state->data_file_length) { DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld", (long) filepos/share->base.reclength, (long) filepos, (long) info->state->records, (long) info->state->del)); fast_mi_writeinfo(info); DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE); } info->lastpos= filepos; info->nextpos= filepos+share->base.pack_reclength; if (! cache_read) /* No cacheing */ { if ((error=_mi_read_static_record(info,filepos,buf))) { if (error > 0) error=my_errno=HA_ERR_RECORD_DELETED; else error=my_errno; } DBUG_RETURN(error); } /* Read record with caching. If my_b_read() returns TRUE, less than the requested bytes have been read. In this case rec_cache.error is either -1 for a read error, or contains the number of bytes copied into the buffer. */ error=my_b_read(&info->rec_cache,(uchar*) buf,share->base.reclength); if (info->s->base.pack_reclength != info->s->base.reclength && !error) { char tmp[8]; /* Skill fill bytes */ error=my_b_read(&info->rec_cache,(uchar*) tmp, info->s->base.pack_reclength - info->s->base.reclength); } if (locked) (void) _mi_writeinfo(info,0); /* Unlock keyfile */ if (!error) { if (!buf[0]) { /* Record is removed */ DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); } /* Found and may be updated */ info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; DBUG_RETURN(0); } /* error is TRUE. my_errno should be set if rec_cache.error == -1 */ if (info->rec_cache.error != -1 || my_errno == 0) { /* If we could not get a full record, we either have a broken record, or are at end of file. */ if (info->rec_cache.error == 0) my_errno= HA_ERR_END_OF_FILE; else my_errno= HA_ERR_WRONG_IN_RECORD; } DBUG_RETURN(my_errno); /* Something wrong (EOF?) */ }
int mi_write(MI_INFO * info, byte * record) { uint i; int save_errno; my_off_t filepos; uchar *buff; MYISAM_SHARE *share = info->s; DBUG_ENTER("mi_write"); DBUG_PRINT("enter", ("isam: %d data: %d", info->s->kfile, info->dfile)); if (share->options & HA_OPTION_READ_ONLY_DATA) { DBUG_RETURN(my_errno = EACCES); } if (_mi_readinfo(info, F_WRLCK, 1)) DBUG_RETURN(my_errno); 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 = ((share->state.dellink != HA_OFFSET_ERROR) ? share->state.dellink : info->state->data_file_length); if (share->base.reloc == (ha_rows) 1 && share->base.records == (ha_rows) 1 && info->state->records == (ha_rows) 1) { /* System file */ my_errno = HA_ERR_RECORD_FILE_FULL; goto err2; } if (info->state->key_file_length >= share->base.margin_key_file_length) { my_errno = HA_ERR_INDEX_FILE_FULL; goto err2; } if (_mi_mark_file_changed(info)) goto err2; /* Calculate and check all unique constraints */ for (i = 0; i < share->state.header.uniques; i++) { if (mi_check_unique(info, share->uniqueinfo + i, record, mi_unique_hash(share->uniqueinfo + i, record), HA_OFFSET_ERROR)) goto err2; } /* Write all keys to indextree */ buff = info->lastkey2; for (i = 0; i < share->base.keys; i++) { if (((ulonglong) 1 << i) & share->state.key_map) { if (share->concurrent_insert) { rw_wrlock(&share->key_root_lock[i]); share->keyinfo[i].version++; } if (share->keyinfo[i].flag & HA_FULLTEXT) { /* SerG *//* SerG */ if (_mi_ft_add(info, i, (char *)buff, record, filepos)) { /* SerG *//* SerG */ if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); DBUG_PRINT("error", ("Got error: %d on write", my_errno)); /* SerG */ goto err; /* SerG */ } /* SerG */ } /* SerG */ else { /* SerG */ uint key_length = _mi_make_key(info, i, buff, record, filepos); if (_mi_ck_write(info, i, buff, key_length)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); DBUG_PRINT("error", ("Got error: %d on write", my_errno)); goto err; } } if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); } } if (share->calc_checksum) info->checksum = (*share->calc_checksum) (info, record); if (!(info->opt_flag & OPT_NO_ROWS)) { if ((*share->write_record) (info, record)) goto err; share->state.checksum += info->checksum; } if (share->base.auto_key) update_auto_increment(info, record); info->update = (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); info->state->records++; info->lastpos = filepos; myisam_log_record(MI_LOG_WRITE, info, record, filepos, 0); VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); err: save_errno = my_errno; if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL) { info->errkey = (int)i; while (i-- > 0) { if (((ulonglong) 1 << i) & share->state.key_map) { if (share->concurrent_insert) rw_wrlock(&share->key_root_lock[i]); /* * The following code block is for text * searching by SerG */ if (share->keyinfo[i].flag & HA_FULLTEXT) { if (_mi_ft_del(info, i, (char *)buff, record, filepos)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); break; } } else { uint key_length = _mi_make_key(info, i, buff, record, filepos); if (_mi_ck_delete(info, i, buff, key_length)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); break; } } if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); } } } else mi_mark_crashed(info); info->update = (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); my_errno = save_errno; err2: save_errno = my_errno; myisam_log_record(MI_LOG_WRITE, info, record, filepos, my_errno); VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(my_errno = save_errno); } /* mi_write */