Bug #79250 mysqld_pre_systemd fails when datadir has irrelevant content (e.g. lost+found)

Submitted: 12 Nov 2015 14:05 Modified: 30 Nov 2015 20:01
Reporter: Timo Gurr Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Packaging Severity:S3 (Non-critical)
Version:5.7.9 OS:Linux
Assigned to: CPU Architecture:Any

[12 Nov 2015 14:05] Timo Gurr
Description:
mysql fails to start due to mysqld_pre_systemd running into an error during initial setup.

lxhost ~ # systemctl start mysqld.service
Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.
lxhost ~ # systemctl status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/x86_64-pc-linux-gnu/lib/systemd/system/mysqld.service; disabled; vendor preset: enabled)
   Active: deactivating (final-sigterm) (Result: exit-code)
  Process: 14081 ExecStart=/usr/x86_64-pc-linux-gnu/bin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=1/FAILURE)
  Process: 14061 ExecStartPre=/usr/x86_64-pc-linux-gnu/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/mysqld.service
           └─14084 /usr/x86_64-pc-linux-gnu/bin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid

Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.099714Z 0 [Note] InnoDB: not started
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.107477Z 0 [Warning] CA certificate ca.pem is self signed.
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.107529Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108381Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108430Z 0 [Note] IPv6 is available.
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108441Z 0 [Note]   - '::' resolves to '::';
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108447Z 0 [Note] Server socket created on IP: '::'.
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108628Z 0 [Warning] Failed to open optimizer cost constant tables
Nov 12 14:51:09 lxhost mysqld[14081]: 2015-11-12T13:51:09.108745Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist
Nov 12 14:51:09 lxhost systemd[1]: mysqld.service: Control process exited, code=exited status=1

When running mysqld_pre_systemd by hand you can see the actual problem:

# /usr/x86_64-pc-linux-gnu/bin/mysqld_pre_systemd
2015-11-12T13:51:31.224066Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2015-11-12T13:51:31.224162Z 0 [Warning] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2015-11-12T13:51:31.224167Z 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
2015-11-12T13:51:31.227758Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
2015-11-12T13:51:31.227845Z 0 [ERROR] Aborting

The directory is not really empty because datadir is on a separate ext4 partition, so there's naturally a lost+found directory in it.

lxhost ~ # ls -la /var/lib/mysql
total 36
drwxr-xr-x  3 mysql mysql 16384 Nov 12 11:34 .
drwxr-xr-x 15 root  root   4096 Nov 12 14:10 ..
drwx------  2 root  root  16384 Nov 30  2009 lost+found

How to repeat:
1. compile from sources
2. install
3. have datadir mounted on a separate partition / or have a .hidden file in it
4. try to start mysql via the provided systemd service

Suggested fix:
Make mysqld_pre_systemd ignore lost+found directories.

Also make it ignore .hidden files since they cause the same error on running mysqld_pre_systemd. Our package manager for example refuses to install empty directories, so we usually create a .hidden file in such directories. Thankfully mysql 5.7.9 creates it's (default) datadir automatically when started via the systemd service file(s) if it doesn't exist, so we don't have a real problem here. But I'd still suggest mysqld_pre_systemd should not error out when the datadir only contains one (or multiple) .hidden files.
[12 Nov 2015 17:11] Terje Røsten
Hi!

Thanks for your report. 

This is due to mysqld --initialize, which insist on empty datadir to run
and is not specific systemd or mysqld_pre_systemd.

I agree the lost+found can be an issue, we might be able to create
a white list or something similar.
[15 Nov 2015 7:43] MySQL Verification Team
Thank you for the report.
I agree with reporter and  Terje that some files should be ignored(lost+found, hidden files etc)

Thanks,
Umesh
[30 Nov 2015 20:01] Paul DuBois
Noted in 5.7.11, 5.8.0 changelogs.

Previously, mysqld --initialize required the data directory to not
exist or, if it existed, to be empty. Now an existing data directory
is permitted to be nonempty if every entry either has a name that
begins with a period (.) or is named using an --ignore-db-dir option.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.041 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.