During the installation process, we do a lot of clearing and rebuilding of the schema cache. This is not by itself a problem, but it also triggers a lot of cache_set()
from SchemaCache::__destruct
. And as a consequence, a lot of lock/unlock and a lot of truncate query on the cache tables.
We should not try to save a DrupalCacheArray
we already know is invalid.
In addition, we don't have a way to *only* clear the schema, without rebuilding it. As a consequence, saving fields is actually very costly because we keep clearing and rebuilding the schema cache, even if we don't have an immediate use for it.
Comments
Comment #1
Damien Tournoud CreditAttribution: Damien Tournoud commentedProposed patch:
DrupalCacheArray::invalidate()
method that we call at the proper timedrupal_get_schema_reset()
that can be called to only clear the schema, not immediately rebuild itComment #2
Damien Tournoud CreditAttribution: Damien Tournoud commentedComment #3
catch+ cache_clear_all('schema:', 'cache', TRUE);
This is throwing an exception because you want cache()->deletePrefix(), hence the 0 passes. Apart from that looks good I think.
Comment #4
Damien Tournoud CreditAttribution: Damien Tournoud commentedRerolled for current 8.x.
Comment #6
amateescu CreditAttribution: amateescu commented#4 was not a reroll but the same patch as #1. Let's try this one, with #3 fixed.
Comment #8
amateescu CreditAttribution: amateescu commentedOk, now we're getting somewhere.
Comment #9
sunThe are some more calls to drupal_get_schema(NULL, TRUE) throughout core, most notably one in drupal_flush_all_caches()...
http://api.drupal.org/api/drupal/core!includes!schema.inc/function/calls...
Were they intentionally omitted?
Comment #10
amateescu CreditAttribution: amateescu commentedYep, because there we want the schema to be rebuilt, not just cleared.
Comment #11
sunMakes sense, thanks!
Comment #12
catchWhy do we want the schema to be rebuilt in drupal_flush_all_caches()? Seems fine for the next request that needs it to do that cache building to me.
Comment #13
amateescu CreditAttribution: amateescu commentedI haven't investigated in depth, just looked at the function doc: "Flushes all persistent caches, resets all variables, and rebuilds all data structures.". If that's not true after all, let's try :)
Comment #14
catchIn the case of the schema cache, it's a data structure, but it's also a straight cache item, so yeah this looks good to me.
Comment #15
sunThere are six lines of inline comment in front of this schema rebuild, which try to explain why this explicit rebuild is needed:
http://api.drupal.org/api/drupal/core!includes!common.inc/function/drupal_flush_all_caches/8
If it is not required anymore, then I at least want to know why or how that is so (and wonder why that isn't covered by tests).
And of course, also removing/replacing the lengthy comment.
Comment #16
catchOK so what we want to do then is prevent saving the schema when there hasn't been a full bootstrap then. That's similar to #592008: Don't save theme registry before modules are included.
I was going to open a follow-up for this, but then realised if we're replacing explicit rebuilds with cache clears all over the place anyway, then there's a much higher potential for that race condition (i.e. a hook_boot() implementation calls drupal_get_schema()), so better to do it here. The ThemeRegistry class already has code that could be borrowed.
Comment #17
Damien Tournoud CreditAttribution: Damien Tournoud commented^ At one point during Drupal 7 cycle, running a InsertQuery / UpdateQuery or MergeQuery on PostgreSQL required a loaded schema information. Since then, we are querying the database directly for this information, so this has not been a problem for a long time.
Of course, as catch mentioned, we should not save the schema if ever it has been built before full bootstrap is reached.
Comment #18
Fabianx CreditAttribution: Fabianx commentedComment #27
catchThis is no longer relevant after #2451395: drupal_get_schema()/drupal_get_complete_schema() no longer work as expected; remove them.