Всем доброго дня! Пишу здесь впервые. На написание меня этой статьи побудило желание рассказать людям об эффективном способе миграции от внутренней базы данных sqlite3 к внешней БД PostgreSQL. Подобной статьи на Хабре я не нашел, поэтому надеюсь будет полезно.
Я перечитал много статей на эту тему и попробовал различные варианты, но получилось у меня только с одним. Спасибо этому человеку: Oodcode. Так же расскажу про остальные способы и что из них вышло.
Предпосылки
Изначально причиной миграции стали ошибки алертов, приходящие из Grafana (~130 штук). А именно: failed to build query 'A': [sqlstore.max-retries-reached] retry 1: database is locked.
Видимо столько алертов слишком сильно грузили внутреннюю БД и она редко выходила из состояния locked
. Про миграцию писали как на сторонних форумах, так и на форуме Grafana, как о решении этой проблемы.
Подготовка
Grafana хранит все данные во внутренней бд sqlite3 grafana.db.
Необходимо подготовить нашу внешнюю БД Postgres и создать схему и таблицы, чтобы было куда переносить.
Поднимаем docker контейнер с Postgres 16:
docker run --name my_postgres
-e POSTGRES_DB=grafana
-e POSTGRES_USER=grafana
-e POSTGRES_PASSWORD=mypassword
-v /path/to/your/data:/var/lib/postgresql/data
-p 5432:5432
-d postgres:16
Далее необходимо остановить Grafana, временно подключить ее к нашей бд, чтобы создать схему и таблицы.
docker run --name my_grafana
-e GF_DATABASE_TYPE=postgres
-e GF_DATABASE_HOST=HOST:5432
-e GF_DATABASE_NAME=grafana
-e GF_DATABASE_USER=grafana
-e GF_DATABASE_PASSWORD=mypassword
-p 3000:3000
-d grafana/grafana
Для удобства можно подключиться к новой БД и проверить, что все создалось:

