Bestimmen der LVM-Extent-Nummern für eine bestimmte Datei

9

Ich bin derzeit mit einer nicht arbeitsbezogenen Hausaufgabe beschäftigt. Ich habe ein ext4-Dateisystem auf einem logischen Volume. Ich teste verschiedene Strategien zur Leistungsoptimierung und diese Idee kam mir in den Sinn. Da pvmove einzelne und Bereiche von Speicherbereichen verschieben kann, gibt es eine Möglichkeit, herauszufinden, welche physischen Speicherbereiche eine bestimmte Datei enthalten (theoretisch kann es sich um Sicherungsdateien für eine Datenbank oder eine große Dateifreigabe handeln, auf die häufig zugegriffen wird) und diese in einen bestimmten Bereich verschieben Speichergerät (zum Beispiel habe ich eine normale Festplatte und ein SSD-Laufwerk in derselben LVM-Volume-Gruppe)?

Ich dachte an die Verwendung von "filefrag", aber dann kam mir der Gedanke, dass ich nicht zu 100% davon überzeugt war, ob die Extent-Nummern notwendigerweise in sequenzieller Reihenfolge verwendet werden würden (daher ist es nicht unbedingt zulässig, zu wissen, wie viele Sektoren in ext4 eine Datei sehen Ich finde heraus, auf welchem ​​Umfang sich die Dateien physisch befinden.

Irgendwelche Ideen?

Bratchley
quelle

Antworten:

13

Die beiden Hauptbestandteile sind hdparm --fibmap file, die Ihnen sagen, wo sich die Datei physisch innerhalb des LV befindet, und lvs -o +seg_pe_ranges,vg_extent_sizedie Ihnen sagt, wo sich der LV physisch auf Ihren Geräten befindet.

Der Rest ist Mathe.

Also zum Beispiel:

# hdparm --fibmap linux-3.8.tar.bz2 

linux-3.8.tar.bz2:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0     288776     298511       9736
     4984832     298520     298623        104
     5038080     298640     298695         56
     5066752     298736     298799         64
     5099520     298824     298895         72
     [...]

Ich weiß nicht, warum dies so fragmentiert ist - mit wget heruntergeladen. Kann ein gutes Beispiel sein, denn wie Sie sehen, bekommen Sie Kopfschmerzen, ohne dies irgendwie zu skripten, zumindest für fragmentierte Dateien. Ich nehme nur das erste Segment 288776-298511 (9736 Sektoren). Die Zählung ist falsch, da es sich nicht um 512-Byte-Sektoren handelt, aber trotzdem.

Überprüfen Sie zunächst, ob diese Daten tatsächlich korrekt sind:

# dd if=linux-3.8.tar.bz2 bs=512 skip=0 count=9736 | md5sum
9736+0 records in
9736+0 records out
4984832 bytes (5.0 MB) copied, 0.0506548 s, 98.4 MB/s
7ac1bb05a8c95d10b97982b07aceafa3  -

# dd if=/dev/lvm/src bs=512 skip=288776 count=9736 | md5sum
9736+0 records in
9736+0 records out
4984832 bytes (5.0 MB) copied, 0.123292 s, 40.4 MB/s
7ac1bb05a8c95d10b97982b07aceafa3  -

Wheeee.Das ist identisch, also lesen wir den LV-src an der richtigen Stelle. Wo befindet sich nun die Quell-LV?

# lvs -o +seg_pe_ranges,vg_extent_size
  LV          VG   Attr      LSize   Pool Origin Data%  Move Log Copy%  Convert PE Ranges             Ext   

[...]
 src         lvm  -wi-ao---   4.00g                                            /dev/dm-1:5920-6047   32.00m
[...]

Das ist langweilig, diese LV ist nicht fragmentiert. Keine Kopfschmerzen hier. Wie auch immer.

Es heißt, src ist auf / dev / dm-1 und beginnt bei PE 5920 und endet bei PE 6047. Die PE-Größe beträgt 32 MiB.

Mal sehen, ob wir dasselbe aus / dev / dm-1 direkt lesen können. In mathematischer Hinsicht ist dies ein kleines Problem, da wir früher eine Blockgröße von 512 Byte verwendet haben ...: - / aber ich bin faul, also berechne ich einfach die MiB und dividiere dann durch 512! Ha! :-D

# dd if=/dev/dm-1 bs=512 skip=$((1024*1024/512 * 32 * 5920 + 288776)) count=9736 | md5sum
9736+0 records in
9736+0 records out
4984832 bytes (5.0 MB) copied, 0.0884709 s, 56.3 MB/s
3858a4cd75b1cf6f52ae2d403b94a685  -

Boo-Boo. Das ist nicht das, wonach wir suchen. Was schief gelaufen ist? Ah! Wir haben vergessen, den Offset hinzuzufügen, der von LVM zu Beginn eines PV zum Speichern von LVM-Metadaten und Mist belegt wird. Normalerweise ist dies MiB-ausgerichtet, fügen Sie also einfach ein weiteres MiB hinzu:

# dd if=/dev/dm-1 bs=512 skip=$((1024*1024/512 * 32 * 5920 + 288776 + 1024*1024/512)) count=9736 | md5sum
9736+0 records in
9736+0 records out
4984832 bytes (5.0 MB) copied, 0.0107592 s, 463 MB/s
7ac1bb05a8c95d10b97982b07aceafa3  -

Hier hast du es.

Frostschutz
quelle
3
Eines Tages werden sie zu Ihrer Ehre Statuen bauen.
Bratchley
Eine Sache, eine Idee, warum mein hdparm-Aufruf segfaulting ist ?
Bratchley
Eigentlich sieht es so aus, als müsste ich mein Google-Fu verbessern . Es ist ein neuer RHEL-Fehler in Bezug auf SSDs und LVM. Ich verstehe das so, dass sich die Datei bereits auf der SSD befindet. Ha
Bratchley
Gibt es ein anderes Dienstprogramm, um die Position der Datei im LV zu bestimmen, bis sie dies behebt?
Bratchley
Du hast es schon erwähnt - filefrag. Andernfalls googeln Sie, wenn ein anderes Tool Fibmap oder Fiemap ausführt.
Frostschutz