Wiki source code of The Attachment Store

Last modified by Eleni Cojocariu on 2026/09/18 15:29

Hide last authors
Eleni Cojocariu 2.1 1 Whatever store holds the content of an attachment, its metadata stays in the database: a row of ##xwikiattachment## while the attachment is there, a row of ##xwikiattrecyclebin## once it is deleted. That row also records the store holding **that** attachment's content, so two attachments of the same Page can sit in different stores. The store configured on a wiki is therefore the one the next attachment saved will use, not the one every attachment uses, and changing it leaves the files already stored exactly where they are.
2
3 {{version since="17.10.0RC1"}}The file-based stores no longer write to the filesystem themselves. They write through a blob store, whose type decides where the files finally land; [[Blob Store>>doc:documentation.xs.admin.store.blob.WebHome]] documents it and the S3 alternative.{{/version}}
4
5 |=|=Filesystem store|=Database store
6 |Default for a new wiki|Since XWiki 10.5|Until XWiki 10.5
7 |Where the content is|Files under the [[permanent directory>>doc:documentation.xs.admin.configuration.directories.permanent-directory.WebHome]]|Three tables of the wiki database
8 |Largest attachment|Over a gigabyte|About 30 MB
9 |To back up|The database and the directory, in step|The database alone
10
11 == The filesystem attachment store ==
12
13 The filesystem store keeps the content of each attachment as a file, and [[Optional Store Features>>doc:documentation.xs.admin.store.optional-features.WebHome]] is where that choice and the other store hints are made. Keeping the content out of the database has three consequences:
14
15 * a dump of the database is no longer a complete copy of the wiki: the files have to be saved with it, and restoring one without the other leaves attachments that are listed but cannot be downloaded, or files no Page points at;
16 * an attachment may be larger than a gigabyte, which the database store cannot hold;
17 * saving one is a two-stage commit, so the file on disk and the row in the database stay consistent even when the database fails to commit the attachment metadata.
18
19 [[Sub-Directories in the Permanent Directory>>doc:documentation.xs.admin.configuration.directories.permanent-directory.sub-directories.WebHome]] says which sub-directory holds them, and how to move that one sub-directory elsewhere.
20
21 Every node of a cluster needs to see the same storage directory, mounted over NFS or by any other means of giving each node the same disk. Give each node a directory of its own and an attachment ends up readable only on the node that happened to receive it.
22
23 XWiki removes empty directories as it deletes files, and ##store.fsattach.cleanOnStartup## in ##xwiki.properties##, ##true## by default, sweeps the whole tree again at startup as a safeguard for the rare cases where that fails. Set it to ##false## if the sweep costs too much on a large store.
24
25 === The format on disk ===
26
27 The tree follows the entities it stores, a wiki holding Pages holding attachments, except that each name is replaced by its MD5 hash, split into a one-character directory, a second one, and the thirty characters left:
28
29 {{code language="none"}}
30 <wiki>/<hash of the Page reference>/attachments/<hash of the attachment name>/<file>
31 {{/code}}
32
33 Hashing keeps the paths short and free of the characters that filesystems restrictive about encoding or path length handle badly. A Page carrying one attachment, ##team-photo.jpg##, saved once, is stored like this:
34
35 {{code language="none"}}
36 xwiki/0/e/8da809e5683e667d5b771cf3b3a508/ the Page
37 attachments/
38 e/d/9f721f27c98900522d4353e958307b/ the attachment
39 fv1.1.jpg the content of version 1.1
40 f.jpg.lnk the current content, a link to fv1.1.jpg
41 ~METADATA.xml the list of stored versions
42 {{/code}}
43
44 A stored version is named ##fv##, then the version number, then the extension of the attachment. The current content is the same name without the version number, ##f.jpg## here, and when it would be identical to a stored version, which is the usual case, XWiki writes a one-line link file pointing at that version rather than a second copy of the file. Deleted attachments are kept beside the live ones, in a ##deleted-attachments## directory of the same Page; [[Deleted Attachments and the Recycle Bin>>doc:documentation.xs.admin.attachments.deleted-attachments.WebHome]] covers what becomes of them.
45
46 == The database attachment store ==
47
48 This was the default until the filesystem store took over, so a wiki upgraded from an older version may still be on it without anyone having chosen it. It keeps the content in three tables beside the metadata: ##xwikiattachment_content## for the current content of each attachment, ##xwikiattachment_archive## for its older versions, and ##xwikiattrecyclebin## for what the attachment recycle bin holds.
49
50 What it costs is size. An attachment is read and written with its content and its whole archive held in memory, so as a rule of thumb one larger than 30 MB is not possible, which is what makes the filesystem store the better default.
51
52 [[Switch to the Database Attachment Store>>doc:documentation.xs.admin.store.attachment-store.switch-database-store.WebHome]] is the procedure.

Get Connected