MySQL / MariaDB
MariaDB is an open-source fork of MySQL and serves as the default MySQL-compatible database in RHEL-based distributions. This article covers MariaDB installation, security initialization, basic SQL operations, user and database management, backup and recovery, and remote access configuration.
Versions Across Distributions
Section titled “Versions Across Distributions”Install MariaDB
Section titled “Install MariaDB”Install from System Default Repository
Section titled “Install from System Default Repository”sudo dnf install mariadb-server mariadb -yUse the MariaDB Official Repository (for Newer Versions)
Section titled “Use the MariaDB Official Repository (for Newer Versions)”The MariaDB version in the system repositories varies by distribution (EL 10 ships 10.11, and some EL 9 repositories also provide 10.11 / 11.8 module streams). If you want a consistent MariaDB 12.3 LTS (the current LTS; 11.8 LTS is still supported), add the official repository:
sudo tee /etc/yum.repos.d/MariaDB.repo << 'EOF'[mariadb]name = MariaDBbaseurl = https://mirror.mariadb.org/yum/12.3/rhel/$releasever/$basearchgpgkey = https://mirror.mariadb.org/yum/RPM-GPG-KEY-MariaDBgpgcheck = 1EOFsudo dnf install MariaDB-server MariaDB-client -yStart the Service
Section titled “Start the Service”sudo systemctl start mariadbsudo systemctl enable mariadbsudo systemctl status mariadbSecurity Initialization
Section titled “Security Initialization”After installation, be sure to run the security initialization script to set the root password and remove insecure defaults:
sudo mysql_secure_installationThe wizard will ask the following questions in order. The recommended responses are:
- Enter current root password — Press Enter on first install (empty password)
- Switch to unix_socket authentication — Choose based on your needs,
Yrecommended - Set root password —
Y, then enter a strong password - Remove anonymous users —
Y - Disallow root remote login —
Y - Delete test database —
Y - Reload privilege tables —
Y
After initialization, test the login:
sudo mysql -u root -pBasic SQL Operations
Section titled “Basic SQL Operations”Here are the most common SQL statements for daily use.
Database Operations
Section titled “Database Operations”-- View all databasesSHOW DATABASES;
-- Create a database (with character set)CREATE DATABASE myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Switch databaseUSE myapp;
-- Drop a databaseDROP DATABASE myapp;Table Operations
Section titled “Table Operations”-- Create a tableCREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
-- View table structureDESCRIBE users;
-- View all tablesSHOW TABLES;CRUD Operations
Section titled “CRUD Operations”-- Insert data
-- Query dataSELECT * FROM users;SELECT username, email FROM users WHERE id = 1;
-- Update data
-- Delete dataDELETE FROM users WHERE username = 'lisi';User and Database Management
Section titled “User and Database Management”In production environments, you should not use the root account for application connections. Instead, create a dedicated user for each application.
Create a User and Database
Section titled “Create a User and Database”-- Create a databaseCREATE DATABASE webapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Create a user (local connections only)CREATE USER 'webapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
-- Grant all privileges on the specified databaseGRANT ALL PRIVILEGES ON webapp.* TO 'webapp_user'@'localhost';
-- Flush privilegesFLUSH PRIVILEGES;View and Manage Users
Section titled “View and Manage Users”-- View all usersSELECT User, Host FROM mysql.user;
-- View user privilegesSHOW GRANTS FOR 'webapp_user'@'localhost';
-- Change user passwordALTER USER 'webapp_user'@'localhost' IDENTIFIED BY 'NewPassword456!';
-- Revoke privilegesREVOKE ALL PRIVILEGES ON webapp.* FROM 'webapp_user'@'localhost';
-- Drop a userDROP USER 'webapp_user'@'localhost';Read-Only User Example
Section titled “Read-Only User Example”CREATE USER 'reader'@'localhost' IDENTIFIED BY 'ReadOnly789!';GRANT SELECT ON webapp.* TO 'reader'@'localhost';FLUSH PRIVILEGES;mysqldump Backup and Recovery
Section titled “mysqldump Backup and Recovery”mysqldump is the built-in logical backup tool for MariaDB/MySQL, suitable for small to medium-sized databases.
Back Up a Single Database
Section titled “Back Up a Single Database”mysqldump -u root -p webapp > /backup/webapp_$(date +%Y%m%d_%H%M%S).sqlBack Up All Databases
Section titled “Back Up All Databases”mysqldump -u root -p --all-databases > /backup/all_databases_$(date +%Y%m%d_%H%M%S).sqlBack Up Specific Tables
Section titled “Back Up Specific Tables”mysqldump -u root -p webapp users > /backup/webapp_users.sqlCompressed Backup
Section titled “Compressed Backup”mysqldump -u root -p webapp | gzip > /backup/webapp_$(date +%Y%m%d).sql.gzRestore a Database
Section titled “Restore a Database”# Create the target database first (if it doesn't exist)mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS webapp;"
# Restore datamysql -u root -p webapp < /backup/webapp_20260324.sqlgunzip < /backup/webapp_20260324.sql.gz | mysql -u root -p webappAutomated Backup Script
Section titled “Automated Backup Script”sudo tee /usr/local/bin/mariadb-backup.sh << 'SCRIPT'#!/bin/bashBACKUP_DIR="/backup/mariadb"DATE=$(date +%Y%m%d_%H%M%S)RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
# Back up all databasesmysqldump -u root --all-databases | gzip > "${BACKUP_DIR}/all_db_${DATE}.sql.gz"
# Delete backups older than the retention periodfind "$BACKUP_DIR" -name "*.sql.gz" -mtime +${RETENTION_DAYS} -delete
echo "Backup completed: ${BACKUP_DIR}/all_db_${DATE}.sql.gz"SCRIPT
sudo chmod +x /usr/local/bin/mariadb-backup.shAdd a cron job to run the backup daily at 2:00 AM:
echo "0 2 * * * root /usr/local/bin/mariadb-backup.sh" | sudo tee /etc/cron.d/mariadb-backupRemote Access Configuration
Section titled “Remote Access Configuration”By default, MariaDB only listens on localhost. To allow remote access, the following configuration changes are needed.
Modify the Bind Address
Section titled “Modify the Bind Address”sudo tee /etc/my.cnf.d/bind-address.conf << 'EOF'[mysqld]bind-address = 0.0.0.0EOFIf you only need to listen on a specific IP, replace 0.0.0.0 with that IP address.
Restart the Service
Section titled “Restart the Service”sudo systemctl restart mariadbCreate a User Allowed to Connect Remotely
Section titled “Create a User Allowed to Connect Remotely”-- Allow connections from any IP (not recommended for production)CREATE USER 'remote_user'@'%' IDENTIFIED BY 'RemotePass123!';GRANT ALL PRIVILEGES ON webapp.* TO 'remote_user'@'%';
-- Allow connections from a specific IP only (recommended)CREATE USER 'remote_user'@'192.168.1.100' IDENTIFIED BY 'RemotePass123!';GRANT ALL PRIVILEGES ON webapp.* TO 'remote_user'@'192.168.1.100';
FLUSH PRIVILEGES;Open the Firewall Port
Section titled “Open the Firewall Port”sudo firewall-cmd --permanent --add-service=mysqlsudo firewall-cmd --reloadTest the Remote Connection
Section titled “Test the Remote Connection”On the remote client, run:
mysql -u remote_user -p -h server_IP_addressSecurity Recommendations
Section titled “Security Recommendations”Remote access introduces additional security risks. The following measures are recommended:
- Restrict user connection source IPs; avoid using the
'%'wildcard - Use firewall rules to restrict access to port 3306
- Consider using an SSH tunnel instead of directly exposing the port
- Enable SSL encrypted connections
# Create an SSH tunnel locallyssh -L 3306:127.0.0.1:3306 user@server_IP_address
# Then connect locallymysql -u webapp_user -p -h 127.0.0.1Common Configuration Optimizations
Section titled “Common Configuration Optimizations”sudo tee /etc/my.cnf.d/custom.conf << 'EOF'[mysqld]# Character setcharacter-set-server = utf8mb4collation-server = utf8mb4_unicode_ci
# InnoDB buffer pool (recommended: 50%-70% of available memory)innodb_buffer_pool_size = 256M
# Separate tablespace per tableinnodb_file_per_table = 1
# Slow query logslow_query_log = 1slow_query_log_file = /var/log/mariadb/slow-query.loglong_query_time = 2
# Maximum connectionsmax_connections = 150EOFsudo systemctl restart mariadbCommon Operations Quick Reference
Section titled “Common Operations Quick Reference”# Start / Stop / Restartsudo systemctl start mariadbsudo systemctl stop mariadbsudo systemctl restart mariadb
# View running statussudo systemctl status mariadb
# Log into the databasemysql -u root -p
# View database versionmysql -V
# View runtime status variablesmysqladmin -u root -p status
# View process listmysqladmin -u root -p processlist
# Check and repair tablesmysqlcheck -u root -p --all-databases --auto-repairFurther Reading
Section titled “Further Reading”- PostgreSQL — Another popular database
- Getting Started with SELinux — Database-related SELinux configuration