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

ALTER leaves rows in a wrong partition, Assertion `old_part_id == m_last_part' fails instead of ER_ROW_IN_WRONG_PARTITION

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 10.2, 10.3, 10.4, 10.5, 10.6
    • Fix Version/s: 10.3, 10.4, 10.5
    • Component/s: Partitioning
    • Labels:
      None

      Description

      --source include/have_partition.inc
       
      CREATE TABLE t1 (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p VALUES LESS THAN (1), PARTITION pmax VALUES LESS THAN (MAXVALUE));
      INSERT INTO t1 VALUES (2,0),(3,0);
      ALTER TABLE t1 CHANGE a c INT, CHANGE b a INT;
       
      UPDATE t1 SET c = 10 WHERE c = 2;
       
      # Cleanup
      DROP TABLE t1;
      

      On 10.2 the scenario above fails on UPDATE with ER_ROW_IN_WRONG_PARTITION

      mysqltest: At line 7: query 'UPDATE t1 SET c = 10 WHERE c = 2' failed: 1863: Found a row in wrong partition (1 != 0) a:0
      

      which is true:

      ALTER TABLE t1 CHANGE a c INT, CHANGE b a INT;
      SELECT * FROM t1 PARTITION (p);
      c	a
      SELECT * FROM t1 PARTITION (pmax);
      c	a
      2	0
      3	0
      

      However, in 10.3, this commit replaced the error with an assertion failure:

      commit 187a163c782fc54225f6a096d4ec2240bde0f145 221d010f3e5429e667725e57c9f025939eef8ed1
      Author:     Sergei Golubchik
      AuthorDate: Thu Feb 15 16:26:31 2018 +0100
      Commit:     Sergei Golubchik <serg@mariadb.org>
      CommitDate: Fri Feb 23 15:33:21 2018 +0100
       
          cleanup: ha_partition::update_row/delete_row
          
          implement log-term TODO item, convert redundant if()-s into asserts.
      

      So, on 10.3+, the non-debug version runs UPDATE without complaints. The updated row gets moved to the right partition, but the remaining row doesn't, it stays in a wrong one:

      ALTER TABLE t1 CHANGE a c INT, CHANGE b a INT;
      SELECT * FROM t1 PARTITION (p);
      c	a
      SELECT * FROM t1 PARTITION (pmax);
      c	a
      2	0
      3	0
      UPDATE t1 SET c = 10 WHERE c = 2;
      SELECT * FROM t1 PARTITION (p);
      c	a
      10	0
      SELECT * FROM t1 PARTITION (pmax);
      c	a
      3	0
      

      And the debug build fails on the added assertion:

      10.3 4c80dcda

      mysqld: /data/src/10.3/sql/ha_partition.cc:4410: virtual int ha_partition::update_row(const uchar*, const uchar*): Assertion `old_part_id == m_last_part' failed.
      210407 22:00:19 [ERROR] mysqld got signal 6 ;
       
      #7  0x00007f90c5bc7f36 in __GI___assert_fail (assertion=0x563496a178b8 "old_part_id == m_last_part", file=0x563496a16240 "/data/src/10.3/sql/ha_partition.cc", line=4410, function=0x563496a17870 "virtual int ha_partition::update_row(const uchar*, const uchar*)") at assert.c:101
      #8  0x00005634965c90c6 in ha_partition::update_row (this=0x7f90a40ae3c8, old_data=0x7f90a40adf98 "\371\002", new_data=0x7f90a40adf88 "\371\n") at /data/src/10.3/sql/ha_partition.cc:4410
      #9  0x0000563495d94e8c in handler::ha_update_row (this=0x7f90a40ae3c8, old_data=0x7f90a40adf98 "\371\002", new_data=0x7f90a40adf88 "\371\n") at /data/src/10.3/sql/handler.cc:6510
      #10 0x0000563495b64efe in mysql_update (thd=0x7f90a4000d90, table_list=0x7f90a4012bc0, fields=..., values=..., conds=0x7f90a40135b0, order_num=0, order=0x0, limit=18446744073709551615, ignore=false, found_return=0x7f90c03edf00, updated_return=0x7f90c03edfc0) at /data/src/10.3/sql/sql_update.cc:955
      #11 0x0000563495a5be40 in mysql_execute_command (thd=0x7f90a4000d90) at /data/src/10.3/sql/sql_parse.cc:4346
      #12 0x0000563495a67f42 in mysql_parse (thd=0x7f90a4000d90, rawbuf=0x7f90a4012ad8 "UPDATE t1 SET c = 10 WHERE c = 2", length=32, parser_state=0x7f90c03ee5c0, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:7871
      #13 0x0000563495a545d6 in dispatch_command (command=COM_QUERY, thd=0x7f90a4000d90, packet=0x7f90a4008f31 "UPDATE t1 SET c = 10 WHERE c = 2", packet_length=32, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:1852
      #14 0x0000563495a52f76 in do_command (thd=0x7f90a4000d90) at /data/src/10.3/sql/sql_parse.cc:1398
      #15 0x0000563495bd20bd in do_handle_one_connection (connect=0x5634995ca610) at /data/src/10.3/sql/sql_connect.cc:1403
      #16 0x0000563495bd1e19 in handle_one_connection (arg=0x5634995ca610) at /data/src/10.3/sql/sql_connect.cc:1308
      #17 0x00005634965a3e17 in pfs_spawn_thread (arg=0x5634995ad640) at /data/src/10.3/storage/perfschema/pfs.cc:1869
      #18 0x00007f90c60d9609 in start_thread (arg=<optimized out>) at pthread_create.c:477
      #19 0x00007f90c5cb3293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      

      So, the problem starts already upon ALTER and it existed pre-10.3. I'm not sure whether it is supposed to behave this way or not (leave rows in a wrong partition). But if it is, then something went wrong with the error=>assertion replacement.

      Reproducible on 10.3-10.6 with at least MyISAM and InnoDB.

      MySQL 5.7 behaves the same way as 10.2 (error on UPDATE).
      MySQL 8.0 refuses to run the ALTER with "ERROR 3855: Column 'a' has a partitioning function dependency and cannot be dropped or renamed".

        Attachments

          Activity

            People

            Assignee:
            serg Sergei Golubchik
            Reporter:
            elenst Elena Stepanova
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated: