aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi6
-rw-r--r--gnu/services/databases.scm52
-rw-r--r--gnu/tests/databases.scm4
3 files changed, 60 insertions, 2 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index bef42e160a..2a98dda324 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -19151,6 +19151,12 @@ Socket file to use for local (non-network) connections.
@item @code{extra-content} (default: @code{""})
Additional settings for the @file{my.cnf} configuration file.
+@item @code{auto-upgrade?} (default: @code{#t})
+Whether to automatically run @command{mysql_upgrade} after starting the
+service. This is necessary to upgrade the @dfn{system schema} after
+``major'' updates (such as switching from MariaDB 10.4 to 10.5), but can
+be disabled if you would rather do that manually.
+
@end table
@end deftp
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 5a88b70d74..60b31e0373 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -6,6 +6,7 @@
;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
+;;; Copyright © 2020 Marius Bakke <marius@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -468,7 +469,8 @@ storage:
(bind-address mysql-configuration-bind-address (default "127.0.0.1"))
(port mysql-configuration-port (default 3306))
(socket mysql-configuration-socket (default "/run/mysqld/mysqld.sock"))
- (extra-content mysql-configuration-extra-content (default "")))
+ (extra-content mysql-configuration-extra-content (default ""))
+ (auto-upgrade? mysql-configuration-auto-upgrade? (default #t)))
(define %mysql-accounts
(list (user-group
@@ -559,6 +561,52 @@ FLUSH PRIVILEGES;
#:user "mysql" #:group "mysql")))
(stop #~(make-kill-destructor)))))
+(define (mysql-upgrade-wrapper mysql socket-file)
+ ;; The MySQL socket and PID file may appear before the server is ready to
+ ;; accept connections. Ensure the socket is responsive before attempting
+ ;; to run the upgrade script.
+ (program-file
+ "mysql-upgrade-wrapper"
+ #~(begin
+ (let ((mysql-upgrade #$(file-append mysql "/bin/mysql_upgrade"))
+ (timeout 10))
+ (begin
+ (let loop ((i 0))
+ (catch 'system-error
+ (lambda ()
+ (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
+ (connect sock AF_UNIX #$socket-file)
+ (close-port sock)
+ ;; The socket is ready!
+ (execl mysql-upgrade mysql-upgrade
+ (string-append "--socket=" #$socket-file))))
+ (lambda args
+ (if (< i timeout)
+ (begin
+ (sleep 1)
+ (loop (+ 1 i)))
+ ;; No luck, give up.
+ (throw 'timeout-error
+ "MySQL server did not appear in time!"))))))))))
+
+(define (mysql-upgrade-shepherd-service config)
+ (list (shepherd-service
+ (provision '(mysql-upgrade))
+ (requirement '(mysql))
+ (one-shot? #t)
+ (documentation "Upgrade MySQL database schemas.")
+ (start (let ((mysql (mysql-configuration-mysql config))
+ (socket (mysql-configuration-socket config)))
+ #~(make-forkexec-constructor
+ (list #$(mysql-upgrade-wrapper mysql socket))
+ #:user "mysql" #:group "mysql"))))))
+
+(define (mysql-shepherd-services config)
+ (if (mysql-configuration-auto-upgrade? config)
+ (append (mysql-shepherd-service config)
+ (mysql-upgrade-shepherd-service config))
+ (mysql-shepherd-service config)))
+
(define mysql-service-type
(service-type
(name 'mysql)
@@ -568,7 +616,7 @@ FLUSH PRIVILEGES;
(service-extension activation-service-type
%mysql-activation)
(service-extension shepherd-root-service-type
- mysql-shepherd-service)))
+ mysql-shepherd-services)))
(default-value (mysql-configuration))))
(define-deprecated (mysql-service #:key (config (mysql-configuration)))
diff --git a/gnu/tests/databases.scm b/gnu/tests/databases.scm
index 1d7f53ec3e..dd1af1dbcc 100644
--- a/gnu/tests/databases.scm
+++ b/gnu/tests/databases.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
+;;; Copyright © 2020 Marius Bakke <marius@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -311,6 +312,9 @@
((pid) (number? pid))))))
marionette))
+ (test-assert "mysql_upgrade completed"
+ (wait-for-file "/var/lib/mysql/mysql_upgrade_info" marionette))
+
(test-end)
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))