Bug #85765 | Assert !rw_lock_own(lock, RW_LOCK_S) rw_lock_s_lock_func in include/sync0rw.ic | ||
---|---|---|---|
Submitted: | 3 Apr 2017 7:43 | Modified: | 13 Oct 2017 16:49 |
Reporter: | Shipra Jain | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
Version: | 8.0.2 (trunk) | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[3 Apr 2017 7:43]
Shipra Jain
[7 Apr 2017 7:12]
Naga Satyanarayana Bodapati
Posted by developer: This is case where a page is latched twice by the same thread. We don't allow recursive S_latch. This kind of latching can only happen with ICP. On why we need this latch across with ICP, according to Jimmy on channel (05:28:52 IST) jimmy.yang: basically, when we find a record, we latch the page, making a copy of it, and then send it to server, release the latch. Then server ask for another record, then do join etc. (05:29:12 IST) jimmy.yang: so each time, we fetch a record etc. (05:30:15 IST) jimmy.yang: when ICP comes, it might do some screening etc. all in InnoDB, so it might involve multiple records. To keep the correctness of the records, the pages holding those records have to be kept latched (05:31:33 IST) jimmy.yang: and if it involves operations between multiple records that eventually leads to the same page, then such multiple attempt of latching the same page could happened But if you observe, the second entry to InnoDB is for reading DD tables. This uses attachable trx. gdb) f 41 #41 0x00000000029553b1 in row_search_mvcc (buf=0x7f4770335d30 "\350\037\241\026", mode=PAGE_CUR_GE, prebuilt=0x7f4770376cc8, match_mode=1, direction=0) at /log/RQG/shipjain/trunkvigdis28/storage/innobase/row/row0sel.cc:5677 5677 switch (row_search_idx_cond_check(buf, prebuilt, rec, offsets)) { (gdb) p prebuilt->trx $16 = (trx_t *) 0x7f4807200b00 (gdb) p prebuilt->trx->id $17 = 0 (gdb) p prebuilt->trx->is_dd_trx $18 = false (gdb) f 41 gdb) p prebuilt->index->name $7 = {m_name = 0x7f4800611e38 "schema_id"} (gdb) p prebuilt->index->table->name $8 = {m_name = 0x7f48005f4b98 "mysql/tables"} gdb) f 12 #12 0x0000000002953c6c in row_search_mvcc (buf=0x7f477353f320 "", mode=PAGE_CUR_GE, prebuilt=0x7f4770361ce8, match_mode=1, direction=0) at /log/RQG/shipjain/trunkvigdis28/storage/innobase/row/row0sel.cc:5081 5081 pcur, 0, &mtr); (gdb) p prebuilt->trx $13 = (trx_t *) 0x7f48072024b0 (gdb) p prebuilt->trx->id $14 = 0 (gdb) p prebuilt->trx->is_dd_trx $15 = true gdb) f 12 #12 0x0000000002953c6c in row_search_mvcc (buf=0x7f477353f320 "", mode=PAGE_CUR_GE, prebuilt=0x7f4770361ce8, match_mode=1, direction=0) at /log/RQG/shipjain/trunkvigdis28/storage/innobase/row/row0sel.cc:5081 5081 pcur, 0, &mtr); (gdb) p prebuilt->index->name $11 = {m_name = 0x7f4800611e38 "schema_id"} (gdb) p prebuilt->index->table->name $12 = {m_name = 0x7f48005f4b98 "mysql/tables"} f 12 -> second entry (attachable trx) f 41 -> first entry (normal trx) So the second read is indeed read caused by attachable trxs. Then why this assert happened? To check if rw_lock is already latched, we use thread_id. Since thread_id is same, we think it is being latched twice by same thread. Acc to Jimmy "block latch is not particular to trx". So even though we use attachable trx, it is still considered as same thread.
[7 Apr 2017 7:14]
Naga Satyanarayana Bodapati
Posted by developer: rw_lock_own used thread_id. See here rw_lock_own( /*========*/ rw_lock_t* lock, /*!< in: rw-lock */ ulint lock_type) /*!< in: lock type: RW_LOCK_S, RW_LOCK_X */ { ut_ad(lock); ut_ad(rw_lock_validate(lock)); rw_lock_debug_mutex_enter(); for (const rw_lock_debug_t* info = UT_LIST_GET_FIRST(lock->debug_list); info != NULL; info = UT_LIST_GET_NEXT(list, info)) { if (os_thread_eq(info->thread_id, os_thread_get_curr_id()) && info->pass == 0 && info->lock_type == lock_type) { rw_lock_debug_mutex_exit(); /* Found! */ return(TRUE); } } rw_lock_debug_mutex_exit(); return(FALSE); }
[16 Oct 2017 12:47]
Paul DuBois
Fixed in 8.0.4, 9.0.0. Queries on the INFORMATION_SCHEMA TABLES and STATISTICS tables, if evaluated using Index Condition Pushdown, could push down internal data dictionary funtions, resulting in an assertion being raised.