pingcap / pingcap/tidb

When executing a complex update operation, the database crashes.

Open
#57,643 9 comments 0 reactions 0 assignees View on GitHub
affects-8.1 sig/execution type/enhancement
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

create two tables and load some data, then execute an update operation.

1. schema.

```sql
-- create table t1 and load some data.
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1`
(
`wkey` int(11) DEFAULT NULL,
`pkey` int(11) NOT NULL,
`c_byoxac` text DEFAULT NULL,
`c_ds_lpd` int(11) DEFAULT NULL,
`c_gatljc` text DEFAULT NULL,
`c_powabc` double DEFAULT NULL,
`c_qmta2c` int(11) DEFAULT NULL,
PRIMARY KEY (`pkey`),
KEY `t_xbsreb` (`wkey`, `pkey`, `c_ds_lpd`, `c_powabc`, `c_qmta2c`),
UNIQUE KEY `t_lxsfwb` (`wkey`, `pkey`, `c_ds_lpd`, `c_qmta2c`)
) ENGINE = InnoDB
DEFAULT CHARSET = `utf8mb4`
COLLATE = `utf8mb4_bin`;

LOCK TABLES `t1` WRITE;
ALTER TABLE `t1`
DISABLE KEYS;
INSERT INTO `t1`
VALUES (928, 5094000, 'tuotuc', NULL, '26f0vb', 71.51, NULL),
(928, 5095000, 'sz1c9d', NULL, 'lqiwic', 100.1, NULL),
(928, 5096000, 'lzdq8b', NULL, 'uza_9c', 53.24, NULL);
ALTER TABLE `t1`
ENABLE KEYS;
UNLOCK TABLES;

-- create table t2 and load some data.
DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2`
(
`wkey` int(11) DEFAULT NULL,
`pkey` int(11) NOT NULL,
`c__6jbk` int(11) DEFAULT NULL,
`c_fgc0z` double DEFAULT NULL,
`c_dkljq` int(11) DEFAULT NULL,
`c_g3ro5c` int(11) DEFAULT NULL,
`c_wit_nb` text DEFAULT NULL,
`c_x_iod` int(11) DEFAULT NULL,
`c_izqedc` double DEFAULT NULL,
`c_wbmsgd` int(11) DEFAULT NULL,
`c_nq_sqb` int(11) DEFAULT NULL,
PRIMARY KEY (`pkey`),
KEY `t_0_u2wb` (`wkey`, `pkey`, `c__6jbk`, `c_fgc0z`, `c_dkljq`, `c_g3ro5c`, `c_x_iod`, `c_izqedc`, `c_wbmsgd`,
`c_nq_sqb`)
) ENGINE = InnoDB
DEFAULT CHARSET = `utf8mb4`
COLLATE = `utf8mb4_bin`;

LOCK TABLES `t2` WRITE;
ALTER TABLE `t2`
DISABLE KEYS;
INSERT INTO `t2`
VALUES (926, 5082000, NULL, NULL, NULL, NULL, '4yjf1', NULL, 2.93, NULL, NULL),
(926, 5083000, NULL, 10.22, NULL, NULL, 'xr2heb', NULL, 95.46, NULL, NULL),
(926, 5084000, NULL, 10.1, NULL, NULL, 'zfnd0d', NULL, NULL, NULL, NULL),
(926, 5085000, NULL, NULL, NULL, NULL, 'esxbpd', NULL, 5.63, NULL, NULL),
(926, 5086000, NULL, 52.61, NULL, NULL, '0aomw', NULL, 25.9, NULL, NULL),
(927, 5087000, NULL, 56.71, NULL, NULL, 'xjm3w', NULL, 67.17, NULL, NULL),
(927, 5088000, NULL, 68.7, NULL, NULL, 'kwavbd', NULL, 54.66, NULL, NULL),
(927, 5089000, NULL, 72.82, NULL, NULL, 'wckvhb', NULL, 10.42, NULL, NULL),
(927, 5090000, NULL, 95.2, NULL, NULL, 'gtqro', NULL, 44.86, NULL, NULL),
(927, 5091000, NULL, 78.45, NULL, NULL, '7oork', NULL, 37.71, NULL, NULL),
(927, 5092000, NULL, 16.25, NULL, NULL, 'atku0d', NULL, 27.86, NULL, NULL),
(927, 5093000, NULL, 25.82, NULL, NULL, 'l0be1c', NULL, NULL, NULL, NULL),
(929, 5100000, NULL, 24.81, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(929, 5101000, NULL, 53.84, NULL, NULL, 'mmsopc', NULL, NULL, NULL, NULL),
(929, 5102000, NULL, NULL, NULL, NULL, 'e6pklc', NULL, NULL, NULL, NULL),
(929, 5103000, NULL, 24.9, NULL, NULL, 'kra4qc', NULL, NULL, NULL, NULL),
(930, 5104000, NULL, 9.81, NULL, NULL, '6pu3jd', NULL, 38.48, NULL, NULL),
(930, 5105000, NULL, 69.35, NULL, NULL, 'kbczh', NULL, 1.93, NULL, NULL),
(930, 5106000, NULL, 83.61, NULL, NULL, '8umbu', NULL, 37.23, NULL, NULL),
(930, 5107000, NULL, 93.48, NULL, NULL, 'cvo9kc', NULL, 82.3, NULL, NULL),
(930, 5108000, NULL, 100.24, NULL, NULL, 'shz4hb', NULL, 97.71, NULL, NULL),
(930, 5109000, NULL, 6.32, NULL, NULL, 'hrfhk', NULL, 20.87, NULL, NULL),
(930, 5110000, NULL, 28.28, NULL, NULL, 'zx5hoc', NULL, 50.3, NULL, NULL),
(930, 5111000, NULL, 5.88, NULL, NULL, 'qgawnc', NULL, 49.7, NULL, NULL),
(931, 5112000, NULL, 74.4, NULL, NULL, 'wkw6a', NULL, 54.89, NULL, NULL),
(931, 5113000, NULL, 19.48, NULL, NULL, 'wkqyb', NULL, 36.18, NULL, NULL),
(931, 5114000, NULL, 81.65, NULL, NULL, 'ejygpb', NULL, 29.42, NULL, NULL),
(931, 5115000, NULL, 33.42, NULL, NULL, 'x6b3pb', NULL, 72.91, NULL, NULL),
(931, 5116000, NULL, 100.72, NULL, NULL, NULL, NULL, 36.17, NULL, NULL);
ALTER TABLE `t2`
ENABLE KEYS;
UNLOCK TABLES;
```

