mirror of
https://github.com/MariaDB/server.git
synced 2026-04-29 03:35:34 +02:00
Percona-Server-5.5.27-rel28.1
This commit is contained in:
parent
651ac12e88
commit
0352f09a2e
32 changed files with 614 additions and 165 deletions
|
|
@ -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(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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,44 @@ read-ahead is not done: this is to prevent flooding the buffer pool with
|
|||
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.
|
||||
|
|
@ -196,6 +234,11 @@ not_to_recover:
|
|||
}
|
||||
thd_wait_end(NULL);
|
||||
|
||||
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;
|
||||
|
|
@ -207,7 +250,9 @@ not_to_recover:
|
|||
if (sync) {
|
||||
/* 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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -2315,6 +2316,7 @@ dict_index_build_internal_non_clust(
|
|||
return(new_index);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*====================== FOREIGN KEY PROCESSING ========================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
|
|
@ -2579,6 +2581,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
|
||||
|
|
@ -2638,6 +2641,7 @@ dict_table_get_index_by_max_id(
|
|||
return(found);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************//**
|
||||
Report an error in a foreign key definition. */
|
||||
static
|
||||
|
|
@ -2803,6 +2807,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
|
||||
|
|
@ -3282,6 +3287,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
|
||||
|
|
@ -4118,7 +4124,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.
|
||||
|
|
@ -4651,12 +4657,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);
|
||||
}
|
||||
}
|
||||
/*===========================================*/
|
||||
|
||||
|
|
@ -4892,6 +4892,7 @@ next_rec:
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************//**
|
||||
Prints info of a foreign key constraint. */
|
||||
static
|
||||
|
|
@ -4922,6 +4923,7 @@ dict_foreign_print_low(
|
|||
fputs(" )\n", stderr);
|
||||
}
|
||||
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/**********************************************************************//**
|
||||
Prints a table data. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -5104,6 +5106,7 @@ dict_field_print_low(
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************//**
|
||||
Outputs info on a foreign key of a table in a format suitable for
|
||||
CREATE TABLE. */
|
||||
|
|
@ -5292,6 +5295,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
|
||||
|
|
@ -5422,6 +5426,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
16
ha/ha0ha.c
16
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. */
|
||||
|
|
|
|||
|
|
@ -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 <mysql/innodb_priv.h>
|
||||
|
|
@ -500,6 +501,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,
|
||||
|
|
@ -1018,6 +1022,20 @@ thd_expand_fast_index_creation(
|
|||
return((ibool) (((THD*) thd)->variables.expand_fast_index_creation));
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
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 */
|
||||
|
|
@ -2900,6 +2918,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;
|
||||
|
||||
|
|
@ -6573,6 +6592,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);
|
||||
|
|
@ -8458,6 +8478,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: */
|
||||
|
||||
|
|
@ -8784,10 +8806,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
|
||||
|
|
@ -12251,7 +12278,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, ~0L, 0);
|
||||
NULL, NULL, 200, 100, ~0UL, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
|
|
@ -12384,7 +12411,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, ~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,
|
||||
|
|
@ -12488,7 +12515,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, ~0L, 0);
|
||||
NULL, NULL, 500L, 1L, ~0UL, 0);
|
||||
|
||||
static MYSQL_SYSVAR_LONG(kill_idle_transaction, srv_kill_idle_transaction,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
|
|
@ -12559,12 +12586,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, ~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, ~0L, 0);
|
||||
NULL, NULL, 6L, 0L, ~0UL, 0);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
|
||||
innobase_thread_concurrency_timer_based,
|
||||
|
|
@ -12580,7 +12607,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, ~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,
|
||||
|
|
@ -12755,7 +12782,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[]=
|
||||
{
|
||||
|
|
@ -12933,6 +12960,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
|
||||
};
|
||||
|
||||
|
|
@ -12953,6 +12981,7 @@ mysql_declare_plugin(innobase)
|
|||
0, /* flags */
|
||||
},
|
||||
i_s_innodb_rseg,
|
||||
i_s_innodb_undo_logs,
|
||||
i_s_innodb_trx,
|
||||
i_s_innodb_locks,
|
||||
i_s_innodb_lock_waits,
|
||||
|
|
|
|||
|
|
@ -712,6 +712,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);
|
||||
|
||||
|
|
@ -780,7 +784,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. */
|
||||
|
|
@ -816,7 +820,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);
|
||||
|
|
@ -1070,7 +1074,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);
|
||||
|
|
@ -1117,7 +1121,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. */
|
||||
|
|
@ -1288,7 +1292,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);
|
||||
|
|
@ -1341,7 +1345,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)) {
|
||||
|
||||
|
|
@ -1385,7 +1389,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);
|
||||
|
|
|
|||
245
handler/i_s.cc
245
handler/i_s.cc
|
|
@ -48,6 +48,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] */
|
||||
|
|
@ -5144,3 +5145,247 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob =
|
|||
STRUCT_FLD(flags, 0UL)
|
||||
};
|
||||
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1191,9 +1191,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 */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -1266,7 +1268,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 */
|
||||
|
|
@ -1287,6 +1289,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. */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -314,4 +314,15 @@ thd_expand_fast_index_creation(
|
|||
void* thd); /*!< in: thread handle (THD*) */
|
||||
|
||||
|
||||
/********************************************************************//**
|
||||
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
|
||||
|
|
|
|||
|
|
@ -765,7 +765,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
|
||||
|
|
@ -775,6 +774,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 */
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -114,13 +114,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -307,6 +307,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 */
|
||||
|
|
@ -333,6 +334,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 __WIN__
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
188
row/row0merge.c
188
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. */
|
||||
|
|
@ -2734,7 +2786,7 @@ func_exit:
|
|||
}
|
||||
|
||||
mem_free(merge_files);
|
||||
os_mem_free_large(block, block_size);
|
||||
os_mem_free_large(block_mem, block_size);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue