noqqe


blog | sammelsurium | projects | about

Das Ext4 Directory Indexing

Mit ext4 kam unter anderem ein Feature hinzu, welches sich Directory Indexing nennt. Es ist dazu gedacht in Verzeichnissen mit vielen Dateien eine Art Map anzulegen an welchen Inodes welche Files liegen und kommt erst ab Fileanzahl X pro Directory automatisch dazu. Ziel der Entwickler war natürlich Performance Gewinn.

Allerdings kauft man mit diesem Feature auch eine zusätzliche Limitierung mit ein, bei der ich mich schwer tat wirklich (aufgrund in meiner Wahrnehmung mangelnder Berichte und Doku) das Problem zu debuggen.

Die Limitierung bei vielen Files sind in den meisten Fällen erstmal die Inodes der Platte. Ist die Platte aber ausreichend groß (oder die Inodes ausreichend klein) kommt hier das Directory Indexing ins Spiel:

EXT4-fs warning (device /dev/sdd): ext4_dx_add_entry: Directory index full!

rsyncs bzw. Schreibende Zugriffe in das Verzeichnis brechen ab und im dmesg findet man obige Meldung. Problem dabei: In dem Directory Index sind so viele Files gelistet, dass in dem (wahrscheinlich FS designtechnisch limitierten, korrigiert mich bitte) Hashmap Block kein Platz mehr ist. Es können schlicht und ergreifend keine neuen Einträge hinzugefügt werden.

Was jetzt?

Längeres wälzen von Dokumentation lässt sich nicht vermeiden.

A linear array of directory entries isn’t great for performance, so a new feature was added to ext3 to provide a faster (but peculiar) balanced tree keyed off a hash of the directory entry name. If the EXT4_INDEX_FL (0x1000) flag is set in the inode, this directory uses a hashed btree (htree) to organize and find directory entries.

Oder auch andere schaurige Threads aus Mailinglisten:

http://www.mail-archive.com/cwelug@googlegroups.com/msg01937.html

Mit debugfs lassen sich die Informationen des Filesystems auszulesen, die einen interessieren. Basic Problematik ist einfach, welches Verzeichnis ist betroffen, wie konnte das passieren und wie bekomme ich es wieder heile.

$ cd /var/
$ debugfs
debugfs> open /dev/sdd1
debugfs> cd log/
debugfs> htree .
[...]
Number of Entries (count): 508
Number of Entries (limit): 508
[...]

htree listet die Indexes in dem Ordner und Informationen zum hashed B-Tree. Die Limit und Count Values sprechen denke ich für sich.

Okay. Problem gefunden. Wie beheb ich es?

Man baut den Directory Index neu auf, wobei der alte Dir Index prinzipiell behalten wird und der Neue an der letzten Stelle auf den weiteren Index referenziert.

fsck.ext4 -yfD /dev/sdd1

Dazu ist ein unmounten zwingend erforderlich, was bei produktiven Systemen unschön ist. Oder man löscht das Verzeichnis.

Wie sich später herausgestellt hat war die Ursache davon ein nicht korrekt funktionierendes Logrotate welches ca 8 Mio. Files produziert hat. Das Löschen hat auch nur ca. 10 Tage gedauert. Nur so am Rande.

Irritiert.

Zum Abschluss muss ich sagen bin ich etwas.. irritiert. Man schafft ein Feature, dass dann einspringt wenn es viele Files werden (bei meinen Tests ab 300.000 Files), welches dann später wegen diesen vielen Files zu fehlern führt. In dem Bereich dazwischen ist das eventuell wirklich nett zu haben, weil Perfomance. Aber dass ich den “Referenzakt” nicht anstossen kann während das FS gemountet ist finde ich dann speziell für den HA Betrieb von Servern … fragwürdig.

Klar es ist in keinem Fall eine gute Idee mehr als 2 Mio. files in ein Verzeichnis zu legen, aber hey.

Wirklich gestört hat mich eher das mangelhaft Dokumentierte Vorgehen dafür. Seitens Entwickler, seitens Community. Aber deswegen hab ich ja jetzt diesen Post verfasst.

Comments (10)

Ice Polar on 2012-03-09T19:45:48
 Mir persöhnlich gefallen solche Hintergrundinformationen ganz besonders, denn sie zeigen auf, was unter der Oberfläche alles passiert. Die Systeme heutzutage sind derart komplex, so dass sich keiner mehr wirklich im Klaren darüber ist, worauf er sich da unter Umständen verlässt... Und so ein Filesystem ist doch immer wieder eine grundlegende Funktion, die man einfach mal so benutzt also ob das die einfachste Sache der Welt wäre.

noqqe on 2012-03-09T20:09:29
 Geb ich dir Recht. War auch interessant zum Debuggen. Hat Spaß gemacht.

sebix on 2012-03-12T20:14:40
 debugfs ist als root auszuführen nicht als normaler User

noqqe on 2012-03-12T20:17:59
 Ich nehme an du machst das an dem Prefix $ fest, dass ich als Identifier für Shell Commands verwende, # für Kommentare. Das ist jedenfalls ein Trugschluss :)

sebix on 2012-03-13T12:34:27
Du hast vollkommen recht ;)

Ice Polar on 2012-03-14T21:59:02
Ob jemand einmal etwas zu den Unterschieden zwischen ext4 und dem neuen MS REFS ( "Resilient File System") sagen kann? 

Datenbank archINFORM on 2012-03-20T08:11:41
Hi Florian, Hatte gerade das gleiche Problem beim zwischencache eines webservers und war auch erstmal ziemlich ratlos, da noch genügend Inodes und Plattenplatz zur Verfügung standen. "Man schafft ein Feature, dass dann einspringt wenn es viele Files werden (bei meinen Tests ab 300.000 Files), welches dann später wegen diesen vielen Files zu fehlern führt." gut auf den Punkt gebracht! ;) Mich würde ja jetzt ziemlich interessieren, wie sich denn nun die maximale Anzahl Files pro Directory bei gegebener Blockgröße, etc. berechnen lässt. Wirklich ein ziemliches Loch in der offiz. Doku. Diese Info ist ja bei entsprechenden Anforderungen schon bei der Einrichtung der Partition (Blockgröße/Inodeanzahl) essentiell. Gruß, Sascha 

noqqe on 2012-03-22T18:10:37
 Jap. Also in den Test-Cases habe ich immer ne max Limit Count von 508 gefunden. Wie man das ext4 formatieren muss um da mehr zu erreichen würde mich auch interessieren... Wahrscheinilch ists aber statisch..

Daniii on 2014-07-31T08:57:42.091639
Toller Artikel!!! hat mir sehr geholfen... haben uns dagegen entschieden den index einzusetzen :-)

Anonymous on 2015-10-14T12:06:16.745945
Danke für den Blogbeitrag! Der war ebenfalls einer der Gründe, wodurch ich auf das Feature von ext4 verzichtet habe.