I just upgraded from Drupal 4.7 to 5.2 (PostgreSQL) and TAC seems to be working okay except that when I update my category permissions, the process takes at least five minutes, during which every page on the site says "access denied."

Comments

klance’s picture

I should add that all roles except admin are blocked during category permissions updates, not just anonymous users.

keve’s picture

Please update your module to 5.x-2-dev The module went through major rewrite.

keve’s picture

Status: Active » Fixed

I mark it fixed, please re-open issue, if your problem persist in the new 2.x version.

klance’s picture

I tried it and the "access denied" message is no longer there while updating permissions, but it still runs really slow when updating permissions. In one case 20 min. for one role. I'll have a look at the indexes and tables and make sure they got properly upgraded.

Anonymous’s picture

Status: Fixed » Closed (fixed)
klance’s picture

Version: 5.x-1.1 » 5.x-2.x-dev
Status: Closed (fixed) » Active

The 5.x-2.x-dev version does almost the same thing, except that the "access denied" messages seem to appear arbitrarily during the update. It's still very slow on a large taxonomy structure (several minutes).

klance’s picture

Unfortunately, the one page that I've noticed consistently reading, "access denied" during the 5 min. update is the front page.

klance’s picture

Priority: Critical » Normal

Actually, I'm wrong. It's still happening all over the place, and seems to be arbitrary.

klance’s picture

Priority: Normal » Critical

No difference in behavior whatsoever. Even though I now have a fraction of the categories in my taxonomy access control lists for each role, it is still incredibly slow, and my entire site says, "Access denied" while updating permissions. I've followed the instructions in Troubleshooting in the docs provided, and rebuilt the permissions on the administer->posts page, and it does fix some permission problems but it doesn't improve performance or help with the "access denied" messages.

klance’s picture

After each permission change, TAC calls node_access_rebuild() which, according to what I've read, has been known to cause timeouts, exhaust memory, etc. in the past. I think this is why the updates take such a long time because when I go to admin->posts and run "Rebuild permissions" it takes several minutes to complete.

klance’s picture

Wow, I've been reading up on this node_access_rebuild() function, and here's what it appears to do: First it deletes the entire contents of its database table, so that access is denied to all nodes on your site. Then it loads every node in the system as though it were being accessed by a user on the site, checks which access permissions are granted/denied to each role, and by what module or "realm," and stores the results of this check in the node_access table. During this process, the nodes that have not been re-evaluated continue to display "access denied" messages to anyone but the admin. With a large site this function is very slow, and is definitely not the type of thing you call at the end of practically every function in your module. In fact, it's intended to be a safety net in case your site's access is screwed up because of orphaned access control permissions that got left behind when an access control module was improperly un-installed. I just had a look at the code, and in the 5.x version of Taxonomy Access control, it's called in seven places, only one of which is when the module is un-installed. In fact, it gets called every time the admin form is submitted.

As downloaded, TAC takes several minutes (15-30) to update any permission changes to a single role on my site, regardless of how minor. I removed all calls to node_access_rebuild() from the taxonomy_access_admin.inc file and the same update was so fast that I hardly noticed the page refresh! Deleting and re-inserting rows instead of keeping track of stuff and doing selective updates may be easier, but it's definitely not efficient. Nice to be a guinea pig, though. I'm not sure why the node_access table has to be used, since I assume node access attempts can be intercepted by TAC via hooks even if all access is granted to all roles in node_access, but I could be wrong. Might be a failsafe in case TAC fails, too.

The function node_access_acquire_grants() is "smart" enough to delete node_access entries before re-inserting them (man, has anybody ever heard of UPDATE?), so you don't even have to search for entries in node_access before selectively rebuilding the permissions for individual nodes. Just get the nids of the nodes that are associated with the categories that you update in TAC, then call node_access_acquire_grants() to revise only the permissions of the affected nodes.

klance’s picture

Status: Closed (duplicate) » Active

