Sirin¶
В данном разделе приведены сведения о Sirin, плагине для СУБД Picodata.
Picodata Enterprise
Функциональность плагина доступна только в коммерческой версии Picodata.
Введение¶
Sirin реализует поддержку API Apache Cassandra (CQL и протокол Cassandra v4) поверх резидентной СУБД Picodata. Sirin позволяет использовать приложения и драйверы из экосистемы Cassandra без изменений, сохраняя при этом производительность и отказоустойчивость Picodata, что упрощает миграцию и интеграцию.
Совместимость и ограничения¶
Таблица совместимости¶
| Возможность Cassandra | Статус в Sirin |
|---|---|
| CQL (основные операторы) | ✅ Поддерживается |
| Prepared statements | ✅ Поддерживается |
| Named parameter markers | ✅ Поддерживается |
| Pagination | ✅ Поддерживается |
| TTL | ✅ Поддерживаются |
| Static columns | ✅ Поддерживаются |
| LIMIT в SELECT | ✅ Поддерживается |
| Телеметрия | ✅ Поддерживается |
| Инструменты (cqlsh, DBeaver, picodata admin) | ✅ Поддерживается |
| BATCH | ✅ Поддерживается |
| Управление ролями и правами (CREATE/ALTER/DROP ROLE, GRANT, REVOKE) | ✅ Поддерживается |
| Lightweight transactions (LWT) | 🟡 Частично |
| User-defined types (UDT) | ❌ Не поддерживаются |
| Материализованные представления (MV) | ❌ Не поддерживаются |
| GROUP BY | ❌ Не поддерживается |
| ALTER TABLE | ❌ Не поддерживается |
Ограничения¶
CREATE KEYSPACEиDROP KEYSPACEподдерживаются синтаксически, но параметры replication_strategy и replication_factor игнорируются. Настройки берутся из конфигурации Picodata- репликация управляется средствами Picodata
- движок хранения по умолчанию — vinyl. Все настройки vinyl влияют на характеристики хранения
- материализованные представления (MV) отсутствуют
- UDT (User-Defined Type) и вложенные коллекции отсутствуют
Типы данных¶
Sirin поддерживает основные типы данных Cassandra. Ниже приведены поддерживаемые типы, их допустимый диапазон значений и формат литералов в CQL.
Числовые типы¶
| Тип | Описание | Диапазон |
|---|---|---|
tinyint |
8-битное целое со знаком | от -128 до 127 |
smallint |
16-битное целое со знаком | от -32 768 до 32 767 |
int |
32-битное целое со знаком | от -2 147 483 648 до 2 147 483 647 |
bigint |
64-битное целое со знаком | от -2^63 до 2^63 - 1 |
float |
32-битное число с плавающей точкой (IEEE 754) | ≈ ±3.4 × 10^38 |
double |
64-битное число с плавающей точкой (IEEE 754) | ≈ ±1.8 × 10^308 |
counter |
64-битный атомарный счётчик; поддерживает только операции + и - |
от -2^63 до 2^63 - 1 |
Строковые и бинарные типы¶
| Тип | Описание |
|---|---|
text, varchar |
UTF-8 строка произвольной длины. text и varchar являются синонимами. |
ascii |
Строка, содержащая только символы US-ASCII. |
blob |
Произвольные двоичные данные. В CQL записываются в hex-формате: 0x<hex>. |
Временны́е типы¶
| Тип | Описание | Формат литерала |
|---|---|---|
timestamp |
Момент времени с точностью до миллисекунды (UTC). | '2024-01-15 10:30:00+0000' или '2024-01-15T10:30:00Z' |
date |
Календарная дата без времени. | '2024-01-15' |
time |
Время суток с точностью до наносекунды. | '10:30:00.000000000' |
Типы UUID¶
Тип |
Описание | Формат литерала |
|---|---|---|
uuid |
UUID версии 4, случайный. | 123e4567-e89b-12d3-a456-426614174000 |
timeuuid |
UUID версии 1, включающий временну́ю метку. Уникален даже при одинаковом времени. Используется для временны́х рядов. | 123e4567-e89b-12d3-a456-426614174000 |
Сетевые типы¶
| Тип | Описание | Пример |
|---|---|---|
inet |
IP-адрес IPv4 или IPv6 в текстовом представлении. Резолвинг имён хостов не поддерживается. | '192.168.1.1', '::1' |
Булев тип¶
| Тип | Описание |
|---|---|
boolean |
Логическое значение: true или false. |
Коллекции¶
Коллекции позволяют хранить несколько значений в одном столбце. Вложенные коллекции не поддерживаются.
| Тип | Описание | Пример литерала |
|---|---|---|
map<K, V> |
Набор пар ключ-значение. Ключи уникальны. | {'key1': 1, 'key2': 2} |
set<T> |
Неупорядоченный набор уникальных значений. | {1, 2, 3} |
Ограничения коллекций
Вложенные коллекции и frozen<> не поддерживаются.
Поддерживаемые возможности CQL¶
Определение схемы (DDL)¶
CREATE KEYSPACE¶
Создаёт пространство имён — логический контейнер для таблиц. Параметры репликации принимаются синтаксически для совместимости с Cassandra, но не применяются: репликацией управляет Picodata.
<create-keyspace-stmt> ::= CREATE KEYSPACE [IF NOT EXISTS] <ks-name>
WITH REPLICATION = <map-literal>
[AND DURABLE_WRITES = <boolean>]
IF NOT EXISTS— не возвращает ошибку, если пространство имён уже существуетreplication_strategyиreplication_factorигнорируютсяdurable_writesигнорируется; запись всегда производится в журнал фиксации
Пример:
CREATE KEYSPACE IF NOT EXISTS mykeyspace
WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': '1'};
DROP KEYSPACE¶
Удаляет пространство имён и все его таблицы.
<drop-keyspace-stmt> ::= DROP KEYSPACE [IF EXISTS] <ks-name>
IF EXISTS— не возвращает ошибку, если пространство имён не существует
Пример:
DROP KEYSPACE IF EXISTS mykeyspace;
CREATE TABLE¶
Создаёт таблицу в указанном пространстве имён.
Каждая таблица должна иметь первичный ключ, состоящий из двух частей:
- Partition key — определяет, на каком узле хранится строка. Может быть составным. Все строки с одинаковым partition key хранятся физически рядом.
- Clustering key — определяет порядок строк внутри partition. Необязателен.
-- Простой первичный ключ (только partition key)
PRIMARY KEY (user_id)
-- Составной первичный ключ (partition key + clustering key)
PRIMARY KEY (device_id, event_time)
-- Составной partition key
PRIMARY KEY ((country, city), user_id)
<create-table-stmt> ::= CREATE TABLE [IF NOT EXISTS] <table-name>
'(' <column-definitions> ',' <primary-key> ')'
[WITH <table-options>]
<table-options> ::= <table-option> [AND <table-option>]*
<table-option> ::= CLUSTERING ORDER BY '(' <clustering-order> [',' <clustering-order>]* ')'
| default_time_to_live '=' <integer>
| COMMENT '=' <string>
| <other-cassandra-option>
Поддерживаемые параметры таблицы:
| Параметр | Описание |
|---|---|
CLUSTERING ORDER BY |
Задаёт порядок сортировки для столбцов кластеризующего ключа. По умолчанию — ASC. |
default_time_to_live |
Время жизни строк в секундах. Значение 0 означает, что строки не удаляются автоматически. Если задано, применяется к каждой вставляемой строке, если явное значение TTL не указано в самом запросе INSERT. |
Остальные параметры Cassandra (compaction, compression, gc_grace_seconds, caching и т. д.) принимаются синтаксически для обеспечения совместимости, но не применяются.
Примеры:
CREATE TABLE users (
user_id uuid,
email text,
name text,
PRIMARY KEY (user_id)
);
CREATE TABLE events (
device_id uuid,
event_time timestamp,
payload text,
PRIMARY KEY (device_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC)
AND default_time_to_live = 86400;
ALTER TABLE¶
На данный момент не поддерживается.
DROP TABLE¶
Удаляет таблицу и все её данные.
<drop-table-stmt> ::= DROP TABLE [IF EXISTS] [<keyspace-name> '.'] <table-name>
IF EXISTS— не возвращает ошибку, если таблица не существует
Пример:
DROP TABLE IF EXISTS mykeyspace.events;
TRUNCATE TABLE¶
Удаляет все строки из таблицы, сохраняя её схему.
<truncate-stmt> ::= TRUNCATE [TABLE] [<keyspace-name> '.'] <table-name>
Пример:
TRUNCATE TABLE mykeyspace.events;
Операции с данными (DML)¶
INSERT¶
Вставляет строку в таблицу. Если строка с таким первичным ключом уже существует, она
полностью заменяется (upsert-семантика): незаданные столбцы получают значение null.
Должны быть указаны все компоненты первичного ключа.
<insert-stmt> ::= INSERT INTO [<keyspace-name> '.'] <table-name>
'(' <column-names> ')'
VALUES '(' <values> ')'
[IF NOT EXISTS]
[USING TTL <int>]
IF NOT EXISTS— вставляет строку только если она не существует (см. LWT)USING TTL <seconds>— задаёт время жизни строки в секундах; переопределяетdefault_time_to_liveтаблицыUSING TIMESTAMP— не поддерживается
Примеры:
INSERT INTO mykeyspace.users (user_id, email, name)
VALUES (uuid(), 'alice@example.com', 'Alice');
```sql title="Вставка с TTL (строка удалится через 1 час)"-- INSERT INTO mykeyspace.sessions (session_id, user_id) VALUES (uuid(), 123e4567-e89b-12d3-a456-426614174000) USING TTL 3600;
```sql title="Вставка только при отсутствии строки"
INSERT INTO mykeyspace.users (user_id, email)
VALUES (uuid(), 'bob@example.com')
IF NOT EXISTS;
UPDATE¶
Обновляет один или несколько столбцов строки. Строка идентифицируется по полному первичному ключу
в WHERE. Если строки с указанным ключом не существует, она будет создана (upsert-семантика) —
за исключением случая, когда указан IF EXISTS.
<update-stmt> ::= UPDATE [<keyspace-name> '.'] <table-name>
[USING TTL <int>]
SET <assignment> [',' <assignment>]*
WHERE <where-clause>
[IF EXISTS]
<assignment> ::= <column-name> '=' <value>
| <column-name> '=' <column-name> '+' <value>
| <column-name> '=' <column-name> '-' <value>
IF EXISTS— обновляет строку только если она существует (см. LWT)USING TTL <int>— устанавливает время жизни (в секундах) для обновляемой строки. Допустимый диапазон: от0до630720000(20 лет). Значение0сбрасывает TTL — срок жизни строки становится неограниченным. Не применяется к таблицам с колонками типаcounter
Ограничения Sirin:
USING TIMESTAMPне поддерживается- операции над коллекциями (
col = col + [...],map[key] = value) не поддерживаются - произвольные
IF-условия (IF col = val) не поддерживаются, толькоIF EXISTS
Виды присваиваний:
| Форма | Применение | Пример |
|---|---|---|
col = value |
Установить значение | name = 'Bob' |
col = col + value |
Инкремент счётчика | visits = visits + 1 |
col = col - value |
Декремент счётчика | visits = visits - 1 |
Примеры:
UPDATE mykeyspace.users
SET name = 'Alice Smith', email = 'alice.smith@example.com'
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
UPDATE mykeyspace.users USING TTL 3600
SET session_token = 'abc'
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
UPDATE mykeyspace.stats
SET page_views = page_views + 1
WHERE page_id = 'home';
UPDATE mykeyspace.users
SET name = 'Bob'
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000
IF EXISTS;
DELETE¶
Удаляет строку целиком или значения отдельных столбцов. Операция всегда задаётся по первичному ключу.
<delete-stmt> ::= DELETE [<column-name> [',' <column-name>]*]
FROM [<keyspace-name> '.'] <table-name>
WHERE <where-clause>
[IF EXISTS]
- Если список столбцов не указан — удаляется вся строка.
- Если список столбцов указан — удаляются только значения этих столбцов (столбцы
получают значение
null). Столбцы первичного ключа удалить нельзя. IF EXISTS— удаляет строку только если она существует (см. LWT)USING TIMESTAMP— не поддерживаетсяWHEREдолжен содержать как минимум полный partition key
Примеры:
DELETE FROM mykeyspace.users
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
DELETE FROM mykeyspace.users
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000
IF EXISTS;
DELETE email FROM mykeyspace.users
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
DELETE FROM mykeyspace.events
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000
AND event_time < '2024-01-01 00:00:00+0000';
SELECT¶
Читает данные из таблицы.
<select-stmt> ::= SELECT <select-clause>
FROM [<keyspace-name> '.'] <table-name>
[WHERE <where-clause>]
[ORDER BY <column-name> [ASC | DESC] [',' ...]]
[LIMIT <number>]
[ALLOW FILTERING]
<select-clause> ::= '*'
| <column-name> [AS <alias>] [',' <column-name> [AS <alias>]]*
WHERE
Задаёт условие фильтрации строк. Поддерживаемые операторы: =, <, >, <=, >=, !=, IN.
Для эффективной работы рекомендуется всегда указывать полный partition key. Фильтрация по
неключевым столбцам требует ALLOW FILTERING.
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000
AND event_time > '2024-01-01 00:00:00+0000'
ORDER BY
Порядок сортировки можно задавать только по столбцам кластеризующего ключа, и только
в том направлении, которое задано в CLUSTERING ORDER BY таблицы или в обратном ему.
LIMIT
Ограничивает общее число возвращаемых строк.
ALLOW FILTERING
По умолчанию Sirin, как и Cassandra, запрещает запросы, требующие полного сканирования всех
partition. Такие запросы необходимо явно пометить ALLOW FILTERING. Следует использовать
осторожно на больших таблицах.
Ограничения:
GROUP BYне поддерживаетсяUSING CONSISTENCY,USING TIMESTAMPне поддерживаются- функции в списке столбцов (
COUNT(*),CAST(), вызовы функций) не поддерживаются - сравнение кортежей, например
(a, b) > (1, 2), не поддерживается
Примеры:
SELECT * FROM mykeyspace.events
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000;
SELECT device_id, event_time, payload
FROM mykeyspace.events
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000
ORDER BY event_time DESC
LIMIT 10;
SELECT user_id AS id, name AS username FROM mykeyspace.users
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
SELECT * FROM mykeyspace.users
WHERE name = 'Alice'
ALLOW FILTERING;
BATCH¶
Объединяет несколько DML-операций в один запрос. Все операции батча применяются атомарно.
<batch-stmt> ::= BEGIN [UNLOGGED] BATCH
<dml-stmt> ';'
[<dml-stmt> ';']*
APPLY BATCH
Батч может содержать операторы INSERT, UPDATE и DELETE. Операции могут
производится над разными таблицами.
UNLOGGED— в Cassandra отключает журнал батча для повышения производительности; в Sirin принимается синтаксически, поведение не меняется.USING TIMESTAMPна уровне батча не поддерживается.
Пример:
BEGIN BATCH
INSERT INTO mykeyspace.users (user_id, name) VALUES (uuid(), 'Alice');
UPDATE mykeyspace.users SET email = 'alice@example.com'
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
DELETE FROM mykeyspace.users
WHERE user_id = 00000000-0000-0000-0000-000000000001;
APPLY BATCH;
LWT (Lightweight transactions)¶
Lightweight transactions позволяют выполнять операции условно — только при выполнении указанного условия. Это обеспечивает семантику «сравни и замени» (compare-and-set) без полного распределённого консенсуса.
Так как реплики в Picodata объединены синхронной репликацией, проверка условия выполняется локально на узле, обрабатывающем запрос.
На данный момент поддерживаются:
| Оператор | Конструкция | Описание |
|---|---|---|
INSERT |
IF NOT EXISTS |
Вставить строку только если её нет |
UPDATE |
IF EXISTS |
Обновить строку только если она есть |
DELETE |
IF EXISTS |
Удалить строку только если она есть |
Каждый LWT-запрос возвращает результирующий набор с псевдостолбцом [applied]:
true— условие выполнено, операция примененаfalse— условие не выполнено, операция не применена
Примеры:
INSERT INTO mykeyspace.users (user_id, name)
VALUES (123e4567-e89b-12d3-a456-426614174000, 'Alice')
IF NOT EXISTS;
[applied]
-----------
True
UPDATE mykeyspace.users SET name = 'Bob'
WHERE user_id = 123e4567-e89b-12d3-a456-426614174000
IF EXISTS;
[applied]
-----------
False
Аутентификация и управление правами доступа¶
Sirin использует ролевую модель управления доступом (RBAC), аналогичную Cassandra. Доступ к данным определяется набором привилегий, назначенных ролям. Роли могут наследоваться друг от друга, образуя иерархию. Аутентификация выполняется по протоколу Cassandra Native Protocol v4 с передачей учётных данных (логин и пароль) при установке соединения.
По умолчанию аутентификация отключена. Как её включить — см. раздел Включение аутентификации.
По умолчанию создаётся суперпользователь cassandra с паролем cassandra. Суперпользователь
обладает полными правами на все ресурсы и может управлять другими ролями.
Внимание!
Рекомендуем сменить пароль суперпользователя cassandra сразу после развёртывания.
CREATE ROLE¶
Создаёт новую роль. Роль может быть учётной записью пользователя (с возможностью входа) или группой для делегирования прав.
<create-role-stmt> ::= CREATE ROLE [IF NOT EXISTS] <role_name>
[WITH <role_options>]
<role_options> ::= <role_option> [AND <role_option>]*
<role_option> ::= PASSWORD = '<string>'
| HASHED PASSWORD = '<bcrypt-hash>'
| LOGIN = (true | false)
| SUPERUSER = (true | false)
| OPTIONS = <map_literal>
| ACCESS TO DATACENTERS <set-literal>
| ACCESS TO ALL DATACENTERS
| ACCESS FROM CIDRS <set-literal>
| ACCESS FROM ALL CIDRS
PASSWORD— пароль в открытом виде, хешируется при сохранении. Задаётся либоPASSWORD, либоHASHED PASSWORD— одновременно оба параметра не допускаютсяHASHED PASSWORD— предварительно вычисленный bcrypt-хеш пароля. Используется при переносе учётных записей из другой Cassandra-совместимой системыLOGIN— разрешает вход в систему. По умолчаниюfalse. ПриLOGIN = trueобязательно указатьPASSWORDилиHASHED PASSWORDSUPERUSER— наделяет ролью суперпользователя с полными правами. По умолчаниюfalseIF NOT EXISTS— не возвращает ошибку, если роль уже существуетACCESS TO DATACENTERS {'dc1', 'dc2', ...}— ограничивает вход только с узлов указанных дата-центров. Каждый узел Picodata имеет параметрinstance.failure_domain— словарь произвольных ключей, описывающих его физическое размещение (например,{"DC": "DC1", "HOST": "node1"}). Параметр конфигурации плагинаrouter.auth.network.dc_failure_domain_keyзадаёт, какой именно ключ из этого словаря считать именем дата-центра (по умолчаниюdc)ACCESS TO ALL DATACENTERS— разрешает вход с узлов любого дата-центра (поведение по умолчанию)ACCESS FROM CIDRS {'group1', 'group2', ...}— разрешает вход только с IP-адресов, принадлежащих указанным CIDR-группам (см. CIDR-группы). Требуетrouter.auth.is_cidr_authorizer_enabled: trueACCESS FROM ALL CIDRS— разрешает вход с любых IP-адресов (поведение по умолчанию)
Примеры:
CREATE ROLE alice WITH PASSWORD = 'secret' AND LOGIN = true;
CREATE ROLE data_readers;
CREATE ROLE admin WITH PASSWORD = 'str0ng' AND LOGIN = true AND SUPERUSER = true;
CREATE ROLE app_user
WITH PASSWORD = 'pass'
AND LOGIN = true
AND ACCESS TO DATACENTERS {'dc-msk'}
AND ACCESS FROM CIDRS {'office_net'};
ALTER ROLE¶
Изменяет параметры существующей роли. Поддерживает те же опции, что и CREATE ROLE,
за исключением IF NOT EXISTS. Незаданные параметры остаются без изменений.
<alter-role-stmt> ::= ALTER ROLE <role_name>
[WITH <role_option> [AND <role_option>]*]
Примеры:
ALTER ROLE alice WITH PASSWORD = 'newpassword';
ALTER ROLE alice WITH SUPERUSER = true;
ALTER ROLE alice WITH ACCESS TO DATACENTERS {'dc-spb'};
DROP ROLE¶
Удаляет роль. При удалении атомарно очищаются все связанные записи: членство в других ролях, разрешения, сетевые ограничения.
<drop-role-stmt> ::= DROP ROLE [IF EXISTS] <role_name>
Пример:
DROP ROLE IF EXISTS alice;
CIDR-группы¶
CIDR-группы — именованные наборы IP-подсетей, используемые в опции ACCESS FROM CIDRS
при создании или изменении ролей. Для применения CIDR-авторизации необходимо включить
параметр router.auth.is_cidr_authorizer_enabled: true в конфигурации плагина.
Отличие от Cassandra
В Apache Cassandra CIDR-группы не управляются через CQL: они задаются
утилитой nodetool updatecidrgroup и обновляются командой
nodetool reloadcidrgroupscache. В Sirin управление CIDR-группами реализовано
в виде CQL-операторов DCL, описанных ниже.
CREATE CIDR GROUP
<create-cidr-group-stmt> ::= CREATE CIDR GROUP <name>
WITH ADDRESSES = {'<cidr>', ...}
ALTER CIDR GROUP
<alter-cidr-group-stmt> ::= ALTER CIDR GROUP <name> ADD ADDRESSES {'<cidr>', ...}
| ALTER CIDR GROUP <name> DROP ADDRESSES {'<cidr>', ...}
DROP CIDR GROUP
<drop-cidr-group-stmt> ::= DROP CIDR GROUP <name>
Примеры:
-- Создание группы
CREATE CIDR GROUP office_net WITH ADDRESSES = {'10.0.0.0/8', '192.168.1.0/24'};
-- Добавление адресов
ALTER CIDR GROUP office_net ADD ADDRESSES {'172.16.0.0/12'};
-- Удаление адресов
ALTER CIDR GROUP office_net DROP ADDRESSES {'192.168.1.0/24'};
-- Удаление группы
DROP CIDR GROUP office_net;
Права на управление CIDR-группами выдаются через
GRANT ... ON CIDR GROUP <name> или GRANT ... ON ALL CIDR GROUPS
(см. раздел GRANT PERMISSION).
GRANT ROLE / REVOKE ROLE¶
Назначает или отзывает членство одной роли в другой. Роль наследует все права родительской роли.
<grant-role-stmt> ::= GRANT <role_name> TO <grantee_role>
<revoke-role-stmt> ::= REVOKE <role_name> FROM <grantee_role>
Примеры:
GRANT data_readers TO alice;
REVOKE data_readers FROM alice;
GRANT PERMISSION¶
Предоставляет привилегии роли на указанный ресурс.
<grant-permission-stmt> ::= GRANT <permissions> ON <resource> TO <role_name>
<permissions> ::= ALL [PERMISSIONS]
| <permission> [, <permission>]* [PERMISSION[S]]
<permission> ::= CREATE | ALTER | DROP | SELECT | MODIFY | AUTHORIZE | DESCRIBE
<resource> ::= ALL KEYSPACES
| KEYSPACE <keyspace_name>
| [TABLE] <table_name>
| ALL ROLES
| ROLE <role_name>
| ALL CIDR GROUPS
| CIDR GROUP <group_name>
Применимые привилегии зависят от типа ресурса:
| Ресурс | Применимые привилегии |
|---|---|
| ALL KEYSPACES, KEYSPACE | CREATE, ALTER, DROP, SELECT, MODIFY, AUTHORIZE |
| TABLE | ALTER, DROP, SELECT, MODIFY, AUTHORIZE |
| ALL ROLES, ROLE | CREATE, ALTER, DROP, AUTHORIZE, DESCRIBE |
| ALL CIDR GROUPS, CIDR GROUP | CREATE, ALTER, DROP, AUTHORIZE, DESCRIBE |
Описание привилегий:
| Привилегия | Описание |
|---|---|
CREATE |
Создание таблиц и пространств имён |
ALTER |
Изменение схемы |
DROP |
Удаление таблиц и пространств имён |
SELECT |
Чтение данных |
MODIFY |
Запись данных (INSERT, UPDATE, DELETE) |
AUTHORIZE |
Управление правами доступа (GRANT, REVOKE) |
DESCRIBE |
Просмотр информации о ролях (LIST ROLES) |
Примеры:
```sql title="Разрешить чтение из всех таблиц пространства имён ks1"
GRANT SELECT ON KEYSPACE ks1 TO data_readers;
GRANT MODIFY ON TABLE ks1.events TO writer;
GRANT ALL PERMISSIONS ON KEYSPACE ks1 TO admin;
GRANT SELECT, MODIFY ON ALL KEYSPACES TO app_role;
GRANT ALTER ON ALL CIDR GROUPS TO netadmin;
LIST ROLES¶
Возвращает список ролей в системе. При указании конкретной роли возвращает роли, членом которых она является.
<list-roles-stmt> ::= LIST ROLES [OF <role_name>] [NORECURSIVE]
OF <role_name>— показать роли, в которые входит указанная рольNORECURSIVE— только прямые членства, без транзитивных
Примеры:
LIST ROLES;
LIST ROLES OF alice;
LIST ROLES OF alice NORECURSIVE;
LIST PERMISSIONS¶
Возвращает список выданных привилегий. Результат можно фильтровать по типу привилегии, ресурсу и роли.
<list-permissions-stmt> ::= LIST <permissions> [ON <resource>] [OF <role_name>] [NORECURSIVE]
<permissions> ::= ALL [PERMISSIONS]
| <permission> [, <permission>]* [PERMISSION[S]]
OF <role_name>— показать привилегии указанной роли и её родительских ролей (по умолчанию рекурсивно)NORECURSIVE— только собственные привилегии роли, без унаследованныхON <resource>— фильтрация по ресурсу
Примеры:
LIST ALL PERMISSIONS;
LIST ALL PERMISSIONS OF alice;
LIST ALL PERMISSIONS OF alice NORECURSIVE;
LIST ALL PERMISSIONS ON KEYSPACE ks1 OF alice;
LIST SELECT PERMISSIONS OF alice;
REVOKE PERMISSION¶
Отзывает ранее выданные привилегии роли на ресурс.
<revoke-permission-stmt> ::= REVOKE <permissions> ON <resource> FROM <role_name>
Примеры:
REVOKE SELECT ON TABLE ks1.users FROM reporter;
REVOKE ALL PERMISSIONS ON KEYSPACE ks1 FROM alice;
TTL и механизм экспирации¶
TTL (Time To Live) определяет время жизни строки в секундах. По истечении TTL строка становится невидимой для чтения и помечается для физического удаления.
Задание TTL¶
TTL можно задать на двух уровнях:
На уровне таблицы — через параметр default_time_to_live в CREATE TABLE. Применяется
ко всем вставляемым строкам, если USING TTL не указан явно в запросе.
CREATE TABLE mykeyspace.sessions (
session_id uuid PRIMARY KEY,
user_id uuid
) WITH default_time_to_live = 86400; -- 24 часа
На уровне строки — через USING TTL в операторах INSERT и UPDATE. Переопределяет default_time_to_live.
INSERT INTO mykeyspace.sessions (session_id, user_id)
VALUES (uuid(), 123e4567-e89b-12d3-a456-426614174000)
USING TTL 600;
INSERT INTO mykeyspace.sessions (session_id, user_id)
VALUES (uuid(), 123e4567-e89b-12d3-a456-426614174000)
USING TTL 0;
Механизм удаления¶
Sirin использует двухэтапный механизм удаления:
-
Логическая экспирация. При чтении строка проверяется на истечение TTL. Истёкшие строки не возвращаются клиенту — они невидимы немедленно после истечения срока.
-
Физическое удаление. Фоновая задача периодически обходит таблицы и физически удаляет истёкшие строки. Интервал и размер пакета настраиваются через конфигурацию плагина (
storage.ttl.timeout,storage.ttl.batch_size).
Такой подход позволяет не влиять на производительность операций чтения и записи.
Функции¶
На данный момент Sirin поддерживает функции для работы со значениями типа timeuuid. Эти функции
используются в условиях WHERE для фильтрации строк по временно́му диапазону.
Функции timeuuid¶
Функция |
Описание |
|---|---|
now() |
Генерирует новый уникальный timeuuid, соответствующий текущему моменту времени. Синонимы: currentTimeuuid(), current_timeuuid(). |
minTimeuuid(t) |
Возвращает минимально возможный timeuuid для заданного момента времени t (типа timestamp). Синонимы: min_timeuuid(). |
maxTimeuuid(t) |
Возвращает максимально возможный timeuuid для заданного момента времени t (типа timestamp). Синонимы: max_timeuuid(). |
Примечание
Функции now(), minTimeuuid(), maxTimeuuid() поддерживаются только в условии WHERE. Использование в списке столбцов оператора SELECT не поддерживается.
Примеры:
SELECT * FROM ks1.events
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000
AND event_id > minTimeuuid('2024-01-01 00:00:00+0000')
AND event_id < maxTimeuuid('2024-01-02 00:00:00+0000');
SELECT * FROM ks1.events
WHERE device_id = 123e4567-e89b-12d3-a456-426614174000
AND event_id < now();
Ограничения¶
- функции поддерживаются только в условии
WHERE, не в списке столбцовSELECT - агрегатные функции (
count,sum,avg,min,max) не поддерживаются - пользовательские функции (UDF) и пользовательские агрегаты (UDA) не поддерживаются
- триггеры не поддерживаются
Примеры использования¶
CREATE TABLE users (
id uuid PRIMARY KEY,
name text,
age int,
country text
);
INSERT INTO users (id, name, age, country) VALUES (2f0cff20-967f-4dfa-a8a1-6140b5fd9255, 'Ivan', 32, 'Russia');
SELECT id, name FROM users LIMIT 10;
INSERT INTO sessions (id, user_id) VALUES (uuid(), 42) USING TTL 600;
Протоколы и драйверы¶
- поддерживается протокол Cassandra Native Protocol v4
- совместимость с драйверами Apache Cassandra для популярных языков:
- Java — DataStax Java Driver
- Python — Python Cassandra Driver
- Go — gocql
- Node.js — cassandra-driver for Node.js
- Rust — ScyllaDB Rust Driver
- совместимость с инструментами:
cqlsh— стандартный CLI для Cassandra- DBeaver — GUI для управления базами данных
Развёртывание, эксплуатация и восстановление¶
Все процедуры полностью соответствуют инфраструктуре Picodata.
См. разделы документации Picodata:
- Установка плагинов
- Создание кластера
- Получение данных о кластере
- Резервное копирование и восстановление
Конфигурация плагина¶
router:
addr: 0.0.0.0:9042 # Адрес, на котором будет доступен протокол cassandra
max_clients: 100 # Максимальное количество конкурентных соединений на узел
auth:
is_required: false # Включить обязательную аутентификацию. По умолчанию false.
permissions_validity: 2s # Интервал обновления кэша прав пользователя в рамках
# активной сессии. По умолчанию 2s.
is_cidr_authorizer_enabled: false # Включить проверку ACCESS FROM CIDRS при входе
network:
# Ключ failure_domain Picodata, значение которого трактуется как имя
# дата-центра для проверки ACCESS TO DATACENTERS.
dc_failure_domain_key: dc
dispatcher:
# Ёмкость канала между IO-потоком и файбер-луп Tarantool. По умолчанию 4096.
channel_capacity: 4096
# Режим Tokio-рантайма IO-потока:
# single (по умолчанию) — однопоточный рантайм
# multi — многопоточный рантайм; дополнительный параметр:
# worker_threads: <N> — число рабочих потоков
# (по умолчанию — по одному на логическое ядро)
#
# Пример — многопоточный рантайм с 4 потоками:
# tokio_runtime:
# mode: multi
# worker_threads: 4
tokio_runtime:
mode: single
storage:
ttl:
timeout: 10 # Частота срабатывания в секундах фоновой задачи, которая
# физически удаляет записи с истёкшим сроком жизни
batch_size: 100 # Размер пакета на одну операцию удаления записей
Включение аутентификации¶
По умолчанию аутентификация отключена (is_required: false). Включить её можно двумя способами:
Через файл конфигурации plugin_config.yaml:
router:
auth:
is_required: true
permissions_validity: 2s
Через SQL-команду ALTER PLUGIN без перезапуска кластера:
ALTER PLUGIN sirin 1.1.0 SET router.auth.is_required='true';
Параметр permissions_validity задаёт интервал, с которым Sirin проверяет изменения прав в рамках
активного соединения. При значении 2s изменения, внесённые через GRANT/REVOKE, начнут
действовать не позднее чем через 2 секунды — без разрыва соединения.
ALTER PLUGIN sirin 1.1.0 SET router.auth.permissions_validity='5s';