365 lines
8.1 KiB
Markdown
365 lines
8.1 KiB
Markdown
|
|
---
|
|
|
|
# Инструкция по переносу схем public из 15 БД в одну БД
|
|
|
|
## Этап 1. Бэкап исходных БД
|
|
|
|
**Ваш скрипт (без изменений):**
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Список баз данных для дампа
|
|
databases=("edemo_ehd1" "edemo_ehd2" "edemo_ehd3" "edemo_ehd4" "edemo_ehd5"
|
|
"edemo_ehd6" "edemo_ehd7" "edemo_ehd8" "edemo_ehd9" "edemo_ehd10"
|
|
"edemo_ehd11" "edemo_ehd12" "edemo_ehd13" "edemo_ehd14" "edemo_ehd15")
|
|
|
|
for db in "${databases[@]}"; do
|
|
echo "Dumping database: $db"
|
|
|
|
# Создаем директорию для дампа (если не существует)
|
|
mkdir -p "/opt/pg_dumps/${db}.dir"
|
|
|
|
pg_dump -p 5432 -U postgres -d "$db" \
|
|
-F d \
|
|
-j 4 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
-f "/opt/pg_dumps/${db}.dir"
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "$db dumped successfully"
|
|
else
|
|
echo "$db failed"
|
|
fi
|
|
done
|
|
```
|
|
|
|
**Выполнить:** `chmod +x script.sh && ./script.sh`
|
|
|
|
---
|
|
|
|
## Этап 2. Рестор бэкапов во временные БД
|
|
|
|
**Ваш скрипт (без изменений):**
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
DB_HOST="localhost"
|
|
DB_PORT="5432"
|
|
DB_USER="postgres"
|
|
DB_OWNER="eds"
|
|
DUMP_BASE_PATH="/pgbkp/20260730"
|
|
|
|
# Список баз
|
|
databases=("db01" "db02" "db03")
|
|
|
|
# Создаем базы
|
|
for db in "${databases[@]}"; do
|
|
echo "Creating: $db"
|
|
psql -p "$DB_PORT" -U "$DB_USER" -c "DROP DATABASE IF EXISTS $db WITH (FORCE)" -q
|
|
|
|
psql -p "$DB_PORT" -U "$DB_USER" -v ON_ERROR_STOP=1 << EOF
|
|
CREATE DATABASE $db
|
|
WITH
|
|
OWNER = $DB_OWNER
|
|
ENCODING = 'UTF8'
|
|
LC_COLLATE = 'en_US.UTF-8'
|
|
LC_CTYPE = 'en_US.UTF-8'
|
|
ICU_LOCALE = 'en-US'
|
|
LOCALE_PROVIDER = 'icu'
|
|
TABLESPACE = pg_default
|
|
CONNECTION LIMIT = -1
|
|
IS_TEMPLATE = False;
|
|
ALTER DATABASE $db
|
|
SET log_statement TO 'ddl';
|
|
EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "Database $db created with owner $DB_OWNER"
|
|
else
|
|
echo "Failed to create database $db"
|
|
exit 1
|
|
fi
|
|
|
|
done
|
|
|
|
export PGPASSWORD=""
|
|
|
|
# Восстанавливаем
|
|
for db in "${databases[@]}"; do
|
|
echo "Restoring: $db"
|
|
if pg_restore -h "$DB_HOST" -p "$DB_PORT" -U "$DB_OWNER" -d "$db" -F d -j 4 --no-owner --no-privileges --no-tablespaces "$DUMP_BASE_PATH/${db}_dir"; then
|
|
echo "Restore $db Done"
|
|
else
|
|
echo "Restore $db Failed"
|
|
fi
|
|
done
|
|
|
|
echo "All done"
|
|
|
|
unset PGPASSWORD
|
|
```
|
|
|
|
**Выполнить:** `chmod +x script.sh && ./script.sh`
|
|
|
|
**ВНИМАНИЕ:** В этом скрипте нужно заменить:
|
|
- `databases=("db01" "db02" "db03")` → `databases=("edemo_ehd1" ... "edemo_ehd15")`
|
|
- `DUMP_BASE_PATH="/pgbkp/20260730"` → `DUMP_BASE_PATH="/opt/pg_dumps"`
|
|
- `${db}_dir` → `${db}.dir`
|
|
|
|
---
|
|
|
|
## Этап 3. Переименование схем public во временных БД
|
|
|
|
**Выполнять вручную через psql!**
|
|
|
|
```sql
|
|
\c edemo_ehd1
|
|
ALTER SCHEMA public RENAME TO ehd1;
|
|
|
|
\c edemo_ehd2
|
|
ALTER SCHEMA public RENAME TO ehd2;
|
|
|
|
\c edemo_ehd3
|
|
ALTER SCHEMA public RENAME TO ehd3;
|
|
|
|
\c edemo_ehd4
|
|
ALTER SCHEMA public RENAME TO ehd4;
|
|
|
|
\c edemo_ehd5
|
|
ALTER SCHEMA public RENAME TO ehd5;
|
|
|
|
\c edemo_ehd6
|
|
ALTER SCHEMA public RENAME TO ehd6;
|
|
|
|
\c edemo_ehd7
|
|
ALTER SCHEMA public RENAME TO ehd7;
|
|
|
|
\c edemo_ehd8
|
|
ALTER SCHEMA public RENAME TO ehd8;
|
|
|
|
\c edemo_ehd9
|
|
ALTER SCHEMA public RENAME TO ehd9;
|
|
|
|
\c edemo_ehd10
|
|
ALTER SCHEMA public RENAME TO ehd10;
|
|
|
|
\c edemo_ehd11
|
|
ALTER SCHEMA public RENAME TO ehd11;
|
|
|
|
\c edemo_ehd12
|
|
ALTER SCHEMA public RENAME TO ehd12;
|
|
|
|
\c edemo_ehd13
|
|
ALTER SCHEMA public RENAME TO ehd13;
|
|
|
|
\c edemo_ehd14
|
|
ALTER SCHEMA public RENAME TO ehd14;
|
|
|
|
\c edemo_ehd15
|
|
ALTER SCHEMA public RENAME TO ehd15;
|
|
```
|
|
|
|
---
|
|
|
|
## Этап 4. Бэкап временных БД
|
|
|
|
**Использовать скрипт из Этапа 1, заменив список баз:**
|
|
|
|
```bash
|
|
databases=("edemo_ehd1" "edemo_ehd2" ... "edemo_ehd15")
|
|
```
|
|
|
|
Дампы сохранятся в `/opt/pg_dumps/` (перезапишут исходные дампы).
|
|
|
|
---
|
|
|
|
## Этап 5. Восстановление в целевую БД
|
|
|
|
**Выполнять вручную для каждой схемы!**
|
|
|
|
### Для схемы ehd1:
|
|
|
|
```bash
|
|
# pre-data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-n ehd1 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=pre-data \
|
|
/opt/pg_dumps/edemo_ehd1.dir/
|
|
|
|
# data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-j 4 \
|
|
-n ehd1 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=data \
|
|
--disable-triggers \
|
|
/opt/pg_dumps/edemo_ehd1.dir/
|
|
|
|
# post-data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-j 4 \
|
|
-n ehd1 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=post-data \
|
|
/opt/pg_dumps/edemo_ehd1.dir/
|
|
```
|
|
|
|
### Для схемы ehd2:
|
|
|
|
```bash
|
|
# pre-data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-n ehd2 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=pre-data \
|
|
/opt/pg_dumps/edemo_ehd2.dir/
|
|
|
|
# data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-j 4 \
|
|
-n ehd2 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=data \
|
|
--disable-triggers \
|
|
/opt/pg_dumps/edemo_ehd2.dir/
|
|
|
|
# post-data
|
|
pg_restore -p 5432 -U eds -d mmedo_main \
|
|
-F d \
|
|
-j 4 \
|
|
-n ehd2 \
|
|
--no-tablespaces \
|
|
--no-owner \
|
|
--no-privileges \
|
|
--section=post-data \
|
|
/opt/pg_dumps/edemo_ehd2.dir/
|
|
```
|
|
|
|
**И так далее до ehd15, подставляя соответствующий номер.**
|
|
|
|
---
|
|
|
|
## Этап 6. Пост-миграционная проверка
|
|
|
|
### Поиск объектов со ссылками на public:
|
|
|
|
```sql
|
|
WITH defs AS (
|
|
SELECT
|
|
'function'::text AS kind,
|
|
n.nspname AS schema_name,
|
|
p.oid::regprocedure::text AS object,
|
|
pg_get_functiondef(p.oid) AS definition
|
|
FROM pg_proc p
|
|
JOIN pg_namespace n ON n.oid = p.pronamespace
|
|
WHERE p.prokind IN ('f', 'p')
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'view/matview',
|
|
n.nspname,
|
|
c.oid::regclass::text,
|
|
pg_get_viewdef(c.oid)
|
|
FROM pg_class c
|
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
WHERE c.relkind IN ('v', 'm')
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'trigger',
|
|
n.nspname,
|
|
format('%s.%s', t.tgrelid::regclass, t.tgname),
|
|
pg_get_triggerdef(t.oid)
|
|
FROM pg_trigger t
|
|
JOIN pg_class c ON c.oid = t.tgrelid
|
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
WHERE NOT t.tgisinternal
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'default',
|
|
n.nspname,
|
|
format('%s.%s', a.attrelid::regclass, a.attname),
|
|
pg_get_expr(d.adbin, d.adrelid)
|
|
FROM pg_attrdef d
|
|
JOIN pg_attribute a ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
|
JOIN pg_class c ON c.oid = a.attrelid
|
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'constraint',
|
|
n.nspname,
|
|
format('%s.%s', c.conrelid::regclass, c.conname),
|
|
pg_get_constraintdef(c.oid)
|
|
FROM pg_constraint c
|
|
JOIN pg_class cl ON cl.oid = c.conrelid
|
|
JOIN pg_namespace n ON n.oid = cl.relnamespace
|
|
WHERE c.conrelid <> 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'index',
|
|
n.nspname,
|
|
i.indexrelid::regclass::text,
|
|
pg_get_indexdef(i.indexrelid)
|
|
FROM pg_index i
|
|
JOIN pg_class c ON c.oid = i.indexrelid
|
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
'rule',
|
|
n.nspname,
|
|
format('%s.%s', r.ev_class::regclass, r.rulename),
|
|
pg_get_ruledef(r.oid)
|
|
FROM pg_rewrite r
|
|
JOIN pg_class c ON c.oid = r.ev_class
|
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
)
|
|
SELECT
|
|
kind,
|
|
schema_name,
|
|
object,
|
|
definition
|
|
FROM defs
|
|
WHERE definition LIKE '%public.%'
|
|
OR definition LIKE '%"public".%'
|
|
ORDER BY schema_name, kind, object;
|
|
```
|
|
|
|
---
|
|
|
|
### Этап 7. Финальная сборка статистики
|
|
|
|
После завершения накатывания пост-данных обновляем статистику, чтобы оптимизатор Postgres знал о размерах таблиц:
|
|
|
|
```bash
|
|
psql -h localhost -p 5432 -U postgres -d eds-main -c "VACUUM ANALYZE;"
|
|
|
|
``` |