I've managed to replace most of the node_access_rebuild() calls with functions that selectively update node permissions, and it works very well. It isn't the cleanest thing ever, because it's the result of a mad scramble to fix my sites, but logically it's very sound. The updates are faster, no memory overruns, no page timeouts, and no "access denied" messages.

klance’s picture

Priority: Normal » Critical
StatusFileSize
new4.56 KB

This is a proof of concept patch to propose a solution to the scalability problem with this module, i.e. the more nodes there are on a site, the longer it takes and the more memory is gobbled up by the node_access_rebuild() function. It greatly reduces the amount of time updates take on larger sites, and eliminates the "access denied" messages on pages during the update process. This is accomplished by individually evaluating node permissions instead of rebuilding them for the entire site, on each form submission. Note: This was done in a hurry so the added functions could probably be replaced with Drupal core API functions, but I've tested it extensively and haven't found any problems with it yet, at least on my sites.

klance’s picture

Status: Active » Closed (duplicate)
edrex’s picture

Component: Miscellaneous » Code
Status: Active » Needs work

agreed, let's get this thing in better shape. I pretty much left 2.x work-in-progress (working but still some areas that clearly should be rewritten) because my funding ran out.

I haven't tested your patch yet, but one nitpick is that you're using sub-SELECT inside the WHERE clause, which breaks compatibility with mysql 4 (the module is currently compatible with later releases of 4, don't recall exact version). Use JOIN instead:
"SELECT nid FROM {term_node} WHERE tid IN (SELECT tid FROM {term_access} WHERE rid = '$rid')"
becomes:
'SELECT nid FROM {term_node} n LEFT JOIN term_access a ON n.tid=a.tid WHERE a.rid = %d', $rid

If you want to update i'll review over the weekend.

edrex’s picture

agreed, let's get this thing in better shape. I pretty much left 2.x work-in-progress (working but still some areas that clearly should be rewritten) because my funding ran out.

I haven't tested your patch yet, but one nitpick is that you're using sub-SELECT inside the WHERE clause, which breaks compatibility with mysql 4 (the module is currently compatible with later releases of 4, don't recall exact version). Use JOIN instead:
"SELECT nid FROM {term_node} WHERE tid IN (SELECT tid FROM {term_access} WHERE rid = '$rid')"
becomes:
'SELECT nid FROM {term_node} n LEFT JOIN term_access a ON n.tid=a.tid WHERE a.rid = %d', $rid

If you want to update i'll review over the weekend.

klance’s picture

StatusFileSize
new5.42 KB

Okay, here's an updated patch with the sub-selects replaced by LEFT JOINs. This patch fixes the following problems:

- Access denied messages displayed on pages while updating TAC permissions
- Extremely long update times
- Memory limit overruns

klance’s picture

Keep in mind that given the cost of node_access functions, TAC would be far more efficient if it compared the data it used to build the admin form, with the submitted values, and acted only on those terms that had been modified. Then it would be slow only if several hundred (or more) nodes were associated with a single taxonomy term that was being updated for a particular role. DELETEs and INSERTs should be replaced by UPDATEs, to take advantage of indexes, and terms should only be deleted if no longer controlled by TAC, and inserted if newly-controlled by TAC.

klance’s picture

StatusFileSize
new1.78 KB

Here's the patch for taxonomy_access.module. It has a couple of node_access_rebuild() calls when categories are added/removed from Drupal, that I converted to use the new functions in taxonomy_access_admin.inc.

klance’s picture

Status: Needs work » Needs review
edrex’s picture

will review after my finals next week, a bit swamped atm

klance’s picture

I just noticed something I have to fix in the second patch. It looks like instead of loading the taxonomy_access_admin.inc file globally in taxonomy_access.module, it is selectively loaded based on a URL condition:

Lines 176-181:

  // Only include administrative callbacks and css if we are viewing an admin page.
  else if (arg(0) == 'admin' AND arg(1) == 'user' AND arg(2) == 'taxonomy_access') {
    $path = drupal_get_path('module', 'taxonomy_access');
    include_once($path . '/taxonomy_access_admin.inc');
    drupal_add_css($path . '/admin.css');
  }

In order for it to load the admin functions I added when adding and removing categories, this condition will have to be modified to include the path to this section of Drupal's admininstration interface, like so:

  // Only include administrative callbacks and css if we are viewing an admin page.
  else if (arg(0) == 'admin' AND ((arg(1) == 'user' AND arg(2) == 'taxonomy_access') OR (arg(1) == 'content' AND arg(2) == 'taxonomy'))) {
    $path = drupal_get_path('module', 'taxonomy_access');
    include_once($path . '/taxonomy_access_admin.inc');
    drupal_add_css($path . '/admin.css');
  }

I'll update the patch and post it again.

kcolwell’s picture

Hi,

I manually applied your last patch and change the code in the taxonomy_access.module but after making a change to a setting on the Taxonomy access permissions page for anonymous users I'm getting the following error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON n.tid = d.tid LEFT JOIN (term_access a ON n.tid = a.tid WHERE n.tid =' at line 2 query: SELECT n.nid FROM term_node n LEFT JOIN (term_data d ON n.tid = d.tid LEFT JOIN (term_access a ON n.tid = a.tid WHERE n.tid = '' AND d.vid = '8' AND a.rid = '' in /web/www/includes/database.mysqli.inc on line 151.

Thanks in Advance,
Ken Colwell

p.s. - I should add that the patch added with the change to the module does indeed solve the problem where it takes 3 years to complete a taxonomy access change and access is denied for anonymous users while the entire node_access table is dropped and rebuilt. So kudos and many thanks!

klance’s picture

Hmm... looks like term_node.tid and term_access.rid aren't making it to the query. I guess it makes sense since anonymous users don't belong to a role, but then I wonder why it's been working on my site fine so far. It doesn't look like a pgsql/mysql compatibility error. I'll have a look and try a bunch of more tests and see if I can get it to do that. BTW I'm glad to see that somebody else is having the same problem, because as you can see I've been talking to myself in here for months!

dinis’s picture

How are you getting along with the testing?

Like many other lurkers, I'm sure this is the root of the terrible performance issues we're having with parts of our site when TAC is enabled.

sadnan’s picture

I am working on TAC 5.x.1.1 version.

I noticed a problem in TAC 5.x.dev latest version that, a user having view, edit and list permission, will make a categorized node --> un categorize during Edit process. The only way to prevent this is to assign him Create permission on particular category, which will be confusing for the user.

Modification in TAC 5.x.1.1 version:
It should be easier, if following logic is embedded:
During ENABLED or DISABLED option call node_access_rebuild() there is no choice but to call this function.

On Submit:
CHECK FOR THE ROLE rid and TERM id
update those entries in node_acess table which matches rid and tid
this will save enormous amount of CPU time and execution will depend upon node being accessible to a particular role.

Problem:
what if rid and tid is not the node_access table??

I will post my un-finish work soon......

Any suggestions or advice????

klance’s picture

StatusFileSize
new5.42 KB

Here's an updated patch to test. As it turns out, I made a syntactical error and put a "(" instead of a "{" in two places. Sorry about that!

dinis’s picture

I'll set this up on a test machine a little later; I'll post results ASAP.

P.S. I don't think this is said enough, but stellar work here guys; I've been demonstrating the effectiveness of an open solution to my companies KM system over the last year or so, and it looks like they are about give me the go ahead and funding to fully develop a Drupal based system.

cameronp’s picture

Cool I'll be looking forward to when this patch gets commited - I've been having the same problems..

keve’s picture

I have no time at the moment to test with hundred of terms.
But patch seems appropriate.
I wait some responses from those who tested. After that, i can commit it. :)

klance’s picture

I have 559 terms on one site and 310 on another, and large updates take a few seconds. My admin is happy with it, and he uses it several times daily.

klance’s picture

Here's an updated patch for each of the affected taxonomy_access files, that:

a) fix an SQL error that occurred with the last one, while updating anonymous users' privileges
b) contain better inline documentation of where the patches have been applied, for the benefit of the developers, and
c) also apply the patch for issue #171675 that causes your logs to fill up with SQL errors

