bookings debug
This commit is contained in:
@@ -15,6 +15,8 @@ BOOKINGS_DB_NAME=bookings
|
|||||||
BOOKINGS_DB_PORT=5434
|
BOOKINGS_DB_PORT=5434
|
||||||
# Начальная дата модельного времени для генерации демобазы
|
# Начальная дата модельного времени для генерации демобазы
|
||||||
BOOKINGS_START_DATE=2017-01-01
|
BOOKINGS_START_DATE=2017-01-01
|
||||||
|
# Количество дней для первой генерации (потом добавляем по одному дню)
|
||||||
|
BOOKINGS_INIT_DAYS=30
|
||||||
# Количество параллельных джобов генератора (по умолчанию 1)
|
# Количество параллельных джобов генератора (по умолчанию 1)
|
||||||
BOOKINGS_JOBS=1
|
BOOKINGS_JOBS=1
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ PYTHON_VERSION := 3.11
|
|||||||
DEMODB_REPO := https://github.com/postgrespro/demodb.git
|
DEMODB_REPO := https://github.com/postgrespro/demodb.git
|
||||||
DEMODB_COMMIT := d68de192850237719f09b47688d5f3fc94653ca6
|
DEMODB_COMMIT := d68de192850237719f09b47688d5f3fc94653ca6
|
||||||
BOOKINGS_JOBS ?= 1
|
BOOKINGS_JOBS ?= 1
|
||||||
|
BOOKINGS_START_DATE ?= 2017-01-01
|
||||||
|
BOOKINGS_INIT_DAYS ?= 30
|
||||||
|
|
||||||
.PHONY: up down airflow-init logs gp-psql ddl-gp \
|
.PHONY: up down airflow-init logs gp-psql ddl-gp \
|
||||||
bookings-clone-demodb bookings-init bookings-psql bookings-generate-day \
|
bookings-clone-demodb bookings-init bookings-psql bookings-generate-day \
|
||||||
@@ -42,23 +44,21 @@ bookings-init: bookings-clone-demodb
|
|||||||
CONNSTR="dbname=demo user=$$POSTGRES_USER password=$$POSTGRES_PASSWORD"; \
|
CONNSTR="dbname=demo user=$$POSTGRES_USER password=$$POSTGRES_PASSWORD"; \
|
||||||
PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -c "ALTER DATABASE demo SET gen.connstr='\''$$CONNSTR'\'';" \
|
PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -c "ALTER DATABASE demo SET gen.connstr='\''$$CONNSTR'\'';" \
|
||||||
'
|
'
|
||||||
|
docker compose -f docker-compose.yml exec bookings-db bash -lc '\
|
||||||
|
PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d demo -c "\
|
||||||
|
ALTER DATABASE demo SET bookings.start_date = '\''$(BOOKINGS_START_DATE)'\''; \
|
||||||
|
ALTER DATABASE demo SET bookings.init_days = '\''$(BOOKINGS_INIT_DAYS)'\''; \
|
||||||
|
ALTER DATABASE demo SET bookings.jobs = '\''$(BOOKINGS_JOBS)'\'';" \
|
||||||
|
'
|
||||||
# Генерируем первый день данных, чтобы база не оставалась пустой
|
# Генерируем первый день данных, чтобы база не оставалась пустой
|
||||||
docker compose -f docker-compose.yml exec -T bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d demo -v start_date="$${BOOKINGS_START_DATE:-2017-01-01}" -v jobs="$(BOOKINGS_JOBS)" <<'"'"'SQL'"'"'
|
docker compose -f docker-compose.yml exec bookings-db bash -lc 'printf "SET bookings.start_date = '\''$(BOOKINGS_START_DATE)'\'';\\nSET bookings.init_days = '\''$(BOOKINGS_INIT_DAYS)'\'';\\nSET bookings.jobs = '\''$(BOOKINGS_JOBS)'\'';\\n\\\\i /bookings/generate_next_day.sql\\n" | PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d demo'
|
||||||
SET bookings.start_date = :'start_date';
|
|
||||||
\i /bookings/generate_next_day.sql
|
|
||||||
RESET bookings.start_date;
|
|
||||||
SQL'
|
|
||||||
|
|
||||||
bookings-psql:
|
bookings-psql:
|
||||||
docker compose -f docker-compose.yml exec bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -U "$$POSTGRES_USER" -d demo'
|
docker compose -f docker-compose.yml exec bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -U "$$POSTGRES_USER" -d demo'
|
||||||
|
|
||||||
bookings-generate-day:
|
bookings-generate-day:
|
||||||
docker compose -f docker-compose.yml up -d bookings-db
|
docker compose -f docker-compose.yml up -d bookings-db
|
||||||
docker compose -f docker-compose.yml exec -T bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d demo -v start_date="$${BOOKINGS_START_DATE:-2017-01-01}" -v jobs="$(BOOKINGS_JOBS)" <<'"'"'SQL'"'"'
|
docker compose -f docker-compose.yml exec bookings-db bash -lc 'printf "SET bookings.start_date = '\''$(BOOKINGS_START_DATE)'\'';\\nSET bookings.init_days = '\''$(BOOKINGS_INIT_DAYS)'\'';\\nSET bookings.jobs = '\''$(BOOKINGS_JOBS)'\'';\\n\\\\i /bookings/generate_next_day.sql\\n" | PGPASSWORD="$$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -U "$$POSTGRES_USER" -d demo'
|
||||||
SET bookings.start_date = :'start_date';
|
|
||||||
\i /bookings/generate_next_day.sql
|
|
||||||
RESET bookings.start_date;
|
|
||||||
SQL'
|
|
||||||
|
|
||||||
dev-setup:
|
dev-setup:
|
||||||
$(UV) python install $(PYTHON_VERSION)
|
$(UV) python install $(PYTHON_VERSION)
|
||||||
|
|||||||
@@ -202,7 +202,8 @@ make logs # Следить за логами Airflow
|
|||||||
- `BOOKINGS_DB_PASSWORD` — пароль пользователя (по умолчанию: bookings)
|
- `BOOKINGS_DB_PASSWORD` — пароль пользователя (по умолчанию: bookings)
|
||||||
- `BOOKINGS_DB_NAME` — база данных, из которой запускается установка генератора (по умолчанию: bookings)
|
- `BOOKINGS_DB_NAME` — база данных, из которой запускается установка генератора (по умолчанию: bookings)
|
||||||
- `BOOKINGS_DB_PORT` — внешний порт для подключения к контейнеру bookings-db (по умолчанию: 5434)
|
- `BOOKINGS_DB_PORT` — внешний порт для подключения к контейнеру bookings-db (по умолчанию: 5434)
|
||||||
- `BOOKINGS_START_DATE` — начальная дата модельного времени для первой генерации данных (по умолчанию: 2017-01-01, генерируем первые сутки сразу после `make bookings-init`)
|
- `BOOKINGS_START_DATE` — начальная дата модельного времени (по умолчанию: 2017-01-01)
|
||||||
|
- `BOOKINGS_INIT_DAYS` — сколько дней сгенерировать при первой инициализации (по умолчанию: 30)
|
||||||
- `BOOKINGS_JOBS` — число параллельных джобов генератора bookings (по умолчанию: 1)
|
- `BOOKINGS_JOBS` — число параллельных джобов генератора bookings (по умолчанию: 1)
|
||||||
|
|
||||||
### CSV pipeline
|
### CSV pipeline
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
-- Если база пуста, берём стартовую дату из параметра :start_date (формат YYYY-MM-DD).
|
-- Если база пуста, берём стартовую дату из GUC bookings.start_date (по умолчанию: 2017-01-01).
|
||||||
-- psql не умеет подставлять :start_date внутрь DO $$...$$, поэтому прокидываем дату через GUC.
|
|
||||||
SET bookings.start_date = :'start_date';
|
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_max_book_date timestamptz;
|
v_max_book_date timestamptz;
|
||||||
v_start_date timestamptz;
|
v_start_date timestamptz;
|
||||||
v_end_date timestamptz;
|
v_end_date timestamptz;
|
||||||
|
v_jobs integer := COALESCE(current_setting('bookings.jobs', true), '1')::integer;
|
||||||
|
v_init_days integer := COALESCE(current_setting('bookings.init_days', true), '1')::integer;
|
||||||
|
v_start_cfg text := COALESCE(current_setting('bookings.start_date', true), '2017-01-01');
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Проверяем, что демобаза установлена
|
-- Проверяем, что демобаза установлена
|
||||||
IF to_regclass('bookings.bookings') IS NULL THEN
|
IF to_regclass('bookings.bookings') IS NULL THEN
|
||||||
@@ -16,20 +17,20 @@ BEGIN
|
|||||||
SELECT max(book_date) INTO v_max_book_date FROM bookings.bookings;
|
SELECT max(book_date) INTO v_max_book_date FROM bookings.bookings;
|
||||||
|
|
||||||
IF v_max_book_date IS NULL THEN
|
IF v_max_book_date IS NULL THEN
|
||||||
-- База пустая: берём стартовую дату из переданного параметра
|
-- База пустая: берём стартовую дату из конфигурации (или дефолтную)
|
||||||
v_start_date := date_trunc('day', current_setting('bookings.start_date')::timestamptz);
|
v_start_date := date_trunc('day', v_start_cfg::timestamptz);
|
||||||
ELSE
|
ELSE
|
||||||
-- Продолжаем с дня, следующего за максимальной датой
|
-- Продолжаем с дня, следующего за максимальной датой
|
||||||
v_start_date := date_trunc('day', v_max_book_date) + interval '1 day';
|
v_start_date := date_trunc('day', v_max_book_date) + interval '1 day';
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
v_end_date := v_start_date + interval '1 day';
|
|
||||||
|
|
||||||
-- Первая генерация вызывает generate(), последующие — continue()
|
-- Первая генерация вызывает generate(), последующие — continue()
|
||||||
IF v_max_book_date IS NULL THEN
|
IF v_max_book_date IS NULL THEN
|
||||||
CALL generate(v_start_date, v_end_date, :'jobs');
|
v_end_date := v_start_date + (v_init_days || ' days')::interval;
|
||||||
|
CALL generate(v_start_date, v_end_date, v_jobs);
|
||||||
ELSE
|
ELSE
|
||||||
CALL continue(v_end_date, :'jobs');
|
v_end_date := v_start_date + interval '1 day';
|
||||||
|
CALL continue(v_end_date, v_jobs);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Ждём завершения фоновых джобов генератора, чтобы данные успели записаться
|
-- Ждём завершения фоновых джобов генератора, чтобы данные успели записаться
|
||||||
@@ -37,6 +38,4 @@ BEGIN
|
|||||||
PERFORM pg_sleep(1);
|
PERFORM pg_sleep(1);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
PERFORM dblink_disconnect(unnest(dblink_get_connections()));
|
PERFORM dblink_disconnect(unnest(dblink_get_connections()));
|
||||||
|
|
||||||
END $$;
|
END $$;
|
||||||
RESET bookings.start_date;
|
|
||||||
|
|||||||
@@ -12,6 +12,24 @@ _Этот файл внутренний, удалить перед итогов
|
|||||||
## Текущее состояние
|
## Текущее состояние
|
||||||
- `Makefile` очищен: убраны автопатчи demodb; добавлены `DEMODB_REPO/DEMODB_COMMIT` с фиксированным хешем `d68de1…`, таргет снова исполняется. `BOOKINGS_JOBS` задаёт число джобов генерации (по умолчанию 1).
|
- `Makefile` очищен: убраны автопатчи demodb; добавлены `DEMODB_REPO/DEMODB_COMMIT` с фиксированным хешем `d68de1…`, таргет снова исполняется. `BOOKINGS_JOBS` задаёт число джобов генерации (по умолчанию 1).
|
||||||
- `.gitignore` дополнен `bookings/demodb/` (клонируем по требованию, не коммитим).
|
- `.gitignore` дополнен `bookings/demodb/` (клонируем по требованию, не коммитим).
|
||||||
- `bookings-init` теперь после установки сразу генерирует 1 день (дата из `BOOKINGS_START_DATE`, по умолчанию 2017-01-01), используя обертку `generate_next_day.sql`.
|
- `bookings-init` теперь после установки запускает генерацию (дата из `BOOKINGS_START_DATE`, дни из `BOOKINGS_INIT_DAYS`, параллельность `BOOKINGS_JOBS`), используя обертку `generate_next_day.sql`.
|
||||||
- `generate_next_day.sql` принимает `:jobs` и ожидает завершения `busy()`, закрывая dblink.
|
- `generate_next_day.sql` читает GUC `bookings.start_date/init_days/jobs`, вызывает `generate/continue`, ждёт `busy()`, закрывает dblink.
|
||||||
- Генерация через `make` надо подтвердить повторно (в DBeaver генерация работает, но медленно на больших окнах; по умолчанию делаем сутки, далее — по одному дню через `bookings-generate-day`).
|
- Генерация через `make` остаётся нестабильной: в логах обрывы dblink, данные не появляются.
|
||||||
|
|
||||||
|
## Текущее состояние тестов/проблем
|
||||||
|
- Прогон `make bookings-init` с `BOOKINGS_JOBS=2`, `BOOKINGS_INIT_DAYS=30`: установка ок, GUC/`gen.connstr` выставлены, `Starting job 1/2: ok`, но `bookings.bookings` пустая, в `gen.events` висит `INIT`, `busy()` может быть `t`. Логи: `could not send data to client: Broken pipe` / `connection to client lost` при `TRUNCATE ... CASCADE` в `do_init`.
|
||||||
|
- С `BOOKINGS_JOBS=1` аналогично. Ручная генерация в DBeaver (CALL generate(now(), now()+interval '1 year')) ранее шла медленно, так что проблема может быть в запуске через `docker exec`/pipe или в dblink-подключениях.
|
||||||
|
|
||||||
|
## Идеи/следующие шаги
|
||||||
|
- Проверить генерацию внутри контейнера через here-doc без пайпа:
|
||||||
|
```
|
||||||
|
docker compose exec -T bookings-db psql -U bookings -d demo <<'SQL'
|
||||||
|
SET bookings.start_date = '2017-01-01';
|
||||||
|
SET bookings.init_days = '30';
|
||||||
|
SET bookings.jobs = '1';
|
||||||
|
\i /bookings/generate_next_day.sql
|
||||||
|
SQL
|
||||||
|
```
|
||||||
|
Наблюдать `busy()`, `gen.log`, `gen.events/events_history`.
|
||||||
|
- Если так ок — переписать Makefile под такой запуск. Если нет — попробовать `gen.connstr` с `host=localhost` и/или оставить `jobs=1` без dblink.
|
||||||
|
- Пока нестабильно, держать `init_days` небольшим (1–3), чтобы быстро видеть прогресс.
|
||||||
|
|||||||
Reference in New Issue
Block a user