Thomas Kramer

IT-COW | Juli 2016

Neuer Server und Backup

By Administrator at Juli 20, 2016 21:41
Filed Under: Administration

Ich habe meinen alten Fujitsu Scaleo 2205-Server, der vorwiegend als Fileserver diente, nun durch einen HP Microserver Gen8 ausgetauscht. Der Server arbeitet in der Basisausstattung mit einem Celeron G1610T, allerdings aufgerüstet auf 12 GB RAM. Im Gegensatz zum Scaleo-Prozessor Pentium E2220 ist der neue Celeron G1610T VT-X fähig, kann also 64-Bit-VMs laufen lassen - eine Eigenschaft die ich bei meinen Studiumsprojekten damals sehr vermisst habe, da Microsoft seine Serversoftware nur noch als 64-Bit-Versionen zur Verfügung stellt. Auch die Fähigkeit zu USB3.0 finde ich bei einem Fileserver durchaus wichtig, mit USB2-Geschwindigkeiten will man sich heute nicht mehr wirklich abgeben.

 

Als Betriebssystem dient nun ein Windows Server 2012. Mit einer SSD (im ODD-Schacht), drei internen Festplatten und einer externen USB3.0-Festplatte (Altbestand) liegt der Stromverbrauch nun bei ca. 47 Watt ohne Auslastung. Das Gerät hat drei Gigabit-Netzwerkanschlüsse, einer davon ist für HPs eigene Managementsoftware gedacht, die anderen zwei Ports können in Server 2012 zusammengeschaltet werden. Das habe ich getestet, konnte aber keinen praktischen Nutzen feststellen da die Transfergeschwindigkeit in einem Gigabit-Netzwerk immer noch bei ca 110 MB/Sec liegt – natürlich limitiert hier die häusliche Infrastruktur, welche eben auf 1 Gigabit-Switches fußt. Theoretisch müsste dieser Server durch die Zusammenschaltung der Netzwerkanschlüsse aber 2 Gigabit/Sec erreichen können. Praktisch gesehen ist dieser Server durch die Auslastung des Gigabit-Netzwerkes immer noch weit schneller als mein vorheriger Server.

 

Ich kann diesen Server nur weiterempfehlen. Für knapp 200 Euro gibt es nichts besseres, schon Festplatten-Leergehäuse mit vier Slots kosten mindestens 100 Euro - dieser Server ist dagegen vollständig, bis auf die fehlenden Datenträger. NAS-Systeme in der gleichen Preisklasse haben nur 2 Slots und sind vom Prozessor und RAM her schlechter ausgestattet – dafür beinhalten NAS-Systeme aber bereits ein Betriebssystem, während der Microserver ohne daherkommt. Es gibt aber natürlich auch kostenlose NAS-Betriebssysteme wie OpenMediaVault und FreeNAS, welche man auch auf dem Microserver aufspielen könnte. Oder ein Ubuntu Server-System.

 

Installiert sind auf diesem Server natürlich auch Oracle XE, MySQL, APEX 5.0, Subversion und hMailServer, im Gegensatz zu diesem Server-Projekt aber bin ich dazu übergegangen PHP, Tiny Tiny RSS und DokuWiki lokal unter dem Windows-eigenen IIS statt unter Apache in einer Linux-VM laufen zu lassen, insbesondere weil mir die Geschwindigkeit in der VM damals doch zu langsam war. Bislang erfüllt der Server alle meine Ansprüche, Paravirtualisierung durch VMWare ESXi oder XenServer vermisse ich nicht, Hyper-V würde mir bei VMs wahrscheinlich reichen. Viele rüsten die CPU bei diesem Server auf, aber dazu sehe ich keinerlei Notwendigkeit.

 

Auf ein RAID-System habe ich weiterhin bewusst verzichtet, weil ein RAID die Kosten erhöht und trotzdem kein Backup ersetzt; Hochverfügbarkeit braucht im privaten Bereich zudem kaum jemand wirklich. Ohne RAID kann ich im Falle eines Falles zudem zumindest Datenrettungstools wie in diesem Blog-Beitrag benutzen. Falls jemand trotzdem Laufwerke für das Videostreaming, z. B. von DVBViewer-TV-Aufnahmen, zusammenschalten und über Kodi-Clients ansprechen möchte, kann er folgende Tricks benutzen:

 

