facebook / mysql-5.6

Facebook's branch of the Oracle MySQL database. This includes MyRocks.

Home Page:http://myrocks.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cached RocksDB transaction object accessed after delete by XA COMMIT

laurynas-biveinis opened this issue · comments

In 8.0.32 but not 8.0.28, the following test, reduced from main.mdl_sync test, which does not fail:

--source include/count_sessions.inc

--echo #
--echo # Bug#21021848 ASSERTION `M_STATUS == DA_ERROR' FAILED.
--echo #
CREATE TABLE t1(c1 INT NOT NULL) ENGINE=CSV;
CREATE TABLE t2(c1 INT NOT NULL) ENGINE=InnoDB;

--echo # Emulate corruption of t1
LOCK TABLES t1 WRITE;
INSERT INTO t1 VALUES(0);
CHECK TABLE t1;
UNLOCK TABLES;

--echo # Start XA txn on default
XA START 'test2';
--echo # Acquire SR on t2
SELECT * FROM t2;
--echo # Block IS query just before calling lock_table_names() (before X on t1)
SET DEBUG_SYNC='recover_ot_repair SIGNAL parked WAIT_FOR go';
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';

--echo # Create a new conncection which will compete for MDL lock
--connect (con1,localhost,root,,)
--echo # Wait until default becomes blocked
SET DEBUG_SYNC='now WAIT_FOR parked';
--echo # Try to acquire X on t1 and t2, which will block while default
--echo # holds SR on t2
--send DROP TABLES t1, t2

--echo # Create control connection
--connect (con2,localhost,root,,)

--echo # Wait until con1 is blocked
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = "Waiting for table metadata lock" and
        info = "DROP TABLES t1, t2";
--source include/wait_condition.inc
--echo # Wake up XA txn/IS query on default
SET DEBUG_SYNC='now SIGNAL go';
--echo # Disconnect control connection
--disconnect con2
--source include/wait_until_disconnected.inc

--echo # Switch to default connection
--connection default
--echo # Wait for IS query which will try repair t1 which requires X.
--echo # Previously that resulted in deadlock with con1 over t1,
--echo # but now t1 is skipped and a warning is issued
--reap

--echo # Finish XA txn 'test2' to release SR on t2 so that con1
--echo # becomes unblocked
XA END 'test2';
XA PREPARE 'test2';
XA COMMIT 'test2';

--echo # Cleanup
SET DEBUG_SYNC= 'RESET';

--echo # Clean up con1 now that the XA txn has finished
--connection con1
--echo # Wait for the now unblocked DROP t1, t2 to complete
--reap
--echo # Disconnecting con1
--disconnect con1
--source include/wait_until_disconnected.inc

--echo # Switching to back to default at end of test case
--connection default

--echo #
--echo # Bug#26739438 DEADLOCK ON GET_LOCK(..., 0)
--echo #
--echo # Run GET_LOCK(...,0) from two connections to which would previously
--echo # cause deadlock

CREATE TABLE t1(i INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0), (1);

--echo # Starting con0
connect (con0,localhost,root,,test,,);
SELECT i FROM t1 WHERE i = 0 AND GET_LOCK(i, 0);

--echo # Starting con1
connect (con1,localhost,root,,test,,);
SELECT i FROM t1 WHERE i = 1 AND GET_LOCK(i, 0);

--echo # Send query which will do a 0-wait on i=0 while holding lock on i=1
SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL wait0 WAIT_FOR go0';
--send SELECT i FROM t1 WHERE GET_LOCK(i, 0) AND i = 0

--echo # Switch to con0. Send query which will do a 0-wait on i=1 while
--echo # holding lock on i=0
connection con0;
SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL wait1 WAIT_FOR go1';
--send SELECT i FROM t1 WHERE GET_LOCK(i, 0) AND i = 1

--echo # Switch to default connection and wait until both con0 and con1
--echo # are ready to check for deadlocks 
connection default;
SET DEBUG_SYNC='now WAIT_FOR wait0';
SET DEBUG_SYNC='now WAIT_FOR wait1';

--echo # Tell both connections to proceed
SET DEBUG_SYNC='now SIGNAL go0';
SET DEBUG_SYNC='now SIGNAL go1';

--echo # Wait for con0
connection con0;
--reap

--echo # Wait for con1 (should not deadlock)
connection con1;
--reap

connection default;
disconnect con0;
disconnect con1;

DROP TABLE t1;

# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

Results in

