[MDEV-28351] Assertion `this->file->children_attached' failed in ha_myisammrg::info Created: 2022-04-19  Updated: 2023-08-12  Resolved: 2023-08-12

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Temporary, Information Schema
Affects Version/s: 11.2.0
Fix Version/s: 11.2.1

Type: Bug Priority: Critical
Reporter: Elena Stepanova Assignee: Anel Husakovic
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Problem/Incident
is caused by MDEV-12459 The information_schema tables for get... Closed

 Description   

CREATE TABLE t (a INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tmp (a INT) ENGINE=MERGE UNION=(t);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test';
 
# Cleanup
DROP TABLE t;

preview-10.9-MDEV-20119-misc e62a2a0615

mariadbd: /data/src/preview-10.9-misc-ubsan/storage/myisammrg/ha_myisammrg.cc:1249: virtual int ha_myisammrg::info(uint): Assertion `this->file->children_attached' failed.
220419 22:32:10 [ERROR] mysqld got signal 6 ;
 
#7  0x00007f1c14a66662 in __GI___assert_fail (assertion=assertion@entry=0x5632fc7f744f "this->file->children_attached", file=file@entry=0x5632fc7f76a8 "/data/src/preview-10.9-misc-ubsan/storage/myisammrg/ha_myisammrg.cc", line=line@entry=1249, function=function@entry=0x5632fc7f7d78 "virtual int ha_myisammrg::info(uint)") at assert.c:101
#8  0x00005632fc06157f in ha_myisammrg::info (this=0x7f1bf403e4a0, flag=212) at /data/src/preview-10.9-misc-ubsan/storage/myisammrg/ha_myisammrg.cc:1249
#9  0x00005632f9498541 in get_schema_tables_record (thd=thd@entry=0x7f1bf4000d48, tables=tables@entry=0x7f1c10259530, table=table@entry=0x7f1bf41e8d60, res=res@entry=false, db_name=db_name@entry=0x7f1bf421e340, table_name=table_name@entry=0x7f1bf421e350) at /data/src/preview-10.9-misc-ubsan/sql/sql_show.cc:5681
#10 0x00005632f94be504 in process_i_s_table_temporary_tables (thd=thd@entry=0x7f1bf4000d48, table=table@entry=0x7f1bf41e8d60, tmp_tbl=tmp_tbl@entry=0x7f1bf41ec208) at /data/src/preview-10.9-misc-ubsan/sql/sql_show.cc:5819
#11 0x00005632f94ca7c9 in get_all_tables (thd=0x7f1bf4000d48, tables=0x7f1bf4014c48, cond=<optimized out>) at /data/src/preview-10.9-misc-ubsan/sql/sql_show.cc:5249
#12 0x00005632f94d0c42 in get_schema_tables_result (join=join@entry=0x7f1bf4016b60, executed_place=executed_place@entry=PROCESSED_BY_JOIN_EXEC) at /data/src/preview-10.9-misc-ubsan/sql/sql_show.cc:8880
#13 0x00005632f93f6558 in JOIN::exec_inner (this=this@entry=0x7f1bf4016b60) at /data/src/preview-10.9-misc-ubsan/sql/sql_select.cc:4706
#14 0x00005632f93f78b6 in JOIN::exec (this=this@entry=0x7f1bf4016b60) at /data/src/preview-10.9-misc-ubsan/sql/sql_select.cc:4527
#15 0x00005632f93ee85a in mysql_select (thd=thd@entry=0x7f1bf4000d48, tables=<optimized out>, fields=..., conds=conds@entry=0x7f1bf40154e8, og_num=og_num@entry=0, order=order@entry=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x7f1bf4016b38, unit=0x7f1bf4005158, select_lex=0x7f1bf4014658) at /data/src/preview-10.9-misc-ubsan/sql/sql_select.cc:5007
#16 0x00005632f93ef904 in handle_select (thd=thd@entry=0x7f1bf4000d48, lex=lex@entry=0x7f1bf4005080, result=result@entry=0x7f1bf4016b38, setup_tables_done_option=setup_tables_done_option@entry=0) at /data/src/preview-10.9-misc-ubsan/sql/sql_select.cc:543
#17 0x00005632f90de877 in execute_sqlcom_select (thd=thd@entry=0x7f1bf4000d48, all_tables=0x7f1bf4014c48) at /data/src/preview-10.9-misc-ubsan/sql/sql_parse.cc:6252
#18 0x00005632f9126b0b in mysql_execute_command (thd=thd@entry=0x7f1bf4000d48, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /data/src/preview-10.9-misc-ubsan/sql/sql_parse.cc:3943
#19 0x00005632f9146d55 in mysql_parse (thd=thd@entry=0x7f1bf4000d48, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x7f1c1025b5e0) at /data/src/preview-10.9-misc-ubsan/sql/sql_parse.cc:8027
#20 0x00005632f91520f7 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x7f1bf4000d48, packet=packet@entry=0x7f1bf410de99 "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'", packet_length=packet_length@entry=67, blocking=blocking@entry=true) at /data/src/preview-10.9-misc-ubsan/sql/sql_parse.cc:1894
#21 0x00005632f915ea76 in do_command (thd=0x7f1bf4000d48, blocking=blocking@entry=true) at /data/src/preview-10.9-misc-ubsan/sql/sql_parse.cc:1402
#22 0x00005632f97d506b in do_handle_one_connection (connect=<optimized out>, connect@entry=0x5633010ea638, put_in_cache=put_in_cache@entry=true) at /data/src/preview-10.9-misc-ubsan/sql/sql_connect.cc:1418
#23 0x00005632f97d62f2 in handle_one_connection (arg=0x5633010ea638) at /data/src/preview-10.9-misc-ubsan/sql/sql_connect.cc:1312
#24 0x00005632fb1e60bb in pfs_spawn_thread (arg=0x56330104a398) at /data/src/preview-10.9-misc-ubsan/storage/perfschema/pfs.cc:2201
#25 0x00007f1c1589cea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
#26 0x00007f1c14b2fdef in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95



 Comments   
