[MDEV-20610] Assertion failed or btr_validate_index(..) in row_upd_sec_index_entry on a time_zone change Created: 2019-09-17  Updated: 2023-04-27

Status: Confirmed
Project: MariaDB Server
Component/s: Data types
Affects Version/s: 10.2, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-18153 Assertion `0' or Assertion `btr_valid... Closed
relates to MDEV-18156 Assertion `0' failed or `btr_validate... Closed
relates to MDEV-20423 Assertion `0' failed or `btr_validate... Closed
relates to MDEV-20618 Assertion `btr_validate_index(index, ... Closed
relates to MDEV-20661 Virtual fields are not recalculated o... Closed
relates to MDEV-20763 Table corruption or Assertion `btr_va... Closed
relates to MDEV-22061 InnoDB: Assertion of missing row in s... Closed
relates to MDEV-26405 Assertion `0' failed in row_upd_sec_i... Closed

 Description   

This script:

SET time_zone='+00:00';
CREATE OR REPLACE TABLE t1 (
  a DATETIME,
  v TIMESTAMP GENERATED ALWAYS AS (a),
  KEY(v)
);
INSERT INTO t1 (a) VALUES ('2001-01-01 10:20:30');
SET time_zone='+10:00';
UPDATE t1 SET a='2000-01-01 10:20:30';

crashes with the following stack trace:

#3  0x00007ffff76eba26 in __assert_fail () from /lib64/libc.so.6
#4  0x0000000000f9eede in row_upd_sec_index_entry (node=0x7fff68070158, 
    thr=0x7fff68073798)
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/row/row0upd.cc:2425
#5  0x0000000000f9f6c9 in row_upd_sec_step (node=0x7fff68070158, 
    thr=0x7fff68073798)
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/row/row0upd.cc:2539
#6  0x0000000000fa256e in row_upd (node=0x7fff68070158, thr=0x7fff68073798)
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/row/row0upd.cc:3315
#7  0x0000000000fa29d5 in row_upd_step (thr=0x7fff68073798)
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/row/row0upd.cc:3430
#8  0x0000000000f4134b in row_update_for_mysql (prebuilt=0x7fff6806f678)
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/row/row0mysql.cc:1889
#9  0x0000000000da6a72 in ha_innobase::update_row (this=0x7fff6806dd88, 
    old_row=0x7fff680698e0 "\371\231g\202\245\036:O\315N\245\245\245\245\245\245\b\231\006h\377\177", 
    new_row=0x7fff680698d0 "\371\231dB\245\036\070mHN\245\245\245\245\245\245\371\231g\202\245\036:O\315N\245\245\245\245\245\245\b\231\006h\377\177")
    at /home/bar/maria-git/server.10.4.frac2/storage/innobase/handler/ha_innodb.cc:8841
#10 0x0000000000b7195f in handler::ha_update_row (this=0x7fff6806dd88, 
    old_data=0x7fff680698e0 "\371\231g\202\245\036:O\315N\245\245\245\245\245\245\b\231\006h\377\177", 
    new_data=0x7fff680698d0 "\371\231dB\245\036\070mHN\245\245\245\245\245\245\371\231g\202\245\036:O\315N\245\245\245\245\245\245\b\231\006h\377\177")
    at /home/bar/maria-git/server.10.4.frac2/sql/handler.cc:6719
#11 0x00000000009242f6 in mysql_update (thd=0x7fff68000d60, 
    table_list=0x7fff68014250, fields=..., values=..., conds=0x0, order_num=0, 
    order=0x0, limit=18446744073709551615, ignore=false, 
    found_return=0x7ffff41d6218, updated_return=0x7ffff41d6210)
    at /home/bar/maria-git/server.10.4.frac2/sql/sql_update.cc:1047

This happens because DATETIME -> TIMESTAMP conversion depends in the @@time_zone system variable.



 Comments   
Comment by Alexander Barkov [ 2019-09-18 ]

The same problem is repeatable with TIMESTAMP->DATETIME conversion:

SET time_zone='+00:00';
CREATE OR REPLACE TABLE t1 (
  a TIMESTAMP,
  v DATETIME GENERATED ALWAYS AS (a),
  KEY(v)
);
INSERT INTO t1 (a) VALUES ('2001-01-01 10:20:30');
SET time_zone='+10:00';
UPDATE t1 SET a='2000-01-01 10:20:30';

Comment by Alexander Barkov [ 2019-09-18 ]

The same problem is repeatable with TIMESTAMP->DECIMAL conversion, because TIMESTAMP is first converted to DATETIME, then DATETIME is converted to DECIMAL:

SET time_zone='+00:00';
CREATE OR REPLACE TABLE t1 (
  a TIMESTAMP,
  v DECIMAL(32,0) GENERATED ALWAYS AS (a),
  KEY(v)
);
INSERT INTO t1 (a) VALUES ('2001-01-01 10:20:30');
SET time_zone='+10:00';
UPDATE t1 SET a='2000-01-01 10:20:30';

Comment by Alexander Barkov [ 2019-09-18 ]

The same problem is repeatable with DECIMAL->TIMESTAMP conversion:

SET time_zone='+00:00';
CREATE OR REPLACE TABLE t1 (
  a DECIMAL(32,0),
  v TIMESTAMP GENERATED ALWAYS AS (a),
  KEY(v)
);
INSERT INTO t1 (a) VALUES (20010101102030);
SET time_zone='+10:00';
UPDATE t1 SET a='20000101102030';

Comment by Alexander Barkov [ 2019-09-25 ]

A similar problem is repeatable with @@dev_precision_increment with MyISAM

SET @@div_precision_increment=4;
CREATE OR REPLACE TABLE t1 (
  a INT,
  v INT GENERATED ALWAYS AS (LENGTH(a/3)),
  KEY(v)
) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (1);
SELECT * FROM t1;
FLUSH TABLES;
SET @@div_precision_increment=8;
SELECT * FROM t1;
CHECK TABLE t1;

+---------+-------+----------+---------------------------------------------------------+
| Table   | Op    | Msg_type | Msg_text                                                |
+---------+-------+----------+---------------------------------------------------------+
| test.t1 | check | error    | Checksum for key:  1 doesn't match checksum for records |
| test.t1 | check | error    | Corrupt                                                 |
+---------+-------+----------+---------------------------------------------------------+

Also repeatable with these scripts:

SET @@div_precision_increment=4;
CREATE OR REPLACE TABLE t1 (
  a INT,
  v VARCHAR(100) GENERATED ALWAYS AS (a/3.000),
  KEY(v)
) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (1);
SELECT * FROM t1;
FLUSH TABLES;
SET @@div_precision_increment=8;
SELECT * FROM t1;
CHECK TABLE t1;

SET @@div_precision_increment=4;
CREATE OR REPLACE TABLE t1 (
  a INT,
  v DECIMAL(48,30) GENERATED ALWAYS AS (a/3.000),
  KEY(v)
) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (1);
SELECT * FROM t1;
FLUSH TABLES;
SET @@div_precision_increment=8;
SELECT * FROM t1;
CHECK TABLE t1;

Comment by Alexander Barkov [ 2019-09-25 ]

The problem is also repeatable with the @@max_allowed_packet variable with MyISAM:

SET GLOBAL max_allowed_packet=16777216*2;
KILL CONNECTION_ID();
 
CREATE OR REPLACE TABLE t1 (
  a VARCHAR(64),
  v INT GENERATED ALWAYS AS (LENGTH(REPEAT(a,16777216*2))),
  KEY(v)
) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES ('a');
SELECT * FROM t1;
KILL CONNECTION_ID();
 
SET GLOBAL max_allowed_packet=16777216;
KILL CONNECTION_ID();
 
CHECK TABLE t1;

+---------+-------+----------+------------------------------------------------------------------------------+
| Table   | Op    | Msg_type | Msg_text                                                                     |
+---------+-------+----------+------------------------------------------------------------------------------+
| test.t1 | check | error    | Checksum for key:  1 doesn't match checksum for records                      |
| test.t1 | check | Warning  | Result of repeat() was larger than max_allowed_packet (16777216) - truncated |
| test.t1 | check | error    | Corrupt                                                                      |
+---------+-------+----------+------------------------------------------------------------------------------+

Comment by Alice Sherepa [ 2021-08-26 ]

also on 10.6:

2021-08-26 12:54:22 4 [ERROR] InnoDB: Record in index `v` of table `test`.`t1` was not found on update: TUPLE (info_bits=0, 2 fields): {[4]:O N(0x3A4FCD4E),[6]      (0x000000000200)} at: COMPACT RECORD(info_bits=0, 1 fields): {[8]infimum (0x696E66696D756D00)}
mariadbd: /10.6/src/storage/innobase/row/row0upd.cc:2051: dberr_t row_upd_sec_index_entry(upd_node_t*, que_thr_t*): Assertion `0' failed.
210826 12:54:22 [ERROR] mysqld got signal 6 ;
 
 
Server version: 10.6.5-MariaDB-debug-log
 
