XtraDB 5.6.22-71.0

This commit is contained in:
Sergei Golubchik 2015-01-21 14:34:58 +01:00
commit 78e131d493
26 changed files with 792 additions and 284 deletions

View file

@ -2518,6 +2518,38 @@ btr_cur_pess_upd_restore_supremum(
page_rec_get_heap_no(rec));
}
/*************************************************************//**
Check if the total length of the modified blob for the row is within 10%
of the total redo log size. This constraint on the blob length is to
avoid overwriting the redo logs beyond the last checkpoint lsn.
@return DB_SUCCESS or DB_TOO_BIG_RECORD. */
static
dberr_t
btr_check_blob_limit(const big_rec_t* big_rec_vec)
{
const ib_uint64_t redo_size = srv_n_log_files * srv_log_file_size
* UNIV_PAGE_SIZE;
const ulint redo_10p = redo_size / 10;
ulint total_blob_len = 0;
dberr_t err = DB_SUCCESS;
/* Calculate the total number of bytes for blob data */
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
total_blob_len += big_rec_vec->fields[i].len;
}
if (total_blob_len > redo_10p) {
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data"
" length (" ULINTPF ") is greater than"
" 10%% of the total redo log size (" UINT64PF
"). Please increase total redo log size.",
total_blob_len, redo_size);
err = DB_TOO_BIG_RECORD;
}
return(err);
}
/*************************************************************//**
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
@ -2756,26 +2788,14 @@ make_external:
}
if (big_rec_vec) {
const ulint redo_10p = srv_log_file_size * UNIV_PAGE_SIZE / 10;
ulint total_blob_len = 0;
/* Calculate the total number of bytes for blob data */
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
total_blob_len += big_rec_vec->fields[i].len;
}
err = btr_check_blob_limit(big_rec_vec);
if (total_blob_len > redo_10p) {
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data"
" length (" ULINTPF ") is greater than"
" 10%% of the redo log file size (" UINT64PF
"). Please increase innodb_log_file_size.",
total_blob_len, srv_log_file_size);
if (err != DB_SUCCESS) {
if (n_reserved > 0) {
fil_space_release_free_extents(
index->space, n_reserved);
}
err = DB_TOO_BIG_RECORD;
goto err_exit;
}
}
@ -4676,7 +4696,6 @@ btr_store_big_rec_extern_fields(
buf_block_t** freed_pages = NULL;
ulint n_freed_pages = 0;
dberr_t error = DB_SUCCESS;
ulint total_blob_len = 0;
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_any_extern(offsets));
@ -4696,21 +4715,11 @@ btr_store_big_rec_extern_fields(
rec_page_no = buf_block_get_page_no(rec_block);
ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
const ulint redo_10p = (srv_log_file_size * UNIV_PAGE_SIZE / 10);
error = btr_check_blob_limit(big_rec_vec);
/* Calculate the total number of bytes for blob data */
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
total_blob_len += big_rec_vec->fields[i].len;
}
if (total_blob_len > redo_10p) {
if (error != DB_SUCCESS) {
ut_ad(op == BTR_STORE_INSERT);
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data length"
" (" ULINTPF ") is greater than 10%% of the"
" redo log file size (" UINT64PF "). Please"
" increase innodb_log_file_size.",
total_blob_len, srv_log_file_size);
return(DB_TOO_BIG_RECORD);
return(error);
}
if (page_zip) {

View file

@ -634,9 +634,14 @@ buf_page_is_corrupted(
checksum_field2 = mach_read_from_4(
read_buf + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM);
#if FIL_PAGE_LSN % 8
#error "FIL_PAGE_LSN must be 64 bit aligned"
#endif
/* declare empty pages non-corrupted */
if (checksum_field1 == 0 && checksum_field2 == 0
&& mach_read_from_4(read_buf + FIL_PAGE_LSN) == 0) {
&& *reinterpret_cast<const ib_uint64_t*>(read_buf +
FIL_PAGE_LSN) == 0) {
/* make sure that the page is really empty */
for (ulint i = 0; i < UNIV_PAGE_SIZE; i++) {
if (read_buf[i] != 0) {
@ -1691,8 +1696,9 @@ buf_pool_watch_is_sentinel(
/****************************************************************//**
Add watch for the given page to be read in. Caller must have
appropriate hash_lock for the bpage. This function may release the
hash_lock and reacquire it.
appropriate hash_lock for the bpage and hold the LRU list mutex to avoid a race
condition with buf_LRU_free_page inserting the same page into the page hash.
This function may release the hash_lock and reacquire it.
@return NULL if watch set, block if the page is in the buffer pool */
UNIV_INTERN
buf_page_t*
@ -1707,6 +1713,8 @@ buf_pool_watch_set(
buf_pool_t* buf_pool = buf_pool_get(space, offset);
prio_rw_lock_t* hash_lock;
ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
hash_lock = buf_page_hash_lock_get(buf_pool, fold);
#ifdef UNIV_SYNC_DEBUG
@ -1775,6 +1783,7 @@ page_found:
bpage->space = static_cast<ib_uint32_t>(space);
bpage->offset = static_cast<ib_uint32_t>(offset);
bpage->buf_fix_count = 1;
bpage->buf_pool_index = buf_pool_index(buf_pool);
mutex_exit(&buf_pool->zip_mutex);
@ -2721,9 +2730,11 @@ loop:
/* Page not in buf_pool: needs to be read from file */
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
mutex_enter(&buf_pool->LRU_list_mutex);
rw_lock_x_lock(hash_lock);
block = (buf_block_t*) buf_pool_watch_set(
space, offset, fold);
mutex_exit(&buf_pool->LRU_list_mutex);
if (UNIV_LIKELY_NULL(block)) {
/* We can release hash_lock after we
@ -3055,15 +3066,19 @@ got_block:
if (buf_LRU_free_page(&fix_block->page, true)) {
mutex_exit(fix_mutex);
rw_lock_x_lock(hash_lock);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
mutex_enter(&buf_pool->LRU_list_mutex);
rw_lock_x_lock(hash_lock);
/* Set the watch, as it would have
been set if the page were not in the
buffer pool in the first place. */
block = (buf_block_t*) buf_pool_watch_set(
space, offset, fold);
mutex_exit(&buf_pool->LRU_list_mutex);
} else {
rw_lock_x_lock(hash_lock);
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
}

View file

@ -831,39 +831,35 @@ buf_flush_init_for_writing(
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
checksum = buf_calc_page_crc32(page);
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
break;
case SRV_CHECKSUM_ALGORITHM_INNODB:
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
checksum = (ib_uint32_t) buf_calc_page_new_checksum(page);
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
checksum = (ib_uint32_t) buf_calc_page_old_checksum(page);
break;
case SRV_CHECKSUM_ALGORITHM_NONE:
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
checksum = BUF_NO_CHECKSUM_MAGIC;
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
break;
/* no default so the compiler will emit a warning if new enum
is added and not handled here */
}
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
/* With the InnoDB checksum, we overwrite the first 4 bytes of
the end lsn field to store the old formula checksum. Since it
depends also on the field FIL_PAGE_SPACE_OR_CHKSUM, it has to
be calculated after storing the new formula checksum.
/* We overwrite the first 4 bytes of the end lsn field to store
the old formula checksum. Since it depends also on the field
FIL_PAGE_SPACE_OR_CHKSUM, it has to be calculated after storing the
new formula checksum. */
if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB
|| srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) {
checksum = (ib_uint32_t) buf_calc_page_old_checksum(page);
/* In other cases we use the value assigned from above.
If CRC32 is used then it is faster to use that checksum
(calculated above) instead of calculating another one.
We can afford to store something other than
buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in
this field because the file will not be readable by old
versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */
}
In other cases we write the same value to both fields.
If CRC32 is used then it is faster to use that checksum
(calculated above) instead of calculating another one.
We can afford to store something other than
buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in
this field because the file will not be readable by old
versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
checksum);

View file

@ -39,6 +39,16 @@ UNIV_INTERN dict_index_t* dict_ind_redundant;
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
UNIV_INTERN dict_index_t* dict_ind_compact;
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
extern UNIV_INTERN uint ibuf_debug;
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
/**********************************************************************
Issue a warning that the row is too big. */
void
ib_warn_row_too_big(const dict_table_t* table);
#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "data0type.h"
@ -2410,11 +2420,18 @@ dict_index_add_to_cache(
new_index->n_fields = new_index->n_def;
new_index->trx_id = index->trx_id;
if (strict && dict_index_too_big_for_tree(table, new_index)) {
if (dict_index_too_big_for_tree(table, new_index)) {
if (strict) {
too_big:
dict_mem_index_free(new_index);
dict_mem_index_free(index);
return(DB_TOO_BIG_RECORD);
dict_mem_index_free(new_index);
dict_mem_index_free(index);
return(DB_TOO_BIG_RECORD);
} else {
ib_warn_row_too_big(table);
}
}
if (dict_index_is_univ(index)) {
@ -5725,11 +5742,11 @@ dict_set_corrupted(
dict_index_copy_types(tuple, sys_index, 2);
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_GE,
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_LE,
BTR_MODIFY_LEAF,
&cursor, 0, __FILE__, __LINE__, &mtr);
if (cursor.up_match == dtuple_get_n_fields(tuple)) {
if (cursor.low_match == dtuple_get_n_fields(tuple)) {
/* UPDATE SYS_INDEXES SET TYPE=index->type
WHERE TABLE_ID=index->table->id AND INDEX_ID=index->id */
ulint len;

View file

@ -1973,7 +1973,8 @@ UNIV_INTERN
ibool
fil_inc_pending_ops(
/*================*/
ulint id) /*!< in: space id */
ulint id, /*!< in: space id */
ibool print_err) /*!< in: need to print error or not */
{
fil_space_t* space;
@ -1982,10 +1983,12 @@ fil_inc_pending_ops(
space = fil_space_get_by_id(id);
if (space == NULL) {
fprintf(stderr,
"InnoDB: Error: trying to do an operation on a"
" dropped tablespace %lu\n",
(ulong) id);
if (print_err) {
fprintf(stderr,
"InnoDB: Error: trying to do an operation on a"
" dropped tablespace %lu\n",
(ulong) id);
}
}
if (space == NULL || space->stop_new_ops) {
@ -4134,7 +4137,18 @@ fil_load_single_table_tablespace(
/* Build up the tablename in the standard form database/table. */
tablename = static_cast<char*>(
mem_alloc(dbname_len + filename_len + 2));
sprintf(tablename, "%s/%s", dbname, filename);
/* When lower_case_table_names = 2 it is possible that the
dbname is in upper case ,but while storing it in fil_space_t
we must convert it into lower case */
sprintf(tablename, "%s" , dbname);
tablename[dbname_len] = '\0';
if (lower_case_file_system) {
dict_casedn_str(tablename);
}
sprintf(tablename+dbname_len,"/%s",filename);
tablename_len = strlen(tablename) - strlen(".ibd");
tablename[tablename_len] = '\0';

View file

@ -36,6 +36,7 @@ Full Text Search interface
#include "dict0priv.h"
#include "dict0stats.h"
#include "btr0pcur.h"
#include <vector>
#include "ha_prototypes.h"
@ -899,12 +900,14 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache->words) {
fts_words_free(index_cache->words);
rbt_free(index_cache->words);
}
if (index_cache != NULL) {
if (index_cache->words) {
fts_words_free(index_cache->words);
rbt_free(index_cache->words);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
ib_vector_remove(cache->indexes, *(void**) index_cache);
}
if (cache->get_docs) {
fts_reset_get_doc(cache);
@ -1255,7 +1258,8 @@ fts_tokenizer_word_get(
#endif
/* If it is a stopword, do not index it */
if (rbt_search(cache->stopword_info.cached_stopword,
if (cache->stopword_info.cached_stopword != NULL
&& rbt_search(cache->stopword_info.cached_stopword,
&parent, text) == 0) {
return(NULL);
@ -3558,6 +3562,12 @@ fts_add_doc_by_id(
rw_lock_x_lock(&table->fts->cache->lock);
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL,
NULL, TRUE, TRUE);
}
fts_cache_add_doc(
table->fts->cache,
get_doc->index_cache,
@ -6072,8 +6082,6 @@ fts_update_hex_format_flag(
return (err);
}
#ifdef _WIN32
/*********************************************************************//**
Rename an aux table to HEX format. It's called when "%016llu" is used
to format an object id in table name, which only happens in Windows. */
@ -6170,8 +6178,8 @@ This function should make sure that either all the parent table and aux tables
are set DICT_TF2_FTS_AUX_HEX_NAME with flags2 or none of them are set */
static __attribute__((nonnull, warn_unused_result))
dberr_t
fts_rename_aux_tables_to_hex_format(
/*================================*/
fts_rename_aux_tables_to_hex_format_low(
/*====================================*/
trx_t* trx, /*!< in: transaction */
dict_table_t* parent_table, /*!< in: parent table */
ib_vector_t* tables) /*!< in: aux tables to rename. */
@ -6295,12 +6303,14 @@ fts_rename_aux_tables_to_hex_format(
"table %s. Please revert manually.",
table->name);
fts_sql_rollback(trx_bg);
trx_free_for_background(trx_bg);
/* Continue to clear aux tables' flags2 */
not_rename = true;
continue;
}
fts_sql_commit(trx_bg);
trx_free_for_background(trx_bg);
}
DICT_TF2_FLAG_UNSET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
@ -6324,7 +6334,11 @@ fts_fake_hex_to_dec(
ret = sprintf(tmp_id, UINT64PFx, id);
ut_ad(ret == 16);
#ifdef _WIN32
ret = sscanf(tmp_id, "%016llu", &dec_id);
#else
ret = sscanf(tmp_id, "%016"PRIu64, &dec_id);
#endif /* _WIN32 */
ut_ad(ret == 1);
return dec_id;
@ -6346,7 +6360,293 @@ fts_check_aux_table_parent_id_cmp(
return static_cast<int>(fa1->parent_id - fa2->parent_id);
}
#endif /* _WIN32 */
/** Mark all the fts index associated with the parent table as corrupted.
@param[in] trx transaction
@param[in, out] parent_table fts index associated with this parent table
will be marked as corrupted. */
static
void
fts_parent_all_index_set_corrupt(
trx_t* trx,
dict_table_t* parent_table)
{
fts_t* fts = parent_table->fts;
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
}
for (ulint j = 0; j < ib_vector_size(fts->indexes); j++) {
dict_index_t* index = static_cast<dict_index_t*>(
ib_vector_getp_const(fts->indexes, j));
dict_set_corrupted(index,
trx, "DROP ORPHANED TABLE");
}
}
/** Mark the fts index which index id matches the id as corrupted.
@param[in] trx transaction
@param[in] id index id to search
@param[in, out] parent_table parent table to check with all
the index. */
static
void
fts_set_index_corrupt(
trx_t* trx,
index_id_t id,
dict_table_t* table)
{
fts_t* fts = table->fts;
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
}
for (ulint j = 0; j < ib_vector_size(fts->indexes); j++) {
dict_index_t* index = static_cast<dict_index_t*>(
ib_vector_getp_const(fts->indexes, j));
if (index->id == id) {
dict_set_corrupted(index, trx,
"DROP ORPHANED TABLE");
break;
}
}
}
/** Check the index for the aux table is corrupted.
@param[in] aux_table auxiliary table
@retval nonzero if index is corrupted, zero for valid index */
static
ulint
fts_check_corrupt_index(
fts_aux_table_t* aux_table)
{
dict_table_t* table;
dict_index_t* index;
table = dict_table_open_on_id(
aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
if (table == NULL) {
return(0);
}
for (index = UT_LIST_GET_FIRST(table->indexes);
index;
index = UT_LIST_GET_NEXT(indexes, index)) {
if (index->id == aux_table->index_id) {
ut_ad(index->type & DICT_FTS);
dict_table_close(table, true, false);
return(dict_index_is_corrupted(index));
}
}
dict_table_close(table, true, false);
return(0);
}
/** Check the validity of the parent table.
@param[in] aux_table auxiliary table
@return true if it is a valid table or false if it is not */
static
bool
fts_valid_parent_table(
const fts_aux_table_t* aux_table)
{
dict_table_t* parent_table;
bool valid = false;
parent_table = dict_table_open_on_id(
aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
if (parent_table != NULL && parent_table->fts != NULL) {
if (aux_table->index_id == 0) {
valid = true;
} else {
index_id_t id = aux_table->index_id;
dict_index_t* index;
/* Search for the FT index in the table's list. */
for (index = UT_LIST_GET_FIRST(parent_table->indexes);
index;
index = UT_LIST_GET_NEXT(indexes, index)) {
if (index->id == id) {
valid = true;
break;
}
}
}
}
if (parent_table) {
dict_table_close(parent_table, TRUE, FALSE);
}
return(valid);
}
/** Try to rename all aux tables of the specified parent table.
@param[in] aux_tables aux_tables to be renamed
@param[in] parent_table parent table of all aux
tables stored in tables. */
static
void
fts_rename_aux_tables_to_hex_format(
ib_vector_t* aux_tables,
dict_table_t* parent_table)
{
dberr_t err;
trx_t* trx_rename = trx_allocate_for_background();
trx_rename->op_info = "Rename aux tables to hex format";
trx_rename->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_rename, TRX_DICT_OP_TABLE);
err = fts_rename_aux_tables_to_hex_format_low(trx_rename,
parent_table, aux_tables);
trx_rename->dict_operation_lock_mode = 0;
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_WARN,
"Rollback operations on all aux tables of table %s. "
"All the fts index associated with the table are "
"marked as corrupted. Please rebuild the "
"index again.", parent_table->name);
fts_sql_rollback(trx_rename);
/* Corrupting the fts index related to parent table. */
trx_t* trx_corrupt;
trx_corrupt = trx_allocate_for_background();
trx_corrupt->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_corrupt, TRX_DICT_OP_TABLE);
fts_parent_all_index_set_corrupt(trx_corrupt, parent_table);
trx_corrupt->dict_operation_lock_mode = 0;
fts_sql_commit(trx_corrupt);
trx_free_for_background(trx_corrupt);
} else {
fts_sql_commit(trx_rename);
}
trx_free_for_background(trx_rename);
ib_vector_reset(aux_tables);
}
/** Set the hex format flag for the parent table.
@param[in, out] parent_table parent table
@param[in] trx transaction */
static
void
fts_set_parent_hex_format_flag(
dict_table_t* parent_table,
trx_t* trx)
{
if (!DICT_TF2_FLAG_IS_SET(parent_table,
DICT_TF2_FTS_AUX_HEX_NAME)) {
DBUG_EXECUTE_IF("parent_table_flag_fail",
ib_logf(IB_LOG_LEVEL_FATAL,
"Setting parent table %s to hex format "
"failed. Please try to restart the server "
"again, if it doesn't work, the system "
"tables might be corrupted.",
parent_table->name);
return;);
dberr_t err = fts_update_hex_format_flag(
trx, parent_table->id, true);
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_FATAL,
"Setting parent table %s to hex format "
"failed. Please try to restart the server "
"again, if it doesn't work, the system "
"tables might be corrupted.",
parent_table->name);
} else {
DICT_TF2_FLAG_SET(
parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
}
}
}
/** Drop the obsolete auxilary table.
@param[in] tables tables to be dropped. */
static
void
fts_drop_obsolete_aux_table_from_vector(
ib_vector_t* tables)
{
dberr_t err;
for (ulint count = 0; count < ib_vector_size(tables);
++count) {
fts_aux_table_t* aux_drop_table;
aux_drop_table = static_cast<fts_aux_table_t*>(
ib_vector_get(tables, count));
trx_t* trx_drop = trx_allocate_for_background();
trx_drop->op_info = "Drop obsolete aux tables";
trx_drop->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_drop, TRX_DICT_OP_TABLE);
err = row_drop_table_for_mysql(
aux_drop_table->name, trx_drop, false, true);
trx_drop->dict_operation_lock_mode = 0;
if (err != DB_SUCCESS) {
/* We don't need to worry about the
failure, since server would try to
drop it on next restart, even if
the table was broken. */
ib_logf(IB_LOG_LEVEL_WARN,
"Fail to drop obsolete aux table '%s', which "
"is harmless. will try to drop it on next "
"restart.", aux_drop_table->name);
fts_sql_rollback(trx_drop);
} else {
ib_logf(IB_LOG_LEVEL_INFO,
"Dropped obsolete aux table '%s'.",
aux_drop_table->name);
fts_sql_commit(trx_drop);
}
trx_free_for_background(trx_drop);
}
}
/** Drop all the auxiliary table present in the vector.
@param[in] trx transaction
@param[in] tables tables to be dropped */
static
void
fts_drop_aux_table_from_vector(
trx_t* trx,
ib_vector_t* tables)
{
for (ulint count = 0; count < ib_vector_size(tables);
++count) {
fts_aux_table_t* aux_drop_table;
aux_drop_table = static_cast<fts_aux_table_t*>(
ib_vector_get(tables, count));
/* Check for the validity of the parent table */
if (!fts_valid_parent_table(aux_drop_table)) {
ib_logf(IB_LOG_LEVEL_WARN,
"Parent table of FTS auxiliary table %s not "
"found.", aux_drop_table->name);
dberr_t err = fts_drop_table(trx, aux_drop_table->name);
if (err == DB_FAIL) {
char* path = fil_make_ibd_name(
aux_drop_table->name, false);
os_file_delete_if_exists(innodb_file_data_key,
path);
mem_free(path);
}
}
}
}
/**********************************************************************//**
Check and drop all orphaned FTS auxiliary tables, those that don't have
@ -6359,9 +6659,12 @@ fts_check_and_drop_orphaned_tables(
trx_t* trx, /*!< in: transaction */
ib_vector_t* tables) /*!< in: tables to check */
{
#ifdef _WIN32
mem_heap_t* heap;
ib_vector_t* aux_tables_to_rename;
ib_vector_t* invalid_aux_tables;
ib_vector_t* valid_aux_tables;
ib_vector_t* drop_aux_tables;
ib_vector_t* obsolete_aux_tables;
ib_alloc_t* heap_alloc;
heap = mem_heap_create(1024);
@ -6372,38 +6675,99 @@ fts_check_and_drop_orphaned_tables(
aux_tables_to_rename = ib_vector_create(heap_alloc,
sizeof(fts_aux_table_t), 128);
/* We store all fake auxiliary table and orphaned table here. */
invalid_aux_tables = ib_vector_create(heap_alloc,
sizeof(fts_aux_table_t), 128);
/* We store all valid aux tables. We use this to filter the
fake auxiliary table from invalid auxiliary tables. */
valid_aux_tables = ib_vector_create(heap_alloc,
sizeof(fts_aux_table_t), 128);
/* We store all auxiliary tables to be dropped. */
drop_aux_tables = ib_vector_create(heap_alloc,
sizeof(fts_aux_table_t), 128);
/* We store all obsolete auxiliary tables to be dropped. */
obsolete_aux_tables = ib_vector_create(heap_alloc,
sizeof(fts_aux_table_t), 128);
/* Sort by parent_id first, in case rename will fail */
ib_vector_sort(tables, fts_check_aux_table_parent_id_cmp);
#endif /* _WIN32 */
for (ulint i = 0; i < ib_vector_size(tables); ++i) {
dict_table_t* parent_table;
fts_aux_table_t* aux_table;
bool drop = false;
#ifdef _WIN32
dict_table_t* table;
fts_aux_table_t* next_aux_table = NULL;
ib_id_t orig_parent_id = 0;
ib_id_t orig_index_id = 0;
bool rename = false;
#endif /* _WIN32 */
aux_table = static_cast<fts_aux_table_t*>(
ib_vector_get(tables, i));
#ifdef _WIN32
table = dict_table_open_on_id(
aux_table->id, TRUE, DICT_TABLE_OP_NORMAL);
orig_parent_id = aux_table->parent_id;
orig_index_id = aux_table->index_id;
if (table == NULL || strcmp(table->name, aux_table->name)) {
/* Skip these aux tables, which are common tables
with wrong table ids */
if (table) {
bool fake_aux = false;
if (table != NULL) {
dict_table_close(table, TRUE, FALSE);
}
continue;
if (i + 1 < ib_vector_size(tables)) {
next_aux_table = static_cast<fts_aux_table_t*>(
ib_vector_get(tables, i + 1));
}
/* To know whether aux table is fake fts or
orphan fts table. */
for (ulint count = 0;
count < ib_vector_size(valid_aux_tables);
count++) {
fts_aux_table_t* valid_aux;
valid_aux = static_cast<fts_aux_table_t*>(
ib_vector_get(valid_aux_tables, count));
if (strcmp(valid_aux->name,
aux_table->name) == 0) {
fake_aux = true;
break;
}
}
/* All aux tables of parent table, whose id is
last_parent_id, have been checked, try to rename
them if necessary. */
if ((next_aux_table == NULL
|| orig_parent_id != next_aux_table->parent_id)
&& (!ib_vector_is_empty(aux_tables_to_rename))) {
ulint parent_id = fts_fake_hex_to_dec(
aux_table->parent_id);
parent_table = dict_table_open_on_id(
parent_id, TRUE,
DICT_TABLE_OP_NORMAL);
fts_rename_aux_tables_to_hex_format(
aux_tables_to_rename, parent_table);
dict_table_close(parent_table, TRUE,
FALSE);
}
/* If the aux table is fake aux table. Skip it. */
if (!fake_aux) {
ib_vector_push(invalid_aux_tables, aux_table);
}
continue;
} else if (!DICT_TF2_FLAG_IS_SET(table,
DICT_TF2_FTS_AUX_HEX_NAME)) {
@ -6416,65 +6780,99 @@ fts_check_and_drop_orphaned_tables(
}
ut_ad(aux_table->id > aux_table->parent_id);
rename = true;
/* Check whether parent table id and index id
are stored as decimal format. */
if (fts_valid_parent_table(aux_table)) {
parent_table = dict_table_open_on_id(
aux_table->parent_id, true,
DICT_TABLE_OP_NORMAL);
ut_ad(parent_table != NULL);
ut_ad(parent_table->fts != NULL);
if (!DICT_TF2_FLAG_IS_SET(
parent_table,
DICT_TF2_FTS_AUX_HEX_NAME)) {
rename = true;
}
dict_table_close(parent_table, TRUE, FALSE);
}
if (!rename) {
/* Reassign the original value of
aux table if it is not in decimal format */
aux_table->parent_id = orig_parent_id;
aux_table->index_id = orig_index_id;
}
}
if (table) {
dict_table_close(table, TRUE, FALSE);
if (table != NULL) {
dict_table_close(table, true, false);
}
if (!rename) {
/* Check the validity of the parent table. */
if (!fts_valid_parent_table(aux_table)) {
drop = true;
}
}
/* Filter out the fake aux table by comparing with the
current valid auxiliary table name . */
for (ulint count = 0;
count < ib_vector_size(invalid_aux_tables); count++) {
fts_aux_table_t* invalid_aux;
invalid_aux = static_cast<fts_aux_table_t*>(
ib_vector_get(invalid_aux_tables, count));
if (strcmp(invalid_aux->name, aux_table->name) == 0) {
ib_vector_remove(
invalid_aux_tables,
*reinterpret_cast<void**>(invalid_aux));
break;
}
}
ib_vector_push(valid_aux_tables, aux_table);
/* If the index associated with aux table is corrupted,
skip it. */
if (fts_check_corrupt_index(aux_table) > 0) {
if (i + 1 < ib_vector_size(tables)) {
next_aux_table = static_cast<fts_aux_table_t*>(
ib_vector_get(tables, i + 1));
}
if (next_aux_table == NULL
|| orig_parent_id != next_aux_table->parent_id) {
parent_table = dict_table_open_on_id(
aux_table->parent_id, TRUE,
DICT_TABLE_OP_NORMAL);
if (!ib_vector_is_empty(aux_tables_to_rename)) {
fts_rename_aux_tables_to_hex_format(
aux_tables_to_rename, parent_table);
} else {
fts_set_parent_hex_format_flag(
parent_table, trx);
}
dict_table_close(parent_table, TRUE, FALSE);
}
continue;
}
#endif /* _WIN32 */
parent_table = dict_table_open_on_id(
aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
if (parent_table == NULL || parent_table->fts == NULL) {
drop = true;
} else if (aux_table->index_id != 0) {
index_id_t id;
fts_t* fts;
drop = true;
fts = parent_table->fts;
id = aux_table->index_id;
/* Search for the FT index in the table's list. */
for (ulint j = 0;
j < ib_vector_size(fts->indexes);
++j) {
const dict_index_t* index;
index = static_cast<const dict_index_t*>(
ib_vector_getp_const(fts->indexes, j));
if (index->id == id) {
drop = false;
break;
}
}
}
if (drop) {
ib_logf(IB_LOG_LEVEL_WARN,
"Parent table of FTS auxiliary table %s not "
"found.", aux_table->name);
dberr_t err = fts_drop_table(trx, aux_table->name);
if (err == DB_FAIL) {
char* path;
path = fil_make_ibd_name(
aux_table->name, false);
os_file_delete_if_exists(innodb_file_data_key,
path);
mem_free(path);
}
ib_vector_push(drop_aux_tables, aux_table);
} else {
if (FTS_IS_OBSOLETE_AUX_TABLE(aux_table->name)) {
@ -6484,49 +6882,13 @@ fts_check_and_drop_orphaned_tables(
This could happen when we try to upgrade
from older server to later one, which doesn't
contain these obsolete tables. */
drop = true;
dberr_t err;
trx_t* trx_drop =
trx_allocate_for_background();
trx_drop->op_info = "Drop obsolete aux tables";
trx_drop->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_drop, TRX_DICT_OP_TABLE);
err = row_drop_table_for_mysql(
aux_table->name, trx_drop, false, true);
trx_drop->dict_operation_lock_mode = 0;
if (err != DB_SUCCESS) {
/* We don't need to worry about the
failure, since server would try to
drop it on next restart, even if
the table was broken. */
ib_logf(IB_LOG_LEVEL_WARN,
"Fail to drop obsolete aux"
" table '%s', which is"
" harmless. will try to drop"
" it on next restart.",
aux_table->name);
fts_sql_rollback(trx_drop);
} else {
ib_logf(IB_LOG_LEVEL_INFO,
"Dropped obsolete aux"
" table '%s'.",
aux_table->name);
fts_sql_commit(trx_drop);
}
trx_free_for_background(trx_drop);
ib_vector_push(obsolete_aux_tables, aux_table);
continue;
}
}
#ifdef _WIN32
/* If the aux table is in decimal format, we should
rename it, so push it to aux_tables_to_rename */
if (!drop && rename) {
ib_vector_push(aux_tables_to_rename, aux_table);
}
@ -6544,38 +6906,16 @@ fts_check_and_drop_orphaned_tables(
them if necessary. We had better use a new background
trx to rename rather than the original trx, in case
any failure would cause a complete rollback. */
dberr_t err;
trx_t* trx_rename = trx_allocate_for_background();
trx_rename->op_info = "Rename aux tables to "
"hex format";
trx_rename->dict_operation_lock_mode = RW_X_LATCH;
trx_start_for_ddl(trx_rename, TRX_DICT_OP_TABLE);
ut_ad(rename);
ut_ad(!DICT_TF2_FLAG_IS_SET(
parent_table, DICT_TF2_FTS_AUX_HEX_NAME));
err = fts_rename_aux_tables_to_hex_format(trx_rename,
parent_table, aux_tables_to_rename);
trx_rename->dict_operation_lock_mode = 0;
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_WARN,
"Rollback operations on all "
"aux tables of table %s. "
"Please check why renaming aux tables "
"failed, and restart the server to "
"upgrade again to "
"get the table work.",
parent_table->name);
fts_sql_rollback(trx_rename);
} else {
fts_sql_commit(trx_rename);
}
trx_free_for_background(trx_rename);
ib_vector_reset(aux_tables_to_rename);
fts_rename_aux_tables_to_hex_format(
aux_tables_to_rename,parent_table);
}
#else /* _WIN32 */
if (!drop) {
/* The IDs are already in correct hex format. */
if (!drop && !rename) {
dict_table_t* table;
table = dict_table_open_on_id(
@ -6590,6 +6930,16 @@ fts_check_and_drop_orphaned_tables(
&& !DICT_TF2_FLAG_IS_SET(
table,
DICT_TF2_FTS_AUX_HEX_NAME)) {
DBUG_EXECUTE_IF("aux_table_flag_fail",
ib_logf(IB_LOG_LEVEL_WARN,
"Setting aux table %s to hex "
"format failed.", table->name);
fts_set_index_corrupt(
trx, aux_table->index_id,
parent_table);
goto table_exit;);
dberr_t err = fts_update_hex_format_flag(
trx, table->id, true);
@ -6597,49 +6947,44 @@ fts_check_and_drop_orphaned_tables(
ib_logf(IB_LOG_LEVEL_WARN,
"Setting aux table %s to hex "
"format failed.", table->name);
fts_set_index_corrupt(
trx, aux_table->index_id,
parent_table);
} else {
DICT_TF2_FLAG_SET(table,
DICT_TF2_FTS_AUX_HEX_NAME);
}
}
#ifndef DBUG_OFF
table_exit:
#endif /* !DBUG_OFF */
if (table != NULL) {
dict_table_close(table, TRUE, FALSE);
}
ut_ad(parent_table != NULL);
if (!DICT_TF2_FLAG_IS_SET(parent_table,
DICT_TF2_FTS_AUX_HEX_NAME)) {
dberr_t err = fts_update_hex_format_flag(
trx, parent_table->id, true);
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_WARN,
"Setting parent table %s of "
"FTS auxiliary %s to hex "
"format failed.",
parent_table->name,
aux_table->name);
} else {
DICT_TF2_FLAG_SET(parent_table,
DICT_TF2_FTS_AUX_HEX_NAME);
}
}
fts_set_parent_hex_format_flag(
parent_table, trx);
}
#endif /* _WIN32 */
if (parent_table) {
if (parent_table != NULL) {
dict_table_close(parent_table, TRUE, FALSE);
}
}
#ifdef _WIN32
fts_drop_aux_table_from_vector(trx, invalid_aux_tables);
fts_drop_aux_table_from_vector(trx, drop_aux_tables);
fts_sql_commit(trx);
fts_drop_obsolete_aux_table_from_vector(obsolete_aux_tables);
/* Free the memory allocated at the beginning */
if (heap != NULL) {
mem_heap_free(heap);
}
#endif /* _WIN32 */
}
/**********************************************************************//**
@ -6738,7 +7083,6 @@ fts_drop_orphaned_tables(void)
if (error == DB_SUCCESS) {
fts_check_and_drop_orphaned_tables(trx, tables);
fts_sql_commit(trx);
break; /* Exit the loop. */
} else {
ib_vector_reset(tables);

View file

@ -190,6 +190,8 @@ cycle for a table. */
struct fts_slot_t {
dict_table_t* table; /*!< Table to optimize */
table_id_t table_id; /*!< Table id */
fts_state_t state; /*!< State of this slot */
ulint added; /*!< Number of doc ids added since the
@ -2575,6 +2577,8 @@ fts_optimize_add_table(
return;
}
ut_ad(table->cached && table->fts != NULL);
/* Make sure table with FTS index cannot be evicted */
if (table->can_be_evicted) {
dict_table_move_from_lru_to_non_lru(table);
@ -2741,6 +2745,7 @@ fts_optimize_new_table(
memset(slot, 0x0, sizeof(*slot));
slot->table = table;
slot->table_id = table->id;
slot->state = FTS_STATE_LOADED;
slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS;
@ -2865,7 +2870,8 @@ fts_is_sync_needed(
slot = static_cast<const fts_slot_t*>(
ib_vector_get_const(tables, i));
if (slot->table && slot->table->fts) {
if (slot->state != FTS_STATE_EMPTY && slot->table
&& slot->table->fts) {
total_memory += slot->table->fts->cache->total_size;
}
@ -2948,6 +2954,7 @@ fts_optimize_thread(
ib_wqueue_t* wq = (ib_wqueue_t*) arg;
ut_ad(!srv_read_only_mode);
my_thread_init();
heap = mem_heap_create(sizeof(dict_table_t*) * 64);
heap_alloc = ib_heap_allocator_create(heap);
@ -3076,9 +3083,11 @@ fts_optimize_thread(
if (slot->state != FTS_STATE_EMPTY) {
dict_table_t* table = NULL;
table = dict_table_open_on_name(
slot->table->name, FALSE, FALSE,
DICT_ERR_IGNORE_INDEX_ROOT);
/*slot->table may be freed, so we try to open
table by slot->table_id.*/
table = dict_table_open_on_id(
slot->table_id, FALSE,
DICT_TABLE_OP_NORMAL);
if (table) {
@ -3101,6 +3110,7 @@ fts_optimize_thread(
ib_logf(IB_LOG_LEVEL_INFO, "FTS optimize thread exiting.");
os_event_set(exit_event);
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */

View file

@ -3273,7 +3273,8 @@ innobase_init(
innobase_hton->flush_logs = innobase_flush_logs;
innobase_hton->show_status = innobase_show_status;
innobase_hton->flags = HTON_SUPPORTS_EXTENDED_KEYS;
innobase_hton->flags = HTON_SUPPORTS_EXTENDED_KEYS |
HTON_SUPPORTS_FOREIGN_KEYS;
innobase_hton->release_temporary_latches =
innobase_release_temporary_latches;
@ -13091,6 +13092,7 @@ ha_innobase::start_stmt(
thr_lock_type lock_type)
{
trx_t* trx;
DBUG_ENTER("ha_innobase::start_stmt");
update_thd(thd);
@ -13114,6 +13116,29 @@ ha_innobase::start_stmt(
prebuilt->hint_need_to_fetch_extra_cols = 0;
reset_template();
if (dict_table_is_temporary(prebuilt->table)
&& prebuilt->mysql_has_locked
&& prebuilt->select_lock_type == LOCK_NONE) {
dberr_t error;
switch (thd_sql_command(thd)) {
case SQLCOM_INSERT:
case SQLCOM_UPDATE:
case SQLCOM_DELETE:
init_table_handle_for_HANDLER();
prebuilt->select_lock_type = LOCK_X;
prebuilt->stored_select_lock_type = LOCK_X;
error = row_lock_table_for_mysql(prebuilt, NULL, 1);
if (error != DB_SUCCESS) {
int st = convert_error_code_to_mysql(
error, 0, thd);
DBUG_RETURN(st);
}
break;
}
}
if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside
this same LOCK TABLES; since MySQL does NOT call external_lock
@ -13151,7 +13176,7 @@ ha_innobase::start_stmt(
++trx->will_lock;
}
return(0);
DBUG_RETURN(0);
}
/******************************************************************//**
@ -18893,3 +18918,27 @@ bool ha_innobase::is_thd_killed()
return thd_kill_level(user_thd);
}
/**********************************************************************
Issue a warning that the row is too big. */
void
ib_warn_row_too_big(const dict_table_t* table)
{
/* If prefix is true then a 768-byte prefix is stored
locally for BLOB fields. Refer to dict_table_get_format() */
const bool prefix = (dict_tf_get_format(table->flags)
== UNIV_FORMAT_A);
const ulint free_space = page_get_free_space_of_empty(
table->flags & DICT_TF_COMPACT) / 2;
THD* thd = current_thd;
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_TO_BIG_ROW,
"Row size too large (> %lu). Changing some columns to TEXT"
" or BLOB %smay help. In current row format, BLOB prefix of"
" %d bytes is stored inline.", free_space
, prefix ? "or using ROW_FORMAT=DYNAMIC or"
" ROW_FORMAT=COMPRESSED ": ""
, prefix ? DICT_MAX_FIXED_COL_LEN : 0);
}

View file

@ -3374,9 +3374,7 @@ ha_innobase::prepare_inplace_alter_table(
ulint fts_doc_col_no = ULINT_UNDEFINED;
bool add_fts_doc_id = false;
bool add_fts_doc_id_idx = false;
#ifdef _WIN32
bool add_fts_idx = false;
#endif /* _WIN32 */
DBUG_ENTER("prepare_inplace_alter_table");
DBUG_ASSERT(!ha_alter_info->handler_ctx);
@ -3525,9 +3523,7 @@ check_if_ok_to_rename:
& ~(HA_FULLTEXT
| HA_PACK_KEY
| HA_BINARY_PACK_KEY)));
#ifdef _WIN32
add_fts_idx = true;
#endif /* _WIN32 */
continue;
}
@ -3538,19 +3534,16 @@ check_if_ok_to_rename:
}
}
#ifdef _WIN32
/* We won't be allowed to add fts index to a table with
fts indexes already but without AUX_HEX_NAME set.
This means the aux tables of the table failed to
rename to hex format but new created aux tables
shall be in hex format, which is contradictory.
It's only for Windows. */
shall be in hex format, which is contradictory. */
if (!DICT_TF2_FLAG_IS_SET(indexed_table, DICT_TF2_FTS_AUX_HEX_NAME)
&& indexed_table->fts != NULL && add_fts_idx) {
my_error(ER_INNODB_FT_AUX_NOT_HEX_ID, MYF(0));
goto err_exit_no_heap;
}
#endif /* _WIN32 */
/* Check existing index definitions for too-long column
prefixes as well, in case max_col_len shrunk. */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -4660,7 +4660,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
tablespace_being_deleted = fil_inc_pending_ops(space);
tablespace_being_deleted = fil_inc_pending_ops(space, true);
if (UNIV_UNLIKELY(tablespace_being_deleted)) {
/* Do not try to read the bitmap page from space;

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -28,7 +28,7 @@ Created 10/16/1994 Heikki Tuuri
#ifdef UNIV_DEBUG
# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\
if (btr_cur_limit_optimistic_insert_debug\
if (btr_cur_limit_optimistic_insert_debug > 1\
&& (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\
CODE;\
}

View file

@ -1367,7 +1367,10 @@ buf_pool_watch_is_sentinel(
const buf_page_t* bpage) /*!< in: block */
__attribute__((nonnull, warn_unused_result));
/****************************************************************//**
Add watch for the given page to be read in. Caller must have the buffer pool
Add watch for the given page to be read in. Caller must have
appropriate hash_lock for the bpage and hold the LRU list mutex to avoid a race
condition with buf_LRU_free_page inserting the same page into the page hash.
This function may release the hash_lock and reacquire it.
@return NULL if watch set, block if the page is in the buffer pool */
UNIV_INTERN
buf_page_t*

View file

@ -85,7 +85,7 @@ dict_get_referenced_table(
mem_heap_t* heap); /*!< in: heap memory */
/*********************************************************************//**
Frees a foreign key struct. */
UNIV_INTERN
void
dict_foreign_free(
/*==============*/

View file

@ -43,6 +43,7 @@ Created 10/25/1995 Heikki Tuuri
#include <list>
extern my_bool lower_case_file_system;
// Forward declaration
struct trx_t;
struct fil_space_t;
@ -586,7 +587,8 @@ UNIV_INTERN
ibool
fil_inc_pending_ops(
/*================*/
ulint id); /*!< in: space id */
ulint id, /*!< in: space id */
ibool print_err); /*!< in: need to print error or not */
/*******************************************************************//**
Decrements the count of pending operations. */
UNIV_INTERN

View file

@ -37,18 +37,38 @@ fts_write_object_id(
/* in: true for fixed hex format,
false for old ambiguous format */
{
#ifdef _WIN32
/* Use this to construct old(5.6.14 and 5.7.3) ambiguous
aux table names */
DBUG_EXECUTE_IF("innodb_test_wrong_non_windows_fts_aux_table_name",
return(sprintf(str, UINT64PFx, id)););
/* Use this to construct old(5.6.14 and 5.7.3) windows
ambiguous aux table names */
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
return(sprintf(str, "%016llu", id)););
#else /* _WIN32 */
/* Use this to construct old(5.6.14 and 5.7.3) windows
ambiguous aux table names */
DBUG_EXECUTE_IF("innodb_test_wrong_windows_fts_aux_table_name",
return(sprintf(str, "%016"PRIu64, id)););
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
return(sprintf(str, UINT64PFx, id)););
#endif /* _WIN32 */
/* As above, but this is only for those tables failing to rename. */
if (!hex_format) {
#ifdef _WIN32
// FIXME: Use ut_snprintf(), so does following one.
return(sprintf(str, "%016llu", id));
}
#else /* _WIN32 */
return(sprintf(str, "%016"PRIu64, id));
#endif /* _WIN32 */
}
return(sprintf(str, UINT64PFx, id));
}

View file

@ -233,7 +233,7 @@ trx_undo_report_row_operation(
inserted undo log record,
0 if BTR_NO_UNDO_LOG
flag was specified */
__attribute__((nonnull(3,4,10), warn_unused_result));
__attribute__((nonnull(4,10), warn_unused_result));
/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
the undo log record exists.

View file

@ -44,10 +44,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
#define INNODB_VERSION_BUGFIX 21
#define INNODB_VERSION_BUGFIX 22
#ifndef PERCONA_INNODB_VERSION
#define PERCONA_INNODB_VERSION 70.0
#define PERCONA_INNODB_VERSION 71.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
@ -121,6 +121,10 @@ if we are compiling on Windows. */
# include <sched.h>
# endif
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# endif
/* We only try to do explicit inlining of functions with gcc and
Sun Studio */

View file

@ -5535,6 +5535,7 @@ loop:
ulint space = lock->un_member.rec_lock.space;
ulint zip_size= fil_space_get_zip_size(space);
ulint page_no = lock->un_member.rec_lock.page_no;
ibool tablespace_being_deleted = FALSE;
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
@ -5555,14 +5556,31 @@ loop:
if (srv_show_verbose_locks) {
mtr_start(&mtr);
DEBUG_SYNC_C("innodb_monitor_before_lock_page_read");
buf_page_get_gen(space, zip_size, page_no,
RW_NO_LATCH, NULL,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr);
/* Check if the space is exists or not. only
when the space is valid, try to get the page. */
tablespace_being_deleted
= fil_inc_pending_ops(space, false);
mtr_commit(&mtr);
if (!tablespace_being_deleted) {
mtr_start(&mtr);
buf_page_get_gen(space, zip_size,
page_no, RW_NO_LATCH,
NULL,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__,
&mtr);
mtr_commit(&mtr);
fil_decr_pending_ops(space);
} else {
fprintf(file, "RECORD LOCKS on"
" non-existing space %lu\n",
(ulong) space);
}
}
load_page_first = FALSE;
@ -5990,7 +6008,7 @@ lock_rec_block_validate(
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
if (!fil_inc_pending_ops(space)) {
if (!fil_inc_pending_ops(space, true)) {
mtr_start(&mtr);
block = buf_page_get_gen(
space, fil_space_get_zip_size(space),
@ -6090,6 +6108,7 @@ lock_rec_insert_check_and_lock(
ut_ad(!dict_index_is_online_ddl(index)
|| dict_index_is_clust(index)
|| (flags & BTR_CREATE_FLAG));
ut_ad((flags & BTR_NO_LOCKING_FLAG) || thr);
if (flags & BTR_NO_LOCKING_FLAG) {

View file

@ -255,7 +255,7 @@ log_buffer_extend(
{
ulint move_start;
ulint move_end;
byte *tmp_buf = (byte*)alloca(OS_FILE_LOG_BLOCK_SIZE);
byte* tmp_buf = static_cast<byte *>(alloca(OS_FILE_LOG_BLOCK_SIZE));
mutex_enter(&(log_sys->mutex));
@ -3050,9 +3050,9 @@ log_archive_do(
ulint* n_bytes)/*!< out: archive log buffer size, 0 if nothing to
archive */
{
ibool calc_new_limit;
ib_uint64_t start_lsn;
ib_uint64_t limit_lsn;
ibool calc_new_limit;
lsn_t start_lsn;
lsn_t limit_lsn = LSN_MAX;
calc_new_limit = TRUE;
loop:
@ -3718,8 +3718,14 @@ loop:
lsn = log_sys->lsn;
if (lsn != log_sys->last_checkpoint_lsn
|| (srv_track_changed_pages && (tracked_lsn != log_sys->last_checkpoint_lsn))
ut_ad(srv_force_recovery != SRV_FORCE_NO_LOG_REDO
|| lsn == log_sys->last_checkpoint_lsn + LOG_BLOCK_HDR_SIZE);
if ((srv_force_recovery != SRV_FORCE_NO_LOG_REDO
&& lsn != log_sys->last_checkpoint_lsn)
|| (srv_track_changed_pages
&& (tracked_lsn != log_sys->last_checkpoint_lsn))
#ifdef UNIV_LOG_ARCHIVE
|| (srv_log_archive_on
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)

View file

@ -3097,7 +3097,8 @@ recv_recovery_from_checkpoint_start_func(
#endif /* UNIV_LOG_ARCHIVE */
byte* buf;
byte* log_hdr_buf;
byte* log_hdr_buf_base = (byte*)alloca(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
byte* log_hdr_buf_base = static_cast<byte *>
(alloca(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE));
dberr_t err;
ut_when_dtor<recv_dblwr_t> tmp(recv_sys->dblwr);

View file

@ -138,6 +138,9 @@ os_thread_create_func(
os_thread_id_t* thread_id) /*!< out: id of the created
thread, or NULL */
{
/* the new thread should look recent changes up here so far. */
os_wmb;
#ifdef __WIN__
os_thread_t thread;
DWORD win_thread_id;

View file

@ -4918,8 +4918,15 @@ page_zip_verify_checksum(
stored = static_cast<ib_uint32_t>(mach_read_from_4(
static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
/* declare empty pages non-corrupted */
if (stored == 0) {
#if FIL_PAGE_LSN % 8
#error "FIL_PAGE_LSN must be 64 bit aligned"
#endif
/* Check if page is empty */
if (stored == 0
&& *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
data)
+ FIL_PAGE_LSN) == 0) {
/* make sure that the page is really empty */
ulint i;
for (i = 0; i < size; i++) {
@ -4927,7 +4934,7 @@ page_zip_verify_checksum(
return(FALSE);
}
}
/* Empty page */
return(TRUE);
}

View file

@ -3805,6 +3805,10 @@ row_drop_table_for_mysql(
pars_info_t* info = NULL;
mem_heap_t* heap = NULL;
DBUG_ENTER("row_drop_table_for_mysql");
DBUG_PRINT("row_drop_table_for_mysql", ("table: %s", name));
ut_a(name != NULL);
if (srv_created_new_raw) {
@ -3814,7 +3818,7 @@ row_drop_table_for_mysql(
"InnoDB: Shut down mysqld and edit my.cnf so that newraw"
" is replaced with raw.\n", stderr);
return(DB_ERROR);
DBUG_RETURN(DB_ERROR);
}
/* The table name is prefixed with the database name and a '/'.
@ -4442,7 +4446,7 @@ funct_exit:
srv_wake_master_thread();
return(err);
DBUG_RETURN(err);
}
/*********************************************************************//**

View file

@ -1614,15 +1614,6 @@ srv_printf_innodb_monitor(
srv_n_system_rows_deleted_old = srv_stats.n_system_rows_deleted;
srv_n_system_rows_read_old = srv_stats.n_system_rows_read;
/* Only if lock_print_info_summary proceeds correctly,
before we call the lock_print_info_all_transactions
to print all the lock information. */
ret = lock_print_info_summary(file, nowait);
if (ret) {
lock_print_info_all_transactions(file);
}
fputs("----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n"
"============================\n", file);

View file

@ -1566,8 +1566,8 @@ innobase_start_or_create_for_mysql(void)
lsn_t min_flushed_lsn;
lsn_t max_flushed_lsn;
#ifdef UNIV_LOG_ARCHIVE
lsn_t min_arch_log_no;
lsn_t max_arch_log_no;
lsn_t min_arch_log_no = LSN_MAX;
lsn_t max_arch_log_no = LSN_MAX;
#endif /* UNIV_LOG_ARCHIVE */
ulint sum_of_new_sizes;
ulint sum_of_data_file_sizes;

View file

@ -321,6 +321,7 @@ rw_lock_free_func(
ib_mutex_t* mutex;
#endif /* !INNODB_RW_LOCKS_USE_ATOMICS */
os_rmb;
ut_ad(rw_lock_validate(lock));
ut_a(lock->lock_word == X_LOCK_DECR);