1. Netzwerkfreigaben mit verlinkten Laufwerken als Unterverzeichnissen nutzen, über Directory Junctions und den mklink /J-Befehl in der DOS-Kommandozeile, denn die Filmerkennung innerhalb von Kodi arbeitet rekursiv und springt entsprechend auf die verlinkten Laufwerke. Auf diese Weise kann man am Server Laufwerke hinzufügen, ohne die Einstellungen jedes Clients einzeln aktualisieren zu müssen. Der Trick funktioniert in Kodi aber nur für Filme, nicht für Serien, denn bei Serien ist in Kodi keine Rekursion implementiert. Ergänzung 01.09.2017: Mit Directory Junctions funktioniert in Kodi die Erkennung neuer Filme irgendwann nicht mehr. Das Änderungsdatum der Verzeichnisse ändert sich bei den Verknüpfungen prinzipiell nicht mehr, und Kodi scheint darauf zu achten. Die Lösung besteht darin, die Directory Junctions über den Windows Task Scheduler und den Aufruf einer Batch-Datei täglich neu zu erstellen:

 

@echo off
echo Entfernen der Directory Junctions
rmdir /Q D:\Filme\1

echo Erstellen der Directory Junctions
mklink /J D:\Filme\1 D:\_Filme

 

2. Die Dateiensuche des FreeCommander kann rekursiv Ordner mit Unterordnern nach bestimmten Dateien durchsuchen, das ist zu empfehlen wenn man Directory Junctions benutzt, denn auf diese Weise muss man Dateisuchen nur einmalig durchführen und kann Dateilisten über alle verlinkten Laufwerke erstellen. Außerdem steht in dieser Dateienliste das typische Kontextmenü des Windows-Dateiexplorers mit allen Optionen zur Verfügung.

 

3. Der DLNA-Server von DVBViewer Recording Service kann über den Alben-Eintrag Listen über alle ihm bekannten Laufwerke erstellen. Der Dienst verabschiedet sich aber ab und zu schon mal, so dass ich empfehlen würde im Windows-Aufgabenplaner eine Aufgabe zu erstellen die diesen Dienst einmal pro Tag automatisch neu startet.

 

Für die Datensicherung habe ich eigene Skripte geschrieben, die ich nachfolgend veröffentliche. Die Skripte unterscheiden sich danach, ob die Backuplaufwerke über Laufwerksbuchstaben oder Linux-typisch als Pfade/Mount Points in den Verzeichnisbaum eingehängt wurden – das ist auch bei Windows möglich, über die Datenträgerverwaltung.

 

Variante 1, Datensicherung über Laufwerksbuchstaben:

 

@echo off
setlocal EnableDelayedExpansion

cls
echo -----------------------------------------------------------------------------
echo Backupskript
echo INFO: Pfade bitte ohne abschliessenden Backslash \ eingeben
echo -----------------------------------------------------------------------------

set Quelle1=%1
set Ziel1=%2
set Ziel2=%3
set Ziel3=%4

if [!Quelle1!]==[] (
set /p Quelle1="Quellpfad> " || set "Quelle1=…"
)

REM Achtung, bei den Zielpfaden Groß- und Kleinschreibung beachten
if [!Ziel1!]==[] (
set /p Ziel1="Zielpfad 1> " || set "Ziel1=…"
)

if [!Ziel2!]==[] (
set /p Ziel2="Zielpfad 2> " || set "Ziel2=…"
)

if [!Ziel3!]==[] (
set /p Ziel3="Zielpfad 3> " || set "Ziel3=…"
)

Set "RoboParms=/E /ZB /COPY:DATSOU /SEC /FP"
Set "RoboParms=%Roboparms% /LOG+:"C:\Users\Administrator\Desktop\backup.log" /NP"

