mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
InnoDB 5.6.22
This commit is contained in:
@@ -234,6 +234,8 @@ col226 text,
|
|||||||
col227 text,
|
col227 text,
|
||||||
col228 text
|
col228 text
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
Warnings:
|
||||||
|
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||||
set innodb_strict_mode = 1;
|
set innodb_strict_mode = 1;
|
||||||
alter table t1 engine=InnoDB;
|
alter table t1 engine=InnoDB;
|
||||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
|
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
|
||||||
|
@@ -2364,6 +2364,38 @@ btr_cur_pess_upd_restore_supremum(
|
|||||||
page_rec_get_heap_no(rec));
|
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
|
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
|
that mtr holds an x-latch on the tree and on the cursor page. If the
|
||||||
@@ -2579,26 +2611,14 @@ make_external:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (big_rec_vec) {
|
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 */
|
err = btr_check_blob_limit(big_rec_vec);
|
||||||
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 (err != DB_SUCCESS) {
|
||||||
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 (n_reserved > 0) {
|
if (n_reserved > 0) {
|
||||||
fil_space_release_free_extents(
|
fil_space_release_free_extents(
|
||||||
index->space, n_reserved);
|
index->space, n_reserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = DB_TOO_BIG_RECORD;
|
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4470,7 +4490,6 @@ btr_store_big_rec_extern_fields(
|
|||||||
buf_block_t** freed_pages = NULL;
|
buf_block_t** freed_pages = NULL;
|
||||||
ulint n_freed_pages = 0;
|
ulint n_freed_pages = 0;
|
||||||
dberr_t error = DB_SUCCESS;
|
dberr_t error = DB_SUCCESS;
|
||||||
ulint total_blob_len = 0;
|
|
||||||
|
|
||||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||||
ut_ad(rec_offs_any_extern(offsets));
|
ut_ad(rec_offs_any_extern(offsets));
|
||||||
@@ -4490,21 +4509,11 @@ btr_store_big_rec_extern_fields(
|
|||||||
rec_page_no = buf_block_get_page_no(rec_block);
|
rec_page_no = buf_block_get_page_no(rec_block);
|
||||||
ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
|
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 */
|
if (error != DB_SUCCESS) {
|
||||||
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) {
|
|
||||||
ut_ad(op == BTR_STORE_INSERT);
|
ut_ad(op == BTR_STORE_INSERT);
|
||||||
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data length"
|
return(error);
|
||||||
" (" 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page_zip) {
|
if (page_zip) {
|
||||||
|
@@ -564,9 +564,14 @@ buf_page_is_corrupted(
|
|||||||
checksum_field2 = mach_read_from_4(
|
checksum_field2 = mach_read_from_4(
|
||||||
read_buf + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM);
|
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 */
|
/* declare empty pages non-corrupted */
|
||||||
if (checksum_field1 == 0 && checksum_field2 == 0
|
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 */
|
/* make sure that the page is really empty */
|
||||||
for (ulint i = 0; i < UNIV_PAGE_SIZE; i++) {
|
for (ulint i = 0; i < UNIV_PAGE_SIZE; i++) {
|
||||||
if (read_buf[i] != 0) {
|
if (read_buf[i] != 0) {
|
||||||
|
@@ -837,39 +837,35 @@ buf_flush_init_for_writing(
|
|||||||
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
case SRV_CHECKSUM_ALGORITHM_CRC32:
|
||||||
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
|
||||||
checksum = buf_calc_page_crc32(page);
|
checksum = buf_calc_page_crc32(page);
|
||||||
|
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
|
||||||
break;
|
break;
|
||||||
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
case SRV_CHECKSUM_ALGORITHM_INNODB:
|
||||||
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
|
||||||
checksum = (ib_uint32_t) buf_calc_page_new_checksum(page);
|
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;
|
break;
|
||||||
case SRV_CHECKSUM_ALGORITHM_NONE:
|
case SRV_CHECKSUM_ALGORITHM_NONE:
|
||||||
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
|
||||||
checksum = BUF_NO_CHECKSUM_MAGIC;
|
checksum = BUF_NO_CHECKSUM_MAGIC;
|
||||||
|
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
|
||||||
break;
|
break;
|
||||||
/* no default so the compiler will emit a warning if new enum
|
/* no default so the compiler will emit a warning if new enum
|
||||||
is added and not handled here */
|
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
|
In other cases we write the same value to both fields.
|
||||||
the old formula checksum. Since it depends also on the field
|
If CRC32 is used then it is faster to use that checksum
|
||||||
FIL_PAGE_SPACE_OR_CHKSUM, it has to be calculated after storing the
|
(calculated above) instead of calculating another one.
|
||||||
new formula checksum. */
|
We can afford to store something other than
|
||||||
|
buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in
|
||||||
if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB
|
this field because the file will not be readable by old
|
||||||
|| srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) {
|
versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */
|
||||||
|
|
||||||
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) */
|
|
||||||
}
|
|
||||||
|
|
||||||
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
|
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
|
||||||
checksum);
|
checksum);
|
||||||
|
@@ -39,6 +39,16 @@ UNIV_INTERN dict_index_t* dict_ind_redundant;
|
|||||||
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
|
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
|
||||||
UNIV_INTERN dict_index_t* dict_ind_compact;
|
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
|
#ifndef UNIV_HOTBACKUP
|
||||||
#include "buf0buf.h"
|
#include "buf0buf.h"
|
||||||
#include "data0type.h"
|
#include "data0type.h"
|
||||||
@@ -2410,11 +2420,18 @@ dict_index_add_to_cache(
|
|||||||
new_index->n_fields = new_index->n_def;
|
new_index->n_fields = new_index->n_def;
|
||||||
new_index->trx_id = index->trx_id;
|
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:
|
too_big:
|
||||||
dict_mem_index_free(new_index);
|
dict_mem_index_free(new_index);
|
||||||
dict_mem_index_free(index);
|
dict_mem_index_free(index);
|
||||||
return(DB_TOO_BIG_RECORD);
|
return(DB_TOO_BIG_RECORD);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ib_warn_row_too_big(table);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict_index_is_univ(index)) {
|
if (dict_index_is_univ(index)) {
|
||||||
@@ -5721,11 +5738,11 @@ dict_set_corrupted(
|
|||||||
|
|
||||||
dict_index_copy_types(tuple, sys_index, 2);
|
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,
|
BTR_MODIFY_LEAF,
|
||||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
&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
|
/* UPDATE SYS_INDEXES SET TYPE=index->type
|
||||||
WHERE TABLE_ID=index->table->id AND INDEX_ID=index->id */
|
WHERE TABLE_ID=index->table->id AND INDEX_ID=index->id */
|
||||||
ulint len;
|
ulint len;
|
||||||
|
@@ -1941,7 +1941,8 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
fil_inc_pending_ops(
|
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;
|
fil_space_t* space;
|
||||||
|
|
||||||
@@ -1950,10 +1951,12 @@ fil_inc_pending_ops(
|
|||||||
space = fil_space_get_by_id(id);
|
space = fil_space_get_by_id(id);
|
||||||
|
|
||||||
if (space == NULL) {
|
if (space == NULL) {
|
||||||
fprintf(stderr,
|
if (print_err) {
|
||||||
"InnoDB: Error: trying to do an operation on a"
|
fprintf(stderr,
|
||||||
" dropped tablespace %lu\n",
|
"InnoDB: Error: trying to do an operation on a"
|
||||||
(ulong) id);
|
" dropped tablespace %lu\n",
|
||||||
|
(ulong) id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space == NULL || space->stop_new_ops) {
|
if (space == NULL || space->stop_new_ops) {
|
||||||
@@ -4109,7 +4112,18 @@ fil_load_single_table_tablespace(
|
|||||||
/* Build up the tablename in the standard form database/table. */
|
/* Build up the tablename in the standard form database/table. */
|
||||||
tablename = static_cast<char*>(
|
tablename = static_cast<char*>(
|
||||||
mem_alloc(dbname_len + filename_len + 2));
|
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_len = strlen(tablename) - strlen(".ibd");
|
||||||
tablename[tablename_len] = '\0';
|
tablename[tablename_len] = '\0';
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ Full Text Search interface
|
|||||||
#include "dict0priv.h"
|
#include "dict0priv.h"
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "btr0pcur.h"
|
#include "btr0pcur.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ha_prototypes.h"
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
@@ -899,12 +900,14 @@ fts_drop_index(
|
|||||||
|
|
||||||
index_cache = fts_find_index_cache(cache, index);
|
index_cache = fts_find_index_cache(cache, index);
|
||||||
|
|
||||||
if (index_cache->words) {
|
if (index_cache != NULL) {
|
||||||
fts_words_free(index_cache->words);
|
if (index_cache->words) {
|
||||||
rbt_free(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) {
|
if (cache->get_docs) {
|
||||||
fts_reset_get_doc(cache);
|
fts_reset_get_doc(cache);
|
||||||
@@ -1255,7 +1258,8 @@ fts_tokenizer_word_get(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If it is a stopword, do not index it */
|
/* 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) {
|
&parent, text) == 0) {
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@@ -3558,6 +3562,12 @@ fts_add_doc_by_id(
|
|||||||
|
|
||||||
rw_lock_x_lock(&table->fts->cache->lock);
|
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(
|
fts_cache_add_doc(
|
||||||
table->fts->cache,
|
table->fts->cache,
|
||||||
get_doc->index_cache,
|
get_doc->index_cache,
|
||||||
@@ -6072,8 +6082,6 @@ fts_update_hex_format_flag(
|
|||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Rename an aux table to HEX format. It's called when "%016llu" is used
|
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. */
|
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 */
|
are set DICT_TF2_FTS_AUX_HEX_NAME with flags2 or none of them are set */
|
||||||
static __attribute__((nonnull, warn_unused_result))
|
static __attribute__((nonnull, warn_unused_result))
|
||||||
dberr_t
|
dberr_t
|
||||||
fts_rename_aux_tables_to_hex_format(
|
fts_rename_aux_tables_to_hex_format_low(
|
||||||
/*================================*/
|
/*====================================*/
|
||||||
trx_t* trx, /*!< in: transaction */
|
trx_t* trx, /*!< in: transaction */
|
||||||
dict_table_t* parent_table, /*!< in: parent table */
|
dict_table_t* parent_table, /*!< in: parent table */
|
||||||
ib_vector_t* tables) /*!< in: aux tables to rename. */
|
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 %s. Please revert manually.",
|
||||||
table->name);
|
table->name);
|
||||||
fts_sql_rollback(trx_bg);
|
fts_sql_rollback(trx_bg);
|
||||||
|
trx_free_for_background(trx_bg);
|
||||||
/* Continue to clear aux tables' flags2 */
|
/* Continue to clear aux tables' flags2 */
|
||||||
not_rename = true;
|
not_rename = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fts_sql_commit(trx_bg);
|
fts_sql_commit(trx_bg);
|
||||||
|
trx_free_for_background(trx_bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
DICT_TF2_FLAG_UNSET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
|
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);
|
ret = sprintf(tmp_id, UINT64PFx, id);
|
||||||
ut_ad(ret == 16);
|
ut_ad(ret == 16);
|
||||||
|
#ifdef _WIN32
|
||||||
ret = sscanf(tmp_id, "%016llu", &dec_id);
|
ret = sscanf(tmp_id, "%016llu", &dec_id);
|
||||||
|
#else
|
||||||
|
ret = sscanf(tmp_id, "%016"PRIu64, &dec_id);
|
||||||
|
#endif /* _WIN32 */
|
||||||
ut_ad(ret == 1);
|
ut_ad(ret == 1);
|
||||||
|
|
||||||
return dec_id;
|
return dec_id;
|
||||||
@@ -6346,7 +6360,293 @@ fts_check_aux_table_parent_id_cmp(
|
|||||||
return static_cast<int>(fa1->parent_id - fa2->parent_id);
|
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
|
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 */
|
trx_t* trx, /*!< in: transaction */
|
||||||
ib_vector_t* tables) /*!< in: tables to check */
|
ib_vector_t* tables) /*!< in: tables to check */
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
ib_vector_t* aux_tables_to_rename;
|
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;
|
ib_alloc_t* heap_alloc;
|
||||||
|
|
||||||
heap = mem_heap_create(1024);
|
heap = mem_heap_create(1024);
|
||||||
@@ -6372,38 +6675,99 @@ fts_check_and_drop_orphaned_tables(
|
|||||||
aux_tables_to_rename = ib_vector_create(heap_alloc,
|
aux_tables_to_rename = ib_vector_create(heap_alloc,
|
||||||
sizeof(fts_aux_table_t), 128);
|
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 */
|
/* Sort by parent_id first, in case rename will fail */
|
||||||
ib_vector_sort(tables, fts_check_aux_table_parent_id_cmp);
|
ib_vector_sort(tables, fts_check_aux_table_parent_id_cmp);
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
for (ulint i = 0; i < ib_vector_size(tables); ++i) {
|
for (ulint i = 0; i < ib_vector_size(tables); ++i) {
|
||||||
dict_table_t* parent_table;
|
dict_table_t* parent_table;
|
||||||
fts_aux_table_t* aux_table;
|
fts_aux_table_t* aux_table;
|
||||||
bool drop = false;
|
bool drop = false;
|
||||||
#ifdef _WIN32
|
|
||||||
dict_table_t* table;
|
dict_table_t* table;
|
||||||
fts_aux_table_t* next_aux_table = NULL;
|
fts_aux_table_t* next_aux_table = NULL;
|
||||||
ib_id_t orig_parent_id = 0;
|
ib_id_t orig_parent_id = 0;
|
||||||
|
ib_id_t orig_index_id = 0;
|
||||||
bool rename = false;
|
bool rename = false;
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
aux_table = static_cast<fts_aux_table_t*>(
|
aux_table = static_cast<fts_aux_table_t*>(
|
||||||
ib_vector_get(tables, i));
|
ib_vector_get(tables, i));
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
table = dict_table_open_on_id(
|
table = dict_table_open_on_id(
|
||||||
aux_table->id, TRUE, DICT_TABLE_OP_NORMAL);
|
aux_table->id, TRUE, DICT_TABLE_OP_NORMAL);
|
||||||
orig_parent_id = aux_table->parent_id;
|
orig_parent_id = aux_table->parent_id;
|
||||||
|
orig_index_id = aux_table->index_id;
|
||||||
|
|
||||||
if (table == NULL || strcmp(table->name, aux_table->name)) {
|
if (table == NULL || strcmp(table->name, aux_table->name)) {
|
||||||
/* Skip these aux tables, which are common tables
|
|
||||||
with wrong table ids */
|
bool fake_aux = false;
|
||||||
if (table) {
|
|
||||||
|
if (table != NULL) {
|
||||||
dict_table_close(table, TRUE, FALSE);
|
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,
|
} else if (!DICT_TF2_FLAG_IS_SET(table,
|
||||||
DICT_TF2_FTS_AUX_HEX_NAME)) {
|
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);
|
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) {
|
if (table != NULL) {
|
||||||
dict_table_close(table, TRUE, FALSE);
|
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(
|
parent_table = dict_table_open_on_id(
|
||||||
aux_table->parent_id, TRUE, DICT_TABLE_OP_NORMAL);
|
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) {
|
if (drop) {
|
||||||
|
ib_vector_push(drop_aux_tables, aux_table);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (FTS_IS_OBSOLETE_AUX_TABLE(aux_table->name)) {
|
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
|
This could happen when we try to upgrade
|
||||||
from older server to later one, which doesn't
|
from older server to later one, which doesn't
|
||||||
contain these obsolete tables. */
|
contain these obsolete tables. */
|
||||||
drop = true;
|
ib_vector_push(obsolete_aux_tables, aux_table);
|
||||||
|
continue;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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) {
|
if (!drop && rename) {
|
||||||
ib_vector_push(aux_tables_to_rename, aux_table);
|
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
|
them if necessary. We had better use a new background
|
||||||
trx to rename rather than the original trx, in case
|
trx to rename rather than the original trx, in case
|
||||||
any failure would cause a complete rollback. */
|
any failure would cause a complete rollback. */
|
||||||
dberr_t err;
|
ut_ad(rename);
|
||||||
trx_t* trx_rename = trx_allocate_for_background();
|
ut_ad(!DICT_TF2_FLAG_IS_SET(
|
||||||
trx_rename->op_info = "Rename aux tables to "
|
parent_table, DICT_TF2_FTS_AUX_HEX_NAME));
|
||||||
"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(trx_rename,
|
fts_rename_aux_tables_to_hex_format(
|
||||||
parent_table, aux_tables_to_rename);
|
aux_tables_to_rename,parent_table);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
#else /* _WIN32 */
|
|
||||||
if (!drop) {
|
/* The IDs are already in correct hex format. */
|
||||||
|
if (!drop && !rename) {
|
||||||
dict_table_t* table;
|
dict_table_t* table;
|
||||||
|
|
||||||
table = dict_table_open_on_id(
|
table = dict_table_open_on_id(
|
||||||
@@ -6590,6 +6930,16 @@ fts_check_and_drop_orphaned_tables(
|
|||||||
&& !DICT_TF2_FLAG_IS_SET(
|
&& !DICT_TF2_FLAG_IS_SET(
|
||||||
table,
|
table,
|
||||||
DICT_TF2_FTS_AUX_HEX_NAME)) {
|
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(
|
dberr_t err = fts_update_hex_format_flag(
|
||||||
trx, table->id, true);
|
trx, table->id, true);
|
||||||
|
|
||||||
@@ -6597,49 +6947,44 @@ fts_check_and_drop_orphaned_tables(
|
|||||||
ib_logf(IB_LOG_LEVEL_WARN,
|
ib_logf(IB_LOG_LEVEL_WARN,
|
||||||
"Setting aux table %s to hex "
|
"Setting aux table %s to hex "
|
||||||
"format failed.", table->name);
|
"format failed.", table->name);
|
||||||
|
|
||||||
|
fts_set_index_corrupt(
|
||||||
|
trx, aux_table->index_id,
|
||||||
|
parent_table);
|
||||||
} else {
|
} else {
|
||||||
DICT_TF2_FLAG_SET(table,
|
DICT_TF2_FLAG_SET(table,
|
||||||
DICT_TF2_FTS_AUX_HEX_NAME);
|
DICT_TF2_FTS_AUX_HEX_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
table_exit:
|
||||||
|
#endif /* !DBUG_OFF */
|
||||||
|
|
||||||
if (table != NULL) {
|
if (table != NULL) {
|
||||||
dict_table_close(table, TRUE, FALSE);
|
dict_table_close(table, TRUE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(parent_table != NULL);
|
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) {
|
fts_set_parent_hex_format_flag(
|
||||||
ib_logf(IB_LOG_LEVEL_WARN,
|
parent_table, trx);
|
||||||
"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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
if (parent_table != NULL) {
|
||||||
|
|
||||||
if (parent_table) {
|
|
||||||
dict_table_close(parent_table, TRUE, FALSE);
|
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 */
|
/* Free the memory allocated at the beginning */
|
||||||
if (heap != NULL) {
|
if (heap != NULL) {
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
@@ -6738,7 +7083,6 @@ fts_drop_orphaned_tables(void)
|
|||||||
|
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
fts_check_and_drop_orphaned_tables(trx, tables);
|
fts_check_and_drop_orphaned_tables(trx, tables);
|
||||||
fts_sql_commit(trx);
|
|
||||||
break; /* Exit the loop. */
|
break; /* Exit the loop. */
|
||||||
} else {
|
} else {
|
||||||
ib_vector_reset(tables);
|
ib_vector_reset(tables);
|
||||||
|
@@ -190,6 +190,8 @@ cycle for a table. */
|
|||||||
struct fts_slot_t {
|
struct fts_slot_t {
|
||||||
dict_table_t* table; /*!< Table to optimize */
|
dict_table_t* table; /*!< Table to optimize */
|
||||||
|
|
||||||
|
table_id_t table_id; /*!< Table id */
|
||||||
|
|
||||||
fts_state_t state; /*!< State of this slot */
|
fts_state_t state; /*!< State of this slot */
|
||||||
|
|
||||||
ulint added; /*!< Number of doc ids added since the
|
ulint added; /*!< Number of doc ids added since the
|
||||||
@@ -2575,6 +2577,8 @@ fts_optimize_add_table(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(table->cached && table->fts != NULL);
|
||||||
|
|
||||||
/* Make sure table with FTS index cannot be evicted */
|
/* Make sure table with FTS index cannot be evicted */
|
||||||
if (table->can_be_evicted) {
|
if (table->can_be_evicted) {
|
||||||
dict_table_move_from_lru_to_non_lru(table);
|
dict_table_move_from_lru_to_non_lru(table);
|
||||||
@@ -2741,6 +2745,7 @@ fts_optimize_new_table(
|
|||||||
memset(slot, 0x0, sizeof(*slot));
|
memset(slot, 0x0, sizeof(*slot));
|
||||||
|
|
||||||
slot->table = table;
|
slot->table = table;
|
||||||
|
slot->table_id = table->id;
|
||||||
slot->state = FTS_STATE_LOADED;
|
slot->state = FTS_STATE_LOADED;
|
||||||
slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS;
|
slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS;
|
||||||
|
|
||||||
@@ -2865,7 +2870,8 @@ fts_is_sync_needed(
|
|||||||
slot = static_cast<const fts_slot_t*>(
|
slot = static_cast<const fts_slot_t*>(
|
||||||
ib_vector_get_const(tables, i));
|
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;
|
total_memory += slot->table->fts->cache->total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2948,6 +2954,7 @@ fts_optimize_thread(
|
|||||||
ib_wqueue_t* wq = (ib_wqueue_t*) arg;
|
ib_wqueue_t* wq = (ib_wqueue_t*) arg;
|
||||||
|
|
||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
|
my_thread_init();
|
||||||
|
|
||||||
heap = mem_heap_create(sizeof(dict_table_t*) * 64);
|
heap = mem_heap_create(sizeof(dict_table_t*) * 64);
|
||||||
heap_alloc = ib_heap_allocator_create(heap);
|
heap_alloc = ib_heap_allocator_create(heap);
|
||||||
@@ -3076,9 +3083,11 @@ fts_optimize_thread(
|
|||||||
if (slot->state != FTS_STATE_EMPTY) {
|
if (slot->state != FTS_STATE_EMPTY) {
|
||||||
dict_table_t* table = NULL;
|
dict_table_t* table = NULL;
|
||||||
|
|
||||||
table = dict_table_open_on_name(
|
/*slot->table may be freed, so we try to open
|
||||||
slot->table->name, FALSE, FALSE,
|
table by slot->table_id.*/
|
||||||
DICT_ERR_IGNORE_INDEX_ROOT);
|
table = dict_table_open_on_id(
|
||||||
|
slot->table_id, FALSE,
|
||||||
|
DICT_TABLE_OP_NORMAL);
|
||||||
|
|
||||||
if (table) {
|
if (table) {
|
||||||
|
|
||||||
@@ -3101,6 +3110,7 @@ fts_optimize_thread(
|
|||||||
ib_logf(IB_LOG_LEVEL_INFO, "FTS optimize thread exiting.");
|
ib_logf(IB_LOG_LEVEL_INFO, "FTS optimize thread exiting.");
|
||||||
|
|
||||||
os_event_set(exit_event);
|
os_event_set(exit_event);
|
||||||
|
my_thread_end();
|
||||||
|
|
||||||
/* We count the number of threads in os_thread_exit(). A created
|
/* 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. */
|
thread should always use that to exit and not use return() to exit. */
|
||||||
|
@@ -2903,7 +2903,8 @@ innobase_init(
|
|||||||
|
|
||||||
innobase_hton->flush_logs = innobase_flush_logs;
|
innobase_hton->flush_logs = innobase_flush_logs;
|
||||||
innobase_hton->show_status = innobase_show_status;
|
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_hton->release_temporary_latches =
|
||||||
innobase_release_temporary_latches;
|
innobase_release_temporary_latches;
|
||||||
@@ -12414,6 +12415,7 @@ ha_innobase::start_stmt(
|
|||||||
thr_lock_type lock_type)
|
thr_lock_type lock_type)
|
||||||
{
|
{
|
||||||
trx_t* trx;
|
trx_t* trx;
|
||||||
|
DBUG_ENTER("ha_innobase::start_stmt");
|
||||||
|
|
||||||
update_thd(thd);
|
update_thd(thd);
|
||||||
|
|
||||||
@@ -12437,6 +12439,29 @@ ha_innobase::start_stmt(
|
|||||||
prebuilt->hint_need_to_fetch_extra_cols = 0;
|
prebuilt->hint_need_to_fetch_extra_cols = 0;
|
||||||
reset_template();
|
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) {
|
if (!prebuilt->mysql_has_locked) {
|
||||||
/* This handle is for a temporary table created inside
|
/* This handle is for a temporary table created inside
|
||||||
this same LOCK TABLES; since MySQL does NOT call external_lock
|
this same LOCK TABLES; since MySQL does NOT call external_lock
|
||||||
@@ -12474,7 +12499,7 @@ ha_innobase::start_stmt(
|
|||||||
++trx->will_lock;
|
++trx->will_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
@@ -17559,3 +17584,27 @@ innobase_convert_to_system_charset(
|
|||||||
static_cast<uint>(len), errors));
|
static_cast<uint>(len), errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@@ -3362,9 +3362,7 @@ ha_innobase::prepare_inplace_alter_table(
|
|||||||
ulint fts_doc_col_no = ULINT_UNDEFINED;
|
ulint fts_doc_col_no = ULINT_UNDEFINED;
|
||||||
bool add_fts_doc_id = false;
|
bool add_fts_doc_id = false;
|
||||||
bool add_fts_doc_id_idx = false;
|
bool add_fts_doc_id_idx = false;
|
||||||
#ifdef _WIN32
|
|
||||||
bool add_fts_idx = false;
|
bool add_fts_idx = false;
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
DBUG_ENTER("prepare_inplace_alter_table");
|
DBUG_ENTER("prepare_inplace_alter_table");
|
||||||
DBUG_ASSERT(!ha_alter_info->handler_ctx);
|
DBUG_ASSERT(!ha_alter_info->handler_ctx);
|
||||||
@@ -3509,9 +3507,7 @@ check_if_ok_to_rename:
|
|||||||
& ~(HA_FULLTEXT
|
& ~(HA_FULLTEXT
|
||||||
| HA_PACK_KEY
|
| HA_PACK_KEY
|
||||||
| HA_BINARY_PACK_KEY)));
|
| HA_BINARY_PACK_KEY)));
|
||||||
#ifdef _WIN32
|
|
||||||
add_fts_idx = true;
|
add_fts_idx = true;
|
||||||
#endif /* _WIN32 */
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3522,19 +3518,16 @@ check_if_ok_to_rename:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/* We won't be allowed to add fts index to a table with
|
/* We won't be allowed to add fts index to a table with
|
||||||
fts indexes already but without AUX_HEX_NAME set.
|
fts indexes already but without AUX_HEX_NAME set.
|
||||||
This means the aux tables of the table failed to
|
This means the aux tables of the table failed to
|
||||||
rename to hex format but new created aux tables
|
rename to hex format but new created aux tables
|
||||||
shall be in hex format, which is contradictory.
|
shall be in hex format, which is contradictory. */
|
||||||
It's only for Windows. */
|
|
||||||
if (!DICT_TF2_FLAG_IS_SET(indexed_table, DICT_TF2_FTS_AUX_HEX_NAME)
|
if (!DICT_TF2_FLAG_IS_SET(indexed_table, DICT_TF2_FTS_AUX_HEX_NAME)
|
||||||
&& indexed_table->fts != NULL && add_fts_idx) {
|
&& indexed_table->fts != NULL && add_fts_idx) {
|
||||||
my_error(ER_INNODB_FT_AUX_NOT_HEX_ID, MYF(0));
|
my_error(ER_INNODB_FT_AUX_NOT_HEX_ID, MYF(0));
|
||||||
goto err_exit_no_heap;
|
goto err_exit_no_heap;
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
/* Check existing index definitions for too-long column
|
/* Check existing index definitions for too-long column
|
||||||
prefixes as well, in case max_col_len shrunk. */
|
prefixes as well, in case max_col_len shrunk. */
|
||||||
|
@@ -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
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -4614,7 +4614,7 @@ ibuf_merge_or_delete_for_page(
|
|||||||
function. When the counter is > 0, that prevents tablespace
|
function. When the counter is > 0, that prevents tablespace
|
||||||
from being dropped. */
|
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)) {
|
if (UNIV_UNLIKELY(tablespace_being_deleted)) {
|
||||||
/* Do not try to read the bitmap page from space;
|
/* Do not try to read the bitmap page from space;
|
||||||
|
@@ -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
|
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
|
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
|
#ifdef UNIV_DEBUG
|
||||||
# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\
|
# 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) {\
|
&& (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\
|
||||||
CODE;\
|
CODE;\
|
||||||
}
|
}
|
||||||
|
@@ -85,7 +85,7 @@ dict_get_referenced_table(
|
|||||||
mem_heap_t* heap); /*!< in: heap memory */
|
mem_heap_t* heap); /*!< in: heap memory */
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Frees a foreign key struct. */
|
Frees a foreign key struct. */
|
||||||
UNIV_INTERN
|
|
||||||
void
|
void
|
||||||
dict_foreign_free(
|
dict_foreign_free(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
|
@@ -42,6 +42,7 @@ Created 10/25/1995 Heikki Tuuri
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
extern my_bool lower_case_file_system;
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
struct trx_t;
|
struct trx_t;
|
||||||
struct fil_space_t;
|
struct fil_space_t;
|
||||||
@@ -590,7 +591,8 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
fil_inc_pending_ops(
|
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. */
|
Decrements the count of pending operations. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@@ -37,18 +37,38 @@ fts_write_object_id(
|
|||||||
/* in: true for fixed hex format,
|
/* in: true for fixed hex format,
|
||||||
false for old ambiguous format */
|
false for old ambiguous format */
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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",
|
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
|
||||||
return(sprintf(str, "%016llu", id)););
|
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. */
|
/* As above, but this is only for those tables failing to rename. */
|
||||||
if (!hex_format) {
|
if (!hex_format) {
|
||||||
|
#ifdef _WIN32
|
||||||
// FIXME: Use ut_snprintf(), so does following one.
|
// FIXME: Use ut_snprintf(), so does following one.
|
||||||
return(sprintf(str, "%016llu", id));
|
return(sprintf(str, "%016llu", id));
|
||||||
}
|
#else /* _WIN32 */
|
||||||
|
return(sprintf(str, "%016"PRIu64, id));
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
}
|
||||||
|
|
||||||
return(sprintf(str, UINT64PFx, id));
|
return(sprintf(str, UINT64PFx, id));
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ Created 1/20/1994 Heikki Tuuri
|
|||||||
|
|
||||||
#define INNODB_VERSION_MAJOR 5
|
#define INNODB_VERSION_MAJOR 5
|
||||||
#define INNODB_VERSION_MINOR 6
|
#define INNODB_VERSION_MINOR 6
|
||||||
#define INNODB_VERSION_BUGFIX 21
|
#define INNODB_VERSION_BUGFIX 22
|
||||||
|
|
||||||
/* The following is the InnoDB version as shown in
|
/* The following is the InnoDB version as shown in
|
||||||
SELECT plugin_version FROM information_schema.plugins;
|
SELECT plugin_version FROM information_schema.plugins;
|
||||||
|
@@ -5497,6 +5497,7 @@ loop:
|
|||||||
ulint space = lock->un_member.rec_lock.space;
|
ulint space = lock->un_member.rec_lock.space;
|
||||||
ulint zip_size= fil_space_get_zip_size(space);
|
ulint zip_size= fil_space_get_zip_size(space);
|
||||||
ulint page_no = lock->un_member.rec_lock.page_no;
|
ulint page_no = lock->un_member.rec_lock.page_no;
|
||||||
|
ibool tablespace_being_deleted = FALSE;
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
|
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
|
||||||
|
|
||||||
@@ -5515,12 +5516,28 @@ loop:
|
|||||||
lock_mutex_exit();
|
lock_mutex_exit();
|
||||||
mutex_exit(&trx_sys->mutex);
|
mutex_exit(&trx_sys->mutex);
|
||||||
|
|
||||||
mtr_start(&mtr);
|
DEBUG_SYNC_C("innodb_monitor_before_lock_page_read");
|
||||||
|
|
||||||
buf_page_get_with_no_latch(
|
/* Check if the space is exists or not. only when the space
|
||||||
space, zip_size, page_no, &mtr);
|
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;
|
load_page_first = FALSE;
|
||||||
|
|
||||||
@@ -5943,7 +5960,7 @@ lock_rec_block_validate(
|
|||||||
|
|
||||||
/* Make sure that the tablespace is not deleted while we are
|
/* Make sure that the tablespace is not deleted while we are
|
||||||
trying to access the page. */
|
trying to access the page. */
|
||||||
if (!fil_inc_pending_ops(space)) {
|
if (!fil_inc_pending_ops(space, true)) {
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
block = buf_page_get_gen(
|
block = buf_page_get_gen(
|
||||||
space, fil_space_get_zip_size(space),
|
space, fil_space_get_zip_size(space),
|
||||||
|
@@ -3407,7 +3407,11 @@ loop:
|
|||||||
|
|
||||||
lsn = log_sys->lsn;
|
lsn = log_sys->lsn;
|
||||||
|
|
||||||
if (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)
|
||||||
#ifdef UNIV_LOG_ARCHIVE
|
#ifdef UNIV_LOG_ARCHIVE
|
||||||
|| (srv_log_archive_on
|
|| (srv_log_archive_on
|
||||||
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
|
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
|
||||||
|
@@ -114,6 +114,9 @@ os_thread_create_func(
|
|||||||
os_thread_id_t* thread_id) /*!< out: id of the created
|
os_thread_id_t* thread_id) /*!< out: id of the created
|
||||||
thread, or NULL */
|
thread, or NULL */
|
||||||
{
|
{
|
||||||
|
/* the new thread should look recent changes up here so far. */
|
||||||
|
os_wmb;
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
os_thread_t thread;
|
os_thread_t thread;
|
||||||
DWORD win_thread_id;
|
DWORD win_thread_id;
|
||||||
|
@@ -4926,12 +4926,19 @@ page_zip_verify_checksum(
|
|||||||
stored = static_cast<ib_uint32_t>(mach_read_from_4(
|
stored = static_cast<ib_uint32_t>(mach_read_from_4(
|
||||||
static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
|
static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
|
||||||
|
|
||||||
|
#if FIL_PAGE_LSN % 8
|
||||||
|
#error "FIL_PAGE_LSN must be 64 bit aligned"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef UNIV_INNOCHECKSUM
|
#ifndef UNIV_INNOCHECKSUM
|
||||||
/* innochecksum doesn't compile with ut_d. Since we don't
|
/* innochecksum doesn't compile with ut_d. Since we don't
|
||||||
need to check for empty pages when running innochecksum,
|
need to check for empty pages when running innochecksum,
|
||||||
just don't include this code. */
|
just don't include this code. */
|
||||||
/* declare empty pages non-corrupted */
|
/* Check if page is empty */
|
||||||
if (stored == 0) {
|
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 */
|
/* make sure that the page is really empty */
|
||||||
ulint i;
|
ulint i;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
@@ -4939,7 +4946,7 @@ page_zip_verify_checksum(
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Empty page */
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -3792,6 +3792,10 @@ row_drop_table_for_mysql(
|
|||||||
pars_info_t* info = NULL;
|
pars_info_t* info = NULL;
|
||||||
mem_heap_t* heap = 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);
|
ut_a(name != NULL);
|
||||||
|
|
||||||
if (srv_created_new_raw) {
|
if (srv_created_new_raw) {
|
||||||
@@ -3801,7 +3805,7 @@ row_drop_table_for_mysql(
|
|||||||
"InnoDB: Shut down mysqld and edit my.cnf so that newraw"
|
"InnoDB: Shut down mysqld and edit my.cnf so that newraw"
|
||||||
" is replaced with raw.\n", stderr);
|
" is replaced with raw.\n", stderr);
|
||||||
|
|
||||||
return(DB_ERROR);
|
DBUG_RETURN(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The table name is prefixed with the database name and a '/'.
|
/* The table name is prefixed with the database name and a '/'.
|
||||||
@@ -4429,7 +4433,7 @@ funct_exit:
|
|||||||
|
|
||||||
srv_wake_master_thread();
|
srv_wake_master_thread();
|
||||||
|
|
||||||
return(err);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@@ -286,6 +286,7 @@ rw_lock_free_func(
|
|||||||
ib_mutex_t* mutex;
|
ib_mutex_t* mutex;
|
||||||
#endif /* !INNODB_RW_LOCKS_USE_ATOMICS */
|
#endif /* !INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
|
|
||||||
|
os_rmb;
|
||||||
ut_ad(rw_lock_validate(lock));
|
ut_ad(rw_lock_validate(lock));
|
||||||
ut_a(lock->lock_word == X_LOCK_DECR);
|
ut_a(lock->lock_word == X_LOCK_DECR);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user