Merge pull request #43161 from AlfVII/fix-race-condition-between-inserts-and-dropping-mvs

Fixed race condition between inserts and dropping MVs
This commit is contained in:
Kruglov Pavel 2022-12-12 13:53:36 +01:00 committed by GitHub
commit d8d7385e68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 3 deletions

View File

@ -255,7 +255,14 @@ Chain buildPushingToViewsChain(
for (const auto & view_id : views)
{
auto view = DatabaseCatalog::instance().getTable(view_id, context);
auto view = DatabaseCatalog::instance().tryGetTable(view_id, context);
if (view == nullptr)
{
LOG_WARNING(
&Poco::Logger::get("PushingToViews"), "Trying to access table {} but it doesn't exist", view_id.getFullTableName());
continue;
}
auto view_metadata_snapshot = view->getInMemoryMetadataPtr();
ASTPtr query;
@ -299,8 +306,19 @@ Chain buildPushingToViewsChain(
if (auto * materialized_view = dynamic_cast<StorageMaterializedView *>(view.get()))
{
auto lock = materialized_view->tryLockForShare(context->getInitialQueryId(), context->getSettingsRef().lock_acquire_timeout);
if (lock == nullptr)
{
// In case the materialized view is dropped at this point, we register a warning and ignore it
assert(materialized_view->is_dropped);
LOG_WARNING(
&Poco::Logger::get("PushingToViews"), "Trying to access table {} but it doesn't exist", view_id.getFullTableName());
continue;
}
type = QueryViewsLogElement::ViewType::MATERIALIZED;
result_chain.addTableLock(materialized_view->lockForShare(context->getInitialQueryId(), context->getSettingsRef().lock_acquire_timeout));
result_chain.addTableLock(lock);
StoragePtr inner_table = materialized_view->getTargetTable();
auto inner_table_id = inner_table->getStorageID();
@ -371,7 +389,7 @@ Chain buildPushingToViewsChain(
}
}
if (views_data)
if (views_data && !views_data->views.empty())
{
size_t num_views = views_data->views.size();
const Settings & settings = context->getSettingsRef();

View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Tags: no-random-settings, no-fasttest, long
set -e
CLICKHOUSE_CLIENT_SERVER_LOGS_LEVEL="error"
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
function insert {
i=0
offset=500
while true;
do
${CLICKHOUSE_CLIENT} -q "INSERT INTO test_race_condition_landing SELECT number, toString(number), toString(number) from system.numbers limit $i, $offset"
i=$(( $i + $RANDOM % 100 + 400 ))
done
}
function drop_mv {
index=$1
while true;
do
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_mv_$index"
${CLICKHOUSE_CLIENT} -q "CREATE MATERIALIZED VIEW IF NOT EXISTS test_race_condition_mv1_$index TO test_race_condition_target AS select count() as number FROM (SELECT a.number, a.n, a.n2, b.number, b.n, b.n2, c.number, c.n, c.n2 FROM test_race_condition_landing a CROSS JOIN test_race_condition_landing b CROSS JOIN test_race_condition_landing c)"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_mv1_$index"
${CLICKHOUSE_CLIENT} -q "CREATE MATERIALIZED VIEW IF NOT EXISTS test_race_condition_mv_$index TO test_race_condition_target AS select count() as number FROM (SELECT a.number, a.n, a.n2, b.number, b.n, b.n2, c.number, c.n, c.n2 FROM test_race_condition_landing a CROSS JOIN test_race_condition_landing b CROSS JOIN test_race_condition_landing c)"
done
}
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_target"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_landing"
${CLICKHOUSE_CLIENT} -q "CREATE TABLE test_race_condition_target (number Int64) Engine=MergeTree ORDER BY number"
${CLICKHOUSE_CLIENT} -q "CREATE TABLE test_race_condition_landing (number Int64, n String, n2 String) Engine=MergeTree ORDER BY number"
export -f drop_mv;
export -f insert;
TIMEOUT=55
for i in {1..4}
do
timeout $TIMEOUT bash -c drop_mv $i &
done
for i in {1..4}
do
timeout $TIMEOUT bash -c insert 20 &
done
wait
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_target"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_landing"
for i in {1..4}
do
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_mv_$i"
${CLICKHOUSE_CLIENT} -q "DROP TABLE IF EXISTS test_race_condition_mv1_$i"
done
echo "PASSED"