Comment by Anel Husakovic [ 2022-04-20 ]

This is where it fails (file->info)

 5680              /* If info() fails, then there's nothing else to do */                                                                                                                                                            │
│   5681              if (unlikely((info_error= file->info(HA_STATUS_VARIABLE |                                                                                                                                                         │
│   5682                                                   HA_STATUS_TIME |                                                                                                                                                             │
│   5683                                                   HA_STATUS_VARIABLE_EXTRA |                                                                                                                                                   │
│   5684                                                   HA_STATUS_AUTO)) != 0)) 

Comment by Anel Husakovic [ 2022-04-20 ]
  1. Culprit TL;DR
    Information_schema get_all_tables() is filling the data on the runtime, from frm files and data sent from storage engines.
    Handlerton file of the MERGE SE is obtained from MERGE but in order to read it we must open tables with open_tables() function that will call handler->file->extra(HA_EXTRA_CHILDREN_CHECK and fill handlerton file.
  2. More about:
    Looking into the code of MERGE engine, merge table or parent table is tmerge while child table is t whose path is in the .MRG file of parent table, relative to datadir.
  • Let's analyse this query with non-MyISAM tables

    # Default InnoDB SE
    MariaDB [test]> create table tmerge(t int) engine=merge union=(t); 
    Query OK, 0 rows affected (0.002 sec)
    

    There will be frm file and MRG files

    root@2d5a561d9015:/var/lib/mysql/test# ls | grep tmerge
    tmerge.MRG
    tmerge.frm
    

  • When creating the temporary MERGE table there is no FRM for temporary (it is in table cache in memory), but exists MRG files (in /tmp/
    Since it is used InnoDB type, create statement will succeed, but nothing else and this is covered in MERGE documentation, however documentation is missing part about usage of TEMPORARY tables.
    We can also check the table

    MariaDB [test]> check table t_temp_merge;
    +-------------------+-------+----------+-----------------------------------------------------------------------------------------------------+
    | Table             | Op    | Msg_type | Msg_text                                                                                            |
    +-------------------+-------+----------+-----------------------------------------------------------------------------------------------------+
    | test.t_temp_merge | check | Error    | Table 'test.t' is differently defined or of non-MyISAM type or doesn't exist                        |
    | test.t_temp_merge | check | Error    | Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist |
    | test.t_temp_merge | check | error    | Corrupt                                                                                             |
    +-------------------+-------+----------+-----------------------------------------------------------------------------------------------------+
    3 rows in set (0.000 sec)
    

    The same error code we get even for tmerge (base table instead of temporary), since the children table t is created with default SE InnoDB.
    Check for MRG file for parent/MERGE temporary table:

    cat /tmp/#sql-temptable-1-3-a.MRG 
    ./test/t
    

  • Use MyISAM SE for the child table

    MariaDB [test]> create table t(t int) engine=MyISAM;
    Query OK, 0 rows affected (0.002 sec)
     
    MariaDB [test]> create table tmerge(t int) engine=merge union=(t);
    Query OK, 0 rows affected (0.001 sec)
     
    MariaDB [test]> show create table tmerge;
    +--------+------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                               |
    +--------+------------------------------------------------------------------------------------------------------------+
    | tmerge | CREATE TABLE `tmerge` (
      `t` int(11) DEFAULT NULL
    ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8mb4 UNION=(`t`) |
    +--------+------------------------------------------------------------------------------------------------------------+
    1 row in set (0.000 sec)
    

    And we get the files

    root@2d5a561d9015:/var/lib/mysql/test# ls
    db.opt  t.MYD  t.MYI  t.frm  tmerge.MRG  tmerge.frm
    root@2d5a561d9015:/var/lib/mysql/test# cat tmerge.MRG 
    t
    

    When trying to use temporary table

    # MRG files exists in /tmp
    MariaDB [test]> create temporary table t_temp_merge(t int) engine=merge union=(t);
    ERROR 1050 (42S01): Table 't_temp_merge' already exists
    MariaDB [test]> drop table t_temp_merge;
    Query OK, 0 rows affected (0.000 sec)
     
    MariaDB [test]> create temporary table t_temp_merge(t int) engine=merge union=(t);
    Query OK, 0 rows affected (0.000 sec)
     
    MariaDB [test]> show create table t_temp_merge;
    +--------------+----------------------------------------------------------------------------------------------------------------------------+
    | Table        | Create Table                                                                                                               |
    +--------------+----------------------------------------------------------------------------------------------------------------------------+
    | t_temp_merge | CREATE TEMPORARY TABLE `t_temp_merge` (
      `t` int(11) DEFAULT NULL
    ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8mb4 UNION=(`t`) |
    +--------------+----------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.000 sec)
    MariaDB [test]> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | t              |
    | tmerge         |
    +----------------+
    2 rows in set (0.000 sec)
     
    # Note that temporary table is not visible in show table status
    MariaDB [test]> show table status;
    +--------+------------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+------------------+-----------+
    | 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 | Max_index_length | Temporary |
    +--------+------------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+------------------+-----------+
    | t      | MyISAM     |      10 | Fixed      |    0 |              0 |           0 | 1970324836974591 |         1024 |         0 |           NULL | 2022-04-20 09:06:18 | 2022-04-20 09:06:18 | NULL       | utf8mb4_general_ci |     NULL |                |         |      17179868160 | N         |
    | tmerge | MRG_MyISAM |      10 | Fixed      |    0 |              5 |           0 |                0 |            0 |         0 |           NULL | NULL                | NULL                | NULL       | utf8mb4_general_ci |     NULL |                |         |                0 | N         |
    +--------+------------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+------------------+-----------+
    2 rows in set (0.000 sec)
    

    Note from the code:

    If child is temporary, parent must be temporary as well. Other parent/child combinations are allowed. 
    

  • When debugging the bug in gdb, we may see how child MRG file gets created, but not frm file (exists in memory).
    Parent table is tmp table, that doesn't have any .frm file.

    $ find mysql-test/ |grep MRG
    mysql-test/var/tmp/mysqld.1/#sql-temptable-29e0-3-0.MRG
    $ cat mysql-test/var/tmp/mysqld.1/#sql-temptable-29e0-3-0.MRG
    ./test/t
    

    For the base table, FRM file of child table t exsists- mysql-test/var/mysqld.1/data/test/t.frm

Comment by Michael Widenius [ 2023-06-21 ]

I have provided a patch that solves this edge case.
It will be in the major branch when the preview is pushed.

Comment by Anel Husakovic [ 2023-07-19 ]

monty or cvicentiu can you please check comment from Marko regarding the Merge table?

Comment by Anel Husakovic [ 2023-08-07 ]

I fixed MSAN failure and pushed with PR 2685 to preview branch (fix).

Generated at Thu Feb 08 10:00:03 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.