aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Myasnikov <asmyasnikov@ydb.tech>2024-01-12 17:56:01 +0300
committerGitHub <noreply@github.com>2024-01-12 21:56:01 +0700
commit24f6e85a7ce085dcb3dad6c2b8f15fb280b027b2 (patch)
treef8e5704ec0bf0babe2fedcdcde93a4d9a3c81c9f
parentf8c1889db7823c51892ceabe487005a9ef637e29 (diff)
downloadydb-24f6e85a7ce085dcb3dad6c2b8f15fb280b027b2.tar.gz
added article about goose into docs (#811)
-rw-r--r--ydb/docs/en/core/_assets/goose-ydb-ui-after-first-migration.pngbin0 -> 175819 bytes
-rw-r--r--ydb/docs/en/core/_assets/goose-ydb-ui-after-second-migration.pngbin0 -> 186058 bytes
-rw-r--r--ydb/docs/en/core/integrations/goose.md376
-rw-r--r--ydb/docs/en/core/integrations/toc_i.yaml2
-rw-r--r--ydb/docs/ru/core/_assets/goose-ydb-ui-after-first-migration.pngbin0 -> 175819 bytes
-rw-r--r--ydb/docs/ru/core/_assets/goose-ydb-ui-after-second-migration.pngbin0 -> 186058 bytes
-rw-r--r--ydb/docs/ru/core/integrations/goose.md362
-rw-r--r--ydb/docs/ru/core/integrations/toc_i.yaml2
8 files changed, 742 insertions, 0 deletions
diff --git a/ydb/docs/en/core/_assets/goose-ydb-ui-after-first-migration.png b/ydb/docs/en/core/_assets/goose-ydb-ui-after-first-migration.png
new file mode 100644
index 0000000000..548b6a1780
--- /dev/null
+++ b/ydb/docs/en/core/_assets/goose-ydb-ui-after-first-migration.png
Binary files differ
diff --git a/ydb/docs/en/core/_assets/goose-ydb-ui-after-second-migration.png b/ydb/docs/en/core/_assets/goose-ydb-ui-after-second-migration.png
new file mode 100644
index 0000000000..a764ce5560
--- /dev/null
+++ b/ydb/docs/en/core/_assets/goose-ydb-ui-after-second-migration.png
Binary files differ
diff --git a/ydb/docs/en/core/integrations/goose.md b/ydb/docs/en/core/integrations/goose.md
new file mode 100644
index 0000000000..4c7367bbe6
--- /dev/null
+++ b/ydb/docs/en/core/integrations/goose.md
@@ -0,0 +1,376 @@
+# Data schema versioning and migration in YDB using "goose"
+
+## Introduction
+
+[Goose](https://github.com/pressly/goose) is an open-source tool that helps to version the data schema in the database and manage migrations between these versions. Goose supports many different database management systems, including YDB. Goose uses migration files and stores the state of migrations directly in the database in a special table.
+
+## Install goose
+
+Goose installation options are described in [its documentation](https://github.com/pressly/goose/blob/master/README.md#install).
+
+## Launch arguments goose
+
+After installation, the `goose` command line utility can be called:
+
+```
+$ goose <DB> <CONNECTION_STRING> <COMMAND> <COMMAND_ARGUMENTS>
+```
+
+Where:
+- `<DB>` - database engine, for YDB you should write `goose ydb`
+- `<CONNECTION_STRING>` - database connection string.
+- `<COMMAND>` - the command to be executed. A complete list of commands is available in the built-in help (`goose help`).
+- `<COMMAND_ARGUMENTS>` - command arguments.
+
+## YDB connection string
+
+To connect to YDB you should use a connection string like:
+
+```
+<protocol>://<host>:<port>/<database_path>?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric
+```
+
+Where:
+- `<protocol>` - connection protocol (`grpc` for an unsecured connection or `grpcs` for a secure [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) connection). The secure connection requires certificates. You should declare certificates like this: `export YDB_SSL_ROOT_CERTIFICATES_FILE=/path/to/ydb/certs/CA.pem`.
+- `<host>` - hostname for connecting to YDB cluster.
+- `<port>` - port for connecting to YDB cluster.
+- `<database_path>` - database in the YDB cluster.
+- `go_query_mode=scripting` - special `scripting` mode for executing queries by default in the YDB driver. In this mode, all requests from goose are sent to the YDB `scripting` service, which allows processing of both [DDL](https://en.wikipedia.org/wiki/Data_definition_language) and [DML](https://en.wikipedia.org/wiki/Data_manipulation_language) SQL statements.
+- `go_fake_tx=scripting` - support for transaction emulation in query execution mode through the YDB `scripting` service. The fact is that in YDB, executing `DDL` `SQL` statements in a transaction is impossible (or incurs significant overhead). In particular, the `scripting` service does not allow interactive transactions (with explicit `Begin`+`Commit`/`Rollback`). Accordingly, the transaction emulation mode does not actually do anything (`noop`) on the `Begin`+`Commit`/`Rollback` calls from `goose`. This trick can, in rare cases, cause an individual migration step to end up in an intermediate state. The YDB team is working on a new `query` service that should eliminate this risk.
+- `go_query_bind=declare,numeric` - support for bindings of auto-inference of YQL types from query parameters (`declare`) and support for bindings of numbered parameters (`numeric`). YQL is a strongly typed language that requires you to explicitly specify the types of query parameters in the body of the `SQL` query itself using the special `DECLARE` statement. Also, YQL only supports named query parameters (for example, `$my_arg`), while the goose core generates SQL queries with numbered parameters (`$1`, `$2`, etc.) . The `declare` and `numeric` bindings modify the original queries from `goose` at the YDB driver level.
+
+If connecting to a local YDB docker container, the connection string could look like:
+
+```
+grpc://localhost:2136/local?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric
+```
+
+Let's store this connection string to an environment variable to re-use it later:
+
+```
+export YDB_CONNECTION_STRING="grpc://localhost:2136/local?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric"
+```
+
+Further examples of calling `goose` commands will contain exactly this connection string.
+
+## Directory with migration files
+
+Let's create a migrations directory and then all `goose` commands should be executed in this directory:
+
+```
+$ mkdir migrations && cd migrations
+```
+
+## Managing migrations using goose
+
+### Creating migration files and applying to database
+
+The migration file can be generated using the `goose create` command:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING create 00001_create_first_table sql
+2024/01/12 11:52:29 Created new file: 20240112115229_00001_create_first_table.sql
+```
+
+This means that the tool has created a new migration file `<timestamp>_00001_create_table_users.sql`:
+```
+$ ls
+20231215052248_00001_create_table_users.sql
+```
+
+After executing the `goose create` command, a migration file `<timestamp>_00001_create_table_users.sql` will be created with the following content :
+
+```
+-- +goose Up
+-- +goose StatementBegin
+SELECT 'up SQL query';
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+SELECT 'down SQL query';
+-- +goose StatementEnd
+```
+
+This migration file structure helps keep the instructions that lead to the next version of the database in context. It is also easy, without unnecessary distractions, to write instructions that roll back a database change.
+
+The migration file consists of two sections:
+
+1. `+goose Up` is an area where we can record the migration steps.
+2. `+goose Down` is an area where we can write queries to revert changes of the `+goose Up` steps.
+
+Goose carefully inserted placeholder queries:
+
+```
+SELECT 'up SQL query';
+```
+
+And
+
+```
+SELECT 'down SQL query';
+```
+
+So that we can replace them with the real migration SQL queries for change the schema for the YDB database, which is accessible through the corresponding connection string.
+
+Let's edit the migration file `<timestamp>_00001_create_table_users.sql` so that when applying the migration we create a table with necessary schema, and when rolling back the migration we delete the created table:
+
+```
+-- +goose Up
+-- +goose StatementBegin
+CREATE TABLE users (
+ id Uint64,
+ username Text,
+ created_at Timestamp,
+ PRIMARY KEY (id)
+);
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+DROP TABLE users;
+-- +goose StatementEnd
+```
+
+We can check status of migrations:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 11:53:50 Applied At Migration
+2024/01/12 11:53:50 =======================================
+2024/01/12 11:53:50 Pending -- 20240112115229_00001_create_first_table.sql
+```
+
+Status `Pending` of migration means that migration has not been applied yet. You can apply such migrations with commands `goose up` or `goose up-by-one`.
+
+Let's apply migration using `goose up`:
+```
+$ goose ydb $YDB_CONNECTION_STRING up
+2024/01/12 11:55:18 OK 20240112115229_00001_create_first_table.sql (93.58ms)
+2024/01/12 11:55:18 goose: successfully migrated database to version: 20240112115229
+```
+
+Let's check the status of migration through `goose status`:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 11:56:00 Applied At Migration
+2024/01/12 11:56:00 =======================================
+2024/01/12 11:56:00 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+```
+
+Status `Pending` changed to timestamp `Fri Jan 12 11:55:18 2024` - this means that migration applied.
+
+There are alternative options to see the applied changes:
+
+{% list tabs %}
+
+- Using YDB UI on http://localhost:8765
+
+ ![YDB UI after the first migration](../_assets/goose-ydb-ui-after-first-migration.png)
+
+- Using YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ └────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+Let's make the second migration that adds a column `password_hash` to the `users` table:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING create 00002_add_column_password_hash_into_table_users sql
+2024/01/12 12:00:57 Created new file: 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Let's edit the migration file `<timestamp>_00002_add_column_password_hash_into_table_users.sql`:
+
+```
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE users ADD COLUMN password_hash Text;
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE users DROP COLUMN password_hash;
+-- +goose StatementEnd
+```
+
+We can check the migration statuses again:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 12:02:40 Applied At Migration
+2024/01/12 12:02:40 =======================================
+2024/01/12 12:02:40 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 12:02:40 Pending -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Now we see the first migration in applied status and the second in pending status.
+
+Let's apply the second migration using `goose up-by-one`:
+```
+$ goose ydb $YDB_CONNECTION_STRING up-by-one
+2024/01/12 12:04:56 OK 20240112120057_00002_add_column_password_hash_into_table_users.sql (59.93ms)
+```
+
+Let's check the migration status through `goose status`:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 12:05:17 Applied At Migration
+2024/01/12 12:05:17 =======================================
+2024/01/12 12:05:17 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 12:05:17 Fri Jan 12 12:04:56 2024 -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Both migration are fully applied.
+
+Let's use the same methods to see the new changes:
+
+{% list tabs %}
+
+- Using YDB UI on http://localhost:8765
+
+ ![YDB UI after apply second migration](../_assets/goose-ydb-ui-after-second-migration.png)
+
+- Using YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌───────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├───────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ │ password_hash │ Utf8? │ │ │
+ └───────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+All subsequent migration files should be created in the same way.
+
+### Downgrading migrations
+
+Let's downgrade (revert) the latest migration using `goose down`:
+```
+$ goose ydb $YDB_CONNECTION_STRING down
+2024/01/12 13:07:18 OK 20240112120057_00002_add_column_password_hash_into_table_users.sql (43ms)
+```
+
+Let's check the migration statuses through `goose status`:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 13:07:36 Applied At Migration
+2024/01/12 13:07:36 =======================================
+2024/01/12 13:07:36 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 13:07:36 Pending -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Status `Fri Jan 12 12:04:56 2024` changed to `Pending` - this means that the latest migration is no longer applied.
+
+Let's check the changes again:
+
+{% list tabs %}
+
+- Using YDB UI on http://localhost:8765
+
+ ![YDB UI after apply first migration](../_assets/goose-ydb-ui-after-first-migration.png)
+
+- Using YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ └────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+
+## Short list of "goose" commands
+
+The `goose` utility allows you to manage migrations via the command line:
+- `goose status` - view the status of applying migrations. For example, `goose ydb $YDB_CONNECTION_STRING status`.
+- `goose up` - apply all known migrations. For example, `goose ydb $YDB_CONNECTION_STRING up`.
+- `goose up-by-one` - apply exactly one “next” migration. For example, `goose ydb $YDB_CONNECTION_STRING up-by-one`.
+- `goose redo` - re-apply the latest migration. For example, `goose ydb $YDB_CONNECTION_STRING redo`.
+- `goose down` - rollback the last migration. For example, `goose ydb $YDB_CONNECTION_STRING down`.
+- `goose reset` - rollback all migrations. For example, `goose ydb $YDB_CONNECTION_STRING reset`.
+
+{% note warning %}
+
+Be careful: the `goose reset` command will revert all your migrations using your statements in blocks `+goose Down`. In many cases it might lead to all data in the database being erased. Make sure you regularly do backups and check that they can be restored to minimize impact of this risk.
+
+{% endnote %}
diff --git a/ydb/docs/en/core/integrations/toc_i.yaml b/ydb/docs/en/core/integrations/toc_i.yaml
index 4aacc38973..ea20cdbe2c 100644
--- a/ydb/docs/en/core/integrations/toc_i.yaml
+++ b/ydb/docs/en/core/integrations/toc_i.yaml
@@ -1,3 +1,5 @@
items:
- name: Log records collection in a Kubernetes cluster using FluentBit and YDB
href: fluent-bit.md
+- name: Schema migrations with goose
+ href: goose.md
diff --git a/ydb/docs/ru/core/_assets/goose-ydb-ui-after-first-migration.png b/ydb/docs/ru/core/_assets/goose-ydb-ui-after-first-migration.png
new file mode 100644
index 0000000000..548b6a1780
--- /dev/null
+++ b/ydb/docs/ru/core/_assets/goose-ydb-ui-after-first-migration.png
Binary files differ
diff --git a/ydb/docs/ru/core/_assets/goose-ydb-ui-after-second-migration.png b/ydb/docs/ru/core/_assets/goose-ydb-ui-after-second-migration.png
new file mode 100644
index 0000000000..a764ce5560
--- /dev/null
+++ b/ydb/docs/ru/core/_assets/goose-ydb-ui-after-second-migration.png
Binary files differ
diff --git a/ydb/docs/ru/core/integrations/goose.md b/ydb/docs/ru/core/integrations/goose.md
new file mode 100644
index 0000000000..edc719df65
--- /dev/null
+++ b/ydb/docs/ru/core/integrations/goose.md
@@ -0,0 +1,362 @@
+# Версионирование схемы данных и миграции в YDB с использованием "goose"
+
+## Введение
+
+Goose – open-source инструмент, который помогает версионировать схему данных в БД и управлять миграциями. Goose поддерживает множество различных баз данных, включая YDB. Goose использует файлы миграций и хранит состояние миграций непосредственно в базе данных в специальной таблице.
+
+## Установка goose
+
+Варианты установки goose описаны в [документации](https://github.com/pressly/goose/blob/master/README.md#install).
+
+## Аргументы запуска goose
+
+Утилита `goose` вызывается командой:
+
+```
+$ goose <DB> <CONNECTION_STRING> <COMMAND> <COMMAND_ARGUMENTS>
+```
+
+где:
+- `<DB>` - движок базы данных, в случае YDB следует писать `goose ydb`
+- `<CONNECTION_STRING>` - строка подключения к базе данных.
+- `<COMMAND>` - команда, которую требуется выполнить. Полный перечень команд доступен во встроенной справке (`goose help`).
+- `<COMMAND_ARGUMENTS>` - аргументы команды.
+
+## Строка подлкючения к YDB
+
+Для подключения к YDB следует использовать строку подключения вида
+
+```
+<protocol>://<host>:<port>/<database_path>?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric
+```
+
+где:
+- `<protocol>` - протокол подключения (`grpc` для незащищенного соединения или `grpcs` для защищенного (`TLS`) соединения). При этом, для защищенного подключения (с `TLS`) следует явно подключить сертификаты `YDB`, например так: `export YDB_SSL_ROOT_CERTIFICATES_FILE=/path/to/ydb/certs/CA.pem`.
+- `<host>` - адрес подключения к YDB.
+- `<port>` - порт подключения к YDB.
+- `<database_path>` - путь к базе данных в кластере YDB.
+- `go_query_mode=scripting` - специальный режим `scripting` выполнения запросов по умолчанию в драйвере YDB. В этом режиме все запросы от goose направляются в YDB сервис `scripting`, который позволяет обрабатывать как `DDL`, так и `DML` инструкции `SQL`.
+- `go_fake_tx=scripting` - поддержка эмуляции транзакций в режиме выполнения запросов через сервис YDB `scripting`. Дело в том, что в YDB выполнение `DDL` инструкций `SQL` в транзакции невозможно (или несет значительные накладные расходы). В частности сервис `scripting` не позволяет делать интерактивные транзакции (с явными `Begin`+`Commit`/`Rollback`). Соответственно, режим эмуляции транзакций на деле не делает ничего (`nop`) на вызовах `Begin`+`Commit`/`Rollback` из `goose`. Этот трюк в редких случаях может привести к тому, что отдельный шаг миграции может оказаться в промежуточном состоянии. Команда YDB работает на новым сервисом `query`, который должен помочь убрать этот риск.
+- `go_query_bind=declare,numeric` - поддержка биндингов авто-выведения типов YQL из параметров запросов (`declare`) и поддержка биндингов нумерованных параметров (`numeric`). Дело в том, что `YQL` - язык со строгой типизацией, требующий явным образом указывать типы параметров запросов в теле самого `SQL`-запроса с помощью специальной инструкции `DECLARE`. Также `YQL` поддерживает только именованные параметры запроса (напрмиер, `$my_arg`), в то время как ядро `goose` генерирует `SQL`-запросы с нумерованными параметрами (`$1`, `$2`, и т.д.). Биндинги `declare` и `numeric` модифицируют исходные запросы из `goose` на уровне драйвера YDB, что позволило в конечном счете встроиться в `goose`.
+
+В случае подключения к ломальному докер-контейнеру YDB строка подключения должна иметь вид:
+
+```
+grpc://localhost:2136/local?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric
+```
+
+Давайте сохраним эту строку в переменную окружения для дальнейшего использования:
+
+```
+export YDB_CONNECTION_STRING="grpc://localhost:2136/local?go_query_mode=scripting&go_fake_tx=scripting&go_query_bind=declare,numeric"
+```
+
+Далее примеры вызова команд `goose` будут содержать именно эту строку подключения.
+
+## Директория с файлами миграций
+
+Создадим директорию migrations и далее все команды `goose` следует выполнять в этой директории:
+
+```
+$ mkdir migrations && cd migrations
+```
+
+## Управление миграциями с помощью goose
+
+### Создание файлов миграций и применение их к базе
+
+Файл миграции можно создать командой `goose create`:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING create 00001_create_first_table sql
+2024/01/12 11:52:29 Created new file: 20240112115229_00001_create_first_table.sql
+```
+
+В результате выполнения команды был создан файл `<timestamp>_00001_create_table_users.sql`:
+```
+$ ls
+20231215052248_00001_create_table_users.sql
+```
+
+Файл `<timestamp>_00001_create_table_users.sql` был создан со следующим содержимым:
+
+```
+-- +goose Up
+-- +goose StatementBegin
+SELECT 'up SQL query';
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+SELECT 'down SQL query';
+-- +goose StatementEnd
+```
+
+Такая структура файла миграции помогает держать в контексте внимания ровно одну миграцию - шаги, чтобы обновить состояние базы, и шаги, чтобы откатить назад измения.
+
+Файл миграции состоит из двух секций. Первая секция `+goose Up` содержит SQL-команды обновления схемы. Вторая секция `+goose Down` отвечает за откат изменений, выполненных в секции `+goose Up`. `Goose` заботливо вставил плейсхолдеры:
+
+```
+SELECT 'up SQL query';
+```
+
+
+```
+SELECT 'down SQL query';
+```
+
+Мы можем заменить эти выражения на необходимые нам SQL-команды создания таблицы `users` и удаления ее в случае отката миграции:
+
+```
+-- +goose Up
+-- +goose StatementBegin
+CREATE TABLE users (
+ id Uint64,
+ username Text,
+ created_at Timestamp,
+ PRIMARY KEY (id)
+);
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+DROP TABLE users;
+-- +goose StatementEnd
+```
+
+Проверим статус миграций:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 11:53:50 Applied At Migration
+2024/01/12 11:53:50 =======================================
+2024/01/12 11:53:50 Pending -- 20240112115229_00001_create_first_table.sql
+```
+
+Статус `Pending` означает, что миграция еще не применена.
+
+Применим миграцию с помощью команды `goose up`:
+```
+$ goose ydb $YDB_CONNECTION_STRING up
+2024/01/12 11:55:18 OK 20240112115229_00001_create_first_table.sql (93.58ms)
+2024/01/12 11:55:18 goose: successfully migrated database to version: 20240112115229
+```
+
+Проверим статус миграций `goose status`:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 11:56:00 Applied At Migration
+2024/01/12 11:56:00 =======================================
+2024/01/12 11:56:00 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+```
+
+Статус `Pending` заменился на временную отметку `Fri Jan 12 11:55:18 2024` - это означает, что миграция успешно применена. Мы также можем убедиться в этом и другими способами:
+
+{% list tabs %}
+
+- Используя YDB UI по адресу http://localhost:8765
+
+ ![YDB UI after apply first migration](../_assets/goose-ydb-ui-after-first-migration.png)
+
+- Используя YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ └────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+Давайте создадим второй файл миграции с добавлением колонки `password_hash` в таблицу `users`:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING create 00002_add_column_password_hash_into_table_users sql
+2024/01/12 12:00:57 Created new file: 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Отредактируем файл `<timestamp>_00002_add_column_password_hash_into_table_users.sql` до следующего содержимого:
+
+```
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE users ADD COLUMN password_hash Text;
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE users DROP COLUMN password_hash;
+-- +goose StatementEnd
+```
+
+Проверим статус миграций:
+
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 12:02:40 Applied At Migration
+2024/01/12 12:02:40 =======================================
+2024/01/12 12:02:40 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 12:02:40 Pending -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Мы видим, что первая миграция применена, а вторая только запланирована (`Pending`).
+
+Применим вторую миграцию с помощью команды `goose up-by-one` (в отличие от `goose uo` команда `goose up-by-one` применяет ровно одну "следующую" миграцию):
+```
+$ goose ydb $YDB_CONNECTION_STRING up-by-one
+2024/01/12 12:04:56 OK 20240112120057_00002_add_column_password_hash_into_table_users.sql (59.93ms)
+```
+
+Проверим статус миграций:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 12:05:17 Applied At Migration
+2024/01/12 12:05:17 =======================================
+2024/01/12 12:05:17 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 12:05:17 Fri Jan 12 12:04:56 2024 -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Обе миграции успешно применены. Убедимся в этом альтернативными способами:
+
+{% list tabs %}
+
+- Используя YDB UI по адресу http://localhost:8765
+
+ ![YDB UI after apply second migration](../_assets/goose-ydb-ui-after-second-migration.png)
+
+- Используя YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌───────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├───────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ │ password_hash │ Utf8? │ │ │
+ └───────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+Все последующие миграции можно создавать аналогичным образом.
+
+### Откат миграции
+
+Откатим последнюю миграцию с помощью команды `goose down`:
+```
+$ goose ydb $YDB_CONNECTION_STRING down
+2024/01/12 13:07:18 OK 20240112120057_00002_add_column_password_hash_into_table_users.sql (43ms)
+```
+
+Проверим статус миграций `goose status`:
+```
+$ goose ydb $YDB_CONNECTION_STRING status
+2024/01/12 13:07:36 Applied At Migration
+2024/01/12 13:07:36 =======================================
+2024/01/12 13:07:36 Fri Jan 12 11:55:18 2024 -- 20240112115229_00001_create_first_table.sql
+2024/01/12 13:07:36 Pending -- 20240112120057_00002_add_column_password_hash_into_table_users.sql
+```
+
+Статус `Fri Jan 12 12:04:56 2024` заменился на статус `Pending` - это означает, что последняя миграция успешно отменена. Мы также можем убедиться в этом и другими способами:
+
+{% list tabs %}
+
+- Используя YDB UI по адресу http://localhost:8765
+
+ ![YDB UI after apply first migration](../_assets/goose-ydb-ui-after-first-migration.png)
+
+- Используя YDB CLI
+
+ ```
+ $ ydb -e grpc://localhost:2136 -d /local scheme describe users
+ <table> users
+
+ Columns:
+ ┌────────────┬────────────┬────────┬─────┐
+ │ Name │ Type │ Family │ Key │
+ ├────────────┼────────────┼────────┼─────┤
+ │ id │ Uint64? │ │ K0 │
+ │ username │ Utf8? │ │ │
+ │ created_at │ Timestamp? │ │ │
+ └────────────┴────────────┴────────┴─────┘
+
+ Storage settings:
+ Store large values in "external blobs": false
+
+ Column families:
+ ┌─────────┬──────┬─────────────┬────────────────┐
+ │ Name │ Data │ Compression │ Keep in memory │
+ ├─────────┼──────┼─────────────┼────────────────┤
+ │ default │ │ None │ │
+ └─────────┴──────┴─────────────┴────────────────┘
+
+ Auto partitioning settings:
+ Partitioning by size: true
+ Partitioning by load: false
+ Preferred partition size (Mb): 2048
+ Min partitions count: 1
+ ```
+
+{% endlist %}
+
+## "Горячий" список команд "goose"
+
+Утилита `goose` позволяет управлять миграциями через командную строку:
+- `goose status` - посмотреть статус применения миграций. Например, `goose ydb $YDB_CONNECTION_STRING status`.
+- `goose up` - применить все известные миграции. Например, `goose ydb $YDB_CONNECTION_STRING up`.
+- `goose up-by-one` - применить ровно одну "следующую" миграцию. Например, `goose ydb $YDB_CONNECTION_STRING up-by-one`.
+- `goose redo` - пере-применить последнюю миграцию. Например, `goose ydb $YDB_CONNECTION_STRING redo`.
+- `goose down` - откатить последнюю миграцию. Например, `goose ydb $YDB_CONNECTION_STRING down`.
+- `goose reset` - откатить все миграции. Например, `goose ydb $YDB_CONNECTION_STRING reset`.
+
+{% note warning %}
+
+Будьте осторожны: команда `goose reset` может удалить все ваши миграции, включая данные в таблицах. Это происходит за счет инструкций в блоке `+goose Down`. Регулярно делайте бекапы и проверяйте их на возможность восстановления, чтобы минимизировать этот риск.
+
+{% endnote %}
diff --git a/ydb/docs/ru/core/integrations/toc_i.yaml b/ydb/docs/ru/core/integrations/toc_i.yaml
index 8b0376cf05..fbcd41c795 100644
--- a/ydb/docs/ru/core/integrations/toc_i.yaml
+++ b/ydb/docs/ru/core/integrations/toc_i.yaml
@@ -1,3 +1,5 @@
items:
- name: Сбор логов в кластере Kubernetes с помощью FluentBit и YDB
href: fluent-bit.md
+- name: goose
+ href: goose.md