[MDEV-28567] Assertion `0' in open_tables upon function-related operations Created: 2022-05-14  Updated: 2022-07-13  Resolved: 2022-06-29

Status: Closed
Project: MariaDB Server
Component/s: Locking, Stored routines, Views
Affects Version/s: 10.9
Fix Version/s: 10.9.2

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Aleksey Midenkov
Resolution: Fixed Votes: 0
Labels: None

Attachments: File bad.log     File good.log    
Issue Links:
Problem/Incident
causes MDEV-29060 main.view_debug sporadically fails wi... Closed
is caused by MDEV-17554 Auto-create history partitions for sy... Closed

 Description   

The test case fails for me every time on a 10.9 debug build, but it is still a concurrent test, so maybe it can fail to fail in some circumstances. Try to run with --repeat then.

CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW UPDATE t2 SET b = 0;
CREATE TRIGGER tr2 BEFORE INSERT ON t2 FOR EACH ROW UPDATE t1 SET a = 6;
CREATE VIEW v1 AS SELECT * FROM t1;
 
SET AUTOCOMMIT=OFF;
SELECT * FROM t1;
 
--connect (con1,localhost,root,,test)
--send
  DROP TRIGGER tr1;
 
--connection default
--error ER_LOCK_DEADLOCK
INSERT INTO t2 SELECT * FROM t2;
--error ER_SP_DOES_NOT_EXIST
SELECT f() FROM t2;
 
--connect (con2,localhost,root,,test)
--send
  ALTER VIEW v1 AS SELECT f() FROM t1;
 
--connection con1
--reap
--send
CREATE FUNCTION f() RETURNS INT RETURN 1;
 
--connection default
SELECT * FROM ( SELECT * FROM v1 ) sq;
 
# Cleanup
COMMIT;
 
--connection con2
--reap
 
DROP VIEW v1;
DROP FUNCTION f;
DROP TABLE t1, t2;

10.9 5dba54bf

mariadbd: /data/src/10.9/sql/sql_base.cc:4658: bool open_tables(THD*, const DDL_options_st&, TABLE_LIST**, uint*, uint, Prelocking_strategy*): Assertion `0' failed.
220515  2:50:36 [ERROR] mysqld got signal 6 ;
 
#7  0x00007f048119f662 in __GI___assert_fail (assertion=0x55d31ad99007 "0", file=0x55d31ad998d8 "/data/src/10.9/sql/sql_base.cc", line=4658, function=0x55d31ad9b130 "bool open_tables(THD*, const DDL_options_st&, TABLE_LIST**, uint*, uint, Prelocking_strategy*)") at assert.c:101
#8  0x000055d319f8e449 in open_tables (thd=0x7f0458000db8, options=..., start=0x7f047c2b3868, counter=0x7f047c2b3884, flags=0, prelocking_strategy=0x7f047c2b3908) at /data/src/10.9/sql/sql_base.cc:4658
#9  0x000055d319f9012e in open_and_lock_tables (thd=0x7f0458000db8, options=..., tables=0x7f0458014030, derived=true, flags=0, prelocking_strategy=0x7f047c2b3908) at /data/src/10.9/sql/sql_base.cc:5540
#10 0x000055d319f46d7d in open_and_lock_tables (thd=0x7f0458000db8, tables=0x7f0458014030, derived=true, flags=0) at /data/src/10.9/sql/sql_base.h:510
#11 0x000055d31a196d4f in mysql_create_view (thd=0x7f0458000db8, views=0x7f0458014030, mode=VIEW_ALTER) at /data/src/10.9/sql/sql_view.cc:465
#12 0x000055d31a043513 in mysql_execute_command (thd=0x7f0458000db8, is_called_from_prepared_stmt=false) at /data/src/10.9/sql/sql_parse.cc:5815
#13 0x000055d31a04a0b3 in mysql_parse (thd=0x7f0458000db8, rawbuf=0x7f0458013b50 "ALTER VIEW v1 AS SELECT f() FROM t1", length=35, parser_state=0x7f047c2b4500) at /data/src/10.9/sql/sql_parse.cc:8047
#14 0x000055d31a03670b in dispatch_command (command=COM_QUERY, thd=0x7f0458000db8, packet=0x7f045800b9a9 "ALTER VIEW v1 AS SELECT f() FROM t1", packet_length=35, blocking=true) at /data/src/10.9/sql/sql_parse.cc:1912
#15 0x000055d31a035038 in do_command (thd=0x7f0458000db8, blocking=true) at /data/src/10.9/sql/sql_parse.cc:1409
#16 0x000055d31a20a720 in do_handle_one_connection (connect=0x55d31d8624b8, put_in_cache=true) at /data/src/10.9/sql/sql_connect.cc:1418
#17 0x000055d31a20a3bf in handle_one_connection (arg=0x55d31d8624b8) at /data/src/10.9/sql/sql_connect.cc:1312
#18 0x000055d31a704a98 in pfs_spawn_thread (arg=0x55d31d96be18) at /data/src/10.9/storage/perfschema/pfs.cc:2201
#19 0x00007f0481669ea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
#20 0x00007f0481268def in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Reproducible with at least MyISAM and InnoDB.
No obvious effect on a non-debug build or on 10.8.

