pingcap / tidb

TiDB is an open-source, cloud-native, distributed, MySQL-Compatible database for elastic scale and real-time analytics. Try AI-powered Chat2Query free at : https://www.pingcap.com/tidb-serverless/
https://pingcap.com
Apache License 2.0
36.93k stars 5.81k forks source link

invalid memory address or nil pointer dereference in `memory.(*Tracker).AttachTo` #55881

Open ycybfhb opened 2 weeks ago

ycybfhb commented 2 weeks ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

SQL to init database [init.sql.txt](https://github.com/user-attachments/files/16886980/init.sql.txt)
SQL that causes error ```sql /* error message: Database execute error: HY000, [MySQL][ODBC 8.4(a) Driver][mysqld-8.0.11-TiDB-v8.4.0-alpha-66-g1167e0c]runtime error: invalid memory address or nil pointer dereference */ WITH cte_0 AS (select ref_0.c_cz as c0, sum( cast(ref_2.c_dph7 as signed)) over (partition by ref_4.c_g7eofzlxn order by ref_2.c_ib1xsf3c8d) as c1, cast((ref_3.c_otj13 DIV ref_1.c_hd2v4v0) as double) as c2 from (t_jg8o as ref_0 right outer join (((t__9r63 as ref_1 right outer join t_dci as ref_2 on ((NOT NOT(cast((cast(ref_1.c_hd2v4v0 as double) >= cast(ref_2.c_l1t as signed)) as unsigned))))) inner join t_jg8o as ref_3 on ((NOT NOT(cast((cast(ref_2.c_kzre as char) <=> cast(ref_3.c_a90ol as char)) as unsigned))))) left outer join (t__9r63 as ref_4 cross join t_jg8o as ref_5 ) on ((NOT NOT(cast((cast(ref_2.c_w9qyk_fpj as double) = cast(ref_5.c__qy as double)) as unsigned))))) on ((NOT NOT(cast((cast(ref_1.c_hd2v4v0 as double) <=> cast(ref_4.c_onfeptr2q as signed)) as unsigned))))) where (cast((ref_0.c_s ^ ref_5.c_z) as char) like 'n_') limit 81), cte_1 AS (select cast((cast(subq_1.c6 as decimal) > cast(round( cast(subq_0.c3 as decimal)) as decimal)) as unsigned) as c0, subq_1.c0 as c1, subq_0.c0 as c2, ltrim( cast(subq_0.c0 as char)) as c3, subq_1.c2 as c4, subq_1.c0 as c5, bit_length( cast(subq_0.c0 as char)) as c6, subq_0.c2 as c7, subq_0.c1 as c8, subq_1.c2 as c9 from ((select ref_8.c_tb3u as c0, ref_8.c_x2erxo10w as c1, ref_7.c_c7njaqnyv7 as c2, ref_7.c_i3ml as c3, ref_7.c__n3bhft5z as c4, ref_8.c_wsr as c5 from ((t_dci as ref_6 right outer join t_glzh3lb0ro as ref_7 on (0<>0)) cross join t__9r63 as ref_8 ) where (NOT NOT(cast((cast(ref_6.c_kzre as char) > cast(ref_6.c_gs6c2wzbdg as char)) as unsigned))) order by c0, c1, c2, c3, c4, c5 asc) as subq_0 cross join (select ref_9.c_b48gd04utl as c0, ref_9.c_yu as c1, ref_9.c_b48gd04utl as c2, ref_9.c_yu as c3, ref_9.c_yu as c4, ref_9.c_b48gd04utl as c5, -1092927402 as c6, ref_9.c_yu as c7, ref_9.c_b48gd04utl as c8, ref_9.c_b48gd04utl as c9, ref_9.c_yu as c10 from t_rc as ref_9 where (NOT NOT(cast((ref_9.c_m2y = ref_9.c_m2y) as unsigned))) limit 85) as subq_1 ) where (NOT NOT(cast((cast(subq_0.c4 as signed) != cast(subq_1.c7 as signed)) as unsigned))) order by c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 desc limit 60), cte_2 AS (select distinct ref_10.c_w9qyk_fpj as c0, ref_10.c_bywfl as c1, case when (ref_10.c_dph7 not in ( select 1344916137 as c0 from t_glzh3lb0ro as ref_15 where ((NOT NOT(cast((cast(cast(null as char) as char) >= cast('nql' as char)) as unsigned)))) and ((NOT NOT(cast((cast(ref_15.c_i3ml as signed) <=> cast(ref_15.c_wd3x as double)) as unsigned)))))) then ref_10.c_gs6c2wzbdg else (select c_tb3u from t__9r63 order by c_tb3u limit 1 offset 4) end as c2, ref_10.c_ib1xsf3c8d as c3, ref_10.c_kzre as c4, cast((cast(ref_10.c_bywfl as decimal) % cast(1=1 as unsigned)) as decimal) as c5, ref_10.c_l1t as c6, cast(nullif( ref_10.c_d3wokzls77, ref_10.c_fzqupuma ) as signed) as c7, (select c_wsr from t__9r63 order by c_wsr limit 1 offset 4) as c8, locate( cast((select c_b48gd04utl from t_rc order by c_b48gd04utl limit 1 offset 15) as char), cast(ref_10.c_gs6c2wzbdg as char), cast(case when (NOT NOT(cast((cast(ref_10.c_bywfl as unsigned) > cast((ref_10.c_kzre not like '%78ij_zdi') as unsigned)) as unsigned))) then -5848773938183963038 else round( cast(4682555756345700129 as signed), cast(ref_10.c_d3wokzls77 as signed)) end as signed)) as c9 from t_dci as ref_10 where ((ref_10.c_d3wokzls77 in ( select ref_14.c_m2y as c0 from ((t_rc as ref_11 inner join (t_rc as ref_12 right outer join t__9r63 as ref_13 on ((NOT NOT(cast((ref_13.c_tb3u < ref_13.c_tb3u) as unsigned))))) on (ref_11.c_b48gd04utl = ref_12.c_b48gd04utl )) left outer join t_rc as ref_14 on (((NOT NOT(cast((cast(((NOT NOT(cast((cast(ref_14.c_yu as unsigned) > cast(ref_13.c_hd2v4v0 as double)) as unsigned)))) and ((((NOT NOT(cast((cast(4713478292361382451 as signed) && cast(ref_13.c_wsr as signed)) as unsigned)))) and (0<>0)) or ((NOT NOT(cast((cast(ref_13.c_tb3u as char) > cast(ref_13.c_tb3u as char)) as unsigned))))) as unsigned) <> cast(ref_12.c_yu as signed)) as unsigned)))) or ((NOT NOT(cast((cast(ref_11.c_b48gd04utl as char) < cast(ref_13.c_tb3u as char)) as unsigned)))))) where (NOT NOT(cast((cast(ref_13.c_tb3u as char) = cast(ref_13.c_tb3u as char)) as unsigned)))))) and ((((NOT NOT(cast((cast(ref_10.c_dph7 as decimal) <> cast(ref_10.c_w9qyk_fpj as double)) as unsigned)))) or ((((select c_b48gd04utl from t_rc order by c_b48gd04utl limit 1 offset 5) like '%')) and ((NOT NOT(cast((cast(65536 as signed) XOR cast(ref_10.c_w9qyk_fpj as double)) as unsigned)))))) and ((cast((cast(ref_10.c_ib1xsf3c8d as signed) DIV cast(cast((cast(ref_10.c_ib1xsf3c8d as unsigned) ^ cast(-740470748171434511 as signed)) as signed) as signed)) as char) not like '%bl')))), cte_3 AS (select subq_2.c2 as c0, cast((cast(subq_2.c10 as signed) <> cast(subq_2.c8 as signed)) as unsigned) as c1, subq_2.c9 as c2, subq_2.c1 as c3 from (select var_pop( cast(0<>0 as unsigned)) as c0, count( cast((NOT NOT(cast((cast(ref_16.c_l1t as signed) || cast((select c_l1t from t_dci order by c_l1t limit 1 offset 4) as signed)) as unsigned))) as unsigned)) as c1, ref_16.c_l1t as c2, count( cast((select count(c_ovz0) from t_jg8o) as char)) as c3, count( cast(ref_16.c_kzre as char)) as c4, count( cast(ref_16.c_kzre as char)) as c5, count( cast(ref_16.c_ib1xsf3c8d as decimal)) as c6, count( cast((select c_r58lkh from t__9r63 order by c_r58lkh limit 1 offset 1) as double)) as c7, count( cast(ref_16.c_w9qyk_fpj as double)) as c8, stddev_samp( cast((NOT NOT(cast((cast(127 as signed) && cast(ref_16.c_ib1xsf3c8d as signed)) as unsigned))) as unsigned)) as c9, count( cast(ref_16.c_ib1xsf3c8d as unsigned)) as c10, count( cast(ref_16.c_gs6c2wzbdg as char)) as c11 from t_dci as ref_16 where (ref_16.c_dph7 <= ( select ref_17.c_otj13 as c0 from t_jg8o as ref_17 where (NOT NOT(cast((cast(ref_17.c_s as signed) != cast(ref_17.c__qy as double)) as unsigned))) limit 1)) group by ref_16.c_l1t) as subq_2 where (inet_ntoa( cast(subq_2.c1 as signed)) not like 'wtkzz_bzg')), cte_4 AS (select ref_19.c_w9qyk_fpj as c0, ref_19.c_kzre as c1, ref_18.c_m2y as c2, ref_18.c_yu as c3, ref_19.c_fzqupuma as c4, ref_18.c_m2y as c5, ref_19.c_ib1xsf3c8d as c6 from (t_rc as ref_18 right outer join t_dci as ref_19 on (((ref_19.c_gs6c2wzbdg like 'w___kbw')) or ((NOT NOT(cast((cast(ref_19.c_bywfl as signed) && cast(ref_19.c_ib1xsf3c8d as signed)) as unsigned)))))) where (case when 1=1 then ref_19.c_gs6c2wzbdg else ref_19.c_kzre end like 't_g') order by c0, c1, c2, c3, c4, c5, c6 asc), cte_5 AS (select subq_3.c9 as c0 from ((select ref_20.c_kzre as c0, ref_20.c_l1t as c1, cast(cast(null as signed) as signed) as c2, ref_20.c_w9qyk_fpj as c3, ref_20.c_dph7 as c4, -453645943 as c5, ref_20.c_dph7 as c6, ref_20.c_kzre as c7, ref_20.c_kzre as c8, ref_20.c_gs6c2wzbdg as c9, ref_20.c_kzre as c10 from t_dci as ref_20 where (NOT NOT(cast((cast((select sum(c_yu) from t_rc) as double) && cast(ref_20.c_dph7 as signed)) as unsigned)))) as subq_3 cross join (select ref_21.c_otj13 as c0, 937315269 as c1, -355306303 as c2 from t_jg8o as ref_21 where (NOT NOT(cast((cast(ref_21.c_cz as char) <= cast((select c_b48gd04utl from t_rc order by c_b48gd04utl limit 1 offset 6) as char)) as unsigned))) limit 78) as subq_4 ) where (subq_3.c10 like 'm_b_48h')) select subq_5.c1 as c0, subq_5.c0 as c1, (select c_yu from t_rc order by c_yu limit 1 offset 6) as c2, subq_5.c0 as c3, case when (NOT NOT(cast((cast(subq_5.c0 as signed) > cast(cast((subq_5.c1 DIV subq_5.c0) as decimal) as decimal)) as unsigned))) then subq_5.c1 else (subq_5.c1 is not NULL) end as c4, case when (NOT NOT(cast((cast((select c_ovz0 from t_jg8o order by c_ovz0 limit 1 offset 3) as double) <=> cast(((NOT NOT(cast((cast(cast(null as double) as double) XOR cast(5.9 as double)) as unsigned)))) or ((((NOT NOT(cast((cast(-834732799192564823 as signed) <> cast(subq_5.c1 as decimal)) as unsigned)))) and ((NOT NOT(cast((cast(41 as signed) >= cast(33.16 as double)) as unsigned))))) or ((subq_5.c2 like 'j_wsa'))) as unsigned)) as unsigned))) then cast((cast(case when (subq_5.c1 in ( select distinct (NOT NOT(cast((cast(ref_23.c_hd2v4v0 as double) < cast(ref_23.c_r58lkh as double)) as unsigned))) as c0 from t__9r63 as ref_23 where (NOT NOT(cast((cast(ref_23.c_o8tsf as double) <=> cast(-8933200491588434896 as signed)) as unsigned))))) then cast(subq_5.c3 as signed) else cast(subq_5.c0 as signed) end as signed) || cast(subq_5.c3 as signed)) as unsigned) else (subq_5.c2 < ( select subq_5.c2 as c0 from (cte_5 as ref_24 cross join t_glzh3lb0ro as ref_25 ) where 1=1 union all ( select subq_5.c2 as c0 from cte_3 as ref_26 where ((subq_5.c2 is not NULL)) or ((subq_5.c3 is NULL)) ) limit 1)) end as c5, cast((case when (EXISTS ( select subq_5.c0 as c0, subq_5.c3 as c1, ref_27.c0 as c2, ref_27.c6 as c3, cast((select stddev_samp(c_l1t) from t_dci) as signed) as c4, ref_27.c0 as c5, ref_27.c3 as c6, subq_5.c3 as c7, cast((select avg(c_l1t) from t_dci) as signed) as c8 from cte_4 as ref_27 where (NOT NOT(cast((cast(subq_5.c2 as char) <=> cast(ref_27.c1 as char)) as unsigned))))) then cast(null as double) else -4294967295.0 end > subq_5.c1) as unsigned) as c6, (select c1 from cte_3 order by c1 limit 1 offset 3) as c7, subq_5.c2 as c8, cast((select count(c_b48gd04utl) from t_rc) as char) as c9, subq_5.c2 as c10, subq_5.c3 as c11, subq_5.c3 as c12, (select c_hd2v4v0 from t__9r63 order by c_hd2v4v0 limit 1 offset 4) as c13, subq_5.c0 as c14, subq_5.c0 as c15, cast((select sum(c_yu) from t_rc) as signed) as c16, subq_5.c0 as c17, subq_5.c2 as c18, subq_5.c3 as c19, subq_5.c1 as c20, subq_5.c3 as c21, subq_5.c2 as c22, subq_5.c3 as c23, subq_5.c3 as c24, subq_5.c1 as c25, cast(nullif( rpad( cast(subq_5.c2 as char), 75, cast(subq_5.c2 as char)), subq_5.c2 ) as char) as c26, subq_5.c0 as c27, subq_5.c0 as c28, cast(cast(null as signed) as signed) as c29, (select c_yu from t_rc order by c_yu limit 1 offset 6) as c30, subq_5.c3 as c31, subq_5.c3 as c32, case when (NOT NOT(cast((subq_5.c0 < cast((-2147483647.2 / -123630112) as double)) as unsigned))) then subq_5.c1 else (subq_5.c3 between subq_5.c3 and subq_5.c3) end as c33, case when (1742643624 not in ( select ref_28.c_x2erxo10w as c0 from t__9r63 as ref_28 where ((NOT NOT(cast((cast((NOT NOT(cast((cast(cast(null as char) as char) >= cast(ref_28.c_tb3u as char)) as unsigned))) as unsigned) > cast(ref_28.c_x2erxo10w as signed)) as unsigned)))) or ((ref_28.c_wsr not in ( 1=1, (NOT NOT(cast((cast(ref_28.c_wsr as signed) < cast(29 as signed)) as unsigned))), (ref_28.c_r58lkh not in ( ref_28.c_r58lkh, ref_28.c_r58lkh, ref_28.c_o8tsf, ref_28.c_r58lkh, ref_28.c_hd2v4v0))))) union ( select ref_29.c4 as c0 from cte_4 as ref_29 where (NOT NOT(cast((cast(ref_29.c0 as double) = cast(ref_29.c6 as signed)) as unsigned))) ))) then subq_5.c0 else (NOT NOT(cast((cast(subq_5.c1 as signed) < cast(round( cast((select c_m2y from t_rc order by c_m2y limit 1 offset 2) as signed)) as signed)) as unsigned))) end as c34, subq_5.c2 as c35, subq_5.c0 as c36, subq_5.c2 as c37, subq_5.c1 as c38, cast((cast(32769.0 as double) > cast(28405 as signed)) as unsigned) as c39, subq_5.c3 as c40, acos( cast(cast((cast((select c_ovz0 from t_jg8o order by c_ovz0 limit 1 offset 4) as double) | cast(subq_5.c3 as signed)) as signed) as signed)) as c41, subq_5.c0 as c42, subq_5.c3 as c43, cast((cast(subq_5.c1 as decimal) <= cast(truncate( cast(subq_5.c3 as signed), cast(subq_5.c3 as signed)) as signed)) as unsigned) as c44, subq_5.c3 as c45, right( cast((select c_kzre from t_dci order by c_kzre limit 1 offset 5) as char), cast((508067673 < ( select subq_5.c3 as c0 from t__9r63 as ref_30 where (NOT NOT(cast((cast(ref_30.c_hd2v4v0 as double) >= cast(0<>0 as unsigned)) as unsigned))) limit 1)) as unsigned)) as c46, subq_5.c3 as c47, cast(nullif( subq_5.c0, (subq_5.c2 not in ( select ref_31.c0 as c0 from cte_0 as ref_31 where 0<>0 union ( select ref_32.c_m0qqv_cl4x as c0 from t_jg8o as ref_32 where 0<>0 ))) ) as unsigned) as c48, subq_5.c3 as c49, subq_5.c3 as c50, subq_5.c3 as c51, subq_5.c1 as c52, degrees( cast(2681972376301496118 as signed)) as c53, case when 0<>0 then cast((cast(subq_5.c1 as signed) - cast(cast((cast((select var_pop(c_ovz0) from t_jg8o) as double) % cast(-2552831182259509367 as signed)) as double) as double)) as double) else cast((case when (NOT NOT(cast(((subq_5.c1 not in ( select (NOT NOT(cast((cast(32769.4 as double) < cast(cast(null as double) as double)) as unsigned))) as c0 from cte_1 as ref_33 where (NOT NOT(cast((cast(69.66 as double) > cast(ref_33.c7 as signed)) as unsigned))) order by c0 desc)) || subq_5.c0) as unsigned))) then cast(cast(null as double) as double) else round( cast(9223372036854775807.7 as double)) end + subq_5.c1) as double) end as c54, cast((cast((NOT NOT(cast((cast(subq_5.c2 as char) <=> cast(cast(null as char) as char)) as unsigned))) as unsigned) | cast( last_value( cast(subq_5.c3 as decimal)) over (partition by subq_5.c1, subq_5.c0 order by subq_5.c3, subq_5.c0) as decimal)) as signed) as c55, subq_5.c3 as c56, subq_5.c0 as c57, subq_5.c1 as c58, cast((cast((subq_5.c3 between subq_5.c3 and subq_5.c3) as unsigned) <= cast(subq_5.c1 as signed)) as unsigned) as c59, cast(coalesce( cast((cast((0<>0) and ((EXISTS ( select ref_34.c_s as c0, ref_34.c_mgjb as c1, ref_34.c_m0qqv_cl4x as c2, ref_34.c_cz as c3, ref_34.c_a90ol as c4, ref_34.c_s as c5 from t_jg8o as ref_34 where (NOT NOT(cast((cast(ref_34.c_z as signed) > cast((select c_wsr from t__9r63 order by c_wsr limit 1 offset 3) as unsigned)) as unsigned))) limit 127))) as unsigned) | cast(truncate( cast(subq_5.c0 as decimal), cast(subq_5.c3 as signed)) as decimal)) as signed), cast(coalesce( 5554697334594895989, cast((cast(31.30 as double) << cast(subq_5.c1 as signed)) as signed) ) as signed) ) as signed) as c60, cast((cast((select c_wsr from t__9r63 order by c_wsr limit 1 offset 2) as signed) & cast(subq_5.c1 as unsigned)) as signed) as c61, subq_5.c0 as c62, subq_5.c2 as c63, radians( cast(257.0 as double)) as c64, subq_5.c2 as c65, subq_5.c1 as c66, cast(((subq_5.c2 not like 'n_8wi17_aw') >> (cast((cast(cast(coalesce( 126.0, cast((select c_wd3x from t_glzh3lb0ro order by c_wd3x limit 1 offset 2) as double) ) as double) as double) <=> cast((NOT NOT(cast((cast((select c_r58lkh from t__9r63 order by c_r58lkh limit 1 offset 2) as double) XOR cast(cast(null as signed) as signed)) as unsigned))) as unsigned)) as unsigned) > ( select (ref_35.c_a90ol not like 'j8_o') as c0 from t_jg8o as ref_35 where (EXISTS ( select ref_36.c0 as c0, ref_35.c_cz as c1, ref_36.c0 as c2, ref_36.c3 as c3, ref_35.c_ovz0 as c4, (select c_tazb9 from t_jg8o order by c_tazb9 limit 1 offset 3) as c5, ref_36.c1 as c6, ref_36.c3 as c7 from cte_3 as ref_36 where (EXISTS ( select 322327666 as c0, cast(null as signed) as c1, ref_37.c2 as c2, ref_37.c4 as c3, ref_36.c0 as c4, ref_37.c3 as c5, ref_36.c2 as c6, ref_37.c4 as c7, ref_37.c4 as c8 from cte_1 as ref_37 where (NOT NOT(cast((cast((select c_otj13 from t_jg8o order by c_otj13 limit 1 offset 2) as signed) = cast(ref_35.c_s as signed)) as unsigned))))))) union ( select (subq_5.c2 not like 'e1b70pe0_n') as c0 from cte_5 as ref_38 where (NOT NOT(cast((cast(subq_5.c3 as decimal) || cast((select count(c_wsr) from t__9r63) as signed)) as unsigned))) ) limit 1))) as signed) as c67, cast((cast(subq_5.c3 as decimal) / cast(truncate( cast(subq_5.c3 as signed), cast(subq_5.c3 as signed)) as signed)) as decimal) as c68, subq_5.c1 as c69, subq_5.c3 as c70, hex( cast(subq_5.c2 as char)) as c71, quote( cast(subq_5.c2 as char)) as c72, subq_5.c0 as c73, subq_5.c3 as c74, subq_5.c3 as c75, subq_5.c2 as c76, subq_5.c3 as c77, subq_5.c3 as c78, sqrt( cast(subq_5.c3 as signed)) as c79, subq_5.c1 as c80, subq_5.c2 as c81, subq_5.c3 as c82, subq_5.c1 as c83, cast((subq_5.c2 != subq_5.c2) as unsigned) as c84, subq_5.c1 as c85 from (select ref_22.c_bywfl as c0, ref_22.c_bywfl as c1, ref_22.c_kzre as c2, ref_22.c_d3wokzls77 as c3 from t_dci as ref_22 where (NOT NOT(cast((cast((select count(c_tb3u) from t__9r63) as char) || cast(21273 as signed)) as unsigned)))) as subq_5 where ((subq_5.c3 between subq_5.c3 and subq_5.c3)) or (('slfyrqos' not like 'm_qpy')) limit 110; ```

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

Expect no crashes

3. What did you see instead (Required)

runtime error: invalid memory address or nil pointer dereference
github.com/pingcap/errors.AddStack
    /root/go/pkg/mod/github.com/pingcap/errors@v0.11.5-0.20240318064555-6bd07397691f/errors.go:178
github.com/pingcap/errors.Trace
    /root/go/pkg/mod/github.com/pingcap/errors@v0.11.5-0.20240318064555-6bd07397691f/juju_adaptor.go:15
github.com/pingcap/tidb/pkg/util.GetRecoverError
    /workspace/source/tidb/pkg/util/util.go:288
github.com/pingcap/tidb/pkg/executor/internal/exec.Next.func1
    /workspace/source/tidb/pkg/executor/internal/exec/executor.go:435
runtime.gopanic
    /usr/local/go/src/runtime/panic.go:914
runtime.panicmem
    /usr/local/go/src/runtime/panic.go:261
runtime.sigpanic
    /usr/local/go/src/runtime/signal_unix.go:861
github.com/pingcap/tidb/pkg/util/memory.(*Tracker).AttachTo
    /workspace/source/tidb/pkg/util/memory/tracker.go:330
github.com/pingcap/tidb/pkg/executor.setupCTEStorageTracker
    /workspace/source/tidb/pkg/executor/cte.go:577
github.com/pingcap/tidb/pkg/executor.(*cteProducer).produce
    /workspace/source/tidb/pkg/executor/cte.go:346
github.com/pingcap/tidb/pkg/executor.(*CTEExec).Next
    /workspace/source/tidb/pkg/executor/cte.go:114
github.com/pingcap/tidb/pkg/executor/internal/exec.Next
    /workspace/source/tidb/pkg/executor/internal/exec/executor.go:451
github.com/pingcap/tidb/pkg/executor/join.(*buildWorkerBase).fetchBuildSideRows
    /workspace/source/tidb/pkg/executor/join/hash_join_base.go:253
github.com/pingcap/tidb/pkg/executor/join.(*HashJoinV1Exec).fetchAndBuildHashTable.func2
    /workspace/source/tidb/pkg/executor/join/hash_join_v1.go:1037
github.com/pingcap/tidb/pkg/util.(*WaitGroupWrapper).RunWithRecover.func1
    /workspace/source/tidb/pkg/util/wait_group_wrapper.go:189
runtime.goexit
    /usr/local/go/src/runtime/asm_amd64.s:1650

4. What is your TiDB version? (Required)

Release Version: v8.4.0-alpha-66-g1167e0c
Edition: Community
Git Commit Hash: 1167e0c06fc8e2dd066bd974315284bc0e884acc
Git Branch: HEAD
UTC Build Time: 2024-09-03 01:15:19
GoVersion: go1.21.13
Race Enabled: false
Check Table Before Drop: false
Store: tikv

We are the BASS team from the School of Cyber Science and Technology at Beihang University. Our main focus is on system software security, operating systems, and program analysis research, as well as the development of automated program testing frameworks for detecting software defects. Using our self-developed database vulnerability testing tool, we have identified the above-mentioned vulnerabilities in TiDB that may lead to database crashes.

windtalker commented 6 days ago

The root cause is

  1. In TiDB, If multiple CTEExec need to read from a same CTE table, TiDB will create a cteProducer, and all CTEExec will share the same cteProducer
  2. CTEExec use
    e.producer.resTbl.Lock()
    defer e.producer.resTbl.Unlock()

    to avoid multi-thread issues. And for the first CTEExec that tries to read cteProducer, it will trigger the calculation of cteProducer, and save cte results in cteProducer for other CTEExec to read. https://github.com/pingcap/tidb/blob/4371a1d4850f8924ba922f179daa7680ef2976da/pkg/executor/cte.go#L110-L117

  3. The following is part of the query plan
    |               │   │ └─Apply_678(Probe)                             | 8.00    | root      |                                              | CARTESIAN left outer join
    |               │   │   ├─HashJoin_679(Build)                        | 8.00    | root      |                                              | CARTESIAN left outer semi join, other cond:eq(issuedb.t_dci.c_bywfl, Column#346)
    |               │   │   │ ├─HashAgg_685(Build)                       | 5.12    | root      |                                              | group by:Column#672, funcs:firstrow(Column#672)->Column#346
    |               │   │   │ │ └─Projection_780                         | 6.40    | root      |                                              | not(not(cast(lt(cast(issuedb.t__9r63.c_hd2v4v0, double BINARY), cast(issuedb.t__9r63.c_r58lkh, double BINARY)), bigint(22) UNSIGNED BINARY)))->Column|               │   │   │ │   └─TableReader_688                      | 6.40    | root      |                                              | data:Selection_687
    |               │   │   │ │     └─Selection_687                      | 6.40    | cop[tikv] |                                              | istrue_with_null(cast(nulleq(cast(issuedb.t__9r63.c_o8tsf, double BINARY), -8.933200491588435e+18), bigint(22) UNSIGNED BINARY))
    |               │   │   │ │       └─TableFullScan_686                | 8.00    | cop[tikv] | table:ref_23                                 | keep order:false, stats:pseudo
    |               │   │   │ └─TableReader_681(Probe)                   | 8.00    | root      |                                              | data:TableFullScan_680
    |               │   │   │   └─TableFullScan_680                      | 8.00    | cop[tikv] | table:ref_22                                 | keep order:false
    |               │   │   └─Limit_691(Probe)                           | 8.00    | root      |                                              | offset:0, count:1
    |               │   │     └─Union_692                                | 8.00    | root      |                                              |
    |               │   │       ├─Projection_693                         | 8.00    | root      |                                              | issuedb.t_dci.c_kzre->Column#363
    |               │   │       │ └─Limit_696                            | 8.00    | root      |                                              | offset:0, count:1
    |               │   │       │   └─HashJoin_697                       | 8.00    | root      |                                              | CARTESIAN inner join
    |               │   │       │     ├─IndexReader_708(Build)           | 704.00  | root      |                                              | index:IndexFullScan_707
    |               │   │       │     │ └─IndexFullScan_707              | 704.00  | cop[tikv] | table:ref_25, index:c_kffac5e63(c_kffac5e63) | keep order:false, stats:pseudo
    |               │   │       │     └─CTEFullScan_699(Probe)           | 499.20  | root      | CTE:cte_5 AS ref_24                          | data:CTE_2
    |               │   │       └─Projection_719                         | 8.00    | root      |                                              | issuedb.t_dci.c_kzre->Column#363
    |               │   │         └─Limit_722                            | 8.00    | root      |                                              | offset:0, count:1
    |               │   │           └─Selection_724                      | 8.00    | root      |                                              | or(not(isnull(issuedb.t_dci.c_kzre)), 0)
    |               │   │             └─CTEFullScan_726                  | 25.60   | root      | CTE:cte_3 AS ref_26                          | data:CTE_1

    Note that CTEFullScan_699 is the apply side of Apply_678, and CTEFullScan_699 is under Limit_691 and Union_692.

  4. Consider that case that
    • time 1: Apply_678 open Limit_691, then CTEFullScan_699 will be opened, but since there is Union_692 executor, it is possible that Limit_691 read enough data from Projection_693 that the Next() of CTEFullScan_699 is not even called.
    • time 2: Apply_678 will close Limit_691, which will close CTEFullScan_699, so cteproducer is closed https://github.com/pingcap/tidb/blob/4371a1d4850f8924ba922f179daa7680ef2976da/pkg/executor/cte.go#L136-L150
    • time 3: Apply_678 open Limit_691 again, and read data from Limit_691, this time, Projection_693 can not provide enough data, so Next() of CTEFullScan_699 will be called.
    • time 4: CTEFullScan_699 will try to trigger the calculation of cteProducer, because e.producer.resTbl.Done() is false. Then e.producer.produce(ctx) will be called on a closed cteProducer, and trigger the invalid memory address error