The usage of the node access grants system was implemented, because the views pager, the search results and the menus were showing nodes, to which users had no access. This brings an non-trivial performance footprint, since node_access_rebuild() is run on every node save via hook_node_presave(), every taxonomy term save via permissions_by_term_submit() and every user creation via hook_user_insert().
Website admins need to be aware, that the process of rebuilding the node access database by node_access_rebuild() can take a relatively long amount of time, when the website has many nodes. Then the max_execution_time in the php.ini file must be set to an appropriate time, to provide enough time to build the node access database.
For performance purpose on large websites (> 10.000 Drupal nodes) it would be good option to have the node access database with PbT optional. Then the direct access to nodes would be prevented by hook_node_access() and menus, search pages and views would be not protected. A configuration entry, that could be set by a PbT config form or the settings.php file should do the job.
Comments
Comment #2
jepster_Note: This issue should be an investigation issue in first place. Chances are, that the batch mode in node_access_rebuild() can bring a performance boost. The investigation should happen with ~1.000 nodes to make the effects visible.
Comment #3
jepster_Comment #4
zerolab commentedI think this should be a critical issue.
With 1000 users (U) and 1000 nodes (N), you get 1 million rows to rebuild.
At the very least on user insert, only the grants for that user should be added. That way it is a question of adding N nodes rather than U x N.
Cheers,
Dan
Comment #5
jepster_I have improved a few things via the new 8.x-1.15 release. See the release notes:
So I keep this issue opened. At least until the functionality for an optional node access records support will be implemented.
Other performance improvement ideas are welcome.
Comment #6
zerolab commentedReal scenario: running a migration with the module enabled results in out-of-memory errors, even for very large max_memory limits for php. :/
Comment #7
zerolab commentedAs expected, we bumped into this.
With a mere 7000 users, attempting to do anything with a node results in out-of-memory errors even with 1G.
Disabling PbT makes the operation a breeze.
Comment #8
jepster_Wow - 7000 users! Then I am optimistic, that you are able to contribute a major performance improvement. ;)
Comment #9
zerolab commentedOK, after a bunch of research, the solution is to simplify the model.
Currently you are creating a separate realm for each user, where is the realm should be per term. So if I create only one PbT term, then there is only 1 realm.
With this, there is no need to touch the
node_accesstable on user insert/update and node insert.Examples:
Also, we are dealing with 50+K users.
Comment #10
jepster_That is a valid suggestion. After some thinking I am quite sure, that we could save a lot of database queries here. We have already the user and role related permissions in the
database tables. From them we could relate to node_access. This would result in a rewrite of the NodeAccess and AccessCheck Service. Probably they could also be merged in this step. I have some new knowledge regarding automated testing, so this process could go with less bugs than in the past of PbT.
However, that's a bit of programming work. Do you have time work with me on this? We could open up two issues and review our patches. To be honest I do not have any project where I am using PbT. No company will pay for my effort. I work on PbT in my spare time. For me PbT is a project for learning Drupal, Symfony and modern PHP programming. My daily job is in Symfony. So it would be really appreciated, if this issue would not wait just for me.
Comment #11
jepster_This issue won't fix. Drupal requires the Node Access records to be by user. Since in the search results hook_node_access() receives only the user account and no node id's. PbT restricts nodes also in search results.
Comment #12
jepster_The PHP timeout/memory issue will be fixed via batch processing by work on this issue: https://www.drupal.org/node/2901186
Comment #13
jepster_There has happened a massive performance improvement by adding only 1 node access record per node. See more details at https://www.drupal.org/node/2901186. Improvement has happened in release version 8.x-1.25.