summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-09-05 13:14:37 +0200
committerSergei Golubchik <sergii@pisem.net>2012-09-05 13:14:37 +0200
commit6af914f8b94b98a5aa648f69383398741dcd9754 (patch)
tree899fb248b22fe3cf16cc940a80f867110d8f4ce7 /storage
parent1f92707978d411a051b2bfa46ed361f60861ff73 (diff)
parent0352f09a2e3e17470ab75678265b98a275cb25a0 (diff)
downloadmariadb-git-6af914f8b94b98a5aa648f69383398741dcd9754.tar.gz
XtraDB from Percona-Server-5.5.27-rel28.1
Diffstat (limited to 'storage')
-rw-r--r--storage/xtradb/btr/btr0btr.c4
-rw-r--r--storage/xtradb/buf/buf0buf.c11
-rw-r--r--storage/xtradb/buf/buf0lru.c51
-rw-r--r--storage/xtradb/buf/buf0rea.c47
-rw-r--r--storage/xtradb/dict/dict0dict.c42
-rw-r--r--storage/xtradb/dict/dict0mem.c4
-rw-r--r--storage/xtradb/fil/fil0fil.c2
-rw-r--r--storage/xtradb/ha/ha0ha.c16
-rw-r--r--storage/xtradb/handler/ha_innodb.cc51
-rw-r--r--storage/xtradb/handler/handler0alter.cc18
-rw-r--r--storage/xtradb/handler/i_s.cc290
-rw-r--r--storage/xtradb/handler/i_s.h2
-rw-r--r--storage/xtradb/include/btr0btr.h3
-rw-r--r--storage/xtradb/include/btr0types.h4
-rw-r--r--storage/xtradb/include/buf0buf.h21
-rw-r--r--storage/xtradb/include/buf0buf.ic2
-rw-r--r--storage/xtradb/include/dict0dict.h5
-rw-r--r--storage/xtradb/include/dict0dict.ic2
-rw-r--r--storage/xtradb/include/ha_prototypes.h11
-rw-r--r--storage/xtradb/include/log0log.h2
-rw-r--r--storage/xtradb/include/os0file.h2
-rw-r--r--storage/xtradb/include/srv0srv.h2
-rw-r--r--storage/xtradb/include/trx0sys.h4
-rw-r--r--storage/xtradb/include/univ.i2
-rw-r--r--storage/xtradb/mem/mem0dbg.c4
-rw-r--r--storage/xtradb/os/os0file.c2
-rw-r--r--storage/xtradb/page/page0zip.c2
-rw-r--r--storage/xtradb/row/row0ins.c6
-rw-r--r--storage/xtradb/row/row0merge.c188
-rw-r--r--storage/xtradb/row/row0vers.c11
-rw-r--r--storage/xtradb/trx/trx0sys.c2
-rw-r--r--storage/xtradb/ut/ut0dbg.c6
-rw-r--r--storage/xtradb/ut/ut0ut.c8
33 files changed, 661 insertions, 166 deletions
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index d4a0ef5ec60..3f11684cb34 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -42,6 +42,7 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "trx0trx.h"
+#endif /* UNIV_HOTBACKUP */
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -64,6 +65,7 @@ btr_corruption_report(
buf_page_print(buf_block_get_frame_fast(block), 0, 0);
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "srv0srv.h"
# include "ut0rbt.h"
@@ -1622,7 +1624,9 @@ btr_page_reorganize_low(
dict_index_t* index, /*!< in: record descriptor */
mtr_t* mtr) /*!< in: mtr */
{
+#ifndef UNIV_HOTBACKUP
buf_pool_t* buf_pool = buf_pool_from_bpage(&block->page);
+#endif /* !UNIV_HOTBACKUP */
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
buf_block_t* temp_block;
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index fd7b8959473..a2ff171e0c5 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -344,7 +344,6 @@ be effective only if PFS_GROUP_BUFFER_SYNC is defined. */
// was allocated for the frames */
// buf_block_t* blocks; /*!< array of buffer control blocks */
//};
-#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
@@ -482,6 +481,7 @@ buf_block_alloc(
return(block);
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
@@ -3907,9 +3907,10 @@ buf_mark_space_corrupt(
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage) /*!< in: pointer to the block in question */
@@ -4057,7 +4058,7 @@ corrupt:
table as corrupted instead of crashing server */
if (bpage->space > TRX_SYS_SPACE
&& buf_mark_space_corrupt(bpage)) {
- return;
+ return(FALSE);
} else {
fputs("InnoDB: Ending processing"
" because of"
@@ -4176,6 +4177,8 @@ retry_mutex:
buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
+
+ return(TRUE);
}
/********************************************************************//**
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index f7b5db2d0cc..16a91358080 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -374,7 +374,7 @@ next_page:
/******************************************************************//**
While flushing (or removing dirty) pages from a tablespace we don't
-want to hog the CPU and resources. Release the buffer pool and block
+want to hog the CPU and resources. Release the LRU list and block
mutex and try to force a context switch. Then reacquire the same mutexes.
The current page is "fixed" before the release of the mutexes and then
"unfixed" again once we have reacquired the mutexes. */
@@ -387,7 +387,7 @@ buf_flush_yield(
{
mutex_t* block_mutex;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(buf_page_in_file(bpage));
block_mutex = buf_page_get_mutex(bpage);
@@ -399,13 +399,13 @@ buf_flush_yield(
buf_page_set_sticky(bpage);
/* Now it is safe to release the buf_pool->mutex. */
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(block_mutex);
/* Try and force a context switch. */
os_thread_yield();
- buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
mutex_enter(block_mutex);
/* "Unfix" the block now that we have both the
@@ -415,9 +415,9 @@ buf_flush_yield(
}
/******************************************************************//**
-If we have hogged the resources for too long then release the buffer
-pool and flush list mutex and do a thread yield. Set the current page
-to "sticky" so that it is not relocated during the yield.
+If we have hogged the resources for too long then release the LRU list
+and flush list mutex and do a thread yield. Set the current page to
+"sticky" so that it is not relocated during the yield.
@return TRUE if yielded */
static
ibool
@@ -439,7 +439,7 @@ buf_flush_try_yield(
buf_flush_list_mutex_exit(buf_pool);
- /* Release the buffer pool and block mutex
+ /* Release the LRU list and block mutex
to give the other threads a go. */
buf_flush_yield(buf_pool, bpage);
@@ -472,7 +472,7 @@ buf_flush_or_remove_page(
mutex_t* block_mutex;
ibool processed = FALSE;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(buf_flush_list_mutex_own(buf_pool));
block_mutex = buf_page_get_mutex(bpage);
@@ -595,11 +595,11 @@ buf_flush_dirty_pages(
ibool all_freed;
do {
- buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
all_freed = buf_flush_or_remove_pages(buf_pool, id);
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
ut_ad(buf_flush_validate(buf_pool));
@@ -659,8 +659,16 @@ scan_again:
goto next_page;
} else {
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
+ block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ /* It may be impossible case...
+ Something wrong, so will be scan_again */
+
+ all_freed = FALSE;
+ goto next_page;
+ }
+
if (bpage->buf_fix_count > 0) {
@@ -694,7 +702,8 @@ scan_again:
ulint page_no;
ulint zip_size;
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
zip_size = buf_page_get_zip_size(bpage);
page_no = buf_page_get_page_no(bpage);
@@ -2370,9 +2379,23 @@ buf_LRU_free_one_page(
be in a state where it can be freed; there
may or may not be a hash index to the page */
{
+#ifdef UNIV_DEBUG
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+#endif
+ mutex_t* block_mutex = buf_page_get_mutex(bpage);
+
+ ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(block_mutex));
+
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
+ } else {
+ /* The block_mutex should have been released by
+ buf_LRU_block_remove_hashed_page() when it returns
+ BUF_BLOCK_ZIP_FREE. */
+ ut_ad(block_mutex == &buf_pool->zip_mutex);
+ mutex_enter(block_mutex);
}
}
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index 4ba0d2cf577..c29dcbf0444 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -51,6 +51,44 @@ i/o-fixed buffer blocks */
#define BUF_READ_AHEAD_PEND_LIMIT 2
/********************************************************************//**
+Unfixes the pages, unlatches the page,
+removes it from page_hash and removes it from LRU. */
+static
+void
+buf_read_page_handle_error(
+/*=======================*/
+ buf_page_t* bpage) /*!< in: pointer to the block */
+{
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ const ibool uncompressed = (buf_page_get_state(bpage)
+ == BUF_BLOCK_FILE_PAGE);
+
+ /* First unfix and release lock on the bpage */
+ buf_pool_mutex_enter(buf_pool);
+ mutex_enter(buf_page_get_mutex(bpage));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
+ ut_ad(bpage->buf_fix_count == 0);
+
+ /* Set BUF_IO_NONE before we remove the block from LRU list */
+ buf_page_set_io_fix(bpage, BUF_IO_NONE);
+
+ if (uncompressed) {
+ rw_lock_x_unlock_gen(
+ &((buf_block_t*) bpage)->lock,
+ BUF_IO_READ);
+ }
+
+ /* remove the block from LRU list */
+ buf_LRU_free_one_page(bpage);
+
+ ut_ad(buf_pool->n_pend_reads > 0);
+ buf_pool->n_pend_reads--;
+
+ mutex_exit(buf_page_get_mutex(bpage));
+ buf_pool_mutex_exit(buf_pool);
+}
+
+/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
@@ -198,6 +236,11 @@ not_to_recover:
((buf_block_t*) bpage)->frame, bpage, trx);
}
+ if (*err == DB_TABLESPACE_DELETED) {
+ buf_read_page_handle_error(bpage);
+ return(0);
+ }
+
if (srv_pass_corrupt_table) {
if (*err != DB_SUCCESS) {
bpage->is_corrupt = TRUE;
@@ -210,7 +253,9 @@ not_to_recover:
thd_wait_end(NULL);
/* The i/o is already completed when we arrive from
fil_read */
- buf_page_io_complete(bpage);
+ if (!buf_page_io_complete(bpage)) {
+ return(0);
+ }
}
return(1);
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 3ee045807ed..516b6e927e0 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -170,6 +170,7 @@ void
dict_field_print_low(
/*=================*/
const dict_field_t* field); /*!< in: field */
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Frees a foreign key struct. */
static
@@ -183,7 +184,7 @@ and unique key errors */
UNIV_INTERN FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
UNIV_INTERN mutex_t dict_foreign_err_mutex;
-
+#endif /* !UNIV_HOTBACKUP */
/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
@@ -2318,6 +2319,7 @@ dict_index_build_internal_non_clust(
return(new_index);
}
+#ifndef UNIV_HOTBACKUP
/*====================== FOREIGN KEY PROCESSING ========================*/
/*********************************************************************//**
@@ -2582,6 +2584,7 @@ dict_foreign_find_equiv_index(
FALSE/* allow columns to be NULL */));
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object by matching on the name and column names and
if more than one index matches return the index with the max id
@@ -2641,6 +2644,7 @@ dict_table_get_index_by_max_id(
return(found);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Report an error in a foreign key definition. */
static
@@ -2806,6 +2810,7 @@ dict_foreign_add_to_cache(
return(DB_SUCCESS);
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity, and
@@ -3285,6 +3290,7 @@ end_of_string:
}
}
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Finds the highest [number] for foreign key constraints of the table. Looks
only at the >= 4.0.18-format id's, which are of the form
@@ -4121,7 +4127,7 @@ syntax_error:
}
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
-
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
Assumes that dict_sys->mutex is already being held.
@@ -4654,12 +4660,6 @@ next_rec:
}
btr_pcur_close(&pcur);
mtr_commit(&mtr);
-
- if (rests) {
- fprintf(stderr, "InnoDB: Warning: failed to store %lu stats entries"
- " of %s/%s to SYS_STATS system table.\n",
- rests, index->table_name, index->name);
- }
}
/*===========================================*/
@@ -4895,6 +4895,7 @@ next_rec:
}
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Prints info of a foreign key constraint. */
static
@@ -4925,6 +4926,7 @@ dict_foreign_print_low(
fputs(" )\n", stderr);
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
@@ -5107,6 +5109,7 @@ dict_field_print_low(
}
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
@@ -5295,6 +5298,7 @@ dict_print_info_on_foreign_keys(
mutex_exit(&(dict_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
@@ -5425,6 +5429,28 @@ dict_table_replace_index_in_foreign_list(
foreign->foreign_index = new_index;
}
}
+
+
+ for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
+ foreign;
+ foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+
+ dict_index_t* new_index;
+
+ if (foreign->referenced_index == index) {
+ ut_ad(foreign->referenced_table == index->table);
+
+ new_index = dict_foreign_find_index(
+ foreign->referenced_table,
+ foreign->referenced_col_names,
+ foreign->n_fields, index,
+ /*check_charsets=*/TRUE, /*check_null=*/FALSE);
+ ut_ad(new_index || !trx->check_foreigns);
+ ut_ad(!new_index || new_index->table == index->table);
+
+ foreign->referenced_index = new_index;
+ }
+ }
}
/**********************************************************************//**
diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c
index 617c68925cb..6b8c11dfa7a 100644
--- a/storage/xtradb/dict/dict0mem.c
+++ b/storage/xtradb/dict/dict0mem.c
@@ -33,8 +33,8 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
-#include "ha_prototypes.h" /* innobase_casedn_str()*/
#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h" /* innobase_casedn_str()*/
# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_BLOB_DEBUG
@@ -274,6 +274,7 @@ dict_mem_index_create(
return(index);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Creates and initializes a foreign constraint memory object.
@return own: foreign constraint struct */
@@ -348,6 +349,7 @@ dict_mem_referenced_table_name_lookup_set(
}
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 3dd00594ee5..4ab2c16d41f 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -867,8 +867,10 @@ fil_node_close_file(
ut_a(node->open);
ut_a(node->n_pending == 0 || node->space->is_being_deleted);
ut_a(node->n_pending_flushes == 0);
+#ifndef UNIV_HOTBACKUP
ut_a(node->modification_counter == node->flush_counter
|| srv_fast_shutdown == 2);
+#endif /* !UNIV_HOTBACKUP */
ret = os_file_close(node->handle);
ut_a(ret);
diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c
index 2f5051e541f..b9499607bce 100644
--- a/storage/xtradb/ha/ha0ha.c
+++ b/storage/xtradb/ha/ha0ha.c
@@ -28,6 +28,7 @@ Created 8/22/1994 Heikki Tuuri
#include "ha0ha.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
# include "buf0buf.h"
#endif /* UNIV_DEBUG */
@@ -51,17 +52,13 @@ ha_create_func(
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
-#ifndef UNIV_HOTBACKUP
ulint i;
-#endif /* !UNIV_HOTBACKUP */
ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
table->adaptive = TRUE;
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */
@@ -74,7 +71,6 @@ ha_create_func(
return(table);
}
-#ifndef UNIV_HOTBACKUP
hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@@ -83,7 +79,6 @@ ha_create_func(
table->heaps[i] = mem_heap_create_in_btr_search(4096);
ut_a(table->heaps[i]);
}
-#endif /* !UNIV_HOTBACKUP */
return(table);
}
@@ -134,7 +129,6 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@@ -143,7 +137,6 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -171,11 +164,9 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
node->fold = fold;
@@ -217,13 +208,11 @@ ha_delete_hash_node(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
@@ -264,13 +253,11 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -278,7 +265,6 @@ ha_search_and_update_if_found_func(
}
}
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index ba13744d5bd..fe48c472e8b 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -49,6 +49,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <sql_acl.h> // PROCESS_ACL
#include <m_ctype.h>
+#include <debug_sync.h> // DEBUG_SYNC
#include <mysys_err.h>
#include <mysql/plugin.h>
#include <innodb_priv.h>
@@ -494,6 +495,9 @@ static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG,
"This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.",
NULL, NULL, FALSE);
+static MYSQL_THDVAR_ULONG(merge_sort_block_size, PLUGIN_VAR_RQCMDARG,
+ "The block size used doing external merge-sort for secondary index creation.",
+ NULL, NULL, 1UL << 20, 1UL << 20, 1UL << 30, 0);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -1010,6 +1014,20 @@ thd_flush_log_at_trx_commit(
return(THDVAR((THD*) thd, flush_log_at_trx_commit));
}
+/******************************************************************//**
+Returns the merge-sort block size used for the secondary index creation
+for the current connection.
+@return the merge-sort block size, in bytes */
+extern "C" UNIV_INTERN
+ulong
+thd_merge_sort_block_size(
+/*================================*/
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
++ the global merge_sort_block_size */
+{
+ return(THDVAR((THD*) thd, merge_sort_block_size));
+}
+
/********************************************************************//**
Obtain the InnoDB transaction of a MySQL thread.
@return reference to transaction pointer */
@@ -2870,6 +2888,7 @@ innobase_change_buffering_inited_ok:
srv_read_ahead &= 3;
srv_adaptive_flushing_method %= 3;
+ srv_flush_neighbor_pages %= 3;
srv_force_recovery = (ulint) innobase_force_recovery;
@@ -6688,6 +6707,7 @@ ha_innobase::index_read(
ulint ret;
DBUG_ENTER("index_read");
+ DEBUG_SYNC_C("ha_innobase_index_read_begin");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
@@ -8578,6 +8598,8 @@ ha_innobase::rename_table(
error = innobase_rename_table(trx, from, to, TRUE);
+ DEBUG_SYNC(thd, "after_innobase_rename_table");
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -8905,10 +8927,15 @@ innobase_get_mysql_key_number_for_index(
}
}
- /* Print an error message if we cannot find the index
- ** in the "index translation table". */
- sql_print_error("Cannot find index %s in InnoDB index "
- "translation table.", index->name);
+ /* If index_count in translation table is set to 0, it
+ is possible we are in the process of rebuilding table,
+ do not spit error in this case */
+ if (share->idx_trans_tbl.index_count) {
+ /* Print an error message if we cannot find the index
+ ** in the "index translation table". */
+ sql_print_error("Cannot find index %s in InnoDB index "
+ "translation table.", index->name);
+ }
}
/* If we do not have an "index translation table", or not able
@@ -12411,7 +12438,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
- NULL, NULL, 200, 100, ~ (ulong) 0L, 0);
+ NULL, NULL, 200, 100, ~0UL, 0);
static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size,
PLUGIN_VAR_OPCMDARG,
@@ -12544,7 +12571,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
"Desired maximum length of the purge queue (0 = no limit)",
- NULL, NULL, 0, 0, ~(ulong) 0L, 0);
+ NULL, NULL, 0, 0, ~0UL, 0);
static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
@@ -12648,7 +12675,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
PLUGIN_VAR_RQCMDARG,
"Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
- NULL, NULL, 500L, 1L, ~(ulong) 0L, 0);
+ NULL, NULL, 500L, 1L, ~0UL, 0);
#ifdef EXTENDED_FOR_KILLIDLE
#define kill_idle_help_text "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
@@ -12718,12 +12745,12 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
PLUGIN_VAR_RQCMDARG,
"Count of spin-loop rounds in InnoDB mutexes (30 by default)",
- NULL, NULL, 30L, 0L, ~ (ulong) 0L, 0);
+ NULL, NULL, 30L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
"Maximum delay between polling for a spin lock (6 by default)",
- NULL, NULL, 6L, 0L, ~ (ulong) 0L, 0);
+ NULL, NULL, 6L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
innobase_thread_concurrency_timer_based,
@@ -12739,7 +12766,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
PLUGIN_VAR_RQCMDARG,
"Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
- NULL, NULL, 10000L, 0L, ~ (ulong) 0L, 0);
+ NULL, NULL, 10000L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -12914,7 +12941,7 @@ innodb_adaptive_flushing_method_update(
void* var_ptr,
const void* save)
{
- *(long *)var_ptr= (*(long *)save) % 4;
+ *(long *)var_ptr= (*(long *)save) % 3;
}
const char *adaptive_flushing_method_names[]=
{
@@ -13092,6 +13119,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(corrupt_table_action),
MYSQL_SYSVAR(lazy_drop_table),
MYSQL_SYSVAR(fake_changes),
+ MYSQL_SYSVAR(merge_sort_block_size),
NULL
};
@@ -13112,6 +13140,7 @@ maria_declare_plugin(xtradb)
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
},
i_s_innodb_rseg_maria,
+i_s_innodb_undo_logs_maria,
i_s_innodb_trx_maria,
i_s_innodb_locks_maria,
i_s_innodb_lock_waits_maria,
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 92e51d37d7d..0496cb98080 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -713,6 +713,10 @@ ha_innobase::add_index(
ut_a(indexed_table == prebuilt->table);
+ if (indexed_table->tablespace_discarded) {
+ DBUG_RETURN(-1);
+ }
+
/* Check that index keys are sensible */
error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table);
@@ -781,7 +785,7 @@ ha_innobase::add_index(
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */
@@ -817,7 +821,7 @@ ha_innobase::add_index(
}
ut_d(dict_table_check_for_dup_indexes(prebuilt->table,
- FALSE));
+ TRUE));
mem_heap_free(heap);
trx_general_rollback_for_mysql(trx, NULL);
row_mysql_unlock_data_dictionary(trx);
@@ -1071,7 +1075,7 @@ ha_innobase::final_add_index(
trx_commit_for_mysql(prebuilt->trx);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx);
@@ -1118,7 +1122,7 @@ ha_innobase::prepare_drop_index(
/* Test and mark all the indexes to be dropped */
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* Check that none of the indexes have previously been flagged
for deletion. */
@@ -1289,7 +1293,7 @@ func_exit:
} while (index);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
row_mysql_unlock_data_dictionary(trx);
DBUG_RETURN(err);
@@ -1342,7 +1346,7 @@ ha_innobase::final_drop_index(
prebuilt->table->flags, user_thd);
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
if (UNIV_UNLIKELY(err)) {
@@ -1386,7 +1390,7 @@ ha_innobase::final_drop_index(
share->idx_trans_tbl.index_count = 0;
func_exit:
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
trx_commit_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
row_mysql_unlock_data_dictionary(trx);
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 7c60b0f7775..5d86ea98d27 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -49,6 +49,7 @@ extern "C" {
#include "trx0i_s.h"
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
#include "trx0rseg.h" /* for trx_rseg_struct */
+#include "trx0undo.h" /* for trx_undo_struct */
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
@@ -4437,3 +4438,292 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
NULL,
INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE
};
+
+
+static ST_FIELD_INFO i_s_innodb_undo_logs_fields_info[] =
+{
+#define IDX_USEG_TRX_ID 0
+ {STRUCT_FLD(field_name, "trx_id"),
+ STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_RSEG_ID 1
+ {STRUCT_FLD(field_name, "rseg_id"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_USEG_ID 2
+ {STRUCT_FLD(field_name, "useg_id"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_TYPE 3
+#define USEG_TYPE_MAX_LEN 256
+ {STRUCT_FLD(field_name, "type"),
+ STRUCT_FLD(field_length, USEG_TYPE_MAX_LEN),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ #define IDX_USEG_STATE 4
+ #define USEG_STATE_MAX_LEN 256
+ {STRUCT_FLD(field_name, "state"),
+ STRUCT_FLD(field_length, USEG_STATE_MAX_LEN),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_SIZE 5
+ {STRUCT_FLD(field_name, "size"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+static
+int
+i_s_innodb_undo_logs_fill_store(
+/*=================*/
+ THD* thd, /* in: thread */
+ TABLE* table, /* in/out: table to fill */
+ trx_undo_t* useg) /* in: useg to fill from */
+{
+ char trx_id[TRX_ID_MAX_LEN + 1];
+
+ DBUG_ENTER("i_s_innodb_undo_logs_fill_store");
+
+ switch (useg->type) {
+ case TRX_UNDO_INSERT:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "INSERT"));
+ break;
+ case TRX_UNDO_UPDATE:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "UPDATE"));
+ break;
+ default:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "UNKNOWN"));
+ break;
+ }
+
+ ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, useg->trx_id);
+
+ switch (useg->state) {
+ case TRX_UNDO_ACTIVE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "ACTIVE"));
+ break;
+ case TRX_UNDO_CACHED:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "CACHED"));
+ break;
+ case TRX_UNDO_TO_FREE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "TO_FREE"));
+ break;
+ case TRX_UNDO_TO_PURGE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "TO_PURGE"));
+ break;
+ case TRX_UNDO_PREPARED:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "PREPARED"));
+ break;
+ default:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "UNKNOWN"));
+ break;
+ }
+
+ table->field[IDX_USEG_RSEG_ID]->store(useg->rseg->id);
+ table->field[IDX_USEG_USEG_ID]->store(useg->id);
+ table->field[IDX_USEG_SIZE]->store(useg->size);
+ if (schema_table_store_record(thd, table)) {
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+static
+int
+i_s_innodb_undo_logs_fill(
+/*=================*/
+ THD* thd, /* in: thread */
+ TABLE_LIST* tables, /* in/out: tables to fill */
+ COND* cond) /* in: condition (ignored) */
+{
+ TABLE* table = (TABLE *) tables->table;
+ int status = 0;
+ trx_rseg_t* rseg;
+ trx_undo_t* useg;
+
+ DBUG_ENTER("i_s_innodb_undo_logs_fill");
+
+ /* deny access to non-superusers */
+ if (check_global_access(thd, PROCESS_ACL)) {
+ DBUG_RETURN(0);
+ }
+
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+ while (rseg && status == 0) {
+ mutex_enter(&(rseg->mutex));
+ useg = UT_LIST_GET_FIRST(rseg->update_undo_list);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->insert_undo_list);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+ mutex_exit(&(rseg->mutex));
+ rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
+ }
+
+ DBUG_RETURN(status);
+}
+
+static
+int
+i_s_innodb_undo_logs_init(
+/*=================*/
+ /* out: 0 on success */
+ void* p) /* in/out: table schema object */
+{
+ DBUG_ENTER("i_s_innodb_undo_logs_init");
+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = i_s_innodb_undo_logs_fields_info;
+ schema->fill_table = i_s_innodb_undo_logs_fill;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_undo_logs =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_UNDO_LOGS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback undo segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_undo_logs_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* reserved for dependency checking */
+ /* void* */
+ STRUCT_FLD(__reserved1, NULL),
+
+ /* Plugin flags */
+ /* unsigned long */
+ STRUCT_FLD(flags, 0UL),
+};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_undo_logs_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_UNDO_LOGS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback undo segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_undo_logs_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE
+};
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index f39172ea0a9..329cc2f5f91 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -43,6 +43,7 @@ extern struct st_mysql_plugin i_s_innodb_sys_fields;
extern struct st_mysql_plugin i_s_innodb_sys_foreign;
extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols;
extern struct st_mysql_plugin i_s_innodb_rseg;
+extern struct st_mysql_plugin i_s_innodb_undo_logs;
extern struct st_mysql_plugin i_s_innodb_sys_stats;
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
@@ -67,6 +68,7 @@ extern struct st_maria_plugin i_s_innodb_sys_foreign_maria;
extern struct st_maria_plugin i_s_innodb_sys_foreign_cols_maria;
extern struct st_maria_plugin i_s_innodb_sys_stats_maria;
extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_undo_logs_maria;
extern struct st_maria_plugin i_s_innodb_table_stats_maria;
extern struct st_maria_plugin i_s_innodb_index_stats_maria;
extern struct st_maria_plugin i_s_innodb_admin_command_maria;
diff --git a/storage/xtradb/include/btr0btr.h b/storage/xtradb/include/btr0btr.h
index 520527d0375..03e89ae3f7d 100644
--- a/storage/xtradb/include/btr0btr.h
+++ b/storage/xtradb/include/btr0btr.h
@@ -92,6 +92,8 @@ insert/delete buffer when the record is not in the buffer pool. */
buffer when the record is not in the buffer pool. */
#define BTR_DELETE 8192
+#endif /* UNIV_HOTBACKUP */
+
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -112,6 +114,7 @@ btr_corruption_report(
ut_error; \
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
/** An index->blobs entry for keeping track of off-page column references */
diff --git a/storage/xtradb/include/btr0types.h b/storage/xtradb/include/btr0types.h
index 6f515c3f58c..43c6b425688 100644
--- a/storage/xtradb/include/btr0types.h
+++ b/storage/xtradb/include/btr0types.h
@@ -39,6 +39,8 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
+#ifndef UNIV_HOTBACKUP
+
/** @brief The latch protecting the adaptive search system
This latch protects the
@@ -56,6 +58,8 @@ Bear in mind (3) and (4) when using the hash index.
extern rw_lock_t** btr_search_latch_part;
+#endif /* UNIV_HOTBACKUP */
+
/** The latch protecting the adaptive search system */
//#define btr_search_latch (*btr_search_latch_temp)
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 5f8220de18d..1a4990be69f 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -608,34 +608,34 @@ ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
buf_block_t* block); /*!< in: block */
-#else /* !UNIV_HOTBACKUP */
-# define buf_block_modify_clock_inc(block) ((void) 0)
-#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
Increments the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_inc_func(
/*=======================*/
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
const char* file, /*!< in: file name */
ulint line, /*!< in: line */
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
buf_block_t* block) /*!< in/out: block to bufferfix */
__attribute__((nonnull));
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
-#else /* UNIV_SYNC_DEBUG */
+# else /* UNIV_SYNC_DEBUG */
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
+#else /* !UNIV_HOTBACKUP */
+# define buf_block_modify_clock_inc(block) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
@@ -1193,9 +1193,10 @@ buf_page_init_for_read(
ulint offset);/*!< in: page number */
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage); /*!< in: pointer to the block in question */
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index 66006d366c6..6595e86a8fe 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -31,6 +31,7 @@ Created 11/5/1995 Heikki Tuuri
*******************************************************/
#include "mtr0mtr.h"
+#ifndef UNIV_HOTBACKUP
#include "buf0flu.h"
#include "buf0lru.h"
#include "buf0rea.h"
@@ -180,6 +181,7 @@ buf_page_peek_if_too_old(
return(!buf_page_peek_if_young(bpage));
}
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Gets the state of a block.
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 6974e480144..de3605b1dfb 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -750,6 +750,7 @@ ulint
dict_table_zip_size(
/*================*/
const dict_table_t* table); /*!< in: table */
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
@@ -766,6 +767,7 @@ void
dict_table_x_unlock_indexes(
/*========================*/
dict_table_t* table); /*!< in: table */
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns.
@@ -1278,7 +1280,7 @@ UNIV_INTERN
void
dict_close(void);
/*============*/
-
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Check whether the table is corrupted.
@return nonzero for corrupted table, zero for valid tables */
@@ -1299,6 +1301,7 @@ dict_index_is_corrupted(
const dict_index_t* index) /*!< in: index */
__attribute__((nonnull, pure, warn_unused_result));
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Flags an index and table corrupted both in the data dictionary cache
and in the system table SYS_INDEXES. */
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 5ed9b182d6c..02eafcc5d9c 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -491,6 +491,7 @@ dict_table_zip_size(
return(dict_table_flags_to_zip_size(table->flags));
}
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
@@ -533,6 +534,7 @@ dict_table_x_unlock_indexes(
rw_lock_x_unlock(dict_index_get_lock(index));
}
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system.
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 2e200ba7f43..2907365a32a 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -312,4 +312,15 @@ innobase_get_lower_case_table_names(void);
/*=====================================*/
+/********************************************************************//**
+Returns the merge-sort block size used for the secondary index creation
+for the current connection.
+@return the merge-sort block size, in bytes */
+
+ulong
+thd_merge_sort_block_size(
+/*======================*/
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
+ the global merge_sort_block_size */
+
#endif
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 6b1c2859cf7..857ec0946c2 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -780,7 +780,6 @@ struct log_struct{
buffer */
#ifndef UNIV_HOTBACKUP
mutex_t mutex; /*!< mutex protecting the log */
-#endif /* !UNIV_HOTBACKUP */
mutex_t log_flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
@@ -790,6 +789,7 @@ struct log_struct{
mtr_commit and still ensure that
insertions in the flush_list happen
in the LSN order. */
+#endif /* !UNIV_HOTBACKUP */
byte* buf_ptr; /* unaligned log buffer */
byte* buf; /*!< log buffer */
ulint buf_size; /*!< log buffer size in bytes */
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index b153b0dba7f..5b1f9339845 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -316,7 +316,7 @@ to original un-instrumented file I/O APIs */
os_file_create_func(name, create, purpose, type, success)
# define os_file_create_simple(key, name, create, access, success) \
- os_file_create_simple_func(name, create_mode, access, success)
+ os_file_create_simple_func(name, create, access, success)
# define os_file_create_simple_no_error_handling( \
key, name, create_mode, access, success) \
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index d99fbfb9463..a40683e00f1 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -117,13 +117,13 @@ extern ulint srv_max_file_format_at_startup;
/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
-#endif /* !UNIV_HOTBACKUP */
/* If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads.
Currently we support native aio on windows and linux */
extern my_bool srv_use_native_aio;
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
extern ibool srv_use_native_conditions;
#endif
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index 976cb31563f..c933fb405e1 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -248,7 +248,6 @@ UNIV_INLINE
trx_id_t
trx_sys_get_new_trx_id(void);
/*========================*/
-#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
@@ -265,7 +264,6 @@ trx_write_trx_id(
/*=============*/
byte* ptr, /*!< in: pointer to memory where written */
trx_id_t id); /*!< in: id */
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
@@ -603,7 +601,6 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
/* @} */
-#ifndef UNIV_HOTBACKUP
/** File format tag */
/* @{ */
/** The offset of the file format tag on the trx system header page
@@ -622,6 +619,7 @@ identifier is added to this 64-bit constant. */
| TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
/* @} */
+#ifndef UNIV_HOTBACKUP
/** Doublewrite control struct */
struct trx_doublewrite_struct{
mutex_t mutex; /*!< mutex protecting the first_free field and
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index d54b467d2c1..ce59a3f2741 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -54,7 +54,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX 8
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 27.0
+#define PERCONA_INNODB_VERSION 28.1
#endif
/* The following is the InnoDB version as shown in
diff --git a/storage/xtradb/mem/mem0dbg.c b/storage/xtradb/mem/mem0dbg.c
index ae43d6097a6..0909b7c9a64 100644
--- a/storage/xtradb/mem/mem0dbg.c
+++ b/storage/xtradb/mem/mem0dbg.c
@@ -24,7 +24,9 @@ but is included in mem0mem.* !
Created 6/9/1994 Heikki Tuuri
*************************************************************************/
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
# ifndef UNIV_HOTBACKUP
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 5d249d52ce9..061d556c6e7 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -303,6 +303,7 @@ UNIV_INTERN ulint os_n_pending_writes = 0;
UNIV_INTERN ulint os_n_pending_reads = 0;
#ifdef UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Validates the consistency the aio system some of the time.
@return TRUE if ok or the check was skipped */
@@ -329,6 +330,7 @@ os_aio_validate_skip(void)
os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
return(os_aio_validate());
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
#ifdef _WIN32
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index d4b0dd8339d..4751f4816a9 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -4437,7 +4437,9 @@ page_zip_reorganize(
dict_index_t* index, /*!< in: index of the B-tree node */
mtr_t* mtr) /*!< in: mini-transaction */
{
+#ifndef UNIV_HOTBACKUP
buf_pool_t* buf_pool = buf_pool_from_block(block);
+#endif /* !UNIV_HOTBACKUP */
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
page_t* page = buf_block_get_frame(block);
buf_block_t* temp_block;
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index a629a4fb195..b21d48c7552 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -1281,7 +1281,8 @@ run_again:
check_index = foreign->foreign_index;
}
- if (check_table == NULL || check_table->ibd_file_missing) {
+ if (check_table == NULL || check_table->ibd_file_missing
+ || check_index == NULL) {
if (check_ref) {
FILE* ef = dict_foreign_err_file;
@@ -1316,9 +1317,6 @@ run_again:
goto exit_func;
}
- ut_a(check_table);
- ut_a(check_index);
-
if (check_table != table) {
/* We already have a LOCK_IX on table, but not necessarily
on check_table */
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index f00706da0d3..c7d6304d6a7 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -89,8 +89,9 @@ rounded to a power of 2.
When not creating a PRIMARY KEY that contains column prefixes, this
can be set as small as UNIV_PAGE_SIZE / 2. See the comment above
-ut_ad(data_size < sizeof(row_merge_block_t)). */
-typedef byte row_merge_block_t[1048576];
+ut_ad(data_size < sizeof(row_merge_block_t)).
+1MB is the default merge-sort block size for innodb */
+typedef byte* row_merge_block_t;
/** @brief Secondary buffer for I/O operations of merge records.
@@ -184,7 +185,6 @@ row_merge_buf_create_low(
row_merge_buf_t* buf;
ut_ad(max_tuples > 0);
- ut_ad(max_tuples <= sizeof(row_merge_block_t));
ut_ad(max_tuples < buf_size);
buf = mem_heap_zalloc(heap, buf_size);
@@ -205,19 +205,19 @@ static
row_merge_buf_t*
row_merge_buf_create(
/*=================*/
- dict_index_t* index) /*!< in: secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ ulint block_size) /*!< in: merge block buffer size */
{
row_merge_buf_t* buf;
ulint max_tuples;
ulint buf_size;
mem_heap_t* heap;
- max_tuples = sizeof(row_merge_block_t)
- / ut_max(1, dict_index_get_min_size(index));
+ max_tuples = block_size / ut_max(1, dict_index_get_min_size(index));
buf_size = (sizeof *buf) + (max_tuples - 1) * sizeof *buf->tuples;
- heap = mem_heap_create(buf_size + sizeof(row_merge_block_t));
+ heap = mem_heap_create(buf_size + block_size);
buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size);
@@ -265,8 +265,10 @@ row_merge_buf_add(
/*==============*/
row_merge_buf_t* buf, /*!< in/out: sort buffer */
const dtuple_t* row, /*!< in: row in clustered index */
- const row_ext_t* ext) /*!< in: cache of externally stored
+ const row_ext_t* ext, /*!< in: cache of externally stored
column prefixes, or NULL */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint i;
ulint n_fields;
@@ -391,10 +393,10 @@ row_merge_buf_add(
page_zip_rec_needs_ext() limit. However, no further columns
will be moved to external storage until the record is inserted
to the clustered index B-tree. */
- ut_ad(data_size < sizeof(row_merge_block_t));
+ ut_ad(data_size < block_size);
/* Reserve one byte for the end marker of row_merge_block_t. */
- if (buf->total_size + data_size >= sizeof(row_merge_block_t) - 1) {
+ if (buf->total_size + data_size >= block_size - 1) {
return(FALSE);
}
@@ -700,9 +702,11 @@ row_merge_read(
ulint offset, /*!< in: offset where to read
in number of row_merge_block_t
elements */
- row_merge_block_t* buf) /*!< out: data */
+ row_merge_block_t buf, /*!< out: data */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
- ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
+ ib_uint64_t ofs = ((ib_uint64_t) offset) * block_size;
ibool success;
#ifdef UNIV_DEBUG
@@ -715,7 +719,7 @@ row_merge_read(
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
- sizeof *buf);
+ block_size);
#ifdef POSIX_FADV_DONTNEED
/* Each block is read exactly once. Free up the file cache. */
posix_fadvise(fd, ofs, sizeof *buf, POSIX_FADV_DONTNEED);
@@ -740,16 +744,17 @@ row_merge_write(
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
- const void* buf) /*!< in: data */
+ const void* buf, /*!< in: data */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
- size_t buf_len = sizeof(row_merge_block_t);
- ib_uint64_t ofs = buf_len * (ib_uint64_t) offset;
+ ib_uint64_t ofs = block_size * (ib_uint64_t) offset;
ibool ret;
ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
- buf_len);
+ block_size);
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
@@ -761,7 +766,7 @@ row_merge_write(
#ifdef POSIX_FADV_DONTNEED
/* The block will be needed on the next merge pass,
but it can be evicted from the file cache meanwhile. */
- posix_fadvise(fd, ofs, buf_len, POSIX_FADV_DONTNEED);
+ posix_fadvise(fd, ofs, block_size, POSIX_FADV_DONTNEED);
#endif /* POSIX_FADV_DONTNEED */
return(UNIV_LIKELY(ret));
@@ -783,7 +788,9 @@ row_merge_read_rec(
const mrec_t** mrec, /*!< out: pointer to merge record,
or NULL on end of list
(non-NULL on I/O error) */
- ulint* offsets)/*!< out: offsets of mrec */
+ ulint* offsets,/*!< out: offsets of mrec */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint extra_size;
ulint data_size;
@@ -820,7 +827,8 @@ row_merge_read_rec(
/* Read another byte of extra_size. */
if (UNIV_UNLIKELY(b >= block[1])) {
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
err_exit:
/* Signal I/O error. */
*mrec = b;
@@ -849,7 +857,8 @@ err_exit:
memcpy(*buf, b, avail_size);
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
goto err_exit;
}
@@ -870,7 +879,7 @@ err_exit:
/* These overflows should be impossible given that
records are much smaller than either buffer, and
the record starts near the beginning of each buffer. */
- ut_a(extra_size + data_size < sizeof *buf);
+ ut_a(extra_size + data_size < block_size);
ut_a(b + data_size < block[1]);
/* Copy the data bytes. */
@@ -885,7 +894,7 @@ err_exit:
rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
data_size = rec_offs_data_size(offsets);
- ut_ad(extra_size + data_size < sizeof *buf);
+ ut_ad(extra_size + data_size < block_size);
b += extra_size + data_size;
@@ -910,7 +919,8 @@ err_exit:
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
goto err_exit;
}
@@ -992,7 +1002,9 @@ row_merge_write_rec(
int fd, /*!< in: file descriptor */
ulint* foffs, /*!< in/out: file offset */
const mrec_t* mrec, /*!< in: record to write */
- const ulint* offsets)/*!< in: offsets of mrec */
+ const ulint* offsets,/*!< in: offsets of mrec */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint extra_size;
ulint size;
@@ -1027,11 +1039,12 @@ row_merge_write_rec(
record to the head of the new block. */
memcpy(b, buf[0], avail_size);
- if (!row_merge_write(fd, (*foffs)++, block)) {
+ if (!row_merge_write(fd, (*foffs)++, block[0],
+ block_size)) {
return(NULL);
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
/* Copy the rest. */
b = block[0];
@@ -1056,7 +1069,9 @@ row_merge_write_eof(
row_merge_block_t* block, /*!< in/out: file buffer */
byte* b, /*!< in: pointer to end of block */
int fd, /*!< in: file descriptor */
- ulint* foffs) /*!< in/out: file offset */
+ ulint* foffs, /*!< in/out: file offset */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ut_ad(block);
ut_ad(b >= block[0]);
@@ -1071,18 +1086,19 @@ row_merge_write_eof(
*b++ = 0;
UNIV_MEM_ASSERT_RW(block[0], b - block[0]);
- UNIV_MEM_ASSERT_W(block[0], sizeof block[0]);
+ UNIV_MEM_ASSERT_W(block[0], block_size);
#ifdef UNIV_DEBUG_VALGRIND
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, block[1] - b);
#endif /* UNIV_DEBUG_VALGRIND */
- if (!row_merge_write(fd, (*foffs)++, block)) {
+ if (!row_merge_write(fd, (*foffs)++, block[0],
+ block_size)) {
return(NULL);
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
return(block[0]);
}
@@ -1140,7 +1156,9 @@ row_merge_read_clustered_index(
dict_index_t** index, /*!< in: indexes to be created */
merge_file_t* files, /*!< in: temporary files */
ulint n_index,/*!< in: number of indexes to create */
- row_merge_block_t* block) /*!< in/out: file buffer */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1168,7 +1186,7 @@ row_merge_read_clustered_index(
merge_buf = mem_alloc(n_index * sizeof *merge_buf);
for (i = 0; i < n_index; i++) {
- merge_buf[i] = row_merge_buf_create(index[i]);
+ merge_buf[i] = row_merge_buf_create(index[i], block_size);
}
mtr_start(&mtr);
@@ -1300,7 +1318,8 @@ row_merge_read_clustered_index(
const dict_index_t* index = buf->index;
if (UNIV_LIKELY
- (row && row_merge_buf_add(buf, row, ext))) {
+ (row && row_merge_buf_add(buf, row, ext,
+ block_size))) {
file->n_rec++;
continue;
}
@@ -1335,12 +1354,12 @@ err_exit:
row_merge_buf_write(buf, file, block);
if (!row_merge_write(file->fd, file->offset++,
- block)) {
+ block[0], block_size)) {
err = DB_OUT_OF_FILE_SPACE;
goto err_exit;
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
merge_buf[i] = row_merge_buf_empty(buf);
if (UNIV_LIKELY(row != NULL)) {
@@ -1349,7 +1368,8 @@ err_exit:
and emptied. */
if (UNIV_UNLIKELY
- (!row_merge_buf_add(buf, row, ext))) {
+ (!row_merge_buf_add(buf, row, ext,
+ block_size))) {
/* An empty buffer should have enough
room for at least one record. */
ut_error;
@@ -1393,14 +1413,16 @@ func_exit:
do { \
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
of->fd, &of->offset, \
- mrec##N, offsets##N); \
+ mrec##N, offsets##N, \
+ block_size); \
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = row_merge_read_rec(&block[N], &buf[N], \
b##N, index, \
file->fd, foffs##N, \
- &mrec##N, offsets##N); \
+ &mrec##N, offsets##N, \
+ block_size); \
if (UNIV_UNLIKELY(!b##N)) { \
if (mrec##N) { \
goto corrupt; \
@@ -1425,9 +1447,11 @@ row_merge_blocks(
ulint* foffs1, /*!< in/out: offset of second
source list in the file */
merge_file_t* of, /*!< in/out: output file */
- struct TABLE* table) /*!< in/out: MySQL table, for
+ struct TABLE* table, /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -1457,8 +1481,10 @@ row_merge_blocks(
/* Write a record and read the next record. Split the output
file in two halves, which can be merged on the following pass. */
- if (!row_merge_read(file->fd, *foffs0, &block[0])
- || !row_merge_read(file->fd, *foffs1, &block[1])) {
+ if (!row_merge_read(file->fd, *foffs0, block[0],
+ block_size)
+ || !row_merge_read(file->fd, *foffs1, block[1],
+ block_size)) {
corrupt:
mem_heap_free(heap);
return(DB_CORRUPTION);
@@ -1469,9 +1495,9 @@ corrupt:
b2 = block[2];
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
- foffs0, &mrec0, offsets0);
+ foffs0, &mrec0, offsets0, block_size);
b1 = row_merge_read_rec(&block[1], &buf[1], b1, index, file->fd,
- foffs1, &mrec1, offsets1);
+ foffs1, &mrec1, offsets1, block_size);
if (UNIV_UNLIKELY(!b0 && mrec0)
|| UNIV_UNLIKELY(!b1 && mrec1)) {
@@ -1521,7 +1547,8 @@ done0:
done1:
mem_heap_free(heap);
- b2 = row_merge_write_eof(&block[2], b2, of->fd, &of->offset);
+ b2 = row_merge_write_eof(&block[2], b2, of->fd, &of->offset,
+ block_size);
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
@@ -1536,7 +1563,9 @@ row_merge_blocks_copy(
const merge_file_t* file, /*!< in: input file */
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: input file offset */
- merge_file_t* of) /*!< in/out: output file */
+ merge_file_t* of, /*!< in/out: output file */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -1563,7 +1592,7 @@ row_merge_blocks_copy(
/* Write a record and read the next record. Split the output
file in two halves, which can be merged on the following pass. */
- if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+ if (!row_merge_read(file->fd, *foffs0, block[0], block_size)) {
corrupt:
mem_heap_free(heap);
return(FALSE);
@@ -1573,7 +1602,7 @@ corrupt:
b2 = block[2];
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
- foffs0, &mrec0, offsets0);
+ foffs0, &mrec0, offsets0, block_size);
if (UNIV_UNLIKELY(!b0 && mrec0)) {
goto corrupt;
@@ -1592,8 +1621,8 @@ done0:
(*foffs0)++;
mem_heap_free(heap);
- return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
- != NULL);
+ return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset,
+ block_size) != NULL);
}
/*************************************************************//**
@@ -1614,9 +1643,10 @@ row_merge(
if applicable */
ulint* num_run,/*!< in/out: Number of runs remain
to be merged */
- ulint* run_offset) /*!< in/out: Array contains the
+ ulint* run_offset, /*!< in/out: Array contains the
first offset number for each merge
run */
+ ulint block_size) /*!< in: merge block buffer size */
{
ulint foffs0; /*!< first input offset */
ulint foffs1; /*!< second input offset */
@@ -1627,7 +1657,7 @@ row_merge(
ulint n_run = 0;
/*!< num of runs generated from this merge */
- UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
+ UNIV_MEM_ASSERT_W(block[0], 3 * block_size);
ut_ad(ihalf < file->offset);
@@ -1659,7 +1689,8 @@ row_merge(
run_offset[n_run++] = of.offset;
error = row_merge_blocks(index, file, block,
- &foffs0, &foffs1, &of, table);
+ &foffs0, &foffs1, &of, table,
+ block_size);
if (error != DB_SUCCESS) {
return(error);
@@ -1677,7 +1708,8 @@ row_merge(
/* Remember the offset number for this run */
run_offset[n_run++] = of.offset;
- if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs0, &of,
+ block_size)) {
return(DB_CORRUPTION);
}
}
@@ -1692,7 +1724,8 @@ row_merge(
/* Remember the offset number for this run */
run_offset[n_run++] = of.offset;
- if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs1, &of,
+ block_size)) {
return(DB_CORRUPTION);
}
}
@@ -1721,7 +1754,7 @@ row_merge(
*tmpfd = file->fd;
*file = of;
- UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], 3 * block_size);
return(DB_SUCCESS);
}
@@ -1739,9 +1772,11 @@ row_merge_sort(
index entries */
row_merge_block_t* block, /*!< in/out: 3 buffers */
int* tmpfd, /*!< in/out: temporary file handle */
- struct TABLE* table) /*!< in/out: MySQL table, for
+ struct TABLE* table, /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint half = file->offset / 2;
ulint num_runs;
@@ -1770,7 +1805,7 @@ row_merge_sort(
/* Merge the runs until we have one big run */
do {
error = row_merge(trx, index, file, block, tmpfd,
- table, &num_runs, run_offset);
+ table, &num_runs, run_offset, block_size);
UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
@@ -1841,7 +1876,9 @@ row_merge_insert_index_tuples(
ulint zip_size,/*!< in: compressed page size of
the old table, or 0 if uncompressed */
int fd, /*!< in: file descriptor */
- row_merge_block_t* block) /*!< in/out: file buffer */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ ulint block_size)
+ /*! in: merge block buffer size */
{
const byte* b;
que_thr_t* thr;
@@ -1880,7 +1917,7 @@ row_merge_insert_index_tuples(
b = *block;
- if (!row_merge_read(fd, foffs, block)) {
+ if (!row_merge_read(fd, foffs, block[0], block_size)) {
error = DB_CORRUPTION;
} else {
mrec_buf_t* buf = mem_heap_alloc(graph_heap, sizeof *buf);
@@ -1891,7 +1928,8 @@ row_merge_insert_index_tuples(
ulint n_ext;
b = row_merge_read_rec(block, buf, b, index,
- fd, &foffs, &mrec, offsets);
+ fd, &foffs, &mrec, offsets,
+ block_size);
if (UNIV_UNLIKELY(!b)) {
/* End of list, or I/O error */
if (mrec) {
@@ -2656,11 +2694,16 @@ row_merge_build_indexes(
if applicable */
{
merge_file_t* merge_files;
- row_merge_block_t* block;
+ /* Some code uses block[1] as the synonym for block + block_size. So
+ we initialize block[3] to the address boundary of block[2], even
+ though space for 3 only buffers is allocated. */
+ row_merge_block_t block[4];
ulint block_size;
ulint i;
ulint error;
int tmpfd;
+ ulint merge_sort_block_size;
+ void* block_mem;
ut_ad(trx);
ut_ad(old_table);
@@ -2668,14 +2711,21 @@ row_merge_build_indexes(
ut_ad(indexes);
ut_ad(n_indexes);
+ merge_sort_block_size = thd_merge_sort_block_size(trx->mysql_thd);
+
trx_start_if_not_started(trx);
/* Allocate memory for merge file data structure and initialize
fields */
merge_files = mem_alloc(n_indexes * sizeof *merge_files);
- block_size = 3 * sizeof *block;
- block = os_mem_alloc_large(&block_size);
+ block_size = 3 * merge_sort_block_size;
+ block_mem = os_mem_alloc_large(&block_size);
+
+ for (i = 0; i < UT_ARR_SIZE(block); i++) {
+ block[i] = (row_merge_block_t ) ((byte *) block_mem +
+ i * merge_sort_block_size);
+ }
for (i = 0; i < n_indexes; i++) {
@@ -2693,7 +2743,7 @@ row_merge_build_indexes(
error = row_merge_read_clustered_index(
trx, table, old_table, new_table, indexes,
- merge_files, n_indexes, block);
+ merge_files, n_indexes, block, merge_sort_block_size);
if (error != DB_SUCCESS) {
@@ -2705,13 +2755,15 @@ row_merge_build_indexes(
for (i = 0; i < n_indexes; i++) {
error = row_merge_sort(trx, indexes[i], &merge_files[i],
- block, &tmpfd, table);
+ block, &tmpfd, table,
+ merge_sort_block_size);
if (error == DB_SUCCESS) {
error = row_merge_insert_index_tuples(
trx, indexes[i], new_table,
dict_table_zip_size(old_table),
- merge_files[i].fd, block);
+ merge_files[i].fd, block,
+ merge_sort_block_size);
}
/* Close the temporary file to free up space. */
@@ -2731,7 +2783,7 @@ func_exit:
}
mem_free(merge_files);
- os_mem_free_large(block, block_size);
+ os_mem_free_large(block_mem, block_size);
return(error);
}
diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c
index 5fd7d082194..6d83dbaf8ee 100644
--- a/storage/xtradb/row/row0vers.c
+++ b/storage/xtradb/row/row0vers.c
@@ -209,17 +209,6 @@ row_vers_impl_x_locked_off_kernel(
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
clust_offsets);
- /* If the trx_id and prev_trx_id are different and if
- the prev_version is marked deleted then the
- prev_trx_id must have already committed for the trx_id
- to be able to modify the row. Therefore, prev_trx_id
- cannot hold any implicit lock. */
- if (vers_del && trx_id != prev_trx_id) {
-
- mutex_enter(&kernel_mutex);
- break;
- }
-
/* The stack of versions is locked by mtr. Thus, it
is safe to fetch the prefixes for externally stored
columns. */
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index dd869a787bd..7d303c2563c 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -137,12 +137,12 @@ UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key;
UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
uint trx_rseg_n_slots_debug = 0;
#endif
-#ifndef UNIV_HOTBACKUP
/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_max = 'x' or when we open
or create a table. */
diff --git a/storage/xtradb/ut/ut0dbg.c b/storage/xtradb/ut/ut0dbg.c
index 64fadd76d1c..53ed4a53044 100644
--- a/storage/xtradb/ut/ut0dbg.c
+++ b/storage/xtradb/ut/ut0dbg.c
@@ -25,7 +25,9 @@ Created 1/30/1994 Heikki Tuuri
#include "univ.i"
#include "ut0dbg.h"
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
+#endif /* !UNIV_HOTBACKUP */
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
@@ -56,7 +58,7 @@ ut_dbg_assertion_failed(
ut_print_timestamp(stderr);
#ifdef UNIV_HOTBACKUP
fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
- innobase_basename(file), line);
+ file, line);
#else /* UNIV_HOTBACKUP */
fprintf(stderr,
" InnoDB: Assertion failure in thread %lu"
diff --git a/storage/xtradb/ut/ut0ut.c b/storage/xtradb/ut/ut0ut.c
index 60def59193a..31c8351a518 100644
--- a/storage/xtradb/ut/ut0ut.c
+++ b/storage/xtradb/ut/ut0ut.c
@@ -245,7 +245,9 @@ ut_print_timestamp(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -288,7 +290,9 @@ ut_sprintf_timestamp(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -333,7 +337,9 @@ ut_sprintf_timestamp_without_extra_chars(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -374,7 +380,9 @@ ut_get_year_month_day(
*month = (ulint)cal_tm.wMonth;
*day = (ulint)cal_tm.wDay;
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;