Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACLCache: Efficiency. Fix duplicate inserts #21993

Merged
merged 3 commits into from
May 5, 2022

Conversation

mattwire
Copy link
Contributor

@mattwire mattwire commented Nov 6, 2021

Overview

Also see discussion on #21978. This includes changes from that PR.

This PR fully solves the issue of trying to insert the same data into the cache multiple times.

This includes debugging to log which should be removed (or controlled by a define) before merge.

As can be seem from the log trace the assumption that we were trying to build the cache for a userID multiple times is correct. In this case it tried to build 8 times and I believe this is what was happening:
Process 1:

  1. cache() is called.
  2. Does checks (including query) for already built. Not already built.
  3. Requests lock, builds and inserts into cache table.

Process 2..X (called almost simultaneously to process 1):

  1. cache() is called.
  2. Does checks (including query) for already built. Not already built.
  3. Requests lock, waits a few milliseconds and gets lock because process 1 completed within a few milliseconds.
  4. No further checks to see if cache built so tries to build and insert - fails because of duplicates (it was already built by process 1).

The effective change in this PR is that we move the check query inside the lock so we can guarantee that only one process is executing at that point and the cache is either built or is not. There is no chance that it can be being built at the same time the check is being done because we only have one lock per userID.

Before

Duplicate DB errors sometimes on cache rebuild.

After

No duplicate DB errors (check is within lock so we know it won't run simultaneously.

Technical Details

Extract from logs with X applied showing that the cache is being built multiple times which causes the duplicate insert errors:

Nov 05 21:32:33  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [debug] cache: building for 2949; operation=View; force=

Nov 05 21:32:34  [error] $Fatal Error Details = Array
(
    [callback] => Array
        (
            [0] => CRM_Core_Error
            [1] => exceptionHandler
        )

    [code] => -5
    [message] => DB Error: already exists
    [mode] => 16
    [debug_info] => INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT 2949 as user_id, contact_a.id as contact_id, 'View' as operation  FROM civicrm_contact contact_a WHERE     ( (
            `contact_a`.id IN (
               SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80) AND status = 'Added'
                UNION SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80)
             )
          ) )  AND (contact_a.is_deleted = 0) GROUP BY contact_a.id [nativecode=1062 ** Duplicate entry '2949-1-View' for key 'UI_user_contact_operation']
    [type] => DB_Error
    [user_info] => INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT 2949 as user_id, contact_a.id as contact_id, 'View' as operation  FROM civicrm_contact contact_a WHERE     ( (
            `contact_a`.id IN (
               SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80) AND status = 'Added'
                UNION SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80)
             )
          ) )  AND (contact_a.is_deleted = 0) GROUP BY contact_a.id [nativecode=1062 ** Duplicate entry '2949-1-View' for key 'UI_user_contact_operation']
    [to_string] => [db_error: message="DB Error: already exists" code=-5 mode=callback callback=CRM_Core_Error::exceptionHandler prefix="" info="INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT 2949 as user_id, contact_a.id as contact_id, 'View' as operation  FROM civicrm_contact contact_a WHERE     ( (
            `contact_a`.id IN (
               SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80) AND status = 'Added'
                UNION SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id IN (14, 25, 46, 47, 48, 49, 50, 51, 74, 80)
             )
          ) )  AND (contact_a.is_deleted = 0) GROUP BY contact_a.id [nativecode=1062 ** Duplicate entry '2949-1-View' for key 'UI_user_contact_operation']"]
)