=================================================================
==30785==ERROR: AddressSanitizer: heap-use-after-free on address 0x00013ce42680 at pc 0x000105793474 bp 0x00017aed1040 sp 0x00017aed1038
READ of size 8 at 0x00013ce42680 thread T83
    #0 0x105793470 in myrocks::Rdb_transaction_impl::set_lock_timeout(int, myrocks::TABLE_TYPE) ha_rocksdb.cc:4830
    #1 0x1056eecc0 in myrocks::get_or_create_tx(THD*, myrocks::TABLE_TYPE) ha_rocksdb.cc:5870
    #2 0x105720d74 in myrocks::ha_rocksdb::external_lock(THD*, int) ha_rocksdb.cc:14032
    #3 0x10078d608 in handler::ha_external_lock(THD*, int) handler.cc:8244
    #4 0x100f939b8 in lock_external(THD*, TABLE**, unsigned int) lock.cc:402
    #5 0x100f91350 in mysql_lock_tables(THD*, TABLE**, unsigned long, unsigned int) lock.cc:338
    #6 0x10152e32c in lock_dictionary_tables(THD*, Table_ref*, unsigned int, unsigned int) sql_base.cc:7279
    #7 0x103e23450 in dd::Open_dictionary_tables_ctx::open_tables() transaction_impl.cc:123
    #8 0x104208cac in bool dd::cache::Storage_adapter::store<dd::Table>(THD*, dd::Table*) storage_adapter.cc:334
    #9 0x103eb91c4 in bool dd::cache::Dictionary_client::store<dd::Table>(dd::Table*) dictionary_client.cc:2565
    #10 0x101acbfa8 in rea_create_base_table(THD*, char const*, dd::Schema const&, char const*, char const*, HA_CREATE_INFO*, List<Create_field>&, unsigned int, KEY*, Alter_info::enum_enable_or_disable, unsigned int, FOREIGN_KEY*, Mem_root_array<Sql_check_constraint_spec*> const*, handler*, bool, bool, partition_info*, bool*, std::__1::unique_ptr<dd::Table, std::__1::default_delete<dd::Table>>*, handlerton**) sql_table.cc:1112
    #11 0x101a513cc in create_table_impl(THD*, dd::Schema const&, char const*, char const*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, bool, unsigned int, bool, bool, bool, bool*, KEY**, unsigned int*, Alter_info::enum_enable_or_disable, FOREIGN_KEY**, unsigned int*, FOREIGN_KEY*, unsigned int, dd::Table const*, unsigned int, bool, std::__1::unique_ptr<dd::Table, std::__1::default_delete<dd::Table>>*, handlerton**) sql_table.cc:8983
    #12 0x101a4e7dc in mysql_create_table_no_lock(THD*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, unsigned int, bool, bool*, handlerton**) sql_table.cc:9224
    #13 0x101a57ea4 in mysql_create_table(THD*, Table_ref*, HA_CREATE_INFO*, Alter_info*) sql_table.cc:10141
    #14 0x1016079e4 in Sql_cmd_create_table::execute(THD*) sql_cmd_ddl_table.cc:434
    #15 0x10180a328 in mysql_execute_command(THD*, bool, unsigned long long*) sql_parse.cc:4424
    #16 0x101801bd0 in dispatch_sql_command(THD*, Parser_state*, unsigned long long*) sql_parse.cc:6263
    #17 0x1017f75d4 in dispatch_command(THD*, COM_DATA const*, enum_server_command) sql_parse.cc:2544
    #18 0x1017fd0a8 in do_command(THD*) sql_parse.cc:1724
    #19 0x101e65d60 in handle_connection(void*) connection_handler_per_thread.cc:307
    #20 0x106642a18 in pfs_spawn_thread(void*) pfs.cc:3022
    #21 0x190465030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
    #22 0x19045fe38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)

0x00013ce42680 is located 0 bytes inside of 616-byte region [0x00013ce42680,0x00013ce428e8)
freed by thread T83 here:
    #0 0x120fad52c in wrap__ZdlPv+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x6152c)
    #1 0x10582c9a0 in myrocks::rocksdb_commit_by_xid(handlerton*, xid_t*) ha_rocksdb.cc:6094
    #2 0x101cbeb00 in (anonymous namespace)::commit_one_ht(THD*, st_plugin_int**, void*) tc_log.cc:189
    #3 0x10189b13c in plugin_foreach_with_mask(THD*, bool (**)(THD*, st_plugin_int**, void*), int, unsigned int, void*) sql_plugin.cc:2843
    #4 0x10189ba8c in plugin_foreach_with_mask(THD*, bool (*)(THD*, st_plugin_int**, void*), int, unsigned int, void*) sql_plugin.cc:2856
    #5 0x101cbe424 in trx_coordinator::commit_detached_by_xid(THD*, bool) tc_log.cc:115
    #6 0x101cbf4c4 in trx_coordinator::commit_in_engines(THD*, bool, bool) tc_log.cc:144
    #7 0x1036e456c in MYSQL_BIN_LOG::commit(THD*, bool) binlog.cc:10781
    #8 0x101d27728 in Sql_cmd_xa_commit::process_detached_xa_commit(THD*) sql_xa_commit.cc:211
    #9 0x101d27254 in Sql_cmd_xa_commit::trans_xa_commit(THD*) sql_xa_commit.cc:94
    #10 0x101d26fc4 in Sql_cmd_xa_commit::execute(THD*) sql_xa_commit.cc:64
    #11 0x10180a1a0 in mysql_execute_command(THD*, bool, unsigned long long*) sql_parse.cc:5489
    #12 0x101801bd0 in dispatch_sql_command(THD*, Parser_state*, unsigned long long*) sql_parse.cc:6263
    #13 0x1017f75d4 in dispatch_command(THD*, COM_DATA const*, enum_server_command) sql_parse.cc:2544
    #14 0x1017fd0a8 in do_command(THD*) sql_parse.cc:1724
    #15 0x101e65d60 in handle_connection(void*) connection_handler_per_thread.cc:307
    #16 0x106642a18 in pfs_spawn_thread(void*) pfs.cc:3022
    #17 0x190465030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
    #18 0x19045fe38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)

