Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the bug that some decoding is not protected by alter_lock #1945

Merged
merged 1 commit into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dbms/src/Storages/Transaction/ApplySnapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void KVStore::onSnapshot(const RegionPtrWrap & new_region_wrap, RegionPtr old_re
try
{
auto & context = tmt.getContext();
// Acquire lock so that no other threads can drop storage
// Acquire `drop_lock` so that no other threads can drop the storage. `alter_lock` is not required.
auto table_lock = storage->lockForShare(getThreadName());
auto dm_storage = std::dynamic_pointer_cast<StorageDeltaMerge>(storage);
auto key_range = DM::RowKeyRange::fromRegionRange(
Expand Down Expand Up @@ -583,13 +583,13 @@ RegionPtr KVStore::handleIngestSSTByDTFile(const RegionPtr & region, const SSTVi
auto & context = tmt.getContext();
try
{
// Acquire lock so that no other threads can drop storage
// Acquire `drop_lock` so that no other threads can drop the storage. `alter_lock` is not required.
auto table_lock = storage->lockForShare(getThreadName());
auto dm_storage = std::dynamic_pointer_cast<StorageDeltaMerge>(storage);
auto key_range = DM::RowKeyRange::fromRegionRange(
region->getRange(), table_id, storage->isCommonHandle(), storage->getRowKeyColumnSize());
// Call `ingestFiles` to ingest external DTFiles.
// Note that ingest sst won't remove the data in the key range
auto dm_storage = std::dynamic_pointer_cast<StorageDeltaMerge>(storage);
dm_storage->ingestFiles(key_range, ingest_ids, /*clear_data_in_range=*/false, context.getSettingsRef());
}
catch (DB::Exception & e)
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Storages/Transaction/KVStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void KVStore::tryFlushRegionCacheInStorage(TMTContext & tmt, const Region & regi

try
{
// Try to get a read lock on `storage` so it won't be dropped during `flushCache`
// Acquire `drop_lock` so that no other threads can drop the storage during `flushCache`. `alter_lock` is not required.
auto storage_lock = storage->lockForShare(getThreadName());
auto rowkey_range = DM::RowKeyRange::fromRegionRange(
region.getRange(), region.getRange()->getMappedTableID(), storage->isCommonHandle(), storage->getRowKeyColumnSize());
Expand Down
14 changes: 9 additions & 5 deletions dbms/src/Storages/Transaction/PartitionStreams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ static void writeRegionDataToStorage(
return true;
}

/// Lock throughout decode and write, during which schema must not change.
/// Get a structure read lock throughout decode, during which schema must not change.
TableStructureLockHolder lock;
try
{
lock = storage->lockStructureForShare(getThreadName());
}
catch (DB::Exception & e)
{
// If the storage is physical dropped (but not removed from `ManagedStorages`) when we want to flsuh raft data into it, consider the write done.
// If the storage is physical dropped (but not removed from `ManagedStorages`) when we want to write raft data into it, consider the write done.
if (e.code() == ErrorCodes::TABLE_IS_DROPPED)
return true;
else
Expand Down Expand Up @@ -439,7 +439,7 @@ RegionPtrWithBlock::CachePtr GenRegionPreDecodeBlockData(const RegionPtr & regio
return true;
}

/// Lock throughout decode and write, during which schema must not change.
/// Get a structure read lock throughout decode, during which schema must not change.
TableStructureLockHolder lock;
try
{
Expand Down Expand Up @@ -502,7 +502,9 @@ AtomicGetStorageSchema(const RegionPtr & region, TMTContext & tmt)
if (storage == nullptr) // Table must have just been GC-ed
return true;
}
auto table_lock = storage->lockForShare(getThreadName());
// Get a structure read lock. It will throw exception if the table has been dropped,
// the caller should handle this situation.
auto table_lock = storage->lockStructureForShare(getThreadName());
is_common_handle = storage->isCommonHandle();
if (unlikely(storage->engineType() != ::TiDB::StorageEngine::DT))
{
Expand Down Expand Up @@ -611,7 +613,9 @@ Block GenRegionBlockDatawithSchema(const RegionPtr & region,

{
Stopwatch watch;
auto table_lock = dm_storage->lockForShare(getThreadName());
// Get a structure read lock. It will throw exception if the table has been
// dropped, the caller should handle this situation.
auto table_lock = dm_storage->lockStructureForShare(getThreadName());
// Compare schema_snap with current schema, throw exception if changed.
auto store = dm_storage->getStore();
auto cur_schema_snap = store->getStoreColumns();
Expand Down
5 changes: 2 additions & 3 deletions dbms/src/Storages/Transaction/RegionTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ void removeObsoleteDataInStorage(

try
{
// acquire a read lock so that no other threads can drop the `storage`
// if storage is already dropped, this will throw exception
// Acquire a `drop_lock` so that no other threads can drop the `storage`
auto storage_lock = storage->lockForShare(getThreadName());

auto dm_storage = std::dynamic_pointer_cast<StorageDeltaMerge>(storage);
Expand All @@ -254,7 +253,7 @@ void removeObsoleteDataInStorage(
}
catch (DB::Exception & e)
{
// We can ignore if storage is already dropped.
// We can ignore if the storage is already dropped.
if (e.code() != ErrorCodes::TABLE_IS_DROPPED)
throw;
}
Expand Down