Closed (fixed)
Project:
Drupal core
Version:
7.x-dev
Component:
update system
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
4 Sep 2008 at 11:36 UTC
Updated:
8 Sep 2009 at 13:34 UTC
Jump to comment: Most recent file
Comments
Comment #1
jody lynnI have the same problem and am unable to upgrade (trying to test a patch for upgrade path).
The problem is coming from database.inc line 356.
I can't get to update.php because this PDOException always redirects me to install.php.
Comment #2
catchThere's also the issue that users who've started with D6 may never have seen their settings.php before, so it will be a shock to upgrade. Opened a new issue for that #304163: Allow update.php to regenerate settings.php.
Comment #3
smk-ka commentedI tried adding a redirect to update.php whenever the old $db_url connection string was detected. However, it then quickly turned out that the real culprit is within drupal_is_denied(), which is called during DRUPAL_BOOTSTRAP_ACCESS while running update.php. This specific function queries a list of blocked IPs from the database, which isn't updated at that point. That is, the {blocked_ips} table doesn't exist, because it has yet to be added as part of the update. And here I'm stuck: I have no idea how to circumvent this little chicken and egg problem.
EDIT: I believe this has formerly been solved by running some preliminary updates (aka. update_fix_d6_requirements()), my guess is that something similar might have to happen for D7, right?
Comment #4
kbahey commentedI too cannot upgrade from D6 to D7.
Here is some more info on this.
First obstacle is this code in includes/bootstrap.inc.
Drupal goes into checking whether access is denied to the IP address of the user, and the blocked_ips table does not exist.
So, it goes here:
The try fails, so it goes into this catch:
At this stage, it cannot find the module_implements, and hence redirects to install.php.
If I comment the chunk in bootstrap.inc like this:
I am able to get to update.php?op=info, but it gives a WSOD and I can't proceed further.
xdebug also reaches a place where there is a
throw new PDOException('...and can't proceed any further.Hope this helps whoever can take it further ...
Comment #5
kbahey commentedHere is a bit more narrowing down where this is:
When update.php?op=info is run, we end up here in that file:
Which starts calling the PDO stuff to do the query.
Then this function gets called because of the autoload
Which does a db_query() on
SELECT filename FROM {registry} WHERE name = :name AND type = :type.This goes on and does a prepare, and then goes to this code:
$args have the following:
And $options have the following:
Then we call this, and that is where the exception happens:
So, we end up here:
In includes/database/database.inc around line 365.
Xdebug complains of:
And hence the WSOD.
Comment #6
kbahey commentedThe underlying reason is that the registry table does not exist, but we are trying to query it. Of course, we will create it in the update.php, but we can't do so. Catch 22!
Comment #7
chx commentedWell, then the registry table needs to be moved to update.php but also -- why do wind up in autoload class? We should not. Manual loading would be good...
Comment #8
catchSo it seems like we need an update_fix_d7_requirements() which creates the blocked_ips and registry tables. It'd be nice not to have to do that, but it's consistent with the 5-6 upgrade (which adds block_cache as soon as you hit update.php and probably some others too).
Comment #9
Crell commentedAs chx says in #7, install.php already does a manual load of the required DB files. update.php should do the same. It's one of those autoloading edge cases that is, fortunately, very easy to bypass. Whether we want to move that utility function to bootstrap.inc or something I am not sure yet, but we certainly can.
Comment #10
David_Rothstein commentedHere is a start at a patch:
function_exists('module_implements')checks (it's not clear to me why that would ever indicate that Drupal is not installed) and replacing them with a single, consolidated check that hopefully makes more sense. That way at least you don't get mistakenly redirected to install.php when you should be getting a WSOD :)ini_set('display_errors', FALSE);in update.php. I guess the PDO error handling changed that, so in the attached patch I have update.php wrap it in atry-catchblock so the errors can once again be correctly suppressed. However, there is maybe a bit of a security issue here since until you've fully updated your site to Drupal 7, any IP addresses which you had previously banned in Drupal 6 can now reach your site without being blocked! For now, I did not try to deal with that; we would probably need to put fallback code in drupal_is_denied() itself to deal with that correctly.So, here is where things stand after the attached patch is applied.... we get further along in the update process and hit some new errors (all WSODs, it seems).
For a privileged user accessing update.php:
This time we wind up in the autoload class because the function
DeleteQuery_mysql()doesn't exist anywhere in Drupal, so it doesn't matter that we've manually loaded all the files. I tried fixing this by addingspl_autoload_unregister()calls within update.php so that the autoloading never happens. If you add that to the patch, then you wind up here:Which is where I got stuck. (Note that in the case of an unprivileged user trying to access update.php, you wind up with the above error too.)
Finally, it's not clear to me if this is a separate issue or not, but above we've been talking about accessing update.php... what about if a regular user comes along and tries to access the main site while the upgrade is happening? We want them to see the maintenance page, but right now they would get a WSOD due to the {blocked_ips} issue:
(And if you remove that, they get other errors instead.) It seems like the ideal solution would therefore be to move a lot of this stuff into the main bootstrap rather than update.php -- i.e., have a function that somehow detects that they still have a Drupal 6 database and, if so, does the necessary loading to prevent things from failing?
Comment #11
David_Rothstein commentedOK, each bug fixed revealed a new one!... but this patch should get them all. It is now possible to run update.php and successfully make it all the way through.
The other problems discussed above could be split off into separate issues, so I think this one is ready for review.
Comment #12
moshe weitzman commentedI did a code review and it looks good. Needs testing.
Comment #13
catchCode looks good, ran a 6-7 update (put the d6 database name into an existing Drupal 7 settings.php). Works great too.
Comment #14
kbahey commentedHere is another +1.
I applied the patch and was able to update a Drupal 6.6 site to HEAD without any issues.
This needs to go in.
Comment #15
webchickWhat a great surprise! I will review this later tonight. :)
Comment #16
webchickHm. This did not work for me. :(
Process:
1. Imported a copy of webchick.sql.gz. This site is just core + Zen + Mollom. I can probably provide an anonymized dump of this, but any basic Drupal 6 site with some dummy content should suffice.
2. Did a checkout of DRUPAL-6 and created settings.php to point at the local copy of the database.
3. Hit ?q=node and, apart from lack of a theme, things worked fine.
4. Did cvs up -r HEAD -dPC
5. Applied the patch.
6. Reloaded ?q=node. Got forwarded to install.php.
7. Manually edited my settings.php file to add in the following:
(this was copy/pasted out of the comments in default.settings.php)
8. Hit ?q=node again, got:
PDOException: SELECT 1 FROM {blocked_ips} WHERE ip = :ip - Array ( [:ip] => ::1 ) SQLSTATE[42S02]: Base table or view not found: 1146 Table 'webchick.blocked_ips' doesn't exist in /Applications/MAMP/htdocs/webchick/includes/database/database.inc on line 421
That's fine. I noticed a hunk about this in the patch.
9. Hit update.php, but received:
Fatal error: Exception thrown without a stack frame in Unknown on line 0
So apart from the fact that this doesn't work. ;) The other thing I'd really like to see in this patch is some sort of notification about the settings.php change requirement. I don't know how long it's going to be (if ever :\) before #304163: Allow update.php to regenerate settings.php is addressed, and we need something for the people who don't follow core commits in the meantime. Seems like it'd be easy enough to parse the existing db_url and then give them a snippet they could just copy/paste.
Comment #17
kbahey commentedSounds like you are missing port?
Mine looks like this:
Also, in my case, I used a Drupal 6 with only core, but lots of generated content (comments, nodes, taxonomy, users).
I was LOGGED OUT when I did the update, and had a working settings.php from before. All I did was change the free access to update to TRUE, and hit update.php, and it all went well.
After the update, I logged in, and all was well.
So, check your settings.php first.
If that does not make a difference, the other differences that I have are: I did not have to convert settings.php manually, and I was logged off, it that makes any difference.
Comment #18
dave reid@17, The port array key is not in the default.settings.php comments. That shouldn't be the problem...?
So I installed a fresh DRUPAL-6, upgraded to CVS HEAD, applied patch from #11. I modified my settings.php to the correct format and the update worked. I'll try with the old $db_url in settings.php
Comment #19
Crell commentedThe port is optional. The auto-generated array includes it because the internal data structure it comes from has it, but it should not be needed unless you're running on a non-standard port.
Comment #20
kbahey commentedHere is a reroll to get rid of offsets introduced lately.
It still works for me, and I am able to update from d6 to d7 without issues.
Comment #21
chx commentedThat can only be because you have not had search module on. Testing more.
Comment #22
chx commentedwebchick's dump works for me.
Comment #23
chx commentedSo the issue was , if you had search module enabled the when the maintenance theme ran theme_get_settings you had a user_access running which tried to query tables which did not exist. FAIL.
Comment #24
webchickOk, I confirm that the most recent patch solves this bug.
We still desperately need a fix for the redirection to install.php until settings.php is manually edited. I don't want to release UNSTABLE-3 until there's a solution for the install.php redirection (and such a solution can be as simple as adding documentation about the change rather than auto-generation, for now). But since this issue is actively holding up efforts such as upgrade testing and benchmarking, I'm okay with committing this patch without that fix.
Want to read this over once more thoroughly after supper. It looks like the behaviour of the search toggle changed so I want to test that a bit.
Comment #25
David_Rothstein commentedAh, I get it... in order to see the last bug, you needed both search module enabled and to not be logged in as user #1; that's why most of us didn't see it.
I started to look into the issue of parsing $db_url and no, it doesn't seem like it will be too hard, but I won't be able to get to posting a patch until tomorrow. It actually occurred to me that once we go through the trouble of parsing it, we could probably just use it to populate the $databases array directly rather than printing anything to the screen that needs to be copy-pasted -- in other words (for now at least) make Drupal 7 completely backwards-compatible with the old $db_url format? More coming tomorrow...
Comment #26
webchickWell that sounds eeeeenteresting. :)
Ok, I think I'm going to hold off then. It would be great to get this fixed fixed.
Comment #27
chx commentedPlease make the settings.php issue separate! And commit this :)
Comment #28
chx commentedWhy a separate issue? Because it's a highly controversial idea to add backwards compatiblity to Drupal -- although this is something different than we had BC before because those things that we broke happily were developer and not enduser facing.
Comment #29
kbahey commentedHere is the other issue for migrating the database settings http://drupal.org/node/326424
The patch at hand works and I agree with chx, it needs to be de-coupled from any migration.
Comment #30
David_Rothstein commentedOK, here is a version with the $db_url parsing so that Drupal 6 settings.php files don't have to be edited. I've tested this on:
(a) a new installation
(b) updating from Drupal 6 with all core modules enabled and logged in as user #1, and
(c) updating from Drupal 6 with all core modules enabled and using $update_free_access = TRUE.
It seems to work fine, although I haven't tested the more obscure possibilities for the $db_url format.
I agree that if this is considered controversial, it's better to commit the patch from #22 now and have this one be a follow-up patch. Although I thought there was some precedent for this kind of thing (didn't Drupal used to have an entire "Legacy" module)? So it might be reasonable to move the function I've introduced here into an includes/legacy.inc or something like that so that it can be included only when necessary...
Comment #31
David_Rothstein commentedOops, crosspost... well, I can always copy my code over to the other issue, depending on what is eventually decided ;)
Comment #32
kbahey commentedThe last patch did not apply.
I fixed it and now it applies AND it does make update.php work.
So a +1 on it going in.
Comment #33
kbahey commentedPatch no longer works.
Specifically, this patch that Dries committed http://drupal.org/node/298600#comment-1085318 made update.php redirect to install.php once again, so we are back to square one.
It is no longer possible to update from D6 to D7.
Comment #34
chx commentedkbahey, remember Steven's advice about microwaves?
You just needed to reroll against HEAD -- only some whitespace changes failed. My patch never stopped working.
Comment #35
kbahey commented@chx,
No, it did not work. And I tried the microwave too ... not derailing anything ...
Here is what I did:
Then I change settings.php to do update free access, and hit update.php.
I get this:
I hit the error page link, which is /update.php?id=2&op=finished
And I get this:
Then visiting the home page or /user gives this error:
So, how can the patch be working for updates?
Comment #36
chx commentedWell, a) you derail stuff because you continued David's patch b) you reported that it redirected to install.php which it never did. I am well aware of the error (it's btw. the create registry statement, the key is too long) but that's NOT related to this issue which is about making the update.php NOT redirect to install.php. That's TWO installs (edit: issues), one fix the registry update (trivial!) two fix the _drupal_log_error function so that it behaves for install and update. I am working on that right now. For a taste of things to come:
does not work yet but I am on it.
Comment #37
kbahey commentedDon't know what "continued David's patch" means ...
Right now, without any patches, and using up to the minute HEAD, if you start with a D6 database, and try to visit any page, be it front, /user or update.php you get redirected to install.php. This is what I reported, and I am still getting it.
Comment #38
kbahey commentedAfter the Halloween scare above, chx and myself worked on this patch.
I can confirm that it does work for me, and update.php works as expected.
Here is a reroll, with a field length change for system.install so hook_update_xxx() matches the schema for the registry table that prevented it from working previously.
More testers with more data needed.
Comment #39
chx commentedRelated issues are #304163: Allow update.php to regenerate settings.php and #328781: Fix horrible things in the error reporting.
Comment #40
catchRead through the patch, everything looks sane, removes the weird function_exists() check and it worked great for me.
I tested:
A clean D7 install
Upgrading a reasonably clean D6 install to D7
Visiting update.php when there's no settings.php
Visiting install.php when Drupal's already installed.
Visiting update.php when there's no updates to run.
Seems pretty solid to me, could do with one further review.
Comment #41
David_Rothstein commentedI tried the patch from #38 and it doesn't work for me. It fails on system_update_7007(). Let me see if I can look into it.
Comment #42
kbahey commentedConfirmed that it fails on the same dataset that was successful a day ago.
Must be something that was committed today that broke it?
Comment #43
David_Rothstein commentedAh, yup, it looks like it's due to #257910: Performance Issue during Indexing - search_dataset.sid_type unique key should be an Index and the problem with update.php has already been noted there (with a patch to fix it). If I apply the patch here along with the patch from comment #17 in the other issue, then it seems to work again. So if both get committed we are OK.
I have no idea why Drupal was reporting to me that the problem is in update #7007 when actually it was in update #7012, but I guess that's part of the overall brokenness of the error handling right now?
The patch here looks good to me, although I'm not sure what's up with this part:
Was that extra line some debug code that got left in?
Comment #44
Sree commentedstill not working for me!
Comment #45
chx commentedHere is the patch and I foudn the same debug piece that David did, sry. Ain't easy to get this flying. There are problems in DBTNG that caused things to fail.
Comment #46
chx commentedminus the error reporting patch.
Comment #47
David_Rothstein commentedAh, yes, so in the course of a single day not one but two new problems appeared!.... Sorry, I (again) forgot to test with the search module enabled, so I didn't see the second one.
I tested the patch in #46 under a few scenarios, and it seems to work fine as long as you start with D6 search module installed. If you don't start with search module installed, you get an error, but that is the issue taken care of by #257910: Performance Issue during Indexing - search_dataset.sid_type unique key should be an Index so I think we are OK here.
I think this is ready but I can't "legally" set to RTBC since a lot of the code was written by me, and it could probably use one more review/test anyway. However, if this doesn't get committed soon, I predict it will be a very short amount of time before it finds itself broken again... :)
Comment #48
kbahey commented#46 fails on 7012 for me.
Comment #49
kbahey commentedSorry. 7010 runs fine, so must be 7011 (not 7012) that fails.
Comment #50
HedgeMage commentedPatch in #46 works like a charm :)
Comment #51
webchickOk. Re-confirmed that the patch continues to work with the webchick.net dump after manually editing settings.php. Though I don't consider this issue /really/ fixed until #304163: Allow update.php to regenerate settings.php is done.
@kbahey: That error is due to #257910: Performance Issue during Indexing - search_dataset.sid_type unique key should be an Index and is unrelated to this patch.
The code overall looks good:
I'll commit #257910: Performance Issue during Indexing - search_dataset.sid_type unique key should be an Index too in a moment, and then it should be /much/ easier to get people to test the upgrade path. :D
Thank you so much for all of your great work, folks!! :D
Comment #52
kbahey commentedWhen #46 is applied with http://drupal.org/node/257910#comment-1089685, the combo works well.
Comment #54
int commentedsee this error #569410: Can't update D6 -> D7 table not found (drupal_blocked_ips)