Перетяжка, Премия ТПрогер, 13.11
Перетяжка, Премия ТПрогер, 13.11
Перетяжка, Премия ТПрогер, 13.11

Вредные советы по работе с базами данных, или как расстроить DBA

Сборник самых раздражающих ошибок в работе с базами данных — с примерами и советами, как делать правильно. По выпуску подкаста «Техно.Логично».

378 открытий4К показов
Вредные советы по работе с базами данных, или как расстроить DBA

Когда разработчик говорит «база упала», администратор баз данных вздыхает и открывает логи. Снова кто-то решил, что временные файлы бесконечны. Или создал 47 индексов на одной таблице. Или оставил транзакцию висеть на выходные.

Классические ошибки повторяются с завидным постоянством. В недавнем выпуске подкаста «Техно.Логично» наши коллеги Владимир Герциков и Николай Волынкин как раз обсуждали типичные проблемы с базами данных — от выбора инструментов до падений в продакшне. Послушав коллег, мы решили не пересказывать их беседу целиком, а на основе их беседы сделать практический список вредных советов.

Получился антигайд: как гарантированно завалить базу данных — и что делать правильно. Если узнаете себя в этих советах, не расстраивайтесь. Через подобное проходят все. А если хотите услышать полную дискуссию о современных СУБД, инструментах и миграции на open source — послушайте оригинальный выпуск.

1. Временные файлы бесконечны — лейте терабайты джойнов

Берите две таблицы по миллиону записей каждая, смело делайте JOIN без WHERE, сортируйте результат — и удивляйтесь, почему закончилось место под временные данные.

Что происходит: PostgreSQL создает временные файлы в pg_tmp для обработки больших запросов. Когда места не хватает, падают конкретные запросы с ошибкой No space left on device, а не весь сервер. Особенно болезненно там, где несколько таких запросов запускаются параллельно — временное пространство переполняется быстрее, чем успевает сработать мониторинг.

Как делать правильно: Планируйте размер временных данных заранее. Добавляйте фильтры перед джойнами, разбивайте сложные запросы на этапы. Настройте temp_file_limit для ограничения временных файлов на запрос и мониторинг заполнения. Если ваш запрос генерирует терабайты промежуточных результатов, скорее всего, есть способ сделать это эффективнее.

2. Суперпользователь для всех задач — что может пойти не так

Создайте пользователя с правами суперадминистратора, используйте его для всех подключений и смело устанавливайте любые расширения, найденные в интернете.

Реальная история: Разработчик развернул постгрес на виртуалке с дефолтными настройками — порт 5432 открыт, пользователь postgres/postgres с правами суперпользователя. Через семь (!) секунд в базу начали ломиться боты. Боты сканируют интернет на стандартные порты СУБД постоянно и превращают сервер в майнинг-ферму быстрее, чем вы успеете допить кофе. Диск переполнился от созданных таблиц, установились неизвестные расширения, начались HTTP-вызовы из базы наружу. Сервер превратился в часть ботнета.

И так все понятно, но еще раз напомним: Суперпользователь может подключить postgres_fdw, dblink и читать/писать любые базы кластера, создавая запросы, которые переполнят временное пространство за минуты. Неподписанные расширения могут содержать что угодно — от бэкдоров до майнеров. А если расширение вызовет segmentation fault, упадет вообще все.

Принцип минимальных прав: Создавайте отдельных пользователей с минимально необходимыми правами. Устанавливайте только официально поддерживаемые расширения. Закрывайте базу от внешнего доступа файрволом, настройте TLS для шифрования трафика, используйте fail2ban против брутфорса и уникальные пароли. Это кажется очевидным, но количество баз с дефолтными паролями в интернете говорит об обратном.

3. Держите транзакции открытыми — счетчик XID все стерпит

Открывайте длинные транзакции и держите их днями. Постгерс умный, сам разберется.

Что сломается: У PostgreSQL есть счетчик транзакций (XID), который может переполниться. Когда возраст транзакций становится критическим, сервер блокирует обычные подключения и пускает только суперпользователя для выполнения VACUUM FULL. Все приложения встают, начинается паника.

Как избежать: Настройте timeout для idle in transaction состояний. Разбивайте большие батчи на маленькие операции. Мониторьте возраст самых старых транзакций. И запомните: транзакция, которая висит неделю, — это не фича, это бомба замедленного действия.

4. На каждый SELECT — свой индекс

Создавайте индекс под каждый запрос. Чем больше индексов, тем быстрее будет работать.

Почему это убивает PostgreSQL: В отличие от других СУБД, PostgreSQL при UPDATE создает новую версию записи, а старую помечает как мертвую. Если у таблицы 30 индексов, каждый UPDATE генерирует 30 мертвых ссылок в индексах. VACUUM начинает работать постоянно, производительность рушится.

Правило 20/80: Покройте индексами 20% самых частых запросов, которые дают 80% нагрузки. Остальную аналитику выносите на реплику для чтения. Регулярно анализируйте статистику использования индексов — неиспользуемые безжалостно удаляйте .

5. Сайзинг не нужен

Ресурсы бесконечны. А DBA разберутся, как бэкапить ваши 100 терабайт.

Физические ограничения: Таблица в PostgreSQL не может быть больше 32 терабайт при дефолтном размере блока. Ограничение можно обойти партиционированием или пересборкой с увеличенным размером блока, но лучше планировать заранее.

Экономика: «Эта функция будет стоить как два сервера, потому что нам нужно оборудование для бэкапа 50-терабайтной базы». В этот момент «бизнес» делает большие глаза и внезапно появляется мотивация оптимизировать архитектуру.

Планирование: Считайте размер данных на год-два вперед. Внедряйте партиционирование с первого дня, если ожидаете рост. Архивируйте старые данные. Удалить лишнее проще, чем добыть дополнительные терабайты дискового пространства в пятницу вечером.

6. Пихайте СУБД в контейнеры

Kubernetes решает все проблемы! Поэтому переносим в контейнеры все, базы данных тоже. Если что-то работает на виртуалках, то в контейнерах точно будет работать лучше.

Проблемы слоеного пирога: Мы слышали, тебе нравится виртуализация, поэтому мы добавили виртуализацию в твою виртуализацию. В результате кратное усложнение отладки. Где тормозит база: железо, гипервизор, менеджер контейнеров?

Где контейнер оправдан? В CI/CD, локальной разработке, тестовых средах. В продакшне контейнеры тоже работают, если использовать Kubernetes-операторы (Patroni, CloudNativePG), правильно настроить Persistent Volumes и протестировать поведение при рестартах. База должна жить в памяти, прогревать кэши, работать стабильно. Но это требует серьезной экспертизы в Kubernetes и готовности разбираться с проблемами на стыке технологий. Если команда не готова изучать все тонкости — лучше не начинать.

Компромисс: Если выбираете контейнеры для продакшна, используйте StatefulSet, настройте правильные storage-классы и OOM-политики. Для stateless-сервисов контейнеры — отличный выбор.

7. Всю бизнес-логику держим в хранимках — так быстрее

Переносите всю логику в базу. Зачем нужны сервисы приложений?

Пример из практики: Система с хранимыми процедурами Oracle обыграла Java-реализацию в тестах производительности. Логика выполнялась рядом с данными, без сетевых задержек. Но когда нагрузка выросла в разы, уперлись в лимит CPU на сервере баз данных. Добавить ресурсы оказалось сложнее, чем масштабировать stateless-сервисы.

Компромисс: Тяжелые агрегации и отчеты делайте в функциях базы. CRUD-операции выносите в сервисы приложений. Следите за загрузкой CPU на сервере БД — когда она приближается к пределу, начинайте выносить логику наружу.

8. Коммерческая СУБД — единственный путь

Только коммерческие решения подходят для серьезных задач. Oracle и SQL Server проверены временем, а всякие open source базы — это для студентов и стартапов.

Что изменилось: События последних лет заставили многие компании пересмотреть подход к выбору СУБД. Компании массово переходят на PostgreSQL Pro и другие open source решения. Тренд только усиливается — игнорировать open source значит отстать от рынка и пропустить инновации, которые часто появляются именно в открытых проектах.

НО: Vanilla PostgreSQL без поддержки — это действительно риск. Когда расширение Oracle FDW падает с разными структурами таблиц, а автор из коммьюнити отвечает «мне в голову не приходило, что кто-то будет так делать», понимаешь ценность платной поддержки. Поэтому open source, но с поддержкой от надежных вендоров.

Заключение

Продовые пожары в базах данных всегда случаются в самый неподходящий момент. Но большинство из них можно предотвратить, следуя простым правилам: планировать ресурсы, ограничивать права, мониторить метрики.

Выберите один совет из этой статьи и примените его сегодня. Возможно, это сэкономит вам несколько часов сна в будущем. А коллеги-DBA скажут спасибо.

Следите за новыми постами
Следите за новыми постами по любимым темам
378 открытий4К показов