Nov 05 21:32:34  [debug] $backTrace = #0 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Error.php(942): CRM_Core_Error::backtrace("backTrace", TRUE)
#1 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(922): CRM_Core_Error::exceptionHandler(Object(DB_Error))
#2 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/db/DB.php(997): PEAR_Error->__construct("DB Error: already exists", -5, 16, (Array:2), "INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#3 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(575): DB_Error->__construct(-5, 16, (Array:2), "INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#4 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(223): PEAR->_raiseError(Object(DB_mysqli), NULL, -5, 16, (Array:2), "INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...", "DB_Error", TRUE)
#5 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/db/DB/common.php(1928): PEAR->__call("raiseError", (Array:7))
#6 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/db/DB/mysqli.php(936): DB_common->raiseError(-5, NULL, NULL, "INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...", "1062 ** Duplicate entry '2949-1-View' for key 'UI_user_contact_operation'")
#7 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/db/DB/mysqli.php(406): DB_mysqli->mysqliRaiseError()
#8 /home/xx/public_html/sites/all/modules/civicrm/vendor/pear/db/DB/common.php(1234): DB_mysqli->simpleQuery("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#9 /home/xx/public_html/sites/all/modules/civicrm/packages/DB/DataObject.php(2696): DB_common->query("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#10 /home/xx/public_html/sites/all/modules/civicrm/packages/DB/DataObject.php(1829): DB_DataObject->_query("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#11 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(468): DB_DataObject->query("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#12 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(1613): CRM_Core_DAO->query("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...", TRUE)
#13 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(289): CRM_Core_DAO::executeQuery("INSERT INTO civicrm_acl_contact_cache (user_id, contact_id, operation) SELECT...")
#14 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#15 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#16 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#17 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#18 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#19 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#20 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#21 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#22 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#23 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#24 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#25 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(23, (Array:21), "51 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#26 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_028389399da4facc55dd967ec5137539", 51, 23, NULL)
#27 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#28 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#29 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#30 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#31 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#32 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#33 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#34 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#35 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#36 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#37 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#38 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#39 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#40 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#41 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#42 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(22, (Array:21), "50 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#43 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_912f5af6d2cca10360ec2168eaa82c5c", 50, 22, NULL)
#44 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#45 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#46 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#47 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#48 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#49 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#50 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#51 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#52 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#53 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#54 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#55 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#56 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#57 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#58 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#59 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(21, (Array:21), "49 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#60 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_1d5afcfa373556ee13c5a9640af159b1", 49, 21, NULL)
#61 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#62 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#63 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#64 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#65 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#66 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#67 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#68 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#69 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#70 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#71 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#72 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#73 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#74 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#75 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#76 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(20, (Array:21), "48 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#77 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_b6b2b50d48f7f32c8cc38ae86e4f77ad", 48, 20, NULL)
#78 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#79 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#80 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#81 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#82 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#83 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#84 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#85 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#86 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#87 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#88 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#89 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#90 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#91 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#92 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#93 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(19, (Array:21), "47 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#94 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_4521c936d0d314a000a1073f154d53cd", 47, 19, NULL)
#95 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#96 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#97 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#98 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#99 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#100 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#101 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#102 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#103 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#104 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Query.php(224): CRM_Core_DAO::getSelectWhereClause()
#105 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Component.php(284): CRM_Case_BAO_Query::where(Object(CRM_Contact_BAO_Query))
#106 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(2072): CRM_Core_Component::alterQuery(Object(CRM_Contact_BAO_Query), "where")
#107 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(575): CRM_Contact_BAO_Query->whereClause(FALSE)
#108 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Query.php(524): CRM_Contact_BAO_Query->initialize(NULL)
#109 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(597): CRM_Contact_BAO_Query->__construct((Array:21), NULL, (Array:273), FALSE, FALSE, 1, TRUE, TRUE, FALSE, NULL, "AND")
#110 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(794): CRM_Contact_BAO_GroupContactCache::getQueryObjectSQL(18, (Array:21), "46 AS group_id", "NOT IN (\n                        SELECT contact_id FROM civicrm_group_contac...")
#111 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(630): CRM_Contact_BAO_GroupContactCache::insertGroupContactsIntoTempTable("civicrm_tmp_e_gccache_fc6f30237a8e33b7248f7fcd4bcc8bdf", 46, 18, NULL)
#112 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/GroupContactCache.php(369): CRM_Contact_BAO_GroupContactCache::buildGroupContactTempTable((Array:1), Object(CRM_Utils_SQL_TempTable))
#113 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/BAO/ACL.php(280): CRM_Contact_BAO_GroupContactCache::load(Object(CRM_Core_DAO))
#114 /home/xx/public_html/sites/all/modules/civicrm/CRM/ACL/API.php(117): CRM_ACL_BAO_ACL::whereClause(2, (Array:0), (Array:0), 2949)
#115 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(262): CRM_ACL_API::whereClause(2, (Array:0), (Array:0), 2949, FALSE, FALSE, TRUE)
#116 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact/Permission.php(361): CRM_Contact_BAO_Contact_Permission::cache(2949)
#117 /home/xx/public_html/sites/all/modules/civicrm/CRM/Contact/BAO/Contact.php(3570): CRM_Contact_BAO_Contact_Permission::cacheSubquery()
#118 /home/xx/public_html/sites/all/modules/civicrm/CRM/Utils/SQL.php(64): CRM_Contact_BAO_Contact->addSelectWhereClause()
#119 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2991): CRM_Utils_SQL::mergeSubquery("Contact")
#120 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/DAO.php(3118): CRM_Case_BAO_Case->addSelectWhereClause()
#121 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/SelectQuery.php(384): CRM_Core_DAO::getSelectWhereClause("a")
#122 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/SelectQuery.php(101): Civi\API\SelectQuery->getAclClause("a", "CRM_Case_BAO_Case")
#123 /home/xx/public_html/sites/all/modules/civicrm/api/v3/utils.php(1266): Civi\API\SelectQuery->__construct("Case", TRUE)
#124 /home/xx/public_html/sites/all/modules/civicrm/api/v3/Case.php(341): _civicrm_api3_basic_get("CRM_Case_BAO_Case", (Array:4), TRUE, "Case", Object(CRM_Utils_SQL_Select))
#125 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Provider/MagicFunctionProvider.php(89): civicrm_api3_case_get((Array:3))
#126 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Kernel.php(149): Civi\API\Provider\MagicFunctionProvider->invoke((Array:8))
#127 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Kernel.php(81): Civi\API\Kernel->runRequest((Array:8))
#128 /home/xx/public_html/sites/all/modules/civicrm/api/api.php(22): Civi\API\Kernel->runSafe("Case", "get", (Array:3))
#129 /home/xx/public_html/sites/all/modules/civicrm/api/v3/Generic.php(281): civicrm_api("Case", "get", (Array:3))
#130 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Provider/MagicFunctionProvider.php(85): civicrm_api3_generic_getcount((Array:8))
#131 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Kernel.php(149): Civi\API\Provider\MagicFunctionProvider->invoke((Array:8))
#132 /home/xx/public_html/sites/all/modules/civicrm/Civi/API/Kernel.php(81): Civi\API\Kernel->runRequest((Array:8))
#133 /home/xx/public_html/sites/all/modules/civicrm/api/api.php(132): Civi\API\Kernel->runSafe("Case", "getcount", (Array:2))
#134 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(1837): civicrm_api3("Case", "getcount", (Array:2))
#135 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/BAO/Case.php(2810): CRM_Case_BAO_Case::caseCount(NULL, FALSE)
#136 /home/xx/public_html/sites/all/modules/civicrm/CRM/Case/Form/Search.php(72): CRM_Case_BAO_Case::isCaseConfigured()
#137 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Form.php(621): CRM_Case_Form_Search->preProcess()
#138 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/QuickForm/Action/Display.php(76): CRM_Core_Form->buildForm()
#139 /home/xx/public_html/sites/all/modules/civicrm/packages/HTML/QuickForm/Controller.php(203): CRM_Core_QuickForm_Action_Display->perform(Object(CRM_Case_Form_Search), "display")
#140 /home/xx/public_html/sites/all/modules/civicrm/packages/HTML/QuickForm/Page.php(103): HTML_QuickForm_Controller->handle(Object(CRM_Case_Form_Search), "display")
#141 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Controller.php(352): HTML_QuickForm_Page->handle("display")
#142 /home/xx/public_html/sites/all/modules/civicrm/CRM/Dashlet/Page/MyCases.php(52): CRM_Core_Controller->run()
#143 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Invoke.php(313): CRM_Dashlet_Page_MyCases->run((Array:3), NULL)
#144 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Invoke.php(69): CRM_Core_Invoke::runItem((Array:13))
#145 /home/xx/public_html/sites/all/modules/civicrm/CRM/Core/Invoke.php(36): CRM_Core_Invoke::_invoke((Array:3))
#146 /home/xx/public_html/sites/all/modules/civicrm/drupal/civicrm.module(458): CRM_Core_Invoke::invoke((Array:3))
#147 /home/xx/public_html/includes/menu.inc(527): civicrm_invoke("dashlet", "myCases")
#148 /home/xx/public_html/index.php(21): menu_execute_active_handler()
#149 {main}


Nov 05 21:32:39  [debug] CRM_Contact_BAO_Contact_Permission::cache already called via check query. Operation: View; UserID: 2949

Comments

@seamuslee001 @johntwyman Alternative (preferred) to #21978 which I think might just solve ACL cache building properly!

@civibot
Copy link

civibot bot commented Nov 6, 2021

(Standard links)

@civibot civibot bot added the master label Nov 6, 2021
@mattwire mattwire changed the title Aclcachequery2 ACLCache: Efficiency. Fix duplicate inserts Nov 6, 2021
@jaapjansma
Copy link
Contributor

@mattwire Betty and I are reviewing PR's do you have an instruction on how we can test/reproduce this problem as a user/administrator? We like step by step instructions as that helps us with reviewing the PR.

@mattwire
Copy link
Contributor Author

@jaapjansma This includes changes from #21978 so we should review/merge that one first. This PR goes further to solve the problem completely.

@johntwyman
Copy link
Contributor

Hey folks. Just wanted to flag that I'm in the process of testing this PR out (alongside the Group Contact cache one). Our environment is particularly tricky/messy as far as ACLs are concerned. So I'm particularly hopeful that this PR works and would argue that if it works for us it's going to work for anyone else. :)

I'll try and post an update with results, etc., in the next couple of days.

