summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-06-06 17:51:28 +0200
committerSergei Golubchik <sergii@pisem.net>2013-06-06 17:51:28 +0200
commit4749d40c635634e25e07d28ce1a04e9263bcc375 (patch)
treec5bb3287675cd8676d76c8ee42ef2d79cc599e25 /storage
parent1ff1cb10fc236010b5969058cab934c2b306c931 (diff)
parent33ef993773449cb3917665b188f6b6575d399bd0 (diff)
downloadmariadb-git-4749d40c635634e25e07d28ce1a04e9263bcc375.tar.gz
5.5 merge
Diffstat (limited to 'storage')
-rw-r--r--storage/federated/ha_federated.cc4
-rw-r--r--storage/federatedx/ha_federatedx.cc9
-rw-r--r--storage/innobase/btr/btr0cur.c43
-rw-r--r--storage/innobase/buf/buf0buf.c15
-rw-r--r--storage/innobase/buf/buf0rea.c10
-rw-r--r--storage/innobase/dict/dict0crea.c9
-rw-r--r--storage/innobase/dict/dict0dict.c16
-rw-r--r--storage/innobase/dyn/dyn0dyn.c8
-rw-r--r--storage/innobase/handler/ha_innodb.cc110
-rw-r--r--storage/innobase/handler/i_s.cc3
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c12
-rw-r--r--storage/innobase/include/db0err.h1
-rw-r--r--storage/innobase/include/dyn0dyn.h84
-rw-r--r--storage/innobase/include/dyn0dyn.ic141
-rw-r--r--storage/innobase/include/ha_prototypes.h11
-rw-r--r--storage/innobase/include/mtr0mtr.h10
-rw-r--r--storage/innobase/include/page0zip.ic6
-rw-r--r--storage/innobase/include/ut0dbg.h42
-rw-r--r--storage/innobase/lock/lock0lock.c5
-rw-r--r--storage/innobase/mtr/mtr0mtr.c149
-rw-r--r--storage/innobase/page/page0zip.c11
-rw-r--r--storage/innobase/row/row0mysql.c2
-rw-r--r--storage/innobase/row/row0sel.c6
-rw-r--r--storage/innobase/srv/srv0srv.c40
-rw-r--r--storage/innobase/sync/sync0arr.c8
-rw-r--r--storage/innobase/trx/trx0sys.c2
-rw-r--r--storage/innobase/ut/ut0dbg.c32
-rw-r--r--storage/innobase/ut/ut0ut.c2
-rw-r--r--storage/maria/ha_maria.cc35
-rw-r--r--storage/maria/ma_blockrec.c73
-rw-r--r--storage/maria/ma_blockrec.h4
-rw-r--r--storage/maria/ma_check.c26
-rw-r--r--storage/maria/ma_delete.c1
-rw-r--r--storage/maria/ma_loghandler.c3
-rw-r--r--storage/maria/ma_open.c30
-rw-r--r--storage/maria/ma_pagecrc.c3
-rw-r--r--storage/maria/ma_recovery.c2
-rw-r--r--storage/maria/ma_scan.c3
-rw-r--r--storage/maria/ma_search.c10
-rw-r--r--storage/maria/ma_state.c45
-rw-r--r--storage/maria/ma_state.h1
-rw-r--r--storage/maria/ma_test1.c3
-rw-r--r--storage/maria/ma_test2.c4
-rw-r--r--storage/maria/ma_update.c1
-rw-r--r--storage/maria/ma_write.c1
-rw-r--r--storage/maria/maria_chk.c69
-rw-r--r--storage/maria/maria_def.h6
-rw-r--r--storage/maria/unittest/ma_test_recovery.expected384
-rw-r--r--storage/myisam/mi_write.c7
-rw-r--r--storage/myisam/myisampack.c3
-rw-r--r--storage/myisammrg/ha_myisammrg.cc2
-rw-r--r--storage/perfschema/pfs_engine_table.cc8
-rw-r--r--storage/perfschema/pfs_global.cc4
-rw-r--r--storage/perfschema/pfs_global.h4
-rw-r--r--storage/sphinx/CMakeLists.txt9
-rw-r--r--storage/sphinx/snippets_udf.cc59
-rw-r--r--storage/xtradb/btr/btr0btr.c38
-rw-r--r--storage/xtradb/btr/btr0cur.c111
-rw-r--r--storage/xtradb/btr/btr0pcur.c13
-rw-r--r--storage/xtradb/btr/btr0sea.c5
-rw-r--r--storage/xtradb/buf/buf0buf.c121
-rw-r--r--storage/xtradb/buf/buf0flu.c9
-rw-r--r--storage/xtradb/buf/buf0lru.c40
-rw-r--r--storage/xtradb/buf/buf0rea.c8
-rw-r--r--storage/xtradb/dict/dict0dict.c6
-rw-r--r--storage/xtradb/fil/fil0fil.c105
-rw-r--r--storage/xtradb/fsp/fsp0fsp.c45
-rw-r--r--storage/xtradb/handler/ha_innodb.cc38
-rw-r--r--storage/xtradb/include/btr0btr.ic2
-rw-r--r--storage/xtradb/include/buf0buf.h1
-rw-r--r--storage/xtradb/include/buf0buf.ic9
-rw-r--r--storage/xtradb/include/buf0flu.ic2
-rw-r--r--storage/xtradb/include/buf0lru.h7
-rw-r--r--storage/xtradb/include/fut0fut.ic5
-rw-r--r--storage/xtradb/include/log0log.h16
-rw-r--r--storage/xtradb/include/log0log.ic23
-rw-r--r--storage/xtradb/include/mtr0mtr.h2
-rw-r--r--storage/xtradb/include/mtr0mtr.ic21
-rw-r--r--storage/xtradb/include/read0read.h33
-rw-r--r--storage/xtradb/include/read0read.ic41
-rw-r--r--storage/xtradb/include/srv0srv.h17
-rw-r--r--storage/xtradb/include/trx0purge.h1
-rw-r--r--storage/xtradb/include/trx0sys.h38
-rw-r--r--storage/xtradb/include/trx0sys.ic46
-rw-r--r--storage/xtradb/include/trx0trx.h43
-rw-r--r--storage/xtradb/include/trx0trx.ic8
-rw-r--r--storage/xtradb/include/univ.i2
-rw-r--r--storage/xtradb/lock/lock0lock.c22
-rw-r--r--storage/xtradb/log/log0log.c19
-rw-r--r--storage/xtradb/mtr/mtr0mtr.c39
-rw-r--r--storage/xtradb/read/read0read.c188
-rw-r--r--storage/xtradb/row/row0ins.c9
-rw-r--r--storage/xtradb/row/row0merge.c6
-rw-r--r--storage/xtradb/row/row0sel.c23
-rw-r--r--storage/xtradb/row/row0vers.c6
-rw-r--r--storage/xtradb/srv/srv0srv.c4
-rw-r--r--storage/xtradb/trx/trx0purge.c16
-rw-r--r--storage/xtradb/trx/trx0roll.c8
-rw-r--r--storage/xtradb/trx/trx0sys.c11
-rw-r--r--storage/xtradb/trx/trx0trx.c243
100 files changed, 1726 insertions, 1315 deletions
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 872eecff9cd..996dee5dce8 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -587,7 +587,7 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
buf_len= min(table->s->connect_string.length,
FEDERATED_QUERY_BUFFER_SIZE-1);
strmake(buf, table->s->connect_string.str, buf_len);
- my_error(error_num, MYF(0), buf);
+ my_error(error_num, MYF(0), buf, 14);
DBUG_RETURN(error_num);
}
@@ -3225,7 +3225,7 @@ int ha_federated::stash_remote_error()
if (!mysql)
DBUG_RETURN(remote_error_number);
remote_error_number= mysql_errno(mysql);
- strmake(remote_error_buf, mysql_error(mysql), sizeof(remote_error_buf)-1);
+ strmake_buf(remote_error_buf, mysql_error(mysql));
if (remote_error_number == ER_DUP_ENTRY ||
remote_error_number == ER_DUP_KEY)
DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index c3f5e6add73..a7f2d887952 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -527,7 +527,7 @@ static int parse_url_error(FEDERATEDX_SHARE *share, TABLE_SHARE *table_s,
buf_len= min(table_s->connect_string.length,
FEDERATEDX_QUERY_BUFFER_SIZE-1);
strmake(buf, table_s->connect_string.str, buf_len);
- my_error(error_num, MYF(0), buf);
+ my_error(error_num, MYF(0), buf, 14);
DBUG_RETURN(error_num);
}
@@ -587,9 +587,8 @@ int get_connection(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share)
DBUG_RETURN(0);
error:
- sprintf(error_buffer, "server name: '%s' doesn't exist!",
- share->connection_string);
- my_error(error_num, MYF(0), error_buffer);
+ my_printf_error(error_num, "server name: '%s' doesn't exist!",
+ MYF(0), share->connection_string);
DBUG_RETURN(error_num);
}
@@ -3423,7 +3422,7 @@ int ha_federatedx::stash_remote_error()
if (!io)
DBUG_RETURN(remote_error_number);
remote_error_number= io->error_code();
- strmake(remote_error_buf, io->error_str(), sizeof(remote_error_buf)-1);
+ strmake_buf(remote_error_buf, io->error_str());
if (remote_error_number == ER_DUP_ENTRY ||
remote_error_number == ER_DUP_KEY)
DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 955be01f032..b48fb705cd8 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -1248,27 +1248,13 @@ btr_cur_optimistic_insert(
Subtract one byte for the encoded heap_no in the
modification log. */
ulint free_space_zip = page_zip_empty_size(
- cursor->index->n_fields, zip_size) - 1;
+ cursor->index->n_fields, zip_size);
ulint n_uniq = dict_index_get_n_unique_in_tree(index);
ut_ad(dict_table_is_comp(index->table));
- /* There should be enough room for two node pointer
- records on an empty non-leaf page. This prevents
- infinite page splits. */
-
- if (UNIV_LIKELY(entry->n_fields >= n_uniq)
- && UNIV_UNLIKELY(REC_NODE_PTR_SIZE
- + rec_get_converted_size_comp_prefix(
- index, entry->fields, n_uniq,
- NULL)
- /* On a compressed page, there is
- a two-byte entry in the dense
- page directory for every record.
- But there is no record header. */
- - (REC_N_NEW_EXTRA_BYTES - 2)
- > free_space_zip / 2)) {
-
+ if (free_space_zip == 0) {
+too_big:
if (big_rec_vec) {
dtuple_convert_back_big_rec(
index, entry, big_rec_vec);
@@ -1276,6 +1262,27 @@ btr_cur_optimistic_insert(
return(DB_TOO_BIG_RECORD);
}
+
+ /* Subtract one byte for the encoded heap_no in the
+ modification log. */
+ free_space_zip--;
+
+ /* There should be enough room for two node pointer
+ records on an empty non-leaf page. This prevents
+ infinite page splits. */
+
+ if (entry->n_fields >= n_uniq
+ && (REC_NODE_PTR_SIZE
+ + rec_get_converted_size_comp_prefix(
+ index, entry->fields, n_uniq, NULL)
+ /* On a compressed page, there is
+ a two-byte entry in the dense
+ page directory for every record.
+ But there is no record header. */
+ - (REC_N_NEW_EXTRA_BYTES - 2)
+ > free_space_zip / 2)) {
+ goto too_big;
+ }
}
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page),
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 2406980196e..31be914afa0 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -2322,6 +2322,10 @@ loop2:
retries = 0;
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
++retries;
+ DBUG_EXECUTE_IF(
+ "innodb_page_corruption_retries",
+ retries = BUF_PAGE_READ_MAX_RETRIES;
+ );
} else {
fprintf(stderr, "InnoDB: Error: Unable"
" to read tablespace %lu page no"
@@ -2359,6 +2363,7 @@ got_block:
/* The page is being read to buffer pool,
but we cannot wait around for the read to
complete. */
+null_exit:
buf_pool_mutex_exit(buf_pool);
return(NULL);
@@ -2373,6 +2378,14 @@ got_block:
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
+ if (mode == BUF_PEEK_IF_IN_POOL) {
+ /* This mode is only used for dropping an
+ adaptive hash index. There cannot be an
+ adaptive hash index for a compressed-only
+ page, so do not bother decompressing the page. */
+ goto null_exit;
+ }
+
bpage = &block->page;
/* Protect bpage->buf_fix_count. */
mutex_enter(&buf_pool->zip_mutex);
diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
index 40550186191..d12fd3fce31 100644
--- a/storage/innobase/buf/buf0rea.c
+++ b/storage/innobase/buf/buf0rea.c
@@ -177,7 +177,10 @@ buf_read_page_low(
ut_ad(buf_page_in_file(bpage));
- thd_wait_begin(NULL, THD_WAIT_DISKIO);
+ if (sync) {
+ thd_wait_begin(NULL, THD_WAIT_DISKIO);
+ }
+
if (zip_size) {
*err = fil_io(OS_FILE_READ | wake_later,
sync, space, zip_size, offset, 0, zip_size,
@@ -189,7 +192,10 @@ buf_read_page_low(
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
((buf_block_t*) bpage)->frame, bpage);
}
- thd_wait_end(NULL);
+
+ if (sync) {
+ thd_wait_end(NULL);
+ }
if (*err == DB_TABLESPACE_DELETED) {
buf_read_page_handle_error(bpage);
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
index d7373a4b8ef..cb3dbcbe4ac 100644
--- a/storage/innobase/dict/dict0crea.c
+++ b/storage/innobase/dict/dict0crea.c
@@ -42,6 +42,7 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0roll.h"
#include "usr0sess.h"
#include "ut0vec.h"
+#include "ha_prototypes.h"
/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
@@ -1427,12 +1428,20 @@ dict_create_add_foreign_to_dictionary(
pars_info_t* info = pars_info_create();
if (foreign->id == NULL) {
+ char* stripped_name;
/* Generate a new constraint id */
ulint namelen = strlen(table->name);
char* id = mem_heap_alloc(foreign->heap, namelen + 20);
/* no overflow if number < 1e13 */
sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++);
foreign->id = id;
+
+ stripped_name = strchr(foreign->id, '/') + 1;
+ if (innobase_check_identifier_length(stripped_name)) {
+ fprintf(stderr, "InnoDB: Generated foreign key "
+ "name (%s) is too long\n", foreign->id);
+ return(DB_IDENTIFIER_TOO_LONG);
+ }
}
pars_info_add_str_literal(info, "id", foreign->id);
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index d5b16d419f1..a887ff0b1ca 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1466,6 +1466,10 @@ dict_index_too_big_for_tree(
/* maximum allowed size of a node pointer record */
ulint page_ptr_max;
+ DBUG_EXECUTE_IF(
+ "ib_force_create_table",
+ return(FALSE););
+
comp = dict_table_is_comp(table);
zip_size = dict_table_zip_size(table);
@@ -1480,7 +1484,10 @@ dict_index_too_big_for_tree(
number in the page modification log. The maximum
allowed node pointer size is half that. */
page_rec_max = page_zip_empty_size(new_index->n_fields,
- zip_size) - 1;
+ zip_size);
+ if (page_rec_max) {
+ page_rec_max--;
+ }
page_ptr_max = page_rec_max / 2;
/* On a compressed page, there is a two-byte entry in
the dense page directory for every record. But there
@@ -4672,6 +4679,7 @@ dict_print_info_on_foreign_key_in_create_format(
dict_foreign_t* foreign, /*!< in: foreign key constraint */
ibool add_newline) /*!< in: whether to add a newline */
{
+ char constraint_name[MAX_TABLE_NAME_LEN];
const char* stripped_id;
ulint i;
@@ -4693,7 +4701,9 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(" CONSTRAINT ", file);
- ut_print_name(file, trx, FALSE, stripped_id);
+ innobase_convert_from_id(&my_charset_filename, constraint_name,
+ stripped_id, MAX_TABLE_NAME_LEN);
+ ut_print_name(file, trx, FALSE, constraint_name);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
diff --git a/storage/innobase/dyn/dyn0dyn.c b/storage/innobase/dyn/dyn0dyn.c
index e1275f040f3..d0f50ad0c32 100644
--- a/storage/innobase/dyn/dyn0dyn.c
+++ b/storage/innobase/dyn/dyn0dyn.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -35,7 +35,7 @@ UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- dyn_array_t* arr) /*!< in: dyn array */
+ dyn_array_t* arr) /*!< in/out: dyn array */
{
mem_heap_t* heap;
dyn_block_t* block;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 4d8f1c7398e..4b77936550b 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.
@@ -1082,6 +1082,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);
}
}
@@ -1162,6 +1164,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
@@ -5846,6 +5879,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. */
@@ -7815,12 +7850,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);
@@ -11478,6 +11519,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();
@@ -11740,6 +11836,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.",
@@ -11927,6 +12030,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),
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 59ea065c5c7..38596bc69b5 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -2295,6 +2295,7 @@ i_s_innodb_buffer_stats_fill_table(
buf_pool_info_t* pool_info;
DBUG_ENTER("i_s_innodb_buffer_fill_general");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Only allow the PROCESS privilege holder to access the stats */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2911,6 +2912,7 @@ i_s_innodb_fill_buffer_pool(
mem_heap_t* heap;
DBUG_ENTER("i_s_innodb_fill_buffer_pool");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
heap = mem_heap_create(10000);
@@ -3480,6 +3482,7 @@ i_s_innodb_fill_buffer_lru(
ulint lru_len;
DBUG_ENTER("i_s_innodb_fill_buffer_lru");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Obtain buf_pool mutex before allocate info_buffer, since
UT_LIST_GET_LEN(buf_pool->LRU) could change */
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 70af56b99f2..11505121fa2 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -4685,6 +4685,16 @@ loop:
== page_no);
ut_ad(ibuf_rec_get_space(&mtr, rec) == space);
+ /* Mark the change buffer record processed,
+ so that it will not be merged again in case
+ the server crashes between the following
+ mtr_commit() and the subsequent mtr_commit()
+ of deleting the change buffer record. */
+
+ btr_cur_set_deleted_flag_for_ibuf(
+ btr_pcur_get_rec(&pcur), NULL,
+ TRUE, &mtr);
+
btr_pcur_store_position(&pcur, &mtr);
ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr);
diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h
index 95ccef16be0..b27bc954940 100644
--- a/storage/innobase/include/db0err.h
+++ b/storage/innobase/include/db0err.h
@@ -114,6 +114,7 @@ enum db_err {
DB_UNDO_RECORD_TOO_BIG, /* the undo log record is too big */
DB_TABLE_IN_FK_CHECK, /* table is being used in foreign
key check */
+ DB_IDENTIFIER_TOO_LONG, /* Identifier name too long */
/* The following are partial failure codes */
DB_FAIL = 1000,
diff --git a/storage/innobase/include/dyn0dyn.h b/storage/innobase/include/dyn0dyn.h
index 121a5946ac7..62ed862e82c 100644
--- a/storage/innobase/include/dyn0dyn.h
+++ b/storage/innobase/include/dyn0dyn.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -47,15 +47,17 @@ UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- dyn_array_t* arr); /*!< in: pointer to a memory buffer of
+ dyn_array_t* arr) /*!< in/out memory buffer of
size sizeof(dyn_array_t) */
+ __attribute__((nonnull));
/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
- dyn_array_t* arr); /*!< in: dyn array */
+ dyn_array_t* arr) /*!< in,own: dyn array */
+ __attribute__((nonnull));
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
@@ -66,8 +68,9 @@ byte*
dyn_array_open(
/*===========*/
dyn_array_t* arr, /*!< in: dynamic array */
- ulint size); /*!< in: size in bytes of the buffer; MUST be
+ ulint size) /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
+ __attribute__((nonnull, warn_unused_result));
/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
@@ -75,7 +78,8 @@ void
dyn_array_close(
/*============*/
dyn_array_t* arr, /*!< in: dynamic array */
- byte* ptr); /*!< in: buffer space from ptr up was not used */
+ const byte* ptr) /*!< in: end of used space */
+ __attribute__((nonnull));
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to
the added element. The caller must copy the element to
@@ -85,8 +89,9 @@ UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- dyn_array_t* arr, /*!< in: dynamic array */
- ulint size); /*!< in: size in bytes of the element */
+ dyn_array_t* arr, /*!< in/out: dynamic array */
+ ulint size) /*!< in: size in bytes of the element */
+ __attribute__((nonnull, warn_unused_result));
/************************************************************//**
Returns pointer to an element in dyn array.
@return pointer to element */
@@ -94,9 +99,10 @@ UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- dyn_array_t* arr, /*!< in: dyn array */
- ulint pos); /*!< in: position of element as bytes
- from array start */
+ const dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos) /*!< in: position of element
+ in bytes from array start */
+ __attribute__((nonnull, warn_unused_result));
/************************************************************//**
Returns the size of stored data in a dyn array.
@return data size in bytes */
@@ -104,30 +110,33 @@ UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- dyn_array_t* arr); /*!< in: dyn array */
+ const dyn_array_t* arr) /*!< in: dyn array */
+ __attribute__((nonnull, warn_unused_result, pure));
/************************************************************//**
-Gets the first block in a dyn array. */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_first_block(
-/*======================*/
- dyn_array_t* arr); /*!< in: dyn array */
+Gets the first block in a dyn array.
+@param arr dyn array
+@return first block */
+#define dyn_array_get_first_block(arr) (arr)
/************************************************************//**
-Gets the last block in a dyn array. */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_last_block(
-/*=====================*/
- dyn_array_t* arr); /*!< in: dyn array */
+Gets the last block in a dyn array.
+@param arr dyn array
+@return last block */
+#define dyn_array_get_last_block(arr) \
+ ((arr)->heap ? UT_LIST_GET_LAST((arr)->base) : (arr))
/********************************************************************//**
Gets the next block in a dyn array.
-@return pointer to next, NULL if end of list */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_next_block(
-/*=====================*/
- dyn_array_t* arr, /*!< in: dyn array */
- dyn_block_t* block); /*!< in: dyn array block */
+@param arr dyn array
+@param block dyn array block
+@return pointer to next, NULL if end of list */
+#define dyn_array_get_next_block(arr, block) \
+ ((arr)->heap ? UT_LIST_GET_NEXT(list, block) : NULL)
+/********************************************************************//**
+Gets the previous block in a dyn array.
+@param arr dyn array
+@param block dyn array block
+@return pointer to previous, NULL if end of list */
+#define dyn_array_get_prev_block(arr, block) \
+ ((arr)->heap ? UT_LIST_GET_PREV(list, block) : NULL)
/********************************************************************//**
Gets the number of used bytes in a dyn array block.
@return number of bytes used */
@@ -135,7 +144,8 @@ UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- dyn_block_t* block); /*!< in: dyn array block */
+ const dyn_block_t* block) /*!< in: dyn array block */
+ __attribute__((nonnull, warn_unused_result, pure));
/********************************************************************//**
Gets pointer to the start of data in a dyn array block.
@return pointer to data */
@@ -143,16 +153,18 @@ UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- dyn_block_t* block); /*!< in: dyn array block */
+ const dyn_block_t* block) /*!< in: dyn array block */
+ __attribute__((nonnull, warn_unused_result, pure));
/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /*!< in: dyn array */
+ dyn_array_t* arr, /*!< in/out: dyn array */
const byte* str, /*!< in: string to write */
- ulint len); /*!< in: string length */
+ ulint len) /*!< in: string length */
+ __attribute__((nonnull));
/*#################################################################*/
diff --git a/storage/innobase/include/dyn0dyn.ic b/storage/innobase/include/dyn0dyn.ic
index 110e674abff..177877ed1fd 100644
--- a/storage/innobase/include/dyn0dyn.ic
+++ b/storage/innobase/include/dyn0dyn.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
@@ -35,56 +35,8 @@ UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- dyn_array_t* arr); /*!< in: dyn array */
-
-
-/************************************************************//**
-Gets the first block in a dyn array. */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_first_block(
-/*======================*/
- dyn_array_t* arr) /*!< in: dyn array */
-{
- return(arr);
-}
-
-/************************************************************//**
-Gets the last block in a dyn array. */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_last_block(
-/*=====================*/
- dyn_array_t* arr) /*!< in: dyn array */
-{
- if (arr->heap == NULL) {
-
- return(arr);
- }
-
- return(UT_LIST_GET_LAST(arr->base));
-}
-
-/********************************************************************//**
-Gets the next block in a dyn array.
-@return pointer to next, NULL if end of list */
-UNIV_INLINE
-dyn_block_t*
-dyn_array_get_next_block(
-/*=====================*/
- dyn_array_t* arr, /*!< in: dyn array */
- dyn_block_t* block) /*!< in: dyn array block */
-{
- ut_ad(arr && block);
-
- if (arr->heap == NULL) {
- ut_ad(arr == block);
-
- return(NULL);
- }
-
- return(UT_LIST_GET_NEXT(list, block));
-}
+ dyn_array_t* arr) /*!< in/out: dyn array */
+ __attribute__((nonnull, warn_unused_result));
/********************************************************************//**
Gets the number of used bytes in a dyn array block.
@@ -93,7 +45,7 @@ UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- dyn_block_t* block) /*!< in: dyn array block */
+ const dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
@@ -107,11 +59,11 @@ UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- dyn_block_t* block) /*!< in: dyn array block */
+ const dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
- return(block->data);
+ return((byte*) block->data);
}
/*********************************************************************//**
@@ -121,7 +73,7 @@ UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- dyn_array_t* arr) /*!< in: pointer to a memory buffer of
+ dyn_array_t* arr) /*!< in/out: memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
@@ -132,10 +84,9 @@ dyn_array_create(
arr->heap = NULL;
arr->used = 0;
-#ifdef UNIV_DEBUG
- arr->buf_end = 0;
- arr->magic_n = DYN_BLOCK_MAGIC_N;
-#endif
+ ut_d(arr->buf_end = 0);
+ ut_d(arr->magic_n = DYN_BLOCK_MAGIC_N);
+
return(arr);
}
@@ -151,9 +102,7 @@ dyn_array_free(
mem_heap_free(arr->heap);
}
-#ifdef UNIV_DEBUG
- arr->magic_n = 0;
-#endif
+ ut_d(arr->magic_n = 0);
}
/*********************************************************************//**
@@ -164,7 +113,7 @@ UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- dyn_array_t* arr, /*!< in: dynamic array */
+ dyn_array_t* arr, /*!< in/out: dynamic array */
ulint size) /*!< in: size in bytes of the element */
{
dyn_block_t* block;
@@ -176,24 +125,23 @@ dyn_array_push(
ut_ad(size);
block = arr;
- used = block->used;
- if (used + size > DYN_ARRAY_DATA_SIZE) {
+ if (block->used + size > DYN_ARRAY_DATA_SIZE) {
/* Get the last array block */
block = dyn_array_get_last_block(arr);
- used = block->used;
- if (used + size > DYN_ARRAY_DATA_SIZE) {
+ if (block->used + size > DYN_ARRAY_DATA_SIZE) {
block = dyn_array_add_block(arr);
- used = block->used;
}
}
+ used = block->used;
+
block->used = used + size;
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
- return((block->data) + used);
+ return(block->data + used);
}
/*********************************************************************//**
@@ -210,7 +158,6 @@ dyn_array_open(
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_block_t* block;
- ulint used;
ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
@@ -218,28 +165,23 @@ dyn_array_open(
ut_ad(size);
block = arr;
- used = block->used;
- if (used + size > DYN_ARRAY_DATA_SIZE) {
+ if (block->used + size > DYN_ARRAY_DATA_SIZE) {
/* Get the last array block */
block = dyn_array_get_last_block(arr);
- used = block->used;
- if (used + size > DYN_ARRAY_DATA_SIZE) {
+ if (block->used + size > DYN_ARRAY_DATA_SIZE) {
block = dyn_array_add_block(arr);
- used = block->used;
ut_a(size <= DYN_ARRAY_DATA_SIZE);
}
}
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
-#ifdef UNIV_DEBUG
ut_ad(arr->buf_end == 0);
+ ut_d(arr->buf_end = block->used + size);
- arr->buf_end = used + size;
-#endif
- return((block->data) + used);
+ return(block->data + block->used);
}
/*********************************************************************//**
@@ -248,8 +190,8 @@ UNIV_INLINE
void
dyn_array_close(
/*============*/
- dyn_array_t* arr, /*!< in: dynamic array */
- byte* ptr) /*!< in: buffer space from ptr up was not used */
+ dyn_array_t* arr, /*!< in/out: dynamic array */
+ const byte* ptr) /*!< in: end of used space */
{
dyn_block_t* block;
@@ -264,9 +206,7 @@ dyn_array_close(
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
-#ifdef UNIV_DEBUG
- arr->buf_end = 0;
-#endif
+ ut_d(arr->buf_end = 0);
}
/************************************************************//**
@@ -276,12 +216,11 @@ UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- dyn_array_t* arr, /*!< in: dyn array */
- ulint pos) /*!< in: position of element as bytes
- from array start */
+ const dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos) /*!< in: position of element
+ in bytes from array start */
{
- dyn_block_t* block;
- ulint used;
+ const dyn_block_t* block;
ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
@@ -290,21 +229,23 @@ dyn_array_get_element(
block = dyn_array_get_first_block(arr);
if (arr->heap != NULL) {
- used = dyn_block_get_used(block);
+ for (;;) {
+ ulint used = dyn_block_get_used(block);
+
+ if (pos < used) {
+ break;
+ }
- while (pos >= used) {
pos -= used;
block = UT_LIST_GET_NEXT(list, block);
ut_ad(block);
-
- used = dyn_block_get_used(block);
}
}
ut_ad(block);
ut_ad(dyn_block_get_used(block) >= pos);
- return(block->data + pos);
+ return((byte*) block->data + pos);
}
/************************************************************//**
@@ -314,10 +255,10 @@ UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- dyn_array_t* arr) /*!< in: dyn array */
+ const dyn_array_t* arr) /*!< in: dyn array */
{
- dyn_block_t* block;
- ulint sum = 0;
+ const dyn_block_t* block;
+ ulint sum = 0;
ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
@@ -344,7 +285,7 @@ UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /*!< in: dyn array */
+ dyn_array_t* arr, /*!< in/out: dyn array */
const byte* str, /*!< in: string to write */
ulint len) /*!< in: string length */
{
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index a0ec09c892f..4ffc64df238 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -307,4 +307,15 @@ ulint
innobase_get_lower_case_table_names(void);
/*=====================================*/
+/**********************************************************************
+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. */
+UNIV_INTERN
+my_bool
+innobase_check_identifier_length(
+/*=============================*/
+ const char* id); /* in: identifier to check. it must belong
+ to charset my_charset_filename */
+
#endif
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 46f1ff9310c..88ac3c138de 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -295,9 +295,10 @@ UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /*!< in: mtr */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
void* object, /*!< in: object */
- ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */
+ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
+ __attribute__((nonnull));
#ifdef UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
/**********************************************************//**
@@ -309,7 +310,8 @@ mtr_memo_contains(
/*==============*/
mtr_t* mtr, /*!< in: mtr */
const void* object, /*!< in: object to search */
- ulint type); /*!< in: type of object */
+ ulint type) /*!< in: type of object */
+ __attribute__((warn_unused_result, nonnull));
/**********************************************************//**
Checks if memo contains the given page.
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index 75cc7a9fcc4..b5480604bdf 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -188,8 +188,8 @@ page_zip_rec_needs_ext(
one record on an empty leaf page. Subtract 1 byte for
the encoded heap number. Check also the available space
on the uncompressed page. */
- return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2)
- >= (page_zip_empty_size(n_fields, zip_size) - 1)
+ return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2 - 1)
+ >= page_zip_empty_size(n_fields, zip_size)
|| rec_size >= page_get_free_space_of_empty(TRUE) / 2);
}
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h
index ce6dcb63049..4913b357768 100644
--- a/storage/innobase/include/ut0dbg.h
+++ b/storage/innobase/include/ut0dbg.h
@@ -55,49 +55,8 @@ ut_dbg_assertion_failed(
ulint line) /*!< in: line number of the assertion */
UNIV_COLD __attribute__((nonnull(2)));
-
-#define UT_DBG_USE_ABORT
-
-
-#ifndef UT_DBG_USE_ABORT
-/** A null pointer that will be dereferenced to trigger a memory trap */
-extern ulint* ut_dbg_null_ptr;
-#endif
-
-#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
-will stop at the next ut_a() or ut_ad(). */
-extern ibool ut_dbg_stop_threads;
-
-/*************************************************************//**
-Stop a thread after assertion failure. */
-UNIV_INTERN
-void
-ut_dbg_stop_thread(
-/*===============*/
- const char* file,
- ulint line);
-#endif
-
-#ifdef UT_DBG_USE_ABORT
/** Abort the execution. */
-#ifdef _WIN32
-# define UT_DBG_PANIC __debugbreak()
-#else
# define UT_DBG_PANIC abort()
-#endif
-/** Stop threads (null operation) */
-# define UT_DBG_STOP do {} while (0)
-#else /* UT_DBG_USE_ABORT */
-/** Abort the execution. */
-# define UT_DBG_PANIC \
- if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
-/** Stop threads in ut_a(). */
-# define UT_DBG_STOP do \
- if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
- ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
- } while (0)
-#endif /* UT_DBG_USE_ABORT */
/** Abort execution if EXPR does not evaluate to nonzero.
@param EXPR assertion expression that should hold */
@@ -107,7 +66,6 @@ ut_dbg_stop_thread(
__FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} \
- UT_DBG_STOP; \
} while (0)
/** Abort execution. */
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index a72be540c1b..a5ce43496af 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -1997,6 +1997,8 @@ lock_rec_lock_fast(
|| mode - (LOCK_MODE_MASK & mode) == 0
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
+ DBUG_EXECUTE_IF("innodb_report_deadlock", return(LOCK_REC_FAIL););
+
lock = lock_rec_get_first_on_page(block);
trx = thr_get_trx(thr);
@@ -2074,6 +2076,8 @@ lock_rec_lock_slow(
trx = thr_get_trx(thr);
+ DBUG_EXECUTE_IF("innodb_report_deadlock", return(DB_DEADLOCK););
+
lock = lock_rec_has_expl(mode, block, heap_no, trx);
if (lock) {
if (lock->type_mode & LOCK_CONV_BY_OTHER) {
@@ -4124,6 +4128,7 @@ lock_rec_unlock(
ut_ad(trx && rec);
ut_ad(block->frame == page_align(rec));
+ ut_ad(trx->conc_state == TRX_ACTIVE);
heap_no = page_rec_get_heap_no(rec);
diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c
index d852ed6f496..a5c98761523 100644
--- a/storage/innobase/mtr/mtr0mtr.c
+++ b/storage/innobase/mtr/mtr0mtr.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,72 +39,81 @@ Created 11/26/1995 Heikki Tuuri
# include "log0recv.h"
/*****************************************************************//**
Releases the item in the slot given. */
-static
+static __attribute__((nonnull))
void
-mtr_memo_slot_release(
-/*==================*/
- mtr_t* mtr, /*!< in: mtr */
+mtr_memo_slot_release_func(
+/*=======================*/
+#ifdef UNIV_DEBUG
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+#endif /* UNIV_DEBUG */
mtr_memo_slot_t* slot) /*!< in: memo slot */
{
- void* object;
- ulint type;
-
- ut_ad(mtr);
- ut_ad(slot);
-
-#ifndef UNIV_DEBUG
- UT_NOT_USED(mtr);
-#endif /* UNIV_DEBUG */
-
- object = slot->object;
- type = slot->type;
+ void* object = slot->object;
+ slot->object = NULL;
- if (UNIV_LIKELY(object != NULL)) {
- if (type <= MTR_MEMO_BUF_FIX) {
- buf_page_release((buf_block_t*)object, type);
- } else if (type == MTR_MEMO_S_LOCK) {
- rw_lock_s_unlock((rw_lock_t*)object);
+ /* slot release is a local operation for the current mtr.
+ We must not be holding the flush_order mutex while
+ doing this. */
+ ut_ad(!log_flush_order_mutex_own());
+
+ switch (slot->type) {
+ case MTR_MEMO_PAGE_S_FIX:
+ case MTR_MEMO_PAGE_X_FIX:
+ case MTR_MEMO_BUF_FIX:
+ buf_page_release((buf_block_t*) object, slot->type);
+ break;
+ case MTR_MEMO_S_LOCK:
+ rw_lock_s_unlock((rw_lock_t*) object);
+ break;
+ case MTR_MEMO_X_LOCK:
+ rw_lock_x_unlock((rw_lock_t*) object);
+ break;
#ifdef UNIV_DEBUG
- } else if (type != MTR_MEMO_X_LOCK) {
- ut_ad(type == MTR_MEMO_MODIFY);
- ut_ad(mtr_memo_contains(mtr, object,
- MTR_MEMO_PAGE_X_FIX));
+ default:
+ ut_ad(slot->type == MTR_MEMO_MODIFY);
+ ut_ad(mtr_memo_contains(mtr, object, MTR_MEMO_PAGE_X_FIX));
#endif /* UNIV_DEBUG */
- } else {
- rw_lock_x_unlock((rw_lock_t*)object);
- }
}
-
- slot->object = NULL;
}
+#ifdef UNIV_DEBUG
+# define mtr_memo_slot_release(mtr, slot) mtr_memo_slot_release_func(mtr, slot)
+#else /* UNIV_DEBUG */
+# define mtr_memo_slot_release(mtr, slot) mtr_memo_slot_release_func(slot)
+#endif /* UNIV_DEBUG */
+
/**********************************************************//**
Releases the mlocks and other objects stored in an mtr memo.
They are released in the order opposite to which they were pushed
to the memo. */
-static
+static __attribute__((nonnull))
void
mtr_memo_pop_all(
/*=============*/
- mtr_t* mtr) /*!< in: mtr */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
- mtr_memo_slot_t* slot;
- dyn_array_t* memo;
- ulint offset;
+ const dyn_block_t* block;
- ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
commit */
- memo = &(mtr->memo);
-
- offset = dyn_array_get_data_size(memo);
- while (offset > 0) {
- offset -= sizeof(mtr_memo_slot_t);
- slot = dyn_array_get_element(memo, offset);
-
- mtr_memo_slot_release(mtr, slot);
+ for (block = dyn_array_get_last_block(&mtr->memo);
+ block;
+ block = dyn_array_get_prev_block(&mtr->memo, block)) {
+ const mtr_memo_slot_t* start
+ = (mtr_memo_slot_t*) dyn_block_get_data(block);
+ mtr_memo_slot_t* slot
+ = (mtr_memo_slot_t*) (dyn_block_get_data(block)
+ + dyn_block_get_used(block));
+
+ ut_ad(!(dyn_block_get_used(block) % sizeof(mtr_memo_slot_t)));
+
+ while (slot-- != start) {
+ if (slot->object != NULL) {
+ mtr_memo_slot_release(mtr, slot);
+ }
+ }
}
}
@@ -288,42 +297,36 @@ UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /*!< in: mtr */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
void* object, /*!< in: object */
ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
- mtr_memo_slot_t* slot;
- dyn_array_t* memo;
- ulint offset;
+ const dyn_block_t* block;
- ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
-
- memo = &(mtr->memo);
-
- offset = dyn_array_get_data_size(memo);
-
- log_flush_order_mutex_enter();
- while (offset > 0) {
- offset -= sizeof(mtr_memo_slot_t);
-
- slot = dyn_array_get_element(memo, offset);
-
- if (object == slot->object && type == slot->type) {
-
- /* We cannot release a page that has been written
- to in the middle of a mini-transaction. */
-
- ut_ad(!(mtr->modifications
- && slot->type == MTR_MEMO_PAGE_X_FIX));
-
- mtr_memo_slot_release(mtr, slot);
-
- break;
+ /* We cannot release a page that has been written to in the
+ middle of a mini-transaction. */
+ ut_ad(!mtr->modifications || type != MTR_MEMO_PAGE_X_FIX);
+
+ for (block = dyn_array_get_last_block(&mtr->memo);
+ block;
+ block = dyn_array_get_prev_block(&mtr->memo, block)) {
+ const mtr_memo_slot_t* start
+ = (mtr_memo_slot_t*) dyn_block_get_data(block);
+ mtr_memo_slot_t* slot
+ = (mtr_memo_slot_t*) (dyn_block_get_data(block)
+ + dyn_block_get_used(block));
+
+ ut_ad(!(dyn_block_get_used(block) % sizeof(mtr_memo_slot_t)));
+
+ while (slot-- != start) {
+ if (object == slot->object && type == slot->type) {
+ mtr_memo_slot_release(mtr, slot);
+ return;
+ }
}
}
- log_flush_order_mutex_exit();
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
index 9f895e60803..f9338da079e 100644
--- a/storage/innobase/page/page0zip.c
+++ b/storage/innobase/page/page0zip.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -837,11 +837,12 @@ page_zip_compress_node_ptrs(
c_stream->next_in = (byte*) rec;
c_stream->avail_in = rec_offs_data_size(offsets)
- REC_NODE_PTR_SIZE;
- ut_ad(c_stream->avail_in);
- err = deflate(c_stream, Z_NO_FLUSH);
- if (UNIV_UNLIKELY(err != Z_OK)) {
- break;
+ if (c_stream->avail_in) {
+ err = deflate(c_stream, Z_NO_FLUSH);
+ if (UNIV_UNLIKELY(err != Z_OK)) {
+ break;
+ }
}
ut_ad(!c_stream->avail_in);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 73da6215f0d..77fa6518b35 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -3840,6 +3840,7 @@ row_rename_table_for_mysql(
ut_a(old_name != NULL);
ut_a(new_name != NULL);
+ ut_ad(trx->conc_state == TRX_ACTIVE);
if (srv_created_new_raw || srv_force_recovery) {
fputs("InnoDB: A new raw disk partition was initialized or\n"
@@ -3864,7 +3865,6 @@ row_rename_table_for_mysql(
}
trx->op_info = "renaming table";
- trx_start_if_not_started(trx);
old_is_tmp = row_is_mysql_tmp_table_name(old_name);
new_is_tmp = row_is_mysql_tmp_table_name(new_name);
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index b46b2eacd9d..76c1f01d63a 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -57,6 +57,8 @@ Created 12/19/1997 Heikki Tuuri
#include "read0read.h"
#include "buf0lru.h"
#include "ha_prototypes.h"
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@@ -3918,7 +3920,9 @@ wait_table_again:
}
rec_loop:
+ DEBUG_SYNC_C("row_search_rec_loop");
if (trx_is_interrupted(trx)) {
+ btr_pcur_store_position(pcur, &mtr);
err = DB_INTERRUPTED;
goto normal_return;
}
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index c0b2f6cb700..86caf9d4243 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -279,7 +279,7 @@ UNIV_INTERN ulint srv_data_read = 0;
/* Internal setting for "innodb_stats_method". Decides how InnoDB treats
NULL value when collecting statistics. By default, it is set to
SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
-ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
+UNIV_INTERN ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
/* here we count the amount of data written in total (in bytes) */
UNIV_INTERN ulint srv_data_written = 0;
@@ -2109,19 +2109,31 @@ srv_export_innodb_status(void)
export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
#ifdef UNIV_DEBUG
- if (trx_sys->max_trx_id < purge_sys->done_trx_no) {
- export_vars.innodb_purge_trx_id_age = 0;
- } else {
- export_vars.innodb_purge_trx_id_age =
- trx_sys->max_trx_id - purge_sys->done_trx_no;
- }
+ {
+ trx_id_t done_trx_no;
+ trx_id_t up_limit_id;
+
+ rw_lock_s_lock(&purge_sys->latch);
+ done_trx_no = purge_sys->done_trx_no;
+ up_limit_id = purge_sys->view
+ ? purge_sys->view->up_limit_id
+ : 0;
+ rw_lock_s_unlock(&purge_sys->latch);
+
+ if (trx_sys->max_trx_id < done_trx_no) {
+ export_vars.innodb_purge_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_trx_id_age =
+ trx_sys->max_trx_id - done_trx_no;
+ }
- if (!purge_sys->view
- || trx_sys->max_trx_id < purge_sys->view->up_limit_id) {
- export_vars.innodb_purge_view_trx_id_age = 0;
- } else {
- export_vars.innodb_purge_view_trx_id_age =
- trx_sys->max_trx_id - purge_sys->view->up_limit_id;
+ if (!up_limit_id
+ || trx_sys->max_trx_id < up_limit_id) {
+ export_vars.innodb_purge_view_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_view_trx_id_age =
+ trx_sys->max_trx_id - up_limit_id;
+ }
}
#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index c6cbfc94dca..b2778184335 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/sync/sync0arr.c
@@ -604,10 +604,6 @@ sync_array_deadlock_step(
new = sync_array_find_thread(arr, thread);
if (UNIV_UNLIKELY(new == start)) {
- /* Stop running of other threads */
-
- ut_dbg_stop_threads = TRUE;
-
/* Deadlock */
fputs("########################################\n"
"DEADLOCK of threads detected!\n", stderr);
@@ -945,6 +941,8 @@ sync_array_print_long_waits(
# define SYNC_ARRAY_TIMEOUT 240
#endif
+ sync_array_enter(sync_primary_wait_array);
+
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
double diff;
@@ -979,6 +977,8 @@ sync_array_print_long_waits(
}
}
+ sync_array_exit(sync_primary_wait_array);
+
if (noticed) {
fprintf(stderr,
"InnoDB: ###### Starts InnoDB Monitor"
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index 0c5e367ac30..bc51dc43032 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -137,7 +137,7 @@ UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key;
#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
-uint trx_rseg_n_slots_debug = 0;
+UNIV_INTERN uint trx_rseg_n_slots_debug = 0;
#endif
/** This is used to track the maximum file format id known to InnoDB. It's
diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c
index 53ed4a53044..a440b72d32a 100644
--- a/storage/innobase/ut/ut0dbg.c
+++ b/storage/innobase/ut/ut0dbg.c
@@ -35,16 +35,6 @@ Created 1/30/1994 Heikki Tuuri
UNIV_INTERN ulint ut_dbg_zero = 0;
#endif
-#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
-will stop at the next ut_a() or ut_ad(). */
-UNIV_INTERN ibool ut_dbg_stop_threads = FALSE;
-#endif
-#ifndef UT_DBG_USE_ABORT
-/** A null pointer that will be dereferenced to trigger a memory trap */
-UNIV_INTERN ulint* ut_dbg_null_ptr = NULL;
-#endif
-
/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
@@ -80,30 +70,8 @@ ut_dbg_assertion_failed(
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
-#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
- ut_dbg_stop_threads = TRUE;
-#endif
}
-#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/*************************************************************//**
-Stop a thread after assertion failure. */
-UNIV_INTERN
-void
-ut_dbg_stop_thread(
-/*===============*/
- const char* file,
- ulint line)
-{
-#ifndef UNIV_HOTBACKUP
- fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
- os_thread_pf(os_thread_get_curr_id()),
- innobase_basename(file), line);
- os_thread_sleep(1000000000);
-#endif /* !UNIV_HOTBACKUP */
-}
-#endif
-
#ifdef UNIV_COMPILE_TEST_FUNCS
#include <sys/types.h>
diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
index 2fe45aad2a7..699af1fcaa1 100644
--- a/storage/innobase/ut/ut0ut.c
+++ b/storage/innobase/ut/ut0ut.c
@@ -728,6 +728,8 @@ ut_strerr(
return("End of index");
case DB_TABLE_IN_FK_CHECK:
return("Table is being used in foreign key check");
+ case DB_IDENTIFIER_TOO_LONG:
+ return("Identifier name is too long");
/* do not add default: in order to produce a warning if new code
is added to the enum but not added here */
}
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 6561bec5f22..f215b04b68f 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1304,8 +1304,9 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
old_proc_info= thd_proc_info(thd, "Checking status");
thd_progress_init(thd, 3);
- (void) maria_chk_status(&param, file); // Not fatal
- error= maria_chk_size(&param, file);
+ error= maria_chk_status(&param, file); // Not fatal
+ if (maria_chk_size(&param, file))
+ error= 1;
if (!error)
error|= maria_chk_del(&param, file, param.testflag);
thd_proc_info(thd, "Checking keys");
@@ -1669,6 +1670,11 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
}
}
thd_proc_info(thd, "Saving state");
+ if (optimize_done && !error && !(param->testflag & T_NO_CREATE_RENAME_LSN))
+ {
+ /* Set trid (needed if the table was moved from another system) */
+ share->state.create_trid= trnman_get_min_safe_trid();
+ }
mysql_mutex_lock(&share->intern_lock);
if (!error)
{
@@ -1684,6 +1690,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
*/
if (file->state != &share->state.state)
*file->state= share->state.state;
+
if (share->base.auto_key)
_ma_update_auto_increment_key(param, file, 1);
if (optimize_done)
@@ -1691,6 +1698,9 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
UPDATE_TIME | UPDATE_OPEN_COUNT |
(local_testflag &
T_STATISTICS ? UPDATE_STAT : 0));
+ /* File is repaired; Mark the file as moved to this system */
+ (void) _ma_set_uuid(share, 0);
+
info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
HA_STATUS_CONST);
if (rows != file->state->records && !(param->testflag & T_VERY_SILENT))
@@ -2411,7 +2421,9 @@ int ha_maria::remember_rnd_pos()
int ha_maria::restart_rnd_next(uchar *buf)
{
- (*file->s->scan_restore_pos)(file, remember_pos);
+ int error;
+ if ((error= (*file->s->scan_restore_pos)(file, remember_pos)))
+ return error;
return rnd_next(buf);
}
@@ -2644,23 +2656,6 @@ int ha_maria::external_lock(THD *thd, int lock_type)
/* Transactional table */
if (lock_type != F_UNLCK)
{
- if (!file->s->lock_key_trees) // If we don't use versioning
- {
- /*
- We come here in the following cases:
- - The table is a temporary table
- - It's a table which is crash safe but not yet versioned, for
- example a table with fulltext or rtree keys
-
- Set the current state to point to save_state so that the
- block_format code don't count the same record twice.
- Copy also the current state. This may have been wrong if the
- same file was used several times in the last statement
- */
- file->state= file->state_start;
- *file->state= file->s->state.state;
- }
-
if (file->trn)
{
/* This can only happen with tables created with clone() */
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 16657ba80ae..03fd0200d18 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -4007,6 +4007,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
uint length, empty_space;
uchar *dir;
DBUG_ENTER("delete_dir_entry");
+ DBUG_PRINT("enter", ("record_number: %u number_of_records: %u",
+ record_number, number_of_records));
#ifdef SANITY_CHECKS
if (record_number >= number_of_records ||
@@ -4023,7 +4025,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
check_directory(buff, block_size, 0, (uint) -1);
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
dir= dir_entry_pos(buff, block_size, record_number);
- length= uint2korr(dir + 2);
+ length= uint2korr(dir + 2); /* Length of entry we just deleted */
+ DBUG_ASSERT(uint2korr(dir) != 0 && length < block_size);
if (record_number == number_of_records - 1)
{
@@ -5240,11 +5243,6 @@ void _ma_scan_end_block_record(MARIA_HA *info)
For the moment we can only remember one position, but this is
good enough for MySQL usage
- @Warning
- When this function is called, we assume that the thread is not deleting
- or updating the current row before ma_scan_restore_block_record()
- is called!
-
@return
@retval 0 ok
@retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position
@@ -5264,15 +5262,18 @@ int _ma_scan_remember_block_record(MARIA_HA *info,
info->scan_save->bitmap_buff= ((uchar*) info->scan_save +
ALIGN_SIZE(sizeof(*info->scan_save)));
}
- /* Point to the last read row */
- *lastpos= info->cur_row.nextpos - 1;
- info->scan.dir+= DIR_ENTRY_SIZE;
+ /* For checking if pages have changed since we last read it */
+ info->scan.row_changes= info->row_changes;
/* Remember used bitmap and used head page */
bitmap_buff= info->scan_save->bitmap_buff;
memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save));
info->scan_save->bitmap_buff= bitmap_buff;
memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2);
+
+ /* Point to the last read row */
+ *lastpos= info->cur_row.nextpos - 1;
+ info->scan_save->dir+= DIR_ENTRY_SIZE;
DBUG_RETURN(0);
}
@@ -5280,15 +5281,22 @@ int _ma_scan_remember_block_record(MARIA_HA *info,
/**
@brief restore scan block it's original values
+ @return
+ 0 ok
+ # error
+
@note
In theory we could swap bitmap buffers instead of copy them.
For the moment we don't do that because there are variables pointing
inside the buffers and it's a bit of hassle to either make them relative
or repoint them.
+
+ If the data file has changed, we will re-read the new block record
+ to ensure that when we continue scanning we can ignore any deleted rows.
*/
-void _ma_scan_restore_block_record(MARIA_HA *info,
- MARIA_RECORD_POS lastpos)
+int _ma_scan_restore_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS lastpos)
{
uchar *bitmap_buff;
DBUG_ENTER("_ma_scan_restore_block_record");
@@ -5299,7 +5307,26 @@ void _ma_scan_restore_block_record(MARIA_HA *info,
info->scan.bitmap_buff= bitmap_buff;
memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2);
- DBUG_VOID_RETURN;
+ if (info->scan.row_changes != info->row_changes)
+ {
+ /*
+ Table has been changed. We have to re-read the current page block as
+ data may have changed on it that we have to see.
+ */
+ if (!(pagecache_read(info->s->pagecache,
+ &info->dfile,
+ ma_recordpos_to_page(info->scan.row_base_page),
+ 0, info->scan.page_buff,
+ info->s->page_type,
+ PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
+ DBUG_RETURN(my_errno);
+ info->scan.number_of_rows=
+ (uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET];
+ info->scan.dir_end= (info->scan.page_buff + info->s->block_size -
+ PAGE_SUFFIX_SIZE -
+ info->scan.number_of_rows * DIR_ENTRY_SIZE);
+ }
+ DBUG_RETURN(0);
}
@@ -5326,7 +5353,7 @@ void _ma_scan_restore_block_record(MARIA_HA *info,
RETURN
0 ok
- # Error code
+ # Error code (Normally HA_ERR_END_OF_FILE)
*/
int _ma_scan_block_record(MARIA_HA *info, uchar *record,
@@ -5345,6 +5372,12 @@ restart_record_read:
uchar *data, *end_of_data;
int error;
+ /* Ensure that scan.dir and record_pos are in sync */
+ DBUG_ASSERT(info->scan.dir == dir_entry_pos(info->scan.page_buff,
+ share->block_size,
+ record_pos));
+
+ /* Search for a valid directory entry (not 0) */
while (!(offset= uint2korr(info->scan.dir)))
{
info->scan.dir-= DIR_ENTRY_SIZE;
@@ -5357,13 +5390,19 @@ restart_record_read:
}
#endif
}
+ /*
+ This should always be true as the directory should always start with
+ a valid entry.
+ */
+ DBUG_ASSERT(info->scan.dir >= info->scan.dir_end);
+
/* found row */
info->cur_row.lastpos= info->scan.row_base_page + record_pos;
info->cur_row.nextpos= record_pos + 1;
data= info->scan.page_buff + offset;
length= uint2korr(info->scan.dir + 2);
end_of_data= data + length;
- info->scan.dir-= DIR_ENTRY_SIZE; /* Point to previous row */
+ info->scan.dir-= DIR_ENTRY_SIZE; /* Point to next row to process */
#ifdef SANITY_CHECKS
if (end_of_data > info->scan.dir_end ||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
@@ -6937,6 +6976,7 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
res= 0;
end:
+ /* The following is true only if _ma_bitmap_flushable() was called earlier */
if (info->non_flushable_state)
_ma_bitmap_flushable(info, -1);
_ma_unpin_all_pages_and_finalize_row(info, lsn);
@@ -6946,6 +6986,11 @@ err:
DBUG_ASSERT(!maria_assert_if_crashed_table);
res= 1;
_ma_mark_file_crashed(share);
+ /*
+ Don't write a new LSN on the used pages. Not important as the file is
+ marked as crashed and need to be repaired before it can be used.
+ */
+ lsn= LSN_IMPOSSIBLE;
goto end;
}
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index 45f5613bb60..40ca2591236 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -167,8 +167,8 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info);
void _ma_scan_end_block_record(MARIA_HA *info);
int _ma_scan_remember_block_record(MARIA_HA *info,
MARIA_RECORD_POS *lastpos);
-void _ma_scan_restore_block_record(MARIA_HA *info,
- MARIA_RECORD_POS lastpos);
+int _ma_scan_restore_block_record(MARIA_HA *info,
+ MARIA_RECORD_POS lastpos);
MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
const uchar *record);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 6bcb9c21a71..fdb2bae3d8c 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -140,13 +140,22 @@ void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info)
Set up transaction handler so that we can see all rows. When rows is read
we will check the found id against param->max_tried
*/
- if (param->max_trid == 0)
+ if (!info->s->base.born_transactional)
+ {
+ /*
+ There are no trids. Howver we want to set max_trid to make test of
+ create_trid simpler.
+ */
+ param->max_trid= ~(TrID) 0;
+ }
+ else if (param->max_trid == 0)
{
if (!ma_control_file_inited())
param->max_trid= 0; /* Give warning for first trid found */
else
param->max_trid= max_trid_in_system();
}
+
maria_ignore_trids(info);
}
@@ -179,6 +188,13 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
if (param->testflag & T_UPDATE_STATE)
param->warning_printed=save;
}
+ if (share->state.create_trid > param->max_trid)
+ {
+ _ma_check_print_warning(param,
+ "Table create_trd (%llu) > current max_transaction id (%llu). Table needs to be repaired or zerofilled to be usable",
+ share->state.create_trid, param->max_trid);
+ return 1;
+ }
return 0;
}
@@ -2424,11 +2440,10 @@ static void restore_table_state_after_repair(MARIA_HA *info,
{
maria_versioning(info, info->s->have_versioning);
info->s->lock_key_trees= org_share->lock_key_trees;
+ DBUG_ASSERT(!info->s->have_versioning || info->s->lock_key_trees);
}
-
-
/**
@brief Drop all indexes
@@ -3553,7 +3568,10 @@ int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const char *name)
/* Ensure state is later flushed to disk, if within maria_chk */
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- /* Reset create_trid to make file comparable */
+ /*
+ Reset create_trid to make file comparable and to ensure that new
+ trid's in the file starts from 0.
+ */
share->state.create_trid= 0;
}
if (reenable_logging)
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 5b8d0e01677..22f7341098d 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -112,6 +112,7 @@ int maria_delete(MARIA_HA *info,const uchar *record)
info->state->checksum-= info->cur_row.checksum;
info->state->records--;
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
+ info->row_changes++;
share->state.changed|= (STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE |
STATE_NOT_ZEROFILLED);
info->state->changed=1;
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 5233e57594c..f0ade217341 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -7472,9 +7472,8 @@ static void translog_force_current_buffer_to_finish()
struct st_translog_buffer *old_buffer= log_descriptor.bc.buffer;
uchar *data= log_descriptor.bc.ptr - log_descriptor.bc.current_page_fill;
uint16 left= TRANSLOG_PAGE_SIZE - log_descriptor.bc.current_page_fill;
- uint16 current_page_fill, write_counter, previous_offset;
+ uint16 UNINIT_VAR(current_page_fill), write_counter, previous_offset;
DBUG_ENTER("translog_force_current_buffer_to_finish");
- LINT_INIT(current_page_fill);
DBUG_PRINT("enter", ("Buffer #%u 0x%lx "
"Buffer addr: (%lu,0x%lx) "
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 88422e3dc5f..d2ae10ccb18 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -437,15 +437,23 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->open_count_not_zero_on_open= 1;
/*
+ A transactional table is not usable on this system if:
+ - share->state.create_trid > trnman_get_max_trid()
+ - Critical as trid as stored releativel to create_trid.
+ - uuid is different
+
+ STATE_NOT_MOVABLE is reset when a table is zerofilled
+ (has no LSN's and no trids)
+
We can ignore testing uuid if STATE_NOT_MOVABLE is set, as in this
- case the uuid will be set in _ma_mark_file_changed()
+ case the uuid will be set in _ma_mark_file_changed().
*/
- if ((share->state.changed & STATE_NOT_MOVABLE) &&
- share->base.born_transactional &&
- ((!(open_flags & HA_OPEN_IGNORE_MOVED_STATE) &&
- memcmp(share->base.uuid, maria_uuid, MY_UUID_SIZE)) ||
- (share->state.create_trid > trnman_get_max_trid() &&
- !maria_in_recovery)))
+ if (share->base.born_transactional &&
+ ((share->state.create_trid > trnman_get_max_trid() &&
+ !maria_in_recovery) ||
+ ((share->state.changed & STATE_NOT_MOVABLE) &&
+ ((!(open_flags & HA_OPEN_IGNORE_MOVED_STATE) &&
+ memcmp(share->base.uuid, maria_uuid, MY_UUID_SIZE))))))
{
DBUG_PRINT("warning", ("table is moved from another system. uuid_diff: %d create_trid: %lu max_trid: %lu",
memcmp(share->base.uuid, maria_uuid,
@@ -756,7 +764,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
goto err;
}
- else
+ else if (!(open_flags & HA_OPEN_FOR_REPAIR))
{
/* create_rename_lsn != LSN_NEEDS_NEW_STATE_LSNS */
share->state.changed|= STATE_NOT_MOVABLE;
@@ -894,8 +902,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
&share->keyinfo[i].root_lock);
mysql_rwlock_init(key_SHARE_mmap_lock, &share->mmap_lock);
- share->row_is_visible= _ma_row_visible_always;
- share->lock.get_status= _ma_reset_update_flag;
+ share->row_is_visible= _ma_row_visible_always;
+ share->lock.get_status= _ma_reset_update_flag;
+ share->lock.start_trans= _ma_start_trans;
+
if (!thr_lock_inited)
{
/* Probably a single threaded program; Don't use concurrent inserts */
diff --git a/storage/maria/ma_pagecrc.c b/storage/maria/ma_pagecrc.c
index 58e3b4b203d..a79f34016c1 100644
--- a/storage/maria/ma_pagecrc.c
+++ b/storage/maria/ma_pagecrc.c
@@ -358,8 +358,7 @@ my_bool maria_flush_log_for_page(uchar *page,
MARIA_SHARE *share= (MARIA_SHARE*) data_ptr;
DBUG_ENTER("maria_flush_log_for_page");
/* share is 0 here only in unittest */
- DBUG_ASSERT(!share || (share->page_type == PAGECACHE_LSN_PAGE &&
- share->now_transactional));
+ DBUG_ASSERT(!share || share->page_type == PAGECACHE_LSN_PAGE);
lsn= lsn_korr(page);
if (translog_flush(lsn))
DBUG_RETURN(1);
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index aeeda26b791..bd2bde1c89a 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3304,7 +3304,7 @@ static LSN parse_checkpoint_record(LSN lsn)
first_log_write_lsn= lsn_korr(ptr);
ptr+= LSN_STORE_SIZE;
name_len= strlen((char *)ptr) + 1;
- strmake(name, (char *)ptr, sizeof(name)-1);
+ strmake_buf(name, (char *)ptr);
ptr+= name_len;
if (new_table(sid, name, first_log_write_lsn))
return LSN_ERROR;
diff --git a/storage/maria/ma_scan.c b/storage/maria/ma_scan.c
index cbac463a2c8..ad526211615 100644
--- a/storage/maria/ma_scan.c
+++ b/storage/maria/ma_scan.c
@@ -68,7 +68,8 @@ int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos)
}
-void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
+int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
{
info->cur_row.nextpos= lastpos;
+ return 0;
}
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index ccb4bf77717..d38bc7af26c 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -424,9 +424,9 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
flag is the value returned by ha_key_cmp and as treated as final
*/
int flag=0, my_flag=-1;
- uint nod_flag, length, len, matched, cmplen, kseg_len;
- uint page_flag, prefix_len,suffix_len;
- int key_len_skip, seg_len_pack, key_len_left;
+ uint nod_flag, UNINIT_VAR(length), len, matched, cmplen, kseg_len;
+ uint page_flag, UNINIT_VAR(prefix_len),suffix_len;
+ int key_len_skip, UNINIT_VAR(seg_len_pack), key_len_left;
uchar *end, *vseg, *UNINIT_VAR(saved_vseg), *UNINIT_VAR(saved_from);
uchar *page;
uchar tt_buff[MARIA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
@@ -439,10 +439,6 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
const uchar *sort_order= keyinfo->seg->charset->sort_order;
DBUG_ENTER("_ma_prefix_search");
- LINT_INIT(seg_len_pack);
- LINT_INIT(prefix_len);
- LINT_INIT(length);
-
t_buff[0]=0; /* Avoid bugs */
page_flag= ma_page->flag;
nod_flag= ma_page->node;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 1f4a7504c56..f130da21d07 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -59,6 +59,8 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
MARIA_STATE_HISTORY *history;
DBUG_ENTER("_ma_setup_live_state");
+ DBUG_ASSERT(share->lock_key_trees);
+
if (maria_create_trn_hook(info))
DBUG_RETURN(1);
@@ -377,6 +379,17 @@ void _ma_reset_update_flag(void *param,
info->state->changed= 0;
}
+my_bool _ma_start_trans(void* param)
+{
+ MARIA_HA *info=(MARIA_HA*) param;
+ if (!info->s->lock_key_trees)
+ {
+ info->state= info->state_start;
+ *info->state= info->s->state.state;
+ }
+ return 0;
+}
+
/**
@brief Check if should allow concurrent inserts
@@ -622,6 +635,22 @@ my_bool _ma_block_start_trans(void* param)
*/
return _ma_setup_live_state(info);
}
+ else
+ {
+ /*
+ We come here in the following cases:
+ - The table is a temporary table
+ - It's a table which is crash safe but not yet versioned, for
+ example a table with fulltext or rtree keys
+
+ Set the current state to point to save_state so that the
+ block_format code don't count the same record twice.
+ Copy also the current state. This may have been wrong if the
+ same file was used several times in the last statement
+ */
+ info->state= info->state_start;
+ *info->state= info->s->state.state;
+ }
/*
Info->trn is set if this table is already handled and we are
@@ -668,9 +697,11 @@ my_bool _ma_block_start_trans_no_versioning(void* param)
{
MARIA_HA *info=(MARIA_HA*) param;
DBUG_ENTER("_ma_block_get_status_no_version");
- DBUG_ASSERT(info->s->base.born_transactional);
+ DBUG_ASSERT(info->s->base.born_transactional && !info->s->lock_key_trees);
info->state->changed= 0; /* from _ma_reset_update_flag() */
+ info->state= info->state_start;
+ *info->state= info->s->state.state;
if (!info->trn)
{
/*
@@ -689,18 +720,22 @@ my_bool _ma_block_start_trans_no_versioning(void* param)
void maria_versioning(MARIA_HA *info, my_bool versioning)
{
+ MARIA_SHARE *share= info->s;
/* For now, this is a hack */
- if (info->s->have_versioning)
+ if (share->have_versioning)
{
enum thr_lock_type save_lock_type;
- /* Assume is a non threaded application (for now) */
- info->s->lock_key_trees= 0;
+ share->lock_key_trees= versioning;
/* Set up info->lock.type temporary for _ma_block_get_status() */
save_lock_type= info->lock.type;
info->lock.type= versioning ? TL_WRITE_CONCURRENT_INSERT : TL_WRITE;
_ma_block_get_status((void*) info, versioning);
info->lock.type= save_lock_type;
- info->state= info->state_start= &info->s->state.common;
+ if (versioning)
+ info->state= &share->state.common;
+ else
+ info->state= &share->state.state; /* Change global values by default */
+ info->state_start= info->state; /* Initial values */
}
}
diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h
index 03ce5c2ea8c..2903986e32a 100644
--- a/storage/maria/ma_state.h
+++ b/storage/maria/ma_state.h
@@ -66,6 +66,7 @@ void _ma_update_status_with_lock(MARIA_HA *info);
void _ma_restore_status(void *param);
void _ma_copy_status(void* to, void *from);
void _ma_reset_update_flag(void *param, my_bool concurrent_insert);
+my_bool _ma_start_trans(void* param);
my_bool _ma_check_status(void *param);
void _ma_block_get_status(void* param, my_bool concurrent_insert);
void _ma_block_update_status(void *param);
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index 945654a0bbe..5a655d4412a 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -55,7 +55,6 @@ static void create_key(uchar *key,uint rownr);
static void create_record(uchar *record,uint rownr);
static void update_record(uchar *record);
-
/*
These are here only for testing of recovery with undo. We are not
including maria_def.h here as this test is also to be an example of
@@ -506,6 +505,7 @@ end:
break;
}
printf("Dying on request without maria_commit()/maria_close()\n");
+ sf_leaking_memory= 1;
exit(0);
}
@@ -514,6 +514,7 @@ end:
if (maria_close(file))
goto err;
maria_end();
+ my_uuid_end();
my_end(MY_CHECK_ERROR);
return (0);
diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c
index ea1978b4ee5..a3b7a2a9e98 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -971,6 +971,7 @@ end:
break;
}
printf("Dying on request without maria_commit()/maria_close()\n");
+ sf_leaking_memory= 1; /* no memory leak reports here */
exit(0);
}
if (maria_commit(file))
@@ -1017,6 +1018,7 @@ reads: %10lu\n",
}
maria_end();
my_free(blob_buffer);
+ my_uuid_end();
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
return(0);
err:
@@ -1029,6 +1031,8 @@ err2:
maria_close(file);
}
maria_end();
+ my_uuid_end();
+ my_end(0);
return(1);
} /* main */
diff --git a/storage/maria/ma_update.c b/storage/maria/ma_update.c
index 0a726c1b7f9..e0e804ca655 100644
--- a/storage/maria/ma_update.c
+++ b/storage/maria/ma_update.c
@@ -173,6 +173,7 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
We can't yet have HA_STATE_AKTIV here, as block_record dosn't support it
*/
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
+ info->row_changes++;
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
info->state->changed= 1;
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 752741d0a5e..09d42a9be72 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -298,6 +298,7 @@ int maria_write(MARIA_HA *info, uchar *record)
info->state->records++;
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED);
+ info->row_changes++;
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
info->state->changed= 1;
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 8a7ba30eb08..065063fcb07 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -88,9 +88,22 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param, MARIA_PAGE *page,
uint sortkey, File new_file,
my_bool update_index);
static my_bool write_log_record(HA_CHECK *param);
+static void my_exit(int exit_code) __attribute__ ((noreturn));
HA_CHECK check_param;
+/* Free memory and exit */
+
+static void my_exit(int exit_code)
+{
+ free_tmpdir(&maria_chk_tmpdir);
+ free_defaults(default_argv);
+ my_end(check_param.testflag & T_INFO ?
+ MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
+ exit(exit_code);
+}
+
+
/* Main program */
int main(int argc, char **argv)
@@ -178,12 +191,8 @@ end:
printf("\nTotal of all %d Aria-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff),
llstr(check_param.total_deleted,buff2));
}
- free_defaults(default_argv);
- free_tmpdir(&maria_chk_tmpdir);
maria_end();
- my_end(check_param.testflag & T_INFO ?
- MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
- exit(error);
+ my_exit(error);
#ifndef _lint
return 0; /* No compiler warning */
#endif
@@ -257,10 +266,10 @@ static struct my_option my_long_options[] =
"Restart with -r if there are any errors in the table. States will be updated as with --update-state.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"HELP", 'H',
- "Display this help and exit.",
+ "Print all argument options sorted alphabetically and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"help", '?',
- "Display this help and exit.",
+ "Print all options by groups and exit. See also --HELP",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"information", 'i',
"Print statistics information about table that is checked.",
@@ -410,7 +419,7 @@ static struct my_option my_long_options[] =
(char**) &maria_stats_method_str, (char**) &maria_stats_method_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "zerofill", 'z',
- "Fill empty space in data and index files with zeroes,",
+ "Fill empty space in data and index files with zeroes. This makes the data file movable between different servers.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "zerofill-keep-lsn", OPT_ZEROFILL_KEEP_LSN,
"Like --zerofill but does not zero out LSN of data/index pages;"
@@ -422,7 +431,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- printf("%s Ver 1.1 for %s at %s\n", my_progname, SYSTEM_TYPE,
+ printf("%s Ver 1.2 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
@@ -441,8 +450,8 @@ static void usage(void)
-#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n");
#endif
printf("\
- -H, --HELP Display this help and exit.\n\
- -?, --help Display this help and exit.\n\
+ -H, --HELP Print all argument options sorted alphabetically.\n\
+ -?, --help Print all options by groups\n\
--datadir=path Path for control file (and logs if --logdir not used)\n\
--logdir=path Path for log files\n\
--ignore-control-file Don't open the control file. Only use this if you\n\
@@ -566,7 +575,9 @@ Recover (repair)/ options (When using '--recover' or '--safe-recover'):\n\
(It may be VERY slow to do a sort the first time!).\n\
-b, --block-search=#\n\
Find a record, a block at given offset belongs to.\n\
- -z, --zerofill Fill empty space in data and index files with zeroes\n\
+ -z, --zerofill Fill empty space in data and index files with zeroes.\n\
+ This makes the data file movable between different \n\
+ servers.\n\
--zerofill-keep-lsn Like --zerofill but does not zero out LSN of\n\
data/index pages.");
@@ -790,7 +801,7 @@ get_one_option(int optid,
fprintf(stderr,
"The value of the sort key is bigger than max key: %d.\n",
MARIA_MAX_KEY);
- exit(1);
+ my_exit(1);
}
}
break;
@@ -818,7 +829,7 @@ get_one_option(int optid,
break;
case 'V':
print_version();
- exit(0);
+ my_exit(0);
case OPT_CORRECT_CHECKSUM:
if (argument == disabled_my_option)
check_param.testflag&= ~T_CALC_CHECKSUM;
@@ -833,7 +844,7 @@ get_one_option(int optid,
if ((method=find_type(argument, &maria_stats_method_typelib, 2)) <= 0)
{
fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
- exit(1);
+ my_exit(1);
}
switch (method-1) {
case 0:
@@ -869,10 +880,11 @@ get_one_option(int optid,
break;
case 'H':
my_print_help(my_long_options);
- exit(0);
+ my_print_variables(my_long_options);
+ my_exit(0);
case '?':
usage();
- exit(0);
+ my_exit(0);
}
return 0;
}
@@ -889,7 +901,7 @@ static void get_options(register int *argc,register char ***argv)
check_param.testflag|=T_WRITE_LOOP;
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
- exit(ho_error);
+ my_exit(ho_error);
/* If using repair, then update checksum if one uses --update-state */
if ((check_param.testflag & T_UPDATE_STATE) &&
@@ -899,7 +911,7 @@ static void get_options(register int *argc,register char ***argv)
if (*argc == 0)
{
usage();
- exit(-1);
+ my_exit(-1);
}
if ((check_param.testflag & T_UNPACK) &&
@@ -907,7 +919,7 @@ static void get_options(register int *argc,register char ***argv)
{
fprintf(stderr, "%s: --unpack can't be used with --quick or --sort-records\n",
my_progname_short);
- exit(1);
+ my_exit(1);
}
if ((check_param.testflag & T_READONLY) &&
(check_param.testflag &
@@ -916,7 +928,7 @@ static void get_options(register int *argc,register char ***argv)
{
fprintf(stderr, "%s: Can't use --readonly when repairing or sorting\n",
my_progname_short);
- exit(1);
+ my_exit(1);
}
if (!opt_debug)
@@ -924,20 +936,26 @@ static void get_options(register int *argc,register char ***argv)
DEBUGGER_OFF; /* Speed up things a bit */
}
if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir))
- exit(1);
+ my_exit(1);
check_param.tmpdir=&maria_chk_tmpdir;
if (set_collation_name)
if (!(set_collation= get_charset_by_name(set_collation_name,
MYF(MY_WME))))
- exit(1);
+ my_exit(1);
if (maria_data_root != default_log_dir && opt_log_dir == default_log_dir)
{
/* --datadir was used and --log-dir was not. Set log-dir to datadir */
opt_log_dir= maria_data_root;
}
+
+ /* If we are using zerofill, then we don't need to read the control file */
+ if ((check_param.testflag & (T_ZEROFILL_KEEP_LSN | T_ZEROFILL)) &&
+ !(check_param.testflag & ~(T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX | T_STATISTICS | T_CHECK | T_FAST | T_CHECK_ONLY_CHANGED)))
+ opt_ignore_control_file= 1;
+
return;
} /* get options */
@@ -1220,8 +1238,11 @@ static int maria_chk(HA_CHECK *param, char *filename)
((param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_ZEROFILL | T_ZEROFILL_KEEP_LSN)) !=
(T_ZEROFILL | T_ZEROFILL_KEEP_LSN)))
+ {
share->state.create_rename_lsn= share->state.is_of_horizon=
share->state.skip_redo_lsn= LSN_NEEDS_NEW_STATE_LSNS;
+ share->state.create_trid= 0;
+ }
}
if (!error && (param->testflag & T_REP_ANY))
{
@@ -1508,6 +1529,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
LSN_IN_PARTS(share->state.create_rename_lsn),
LSN_IN_PARTS(share->state.is_of_horizon),
LSN_IN_PARTS(share->state.skip_redo_lsn));
+ printf("create_trid: %s\n",
+ llstr(share->state.create_trid, llbuff));
}
compile_time_assert((MY_UUID_STRING_LENGTH + 1) <= sizeof(buff));
buff[MY_UUID_STRING_LENGTH]= 0;
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index a1275e7ccd2..8c19d0f18f3 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -389,7 +389,7 @@ typedef struct st_maria_share
/* End scan */
void (*scan_end)(MARIA_HA *);
int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
- void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
+ int (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
/* Pre-write of row (some handlers may do the actual write here) */
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
/* Write record (or accept write_record_init) */
@@ -564,6 +564,7 @@ typedef struct st_maria_block_scan
ulonglong bits;
uint number_of_rows, bit_pos;
MARIA_RECORD_POS row_base_page;
+ ulonglong row_changes;
} MARIA_BLOCK_SCAN;
//typedef ICP_RESULT (*index_cond_func_t)(void *param);
@@ -606,6 +607,7 @@ struct st_maria_handler
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
invalidator_by_filename invalidator; /* query cache invalidator */
ulonglong last_auto_increment; /* auto value at start of statement */
+ ulonglong row_changes; /* Incremented for each change */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */
@@ -1297,7 +1299,7 @@ my_bool _ma_check_status(void *param);
void _ma_restore_status(void *param);
void _ma_reset_status(MARIA_HA *maria);
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
-void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
+int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
#include "ma_commit.h"
diff --git a/storage/maria/unittest/ma_test_recovery.expected b/storage/maria/unittest/ma_test_recovery.expected
index 6a6051735c5..6aaff86e6cf 100644
--- a/storage/maria/unittest/ma_test_recovery.expected
+++ b/storage/maria/unittest/ma_test_recovery.expected
@@ -69,8 +69,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -78,8 +78,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -87,8 +87,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -98,8 +98,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -107,8 +107,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -116,8 +116,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -166,8 +166,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -175,8 +175,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -184,8 +184,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -195,8 +195,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -204,8 +204,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -213,8 +213,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -263,8 +263,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -272,8 +272,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -281,8 +281,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -292,8 +292,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -301,8 +301,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -310,8 +310,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -360,8 +360,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -369,8 +369,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -378,8 +378,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -389,8 +389,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -398,8 +398,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -407,8 +407,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -457,8 +457,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -466,8 +466,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -475,8 +475,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -486,8 +486,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -495,8 +495,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -504,8 +504,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -554,8 +554,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -563,8 +563,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -572,8 +572,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -583,8 +583,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -592,8 +592,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -601,8 +601,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -651,8 +651,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -660,8 +660,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -669,8 +669,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -680,8 +680,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -689,8 +689,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -698,8 +698,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -748,8 +748,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -757,8 +757,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -766,8 +766,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -777,8 +777,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -786,8 +786,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -795,8 +795,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -845,8 +845,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -854,8 +854,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -863,8 +863,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -874,8 +874,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -883,8 +883,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -892,8 +892,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -942,8 +942,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -951,8 +951,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -960,8 +960,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -971,8 +971,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -980,8 +980,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -989,8 +989,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1039,8 +1039,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1048,8 +1048,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1057,8 +1057,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1068,8 +1068,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1077,8 +1077,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1086,8 +1086,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1136,8 +1136,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1145,8 +1145,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1154,8 +1154,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1165,8 +1165,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1174,8 +1174,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1183,8 +1183,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1233,8 +1233,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1242,8 +1242,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1251,8 +1251,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1262,8 +1262,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1271,8 +1271,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1280,8 +1280,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1330,8 +1330,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1339,8 +1339,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1348,8 +1348,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1359,8 +1359,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1368,8 +1368,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1377,8 +1377,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1427,8 +1427,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1436,8 +1436,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1445,8 +1445,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1456,8 +1456,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1465,8 +1465,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1474,8 +1474,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1524,8 +1524,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1533,8 +1533,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1542,8 +1542,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1553,8 +1553,8 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1562,8 +1562,8 @@ testing idempotency
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
@@ -1571,8 +1571,8 @@ testing applying of CLRs to recreate table
applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
+7c7
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
---
> Status: changed
========DIFF END=======
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index 60ea7757827..011df5e8eb9 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -85,9 +85,10 @@ int mi_write(MI_INFO *info, uchar *record)
/* Calculate and check all unique constraints */
for (i=0 ; i < share->state.header.uniques ; i++)
{
- if (mi_check_unique(info,share->uniqueinfo+i,record,
- mi_unique_hash(share->uniqueinfo+i,record),
- HA_OFFSET_ERROR))
+ MI_UNIQUEDEF *def= share->uniqueinfo + i;
+ if (mi_is_key_active(share->state.key_map, def->key) &&
+ mi_check_unique(info, def, record, mi_unique_hash(def, record),
+ HA_OFFSET_ERROR))
goto err2;
}
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 1985a53acf8..74be8b99d87 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -2144,7 +2144,8 @@ static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees)
*/
if (!(packed_tree=(uint*) my_alloca(sizeof(uint)*length*2)))
{
- my_error(EE_OUTOFMEMORY,MYF(ME_BELL),sizeof(uint)*length*2);
+ my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR),
+ sizeof(uint)*length*2);
return 0;
}
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 5d9b5b5808b..481ca41ba9d 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1460,7 +1460,7 @@ static void split_file_name(const char *file_name,
char buff[FN_REFLEN];
db->length= 0;
- strmake(buff, file_name, sizeof(buff)-1);
+ strmake_buf(buff, file_name);
dir_length= dirname_length(buff);
if (dir_length > 1)
{
diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc
index 38f6df3003d..2c9951e3f46 100644
--- a/storage/perfschema/pfs_engine_table.cc
+++ b/storage/perfschema/pfs_engine_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -512,7 +512,7 @@ bool pfs_show_status(handlerton *hton, THD *thd,
uint buflen;
const char *name;
int i;
- uint size;
+ size_t size;
DBUG_ENTER("pfs_show_status");
@@ -526,7 +526,7 @@ bool pfs_show_status(handlerton *hton, THD *thd,
if (stat != HA_ENGINE_STATUS)
DBUG_RETURN(false);
- uint total_memory= 0;
+ size_t total_memory= 0;
for (i=0; /* empty */; i++)
{
@@ -763,7 +763,7 @@ bool pfs_show_status(handlerton *hton, THD *thd,
break;
}
- buflen= int10_to_str(size, buf, 10) - buf;
+ buflen= longlong10_to_str(size, buf, 10) - buf;
if (print(thd,
PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length,
name, strlen(name),
diff --git a/storage/perfschema/pfs_global.cc b/storage/perfschema/pfs_global.cc
index fa57f335325..335f57c69c6 100644
--- a/storage/perfschema/pfs_global.cc
+++ b/storage/perfschema/pfs_global.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
#include <string.h>
bool pfs_initialized= false;
-ulonglong pfs_allocated_memory= 0;
+size_t pfs_allocated_memory= 0;
/**
Memory allocation for the performance schema.
diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h
index c0c0490a380..5a3cc342b7d 100644
--- a/storage/perfschema/pfs_global.h
+++ b/storage/perfschema/pfs_global.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
*/
extern bool pfs_initialized;
-extern ulonglong pfs_allocated_memory;
+extern size_t pfs_allocated_memory;
void *pfs_malloc(size_t size, myf flags);
#define PFS_MALLOC_ARRAY(n, T, f) \
diff --git a/storage/sphinx/CMakeLists.txt b/storage/sphinx/CMakeLists.txt
index d9320d10cf7..3e26637218f 100644
--- a/storage/sphinx/CMakeLists.txt
+++ b/storage/sphinx/CMakeLists.txt
@@ -3,3 +3,12 @@ IF(MSVC)
LINK_LIBRARIES(ws2_32)
ENDIF(MSVC)
MYSQL_ADD_PLUGIN(sphinx ha_sphinx.cc STORAGE_ENGINE)
+
+IF(NOT WITHOUT_SPHINX_STORAGE_ENGINE)
+ ADD_LIBRARY(snippets_udf MODULE snippets_udf.cc)
+ TARGET_LINK_LIBRARIES(snippets_udf mysys) # my_error
+ ADD_DEPENDENCIES(snippets_udf GenError) # uses generated error constants
+ SET_TARGET_PROPERTIES(snippets_udf PROPERTIES OUTPUT_NAME sphinx PREFIX "")
+ INSTALL(TARGETS snippets_udf COMPONENT Server DESTINATION ${INSTALL_PLUGINDIR})
+ENDIF()
+
diff --git a/storage/sphinx/snippets_udf.cc b/storage/sphinx/snippets_udf.cc
index 85fb66ab793..5318592ab5f 100644
--- a/storage/sphinx/snippets_udf.cc
+++ b/storage/sphinx/snippets_udf.cc
@@ -1,5 +1,5 @@
//
-// $Id: snippets_udf.cc 3087 2012-01-30 23:07:35Z shodan $
+// $Id: snippets_udf.cc 3508 2012-11-05 11:48:48Z kevg $
//
//
@@ -17,12 +17,19 @@
#include <string.h>
#include <assert.h>
+#ifndef __WIN__
#include <sys/un.h>
#include <netdb.h>
+#else
+#include <winsock2.h>
+#endif
#include <mysql_version.h>
-#if MYSQL_VERSION_ID>50100
+#if MYSQL_VERSION_ID>=50515
+#include "sql_class.h"
+#include "sql_array.h"
+#elif MYSQL_VERSION_ID>50100
#include "mysql_priv.h"
#include <mysql/plugin.h>
#else
@@ -84,9 +91,9 @@ void sphUnalignedWrite ( void * pPtr, const T & tVal )
#define SafeDeleteArray(_arg) { if ( _arg ) delete [] ( _arg ); (_arg) = NULL; }
#define Min(a,b) ((a)<(b)?(a):(b))
-
+#ifndef __WIN__
typedef unsigned int DWORD;
-
+#endif
inline DWORD sphF2DW ( float f ) { union { float f; uint32 d; } u; u.f = f; return u.d; }
static char * sphDup ( const char * sSrc, int iLen=-1 )
@@ -158,7 +165,7 @@ enum
SEARCHD_COMMAND_EXCERPT = 1,
- VER_COMMAND_EXCERPT = 0x103,
+ VER_COMMAND_EXCERPT = 0x104,
};
/// known answers
@@ -380,23 +387,44 @@ int CSphUrl::Connect()
else
{
int tmp_errno;
+ bool bError = false;
+
+#if MYSQL_VERSION_ID>=50515
+ struct addrinfo *hp = NULL;
+ tmp_errno = getaddrinfo ( m_sHost, NULL, NULL, &hp );
+ if ( !tmp_errno || !hp || !hp->ai_addr )
+ {
+ bError = true;
+ if ( hp )
+ freeaddrinfo ( hp );
+ }
+#else
struct hostent tmp_hostent, *hp;
char buff2 [ GETHOSTBYNAME_BUFF_SIZE ];
-
hp = my_gethostbyname_r ( m_sHost, &tmp_hostent, buff2, sizeof(buff2), &tmp_errno );
if ( !hp )
{
my_gethostbyname_r_free();
+ bError = true;
+ }
+#endif
+ if ( bError )
+ {
char sError[256];
- snprintf ( sError, sizeof(sError), "failed to resolve searchd host (name=%s)", m_sHost );
+ my_snprintf ( sError, sizeof(sError), "failed to resolve searchd host (name=%s)", m_sHost );
my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), sError );
return -1;
}
+#if MYSQL_VERSION_ID>=50515
+ memcpy ( &sin.sin_addr, hp->ai_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->ai_addrlen ) );
+ freeaddrinfo ( hp );
+#else
memcpy ( &sin.sin_addr, hp->h_addr, Min ( sizeof(sin.sin_addr), (size_t)hp->h_length ) );
my_gethostbyname_r_free();
+#endif
}
} else
{
@@ -534,12 +562,16 @@ CSphResponse::Read ( int iSocket, int iClientVersion )
}
/// udf
-
+#ifdef _MSC_VER
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
extern "C"
{
- my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessage );
- void sphinx_snippets_deinit ( UDF_INIT * pUDF );
- char * sphinx_snippets ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sResult, unsigned long * pLength, char * pIsNull, char * sError );
+ DLLEXPORT my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessage );
+ DLLEXPORT void sphinx_snippets_deinit ( UDF_INIT * pUDF );
+ DLLEXPORT char * sphinx_snippets ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sResult, unsigned long * pLength, char * pIsNull, char * sError );
};
#define MAX_MESSAGE_LENGTH 255
@@ -608,7 +640,7 @@ struct CSphSnippets
}
#define STRING CHECK_TYPE(STRING_RESULT)
-#define INT CHECK_TYPE(INT_RESULT); int iValue = *(long long *)pArgs->args[i]
+#define INT CHECK_TYPE(INT_RESULT); int iValue =(int) *(long long *)pArgs->args[i]
my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessage )
{
@@ -662,6 +694,7 @@ my_bool sphinx_snippets_init ( UDF_INIT * pUDF, UDF_ARGS * pArgs, char * sMessag
KEYWORD("load_files") { INT; if ( iValue ) pOpts->m_iFlags |= 128; }
KEYWORD("allow_empty") { INT; if ( iValue ) pOpts->m_iFlags |= 256; }
KEYWORD("emit_zones") { INT; if ( iValue ) pOpts->m_iFlags |= 512; }
+ KEYWORD("load_files_scattered") { INT; if ( iValue ) pOpts->m_iFlags |= 1024; }
else
{
snprintf ( sMessage, MAX_MESSAGE_LENGTH, "unrecognized argument: %.*s",
@@ -787,5 +820,5 @@ void sphinx_snippets_deinit ( UDF_INIT * pUDF )
}
//
-// $Id: snippets_udf.cc 3087 2012-01-30 23:07:35Z shodan $
+// $Id: snippets_udf.cc 3508 2012-11-05 11:48:48Z kevg $
//
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index a3e57d632a0..79a8eb9dcc6 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -688,7 +688,7 @@ btr_root_fseg_validate(
{
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
- if (UNIV_UNLIKELY(srv_pass_corrupt_table)) {
+ if (UNIV_UNLIKELY(srv_pass_corrupt_table != 0)) {
return (mach_read_from_4(seg_header + FSEG_HDR_SPACE) == space)
&& (offset >= FIL_PAGE_DATA)
&& (offset <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
@@ -723,17 +723,14 @@ btr_root_block_get(
block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
index, mtr);
- if (srv_pass_corrupt_table && !block) {
- return(0);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(0););
btr_assert_not_corrupted(block, index);
#ifdef UNIV_BTR_DEBUG
if (!dict_index_is_ibuf(index)) {
const page_t* root = buf_block_get_frame(block);
- if (UNIV_UNLIKELY(srv_pass_corrupt_table)) {
+ if (UNIV_UNLIKELY(srv_pass_corrupt_table != 0)) {
if (!btr_root_fseg_validate(FIL_PAGE_DATA
+ PAGE_BTR_SEG_LEAF
+ root, space))
@@ -1063,11 +1060,11 @@ btr_get_size(
root = btr_root_get(index, mtr);
- if (srv_pass_corrupt_table && !root) {
+ SRV_CORRUPT_TABLE_CHECK(root,
+ {
mtr_commit(mtr);
return(0);
- }
- ut_a(root);
+ });
if (flag == BTR_N_LEAF_PAGES) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
@@ -1525,11 +1522,11 @@ leaf_loop:
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
NULL, &mtr);
- if (srv_pass_corrupt_table && !root) {
+ SRV_CORRUPT_TABLE_CHECK(root,
+ {
mtr_commit(&mtr);
return;
- }
- ut_a(root);
+ });
#ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
@@ -1555,11 +1552,12 @@ top_loop:
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
NULL, &mtr);
- if (srv_pass_corrupt_table && !root) {
+ SRV_CORRUPT_TABLE_CHECK(root,
+ {
mtr_commit(&mtr);
return;
- }
- ut_a(root);
+ });
+
#ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
+ root, space));
@@ -1593,10 +1591,7 @@ btr_free_root(
block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
NULL, mtr);
- if (srv_pass_corrupt_table && !block) {
- return;
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return;);
btr_search_drop_page_hash_index(block);
@@ -4565,10 +4560,11 @@ btr_validate_index(
root = btr_root_get(index, &mtr);
- if (UNIV_UNLIKELY(srv_pass_corrupt_table && !root)) {
+ SRV_CORRUPT_TABLE_CHECK(root,
+ {
mtr_commit(&mtr);
return(FALSE);
- }
+ });
n = btr_page_get_level(root, &mtr);
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index d089fb5ad22..488212f087c 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -258,10 +258,8 @@ btr_cur_latch_leaves(
get_block = btr_block_get(
space, zip_size, page_no, mode, cursor->index, mtr);
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
#endif /* UNIV_BTR_DEBUG */
@@ -283,10 +281,8 @@ btr_cur_latch_leaves(
space, zip_size, left_page_no,
sibling_mode, cursor->index, mtr);
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame)
== page_is_comp(page));
@@ -309,10 +305,8 @@ btr_cur_latch_leaves(
space, zip_size, page_no,
mode, cursor->index, mtr);
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
#endif /* UNIV_BTR_DEBUG */
@@ -325,10 +319,8 @@ btr_cur_latch_leaves(
space, zip_size, right_page_no,
sibling_mode, cursor->index, mtr);
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame)
== page_is_comp(page));
@@ -357,10 +349,8 @@ btr_cur_latch_leaves(
left_page_no, mode, cursor->index, mtr);
cursor->left_block = get_block;
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame)
== page_is_comp(page));
@@ -373,10 +363,8 @@ btr_cur_latch_leaves(
get_block = btr_block_get(
space, zip_size, page_no, mode, cursor->index, mtr);
- if (srv_pass_corrupt_table && !get_block) {
- return;
- }
- ut_a(get_block);
+ SRV_CORRUPT_TABLE_CHECK(get_block, return;);
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
#endif /* UNIV_BTR_DEBUG */
@@ -652,18 +640,19 @@ retry_page_get:
file, line, mtr);
if (block == NULL) {
- if (srv_pass_corrupt_table
- && buf_mode != BUF_GET_IF_IN_POOL
- && buf_mode != BUF_GET_IF_IN_POOL_OR_WATCH) {
- page_cursor->block = 0;
- page_cursor->rec = 0;
- if (estimate) {
- cursor->path_arr->nth_rec = ULINT_UNDEFINED;
- }
- goto func_exit;
- }
- ut_a(buf_mode == BUF_GET_IF_IN_POOL
- || buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH);
+ SRV_CORRUPT_TABLE_CHECK(buf_mode == BUF_GET_IF_IN_POOL ||
+ buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH,
+ {
+ page_cursor->block = 0;
+ page_cursor->rec = 0;
+ if (estimate) {
+
+ cursor->path_arr->nth_rec =
+ ULINT_UNDEFINED;
+ }
+
+ goto func_exit;
+ });
/* This must be a search to perform an insert/delete
mark/ delete; try using the insert/delete buffer */
@@ -739,15 +728,18 @@ retry_page_get:
block->check_index_page_at_flush = TRUE;
page = buf_block_get_frame(block);
- if (srv_pass_corrupt_table && !page) {
+ SRV_CORRUPT_TABLE_CHECK(page,
+ {
page_cursor->block = 0;
page_cursor->rec = 0;
+
if (estimate) {
+
cursor->path_arr->nth_rec = ULINT_UNDEFINED;
}
+
goto func_exit;
- }
- ut_a(page);
+ });
if (rw_latch != RW_NO_LATCH) {
#ifdef UNIV_ZIP_DEBUG
@@ -943,15 +935,19 @@ btr_cur_open_at_index_side_func(
file, line, mtr);
page = buf_block_get_frame(block);
- if (srv_pass_corrupt_table && !page) {
+ SRV_CORRUPT_TABLE_CHECK(page,
+ {
page_cursor->block = 0;
page_cursor->rec = 0;
+
if (estimate) {
- cursor->path_arr->nth_rec = ULINT_UNDEFINED;
+
+ cursor->path_arr->nth_rec =
+ ULINT_UNDEFINED;
}
- break;
- }
- ut_a(page);
+ /* Can't use break with the macro */
+ goto exit_loop;
+ });
ut_ad(index->id == btr_page_get_index_id(page));
@@ -1021,6 +1017,7 @@ btr_cur_open_at_index_side_func(
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
}
+exit_loop:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1074,12 +1071,13 @@ btr_cur_open_at_rnd_pos_func(
file, line, mtr);
page = buf_block_get_frame(block);
- if (srv_pass_corrupt_table && !page) {
+ SRV_CORRUPT_TABLE_CHECK(page,
+ {
page_cursor->block = 0;
page_cursor->rec = 0;
- break;
- }
- ut_a(page);
+
+ goto exit_loop;
+ });
ut_ad(index->id == btr_page_get_index_id(page));
@@ -1112,6 +1110,7 @@ btr_cur_open_at_rnd_pos_func(
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
}
+exit_loop:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1300,10 +1299,7 @@ btr_cur_optimistic_insert(
block = btr_cur_get_block(cursor);
- if (srv_pass_corrupt_table && !block) {
- return(DB_CORRUPTION);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(DB_CORRUPTION););
page = buf_block_get_frame(block);
index = cursor->index;
@@ -3149,10 +3145,7 @@ btr_cur_optimistic_delete(
block = btr_cur_get_block(cursor);
- if (srv_pass_corrupt_table && !block) {
- return(DB_CORRUPTION);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(DB_CORRUPTION););
ut_ad(page_is_leaf(buf_block_get_frame(block)));
@@ -3868,10 +3861,7 @@ btr_estimate_number_of_different_key_vals(
page = btr_cur_get_page(&cursor);
- if (srv_pass_corrupt_table && !page) {
- break;
- }
- ut_a(page);
+ SRV_CORRUPT_TABLE_CHECK(page, goto exit_loop;);
rec = page_rec_get_next(page_get_infimum_rec(page));
@@ -3957,6 +3947,7 @@ btr_estimate_number_of_different_key_vals(
mtr_commit(&mtr);
}
+exit_loop:
/* If we saw k borders between different key values on
n_sample_pages leaf pages, we can estimate how many
there will be in index->stat_n_leaf_pages */
diff --git a/storage/xtradb/btr/btr0pcur.c b/storage/xtradb/btr/btr0pcur.c
index a1b7affdeb7..7c4ec2dd1ac 100644
--- a/storage/xtradb/btr/btr0pcur.c
+++ b/storage/xtradb/btr/btr0pcur.c
@@ -116,10 +116,7 @@ btr_pcur_store_position(
block = btr_pcur_get_block(cursor);
- if (srv_pass_corrupt_table && !block) {
- return;
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return;);
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
@@ -439,14 +436,16 @@ btr_pcur_move_to_next_page(
btr_pcur_get_btr_cur(cursor)->index, mtr);
next_page = buf_block_get_frame(next_block);
- if (srv_pass_corrupt_table && !next_page) {
+ SRV_CORRUPT_TABLE_CHECK(next_page,
+ {
btr_leaf_page_release(btr_pcur_get_block(cursor),
cursor->latch_mode, mtr);
btr_pcur_get_page_cur(cursor)->block = 0;
btr_pcur_get_page_cur(cursor)->rec = 0;
+
return;
- }
- ut_a(next_page);
+ });
+
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(next_page) == page_is_comp(page));
ut_a(btr_page_get_prev(next_page, mtr)
diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c
index 7e9449a6474..d53452bb959 100644
--- a/storage/xtradb/btr/btr0sea.c
+++ b/storage/xtradb/btr/btr0sea.c
@@ -649,10 +649,7 @@ btr_search_info_update_slow(
block = btr_cur_get_block(cursor);
- if (srv_pass_corrupt_table && !block) {
- return;
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return;);
/* NOTE that the following two function calls do NOT protect
info or block->n_fields etc. with any semaphore, to save CPU time!
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index 5bcfb0f51b9..ae4b2fba98d 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -2002,27 +2002,6 @@ lookup:
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
- if (UNIV_UNLIKELY(bpage->space_was_being_deleted)) {
- /* This page is obsoleted, should discard and retry */
- rw_lock_s_unlock(&buf_pool->page_hash_latch);
-
- mutex_enter(&buf_pool->LRU_list_mutex);
- block_mutex = buf_page_get_mutex_enter(bpage);
-
- if (UNIV_UNLIKELY(!block_mutex)) {
- mutex_exit(&buf_pool->LRU_list_mutex);
- goto lookup;
- }
-
- buf_LRU_free_block(bpage, TRUE, TRUE);
-
- mutex_exit(&buf_pool->LRU_list_mutex);
- mutex_exit(block_mutex);
- block_mutex = NULL;
-
- goto lookup;
- }
-
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
err_exit:
@@ -2031,11 +2010,11 @@ err_exit:
return(NULL);
}
- if (srv_pass_corrupt_table <= 1) {
- if (bpage->is_corrupt) {
- rw_lock_s_unlock(&buf_pool->page_hash_latch);
- return(NULL);
- }
+ if (UNIV_UNLIKELY(bpage->is_corrupt && srv_pass_corrupt_table <= 1)) {
+
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
+
+ return(NULL);
}
block_mutex = buf_page_get_mutex_enter(bpage);
@@ -2533,26 +2512,6 @@ loop:
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
if (block) {
- if (UNIV_UNLIKELY(block->page.space_was_being_deleted)) {
- /* This page is obsoleted, should discard and retry */
- rw_lock_s_unlock(&buf_pool->page_hash_latch);
-
- mutex_enter(&buf_pool->LRU_list_mutex);
- block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-
- if (UNIV_UNLIKELY(!block_mutex)) {
- mutex_exit(&buf_pool->LRU_list_mutex);
- goto loop;
- }
-
- buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
-
- mutex_exit(&buf_pool->LRU_list_mutex);
- mutex_exit(block_mutex);
- block_mutex = NULL;
-
- goto loop;
- }
block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
ut_a(block_mutex);
@@ -2640,11 +2599,12 @@ got_block:
return(NULL);
}
- if (srv_pass_corrupt_table <= 1) {
- if (block->page.is_corrupt) {
- mutex_exit(block_mutex);
- return(NULL);
- }
+ if (UNIV_UNLIKELY(block->page.is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
+
+ mutex_exit(block_mutex);
+
+ return(NULL);
}
switch (buf_block_get_state(block)) {
@@ -3487,28 +3447,12 @@ buf_page_init_for_read(
fold = buf_page_address_fold(space, offset);
-retry:
//buf_pool_mutex_enter(buf_pool);
mutex_enter(&buf_pool->LRU_list_mutex);
rw_lock_x_lock(&buf_pool->page_hash_latch);
watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
- if (UNIV_UNLIKELY(watch_page && watch_page->space_was_being_deleted)) {
- mutex_t* block_mutex = buf_page_get_mutex_enter(watch_page);
-
- /* This page is obsoleted, should discard and retry */
- rw_lock_x_unlock(&buf_pool->page_hash_latch);
- ut_a(block_mutex);
-
- buf_LRU_free_block(watch_page, TRUE, TRUE);
-
- mutex_exit(&buf_pool->LRU_list_mutex);
- mutex_exit(block_mutex);
-
- goto retry;
- }
-
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
/* The page is already in the buffer pool. */
watch_page = NULL;
@@ -3637,7 +3581,6 @@ err_exit:
bpage->state = BUF_BLOCK_ZIP_PAGE;
bpage->space = space;
bpage->offset = offset;
- bpage->space_was_being_deleted = FALSE;
#ifdef UNIV_DEBUG
bpage->in_page_hash = FALSE;
@@ -3722,7 +3665,6 @@ buf_page_create(
fold = buf_page_address_fold(space, offset);
-retry:
//buf_pool_mutex_enter(buf_pool);
mutex_enter(&buf_pool->LRU_list_mutex);
rw_lock_x_lock(&buf_pool->page_hash_latch);
@@ -3730,21 +3672,6 @@ retry:
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
- if (UNIV_UNLIKELY(block && block->page.space_was_being_deleted)) {
- mutex_t* block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-
- /* This page is obsoleted, should discard and retry */
- rw_lock_x_unlock(&buf_pool->page_hash_latch);
- ut_a(block_mutex);
-
- buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
-
- mutex_exit(&buf_pool->LRU_list_mutex);
- mutex_exit(block_mutex);
-
- goto retry;
- }
-
if (block
&& buf_page_in_file(&block->page)
&& !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
@@ -4001,7 +3928,8 @@ buf_page_io_complete(
(ulong) bpage->offset);
}
- if (!srv_pass_corrupt_table || !bpage->is_corrupt) {
+ if (UNIV_LIKELY(!bpage->is_corrupt ||
+ !srv_pass_corrupt_table)) {
/* From version 3.23.38 up we store the page checksum
to the 4 first bytes of the page end lsn field */
@@ -4086,13 +4014,26 @@ corrupt:
}
if (uncompressed && !recv_no_ibuf_operations) {
+
+ buf_block_t* block;
+ ibool update_ibuf_bitmap;
+
+ if (UNIV_UNLIKELY(bpage->is_corrupt &&
+ srv_pass_corrupt_table)) {
+
+ block = NULL;
+ update_ibuf_bitmap = FALSE;
+
+ } else {
+
+ block = (buf_block_t *) bpage;
+ update_ibuf_bitmap = TRUE;
+ }
+
ibuf_merge_or_delete_for_page(
- /* Delete possible entries, if bpage is_corrupt */
- (srv_pass_corrupt_table && bpage->is_corrupt) ? NULL :
- (buf_block_t*) bpage, bpage->space,
+ block, bpage->space,
bpage->offset, buf_page_get_zip_size(bpage),
- (srv_pass_corrupt_table && bpage->is_corrupt) ? FALSE :
- TRUE);
+ update_ibuf_bitmap);
}
}
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index 663e2d8f537..9452b53df38 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -459,7 +459,7 @@ buf_flush_ready_for_replace(
if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
- return((bpage->oldest_modification == 0 || bpage->space_was_being_deleted)
+ return(bpage->oldest_modification == 0
&& buf_page_get_io_fix(bpage) == BUF_IO_NONE
&& bpage->buf_fix_count == 0);
}
@@ -501,13 +501,6 @@ buf_flush_ready_for_flush(
&& buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
ut_ad(bpage->in_flush_list);
- if (bpage->space_was_being_deleted) {
- /* should be removed from flush_list here */
- /* because buf_flush_try_neighbors() cannot flush without fil_space_get_size(space) */
- buf_flush_remove(bpage);
- return(FALSE);
- }
-
if (flush_type != BUF_FLUSH_LRU) {
return(TRUE);
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index cd99d3e4e13..8a35c87c92f 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -884,42 +884,6 @@ buf_LRU_flush_or_remove_pages(
}
}
-/******************************************************************//**
-*/
-UNIV_INTERN
-void
-buf_LRU_mark_space_was_deleted(
-/*===========================*/
- ulint id) /*!< in: space id */
-{
- ulint i;
-
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
- buf_page_t* bpage;
-
- buf_pool = buf_pool_from_array(i);
-
- mutex_enter(&buf_pool->LRU_list_mutex);
-
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- while (bpage != NULL) {
- if (buf_page_get_space(bpage) == id) {
- bpage->space_was_being_deleted = TRUE;
- }
- bpage = UT_LIST_GET_NEXT(LRU, bpage);
- }
-
- mutex_exit(&buf_pool->LRU_list_mutex);
-
- /* The AHI entries for the tablespace being deleted should be
- removed by now. */
- ut_ad(buf_LRU_drop_page_hash_for_tablespace(buf_pool, id)
- == 0);
- }
-}
-
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
@@ -1891,10 +1855,6 @@ buf_LRU_free_block(
return(FALSE);
}
- if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) {
- buf_flush_remove(bpage);
- }
-
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0);
#endif /* UNIV_IBUF_COUNT_DEBUG */
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index cf0a029df92..5edbeadb64e 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -245,13 +245,7 @@ not_to_recover:
return(0);
}
- if (srv_pass_corrupt_table) {
- if (*err != DB_SUCCESS) {
- bpage->is_corrupt = TRUE;
- }
- } else {
- ut_a(*err == DB_SUCCESS);
- }
+ SRV_CORRUPT_TABLE_CHECK(*err == DB_SUCCESS, bpage->is_corrupt = TRUE;);
if (sync) {
/* The i/o is already completed when we arrive from
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 29063f028f1..817da6e6074 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -4419,7 +4419,7 @@ dict_reload_statistics(
while (index) {
mtr_t mtr;
- if (table->is_corrupt) {
+ if (UNIV_UNLIKELY(table->is_corrupt)) {
ut_a(srv_pass_corrupt_table);
mem_heap_free(heap);
return(FALSE);
@@ -4577,7 +4577,7 @@ dict_store_statistics(
heap = mem_heap_create(1000);
while (index) {
- if (table->is_corrupt) {
+ if (UNIV_UNLIKELY(table->is_corrupt)) {
ut_a(srv_pass_corrupt_table);
mem_heap_free(heap);
return;
@@ -4771,7 +4771,7 @@ dict_update_statistics(
mtr_t mtr;
ulint size;
- if (table->is_corrupt) {
+ if (UNIV_UNLIKELY(table->is_corrupt)) {
ut_a(srv_pass_corrupt_table);
dict_table_stats_unlock(table, RW_X_LATCH);
return;
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 397c4de4b6e..ff4e5b1b033 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -2426,15 +2426,11 @@ try_again:
To deal with potential read requests by checking the
::stop_new_ops flag in fil_io() */
- if (srv_lazy_drop_table) {
- buf_LRU_mark_space_was_deleted(id);
- } else {
buf_LRU_flush_or_remove_pages(
id, evict_all
? BUF_REMOVE_ALL_NO_WRITE
: BUF_REMOVE_FLUSH_NO_WRITE);
- }
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
@@ -5326,22 +5322,6 @@ _fil_io(
srv_data_written+= len;
}
- /* if the table space was already deleted, space might not exist already. */
- if (message
- && space_id < SRV_LOG_SPACE_FIRST_ID
- && ((buf_page_t*)message)->space_was_being_deleted) {
-
- if (mode == OS_AIO_NORMAL) {
- buf_page_io_complete(message);
- return(DB_SUCCESS); /*fake*/
- }
- if (type == OS_FILE_READ) {
- return(DB_TABLESPACE_DELETED);
- } else {
- return(DB_SUCCESS); /*fake*/
- }
- }
-
/* Reserve the fil_system mutex and make sure that we can open at
least one file while holding it, if the file is not already open */
@@ -5445,35 +5425,38 @@ _fil_io(
ut_a(byte_offset % OS_MIN_LOG_BLOCK_SIZE == 0);
ut_a((len % OS_MIN_LOG_BLOCK_SIZE) == 0);
- if (srv_pass_corrupt_table == 1 && space->is_corrupt) {
+#ifndef UNIV_HOTBACKUP
+ if (UNIV_UNLIKELY(space->is_corrupt && srv_pass_corrupt_table)) {
+
/* should ignore i/o for the crashed space */
- mutex_enter(&fil_system->mutex);
- fil_node_complete_io(node, fil_system, type);
- mutex_exit(&fil_system->mutex);
- if (mode == OS_AIO_NORMAL) {
- ut_a(space->purpose == FIL_TABLESPACE);
- buf_page_io_complete(message);
+ if (srv_pass_corrupt_table == 1 ||
+ type == OS_FILE_WRITE) {
+
+ mutex_enter(&fil_system->mutex);
+ fil_node_complete_io(node, fil_system, type);
+ mutex_exit(&fil_system->mutex);
+ if (mode == OS_AIO_NORMAL) {
+ ut_a(space->purpose == FIL_TABLESPACE);
+ buf_page_io_complete(message);
+ }
}
- if (type == OS_FILE_READ) {
+
+ if (srv_pass_corrupt_table == 1 && type == OS_FILE_READ) {
+
return(DB_TABLESPACE_DELETED);
- } else {
+
+ } else if (type == OS_FILE_WRITE) {
+
return(DB_SUCCESS);
}
- } else {
- if (srv_pass_corrupt_table > 1 && space->is_corrupt) {
- /* should ignore write i/o for the crashed space */
- if (type == OS_FILE_WRITE) {
- mutex_enter(&fil_system->mutex);
- fil_node_complete_io(node, fil_system, type);
- mutex_exit(&fil_system->mutex);
- if (mode == OS_AIO_NORMAL) {
- ut_a(space->purpose == FIL_TABLESPACE);
- buf_page_io_complete(message);
- }
- return(DB_SUCCESS);
- }
- }
-#ifdef UNIV_HOTBACKUP
+ } /**/
+
+ /* Queue the aio request */
+ ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
+ offset_low, offset_high, len, node, message, space_id,
+ trx);
+
+#else
/* In ibbackup do normal i/o, not aio */
if (type == OS_FILE_READ) {
ret = os_file_read(node->handle, buf, offset_low, offset_high,
@@ -5482,26 +5465,7 @@ _fil_io(
ret = os_file_write(node->name, node->handle, buf,
offset_low, offset_high, len);
}
-#else
- /* Queue the aio request */
- ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
- offset_low, offset_high, len, node, message, space_id, trx);
#endif
- } /**/
-
- /* if the table space was already deleted, space might not exist already. */
- if (message
- && space_id < SRV_LOG_SPACE_FIRST_ID
- && ((buf_page_t*)message)->space_was_being_deleted) {
-
- if (mode == OS_AIO_SYNC) {
- if (type == OS_FILE_READ) {
- return(DB_TABLESPACE_DELETED);
- } else {
- return(DB_SUCCESS); /*fake*/
- }
- }
- }
ut_a(ret);
@@ -5625,21 +5589,6 @@ fil_aio_wait(
&message, &type, &space_id);
}
- /* if the table space was already deleted, fil_node might not exist already. */
- if (message
- && space_id < SRV_LOG_SPACE_FIRST_ID
- && ((buf_page_t*)message)->space_was_being_deleted) {
-
- /* intended not to be uncompress read page */
- ut_a(buf_page_get_io_fix_unlocked(message) == BUF_IO_WRITE
- || !buf_page_get_zip_size(message)
- || buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);
-
- srv_set_io_thread_op_info(segment, "complete io for buf page");
- buf_page_io_complete(message);
- return;
- }
-
ut_a(ret);
if (UNIV_UNLIKELY(fil_node == NULL)) {
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c
index 5cbc74b0862..d5717638f29 100644
--- a/storage/xtradb/fsp/fsp0fsp.c
+++ b/storage/xtradb/fsp/fsp0fsp.c
@@ -317,10 +317,7 @@ fsp_get_space_header(
block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
- if (srv_pass_corrupt_table && !block) {
- return(0);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(0););
header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
@@ -728,10 +725,7 @@ xdes_get_descriptor(
block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
- if (srv_pass_corrupt_table && !block) {
- return(0);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(0););
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
@@ -1879,10 +1873,7 @@ fsp_seg_inode_page_find_free(
{
fseg_inode_t* inode;
- if (srv_pass_corrupt_table && !page) {
- return(ULINT_UNDEFINED);
- }
- ut_a(page);
+ SRV_CORRUPT_TABLE_CHECK(page, return(ULINT_UNDEFINED););
for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
@@ -1996,10 +1987,7 @@ fsp_alloc_seg_inode(
page = buf_block_get_frame(block);
- if (srv_pass_corrupt_table && !page) {
- return(0);
- }
- ut_a(page);
+ SRV_CORRUPT_TABLE_CHECK(page, return(0););
n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
@@ -2094,10 +2082,7 @@ fseg_inode_try_get(
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
- if (srv_pass_corrupt_table && !inode) {
- return(0);
- }
- ut_a(inode);
+ SRV_CORRUPT_TABLE_CHECK(inode, return(0););
if (UNIV_UNLIKELY(!mach_read_from_8(inode + FSEG_ID))) {
@@ -2125,7 +2110,7 @@ fseg_inode_get(
{
fseg_inode_t* inode
= fseg_inode_try_get(header, space, zip_size, mtr);
- ut_a(srv_pass_corrupt_table || inode);
+ SRV_CORRUPT_TABLE_CHECK(inode, ; /* do nothing */);
return(inode);
}
@@ -3317,12 +3302,12 @@ fseg_free_page_low(
descr = xdes_get_descriptor(space, zip_size, page, mtr);
- if (srv_pass_corrupt_table && !descr) {
+ SRV_CORRUPT_TABLE_CHECK(descr,
+ {
/* The page may be corrupt. pass it. */
return;
- }
+ });
- ut_a(descr);
if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
fputs("InnoDB: Dump of the tablespace extent descriptor: ",
stderr);
@@ -3571,15 +3556,15 @@ fseg_free_step(
descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
- if (srv_pass_corrupt_table && !descr) {
+ SRV_CORRUPT_TABLE_CHECK(descr,
+ {
/* The page may be corrupt. pass it. */
return(TRUE);
- }
+ });
/* Check that the header resides on a page which has not been
freed yet */
- ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_try_get(header, space, zip_size, mtr);
@@ -3660,11 +3645,11 @@ fseg_free_step_not_header(
inode = fseg_inode_get(header, space, zip_size, mtr);
- if (srv_pass_corrupt_table && !inode) {
+ SRV_CORRUPT_TABLE_CHECK(inode,
+ {
/* ignore the corruption */
return(TRUE);
- }
- ut_a(inode);
+ });
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index a25a3b8679f..f7507a04412 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -204,6 +204,8 @@ static ulong innobase_sys_stats_root_page = 0;
#endif
static my_bool innobase_buffer_pool_shm_checksum = TRUE;
static uint innobase_buffer_pool_shm_key = 0;
+static ulint srv_lazy_drop_table = 0;
+
static char* internal_innobase_data_file_path = NULL;
@@ -1896,7 +1898,7 @@ trx_is_started(
/*===========*/
trx_t* trx) /* in: transaction */
{
- return(trx->conc_state != TRX_NOT_STARTED);
+ return(trx->state != TRX_NOT_STARTED);
}
/*********************************************************************//**
@@ -3016,6 +3018,12 @@ innobase_change_buffering_inited_ok:
"InnoDB: innodb_buffer_pool_shm_key was ignored.\n");
}
+ if (srv_lazy_drop_table) {
+ fprintf(stderr,
+ "InnoDB: Warning: "
+ "innodb_lazy_drop_table is deprecated and ignored.\n");
+ }
+
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
@@ -4725,7 +4733,8 @@ ha_innobase::open(
DBUG_RETURN(1);
}
- if (srv_pass_corrupt_table <= 1 && share->ib_table && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
free_share(share);
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
@@ -4750,7 +4759,8 @@ retry:
/* Get pointer to a table object in InnoDB dictionary cache */
ib_table = dict_table_get(norm_name, TRUE);
- if (srv_pass_corrupt_table <= 1 && ib_table && ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(ib_table && ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
free_share(share);
my_free(upd_buf);
upd_buf = NULL;
@@ -7037,7 +7047,8 @@ ha_innobase::index_read(
ha_statistic_increment(&SSV::ha_read_key_count);
- if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -7108,7 +7119,8 @@ ha_innobase::index_read(
ret = DB_UNSUPPORTED;
}
- if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -7226,7 +7238,8 @@ ha_innobase::change_active_index(
{
DBUG_ENTER("change_active_index");
- if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -7344,7 +7357,8 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
- if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -7357,7 +7371,8 @@ ha_innobase::general_fetch(
innodb_srv_conc_exit_innodb(prebuilt->trx);
- if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
+ if (UNIV_UNLIKELY(share->ib_table->is_corrupt &&
+ srv_pass_corrupt_table <= 1)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -9390,7 +9405,7 @@ ha_innobase::info_low(
prebuilt->trx->op_info = "confirming rows of SYS_STATS to store statistics";
- ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
+ ut_a(!trx_is_started(prebuilt->trx));
for (index = dict_table_get_first_index(ib_table);
index != NULL;
@@ -9403,7 +9418,7 @@ ha_innobase::info_low(
innobase_commit_low(prebuilt->trx);
}
- ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
+ ut_a(!trx_is_started(prebuilt->trx));
}
prebuilt->trx->op_info = "updating table statistics";
@@ -13428,8 +13443,7 @@ static MYSQL_SYSVAR_ENUM(corrupt_table_action, srv_pass_corrupt_table,
static MYSQL_SYSVAR_ULINT(lazy_drop_table, srv_lazy_drop_table,
PLUGIN_VAR_RQCMDARG,
- "At deleting tablespace, only miminum needed processes at the time are done. "
- "e.g. for http://bugs.mysql.com/51325",
+ "[Deprecated option] no effect",
NULL, NULL, 0, 0, 1, 0);
static MYSQL_SYSVAR_BOOL(locking_fake_changes, srv_fake_changes_locks,
diff --git a/storage/xtradb/include/btr0btr.ic b/storage/xtradb/include/btr0btr.ic
index 53c8159c448..798107628d7 100644
--- a/storage/xtradb/include/btr0btr.ic
+++ b/storage/xtradb/include/btr0btr.ic
@@ -59,7 +59,7 @@ btr_block_get_func(
block = buf_page_get_gen(space, zip_size, page_no, mode,
NULL, BUF_GET, file, line, mtr);
- ut_a(srv_pass_corrupt_table || block);
+ SRV_CORRUPT_TABLE_CHECK(block, ; /* do nothing */);
if (block && mode != RW_NO_LATCH) {
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index e0d7a974fc3..f00a06c8805 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -1589,7 +1589,6 @@ struct buf_page_struct{
0 if the block was never accessed
in the buffer pool. Protected by
block mutex */
- ibool space_was_being_deleted;
ibool is_corrupt;
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index 8d5c3edeef8..18c46b6412e 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -430,7 +430,6 @@ buf_block_set_file_page(
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
block->page.space = space;
block->page.offset = page_no;
- block->page.space_was_being_deleted = FALSE;
}
/*********************************************************************//**
@@ -712,13 +711,7 @@ buf_block_get_frame(
/*================*/
const buf_block_t* block) /*!< in: pointer to the control block */
{
- ut_a(srv_pass_corrupt_table || block);
-
- if (srv_pass_corrupt_table && !block) {
- return(0);
- }
-
- ut_ad(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(0););
switch (buf_block_get_state(block)) {
case BUF_BLOCK_ZIP_FREE:
diff --git a/storage/xtradb/include/buf0flu.ic b/storage/xtradb/include/buf0flu.ic
index 30e2cc8efe8..8228c025d23 100644
--- a/storage/xtradb/include/buf0flu.ic
+++ b/storage/xtradb/include/buf0flu.ic
@@ -70,7 +70,7 @@ buf_flush_note_modification(
ut_ad(!buf_pool_mutex_own(buf_pool));
ut_ad(!buf_flush_list_mutex_own(buf_pool));
- ut_ad(log_flush_order_mutex_own());
+ ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
ut_ad(mtr->start_lsn != 0);
ut_ad(mtr->modifications);
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index 2ea4f9b1ecf..8bb3aed4059 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -73,13 +73,6 @@ buf_LRU_flush_or_remove_pages(
enum buf_remove_t buf_remove);/*!< in: remove or flush
strategy */
-/******************************************************************//**
-*/
-UNIV_INTERN
-void
-buf_LRU_mark_space_was_deleted(
-/*===========================*/
- ulint id); /*!< in: space id */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
diff --git a/storage/xtradb/include/fut0fut.ic b/storage/xtradb/include/fut0fut.ic
index 529f2a516d3..63e5736d99e 100644
--- a/storage/xtradb/include/fut0fut.ic
+++ b/storage/xtradb/include/fut0fut.ic
@@ -50,10 +50,7 @@ fut_get_ptr(
block = buf_page_get(space, zip_size, addr.page, rw_latch, mtr);
- if (srv_pass_corrupt_table && !block) {
- return(0);
- }
- ut_a(block);
+ SRV_CORRUPT_TABLE_CHECK(block, return(0););
ptr = buf_block_get_frame(block) + addr.boffset;
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 4f017e01dfd..59dfb457d56 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -122,14 +122,22 @@ UNIV_INLINE
void
log_free_check(void);
/*================*/
+/**************************************************************************//**
+Locks the log mutex and opens the log for log_write_low. The log must be closed
+with log_close and released with log_release.
+@return start lsn of the log record */
+UNIV_INLINE
+ib_uint64_t
+log_reserve_and_open(
+/*=================*/
+ ulint len); /*!< in: length of data to be catenated */
/************************************************************//**
-Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release.
+Opens the log for log_write_low. The log must be closed with log_close.
@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
-log_reserve_and_open(
-/*=================*/
+log_open(
+/*=====*/
ulint len); /*!< in: length of data to be catenated */
/************************************************************//**
Writes to the log the string given. It is assumed that the caller holds the
diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic
index b54697637b0..5b864f3d7d4 100644
--- a/storage/xtradb/include/log0log.ic
+++ b/storage/xtradb/include/log0log.ic
@@ -332,10 +332,10 @@ log_reserve_and_write_fast(
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
- /* The string does not fit within the current log block
- or the log block would become full */
-
- mutex_exit(&log_sys->mutex);
+ /* The string does not fit within the current log block or the
+ log block would become full. Do not release the log mutex,
+ because it has to be reacquired immediately for the "slow" write
+ procedure via log_write_low(). */
return(0);
}
@@ -382,6 +382,21 @@ log_reserve_and_write_fast(
return(log_sys->lsn);
}
+/**************************************************************************//**
+Locks the log mutex and opens the log for log_write_low. The log must be closed
+with log_close and released with log_release.
+@return start lsn of the log record */
+UNIV_INLINE
+ib_uint64_t
+log_reserve_and_open(
+/*=================*/
+ ulint len) /*!< in: length of data to be catenated */
+{
+ mutex_enter(&(log_sys->mutex));
+
+ return log_open(len);
+}
+
/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index 46f1ff9310c..c51632e0ed5 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -375,6 +375,8 @@ struct mtr_struct{
ibool modifications;
/* TRUE if the mtr made modifications to
buffer pool pages */
+ ibool made_dirty;/*!< TRUE if mtr has made at least
+ one buffer pool page dirty */
ulint n_log_recs;
/* count of how many page initial log records
have been written to the mtr log */
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index a03a0271535..7b5d268b70f 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -29,6 +29,17 @@ Created 11/26/1995 Heikki Tuuri
#endif /* !UNIV_HOTBACKUP */
#include "mach0data.h"
+/***************************************************//**
+Checks if a mini-transaction is dirtying a clean page.
+@return TRUE if the mtr is dirtying a clean page. */
+UNIV_INTERN
+ibool
+mtr_block_dirtied(
+/*==============*/
+ const buf_block_t* block) /*!< in: block being x-fixed */
+ __attribute__((nonnull,warn_unused_result));
+
+
/***************************************************************//**
Starts a mini-transaction. */
UNIV_INLINE
@@ -47,6 +58,7 @@ mtr_start(
mtr->inside_ibuf = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
+ mtr->made_dirty = FALSE;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
@@ -65,6 +77,15 @@ mtr_memo_push(
dyn_array_t* memo;
mtr_memo_slot_t* slot;
+ /* If this mtr has x-fixed a clean page then we set
+ the made_dirty flag. This tells us if we need to
+ grab log_flush_order_mutex at mtr_commit so that we
+ can insert the dirtied page to the flush list. */
+ if (type == MTR_MEMO_PAGE_X_FIX && !mtr->made_dirty) {
+ mtr->made_dirty =
+ mtr_block_dirtied((const buf_block_t *)object);
+ }
+
ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
ut_ad(type <= MTR_MEMO_X_LOCK);
diff --git a/storage/xtradb/include/read0read.h b/storage/xtradb/include/read0read.h
index 0c9468d985e..dd378ecc997 100644
--- a/storage/xtradb/include/read0read.h
+++ b/storage/xtradb/include/read0read.h
@@ -32,6 +32,7 @@ Created 2/16/1997 Heikki Tuuri
#include "ut0byte.h"
#include "ut0lst.h"
#include "trx0trx.h"
+#include "trx0sys.h"
#include "read0types.h"
/*********************************************************************//**
@@ -44,8 +45,11 @@ read_view_open_now(
/*===============*/
trx_id_t cr_trx_id, /*!< in: trx_id of creating
transaction, or 0 used in purge */
- mem_heap_t* heap); /*!< in: memory heap from which
- allocated */
+ read_view_t* view, /*!< in: current read view or NULL if it
+ doesn't exist yet */
+ ibool exclude_self); /*!< in: TRUE, if cr_trx_id should be
+ excluded from the resulting view */
+
/*********************************************************************//**
Makes a copy of the oldest existing read view, or opens a new. The view
must be closed with ..._close.
@@ -56,8 +60,8 @@ read_view_oldest_copy_or_open_new(
/*==============================*/
trx_id_t cr_trx_id, /*!< in: trx_id of creating
transaction, or 0 used in purge */
- mem_heap_t* heap); /*!< in: memory heap from which
- allocated */
+ read_view_t* view); /*!< in: pre-allocated view array or
+ NULL if a new one needs to be created */
/*********************************************************************//**
Closes a read view. */
UNIV_INTERN
@@ -66,6 +70,13 @@ read_view_close(
/*============*/
read_view_t* view); /*!< in: read view */
/*********************************************************************//**
+Frees memory allocated by a read view. */
+UNIV_INTERN
+void
+read_view_free(
+/*===========*/
+ read_view_t* view); /*< in: read view */
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
@@ -143,16 +154,20 @@ struct read_view_struct{
are strictly smaller (<) than this value.
In other words,
this is the "low water mark". */
- ulint n_trx_ids;
+ ulint n_descr;
/*!< Number of cells in the trx_ids array */
- trx_id_t* trx_ids;/*!< Additional trx ids which the read should
- not see: typically, these are the active
+ ulint max_descr;
+ /*!< Maximum number of cells in the trx_ids
+ array */
+ trx_id_t* descriptors;
+ /*!< Array of trx descriptors which the read
+ should not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
descending order. These trx_ids should be
- between the "low" and "high" water marks,
- that is, up_limit_id and low_limit_id. */
+ between the "low" and "high" water marks, that
+ is, up_limit_id and low_limit_id. */
trx_id_t creator_trx_id;
/*!< trx id of creating transaction, or
0 used in purge */
diff --git a/storage/xtradb/include/read0read.ic b/storage/xtradb/include/read0read.ic
index 5bb5249b591..ebcdb767406 100644
--- a/storage/xtradb/include/read0read.ic
+++ b/storage/xtradb/include/read0read.ic
@@ -25,6 +25,11 @@ Created 2/16/1997 Heikki Tuuri
/*********************************************************************//**
Gets the nth trx id in a read view.
+
+Upstream code stores array of trx_ids in the descending order. Percona Server
+keeps it in the ascending order for performance reasons. Let us keep the
+semantics.
+
@return trx id */
UNIV_INLINE
trx_id_t
@@ -33,13 +38,17 @@ read_view_get_nth_trx_id(
const read_view_t* view, /*!< in: read view */
ulint n) /*!< in: position */
{
- ut_ad(n < view->n_trx_ids);
+ ut_ad(n < view->n_descr);
- return(*(view->trx_ids + n));
+ return(view->descriptors[view->n_descr - 1 - n]);
}
/*********************************************************************//**
-Sets the nth trx id in a read view. */
+Sets the nth trx id in a read view.
+
+Upstream code stores array of trx_ids in the descending order. Percona Server
+keeps it in the ascending order for performance reasons. Let us keep the
+semantics. */
UNIV_INLINE
void
read_view_set_nth_trx_id(
@@ -48,9 +57,9 @@ read_view_set_nth_trx_id(
ulint n, /*!< in: position */
trx_id_t trx_id) /*!< in: trx id to set */
{
- ut_ad(n < view->n_trx_ids);
+ ut_ad(n < view->n_descr);
- *(view->trx_ids + n) = trx_id;
+ view->descriptors[view->n_descr - 1 - n] = trx_id;
}
/*********************************************************************//**
@@ -63,9 +72,6 @@ read_view_sees_trx_id(
const read_view_t* view, /*!< in: read view */
trx_id_t trx_id) /*!< in: trx id */
{
- ulint n_ids;
- ulint i;
-
if (trx_id < view->up_limit_id) {
return(TRUE);
@@ -76,21 +82,8 @@ read_view_sees_trx_id(
return(FALSE);
}
- /* We go through the trx ids in the array smallest first: this order
- may save CPU time, because if there was a very long running
- transaction in the trx id array, its trx id is looked at first, and
- the first two comparisons may well decide the visibility of trx_id. */
-
- n_ids = view->n_trx_ids;
-
- for (i = 0; i < n_ids; i++) {
- trx_id_t view_trx_id
- = read_view_get_nth_trx_id(view, n_ids - i - 1);
-
- if (trx_id <= view_trx_id) {
- return(trx_id != view_trx_id);
- }
- }
+ /* Do a binary search over this view's descriptors array */
- return(TRUE);
+ return(trx_find_descriptor(view->descriptors, view->n_descr,
+ trx_id) == NULL);
}
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 586c1e73879..53dbf21e455 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -274,9 +274,22 @@ extern ulong srv_adaptive_flushing_method;
extern ulong srv_expand_import;
extern ulong srv_pass_corrupt_table;
-extern ulint srv_dict_size_limit;
+/* Helper macro to support srv_pass_corrupt_table checks. If 'cond' is FALSE,
+execute 'code' if srv_pass_corrupt_table is non-zero, or trigger a fatal error
+otherwise. The break statement in 'code' will obviously not work as expected. */
+
+#define SRV_CORRUPT_TABLE_CHECK(cond,code) \
+ do { \
+ if (UNIV_UNLIKELY(!(cond))) { \
+ if (srv_pass_corrupt_table) { \
+ code \
+ } else { \
+ ut_error; \
+ } \
+ } \
+ } while(0)
-extern ulint srv_lazy_drop_table;
+extern ulint srv_dict_size_limit;
/*-------------------------------------------*/
extern ulint srv_n_rows_inserted;
diff --git a/storage/xtradb/include/trx0purge.h b/storage/xtradb/include/trx0purge.h
index 1e8acd65e01..1ddc9068b8e 100644
--- a/storage/xtradb/include/trx0purge.h
+++ b/storage/xtradb/include/trx0purge.h
@@ -143,6 +143,7 @@ struct trx_purge_struct{
obtaining an s-latch here. */
read_view_t* view; /*!< The purge will not remove undo logs
which are >= this view (purge view) */
+ read_view_t* prebuilt_view; /*!< Pre-built view array */
ulonglong n_pages_handled;/*!< Approximate number of undo log
pages processed in purge */
ulonglong handle_limit; /*!< Target of how many pages to get
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index cba21ae97a9..75a3b0fb4fd 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -249,6 +249,17 @@ trx_id_t
trx_sys_get_new_trx_id(void);
/*========================*/
+/*************************************************************//**
+Find a slot for a given trx ID in a descriptors array.
+@return: slot pointer */
+UNIV_INLINE
+trx_id_t*
+trx_find_descriptor(
+/*================*/
+ const trx_id_t* descriptors, /*!< in: descriptors array */
+ ulint n_descr, /*!< in: array size */
+ trx_id_t trx_id); /*!< in: trx pointer */
+
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
extern uint trx_rseg_n_slots_debug;
@@ -633,6 +644,8 @@ identifier is added to this 64-bit constant. */
| TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
/* @} */
+#define TRX_DESCR_ARRAY_INITIAL_SIZE 1000
+
#ifndef UNIV_HOTBACKUP
/** Doublewrite control struct */
struct trx_doublewrite_struct{
@@ -660,16 +673,41 @@ struct trx_sys_struct{
trx_id_t max_trx_id; /*!< The smallest number not yet
assigned as a transaction id or
transaction number */
+ char pad1[64]; /*!< Ensure max_trx_id does not share
+ cache line with other fields. */
+ trx_id_t* descriptors; /*!< Array of trx descriptors */
+ ulint descr_n_max; /*!< The current size of the descriptors
+ array. */
+ char pad2[64]; /*!< Ensure static descriptor fields
+ do not share cache lines with
+ descr_n_used */
+ ulint descr_n_used; /*!< Number of used elements in the
+ descriptors array. */
+ char pad3[64]; /*!< Ensure descriptors do not share
+ cache line with other fields */
UT_LIST_BASE_NODE_T(trx_t) trx_list;
/*!< List of active and committed in
memory transactions, sorted on trx id,
biggest first */
+ char pad4[64]; /*!< Ensure list base nodes do not
+ share cache line with other fields */
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
/*!< List of transactions created
for MySQL */
+ char pad5[64]; /*!< Ensure list base nodes do not
+ share cache line with other fields */
+ UT_LIST_BASE_NODE_T(trx_t) trx_serial_list;
+ /*!< trx->no ordered List of
+ transactions in either TRX_PREPARED or
+ TRX_ACTIVE which have already been
+ assigned a serialization number */
+ char pad6[64]; /*!< Ensure trx_serial_list does not
+ share cache line with other fields */
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
/*!< List of rollback segment
objects */
+ char pad7[64]; /*!< Ensure list base nodes do not
+ share cache line with other fields */
trx_rseg_t* latest_rseg; /*!< Latest rollback segment in the
round-robin assignment of rollback
segments to transactions */
diff --git a/storage/xtradb/include/trx0sys.ic b/storage/xtradb/include/trx0sys.ic
index af05ab2f5ed..3af98cdf98b 100644
--- a/storage/xtradb/include/trx0sys.ic
+++ b/storage/xtradb/include/trx0sys.ic
@@ -367,28 +367,11 @@ trx_is_active(
/*==========*/
trx_id_t trx_id) /*!< in: trx id of the transaction */
{
- trx_t* trx;
-
ut_ad(mutex_own(&(kernel_mutex)));
- if (trx_id < trx_list_get_min_trx_id()) {
-
- return(FALSE);
- }
-
- if (UNIV_UNLIKELY(trx_id >= trx_sys->max_trx_id)) {
-
- /* There must be corruption: we return TRUE because this
- function is only called by lock_clust_rec_some_has_impl()
- and row_vers_impl_x_locked_off_kernel() and they have
- diagnostic prints in this case */
-
- return(TRUE);
- }
-
- trx = trx_get_on_id(trx_id);
- if (trx && (trx->conc_state == TRX_ACTIVE
- || trx->conc_state == TRX_PREPARED)) {
+ if (trx_find_descriptor(trx_sys->descriptors,
+ trx_sys->descr_n_used,
+ trx_id)) {
return(TRUE);
}
@@ -425,4 +408,27 @@ trx_sys_get_new_trx_id(void)
return(id);
}
+
+/*************************************************************//**
+Find a slot for a given trx ID in a descriptors array.
+@return: slot pointer */
+UNIV_INLINE
+trx_id_t*
+trx_find_descriptor(
+/*================*/
+ const trx_id_t* descriptors, /*!< in: descriptors array */
+ ulint n_descr, /*!< in: array size */
+ trx_id_t trx_id) /*!< in: trx pointer */
+{
+ ut_ad(descriptors != trx_sys->descriptors ||
+ mutex_own(&kernel_mutex));
+
+ if (UNIV_UNLIKELY(n_descr == 0)) {
+
+ return(NULL);
+ }
+
+ return((trx_id_t *) bsearch(&trx_id, descriptors, n_descr,
+ sizeof(trx_id_t), trx_descr_cmp));
+}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index a03f7aceafa..40f441295b0 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -447,6 +447,23 @@ trx_get_que_state_str(
/*==================*/
const trx_t* trx); /*!< in: transaction */
+/*************************************************************//**
+Callback function for trx_find_descriptor() to compare trx IDs. */
+UNIV_INTERN
+int
+trx_descr_cmp(
+/*==========*/
+ const void *a, /*!< in: pointer to first comparison argument */
+ const void *b); /*!< in: pointer to second comparison argument */
+
+/*************************************************************//**
+Release a slot for a given trx in the global descriptors array. */
+UNIV_INTERN
+void
+trx_release_descriptor(
+/*===================*/
+ trx_t* trx); /*!< in: trx pointer */
+
/* Signal to a transaction */
struct trx_sig_struct{
unsigned type:3; /*!< signal type */
@@ -477,10 +494,18 @@ struct trx_struct{
const char* op_info; /*!< English text describing the
current operation, or an empty
string */
- ulint conc_state; /*!< state of the trx from the point
- of view of concurrency control:
- TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
- ... */
+ ulint state; /*!< state of the trx from the point of
+ view of concurrency control: TRX_ACTIVE,
+ TRX_COMMITTED_IN_MEMORY, ... This was
+ called 'conc_state' in the upstream and
+ has been renamed in Percona Server,
+ because changing it's value to/from
+ either TRX_ACTIVE or TRX_PREPARED
+ requires calling
+ trx_reserve_descriptor() /
+ trx_release_descriptor(). Different name
+ ensures we notice any new code changing
+ the state. */
/*------------------------------*/
/* MySQL has a transaction coordinator to coordinate two phase
commit between multiple storage engines and the binary log. When
@@ -494,6 +519,9 @@ struct trx_struct{
this is set to 1 then registered should
also be set to 1. This is used in the
XA code */
+ unsigned is_in_trx_serial_list:1;
+ /* Set when transaction is in the
+ trx_serial_list */
/*------------------------------*/
ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */
ulint check_foreigns; /* normally TRUE, but if the user
@@ -627,6 +655,9 @@ struct trx_struct{
UT_LIST_NODE_T(trx_t)
mysql_trx_list; /*!< list of transactions created for
MySQL */
+ UT_LIST_NODE_T(trx_t)
+ trx_serial_list;/*!< list node for
+ trx_sys->trx_serial_list */
/*------------------------------*/
ulint error_state; /*!< 0 if no error, otherwise error
number; NOTE That ONLY the thread
@@ -685,9 +716,6 @@ struct trx_struct{
UT_LIST_BASE_NODE_T(lock_t)
trx_locks; /*!< locks reserved by the transaction */
/*------------------------------*/
- mem_heap_t* global_read_view_heap;
- /* memory heap for the global read
- view */
read_view_t* global_read_view;
/* consistent read view associated
to a transaction or NULL */
@@ -697,6 +725,7 @@ struct trx_struct{
associated to a transaction (i.e.
same as global_read_view) or read view
associated to a cursor */
+ read_view_t* prebuilt_view; /* pre-built view array */
/*------------------------------*/
UT_LIST_BASE_NODE_T(trx_named_savept_t)
trx_savepoints; /*!< savepoints set with SAVEPOINT ...,
diff --git a/storage/xtradb/include/trx0trx.ic b/storage/xtradb/include/trx0trx.ic
index 4a1d3bcde0b..1a1fc91eac5 100644
--- a/storage/xtradb/include/trx0trx.ic
+++ b/storage/xtradb/include/trx0trx.ic
@@ -31,9 +31,9 @@ trx_start_if_not_started(
/*=====================*/
trx_t* trx) /*!< in: transaction */
{
- ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
+ ut_ad(trx->state != TRX_COMMITTED_IN_MEMORY);
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
trx_start(trx, ULINT_UNDEFINED);
}
@@ -48,9 +48,9 @@ trx_start_if_not_started_low(
/*=========================*/
trx_t* trx) /*!< in: transaction */
{
- ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
+ ut_ad(trx->state != TRX_COMMITTED_IN_MEMORY);
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
trx_start_low(trx, ULINT_UNDEFINED);
}
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 60c5cc79852..0fefdbaeb9a 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 30.1
+#define PERCONA_INNODB_VERSION 30.2
#endif
#define INNODB_VERSION_STR MYSQL_SERVER_VERSION "-" IB_TO_STR(PERCONA_INNODB_VERSION)
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index 47d082ed49f..f4c991d4fe9 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -4652,7 +4652,7 @@ lock_print_info_all_transactions(
trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
while (trx) {
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
fputs("---", file);
trx_print(file, trx, 600);
}
@@ -4820,9 +4820,9 @@ lock_table_queue_validate(
lock = UT_LIST_GET_FIRST(table->locks);
while (lock) {
- ut_a(((lock->trx)->conc_state == TRX_ACTIVE)
- || ((lock->trx)->conc_state == TRX_PREPARED)
- || ((lock->trx)->conc_state == TRX_COMMITTED_IN_MEMORY));
+ ut_a(((lock->trx)->state == TRX_ACTIVE)
+ || ((lock->trx)->state == TRX_PREPARED)
+ || ((lock->trx)->state == TRX_COMMITTED_IN_MEMORY));
if (!lock_get_wait(lock)) {
@@ -4870,7 +4870,7 @@ lock_rec_queue_validate(
lock = lock_rec_get_first(block, heap_no);
while (lock) {
- switch(lock->trx->conc_state) {
+ switch(lock->trx->state) {
case TRX_ACTIVE:
case TRX_PREPARED:
case TRX_COMMITTED_IN_MEMORY:
@@ -4957,9 +4957,9 @@ lock_rec_queue_validate(
lock = lock_rec_get_first(block, heap_no);
while (lock) {
- ut_a(lock->trx->conc_state == TRX_ACTIVE
- || lock->trx->conc_state == TRX_PREPARED
- || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY);
+ ut_a(lock->trx->state == TRX_ACTIVE
+ || lock->trx->state == TRX_PREPARED
+ || lock->trx->state == TRX_COMMITTED_IN_MEMORY);
ut_a(trx_in_trx_list(lock->trx));
if (index) {
@@ -5036,9 +5036,9 @@ loop:
}
ut_a(trx_in_trx_list(lock->trx));
- ut_a(lock->trx->conc_state == TRX_ACTIVE
- || lock->trx->conc_state == TRX_PREPARED
- || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY);
+ ut_a(lock->trx->state == TRX_ACTIVE
+ || lock->trx->state == TRX_PREPARED
+ || lock->trx->state == TRX_COMMITTED_IN_MEMORY);
# ifdef UNIV_SYNC_DEBUG
/* Only validate the record queues when this thread is not
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index e7c7a165b9c..a5243d22e8d 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -265,13 +265,12 @@ log_check_tracking_margin(
}
/************************************************************//**
-Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release.
+Opens the log for log_write_low. The log must be closed with log_close.
@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
-log_reserve_and_open(
-/*=================*/
+log_open(
+/*=====*/
ulint len) /*!< in: length of data to be catenated */
{
log_t* log = log_sys;
@@ -284,7 +283,6 @@ log_reserve_and_open(
ut_a(len < log->buf_size / 2);
loop:
- mutex_enter(&(log->mutex));
ut_ad(!recv_no_log_write);
/* Calculate an upper limit for the space the string may take in the
@@ -305,6 +303,8 @@ loop:
ut_ad(++count < 50);
+ mutex_enter(&(log->mutex));
+
goto loop;
}
@@ -318,6 +318,8 @@ loop:
os_thread_sleep(10000);
+ mutex_enter(&(log->mutex));
+
goto loop;
}
@@ -338,6 +340,8 @@ loop:
ut_ad(++count < 50);
+ mutex_enter(&(log->mutex));
+
goto loop;
}
}
@@ -494,9 +498,12 @@ log_close(void)
if (tracked_lsn_age >= log->log_group_capacity) {
- fprintf(stderr, " InnoDB: Error: the age of the "
+ fprintf(stderr, "InnoDB: Error: the age of the "
"oldest untracked record exceeds the log "
"group capacity!\n");
+ fprintf(stderr, "InnoDB: Error: stopping the log "
+ "tracking thread at LSN %llu\n", tracked_lsn);
+ srv_track_changed_pages = FALSE;
}
}
diff --git a/storage/xtradb/mtr/mtr0mtr.c b/storage/xtradb/mtr/mtr0mtr.c
index 092bd702115..9eb7b18f301 100644
--- a/storage/xtradb/mtr/mtr0mtr.c
+++ b/storage/xtradb/mtr/mtr0mtr.c
@@ -38,6 +38,25 @@ Created 11/26/1995 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
# include "log0recv.h"
+
+/***************************************************//**
+Checks if a mini-transaction is dirtying a clean page.
+@return TRUE if the mtr is dirtying a clean page. */
+UNIV_INTERN
+ibool
+mtr_block_dirtied(
+/*==============*/
+ const buf_block_t* block) /*!< in: block being x-fixed */
+{
+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
+ ut_ad(block->page.buf_fix_count > 0);
+
+ /* It is OK to read oldest_modification because no
+ other thread can be performing a write of it and it
+ is only during write that the value is reset to 0. */
+ return(block->page.oldest_modification == 0);
+}
+
/*****************************************************************//**
Releases the item in the slot given. */
static
@@ -126,7 +145,7 @@ mtr_memo_slot_note_modification(
buf_block_t* block = (buf_block_t*) slot->object;
#ifdef UNIV_DEBUG
- ut_ad(log_flush_order_mutex_own());
+ ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
#endif /* UNIV_DEBUG */
buf_flush_note_modification(block, mtr);
}
@@ -202,12 +221,14 @@ mtr_log_reserve_and_write(
Add pages to flush list and exit */
goto func_exit;
}
+ } else {
+ mutex_enter(&log_sys->mutex);
}
data_size = dyn_array_get_data_size(mlog);
/* Open the database log for log_write_low */
- mtr->start_lsn = log_reserve_and_open(data_size);
+ mtr->start_lsn = log_open(data_size);
if (mtr->log_mode == MTR_LOG_ALL) {
@@ -226,7 +247,15 @@ mtr_log_reserve_and_write(
mtr->end_lsn = log_close();
func_exit:
- log_flush_order_mutex_enter();
+
+ /* No need to acquire log_flush_order_mutex if this mtr has
+ not dirtied a clean page. log_flush_order_mutex is used to
+ ensure ordered insertions in the flush_list. We need to
+ insert in the flush_list iff the page in question was clean
+ before modifications. */
+ if (mtr->made_dirty) {
+ log_flush_order_mutex_enter();
+ }
/* It is now safe to release the log mutex because the
flush_order mutex will ensure that we are the first one
@@ -237,7 +266,9 @@ func_exit:
mtr_memo_note_modifications(mtr);
}
- log_flush_order_mutex_exit();
+ if (mtr->made_dirty) {
+ log_flush_order_mutex_exit();
+ }
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/read/read0read.c b/storage/xtradb/read/read0read.c
index f049dd21e8d..c04dae51ff5 100644
--- a/storage/xtradb/read/read0read.c
+++ b/storage/xtradb/read/read0read.c
@@ -145,14 +145,27 @@ read_view_t*
read_view_create_low(
/*=================*/
ulint n, /*!< in: number of cells in the trx_ids array */
- mem_heap_t* heap) /*!< in: memory heap from which allocated */
+ read_view_t* view) /*!< in: pre-allocated view array or NULL if a
+ new one needs to be created */
{
- read_view_t* view;
+ if (view == NULL) {
+ view = ut_malloc(sizeof(read_view_t));
+ view->max_descr = 0;
+ view->descriptors = NULL;
+ }
+
+ if (UNIV_UNLIKELY(view->max_descr < n)) {
- view = mem_heap_alloc(heap, sizeof(read_view_t));
+ /* avoid frequent re-allocations by extending the array to the
+ desired size + 10% */
+
+ view->max_descr = n + n / 10;
+ view->descriptors = ut_realloc(view->descriptors,
+ view->max_descr *
+ sizeof(trx_id_t));
+ }
- view->n_trx_ids = n;
- view->trx_ids = mem_heap_alloc(heap, n * sizeof *view->trx_ids);
+ view->n_descr = n;
return(view);
}
@@ -169,8 +182,8 @@ read_view_oldest_copy_or_open_new(
/*==============================*/
trx_id_t cr_trx_id, /*!< in: trx_id of creating
transaction, or 0 used in purge */
- mem_heap_t* heap) /*!< in: memory heap from which
- allocated */
+ read_view_t* view) /*!< in: pre-allocated view array or
+ NULL if a new one needs to be created */
{
read_view_t* old_view;
read_view_t* view_copy;
@@ -185,10 +198,10 @@ read_view_oldest_copy_or_open_new(
if (old_view == NULL) {
- return(read_view_open_now(cr_trx_id, heap));
+ return(read_view_open_now(cr_trx_id, view, TRUE));
}
- n = old_view->n_trx_ids;
+ n = old_view->n_descr;
if (old_view->creator_trx_id) {
n++;
@@ -196,7 +209,7 @@ read_view_oldest_copy_or_open_new(
needs_insert = FALSE;
}
- view_copy = read_view_create_low(n, heap);
+ view_copy = read_view_create_low(n, view);
/* Insert the id of the creator in the right place of the descending
array of ids, if needs_insert is TRUE: */
@@ -204,7 +217,7 @@ read_view_oldest_copy_or_open_new(
i = 0;
while (i < n) {
if (needs_insert
- && (i >= old_view->n_trx_ids
+ && (i >= old_view->n_descr
|| old_view->creator_trx_id
> read_view_get_nth_trx_id(old_view, i))) {
@@ -251,16 +264,17 @@ read_view_open_now(
/*===============*/
trx_id_t cr_trx_id, /*!< in: trx_id of creating
transaction, or 0 used in purge */
- mem_heap_t* heap) /*!< in: memory heap from which
- allocated */
+ read_view_t* view, /*!< in: current read view or NULL if it
+ doesn't exist yet */
+ ibool exclude_self) /*!< in: TRUE, if cr_trx_id should be
+ excluded from the resulting view */
{
- read_view_t* view;
- trx_t* trx;
- ulint n;
+ trx_id_t* descr;
+ ulint i;
ut_ad(mutex_own(&kernel_mutex));
- view = read_view_create_low(UT_LIST_GET_LEN(trx_sys->trx_list), heap);
+ view = read_view_create_low(trx_sys->descr_n_used, view);
view->creator_trx_id = cr_trx_id;
view->type = VIEW_NORMAL;
@@ -271,40 +285,58 @@ read_view_open_now(
view->low_limit_no = trx_sys->max_trx_id;
view->low_limit_id = view->low_limit_no;
- n = 0;
- trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
+ /* No active transaction should be visible */
- /* No active transaction should be visible, except cr_trx */
+ descr = trx_find_descriptor(trx_sys->descriptors,
+ trx_sys->descr_n_used,
+ cr_trx_id);
- while (trx) {
- if (trx->id != cr_trx_id
- && (trx->conc_state == TRX_ACTIVE
- || trx->conc_state == TRX_PREPARED)) {
+ if (UNIV_LIKELY(exclude_self && descr != NULL)) {
- read_view_set_nth_trx_id(view, n, trx->id);
+ ut_ad(trx_sys->descr_n_used > 0);
+ ut_ad(view->n_descr > 0);
- n++;
+ view->n_descr--;
- /* NOTE that a transaction whose trx number is <
- trx_sys->max_trx_id can still be active, if it is
- in the middle of its commit! Note that when a
- transaction starts, we initialize trx->no to
- IB_ULONGLONG_MAX. */
+ i = descr - trx_sys->descriptors;
+ } else {
+ i = trx_sys->descr_n_used;
+ }
- if (view->low_limit_no > trx->no) {
+ if (UNIV_LIKELY(i > 0)) {
- view->low_limit_no = trx->no;
- }
- }
+ /* Copy the [0; i-1] range */
+ memcpy(view->descriptors, trx_sys->descriptors,
+ i * sizeof(trx_id_t));
+ }
- trx = UT_LIST_GET_NEXT(trx_list, trx);
+ if (UNIV_UNLIKELY(i + 1 < trx_sys->descr_n_used)) {
+
+ /* Copy the [i+1; descr_n_used-1] range */
+ memcpy(view->descriptors + i,
+ trx_sys->descriptors + i + 1,
+ (trx_sys->descr_n_used - i - 1) *
+ sizeof(trx_id_t));
}
- view->n_trx_ids = n;
+ /* NOTE that a transaction whose trx number is < trx_sys->max_trx_id can
+ still be active, if it is in the middle of its commit! Note that when a
+ transaction starts, we initialize trx->no to IB_ULONGLONG_MAX. */
- if (n > 0) {
+ if (UT_LIST_GET_LEN(trx_sys->trx_serial_list) > 0) {
+
+ trx_id_t trx_no;
+
+ trx_no = UT_LIST_GET_FIRST(trx_sys->trx_serial_list)->no;
+
+ if (trx_no < view->low_limit_no) {
+ view->low_limit_no = trx_no;
+ }
+ }
+
+ if (UNIV_LIKELY(view->n_descr > 0)) {
/* The last active transaction has the smallest id: */
- view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
+ view->up_limit_id = view->descriptors[0];
} else {
view->up_limit_id = view->low_limit_id;
}
@@ -329,6 +361,23 @@ read_view_close(
}
/*********************************************************************//**
+Frees resource allocated by a read view. */
+UNIV_INTERN
+void
+read_view_free(
+/*===========*/
+ read_view_t* view) /*< in: read view */
+{
+ ut_ad(mutex_own(&kernel_mutex));
+
+ if (view->descriptors != NULL) {
+ ut_free(view->descriptors);
+ }
+
+ ut_free(view);
+}
+
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
@@ -343,8 +392,6 @@ read_view_close_for_mysql(
read_view_close(trx->global_read_view);
- mem_heap_empty(trx->global_read_view_heap);
-
trx->read_view = NULL;
trx->global_read_view = NULL;
@@ -382,7 +429,7 @@ read_view_print(
fprintf(file, "Read view individually stored trx ids:\n");
- n_ids = view->n_trx_ids;
+ n_ids = view->n_descr;
for (i = 0; i < n_ids; i++) {
fprintf(file, "Read view trx id " TRX_ID_FMT "\n",
@@ -404,8 +451,6 @@ read_cursor_view_create_for_mysql(
cursor_view_t* curview;
read_view_t* view;
mem_heap_t* heap;
- trx_t* trx;
- ulint n;
ut_a(cr_trx);
@@ -424,61 +469,14 @@ read_cursor_view_create_for_mysql(
mutex_enter(&kernel_mutex);
- curview->read_view = read_view_create_low(
- UT_LIST_GET_LEN(trx_sys->trx_list), curview->heap);
+ curview->read_view = read_view_open_now(cr_trx->id, NULL, FALSE);
+
+ mutex_exit(&kernel_mutex);
view = curview->read_view;
- view->creator_trx_id = cr_trx->id;
view->type = VIEW_HIGH_GRANULARITY;
view->undo_no = cr_trx->undo_no;
- /* No future transactions should be visible in the view */
-
- view->low_limit_no = trx_sys->max_trx_id;
- view->low_limit_id = view->low_limit_no;
-
- n = 0;
- trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
-
- /* No active transaction should be visible */
-
- while (trx) {
-
- if (trx->conc_state == TRX_ACTIVE
- || trx->conc_state == TRX_PREPARED) {
-
- read_view_set_nth_trx_id(view, n, trx->id);
-
- n++;
-
- /* NOTE that a transaction whose trx number is <
- trx_sys->max_trx_id can still be active, if it is
- in the middle of its commit! Note that when a
- transaction starts, we initialize trx->no to
- IB_ULONGLONG_MAX. */
-
- if (view->low_limit_no > trx->no) {
-
- view->low_limit_no = trx->no;
- }
- }
-
- trx = UT_LIST_GET_NEXT(trx_list, trx);
- }
-
- view->n_trx_ids = n;
-
- if (n > 0) {
- /* The last active transaction has the smallest id: */
- view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
- } else {
- view->up_limit_id = view->low_limit_id;
- }
-
- UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
-
- mutex_exit(&kernel_mutex);
-
return(curview);
}
@@ -503,6 +501,8 @@ read_cursor_view_close_for_mysql(
mutex_enter(&kernel_mutex);
read_view_close(curview->read_view);
+ read_view_free(curview->read_view);
+
trx->read_view = trx->global_read_view;
mutex_exit(&kernel_mutex);
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index fda0c55b5c7..0002f4410d6 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -1346,11 +1346,11 @@ run_again:
const rec_t* rec = btr_pcur_get_rec(&pcur);
const buf_block_t* block = btr_pcur_get_block(&pcur);
- if (srv_pass_corrupt_table && !block) {
+ SRV_CORRUPT_TABLE_CHECK(block,
+ {
err = DB_CORRUPTION;
- break;
- }
- ut_a(block);
+ goto exit_loop;
+ });
if (page_rec_is_infimum(rec)) {
@@ -1474,6 +1474,7 @@ run_again:
}
} while (btr_pcur_move_to_next(&pcur, &mtr));
+exit_loop:
if (check_ref) {
row_ins_foreign_report_add_err(
trx, foreign, btr_pcur_get_rec(&pcur), entry);
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index 0b6a6302854..40e7d99b839 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -1298,11 +1298,11 @@ row_merge_read_clustered_index(
if (UNIV_LIKELY(has_next)) {
rec = btr_pcur_get_rec(&pcur);
- if (srv_pass_corrupt_table && !rec) {
+ SRV_CORRUPT_TABLE_CHECK(rec,
+ {
err = DB_CORRUPTION;
goto err_exit;
- }
- ut_a(rec);
+ });
offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &row_heap);
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index 858d50fd5a6..dec192585ce 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -3952,9 +3952,9 @@ release_search_latch_if_needed:
trx->has_search_latch = FALSE;
}
- ut_ad(prebuilt->sql_stat_start || trx->conc_state == TRX_ACTIVE);
- ut_ad(trx->conc_state == TRX_NOT_STARTED
- || trx->conc_state == TRX_ACTIVE);
+ ut_ad(prebuilt->sql_stat_start || trx->state == TRX_ACTIVE);
+ ut_ad(trx->state == TRX_NOT_STARTED
+ || trx->state == TRX_ACTIVE);
ut_ad(prebuilt->sql_stat_start
|| prebuilt->select_lock_type != LOCK_NONE
|| trx->read_view);
@@ -4137,11 +4137,11 @@ rec_loop:
rec = btr_pcur_get_rec(pcur);
- if (srv_pass_corrupt_table && !rec) {
+ SRV_CORRUPT_TABLE_CHECK(rec,
+ {
err = DB_CORRUPTION;
goto lock_wait_or_error;
- }
- ut_a(rec);
+ });
ut_ad(!!page_rec_is_comp(rec) == comp);
#ifdef UNIV_SEARCH_DEBUG
@@ -4278,8 +4278,9 @@ wrong_offs:
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
- if (UNIV_UNLIKELY(srv_force_recovery > 0)
- || (srv_pass_corrupt_table == 2 && index->table->is_corrupt)) {
+ if (UNIV_UNLIKELY(srv_force_recovery > 0
+ || (index->table->is_corrupt &&
+ srv_pass_corrupt_table == 2))) {
if (!rec_validate(rec, offsets)
|| !btr_index_rec_validate(rec, index, FALSE)) {
fprintf(stderr,
@@ -5092,8 +5093,10 @@ row_search_check_if_query_cache_permitted(
if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
&& !trx->read_view) {
- trx->read_view = read_view_open_now(
- trx->id, trx->global_read_view_heap);
+ trx->read_view =
+ read_view_open_now(trx->id,
+ NULL, TRUE);
+
trx->global_read_view = trx->read_view;
}
}
diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c
index 6d83dbaf8ee..3fd13b829a2 100644
--- a/storage/xtradb/row/row0vers.c
+++ b/storage/xtradb/row/row0vers.c
@@ -667,9 +667,9 @@ row_vers_build_for_semi_consistent_read(
mutex_enter(&kernel_mutex);
version_trx = trx_get_on_id(version_trx_id);
- if (version_trx
- && (version_trx->conc_state == TRX_COMMITTED_IN_MEMORY
- || version_trx->conc_state == TRX_NOT_STARTED)) {
+ if (version_trx &&
+ (version_trx->state == TRX_COMMITTED_IN_MEMORY
+ || version_trx->state == TRX_NOT_STARTED)) {
version_trx = NULL;
}
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 6edfbaa7755..3119c870d2c 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -434,8 +434,6 @@ UNIV_INTERN ulong srv_expand_import = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
UNIV_INTERN ulint srv_dict_size_limit = 0;
-
-UNIV_INTERN ulint srv_lazy_drop_table = 0;
/*-------------------------------------------*/
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
@@ -2932,7 +2930,7 @@ rescan_idle:
mutex_enter(&kernel_mutex);
trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
while (trx) {
- if (trx->conc_state == TRX_ACTIVE
+ if (trx->state == TRX_ACTIVE
&& trx->mysql_thd
&& innobase_thd_is_idle(trx->mysql_thd)) {
ib_int64_t start_time = innobase_thd_get_start_time(trx->mysql_thd);
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index b048dc66efe..1e119c6828b 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -263,8 +263,9 @@ trx_purge_sys_create(
purge_sys->query = trx_purge_graph_build();
- purge_sys->view = read_view_oldest_copy_or_open_new(0,
- purge_sys->heap);
+ purge_sys->prebuilt_view =
+ read_view_oldest_copy_or_open_new(0, NULL);
+ purge_sys->view = purge_sys->prebuilt_view;
}
/************************************************************************
@@ -279,7 +280,12 @@ trx_purge_sys_close(void)
que_graph_free(purge_sys->query);
ut_a(purge_sys->sess->trx->is_purge);
- purge_sys->sess->trx->conc_state = TRX_NOT_STARTED;
+ purge_sys->sess->trx->state = TRX_NOT_STARTED;
+
+ mutex_enter(&kernel_mutex);
+ trx_release_descriptor(purge_sys->sess->trx);
+ mutex_exit(&kernel_mutex);
+
sess_close(purge_sys->sess);
purge_sys->sess = NULL;
@@ -289,6 +295,8 @@ trx_purge_sys_close(void)
mutex_enter(&kernel_mutex);
read_view_close(purge_sys->view);
+ read_view_free(purge_sys->prebuilt_view);
+ purge_sys->prebuilt_view = NULL;
purge_sys->view = NULL;
mutex_exit(&kernel_mutex);
@@ -1177,7 +1185,7 @@ trx_purge(
}
purge_sys->view = read_view_oldest_copy_or_open_new(
- 0, purge_sys->heap);
+ 0, purge_sys->prebuilt_view);
mutex_exit(&kernel_mutex);
diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c
index b55471959ce..ae42623a1d9 100644
--- a/storage/xtradb/trx/trx0roll.c
+++ b/storage/xtradb/trx/trx0roll.c
@@ -132,7 +132,7 @@ trx_rollback_for_mysql(
{
int err;
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
return(DB_SUCCESS);
}
@@ -161,7 +161,7 @@ trx_rollback_last_sql_stat_for_mysql(
{
int err;
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
return(DB_SUCCESS);
}
@@ -263,7 +263,7 @@ trx_rollback_to_savepoint_for_mysql(
return(DB_NO_SAVEPOINT);
}
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: transaction has a savepoint ", stderr);
ut_print_name(stderr, trx, FALSE, savep->name);
@@ -560,7 +560,7 @@ loop:
continue;
}
- switch (trx->conc_state) {
+ switch (trx->state) {
case TRX_NOT_STARTED:
case TRX_PREPARED:
continue;
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index c40bf02a7a2..2c44cee60fe 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -1319,6 +1319,12 @@ trx_sys_init_at_db_start(void)
trx_sys = mem_zalloc(sizeof(*trx_sys));
+ /* Allocate the trx descriptors array */
+ trx_sys->descriptors = ut_malloc(sizeof(trx_id_t) *
+ TRX_DESCR_ARRAY_INITIAL_SIZE);
+ trx_sys->descr_n_max = TRX_DESCR_ARRAY_INITIAL_SIZE;
+ trx_sys->descr_n_used = 0;
+
sys_header = trx_sysf_get(&mtr);
trx_rseg_list_and_array_init(sys_header, ib_bh, &mtr);
@@ -1346,7 +1352,7 @@ trx_sys_init_at_db_start(void)
for (;;) {
- if (trx->conc_state != TRX_PREPARED) {
+ if (trx->state != TRX_PREPARED) {
rows_to_undo += trx->undo_no;
}
@@ -2028,6 +2034,9 @@ trx_sys_close(void)
ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
+ ut_ad(trx_sys->descr_n_used == 0);
+ ut_free(trx_sys->descriptors);
+
mem_free(trx_sys);
trx_sys = NULL;
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index a17f8abdad0..a2a41ef006f 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -85,6 +85,126 @@ trx_set_detailed_error_from_file(
sizeof(trx->detailed_error));
}
+/*************************************************************//**
+Callback function for trx_find_descriptor() to compare trx IDs. */
+UNIV_INTERN
+int
+trx_descr_cmp(
+/*==========*/
+ const void *a, /*!< in: pointer to first comparison argument */
+ const void *b) /*!< in: pointer to second comparison argument */
+{
+ const trx_id_t* da = (const trx_id_t*) a;
+ const trx_id_t* db = (const trx_id_t*) b;
+
+ if (*da < *db) {
+ return -1;
+ } else if (*da > *db) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*************************************************************//**
+Reserve a slot for a given trx in the global descriptors array. */
+UNIV_INLINE
+void
+trx_reserve_descriptor(
+/*===================*/
+ const trx_t* trx) /*!< in: trx pointer */
+{
+ ulint n_used;
+ ulint n_max;
+ trx_id_t* descr;
+
+ ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!trx_find_descriptor(trx_sys->descriptors,
+ trx_sys->descr_n_used,
+ trx->id));
+
+ n_used = trx_sys->descr_n_used + 1;
+ n_max = trx_sys->descr_n_max;
+
+ if (UNIV_UNLIKELY(n_used > n_max)) {
+
+ n_max = n_max * 2;
+
+ trx_sys->descriptors =
+ ut_realloc(trx_sys->descriptors,
+ n_max * sizeof(trx_id_t));
+
+ trx_sys->descr_n_max = n_max;
+ }
+
+ descr = trx_sys->descriptors + n_used - 1;
+
+ if (UNIV_UNLIKELY(n_used > 1 && trx->id < descr[-1])) {
+
+ /* Find the slot where it should be inserted. We could use a
+ binary search, but in reality linear search should be faster,
+ because the slot we are looking for is near the array end. */
+
+ trx_id_t* tdescr;
+
+ for (tdescr = descr - 1;
+ tdescr >= trx_sys->descriptors && *tdescr > trx->id;
+ tdescr--) {
+ }
+
+ tdescr++;
+
+ ut_memmove(tdescr + 1, tdescr, (descr - tdescr) *
+ sizeof(trx_id_t));
+
+ descr = tdescr;
+ }
+
+ *descr = trx->id;
+
+ trx_sys->descr_n_used = n_used;
+}
+
+/*************************************************************//**
+Release a slot for a given trx in the global descriptors array. */
+UNIV_INTERN
+void
+trx_release_descriptor(
+/*===================*/
+ trx_t* trx) /*!< in: trx pointer */
+{
+ ulint size;
+ trx_id_t* descr;
+
+ ut_ad(mutex_own(&kernel_mutex));
+
+ if (UNIV_LIKELY(trx->is_in_trx_serial_list)) {
+
+ UT_LIST_REMOVE(trx_serial_list, trx_sys->trx_serial_list,
+ trx);
+ trx->is_in_trx_serial_list = 0;
+ }
+
+ descr = trx_find_descriptor(trx_sys->descriptors,
+ trx_sys->descr_n_used,
+ trx->id);
+
+ if (UNIV_UNLIKELY(descr == NULL)) {
+
+ return;
+ }
+
+ size = (trx_sys->descriptors + trx_sys->descr_n_used - 1 - descr) *
+ sizeof(trx_id_t);
+
+ if (UNIV_LIKELY(size > 0)) {
+
+ ut_memmove(descr, descr + 1, size);
+ }
+
+ trx_sys->descr_n_used--;
+}
+
/****************************************************************//**
Creates and initializes a transaction object.
@return own: the transaction */
@@ -107,7 +227,7 @@ trx_create(
trx->is_purge = 0;
trx->is_recovered = 0;
- trx->conc_state = TRX_NOT_STARTED;
+ trx->state = TRX_NOT_STARTED;
trx->is_registered = 0;
trx->active_commit_ordered = 0;
@@ -118,6 +238,7 @@ trx_create(
trx->id = 0;
trx->no = IB_ULONGLONG_MAX;
+ trx->is_in_trx_serial_list = 0;
trx->support_xa = TRUE;
@@ -189,9 +310,9 @@ trx_create(
trx->declared_to_be_inside_innodb = FALSE;
trx->n_tickets_to_enter_innodb = 0;
- trx->global_read_view_heap = mem_heap_create(256);
trx->global_read_view = NULL;
trx->read_view = NULL;
+ trx->prebuilt_view = NULL;
trx->io_reads = 0;
trx->io_read = 0;
@@ -327,7 +448,7 @@ trx_free(
trx->magic_n = 11112222;
- ut_a(trx->conc_state == TRX_NOT_STARTED);
+ ut_a(trx->state == TRX_NOT_STARTED);
mutex_free(&(trx->undo_mutex));
@@ -354,18 +475,18 @@ trx_free(
ut_a(UT_LIST_GET_LEN(trx->trx_locks) == 0);
- if (trx->global_read_view_heap) {
- mem_heap_free(trx->global_read_view_heap);
+ if (trx->prebuilt_view != NULL) {
+ read_view_free(trx->prebuilt_view);
}
- trx->global_read_view = NULL;
-
ut_a(trx->read_view == NULL);
ut_a(ib_vector_is_empty(trx->autoinc_locks));
/* We allocated a dedicated heap for the vector. */
ib_vector_free(trx->autoinc_locks);
+ trx_release_descriptor(trx);
+
mem_free(trx);
}
@@ -378,7 +499,7 @@ trx_free_prepared(
trx_t* trx) /*!< in, own: trx object */
{
ut_ad(mutex_own(&kernel_mutex));
- ut_a(trx->conc_state == TRX_PREPARED);
+ ut_a(trx->state == TRX_PREPARED);
ut_a(trx->magic_n == TRX_MAGIC_N);
/* Prepared transactions are sort of active; they allow
@@ -411,15 +532,19 @@ trx_free_prepared(
mem_heap_free(trx->lock_heap);
}
- if (trx->global_read_view_heap) {
- mem_heap_free(trx->global_read_view_heap);
- }
-
ut_a(ib_vector_is_empty(trx->autoinc_locks));
ib_vector_free(trx->autoinc_locks);
+ trx_release_descriptor(trx);
+
+ if (trx->prebuilt_view != NULL) {
+ read_view_free(trx->prebuilt_view);
+ }
+
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
+ ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
+
mem_free(trx);
}
@@ -528,6 +653,7 @@ trx_lists_init_at_db_start(void)
ut_ad(mutex_own(&kernel_mutex));
UT_LIST_INIT(trx_sys->trx_list);
+ UT_LIST_INIT(trx_sys->trx_serial_list);
/* Look from the rollback segments if there exist undo logs for
transactions */
@@ -564,7 +690,7 @@ trx_lists_init_at_db_start(void)
if (srv_force_recovery == 0) {
- trx->conc_state = TRX_PREPARED;
+ trx->state = TRX_PREPARED;
trx_n_prepared++;
} else {
fprintf(stderr,
@@ -574,11 +700,12 @@ trx_lists_init_at_db_start(void)
" rollback it"
" anyway.\n");
- trx->conc_state = TRX_ACTIVE;
+ trx->state = TRX_ACTIVE;
}
+
+ trx_reserve_descriptor(trx);
} else {
- trx->conc_state
- = TRX_COMMITTED_IN_MEMORY;
+ trx->state = TRX_COMMITTED_IN_MEMORY;
}
/* We give a dummy value for the trx no;
@@ -590,12 +717,15 @@ trx_lists_init_at_db_start(void)
trx->no = trx->id;
} else {
- trx->conc_state = TRX_ACTIVE;
+ trx->state = TRX_ACTIVE;
/* A running transaction always has the number
field inited to IB_ULONGLONG_MAX */
trx->no = IB_ULONGLONG_MAX;
+
+ trx_reserve_descriptor(trx);
+
}
if (undo->dict_operation) {
@@ -640,7 +770,7 @@ trx_lists_init_at_db_start(void)
if (srv_force_recovery == 0) {
- trx->conc_state
+ trx->state
= TRX_PREPARED;
trx_n_prepared++;
} else {
@@ -651,11 +781,12 @@ trx_lists_init_at_db_start(void)
" rollback it"
" anyway.\n");
- trx->conc_state
- = TRX_ACTIVE;
+ trx->state = TRX_ACTIVE;
+ trx_reserve_descriptor(
+ trx);
}
} else {
- trx->conc_state
+ trx->state
= TRX_COMMITTED_IN_MEMORY;
}
@@ -664,13 +795,14 @@ trx_lists_init_at_db_start(void)
trx->no = trx->id;
} else {
- trx->conc_state = TRX_ACTIVE;
-
+ trx->state = TRX_ACTIVE;
/* A running transaction always has
the number field inited to
IB_ULONGLONG_MAX */
trx->no = IB_ULONGLONG_MAX;
+
+ trx_reserve_descriptor(trx);
}
trx->rseg = rseg;
@@ -741,13 +873,15 @@ trx_start_low(
if (trx->is_purge) {
trx->id = 0;
- trx->conc_state = TRX_ACTIVE;
+ /* Don't reserve a descriptor, since this trx is not added to
+ trx_list. */
+ trx->state = TRX_ACTIVE;
trx->start_time = time(NULL);
return(TRUE);
}
- ut_ad(trx->conc_state != TRX_ACTIVE);
+ ut_ad(trx->state != TRX_ACTIVE);
ut_a(rseg_id == ULINT_UNDEFINED);
@@ -762,7 +896,10 @@ trx_start_low(
trx->rseg = rseg;
- trx->conc_state = TRX_ACTIVE;
+ trx->state = TRX_ACTIVE;
+
+ trx_reserve_descriptor(trx);
+
trx->start_time = time(NULL);
UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx);
@@ -819,6 +956,14 @@ trx_serialisation_number_get(
trx->no = trx_sys_get_new_trx_id();
+ if (UNIV_LIKELY(trx->is_in_trx_serial_list == 0)) {
+
+ UT_LIST_ADD_LAST(trx_serial_list, trx_sys->trx_serial_list,
+ trx);
+
+ trx->is_in_trx_serial_list = 1;
+ }
+
/* If the rollack segment is not empty then the
new trx_t::no can't be less than any trx_t::no
already in the rollback segment. User threads only
@@ -1000,10 +1145,10 @@ trx_commit_off_kernel(
lsn = 0;
}
- ut_ad(trx->conc_state == TRX_ACTIVE || trx->conc_state == TRX_PREPARED);
+ ut_ad(trx->state == TRX_ACTIVE || trx->state == TRX_PREPARED);
ut_ad(mutex_own(&kernel_mutex));
- if (UNIV_UNLIKELY(trx->conc_state == TRX_PREPARED)) {
+ if (UNIV_UNLIKELY(trx->state == TRX_PREPARED)) {
ut_a(trx_n_prepared > 0);
trx_n_prepared--;
}
@@ -1023,7 +1168,9 @@ trx_commit_off_kernel(
committed. */
/*--------------------------------------*/
- trx->conc_state = TRX_COMMITTED_IN_MEMORY;
+ trx->state = TRX_COMMITTED_IN_MEMORY;
+ /* The following also removes trx from trx_serial_list */
+ trx_release_descriptor(trx);
/*--------------------------------------*/
/* If we release kernel_mutex below and we are still doing
@@ -1044,7 +1191,6 @@ trx_commit_off_kernel(
if (trx->global_read_view) {
read_view_close(trx->global_read_view);
- mem_heap_empty(trx->global_read_view_heap);
trx->global_read_view = NULL;
}
@@ -1131,7 +1277,7 @@ trx_commit_off_kernel(
/* Free all savepoints */
trx_roll_free_all_savepoints(trx);
- trx->conc_state = TRX_NOT_STARTED;
+ trx->state = TRX_NOT_STARTED;
trx->rseg = NULL;
trx->undo_no = 0;
trx->last_sql_stat_start.least_undo_no = 0;
@@ -1141,6 +1287,8 @@ trx_commit_off_kernel(
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
+ ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
+
trx->error_state = DB_SUCCESS;
}
@@ -1159,12 +1307,15 @@ trx_cleanup_at_db_startup(
trx_undo_insert_cleanup(trx);
}
- trx->conc_state = TRX_NOT_STARTED;
+ trx->state = TRX_NOT_STARTED;
+ trx_release_descriptor(trx);
trx->rseg = NULL;
trx->undo_no = 0;
trx->last_sql_stat_start.least_undo_no = 0;
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
+
+ ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
}
/********************************************************************//**
@@ -1178,7 +1329,7 @@ trx_assign_read_view(
/*=================*/
trx_t* trx) /*!< in: active transaction */
{
- ut_ad(trx->conc_state == TRX_ACTIVE);
+ ut_ad(trx->state == TRX_ACTIVE);
if (trx->read_view) {
return(trx->read_view);
@@ -1186,11 +1337,9 @@ trx_assign_read_view(
mutex_enter(&kernel_mutex);
- if (!trx->read_view) {
- trx->read_view = read_view_open_now(
- trx->id, trx->global_read_view_heap);
- trx->global_read_view = trx->read_view;
- }
+ trx->read_view = read_view_open_now(trx->id, trx->prebuilt_view, TRUE);
+ trx->prebuilt_view = trx->read_view;
+ trx->global_read_view = trx->read_view;
mutex_exit(&kernel_mutex);
@@ -1555,7 +1704,7 @@ loop:
return;
}
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
trx_start_low(trx, ULINT_UNDEFINED);
}
@@ -1851,7 +2000,7 @@ trx_mark_sql_stat_end(
{
ut_a(trx);
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->state == TRX_NOT_STARTED) {
trx->undo_no = 0;
}
@@ -1874,7 +2023,7 @@ trx_print(
fprintf(f, "TRANSACTION " TRX_ID_FMT, (ullint) trx->id);
- switch (trx->conc_state) {
+ switch (trx->state) {
case TRX_NOT_STARTED:
fputs(", not started", f);
break;
@@ -1890,7 +2039,7 @@ trx_print(
fputs(", COMMITTED IN MEMORY", f);
break;
default:
- fprintf(f, " state %lu", (ulong) trx->conc_state);
+ fprintf(f, " state %lu", (ulong) trx->state);
}
if (*trx->op_info) {
@@ -2085,7 +2234,11 @@ trx_prepare_off_kernel(
ut_ad(mutex_own(&kernel_mutex));
/*--------------------------------------*/
- trx->conc_state = TRX_PREPARED;
+ if (UNIV_UNLIKELY(trx->state != TRX_ACTIVE)) {
+
+ trx_reserve_descriptor(trx);
+ }
+ trx->state = TRX_PREPARED;
trx_n_prepared++;
/*--------------------------------------*/
@@ -2199,7 +2352,7 @@ trx_recover_for_mysql(
trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
while (trx) {
- if (trx->conc_state == TRX_PREPARED) {
+ if (trx->state == TRX_PREPARED) {
xid_list[count] = trx->xid;
if (count == 0) {
@@ -2272,7 +2425,7 @@ trx_get_trx_by_xid(
the same */
if (trx->is_recovered
- && trx->conc_state == TRX_PREPARED
+ && trx->state == TRX_PREPARED
&& xid->gtrid_length == trx->xid.gtrid_length
&& xid->bqual_length == trx->xid.bqual_length
&& memcmp(xid->data, trx->xid.data,