> (you don't have to strictly follow this form)

**Use case**

Sometimes, for really sophisticated scenarios it can be hard to control the amount of in-progress backups run externally. For the purpose of simpler control we can introduce server-level setting which disallows running concurrent backups of any type. 

Something like this in `config.xml` (enabled by default):
`<allow_concurrent_backups>true</allow_concurrent_backups>`

**Describe the solution you'd like**

It's important that backups can be executed in distributed way on multiple servers. Need to take it into account.

**Describe alternatives you've considered**
External check of `system.backups` table, but it can be complex.

ErrorCodes::CANNOT_PARSE_BACKUP_SETTINGS,
                        "Setting cluster_host_ids has wrong format, must be array of arrays of string literals");
                res[i][j] = replica.get<const String &>();
            }
        }
    }
    return res;
}
ASTPtr BackupSettings::Util::clusterHostIDsToAST(const std::vector<Strings> & cluster_host_ids)
{
    if (cluster_host_ids.empty())
        return nullptr;
    auto res = std::make_shared<ASTFunction>();
    res->name = "array";
    auto res_replicas = std::make_shared<ASTExpressionList>();
    res->arguments = res_replicas;
    res->children.push_back(res_replicas);
    res_replicas->children.resize(cluster_host_ids.size());
    for (size_t i = 0; i != cluster_host_ids.size(); ++i)
    {
        const auto & shard = cluster_host_ids[i];
        Array res_shard;
        res_shard.resize(shard.size());
        for (size_t j = 0; j != shard.size(); ++j)
            res_shard[j] = Field{shard[j]};
        res_replicas->children[i] = std::make_shared<ASTLiteral>(Field{std::move(res_shard)});
    }
    return res;
}
std::pair<size_t, size_t> BackupSettings::Util::findShardNumAndReplicaNum(const std::vector<Strings> & cluster_host_ids, const String & host_id)