# CREATE RESOURCE POOL CLASSIFIER

CREATE RESOURCE POOL CLASSIFIER creates a resource pool classifier.

Syntax

CREATE RESOURCE POOL CLASSIFIER <name>
WITH ( <parameter_name> [= <parameter_value>] [, ... ] )
  • name тАФ the name of the resource pool classifier being created. It must be unique. The name must not contain characters prohibited for schema objects.
  • WITH ( <parameter_name> [= <parameter_value>] [, ... ] ) тАФ allows you to set parameter values that define the behavior of the resource pool classifier.

Common parameters

  • RANK (Int64) тАФ an optional field that specifies the selection order of the resource pool classifier. If the value is not specified, the maximum existing RANK is taken and 1000 is added to it. Valid values: a unique number in the range .
  • RESOURCE_POOL (String) тАФ the name of the resource pool to which requests matching the classifier's predicates are directed.
  • ACTION (Enum) тАФ the action applied to a request when the classifier matches. Allowed value тАФ reject: the request is rejected, and the user receives an error of the form Request is rejected by classifier '<name>' (rank=<rank>).

Note

The RESOURCE_POOL and ACTION parameters are mutually exclusive: exactly one of them must be specified in a classifier.

Predicate parameters

A predicate is a condition checked for an incoming request. A classifier matches if all of its predicates are satisfied (logical AND). To express OR logic, create multiple classifiers with different RANK values. Classifiers are processed in ascending order of RANK; processing stops at the first match тАФ the request has that classifier's ACTION applied or is directed to its RESOURCE_POOL.

Predicate parameters are optional. A classifier without any predicates matches any request тАФ this is useful for a "catch-all" classifier with the maximum RANK, for example, to direct all unclassified traffic to a specific pool (RESOURCE_POOL) or to reject it (ACTION='reject').

Warning

Be careful when creating a "catch-all" classifier: all classifiers following it by RANK will never fire тАФ processing stops at the first match, and the "catch-all" always matches.

List of predicates:

  • MEMBER_NAME (String) тАФ the SID of the user or group on whose behalf the request was made. See below for details.
  • HAS_PATH (String) тАФ path to a YDB object accessed by the request; supports wildcards * and ?. See below for details.
  • HAS_APP_NAME (String) тАФ client application identifier. See below for details.
  • HAS_FULL_SCAN (String) тАФ path to an object for which a full scan is expected; supports wildcards * and ?. See below for details.
  • HAS_STREAM (Bool) тАФ indicates whether the request is streaming. See below for details.

MEMBER_NAME

MEMBER_NAME is compared character by character with the user's SID or any group SID from their authentication token. The SID format depends on how the user logged into the system.

You can specify either the SID of a specific user or the SID of a group. The all-users@well-known group is automatically added to all authenticated users тАФ it is convenient when you need to direct queries from all authenticated clients to a pool.

Example. Direct requests from user user1@ldap to the olap pool:

CREATE RESOURCE POOL CLASSIFIER cl_user WITH (
    RANK=100,
    RESOURCE_POOL='olap',
    MEMBER_NAME='user1@ldap'
);

HAS_PATH

HAS_PATH compares the paths of YDB objects accessed by the request against the specified mask. The mask supports wildcards: * тАФ any sequence of characters, ? тАФ any single character. The predicate matches if at least one object in the request plan matches the mask.

Example. Direct requests to archive tables to the pool_archive pool:

CREATE RESOURCE POOL CLASSIFIER cl_archive WITH (
    RANK=700,
    RESOURCE_POOL='pool_archive',
    HAS_PATH='/Root/db/archive/*'
);

HAS_APP_NAME

HAS_APP_NAME compares the value against the client application identifier. The value is passed by the client in gRPC request metadata via the x-ydb-application-name header; YDB SDKs provide a way to set it on the client side. Comparison is exact match (no wildcards).

Warning

The HAS_APP_NAME value is set by the client and is not authenticated by the server тАФ do not use it as an access control mechanism. For effective isolation, combine it with MEMBER_NAME or direct unrecognized requests to a sandbox pool with strict limits.

Setting the application identifier on the client:

  • YDB UI — fixed value ydb-ui, set by the viewer and not user-configurable.
  • YDB CLI — not supported: the client application identifier is not sent in requests.
  • YDB C++ SDK — per request via the Header parameter of TRequestSettings: settings.Header({{ NYdb::YDB_APPLICATION_NAME, "my-app" }}), where the YDB_APPLICATION_NAME constant equals x-ydb-application-name.
  • YDB Go SDK — at the driver level via the WithApplicationName option in the ydb.Open call.
  • YDB Java SDK — at the transport level via the GrpcTransportBuilder.withApplicationName method.
  • YDB Python SDK — no dedicated parameter; the value is set per request via a generic header: settings.with_header("x-ydb-application-name", "my-app") (the BaseRequestSettings.with_header method).

