diff options
Diffstat (limited to 'storage/myisam')
-rw-r--r-- | storage/myisam/mi_packrec.c | 45 | ||||
-rw-r--r-- | storage/myisam/mi_static.c | 3 | ||||
-rw-r--r-- | storage/myisam/myisamdef.h | 1 |
3 files changed, 45 insertions, 4 deletions
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index ee56d86f5ba..b3a6bf78566 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1492,20 +1492,54 @@ static int _mi_read_rnd_mempack_record(MI_INFO*, uchar *,my_off_t, my_bool); my_bool _mi_memmap_file(MI_INFO *info) { MYISAM_SHARE *share=info->s; + my_bool eom; + DBUG_ENTER("mi_memmap_file"); if (!info->s->file_map) { + my_off_t data_file_length= share->state.state.data_file_length; + + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + eom= data_file_length > myisam_mmap_size - myisam_mmap_used - MEMMAP_EXTRA_MARGIN; + if (!eom) + myisam_mmap_used+= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } + else + eom= data_file_length > myisam_mmap_size - MEMMAP_EXTRA_MARGIN; + + if (eom) + { + DBUG_PRINT("warning", ("File is too large for mmap")); + DBUG_RETURN(0); + } if (mysql_file_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) < share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN) { DBUG_PRINT("warning",("File isn't extended for memmap")); + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } DBUG_RETURN(0); } if (mi_dynmap_file(info, share->state.state.data_file_length + MEMMAP_EXTRA_MARGIN)) + { + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } DBUG_RETURN(0); + } } info->opt_flag|= MEMMAP_USED; info->read_record= share->read_record= _mi_read_mempack_record; @@ -1516,8 +1550,15 @@ my_bool _mi_memmap_file(MI_INFO *info) void _mi_unmap_file(MI_INFO *info) { - (void) my_munmap((char*) info->s->file_map, - (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN); + (void) my_munmap((char*) info->s->file_map, + (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN); + + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } } diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c index aaa7405bbb5..b763308a4a9 100644 --- a/storage/myisam/mi_static.c +++ b/storage/myisam/mi_static.c @@ -40,7 +40,8 @@ ulong myisam_concurrent_insert= 0; my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; - +ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; +pthread_mutex_t THR_LOCK_myisam_mmap; static int always_valid(const char *filename __attribute__((unused))) { diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 43746975232..a1142ff418a 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -442,7 +442,6 @@ typedef struct st_mi_sort_param #define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1))) #define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32)) -#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */ #define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */ #define PACK_TYPE_SPACE_FIELDS 2 |