Problem/Motivation

If db updates exist in an update, we need to decide what to do. We could:

  • roll back the update
  • run db updates
  • put site in maintenance mode
  • do nothing and hope for the best (site will maybe break, maybe it will be lucky and it won't break)

Proposed resolution

8x: default to putting site in maintenance mode, running db updates, then taking site out of maintenance mode. There is no UI for changing this (yet). But the order and sequence of how to handle db updates is configurable via config in automatic_updates.settings.yml. Alternatively, override via settings.php $config['automatic_updates.settings']['database_update_handling'] = ['rollback']. It is a an array of plugin IDs. Yes, db handling is done via plugins and a plugin manager.

Available plugins bundled in the module:

  • 'execute_updates'
  • 'ignore_updates'
  • 'maintenance_mode_activate'
  • 'maintenance_mode_disactivate'
  • 'rollback'

A specific site (or agency or hosting provider) might decide to provide additional db handling options beyond these. For example, run a db dump and offload it to S3 or send emails/notices to slack. Then run the update.

7x: default to rolling back the upgrade if a database update exists. Very few db updates are bundled in drupal core at this point in its life-cycle. Safer to just rollback.

Lastly, of note is that a tricky part of the implementation of this feature set is that class loading/caching was a big hurdle. The only way around it was to shell out to a drush-like series of commands to determine if 1) db updates exist to execute 2) execute those db updates 3) flush cache. Cache flushing is needed as part of the db update process + it is always run after an upgrade, even no db updates exist.

For 8x, these are symfony console commands. For 7x, these are homegrown php shell scripts. Fewer options are available in 7x due to the lack of external dependencies.
The commands mirror drush very closely:

  • updatedb [updb] Apply any database updates required (as with running update.php). (8x only)
  • updatedb-status [updbst|updatedb:status] List any pending database updates.
  • cache:rebuild [cr, rebuild] Rebuild a Drupal site and clear all its caches.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

heddn created an issue. See original summary.

heddn’s picture

Issue summary: View changes
heddn’s picture

Title: Add option to run db updates or put site in maintenance mode if updates exist » Add options to handle database updates
ressa’s picture

I think running any available db updates should be default, after enabling the module, to complete the security update. In theory, the database update itself could be doing the plugging of a security hole, right? Essentially a drush up --security-only -y.

Database update options
x Run after updating files
  Put site in maintenance mode
  Do nothing

(^^ options are radio buttons)

In which scenarios would we want to roll back the update? Or do you mean roll back, if something fails?

heddn’s picture

Status: Active » Needs review
StatusFileSize
new13.9 KB

No UI yet, but let's see how badly this makes things.

ressa’s picture

The patch applies fine, and both Cron-triggered and the experimental link still updates the code from 8.7.4 to 8.7.9. But I get the error "The website encountered an unexpected error. Please try again later.", for both afterwards, and the db updates are not applied, but have to be applied manually.

heddn’s picture

Status: Needs review » Needs work
StatusFileSize
new14.49 KB

Just another WIP patch. Ignore the noise for now. Got to fix #3093782: Use an external csig file, not packaged inside zip archive first before we can keep moving here.

heddn’s picture

Status: Needs work » Needs review
StatusFileSize
new28.03 KB
new20.74 KB

Not sure how helpful the interdiff will be. This does work now, at least for rollbacks with manual testing from 8.7.5 and upgrade to 8.8.0-beta1. That manual testing demonstrated that some of the rolling back wasn't actually working as expected.

Still no UI. But there are now 4 "options" for handling database updates. These options are all plugins.

heddn’s picture

StatusFileSize
new21.12 KB
new33.01 KB

There's something a little odd going on where it always seems to think there are db updates and tries to roll things back. But incremental progress.

heddn’s picture

StatusFileSize
new33.14 KB
new5.29 KB
heddn’s picture

StatusFileSize
new3.3 KB

Here's a 7.x patch while we're working on the test failures.

heddn’s picture

StatusFileSize
new16.26 KB
new42.61 KB
heddn’s picture

StatusFileSize
new5.48 KB
new44.14 KB

There are some serious issues with actually running database updates. Besides the philosophical ones, there's also technical ones that we're doing the entire update in a single PHP thread. Which means that class cache will have the old version of the classes; prior to updating. And its a bit of a catch-22, because you can't even flush cache or rebuild the container mid-flight or the site will start to 500. More time should be spent thinking about db updates. For now, if there's a db update, it defaults to rolling back the update.

heddn’s picture

To be more clear, don't use the execute_updates db update handler because it currently doesn't work. Examples of errors while updating from 8.7.10 => 8.8.0-rc1:

Call to undefined method Drupal\Core\File\FileSystem::scanDirectory()";s:9:"%function";s:53:"Drupal\Core\Asset\CssCollectionOptimizer->deleteAll()";s:5:"%file";s:113:"core/lib/Drupal/Core/Asset/CssCollectionOptimizer.php

RuntimeException: SplFileInfo::getMTime(): stat failed for core/modules/system/tests/modules/path_test/path_test.info.yml in SplFileInfo->getMTime()

Argument 1 passed to Drupal\Core\Config\Entity\ConfigEntityUpdater::update() must be of the type array, null given, called in core/modules/text/text.post_update.php on line 47

heddn’s picture

StatusFileSize
new3.13 KB
new44.23 KB

So, here we disable the cache clear in the db update. That get's a little further, but then we don't actually finish clearing cache ever and the site still doesn't work. A simple cache clear brings the site back to a functioning state. But until then, the site 500s.

heddn’s picture

StatusFileSize
new5.47 KB
new48.5 KB
heddn’s picture

StatusFileSize
new2.01 KB
new48.59 KB
heddn’s picture

StatusFileSize
new2.69 KB
new48.75 KB
andypost’s picture

+++ b/automatic_updates.module
@@ -141,3 +142,19 @@ function automatic_updates_mail($key, &$message, $params) {
+  if (function_exists('opcache_reset')) {
+    opcache_reset();

moreover apcu cache (used by autoloader by default) probably also need clean-up

heddn’s picture

Re #19, wouldn't that get caught by normal cache clearing? Apcu seems to be registered as a cache backend service (cache.backend.apcu).

heddn’s picture

StatusFileSize
new3.82 KB
new50.82 KB

Here's a console command cache clear. We'll do it differently in D7.

andypost’s picture

heddn’s picture

StatusFileSize
new37.25 KB
new57.38 KB

If this passes green, I think it is ready for reviews.

heddn’s picture

StatusFileSize
new57.15 KB
new1.43 KB

Clean-up to remove debugging.

heddn’s picture

StatusFileSize
new705 bytes
new57.07 KB

Removing more statements.

heddn’s picture

StatusFileSize
new3.12 KB
new56.49 KB
heddn’s picture

Good, green.

heddn’s picture

StatusFileSize
new6.22 KB
new57.15 KB

More minor clean-up.

heddn’s picture

StatusFileSize
new10.82 KB
heddn’s picture

StatusFileSize
new718 bytes
new10.99 KB
new1.29 KB
new57.28 KB

heddn’s picture

Adding credit for assistance w/ the final approach.

  • heddn committed e6e3c83 on 8.x-1.x
    Issue #3093993 by heddn, andypost, greg.1.anderson: Add options to...

  • heddn committed 4c25931 on 7.x-1.x
    Issue #3093993 by heddn, andypost, greg.1.anderson: Add options to...
heddn’s picture

Status: Needs review » Fixed
ressa’s picture

Great job heddn, andypost and greg.1.anderson! I just updated from 8.7.4 to 8.7.10 by enabling "Enable automatic updates of Drupal core via cron" and running Cron. Also, there weren't any updates available at update.php, and this in the log files:

Database update handling has finished.
Database update finished with arguments "Array ( [0] => taxonomy [1] => 8702 [2] => Array ( ) ) "
Database update running with arguments "Array ( [0] => taxonomy [1] => 8702 [2] => Array ( ) ) "
Database update handling has started.

... so the available updates were applied.

I don't see any settings though, which is fine. But perhaps the Issue summary could have a bit of text about the solution which was decided on? Also the text on the admin/config/automatic_updates page says "Database updates are not run after an update.".

The only possible error I found was the warning I get after the update has run:

Warnings found
Update readiness checks
689 checks failed:
The hash for composer.lock does not match its original. Updates that include that file will fail and require manual intervention.
The hash for core/MAINTAINERS.txt does not match its original. Updates that include that file will fail and require manual intervention.
The hash for core/assets/vendor/ckeditor/lang/de.js does not match its original. Updates that include that file will fail and require manual intervention.
...

Flushing the cache didn't make a difference, but running the readiness check takes care of it. So perhaps it's working as designed, since the user should check if files are ready manually themselves, after an automatic update has been executed?

heddn’s picture

Issue summary: View changes
chi’s picture

To make it compatible with Symfony 4.4+ command execute methods should return exit code.
See #3099295: Always return exit code in Symfony console commands for details.

heddn’s picture

Issue summary: View changes
heddn’s picture

ressa’s picture

Thanks for updating the Issue Summary. You all have really made a lot of progress, and it's coming along nicely. I'll test the patches in the other issues.

  • heddn committed a32361f on 8.x-1.x
    Issue #3099321 by heddn, ressa: Remove module settings form copy about...

  • heddn committed cdc1112 on 7.x-1.x
    Issue #3099321 by heddn, ressa: Remove module settings form copy about...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.