From 09c940ea0e51e59ae1ed05ef9cd887ac6bc057f1 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 28 Feb 2026 19:36:48 +0300 Subject: [PATCH] =?UTF-8?q?fix(bookings):=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B1=D0=B5=D1=81=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D1=87=D0=BD=D1=8B=D0=B9=20=D1=86=D0=B8=D0=BA=D0=BB=20bus?= =?UTF-8?q?y()=20=D0=B8=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B8=D0=BC=D1=91=D0=BD=20=D0=BF=D0=B0=D1=81=D1=81?= =?UTF-8?q?=D0=B0=D0=B6=D0=B8=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - генератор demodb зависал при jobs=1 из-за самоблокировки busy() - get_passenger_name() попадал в бесконечный цикл из-за NULL в cume_dist - Что: - добавлен SET LOCAL application_name = 'psql' после вызова generate/continue - добавлена загрузка firstnames.dat и lastnames.dat в Makefile - добавлено заполнение cume_dist для firstnames, lastnames и airport_to_prob - Проверка: - make bookings-generate-day выполняется успешно, создаётся ~45K бронирований --- Makefile | 30 ++++++++++++++++++++++++++++++ _vendor/demodb | 1 + bookings/generate_next_day.sql | 3 +++ 3 files changed, 34 insertions(+) create mode 160000 _vendor/demodb diff --git a/Makefile b/Makefile index bf7f3ec..59d0a76 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,36 @@ bookings-init: bookings-clone-demodb 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 -f /bookings/generate_next_day.sql \ ' + # Проверяем и загружаем reference-данные, если таблицы пустые (иногда \copy в install.sql не срабатывает) + 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 "\ + DO \$$ \ + BEGIN \ + IF (SELECT COUNT(*) FROM gen.airports_data) = 0 THEN \ + COPY gen.airports_data FROM '\''/bookings/demodb/airports_data.dat'\''; \ + COPY gen.airplanes_data FROM '\''/bookings/demodb/airplanes_data.dat'\''; \ + COPY gen.seats FROM '\''/bookings/demodb/seats.dat'\''; \ + COPY gen.firstnames FROM '\''/bookings/demodb/firstnames.dat'\''; \ + COPY gen.lastnames FROM '\''/bookings/demodb/lastnames.dat'\''; \ + END IF; \ + END \$$;" \ + ' + # Заполняем cume_dist для firstnames/lastnames (иначе get_passenger_name зависнет в бесконечном цикле) + 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 "\ + UPDATE gen.firstnames SET cume_dist = sub.cumedist FROM ( \ + SELECT country, grp, name, cume_dist() OVER (PARTITION BY country ORDER BY qty) as cumedist \ + FROM gen.firstnames \ + ) sub WHERE gen.firstnames.country = sub.country AND gen.firstnames.grp = sub.grp AND gen.firstnames.name = sub.name; \ + UPDATE gen.lastnames SET cume_dist = sub.cumedist FROM ( \ + SELECT country, grp, name, cume_dist() OVER (PARTITION BY country, grp ORDER BY qty) as cumedist \ + FROM gen.lastnames \ + ) sub WHERE gen.lastnames.country = sub.country AND gen.lastnames.grp = sub.grp AND gen.lastnames.name = sub.name; \ + UPDATE gen.airport_to_prob SET cume_dist = sub.cumedist FROM ( \ + SELECT departure_airport, arrival_airport, domestic, cume_dist() OVER (PARTITION BY departure_airport, domestic ORDER BY prob) as cumedist \ + FROM gen.airport_to_prob \ + ) sub WHERE gen.airport_to_prob.departure_airport = sub.departure_airport AND gen.airport_to_prob.arrival_airport = sub.arrival_airport AND (gen.airport_to_prob.domestic = sub.domestic OR gen.airport_to_prob.domestic IS NULL);" \ + ' bookings-psql: docker compose -f docker-compose.yml exec bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -U "$$POSTGRES_USER" -d demo' diff --git a/_vendor/demodb b/_vendor/demodb new file mode 160000 index 0000000..d68de19 --- /dev/null +++ b/_vendor/demodb @@ -0,0 +1 @@ +Subproject commit d68de192850237719f09b47688d5f3fc94653ca6 diff --git a/bookings/generate_next_day.sql b/bookings/generate_next_day.sql index 58afdc8..8fb4fdf 100644 --- a/bookings/generate_next_day.sql +++ b/bookings/generate_next_day.sql @@ -35,6 +35,9 @@ BEGIN END IF; -- Ждём завершения фоновых джобов генератора, чтобы данные успели записаться + -- Сбрасываем application_name, чтобы busy() не находил сам себя при синхронном вызове (jobs=1) + -- Примечание: generate()/continue() делают COMMIT внутри себя, поэтому мы уже в новой транзакции + SET LOCAL application_name = 'psql'; WHILE busy() LOOP PERFORM pg_sleep(1); END LOOP;