This document describes MinIO's metadata management system, which ensures consistent and efficient storage and retrieval of object metadata across a distributed erasure-coded storage cluster. It covers the xl.meta file format (xlMetaV2), version management, inline data storage, the metacache system for list optimization, and metadata quorum resolution. For information about the storage layer that persists these structures, see Storage Layer Architecture. For details about the erasure coding that distributes metadata across disks, see Erasure Coding Engine.
Sources: cmd/xl-storage.go1-2358 cmd/xl-storage-format-v2.go1-2522 cmd/metacache-set.go1-1319
MinIO stores all object metadata in files named xl.meta located alongside object data. The xlMetaV2 format is a versioned, binary format that supports multiple object versions, delete markers, and inline data storage.
Sources: cmd/xl-storage-format-v2.go42-103 cmd/xl-storage-format-v2.go148-187
The file begins with an 8-byte header containing the magic bytes 'X', 'L', '2', ' ' followed by a 4-byte version number encoded as little-endian [major:2, minor:2]. The current version is 1.3. After the header, the payload is encoded using MessagePack (msgpack) format.
| Component | Description | Location |
|---|---|---|
xlHeader | Magic bytes identifying XL format | First 4 bytes |
xlVersionCurrent | Major and minor version (1.3) | Bytes 4-8 |
| Payload | Msgpack-encoded metadata | Bytes 8+ |
Sources: cmd/xl-storage-format-v2.go42-71 cmd/xl-storage-format-v2.go219-241
The core of xlMetaV2 is the version journal - an array that stores all versions of an object. Each entry represents either an object version, a delete marker, or a legacy object from the xlV1 format.
Sources: cmd/xl-storage-format-v2.go105-187 cmd/xl-storage-format-v2.go149-175
The xlMetaV2Version struct is a discriminated union where the Type field determines which of the three optional fields is populated:
xlMetaV2Object with full object metadata including erasure coding parameters, part information, size, modification time, and user/system metadata.xlMetaV2DeleteMarker representing a delete marker with version ID and modification time.xlMetaV1Object for backward compatibility with the previous format.Sources: cmd/xl-storage-format-v2.go181-187
Each version can be efficiently represented by a compact header for operations that don't require full metadata:
Sources: cmd/xl-storage-format-v2.go248-267 cmd/xl-storage-format-v2.go189-217
The flags field provides quick information about version characteristics:
Sources: cmd/xl-storage-format-v2.go189-217
For small files (typically under 128 KiB), MinIO can store the actual object data directly within the xl.meta file instead of creating separate data files. This reduces the number of disk operations and improves performance for small objects.
Sources: cmd/xl-storage.go59-73 cmd/xl-storage-format-v2.go384-401
The smallFileThreshold constant defines the size boundary (128 KiB optimized for NVMe/SSDs). When data is inlined, it's stored in the data map of the xlMetaV2 structure, keyed by version ID. The flag xlFlagInlineData is set in the version header to indicate this optimization.
Sources: cmd/xl-storage.go59-73
MinIO maintains a complete version history for objects in versioned buckets. The version journal in xl.meta stores versions in most-recent-first order.
Sources: cmd/xl-storage-format-v2.go73-103 cmd/xl-storage-format-v2.go384-387
The version array maintains three types of entries:
Sources: cmd/xl-storage-format-v2.go85-88
The xlMetaV2 structure provides methods for managing versions:
| Operation | Method | Description |
|---|---|---|
| Add Version | AddVersion() | Appends a new version to the journal |
| Delete Version | DeleteVersion() | Removes or marks a version as deleted |
| Get Latest | ToFileInfo() | Retrieves the most recent version |
| List Versions | ListVersions() | Returns all non-free versions |
| Free Versions | FreeVersions | Separate array for cleanup tracking |
Sources: cmd/xl-storage-format-v2.go445-461
Each version has a signature used to verify consistency across disks in the erasure set:
Sources: cmd/xl-storage-format-v2.go405-416 cmd/xl-storage-format-v2.go269-285
The signature is a 4-byte hash that uniquely identifies a version's content and metadata. During read operations, signatures are compared across disks to detect inconsistencies. The matchesNotStrict() method allows some flexibility in matching (e.g., ignoring signature differences but requiring version ID and type to match) which is useful during healing operations.
Sources: cmd/xl-storage-format-v2.go269-278
In an erasure-coded environment, xl.meta files exist on multiple disks within an erasure set. MinIO must reconcile potentially divergent metadata copies to determine the authoritative version.
Diagram: Metadata Quorum Resolution Flow
Sources: cmd/erasure-object.go1-66 cmd/xl-storage-format-v2.go248-285 cmd/xl-storage-format-v2.go357-382 cmd/xl-storage-format-v2.go445-461 cmd/metacache-entries.go69-157
The quorum resolution algorithm:
xlMetaV2VersionHeader from each xl.meta containing version ID, signature, modification time, and flagsSources: cmd/xl-storage-format-v2.go258-267 cmd/xl-storage-format-v2.go269-285
The xlMetaV2VersionHeader provides a compact representation for comparison:
Sources: cmd/xl-storage-format-v2.go269-321
Matching modes:
sortsBefore() selects based on newest modtime, then consistent ordering by signature and version IDSources: cmd/xl-storage-format-v2.go269-321
Diagram: Quorum-Based Read Methods
Sources: cmd/xl-storage.go489-527 cmd/xl-storage.go1288-1361
Key reading methods:
readMetadata(): Reads xl.meta with a context deadline, returns raw bytes from a single diskreadMetadataWithDMTime(): Additionally returns the file's modification time for cache validationReadVersion(): Decodes xl.meta and returns a specific version as FileInfo from a single diskReadXL(): Returns raw xl.meta content with minimal processing from a single diskgetObjectFileInfo(): Higher-level erasure layer method that reads from multiple disks and applies quorum resolutionSources: cmd/xl-storage.go522-527 cmd/xl-storage.go489-520
Metadata writes must achieve write quorum (N/2 + 1 disks) to be considered successful:
Diagram: Metadata Write with Quorum
Sources: cmd/xl-storage.go1086-1184 cmd/storage-datatypes.go32-41
Write operations follow these steps:
LoadOrConvert()For DeleteVersion(), if the version's DataDir is specified, it also removes the associated data directory after updating xl.meta. The erasure layer ensures that version deletions are coordinated across all disks with appropriate quorum checks.
Sources: cmd/xl-storage.go1086-1184 cmd/storage-rest-server.go435-458
| Operation | Read Quorum | Write Quorum | Notes |
|---|---|---|---|
| GetObject | N/2 | - | Must read consistent metadata from majority |
| PutObject | - | N/2 + 1 | Must write to majority before success |
| DeleteObject | N/2 | N/2 + 1 | Read to find version, write to mark deleted |
| ListObjects | 1 (per disk) | - | Uses metacache, eventual consistency |
| HeadObject | N/2 | - | Same as GetObject for metadata |
Sources: cmd/erasure.go1-66 cmd/xl-storage.go1086-1184
Diagram: Storage Layer Caching Strategy
Sources: cmd/xl-storage.go115-130 cmd/xl-storage.go771-781
The storage layer intentionally avoids caching xl.meta content because:
The only cached values at the storage layer are:
diskInfoCache: Caches disk information for 1 second to avoid repeated syscalls in DiskInfo() methodGetDiskID() to validate requestsSources: cmd/xl-storage.go115-117 cmd/xl-storage.go820-897 cmd/xl-storage-disk-id-check.go289-341
The metacache system is a specialized caching layer designed to optimize expensive directory listing operations (ListObjects, ListObjectsV2). It creates compressed, indexed snapshots of directory structures that can be efficiently streamed to clients.
Sources: cmd/metacache-manager.go27-72 cmd/metacache.go30-75
The metacache system consists of:
localMetacacheMgr: Global singleton that manages all cachesmetacacheBucket: Per-bucket cache storage, managing multiple cache entriesmetacache: Individual cache entry with lifecycle state (started, success, error).minio.sys/buckets/<bucket>/.metacache/<id>/Sources: cmd/metacache-manager.go32-55 cmd/metacache-bucket.go26-60
Each metacache entry stores metadata about a listing operation and the associated cached data:
Sources: cmd/metacache.go30-75 cmd/metacache-set.go336-345
The cache stores data in S2-compressed blocks (Snappy variant) at paths like .minio.sys/buckets/<bucket>/.metacache/<id>/block-N.s2. Each block contains a sequential portion of the directory listing, allowing streaming reads without loading the entire listing into memory.
Sources: cmd/metacache-set.go343-345
Sources: cmd/metacache.go77-98 cmd/metacache-set.go148-164
Cache lifecycle states:
A cache entry in the scanStateSuccess state can serve multiple concurrent ListObjects requests by streaming from the stored blocks. The cache remains valid until:
Sources: cmd/metacache.go77-98
When a ListObjects request is received, the system determines whether to use an existing cache or create a new one:
Diagram: Cache Decision Flow with Function Names
Sources: cmd/metacache-server-pool.go60-159 cmd/metacache-set.go271-316 cmd/metacache-set.go369-416 cmd/metacache-set.go418-609 cmd/metacache-stream.go94-126
Key operations:
metacacheBucket.findCache() locates a compatible cache based on bucket, prefix, and recursive flaglistPathOptions.findFirstPart() locates the first cache block containing entries >= the markererasureObjects.streamMetadataParts() reads blocks sequentially, decompressing and filtering entriesmetacacheReader.filter() applies prefix, delimiter, and limit constraints to cached entrieserasureServerPools.listAndSave() creates new cache by calling xlStorage.WalkDir() on each diskSources: cmd/metacache-set.go271-316 cmd/metacache-set.go369-416 cmd/metacache-set.go418-609 cmd/metacache-walk.go73-455
The metacache system must invalidate caches when underlying data changes:
Sources: cmd/metacache-bucket.go146-185 cmd/metacache-bucket.go187-215
Invalidation mechanisms:
Sources: cmd/metacache-bucket.go187-215
Entries in metacache blocks use a specialized compact format:
Sources: cmd/metacache-entries.go32-60
The metaCacheEntry structure represents:
name ends with / and metadata is emptyname is the full path and metadata contains xl.meta content/ (explicitly created with trailing slash)The cached field optionally holds a decoded xlMetaV2 structure to avoid repeated decoding. The reusable flag indicates whether the metadata buffer can be reused (single reference) or must be copied.
Sources: cmd/metacache-entries.go32-45
The metacache system provides significant performance benefits:
| Operation | Without Cache | With Cache |
|---|---|---|
| First ListObjects | O(N) disk walk | O(N) disk walk + write cache |
| Subsequent ListObjects | O(N) disk walk | O(K) cache read (K = results returned) |
| Paginated listing | O(N) per page | O(K) per page, resume from marker |
| Concurrent listings | N × O(N) | N × O(K) + single cache creation |
Sources: cmd/metacache-set.go703-767
The streaming design allows handling arbitrarily large directories without excessive memory consumption, as only the current block (typically 4-32 MB compressed) needs to be in memory at once.
Sources: cmd/metacache-stream.go94-126
Sources: cmd/xl-storage.go1-2358 cmd/xl-storage-format-v2.go1-2522 cmd/metacache-set.go1-1319 cmd/metacache-walk.go1-455 cmd/metacache-entries.go1-735 cmd/metacache-bucket.go1-277 cmd/metacache-manager.go1-178 cmd/metacache.go1-256 cmd/metacache-stream.go1-764
Refresh this wiki