Example. Direct requests from YDB UI to the pool_adhoc pool:

CREATE RESOURCE POOL CLASSIFIER cl_adhoc_ui WITH (
    RANK=200,
    RESOURCE_POOL='pool_adhoc',
    HAS_APP_NAME='ydb-ui'
);

HAS_FULL_SCAN

HAS_FULL_SCAN identifies requests that contain a full scan of the specified objects. A full scan is a table read without a key or key-range constraint. The argument is a path mask supporting wildcards * and ?; the predicate matches if there is at least one such object in the request plan. Both row-oriented and column-oriented tables are supported. Objects to which the full-scan concept does not apply (for example, topics) are not considered.

Details of full-scan detection:

  • LIMIT does not cancel a full scan. Without a key condition, the physical plan processes the entire table; LIMIT only limits the size of the result.

  • Secondary indexes. A full scan of a secondary index's implementation table is counted against its own path. For example, for the table

    CREATE TABLE orders (
        Id Uint64 NOT NULL,
        Status Utf8,
        PRIMARY KEY (Id),
        INDEX by_status GLOBAL ON (Status)
    );
    

    the index table has path /Root/orders/by_status/indexImplTable. The query SELECT * FROM orders VIEW by_status performs a full scan of the index table тАФ the main /Root/orders is not scanned. Therefore:

    • HAS_FULL_SCAN='/Root/orders' тАФ will not match;
    • HAS_FULL_SCAN='/Root/orders/by_status/indexImplTable' or HAS_FULL_SCAN='/Root/orders/*' тАФ will match.

Example. Reject requests that cause a full scan of the orders archive:

CREATE RESOURCE POOL CLASSIFIER cl_fullscan_reject WITH (
    RANK=100,
    ACTION='reject',
    HAS_FULL_SCAN='/Root/db/orders_archive/*'
);

HAS_STREAM

HAS_STREAM determines whether a request is streaming тАФ that is, performs a long-running continuous read and/or write over data streams. Allowed values:

  • true тАФ the classifier matches streaming requests;
  • false тАФ the classifier matches non-streaming requests.

Example. Direct streaming requests to the pool_stream pool:

CREATE RESOURCE POOL CLASSIFIER cl_stream WITH (
    RANK=500,
    RESOURCE_POOL='pool_stream',
    HAS_STREAM=true
);

Notes

If RANK is not specified in the DDL for creating a resource pool classifier, it will be assigned the default value . All RANK values must be unique to ensure a strictly deterministic order of resource pool selection in case of conflicting conditions. This behavior is chosen to allow adding new resource pool classifiers between existing ones.

It is also possible to have a classifier that references a non-existent resource pool or one to which the user does not have access. In that case, it is skipped.

For limitations on the number of classifiers, see the limitations page.

Permissions

The permission USE on the database is required.

Example of granting such a permission:

GRANT 'USE' ON `/my_db` TO `user1@domain`;

Examples

Below is a combined example that composes several classifiers and predicates: rejecting full scans of archive tables, isolating streaming requests, and dedicating a pool for interactive admin queries from YDB UI.

Creating resource pools:

CREATE RESOURCE POOL pool_stream WITH (
    TOTAL_CPU_LIMIT_PERCENT_PER_NODE=20
);

CREATE RESOURCE POOL pool_adhoc_admin WITH (
    TOTAL_CPU_LIMIT_PERCENT_PER_NODE=10
);

Creating classifiers:

-- Reject full scans of archive tables.
CREATE RESOURCE POOL CLASSIFIER cl_fullscan_reject WITH (
    RANK=100,
    ACTION='reject',
    HAS_FULL_SCAN='/Root/db/orders_archive/*'
);

-- Direct streaming requests to a dedicated pool.
CREATE RESOURCE POOL CLASSIFIER cl_stream WITH (
    RANK=200,
    RESOURCE_POOL='pool_stream',
    HAS_STREAM=true
);

-- Admin requests from YDB UI — into the interactive-queries pool.
-- AND condition: both MEMBER_NAME and HAS_APP_NAME must match.
CREATE RESOURCE POOL CLASSIFIER cl_adhoc_admin WITH (
    RANK=300,
    RESOURCE_POOL='pool_adhoc_admin',
    MEMBER_NAME='admin',
    HAS_APP_NAME='ydb-ui'
);

Classifiers are processed in ascending order of RANK; the first matching classifier is applied to the request. A request that does not match any classifier is directed to the default pool.

See also