MDEV-17989 InnoDB: Failing assertion: dict_tf2_is_valid(flags, flags2)
With innodb_default_row_format=redundant, InnoDB would crash when using table options that are incompatible with ROW_FORMAT=REDUNDANT. create_table_info_t::m_default_row_format: Cache the value of innodb_default_row_format. create_table_info_t::check_table_options(): Validate ROW_TYPE_DEFAULT with m_default_row_format. create_table_info_t::innobase_table_flags(): Use the cached m_default_row_format. create_table_info_t: Never read m_form->s->row_type. Use m_create_info->row_type instead. dict_tf_set(): Never set invalid flags for ROW_FORMAT=REDUNDANT. ha_innobase::truncate(): Set info.row_type based on the ROW_FORMAT of the current table.
This commit is contained in:
parent
1a780eefc9
commit
e3dda3d95e
@ -9,3 +9,14 @@
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||||
SHOW TABLE STATUS LIKE 't1';
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
@@ -31,8 +31,9 @@
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB page_compressed=1;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
-t1 InnoDB # Dynamic # # # # # # NULL # NULL NULL latin1_swedish_ci NULL `page_compressed`=1
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
+Warnings:
|
||||||
|
+Note 1051 Unknown table 'test.t1'
|
||||||
|
SET @save_format = @@GLOBAL.innodb_default_row_format;
|
||||||
|
SET GLOBAL innodb_default_row_format = redundant;
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||||
|
@ -19,8 +19,26 @@ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length I
|
|||||||
t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL row_format=REDUNDANT
|
t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL row_format=REDUNDANT
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB
|
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB
|
||||||
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
ROW_FORMAT=COMPRESSED;
|
||||||
SHOW TABLE STATUS LIKE 't1';
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
t1 InnoDB # Compressed # # # # # # NULL # NULL NULL latin1_swedish_ci NULL row_format=COMPRESSED key_block_size=1
|
t1 InnoDB # Compressed # # # # # # NULL # NULL NULL latin1_swedish_ci NULL row_format=COMPRESSED
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 InnoDB # Compressed # # # # # # NULL # NULL NULL latin1_swedish_ci NULL row_format=COMPRESSED
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB page_compressed=1;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 InnoDB # Dynamic # # # # # # NULL # NULL NULL latin1_swedish_ci NULL `page_compressed`=1
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
SET @save_format = @@GLOBAL.innodb_default_row_format;
|
||||||
|
SET GLOBAL innodb_default_row_format = redundant;
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||||
|
SET GLOBAL innodb_default_row_format = @save_format;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -22,7 +22,25 @@ SHOW TABLE STATUS LIKE 't1';
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB
|
CREATE TABLE t1(c1 TEXT,c2 BLOB) ENGINE=InnoDB
|
||||||
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
ROW_FORMAT=COMPRESSED;
|
||||||
|
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--error 0,ER_CANT_CREATE_TABLE
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB page_compressed=1;
|
||||||
|
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
|
||||||
|
SET @save_format = @@GLOBAL.innodb_default_row_format;
|
||||||
|
SET GLOBAL innodb_default_row_format = redundant;
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
|
||||||
|
SET GLOBAL innodb_default_row_format = @save_format;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
|
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
|
||||||
SHOW TABLE STATUS LIKE 't1';
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -5580,6 +5580,25 @@ normalize_table_name_c_low(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_table_info_t::create_table_info_t(
|
||||||
|
THD* thd,
|
||||||
|
TABLE* form,
|
||||||
|
HA_CREATE_INFO* create_info,
|
||||||
|
char* table_name,
|
||||||
|
char* remote_path,
|
||||||
|
bool file_per_table,
|
||||||
|
trx_t* trx)
|
||||||
|
: m_thd(thd),
|
||||||
|
m_trx(trx),
|
||||||
|
m_form(form),
|
||||||
|
m_default_row_format(innodb_default_row_format),
|
||||||
|
m_create_info(create_info),
|
||||||
|
m_table_name(table_name), m_drop_before_rollback(false),
|
||||||
|
m_remote_path(remote_path),
|
||||||
|
m_innodb_file_per_table(file_per_table)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Normalizes a table name string.
|
/** Normalizes a table name string.
|
||||||
A normalized name consists of the database name catenated to '/'
|
A normalized name consists of the database name catenated to '/'
|
||||||
and table name. For example: test/mytable.
|
and table name. For example: test/mytable.
|
||||||
@ -11698,7 +11717,7 @@ Check engine specific table options not handled by SQL-parser.
|
|||||||
const char*
|
const char*
|
||||||
create_table_info_t::check_table_options()
|
create_table_info_t::check_table_options()
|
||||||
{
|
{
|
||||||
enum row_type row_format = m_form->s->row_type;
|
enum row_type row_format = m_create_info->row_type;
|
||||||
ha_table_option_struct *options= m_form->s->option_struct;
|
ha_table_option_struct *options= m_form->s->option_struct;
|
||||||
fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
|
fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
|
||||||
bool should_encrypt = (encrypt == FIL_ENCRYPTION_ON);
|
bool should_encrypt = (encrypt == FIL_ENCRYPTION_ON);
|
||||||
@ -11745,7 +11764,16 @@ create_table_info_t::check_table_options()
|
|||||||
return "PAGE_COMPRESSED";
|
return "PAGE_COMPRESSED";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row_format == ROW_TYPE_REDUNDANT) {
|
switch (row_format) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ROW_TYPE_DEFAULT:
|
||||||
|
if (m_default_row_format
|
||||||
|
!= DEFAULT_ROW_FORMAT_REDUNDANT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case ROW_TYPE_REDUNDANT:
|
||||||
push_warning(
|
push_warning(
|
||||||
m_thd, Sql_condition::WARN_LEVEL_WARN,
|
m_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
HA_WRONG_CREATE_OPTION,
|
HA_WRONG_CREATE_OPTION,
|
||||||
@ -11956,9 +11984,9 @@ create_table_info_t::parse_table_name(
|
|||||||
|
|
||||||
/** Determine InnoDB table flags.
|
/** Determine InnoDB table flags.
|
||||||
If strict_mode=OFF, this will adjust the flags to what should be assumed.
|
If strict_mode=OFF, this will adjust the flags to what should be assumed.
|
||||||
@retval true if successful, false if error */
|
@retval true on success
|
||||||
bool
|
@retval false on error */
|
||||||
create_table_info_t::innobase_table_flags()
|
bool create_table_info_t::innobase_table_flags()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("innobase_table_flags");
|
DBUG_ENTER("innobase_table_flags");
|
||||||
|
|
||||||
@ -11966,7 +11994,7 @@ create_table_info_t::innobase_table_flags()
|
|||||||
ulint zip_ssize = 0;
|
ulint zip_ssize = 0;
|
||||||
enum row_type row_type;
|
enum row_type row_type;
|
||||||
rec_format_t innodb_row_format =
|
rec_format_t innodb_row_format =
|
||||||
get_row_format(innodb_default_row_format);
|
get_row_format(m_default_row_format);
|
||||||
const bool is_temp
|
const bool is_temp
|
||||||
= m_create_info->options & HA_LEX_CREATE_TMP_TABLE;
|
= m_create_info->options & HA_LEX_CREATE_TMP_TABLE;
|
||||||
bool zip_allowed
|
bool zip_allowed
|
||||||
@ -12080,7 +12108,7 @@ index_bad:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row_type = m_form->s->row_type;
|
row_type = m_create_info->row_type;
|
||||||
|
|
||||||
if (zip_ssize && zip_allowed) {
|
if (zip_ssize && zip_allowed) {
|
||||||
/* if ROW_FORMAT is set to default,
|
/* if ROW_FORMAT is set to default,
|
||||||
@ -12420,8 +12448,6 @@ create_table_info_t::initialize()
|
|||||||
DBUG_RETURN(HA_ERR_WRONG_INDEX);
|
DBUG_RETURN(HA_ERR_WRONG_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(m_form->s->row_type == m_create_info->row_type);
|
|
||||||
|
|
||||||
/* Get the transaction associated with the current thd, or create one
|
/* Get the transaction associated with the current thd, or create one
|
||||||
if not yet created */
|
if not yet created */
|
||||||
|
|
||||||
@ -12465,8 +12491,6 @@ int create_table_info_t::prepare_create_table(const char* name, bool strict)
|
|||||||
ut_ad(m_thd != NULL);
|
ut_ad(m_thd != NULL);
|
||||||
ut_ad(m_create_info != NULL);
|
ut_ad(m_create_info != NULL);
|
||||||
|
|
||||||
ut_ad(m_form->s->row_type == m_create_info->row_type);
|
|
||||||
|
|
||||||
set_tablespace_type(false);
|
set_tablespace_type(false);
|
||||||
|
|
||||||
normalize_table_name(m_table_name, name);
|
normalize_table_name(m_table_name, name);
|
||||||
@ -13530,6 +13554,21 @@ int ha_innobase::truncate()
|
|||||||
trx_rollback_for_mysql(trx);
|
trx_rollback_for_mysql(trx);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
} else {
|
} else {
|
||||||
|
switch (dict_tf_get_rec_format(ib_table->flags)) {
|
||||||
|
case REC_FORMAT_REDUNDANT:
|
||||||
|
info.row_type = ROW_TYPE_REDUNDANT;
|
||||||
|
break;
|
||||||
|
case REC_FORMAT_COMPACT:
|
||||||
|
info.row_type = ROW_TYPE_COMPACT;
|
||||||
|
break;
|
||||||
|
case REC_FORMAT_COMPRESSED:
|
||||||
|
info.row_type = ROW_TYPE_COMPRESSED;
|
||||||
|
break;
|
||||||
|
case REC_FORMAT_DYNAMIC:
|
||||||
|
info.row_type = ROW_TYPE_DYNAMIC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
err = create(name, table, &info,
|
err = create(name, table, &info,
|
||||||
ib_table->is_temporary()
|
ib_table->is_temporary()
|
||||||
|| dict_table_is_file_per_table(ib_table), trx);
|
|| dict_table_is_file_per_table(ib_table), trx);
|
||||||
|
@ -641,15 +641,7 @@ public:
|
|||||||
char* table_name,
|
char* table_name,
|
||||||
char* remote_path,
|
char* remote_path,
|
||||||
bool file_per_table,
|
bool file_per_table,
|
||||||
trx_t* trx = NULL)
|
trx_t* trx = NULL);
|
||||||
:m_thd(thd),
|
|
||||||
m_trx(trx),
|
|
||||||
m_form(form),
|
|
||||||
m_create_info(create_info),
|
|
||||||
m_table_name(table_name), m_drop_before_rollback(false),
|
|
||||||
m_remote_path(remote_path),
|
|
||||||
m_innodb_file_per_table(file_per_table)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Initialize the object. */
|
/** Initialize the object. */
|
||||||
int initialize();
|
int initialize();
|
||||||
@ -758,6 +750,9 @@ private:
|
|||||||
/** Information on table columns and indexes. */
|
/** Information on table columns and indexes. */
|
||||||
const TABLE* m_form;
|
const TABLE* m_form;
|
||||||
|
|
||||||
|
/** Value of innodb_default_row_format */
|
||||||
|
const ulong m_default_row_format;
|
||||||
|
|
||||||
/** Create options. */
|
/** Create options. */
|
||||||
HA_CREATE_INFO* m_create_info;
|
HA_CREATE_INFO* m_create_info;
|
||||||
|
|
||||||
|
@ -727,31 +727,30 @@ dict_tf_set(
|
|||||||
ulint page_compression_level,
|
ulint page_compression_level,
|
||||||
ulint not_used)
|
ulint not_used)
|
||||||
{
|
{
|
||||||
|
*flags = use_data_dir ? 1 << DICT_TF_POS_DATA_DIR : 0;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case REC_FORMAT_REDUNDANT:
|
case REC_FORMAT_REDUNDANT:
|
||||||
*flags = 0;
|
|
||||||
ut_ad(zip_ssize == 0);
|
ut_ad(zip_ssize == 0);
|
||||||
break;
|
/* no other options are allowed */
|
||||||
|
ut_ad(!page_compressed);
|
||||||
|
return;
|
||||||
case REC_FORMAT_COMPACT:
|
case REC_FORMAT_COMPACT:
|
||||||
*flags = DICT_TF_COMPACT;
|
*flags |= DICT_TF_COMPACT;
|
||||||
ut_ad(zip_ssize == 0);
|
ut_ad(zip_ssize == 0);
|
||||||
break;
|
break;
|
||||||
case REC_FORMAT_COMPRESSED:
|
case REC_FORMAT_COMPRESSED:
|
||||||
*flags = DICT_TF_COMPACT
|
*flags |= DICT_TF_COMPACT
|
||||||
| (1 << DICT_TF_POS_ATOMIC_BLOBS)
|
| (1 << DICT_TF_POS_ATOMIC_BLOBS)
|
||||||
| (zip_ssize << DICT_TF_POS_ZIP_SSIZE);
|
| (zip_ssize << DICT_TF_POS_ZIP_SSIZE);
|
||||||
break;
|
break;
|
||||||
case REC_FORMAT_DYNAMIC:
|
case REC_FORMAT_DYNAMIC:
|
||||||
*flags = DICT_TF_COMPACT
|
*flags |= DICT_TF_COMPACT
|
||||||
| (1 << DICT_TF_POS_ATOMIC_BLOBS);
|
| (1 << DICT_TF_POS_ATOMIC_BLOBS);
|
||||||
ut_ad(zip_ssize == 0);
|
ut_ad(zip_ssize == 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_data_dir) {
|
|
||||||
*flags |= (1 << DICT_TF_POS_DATA_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (page_compressed) {
|
if (page_compressed) {
|
||||||
*flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
|
*flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
|
||||||
| (1 << DICT_TF_POS_PAGE_COMPRESSION)
|
| (1 << DICT_TF_POS_PAGE_COMPRESSION)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user