summaryrefslogtreecommitdiff
path: root/storage/innobase/handler/ha_innodb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/handler/ha_innodb.cc')
-rw-r--r--storage/innobase/handler/ha_innodb.cc110
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),