Merge branch 'fix/greenplum-pxf'
This commit is contained in:
@@ -22,9 +22,10 @@ stop:
|
||||
docker compose -f docker-compose.yml stop
|
||||
|
||||
down:
|
||||
docker compose -f docker-compose.yml down -v
|
||||
docker compose -f docker-compose.yml down
|
||||
|
||||
clean: down
|
||||
clean:
|
||||
docker compose -f docker-compose.yml down -v
|
||||
|
||||
airflow-init:
|
||||
docker compose -f docker-compose.yml run --rm airflow-init
|
||||
|
||||
@@ -82,11 +82,12 @@ CSV-файлы после выполнения DAG остаются в дире
|
||||
Если после изменений что‑то «сломалось»:
|
||||
|
||||
```bash
|
||||
make down # Остановить и стереть данные в контейнерах
|
||||
make down # Остановить и удалить контейнеры/сети (volumes сохраняются)
|
||||
make up
|
||||
```
|
||||
|
||||
Это помогает, когда Greenplum не стартует из‑за «грязной» остановки и внутренних файлов.
|
||||
Если проблема связана с «грязной» остановкой и данными в томах (например, Greenplum не стартует),
|
||||
используйте полный reset: `make clean && make up` (данные в Docker-томах будут потеряны).
|
||||
|
||||
---
|
||||
|
||||
@@ -150,10 +151,10 @@ make gp-psql # Подключение к Greenplum
|
||||
|
||||
- базовые конфиги PXF копируются в `PXF_BASE/conf` (если их ещё нет);
|
||||
- создаются каталоги `PXF_BASE/run` и `PXF_BASE/logs`;
|
||||
- `CREATE EXTENSION pxf` выполняется автоматически, когда Greenplum становится доступен.
|
||||
- `CREATE EXTENSION pxf` выполняется автоматически, когда Greenplum становится доступен (с ретраями).
|
||||
|
||||
Healthcheck сервиса `greenplum` учитывает не только готовность Greenplum, но и запуск PXF —
|
||||
это нужно, чтобы Airflow не стартовал раньше PXF.
|
||||
Healthcheck сервиса `greenplum` учитывает не только готовность Greenplum, но и запуск PXF,
|
||||
а также наличие `extension pxf` — это нужно, чтобы Airflow не стартовал раньше PXF.
|
||||
|
||||
Сборка и запуск:
|
||||
|
||||
@@ -240,6 +241,9 @@ make bookings-psql # Подключиться к демобазе bookings
|
||||
# Проверка данных
|
||||
make logs # Следить за логами Airflow
|
||||
|
||||
# Логи задач Airflow сохраняются в Docker-томе `airflow_logs`
|
||||
# и переживают `docker compose down`/`up` (удаляются при `docker compose down -v` / `make clean`).
|
||||
|
||||
# Контроль генерации bookings
|
||||
docker compose -f docker-compose.yml exec bookings-db bash -lc 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -d demo -c "SELECT busy();"'
|
||||
# busy() = t — генерация ещё идёт; f — завершена. При необходимости можно вызвать CALL abort(); и запустить генерацию заново.
|
||||
@@ -409,11 +413,12 @@ load_bookings_to_stg = PostgresOperator(
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| Airflow UI не открывается | Дождитесь сообщения `Listening at: http://0.0.0.0:8080` в логах (`make logs`) |
|
||||
| `database "demo" does not exist` в bookings‑DAG | Вы сделали полный reset с удалением томов (`docker compose down -v` / `make clean`), поэтому демобаза bookings не установлена. Запустите `make bookings-init` и повторите DAG. |
|
||||
| Ошибка подключения к Greenplum | Убедитесь, что контейнер `greenplum` стал статусом `healthy` (проверьте `docker compose ps`) |
|
||||
| Не открывается порт 8080/5433/5434/5435 | Проверьте, что эти порты не заняты локальными сервисами; при необходимости остановите их или измените порты в `.env`/`docker-compose.yml` |
|
||||
| Нет файла в `./data` после запуска DAG | Проверьте логи задачи `generate_csv`, убедитесь, что `CSV_DIR` смонтирован в docker-compose |
|
||||
| Команда `make` не найдена | Используйте полные команды `docker compose` или установите make |
|
||||
| Greenplum не стартует/падает при старте | Выполните `make down`, затем `make up` (очищает тома и поднимает заново, включая авто‑инициализацию Airflow) |
|
||||
| Greenplum не стартует/падает при старте | Попробуйте `make down && make up`. Если не помогло — полный reset: `make clean && make up` (удалит тома). |
|
||||
| `protocol "pxf" does not exist` | Перезапустите `greenplum` и повторите `bookings_stg_ddl`/`make ddl-gp` — расширение `pxf` создаётся автоматически при старте контейнера. |
|
||||
| PXF не отвечает (Connection refused к порту 5888) | Проверьте `pxf cluster status` в контейнере `greenplum` и перезапустите сервис `greenplum`. |
|
||||
| PXF не подхватывает изменения конфигов | Пересоберите образ (`make build`) и перезапустите `greenplum`. Для принудительной перезаписи файлов задайте `PXF_SEED_OVERWRITE=1`. |
|
||||
|
||||
+4
-3
@@ -37,14 +37,15 @@
|
||||
- Проверить, что все 5 задач Success и логи содержат `Проверка пройдена`.
|
||||
|
||||
- DAG `bookings_to_gp_stage` (полная проверка цепочки bookings → Greenplum STG):
|
||||
- предварительно выполнить один раз: `make bookings-init` (инициализация демо‑БД bookings) и `make ddl-gp` (создаёт `stg.bookings_ext` и `stg.bookings` в Greenplum);
|
||||
- предварительно выполнить один раз: `make bookings-init` (установка демобазы `demo` в контейнере `bookings-db`) и `make ddl-gp` (создаёт `stg.bookings_ext` и `stg.bookings` в Greenplum);
|
||||
- важно: DAG `bookings_stg_ddl` **не** создаёт базу `demo` в `bookings-db`; если вы делали `docker compose down -v` / `make clean`, `make bookings-init` обязателен;
|
||||
- включить DAG `bookings_to_gp_stage` и запустить `Trigger DAG`;
|
||||
- убедиться, что все задачи (`generate_bookings_day`, `load_bookings_to_stg`, `check_row_counts`, `finish_summary`) завершились со статусом Success;
|
||||
- при желании проверить данные: в `bookings-db` появился новый день, а в Greenplum в `stg.bookings` — строки с актуальным `batch_id` (см. пример запросов в разделе 5).
|
||||
|
||||
- (опционально, для менторов/разработчиков) Smoke-тест DAG через Airflow CLI без UI:
|
||||
- `docker compose -f docker-compose.yml exec gp_airflow_webserver airflow dags test bookings_to_gp_stage 2024-01-01` — прогоняет `bookings_to_gp_stage` целиком в «off-line» режиме;
|
||||
- `docker compose -f docker-compose.yml exec gp_airflow_webserver airflow dags trigger bookings_to_gp_stage` — создаёт реальный запуск DAG (логи и статус можно смотреть либо через UI, либо командой `airflow tasks list`/`airflow tasks logs` внутри контейнера).
|
||||
- `docker compose -f docker-compose.yml exec airflow-webserver airflow dags test bookings_to_gp_stage 2024-01-01` — прогоняет `bookings_to_gp_stage` целиком в «off-line» режиме;
|
||||
- `docker compose -f docker-compose.yml exec airflow-webserver airflow dags trigger bookings_to_gp_stage` — создаёт реальный запуск DAG (логи и статус можно смотреть либо через UI, либо командой `airflow tasks list`/`airflow tasks logs` внутри контейнера).
|
||||
|
||||
## 5. Проверка данных в Greenplum
|
||||
- `make gp-psql` — запустить psql в контейнере от имени `gpadmin`.
|
||||
|
||||
+8
-3
@@ -10,6 +10,7 @@ x-airflow-common-volumes: &airflow-volumes
|
||||
- ./airflow/dags:/opt/airflow/dags
|
||||
- ./sql:/sql:ro
|
||||
- airflow_data:/opt/airflow/data
|
||||
- airflow_logs:/opt/airflow/logs
|
||||
|
||||
x-airflow-common-depends: &airflow-depends
|
||||
pgmeta:
|
||||
@@ -86,7 +87,7 @@ services:
|
||||
healthcheck:
|
||||
# Ждём не только доступность GPDB, но и готовность PXF,
|
||||
# чтобы Airflow не стартовал раньше PXF.
|
||||
test: [ "CMD-SHELL", "/usr/local/greenplum-db/bin/pg_isready -h 127.0.0.1 -p 5432 -U ${GP_USER:-gpadmin} -d ${GP_DB:-gp_dwh} && su - ${GP_USER:-gpadmin} -c '/usr/local/pxf/bin/pxf cluster status' >/dev/null 2>&1" ]
|
||||
test: [ "CMD-SHELL", "/usr/local/greenplum-db/bin/pg_isready -h 127.0.0.1 -p 5432 -U ${GP_USER:-gpadmin} -d ${GP_DB:-gp_dwh} && PGPASSWORD=${GP_PASSWORD:-gpadmin} /usr/local/greenplum-db/bin/psql -h 127.0.0.1 -p 5432 -U ${GP_USER:-gpadmin} -d ${GP_DB:-gp_dwh} -t -A -c \"SELECT 1 FROM pg_extension WHERE extname='pxf';\" | grep -q 1 && su - ${GP_USER:-gpadmin} -c '/usr/local/pxf/bin/pxf cluster status' >/dev/null 2>&1" ]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
@@ -101,13 +102,14 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
<<: *airflow-env
|
||||
command: airflow webserver
|
||||
command: bash -lc "rm -f /opt/airflow/airflow-webserver.pid && exec airflow webserver"
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./airflow/dags:/opt/airflow/dags
|
||||
- ./sql:/sql:ro
|
||||
- airflow_data:/opt/airflow/data
|
||||
- airflow_logs:/opt/airflow/logs
|
||||
- ./airflow/requirements.txt:/opt/airflow/requirements.txt
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
@@ -132,6 +134,7 @@ services:
|
||||
- ./airflow/dags:/opt/airflow/dags
|
||||
- ./sql:/sql:ro
|
||||
- airflow_data:/opt/airflow/data
|
||||
- airflow_logs:/opt/airflow/logs
|
||||
- ./airflow/requirements.txt:/opt/airflow/requirements.txt
|
||||
depends_on:
|
||||
<<: *airflow-depends
|
||||
@@ -150,10 +153,11 @@ services:
|
||||
- ./airflow/dags:/opt/airflow/dags
|
||||
- ./sql:/sql:ro
|
||||
- airflow_data:/opt/airflow/data
|
||||
- airflow_logs:/opt/airflow/logs
|
||||
command: >
|
||||
bash -lc "
|
||||
set -e;
|
||||
mkdir -p /opt/airflow/data && chown -R airflow:root /opt/airflow/data;
|
||||
mkdir -p /opt/airflow/data /opt/airflow/logs && chown -R airflow:root /opt/airflow/data /opt/airflow/logs;
|
||||
# Дожидаемся готовности БД ретрая миграции
|
||||
for i in {1..30}; do
|
||||
su -s /bin/bash airflow -c \"PATH='/home/airflow/.local/bin:$${PATH}' airflow db migrate\" && break || echo 'waiting for pgmeta' && sleep 3;
|
||||
@@ -170,3 +174,4 @@ volumes:
|
||||
bookings_data:
|
||||
greenplum_data:
|
||||
airflow_data:
|
||||
airflow_logs:
|
||||
|
||||
@@ -101,13 +101,13 @@
|
||||
- причина: файлы уже лежат в `PXF_BASE` на томе, а seed из образа по умолчанию не перетирает их;
|
||||
- решение: `make build` + restart `greenplum` + (при необходимости) `PXF_SEED_OVERWRITE=1`.
|
||||
|
||||
## 9. Известная проблема: `protocol "pxf" does not exist` на «холодном старте»
|
||||
## 9. Известная проблема: `protocol "pxf" does not exist` на «холодном старте» (исправлено)
|
||||
|
||||
Иногда (и это воспроизводится в `./scripts/e2e_smoke.sh`) при первом `make ddl-gp` можно получить:
|
||||
Раньше (воспроизводилось в `./scripts/e2e_smoke.sh`) при первом `make ddl-gp` можно было получить:
|
||||
|
||||
`ERROR: protocol "pxf" does not exist`
|
||||
|
||||
### Почему так происходит
|
||||
### Почему так происходило
|
||||
|
||||
В базовом `/start_gpdb.sh` из образа Greenplum создание расширения `pxf` связано с проверкой
|
||||
файла `${PXF_BASE}/conf/pxf-env.sh`:
|
||||
@@ -116,35 +116,26 @@
|
||||
`CREATE EXTENSION IF NOT EXISTS pxf`;
|
||||
- если `pxf-env.sh` **уже существует**, этот блок **пропускается**, и расширение может не появиться.
|
||||
|
||||
При этом наш ensure‑скрипт `pxf/init/10_pxf_bookings.sh` копирует `pxf-env.sh` в `${PXF_BASE}`
|
||||
ещё до запуска Greenplum, из‑за чего базовый скрипт считает PXF “уже настроенным” и
|
||||
пропускает создание расширения.
|
||||
При этом наш ensure‑скрипт `pxf/init/10_pxf_bookings.sh` копировал `pxf-env.sh` в `${PXF_BASE}`
|
||||
ещё до запуска Greenplum, из‑за чего базовый скрипт считал PXF “уже настроенным” и
|
||||
пропускал создание расширения.
|
||||
|
||||
Отдельно `/start_greenplum_with_pxf.sh` пытается выполнить `CREATE EXTENSION IF NOT EXISTS pxf`
|
||||
в фоне, но это может “не попасть” в окно готовности базы (гонка при старте), поэтому после старта:
|
||||
- PXF может быть “running” (`pxf cluster status`), но
|
||||
- `protocol pxf` в базе ещё не создан.
|
||||
### Что изменили
|
||||
|
||||
### Как проверить
|
||||
- создание `extension pxf` вынесено в `start_greenplum_with_pxf.sh` и обёрнуто ретраями;
|
||||
- `pxf-env.sh` по‑прежнему копируется в `PXF_BASE`, чтобы `/start_gpdb.sh` не пытался выполнять
|
||||
`pxf cluster prepare` на непустом `PXF_BASE`;
|
||||
- healthcheck `greenplum` ждёт не только PXF, но и наличие `extension pxf`.
|
||||
- добавлен экспорт `PGPASSWORD` для `pxf cluster start`, чтобы `docker compose stop/start`
|
||||
не ломал запуск из‑за `password authentication failed` для `gpadmin`.
|
||||
|
||||
- `docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gp_dwh -t -A -c \"SELECT extname FROM pg_extension WHERE extname = ''pxf'';\"'"`
|
||||
### Если ошибка всё ещё возникает
|
||||
|
||||
Если команда ничего не вернула — расширение не создано.
|
||||
1) Пересоберите образ и перезапустите контейнер `greenplum`:
|
||||
`make build && make down && make up`
|
||||
|
||||
### Временный workaround (ручной)
|
||||
|
||||
1) Создать расширение:
|
||||
`docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gp_dwh -c \"CREATE EXTENSION IF NOT EXISTS pxf;\"'"`
|
||||
|
||||
2) Повторить DDL:
|
||||
`make ddl-gp`
|
||||
|
||||
### Что чинить в коде (идея фикса)
|
||||
|
||||
Сделать создание расширения `pxf` независимым от наличия `pxf-env.sh`:
|
||||
- либо убрать/изменить условие в `/start_gpdb.sh` (в образе),
|
||||
- либо перестать копировать `pxf-env.sh` в ensure‑скрипте и дать базовому скрипту создать его,
|
||||
- либо сделать retry‑логику `CREATE EXTENSION pxf` надёжной (повторять попытки и проверять результат).
|
||||
2) Проверьте наличие extension:
|
||||
`docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gp_dwh -t -A -c \"SELECT extname FROM pg_extension WHERE extname = ''pxf'';\"'"`
|
||||
|
||||
## 8. Связанные файлы
|
||||
|
||||
@@ -153,3 +144,58 @@
|
||||
- `pxf/init/10_pxf_bookings.sh` (ensure‑логика)
|
||||
- `pxf/init/start_greenplum_with_pxf.sh` (старт контейнера)
|
||||
- `README.md` (раздел «Greenplum + PXF: свой образ»)
|
||||
|
||||
## 10. Известная проблема: после `docker compose stop/start` Greenplum может упасть (auth для PXF)
|
||||
|
||||
### Симптом
|
||||
|
||||
После `docker compose stop`, затем `docker compose start` контейнер `greenplum` иногда уходит в `Exited (1)`.
|
||||
В логах видно, что GPDB поднялся, но упал на старте PXF:
|
||||
|
||||
- `INFO - pxf cluster start`
|
||||
- `ERROR: Could not connect to GPDB`
|
||||
- `FATAL: password authentication failed for user "gpadmin"`
|
||||
|
||||
### Текущее понимание причины (почему это “иногда”)
|
||||
|
||||
1) При старте GPDB образ `woblerr/greenplum` генерирует/дописывает `pg_hba.conf` на persistent volume.
|
||||
2) В `pg_hba.conf` присутствует trust‑правило для **конкретного IP** контейнера в docker‑сети
|
||||
(пример из диагностики: `host all gpadmin 172.21.0.2/32 trust`).
|
||||
3) После `docker compose stop/start` Docker может выдать контейнеру **другой IP** (например, `172.21.0.3`).
|
||||
Тогда trust‑правило больше не подходит, и подключение начинает идти по `md5`.
|
||||
4) `pxf cluster start` подключается к GPDB по TCP на `host=gpdbsne` (hostname контейнера),
|
||||
то есть попадает именно в `pg_hba.conf` (а не в local‑auth).
|
||||
5) В результате при “не совпавшем IP” получаем `md5` + пароль (возможно пустой/не тот) → падение на `28P01`.
|
||||
|
||||
Эта проблема выглядит флапающей, потому что IP после `stop/start` иногда совпадает с захардкоженным trust‑/32,
|
||||
а иногда нет.
|
||||
|
||||
### Как подтвердить при следующем воспроизведении
|
||||
|
||||
1) Посмотреть логи `greenplum`:
|
||||
`docker compose logs --tail=200 greenplum`
|
||||
|
||||
2) Найти реальный IP клиента в master‑логах GPDB (на томе):
|
||||
`Password does not match ...` обычно содержит адрес вида `172.21.0.X`.
|
||||
|
||||
3) Сравнить его с trust‑строкой в `pg_hba.conf` на томе:
|
||||
`/data/master/gpseg-1/pg_hba.conf`
|
||||
|
||||
Если IP в ошибке (например, `172.21.0.3`) **не** совпадает с trust‑/32 (например, `172.21.0.2/32`) —
|
||||
это почти наверняка корень падения.
|
||||
|
||||
### Что с этим делать дальше (варианты решения, без реализации здесь)
|
||||
|
||||
Основная цель — убрать зависимость от “случайного IP после stop/start”:
|
||||
|
||||
- заставить `pxf cluster start` подключаться к GPDB через `127.0.0.1` (тогда работает существующий trust на localhost);
|
||||
- или перестать добавлять в `pg_hba.conf` trust на конкретный `172.21.0.2/32` и заменить на более стабильное правило
|
||||
(например, на подсеть docker‑сети или на `samehost`);
|
||||
- или закрепить IP контейнера в compose (static IP), чтобы он не “плавал”;
|
||||
- или отказаться от `stop/start` в пользу сценария, который не меняет сетевое окружение (но это хуже для UX студентов).
|
||||
|
||||
### Что реализовано
|
||||
|
||||
- В `pxf/init/start_greenplum_with_pxf.sh` добавлен шаг, который на каждом старте
|
||||
обеспечивает в `pg_hba.conf` trust‑правило `host all gpadmin samehost trust`
|
||||
(вставка перед `host all all 0.0.0.0/0 md5`), и делает `pg_ctl reload`, если GPDB уже запущен.
|
||||
|
||||
@@ -1,9 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Этот скрипт — "обёртка" над стандартным стартом Greenplum (exec /start_gpdb.sh),
|
||||
# которая добавляет устойчивый старт PXF для учебного стенда.
|
||||
#
|
||||
# Задачи скрипта (почему он нужен):
|
||||
# 1) Подготовить PXF_BASE на persistent volume (через ensure-скрипт).
|
||||
# 2) Обеспечить стабильную аутентификацию PXF → GPDB после `docker compose stop/start`
|
||||
# (не зависеть от «плавающего» IP контейнера в docker-сети).
|
||||
# 3) Гарантировать наличие расширения `pxf` в БД GPDB (иначе внешние таблицы падают с
|
||||
# `ERROR: protocol "pxf" does not exist`).
|
||||
#
|
||||
# Важно: это учебный стенд, поэтому мы сознательно выбираем простые и надёжные решения
|
||||
# (например, trust для samehost), а не «боевой» hardened security.
|
||||
|
||||
ensure_script="/opt/pxf-scripts/ensure_pxf_bookings.sh"
|
||||
|
||||
# PXF CLI использует libpq и при `pxf cluster start` подключается к GPDB как к обычному Postgres.
|
||||
# После `docker compose stop/start` может внезапно потребоваться пароль (см. ensure_pg_hba_trust ниже),
|
||||
# поэтому экспортируем PGPASSWORD заранее: это уменьшает "флап" и делает поведение воспроизводимым.
|
||||
if [ -z "${PGPASSWORD:-}" ]; then
|
||||
export PGPASSWORD="${GREENPLUM_PASSWORD:-gpadmin}"
|
||||
fi
|
||||
|
||||
ensure_pg_hba_trust() {
|
||||
# После `docker compose stop/start` Docker может выдать контейнеру другой IP.
|
||||
# У базового образа Greenplum встречается trust-правило на конкретный /32 (старый IP),
|
||||
# и тогда аутентификация по TCP начинает идти через md5 → PXF падает на `28P01`.
|
||||
#
|
||||
# Решение: добавить правило `host all gpadmin samehost trust`, которое срабатывает для
|
||||
# подключений "с этого же контейнера" (PXF запускается рядом с master).
|
||||
# Это максимально простое и стабильное правило для учебного стенда.
|
||||
local gp_user="${GREENPLUM_USER:-gpadmin}"
|
||||
local data_dir="${GREENPLUM_DATA_DIRECTORY:-/data}"
|
||||
local attempts=60
|
||||
local pg_hba=""
|
||||
local trust_line="host all ${gp_user} samehost trust"
|
||||
|
||||
find_pg_hba() {
|
||||
local candidate
|
||||
for candidate in "${data_dir}/master"/*/pg_hba.conf; do
|
||||
if [ -f "${candidate}" ]; then
|
||||
echo "${candidate}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
for _ in $(seq 1 "${attempts}"); do
|
||||
pg_hba="$(find_pg_hba || true)"
|
||||
if [ -n "${pg_hba}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "${pg_hba}" ]; then
|
||||
echo "WARN - pg_hba.conf не найден, пропускаем trust для ${gp_user}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if grep -Eq "^[[:space:]]*host[[:space:]]+all[[:space:]]+${gp_user}[[:space:]]+samehost[[:space:]]+trust" "${pg_hba}"; then
|
||||
echo "INFO - pg_hba.conf уже содержит trust для ${gp_user} samehost"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Вставляем trust-правило перед самым "общим" md5-правилом (0.0.0.0/0),
|
||||
# чтобы samehost гарантированно матчился раньше.
|
||||
awk -v trust_line="${trust_line}" '
|
||||
BEGIN { added = 0 }
|
||||
$0 ~ /^[[:space:]]*host[[:space:]]+all[[:space:]]+all[[:space:]]+0\.0\.0\.0\/0[[:space:]]+md5/ && added == 0 {
|
||||
print trust_line
|
||||
added = 1
|
||||
}
|
||||
{ print }
|
||||
END {
|
||||
if (added == 0) {
|
||||
print trust_line
|
||||
}
|
||||
}
|
||||
' "${pg_hba}" > "${pg_hba}.tmp" && mv "${pg_hba}.tmp" "${pg_hba}"
|
||||
|
||||
echo "INFO - pg_hba.conf: добавлен trust для ${gp_user} samehost"
|
||||
|
||||
local master_dir="${pg_hba%/pg_hba.conf}"
|
||||
# Если GPDB уже поднялся, достаточно reload, чтобы новое правило применилось без рестарта.
|
||||
if /usr/local/greenplum-db/bin/pg_ctl -D "${master_dir}" status >/dev/null 2>&1; then
|
||||
if ! /usr/local/greenplum-db/bin/pg_ctl -D "${master_dir}" reload >/dev/null 2>&1; then
|
||||
echo "WARN - не удалось перезагрузить pg_hba.conf (pg_ctl reload)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_pxf_extension() {
|
||||
# В базовом /start_gpdb.sh создание `CREATE EXTENSION pxf` зависит от наличия
|
||||
# `${PXF_BASE}/conf/pxf-env.sh`. В нашем стенде pxf-env.sh может быть уже создан
|
||||
# ensure-скриптом (PXF_BASE на томе), и тогда /start_gpdb.sh пропускает extension.
|
||||
#
|
||||
# Чтобы внешние таблицы через PXF работали после любого рестарта, создаём extension сами,
|
||||
# но только когда GPDB начнёт принимать подключения (с ретраями).
|
||||
local gp_user="${GREENPLUM_USER:-gpadmin}"
|
||||
local gp_db="${GREENPLUM_DATABASE_NAME:-gp_dwh}"
|
||||
local gp_password="${GREENPLUM_PASSWORD:-gpadmin}"
|
||||
@@ -13,30 +109,53 @@ ensure_pxf_extension() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
for _ in $(seq 1 "${attempts}"); do
|
||||
extension_exists() {
|
||||
local result
|
||||
# Подключаемся к localhost: это "локальный" путь и на нём обычно уже есть trust.
|
||||
result=$(PGPASSWORD="${gp_password}" /usr/local/greenplum-db/bin/psql \
|
||||
-h 127.0.0.1 -p 5432 -U "${gp_user}" -d "${gp_db}" \
|
||||
-t -A -c "SELECT 1 FROM pg_extension WHERE extname='pxf';" 2>/dev/null || true)
|
||||
[ "${result}" = "1" ]
|
||||
}
|
||||
|
||||
for attempt in $(seq 1 "${attempts}"); do
|
||||
# Ждём, пока master начнёт принимать подключения.
|
||||
if /usr/local/greenplum-db/bin/pg_isready \
|
||||
-h 127.0.0.1 -p 5432 -U "${gp_user}" -d "${gp_db}" >/dev/null 2>&1; then
|
||||
if extension_exists; then
|
||||
echo "INFO - extension pxf уже создано"
|
||||
return 0
|
||||
fi
|
||||
if PGPASSWORD="${gp_password}" /usr/local/greenplum-db/bin/psql \
|
||||
-h 127.0.0.1 -p 5432 -U "${gp_user}" -d "${gp_db}" \
|
||||
-v ON_ERROR_STOP=1 -c "CREATE EXTENSION IF NOT EXISTS pxf;" >/dev/null; then
|
||||
-v ON_ERROR_STOP=1 -c "CREATE EXTENSION IF NOT EXISTS pxf;" >/dev/null 2>&1; then
|
||||
if extension_exists; then
|
||||
echo "INFO - extension pxf готово"
|
||||
else
|
||||
echo "WARN - не удалось создать extension pxf"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
echo "WARN - попытка ${attempt}/${attempts}: не удалось создать extension pxf"
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "WARN - Greenplum не готов, пропускаем CREATE EXTENSION pxf"
|
||||
echo "WARN - Greenplum не готов или extension pxf не создано"
|
||||
}
|
||||
|
||||
# 1) Подготовка PXF_BASE (копирование seed, конфигов и т.д.).
|
||||
if [ -f "${ensure_script}" ]; then
|
||||
"${ensure_script}"
|
||||
else
|
||||
echo "WARN - не найден ensure-скрипт PXF: ${ensure_script}"
|
||||
fi
|
||||
|
||||
# 2) Дальше запускаем две "подстраховки" параллельно, чтобы не замедлять старт контейнера:
|
||||
# - правка pg_hba.conf (как только он появится на томе);
|
||||
# - создание extension pxf (как только GPDB начнёт отвечать).
|
||||
ensure_pg_hba_trust &
|
||||
|
||||
ensure_pxf_extension &
|
||||
|
||||
# 3) Стартуем GPDB "как обычно". Важно использовать exec, чтобы сигналы Docker
|
||||
# (stop/restart) корректно приходили в основной процесс entrypoint.
|
||||
exec /start_gpdb.sh
|
||||
|
||||
Reference in New Issue
Block a user