Database containers would be far more useful for local/test/dev environments if they were ready to be used very quickly after container startup (versus waiting 30s to several minutes for initialization and loading of .sql
or .sh
files in /docker-entrypoint-initdb.d
on startup. This would enable distributing production-mirrored database schemas and fixture/test data pre-loaded so it is readily available on startup.
I've had great success providing ready-to-use end-to-end/integration test fixture containers with this approach for other datastores, e.g. Cassandra, Zookeeper. I essentially have this for MySQL databases as well, except for the really slow wait time and the fact that MySQL starts/stops/starts again (healthchecks are misleading). You have to wait a fair amount of time before the DDL and DML statements in /docker-entrypoint-initdb.d
finish running.
I've been working on a patch to enable this in these containers, or at least make it possible for people to leverage by using these containers as base images (FROM
). The cleanest way I can see to do this is to make docker-entrypoint.sh
allow a switch to be passed (buildinit
or something) to it to avoid the final step exec "$@"
at the end...
The problem I'm running into is when I try to start the container after it finishes building w/ the schema & fixture data already loaded is I get an error:
171125 23:43:44 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
Messy proof of concept: https://github.com/stantonk/percona/tree/perform-bootstrapping-during-build/5.5
Here's a Dockerfile trying to use the percona image as a base:
FROM percona:5.5
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
ADD ./schema/mysql-maindb.sql /docker-entrypoint-initdb.d
ADD ./triggers/triggers.sql /docker-entrypoint-initdb.d
RUN echo "********bootstrapping database*********" \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
&& /usr/local/bin/bootstrap-mysql.sh mysqld
CMD ["mysqld"]
This builds fine, and appears to bootstrap from docker-entrypoint-initdb.d
:
$ docker build --no-cache -t mysql-maindb .
Sending build context to Docker daemon 323.6kB
Step 1/6 : FROM percona:5.5
---> f054fae95c86
Step 2/6 : ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
---> Running in 98b077bbc248
---> 4063932e4e21
Removing intermediate container 98b077bbc248
Step 3/6 : ADD ./schema/mysql-maindb.sql /docker-entrypoint-initdb.d
---> 6295eac9dcb0
Removing intermediate container 6ab71d72f91f
Step 4/6 : ADD ./triggers/triggers.sql /docker-entrypoint-initdb.d
---> ccacbaa87b57
Removing intermediate container c89a8821b22a
Step 5/6 : RUN echo "********bootstrapping database*********" && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld && /usr/local/bin/bootstrap-mysql.sh mysqld
---> Running in e84d157d3427
********bootstrapping database*********
Initializing database
171125 23:52:03 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:52:03 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
171125 23:52:03 [Note] /usr/sbin/mysqld (mysqld 5.5.57-38.9) starting as process 66 ...
171125 23:52:03 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:52:03 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
171125 23:52:03 [Note] /usr/sbin/mysqld (mysqld 5.5.57-38.9) starting as process 72 ...
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h password 'new-password'
Alternatively you can run:
/usr/bin/mysql_secure_installation
which will also give you the option of removing the test
databases and anonymous user created by default. This is
strongly recommended for production servers.
See the manual for more instructions.
Please report any problems at
https://bugs.launchpad.net/percona-server/+filebug
Percona recommends that all production deployments be protected with a support
contract (http://www.percona.com/mysql-suppport/) to ensure the highest uptime,
be eligible for hot fixes, and boost your team's productivity.
Database initialized
171125 23:52:03 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:52:03 [Note] mysqld (mysqld 5.5.57-38.9) starting as process 76 ...
MySQL init process in progress...
171125 23:52:03 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:52:03 [Note] Plugin 'FEDERATED' is disabled.
171125 23:52:03 InnoDB: The InnoDB memory heap is disabled
171125 23:52:03 InnoDB: Mutexes and rw_locks use GCC atomic builtins
171125 23:52:03 InnoDB: Compressed tables use zlib 1.2.8
171125 23:52:03 InnoDB: Using Linux native AIO
171125 23:52:03 InnoDB: Initializing buffer pool, size = 128.0M
171125 23:52:03 InnoDB: Completed initialization of buffer pool
InnoDB: The first specified data file ./ibdata1 did not exist:
InnoDB: a new database to be created!
171125 23:52:03 InnoDB: Setting file ./ibdata1 size to 10 MB
InnoDB: Database physically writes the file full: wait...
171125 23:52:03 InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
171125 23:52:03 InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: 127 rollback segment(s) active.
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
171125 23:52:03 InnoDB: Waiting for the background threads to start
MySQL init process in progress...
171125 23:52:04 Percona XtraDB (http://www.percona.com) 5.5.57-38.9 started; log sequence number 0
171125 23:52:04 [Warning] 'user' entry 'root@e84d157d3427' ignored in --skip-name-resolve mode.
171125 23:52:04 [Warning] 'user' entry '@e84d157d3427' ignored in --skip-name-resolve mode.
171125 23:52:04 [Warning] 'proxies_priv' entry '@ root@e84d157d3427' ignored in --skip-name-resolve mode.
171125 23:52:04 [Note] Event Scheduler: Loaded 0 events
171125 23:52:04 [Note] mysqld: ready for connections.
Version: '5.5.57-38.9' socket: '/var/run/mysqld/mysqld.sock' port: 0 Percona Server (GPL), Release 38.9, Revision fc6d4f87a88
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
171125 23:52:07 [Warning] 'proxies_priv' entry '@ root@e84d157d3427' ignored in --skip-name-resolve mode.
/usr/local/bin/bootstrap-mysql.sh: running /docker-entrypoint-initdb.d/mysql-maindb.sql
/usr/local/bin/bootstrap-mysql.sh: running /docker-entrypoint-initdb.d/triggers.sql
171125 23:52:09 [Note] mysqld: Normal shutdown
171125 23:52:09 [Note] Event Scheduler: Purging the queue. 0 events
171125 23:52:09 InnoDB: Starting shutdown...
171125 23:52:13 InnoDB: Shutdown completed; log sequence number 3042552
171125 23:52:13 [Note] mysqld: Shutdown complete
MySQL init process done. Ready for start up.
---> 5fd5922e78d3
Removing intermediate container e84d157d3427
Step 6/6 : CMD mysqld
---> Running in 4ec998af647b
---> b3ccbeb8e52a
Removing intermediate container 4ec998af647b
Successfully built b3ccbeb8e52a
Successfully tagged mysql-maindb:latest
But when the resulting image is started, it fails:
$ docker run -p3306:3306 mysql-maindb:latest
about to exec... /usr/local/bin/docker-entrypoint.sh mysqld
171125 23:53:24 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:53:24 [Note] mysqld (mysqld 5.5.57-38.9) starting as process 1 ...
171125 23:53:24 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.
171125 23:53:24 [Note] Plugin 'FEDERATED' is disabled.
mysqld: Table 'mysql.plugin' doesn't exist
171125 23:53:24 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
171125 23:53:24 InnoDB: The InnoDB memory heap is disabled
171125 23:53:24 InnoDB: Mutexes and rw_locks use GCC atomic builtins
171125 23:53:24 InnoDB: Compressed tables use zlib 1.2.8
171125 23:53:24 InnoDB: Using Linux native AIO
171125 23:53:24 InnoDB: Initializing buffer pool, size = 128.0M
171125 23:53:24 InnoDB: Completed initialization of buffer pool
InnoDB: The first specified data file ./ibdata1 did not exist:
InnoDB: a new database to be created!
171125 23:53:24 InnoDB: Setting file ./ibdata1 size to 10 MB
InnoDB: Database physically writes the file full: wait...
171125 23:53:25 InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
171125 23:53:25 InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: 127 rollback segment(s) active.
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
171125 23:53:25 InnoDB: Waiting for the background threads to start
171125 23:53:26 Percona XtraDB (http://www.percona.com) 5.5.57-38.9 started; log sequence number 0
171125 23:53:26 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
I'm sure I am doing something silly but this error message is rather opaque in what it actually means, and I'm not sure how to inspect those tables if I can't get mysql to start.