-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
PHP checks the filesystem for file existing even if available in opcache and all opcache validations are disabled #13989
Comments
|
Sorry, I misread the description. So you just used Docker to reproduce the issue, right? Has that happened outside of a docker environment? Or haven't you tried that yet? |
@SakiTakamachi NP:
Correct! It's a bit convoluted, but easiest to reproduce in Docker. I haven't tried it yet outside Docker, no. It should be quite doable, but since you need to tweak opcache settings and have it use the filesystem for storage, it's a bit more of a PITA to do. For one thing: you'd need to prepopulate the build the opcache using the file on the filesystem, then remove the file and ensure it's not in some cache still, then rerun PHP which shouldn't do a filesystem check. Docker allows us to make this much simpler since it's restarting from scratch in step 2 with artifacts generated in step 1, we know there's nothing on the filesystem. |
@SakiTakamachi I did managed to reproduce this without Docker, like so
|
I had a quick look. From what I understand, PHP still tries to open the file because it needs to resolve its path. There might be benefits in trying to resolve the path without looking up the file on the file system. Also note that include / cli scripts are actually two different code-paths, so this assumption would likely need to be adjusted in multiple places. |
Ah, so you're saying it's doing realpath() just to figure out the absolute path and only then checking opcache? Basically, the file needs to exist just to figure out the absolute path? |
Yes. We might try to normalize the path without using the file system, and only revert to it when the lookup fails. But this might require quite a few changes. |
Wouldn't that have a good probability of improving performance in the hot path quite a bit since you'd eliminate expensive I/O when using opcache? 🤔 |
Not normally. Once the file is compiled to shm the file is not touched anymore. Repeated opening of the file only happens when using file cache without shared memory ( |
@iluuu1994 but the file based cache is technically "shm" too, no? |
Not quite. "Shared memory" or shm commonly refers to memory a block of memory, allocated by your operating system, that multiple processes can access. The file cache without shm simply reads and loads the cache file for every request. This is still very much non-optimal for performance (but definitely better than no opcache). |
I know what SHM is, my argument is the file system based shared memory (hence the quotes, "SHM") is serving the same purpose as the real SHM so if the filesystem path is not checked when using the real memory, it shouldn't be using the fake one either. |
I did not say that this is not worth fixing, just that it doesn't normally occur with the normal opcache workflow. When using file cache without shm, you're already opting out of quite a bit of performance. |
Maybe you've misunderstood my tone. 😃 It was less "WHY DOESN'T THIS WORK OMG" and more "What's the technical reason the file is required to exist with file based opcache while it's not required with SHM based opcache, assuming both caches are serving the same purpose?" It feels like it should work for both or neither in sync to me, judging from an outsider. |
No, you're right, there's none. I'm not disagreeing. 😄 My response was targeted at:
I answered no, because that's not usually happening. Each file is only touched once for the first request after the server has started, or when using |
But, if you've said the real path is resolved (and the path needs to exist) before looking up opcache, the same thing is not happening when opcache is in SHM? How does it resolve the real path on subsequent requests then when in SHM? 🤔 |
It is happening without file cache too, but for more obvious reasons: The file needs to be read and compiled. Once it's in shm, it no longer happens. We use the unresolved filename passed to require/include as a key in a map to the persisted script. So, when you do
For file cache, we need the whole path to resolve the fully qualified file within the cache folder. If |
OK, let me recap my understanding of this problem and what we wrote here and you hopefully point out where I got it wrong: Let's say there's three scenarios:
No opcache is boring "always redo everything from scratch", we can skip it.
|
This part is not accurate. On
Your file cache description is an oversimplification, because without
Yeah, thsi is not correct. See above. File cache is usually used in addition to shm, not in instead of shm.
Both of these could be improved by trying to resolve relative paths and checking for the cached file first, and only then resorting to opening the file.
Shm can never be shared in unrelated processes. It's an |
Sorry, just noticed the original issue had the old INI paste, the reproducer was always correct. I am using The idea is being able to put opcache in a PHAR with a static executable shim (or into a Docker image) and ship just opcache, without the original source code, the |
This means you could get a stampede to warm this if you're moving from
OK, then I think I finally understand now, thanks for your patience! |
|
you need at least one file as a entry point and do not enable file_cache_only
|
@asamats file based opcache is the entire point here, in your case it's just using SHM opcache. |
@dkarlovi I'm not sure what exacly you want to achive but in this way you can compleatly delete all source code, just lease one empty index.php call opcache_compile_file with set opcache.file_cache
Second run
Maybe I do not undersand properly how it works, but there is not SHM at the second run, it gets from fs_opcache the op codes and puts to SHM. @dkarlovi why do you want compleatly disable SHM? Just use both of them SHM + fs_opcache |
Description
The following code:
will still trigger "File doesn't exist" even though opcache is correctly prepopulated. If I create an empty folder with an empty file, it works as expected.
See (reproduced in Docker, but this is not Docker specific, it's only convenient to reproduce there):
https://github.com/dkarlovi/docker-php-opcache-only/blob/main/Dockerfile#L15
Try it like here:
https://github.com/dkarlovi/docker-php-opcache-only/blob/main/README.md
PHP Version
PHP 8.2, 8.3
Operating System
Docker PHP image
The text was updated successfully, but these errors were encountered: