Performance
- Mariadb Slow log
- Journal log size Opimization
- Essential logs to watch
- Root log in by both socket and password
Mariadb Slow log
/var/log/mysql/mariadb-slow.log is the standard file path used to store the slow query log in MariaDB and MySQL databases on Linux systems. This log records any SQL queries that exceed a defined execution time threshold, helping database administrators diagnose and troubleshoot performance bottlenecks. [1, 2, 3, 4]SHOW VARIABLES LIKE 'slow_query_log%';
SHOW VARIABLES LIKE 'long_query_time';
slow_query_log: Should beONto record queries.slow_query_log_file: Path to the log file (e.g.,/var/log/mysql/mariadb-slow.log).long_query_time: The threshold in seconds. Queries taking longer than this value are logged. [1, 2, 3, 4]
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/mariadb-slow.log';
SET GLOBAL long_query_time = 2; -- Logs queries taking over 2 seconds
SET GLOBAL log_queries_not_using_indexes = 'ON'; -- Optional: logs unindexed queries
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mariadb-slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
sudo mkdir -p /var/log/mysql
sudo touch /var/log/mysql/mariadb-slow.log
sudo chown -R mysql:mysql /var/log/mysql
sudo chmod 750 /var/log/mysql
sudo systemctl restart mariadb
# Or on some systems: sudo systemctl restart mysql
cat or vi, use native parsing tools: [1, 2]- Using
mysqldumpslow: A built-in command-line tool that groups similar queries together and sorts them by execution time.bashmysqldumpslow -s t /var/log/mysql/mariadb-slow.logUse code with caution. - Using
pt-query-digest: Part of the advanced Percona Toolkit, this creates highly detailed and easily readable performance summaries.bashpt-query-digest /var/log/mysql/mariadb-slow.log[1, 2]Use code with caution.
- Is your database currently experiencing slow downs or high CPU usage?
- Do you need help optimizing a specific slow query found in this log?
- Are you getting a permission denied error when MariaDB tries to create the file?
-
mariadb.comSlow Query Log Overview | Server | MariaDB DocumentationSlow Query Log Overview. Complete Slow Query Log Overview gu...
-
PleskHow to enable the MySQL/MariaDB slow query log and analyze it on ...Answer * Connect to your Plesk server via SSH. * Enable the ...
-
cPanelHow to Enable the Slow Query Log in MySQL® or MariaDBTo enable the Slow Query Log for MySQL or MariaDB: * Log in ...
- Identifies slow pages: If a website page takes 5 seconds to load, this log reveals the exact SQL query causing the delay.
- Pins down high CPU/Memory: Queries that scan millions of rows without using indexes spike server resources. The log flags them immediately.
- Spotting unindexed tables: By enabling
log_queries_not_using_indexes, the log captures queries performing full table scans. - Easy fixes: Adding a single index to a column flagged in this log can often drop a query's execution time from 3 seconds to 3 milliseconds.
- Poorly written ORM queries: Modern web frameworks (like Laravel, Hibernate, or Django) sometimes generate massive, inefficient SQL joins behind the scenes.
- N+1 query problems: It reveals loops where your application accidentally runs hundreds of tiny, redundant queries instead of one efficient query.
- Tracking growth trends: By comparing log sizes and query counts month-over-month, you can see if your database performance is degrading as your user base grows.
- Postponing costly upgrades: Optimizing the top 3 slow queries in this log can often slash server resource usage by 50%, saving you from paying for a larger, more expensive server.
- Is your database currently running slow, or are you just setting this up proactively?
- What application or framework (e.g., WordPress, Node.js, Python) is connecting to this database?
- Would you like an example of how to read a raw entry from this log file?
mariadb-slow.log.1 is not normal for a healthy, optimized production database..1 extension indicates this is a rotated log file (an older log preserved by Linux logrotate), meaning your database generated 3 GB of slow query data in a single log rotation period—typically just one week or one day.- Missing Indexes (Most Common): If a query searches a table with 1 million rows without an index, MariaDB must read all 1 million rows from the disk every single time. This is called a "Full Table Scan."
log_queries_not_using_indexesis ON: If this setting is enabled, MariaDB logs every single query that doesn't use an index, even if it executes in 0.001 seconds. On a busy site, this will inflate the log file to gigabytes in hours.long_query_timeis set too low: If this is set to0or a very low fraction (like0.01seconds) on a high-traffic application, almost every single query gets logged.- An Application Loop Bug: Your application code might be trapped in a loop, running the same slow query thousands of times per minute.
cat, nano, or vi, as it can freeze your server's memory. Instead, look at just the first few lines:head -n 50 /var/log/mysql/mariadb-slow.log.1
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
SHOW VARIABLES LIKE 'long_query_time';
- If
log_queries_not_using_indexesisONand you have a busy database, turn it off to stop the log explosion:sqlSET GLOBAL log_queries_not_using_indexes = 'OFF';Use code with caution.
mysqldumpslow to extract the top 5 worst offending queries that are taking up all that space:mysqldumpslow -s c -t 5 /var/log/mysql/mariadb-slow.log.1
-s c) and shows the top 5 (-t 5) query patterns causing the bulk of the log size).sudo truncate -s 0 /var/log/mysql/mariadb-slow.log.1
- What is the output of the
mysqldumpslowcommand above? (You can paste a small snippet of the top query pattern). - What are your current
long_query_timeandlog_queries_not_using_indexesvalues? - Is your server currently running out of disk space because of this?
oc_filecache table). The log is exploding because log_queries_not_using_indexes is turned ON, combined with Nextcloud constantly checking its app data folder.Query_time: 0.089309: The query is actually very fast, taking only 0.08 seconds (well below your 2.0-secondlong_query_timethreshold).Full_scan: Yes: The query is doing a full table scan, checking all191,623rows in theoc_filecachetable every single time it runs.- Why it's logged: Because
log_queries_not_using_indexes = ON, MariaDB is forced to write this fast query to your log file every few hours. On a busy server with multiple users or cron jobs, this fills up gigabytes of text very quickly.
SET GLOBAL log_queries_not_using_indexes = 'OFF';
/etc/mysql/mariadb.conf.d/50-server.cnf or /etc/my.cnf) and change or add this line under the [mysqld] section:log_queries_not_using_indexes = 0
sudo truncate -s 0 /var/log/mysql/mariadb-slow.log.1
SELECT COUNT(*) FROM oc_filecache WHERE path LIKE 'appdata_...%' uses a wildcard (%) at the end of the string. Nextcloud should be using its built-in index on the path column, but sometimes these indexes get corrupted or missing during major Nextcloud upgrades./var/www/nextcloud or /var/www/html):sudo -u www-data php occ db:add-missing-indices
www-data with your web server user if you are using a different one like nginx or apache).- Did turning off
log_queries_not_using_indexessuccessfully stop the log from growing? - Do you know the exact directory path where your Nextcloud/OwnCloud instance is installed?
- Are you running this instance inside a Docker container, or directly on the host system?
Journal log size Opimization
sudo journalctl --vacuum-size=100M to limit the size of your system logs. [1]- Check current size: Run
journalctl --disk-usageto see how much space the logs take. - Reduce by size: Run
sudo journalctl --vacuum-size=500Mto shrink the logs down to 500 megabytes (or another size like1G). - Reduce by time: Run
sudo journalctl --vacuum-time=2weeksto delete logs older than a specific timeframe. [1, 2, 3]
- Open config file: Edit
/etc/systemd/journald.confusing a text editor with root privileges (likesudo nano /etc/systemd/journald.conf). - Set maximum limits: Find and uncomment (remove the
#at the start of) lines likeSystemMaxUse=500MorSystemMaxFileSize=50Mto
-
Linux MintSOLVED: var/log is large and keeps growing... /var/log/lightdm 4.0K /var/log/mintsystem.log 4.0K /var/
-
Debian forums[Solved] How to manage the size of /var/log/journalMy system runs headless and I have only 782 packages install...
-
SiteLintHow do I clear a big /var/log/journal folder? - SiteLintLet's then delete old log files from the /var/log/journal fo...
- Desktop / Personal PC (500MB – 1GB): Enough for daily troubleshooting without wasting SSD space.
- Standard Web/App Server (1GB – 2GB): Retains weeks of operational history for debugging.
- Production / High-Traffic Server (4GB – 10GB): Necessary if you log heavy application traffic locally.
- Containers / Microservices (50MB – 100MB): Keep it minimal since logs should stream to an external aggregator.
- Disk Capacity: A safe rule of thumb is to limit your journal to 10% of your total partition size (systemd's default behavior) or caps at 4GB, whichever is smaller.
- Log Rotation Frequency: If your system generates 500MB of logs a day, a 1GB limit only gives you 2 days of history.
- External Forwarding: If you send logs to a central server (like Elasticsearch or Datadog), you can safely set the local journal size much lower.
- Is this for a personal PC or a server?
- What is the total storage capacity of your drive?
sudo nano /etc/systemd/journald.confSystemMaxUse=2G(Caps total disk space used by logs)SystemMaxFileSize=200M(Splits logs into smaller, easier-to-read files)RuntimeMaxUse=200M(Caps log memory usage to protect your 8GB RAM)
sudo systemctl restart systemd-journaldEssential logs to watch
For an Ubuntu server administrator, I recommend monitoring logs in six major areas: kernel/hardware, storage, system services, security, networking, and applications.
1. System and Kernel Logs — highest priority
Kernel messages
journalctl -k
dmesg -T
Watch for:
I/O errorEXT4-fs errorBuffer I/O errorresetdisconnectUSB errorOut of memoryOOM killersegfaulthardware errorthermalwatchdog
For live monitoring:
journalctl -kf
2. Storage and Disk Health ⚠️
Especially important for servers running databases, Docker, Nextcloud, Immich, etc.
Filesystem errors
journalctl -k | grep -iE "error|ext4|xfs|btrfs|i/o"
Critical messages include:
EXT4-fs error
Buffer I/O error
blk_update_request
I/O error
device offline
reset
Disk SMART health
sudo smartctl -a /dev/sda
Monitor:
| SMART Attribute | Concern |
|---|---|
| Reallocated_Sector_Ct | Growing |
| Current_Pending_Sector | > 0 |
| Offline_Uncorrectable | > 0 |
| UDMA_CRC_Error_Count | Increasing |
| Temperature | High |
| Power_On_Hours | Aging disks |
Run long tests periodically:
sudo smartctl -t long /dev/sda
3. Memory and OOM Events
OOM killer
journalctl | grep -iE "out of memory|oom|killed process"
Live:
journalctl -f | grep -iE "oom|memory"
Check memory:
free -h
Swap:
swapon --show
For servers, unexpected OOM events are high priority because they may silently kill:
- MariaDB
- PHP-FPM
- Redis
- Docker containers
- Nextcloud background processes
4. Failed System Services
One of the most useful administrator commands:
systemctl --failed
Check system errors:
journalctl -p err..alert
Recent boot errors:
journalctl -b -p warning
Useful services to watch:
systemctl status nginx
systemctl status php8.3-fpm
systemctl status mariadb
systemctl status redis-server
systemctl status docker
Depending on your PHP version:
systemctl list-units --type=service
5. Nginx Web Server
For web servers:
tail -f /var/log/nginx/error.log
Access log:
tail -f /var/log/nginx/access.log
Important errors:
502 Bad Gateway
504 Gateway Timeout
connect() failed
upstream timed out
permission denied
too many open files
For error frequency:
grep -i "error" /var/log/nginx/error.log
6. PHP-FPM
Check:
journalctl -u php8.3-fpm
Live:
journalctl -fu php8.3-fpm
Watch for:
- PHP worker crashes
server reached pm.max_children- Out of memory
- Slow requests
- Permission errors
- Session errors
A particularly important message:
server reached pm.max_children
This usually means PHP-FPM is saturated.
7. MariaDB / MySQL Database
Check logs:
journalctl -u mariadb
Live:
journalctl -fu mariadb
Watch for:
- InnoDB corruption
- Disk full
- Connection exhaustion
- Crashes
- Table corruption
Useful checks:
mysqladmin status
Connections:
mysqladmin processlist
8. Docker
For your type of server setup, Docker should be monitored continuously.
Docker daemon
journalctl -u docker
Live:
journalctl -fu docker
Container status
docker ps
Stopped containers:
docker ps -a
Container logs:
docker logs CONTAINER_NAME
Live:
docker logs -f CONTAINER_NAME
Check Docker disk usage:
docker system df
This is important because Docker logs and images can unexpectedly fill the filesystem.
9. Disk Space 🚨
Run:
df -h
Also check inode exhaustion:
df -ih
Administrators should generally investigate:
| Usage | Status |
|---|---|
| < 70% | Normal |
| 70–85% | Monitor |
| 85–95% | Warning |
| >95% | Critical |
Find large directories:
sudo du -xh / --max-depth=1 2>/dev/null | sort -h
For logs:
journalctl --disk-usage
Reduce old journals if necessary:
sudo journalctl --vacuum-time=14d
10. Network Problems
Check networking services:
journalctl -u NetworkManager
For Ubuntu Server using systemd-networkd:
journalctl -u systemd-networkd
Current network connections:
ss -tulpn
Network errors:
ip -s link
Watch for:
- RX errors
- TX errors
- Dropped packets
- Interface resets
11. SSH and Security 🔐
Ubuntu authentication log:
sudo tail -f /var/log/auth.log
Failed SSH attempts:
grep "Failed password" /var/log/auth.log
Successful logins:
grep "Accepted" /var/log/auth.log
Current users:
who
Recent logins:
last
Failed login database:
lastb
12. System Reboots and Unexpected Shutdowns
Check reboot history:
last reboot
Previous boot:
journalctl -b -1
Check for unexpected shutdown:
journalctl | grep -iE "shutdown|reboot|panic|crash"
Kernel panic:
journalctl -k | grep -i panic
13. Cron and Scheduled Jobs
Depending on Ubuntu configuration:
journalctl -u cron
Or:
grep CRON /var/log/syslog
Important for:
- Nextcloud cron
- Backups
- Database dumps
- SSL certificate renewal
- Monitoring scripts
14. Nextcloud-specific Monitoring
For your Nextcloud servers, I would specifically watch:
sudo -u www-data php /var/www/nextcloud/occ status
Cron:
sudo -u www-data php /var/www/nextcloud/occ background:cron
Logs:
tail -f /path/to/nextcloud/data/nextcloud.log
Watch for:
- Database errors
- Redis connection failures
- File locking problems
- PHP memory exhaustion
- Background job failures
- WebDAV errors
- WOPI/Collabora errors
⭐ My Recommended Administrator Dashboard
For a self-hosted Ubuntu server, these are the most important things to continuously monitor:
┌───────────────────────────────────────┐
│ Ubuntu Server Monitoring │
├───────────────────────────────────────┤
│ 🔴 Disk I/O / Filesystem errors │
│ 🔴 SMART disk health │
│ 🔴 Disk space / inode usage │
│ 🔴 OOM / memory exhaustion │
│ 🔴 Failed systemd services │
│ 🔴 Docker container failures │
│ 🟠 Nginx 502/504 errors │
│ 🟠 PHP-FPM saturation │
│ 🟠 MariaDB errors │
│ 🟠 Network interface errors │
│ 🟠 SSH/security attacks │
│ 🟡 Backup failures │
│ 🟡 SSL certificate expiration │
│ 🟡 Temperature / hardware issues │
└───────────────────────────────────────┘
🚀 My recommended daily commands
# Critical system errors
journalctl -p err..alert --since today
# Failed services
systemctl --failed
# Disk usage
df -h
# Memory
free -h
# Docker containers
docker ps -a
# Kernel/hardware errors
journalctl -k -p err..alert
# Recent authentication failures
grep "Failed password" /var/log/auth.log | tail
For your Ubuntu servers specifically
Given that you operate multiple Ubuntu servers with Nextcloud, Nginx, PHP-FPM, MariaDB, Redis, Docker, Immich, and other self-hosted services, I would prioritize:
1. Disk I/O errors → 2. SMART health → 3. OOM events → 4. disk capacity → 5. failed services → 6. Docker container health → 7. Nginx/PHP/MariaDB errors.
Root log in by both socket and password
The fix: let root log in by socket or password
First, look at how root is currently set up. Don’t paste the output here, since it contains the password hash:
sudo mariadb -u root -p -e "SHOW CREATE USER 'root'@'localhost'\G"
You’ll see something like IDENTIFIED BY PASSWORD '*ABC...' (the mysql_native_password plugin) or IDENTIFIED VIA .... If it’s the common native-password form, add the socket as an alternative while keeping the same hash, so the password stays unchanged:
sudo mariadb -u root -p -e "ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING '<hash from SHOW CREATE USER>' OR unix_socket;"
Replace <hash from SHOW CREATE USER> with the *... string from the previous command. If it shows a different plugin (for example ed25519), tell me the plugin name only and I’ll adjust the statement.
Keep a second terminal logged in as mariadb -u root -p while you do this, so a typo can’t lock you out.
Verify
sudo mariadb -e "SELECT CURRENT_USER();" # works without a password now
sudo mariadb -u root -p -e "SELECT 1;" # password still works
sudo mariadb-admin --local flush-slow-log && echo "flush ok"
Catch up on skipped maintenance
Once the socket login works, run the start-up script once by hand. It runs mariadb-upgrade and the root-account check, both safe to repeat:
sudo /etc/mysql/debian-start
You should see “Upgrading MariaDB tables if necessary” without the FATAL ERROR line. You have a dump from earlier if you ran the backup step, but for the medical instance I’d make a fresh one first.