php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #80812 opcache.cache_id should be PHP_INI_PERDIR
Submitted: 2021-02-28 14:26 UTC Modified: 2021-03-05 14:12 UTC
From: aschmidt at anamera dot net Assigned: cmb (profile)
Status: Closed Package: opcache
PHP Version: 7.4.15 OS: Windows
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: aschmidt at anamera dot net
New email:
PHP Version: OS:

 

 [2021-02-28 14:26 UTC] aschmidt at anamera dot net
Description:
------------
I have a Windows Service (PHP 7.4 CLI), plus two IIS web sites, configured to run under the same Windows User ID with network privileges, because they need to access a certain network share.

One web site was using PHP 7.3, and one web site PHP 7.4 (because it's a development/staging site). 

In the 7.4 php.ini "cache_id" is set.

When I attempt to run the first web site also under 7.4, then scripts will start failing, due to "Fatal Error Cannot create mutex". I'm assuming, since both IIS sites (with different application code versions) now share the same PHP version and UserID, this results in a clash?

If so, would the solution be to allow different/unique "cache_id"s to be configured in the .user.ini of each IIS site, rather than only being able to configure a common one in the system-wide php.ini?



Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-03-01 11:54 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2021-03-01 11:54 UTC] cmb@php.net
> "Fatal Error Cannot create mutex"

Great error message.  It should at least contain the error code,
to be able to diagnose the problem.

Anyhow, if both sites run under the same user account (and both
use impersonation or not), that shouldn't cause CreateMutex() to
fail.  But still it is likely a good idea not to share the OPcache
instance in your case.  I'm not sure that changing
opcache.cache_id to PHP_INI_PERDIR is sensible, but it shouldn't
be necessary for IIS anyway, because you can run the two sites
with different application pools, and you can use pool specific
environment variables to run with different cache_ids.
 [2021-03-01 13:53 UTC] aschmidt at anamera dot net
-Status: Feedback +Status: Assigned
 [2021-03-01 13:53 UTC] aschmidt at anamera dot net
Yes, the mutex log entry is not helpful at all. I've struggled with that message for a long time, trying to isolate directories by PHP version, trying to add cache_ids, trying to set most liberal NTFS permissions - but without knowing WHAT the actual problem (herror) is, I'm just blindly plugging my finger into every hole I can think of, until the flow happens to stop.

>> pool specific environment variables <<

The manual doesn't mention environment variables to control OPcache.

Can you please clarify if your suggestion is to assign an entire unique PHP.ini via environment variable. I understand that this might be a hypothetical option, but in my opinion a very poor one. It's not good practice to maintain (keep synched) a potentially large number of (mostly) identical PHP.ini's, depending on the number of sites. Incremental differences is the whole purpose of PHP's ".user.ini" file.

That's the reason for me suggesting PHP_INI_PERDIR as the allow the user to specifically override whatever .ini parameter(s) that are unique for a particular site.

>> if both sites run under the same user account (and both use impersonation or not), that shouldn't cause CreateMutex() to fail. <<

Well, the moment I changed one site back to 7.3 yesterday, the problem vanished. I've been through too many iterations over the last years to remember every detail, but I'm fairly certain I had the same Mutex problem before you had added the "cache_id" in 7.4:

At present, it all works because 7.3 runs without a cache_id, and 7.4 runs with a cache_id. It's only after I switched the first site to 7.4, with both sites now sharing same cache_id, and the Mutex problem resurfaced.

