简体   繁体   中英

mysql create table with data directory: access denied

I have my main database on an SSD but I also want to hold semi-temporary data in a ramdisk. This is all on Ubuntu with mySQL 8.0.23. However, I'm unable to issue the following query:

mysql> create table t1 (c1 int) data directory = '/mnt/ramdisk/mysql';

I get this:

ERROR 1045 (28000): Access denied for user 'username'@'localhost' (using password: NO)

However, I can do it without the data directory option.

I have the directory in innodb_directories:

mysql> show variables like 'innodb_directories';
+--------------------+--------------------+
| Variable_name      | Value              |
+--------------------+--------------------+
| innodb_directories | /mnt/ramdisk/mysql |
+--------------------+--------------------+

Permissions to the directory seem okay:

root@localhost:~# ls -ld /mnt/ramdisk/mysql/
drwxr-xr-x 2 mysql mysql 40 Feb 19 10:59 /mnt/ramdisk/mysql/

edit: Suggestion below pointed to the "file" privilege. After granting "file" privs:

mysql> grant create on ib.* to username@localhost;

Now complains about this when creating the table:

ERROR 1030 (HY000): Got error 168 - 'Unknown (generic) error from engine' from storage engine

With error.log reporting the following even though the directory has rwx perms for all:

2021-02-19T19:20:16.105812Z 26 [ERROR] [MY-012592] [InnoDB] Operating system error number 13 in a file operation.
2021-02-19T19:20:16.105879Z 26 [ERROR] [MY-012595] [InnoDB] The error means mysqld does not have the access rights to the directory.

edit: After creating a subdirectory for the database named "db", and chown'ing it to mysql:

/mnt/ramdisk/mysql/db

I'm getting this:

2021-02-20T02:47:04.997841Z 8 [ERROR] [MY-012592] [InnoDB] Operating system error number 13 in a file operation.
2021-02-20T02:47:04.997854Z 8 [ERROR] [MY-012595] [InnoDB] The error means mysqld does not have the access rights to the directory.
2021-02-20T02:47:04.997869Z 8 [ERROR] [MY-012126] [InnoDB] Cannot create file '/mnt/ramdisk/mysql/db/table.ibd'

edit: I noticed that I was able to create the table if I used /tmp... now things are getting interesting...

I did an strace on mysqld to see what was causing the issue and got this:

99911 openat(AT_FDCWD, "/mnt/ramdisk/mysql/db/table.ibd", O_RDWR|O_CREAT|O_EXCL, 0640) = -1 EACCES (Permission denied)

Not knowing what all those flags are, I wrote a quick C program to do the same thing... and it worked. It's not even that the mysql user (running mysqld) can't do it, since the following worked:

sudo -u mysql <the C program>

Any pointers? Thanks...

Okay, sort of figured it out. If the mount point is /mnt, or some other directory that I make, I get the issues described above. If the mount point is /tmp, it works. This is even if I use the same attributes as /tmp. In the end, I'm convinced it's not a mysql issue, but something to do with the filesystem.

This being just about the only relevant post I could find when encountering this problem myself, I'll post my solution.

But first, the problem, apparmor !

Here's how to check if apparmor or similar.@$@#$ is the reason for your grievances.

If running:

journal -fx

return something akin to this when you try to create your db: (removed timestamps etc)

audit[813063]: AVC apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/mnt/volume_fra1_01/mysql/mydb/tda.ibd" pid=813063 comm="connection" requested_mask="c" denied_mask="c" fsuid=112 ouid=112
audit: type=1400 audit(1664628440.627:200): apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/mnt/volume_fra1_01/mysql/mydb/tda.ibd" pid=813063 comm="connection" requested_mask="c" denied_mask="c" fsuid=112 ouid=112

Then you've hit jackpot!

Find mysql's apparmor file, mine is in /etc/apparmor.d/usr.sbin.mysqld . Find the rows allowing access to mysql's default data dir and add your rows, my addition is the two last ones, you'll of course need to change them to suit yours, if you're feeling frisky you can just allow access to /mnt/ and be done with it.

# Allow data dir access
  /var/lib/mysql/ r,
  /var/lib/mysql/** rwk,

  /mnt/volume_fra1_01/mysql/ r,
  /mnt/volume_fra1_01/mysql/** rwk,

Once you've edited your apparmor file you may swear some more and run:

apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld

Done! Now run your CREATE TABLE again and go on with your life to greener pastures.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM