AppArmor profile on Ubuntu is (rightly) restrictive and prevents the daemon binary mysqld
from writing to unexpected locations.
So here’s another one in my series of ‘stupid notes to self’ — things that may help a reader, things that will help me, but things that are not proper or full guides to solving a problem.
Starting an already initialized datadir:
normal-user$ /usr/sbin/mysqld --defaults-file=/tmp/barproject-mysql-my.cnf
2018-01-09T21:24:28.090896Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
2018-01-09T21:24:28.090907Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
Initializing a new one:
normal-user$ /usr/sbin/mysqld --defaults-file=/tmp/barproject-mysql-my.cnf --datadir="$(pwd)/mysql" --log-level-verbosity=VERBOSE --initialize-insecure
mysqld: Can't create directory '/home/foo/projects/bar/_dev/mysql/' (Errcode: 13 - Permission denied)
2016-10-10T16:23:29.515470Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2016-10-10T16:23:29.519420Z 0 [ERROR] Aborting
(Note that /tmp/barproject-mysql-my.cnf
has been created from a template prior to running either of these. It specifies many values including datadir.)
First, I worked under the assumption the daemon was running under the wrong user or that the directory has wrong permissions. However, changing settings to any reasonable value did not get rid of errors with either initialization step or run step.
AppArmor has profiles that may block accesses atypical for the program executed. One such profile is for /usr/sbin/mysqld
and is located in /etc/apparmor.d/usr.sbin.mysqld
.
I tried symlinking it to /etc/apparmor.d/disable directory and restarting apparmor with systemctl restart apparmor
. This didn’t change anything. I also tried whitelisting the directory by adding a local configuration change to /etc/apparmor.d/local/usr.sbin.mysqld
:
/home/foo/projects/bar/_dev/mysql/** rwk,
systemctl restart apparmor
— i.e. restarting through systemd — did not help.
However telling apparmor to tear itself down using the service
command, as well as telling it to reload its profile cache, did:
service apparmor stop
service apparmor teardown
service apparmor recache
service apparmor start
There’s probably a smarter way, but this is good enough for me.