This guide walks you through installing MariaDB 11.x on Debian 13 (Trixie) or Debian 12 (Bookworm), securing it for production use, and applying essential performance tuning. Every command has been tested on both releases.

Prerequisites

Before you begin, confirm the following:

  • A Debian 13 or Debian 12 server with root or sudo access
  • At least 1 GB of RAM (2 GB+ recommended for production)
  • A working internet connection
  • System packages up to date

Update your system first:

sudo apt update && sudo apt upgrade -y

Install required dependencies:

sudo apt install -y apt-transport-https curl gnupg

Step 1 – Add the Official MariaDB Repository

Debian ships with MariaDB in its default repos, but the version is often behind. To get MariaDB 11.x, use the official mariadb_repo_setup script provided by the MariaDB Foundation.

Download and run the script:

curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-11.4"

MariaDB 11.4 is the current Long Term Support (LTS) release – the best choice for production servers. If you want the latest short-term release instead, replace 11.4 with 11.8 or check the MariaDB releases page for what is current.

Verify the repository was added:

cat /etc/apt/sources.list.d/mariadb.list

You should see entries pointing to dlm.mariadb.com for your Debian release.

Update the package index:

sudo apt update

Step 2 – Install MariaDB Server and Client

sudo apt install -y mariadb-server mariadb-client

Verify the installed version:

mariadb --version

Expected output (version number may differ slightly):

mariadb  Ver 15.1 Distrib 11.4.x-MariaDB, for debian-linux-gnu (x86_64) using  EditLine wrapper

Step 3 – Enable and Start MariaDB

sudo systemctl enable --now mariadb

Verify the service is running:

sudo systemctl status mariadb

Look for Active: active (running) in the output. You can also confirm the server responds:

sudo mariadb -e "SELECT VERSION();"

Step 4 – Secure the Installation

Run the security hardening script that ships with MariaDB:

sudo mariadb-secure-installation

The script asks several questions. Here is what to answer for a production setup:

PromptRecommended Answer
Enter current password for rootPress Enter (blank by default on fresh install)
Switch to unix_socket authentication?Y (keeps root login tied to the OS root user)
Change the root password?Y – set a strong password
Remove anonymous users?Y
Disallow root login remotely?Y
Remove test database?Y
Reload privilege tables now?Y

Verify you can log in after securing:

sudo mariadb -u root -p -e "SHOW DATABASES;"

Step 5 – Create a Database and User

Log in to the MariaDB shell:

sudo mariadb -u root -p

Create a database and a dedicated user with proper privileges. Replace the placeholder values with your own:

CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'Strong_P@ssw0rd!';

GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'localhost';

FLUSH PRIVILEGES;

If the user needs to connect from a remote host, create the account with the remote IP or use '%' for any host:

CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'Strong_P@ssw0rd!';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'192.168.1.%';
FLUSH PRIVILEGES;

Verify the grants:

SHOW GRANTS FOR 'app_user'@'localhost';

Exit the shell:

EXIT;

Test the new user login:

mariadb -u app_user -p app_db -e "SELECT DATABASE();"

Step 6 – Configure Remote Access

By default, MariaDB only listens on 127.0.0.1. To allow connections from other servers, edit the configuration:

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

Find the bind-address line and change it:

# Listen on all interfaces
bind-address = 0.0.0.0

If you only need one specific interface, set its IP instead of 0.0.0.0.

Restart MariaDB to apply:

sudo systemctl restart mariadb

Verify MariaDB is listening on port 3306:

ss -tlnp | grep 3306

Open Firewall Port 3306

If you are running ufw:

sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw reload

If you are using nftables (default on Debian 12/13):

sudo nft add rule inet filter input tcp dport 3306 ip saddr 192.168.1.0/24 accept

Replace 192.168.1.0/24 with your actual trusted network. Never open 3306 to the entire internet on a production server.

Test a remote connection from another machine:

mariadb -u app_user -p -h <server-ip> app_db -e "SELECT 1;"

Step 7 – Performance Tuning

The default MariaDB configuration is conservative. For a production server, tuning a few InnoDB parameters makes a significant difference.

Create a custom configuration file so your changes survive package upgrades:

sudo nano /etc/mysql/mariadb.conf.d/99-custom-tuning.cnf

Add the following – adjust values based on your available RAM:

[mysqld]
# InnoDB buffer pool - set to ~70% of total RAM on a dedicated DB server
# For a 4 GB server, use 2G-3G. For 8 GB, use 5G-6G.
innodb_buffer_pool_size = 2G

# InnoDB log file size - larger values improve write performance
# but increase crash recovery time
innodb_log_file_size = 512M

# Maximum concurrent connections
# Default is 151. Increase based on your application needs.
max_connections = 300

# Per-thread buffers - be conservative, these multiply by max_connections
sort_buffer_size = 2M
join_buffer_size = 2M
read_rnd_buffer_size = 2M

# Temp table size before writing to disk
tmp_table_size = 64M
max_heap_table_size = 64M

# Query cache is removed in MariaDB 11.x
# Do not add query_cache settings - they will cause errors

# Log slow queries for analysis
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2

Check the configuration for syntax errors before restarting:

sudo mariadbd --verbose --help 2>&1 | head -5

If there are no errors, restart:

sudo systemctl restart mariadb

Verify the new settings are active:

sudo mariadb -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
sudo mariadb -e "SHOW VARIABLES LIKE 'max_connections';"
sudo mariadb -e "SHOW VARIABLES LIKE 'innodb_log_file_size';"

Step 8 – Backup with mariadb-dump

Regular backups are non-negotiable. The mariadb-dump tool (the modern replacement for mysqldump) handles logical backups.

Dump a single database:

mariadb-dump -u root -p --single-transaction --routines --triggers app_db > /backup/app_db_$(date +%F).sql

Dump all databases:

mariadb-dump -u root -p --single-transaction --routines --triggers --all-databases > /backup/all_databases_$(date +%F).sql

Restore a database from a dump file:

mariadb -u root -p app_db < /backup/app_db_2026-03-18.sql

Automate daily backups with cron:

sudo crontab -e

Add this line to run a backup every day at 2 AM:

0 2 * * * /usr/bin/mariadb-dump -u root --single-transaction --routines --triggers --all-databases | gzip > /backup/all_databases_$(date +\%F).sql.gz 2>> /var/log/mariadb-backup.log

Make sure the backup directory exists and has correct permissions:

sudo mkdir -p /backup
sudo chmod 700 /backup

For production workloads, also consider MariaDB Backup (mariabackup) for hot physical backups that are faster to restore on large datasets.

Troubleshooting

MariaDB fails to start

Check the error log first:

sudo journalctl -u mariadb --no-pager -n 50
sudo tail -50 /var/log/mysql/error.log

Common causes:

  • innodb_buffer_pool_size set too high - if it exceeds available RAM, MariaDB will fail to allocate memory. Lower the value and restart.
  • Port 3306 already in use - check with ss -tlnp | grep 3306. Another MariaDB/MySQL instance or a leftover process may be holding the port.
  • Permission issues on data directory - run ls -la /var/lib/mysql/ and confirm ownership is mysql:mysql. Fix with sudo chown -R mysql:mysql /var/lib/mysql.

Cannot connect remotely

  • Confirm bind-address is set to 0.0.0.0 or the correct interface IP, not 127.0.0.1.
  • Confirm the user account was created with the correct host ('user'@'%' or 'user'@'192.168.x.%').
  • Check the firewall: sudo ufw status or sudo nft list ruleset.
  • Test basic connectivity: telnet <server-ip> 3306.

Access denied errors

Check what host the user is connecting from - it must match the user account definition exactly:

SELECT user, host FROM mysql.user;

If you locked yourself out of root, you can reset access using the --skip-grant-tables method:

sudo systemctl stop mariadb
sudo mariadbd-safe --skip-grant-tables &
mariadb -u root

Then reset the password:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword123!';
FLUSH PRIVILEGES;
EXIT;

Stop the unsafe instance and start MariaDB normally:

sudo kill $(cat /var/run/mysqld/mysqld.pid)
sudo systemctl start mariadb

Slow query performance

Enable the slow query log (shown in the tuning section above), then analyze it:

sudo mariadb-dumpslow -s t /var/log/mysql/slow-query.log | head -20

Check current InnoDB status for lock waits and other issues:

sudo mariadb -e "SHOW ENGINE INNODB STATUS\G" | head -80

Summary

You now have MariaDB 11.x running on Debian 13 or Debian 12 with a secured installation, a production-ready configuration, remote access configured, and automated backups in place. From here, monitor your slow query log regularly, keep MariaDB updated with sudo apt update && sudo apt upgrade, and test your backup restores - a backup you have never tested is not a backup.

1 COMMENT

  1. Hello,
    Unfortunately, Debian 9 is EOL.
    Any idea how to force the update ?
    Thank you

    # [error] Debian 9 ‘stretch’ has reached End of Life and is no longer supported
    # [error] # The MariaDB Repository only supports these distributions:
    # * RHEL/Rocky 8 & 9 (rhel)
    # * RHEL/CentOS 7 (rhel)
    # * Ubuntu 18.04 LTS (bionic), 20.04 LTS (focal), and 22.04 LTS (jammy)
    # * Debian 10 (buster), & 11 (bullseye)
    # * SLES 12 & 15 (sles)

LEAVE A REPLY

Please enter your comment!
Please enter your name here