When managing system resources in CentOS 7, many administrators encounter situations where process limits (nproc) and file descriptors (nofile) set in /etc/security/limits.conf
don't properly apply to systemd-managed services. This is particularly noticeable with services like MariaDB, Apache, or custom daemons.
The standard Unix PAM limits mechanism doesn't work for systemd services because:
1. Systemd doesn't use PAM for service processes by default
2. Services often run as non-login accounts (like mysql)
3. The systemd process manager implements its own resource control
For MariaDB specifically, you need a multi-pronged approach:
Method 1: Systemd Service Unit Override
# Create override directory if needed
sudo mkdir -p /etc/systemd/system/mariadb.service.d/
# Create override file
sudo tee /etc/systemd/system/mariadb.service.d/limits.conf > /dev/null <
Method 2: Global Systemd Configuration
# Edit /etc/systemd/system.conf
sudo sed -i '/^#DefaultLimitNOFILE=/s/^#//' /etc/systemd/system.conf
sudo sed -i '/^DefaultLimitNOFILE=/s/[0-9]*$/102400/' /etc/systemd/system.conf
# Similarly for nproc
sudo sed -i '/^#DefaultLimitNPROC=/s/^#//' /etc/systemd/system.conf
sudo sed -i '/^DefaultLimitNPROC=/s/[0-9]*$/10240/' /etc/systemd/system.conf
sudo systemctl daemon-reload
After making changes, verify with:
# Check service limits
cat /proc/$(pgrep -f mariadbd)/limits
# Alternative method for running services
systemctl show mariadb --property LimitNOFILE,LimitNPROC
# System-wide settings check
systemctl show --property DefaultLimitNOFILE
systemctl show --property DefaultLimitNPROC
Even with systemd limits set, MariaDB has its own configuration parameters that may need adjustment in /etc/my.cnf.d/server.cnf
:
[server]
open_files_limit = 102400
table_open_cache = 2000
max_connections = 500
If limits still aren't applying:
- Check if SELinux is enforcing:
getenforce
- Verify the service isn't being started through an init script
- Ensure no conflicting settings in
/etc/security/limits.d/
- Check for user-specific overrides:
systemctl show user@$(id -u).service
When increasing these limits:
- Monitor kernel memory usage (
cat /proc/meminfo | grep Slab
) - Adjust kernel parameters if needed:
sysctl -w fs.file-max=2097152
- For high-connection services, consider TCP stack tuning
When working with systemd-managed services on CentOS 7, you'll notice that traditional methods like /etc/security/limits.conf
don't affect daemon processes. This occurs because systemd implements its own resource control mechanism through service unit files.
# Traditional limits.conf won't work for systemd services
* soft nofile 102400
* hard nofile 102400
For services managed by systemd (like MariaDB, Apache, or Postfix), you need to modify their service unit files or create drop-in configurations:
# For MariaDB example
sudo systemctl edit mariadb.service
[Service]
LimitNOFILE=102400
LimitNPROC=10240
To check actual limits applied to running processes:
cat /proc/$(pgrep -f mysqld)/limits | grep "Max open files"
cat /proc/$(pgrep -f httpd)/limits | grep "Max processes"
For different services, here are specific implementation examples:
# Apache httpd example
sudo mkdir -p /etc/systemd/system/httpd.service.d/
sudo tee /etc/systemd/system/httpd.service.d/limits.conf <<EOF
[Service]
LimitNOFILE=102400
LimitNPROC=10240
EOF
# Postfix example (using override.conf)
sudo systemctl edit postfix
[Service]
LimitNOFILE=40960
LimitNPROC=20480
For global defaults affecting all systemd services:
# Create system-wide configuration
sudo tee /etc/systemd/system.conf.d/limits.conf <<EOF
[Manager]
DefaultLimitNOFILE=102400:102400
DefaultLimitNPROC=10240:10240
EOF
After making changes, always remember to:
sudo systemctl daemon-reload
sudo systemctl restart mariadb
sudo systemctl restart httpd
When encountering issues, check these diagnostic commands:
# Check applied limits
systemctl show mariadb | grep -i limit
# Verify kernel parameters
sysctl fs.file-max
sysctl fs.nr_open
# Compare with process limits
grep -i "max open files" /proc/$(pgrep -f mysqld)/limits