linux/raise.c:51(__GI_raise)[0x7f7c31eb218b]
stdlib/abort.c:81(__GI_abort)[0x7f7c31e91859]
intl/loadmsgcat.c:509(get_sysdep_segment_value)[0x7f7c31e91729]
:0(__GI___assert_fail)[0x7f7c31ea2f36]
row/row0upd.cc:2055(row_upd_sec_index_entry(upd_node_t*, que_thr_t*))[0x55fc88ed6a25]
row/row0upd.cc:2200(row_upd_sec_step(upd_node_t*, que_thr_t*))[0x55fc88ed7a30]
row/row0upd.cc:2936(row_upd(upd_node_t*, que_thr_t*))[0x55fc88edccbc]
row/row0upd.cc:3051(row_upd_step(que_thr_t*))[0x55fc88edd7c1]
row/row0mysql.cc:1723(row_update_for_mysql(row_prebuilt_t*))[0x55fc88e329f1]
handler/ha_innodb.cc:8554(ha_innobase::update_row(unsigned char const*, unsigned char const*))[0x55fc88a8b2a0]
sql/handler.cc:7567(handler::ha_update_row(unsigned char const*, unsigned char const*))[0x55fc87fa981f]
sql/sql_update.cc:1081(mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, bool, unsigned long long*, unsigned long long*))[0x55fc87a32dcd]
sql/sql_parse.cc:4408(mysql_execute_command(THD*, bool))[0x55fc8770ea4a]
sql/sql_parse.cc:8030(mysql_parse(THD*, char*, unsigned int, Parser_state*))[0x55fc8772841a]
sql/sql_parse.cc:1898(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool))[0x55fc876fe4c8]
sql/sql_parse.cc:1404(do_command(THD*, bool))[0x55fc876fb1ec]
sql/sql_connect.cc:1418(do_handle_one_connection(CONNECT*, bool))[0x55fc87b611fb]
sql/sql_connect.cc:1314(handle_one_connection)[0x55fc87b60a87]
perfschema/pfs.cc:2203(pfs_spawn_thread)[0x55fc8887f697]
nptl/pthread_create.c:478(start_thread)[0x7f7c323b9609]
x86_64/clone.S:97(__GI___clone)[0x7f7c31f8e293]
 
Query (0x62b0000a82a8): UPDATE t1 SET a='2000-01-01 10:20:30'

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