REM --------------- Start des Kopiervorganges ---------------
cls
echo Anfang %DATE% %TIME%
call :CopyFiles !Quelle1!
echo Ende %DATE% %TIME%

REM --------------- Beendigung                ---------------
goto end

:CopyFiles
set Quelle=%1
FOR /R %Quelle% %%G in (*.*) DO (
  rem echo %%G
  set filedrive=%%~dG
  set filepath=%%~pG
  set filefullpath=!filedrive!!filepath!
  REM abschließenden \ entfernen
  set filefullpath=!filefullpath:~,-1!
  set filename=%%~nG
  set fileextension=%%~xG
  set filefullname=%%~nxG
  echo %%~nxG
  REM Dateigröße der zu kopierenden Datei ermitteln
  set filesize=%%~zG
  REM echo Quellpfad entfernen, Unterordner-Pfad für Ziel separieren
  set subpath=!filefullpath:%Quelle%=!

  REM Zuerst ermitteln ob die Datei auf den Ziellaufwerken bereits existiert, wenn ja dort fortsetzen
  set gefunden=0
  if exist !Ziel1!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel1!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel1%
  ) 
  if exist !Ziel2!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel2!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel2%
  ) 
  if exist !Ziel3!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel3!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel3%
  ) 

  REM Datei existiert noch nicht auf den Ziellaufwerken, Bestimmung des Laufwerks mit dem größten freien Speicherplatz
  if !gefunden!==0 (    
    REM Freien Speicherplatz auf Ziellaufwerken ermitteln
    REM Zahlenvergleiche, zumal so große, funktionieren in DOS nur korrekt wenn die Zahlen zuvor mit führenden Nullen
    REM auf die gleiche Länge gebracht werden
    REM Von den angegebenen Zielpfaden werden die ersten beiden Zeichen für die Laufwerksbuchstaben und : abgeschnitten
    REM WMI-Infos: "https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx
    for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel1:~0,2%"') do set drivefreeSpace1=%%S
    REM for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace ^| findstr "%Ziel1%"') do set drivefreeSpace1=%%S
    set drivefreeSpace1=00000000000000000000!drivefreeSpace1!
    set drivefreeSpace1=!drivefreeSpace1:~-20!
    for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel2:~0,2%"') do set drivefreeSpace2=%%S
    REM for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace ^| findstr "%Ziel2%"') do set drivefreeSpace2=%%S
    set drivefreeSpace2=00000000000000000000!drivefreeSpace2!
    set drivefreeSpace2=!drivefreeSpace2:~-20!
    for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel3:~0,2%"') do set drivefreeSpace3=%%S
    REM for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace^| findstr "%Ziel3%"') do set drivefreeSpace3=%%S
    set drivefreeSpace3=00000000000000000000!drivefreeSpace3!
    set drivefreeSpace3=!drivefreeSpace3:~-20!
    rem echo !drivefreeSpace1! !drivefreeSpace2! !drivefreeSpace3! >C:\Users\Administrator\Desktop\test.log
    REM Bestimmung des Ziellaufwerks mit dem größten freien Speicherplatz
    set ZielLaufwerk=%Ziel1%
    set ZielGroesse=!drivefreeSpace1!
    if !drivefreeSpace2! gtr !ZielGroesse! (
      set ZielLaufwerk=%Ziel2%
      set ZielGroesse=!drivefreeSpace2!
    )
    if !drivefreeSpace3! gtr !ZielGroesse! (
      set ZielLaufwerk=%Ziel3%
      set ZielGroesse=!drivefreeSpace3!
    ) 
  )
  REM Datei einzeln kopieren
  rem echo Robocopy.exe "!filefullpath!" "!Ziellaufwerk!!subpath!" !RoboParms! /IF "!filefullname!"  
  Robocopy.exe "!filefullpath!" "!Ziellaufwerk!!subpath!" %RoboParms% /IF "!filefullname!" >NUL 
)
goto :eof

:END

 

Variante 2, Datensicherung über Mount Points:

 

@echo off
setlocal EnableDelayedExpansion

