From b21cf962e381300def1bb91d33f6ab411c0c0cc4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 May 2005 12:08:08 +0300 Subject: concurrent-insert can now be set to 2 for concurrent inserts when there is holes in the data file myisam_max_extra_sort_file_size is depricated Ensure that myisam_data_pointer_size is honoured when creating new MyISAM files Changed default value of myisam_data_pointer_size from 4 to 6 to get rid of 'table-is-full' errors include/myisam.h: Change type of myisam_block_size and myisam_concurrent_insert to make them changeable in mysqld.cc Removed not used varaible myisam_max_extra_temp_length include/thr_lock.h: Added extra parameter to get_status myisam/mi_create.c: Ensure that myisam_data_pointer_size is honoured myisam/mi_dynrec.c: If 'append_insert_at_end' is set, only write at end of myisam record file myisam/mi_locking.c: Add extra argument to 'mi_get_status' to allow thr_lock to signal that we want to do a concurrent insert If this is used, we will append new insert rows at end of data file. Change mi_check_status() to allow concurrent_inserts even if there are holes in the file when myisam_concurent_insert=2 myisam/mi_static.c: Change behavior of myisam_concurrent_insert so that setting this to 2 allows inserts even if there is a hole in the data file. Default value is 2 for MyISAM direct usage but will be set to 1 (old default) by mysqld.cc myisam/mi_statrec.c: If 'append_insert_at_end' is set, only write at end of myisam record file myisam/mi_write.c: If 'append_insert_at_end' is set, only write at end of myisam record file myisam/myisamdef.h: Support for insert-at-end even if there is holes in data file mysql-test/r/gis-rtree.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/group_min_max.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/index_merge.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/index_merge_ror.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/merge.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/myisam.result: Test of concurrent_insert=2 mysql-test/r/null.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/preload.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/ps_1general.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/range.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/r/variables.result: concurrent_insert is now a integer, not a boolean myisam_extra_sort_file_size is deleted mysql-test/r/view.result: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/t/index_merge.test: Test result changed because default value for myisam_data_pointer_size is changed from 4 -> 6 mysql-test/t/myisam.test: Test of concurrent_insert=2 mysql-test/t/ps_1general.test: Drop test table mysql-test/t/variables.test: concurrent_insert is now a integer, not a boolean myisam_extra_sort_file_size is deleted mysql-test/t/view.test: Drop tables that may be left from previous tests mysys/thr_lock.c: Extra paramter to get_status to signal if concurrent_insert was used sql/mysqld.cc: concurrent-insert can now be set to 2 for concurrent inserts when there is holes in the data file myisam_max_extra_sort_file_size is depricated sql/set_var.cc: concurrent-insert is now an integer, not a bool myisam_max_extra_sort_file_size is deleted --- myisam/mi_create.c | 7 +++---- myisam/mi_dynrec.c | 12 ++++++++---- myisam/mi_locking.c | 45 ++++++++++++++++++++++++++++++++++++++------- myisam/mi_static.c | 7 +++---- myisam/mi_statrec.c | 3 ++- myisam/mi_write.c | 3 ++- myisam/myisamdef.h | 3 ++- 7 files changed, 58 insertions(+), 22 deletions(-) (limited to 'myisam') diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 8635d6bcf36..12b03e65baa 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -191,11 +191,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD)); min_pack_length+=packed; - if (!ci->data_file_length) + if (!ci->data_file_length && ci->max_rows) { - if (ci->max_rows == 0 || pack_reclength == INT_MAX32) - ci->data_file_length= INT_MAX32-1; /* Should be enough */ - else if ((~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength) + if (pack_reclength == INT_MAX32 || + (~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength) ci->data_file_length= ~(ulonglong) 0; else ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength; diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 3a4dafade23..8de500a7351 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -149,7 +149,9 @@ static int write_dynamic_record(MI_INFO *info, const byte *record, { if (_mi_find_writepos(info,reclength,&filepos,&length)) goto err; - if (_mi_write_part_record(info,filepos,length,info->s->state.dellink, + if (_mi_write_part_record(info,filepos,length, + (info->append_insert_at_end ? + HA_OFFSET_ERROR : info->s->state.dellink), (byte**) &record,&reclength,&flag)) goto err; } while (reclength); @@ -171,7 +173,8 @@ static int _mi_find_writepos(MI_INFO *info, ulong tmp; DBUG_ENTER("_mi_find_writepos"); - if (info->s->state.dellink != HA_OFFSET_ERROR) + if (info->s->state.dellink != HA_OFFSET_ERROR && + !info->append_insert_at_end) { /* Deleted blocks exists; Get last used block */ *filepos=info->s->state.dellink; @@ -420,8 +423,9 @@ int _mi_write_part_record(MI_INFO *info, else if (length-long_block < *reclength+4) { /* To short block */ if (next_filepos == HA_OFFSET_ERROR) - next_filepos=info->s->state.dellink != HA_OFFSET_ERROR ? - info->s->state.dellink : info->state->data_file_length; + next_filepos= (info->s->state.dellink != HA_OFFSET_ERROR && + !info->append_insert_at_end ? + info->s->state.dellink : info->state->data_file_length); if (*flag == 0) /* First block */ { if (*reclength > MI_MAX_BLOCK_LENGTH) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 789d74680ef..8d48c5242e5 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -238,13 +238,24 @@ int mi_lock_database(MI_INFO *info, int lock_type) The following functions are called by thr_lock() in threaded applications ****************************************************************************/ -void mi_get_status(void* param) +/* + Create a copy of the current status for the table + + SYNOPSIS + mi_get_status() + param Pointer to Myisam handler + concurrent_insert Set to 1 if we are going to do concurrent inserts + (THR_WRITE_CONCURRENT_INSERT was used) +*/ + +void mi_get_status(void* param, int concurrent_insert) { MI_INFO *info=(MI_INFO*) param; DBUG_ENTER("mi_get_status"); - DBUG_PRINT("info",("key_file: %ld data_file: %ld", + DBUG_PRINT("info",("key_file: %ld data_file: %ld concurrent_insert: %d", (long) info->s->state.state.key_file_length, - (long) info->s->state.state.data_file_length)); + (long) info->s->state.state.data_file_length, + concurrent_insert)); #ifndef DBUG_OFF if (info->state->key_file_length > info->s->state.state.key_file_length || info->state->data_file_length > info->s->state.state.data_file_length) @@ -254,9 +265,11 @@ void mi_get_status(void* param) #endif info->save_state=info->s->state.state; info->state= &info->save_state; + info->append_insert_at_end= concurrent_insert; DBUG_VOID_RETURN; } + void mi_update_status(void* param) { MI_INFO *info=(MI_INFO*) param; @@ -281,6 +294,7 @@ void mi_update_status(void* param) info->s->state.state= *info->state; info->state= &info->s->state.state; } + info->append_insert_at_end= 0; /* We have to flush the write cache here as other threads may start @@ -307,20 +321,37 @@ void mi_copy_status(void* to,void *from) Check if should allow concurrent inserts IMPLEMENTATION - Don't allow concurrent inserts if we have a hole in the table. + Allow concurrent inserts if we don't have a hole in the table or + if there is no active write lock and there is active read locks and + myisam_concurrent_insert == 2. In this last case the new + row('s) are inserted at end of file instead of filling up the hole. + + The last case is to allow one to inserts into a heavily read-used table + even if there is holes. NOTES - Rtree indexes are disabled in mi_open() + If there is a an rtree indexes in the table, concurrent inserts are + disabled in mi_open() RETURN 0 ok to use concurrent inserts 1 not ok */ -my_bool mi_check_status(void* param) +my_bool mi_check_status(void *param) { MI_INFO *info=(MI_INFO*) param; - return (my_bool) (info->s->state.dellink != HA_OFFSET_ERROR); + /* + The test for w_locks == 1 is here because this thread has already done an + external lock (in other words: w_locks == 1 means no other threads has + a write lock) + */ + DBUG_PRINT("info",("dellink: %ld r_locks: %u w_locks: %u", + (long) info->s->state.dellink, (uint) info->s->r_locks, + (uint) info->s->w_locks)); + return (my_bool) !(info->s->state.dellink == HA_OFFSET_ERROR || + (myisam_concurrent_insert == 2 && info->s->r_locks && + info->s->w_locks == 1)); } diff --git a/myisam/mi_static.c b/myisam/mi_static.c index f41aeff8453..4c9d814f7d6 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -31,14 +31,13 @@ uchar NEAR myisam_pack_file_magic[]= my_string myisam_log_filename=(char*) "myisam.log"; File myisam_log_file= -1; uint myisam_quick_table_bits=9; -uint myisam_block_size=MI_KEY_BLOCK_LENGTH; /* Best by test */ +ulong myisam_block_size= MI_KEY_BLOCK_LENGTH; /* Best by test */ my_bool myisam_flush=0, myisam_delay_key_write=0, myisam_single_user=0; #if defined(THREAD) && !defined(DONT_USE_RW_LOCKS) -my_bool myisam_concurrent_insert=1; +ulong myisam_concurrent_insert= 2; #else -my_bool myisam_concurrent_insert=0; +ulong myisam_concurrent_insert= 0; #endif -my_off_t myisam_max_extra_temp_length= (my_off_t)MI_MAX_TEMP_LENGTH; my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c index 8f5cde45e24..42352f63c66 100644 --- a/myisam/mi_statrec.c +++ b/myisam/mi_statrec.c @@ -23,7 +23,8 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) { uchar temp[8]; /* max pointer length */ - if (info->s->state.dellink != HA_OFFSET_ERROR) + 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 */ diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 5d7e245c58f..dd062b79769 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -67,7 +67,8 @@ int mi_write(MI_INFO *info, byte *record) MYF(MY_SEEK_NOT_DONE) | info->lock_wait)) goto err; #endif - filepos= ((share->state.dellink != HA_OFFSET_ERROR) ? + filepos= ((share->state.dellink != HA_OFFSET_ERROR && + !info->append_insert_at_end) ? share->state.dellink : info->state->data_file_length); diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index a2d3dedf6df..5688b377d3d 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -271,6 +271,7 @@ struct st_myisam_info { uint preload_buff_size; /* When preloading indexes */ myf lock_wait; /* is 0 or MY_DONT_WAIT */ my_bool was_locked; /* Was locked in panic */ + my_bool append_insert_at_end; /* Set if concurrent insert */ my_bool quick_mode; my_bool page_changed; /* If info->buff can't be used for rnext */ my_bool buff_used; /* If info->buff has to be reread for rnext */ @@ -702,7 +703,7 @@ int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def, const byte *record, my_off_t pos); int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b, my_bool null_are_equal); -void mi_get_status(void* param); +void mi_get_status(void* param, int concurrent_insert); void mi_update_status(void* param); void mi_copy_status(void* to,void *from); my_bool mi_check_status(void* param); -- cgit v1.2.1