[MDEV-12882] Assertion `mdl_ticket->m_type == MDL_SHARED_UPGRADABLE || mdl_ticket->m_type == MDL_SHARED_NO_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE || mdl_ticket->m_type == MDL_SHARED_READ' failed in MDL_context::upgrade_shared_lock Created: 2017-05-23  Updated: 2017-06-26  Resolved: 2017-06-26

Status: Closed
Project: MariaDB Server
Component/s: Locking
Affects Version/s: 10.2
Fix Version/s: 10.2.7, 10.3.1

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Sergey Vojtovich
Resolution: Fixed Votes: 0
Labels: None


 Description   

--source include/have_innodb.inc
CREATE TABLE t (a INT) ENGINE=InnoDB;
LOCK TABLES t AS t1 WRITE CONCURRENT, t AS t2 READ;

10.2 7edadde72eb23e9110db8cea810c023104e9d15e

mysqld: /data/src/10.2/sql/mdl.cc:2327: bool MDL_context::upgrade_shared_lock(MDL_ticket*, enum_mdl_type, double): Assertion `mdl_ticket->m_type == MDL_SHARED_UPGRADABLE || mdl_ticket->m_type == MDL_SHARED_NO_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE || mdl_ticket->m_type == MDL_SHARED_READ' failed.
170523 23:16:49 [ERROR] mysqld got signal 6 ;
 
#7  0x00007fa10084dee2 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
#8  0x00007fa1030be241 in MDL_context::upgrade_shared_lock (this=0x7fa0a8000c00, mdl_ticket=0x7fa0a8079470, new_type=MDL_SHARED_READ_ONLY, lock_wait_timeout=86400) at /data/src/10.2/sql/mdl.cc:2324
#9  0x00007fa102f6a3ee in lock_tables_open_and_lock_tables (thd=0x7fa0a8000b00, tables=0x7fa0a8012470) at /data/src/10.2/sql/sql_parse.cc:2800
#10 0x00007fa102f7020d in mysql_execute_command (thd=0x7fa0a8000b00) at /data/src/10.2/sql/sql_parse.cc:4876
#11 0x00007fa102f798f0 in mysql_parse (thd=0x7fa0a8000b00, rawbuf=0x7fa0a8012348 "LOCK TABLES t AS t1 WRITE CONCURRENT, t AS t2 READ", length=50, parser_state=0x7fa0f4094200, is_com_multi=false, is_next_command=false) at /data/src/10.2/sql/sql_parse.cc:7874
#12 0x00007fa102f679c8 in dispatch_command (command=COM_QUERY, thd=0x7fa0a8000b00, packet=0x7fa0a81406b1 "LOCK TABLES t AS t1 WRITE CONCURRENT, t AS t2 READ", packet_length=50, is_com_multi=false, is_next_command=false) at /data/src/10.2/sql/sql_parse.cc:1812
#13 0x00007fa102f66338 in do_command (thd=0x7fa0a8000b00) at /data/src/10.2/sql/sql_parse.cc:1362
#14 0x00007fa1030b10cf in do_handle_one_connection (connect=0x7fa105f36420) at /data/src/10.2/sql/sql_connect.cc:1354
#15 0x00007fa1030b0e5c in handle_one_connection (arg=0x7fa105f36420) at /data/src/10.2/sql/sql_connect.cc:1260
#16 0x00007fa1034cad02 in pfs_spawn_thread (arg=0x7fa105e99d90) at /data/src/10.2/storage/perfschema/pfs.cc:1862
#17 0x00007fa102587494 in start_thread (arg=0x7fa0f4095700) at pthread_create.c:333
#18 0x00007fa10090a93f in clone () from /lib/x86_64-linux-gnu/libc.so.6



 Comments   
Comment by Sergey Vojtovich [ 2017-06-21 ]

Even though table is locked multiple times connection can hold only one lock, the strongest one. Currently there's no lock having semantics suitable for the above test case, that is:

  • disallow concurrent writes (because of MDL_SHARED_READ_ONLY)
  • disallow concurrent LOCK TABLE innodb READ (because of MDL_SHARED_WRITE)
  • allow concurrent reads

I can see the following possible fixes:

  • implement this new lock type
  • forbid such scenario
  • use lock with stronger semantics, that is MDL_SHARED_NO_READ_WRITE

serg, what's your thinking?

Comment by Sergei Golubchik [ 2017-06-21 ]

I'd either use the stronger lock or issue an error.
I think I'd prefer a stronger lock, if there's a good explanation why it's not an error. And here it is:

insert t1 select * from t1

this needs to read from and to write to the table. and it takes a stronger lock, there's no error here.

Comment by Sergey Vojtovich [ 2017-06-21 ]

Hmm... I believe this example is not completely applicable, because semantically we have to take MDL_SHARED_WRITE in this case. Right?

But in this bug semantically we can allow concurrent reads (except for LOCK TABLE ... READ). The only reason why we wouldn't allow them is that we don't want to add a lot of code just to handle this edge case.

Comment by Sergei Golubchik [ 2017-06-21 ]

Yes, I just mean that the server takes a stronger lock. I could, probably, come with with a more complex example with a couple of triggers that require different locks on the same table and how prelocking handles it.

But I think it's enough to say that when many locks are requested, the stronger lock wins.

Comment by Sergey Vojtovich [ 2017-06-21 ]

In our case requested locks will be MDL_SHARED_WRITE and MDL_SHARED_READ_ONLY. And the winner is out of sudden MDL_SHARED_NO_READ_WRITE. I don't think we had anything similar before MDL_SHARED_READ_ONLY was introduced.

I'm all for upgrading to MDL_SHARED_NO_READ_WRITE. Just trying to understand your arguments.

Comment by Sergey Vojtovich [ 2017-06-22 ]

serg, please review fix for this bug.

Comment by Sergei Golubchik [ 2017-06-23 ]

ok to push

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