提交 199d8734 编写于 作者: A Alexey Milovidov

Fixed race condition in DROP/CREATE MergeTree tables [#CLICKHOUSE-3939]

上级 836bf136
......@@ -82,7 +82,6 @@ public:
~QueryScope();
};
public:
/// Implicitly finalizes current thread in the destructor
class ThreadScope
{
......
......@@ -576,9 +576,18 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
context.getSessionContext().addExternalTable(table_name, res, query_ptr);
else
database->createTable(context, table_name, res, query_ptr);
}
res->startup();
/// We must call "startup" and "shutdown" while holding DDLGuard.
/// Because otherwise method "shutdown" (from InterpreterDropQuery) can be called before startup
/// (in case when table was created and instantly dropped before started up)
///
/// Method "startup" may create background tasks and method "shutdown" will wait for them.
/// But if "shutdown" is called before "startup", it will exit early, because there are no background tasks to wait.
/// Then background task is created by "startup" method. And when destructor of a table object is called, background task is still active,
/// and the task will use references to freed data.
res->startup();
}
/// If the query is a CREATE SELECT, insert the data into the table.
if (create.select && !create.attach
......
......@@ -208,7 +208,7 @@ DatabaseAndTable InterpreterDropQuery::tryGetDatabaseAndTable(String & database_
throw Exception("Table " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(table_name) + " doesn't exist.",
ErrorCodes::UNKNOWN_TABLE);
return std::make_pair<DatabasePtr, StoragePtr>(std::move(database), std::move(table));
return {std::move(database), std::move(table)};
}
return {};
}
......
#!/usr/bin/env bash
set -e
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
. $CURDIR/../shell_config.sh
function stress()
{
while true; do
${CLICKHOUSE_CLIENT} --query "CREATE TABLE IF NOT EXISTS test.table (x UInt8) ENGINE = MergeTree ORDER BY tuple()" 2>/dev/null
${CLICKHOUSE_CLIENT} --query "DROP TABLE test.table" 2>/dev/null
done
}
# https://stackoverflow.com/questions/9954794/execute-a-shell-function-with-timeout
export -f stress
for thread in {1..5}; do
timeout 10 bash -c stress &
done
wait
echo
${CLICKHOUSE_CLIENT} --query "DROP TABLE IF EXISTS test.table";
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册