The failure started happening on 10.9 after this commit:

commit 92bfc0e8c4bb5c86359c29458d67f3e7836ec18a
Author: Aleksey Midenkov
Date:   Fri May 6 10:45:17 2022 +0300
 
    MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT

However, I can't claim it is a regression, because the commit added the assert itself:

+            // FIXME: is this really used?
+            DBUG_ASSERT(0);



 Comments   
Comment by Aleksey Midenkov [ 2022-06-18 ]

Good and Bad script behaviour:

CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW UPDATE t2 SET b = 0;
CREATE TRIGGER tr2 BEFORE INSERT ON t2 FOR EACH ROW UPDATE t1 SET a = 6;
CREATE VIEW v1 AS SELECT * FROM t1;
 
SET AUTOCOMMIT=OFF;
SELECT * FROM t1;
# T@6
# Seized:   test/t1 (MDL_SHARED_READ)
 
--connect (con1,localhost,root,,test)
--send
  DROP TRIGGER tr1;
# T@7
# Seized:   test/t1 (MDL_SHARED_NO_WRITE)
# Waiting: test/t1 (MDL_EXCLUSIVE)
# Waiting: test/t1 (MDL_SHARED_WRITE)
# Deadlock: test/t1 (MDL_SHARED_WRITE)
 
--connection default
--error 0,ER_LOCK_DEADLOCK
INSERT INTO t2 SELECT * FROM t2;
# T@6
# Released: test/t1 (MDL_SHARED_READ)
# T@7
# Acquired: test/t1 (MDL_EXCLUSIVE) (good)
--error ER_SP_DOES_NOT_EXIST
SELECT f() FROM t2;
# T@6
# Seized:   test/f (MDL_SHARED)
# T@7
# Released: test/t1 (MDL_EXCLUSIVE)
# Good1: continue T@6 below
# Bad1: continue T@8 below
 
--connect (con2,localhost,root,,test)
--send
  ALTER VIEW v1 AS SELECT f() FROM t1;
# T@8
# Good2: Waiting: test/v1 (MDL_EXCLUSIVE)
# Good2-3: continue T@7 below
# Good5: Acquired: test/v1 (MDL_EXCLUSIVE)
# Good5: Seized: test/v1 (MDL_EXCLUSIVE)
# Good5-6: continue T@7 below
# Good7: Seized:   test/t1 (MDL_SHARED_READ)
# Good7: Waiting: test/f (MDL_SHARED)
# Good7-8: continue T@7 below
# Good9: Acquired: test/f (MDL_SHARED)
# Good9: Released: test/f (MDL_SHARED)
# Good9: Released: test/t1 (MDL_SHARED_READ)
# Good9: Released: test/v1 (MDL_EXCLUSIVE)
# Good9: command finished without error
# Bad1: Seized: test/v1 (MDL_EXCLUSIVE)
# Bad1: Seized: test/v1 (MDL_EXCLUSIVE)
# Bad1: Seized: test/t1 (MDL_SHARED_READ)
# Bad1-2: continue T@6 below
# Bad4: Waiting: test/f (MDL_SHARED)
# Bad4: Deadlock: test/f (MDL_SHARED)
# Bad4: command finished with error
 
--connection con1
--reap
--send
CREATE FUNCTION f() RETURNS INT RETURN 1;
# T@7
# Good3: Waiting: test/f (MDL_EXCLUSIVE)
# Good3-4: continue T@6 below
# Good6: Acquired: test/f (MDL_EXCLUSIVE)
# Good6-7: continue T@8 above
# Good8: Released: test/f (MDL_EXCLUSIVE)
# Good8-9: continue T@8 above
# Bad3: Waiting: test/f (MDL_EXCLUSIVE)
# Bad3-4: continue T@8 above
 
--connection default
SELECT * FROM ( SELECT * FROM v1 ) sq;
# T@6
# Good1: Seized:   test/v1 (MDL_SHARED_READ)
# Good1-2: continue T@8 above
# Good4: Seized:   test/t1 (MDL_SHARED_READ)
# Bad2: Waiting: test/v1 (MDL_SHARED_READ)
# Bad2-3: continue T@7 above
 
# Cleanup
COMMIT;
# Good4: Released: test/t1 (MDL_SHARED_READ)
# Good4: Released: test/v1 (MDL_SHARED_READ)
# Good4: Released: test/f (MDL_SHARED)
# Good4-5: continue T@8 above
 
--connection con2
--reap
 
DROP VIEW v1;
DROP FUNCTION f;
DROP TABLE t1, t2;

Good: SELECT seized v1; ALTER waiting v1; CREATE waiting f; SELECT seized t1; COMMIT released t1, v1, f; etc...

Bad: ALTER seized v1, t1; SELECT waiting v1; CREATE waiting f; ALTER waiting f, deadlock f.

In Good ALTER is waiting on v1 until COMMIT releases f and that avoids deadlock situation.

For details see diff between attached good.log and bad.log.

Comment by Aleksey Midenkov [ 2022-06-20 ]

Please review bb-10.9-midenok

Comment by Oleksandr Byelkin [ 2022-06-21 ]

OK to push

Generated at Thu Feb 08 10:01:44 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.