MDEV-29273 Race condition between drop table and closing of table

- This issue caused by race condition between drop thread
and fil_encrypt_thread. fil_encrypt_thread closes
the tablespace if the number of opened files
exceeds innodb_open_files. fil_node_open_file()
closes the tablespace which are open and it doesn't
have pending operations. At that time, InnoDB drop tries
to write the redo log for the file delete operation.
It throws the bad file descriptor error.

- When trying to close the file, InnoDB should check
whether the table is going to be dropped.
parent a091d6ac
......@@ -100,7 +100,13 @@ bool fil_space_t::try_to_close(bool print_info)
if (!node->is_open())
continue;
if (const auto n= space.set_closing())
/* Other thread is trying to do fil_delete_tablespace()
concurrently for the same tablespace. So ignore this
tablespace and try to close the other one */
const auto n= space.set_closing();
if (n & STOPPING)
continue;
if (n & (PENDING | NEEDS_FSYNC))
{
if (!print_info)
continue;
......@@ -1372,7 +1378,10 @@ void fil_space_t::close_all()
for (ulint count= 10000; count--;)
{
if (!space.set_closing())
const auto n= space.set_closing();
if (n & STOPPING)
goto next;
if (!(n & (PENDING | NEEDS_FSYNC)))
{
node->close();
goto next;
......
......@@ -628,8 +628,7 @@ struct fil_space_t final
@return number of pending operations, possibly with NEEDS_FSYNC flag */
uint32_t set_closing()
{
return n_pending.fetch_or(CLOSING, std::memory_order_acquire) &
(PENDING | NEEDS_FSYNC);
return n_pending.fetch_or(CLOSING, std::memory_order_acquire);
}
public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment