Error writing to CDB file when several MediaWiki installations use the same tmp directory
Closed, DuplicatePublic

Description

Out of the box, the MediaWiki configuration has used wfTempDir() since 99fdc6e8 to store temporary files.

The CDB l10n_cache-en.cdb file is stored in this temporary directory.

If several MediaWiki installations run on the same machine, tihs means they will each update this cache, which has two different undesired effect:

  • If the content to cache diverges, the content of one wiki will overwrite the content of another
  • If the two wikis are run by different user accounts (e.g. two different php-fpm pools), an exception will be thrown as it's not possible to overwrite the file.
Warning: rename(/tmp/l10n_cache-en.cdb.tmp.1665604027,/tmp/l10n_cache-en.cdb): Operation not permitted in .../vendor/wikimedia/cdb/src/Writer/PHP.php on line 89

[...]

Fatal Error: Uncaught exception 'Cdb\Exception' with message 'Error writing to CDB file '/tmp/l10n_cache-en.cdb.tmp.1665604027'.' in .../vendor/wikimedia/cdb/src/Writer/PHP.php:239
Stack trace:
#0 .../vendor/wikimedia/cdb/src/Writer/PHP.php(102): Cdb\Writer\PHP->throwException('Error writing t...')
#1 .../vendor/wikimedia/cdb/src/Writer/PHP.php(215): Cdb\Writer\PHP->write('\x00\f\xD1\xB6\xB6\xC1\x02\x00')
#2 .../vendor/wikimedia/cdb/src/Writer/PHP.php(82): Cdb\Writer\PHP->finish()
#3 .../vendor/wikimedia/cdb/src/Writer.php(88): Cdb\Writer\PHP->close()
#4 [internal function]: Cdb\Writer->__destruct()
#5 {main}
  thrown in <b>.../vendor/wikimedia/cdb/src/Writer/PHP.php</b> on line <b>239</b><br />

We could perhaps mitigate this creating a subdirectory mw-<random value> in wfTempDir().

Dereckson updated the task description. (Show Details)
Dereckson raised the priority of this task from to High.
Dereckson added a project: CDB.
Dereckson added a subscriber: Dereckson.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptFeb 16 2016, 10:43 PM

[ High priority, as this affects every wiki updated on a machine with different installations. Not Unbreak now! as this can be mitigated adding a manual $wgTmpDirectory setting to the configuration. ]

Restricted Application added projects: Multimedia, Commons. · View Herald TranscriptFeb 16 2016, 10:44 PM
Restricted Application added a subscriber: Steinsplitter. · View Herald Transcript
Restricted Application added a subscriber: Matanya. · View Herald TranscriptFeb 16 2016, 10:45 PM

If you're running a wiki-farm, why are you not setting $wgCacheDirectory to different directories for each wiki?

I don't think this is the file management you're looking for, this project is about the File: namespace files.

matmarex set Security to None.
matmarex removed a subscriber: matmarex.
Krinkle added a subscriber: Krinkle.

CDB project on Phabricator is about the library we maintain for interacting with CDB files. This isn't an issue with that library. It's an issue with how the internationalisation system (specifically, LocalisationCache) writes its temporary files (which happen to use CDB, but be sqlite or anything else).

In T127127, @Dereckson wrote:

If several MediaWiki installations run on the same machine, this means they will each update this cache

This seems like a configuration problem, not an issue with MediaWiki. If you run multiple MediaWiki installs on the same machine, each should have its own database (or unique table prefix), its own script path (or virtualhost wgServer), and its own temporary directory.

Wikimedia Foundation uses similar configuration on their servers for example. While WMF shares the same install with multiple wikis, WMF does have multiple installs (usually two around any given time, continuous deployment). Those two installs each have their own temp directory assigned in the configuration, like so:

// $IP is like "/srv/mediawiki/1.27.0-wmf.13"
$mwVersionName = basename( $IP );
$wgCacheDirectory = '/tmp/mw-cache-' . $mwGitBranchName;

If you're running a wiki-farm, why are you not setting $wgCacheDirectory to different directories for each wiki?

That's not the use case for this bug. On a wiki farm, there is a comprehensive directory structure, a careful design and test of the configuration.

The use case is servers used by independent users, shared hosting, etc. where there is no coordination among them and no centralized configuration like in a wiki farm.

There is here a cost/benefit analysis: it costs us fairly little to tweak our default settings to play nice in this scenario.

