Merge pull request #15158 from ClickHouse/aku/rethrow-copy

Rethrow copy of exception in SSD dictionaries
This commit is contained in:
Alexander Kuzmenkov 2020-09-23 09:50:26 +03:00 committed by GitHub
commit 27036f5079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 5 deletions

View File

@ -835,7 +835,8 @@ void CacheDictionary::waitForCurrentUpdateFinish(UpdateUnitPtr & update_unit_ptr
catch (...)
{
throw DB::Exception(ErrorCodes::CACHE_DICTIONARY_UPDATE_FAIL,
"Dictionary update failed: {}",
"Update failed for dictionary '{}': {}",
getDictionaryID().getNameForLogs(),
getCurrentExceptionMessage(true /*with stack trace*/,
true /*check embedded stack trace*/));
}

View File

@ -53,6 +53,7 @@ namespace ErrorCodes
extern const int AIO_READ_ERROR;
extern const int AIO_WRITE_ERROR;
extern const int BAD_ARGUMENTS;
extern const int CACHE_DICTIONARY_UPDATE_FAIL;
extern const int CANNOT_ALLOCATE_MEMORY;
extern const int CANNOT_CREATE_DIRECTORY;
extern const int CANNOT_FSYNC;
@ -1193,9 +1194,24 @@ void SSDCacheStorage::update(DictionarySourcePtr & source_ptr, const std::vector
{
/// TODO: use old values
/// We don't have expired data for that `id` so all we can do is to rethrow `last_exception`.
// We don't have expired data for that `id` so all we can do is
// to rethrow `last_exception`. We might have to throw the same
// exception for different callers of dictGet() in different
// threads, which might then modify the exception object, so we
// have to throw a copy.
try
{
std::rethrow_exception(last_update_exception);
}
catch (...)
{
throw DB::Exception(ErrorCodes::CACHE_DICTIONARY_UPDATE_FAIL,
"Update failed for dictionary '{}': {}",
getPath(),
getCurrentExceptionMessage(true /*with stack trace*/,
true /*check embedded stack trace*/));
}
}
/// Set key
std::get<SSDCachePartition::Attribute::Container<UInt64>>(new_keys.values).push_back(id);

View File

@ -54,6 +54,7 @@ namespace ErrorCodes
extern const int AIO_READ_ERROR;
extern const int AIO_WRITE_ERROR;
extern const int BAD_ARGUMENTS;
extern const int CACHE_DICTIONARY_UPDATE_FAIL;
extern const int CANNOT_ALLOCATE_MEMORY;
extern const int CANNOT_CREATE_DIRECTORY;
extern const int CANNOT_FSYNC;
@ -1266,9 +1267,24 @@ void SSDComplexKeyCacheStorage::update(
{
/// TODO: use old values.
/// We don't have expired data for that `id` so all we can do is to rethrow `last_exception`.
// We don't have expired data for that `id` so all we can do is
// to rethrow `last_exception`. We might have to throw the same
// exception for different callers of dictGet() in different
// threads, which might then modify the exception object, so we
// have to throw a copy.
try
{
std::rethrow_exception(last_update_exception);
}
catch (...)
{
throw DB::Exception(ErrorCodes::CACHE_DICTIONARY_UPDATE_FAIL,
"Update failed for dictionary '{}': {}",
getPath(),
getCurrentExceptionMessage(true /*with stack trace*/,
true /*check embedded stack trace*/));
}
}
std::uniform_int_distribution<UInt64> distribution{lifetime.min_sec, lifetime.max_sec};
metadata.emplace_back();