Пока наша Grafana остановлена, создайте бэкап grafana.db и можно вернуть Grafana в рабочее состояние.
Теперь мы имеем на руках:
-
Копию grafana.db
-
Подготовленную БД Postgres
Миграция
Способа имеется два:
-
grafana-migrator (не получилось)
Pgloader
Устанавливаем на хост pgloader:
sudo apt update
sudo apt install pgloader
Создаем файл grafana.load
с таким содержанием (не забудь изменить данные для подключения Postgres):
load database
from sqlite:///path-to-grafana.db
into postgresql://grafana:mypassword@host:5432/grafana?sslmode=prefer
with data only, reset sequences
set work_mem to '16MB', maintenance_work_mem to '512 MB';
Запускаем этот конфиг:
pgloader grafana.load
По итогу у нас вылезут ошибки и это нормально. Вывод примерно такой:
2025-04-29T16:15:13.213561-04:00 ERROR Database error 23505: duplicate key value violates unique constraint "org_pkey" DETAIL: Key (id)=(1) already exists. CONTEXT: COPY org, line 1 2025-04-29T16:15:13.233584-04:00 ERROR Database error 23505: duplicate key value violates unique constraint "user_pkey1" DETAIL: Key (id)=(1) already exists. CONTEXT: COPY user, line 1 2025-04-29T16:15:13.258421-04:00 ERROR Database error 23505: duplicate key value violates unique constraint "migration_log_pkey" DETAIL: Key (id)=(1) already exists. CONTEXT: COPY migration_log, line 1 ...
Теперь, когда мы видим с какими таблицами у нас возникли ошибки при миграции данных, мы составим список. Сейчас нам необходимо полностью очистить БД Postgres, снова подключить Grafana к БД для создания схем и таблиц и остановить Grafana.
Возьмем таблицы из нашего списка, их необходимо очистить. Мой список получился такой:
TRUNCATE TABLE alert_configuration;
TRUNCATE TABLE alert_configuration_history;
TRUNCATE TABLE signing_key;
TRUNCATE TABLE"user";
TRUNCATE TABLE org;
TRUNCATE TABLE org_user;
TRUNCATE TABLE dashboard_acl;
TRUNCATE TABLE cache_data;
TRUNCATE TABLE kv_store;
TRUNCATE TABLE migration_log;
TRUNCATE TABLE server_lock;
После этого снова запускаем миграцию:
pgloader grafana.load
Утилита выдаст WARNING’и (это нормально) и итоговый отчет:
2023-05-29T15:24:21.045861-04:00 LOG report summary reset table name errors rows bytes total time --------------------------- --------- --------- --------- -------------- fetch 0 0 0.000s fetch meta data 0 63 0.044s Drop Foreign Keys 0 0 0.000s --------------------------- --------- --------- --------- -------------- "user" 0 20 4.2 kB 0.530s migration_log 0 487 81.1 kB 0.562s org 0 1 0.1 kB 0.546s dashboard_tag 0 1 0.0 kB 1.023s dashboard_provisioning 0 0 1.093s api_key 0 0 1.517s quota 0 0 1.585s star 0 5 0.0 kB 0.814s session 0 0 2.090s org_user 0 20 1.1 kB 1.070s playlist_item 0 0 2.058s dashboard 0 36 1.0 MB 1.420s alert 0 12 21.0 kB 2.549s annotation 0 4490 902.4 kB 2.831s data_source 0 2 0.5 kB 1.555s dashboard_snapshot 0 1 6.1 kB 1.968s plugin_setting 0 0 2.042s playlist 0 0 2.493s preferences 0 3 0.3 kB 2.600s alert_notification 0 6 1.6 kB 2.944s test_data 0 0 3.071s team 0 6 0.3 kB 3.533s dashboard_acl 0 12 0.7 kB 3.642s login_attempt 0 0 4.112s alert_notification_state 0 22 0.8 kB 4.214s user_auth_token 0 12 3.8 kB 4.607s temp_user 0 9 1.2 kB 4.703s annotation_tag 0 0 5.115s alert_instance 0 16 4.6 kB 5.137s alert_rule_version 0 302 548.1 kB 5.674s library_element 0 0 5.595s ngalert_configuration 0 0 6.066s data_keys 0 110 21.5 kB 6.111s role 0 28 3.1 kB 6.533s user_role 0 19 0.6 kB 6.532s query_history 0 1 0.3 kB 7.007s query_history_star 0 0 6.989s secrets 0 2 0.4 kB 7.472s entity_event 0 0 7.464s file 0 0 8.040s seed_assignment 0 0 7.973s folder 0 0 8.446s dashboard_version 0 406 14.8 MB 4.523s team_member 0 22 1.2 kB 3.185s tag 0 0 3.709s user_auth 0 19 33.9 kB 4.238s server_lock 0 4 0.2 kB 4.762s cache_data 0 0 4.839s alert_rule_tag 0 0 5.298s short_url 0 2 0.3 kB 5.343s alert_rule 0 15 26.0 kB 5.791s alert_configuration 0 1 3.1 kB 5.826s library_element_connection 0 0 6.253s kv_store 0 5 0.5 kB 6.292s permission 0 160 13.1 kB 6.720s team_role 0 6 0.2 kB 6.786s builtin_role 0 3 0.2 kB 7.238s provenance_type 0 0 7.297s alert_image 0 0 7.713s correlation 0 0 7.783s dashboard_public 0 0 8.211s file_meta 0 0 8.265s alert_configuration_history 0 19 78.7 kB 8.362s --------------------------- --------- --------- --------- -------------- COPY Threads Completion 0 4 8.694s Reset Sequences 0 55 0.837s Create Foreign Keys 0 0 0.000s Install Comments 0 0 0.000s --------------------------- --------- --------- --------- -------------- Total import time ✓ 6285 17.5 MB 9.532s
После этого можно подключить Grafana к БД Postgres и продолжать работу
Grafana-migrator
Этот способ намного проще, но с Grafana 11.3.5 и PostgreSQL 16 решение не сработало. Но это не мешает попробовать вам.
Это утилита из github: https://github.com/wbh1/grafana-sqlite-to-postgres
Скачиваем бинарник, делаем его исполняемым и запускаем с grafana.db:
chmod +x grafana-migrate_linux_amd64-v2.2.5
./grafana-migrate_linux_amd64-v2.2.5 /var/lib/grafana/grafana.db 'postgres://grafana:
mypassword@localhost:5432
/grafana?sslmode=disable'
Но у меня вылезала похожая ошибка:
INFO[2024-07-25T14:48:29+03:00] SQLlite file: grafana.db
INFO[2024-07-25T14:48:29+03:00] Dump directory: /tmp
INFO[2024-07-25T14:48:29+03:00] sqlite3 command exists
INFO[2024-07-25T14:48:30+03:00] sqlite3 database dumped to /tmp/grafana.sql
INFO[2024-07-25T14:48:33+03:00] CREATE statements removed from dump file
INFO[2024-07-25T14:48:43+03:00] sqlite3 dump sanitized
INFO[2024-07-25T14:48:48+03:00] migration_log statements removed
INFO[2024-07-25T14:48:49+03:00] char keyword transformed
INFO[2024-07-25T14:48:50+03:00] hex-encoded data values wrapped for insertion
FATAL[2024-07-25T14:48:51+03:00] pq: invalid input syntax for type bigint: «AbiGL-yVz» INSERT INTO «playlist» VALUES(3,’Live Managment’,’5m’,5,’AbiGL-yVz’,0,0) — failed to import dump file to Postgres.
P. S. Я бы хотел привести больше скринов и выводов из консоли, но к моменту написания статьи этого уже нет. Пару моментов позаимствовал у Oodcode и из официального репозитория grafana‑migrator.
ссылка на оригинал статьи https://habr.com/ru/articles/897400/
Добавить комментарий