Note: Please apply these patches from the main drupal directory, and make sure your modules/taxonomy_access directory contains a clean copy of 5.x-2.x-dev.

dinis’s picture

Quick update on testing the 24/01/08 patch:

All is well so far, massive improvement on performance with category deletions and permissions changes now taking a few seconds from about 15 mins before.

Still testing permissions & multi-tenancy functionality, and the "white page of death still occurs when an admin with access to *all* categories posts an article; going to look into this issue further as I'm now having some doubts now that it's caused by TAC.

Cheers again for your work on this, it's really good stuff :)

dinis’s picture

Quick update:

Releasing this onto the public server today, seems to be working flawlessly.

keve’s picture

Thanks Dinis for comment.
Does anyone else tested with massive taxonomy system?

For me, patch works without problem.

Do you think, TAC with this patch, worth to be tagged as 5-x 2.0?

dinis’s picture

After using this patched version on a production site for a while now, I would *definately* reccomened anyone using TAC on a site with more than a few dozen categories use this one.

I would not say it's quite ready for a full new release as I think there are a couple of features which need to be added:

  • Administration of uncategorised content
  • Interface to allow all terms in a category to be added at once, perhaps multi select if possible
  • Other than that, I'd say it's good to go and can find no problems other than some niggles with the UI (which as has been posted, is an early build).

    Interestingly, when adding the patch to a site which is fully configured with the official realease, it's actually slower updating the permissions untill you reset the TAC for that role and rebuild the permissions :)

    Many thanks once again, superb work.

    micahw156’s picture

    I can't speak for a large site, but I'm implementing a new site using TAC and decided to apply the patches in #32 before I even started. Everything seems to be working ok at this point. Based on the number of comments here and in some duplicate threads, I'd vote +1 towards getting this committed into 5.x-2.x dev and having Dinis' suggestions in #36 opened as a new feature request.

    keve’s picture

    Thanks klance for the patch.
    I commited his patch to 5.x-2-dev.

    It is also included in HEAD version. (already ported to drupal6).

    keve’s picture

    Regarding migration to D6, there is a major improval of node_access_rebuild functionality:
    Please, read: http://drupal.org/node/114774#node_access_rebuild_batch

    What do you think of these?
    Is there a need for 'batch mode' or node_access_needs_rebuild() to boost perforamance?
    Or is everybody satisfied with the patch made by klance?

    dinis’s picture

    Hi Keve :)

    The patch by klance has had a huge positive impact on performance and will suit most medium to fairly large sites; I think it's worth mentioning though that I can measure a performance decrease when comparing a small number of categories/terms/nodes/roles etc. with my production site so for very large sites say 20,000+ nodes and 2,000+ cateories then the performance will quite possibly be slow(ish) again.

    It's also worth mentioning that if one upgrades an existing site using an older version of TAC, then no performance gains will be made until the admin goes through each role and "rebuilds" the permissions settings for each role from scratch (i.e. disable TAC for that role, then set it up again with just the categories and terms to apply TAC settings to). I know the notes say to install the patch from a clean install, but I don't think I read about upgrading exsiting TAC installations.

    Note though, that my findings are currently far from scientific and controlled, and just based on observation. I'll be doing more involved scalability testing later in the year, probably during the summer when we put 6.x migration onto the roadmap (and will happily take on any users testing requirements while we're at it).

    Thanks again to everyone for all the superb work put into this mod.

    keve’s picture

    Thanks for your comment, i will include it in install/update.txt.

    If later anyone will have trouble with huge taxonomy system, and he is eager to test, we can try the new node_access_rebuild in BATCH MODE (in drupal 6 only).

    dinis’s picture

    I'll be setting up a test site with 500,000 nodes, 20,000 categories / terms and 25,000 users for scaling testing.

    It won't be until the summer as I mentioned earlier, but I'll be happy to use it for TAC testing and can probably populate the site with a lot more users / content etc. if that would help.

    keve’s picture

    Status: Needs review » Fixed
    Anonymous’s picture

    Status: Fixed » Closed (fixed)

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