(PS: Before you ask... I'm forced to keep some of my WordPress Sites running 7.3, because of open 7.4 problems with the uopz and/or componere components.)
 [2021-03-01 14:14 UTC] cmb@php.net
-Status: Assigned +Status: Feedback
 [2021-03-01 14:14 UTC] cmb@php.net
> Yes, the mutex log entry is not helpful at all.

Yes, that should be fixed.

> Can you please clarify if your suggestion is to assign an entire
> unique PHP.ini via environment variable.

That can be an option, but my idea was more like using the
environment variable in php.ini, e.g.

    opcache.cache_id=${OPCACHE_ID}

Would that work for you?

Changing to PHP_INI_PERDIR might generally make sense, though, but
it appears that would be the only OPcache setting with that
changeability.
 [2021-03-01 22:07 UTC] aschmidt at anamera dot net
-Status: Feedback +Status: Assigned
 [2021-03-01 22:07 UTC] aschmidt at anamera dot net
That's a helpful suggestion. The tricky part is that Windows sets Environment Variables "per User", which is the same for all sites in my scenario. With IIS 10 there's an option that will support setting "per Pool" Environment Variables.

However, even in prior IIS versions, the Application Pool Name itself is available as an environment variable, so one can use:

opcache.cache_id=v74_${APP_POOL_ID}

I've activated the above and initial tests have not yet caused any Mutex errors.
 [2021-03-02 11:26 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Print error code if CreateMutex() fails
On GitHub:  https://github.com/php/php-src/pull/6745
Patch:      https://github.com/php/php-src/pull/6745.patch
 [2021-03-02 11:47 UTC] cmb@php.net
-Status: Assigned +Status: Feedback
 [2021-03-02 11:47 UTC] cmb@php.net
Oh, I was not aware that app pool specific enviroments are only
supported as of IIS 10.  But your suggestion to use APP_POOL_ID
for this purpose is great, so I've documented that[1].

Do you still want to have the changeability of opcache.cache_id
changed to PHP_INI_PERDIR, or can this request be closed?

[1] <https://github.com/php/doc-en/commit/7c6c83d08e97007ca75f739873f8125c6c0640cf>
 [2021-03-02 15:05 UTC] aschmidt at anamera dot net
-Status: Feedback +Status: Closed
 [2021-03-02 15:05 UTC] aschmidt at anamera dot net
Two closing comments:

a) Here's my working cache_id setting which will also cover CLI environments (where an AppPool ID doesn't exist), and further making it unique per PHP version to avoid the possibility of version clashes:

   opcache.cache_id="v"PHP_MAJOR_VERSION""PHP_MINOR_VERSION"_${APP_POOL_ID}"

b) Please do note that the necessity of the above disproves the assertion/assumption that in my scenario there should not have been any Mutex problems in the first place.
 [2021-03-02 15:54 UTC] cmb@php.net
I do not understand why you would need to add the PHP versions
there.  A part of the mutex name is the "system" hash, which also
includes the PHP version (in case of -dev versions even the
timestamp of the build).  Is there possibly a hash collision?  You
can check the names of the mutexes with Process Explorer[1];
select the PHP process, and press CTRL+H.  The mutex name should
begin with ZendOPcache.SharedMemoryMutex@.

[1] <https://docs.microsoft.com/de-de/sysinternals/downloads/process-explorer>
 [2021-03-02 16:20 UTC] aschmidt at anamera dot net
Understood - thanks for those instructions, and (as usual) your patience.

 I will readily admit that I have stumbled upon this working configuration of mine through trial and error while progressing through PHP version, NOT through any deep understanding.

It's entirely possible that I have by now "overcompensated" beyond the bare necessity. 

I have looked up the two mutexes between my batch and IIS instance and they are clearly different, as you suggested:

\BaseNamedObjects\ZendOPcache.SharedMemoryMutex@5975a76bcbe21efa4a56d51fca8d6170@cli@808e3d627370b34f95293d8c0c3c6c26
\BaseNamedObjects\ZendOPcache.SharedMemoryMutex@dfff58c6ad17f8ba242c3d888a6b2843@cgi-fcgi@ec6cf683fce841a5803f62b5956b5f47

I will leave things alone for now - but the next time I do a version change, I'll make a point to set time aside and "step back" my "opcache_id" setting, and then use Process Explorer to view the respective handles.
 [2021-03-05 14:12 UTC] cmb@php.net
The patch to show the error code for failing CreateMutex() has
just landed, and should be in PHP 7.4.17.  This may also help to
analyze the issue.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 01:01:30 2024 UTC