2. sql statement.

```sql
update `t1`
set `wkey` = 939
where 1 in (select `ref_13`.`c_wbmsgd` is not NULL as `c0`
from ((`t2` as `ref_12` cross join `t2` as `ref_13`)
cross join (`t2` as `ref_14`
cross join (`t2` as `ref_15`
cross join `t2` as `ref_16`
)
)
)
where exists (select `ref_14`.`wkey` as `c0`,
43 as `c1`
from `t2` as `ref_17`))
xor exists (select `ref_18`.`c_fgc0z` as `c0`,
`ref_18`.`c_x_iod` as `c1`,
`ref_19`.`pkey` as `c2`,
`ref_18`.`c_izqedc` as `c3`,
`ref_18`.`c_wit_nb` as `c5`,
`ref_18`.`c_izqedc` as `c6`,
`ref_18`.`c_izqedc` as `c7`
from (`t2` as `ref_18`
inner join `t2` as `ref_19`
on (`ref_18`.`c_x_iod` = `ref_19`.`wkey`))
where nullif((select count(`c_wit_nb`) from `t2`),39) >= 18);
```

### 2. What did you expect to see? (Required)

This update operation pattern just like the following:

```sql
update `t1`
set `wkey` = 939 where A xor B;
```

Under normal circumstances, it cannot crash.

And when I execute select A or select B respectively, the result is no problem.

```sql
-- select A
MySQL [test]> select 1 in (select `ref_13`.`c_wbmsgd` is not NULL as `c0`
-> from ((`t2` as `ref_12` cross join `t2` as `ref_13`)
-> cross join (`t2` as `ref_14`
-> cross join (`t2` as `ref_15`
-> cross join `t2` as `ref_16`
-> )
-> )
-> )
-> where exists (select `ref_14`.`wkey` as `c0`,
-> 43 as `c1`
-> from `t2` as `ref_17`)) as result;
+--------+
| result |
+--------+
| 0 |
+--------+
1 row in set (5.95 sec)

-- select B
MySQL [test]> select exists (select `ref_18`.`c_fgc0z` as `c0`,
-> `ref_18`.`c_x_iod` as `c1`,
-> `ref_19`.`pkey` as `c2`,
-> `ref_18`.`c_izqedc` as `c3`,
-> `ref_18`.`c_wit_nb` as `c5`,
-> `ref_18`.`c_izqedc` as `c6`,
-> `ref_18`.`c_izqedc` as `c7`
-> from (`t2` as `ref_18`
-> inner join `t2` as `ref_19`
-> on (`ref_18`.`c_x_iod` = `ref_19`.`wkey`))
-> where nullif(
-> (select count(`c_wit_nb`) from `t2`)
-> ,
-> 39) >= 18) as resultB;
+---------+
| resultB |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
```

And when I want to know whether the bug caused by xor, but the result is also no problem.

```sql
-- update with xor
MySQL [test]> update `t1` set `wkey` = 939 where 0 xor 0;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0

-- select with xor
MySQL [test]> select 0 xor 0;
+---------+
| 0 xor 0 |
+---------+
| 0 |
+---------+
1 row in set (0.01 sec)
```

### 3. What did you see instead (Required)

```sql
MySQL [test]> update `t1`
-> set `wkey` = 939
-> where 1 in (select `ref_13`.`c_wbmsgd` is not NULL as `c0`
-> from ((`t2` as `ref_12` cross join `t2` as `ref_13`)
-> cross join (`t2` as `ref_14`
-> cross join (`t2` as `ref_15`
-> cross join `t2` as `ref_16`
-> )
-> )
-> )
-> where exists (select `ref_14`.`wkey` as `c0`,
-> 43 as `c1`
-> from `t2` as `ref_17`))
xor exists (select `ref_18`.`c_fgc0z` as `c0`,
-> xor exists (select `ref_18`.`c_fgc0z` as `c0`,
-> `ref_18`.`c_x_iod` as `c1`,
-> `ref_19`.`pkey` as `c2`,
-> `ref_18`.`c_izqedc` as `c3`,
-> `ref_18`.`c_wit_nb` as `c5`,
-> `ref_18`.`c_izqedc` as `c6`,
-> `ref_18`.`c_izqedc` as `c7`
-> from (`t2` as `ref_18`
-> inner join `t2` as `ref_19`
-> on (`ref_18`.`c_x_iod` = `ref_19`.`wkey`))
-> where nullif(
-> (select count(`c_wit_nb`) from `t2`)
-> ,
-> 39) >= 18);
ERROR 8175 (HY000): Your query has been cancelled due to exceeding the allowed memory limit for a single SQL query. Please try narrowing your query scope or increase the tidb_mem_quota_query limit and try again.[conn=299892744]
```

The machine memory is 16GB.

I suspect it's not a matter of memory capacity, as all the decomposed SQL mentioned above can be executed normally.

### 4. What is your TiDB version? (Required)

tidb v8.1.1

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.