[Bug] fix bug that dead lock may occur when drop tablet concurrent with tablet distribution interface (#5278)

Fix bug that dead lock may occur when drop tablet concurrent with calling tablet distribution interface.
This commit is contained in:
weizuo93
2021-02-06 23:14:43 +08:00
committed by GitHub
parent 4ce6f49c0f
commit fd7caf775c

View File

@ -1496,9 +1496,16 @@ void TabletManager::get_tablets_distribution_on_different_disks(
std::map<int64_t, std::map<DataDir*, int64_t>> &tablets_num_on_disk,
std::map<int64_t, std::map<DataDir*, std::vector<TabletSize>>> &tablets_info_on_disk) {
std::vector<DataDir*> data_dirs = StorageEngine::instance()->get_stores();
ReadLock rlock(&_partition_tablet_map_lock);
std::map<int64_t, std::set<TabletInfo>>::iterator partition_iter = _partition_tablet_map.begin();
for (; partition_iter != _partition_tablet_map.end(); partition_iter++) {
std::map<int64_t, std::set<TabletInfo>> partition_tablet_map;
{
// When drop tablet, '_partition_tablet_map_lock' is locked in 'tablet_shard_lock'.
// To avoid locking 'tablet_shard_lock' in '_partition_tablet_map_lock', we lock and
// copy _partition_tablet_map here.
ReadLock rlock(&_partition_tablet_map_lock);
partition_tablet_map = _partition_tablet_map;
}
std::map<int64_t, std::set<TabletInfo>>::iterator partition_iter = partition_tablet_map.begin();
for (; partition_iter != partition_tablet_map.end(); partition_iter++) {
std::map<DataDir*, int64_t> tablets_num;
std::map<DataDir*, std::vector<TabletSize>> tablets_info;
for(int i = 0; i < data_dirs.size(); i++) {
@ -1507,7 +1514,11 @@ void TabletManager::get_tablets_distribution_on_different_disks(
int64_t partition_id = partition_iter->first;
std::set<TabletInfo>::iterator tablet_info_iter = (partition_iter->second).begin();
for(; tablet_info_iter != (partition_iter->second).end(); tablet_info_iter++) {
// get_tablet() will hold 'tablet_shard_lock'
TabletSharedPtr tablet = get_tablet(tablet_info_iter->tablet_id, tablet_info_iter->schema_hash);
if (tablet == nullptr) {
continue;
}
DataDir* data_dir = tablet->data_dir();
size_t tablet_footprint = tablet->tablet_footprint();
tablets_num[data_dir]++;