[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for Sharded PostgreSQL](../index.md) > Вопросы и ответы > Все вопросы на одной странице

# Вопросы и ответы про Managed Service for Sharded PostgreSQL {#general}

### Общие вопросы про Managed Service for Sharded PostgreSQL {#toc-general}

* [Что такое Managed Service for Sharded PostgreSQL?](#what-is-mspqr)

* [Какие преимущества предоставляет Managed Service for Sharded PostgreSQL?](#mspqr-benefits)

* [В каких случаях стоит использовать Managed Service for Sharded PostgreSQL?](#use-cases)

* [В каких случаях мне не подходит Managed Service for Sharded PostgreSQL?](#not-suitable-use-cases)

* [Поддерживаются ли JSONB и большие объекты?](#jsonb-support)

* [Зачем использовать Managed Service for Sharded PostgreSQL вместо Yandex Managed Service for YDB?](#mspqr-vs-ydb)

* [Может ли кластер Managed Service for PostgreSQL из нескольких хостов быть шардом в Managed Service for Sharded PostgreSQL?](#multi-host-pg-cluster)

* [Имеет ли смысл переносить мощные инстансы PostgreSQL (например, 96 vCPU) на Sharded PostgreSQL?](#powerful-pg-instances)

* [Чем Managed Service for Sharded PostgreSQL отличается от Neon?](#mspqr-vs-neon)

* [Чем Managed Service for Sharded PostgreSQL отличается от Citus/Vitess?](#mspqr-vs-citus-vs-vitess)

* [Как начать работу с сервисом Managed Service for Sharded PostgreSQL?](#how-to-start)

### Безопасность и эксплуатация {#toc-security}

* [Как обеспечивается безопасность данных?](#data-security)

* [Не утекают ли учетные данные через роутер?](#router-security)

* [Как настроить резервное копирование?](#how-to-set-up-backups)

* [Как обеспечить высокую доступность?](#high-availability)

* [Что происходит при перегрузках?](#overload-behaviour)

* [Как обрабатывается отмена запросов?](#cancel-query-processing)

* [Есть ли риски дублирования запросов при использовании балансировщика перед роутерами?](#query-duplication)

* [Как ограничить доступ к административной консоли?](#restrict-access-to-admin-console)

### Распределенные запросы {#toc-distributed-queries-and-transactions}

* [Как Sharded PostgreSQL обрабатывает SQL-запросы?](#sql-queries-parcing)

* [Как выполнять транзакции с несколькими шардами?](#multi-shard-transactions)

* [Как принудительно указать, на каком шарде выполнить запрос?](#how-to-specify-shard)

* [Какие стратегии фиксации транзакций поддерживаются?](#commit-strategy)

* [Как работают справочные таблицы (reference tables)?](#reference-tables)

* [Как создать справочные таблицы (reference tables)?](#how-to-create-reference-table)

* [Поддерживает ли Sharded PostgreSQL распределенные последовательности (distributed sequences)?](#distributed-sequences)

* [Можно ли шардировать связанные таблицы по одному ключу?](#single-key-sharding-for-connected-tables)

* [Как выполняются запросы без явного ключа шардирования?](#queries-with-no-explicit-key)

### Подключение {#toc-connection}

* [Как подключиться к роутеру?](#how-to-connect-to-router)

* [Как подключиться к консоли администратора Sharded PostgreSQL?](#how-to-connect-to-admin-console)

* [Что такое сессионный и транзакционный режимы?](#session-vs-transaction-modes)

* [Как получить статистику и состояние подключений?](#connections-monitoring)

* [Как настроить подключение приложения к Sharded PostgreSQL?](#how-to-connect-app-to-spqr)

* [Какие опции есть для управления маршрутизацией соединений?](#connection-routing-management)

### Производительность {#toc-performance}

* [Как повысить производительность?](#how-to-improve-performance)

* [Как снизить задержки при чтении?](#how-to-decrease-read-latency)

* [Как ограничить нагрузку от загрузки данных?](#how-to-improve-data-upload-performance)

* [Как настроить чтение с реплик?](#how-to-read-from-replicas)

* [Какие ресурсы требуются для роутеров и координаторов?](#router-and-coordinator-resources)

### Миграция данных {#toc-data-migration}

* [Можно ли шардировать по композитному ключу?](#composite-sharding-key)

* [Можно ли создать "шард по умолчанию" для непривязанных ключей?](#default-shard-for-unbound-keys)

* [Как добавить новый шард и перебалансировать данные?](#how-to-add-new-shard)

* [Как происходит перебалансировка данных при добавлении нового шарда?](#data-rebalancing-for-new-shard)

* [Как загружать большие объемы данных?](#how-to-upload-big-chunks-of-data)

* [Как ускорить миграцию больших объемов данных?](#how-to-improve-migration-of-big-chunks-of-data)

* [Что происходит при сбое во время миграции данных?](#data-migration-failure)

* [Как переименовать таблицу, сохранив ее доступность?](#how-to-rename-table-and-keep-it-available)

### Ограничения {#toc-limitations}

* [Какие типы данных доступны для шардирования?](#available-data-types)

* [Какие лимиты существуют для кластера Managed Service for Sharded PostgreSQL?](#cluster-limits)

* [Можно ли выполнять JOIN между шардами?](#cross-shard-join-queries)

* [Поддерживаются ли кросс-шардовые запросы?](#cross-shard-queries)

* [Какая политика повторных попыток (retry) используется в Sharded PostgreSQL?](#retry-policy)

* [Как Sharded PostgreSQL управляет лимитами подключений?](#connection-limits)

* [Есть ли дедупликация запросов?](#query-deduplication)

* [Разрешены ли операции DDL (например, `ALTER TABLE`, `RENAME`) в транзакциях?](#ddl-operations)

### Устранение неполадок {#toc-troubleshooting}

* [Транзакция не применяется на всех шардах](#cross-shard-transaction-failure)

* [Запросы не направляются на новый шард](#queries-routing-fails-for-new-shard)

* [Ошибка `failed to get connection to any shard host within` при подключении к хостам кластера](#failed-to-get-connection)

* [Ошибка `error processing query ... : syntax error` при выполнении запроса](#error-processing-query)

* [Ошибка `permission denied for schema`](#permission-denied-for-schema)

* [Ошибка `failed to find primary within host`](#failed-to-find-primary)

* [Ошибка `failed to match any datashard` или блокировка запроса](#failed-to-match-any-datashard)

## Общие вопросы про Managed Service for Sharded PostgreSQL {#general}

#### Что такое Managed Service for Sharded PostgreSQL? {#what-is-mspqr}

Managed Service for Sharded PostgreSQL (Sharded PostgreSQL) — это управляемый сервис для горизонтального масштабирования PostgreSQL через автоматическое [шардирование](../concepts/sharding.md). Он функционирует как интеллектуальный прокси-роутер, который обрабатывает SQL-запросы и распределяет их по шардам на основе заданных правил — [ключей шардирования](../concepts/sharding-keys.md). При этом сервис Managed Service for Sharded PostgreSQL:

- Использует высокодоступные кластеры как основу шардирования для максимальной надежности.
- Сохраняет доступность кластера при переходе между монолитной и шардированной архитектурой.
- Оптимизирован под OLTP-запросы с минимальными накладными расходами.

Возможности:

* Шардирование по диапазону значений или по хешу: [роутер](../concepts/index.md#router) определяет, на каком [шарде](../concepts/index.md#shard) нужно выполнить запрос.
* Совместимость с расширенным протоколом PostgreSQL, что позволяет использовать подготовленные выражения и клиентские библиотеки без изменений.
* Поддержка сессионного и транзакционного режимов.
* Неограниченное количество роутеров.
* [Перебалансировка](../concepts/sharding-method.md#data-rebalancing) — миграция данных между шардами для равномерного распределения нагрузки.
* Возможность указать несколько серверов для одного шарда. В таком случае роутер будет распределять запросы только для чтения среди реплик и автоматически определять, где находится мастер.

#### Какие преимущества предоставляет Managed Service for Sharded PostgreSQL? {#mspqr-benefits}

С Managed Service for Sharded PostgreSQL вы получаете следующие преимущества:

* Управляемый сервис — автообновления, мониторинг и резервное копирование доступны «из коробки».
* Высокая доступность — автоматическое переключение на реплики при сбоях.
* Динамическая перебалансировка — перераспределение данных между шардами командой `REDISTRIBUTE KEY RANGE`.
* Транзакционная поддержка — сессионный (`SESSION`) и транзакционный (`TRANSACTION`) режимы управления соединениями.
* Мониторинг ресурсов (но контроль за нагрузкой остается на пользователе).
* Консультационная поддержка.

#### В каких случаях стоит использовать Managed Service for Sharded PostgreSQL? {#use-cases}

Сервис оптимален для сценариев, где выполняется одно или несколько условий:
* Размер данных превышает 1 ТБ, при этом возможности вертикального масштабирования исчерпаны.
* Нагрузка превышает 20 000 запросов в секунду, при этом наблюдается деградация производительности.
* Нужно охлаждение данных (архивация старых данных с сохранением их доступности).
* Необходимо автоматизировать существующую шардированную инфраструктуру.

Рекомендуется начинать шардирование, если в кластере больше четырех хостов, больше 40 ядер CPU или размер диска превышает 600 ГБ. Миграция на Managed Service for Sharded PostgreSQL на раннем этапе проще, чем при терабайтных объемах.

#### В каких случаях мне не подходит Managed Service for Sharded PostgreSQL? {#not-suitable-use-cases}

Сервис Managed Service for Sharded PostgreSQL не подходит для:

* OLAP-нагрузок (для этого рекомендуется использовать сервис [Yandex MPP Analytics for PostgreSQL](../../managed-greenplum/index.md)).
* Выполнения сложных запросов, которые затрагивают данные нескольких шардов (например, JOIN между разными шардами).

#### Поддерживаются ли JSONB и большие объекты? {#jsonb-support}
Да, Managed Service for Sharded PostgreSQL полностью совместим с типами данных PostgreSQL, включая JSONB. При этом большие объекты могут влиять на производительность сети.

#### Зачем использовать Managed Service for Sharded PostgreSQL вместо Yandex Managed Service for YDB? {#mspqr-vs-ydb}
Managed Service for Sharded PostgreSQL решает проблему масштабирования для PostgreSQL без смены типа СУБД.

#### Может ли кластер Managed Service for PostgreSQL из нескольких хостов быть шардом в Managed Service for Sharded PostgreSQL? {#multi-host-pg-cluster}
Да. В Managed Service for Sharded PostgreSQL шардом может быть как однохостовый, так и многохостовый кластер Managed Service for PostgreSQL.

#### Имеет ли смысл переносить мощные инстансы PostgreSQL (например, 96 vCPU) на Sharded PostgreSQL? {#powerful-pg-instances}
Да, если клиент готов к шардированию. Sharded PostgreSQL позволяет добавлять ресурсы горизонтально: вместо одного мощного хоста — несколько меньших, с балансировкой нагрузки.

#### Чем Managed Service for Sharded PostgreSQL отличается от Neon? {#mspqr-vs-neon}

Neon реализует разделение compute- и storage-слоев (как Amazon Aurora), но не является шардированным решением и не позволяет горизонтально масштабировать кластер. Sharded PostgreSQL обеспечивает горизонтальное масштабирование через шардирование данных и запросов между независимыми узлами PostgreSQL.

#### Чем Managed Service for Sharded PostgreSQL отличается от Citus/Vitess? {#mspqr-vs-citus-vs-vitess}

| **Критерий** | **Managed Service for Sharded PostgreSQL** | **Citus** | **Vitess** |
|--------------|--------------------------------|-----------|------------|
| Производительность, по сравнению с PostgreSQL | На 10–30% меньше | На 15–40% меньше | На 20–50% меньше |
| Протокол | Нативный PostgreSQL | Расширения PostgreSQL | Проприетарный |
| Перебалансировка | Командой `REDISTRIBUTE KEY RANGE`, при этом кластер остается доступен на чтение и запись | Требует остановки | Через VReplication |
| Управление | Полная интеграция с управляемыми БД | Ручное администрирование | Комплексная настройка |
| Чтение с реплик | Автоматическое | Только через мастер | Через VTGate |
| Лицензия | Открытая лицензия PostgreSQL | GNU AGPLv3 с ограничениями | Apache License 2.0 |

#### Как начать работу с сервисом Managed Service for Sharded PostgreSQL? {#how-to-start}

Создайте ваш первый кластер Managed Service for Sharded PostgreSQL. Подробная инструкция приведена в разделе [Начало работы с Managed Service for Sharded PostgreSQL](../quickstart.md).

Перед началом работы определитесь с характеристиками вашего кластера:
* [Тип шардирования](../concepts/sharding.md#shard-management).
* [Сеть](../../vpc/concepts/network.md#network), к которой будет подключен ваш кластер.
* [Зона доступности](../../overview/concepts/geo-scope.md), в которой будут расположены хосты вашего кластера.
* Количество и [класс хостов](../concepts/instance-types.md).
* Объем [хранилища](../concepts/storage.md) (резервируется в полном объеме при создании кластера).

## Безопасность и эксплуатация {#security}

#### Как обеспечивается безопасность данных? {#data-security}

Sharded PostgreSQL хранит только метаданные о расположении данных. За безопасность данных отвечает сервис [Managed Service for PostgreSQL](../../managed-postgresql/index.md), при этом:

* Поддерживается шифрование трафика — TLS 1.3 для всех соединений (клиент ↔ роутер ↔ шард).
* Доступен аудит — [логи доступа](../at-ref.md) хранятся в сервисе [Yandex Audit Trails](../../audit-trails/index.md) в течение 30 дней. [Подробнее о просмотре логов в кластере Managed Service for Sharded PostgreSQL](../operations/cluster-logs.md).

#### Не утекают ли учетные данные через роутер? {#router-security}

Нет, данные не утекают. Риски аналогичны использованию пулера подключений (например, [Odyssey](https://yandex.ru/dev/odyssey/)). Данные передаются через Sharded PostgreSQL, но практики безопасности соответствуют [стандартам Yandex Cloud](../../security/standarts.md).

#### Как настроить резервное копирование? {#how-to-set-up-backups}

Резервное копирование запускается автоматически для всех задействованных кластеров. Опционально вы можете задать время начала резервного копирования и выбрать срок хранения резервных копий. [Подробнее о настройке резервного копирования в Managed Service for Sharded PostgreSQL](../operations/cluster-backups.md).

#### Как обеспечить высокую доступность? {#high-availability}

Чтобы обеспечить высокую доступность кластера Managed Service for Sharded PostgreSQL:

* Создавайте шарды таким образом, чтобы каждый шард (то есть кластер Managed Service for PostgreSQL) включал не менее трех хостов (мастер и реплики), расположенных в разных зонах доступности.
* Для кластеров Managed Service for Sharded PostgreSQL со стандартным шардированием создайте не менее трех хостов `INFRA` в разных зонах доступности.
* Для кластеров Managed Service for Sharded PostgreSQL с расширенным шардированием создайте не менее трех хостов `COORDINATOR` и трех хостов `ROUTER` в разных зонах доступности.

#### Что происходит при перегрузках? {#overload-behaviour}

Перегруженная реплика становится недоступной, и кластер перестает отправлять к ней запросы до возобновления ее работы. 

Например, кластер получает 95% запросов на запись и 5% на чтение. Если параметр конфигурации роутера `default_target_session_attrs = read-only`, то запросы на чтение равномерно распределяются между репликами. Если в какой-то момент реплика становится недоступной (`SELECT pg_is_in_recovery();` не выполняется в заданное время), сервис перестает отправлять запросы к реплике и проверяет ее статус. Как только реплика снова отвечает, отправка запросов к ней возобновляется.

#### Как обрабатывается отмена запросов? {#cancel-query-processing}

Приложение прерывает текущее соединение с роутером, открывает новое и отправляет роутеру cancel-сообщение с идентификатором запроса. Роутер получает cancel-сообщение и передает его на шард, которому адресован запрос.

{% note tip %}

Отмена запроса вызывает переподключения и повышение нагрузки на TLS handshake, поэтому не рекомендуется использовать таймаут запросов менее 100 мс.

{% endnote %}

#### Есть ли риски дублирования запросов при использовании балансировщика перед роутерами? {#query-duplication}

Да. Если клиент разрывает соединение и балансировщик повторяет запрос, Sharded PostgreSQL обработает его как новый, что может привести к дублированию (например, для `INSERT`). Рекомендуется использовать идемпотентные операции или реализовать механизм дедупликации на уровне приложения.

#### Как ограничить доступ к административной консоли? {#restrict-access-to-admin-console}

Доступ к административной консоли ограничен по умолчанию. [Подключиться](../operations/connect.md) к консоли можно только с TLS при помощи пароля.

Пароль для доступа к административной консоли задается при [создании кластера](../operations/cluster-create.md). При необходимости вы можете [изменить пароль](../operations/cluster-update.md) на работающем кластере.

## Распределенные запросы {#distributed-queries-and-transactions}

#### Как Sharded PostgreSQL обрабатывает SQL-запросы? {#sql-queries-parcing}
Sharded PostgreSQL обрабатывает SQL-запросы в зависимости от их типа и контекста:

* Обычные запросы — Sharded PostgreSQL обрабатывает запрос, определяет таблицу, колонку и значение, к которому происходит обращение. Эти данные сопоставляются с заранее заданными правилами шардирования (например, по ключу или диапазону). На основе этих правил система определяет целевой шард, на который нужно отправить запрос.

* Запросы с настройками роутинга — на маршрутизацию такого запроса могут влиять виртуальные параметры, которые указываются в виде комментариев в SQL-запросе или в конфигурации роутера.

* Транзакции — при получении команды `BEGIN TRANSACTION` Sharded PostgreSQL не выполняет запросы немедленно. Вместо этого он сохраняет все последующие запросы в памяти (например, команды `SET`). Вся транзакция отправляется на конкретный шард целиком только при поступлении запроса, для которого можно однозначно определить целевой шард. Это позволяет выполнить всю транзакцию на одном шарде.

#### Как выполнять транзакции с несколькими шардами? {#multi-shard-transactions}

Для атомарных кросс-шардовых транзакций используйте двухэтапную фиксацию (2PC):

1. В начале сессии — `SET __spqr__commit_strategy TO '2pc'`.
1. В отдельной операции `COMMIT` — добавьте виртуальный параметр `/* __spqr__commit_strategy: 2pc */`.
1. Убедитесь, что на шардах установлена настройка `max_prepared_transactions > 0`.

  {% note warning %}

  Без 2PC изменения могут быть применены частично.

  {% endnote %}

Операции `COPY` поддерживаются с виртуальным параметром `/* __spqr__allow_multishard: true */`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

#### Как принудительно указать, на каком шарде выполнить запрос? {#how-to-specify-shard}

Чтобы указать шард для выполнения запроса, используйте виртуальные параметры:

* `/* __spqr__execute_on: <имя_шарда> */` — указывает конкретный шард для выполнения запроса.

  Чтобы узнать имя шарда, выполните SQL-запрос `SHOW shards;`.

* `/* __spqr__auto_distribution: ... */` — выбирает правило шардирования для маршрутизации.
* `/* __spqr__scatter_query: true */` — включает отправку запроса на все шарды.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

Подробнее о настройках выполнения запроса в [документации SPQR](https://docs.pg-sharding.tech/routing/hints#__spqr__target_session_attrs).

#### Какие стратегии фиксации транзакций поддерживаются? {#commit-strategy}

Sharded PostgreSQL поддерживает однофазную и двухэтапную фиксацию.

Способ фиксации в распределенной транзакции задается виртуальным параметром `__spqr__commit_strategy`. Возможные значения:

* `1pc` — одноэтапная фиксация (best-effort фиксация).
* `2pc` — двухэтапная фиксация.

  Для двухэтапной фиксации используйте виртуальный параметр `/* __spqr__engine_v2: true */` и установите параметр PostgreSQL `max_prepared_transactions` на всех шардах.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

#### Как работают справочные таблицы (reference tables)? {#reference-tables}

Данные в таких таблицах реплицируются на все шарды. Запросы к ним автоматически рассылаются на все узлы с помощью двухэтапной фиксации.

#### Как создать справочные таблицы (reference tables)? {#how-to-create-reference-table}

Таблицы, идентичные на всех шардах, создаются через координатор:

```sql
CREATE REFERENCE TABLE table_name (...);
```

Данные автоматически реплицируются на все шарды. Запросы к ним выполняются без указания шардирования.

Подробнее о создании справочных таблиц в [документации SPQR](https://docs.pg-sharding.tech/sharding/console/sql_commands#create-reference-table).

#### Поддерживает ли Sharded PostgreSQL распределенные последовательности (distributed sequences)? {#distributed-sequences}

Да, через команду `CREATE REFERENCE TABLE ... AUTO INCREMENT`. Sharded PostgreSQL гарантирует уникальность автоинкремента на уровне кластера.

#### Можно ли шардировать связанные таблицы по одному ключу? {#single-key-sharding-for-connected-tables}
Да. Sharded PostgreSQL позволяет хранить связанные данные из разных таблиц на одном шарде, что упрощает JOIN-операции в пределах шарда.

#### Как выполняются запросы без явного ключа шардирования? {#queries-with-no-explicit-key}

По умолчанию запросы без ключа шардирования (мультишардовые запросы) запрещены. Их можно разрешить с помощью виртуального параметра `/* __spqr__scatter_query: true */`. Результаты с каждого шарда склеиваются, но без гарантии консистентности.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

## Подключение {#connection}

#### Как подключиться к роутеру? {#how-to-connect-to-router}

Вы можете подключиться к роутеру в кластере Managed Service for Sharded PostgreSQL с помощью клиента PostgreSQL. Для этого выполните команду:

```bash
psql "host=<FQDN_хоста> \
      port=6432 \
      sslmode=verify-full \
      dbname=<имя_БД> \
      user=<имя_пользователя> \
      target_session_attrs=read-write"
```

Где `target_session_attrs` определяет тип запроса к хосту. Например, значение `read-write` дает возможность чтения и записи. Подробнее читайте в [документации SPQR](https://docs.pg-sharding.tech/routing/hints#__spqr__target_session_attrs).

После выполнения команды введите пароль пользователя для завершения процедуры подключения.

#### Как подключиться к консоли администратора Sharded PostgreSQL? {#how-to-connect-to-admin-console}

Используйте порт `6432`, пользователя `spqr-console` и БД `spqr-console`. Пример:

```bash
psql "host=<FQDN_роутера> port=6432 user=spqr-console dbname=spqr-console sslmode=verify-full"
```

#### Что такое сессионный и транзакционный режимы? {#session-vs-transaction-modes}

В сессионном режиме клиентское соединение устанавливается при первом запросе к базе данных и поддерживается до тех пор, пока клиент не разорвет сессию. Затем это соединение может быть использовано другим или этим же клиентом. Такой подход позволяет хорошо переживать момент установления большого количества клиентских соединений к СУБД (например, при старте приложений, обращающихся к базам данных), но является менее производительным, чем транзакционный режим.

В транзакционном режиме клиентское соединение устанавливается при первом запросе к базе данных и поддерживается до завершения транзакции. Затем это соединение может быть использовано другим или этим же клиентом. Такой подход позволяет поддерживать небольшое количество серверных соединений между менеджером подключений и хостами PostgreSQL при большом количестве клиентских соединений.

Транзакционный режим обеспечивает высокую производительность и позволяет максимально эффективно нагрузить СУБД, но в нем недоступно использование:

* временных таблиц ([temporary tables](https://www.postgresql.org/docs/current/sql-createtable.html)), курсоров ([cursors](https://www.postgresql.org/docs/current/plpgsql-cursors.html)) и рекомендательных блокировок ([advisory locks](https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS)), которые существуют дольше одной транзакции;

* подготовленных выражений ([prepared statements](https://www.postgresql.org/docs/current/sql-prepare.html)).

Настройка режима производится в параметре `pool_mode` в конфигурации роутера. По умолчанию включен транзакционный режим.

#### Как получить статистику и состояние подключений? {#connections-monitoring}
Роутер предоставляет административную консоль по протоколу PostgreSQL. В консоли доступны команды `SHOW` для получения статистики, например:

* `SHOW clients WHERE dbname = <имя_базы_данных>;` — отображает список клиентов, маршрут, адрес роутера и состояние соединения.
* `SHOW shards` — выводит список шардов.
* `SHOW backend_connections` — выводит список подключений к хостам шардов.

#### Как настроить подключение приложения к Sharded PostgreSQL? {#how-to-connect-app-to-spqr}

Для подключения из приложений используйте стандартные PostgreSQL-драйверы (например, pgx). В конфигурации укажите все роутеры кластера. Убедитесь, что группы безопасности кластера разрешают подключение к нему.

Для сложных запросов (например, с CTE) используйте виртуальный параметр `/* __spqr__engine_v2: true */`. Виртуальные параметры можно задавать комментариями в SQL или через `SET`. Подробнее о виртуальных параметрах читайте в [документации SPQR](https://docs.pg-sharding.tech/routing/hints#__spqr__target_session_attrs).

#### Какие опции есть для управления маршрутизацией соединений? {#connection-routing-management}

Управлять можно только типом запроса к хосту. Для этого используйте виртуальный параметр `/*__spqr__target_session_attrs */` или параметр `target_session_attrs` и укажите в нем желаемый тип запроса: `read-write`, `smart-read-write`, `read-only`, `prefer-standby` или `any`. 

Тип запроса влияет на поведение кластера при обработке запроса. Например, `read-only` позволяет подключаться только к репликам, `prefer-standby` выбирает реплику и переключается на мастер при отсутствии реплик. Это полезно при наличии нескольких серверов и автоматическом переключении мастера. Подробнее о типах запросов в [документации SPQR](https://docs.pg-sharding.tech/routing/hints#__spqr__target_session_attrs).

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

## Производительность {#performance}

#### Как повысить производительность? {#how-to-improve-performance}

* Увеличьте ресурсы (CPU, RAM) имеющихся роутеров.

* Добавьте новые роутеры.

* Отключите debug-логирование роутеров для снижения нагрузки на вычислительные ресурсы.

* В конфигурации роутера отключите настройку `show_notice_messages`, так как сообщения NOTICE увеличивают нагрузку на Sharded PostgreSQL.

* Избегайте частых переподключений: настройте пул соединений в приложении.

* Включите чтение с реплик. Для этого передайте в SQL-запросе виртуальный параметр:

  ```sql
  SELECT * FROM orders /* target-session-attrs: read-only */;
  ```
* Ограничьте время выполнения долгих запросов:

  ```sql
  SET session_duration_timeout = '5min';
  ```

#### Как снизить задержки при чтении? {#how-to-decrease-read-latency}

* Включите чтение с реплик:

  ```sql
  SELECT * FROM table /* target-session-attrs: read-only */;
  ```

* Увеличьте значение `max_connections` для пользователя.

#### Как ограничить нагрузку от загрузки данных? {#how-to-improve-data-upload-performance}

* Создайте отдельного пользователя и ограничьте количество подключений для него (настройка `conn_limit`).
* Используйте выделенный роутер для ETL-операций.
* Настройте `session_duration_timeout` для автоматического завершения долгих сессий.

#### Как настроить чтение с реплик? {#how-to-read-from-replicas}

В конфигурации можно указать несколько серверов для одного шарда. Роутер автоматически распределит read‑only запросы между репликами. Для конкретного запроса можно явно задать параметр `target-session-attrs`:

* `read-write` (по умолчанию) — запросы только к мастеру.
* `smart-read-write` — запросы только к мастеру, но при этом запросы только на чтение перенаправляются к репликам.
* `read-only` — запросы только к репликам (если доступны).
* `prefer-standby` или `prefer-replica` — запросы к репликам. Если ни одна не доступна, запросы направляются к мастеру.
* `any` — запросы к любому доступному узлу (предпочтительно локальному). Для уменьшения задержек рекомендуется использовать это значение вместе с выбором ближайшего хоста.

#### Какие ресурсы требуются для роутеров и координаторов? {#router-and-coordinator-resources}

Рекомендуется выбирать конфигурацию вычислительных ресурсов для роутера и координатора в соответствии с ожидаемой нагрузкой.

Рекомендуемые конфигурации при нагрузке в 20 000 запросов на чтение в секунду:

#|
|| Уровень требований | Конфигурация роутеров | Конфигурация координаторов | Общая конфигурация ||

|| Минимальный 
| 
* 3 роутера. Класс хостов каждого роутера должен включать 4 vCPU с гарантированной долей vCPU 100% и 16 ГБ RAM.
* Диск `local-ssd` 10 ГБ
| 
* 3 координатора. Класс хостов каждого координатора должен включать 2 vCPU с гарантированной долей vCPU 100% и 4 ГБ RAM.
* Диск `local-ssd` 10 ГБ
|
* 18 vCPU с гарантированной долей vCPU 100%.
* 60 ГБ RAM.
* Диски `local-ssd` 60 ГБ
||
|| Оптимальный
|
* 3 роутера. Класс хостов каждого роутера должен включать 4 vCPU с гарантированной долей vCPU 100% и 16 ГБ RAM.
* Диск `local-ssd` 10 ГБ
|
* 3 координатора. Класс хостов каждого координатора должен включать 2 vCPU с гарантированной долей vCPU 100%, 8 ГБ RAM.
* Диск `local-ssd` 10 ГБ
|
* 18 vCPU с гарантированной долей vCPU 100%.
* 72 ГБ RAM.
* Диски `local-ssd` 60 ГБ
||
|| С запасом
|
* 5 роутеров. Класс хостов каждого роутера должен включать 4 vCPU с гарантированной долей vCPU 100% и 16 ГБ RAM.
* Диск `local-ssd` 10 ГБ
|
* 3 координатора. Класс хостов каждого координатора должен включать 2 vCPU с гарантированной долей vCPU 100% и 8 ГБ RAM.
* Диск `local-ssd` 10 ГБ
|
* 26 vCPU с гарантированной долей vCPU 100%.
* 104 ГБ RAM.
* Диски `local-ssd` 80 ГБ
||
|#

Чтобы рассчитать стоимость кластера Managed Service for Sharded PostgreSQL, [воспользуйтесь калькулятором](https://yandex.cloud/ru/services/managed-spqr#calculator).

## Миграция данных {#data-migration}

#### Можно ли шардировать по композитному ключу? {#composite-sharding-key}

Да. Для этого создайте композитный ключ:

```sql
CREATE DISTRIBUTION <имя_правила_шардирования> COLUMN TYPES integer, varchar;
ALTER DISTRIBUTION <имя_правила_шардирования> ATTACH RELATION orders DISTRIBUTION KEY user_id, order_date;
```

Подробнее о композитных ключах шардирования в [документации SPQR](https://docs.pg-sharding.tech/sharding/composite_keys).

#### Можно ли создать шард по умолчанию для непривязанных ключей? {#default-shard-for-unbound-keys}

Да. Для этого используйте команду:

```sql
ALTER DISTRIBUTION <имя_правила_шардирования> ADD DEFAULT SHARD <имя_шарда>;
```

Подробнее о шардах по умолчанию в [документации SPQR](https://docs.pg-sharding.tech/sharding/default_shard).

#### Как добавить новый шард и перебалансировать данные? {#how-to-add-new-shard}

1. [Создайте новый шард](../operations/shards.md#create-shard).
1. Используйте команду `SYNC REFERENCE TABLES` для копирования справочных таблиц.
1. Перераспределите диапазоны ключей. Используйте команды:
    * `SPLIT KEY RANGE` — чтобы разделить диапазон ключей.
    * `REDISTRIBUTE KEY RANGE` — чтобы перенести данные автоматически.

#### Как происходит перебалансировка данных при добавлении нового шарда? {#data-rebalancing-for-new-shard}

При добавлении нового шарда нужно запустить ручной перенос данных с помощью команды `REDISTRIBUTE KEY RANGE`. В этом случае Sharded PostgreSQL перемещает небольшие диапазоны данных, чтобы минимизировать недоступность кластера на запись.

#### Как загружать большие объемы данных? {#how-to-upload-big-chunks-of-data}

Для загрузки больших объемов данных доступны два варианта:

* `COPY` с виртуальным параметром `/* __spqr__allow_multishard: true */`.

    Например, для загрузки из CSV-файла:

    ```sql
    COPY <имя_таблицы> FROM 'data.csv' WITH DELIMITER ',' /* __spqr__allow_multishard: true */;
    ```

    {% note warning %}

    Использование `COPY` может приводить к высокой нагрузке на роутер. Если вы регулярно используете `COPY`, рекомендуется создать для этой задачи отдельный роутер.

    {% endnote %}

* Одновременная вставка нескольких строк в таблице (batch insert) с виртуальным параметром `/* __spqr__engine_v2: true */`. В таком случае роутер анализирует каждую строку, определяет целевой шард на основе ключа шардирования и преобразовывает запрос в отдельные команды `INSERT` для каждого шарда.

    Например, команда:

    ```sql
    INSERT INTO users (id, name) VALUES
      (1, 'Alice'),      -- отправляется на шард sh1
      (100, 'Bob'),      -- отправляется на шард sh2
      (2, 'Charlie')     -- отправляется на шард sh1
    /* __spqr__engine_v2: true */;
    -- NOTICE: send query to shard(s) : sh1,sh2
    ```

    будет преобразована в:

    * `INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Charlie');` для шарда `sh1`.
    * `INSERT INTO users (id, name) VALUES (100, 'Bob');` для шарда `sh2`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

Подробнее о вставке больших объемов данных в [документации SPQR](https://docs.pg-sharding.tech/sharding/bulk).

#### Как ускорить миграцию больших объемов данных? {#how-to-improve-migration-of-big-chunks-of-data}

* Увеличьте размер чанка.
* Убедитесь, что на шардах есть индекс по ключу шардирования.
* Избегайте параллельных операций записи во время миграции.

#### Что происходит при сбое во время миграции данных? {#data-migration-failure}
Sharded PostgreSQL обеспечивает атомарность на уровне диапазона. При сбое данные могут временно находиться на обоих шардах. Операция будет отменена или возобновлена после восстановления.

#### Как переименовать таблицу, сохранив ее доступность? {#how-to-rename-table-and-keep-it-available}

Выполните последовательность `ALTER TABLE` в одной транзакции. Для включения этой возможности используйте виртуальный параметр `/* __spqr__multishard_ddl: true */`.

```sql
ALTER TABLE ... /* __spqr__multishard_ddl: true */;
```

{% note warning}

Действие не транзакционно. Переименование таблиц требует осторожности.

{% endnote %}

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

## Ограничения {#limitations}

#### Какие типы данных доступны для шардирования? {#available-data-types}

* Целочисленные (`INT`, `BIGINT`).
* Строки (`VARCHAR`).
* `UUID`.
* Составные ключи.
* Хеш-функции: `CITY`, `MURMUR` (только для целых чисел).

  {% note warning %}

  Пользовательские хеш-функции не поддерживаются.

  {% endnote %}

Если вам не хватает какого-либо типа данных, вы можете завести issue в [репозитории проекта на Github](https://github.com/pg-sharding/spqr/issues).

#### Какие лимиты существуют для кластера Managed Service for Sharded PostgreSQL? {#cluster-limits}

Количество роутеров и шардов в кластере Managed Service for Sharded PostgreSQL не ограничено.

Подробнее о [квотах и лимитах в Managed Service for Sharded PostgreSQL](../concepts/limits.md).

#### Можно ли выполнять JOIN между шардами? {#cross-shard-join-queries}

Нет. JOIN возможен только в пределах одного шарда. При работе со связанными данными используйте одинаковые ключи шардирования для связанных таблиц, чтобы данные находились на одном шарде.

Если вам нужно выполнять JOIN между шардами, рекомендуем использовать [Yandex MPP Analytics for PostgreSQL](../../managed-greenplum/index.md).

#### Поддерживаются ли кросс-шардовые запросы? {#cross-shard-queries}

Поддерживаются только для следующих случаев:

* Справочные таблицы (reference tables) с виртуальным параметром: `/* __spqr__engine_v2: true */`.
* `COPY` с виртуальным параметром `/* __spqr__allow_multishard: true */`.
* Транзакции, в которых передан DDL и виртуальный параметр `/* __spqr__default_route_behaviour: ALLOW */`.
* Запросы, к которым явно указан виртуальный параметр `/* __spqr__scatter_query: true */`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

#### Какая политика повторных попыток (retry) используется в Sharded PostgreSQL? {#retry-policy}
Роутер не выполняет пользовательские запросы повторно. Пользователю нужно самостоятельно реализовать политику повторов, исходя из своей бизнес-логики.

#### Как Sharded PostgreSQL управляет лимитами подключений? {#connection-limits}
Лимит подключений задается отдельно для каждого пользователя в параметре `conn_limit`.

#### Есть ли дедупликация запросов? {#query-deduplication}

Нет. Если клиент отключается и повторяет запрос, роутер обработает его как новый.

#### Разрешены ли операции DDL (например, ALTER TABLE, RENAME) в транзакциях? {#ddl-operations}

Да, если включен `/* __spqr__default_route_behaviour: ALLOW */`.

В зависимости от ваших задач рекомендуется использовать виртуальный параметр:

* С однофазной фиксацией — `/* __spqr__commit_strategy: 1pc */`.
* С двухфазной фиксацией — `/* __spqr__commit_strategy: 2pc */`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

## Устранение неполадок {#troubleshooting}

#### Транзакция не применяется на всех шардах {#cross-shard-transaction-failure}

**Причина:** для кросс-шардовых операций не включена двухфазная фиксация.
**Решение:** включите двухфазную фиксацию:

```sql
BEGIN;
SET __spqr__commit_strategy TO '2pc';
INSERT INTO orders ...; /* затрагивает несколько шардов */
COMMIT;
```

{% note warning %}

Параметр `max_prepared_transactions` должен быть строго больше нуля на всех шардах.

{% endnote %}

#### Запросы не направляются на новый шард {#queries-routing-fails-for-new-shard}

При добавлении нового шарда вы можете столкнуться с тем, что запросы не направляются на него. Чтобы отследить роутинг запросов, вы можете:

* Включить настройку `show_notice_message`.
* Использовать виртуальный параметр `/* __spqr__reply_notice: true */`.

  Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

В обоих случаях роутер отправит приложению информационное сообщение с указанием шарда, на который был направлен запрос.

**Решение**:

* Проверьте, отображается ли новый шард в Sharded PostgreSQL (`SHOW shards`).
* Если вы используете шардированную таблицу, убедитесь, что данные должны быть именно на этом шарде (`SHOW key_ranges`).
* Если вы используете справочную таблицу, убедитесь, что таблица создана именно на этом шарде (`SHOW reference_relations`).

#### Ошибка failed to get connection to any shard host within при подключении к хостам кластера {#failed-to-get-connection}

Пример ошибки:

```bash
failed to get connection to any shard host within: host {rc1d-cofs7cre********.mdb.yandexcloud.net:6432 rc1d}: dial tcp 10.151.25.35:6432: i/o timeout, host {rc1b-49796b52********.mdb.yandexcloud.net:6432 rc1b}: dial tcp 10.149.25.23:6432: i/o timeout, host {rc1a-kdm7v4qm********.mdb.yandexcloud.net:6432 rc1a}: dial tcp 10.148.25.15:6432: i/o timeout
```

Ошибка появляется, если [роутер](../concepts/index.md#router) не может подключиться к хостам [шарда](../concepts/index.md#shard).

**Решение**:

1. Убедитесь, что кластер Managed Service for Sharded PostgreSQL и шарды находятся в одной сети и в одной [группе безопасности](../../vpc/concepts/security-groups.md).
1. В группу безопасности [добавьте правила](../../vpc/operations/security-group-add-rule.md) для входящего и исходящего трафика, разрешающие TCP-подключение на порт `6432`:

    * **Диапазон портов** — `6432`.
    * **Протокол** — `TCP`.
    * **Назначение** — `Диапазон адресов`.
    * **IPv4 CIDR** — укажите CIDR кластера, например `10.96.0.0/16`.

#### Ошибка error processing query ... : syntax error при выполнении запроса {#error-processing-query}

Эта ошибка возникает из-за внутренних проблем Sharded PostgreSQL, а не из-за синтаксических ошибок в вашем SQL-запросе. Sharded PostgreSQL использует собственный парсер SQL, который может не поддерживать некоторые нюансы:

* специфические операторы PostgreSQL;
* редкие варианты синтаксиса;
* нестандартные функции.

**Решение**: сообщите о проблеме разработчикам Sharded PostgreSQL — создайте issue в [репозитории проекта на Github](https://github.com/pg-sharding/spqr/issues), приложите полный текст запроса.

#### Ошибка permission denied for schema {#permission-denied-for-schema}

Ошибка возникает, если у пользователя недостаточно прав для работы со схемой.

**Решение**: Выдайте права на схему пользователю командой `GRANT ALL ON SCHEMA <имя_схемы> TO <имя_пользователя>;` на нужном шарде или на всех шардах.

#### Ошибка failed to find primary within host {#failed-to-find-primary}

Эта ошибка означает, что роутер не может подключиться к мастеру шарда в заданное время.

**Возможные причины**:

* Сетевые проблемы между роутером и шардом.
* Перегрузка шарда (например, высокий показатель CPU wait).
* Неверные настройки `target-session-attrs` (например, `read-only` при запросе на запись).

**Решение**:

* Убедитесь, что сетевая связность между роутером и шардом не нарушена.
* Увеличьте вычислительные ресурсы в кластере PostgreSQL, который является перегруженным шардом.
* Проверьте соответствие настроек `target-session-attrs` вашему запросу.

{% note info %}

Предположительно, проблема была исправлена в [релизе 2.9.0](https://github.com/pg-sharding/spqr/releases/tag/2.9.0). Если вы видите эту ошибку в логах, создайте issue в [репозитории проекта на Github](https://github.com/pg-sharding/spqr/issues).

{% endnote %}

#### Ошибка failed to match any datashard или блокировка запроса {#failed-to-match-any-datashard}

Ошибка возникает, если роутер не может соотнести запрос с конкретным диапазоном ключей шардирования. Например, если параметр конфигурации роутера `default_route_behaviour` имеет значение `BLOCK`, запросы без ключа шардирования блокируются.

**Решение**:

* Измените поведение роутера при сопоставлении запросов:

  * Перманентно — в конфигурации роутера установите для параметра `default_route_behaviour` значение `ALLOW`.
  * Временно — через виртуальный параметр `/* __spqr__default_route_behaviour: allow */`.
* Проверьте:
  * Корректность ключа шардирования в запросе: название ключа в запросе должно соответствовать названию ключа в метаданных Sharded PostgreSQL.
  * Наличие правил шардирования (`SHOW distributions`).
  * Наличие таблиц (`SHOW relations`).
  * Наличие диапазонов (`SHOW key_ranges`).
* Для мультишардовых запросов активируйте engine_v2 через виртуальный параметр `/* __spqr__engine_v2: true */`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.