XFS (preferred) or EXT4.
/var/lib/mysql should be created as a distinct mount point sized to hold the expected aggregate size of the database files. If expected database size is not known, a sensible default is 50GB.
/backup should be created as a distinct mount point sized to hold the expected size of at least one complete backup. If expected database size is not known, a sensible default is 50GB.
Mount options...
noatime,nodiratime,relatime
df -h
Refer to the Sensible Starting Sizes and Cookie Cutter Configs shown on the MySQL Install Page
lscpu
free -h
MySQL prefers low or zero swap usage. Best practice:
Swap enabled but small (1–2 GB)
swappiness=1
Never disable swap on production.
free -h
sysctl vm.swappiness
Make sure you can access the repositories via the internet or ensure you have a local up to date repository available.
More information about where to populate your local repositories from can be found on the distribution specific install pages.Ensure there are no MariaDB or MySQL CE libraries already installed (some of these have shipped by default on some distributions)....
yum list installed | grep -i maria
yum list installed | grep -i mysql
To remove, if necessary, use...
sudo yum remove mariadb-libs.x86_64
sudo yum remove mysql-community-*
sudo yum remove mysql-release-el7.x86_64
sudo yum clean all
yum list installed | grep -i libaio
yum list installed | grep -i numactl-libs
yum list installed | grep -i perl
yum list installed | grep -i wget
yum list installed | grep -i tar
sudo dnf install -y libaio numactl-libs perl wget tar
sysctl vm.swappiness
sysctl vm.overcommit_memory
sysctl fs.aio-max-nr
sysctl fs.file-max
sysctl net.core.somaxconn
sudo vi /etc/sysctl.d/mysql.conf
vm.swappiness = 1
vm.overcommit_memory = 0
fs.aio-max-nr = 1048576
fs.file-max = 1000000
net.core.somaxconn = 65535
sudo sysctl --system
If you use an RPM or DEB install (i.e. YUM or APT), then this will be done automatically.
SELinux should be enabled and enforcing. Check with…
getenforce
sestatus
sudo semanage port -l | grep mysql
sudo semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?"
sudo restorecon -Rv /data/mysql
sudo aa-status
sudo nano /etc/apparmor.d/usr.sbin.mysqld
AppArmor
MySQL should be reachable on port 3306.
sudo firewall-cmd --permanent --zone=public --list-ports
To fix...
sudo firewall-cmd --add-service=mysql --permanent
sudo firewall-cmd --reload
firewalld
sudo ufw allow 3306/tcp
ufw
Transparent Huge Pages should be disabled.
Check with...
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
Should show [never]sudo vi /etc/tmpfiles.d/disable-thp.conf
w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
w /sys/kernel/mm/transparent_hugepage/defrag - - - - never
sudo systemd-tmpfiles –create
ls -d /sys/devices/system/node/node*
If only node0 is returned, then server does not have NUMANUMA imbalance can lead to severe stalls under high load.
If NUMA exists, best practice:
Bind mysqld to all nodes equally, or
Disable NUMA in BIOS, or
Run mysqld with numactl:
numactl --interleave=all mysqld
MySQL replication and GTIDs depend on correct time. Use tools like chrony.
Assuming chrnoyd is used. Check with…
systemctl status chronyd
chronyc sources -v
chronyc tracking
sudo chronyc selectdata
If the hostname cannot be resolved, MySQL startup or replication may hang.
Check with...
hostname -f
getent hosts $(hostname -f)