mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-01 20:12:02 +00:00
97f2a2213e
* Move some code outside dbms/src folder * Fix paths
140 lines
5.1 KiB
C++
140 lines
5.1 KiB
C++
#pragma once
|
|
|
|
#include <Access/IAccessEntity.h>
|
|
#include <Access/ExtendedRoleSet.h>
|
|
#include <chrono>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
/** Quota for resources consumption for specific interval.
|
|
* Used to limit resource usage by user.
|
|
* Quota is applied "softly" - could be slightly exceed, because it is checked usually only on each block of processed data.
|
|
* Accumulated values are not persisted and are lost on server restart.
|
|
* Quota is local to server,
|
|
* but for distributed queries, accumulated values for read rows and bytes
|
|
* are collected from all participating servers and accumulated locally.
|
|
*/
|
|
struct Quota : public IAccessEntity
|
|
{
|
|
enum ResourceType
|
|
{
|
|
QUERIES, /// Number of queries.
|
|
ERRORS, /// Number of queries with exceptions.
|
|
RESULT_ROWS, /// Number of rows returned as result.
|
|
RESULT_BYTES, /// Number of bytes returned as result.
|
|
READ_ROWS, /// Number of rows read from tables.
|
|
READ_BYTES, /// Number of bytes read from tables.
|
|
EXECUTION_TIME, /// Total amount of query execution time in nanoseconds.
|
|
};
|
|
static constexpr size_t MAX_RESOURCE_TYPE = 7;
|
|
|
|
using ResourceAmount = UInt64;
|
|
static constexpr ResourceAmount UNLIMITED = 0; /// 0 means unlimited.
|
|
|
|
/// Amount of resources available to consume for each duration.
|
|
struct Limits
|
|
{
|
|
ResourceAmount max[MAX_RESOURCE_TYPE];
|
|
std::chrono::seconds duration = std::chrono::seconds::zero();
|
|
|
|
/// Intervals can be randomized (to avoid DoS if intervals for many users end at one time).
|
|
bool randomize_interval = false;
|
|
|
|
Limits();
|
|
friend bool operator ==(const Limits & lhs, const Limits & rhs);
|
|
friend bool operator !=(const Limits & lhs, const Limits & rhs) { return !(lhs == rhs); }
|
|
};
|
|
|
|
std::vector<Limits> all_limits;
|
|
|
|
/// Key to share quota consumption.
|
|
/// Users with the same key share the same amount of resource.
|
|
enum class KeyType
|
|
{
|
|
NONE, /// All users share the same quota.
|
|
USER_NAME, /// Connections with the same user name share the same quota.
|
|
IP_ADDRESS, /// Connections from the same IP share the same quota.
|
|
CLIENT_KEY, /// Client should explicitly supply a key to use.
|
|
CLIENT_KEY_OR_USER_NAME, /// Same as CLIENT_KEY, but use USER_NAME if the client doesn't supply a key.
|
|
CLIENT_KEY_OR_IP_ADDRESS, /// Same as CLIENT_KEY, but use IP_ADDRESS if the client doesn't supply a key.
|
|
};
|
|
static constexpr size_t MAX_KEY_TYPE = 6;
|
|
KeyType key_type = KeyType::NONE;
|
|
|
|
/// Which roles or users should use this quota.
|
|
ExtendedRoleSet to_roles;
|
|
|
|
bool equal(const IAccessEntity & other) const override;
|
|
std::shared_ptr<IAccessEntity> clone() const override { return cloneImpl<Quota>(); }
|
|
|
|
static const char * getNameOfResourceType(ResourceType resource_type);
|
|
static const char * resourceTypeToKeyword(ResourceType resource_type);
|
|
static const char * resourceTypeToColumnName(ResourceType resource_type);
|
|
static const char * getNameOfKeyType(KeyType key_type);
|
|
static double executionTimeToSeconds(ResourceAmount ns);
|
|
static ResourceAmount secondsToExecutionTime(double s);
|
|
};
|
|
|
|
|
|
inline const char * Quota::getNameOfResourceType(ResourceType resource_type)
|
|
{
|
|
switch (resource_type)
|
|
{
|
|
case Quota::QUERIES: return "queries";
|
|
case Quota::ERRORS: return "errors";
|
|
case Quota::RESULT_ROWS: return "result rows";
|
|
case Quota::RESULT_BYTES: return "result bytes";
|
|
case Quota::READ_ROWS: return "read rows";
|
|
case Quota::READ_BYTES: return "read bytes";
|
|
case Quota::EXECUTION_TIME: return "execution time";
|
|
}
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
|
|
inline const char * Quota::resourceTypeToKeyword(ResourceType resource_type)
|
|
{
|
|
switch (resource_type)
|
|
{
|
|
case Quota::QUERIES: return "QUERIES";
|
|
case Quota::ERRORS: return "ERRORS";
|
|
case Quota::RESULT_ROWS: return "RESULT ROWS";
|
|
case Quota::RESULT_BYTES: return "RESULT BYTES";
|
|
case Quota::READ_ROWS: return "READ ROWS";
|
|
case Quota::READ_BYTES: return "READ BYTES";
|
|
case Quota::EXECUTION_TIME: return "EXECUTION TIME";
|
|
}
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
|
|
inline const char * Quota::getNameOfKeyType(KeyType key_type)
|
|
{
|
|
switch (key_type)
|
|
{
|
|
case KeyType::NONE: return "none";
|
|
case KeyType::USER_NAME: return "user name";
|
|
case KeyType::IP_ADDRESS: return "ip address";
|
|
case KeyType::CLIENT_KEY: return "client key";
|
|
case KeyType::CLIENT_KEY_OR_USER_NAME: return "client key or user name";
|
|
case KeyType::CLIENT_KEY_OR_IP_ADDRESS: return "client key or ip address";
|
|
}
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
|
|
inline double Quota::executionTimeToSeconds(ResourceAmount ns)
|
|
{
|
|
return std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::nanoseconds{ns}).count();
|
|
}
|
|
|
|
inline Quota::ResourceAmount Quota::secondsToExecutionTime(double s)
|
|
{
|
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(s)).count();
|
|
}
|
|
|
|
|
|
using QuotaPtr = std::shared_ptr<const Quota>;
|
|
}
|