Merge pull request #10209 from ClickHouse/akz/fix_segfault_in_system_tables

Fix N.P. segfault in StorageSystemTables for database engine "Lazy"
This commit is contained in:
alexey-milovidov 2020-04-13 16:33:27 +03:00 committed by GitHub
commit 396360cd90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 9 deletions

View File

@ -239,20 +239,25 @@ protected:
StoragePtr table = nullptr;
TableStructureReadLockHolder lock;
try
if (need_lock_structure)
{
if (need_lock_structure)
table = tables_it->table();
if (table == nullptr)
{
// Table might have just been removed or detached for Lazy engine (see DatabaseLazy::tryGetTable())
continue;
}
try
{
table = tables_it->table();
lock = table->lockStructureForShare(
false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout);
}
}
catch (const Exception & e)
{
if (e.code() == ErrorCodes::TABLE_IS_DROPPED)
continue;
throw;
catch (const Exception & e)
{
if (e.code() == ErrorCodes::TABLE_IS_DROPPED)
continue;
throw;
}
}
++rows_count;

View File

@ -0,0 +1,109 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
. $CURDIR/../shell_config.sh
export CURR_DATABASE="test_lazy_01014_concurrent_${CLICKHOUSE_DATABASE}"
function recreate_lazy_func1()
{
$CLICKHOUSE_CLIENT -q "
CREATE TABLE $CURR_DATABASE.log (a UInt64, b UInt64) ENGINE = Log;
";
while true; do
$CLICKHOUSE_CLIENT -q "
DETACH TABLE $CURR_DATABASE.log;
";
$CLICKHOUSE_CLIENT -q "
ATTACH TABLE $CURR_DATABASE.log;
";
done
}
function recreate_lazy_func2()
{
while true; do
$CLICKHOUSE_CLIENT -q "
CREATE TABLE $CURR_DATABASE.tlog (a UInt64, b UInt64) ENGINE = TinyLog;
";
$CLICKHOUSE_CLIENT -q "
DROP TABLE $CURR_DATABASE.tlog;
";
done
}
function recreate_lazy_func3()
{
$CLICKHOUSE_CLIENT -q "
CREATE TABLE $CURR_DATABASE.slog (a UInt64, b UInt64) ENGINE = StripeLog;
";
while true; do
$CLICKHOUSE_CLIENT -q "
ATTACH TABLE $CURR_DATABASE.slog;
";
$CLICKHOUSE_CLIENT -q "
DETACH TABLE $CURR_DATABASE.slog;
";
done
}
function recreate_lazy_func4()
{
while true; do
$CLICKHOUSE_CLIENT -q "
CREATE TABLE $CURR_DATABASE.tlog2 (a UInt64, b UInt64) ENGINE = TinyLog;
";
$CLICKHOUSE_CLIENT -q "
DROP TABLE $CURR_DATABASE.tlog2;
";
done
}
function show_tables_func()
{
while true; do
$CLICKHOUSE_CLIENT -q "SELECT * FROM system.tables WHERE database = '$CURR_DATABASE' FORMAT Null";
done
}
export -f recreate_lazy_func1;
export -f recreate_lazy_func2;
export -f recreate_lazy_func3;
export -f recreate_lazy_func4;
export -f show_tables_func;
${CLICKHOUSE_CLIENT} -n -q "
DROP DATABASE IF EXISTS $CURR_DATABASE;
CREATE DATABASE $CURR_DATABASE ENGINE = Lazy(1);
"
TIMEOUT=30
timeout $TIMEOUT bash -c recreate_lazy_func1 2> /dev/null &
timeout $TIMEOUT bash -c recreate_lazy_func2 2> /dev/null &
timeout $TIMEOUT bash -c recreate_lazy_func3 2> /dev/null &
timeout $TIMEOUT bash -c recreate_lazy_func4 2> /dev/null &
timeout $TIMEOUT bash -c show_tables_func 2> /dev/null &
wait
sleep 1
${CLICKHOUSE_CLIENT} -n -q "
DROP TABLE IF EXISTS $CURR_DATABASE.log;
DROP TABLE IF EXISTS $CURR_DATABASE.slog;
DROP TABLE IF EXISTS $CURR_DATABASE.tlog;
DROP TABLE IF EXISTS $CURR_DATABASE.tlog2;
"
# DROP DATABASE $CURR_DATABASE; -- This fails for some reason
echo "Test OK"