Skip to content

криптобиржа изобилие #14

Description

@myltik1702

Итоговый чек‑лист и дополнительные скрипты для запуска

Ниже — финальный контрольный список и дополнительные полезные скрипты для безопасного развёртывания схемы.


1. Проверка целостности схемы (перед запуском)

Скрипт для аудита ограничений:

-- Проверить все внешние ключи
SELECT 
    conname AS constraint_name,
    conrelid::regclass AS table_name,
    confrelid::regclass AS referenced_table
FROM pg_constraint
WHERE contype = 'f'
    AND conrelid IN ('orders'::regclass, 'trading_pairs'::regclass);

-- Проверить все CHECK-ограничения
SELECT
    conname AS constraint_name,
    conrelid::regclass AS table_name,
    pg_get_constraintdef(oid) AS definition
FROM pg_constraint
WHERE contype = 'c'
    AND conrelid IN ('orders'::regclass, 'trading_pairs'::regclass);

Ожидаемый результат:

  • Все FOREIGN KEY должны присутствовать (особенно fk_orders_user_id и fk_orders_pair_id).
  • Все CHECK‑ограничения должны быть перечислены.

2. Тестовые данные (для проверки триггеров и ограничений)

Вставить тестовую торговую пару:

INSERT INTO trading_pairs (base_asset, quote_asset)
VALUES ('BTC', 'USDT')
RETURNING id;

Вставить тестовый ордер (limit):

INSERT INTO orders (
    user_id, pair_id, side, price, quantity, order_type, client_order_id
)
VALUES (
    '123e4567-e89b-12d3-a456-426614174000',
    1,
    'buy',
    50000.00,
    0.1,
    'limit',
    'test-order-001'
)
RETURNING id, created_at, updated_at;

Проверить обновление updated_at при изменении:

UPDATE orders
SET status = 'partially_filled', filled_quantity = 0.05
WHERE client_order_id = 'test-order-001';

SELECT id, status, filled_quantity, updated_at FROM orders WHERE client_order_id = 'test-order-001';

Ожидаемое: updated_at должен измениться на текущее время.


3. Скрипты для мониторинга и обслуживания

Автоматическое создание партиций (функция):

CREATE OR REPLACE FUNCTION create_orders_partition(year INT)
RETURNS VOID AS $$
DECLARE
    partition_name TEXT := 'orders_y' || year;
    start_date TEXT := year || '-01-01';
    end_date TEXT := (year + 1) || '-01-01';
BEGIN
    EXECUTE format(
        'CREATE TABLE %I PARTITION OF orders FOR VALUES FROM (%L) TO (%L)',
        partition_name, start_date, end_date
    );
END;
$$ LANGUAGE plpgsql;

-- Пример вызова:
SELECT create_orders_partition(2026);

Проверка актуальности партиций:

SELECT
    child.relname AS partition_name,
    pg_get_expr(child.relpartbound, child.oid) AS bound_expr
FROM pg_inherits
    JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'orders';

4. Безопасность: настройки доступа

Создать роль для приложения:

CREATE ROLE app_user WITH LOGIN PASSWORD 'secure_password';
GRANT CONNECT ON DATABASE your_db TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;

-- Права на таблицы
GRANT SELECT, INSERT, UPDATE ON orders TO app_user;
GRANT SELECT, INSERT ON trading_pairs TO app_user;

-- Права на последовательности (если нужны)
GRANT USAGE ON SEQUENCE trading_pairs_id_seq TO app_user;

Ограничить доступ к критическим операциям:

-- Запретить DELETE для ордеров
REVOKE DELETE ON orders FROM app_user;
-- Разрешить только через API (статус 'cancelled')

5. Резервное копирование: автоматизация

Скрипт для ежедневного бэкапа (bash):

#!/bin/bash
BACKUP_DIR="/backup/postgres"
DATE=$(date +"%Y%m%d")


pg_dump -h localhost -U backup_user -F c -b -v -f "$BACKUP_DIR/orders_$DATE.dump" orders
pg_dump -h localhost -U backup_user -F c -b -v -f "$BACKUP_DIR/trading_pairs_$DATE.dump" trading_pairs

gzip $BACKUP_DIR/*.dump

Добавить в cron (ежедневно в 02:00):

0 2 * * * /path/to/backup_script.sh

6. Чек‑лист перед продакшеном

  1. Данные:

    • Заполнены ли trading_pairs для всех поддерживаемых пар?
    • Протестированы ли крайние случаи (нулевые комиссии, экстремальные цены)?
  2. Производительность:

    • Созданы ли все индексы?
    • Настроены ли VACUUM/ANALYZE в cron?
    • Проверено ли время выполнения ключевых запросов (раздел «Мониторинг»)?
  3. Безопасность:

    • Ограничены ли права пользователей БД?
    • Включена ли WAL‑архивация?
    • Есть ли доступ к бэкапам из изолированной среды?
  4. Отказоустойчивость:

    • Настроена ли репликация?
    • Протестировано ли восстановление из бэкапа?
  5. Логирование:

    • Записываются ли медленные запросы (log_min_duration_statement в postgresql.conf)?
    • Мониторятся ли pg_stat_statements и pg_stat_user_indexes?

7. Дополнительные рекомендации

  1. Для высокой нагрузки:

    • Используйте pgbouncer с transaction‑режимом.
    • Включите synchronous_commit = off для ордеров (если допустимы потери <1 сек).
  2. Для аудита:

    • Добавьте таблицу order_history для логирования изменений статусов.
    • Используйте EVENT TRIGGER для отслеживания DDL‑изменений.
  3. Для аналитики:

    • Создайте материализованное представление для агрегации торгов:
      CREATE MATERIALIZED VIEW daily_volume AS
      SELECT
          pair_id,
          DATE(created_at) AS trade_date,
          SUM(filled_quantity * price) AS volume
      FROM orders
      WHERE status = 'filled'
      GROUP BY pair_id, DATE(created_at);
  4. Для API:

    • Реализуйте SELECT FOR UPDATE SKIP LOCKED для конкурентной обработки ордеров.
    • Используйте NOTIFY для оповещения о новых ордерах.

Финальная проверка:

  1. Запустите все тестовые скрипты.
  2. Убедитесь, что триггеры и ограничения работают.
  3. Проверьте права доступа.
  4. Протестируйте восстановление из бэкапа.
  5. Запланируйте мониторинг производительности на первые 24 часа после запуска.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions