Короткий ответ: MySQL 8 ставится командой apt install mysql-server и по умолчанию слушает только локальный интерфейс — это правильное поведение. Сразу после установки нужно выполнить mysql_secure_installation, создать отдельного пользователя для приложения и убедиться, что bind-address указывает на 127.0.0.1. Работать под пользователем root из приложения нельзя.
Этот материал — часть цикла про настройку Ubuntu 24.04 на VPS. Если нужна именно PostgreSQL, он разобран отдельно — установка PostgreSQL на VPS.
Установка
apt update
apt install -y mysql-server
systemctl enable --now mysql
mysql --version
systemctl status mysql --no-pager
Проверить, что служба слушает только локально:
ss -tlnp | grep 3306
В выводе должен быть адрес 127.0.0.1:3306. Если там 0.0.0.0:3306 — база доступна из интернета, и это нужно исправить немедленно.
Первичная защита
mysql_secure_installation
Скрипт задаёт несколько вопросов. Разумные ответы:
| Вопрос | Ответ | Почему |
|---|---|---|
| Validate password component | По ситуации | Для приложения достаточно длинного случайного пароля; политика сложности иногда мешает автоматизации |
| Change root password | Да | Начальный пароль может быть пустым |
| Remove anonymous users | Да | Анонимный доступ не нужен |
| Disallow root login remotely | Да | Вход root снаружи — лишний риск |
| Remove test database | Да | Тестовая база доступна всем |
| Reload privilege tables | Да | Применяет изменения |
Пользователь для приложения
Приложение должно работать под отдельным пользователем с правами только на свою базу:
mysql -u root -p
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'длинный_случайный_пароль';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Кодировка utf8mb4 обязательна: она поддерживает полный набор символов Unicode, включая эмодзи. Старая utf8 в MySQL — это урезанный трёхбайтовый вариант, и данные с четырёхбайтовыми символами в неё не поместятся.
Проверка прав:
SHOW GRANTS FOR 'appuser'@'localhost';
Настройка под сервер
Основной файл конфигурации — /etc/mysql/mysql.conf.d/mysqld.cnf. Ключевые параметры для VPS:
[mysqld]
bind-address = 127.0.0.1
max_connections = 100
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 2
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
| Параметр | Смысл |
|---|---|
bind-address |
Слушать только локальный интерфейс |
innodb_buffer_pool_size |
Основной кэш. Обычно 50–70 % доступной памяти сервера |
max_connections |
Потолок подключений. Слишком большое значение расходует память впустую |
innodb_flush_log_at_trx_commit |
Компромисс между надёжностью и скоростью записи |
slow_query_log |
Журнал медленных запросов — основа для оптимизации |
Значение innodb_buffer_pool_size — самый важный параметр производительности. Если база небольшая, а памяти на сервере много, разумно поднять его так, чтобы данные целиком помещались в кэш.
После правки:
systemctl restart mysql
mysql -e "SELECT @@innodb_buffer_pool_size/1024/1024 AS mb;"
Резервное копирование
mysqldump --single-transaction --routines --triggers
-u appuser -p appdb > /var/backups/appdb_$(date +%F).sql
Флаг --single-transaction даёт согласованный слепок без остановки базы. Копировать файлы данных работающего MySQL напрямую нельзя — слепок будет противоречивым. Подробнее о копировании — в материале про резервное копирование VPS.
Диагностика
| Команда | Что показывает |
|---|---|
SHOW PROCESSLIST; |
Активные запросы и их состояние |
SHOW STATUS LIKE 'Threads_connected'; |
Число текущих подключений |
SHOW VARIABLES LIKE 'max_connections'; |
Установленный потолок |
SHOW ENGINE INNODB STATUSG |
Состояние InnoDB, блокировки, последняя ошибка |
mysqladmin status -u root -p |
Краткая сводка нагрузки |
Журнал медленных запросов — самый полезный инструмент оптимизации. Запрос, который выполняется секундами, обычно обнаруживается именно там, а не по симптомам «сайт тормозит».
Типичные ошибки
- Открытый наружу порт 3306. Самая опасная и самая частая ошибка.
- Работа приложения под root. Ошибка в коде приложения тогда может изменить любую базу.
- Кодировка
utf8вместоutf8mb4. Приводит к потере части символов. - Слишком большой
max_connections. На сервере с небольшой памятью это ускоряет исчерпание ресурсов. - Отсутствие журнала медленных запросов. Без него оптимизация превращается в угадывание.
- Копирование файлов данных вместо дампа. Даёт повреждённый слепок.