Nuclearsugar added a subscriber: Nuclearsugar.EditedJul 18 2016, 6:43 PM

I ran into exactly this issue since I’m on a shared web server and have multiple Mediawiki installations. I was upgrading from 1.24.0 to 1.27.0.

And I think it’s important to share that this bug report is the ONLY documentation that I can find which mentions the fix of setting a custom $wgTmpDirectory in the LocalSettings.php.

I wanted to share my experience since this isn’t the ideal place to be finding a solution to what I imagine is a very common problem. (I’m not a developer, I registered an account just to share this). Though I’m going to share my findings on the Manual Talk:Upgrading page, since the page itself is locked.

Nuclearsugar added a comment.EditedJul 18 2016, 8:31 PM

Also, is this a safe temporary fix? I'm not sure if there is any sensitive info that is stored in the system temp folder that is now instead publicly viewable. This documentation is all I can find on the matter.

$wgTmpDirectory = "$IP/images/temp";

Though I think this is a better technique since the files remain hidden. I believe this points to the same default temp folder, and then I simply dump the temp files into a unique sub-directory.

$wgTmpDirectory = "{$wgUploadDirectory}/tmp/uniquename";
Krinkle removed a subscriber: Krinkle.Jul 18 2016, 8:52 PM
Mbrt added a subscriber: Mbrt.Jan 23 2017, 4:54 AM

Hi all I've same bug, and how to repair them?

You need to set $wgTmpDirectory in each installation (to be a different directory for each one; otherwise they share the system-wide tmp dir).

Mbrt added a comment.Jan 24 2017, 6:23 AM

@Samwilson how to set in myLocalSetting.php can you explain to me and all user with command. Thanks before

@Mbrt: You need to set $wgTmpDirectory to something unique to your wiki. For example, add this at the end of your LocalSettings.php:

$wgTmpDirectory = "$IP/tmp";
Mbrt added a comment.Jan 24 2017, 8:58 AM

@Samwilson after I copypaste your code I geting error message " Sorry! This site is experiencing technical difficulties.
Try waiting a few minutes and reloading.
(Cannot access the database)" And how?

Make sure the tmp directory exists. Also, you can turn on debugging so it'll tell you more about what's actually going wrong.

Mbrt added a comment.Jan 24 2017, 9:05 AM

@Samwilson where create new directory tmp?

Mbrt added a comment.Jan 24 2017, 9:08 AM

@Samwilson I have directory tmp and contai l10n_cache-en.cdb and l10n_cache-id.cdb.

This task is not a general support forum. For generic "How to do...?" questions, please use the MediaWiki Support Desk instead. Thanks.

Seb35 added a subscriber: Seb35.Sep 25 2018, 8:13 PM

I’m not sure everybody speaks about the same configuration parameters here:

  • $wgCacheDirectory: should be configured per-wiki for various long-life cache file – currently mainly l10n_cache-XX.cdb and lessphp_XXX.lesscache – and defaults to false
  • $wgTmpDirectory: short-life files - this is now wfTempDir() redirecting to TempFSFile::getUsableTempDirectory() which now guarantee the temp directory is writable (else throw a RuntimeException)

From what I understand from the code, the CDB files were and are written in $wgCacheDirectory, or more specifically in $wgLocalisationCacheConf['storeDirectory'] which defaults in $wgCacheDirectory. Assuming the parameter $wgLocalisationCacheConf is not changed (this is quite advanced configuration), I’m only able to reproduce this issue by setting $wgCacheDirectory to "/tmp", but this seems to be a bad configuration if $wgCacheDirectory is documented as strictly per-wiki.

Consequently I do not understand if there is really an issue in the code, although there are probably issues in documentation.

Could anybody give more details about a problematic configuration triggering this issue? (values of $wgCacheDirectory and $wgTmpDirectory and $wgLocalisationCacheConf for those who are modified)

Seb35 added a comment.Sep 28 2018, 7:29 AM

I found the missing link I didn’t understand: between 1.27.0 and 1.27.2 the CDB caches were indeed either in $wgCacheDirectory if set else in wfTempDir() after rMW36171312ef0e1. In 1.27.2 the security task T161453 was fixed and wfTempDir() was no more the fallback if $wgCacheDirectory is not set - hence the database became again the fallback for localisation cache.

This task is a duplicate of T161453.