TL;DR Skip the fluff and copy-paste the commands. This guide shows you how to:
- run MySQL 8.0 on 2 GB RAM without swapping to death
- remove every last Alibaba “security” agent that eats half your memory
- keep seven days of encrypted, compressed backups on two different machines
Prerequisites
- Debian 12 VPS:
192.168.0.2
, 2 vCPU / 2 GB RAM, 2 120 IOPS (the vendor lied—expect ~2 000). - Backup box on the same LAN:
192.168.0.3
, SSH daemon listening on22102/tcp
. - Alibaba Cloud Security Group already allows
53768/tcp
(SSH) and33106/tcp
(MySQL). - You have sudo and your SSH key on the server.
1. Change SSH Port and Disable Local Firewall
# 1. Open new port first—don’t lock yourself out
sudo sed -i 's/#Port 22/Port 53768/' /etc/ssh/sshd_config
sudo systemctl restart sshd
# 2. Once you can log in on 53768, kill UFW
sudo systemctl stop ufw
sudo systemctl disable ufw
sudo apt purge ufw -y
Security Group handles the rest; UFW is dead weight on 2 GB.
2. Remove Alibaba Cloud Agents (Aegis, CloudMonitor, Aliyun Assist)
sudo systemctl stop aliyun.service
sudo systemctl disable aliyun.service
sudo rm -rf /usr/local/aegis* /usr/local/cloudmonitor /etc/init.d/aegis
sudo rm -rf /etc/systemd/system/aliyun*
sudo apt purge aliyun-assist aliyun-cli -y
Reboot and run ps aux | grep -E 'aegis|aliyun'
—should be empty.
3. Install MySQL 8.0 from the Official APT Repo
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb # choose 8.0
sudo apt update && sudo apt install -y mysql-server
Do not start it yet—tune first.
4. Tuning my.cnf for 2 120 IOPS and 2 GB RAM
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# Network
bind-address = 192.168.0.2
port = 33106
user = mysql
default_authentication_plugin = mysql_native_password
# InnoDB for 2 120 IOPS
innodb_buffer_pool_size = 768M
innodb_log_file_size = 128M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2000
innodb_io_capacity_max = 3000
# Save RAM
skip_name_resolve = 1
performance_schema = OFF
max_connections = 50
key_buffer_size = 32M
tmp_table_size = 32M
max_heap_table_size = 32M
sudo systemctl restart mysql
sudo systemctl enable mysql
5. Lock Down Accounts
sudo mysql -uroot -p
-- root only from localhost
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'SuperStrongRootPass';
-- application user, one source IP only
CREATE USER IF NOT EXISTS 'app'@'192.168.0.3' IDENTIFIED WITH mysql_native_password BY 'AppUserPass';
GRANT ALL PRIVILEGES ON *.* TO 'app'@'192.168.0.3';
FLUSH PRIVILEGES;
Test from the backup host:
mysql -h192.168.0.2 -P33106 -uapp -p
6. Encrypted Nightly Backups (Local + Remote)
6.1 Install tools
sudo apt install zip msmtp rsync -y
6.2 Backup script: /usr/local/bin/mysql_backup.sh
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/www/bak/db"
REMOTE_HOST="192.168.0.3"
REMOTE_PORT="22102"
REMOTE_DIR="/www/bak/mysql"
RETAIN_DAYS=3
ZIP_PASS="12345678"
MAIL_TO="123@163.com"
mkdir -p "$BACKUP_DIR"
cd "$BACKUP_DIR"
# Dump each DB
for DB in $(mysql -uroot -p'SuperStrongRootPass' -N -e "SHOW DATABASES;" | grep -Ev '^(information_schema|performance_schema|mysql|sys)$'); do
TS=$(date +%F-%H%M%S)
DUMP_FILE="${DB}_${TS}.sql"
mysqldump -uroot -p'SuperStrongRootPass' --single-transaction --routines --triggers "$DB" > "$DUMP_FILE"
zip -P "$ZIP_PASS" "${DUMP_FILE}.zip" "$DUMP_FILE"
rm "$DUMP_FILE"
done
# Push to remote
rsync -avz -e "ssh -p $REMOTE_PORT" ./*.zip root@$REMOTE_HOST:$REMOTE_DIR/
# Prune local & remote
find "$BACKUP_DIR" -type f -mtime +$RETAIN_DAYS -delete
ssh -p $REMOTE_PORT root@$REMOTE_HOST "find $REMOTE_DIR -type f -mtime +$RETAIN_DAYS -delete"
# Ping us
echo "MySQL backup $(date +%F) completed" | msmtp "$MAIL_TO"
sudo chmod +x /usr/local/bin/mysql_backup.sh
6.3 Schedule it
sudo crontab -e
0 1 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
7. msmtp for Email Alerts
sudo nano /etc/msmtprc
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
account default
host smtp.163.com
port 465
from 123@163.com
user 123@163.com
password YOUR_SMTP_AUTH_TOKEN
Test:
echo "test" | msmtp 123@163.com
8. Smoke Test
- Reboot:
sudo reboot
- SSH into
192.168.0.2:53768
- Connect from backup box:
mysql -h192.168.0.2 -P33106 -uapp -p
- Wait for 01:00 UTC and check
/www/bak/db
and192.168.0.3:/www/bak/mysql
9. Pitfalls (a.k.a. “Why it broke at 3 a.m.”)
- Security Group or remote
ufw
forgot port 22102 → rsync dies with “broken pipe”. - Special characters in password → wrap in single quotes inside the script.
- innodb_buffer_pool_size > 1 GB → OOM killer loves MySQL.
- 163 SMTP needs an auth token, not your login password.
10. TL;DR Recap
- Debian 12 + MySQL 8.0: 768 MB buffer pool, 2 000 IOPS tuned.
- Alibaba bloatware nuked—freeing ~120 MB RAM.
- Encrypted, compressed backups on two hosts, auto-pruned after three days.
Happy hacking, and may your pagers stay silent.
Comments NOTHING