diff --git a/build.xml b/build.xml
index 1d3805b9d30c14d6e28a474d3feb2fae528925bc..609d8048a067033f3e3a1865e02ce4fc3e941f9e 100644
--- a/build.xml
+++ b/build.xml
@@ -284,7 +284,9 @@
         <!-- build database -->
         <exec command="mysqladmin -f -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} drop ${vufinddb}" />
         <exec command="mysqladmin -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} create ${vufinddb}" checkreturn="true" />
-        <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;GRANT SELECT,INSERT,UPDATE,DELETE ON ${vufinddb}.* TO '${vufinddbuser}'@'${mysqlhost}' IDENTIFIED BY '${vufinddbpass}' WITH GRANT OPTION&quot;" checkreturn="true" />
+        <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;DROP USER '${vufinddbuser}'@'${mysqlhost}'&quot;" />
+        <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;CREATE USER '${vufinddbuser}'@'${mysqlhost}' IDENTIFIED BY '${vufinddbpass}'&quot;" checkreturn="true" />
+        <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;GRANT SELECT,INSERT,UPDATE,DELETE ON ${vufinddb}.* TO '${vufinddbuser}'@'${mysqlhost}' WITH GRANT OPTION&quot;" checkreturn="true" />
         <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;FLUSH PRIVILEGES&quot;" checkreturn="true" />
         <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -D ${vufinddb} &lt; ${srcdir}/module/VuFind/sql/mysql.sql" checkreturn="true" />
 
@@ -352,6 +354,7 @@
         <exec command="sudo su -c &quot;psql -c \&quot;DROP USER ${vufinddbuser};\&quot;&quot; ${pgsqlrootuser}" checkreturn="true" />
       </then>
       <else>
+        <exec command="mysql -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} -e &quot;DROP USER '${vufinddbuser}'@'${mysqlhost}'&quot;" />
         <exec command="mysqladmin -f -h ${mysqlhost} -u ${mysqlrootuser} ${mysqlpwswitch}${mysqlrootpass} drop ${vufinddb}" />
       </else>
     </if>
diff --git a/module/VuFind/src/VuFind/Controller/InstallController.php b/module/VuFind/src/VuFind/Controller/InstallController.php
index 2408da178972b8a9784b43fe882237d0ba05d323..8269e32c7f6d2cf117594d85131b0409575b48b4 100644
--- a/module/VuFind/src/VuFind/Controller/InstallController.php
+++ b/module/VuFind/src/VuFind/Controller/InstallController.php
@@ -454,11 +454,13 @@ class InstallController extends AbstractBase
             return [$create, $escape, $cuser, $grant];
         }
         // Default: MySQL:
+        $user = "CREATE USER '{$view->dbuser}'@'{$view->vufindhost}'"
+            . "IDENTIFIED BY {$escapedPass}";
         $grant = "GRANT SELECT,INSERT,UPDATE,DELETE ON "
             . $view->dbname
             . ".* TO '{$view->dbuser}'@'{$view->vufindhost}' "
-            . "IDENTIFIED BY {$escapedPass} WITH GRANT OPTION";
-        return [$create, $grant, 'FLUSH PRIVILEGES'];
+            . "WITH GRANT OPTION";
+        return [$create, $user, $grant, 'FLUSH PRIVILEGES'];
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php b/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
index b00bd2737e17dc33fd661e0ff8098dff8c9d3a48..34610c9991144756dbac2d62e781044bc710b945 100644
--- a/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
+++ b/module/VuFind/src/VuFind/Controller/Plugin/DbUpgrade.php
@@ -627,6 +627,26 @@ class DbUpgrade extends AbstractPlugin
         return $missing;
     }
 
+    /**
+     * Normalize constraint values.
+     *
+     * @param array $constraints Constraints to normalize
+     *
+     * @return array
+     */
+    protected function normalizeConstraints($constraints)
+    {
+        foreach (['deleteRule', 'updateRule'] as $key) {
+            // NO ACTION and RESTRICT are equivalent in MySQL, but different
+            // versions return different values. Here we normalize them to RESTRICT
+            // for simplicity/consistency.
+            if ($constraints[$key] == 'NO ACTION') {
+                $constraints[$key] = 'RESTRICT';
+            }
+        }
+        return $constraints;
+    }
+
     /**
      * Compare expected vs. actual constraint actions and return an array of SQL
      * clauses required to create the modified constraints.
@@ -646,7 +666,7 @@ class DbUpgrade extends AbstractPlugin
                         "Could not find constraint '$name' in actual constraints"
                     );
                 }
-                $actualConstr = $actual[$type][$name];
+                $actualConstr = $this->normalizeConstraints($actual[$type][$name]);
                 if ($constraint['deleteRule'] !== $actualConstr['deleteRule']
                     || $constraint['updateRule'] !== $actualConstr['updateRule']
                 ) {