Fix race condition, add test

This commit is contained in:
alesapin 2019-10-17 20:36:53 +03:00
parent 05392fd882
commit c29b39002d
3 changed files with 111 additions and 3 deletions

View File

@ -770,6 +770,10 @@ private:
if (!new_object && !new_exception)
throw Exception("No object created and no exception raised for " + type_name, ErrorCodes::LOGICAL_ERROR);
/// Lock the mutex again to store the changes.
if (async)
lock.lock();
/// Calculate a new update time.
TimePoint next_update_time;
try
@ -778,6 +782,7 @@ private:
++error_count;
else
error_count = 0;
next_update_time = calculateNextUpdateTime(new_object, error_count);
}
catch (...)
@ -786,9 +791,6 @@ private:
next_update_time = TimePoint::max();
}
/// Lock the mutex again to store the changes.
if (async)
lock.lock();
info = getInfo(name);
/// And again we should check if this is still the same loading as we were doing.

View File

@ -0,0 +1,8 @@
100
100
200
200
200
300
300
300

View File

@ -0,0 +1,98 @@
SET send_logs_level = 'none';
DROP DATABASE IF EXISTS database_for_dict;
CREATE DATABASE database_for_dict Engine = Ordinary;
CREATE TABLE database_for_dict.table_for_dict
(
key_column UInt64,
second_column UInt8,
third_column String,
fourth_column Float64
)
ENGINE = MergeTree()
ORDER BY key_column;
INSERT INTO database_for_dict.table_for_dict SELECT number, number % 17, toString(number * number), number / 2.0 from numbers(100);
DROP DICTIONARY IF EXISTS database_for_dict.dict1;
CREATE DICTIONARY database_for_dict.dict1
(
key_column UInt64 DEFAULT 0,
second_column UInt8 DEFAULT 1,
third_column String DEFAULT 'qqq',
fourth_column Float64 DEFAULT 42.0
)
PRIMARY KEY key_column
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict' DB 'database_for_dict'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(FLAT());
SELECT count(*) from database_for_dict.dict1;
CREATE DICTIONARY database_for_dict.dict2
(
key_column UInt64 DEFAULT 0,
second_column UInt8 DEFAULT 1,
third_column String DEFAULT 'qqq',
fourth_column Float64 DEFAULT 42.0
)
PRIMARY KEY key_column
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict1' DB 'database_for_dict'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(HASHED());
SELECT count(*) FROM database_for_dict.dict2;
INSERT INTO database_for_dict.table_for_dict SELECT number, number % 17, toString(number * number), number / 2.0 from numbers(100, 100);
SYSTEM RELOAD DICTIONARIES;
SELECT count(*) from database_for_dict.dict2;
SELECT count(*) from database_for_dict.dict1;
CREATE DICTIONARY database_for_dict.dict3
(
key_column UInt64 DEFAULT 0,
second_column UInt8 DEFAULT 1,
third_column String DEFAULT 'qqq',
fourth_column Float64 DEFAULT 42.0
)
PRIMARY KEY key_column
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict2' DB 'database_for_dict'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(HASHED());
SELECT count(*) FROM database_for_dict.dict3;
INSERT INTO database_for_dict.table_for_dict SELECT number, number % 17, toString(number * number), number / 2.0 from numbers(200, 100);
SYSTEM RELOAD DICTIONARIES;
SELECT count(*) from database_for_dict.dict3;
SELECT count(*) from database_for_dict.dict2;
SELECT count(*) from database_for_dict.dict1;
CREATE DICTIONARY database_for_dict.dict4
(
key_column UInt64 DEFAULT 0,
second_column UInt8 DEFAULT 1,
third_column String DEFAULT 'qqq',
fourth_column Float64 DEFAULT 42.0
)
PRIMARY KEY key_column
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'non_existing_table' DB 'database_for_dict'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(HASHED());
SELECT count(*) FROM database_for_dict.dict4; -- {serverError 60}
DROP DATABASE IF EXISTS database_for_dict;
SELECT count(*) from database_for_dict.dict3; --{serverError 81}
SELECT count(*) from database_for_dict.dict2; --{serverError 81}
SELECT count(*) from database_for_dict.dict1; --{serverError 81}