syslog - EXT3-fs warning

schumiel

New Member
Hallo,

was sagt das aus?
Was genau muss ich hier tun, damit dieser Meldung nicht mehr erscheint?
Und hat sie negativen Einfluss?

Mar 29 13:57:56 ... kernel: [28189319.959698] EXT3-fs warning (device md1): ext3_dx_add_entry: Directory index full!
 
Das hatte ich bereits vor diesen Beitrag schon gemacht. Leider hat mir nichts davon weitergeholfen, das aber sicherlich an meinen bescheidenen Englischkenntnissen liegt. :(
 
Was genau muss ich hier tun, damit dieser Meldung nicht mehr erscheint?

Backup deiner Daten erstellen, Rescue-System starten, fsck ausführen.

Generell solltest du eigentlich immer ein funktionierendes und konsistentes Backup haben.

Ursachen kann es mehrere geben: Bspw. korruptes Dateisystem oder mehr als 31998 Sub-Folder unterhalb eines Verzeichnisses.
 
#09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete
Habe ich seit 3 Jahren deaktiviert und der Ordner ist vollgelaufen. Es scheint, dass das die Ursache des Fehlers ist. Da meine Seiten monatl. mind. 5 Mio. Seitenzugriffe haben, sind hier 5 * 12 * 3 = 180 Mio. Dateien drin. Aktiviere ich den zitierten Quote, überlagern sich die Ausführung, weil dies Stunden dauert. Habe es sogar nur einmal gestartet und war selbst über Nacht, also nach 12 Stunde immer noch nicht fertig. Mein Server lahmte in dieser Zeit. Der Ordner ist mit "ls" leider nicht einsehbar, weil das Anzeigen der Dateien auch viele Stunden dauert, ohne Erfolg auf ein Ergebnis.

Hat denn jemand ein Tipp für mich, wie ich die 180 Mio. Dateien gelöscht bekomme?
 
Quick+Dirty als c-Programm:

Braucht aber viel Hauptspeicher.

Löscht Dateien die auf sess_* lauten.

Ist ursprünglich nicht von mir, Quelle weiss ich aber leider nicht mehr.

Verwendung auf eigene Gefahr.

Code:
/* I can be compiled with the command "gcc -o dentls dentls.c" */

#define _GNU_SOURCE
#include <dirent.h>     /* Defines DT_* constants */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <string.h>


struct linux_dirent {
        long           d_ino;
        off_t          d_off;
        unsigned short d_reclen;
        char           d_name[256];
        char           d_type;
};

int main(const int argc, const char** argv) {
    int totalfiles = 0;
    int dirfd = -1;
    int offset = 0;
    int bufcount = 0;
    void *buffer = NULL;
    char *d_type;
    struct linux_dirent *dent = NULL;
    struct stat dstat;

    /* Test we have a directory path */
    if (argc < 2) {
        fprintf(stderr, "You must supply a valid directory path.\n");
        exit(1);
    }

    const char *path = argv[1];

    /* Standard sanity checking stuff */
    if (access(path, R_OK) < 0) {
        perror("Could not access directory");
        exit(1);
    }

    if (lstat(path, &dstat) < 0) {
        perror("Unable to lstat path");
        exit(1);
    }

    if (!S_ISDIR(dstat.st_mode)) {
        fprintf(stderr, "The path %s is not a directory.\n", path);
        exit(1);
    }

    /* Allocate a buffer of equal size to the directory to store dents */
    if ((buffer = malloc(dstat.st_size+10240)) == NULL) {
        perror("malloc failed");
        exit(1);
    }

    /* Open the directory */
    if ((dirfd = open(path, O_RDONLY)) < 0) {
        perror("Open error");
        exit(1);
    }

    /* Switch directories */
    fchdir(dirfd);

    while (bufcount = syscall(SYS_getdents, dirfd, buffer, dstat.st_size+10240)) {
        offset = 0;
        dent = buffer;
        while (offset < bufcount) {
            /* Dont print thisdir and parent dir */
            if (!((strcmp(".",dent->d_name) == 0) || (strcmp("..",dent->d_name) == 0))) {
                d_type = (char *)dent + dent->d_reclen-1;
                /* Only print files */
                if (*d_type == DT_REG) {
//                    printf("%s\n", dent->d_name);
                    /* For deleting files, uncomment me */
                    if(strstr(dent->d_name, "sess_"))
                    {   
                        if (unlink(dent->d_name) < 0) {
                        perror("unlink");
                        }
                        else {
//                          printf("deleted %s\n", dent->d_name);
                        }
                    }
                }
            }
            totalfiles++;
            offset += dent->d_reclen;
            dent = buffer + offset;
        }
    }
    fprintf(stderr, "Total files: %d\n", totalfiles);

    close(dirfd);

}
 
Ich würde folgenden Befehl in einer Screen Session starten:

Code:
find /var/lib/php5/ -type f -cmin +1 | xargs -n5000 -P5 rm -f

ein einzelnes rm würde scheitern, da die Anzahl der Dateien zu groß ist.

Quelle: Ich verweise hier auch gerne auf die Antwort von Firewire2002 aus diesem Thema.
 
Last edited by a moderator:
Ganz vergessen ...
Code:
find /var/lib/php5/ -type f -cmin +1 | xargs -n5000 -P5 rm -f
... wurde ebenso schon durchgeführt. Habe ich auch nach ca. 11 Std. abgebrochen, weil der Prozess auch mein Server erlahmte und die syslog weiterhin die Fehlermeldungen auflistete.
 
Dort ist die Rede von 8 Mio. Dateien, die wenn ich das richtig übersetzt hat, diese in 4 Stunden löscht. Bei mir sind es aber 180 Mio.
Und wie wirkt sich das auf die Auslastung des Servers aus?
 
Würde es denn was bringen, den Ordner /var/lib/php5 in /var/lib/php5_old umzubenennen und einen neuen Ordner "php5" zu erstellen?

So könnte ich den cronjob aktivieren und das Löschen würde vielleicht schneller gehen, weil im php5_old nicht neue Dateien dazu kommen würden?
 
Ist /var ein eigenes Dateisystem? Evtl. könntest Du den Rest von var auf ein neues Dateisystem kopieren und dein altes var danach einfach löschen.

Du solltest vielleicht auch mal mit
Code:
df -i
schauen (abschätzen), wie viele Dateien es wirklich sind, die 180 Millionen bezweifle ich etwas. Das müsste schon ein ziemlich großes Dateisystem oder eine enorme inode-Dichte sein.

Deine Idee mit dem umbenennen und neuanlegen könnte funktionieren.

viel Erfolg,
Nils
 
Danke für deine Antworten.

Wäre denn ein Ordner löschen schneller, als Dateien löschen?

rm /var/lib/php5
schneller als
rm /var/lib/php5/*
?

Ich müsste aber bestimmt den apache2 stoppen oder?

Ob es nun 180 Mio. Dateien sind, weiß ich selbst nicht. Alle Versuche dies abzufragen endet ergebnislos, weil der Prozess selbst nach 12 Stunden noch danach zählt. Ich kann es mir also nur aus den Seitenzugriffen errechnen.
 
Back
Top