Error
Error Code:
21
MySQL Error 21: Directory Creation Failure
Description
MySQL Error 21 indicates that the MySQL server process was unable to create a necessary directory on the file system. This typically occurs when MySQL attempts to create data files, log files, or temporary files but lacks the required permissions or encounters an issue with the specified path.
Error Message
Can't create directory '%s' (OS errno %d - %s)
Known Causes
4 known causesInsufficient Directory Permissions
The operating system user account running the MySQL server process does not have the necessary write permissions for the parent directory where it attempted to create a new directory.
Invalid or Non-existent Path
The configured path for the directory MySQL tried to create does not exist, or a component of the path is incorrect, preventing the creation of the target directory.
Disk Space Exhaustion
The file system where MySQL is attempting to create the directory has run out of available disk space, making it impossible to allocate new directory entries.
Read-Only File System
The underlying file system or mount point where MySQL is trying to create a directory is mounted as read-only, preventing any write operations.
Solutions
3 solutions available1. Verify and Grant Directory Permissions easy
Ensure the MySQL user has write permissions to the target directory.
1
Identify the directory MySQL is trying to create. This is usually found in the MySQL error log or within the context of the operation that failed (e.g., `datadir`, `tmpdir`, log file paths). The error message '%s' will typically show this path.
2
Determine the user that the MySQL server process is running as. This can often be found by inspecting the MySQL service configuration or using system commands.
ps aux | grep mysqld
3
Grant write permissions to the MySQL user for the identified directory. Replace `/path/to/mysql/directory` with the actual directory and `mysql_user` with the user identified in the previous step.
sudo chown -R mysql_user:mysql_user /path/to/mysql/directory
sudo chmod -R u+w /path/to/mysql/directory
4
Restart the MySQL service to apply the permission changes.
sudo systemctl restart mysql
2. Check for SELinux or AppArmor Restrictions medium
Temporarily disable or configure SELinux/AppArmor if they are blocking directory creation.
1
Check the system's security logs for SELinux or AppArmor denial messages related to MySQL or the target directory.
sudo ausearch -m avc -ts recent | grep mysql
sudo tail /var/log/audit/audit.log
sudo tail /var/log/syslog | grep -i apparmor
2
Temporarily set SELinux to permissive mode to test if it's the cause. If this resolves the issue, you'll need to create specific SELinux policies for MySQL.
sudo setenforce 0
3
If SELinux was the cause, re-enable it and create a policy. This is a complex topic, but a common fix involves setting the correct SELinux context for MySQL directories. Consult your distribution's SELinux documentation for detailed steps. For a quick test, you might try:
sudo semanage fcontext -a -t mysqld_db_t '/path/to/mysql/directory(/.*)?'
sudo restorecon -Rv /path/to/mysql/directory
4
For AppArmor, you might need to edit the MySQL profile (`/etc/apparmor.d/usr.sbin.mysqld`) to allow access to the problematic directory.
5
Restart the MySQL service after making any SELinux or AppArmor adjustments.
sudo systemctl restart mysql
3. Verify Disk Space and Inode Availability easy
Ensure the partition hosting the MySQL data directory has sufficient free space and inodes.
1
Check the available disk space on the partition where MySQL is trying to create the directory. The error message might not directly indicate this, but it's a common underlying cause.
df -h
2
Check the inode usage on the partition. Running out of inodes can prevent new file/directory creation even if there's disk space.
df -i
3
If disk space is low, free up space by deleting unnecessary files or expanding the partition. If inode usage is high, consider cleaning up small files or reformatting the partition with more inodes (a more involved process).
4
Restart the MySQL service after resolving disk space or inode issues.
sudo systemctl restart mysql