cls
echo -----------------------------------------------------------------------------
echo Backupskript
echo INFO: Pfade bitte ohne abschliessenden Backslash \ eingeben
echo -----------------------------------------------------------------------------

set Quelle1=%1
set Ziel1=%2
set Ziel2=%3
set Ziel3=%4

if [!Quelle1!]==[] (
set /p Quelle1="Quellpfad> " || set "Quelle1=…"
)

REM Achtung, bei den Zielpfaden Groß- und Kleinschreibung beachten
if [!Ziel1!]==[] (
set /p Ziel1="Zielpfad 1> " || set "Ziel1=…"
)

if [!Ziel2!]==[] (
set /p Ziel2="Zielpfad 2> " || set "Ziel2=…"
)

if [!Ziel3!]==[] (
set /p Ziel3="Zielpfad 3> " || set "Ziel3=…"
)

Set "RoboParms=/E /ZB /COPY:DATSOU /SEC /FP"
Set "RoboParms=%Roboparms% /LOG+:"C:\Users\Administrator\Desktop\backup.log" /NP"

REM --------------- Start des Kopiervorganges ---------------
cls
echo Anfang %DATE% %TIME%
call :CopyFiles !Quelle1!
echo Ende %DATE% %TIME%

REM --------------- Beendigung                ---------------
goto end

:CopyFiles
set Quelle=%1
FOR /R %Quelle% %%G in (*.*) DO (
  rem echo %%G
  set filedrive=%%~dG
  set filepath=%%~pG
  set filefullpath=!filedrive!!filepath!
  REM abschließenden \ entfernen
  set filefullpath=!filefullpath:~,-1!
  set filename=%%~nG
  set fileextension=%%~xG
  set filefullname=%%~nxG
  echo %%~nxG
  REM Dateigröße der zu kopierenden Datei ermitteln
  set filesize=%%~zG
  REM echo Quellpfad entfernen, Unterordner-Pfad für Ziel separieren
  set subpath=!filefullpath:%Quelle%=!

  REM Zuerst ermitteln ob die Datei auf den Ziellaufwerken bereits existiert, wenn ja dort fortsetzen
  set gefunden=0
  if exist !Ziel1!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel1!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel1%
  ) 
  if exist !Ziel2!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel2!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel2%
  ) 
  if exist !Ziel3!!subpath!\!filefullname! (
    echo Datei existiert schon auf !Ziel3!!subpath!\, kopieren wird dort fortgesetzt oder uebersprungen
    set gefunden=1
    set ZielLaufwerk=%Ziel3%
  ) 

  REM Datei existiert noch nicht auf den Ziellaufwerken, Bestimmung des Laufwerks mit dem größten freien Speicherplatz
  if !gefunden!==0 (    
    REM Freien Speicherplatz auf Ziellaufwerken ermitteln
    REM Zahlenvergleiche, zumal so große, funktionieren in DOS nur korrekt wenn die Zahlen zuvor mit führenden Nullen
    REM auf die gleiche Länge gebracht werden
    REM Von den angegebenen Zielpfaden werden die ersten beiden Zeichen für die Laufwerksbuchstaben und : abgeschnitten
    REM WMI-Infos: "https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx
    REM for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel1:~0,2%"') do set drivefreeSpace1=%%S
    for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace ^| findstr "%Ziel1%"') do set drivefreeSpace1=%%S
    set drivefreeSpace1=00000000000000000000!drivefreeSpace1!
    set drivefreeSpace1=!drivefreeSpace1:~-20!
    REM for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel2:~0,2%"') do set drivefreeSpace2=%%S
    for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace ^| findstr "%Ziel2%"') do set drivefreeSpace2=%%S
    set drivefreeSpace2=00000000000000000000!drivefreeSpace2!
    set drivefreeSpace2=!drivefreeSpace2:~-20!
    REM for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel3:~0,2%"') do set drivefreeSpace3=%%S
    for /f "tokens=1" %%S in ('wmic volume get Name^, FreeSpace^| findstr "%Ziel3%"') do set drivefreeSpace3=%%S
    set drivefreeSpace3=00000000000000000000!drivefreeSpace3!
    set drivefreeSpace3=!drivefreeSpace3:~-20!
    rem echo !drivefreeSpace1! !drivefreeSpace2! !drivefreeSpace3! >C:\Users\Administrator\Desktop\test.log
    REM Bestimmung des Ziellaufwerks mit dem größten freien Speicherplatz
    set ZielLaufwerk=%Ziel1%
    set ZielGroesse=!drivefreeSpace1!
    if !drivefreeSpace2! gtr !ZielGroesse! (
      set ZielLaufwerk=%Ziel2%
      set ZielGroesse=!drivefreeSpace2!
    )
    if !drivefreeSpace3! gtr !ZielGroesse! (
      set ZielLaufwerk=%Ziel3%
      set ZielGroesse=!drivefreeSpace3!
    ) 
  )
  REM Datei einzeln kopieren
  rem echo Robocopy.exe "!filefullpath!" "!Ziellaufwerk!!subpath!" !RoboParms! /IF "!filefullname!"  
  Robocopy.exe "!filefullpath!" "!Ziellaufwerk!!subpath!" %RoboParms% /IF "!filefullname!" >NUL 
)
goto :eof

