Commit 0474be0a authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.3 into 10.4

parents 937c90ce 4e75bfcb
......@@ -489,7 +489,9 @@ DROP TABLE t1;
SET DEBUG_SYNC= 'alter_table_copy_after_lock_upgrade SIGNAL upgraded';
#Setup a table with FULLTEXT index.
connection default;
CREATE TABLE t1(fld1 CHAR(10), FULLTEXT(fld1)) ENGINE= INNODB;
CREATE TABLE t1(fld1 CHAR(10), FULLTEXT(fld1), FULLTEXT(fld1)) ENGINE= INNODB;
Warnings:
Note 1831 Duplicate index `fld1_2`. This is deprecated and will be disallowed in a future release
INSERT INTO t1 VALUES("String1");
#OPTIMIZE TABLE operation.
OPTIMIZE TABLE t1;
......
......@@ -650,7 +650,7 @@ SET DEBUG_SYNC= 'alter_table_copy_after_lock_upgrade SIGNAL upgraded';
--echo #Setup a table with FULLTEXT index.
--connection default
CREATE TABLE t1(fld1 CHAR(10), FULLTEXT(fld1)) ENGINE= INNODB;
CREATE TABLE t1(fld1 CHAR(10), FULLTEXT(fld1), FULLTEXT(fld1)) ENGINE= INNODB;
INSERT INTO t1 VALUES("String1");
--echo #OPTIMIZE TABLE operation.
......
......@@ -439,17 +439,17 @@ tt CREATE TABLE `tt` (
FULLTEXT KEY `ct` (`ct`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
ALTER TABLE tt ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
CREATE TABLE tu (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
ALTER TABLE tu ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
DROP TABLE tu;
CREATE TABLE tv (
pk INT PRIMARY KEY, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, t TEXT,
......@@ -457,9 +457,9 @@ UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
FULLTEXT INDEX(t)
) ENGINE=InnoDB;
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL FIRST, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
ALTER TABLE tv ADD COLUMN c CHAR(1) NOT NULL, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
DROP TABLE tv;
ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
ERROR 42000: Incorrect column name 'dB_row_Id'
......@@ -500,8 +500,6 @@ ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY
ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY
ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try ALGORITHM=COPY
ALTER TABLE t1o DROP COLUMN FTS_DOC_ID;
......
......@@ -272,13 +272,8 @@ ALTER TABLE t1o ADD FULLTEXT INDEX(cu),
ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
# Replace the hidden FTS_DOC_ID column with a user-visible one.
# This used to work if there is at most one fulltext index.
# Currently, we disallow native ALTER TABLE if the table
# contains any FULLTEXT indexes.
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
ALGORITHM=INPLACE;
ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
# Replace the user-visible FTS_DOC_ID column with a hidden one.
# We do not support this in-place.
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
......
......@@ -79,7 +79,7 @@ CREATE FULLTEXT INDEX idx on fts_test (title, body) LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY;
ALTER TABLE fts_test ROW_FORMAT=REDUNDANT, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try LOCK=SHARED
ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED
ALTER TABLE fts_test ROW_FORMAT=REDUNDANT;
SELECT * FROM fts_test WHERE MATCH (title, body)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE);
......@@ -228,3 +228,12 @@ DROP TABLE articles;
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
DROP TABLE t1;
#
# MDEV-18152 Assertion 'num_fts_index <= 1' failed
# in prepare_inplace_alter_table_dict
#
CREATE TABLE t1
(a VARCHAR(128), b VARCHAR(128), FULLTEXT INDEX(a), FULLTEXT INDEX(b))
ENGINE=InnoDB;
ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
......@@ -276,3 +276,13 @@ ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b)
# Cleanup
DROP TABLE t1;
--echo #
--echo # MDEV-18152 Assertion 'num_fts_index <= 1' failed
--echo # in prepare_inplace_alter_table_dict
--echo #
CREATE TABLE t1
(a VARCHAR(128), b VARCHAR(128), FULLTEXT INDEX(a), FULLTEXT INDEX(b))
ENGINE=InnoDB;
ALTER TABLE t1 ADD c SERIAL;
DROP TABLE t1;
......@@ -290,11 +290,12 @@ thd_destructor_proxy(void *)
mysql_cond_init(PSI_NOT_INSTRUMENTED, &thd_destructor_cond, 0);
st_my_thread_var *myvar= _my_thread_var();
myvar->current_mutex = &thd_destructor_mutex;
myvar->current_cond = &thd_destructor_cond;
THD *thd= create_thd();
thd_proc_info(thd, "InnoDB shutdown handler");
myvar->current_mutex = &thd_destructor_mutex;
myvar->current_cond = &thd_destructor_cond;
mysql_mutex_lock(&thd_destructor_mutex);
srv_running.store(myvar, std::memory_order_relaxed);
......
......@@ -1242,20 +1242,18 @@ my_error_innodb(
/** Determine if fulltext indexes exist in a given table.
@param table MySQL table
@return whether fulltext indexes exist on the table */
static
bool
innobase_fulltext_exist(
/*====================*/
const TABLE* table)
@return number of fulltext indexes */
static uint innobase_fulltext_exist(const TABLE* table)
{
uint count = 0;
for (uint i = 0; i < table->s->keys; i++) {
if (table->key_info[i].flags & HA_FULLTEXT) {
return(true);
count++;
}
}
return(false);
return count;
}
/** Determine whether indexed virtual columns exist in a table.
......@@ -1807,11 +1805,14 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
const char* reason_rebuild = NULL;
switch (ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) {
case ALTER_OPTIONS:
if (alter_options_need_rebuild(ha_alter_info, table)) {
ha_alter_info->unsupported_reason = my_get_err_msg(
reason_rebuild = my_get_err_msg(
ER_ALTER_OPERATION_TABLE_OPTIONS_NEED_REBUILD);
ha_alter_info->unsupported_reason = reason_rebuild;
break;
}
/* fall through */
......@@ -1946,8 +1947,9 @@ ha_innobase::check_if_supported_inplace_alter(
}
/* We should be able to do the operation in-place.
See if we can do it online (LOCK=NONE). */
bool online = true;
See if we can do it online (LOCK=NONE) or without rebuild. */
bool online = true, need_rebuild = false;
const uint fulltext_indexes = innobase_fulltext_exist(altered_table);
List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list);
......@@ -2008,8 +2010,7 @@ ha_innobase::check_if_supported_inplace_alter(
/* We cannot replace a hidden FTS_DOC_ID
with a user-visible FTS_DOC_ID. */
if (m_prebuilt->table->fts
&& innobase_fulltext_exist(altered_table)
if (fulltext_indexes && m_prebuilt->table->fts
&& !my_strcasecmp(
system_charset_info,
key_part->field->field_name.str,
......@@ -2025,8 +2026,8 @@ ha_innobase::check_if_supported_inplace_alter(
& AUTO_INCREMENT_FLAG));
if (key_part->field->flags & AUTO_INCREMENT_FLAG) {
/* We cannot assign an AUTO_INCREMENT
column values during online ALTER. */
/* We cannot assign AUTO_INCREMENT values
during online or instant ALTER. */
DBUG_ASSERT(key_part->field == altered_table
-> found_next_number_field);
......@@ -2036,6 +2037,7 @@ ha_innobase::check_if_supported_inplace_alter(
}
online = false;
need_rebuild = true;
}
if (innobase_is_v_fld(key_part->field)) {
......@@ -2068,7 +2070,7 @@ ha_innobase::check_if_supported_inplace_alter(
|| (m_prebuilt->table->fts->doc_col
< dict_table_get_n_user_cols(m_prebuilt->table)));
if (m_prebuilt->table->fts && innobase_fulltext_exist(altered_table)) {
if (fulltext_indexes && m_prebuilt->table->fts) {
/* FULLTEXT indexes are supposed to remain. */
/* Disallow DROP INDEX FTS_DOC_ID_INDEX */
......@@ -2113,7 +2115,8 @@ ha_innobase::check_if_supported_inplace_alter(
cf_it.rewind();
Field **af = altered_table->field;
bool fts_need_rebuild = false;
const bool need_rebuild = innobase_need_rebuild(ha_alter_info, table);
need_rebuild = need_rebuild
|| innobase_need_rebuild(ha_alter_info, table);
while (Create_field* cf = cf_it++) {
DBUG_ASSERT(cf->field
......@@ -2165,8 +2168,7 @@ ha_innobase::check_if_supported_inplace_alter(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL);
} else if (!is_non_const_value(*af)
&& set_default_value(*af)) {
if (m_prebuilt->table->fts
&& innobase_fulltext_exist(altered_table)
if (fulltext_indexes > 1
&& !my_strcasecmp(system_charset_info,
(*af)->field_name.str,
FTS_DOC_ID_COL_NAME)) {
......@@ -2189,42 +2191,36 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_INSTANT);
}
if (!online) {
/* We already determined that only a non-locking
operation is possible. */
} else if ((need_rebuild || (ha_alter_info->handler_flags
& ALTER_ADD_PK_INDEX))
&& (innobase_fulltext_exist(altered_table)
|| innobase_spatial_exist(altered_table)
|| innobase_indexed_virtual_exist(altered_table))) {
/* Refuse to rebuild the table online, if
FULLTEXT OR SPATIAL indexes are to survive the rebuild. */
online = false;
if (need_rebuild
&& (fulltext_indexes
|| innobase_spatial_exist(altered_table)
|| innobase_indexed_virtual_exist(altered_table))) {
/* If the table already contains fulltext indexes,
refuse to rebuild the table natively altogether. */
if (m_prebuilt->table->fts) {
if (fulltext_indexes > 1) {
cannot_create_many_fulltext_index:
ha_alter_info->unsupported_reason =
my_get_err_msg(ER_INNODB_FT_LIMIT);
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
if (ha_alter_info->online
&& !ha_alter_info->unsupported_reason) {
if (innobase_spatial_exist(altered_table)) {
ha_alter_info->unsupported_reason = my_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
} else if (!innobase_fulltext_exist(altered_table)) {
/* MDEV-14341 FIXME: Remove this limitation. */
ha_alter_info->unsupported_reason =
"online rebuild with indexed virtual columns";
} else {
ha_alter_info->unsupported_reason = my_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS);
}
if (!online || !ha_alter_info->online
|| ha_alter_info->unsupported_reason != reason_rebuild) {
/* Either LOCK=NONE was not requested, or we already
gave specific reason to refuse it. */
} else if (fulltext_indexes) {
ha_alter_info->unsupported_reason = my_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS);
} else if (innobase_spatial_exist(altered_table)) {
ha_alter_info->unsupported_reason = my_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
} else {
/* MDEV-14341 FIXME: Remove this limitation. */
ha_alter_info->unsupported_reason =
"online rebuild with indexed virtual columns";
}
online = false;
}
if (ha_alter_info->handler_flags
......
/*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation.
Copyright (c) 2015, 2019, MariaDB Corporation.
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
......@@ -3425,8 +3425,11 @@ row_drop_table_for_mysql(
calling btr_search_drop_page_hash_index() while we
hold the InnoDB dictionary lock, we will drop any
adaptive hash index entries upfront. */
bool immune = is_temp_name
|| strstr(table->name.m_name, "/FTS");
while (buf_LRU_drop_page_hash_for_tablespace(table)) {
if ((!is_temp_name && trx_is_interrupted(trx))
if ((!immune && trx_is_interrupted(trx))
|| srv_shutdown_state
!= SRV_SHUTDOWN_NONE) {
err = DB_INTERRUPTED;
......
......@@ -254,9 +254,9 @@ row_sel_sec_rec_is_for_clust_rec(
clust_field = static_cast<byte*>(vfield->data);
} else {
clust_pos = dict_col_get_clust_pos(col, clust_index);
ut_ad(!rec_offs_nth_default(clust_offs, clust_pos));
clust_field = rec_get_nth_field(
clust_rec, clust_offs, clust_pos, &clust_len);
clust_field = rec_get_nth_cfield(
clust_rec, clust_index, clust_offs,
clust_pos, &clust_len);
}
sec_field = rec_get_nth_field(sec_rec, sec_offs, i, &sec_len);
......@@ -2972,17 +2972,7 @@ row_sel_store_mysql_field_func(
} else {
/* The field is stored in the index record, or
in the metadata for instant ADD COLUMN. */
if (rec_offs_nth_default(offsets, field_no)) {
ut_ad(dict_index_is_clust(index));
ut_ad(index->is_instant());
const dict_index_t* clust_index
= dict_table_get_first_index(prebuilt->table);
ut_ad(index == clust_index);
data = clust_index->instant_field_value(field_no,&len);
} else {
data = rec_get_nth_field(rec, offsets, field_no, &len);
}
data = rec_get_nth_cfield(rec, index, offsets, field_no, &len);
if (len == UNIV_SQL_NULL) {
/* MySQL assumes that the field for an SQL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment