@ -44,26 +44,51 @@ static const char *ha_tokudb_exts[] = {
NullS
} ;
// XXX 4530 get read or write locks on the key file array,
// so that functions not synchronized by mysql table locks
// don't race.
//
// ha_tokudb::info() does not take any table locks
// so it needs to grab a read lock. any other function writing
// to the key file array needs to grab a write lock.
// In older (< 5.5) versions of MySQL and MariaDB, it is necessary to
// use a read/write lock on the key_file array in a table share,
// because table locks do not protect the race of some thread closing
// a table and another calling ha_tokudb::info()
//
// In version 5.5 and, a higher layer "metadata lock" was introduced
// to synchronize threads that open, close, call info(), etc on tables.
// In these versions, we don't need the key_file lock
# if MYSQL_VERSION_ID < 50500
# define HA_TOKUDB_NEEDS_KEY_FILE_LOCK
# endif
static void share_key_file_lock_init ( TOKUDB_SHARE * share )
{
# ifdef HA_TOKUDB_NEEDS_KEY_FILE_LOCK
my_rwlock_init ( & share - > key_file_lock , 0 ) ;
# endif
}
static void share_key_file_lock_destroy ( TOKUDB_SHARE * share )
{
# ifdef HA_TOKUDB_NEEDS_KEY_FILE_LOCK
rwlock_destroy ( & share - > key_file_lock ) ;
# endif
}
static void share_key_file_rdlock ( TOKUDB_SHARE * share )
{
# ifdef HA_TOKUDB_NEEDS_KEY_FILE_LOCK
rw_rdlock ( & share - > key_file_lock ) ;
# endif
}
static void share_key_file_wrlock ( TOKUDB_SHARE * share )
{
# ifdef HA_TOKUDB_NEEDS_KEY_FILE_LOCK
rw_wrlock ( & share - > key_file_lock ) ;
# endif
}
static void share_key_file_unlock ( TOKUDB_SHARE * share )
{
# ifdef HA_TOKUDB_NEEDS_KEY_FILE_LOCK
rw_unlock ( & share - > key_file_lock ) ;
# endif
}
//
@ -179,8 +204,7 @@ static TOKUDB_SHARE *get_share(const char *table_name, TABLE_SHARE* table_share)
}
thr_lock_init ( & share - > lock ) ;
pthread_mutex_init ( & share - > mutex , MY_MUTEX_INIT_FAST ) ;
// XXX 4530 initialize the key file lock
my_rwlock_init ( & share - > key_file_lock , 0 ) ;
share_key_file_lock_init ( share ) ;
my_rwlock_init ( & share - > num_DBs_lock , 0 ) ;
}
@ -250,6 +274,7 @@ static int free_share(TOKUDB_SHARE * share, bool mutex_is_locked) {
my_hash_delete ( & tokudb_open_tables , ( uchar * ) share ) ;
thr_lock_delete ( & share - > lock ) ;
pthread_mutex_destroy ( & share - > mutex ) ;
share_key_file_lock_destroy ( share ) ;
rwlock_destroy ( & share - > num_DBs_lock ) ;
my_free ( ( uchar * ) share , MYF ( 0 ) ) ;
}
@ -5650,7 +5675,6 @@ int ha_tokudb::info(uint flag) {
error = db_env - > txn_begin ( db_env , NULL , & txn , DB_READ_UNCOMMITTED ) ;
if ( error ) { goto cleanup ; }
// XXX 4530 lock the key file lock for reading
share_key_file_rdlock ( share ) ;
key_file_lock_taken = true ;
// we should always have a primary key
@ -5753,7 +5777,6 @@ int ha_tokudb::info(uint flag) {
}
error = 0 ;
cleanup :
// XXX 4530 unlock the key file lock if it was taken
if ( key_file_lock_taken ) {
share_key_file_unlock ( share ) ;
}
@ -7851,7 +7874,6 @@ int ha_tokudb::drop_indexes(TABLE *table_arg, uint *key_num, uint num_of_keys, D
TOKUDB_DBUG_ENTER ( " ha_tokudb::drop_indexes " ) ;
while ( ha_tokudb_drop_indexes_wait ) sleep ( 1 ) ; // debug
// XXX 4530 lock the key file lock for writing.
share_key_file_wrlock ( share ) ;
int error = 0 ;
@ -7881,7 +7903,6 @@ cleanup:
another transaction has accessed the table . \
To drop indexes , make sure no transactions touch the table . " , share->table_name);
}
// XXX 4530 unlock the key file lock
share_key_file_unlock ( share ) ;
TOKUDB_DBUG_RETURN ( error ) ;
}
@ -7891,7 +7912,6 @@ To drop indexes, make sure no transactions touch the table.", share->table_name)
// Restores dropped indexes in case of error in error path of prepare_drop_index and alter_table_phase2
//
void ha_tokudb : : restore_drop_indexes ( TABLE * table_arg , uint * key_num , uint num_of_keys ) {
// XXX 4530 lock the key file lock for writing
share_key_file_wrlock ( share ) ;
//
@ -7911,7 +7931,6 @@ void ha_tokudb::restore_drop_indexes(TABLE *table_arg, uint *key_num, uint num_o
assert ( ! r ) ;
}
}
// XXX 4530 unlock the key file lock
share_key_file_unlock ( share ) ;
}
@ -8203,7 +8222,6 @@ int ha_tokudb::delete_all_rows_internal() {
uint curr_num_DBs = 0 ;
DB_TXN * txn = NULL ;
// XXX 4530 lock the key file array for writing
share_key_file_wrlock ( share ) ;
error = db_env - > txn_begin ( db_env , 0 , & txn , 0 ) ;
@ -8274,7 +8292,6 @@ cleanup:
}
}
}
// XXX 4530 unlock the key file lock
share_key_file_unlock ( share ) ;
TOKUDB_DBUG_RETURN ( error ) ;
}