NEO: make MariaDB database creation more robust
-
Developer
@jm : this commit breaks the script used to import a dump in mariadb, and the script used to setup a replication slave :
As they empty datadir instead of deleting it, this script doesn't run (the directory exists), but mariadb crashes at start as it can't find any table.
Would it be if I update the 2 scripts as such ?
- find "$DATA_DIRECTORY" -mindepth 1 -delete + if [ -d "$DATA_DIRECTORY" ] ; then rm -rf "$DATA_DIRECTORY"; fi
/cc @vpelletier
-
Developer
On issue I see with this
rm $DATA_DIRECTORY
would be for cases where a faster disk is mounted on this directory. Thenrm
fails withDevice or resource busy
(this case is not innocent, I know 2 projects doing so)
-
Developer
Also, the newly created
$DATA_DIRECTORY
doesn't have the same set of permissions as the original directory created by buildout -
Owner
Part of this commit is a workaround for the fact that MariaDB does not provide a way to check whether initialization could be completed or not. And with this workaround, initialization is already broken if datadir is a mount point, but such configuration seems to be never used when setting up a new instance (i.e. a mount point is set up only after the DB has exceeded some size/load).
- find "$DATA_DIRECTORY" -mindepth 1 -delete + if [ -d "$DATA_DIRECTORY" ] ; then rm -rf "$DATA_DIRECTORY"; fi
No. Among all code dealing with MariaDB data, the current find line is the only part that can't be written differently (hmm... except in below case 2).
-
Ideally,
mysql_install_db
should end by creating a marker file (which should be deleted explicitly just before any code emptying the datadir), since there does not seem to exist any. The difficult part is to compatibility: how to distinguish a datadir that must be upgraded from one that didn't complete initialization. I'm also not fond of patching upstream code: we should rather request such change upstream but it may not be easy to convince. -
Another option is to be stricter about mount points, by mounting an ancestor directory of the datadir, and being able to configuring a different parent directory for datadir (the default being ~/srv). Thus, the datadir is never a mount point.
-
But the easier solution is that the resilience does its own initialization. Here, there's no need to initialize in an atomic way.
-
-
Owner
(i.e. a mount point is set up only after the DB has exceeded some size/load).
This is not always the case, precisely in Nicolas' case of restoring a backup:
- we already know the data will eventually be big, it would be wasteful to start restoring on a drive and then move a massive database to another drive, when we can just restore directly to the final drive.
- the restoration script must ensure it starts from a completely empty database, and to do so uses the given
find
command.
This said, what the backup restoration script could rather do is to call
mysql_install_db
right after thatfind
statement, as it knows the datadir is not initialised (despite existing).If I continue this train of thought, I reach the conclusion that it's wrong for mariadb start script to try to create the database: it should rather be called by buildout during instanciation. I believe it was not done at that point because of the (misguided, IMHO) idea that instanciation should not do "slow" things.
-
Owner
You misread « DB ». I'm not considering the size/load of a datadir/mysqld at some precise moment before restoration because it is empty/nonexistent. I'm rather talking about the project, usually the production instance of this project: at the beginning, it's small and with little load and it's only after we start tuning. And of course, moving a datadir to a separate mount point is likely to also apply to the restoration part.
So...
we already know the data will eventually be big, it would be wasteful to start restoring on a drive and then move a massive database to another drive, when we can just restore directly to the final drive.
I didn't say the contrary.
it should rather be called by buildout during instanciation
That does not solve anything. The goal is to have something idempotent: if initialization crashes in the middle, it must recover. Given how MariaDB is complex (we could let
mysql_install_db
, as we used to do in the past, but it may not work if MariaDB version has changed since the crash), it's easier by making initialization atomic. -
Owner
You misread « DB ».
I did not. We are talking about datadir initialisation and DB backup restoration.
I'm rather talking about the project, usually the production instance of this project: at the beginning, it's small and with little load and it's only after we start tuning.
I don't see the the relation of such statement with current discussion. We are not in the case you describe, as it does not involve initialising the datadir but merely moving it.
Unlike restoring a backup, which is the current discussion, which requires emptying the existing datadir and initialising it, because backup restoration may happen after the instance has seen some use.
That does not solve anything.
It does solve a few things:
- It removes database initialisation from statrup script. By this removal, it becomes clearer that it must not be expected from the startup script to be able to succesfuly initialise the datadir (because it fails at doing so in our case).
- It makes it clearer that the applicability scope of this datadir initialisation strategy only applies to the code which also creates parent folder.
With these, the solution (to our current issue) of initialising the datadir explicitly within the backup restoration script becomes obvious, and we would not need to have this discussion. And in such case, the "create elsewhere and move" strategy is not needed, the restoration script anyway empties the directory before every attempt, and exits if DB initialisation fails.
Do you see now the advantages of this approach ?
-
Owner
the solution (to our current issue) of initialising the datadir explicitly within the backup restoration script
Note that this is exactly what I described as solution 3 above. So, I'm fine with this.
But the startup script has to remain as it is.