@andyburnsco
Copy link
Contributor

andyburnsco commented Apr 22, 2022

I have had this PR running on a production site for a week with several concurrent users (~120/week) and not had any issues. Using Multisite so using the acl_contact_cache table for nearly all users. Civi 5.46.3If you are looking for specific tests, please let me know the criteria of those tests.

Applied this PR at the same time: #21943

@mattwire mattwire added the merge ready PR will be merged after a few days if there are no objections label Apr 23, 2022
@mattwire
Copy link
Contributor Author

mattwire commented May 5, 2022

Merging so it can be in next RC.

@mattwire mattwire merged commit 99b43f2 into civicrm:master May 5, 2022
@mattwire mattwire deleted the aclcachequery2 branch May 5, 2022 18:04
@agileware-justin
Copy link
Contributor

Thanks @mattwire looking forward to improvements 😄

On the topic of database performance improvements, it would be really interesting to know why the decision was made to:

  1. Have the modified_date field on the civicrm_contact table, and
  2. Implement table triggers on all tables which have contact custom fields, address, phone, email etc.

Because the impact is that any time a contact or related contact field is modified the trigger fires and locks the civicrm_contact table, preventing writes during the exact time a write is required.

Moving the modified_date field to a different table would seem to be a fairly simple solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
master merge ready PR will be merged after a few days if there are no objections
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants