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

Assertion `global_status_var.global_memory_used == 0 ' failed upon server restart with partitioned RocksDB table

Details

    Description

      --source include/have_partition.inc
       
      INSTALL SONAME 'ha_rocksdb';
      CREATE TABLE t1 (a INT) ENGINE=RocksDB PARTITION BY HASH(a) PARTITIONS 2;
      INSERT INTO t1 (a) VALUES (1),(2);
      ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
      --source include/restart_mysqld.inc
      SELECT 1;
      

      10.2 0992be927e1c686c39c39fe53fc2a7869d55143d

      mysqld: /data/src/10.2/sql/mysqld.cc:2160: void mysqld_exit(int): Assertion `global_status_var.global_memory_used == 0' failed.
      170622 19:22:06 [ERROR] mysqld got signal 6 ;
       
      #3  <signal handler called>
      #4  0x00007fca74f0ffcf in raise () from /lib/x86_64-linux-gnu/libc.so.6
      #5  0x00007fca74f113fa in abort () from /lib/x86_64-linux-gnu/libc.so.6
      #6  0x00007fca74f08e37 in __assert_fail_base () from /lib/x86_64-linux-gnu/libc.so.6
      #7  0x00007fca74f08ee2 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
      #8  0x000055fa47a9713c in mysqld_exit (exit_code=0) at /data/src/10.2/sql/mysqld.cc:2160
      #9  0x000055fa47a9efa5 in mysqld_main (argc=129, argv=0x55fa49ea9f50) at /data/src/10.2/sql/mysqld.cc:6079
      #10 0x000055fa47a937b0 in main (argc=7, argv=0x7fff875cab38) at /data/src/10.2/sql/main.cc:25
      

      Attachments

        Activity

          If I use BIGINT in table definition

          CREATE TABLE t1 (a BIGINT) ENGINE=RocksDB PARTITION BY HASH(a) PARTITIONS 2;
          

          I get a bigger leak.

          psergei Sergei Petrunia added a comment - If I use BIGINT in table definition CREATE TABLE t1 (a BIGINT ) ENGINE=RocksDB PARTITION BY HASH(a) PARTITIONS 2; I get a bigger leak.

          Analysis:

          Ok ,the cause seems to be in ha_partition::change_partitions().
          It calls get_new_handler to create ha_rocksdb objects for the new partitions but then these objects are never deleted properly.
          The objects are put into a MEM_ROOT, so the memory where ha_rocksdb objects themselves are stored are not leaked.
          However, members like String ha_rocksdb::m_storage_record are not de-initialized properly, and if they had kept any pointers, we're out of luck.

          psergei Sergei Petrunia added a comment - Analysis: Ok ,the cause seems to be in ha_partition::change_partitions() . It calls get_new_handler to create ha_rocksdb objects for the new partitions but then these objects are never deleted properly. The objects are put into a MEM_ROOT, so the memory where ha_rocksdb objects themselves are stored are not leaked. However, members like String ha_rocksdb::m_storage_record are not de-initialized properly, and if they had kept any pointers, we're out of luck.

          There are two possible solutions:
          1. Make ha_rocksdb::close() clean up all String objects (This is a hack)
          2. Make ha_partition code properly delete all the objects it has allocated

          The first one is easier to do but looks like a hack.

          psergei Sergei Petrunia added a comment - There are two possible solutions: 1. Make ha_rocksdb::close() clean up all String objects (This is a hack) 2. Make ha_partition code properly delete all the objects it has allocated The first one is easier to do but looks like a hack.
          psergei Sergei Petrunia added a comment - - edited

          Investigating how to do the second one ...

          fast_alter_partition_table() does partitioning DDL operation in several steps. Listing them in the order they are done:

          mysql_change_partitions/ ha_partition::change_partitions
          > here new partitions are created and saved in ha_partition::m_new_file, ha_partition::m_added_file

          alter_close_table()
          > here it calls ha_partition->external_lock() to remove the lock
          > and also calls ha_partition->close()
          > // Looks like a good place to cleanup ha_partition::m_new_file except that it's not.

          mysql_rename_partitions() / ha_partition::rename_partitions()
          > here it calls file->ha_delete_table() and file->ha_rename_table() for the children tables
          > // This is why we could not remove them on the previous step.

          psergei Sergei Petrunia added a comment - - edited Investigating how to do the second one ... fast_alter_partition_table() does partitioning DDL operation in several steps. Listing them in the order they are done: mysql_change_partitions/ ha_partition::change_partitions > here new partitions are created and saved in ha_partition::m_new_file, ha_partition::m_added_file alter_close_table() > here it calls ha_partition->external_lock() to remove the lock > and also calls ha_partition->close() > // Looks like a good place to cleanup ha_partition::m_new_file except that it's not. mysql_rename_partitions() / ha_partition::rename_partitions() > here it calls file->ha_delete_table() and file->ha_rename_table() for the children tables > // This is why we could not remove them on the previous step.

          Looking at the above, I dont see where exactly ha_partition should delete its newly-created child partitions. The workflow is apparently tightly coupled with the SQL layer.
          Should we add handler::partitioning_ddl_done() call and have SQL layer call it, and ha_partition use this method?

          (serg Any thoughts?)

          psergei Sergei Petrunia added a comment - Looking at the above, I dont see where exactly ha_partition should delete its newly-created child partitions. The workflow is apparently tightly coupled with the SQL layer. Should we add handler::partitioning_ddl_done() call and have SQL layer call it, and ha_partition use this method? ( serg Any thoughts?)

          Could you do it from ha_partition::close() or from ha_partition::~ha_partition()? Both are called (in that order) after mysql_rename_partitions() at the end of fast_alter_partition_table().

          serg Sergei Golubchik added a comment - Could you do it from ha_partition::close() or from ha_partition::~ha_partition() ? Both are called (in that order) after mysql_rename_partitions() at the end of fast_alter_partition_table() .

          serg, thanks for the reply!

          > Could you do it from ha_partition::close()

          Cannot do that from there, as I wrote above, alter_close_table() calls ha_partition->close(), and then ha_partition::rename_partitions() requires that newly created ha_xxx ojbects are still present.

          > or from ha_partition::~ha_partition()?

          This one seems to work, created a patch with this, now testing in buildbot.

          > Both are called (in that order) after mysql_rename_partitions() at the end of fast_alter_partition_table().

          psergei Sergei Petrunia added a comment - serg , thanks for the reply! > Could you do it from ha_partition::close() Cannot do that from there, as I wrote above, alter_close_table() calls ha_partition->close(), and then ha_partition::rename_partitions() requires that newly created ha_xxx ojbects are still present. > or from ha_partition::~ha_partition()? This one seems to work, created a patch with this, now testing in buildbot. > Both are called (in that order) after mysql_rename_partitions() at the end of fast_alter_partition_table().
          psergei Sergei Petrunia added a comment - http://buildbot.askmonty.org/buildbot/grid?category=main&branch=bb-10.2-mdev13153

          upstream MyRocks is not affected by this issue for some reason.

          psergei Sergei Petrunia added a comment - upstream MyRocks is not affected by this issue for some reason.

          People

            psergei Sergei Petrunia
            elenst Elena Stepanova
            Votes:
            0 Vote for this issue
            Watchers:
            3 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.