Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-28351

Assertion `this->file->children_attached' failed in ha_myisammrg::info

Details

    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
      

      Attachments

        Issue Links

          Activity

            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)) 
            

            anel Anel Husakovic added a comment - 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))
            anel Anel Husakovic added a comment - - edited
            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

            anel Anel Husakovic added a comment - - edited 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. 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

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

            monty Michael Widenius added a comment - I have provided a patch that solves this edge case. It will be in the major branch when the preview is pushed.
            anel Anel Husakovic added a comment - - edited

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

            anel Anel Husakovic added a comment - - edited monty or cvicentiu can you please check comment from Marko regarding the Merge table?

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

            anel Anel Husakovic added a comment - I fixed MSAN failure and pushed with PR 2685 to preview branch ( fix ).

            People

              anel Anel Husakovic
              elenst Elena Stepanova
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.