diff options
author | unknown <jani@labbari.dsl.inet.fi> | 2007-07-07 18:03:07 +0300 |
---|---|---|
committer | unknown <jani@labbari.dsl.inet.fi> | 2007-07-07 18:03:07 +0300 |
commit | 1ea806b1748c4ffc0904021d7d1e938fe837d73e (patch) | |
tree | 66e86ba43432e208ac5184873ea51fbe95cc8c60 | |
parent | 6ed46be70e0c1886231729458b94fb3321ac1a31 (diff) | |
parent | 23d10db8a3fd1830afbca1e0ab374799cc715aaa (diff) | |
download | mariadb-git-1ea806b1748c4ffc0904021d7d1e938fe837d73e.tar.gz |
Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-maria
into labbari.dsl.inet.fi:/home/my/bk/mysql-maria.prod
mysys/thr_lock.c:
Auto merged
storage/csv/ha_tina.cc:
Auto merged
storage/csv/ha_tina.h:
Auto merged
storage/maria/ma_blockrec.c:
Auto merged
storage/maria/ma_check.c:
Auto merged
storage/maria/ma_loghandler.c:
Auto merged
storage/maria/trnman.c:
Auto merged
storage/myisam/mi_locking.c:
Auto merged
sql/lock.cc:
SCCS merged
-rw-r--r-- | mysys/thr_lock.c | 20 | ||||
-rw-r--r-- | sql/lock.cc | 4 | ||||
-rw-r--r-- | storage/csv/ha_tina.cc | 12 | ||||
-rw-r--r-- | storage/csv/ha_tina.h | 4 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.c | 2 | ||||
-rw-r--r-- | storage/maria/ma_check.c | 6 | ||||
-rw-r--r-- | storage/maria/ma_control_file.h | 2 | ||||
-rw-r--r-- | storage/maria/ma_locking.c | 6 | ||||
-rw-r--r-- | storage/maria/ma_loghandler.c | 4 | ||||
-rwxr-xr-x | storage/maria/ma_test_all.sh | 12 | ||||
-rw-r--r-- | storage/maria/trnman.c | 21 | ||||
-rw-r--r-- | storage/maria/unittest/Makefile.am | 2 | ||||
-rw-r--r-- | storage/myisam/mi_locking.c | 52 |
13 files changed, 98 insertions, 49 deletions
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 20edffb49c2..d38bd2944f0 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -24,7 +24,7 @@ Locks are prioritized according to: The current lock types are: -TL_READ # Low priority read +TL_READ # Low priority read TL_READ_WITH_SHARED_LOCKS TL_READ_HIGH_PRIORITY # High priority read TL_READ_NO_INSERT # Read without concurrent inserts @@ -57,8 +57,12 @@ check_status: In MyISAM this is a simple check if the insert can be done at the end of the datafile. update_status: - Before a write lock is released, this function is called. - In MyISAM this functions updates the count and length of the datafile + in thr_reschedule_write_lock(), when an insert delayed thread + downgrades TL_WRITE lock to TL_WRITE_DELAYED, to allow SELECT + threads to proceed. + A storage engine should also call update_status internally + in the ::external_lock(F_UNLCK) method. + In MyISAM and CSV this functions updates the length of the datafile. get_status: When one gets a lock this functions is called. In MyISAM this stores the number of rows and size of the datafile @@ -762,16 +766,6 @@ void thr_unlock(THR_LOCK_DATA *data) } else lock->write.last=data->prev; - if (lock_type >= TL_WRITE_CONCURRENT_INSERT) - { - if (lock->update_status) - (*lock->update_status)(data->status_param); - } - else - { - if (lock->restore_status) - (*lock->restore_status)(data->status_param); - } if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ diff --git a/sql/lock.cc b/sql/lock.cc index 50922a682a2..e129da27005 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -289,10 +289,10 @@ static int lock_external(THD *thd, TABLE **tables, uint count) void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) { DBUG_ENTER("mysql_unlock_tables"); - if (sql_lock->lock_count) - thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); if (sql_lock->table_count) VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); + if (sql_lock->lock_count) + thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); my_free((uchar*) sql_lock,MYF(0)); DBUG_VOID_RETURN; } diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 6de153c82d7..1beb999b2e9 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -441,7 +441,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) */ current_position(0), next_position(0), local_saved_data_file_length(0), file_buff(0), chain_alloced(0), chain_size(DEFAULT_CHAIN_LENGTH), - records_is_known(0) + records_is_known(0), curr_lock_type(F_UNLCK) { /* Set our original buffers from pre-allocated memory */ buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); @@ -1395,6 +1395,14 @@ int ha_tina::delete_all_rows() DBUG_RETURN(rc); } +int ha_tina::external_lock(THD *thd __attribute__((unused)), int lock_type) +{ + if (lock_type==F_UNLCK && curr_lock_type == F_WRLCK) + update_status(); + curr_lock_type= lock_type; + return 0; +} + /* Called by the database to lock the table. Keep in mind that this is an internal lock. @@ -1409,7 +1417,7 @@ THR_LOCK_DATA **ha_tina::store_lock(THD *thd, return to; } -/* +/* Create a table. You do not want to leave the table open after a call to this (the database will call ::open() if it needs to). */ diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 8d2c6855b84..2572cbd286a 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -81,6 +81,8 @@ class ha_tina: public handler bool records_is_known; private: + int curr_lock_type; + bool get_write_pos(off_t *end_pos, tina_set *closest_hole); int open_update_temp_file_if_needed(); int init_tina_writer(); @@ -155,6 +157,8 @@ public: bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + int external_lock(THD *thd, int lock_type); + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 3292ce65ff1..6376a3fef87 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -1811,10 +1811,12 @@ static my_bool write_block_record(MARIA_HA *info, ulong length; ulong data_length= (tmp_data - info->rec_buff); +#ifdef MONTY_WILL_KNOW #ifdef SANITY_CHECKS if (cur_block->sub_blocks == 1) goto crashed; /* no reserved full or tails */ #endif +#endif /* Find out where to write tail for non-blob fields. diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 4d23b66421d..7d936409170 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -1925,7 +1925,11 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend) Recover old table by reading each record and writing all keys NOTES - Save new datafile-name in temp_filename + Save new datafile-name in temp_filename. + We overwrite the index file as we go (writekeys() for example), so if we + crash during this the table is unusable and user (or Recovery in the + future) must repeat the REPAIR/OPTIMIZE operation. We could use a + temporary index file in the future (drawback: more disk space). IMPLEMENTATION (for hard repair with block format) - Create new, unrelated MARIA_HA of the table diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index fa4ec442e41..d6c121b21be 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -18,7 +18,7 @@ First version written by Guilhem Bichot on 2006-04-27. */ -#define CONTROL_FILE_BASE_NAME "maria_control" +#define CONTROL_FILE_BASE_NAME "maria_log_control" /* Here is the interface of this module */ diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c index 1825367c44c..f709d7e5759 100644 --- a/storage/maria/ma_locking.c +++ b/storage/maria/ma_locking.c @@ -55,9 +55,15 @@ int maria_lock_database(MARIA_HA *info, int lock_type) case F_UNLCK: maria_ftparser_call_deinitializer(info); if (info->lock_type == F_RDLCK) + { count= --share->r_locks; + _ma_restore_status(info); + } else + { count= --share->w_locks; + _ma_update_status(info); + } --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks) { diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 8e38e374a4d..d5c4d59c45f 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -5623,7 +5623,7 @@ static my_bool write_hook_for_redo(enum translog_record_type type non-transactional log records (REPAIR, CREATE, RENAME, DROP) should not call this hook; we trust them but verify ;) */ - DBUG_ASSERT(trn->trid != 0); + DBUG_ASSERT(!(maria_multi_threaded && (trn->trid == 0))); /* If the hook stays so simple, it would be faster to pass !trn->rec_lsn ? trn->rec_lsn : some_dummy_lsn @@ -5650,7 +5650,7 @@ static my_bool write_hook_for_undo(enum translog_record_type type struct st_translog_parts *parts __attribute__ ((unused))) { - DBUG_ASSERT(trn->trid != 0); /* see write_hook_for_redo() */ + DBUG_ASSERT(!(maria_multi_threaded && (trn->trid == 0))); trn->undo_lsn= *lsn; if (unlikely(LSN_WITH_FLAGS_TO_LSN(trn->first_undo_lsn) == 0)) trn->first_undo_lsn= diff --git a/storage/maria/ma_test_all.sh b/storage/maria/ma_test_all.sh index 5ea76a7037d..a6786315afe 100755 --- a/storage/maria/ma_test_all.sh +++ b/storage/maria/ma_test_all.sh @@ -9,6 +9,8 @@ # Remove # from following line if you need some more information #set -x -v -e +set -e # abort at first failure + valgrind="valgrind --alignment=8 --leak-check=yes" silent="-s" suffix="" @@ -196,15 +198,19 @@ run_repair_tests "-M -T" run_pack_tests "-M -T" # -# Tests that gives warnings +# Tests that gives warnings or errors # $maria_path/ma_test2$suffix $silent -L -K -W -P -S -R1 -m500 $maria_path/maria_chk$suffix -sm test2 echo "ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135" -$maria_path/ma_test2$suffix $silent -L -K -R1 -m2000 +$maria_path/ma_test2$suffix $silent -L -K -R1 -m2000 >ma_test2_message.txt 2>&1 && false # success is failure +cat ma_test2_message.txt +grep "Error: 135" ma_test2_message.txt > /dev/null echo "$maria_path/maria_chk$suffix -sm test2 will warn that 'Datafile is almost full'" -$maria_path/maria_chk$suffix -sm test2 +$maria_path/maria_chk$suffix -sm test2 >ma_test2_message.txt 2>&1 +cat ma_test2_message.txt +grep "warning: Datafile is almost full" ma_test2_message.txt >/dev/null $maria_path/maria_chk$suffix -ssm test2 # diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index 4f009a7d5a8..75226588912 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -209,16 +209,21 @@ static TrID new_trid() static void set_short_trid(TRN *trn) { int i= (global_trid_generator + (intptr)trn) * 312089 % SHORT_TRID_MAX + 1; - my_atomic_rwlock_wrlock(&LOCK_short_trid_to_trn); - for ( ; ; i= i % SHORT_TRID_MAX + 1) /* the range is [1..SHORT_TRID_MAX] */ + for ( ; !trn->short_id ; i= 1) { - void *tmp= NULL; - if (short_trid_to_active_trn[i] == NULL && - my_atomic_casptr((void **)&short_trid_to_active_trn[i], &tmp, trn)) - break; + my_atomic_rwlock_wrlock(&LOCK_short_trid_to_trn); + for ( ; i <= SHORT_TRID_MAX; i++) /* the range is [1..SHORT_TRID_MAX] */ + { + void *tmp= NULL; + if (short_trid_to_active_trn[i] == NULL && + my_atomic_casptr((void **)&short_trid_to_active_trn[i], &tmp, trn)) + { + trn->short_id= i; + break; + } + } + my_atomic_rwlock_wrunlock(&LOCK_short_trid_to_trn); } - my_atomic_rwlock_wrunlock(&LOCK_short_trid_to_trn); - trn->short_id= i; } /* diff --git a/storage/maria/unittest/Makefile.am b/storage/maria/unittest/Makefile.am index 28264d5d903..b63cb60c059 100644 --- a/storage/maria/unittest/Makefile.am +++ b/storage/maria/unittest/Makefile.am @@ -84,6 +84,6 @@ ma_pagecache_consist_64kWR_t_big_CPPFLAGS = $(ma_pagecache_common_cppflags) -DPA # the generic lock manager may not be used in the end and lockman1-t crashes, # so we don't build lockman-t and lockman1-t -CLEANFILES = maria_control page_cache_test_file_1 \ +CLEANFILES = maria_log_control page_cache_test_file_1 \ maria_log.???????? diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 6aa62b70ae3..e6d446d0b40 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -56,9 +56,15 @@ int mi_lock_database(MI_INFO *info, int lock_type) case F_UNLCK: ftparser_call_deinitializer(info); if (info->lock_type == F_RDLCK) + { count= --share->r_locks; + mi_restore_status(info); + } else + { count= --share->w_locks; + mi_update_status(info); + } --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks && !share->delay_key_write && flush_key_blocks(share->key_cache, @@ -84,16 +90,16 @@ int mi_lock_database(MI_INFO *info, int lock_type) if (share->changed && !share->w_locks) { #ifdef HAVE_MMAP - if ((info->s->mmaped_length != info->s->state.state.data_file_length) && - (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS)) - { - if (info->s->concurrent_insert) - rw_wrlock(&info->s->mmap_lock); - mi_remap_file(info, info->s->state.state.data_file_length); - info->s->nonmmaped_inserts= 0; - if (info->s->concurrent_insert) - rw_unlock(&info->s->mmap_lock); - } + if ((info->s->mmaped_length != info->s->state.state.data_file_length) && + (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS)) + { + if (info->s->concurrent_insert) + rw_wrlock(&info->s->mmap_lock); + mi_remap_file(info, info->s->state.state.data_file_length); + info->s->nonmmaped_inserts= 0; + if (info->s->concurrent_insert) + rw_unlock(&info->s->mmap_lock); + } #endif share->state.process= share->last_process=share->this_process; share->state.unique= info->last_unique= info->this_unique; @@ -300,6 +306,7 @@ void mi_get_status(void* param, int concurrent_insert) void mi_update_status(void* param) { MI_INFO *info=(MI_INFO*) param; + DBUG_ENTER("mi_update_status"); /* Because someone may have closed the table we point at, we only update the state if its our own state. This isn't a problem as @@ -336,20 +343,32 @@ void mi_update_status(void* param) } info->opt_flag&= ~WRITE_CACHE_USED; } + DBUG_VOID_RETURN; } void mi_restore_status(void *param) { MI_INFO *info= (MI_INFO*) param; + DBUG_ENTER("mi_restore_status"); + DBUG_PRINT("info",("key_file: %ld data_file: %ld", + (long) info->s->state.state.key_file_length, + (long) info->s->state.state.data_file_length)); info->state= &info->s->state.state; info->append_insert_at_end= 0; + DBUG_VOID_RETURN; } void mi_copy_status(void* to,void *from) { - ((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state; + MI_INFO *info= (MI_INFO*) to; + DBUG_ENTER("mi_copy_status"); + info->state= &((MI_INFO*) from)->save_state; + DBUG_PRINT("info",("key_file: %ld data_file: %ld", + (long) info->state->key_file_length, + (long) info->state->data_file_length)); + DBUG_VOID_RETURN; } @@ -377,17 +396,18 @@ void mi_copy_status(void* to,void *from) my_bool mi_check_status(void *param) { MI_INFO *info=(MI_INFO*) param; + DBUG_ENTER("mi_check_status"); + 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)); /* 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 || + DBUG_RETURN((my_bool) !(info->s->state.dellink == HA_OFFSET_ERROR || (myisam_concurrent_insert == 2 && info->s->r_locks && - info->s->w_locks == 1)); + info->s->w_locks == 1))); } |