The table structure for the url_alias table is improper right now. There is a UNIQUE index set on the dst_language_pid grouping. The pid column should be removed from that index as it's now possible to have duplicate destinations for the same language because pid is ALWAYS a unique value.
This should be changed to UNIQUE KEY (`dst`, `language`) to correct this structural issue.
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | url-alias-818214-17.patch | 2.16 KB | David_Rothstein |
| #14 | url-alias-818214-14.patch | 1.41 KB | David_Rothstein |
| #13 | 818214_url_alias_index.patch | 1.18 KB | JacobSingh |
| #6 | url-alias-818214-6.patch | 1.34 KB | David_Rothstein |
| #2 | 818214-url_alias-index.patch | 1.16 KB | dawehner |
Comments
Comment #1
damien tournoud commentedIndeed. Bumping to Drupal 7: we fix bugs in the current development version first, before backporting them.
Comment #2
dawehnerHere is a patch
Comment #3
dries commentedIndeed-ly. Committed to CVS HEAD.
Comment #4
andypostThis change come from #358315: drupal_lookup_path() not respects alias' order
So rollin back this change should be measured!
Comment #5
David_Rothstein commentedIt looks from #358315: drupal_lookup_path() not respects alias' order like pid was originally added to the index in an attempt to avoid a filesort, but given that it is already a primary key that doesn't seem necessary? And the current queries in core certainly don't seem to have performance problems in that regard:
So from a performance perspective I think the change committed here was OK.
However, there are other considerations for why we might roll it back. The patch committed here overall seems like an API change, and it's not clear what bug it was fixing. I don't know why we need to prevent multiple sources for the same alias/language at the database schema level, given that:
Unless there is a good reason for the database schema change that was not explained above, then I think the simplest thing to do here is to roll this back for Drupal 7 and maybe consider it again for Drupal 8.
Comment #6
David_Rothstein commentedInstead of a complete rollback, we could maybe do the attached (only lightly tested) patch.
This continues to leave 'pid' out of the indexes - since it doesn't really make sense there - but changes the unique key to a regular index in recognition of the fact that in Drupal 6 at the moment the inclusion of 'pid' means that it is not actually meaningfully unique anyway. Thus, we stay consistent with Drupal 6 and do not need to deal with any of the potential code changes I mentioned above.
Comment #7
damien tournoud commentedNo, we certainly don't want to roll the change back. As indicated in the original post, there is a structural issue in url_alias: we define a unique key on
'alias', 'language', 'pid', which is *completely useless* because pid is already unique by design.So we probably want just to remove that constraint and live an happy life ever after.
Comment #8
damien tournoud commentedCross-posted with #6.
This said, we actually want the pid to be part of the index, because of the sort on language, pid.
Comment #9
David_Rothstein commentedWell, pid is already a primary key, and the EXPLAIN queries above show that there is no filesort even without it being part of the index. (Also, in the typical case, the sorting by pid probably won't even need to happen, or at least only happen to a very small number of rows.)
Do you think there is still a big advantage to explicitly making it part of the index?
Comment #10
damien tournoud commented@David: because the conditions (the WHERE part) return only one row, MySQL doesn't have to sort, so it will not even care in the examples you copied. Try to remove the UNIQUE key and add more data, and you will see the filesort reappearing.
Comment #11
David_Rothstein commentedI am still not reproducing a filesort, even with no unique key and more data. If I apply the patch from #6 and reinstall Drupal, then do the following, there doesn't appear to be a filesort:
Comment #12
andypostunique key make no sense with pid within.
Another issue that LANGUAGE_NONE is 'und' so idea "...The language should have priority over the empty language." is totally broken because there are different languages
I think query should LIMIT 1 because static cache of drupal_lookup_path() stores only first row
Comment #13
JacobSingh commentedI don't know any place in the code where we do a query on this table sorting by language,pid which doesn't have a WHERE clause attached to it. But even so, and index on this table is probably not a big deal as inserts aren't usually a performance concern anyway.
Here's a patch which includes the pid field.
Comment #14
David_Rothstein commentedOK, fine with me - I agree it doesn't hurt much to have it there.
However, if we're keeping pid in the alias index, we need to keep it in the source index also; they are parallel. See attached patch.
So basically, after this patch, the end result of the D6->D7 update would be only one meaningful change to the url_alias table: The unique key in D6 (which was not actually providing any meaningful uniqueness constraint) becomes an index, and everything else stays the same.
Comment #15
JacobSingh commentedworks for me.
Comment #16
andypost@JacobSingh take a look at drupal_lookup_path()
Suppose better to incorporate this with system_update_7042()
And remove system_update_7056() as useless also making upgrade process a bit quicker
Comment #17
David_Rothstein commented@andypost, the queries in drupal_lookup_path() are the ones Jacob was looking at. None of them appear to cause an issue.
Anyway, I agree with you about system_update_7042() - the attached patch does that. We don't seem to be renumbering update functions when we take them out (there are variety of gaps all over the place at the moment) so I didn't do any renumbering related to removing system_update_7056() either.
Does this look good?
Comment #18
David_Rothstein commentedI created a (preemptive) HEAD to HEAD patch for this here: #863184: Update for improper {url_alias} table structure
Comment #19
andypostGreat, but whats about #12 - priority of aliases? separate issue?
+1 RTBC #17
Comment #20
David_Rothstein commentedSounds to me like a separate issue, yeah.
Comment #21
andypostI file separate issue #863318: Wrong sort order of aliases for different languages
Comment #22
dries commentedCommitted to CVS HEAD. I'm moving this to HEAD 2 HEAD so we can look at it in that context just to make sure.
Comment #23
rfay@Dries please change your workflow to create new issues in head2head.
#863682: Handle Improper table structure for url_alias created in HEAD2HEAD
Comment #24
David_Rothstein commentedThanks for committing.
Especially since in this case, I already created the Head2Head issue, linked to it above (in #18), and already had a patch posted there :)
Comment #26
c960657 commentedI don't understand why the uniqueness on alias+language was removed.
Obviously an internal path can have any number of aliases. But is the same alias really allowed to point to more than one internal path per language? And what does it mean if it does?
If a try to create a duplicate alias on admin/config/search/path/add, I am blocked by the following code in path_admin_form_validate() that seems to indicate that alias+language is supposed to be unique:
pid was added to the unique key in #358315: drupal_lookup_path() not respects alias' order for performance reasons. The patch added
ORDER BY pid DESCto two different queries, but AFAICT it was only necessary for one of them. For the other one (shown below) there was no need to order by pid too, because dst+language were already unique.Do you agree, or did I misunderstand something?
Comment #27
David_Rothstein commented@c960657, the same alias pointing to multiple sources is blocked via the UI, but still handled in path.inc (it's allowed via the API).
And as described above, it didn't seem worth adding this restriction to the database schema this late in the cycle (and dealing with any potential update headaches this might cause). It might be a good idea for Drupal 8, though.
Given that, I'm not sure if you're still saying there is some way we could improve the existing queries in Drupal 7 (it sounds like there might be)... probably better to open a separate issue for that?
Comment #28
c960657 commentedNo, I think the existing queries are fine, given the current database schema.
I know it's late in the cycle, but on the other hand it's one of those problems that get harder to fix, the longer you wait. I think it's a regression, but that regression was introduced in D6 as well, so I guess this is not a blocker. I have created a new issue for this: #925474: Improve table structure for {url_alias} #2.