|
Also see MDEV-22651
|
|
Different assertion failure, probably the same root cause:
--source include/have_innodb.inc
|
|
CREATE TABLE t1 (a TEXT CHARSET utf8, b INT) ENGINE=InnoDB CHARSET utf8mb4;
|
ALTER TABLE t1 MODIFY a TEXT AFTER b;
|
|
# Cleanup
|
DROP TABLE t1;
|
|
10.4 debug 9bdf35e9
|
mysqld: /data/src/10.4/storage/innobase/handler/handler0alter.cc:550: bool dict_table_t::instant_column(const dict_table_t&, const ulint*): Assertion `c.same_type(*o)' failed.
|
200615 18:40:05 [ERROR] mysqld got signal 6 ;
|
|
#7 0x00007f7984ac4f12 in __GI___assert_fail (assertion=0x561311a54754 "c.same_type(*o)", file=0x561311a53a28 "/data/src/10.4/storage/innobase/handler/handler0alter.cc", line=550, function=0x561311a5ca20 <dict_table_t::instant_column(dict_table_t const&, unsigned long const*)::__PRETTY_FUNCTION__> "bool dict_table_t::instant_column(const dict_table_t&, const ulint*)") at assert.c:101
|
#8 0x000056131113c5e4 in dict_table_t::instant_column (this=0x7f792c1a0310, table=..., col_map=0x7f792c148be0) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:550
|
#9 0x000056131113fc03 in ha_innobase_inplace_ctx::instant_column (this=0x7f792c014878) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:1088
|
#10 0x000056131111dcb8 in innobase_instant_try (ha_alter_info=0x7f7979e2ad50, ctx=0x7f792c014878, altered_table=0x7f7979e2adf0, table=0x7f792c1587b0, trx=0x7f797a8c8268) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:5710
|
#11 0x000056131114366d in commit_try_norebuild (ha_alter_info=0x7f7979e2ad50, ctx=0x7f792c014878, altered_table=0x7f7979e2adf0, old_table=0x7f792c1587b0, trx=0x7f797a8c8268, table_name=0x7f792c1573f5 "t1") at /data/src/10.4/storage/innobase/handler/handler0alter.cc:10256
|
#12 0x0000561311130dc5 in ha_innobase::commit_inplace_alter_table (this=0x7f792c19fb18, altered_table=0x7f7979e2adf0, ha_alter_info=0x7f7979e2ad50, commit=true) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:11007
|
#13 0x0000561310e9c9ed in handler::ha_commit_inplace_alter_table (this=0x7f792c19fb18, altered_table=0x7f7979e2adf0, ha_alter_info=0x7f7979e2ad50, commit=true) at /data/src/10.4/sql/handler.cc:4593
|
#14 0x0000561310c2540f in mysql_inplace_alter_table (thd=0x7f792c000af0, table_list=0x7f792c013290, table=0x7f792c1587b0, altered_table=0x7f7979e2adf0, ha_alter_info=0x7f7979e2ad50, inplace_supported=HA_ALTER_INPLACE_INSTANT, target_mdl_request=0x7f7979e2bbc0, alter_ctx=0x7f7979e2c700) at /data/src/10.4/sql/sql_table.cc:7797
|
#15 0x0000561310c2c08c in mysql_alter_table (thd=0x7f792c000af0, new_db=0x7f792c0052b0, new_name=0x7f792c0056b8, create_info=0x7f7979e2d2f0, table_list=0x7f792c013290, alter_info=0x7f7979e2d230, order_num=0, order=0x0, ignore=false) at /data/src/10.4/sql/sql_table.cc:10151
|
#16 0x0000561310cc42f1 in Sql_cmd_alter_table::execute (this=0x7f792c013a80, thd=0x7f792c000af0) at /data/src/10.4/sql/sql_alter.cc:520
|
#17 0x0000561310b41f26 in mysql_execute_command (thd=0x7f792c000af0) at /data/src/10.4/sql/sql_parse.cc:6101
|
#18 0x0000561310b47411 in mysql_parse (thd=0x7f792c000af0, rawbuf=0x7f792c013198 "ALTER TABLE t1 MODIFY a TEXT AFTER b", length=36, parser_state=0x7f7979e2e570, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:7901
|
#19 0x0000561310b3399b in dispatch_command (command=COM_QUERY, thd=0x7f792c000af0, packet=0x7f792c0083a1 "ALTER TABLE t1 MODIFY a TEXT AFTER b", packet_length=36, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:1842
|
#20 0x0000561310b3213d in do_command (thd=0x7f792c000af0) at /data/src/10.4/sql/sql_parse.cc:1360
|
#21 0x0000561310cbad0c in do_handle_one_connection (connect=0x561314a84580) at /data/src/10.4/sql/sql_connect.cc:1412
|
#22 0x0000561310cbaa5b in handle_one_connection (arg=0x561314a84580) at /data/src/10.4/sql/sql_connect.cc:1316
|
#23 0x00005613116b9165 in pfs_spawn_thread (arg=0x561314a02530) at /data/src/10.4/storage/perfschema/pfs.cc:1869
|
#24 0x00007f7986a4d4a4 in start_thread (arg=0x7f7979e2f700) at pthread_create.c:456
|
#25 0x00007f7984b81d0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
|
|
|
Thank you Elena.
Seen thus far:
fields[i].same(instant.fields[i])|SIGABRT|dict_index_t::instant_add_field|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try ## Original testcase
|
c.same_type(*o)|SIGABRT|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try|commit_try_norebuild ## Elena's testcase
|
trx_id_offset == instant.trx_id_offset|SIGABRT|dict_index_t::instant_add_field|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try ## Testcase below
|
|
|
Another assert/testcase.
USE test;
|
CREATE TABLE t (a TEXT,b CHAR(255) PRIMARY KEY) CHARSET=utf8;
|
SET GLOBAL innodb_default_row_format = 0;
|
ALTER TABLE t ADD COLUMN c INT FIRST;
|
Leads to:
|
10.5.5 e1013725ce0f3f947e728491eef75d9985e8db2f
|
mysqld: /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:417: void dict_index_t::instant_add_field(const dict_index_t&): Assertion `trx_id_offset == instant.trx_id_offset' failed.
|
|
10.5.5 e1013725ce0f3f947e728491eef75d9985e8db2f
|
Core was generated by `/test/MD250620-mariadb-10.5.5-linux-x86_64-dbg/bin/mysqld --no-defaults --core-'.
|
Program terminated with signal SIGABRT, Aborted.
|
#0 __pthread_kill (threadid=<optimized out>, signo=signo@entry=6)
|
at ../sysdeps/unix/sysv/linux/pthread_kill.c:57
|
[Current thread is 1 (Thread 0x14c0b917c700 (LWP 1762421))]
|
(gdb) bt
|
#0 __pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:57
|
#1 0x000055863897a7d0 in my_write_core (sig=sig@entry=6) at /test/10.5_dbg/mysys/stacktrace.c:518
|
#2 0x000055863813347a in handle_fatal_signal (sig=6) at /test/10.5_dbg/sql/signal_handler.cc:330
|
#3 <signal handler called>
|
#4 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
|
#5 0x000014c0b74128b1 in __GI_abort () at abort.c:79
|
#6 0x000014c0b740242a in __assert_fail_base (fmt=0x14c0b7589a38 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x558638d77360 "trx_id_offset == instant.trx_id_offset", file=file@entry=0x558638d6de88 "/test/10.5_dbg/storage/innobase/handler/handler0alter.cc", line=line@entry=417, function=function@entry=0x558638d73000 <dict_index_t::instant_add_field(dict_index_t const&)::__PRETTY_FUNCTION__> "void dict_index_t::instant_add_field(const dict_index_t&)") at assert.c:92
|
#7 0x000014c0b74024a2 in __GI___assert_fail (assertion=assertion@entry=0x558638d77360 "trx_id_offset == instant.trx_id_offset", file=file@entry=0x558638d6de88 "/test/10.5_dbg/storage/innobase/handler/handler0alter.cc", line=line@entry=417, function=function@entry=0x558638d73000 <dict_index_t::instant_add_field(dict_index_t const&)::__PRETTY_FUNCTION__> "void dict_index_t::instant_add_field(const dict_index_t&)") at assert.c:101
|
#8 0x0000558638536aae in dict_index_t::instant_add_field (this=this@entry=0x14c094cde698, instant=@0x14c094cdf118: {static MAX_N_FIELDS = 1023, id = 0, heap = 0x14c094c63818, name = {m_name = 0x14c094cea998 "PRIMARY"}, table = 0x14c094c55298, page = 4294967295, merge_threshold = 50, type = 3, trx_id_offset = 765, n_user_defined_cols = 1, nulls_equal = 0, n_uniq = 1, n_def = 5, n_fields = 5, n_nullable = 2, n_core_fields = 4, n_core_null_bytes = 1, static NO_CORE_NULL_BYTES = 255, static DICT_INDEXES_ID = 3, cached = 1, to_be_dropped = 0, online_status = 0, uncommitted = 0, is_dummy = false, in_instant_init = false, magic_n = 76789786, fields = 0x14c094c42bf0, parser = 0x0, has_new_v_col = false, indexes = {prev = 0x0, next = 0x0}, search_info = 0x14c094ceaa68, online_log = 0x0, stat_n_diff_key_vals = 0x14c094ceaa50, stat_n_sample_sizes = 0x14c094ceaa58, stat_n_non_null_key_vals = 0x14c094ceaa60, stat_index_size = 1, stat_n_leaf_pages = 1, stats_error_printed = false, stat_defrag_modified_counter = 0, stat_defrag_n_pages_freed = 0, stat_defrag_n_page_split = 0, stat_defrag_data_size_sample = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, stat_defrag_sample_next_slot = 0, rtr_ssn = {m = {<std::__atomic_base<unsigned int>> = {static _S_alignment = 4, _M_i = 0}, <No data fields>}}, rtr_track = 0x0, trx_id = 0, zip_pad = {mutex = {m_impl = {m_freed = false, m_locked = false, m_destroy_at_exit = true, m_mutex = {m_freed = false, m_mutex = pthread_mutex_t = {
|
Type = Normal,
|
Status = Not acquired,
|
Robust = No,
|
Shared = No,
|
Protocol = None
|
}}, m_policy = {context = {<latch_t> = {_vptr.latch_t = 0x5586394d1120 <vtable for MutexDebug<OSTrackMutex<GenericPolicy> >+16>, m_id = LATCH_ID_ZIP_PAD_MUTEX, m_rw_lock = false}, m_mutex = 0x0, m_filename = 0x0, m_line = 0, m_thread_id = 18446744073709551615, m_debug_mutex = {m_freed = false, m_mutex = pthread_mutex_t = {
|
Type = Normal,
|
Status = Not acquired,
|
Robust = No,
|
Shared = No,
|
Protocol = None
|
}}}, m_count = {m_spins = 0, m_waits = 0, m_calls = 0, m_enabled = false}, m_id = LATCH_ID_ZIP_PAD_MUTEX}}, m_ptr = 0x0}, pad = {m = {<std::__atomic_base<unsigned long>> = {static _S_alignment = 8, _M_i = 0}, <No data fields>}}, success = 0, failure = 0, n_rounds = 0}, lock = {<latch_t> = {_vptr.latch_t = 0x5586394d1690 <vtable for rw_lock_t+16>, m_id = LATCH_ID_INDEX_TREE, m_rw_lock = true}, lock_word = {m = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = 536870912}, <No data fields>}}, waiters = {m = {<std::__atomic_base<unsigned int>> = {static _S_alignment = 4, _M_i = 0}, <No data fields>}}, sx_recursive = 0, writer_is_wait_ex = false, writer_thread = 0, event = 0x14c094c61d58, wait_ex_event = 0x14c094c61df8, cfile_name = 0x558638e26670 "/test/10.5_dbg/storage/innobase/dict/dict0dict.cc", last_x_file_name = 0x558638dea4a1 "not yet reserved", cline = 2155, is_block_lock = 0, last_x_line = 0, count_os_wait = 0, list = {prev = 0x0, next = 0x14c094c55450}, pfs_psi = 0x0, debug_list = {count = 0, start = 0x0, end = 0x0, node = &rw_lock_debug_t::list, init = 51966}, level = SYNC_INDEX_TREE}}) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:417
|
#9 0x000055863854065d in dict_table_t::instant_column (this=0x14c094c52f98, table=<optimized out>, col_map=<optimized out>) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:604
|
#10 0x0000558638540c68 in ha_innobase_inplace_ctx::instant_column (this=this@entry=0x14c094c75b60) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:1050
|
#11 0x0000558638540ebe in innobase_instant_try (ha_alter_info=ha_alter_info@entry=0x14c0b9177940, ctx=ctx@entry=0x14c094c75b60, altered_table=altered_table@entry=0x14c0b91779e0, table=table@entry=0x14c094cbf088, trx=trx@entry=0x14c0a3c03548) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:5629
|
#12 0x0000558638544694 in commit_try_norebuild (ha_alter_info=ha_alter_info@entry=0x14c0b9177940, ctx=ctx@entry=0x14c094c75b60, altered_table=altered_table@entry=0x14c0b91779e0, old_table=0x14c094cbf088, trx=0x14c0a3c03548, table_name=<optimized out>) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:10179
|
#13 0x0000558638530cda in ha_innobase::commit_inplace_alter_table (this=0x14c094c36ca0, altered_table=0x14c0b91779e0, ha_alter_info=0x14c0b9177940, commit=true) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:10899
|
#14 0x0000558638141c9b in handler::ha_commit_inplace_alter_table (this=0x14c094c36ca0, altered_table=altered_table@entry=0x14c0b91779e0, ha_alter_info=ha_alter_info@entry=0x14c0b9177940, commit=commit@entry=true) at /test/10.5_dbg/sql/handler.cc:4831
|
#15 0x0000558637f4fc04 in mysql_inplace_alter_table (thd=thd@entry=0x14c094c15088, table_list=0x14c094c74198, table=table@entry=0x14c094cbf088, altered_table=altered_table@entry=0x14c0b91779e0, ha_alter_info=ha_alter_info@entry=0x14c0b9177940, inplace_supported=inplace_supported@entry=HA_ALTER_INPLACE_INSTANT, target_mdl_request=0x14c0b91787a0, alter_ctx=0x14c0b9179630) at /test/10.5_dbg/sql/sql_table.cc:8074
|
#16 0x0000558637f601f4 in mysql_alter_table (thd=thd@entry=0x14c094c15088, new_db=new_db@entry=0x14c094c19948, new_name=new_name@entry=0x14c094c19d50, create_info=create_info@entry=0x14c0b917a220, table_list=<optimized out>, table_list@entry=0x14c094c74198, alter_info=alter_info@entry=0x14c0b917a150, order_num=0, order=0x0, ignore=false, if_exists=false) at /test/10.5_dbg/sql/sql_table.cc:10595
|
#17 0x0000558637fe3f92 in Sql_cmd_alter_table::execute (this=<optimized out>, thd=0x14c094c15088) at /test/10.5_dbg/sql/sql_alter.cc:532
|
#18 0x0000558637e8dd26 in mysql_execute_command (thd=thd@entry=0x14c094c15088) at /test/10.5_dbg/sql/sql_parse.cc:5953
|
#19 0x0000558637e95638 in mysql_parse (thd=thd@entry=0x14c094c15088, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14c0b917b350, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_parse.cc:7995
|
#20 0x0000558637e82110 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14c094c15088, packet=packet@entry=0x14c094c67089 "ALTER TABLE t ADD COLUMN c INT FIRST", packet_length=packet_length@entry=36, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_parse.cc:1874
|
#21 0x0000558637e808ea in do_command (thd=0x14c094c15088) at /test/10.5_dbg/sql/sql_parse.cc:1355
|
#22 0x0000558637fdc15f in do_handle_one_connection (connect=<optimized out>, connect@entry=0x14c0980d2808, put_in_cache=put_in_cache@entry=true) at /test/10.5_dbg/sql/sql_connect.cc:1411
|
#23 0x0000558637fdc87b in handle_one_connection (arg=arg@entry=0x14c0980d2808) at /test/10.5_dbg/sql/sql_connect.cc:1313
|
#24 0x000055863843f11c in pfs_spawn_thread (arg=0x14c0b6046508) at /test/10.5_dbg/storage/perfschema/pfs.cc:2201
|
#25 0x000014c0b80f56db in start_thread (arg=0x14c0b917c700) at pthread_create.c:463
|
#26 0x000014c0b74f3a3f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
|
Bug confirmed present in:
MariaDB: 10.4.14 (dbg), 10.5.5 (dbg)
Bug confirmed not present in:
MariaDB: 10.1.46 (dbg), 10.1.46 (opt), 10.2.33 (dbg), 10.2.33 (opt), 10.3.24 (dbg), 10.3.24 (opt), 10.4.14 (opt), 10.5.5 (opt)
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.47 (dbg), 5.6.47 (opt), 5.7.29 (dbg), 5.7.29 (opt), 8.0.19 (dbg), 8.0.19 (opt)
|
|
I can repeat this with the following test:
--source include/have_innodb.inc
|
CREATE TABLE t (a CHAR(198)) ENGINE=InnoDB;
|
ALTER TABLE t CHANGE COLUMN a a CHAR(220) BINARY;
|
#ALTER TABLE t ADD COLUMN va INT GENERATED ALWAYS AS (length(a));
|
#--source include/restart_mysqld.inc
|
ALTER TABLE t ADD COLUMN b INT FIRST;
|
DROP TABLE t;
|
Notably, CHECK TABLE would not fail. Furthermore, if I cause the table definition to be reloaded into the InnoDB dict_sys cache by enabling one of the two commented-out lines, the test case will not crash.
|
|
In innobase_rename_or_enlarge_columns_cache(), we update dict_col_t::len but not dict_field_t::fixed_len. This is correct: as noted in MDEV-18627, we can only instantly extend a variable-length encoded column, but not a fixed-length one.
Note: MySQL 5.7 and MariaDB 10.2.2 made it possible to extend VARCHAR columns instantly. MDEV-15563 lifted some limitations on extending those columns, related to crossing the maximum-length boundary of 255 bytes. But, after the MDEV-18627 fix, it was never the intention that fixed-length columns could be extended without rebuilding the table.
|
|
I can repeat a crash with the change for addressing MDEV-17301, but not with the parent of that commit:
--source include/have_innodb.inc
|
CREATE TABLE t (a CHAR(1)) ENGINE=InnoDB;
|
ALTER TABLE t CHANGE COLUMN a a CHAR(3) BINARY;
|
INSERT INTO t VALUES('abc');
|
SELECT a FROM t;
|
DROP TABLE t;
|
The INSERT statement would crash as follows:
|
10.4 854c219a7f0e1878517d5a821992f650342380dd
|
mysqltest: At line 4: query 'INSERT INTO t VALUES('abc')' failed: 2013: Lost connection to MySQL server during query
|
…
|
Version: '10.4.7-MariaDB-debug-log' socket: '/dev/shm/10.4/mysql-test/var/tmp/mysqld.1.sock' port: 16000 Source distribution
|
mysqld: /mariadb/10.4/storage/innobase/rem/rem0rec.cc:1216: ulint rec_get_converted_size_comp_prefix_low(const dict_index_t*, const dfield_t*, ulint, ulint*, rec_comp_status_t, bool) [with bool mblob = false; ulint = long unsigned int]: Assertion `len <= fixed_len' failed.
|
|
|
I think that the condition for ROW_FORMAT is bogus when it comes to CHAR columns. We should instead check if the character set is variable-length. With the following fix, the test case works for me:
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
|
index f85ee3f26fb..d0b1bbc8a33 100644
|
--- a/storage/innobase/handler/ha_innodb.cc
|
+++ b/storage/innobase/handler/ha_innodb.cc
|
@@ -20986,43 +20986,34 @@ is_part_of_a_primary_key(const Field* field)
|
&& field->part_of_key.is_set(s->primary_key);
|
}
|
|
-bool
|
-ha_innobase::can_convert_string(const Field_string* field,
|
- const Column_definition& new_type) const
|
+bool ha_innobase::can_convert_string(const Field_string *field,
|
+ const Column_definition &new_type) const
|
{
|
- DBUG_ASSERT(!field->compression_method());
|
- if (new_type.type_handler() != field->type_handler()) {
|
- return false;
|
- }
|
+ DBUG_ASSERT(!field->compression_method());
|
+ if (new_type.type_handler() != field->type_handler())
|
+ return false;
|
|
- if (new_type.char_length < field->char_length()) {
|
- return false;
|
- }
|
+ if (new_type.char_length < field->char_length())
|
+ return false;
|
|
- if (new_type.charset != field->charset()) {
|
- if (new_type.length != field->max_display_length()
|
- && !m_prebuilt->table->not_redundant()) {
|
- return IS_EQUAL_NO;
|
- }
|
+ const Charset field_cs(field->charset());
|
|
- Charset field_cs(field->charset());
|
- if (!field_cs.encoding_allows_reinterpret_as(
|
- new_type.charset)) {
|
- return false;
|
- }
|
+ if (field_cs.mbminlen() == field_cs.mbmaxlen() &&
|
+ new_type.length != field->max_display_length())
|
+ return false;
|
|
- if (!field_cs.eq_collation_specific_names(new_type.charset)) {
|
- return !is_part_of_a_primary_key(field);
|
- }
|
+ if (new_type.charset != field->charset())
|
+ {
|
+ if (!field_cs.encoding_allows_reinterpret_as(new_type.charset))
|
+ return false;
|
|
- return true;
|
- }
|
+ if (!field_cs.eq_collation_specific_names(new_type.charset))
|
+ return !is_part_of_a_primary_key(field);
|
|
- if (new_type.length != field->max_display_length()) {
|
- return false;
|
- }
|
+ return true;
|
+ }
|
|
- return true;
|
+ return true;
|
}
|
|
static bool
|
The essential fix is that we remove the code that returned IS_EQUAL_NO, and enforce the ‘enlargement check’ independent of any charset change:
if (field_cs.mbminlen() == field_cs.mbmaxlen() &&
|
new_type.length != field->max_display_length())
|
return false;
|
This also replaces the check at the very end of the function.
|
|
I forgot that for ROW_FORMAT=REDUNDANT, we cannot support any CHAR extension even for variable-length character sets, because the optimization related to trying to allocate n*mbminlen bytes for CHAR only applies to ROW_FORMAT=COMPACT and later formats. For COMPACT and DYNAMIC, I would still get a failure
|
10.4 with tentative fix
|
CURRENT_TEST: innodb.instant_alter_extend
|
mysqltest: At line 61: query 'select count(a) from t where a = @bigval' failed: 2013: Lost connection to MySQL server during query
|
…
|
mysqld: /mariadb/10.4/storage/innobase/row/row0sel.cc:2806: void row_sel_field_store_in_mysql_format_func(byte*, const mysql_row_templ_t*, const dict_index_t*, ulint, const byte*, ulint): Assertion `len * templ->mbmaxlen >= templ->mysql_col_len || (field_no == templ->icp_rec_field_no && field->prefix_len > 0) || templ->rec_field_is_prefix' failed.
|
We are reading a row from the table, and the column had a length of 600 bytes, corresponding to CHAR(200) in {my_charset_utf8_general_ci}}, while the column had meanwhile been extended to CHAR(220). For compatibility with DML code, we must not allow any instantaneous change of the number of characters. We can only allow a change of bytes when the number of characters remains unchanged.
I am now testing the following change:
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
|
index f85ee3f26fb..6d100576c20 100644
|
--- a/storage/innobase/handler/ha_innodb.cc
|
+++ b/storage/innobase/handler/ha_innodb.cc
|
@@ -20986,43 +20986,35 @@ is_part_of_a_primary_key(const Field* field)
|
&& field->part_of_key.is_set(s->primary_key);
|
}
|
|
-bool
|
-ha_innobase::can_convert_string(const Field_string* field,
|
- const Column_definition& new_type) const
|
+bool ha_innobase::can_convert_string(const Field_string *field,
|
+ const Column_definition &new_type) const
|
{
|
- DBUG_ASSERT(!field->compression_method());
|
- if (new_type.type_handler() != field->type_handler()) {
|
- return false;
|
- }
|
+ DBUG_ASSERT(!field->compression_method());
|
+ if (new_type.type_handler() != field->type_handler())
|
+ return false;
|
|
- if (new_type.char_length < field->char_length()) {
|
- return false;
|
- }
|
+ if (new_type.char_length != field->char_length())
|
+ return false;
|
|
- if (new_type.charset != field->charset()) {
|
- if (new_type.length != field->max_display_length()
|
- && !m_prebuilt->table->not_redundant()) {
|
- return IS_EQUAL_NO;
|
- }
|
+ const Charset field_cs(field->charset());
|
|
- Charset field_cs(field->charset());
|
- if (!field_cs.encoding_allows_reinterpret_as(
|
- new_type.charset)) {
|
- return false;
|
- }
|
+ if (new_type.length != field->max_display_length() &&
|
+ (!m_prebuilt->table->not_redundant() ||
|
+ field_cs.mbminlen() == field_cs.mbmaxlen()))
|
+ return false;
|
|
- if (!field_cs.eq_collation_specific_names(new_type.charset)) {
|
- return !is_part_of_a_primary_key(field);
|
- }
|
+ if (new_type.charset != field->charset())
|
+ {
|
+ if (!field_cs.encoding_allows_reinterpret_as(new_type.charset))
|
+ return false;
|
|
- return true;
|
- }
|
+ if (!field_cs.eq_collation_specific_names(new_type.charset))
|
+ return !is_part_of_a_primary_key(field);
|
|
- if (new_type.length != field->max_display_length()) {
|
- return false;
|
- }
|
+ return true;
|
+ }
|
|
- return true;
|
+ return true;
|
}
|
|
static bool
|
|
|
The following test case change would also trigger another assertion failure:
diff --git a/mysql-test/suite/innodb/t/instant_alter_extend.test b/mysql-test/suite/innodb/t/instant_alter_extend.test
|
index 4320d9bae05..7258ba6d238 100644
|
--- a/mysql-test/suite/innodb/t/instant_alter_extend.test
|
+++ b/mysql-test/suite/innodb/t/instant_alter_extend.test
|
@@ -64,6 +64,15 @@ select a, length(a) from t where a = 'z';
|
check table t extended;
|
call check_table('t');
|
|
+--enable_info
|
+ALTER TABLE t CHANGE COLUMN a a CHAR(230) BINARY;
|
+ALTER TABLE t ADD COLUMN b INT FIRST;
|
+ALTER TABLE t DROP b;
|
+--disable_info
|
+
|
+check table t extended;
|
+call check_table('t');
|
+
|
--echo # Convert from VARCHAR to a bigger CHAR
|
--enable_info
|
alter table t modify a varchar(200);
|
|
10.4 0a7faed75ad49b99bace0882f89e08639c85679b
|
innodb.instant_alter_extend 'debug,dynamic,innodb,utf8' [ fail ]
|
Test ended at 2020-07-20 14:25:44
|
|
CURRENT_TEST: innodb.instant_alter_extend
|
mysqltest: At line 78: query 'alter table t modify a varchar(200)' failed: 2013: Lost connection to MySQL server during query
|
…
|
mysqld: /mariadb/10.4/storage/innobase/row/row0sel.cc:2806: void row_sel_field_store_in_mysql_format_func(byte*, const mysql_row_templ_t*, const dict_index_t*, ulint, const byte*, ulint): Assertion `len * templ->mbmaxlen >= templ->mysql_col_len || (field_no == templ->icp_rec_field_no && field->prefix_len > 0) || templ->rec_field_is_prefix' failed.
|
|
|
Another similar testcase.
USE test;
|
CREATE TABLE t (c CHAR(255), PRIMARY KEY (c)) CHARSET=utf8;
|
ALTER TABLE t ADD COLUMN b INT FIRST;
|
SET GLOBAL INNODB_DEFAULT_ROW_FORMAT = 0;
|
ALTER TABLE t ADD COLUMN a INT FIRST;
|
Leads to:
|
10.5.5 30e7a0a866dce530d8328c6d614e48d39a264f9b (Debug)
|
mysqld: /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:417: void dict_index_t::instant_add_field(const dict_index_t&): Assertion `trx_id_offset == instant.trx_id_offset' failed.
|
|
10.5.5 30e7a0a866dce530d8328c6d614e48d39a264f9b (Debug)
|
Core was generated by `/test/MD140720-mariadb-10.5.5-linux-x86_64-dbg/bin/mysqld --no-defaults --core-'.
|
Program terminated with signal SIGABRT, Aborted.
|
#0 __pthread_kill (threadid=<optimized out>, signo=signo@entry=6)
|
at ../sysdeps/unix/sysv/linux/pthread_kill.c:57
|
[Current thread is 1 (Thread 0x1487b10ff700 (LWP 999380))]
|
(gdb) bt
|
#0 __pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:57
|
#1 0x0000561dcf67b4d7 in my_write_core (sig=sig@entry=6) at /test/10.5_dbg/mysys/stacktrace.c:518
|
#2 0x0000561dcee359ba in handle_fatal_signal (sig=6) at /test/10.5_dbg/sql/signal_handler.cc:330
|
#3 <signal handler called>
|
#4 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
|
#5 0x00001487af3958b1 in __GI_abort () at abort.c:79
|
#6 0x00001487af38542a in __assert_fail_base (fmt=0x1487af50ca38 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x561dcfa78900 "trx_id_offset == instant.trx_id_offset", file=file@entry=0x561dcfa6f428 "/test/10.5_dbg/storage/innobase/handler/handler0alter.cc", line=line@entry=417, function=function@entry=0x561dcfa745a0 <dict_index_t::instant_add_field(dict_index_t const&)::__PRETTY_FUNCTION__> "void dict_index_t::instant_add_field(const dict_index_t&)") at assert.c:92
|
#7 0x00001487af3854a2 in __GI___assert_fail (assertion=assertion@entry=0x561dcfa78900 "trx_id_offset == instant.trx_id_offset", file=file@entry=0x561dcfa6f428 "/test/10.5_dbg/storage/innobase/handler/handler0alter.cc", line=line@entry=417, function=function@entry=0x561dcfa745a0 <dict_index_t::instant_add_field(dict_index_t const&)::__PRETTY_FUNCTION__> "void dict_index_t::instant_add_field(const dict_index_t&)") at assert.c:101
|
#8 0x0000561dcf239900 in dict_index_t::instant_add_field (this=this@entry=0x14878d0dc698, instant=@0x14878d0dd818: {static MAX_N_FIELDS = 1023, id = 0, heap = 0x14878d063718, name = {m_name = 0x14878d0e8298 "PRIMARY"}, table = 0x14878d055298, page = 4294967295, merge_threshold = 50, type = 3, trx_id_offset = 765, n_user_defined_cols = 1, nulls_equal = 0, n_uniq = 1, n_def = 5, n_fields = 5, n_nullable = 2, n_core_fields = 3, n_core_null_bytes = 0, static NO_CORE_NULL_BYTES = 255, static DICT_INDEXES_ID = 3, cached = 1, to_be_dropped = 0, online_status = 0, uncommitted = 0, is_dummy = false, in_instant_init = false, magic_n = 76789786, fields = 0x14878d043ff0, parser = 0x0, has_new_v_col = false, indexes = {prev = 0x0, next = 0x0}, search_info = 0x14878d0e8368, online_log = 0x0, stat_n_diff_key_vals = 0x14878d0e8350, stat_n_sample_sizes = 0x14878d0e8358, stat_n_non_null_key_vals = 0x14878d0e8360, stat_index_size = 1, stat_n_leaf_pages = 1, stats_error_printed = false, stat_defrag_modified_counter = 0, stat_defrag_n_pages_freed = 0, stat_defrag_n_page_split = 0, stat_defrag_data_size_sample = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, stat_defrag_sample_next_slot = 0, rtr_ssn = {m = {<std::__atomic_base<unsigned int>> = {static _S_alignment = 4, _M_i = 0}, <No data fields>}}, rtr_track = 0x0, trx_id = 0, zip_pad = {mutex = {m_impl = {m_freed = false, m_locked = false, m_destroy_at_exit = true, m_mutex = {m_freed = false, m_mutex = pthread_mutex_t = {
|
Type = Normal,
|
Status = Not acquired,
|
Robust = No,
|
Shared = No,
|
Protocol = None
|
}}, m_policy = {context = {<latch_t> = {_vptr.latch_t = 0x561dd01d1fa0 <vtable for MutexDebug<OSTrackMutex<GenericPolicy> >+16>, m_id = LATCH_ID_ZIP_PAD_MUTEX, m_rw_lock = false}, m_mutex = 0x0, m_filename = 0x0, m_line = 0, m_thread_id = 18446744073709551615, m_debug_mutex = {m_freed = false, m_mutex = pthread_mutex_t = {
|
Type = Normal,
|
Status = Not acquired,
|
Robust = No,
|
Shared = No,
|
Protocol = None
|
}}}, m_filename = 0x561dcfb2f068 "/test/10.5_dbg/storage/innobase/dict/dict0mem.cc", m_line = 807, m_count = {m_spins = 0, m_waits = 0, m_calls = 0, m_enabled = false}, m_id = LATCH_ID_ZIP_PAD_MUTEX}}, m_ptr = 0x0}, pad = {m = {<std::__atomic_base<unsigned long>> = {static _S_alignment = 8, _M_i = 0}, <No data fields>}}, success = 0, failure = 0, n_rounds = 0}, lock = {<latch_t> = {_vptr.latch_t = 0x561dd01d2510 <vtable for rw_lock_t+16>, m_id = LATCH_ID_INDEX_TREE, m_rw_lock = true}, <ilist_node<void>> = {next = 0x14878d055460, prev = 0x561dd0c95520 <rw_lock_list>}, created = true, lock_word = {m = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = 536870912}, <No data fields>}}, waiters = {m = {<std::__atomic_base<unsigned int>> = {static _S_alignment = 4, _M_i = 0}, <No data fields>}}, sx_recursive = 0, writer_is_wait_ex = false, writer_thread = 0, event = 0x14878d061178, wait_ex_event = 0x14878d0617b8, cfile_name = 0x561dcfb274b0 "/test/10.5_dbg/storage/innobase/dict/dict0dict.cc", last_x_file_name = 0x561dcfaeb4af "not yet reserved", cline = 2155, is_block_lock = 0, last_x_line = 0, count_os_wait = 0, pfs_psi = 0x0, debug_list = {count = 0, start = 0x0, end = 0x0, node = &rw_lock_debug_t::list, init = 51966}, level = SYNC_INDEX_TREE}}) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:417
|
#9 0x0000561dcf2434af in dict_table_t::instant_column (this=0x14878d052f98, table=<optimized out>, col_map=<optimized out>) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:604
|
#10 0x0000561dcf243aba in ha_innobase_inplace_ctx::instant_column (this=this@entry=0x14878d075b10) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:1050
|
#11 0x0000561dcf243d10 in innobase_instant_try (ha_alter_info=ha_alter_info@entry=0x1487b10fb330, ctx=ctx@entry=0x14878d075b10, altered_table=altered_table@entry=0x1487b10fb3d0, table=table@entry=0x14878d053988, trx=trx@entry=0x14879bc03578) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:5629
|
#12 0x0000561dcf2474e6 in commit_try_norebuild (ha_alter_info=ha_alter_info@entry=0x1487b10fb330, ctx=ctx@entry=0x14878d075b10, altered_table=altered_table@entry=0x1487b10fb3d0, old_table=0x14878d053988, trx=0x14879bc03578, table_name=<optimized out>) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:10179
|
#13 0x0000561dcf233b54 in ha_innobase::commit_inplace_alter_table (this=0x14878d0394a0, altered_table=0x1487b10fb3d0, ha_alter_info=0x1487b10fb330, commit=true) at /test/10.5_dbg/storage/innobase/handler/handler0alter.cc:10900
|
#14 0x0000561dcee44665 in handler::ha_commit_inplace_alter_table (this=0x14878d0394a0, altered_table=altered_table@entry=0x1487b10fb3d0, ha_alter_info=ha_alter_info@entry=0x1487b10fb330, commit=commit@entry=true) at /test/10.5_dbg/sql/handler.cc:4839
|
#15 0x0000561dcec51686 in mysql_inplace_alter_table (thd=thd@entry=0x14878d015088, table_list=0x14878d074198, table=table@entry=0x14878d053988, altered_table=altered_table@entry=0x1487b10fb3d0, ha_alter_info=ha_alter_info@entry=0x1487b10fb330, inplace_supported=inplace_supported@entry=HA_ALTER_INPLACE_INSTANT, target_mdl_request=0x1487b10fb7a0, alter_ctx=0x1487b10fc630) at /test/10.5_dbg/sql/sql_table.cc:8038
|
#16 0x0000561dcec61cb1 in mysql_alter_table (thd=thd@entry=0x14878d015088, new_db=new_db@entry=0x14878d019948, new_name=new_name@entry=0x14878d019d50, create_info=create_info@entry=0x1487b10fd220, table_list=<optimized out>, table_list@entry=0x14878d074198, alter_info=alter_info@entry=0x1487b10fd150, order_num=0, order=0x0, ignore=false, if_exists=false) at /test/10.5_dbg/sql/sql_table.cc:10564
|
#17 0x0000561dcece5a6a in Sql_cmd_alter_table::execute (this=<optimized out>, thd=0x14878d015088) at /test/10.5_dbg/sql/sql_alter.cc:532
|
#18 0x0000561dceb8ee4a in mysql_execute_command (thd=thd@entry=0x14878d015088) at /test/10.5_dbg/sql/sql_parse.cc:5951
|
#19 0x0000561dceb96752 in mysql_parse (thd=thd@entry=0x14878d015088, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x1487b10fe350, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_parse.cc:7993
|
#20 0x0000561dceb83204 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14878d015088, packet=packet@entry=0x14878d067089 "ALTER TABLE t ADD COLUMN a INT FIRST", packet_length=packet_length@entry=36, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_parse.cc:1866
|
#21 0x0000561dceb819de in do_command (thd=0x14878d015088) at /test/10.5_dbg/sql/sql_parse.cc:1347
|
#22 0x0000561dcecddc3b in do_handle_one_connection (connect=<optimized out>, connect@entry=0x1487900c7808, put_in_cache=put_in_cache@entry=true) at /test/10.5_dbg/sql/sql_connect.cc:1411
|
#23 0x0000561dcecde357 in handle_one_connection (arg=arg@entry=0x1487900c7808) at /test/10.5_dbg/sql/sql_connect.cc:1313
|
#24 0x0000561dcf141ca8 in pfs_spawn_thread (arg=0x1487adc46508) at /test/10.5_dbg/storage/perfschema/pfs.cc:2201
|
#25 0x00001487b00786db in start_thread (arg=0x1487b10ff700) at pthread_create.c:463
|
#26 0x00001487af476a3f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
|
Bug confirmed present in:
MariaDB: 10.4.14 (dbg), 10.4.14 (opt), 10.5.5 (dbg), 10.5.5 (opt)
Bug confirmed not present in:
MariaDB: 10.1.46 (dbg), 10.1.46 (opt), 10.2.33 (dbg), 10.2.33 (opt), 10.3.24 (dbg), 10.3.24 (opt)
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.47 (dbg), 5.6.47 (opt), 5.7.29 (dbg), 5.7.29 (opt), 8.0.19 (dbg), 8.0.19 (opt)
Assume it is covered in the fix.
|
|
Unique id's seen
trx_id_offset == instant.trx_id_offset|SIGABRT|dict_index_t::instant_add_field|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try
|
fields[i].same(instant.fields[i])|SIGABRT|dict_index_t::instant_add_field|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try
|
c.same_type(*o)|SIGABRT|dict_table_t::instant_column|ha_innobase_inplace_ctx::instant_column|innobase_instant_try|commit_try_norebuild
|
SIGABRT|ib::fatal::~fatal|btr_page_reorganize_low|btr_page_reorganize|btr_cur_pessimistic_update
|
|