MDEV-14843: Assertion `s_tx_list.size() == 0' failed in myrocks::Rdb_transaction::term_mutex

When the plugin is unloaded, walk the s_trx_list and delete the left over
Rdb_transaction objects.
It is responsibility of the SQL layer to make sure that the storage engine
has no open tables when the plugin is being unloaded.
This commit is contained in:
Sergei Petrunia 2018-03-26 21:22:40 +03:00
parent b3cdafcb93
commit 60438451c3
4 changed files with 77 additions and 0 deletions

View File

@ -4416,6 +4416,49 @@ static int rocksdb_done_func(void *const p) {
error = 1;
}
/*
MariaDB: When the plugin is unloaded with UNINSTALL SONAME command, some
connections may still have Rdb_transaction objects.
These objects are not genuine transactions (as SQL layer makes sure that
a plugin that is being unloaded has no open tables), they are empty
Rdb_transaction objects that were left there to save on object
creation/deletion.
Go through the list and delete them.
*/
{
class Rdb_trx_deleter: public Rdb_tx_list_walker {
public:
std::set<Rdb_transaction*> rdb_trxs;
void process_tran(const Rdb_transaction *const tx) override {
/*
Check if the transaction is really empty. We only check
non-WriteBatch-based transactions, because there is no easy way to
check WriteBatch-based transactions.
*/
if (!tx->is_writebatch_trx()) {
const auto tx_impl = static_cast<const Rdb_transaction_impl *>(tx);
DBUG_ASSERT(tx_impl);
if (tx_impl->get_rdb_trx())
DBUG_ASSERT(0);
}
rdb_trxs.insert((Rdb_transaction*)tx);
};
} deleter;
Rdb_transaction::walk_tx_list(&deleter);
for (std::set<Rdb_transaction*>::iterator it= deleter.rdb_trxs.begin();
it != deleter.rdb_trxs.end();
++it)
{
// When a transaction is deleted, it removes itself from s_tx_list.
delete *it;
}
}
/*
destructors for static objects can be called at _exit(),
but we want to free the memory at dlclose()

View File

@ -0,0 +1,12 @@
#
# MDEV-14843: Assertion `s_tx_list.size() == 0' failed in myrocks::Rdb_transaction::term_mutex
#
INSTALL SONAME 'ha_rocksdb';
CREATE TABLE t1 (i INT) ENGINE=RocksDB;
insert into t1 values (1);
connect con1,localhost,root,,;
connection con1;
insert into test.t1 values (1);
connection default;
DROP TABLE t1;
UNINSTALL SONAME 'ha_rocksdb';

View File

@ -0,0 +1 @@
--default-storage-engine=myisam --plugin-load='' --ignore-db-dirs=#rocksdb

View File

@ -0,0 +1,21 @@
--source include/have_log_bin.inc
--source include/have_binlog_format_row.inc
--echo #
--echo # MDEV-14843: Assertion `s_tx_list.size() == 0' failed in myrocks::Rdb_transaction::term_mutex
--echo #
INSTALL SONAME 'ha_rocksdb';
CREATE TABLE t1 (i INT) ENGINE=RocksDB;
insert into t1 values (1);
connect (con1,localhost,root,,);
connection con1;
insert into test.t1 values (1);
connection default;
# Cleanup
DROP TABLE t1;
UNINSTALL SONAME 'ha_rocksdb';