Bug #106516 Upgrade from version 8.0.13 with discarded partitions asserts when opening table
Submitted: 19 Feb 2022 7:21 Modified: 21 Feb 2022 3:38
Reporter: Hope Lee (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Data Dictionary Severity:S6 (Debug Builds)
Version:8.0.27 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[19 Feb 2022 7:21] Hope Lee
Description:
After upgrading the server with discarded partitions from version '80013' to '80027', the server asserts when opening the partitioned table with discarded partitions.

How to repeat:
1. Initialize a data directory with MySQL 8.0.13 and create the test partitioned table with discarded partitions.

mysql-8.0.13 > CREATE DATABASE partitions;

mysql-8.0.13 > CREATE TABLE partitions.t1(c1 INT,c2 INT) PARTITION BY KEY(c1) PARTITIONS 4;

mysql-8.0.13 > ALTER TABLE partitions.t1 DISCARD PARTITION p0 TABLESPACE;

2. Upgrade above the 8.0.13 data directory with MySQL 8.0.27.

3. Doing a query on the partitioned table.

mysql-8.0.27 > SELECT * FROM partitions.t1;

And you will see the server asserts:
(gdb) bt
#0  0x00007ffff5f9f8af in raise () from /lib64/libc.so.6
#1  0x00007ffff5fa14aa in abort () from /lib64/libc.so.6
#2  0x0000000004c6cfab in ut_dbg_assertion_failed (expr=0x6bb51c8 "index->type & 32 || root != FIL_NULL || dict_table_is_discarded(m_table)", file=0x6bb2f78 "storage/innobase/dict/dict0dd.cc", line=4314) at storage/innobase/ut/ut0dbg.cc:99
#3  0x0000000004e02c12 in dd_open_table_one<dd::Partition> (client=0x7fff3c013b10, table=0x7fff3c0af2f0, norm_name=0x7fff3c0232a8 "partitions/t1#p#p0", dd_table=0x7fff3c0a14a0, thd=0x7fff3c010320, fk_list=std::deque with 0 elements) at storage/innobase/dict/dict0dd.cc:4313
#4  0x0000000004e003e7 in dd_open_table<dd::Partition> (client=0x7fff3c013b10, table=0x7fff3c0af2f0, norm_name=0x7fff3c0232a8 "partitions/t1#p#p0", dd_table=0x7fff3c0a14a0, thd=0x7fff3c010320) at storage/innobase/dict/dict0dd.cc:4530
#5  0x0000000004990cd8 in Ha_innopart_share::open_one_table_part (client=0x7fff3c013b10, thd=0x7fff3c010320, table=0x7fff3c0af2f0, dd_part=0x7fff3c0a14a0, part_name=0x7fff3c0232a8 "partitions/t1#p#p0", part_dict_table=0x7fff3c0a30f0) at storage/innobase/handler/ha_innopart.cc:165
#6  0x00000000049913b1 in Ha_innopart_share::open_table_parts (thd=0x7fff3c010320, table=0x7fff3c0af2f0, dd_table=0x7fff3c091dd0, part_info=0x7fff3c0b2568, table_name=0x7fffa834c370 "partitions/t1") at storage/innobase/handler/ha_innopart.cc:296
#7  0x00000000049922c2 in ha_innopart::open (this=0x7fff3c0b03c8, name=0x7fff3c00d6c0 "./partitions/t1", table_def=0x7fff3c091dd0) at storage/innobase/handler/ha_innopart.cc:848
#8  0x0000000003610a64 in handler::ha_open (this=0x7fff3c0b03c8, table_arg=0x7fff3c0af2f0, name=0x7fff3c00d6c0 "./partitions/t1", mode=2, test_if_locked=2, table_def=0x7fff3c091dd0) at sql/handler.cc:2812
#9  0x0000000003401bd0 in open_table_from_share (thd=0x7fff3c010320, share=0x7fff3c00d318, alias=0x7fff3c00c260 "t1", db_stat=39, prgflag=8, ha_open_flags=0, outparam=0x7fff3c0af2f0, is_create_table=false, table_def_param=0x7fff3c091dd0) at sql/table.cc:3186
#10 0x0000000003187012 in open_table (thd=0x7fff3c010320, table_list=(TABLE_LIST *) 0x7fff3c00c268 table_name = t1, ot_ctx=0x7fffa834d1b0) at sql/sql_base.cc:3367
#11 0x000000000318a99b in open_and_process_table (thd=0x7fff3c010320, lex=0x7fff3c013260, tables=(TABLE_LIST * const) 0x7fff3c00c268 table_name = t1, counter=0x7fff3c0132b8, prelocking_strategy=0x7fffa834d2d8, has_prelocking_list=false, ot_ctx=0x7fffa834d1b0) at sql/sql_base.cc:5034
#12 0x000000000318c336 in open_tables (thd=0x7fff3c010320, start=(TABLE_LIST **) 0x7fffa834d280 table_name = t1, counter=0x7fff3c0132b8, flags=0, prelocking_strategy=0x7fffa834d2d8) at sql/sql_base.cc:5842
#13 0x000000000318dc59 in open_tables_for_query (thd=0x7fff3c010320, tables=(TABLE_LIST *) 0x7fff3c00c268 table_name = t1, flags=0) at sql/sql_base.cc:6722
#14 0x0000000003306d22 in Sql_cmd_dml::prepare (this=0x7fff3c01e6a8, thd=0x7fff3c010320) at sql/sql_select.cc:366
#15 0x000000000330771a in Sql_cmd_dml::execute (this=0x7fff3c01e6a8, thd=0x7fff3c010320) at sql/sql_select.cc:526
#16 0x00000000032895f9 in mysql_execute_command (thd=0x7fff3c010320, first_level=true) at sql/sql_parse.cc:4505

Suggested fix:
This is because the bugfix commit #2ceb9022337168 doesn't consider the data dictionary in some old version like 8.0.13 using 'discard=1;' in table `mysql.tablespaces` column `se_private_data` to indicate that the tablespace is discarded instead of 'state=discarded;' in newer versions like 8.0.20.

We should deal with that scenario in the upgrade process function update_meta_data().
[19 Feb 2022 7:22] Hope Lee
[PATCH] Bugfix Upgrade old version data directory with discarded partitions asserts

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: 0001-Bugfix-Upgrade-old-version-data-directory-with-disca.patch (application/octet-stream, text), 1.00 KiB.

[19 Feb 2022 9:41] MySQL Verification Team
Hello Lee,

Thank you for the report and contribution.
Observed with 8.0.13->8.0.28 in-place upgrade but with debug builds only.

regards,
Umesh
[21 Feb 2022 3:38] Hope Lee
Not only debug build is affected, but also DISCARD/IMPORT/REBUILD/DROP functions for partitioned table in test case `innodb.discarded_partition.test` should be influenced in release build.