:END

 

Der Sinn der Skripte ist es, große Dateien von einem Quelllaufwerk auf kleinere Ziellaufwerke gleichmäßig zu verteilen - bei einem 1:1-Backup könnte man ansonsten einfach alle Dateien rüberkopieren, dazu müsste das Ziellaufwerk aber gleich groß dem Quelllaufwerk sein.

 

Die Skripte benutzen das Windows-eigene Robocopy-Tool, und kopieren die Dateien von einem Quelllaufwerk auf drei Ziellaufwerke. Bei dem Ziellaufwerk wird nach jeder Datei das Laufwerk von den drei angegebenen ausgewählt, auf dem noch am meisten Speicherplatz frei ist. Die Verzeichnisstruktur vom Quelllaufwerk bzw. -pfad wird auf den Ziellaufwerken gespiegelt, nur die Dateien werden zwischen den drei Ziellaufwerken verteilt.

 

Da das DOS-Skripte sind, sollte bei jeder Zeile mit einer SET-Zuweisung darauf geachtet werden dass keine Leerzeichen am Ende dieser Zeile im Editor angehängt werden, weil sonst die Leerzeichen mit in die Variablen übernommen werden und die Bestimmung des Ziellaufwerks mit dem größten freien Speicherplatz nicht mehr korrekt funktioniert. Die Skripte sollten mit der Dateiendung .BAT abgespeichert werden, damit Windows sie erkennt und sie per Doppelklick ausführbar sind.

 

Wenn das Backup durchgelaufen ist existiert anschließend auf dem Desktop eine Log-Datei. Wer den Microsoft Log-Parser (Freeware) benutzt, kann zur Überprüfung, ob wirklich alle Dateien gesichert werden, folgendes DOS-Kommando benutzen:

 

logparser -i:FS -o:DATAGRID "select name from $Quelle\*.* where name not in (select name from $Ziel1\*.*,$Ziel2\*.*,$Ziel3\*.*)"

 

Erfahrungsgemäß hat DOS Probleme mit Umlauten im Dateinamen, ein Check ist daher schon zu empfehlen. Insgesamt entfällt mit diesen Backup-Skripten die Notwendigkeit, dass ein Ziellaufwerk genauso groß wie sein Quelllaufwerk sein muss, und man kann die Vorteile von Robocopy wie z. B. Fortsetzen nach Netzwerkunterbrechung mitnehmen.

 

Doppelte Dateien können über den Logparser durch folgenden Befehl gefunden werden:

 

logparser -i:FS -o:DATAGRID "select extract_prefix(name,-1,'.') as prefix from $Ziel1\*.*, $Ziel2\*.*, $Ziel3\*.* where (extract_extension(name)='avi' or extract_extension(name) = 'mkv') group by prefix having count(*)>1 order by prefix"

   

Tag-Wolke

Monats-Liste