Встановлення MySQL — одна команда. Основна робота починається потім: користувач для застосунку, спосіб дістатися до бази зі свого комп'ютера, не виставляючи порт 3306 в інтернет, налаштування пам'яті для невеликого сервера й бекапи, які йдуть без вашої участі. Цей посібник закриває всі чотири пункти на Ubuntu 24.04. Кожен крок виконано на нашому образі Ubuntu 24.04, і цифри нижче — з того самого сервера.
Виконуйте команди від користувача з sudo. Його створює посібник із налаштування Ubuntu.
1. Встановіть
sudo apt update
sudo apt install -y mysql-server
mysql --version
На нашому сервері встановлення забрало 51 секунду і поставило MySQL 8.0.46. Він одразу запускається, стартує під час кожного завантаження і слухає лише на самому сервері: 127.0.0.1:3306 для звичайних підключень і 127.0.0.1:33060 для нового X-протоколу MySQL. Ззовні поки нічого не доступно.
2. Створіть базу й користувача
Обліковий запис root у MySQL в Ubuntu використовує автентифікацію через сокет, тож sudo mysql пускає вас без пароля. Створіть базу й користувача для застосунку:
sudo mysql
CREATE DATABASE app CHARACTER SET utf8mb4;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'localhost';
EXIT;
Перевірте так, як підключатиметься застосунок:
mysql -u app -p app -e "SELECT CURRENT_USER();"
Має вивести app@localhost. На неправильний пароль приходить ERROR 1045 (28000): Access denied for user 'app'@'localhost'. Користувач може все всередині app і нічого поза нею.
3. Підключення зі свого комп'ютера: SSH-тунель
Щоб працювати з настільним клієнтом на кшталт DBeaver, MySQL Workbench чи консольного mysql на своєму комп'ютері, не відкривайте порт. Перенаправте його через SSH:
ssh -L 3307:127.0.0.1:3306 deploy@YOUR.SERVER.IP
На тарифі з NAT додайте -p і персональний SSH-порт із кабінету. Поки це вікно відкрите, спрямуйте клієнт на хост 127.0.0.1, порт 3307, користувач app. З локального боку ми взяли 3307, щоб не заважати MySQL, який може працювати у вас на комп'ютері. У нашому тесті сервер одразу відповів через тунель, а пряме підключення до його адреси на 3306 було відхилено.
4. Прямий доступ для одного іншого сервера
Буває, що застосунок працює на другому сервері й має підключатися напряму. Для цього базі потрібен тариф із власним IPv4, бо тариф з NAT перенаправляє лише ваш SSH-порт. Три зміни, і всі обмежені адресою сервера застосунку (тут 203.0.113.20):
sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp
CREATE USER 'app'@'203.0.113.20' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'203.0.113.20';
Якщо ufw ще не ввімкнено, спершу дозвольте SSH (sudo ufw allow OpenSSH), а потім виконайте sudo ufw enable. Подробиці — у посібнику з ufw.
Ми перевірили обидва замки окремо. З правилом у файрволі, але без відповідного користувача MySQL сервер відмовив з error 1130: Host '…' is not allowed to connect to this MySQL server. Після додавання користувача підключення пройшло. Без правила у файрволі підключення просто зависало за таймаутом. Будь-яка інша адреса в інтернеті отримує той самий таймаут.
5. Менше пам'яті
У простої, без власних даних, MySQL 8.0 займав на нашому сервері 383 МБ. Більшу частину забирає Performance Schema — діагностичний механізм, який резервує пам'ять заздалегідь. На невеликому VPS вимкніть його і задайте розмір основного кешу самі:
sudo tee /etc/mysql/mysql.conf.d/zz-small-vps.cnf >/dev/null <<'EOF'
[mysqld]
performance_schema = OFF
innodb_buffer_pool_size = 256M
max_connections = 50
EOF
sudo systemctl restart mysql
ps -o rss= -C mysqld
Після перезапуску MySQL займав 165 МБ. Буферний пул кешує дані й індекси, і 256 МБ підходять серверу на 2 ГБ, на якому працює й застосунок. Збільште його, якщо база — головне на сервері й виросла більшою за кеш. max_connections = 50 із запасом вистачає одному застосунку з пулом з'єднань. Ви втрачаєте статистику performance_schema. Увімкніть її назад, якщо знадобиться детально розбирати повільні запити.
6. Нічні бекапи
mysqldump --single-transaction знімає узгоджену копію таблиць InnoDB, не блокуючи застосунок. Оформіть це невеликим скриптом:
sudo tee /usr/local/bin/mysql-backup >/dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077
mkdir -p /var/backups/mysql
mysqldump --single-transaction --routines --triggers app | gzip > /var/backups/mysql/app-$(date +%F).sql.gz
find /var/backups/mysql -name 'app-*.sql.gz' -mtime +14 -delete
EOF
sudo chmod 755 /usr/local/bin/mysql-backup
echo '0 3 * * * root /usr/local/bin/mysql-backup' | sudo tee /etc/cron.d/mysql-backup
sudo /usr/local/bin/mysql-backup && sudo ls -l /var/backups/mysql
Кожен рядок має причину:
umask 077робить дамп доступним для читання лише root (-rw-------), адже в ньому всі ваші дані.pipefailзмушує весь скрипт упасти, якщо впавmysqldump. Без ньогоgzipзаписав би крихітний порожній архів і відзвітував би про успіх. Ми навмисно зламали команду, і скрипт завершився з кодом 2, як і має.find … -mtime +14 -deleteзберігає копії за два тижні.- Скрипт працює від root, тож
mysqldumpвходить через сокет і пароль ніде не лежить у файлі.
Бекап, який ви жодного разу не відновлювали, поки не рахується. Відновіть його в тимчасову базу й подивіться на дані:
sudo mysql -e "CREATE DATABASE app_restore"
gunzip -c /var/backups/mysql/app-2026-10-25.sql.gz | sudo mysql app_restore
sudo mysql -e "SHOW TABLES FROM app_restore"
sudo mysql -e "DROP DATABASE app_restore"
У нашому тесті у відновленій таблиці були ті самі рядки, що й у вихідній. Копії на тому самому диску не врятують, якщо зникне сам сервер, тож час від часу забирайте їх на іншу машину через scp або restic. Managed Backups зверху додають щоденні точки відновлення всього сервера.
Який тариф
Micro (2 vCPU, 2 ГБ, 25 ГБ, $5/міс) тримає MySQL з таким налаштуванням плюс вебзастосунок. Якщо сама база виросте за кілька гігабайтів, Small з 4 ГБ і 35 ГБ за $8/міс дасть змогу віддати буферному пулу 1 ГБ і більше. Обидва тарифи з NAT, і SSH-тунель із кроку 3 на них працює. Для кроку 4 потрібен власний IPv4: Micro-IP коштує $10/міс.
Віддаєте перевагу PostgreSQL? Посібник із PostgreSQL побудовано за тим самим планом. Усі тарифи — у розділі VPS, оплата в USDT, USDC або ETH у мережах Base, Ethereum або Polygon.
Коментарі
Поки немає коментарів. Будьте першим.