previously allocated by thread T83 here:
    #0 0x120fad0ec in wrap__Znwm+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x610ec)
    #1 0x1081a934c in rocksdb::WriteCommittedTxnDB::BeginTransaction(rocksdb::WriteOptions const&, rocksdb::TransactionOptions const&, rocksdb::Transaction*) pessimistic_transaction_db.cc:185
    #2 0x105797390 in myrocks::Rdb_transaction_impl::start_tx(myrocks::TABLE_TYPE) ha_rocksdb.cc:5255
    #3 0x1056eee4c in myrocks::get_or_create_tx(THD*, myrocks::TABLE_TYPE) ha_rocksdb.cc:5864
    #4 0x105720d74 in myrocks::ha_rocksdb::external_lock(THD*, int) ha_rocksdb.cc:14032
    #5 0x10078d608 in handler::ha_external_lock(THD*, int) handler.cc:8244
    #6 0x100f939b8 in lock_external(THD*, TABLE**, unsigned int) lock.cc:402
    #7 0x100f91350 in mysql_lock_tables(THD*, TABLE**, unsigned long, unsigned int) lock.cc:338
    #8 0x10152e32c in lock_dictionary_tables(THD*, Table_ref*, unsigned int, unsigned int) sql_base.cc:7279
    #9 0x103e23450 in dd::Open_dictionary_tables_ctx::open_tables() transaction_impl.cc:123
    #10 0x104208cac in bool dd::cache::Storage_adapter::store<dd::Table>(THD*, dd::Table*) storage_adapter.cc:334
    #11 0x103eb91c4 in bool dd::cache::Dictionary_client::store<dd::Table>(dd::Table*) dictionary_client.cc:2565
    #12 0x101acbfa8 in rea_create_base_table(THD*, char const*, dd::Schema const&, char const*, char const*, HA_CREATE_INFO*, List<Create_field>&, unsigned int, KEY*, Alter_info::enum_enable_or_disable, unsigned int, FOREIGN_KEY*, Mem_root_array<Sql_check_constraint_spec*> const*, handler*, bool, bool, partition_info*, bool*, std::__1::unique_ptr<dd::Table, std::__1::default_delete<dd::Table>>*, handlerton**) sql_table.cc:1112
    #13 0x101a513cc in create_table_impl(THD*, dd::Schema const&, char const*, char const*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, bool, unsigned int, bool, bool, bool, bool*, KEY**, unsigned int*, Alter_info::enum_enable_or_disable, FOREIGN_KEY**, unsigned int*, FOREIGN_KEY*, unsigned int, dd::Table const*, unsigned int, bool, std::__1::unique_ptr<dd::Table, std::__1::default_delete<dd::Table>>*, handlerton**) sql_table.cc:8983
    #14 0x101a4e7dc in mysql_create_table_no_lock(THD*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, unsigned int, bool, bool*, handlerton**) sql_table.cc:9224
    #15 0x101a57ea4 in mysql_create_table(THD*, Table_ref*, HA_CREATE_INFO*, Alter_info*) sql_table.cc:10141
    #16 0x1016079e4 in Sql_cmd_create_table::execute(THD*) sql_cmd_ddl_table.cc:434
    #17 0x10180a328 in mysql_execute_command(THD*, bool, unsigned long long*) sql_parse.cc:4424
    #18 0x101801bd0 in dispatch_sql_command(THD*, Parser_state*, unsigned long long*) sql_parse.cc:6263
    #19 0x1017f75d4 in dispatch_command(THD*, COM_DATA const*, enum_server_command) sql_parse.cc:2544
    #20 0x1017fd0a8 in do_command(THD*) sql_parse.cc:1724
    #21 0x101e65d60 in handle_connection(void*) connection_handler_per_thread.cc:307
    #22 0x106642a18 in pfs_spawn_thread(void*) pfs.cc:3022
    #23 0x190465030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
    #24 0x19045fe38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)