diff options
author | monty@mysql.com <> | 2004-10-06 19:14:33 +0300 |
---|---|---|
committer | monty@mysql.com <> | 2004-10-06 19:14:33 +0300 |
commit | 62f3cd6a31d3c1ffe7ad17d9de862a3c0859f56a (patch) | |
tree | 4e2cfa6a6a8032773454e22aa802b2798b2935b8 /myisam | |
parent | 96458f8f64641d5b974a17733af8c709b513bfe0 (diff) | |
parent | 0944bed7fcb59fb38230a750bd820a22b3b6b476 (diff) | |
download | mariadb-git-62f3cd6a31d3c1ffe7ad17d9de862a3c0859f56a.tar.gz |
Merge with 4.0 for 4.1 release
Noteworthy:
- New HANDLER code
- New multi-update-grant-check code
- Table lock code in ha_innodb.cc was not applied
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/mi_check.c | 2 | ||||
-rw-r--r-- | myisam/mi_close.c | 6 | ||||
-rw-r--r-- | myisam/mi_create.c | 13 | ||||
-rw-r--r-- | myisam/mi_locking.c | 54 | ||||
-rw-r--r-- | myisam/myisampack.c | 6 |
5 files changed, 61 insertions, 20 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 1f6089d0a3c..4da388af1c7 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3743,7 +3743,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) create_info.raid_chunksize= share.base.raid_chunksize; create_info.language = (param->language ? param->language : share.state.header.language); - + create_info.key_file_length= status_info.key_file_length; /* We don't have to handle symlinks here because we are using HA_DONT_TOUCH_DATA */ if (mi_create(filename, diff --git a/myisam/mi_close.c b/myisam/mi_close.c index deb0ccee8f3..62f5617de1a 100644 --- a/myisam/mi_close.c +++ b/myisam/mi_close.c @@ -70,6 +70,12 @@ int mi_close(register MI_INFO *info) error=my_errno; if (share->kfile >= 0) { + /* + If we are crashed, we can safely flush the current state as it will + not change the crashed state. + We can NOT write the state in other cases as other threads + may be using the file at this point + */ if (share->mode != O_RDONLY && mi_is_crashed(info)) mi_state_info_write(share->kfile, &share->state, 1); if (my_close(share->kfile,MYF(0))) diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 683640630f6..7fc7cc4edf1 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -48,7 +48,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ulong reclength, real_reclength,min_pack_length; char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; ulong pack_reclength; - ulonglong tot_length,max_rows; + ulonglong tot_length,max_rows, tmp; enum en_fieldtype type; MYISAM_SHARE share; MI_KEYDEF *keydef,tmp_keydef; @@ -464,10 +464,15 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, share.state.auto_increment=ci->auto_increment; share.options=options; share.base.rec_reflength=pointer; + /* Get estimate for index file length (this may be wrong for FT keys) */ + tmp= (tot_length + max_key_block_length * keys * + MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH; + /* + use maximum of key_file_length we calculated and key_file_length value we + got from MYI file header (see also myisampack.c:save_state) + */ share.base.key_reflength= - mi_get_pointer_length((tot_length + max_key_block_length * keys * - MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH, - 3); + mi_get_pointer_length(max(ci->key_file_length,tmp),3); share.base.keys= share.state.header.keys= keys; share.state.header.uniques= uniques; share.state.header.fulltext_keys= fulltext_keys; diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index b13ebfb4cad..2487f68d170 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -19,7 +19,20 @@ reads info from a isam-table. Must be first request before doing any furter calls to any isamfunktion. Is used to allow many process use the same isamdatabase. - */ +*/ + +/* + state.open_count in the .MYI file is used the following way: + - For the first change of the file in this process it's incremented with + mi_mark_file_change(). (We have a write lock on the file in this case) + - In mi_close() it's decremented by _mi_decrement_open_count() if it + was incremented in the same process. + + This mean that if we are the only process using the file, the open_count + tells us if the MYISAM file wasn't properly closed. (This is true if + my_disable_locking is set). +*/ + #include "myisamdef.h" @@ -32,12 +45,17 @@ int mi_lock_database(MI_INFO *info, int lock_type) MYISAM_SHARE *share=info->s; uint flag; DBUG_ENTER("mi_lock_database"); - DBUG_PRINT("info",("lock_type: %d", lock_type)); + DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u " + "global_changed: %d open_count: %u name: '%s'", + lock_type, info->lock_type, share->r_locks, + share->w_locks, + share->global_changed, share->state.open_count, + share->index_file_name)); if (share->options & HA_OPTION_READ_ONLY_DATA || info->lock_type == lock_type) DBUG_RETURN(0); - if (lock_type == F_EXTRA_LCK) + if (lock_type == F_EXTRA_LCK) /* Used by TMP tables */ { ++share->w_locks; ++share->tot_locks; @@ -51,7 +69,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) { switch (lock_type) { case F_UNLCK: - DBUG_PRINT("info", ("old lock: %d", info->lock_type)); if (info->lock_type == F_RDLCK) count= --share->r_locks; else @@ -81,7 +98,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) share->state.process= share->last_process=share->this_process; share->state.unique= info->last_unique= info->this_unique; share->state.update_count= info->last_loop= ++info->this_loop; - if (mi_state_info_write(share->kfile, &share->state, 1)) + if (mi_state_info_write(share->kfile, &share->state, 1)) error=my_errno; share->changed=0; if (myisam_flush) @@ -119,11 +136,17 @@ int mi_lock_database(MI_INFO *info, int lock_type) break; case F_RDLCK: if (info->lock_type == F_WRLCK) - { /* Change RW to READONLY */ + { + /* + Change RW to READONLY + + mysqld does not turn write locks to read locks, + so we're never here in mysqld. + */ if (share->w_locks == 1) { flag=1; - if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, + if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, MYF(MY_SEEK_NOT_DONE))) { error=my_errno; @@ -346,9 +369,10 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer) } /* _mi_readinfo */ - /* Every isam-function that uppdates the isam-database must! end */ - /* with this request */ - /* ARGSUSED */ +/* + Every isam-function that uppdates the isam-database MUST end with this + request +*/ int _mi_writeinfo(register MI_INFO *info, uint operation) { @@ -421,6 +445,8 @@ int _mi_mark_file_changed(MI_INFO *info) { char buff[3]; register MYISAM_SHARE *share=info->s; + DBUG_ENTER("_mi_mark_file_changed"); + if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed) { share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED | @@ -434,12 +460,12 @@ int _mi_mark_file_changed(MI_INFO *info) { mi_int2store(buff,share->state.open_count); buff[2]=1; /* Mark that it's changed */ - return (my_pwrite(share->kfile,buff,sizeof(buff), - sizeof(share->state.header), - MYF(MY_NABP))); + DBUG_RETURN(my_pwrite(share->kfile,buff,sizeof(buff), + sizeof(share->state.header), + MYF(MY_NABP))); } } - return 0; + DBUG_RETURN(0); } diff --git a/myisam/myisampack.c b/myisam/myisampack.c index de4bd80805a..0bbf2721cb3 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -2044,7 +2044,11 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, share->state.split=(ha_rows) mrg->records; share->state.version=(ulong) time((time_t*) 0); share->state.key_map=0; - share->state.state.key_file_length=share->base.keystart; + /* + Don't save key_file_length here, keep key_file_length of original file + so "myisamchk -rq" can use this value (this is necessary because index + size cannot be easily calculated for fulltext keys) + */ for (key=0 ; key < share->base.keys ; key++) share->state.key_root[key]= HA_OFFSET_ERROR; for (key=0 ; key < share->state.header.max_block_size ; key++) |