Loading include/myisam.h +3 −3 Original line number Diff line number Diff line Loading @@ -190,10 +190,10 @@ typedef struct st_columndef /* column information */ typedef void (* invalidator_by_filename)(const char * filename); extern my_string myisam_log_filename; /* Name of logfile */ extern uint myisam_block_size; extern ulong myisam_block_size; extern ulong myisam_concurrent_insert; extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; extern my_bool myisam_concurrent_insert; extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length; extern my_off_t myisam_max_temp_length; extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; /* Prototypes for myisam-functions */ Loading include/thr_lock.h +2 −2 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ typedef struct st_thr_lock { /* write_lock_count is incremented for write locks and reset on read locks */ ulong write_lock_count; uint read_no_write_count; void (*get_status)(void*); /* When one gets a lock */ void (*get_status)(void*, int); /* When one gets a lock */ void (*copy_status)(void*,void*); void (*update_status)(void*); /* Before release of write */ my_bool (*check_status)(void *); Loading myisam/mi_create.c +3 −4 Original line number Diff line number Diff line Loading @@ -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; Loading myisam/mi_dynrec.c +8 −4 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading Loading @@ -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) Loading myisam/mi_locking.c +38 −7 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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; Loading @@ -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 Loading @@ -307,10 +321,17 @@ 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 Loading @@ -320,7 +341,17 @@ void mi_copy_status(void* to,void *from) 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)); } Loading Loading
include/myisam.h +3 −3 Original line number Diff line number Diff line Loading @@ -190,10 +190,10 @@ typedef struct st_columndef /* column information */ typedef void (* invalidator_by_filename)(const char * filename); extern my_string myisam_log_filename; /* Name of logfile */ extern uint myisam_block_size; extern ulong myisam_block_size; extern ulong myisam_concurrent_insert; extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; extern my_bool myisam_concurrent_insert; extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length; extern my_off_t myisam_max_temp_length; extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; /* Prototypes for myisam-functions */ Loading
include/thr_lock.h +2 −2 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ typedef struct st_thr_lock { /* write_lock_count is incremented for write locks and reset on read locks */ ulong write_lock_count; uint read_no_write_count; void (*get_status)(void*); /* When one gets a lock */ void (*get_status)(void*, int); /* When one gets a lock */ void (*copy_status)(void*,void*); void (*update_status)(void*); /* Before release of write */ my_bool (*check_status)(void *); Loading
myisam/mi_create.c +3 −4 Original line number Diff line number Diff line Loading @@ -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; Loading
myisam/mi_dynrec.c +8 −4 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading Loading @@ -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) Loading
myisam/mi_locking.c +38 −7 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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; Loading @@ -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 Loading @@ -307,10 +321,17 @@ 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 Loading @@ -320,7 +341,17 @@ void mi_copy_status(void* to,void *from) 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)); } Loading