diff options
Diffstat (limited to 'storage/innobase/handler/ha_innodb.cc')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 19a6512a14f..0bedbcca73c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -1078,6 +1078,8 @@ convert_error_code_to_mysql( return(HA_ERR_UNDO_REC_TOO_BIG); case DB_OUT_OF_MEMORY: return(HA_ERR_OUT_OF_MEM); + case DB_IDENTIFIER_TOO_LONG: + return(HA_ERR_INTERNAL_ERROR); } } @@ -1158,6 +1160,37 @@ innobase_convert_from_table_id( strconvert(cs, from, &my_charset_filename, to, (uint) len, &errors); } +/********************************************************************** +Check if the length of the identifier exceeds the maximum allowed. +The input to this function is an identifier in charset my_charset_filename. +return true when length of identifier is too long. */ +extern "C" UNIV_INTERN +my_bool +innobase_check_identifier_length( +/*=============================*/ + const char* id) /* in: identifier to check. it must belong + to charset my_charset_filename */ +{ + char tmp[MAX_TABLE_NAME_LEN + 10]; + uint errors; + uint len; + int well_formed_error = 0; + CHARSET_INFO* cs1 = &my_charset_filename; + CHARSET_INFO* cs2 = thd_charset(current_thd); + + len = strconvert(cs1, id, cs2, tmp, MAX_TABLE_NAME_LEN + 10, &errors); + + uint res = cs2->cset->well_formed_len(cs2, tmp, tmp + len, + NAME_CHAR_LEN, + &well_formed_error); + + if (well_formed_error || res != len) { + my_error(ER_TOO_LONG_IDENT, MYF(0), tmp); + return(true); + } + return(false); +} + /******************************************************************//** Converts an identifier to UTF-8. */ extern "C" UNIV_INTERN @@ -5699,6 +5732,8 @@ ha_innobase::unlock_row(void) { DBUG_ENTER("ha_innobase::unlock_row"); + ut_ad(prebuilt->trx->conc_state == TRX_ACTIVE); + /* Consistent read does not take any locks, thus there is nothing to unlock. */ @@ -7668,12 +7703,18 @@ innobase_rename_table( DEBUG_SYNC_C("innodb_rename_table_ready"); /* Serialize data dictionary operations with dictionary mutex: - no deadlocks can occur then in these operations */ + no deadlocks can occur then in these operations. Start the + transaction first to avoid a possible deadlock in the server. */ + trx_start_if_not_started(trx); if (lock_and_commit) { row_mysql_lock_data_dictionary(trx); } + /* Flag this transaction as a dictionary operation, so that + the data dictionary will be locked in crash recovery. */ + trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); + error = row_rename_table_for_mysql( norm_from, norm_to, trx, lock_and_commit); @@ -11331,6 +11372,61 @@ innodb_change_buffering_update( *static_cast<const char*const*>(save); } +#ifndef DBUG_OFF +static char* srv_buffer_pool_evict; + +/****************************************************************//** +Called on SET GLOBAL innodb_buffer_pool_evict=... +Handles some values specially, to evict pages from the buffer pool. +SET GLOBAL innodb_buffer_pool_evict='uncompressed' +evicts all uncompressed page frames of compressed tablespaces. */ +static +void +innodb_buffer_pool_evict_update( +/*============================*/ + THD* thd, /*!< in: thread handle */ + struct st_mysql_sys_var*var, /*!< in: pointer to system variable */ + void* var_ptr,/*!< out: ignored */ + const void* save) /*!< in: immediate result + from check function */ +{ + if (const char* op = *static_cast<const char*const*>(save)) { + if (!strcmp(op, "uncompressed")) { + /* Evict all uncompressed pages of compressed + tables from the buffer pool. Keep the compressed + pages in the buffer pool. */ + + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool = &buf_pool_ptr[i]; + + buf_pool_mutex_enter(buf_pool); + + for (buf_block_t* block = UT_LIST_GET_LAST( + buf_pool->unzip_LRU); + block != NULL; ) { + + buf_block_t* prev_block + = UT_LIST_GET_PREV(unzip_LRU, + block); + ut_ad(buf_block_get_state(block) + == BUF_BLOCK_FILE_PAGE); + ut_ad(block->in_unzip_LRU_list); + ut_ad(block->page.in_LRU_list); + + mutex_enter(&block->mutex); + buf_LRU_free_block(&block->page, + FALSE); + mutex_exit(&block->mutex); + block = prev_block; + } + + buf_pool_mutex_exit(buf_pool); + } + } + } +} +#endif /* !DBUG_OFF */ + static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff) { innodb_export_status(); @@ -11586,6 +11682,13 @@ static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment, "Data file autoextend increment in megabytes", NULL, NULL, 8L, 1L, 1000L, 0); +#ifndef DBUG_OFF +static MYSQL_SYSVAR_STR(buffer_pool_evict, srv_buffer_pool_evict, + PLUGIN_VAR_RQCMDARG, + "Evict pages from the InnoDB buffer pool.", + NULL, innodb_buffer_pool_evict_update, ""); +#endif /* !DBUG_OFF */ + static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", @@ -11773,6 +11876,9 @@ static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks, static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), +#ifndef DBUG_OFF + MYSQL_SYSVAR(buffer_pool_evict), +#endif /* !DBUG_OFF */ MYSQL_SYSVAR(buffer_pool_size), MYSQL_SYSVAR(buffer_pool_instances), MYSQL_SYSVAR(checksums), |