diff --git a/doc/arch.obj b/doc/arch.obj new file mode 100644 index 0000000..163f420 --- /dev/null +++ b/doc/arch.obj @@ -0,0 +1,341 @@ +%TGIF 4.1.45-QPL +state(0,37,100.000,0,200,0,16,1,6,1,1,0,0,1,0,1,0,'Courier',0,80640,0,0,1,10,0,0,1,0,0,16,0,0,1,1,1,1,1050,1485,0,0,2880,0). +% +% @(#)$Header$ +% %W% +% +unit("1 pixel/pixel"). +color_info(19,65535,0,[ + "magenta", 65535, 0, 65535, 65535, 0, 65535, 1, + "red", 65535, 0, 0, 65535, 0, 0, 1, + "green", 0, 65535, 0, 0, 65535, 0, 1, + "blue", 0, 0, 65535, 0, 0, 65535, 1, + "yellow", 65535, 65535, 0, 65535, 65535, 0, 1, + "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1, + "cyan", 0, 65535, 65535, 0, 65535, 65535, 1, + "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1, + "white", 65535, 65535, 65535, 65535, 65535, 65535, 1, + "black", 0, 0, 0, 0, 0, 0, 1, + "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1, + "#00000000c000", 0, 0, 49344, 0, 0, 49152, 1, + "#820782070000", 33410, 33410, 0, 33287, 33287, 0, 1, + "#3cf3fbee34d2", 15420, 64507, 13364, 15603, 64494, 13522, 1, + "#3cf3fbed34d3", 15420, 64507, 13364, 15603, 64493, 13523, 1, + "#ffffa6990000", 65535, 42662, 0, 65535, 42649, 0, 1, + "#ffff0000fffe", 65535, 0, 65535, 65535, 0, 65534, 1, + "#fffe0000fffe", 65535, 0, 65535, 65534, 0, 65534, 1, + "#fffe00000000", 65535, 0, 0, 65534, 0, 0, 1 +]). +script_frac("0.6"). +fg_bg_colors('cyan','white'). +dont_reencode("FFDingbests:ZapfDingbats"). +objshadow_info('#c0c0c0',2,2). +page(1,"",1,''). +group([ +oval('blue','',50,500,150,540,1,1,1,1,0,0,0,0,0,'1',0,[ +]), +box('blue','',50,470,150,520,1,1,1,2,0,0,0,0,0,'1',0,[ +]), +oval('cyan','',50,450,150,490,1,1,1,0,0,0,0,0,0,'1',0,[ +]) +], +38,0,0,[ +]). +group([ +oval('blue','',350,500,450,540,1,1,1,44,0,0,0,0,0,'1',0,[ +]), +box('blue','',350,470,450,520,1,1,1,45,0,0,0,0,0,'1',0,[ +]), +oval('cyan','',350,450,450,490,1,1,1,46,0,0,0,0,0,'1',0,[ +]) +], +43,0,0,[ +]). +group([ +oval('blue','',500,500,600,540,1,1,1,48,0,0,0,0,0,'1',0,[ +]), +box('blue','',500,470,600,520,1,1,1,49,0,0,0,0,0,'1',0,[ +]), +oval('cyan','',500,450,600,490,1,1,1,50,0,0,0,0,0,'1',0,[ +]) +], +47,0,0,[ +]). +group([ +box('black','',750,650,800,700,2,1,1,66,0,0,0,0,0,'1',0,[ +]), +oval('black','',760,660,790,690,0,1,1,64,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 775,660,795,660],0,1,1,65,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]) +], +84,0,0,[ +]). +group([ +box('black','',755,655,805,705,2,1,1,86,0,0,0,0,0,'1',0,[ +]), +oval('black','',765,665,795,695,0,1,1,87,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 780,665,800,665],0,1,1,88,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]) +], +85,0,0,[ +]). +group([ +box('black','',760,660,810,710,2,1,1,90,0,0,0,0,0,'1',0,[ +]), +oval('black','',770,670,800,700,0,1,1,91,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 785,670,805,670],0,1,1,92,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]) +], +89,0,0,[ +]). +group([ +box('black','',765,665,815,715,2,1,1,94,0,0,0,0,0,'1',0,[ +]), +oval('black','',775,675,805,705,0,1,1,95,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 790,675,810,675],0,1,1,96,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]) +], +93,0,0,[ +]). +group([ +box('black','',770,670,820,720,2,1,1,98,0,0,0,0,0,'1',0,[ +]), +oval('black','',780,680,810,710,0,1,1,99,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 795,680,815,680],0,1,1,100,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]) +], +97,0,0,[ +]). +group([ +box('black','',625,425,825,625,2,2,1,111,0,0,0,0,0,'2',0,[ +]), +group([ +oval('black','',760,460,790,490,0,1,1,52,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 775,460,795,460],0,1,1,53,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]), +box('black','',750,450,800,500,0,1,1,54,0,0,0,0,0,'1',0,[ +]) +], +51,0,0,[ +]), +group([ +oval('black','',760,510,790,540,0,1,1,56,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 775,510,795,510],0,1,1,57,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]), +box('black','',750,500,800,550,0,1,1,58,0,0,0,0,0,'1',0,[ +]) +], +55,0,0,[ +]), +group([ +oval('black','',760,560,790,590,0,1,1,60,0,0,0,0,0,'1',0,[ +]), +poly('black','',2,[ + 775,560,795,560],0,1,1,61,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]), +box('black','',750,550,800,600,0,1,1,62,0,0,0,0,0,'1',0,[ +]) +], +59,0,0,[ +]), +box('black','',640,450,710,485,2,1,1,104,0,0,0,0,0,'1',0,[ +]), +box('black','',650,455,700,465,2,1,1,106,0,0,0,0,0,'1',0,[ +]), +box('black','',690,475,700,480,2,1,1,107,0,0,0,0,0,'1',0,[ +]), +polygon('black','',14,[ + 650,520,700,520,710,510,740,510,740,520,715,520,710,525,715,530, + 740,530,740,540,710,540,700,530,650,530,650,520],2,1,1,0,108,0,0,0,0,0,'1',0, + "0000",[ +]) +], +131,0,0,[ +]). +box('black','',50,250,150,400,2,2,1,132,0,0,0,0,0,'2',0,[ +]). +rcbox('black','',100,350,140,390,2,2,1,0,16,133,0,0,0,0,'2',0,[ +]). +text('black',120,358,1,1,1,18,15,134,12,3,2,0,0,0,2,18,15,0,0,"",0,0,0,0,370,'',[ +minilines(18,15,0,0,1,0,0,[ +mini_line(18,12,3,0,0,0,[ +str_block(0,18,12,3,0,-1,0,0,0,[ +str_seg('black','Courier',0,80640,18,12,3,0,-1,0,0,0,0,0, + "DA")]) +]) +])]). +text('black',60,258,1,0,1,54,15,136,12,3,2,0,0,0,2,54,15,0,0,"",0,0,0,0,270,'',[ +minilines(54,15,0,0,0,0,0,[ +mini_line(54,12,3,0,0,0,[ +str_block(0,54,12,3,0,-2,0,0,0,[ +str_seg('black','Courier',0,80640,54,12,3,0,-2,0,0,0,0,0, + "Client")]) +]) +])]). +box('black','',350,250,850,400,2,2,1,138,0,0,0,0,0,'2',0,[ +]). +text('black',360,258,1,0,1,117,15,139,12,3,2,0,0,0,2,117,15,0,0,"",0,0,0,0,270,'',[ +minilines(117,15,0,0,0,0,0,[ +mini_line(117,12,3,0,0,0,[ +str_block(0,117,12,3,0,-1,0,0,0,[ +str_seg('black','Courier',0,80640,117,12,3,0,-1,0,0,0,0,0, + "Backup Server")]) +]) +])]). +group([ +oval('blue','',430,600,530,640,1,1,1,142,0,0,0,0,0,'1',0,[ +]), +box('blue','',430,570,530,620,1,1,1,143,0,0,0,0,0,'1',0,[ +]), +oval('cyan','',430,550,530,590,1,1,1,144,0,0,0,0,0,'1',0,[ +]) +], +141,0,0,[ +]). +rcbox('black','',500,350,600,390,2,2,1,0,16,148,0,0,0,0,'2',0,[ +]). +text('black',510,358,1,0,1,18,15,149,12,3,2,0,0,0,2,18,15,0,0,"",0,0,0,0,370,'',[ +minilines(18,15,0,0,0,0,0,[ +mini_line(18,12,3,0,0,0,[ +str_block(0,18,12,3,0,-1,0,0,0,[ +str_seg('black','Courier',0,80640,18,12,3,0,-1,0,0,0,0,0, + "MA")]) +]) +])]). +poly('red','',2,[ + 400,360,140,360],1,1,1,153,0,2,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',2,[ + 140,380,400,380],1,1,1,156,0,2,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',4,[ + 460,390,460,420,460,420,460,550],3,1,1,158,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',4,[ + 520,390,520,420,490,420,490,550],3,1,1,159,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',6,[ + 430,450,430,440,530,440,530,380,550,380,550,450],1,1,1,162,0,0,0,0,0,0,0,'1',0,0, + "00","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',4,[ + 570,450,570,380,680,380,680,450],1,1,1,164,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +group([ +rcbox('black','',400,350,490,390,2,2,1,0,16,145,0,0,0,0,'2',0,[ +]), +text('black',420,358,1,0,1,18,15,146,12,3,2,0,0,0,2,18,15,0,0,"",0,0,0,0,370,'',[ +minilines(18,15,0,0,0,0,0,[ +mini_line(18,12,3,0,0,0,[ +str_block(0,18,12,3,0,-1,0,0,0,[ +str_seg('black','Courier',0,80640,18,12,3,0,-1,0,0,0,0,0, + "CA")]) +]) +])]) +], +171,0,0,[ +]). +poly('green','',4,[ + 440,390,440,420,410,420,410,450],1,1,1,189,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +group([ +rcbox('black','',360,300,450,340,0,2,1,0,16,190,0,0,0,0,'2',0,[ +]), +text('black',380,308,1,0,1,45,15,191,12,3,0,0,0,0,2,45,15,0,0,"",0,0,0,0,320,'',[ +minilines(45,15,0,0,0,0,0,[ +mini_line(45,12,3,0,0,0,[ +str_block(0,45,12,3,0,-1,0,0,0,[ +str_seg('black','Courier',0,80640,45,12,3,0,-1,0,0,0,0,0, + "Samba")]) +]) +])]) +], +196,0,0,[ +]). +poly('green','',2,[ + 380,450,380,340],1,1,1,197,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',2,[ + 360,320,150,320],1,1,1,199,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',2,[ + 120,450,120,390],1,1,1,200,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +poly('green','',2,[ + 90,400,90,450],1,1,1,201,0,0,0,0,0,0,0,'1',0,0, + "0","",[ + 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[ +]). +text('cyan',360,498,1,0,1,72,15,206,12,3,0,0,0,0,2,72,15,0,0,"",0,0,0,0,510,'',[ +minilines(72,15,0,0,0,0,0,[ +mini_line(72,12,3,0,0,0,[ +str_block(0,72,12,3,0,-1,0,0,0,[ +str_seg('cyan','Courier',0,80640,72,12,3,0,-1,0,0,0,0,0, + "FS Cache")]) +]) +])]). +text('cyan',500,498,1,0,1,99,15,208,12,3,0,0,0,0,2,99,15,0,0,"",0,0,0,0,510,'',[ +minilines(99,15,0,0,0,0,0,[ +mini_line(99,12,3,0,0,0,[ +str_block(0,99,12,3,0,-1,0,0,0,[ +str_seg('cyan','Courier',0,80640,99,12,3,0,-1,0,0,0,0,0, + "Media Queue")]) +]) +])]). +text('cyan',450,598,1,0,1,63,15,210,12,3,0,0,0,0,2,63,15,0,0,"",0,0,0,0,610,'',[ +minilines(63,15,0,0,0,0,0,[ +mini_line(63,12,3,0,0,0,[ +str_block(0,63,12,3,0,-1,0,0,0,[ +str_seg('cyan','Courier',0,80640,63,12,3,0,-1,0,0,0,0,0, + "Catalog")]) +]) +])]). diff --git a/doc/arch.png b/doc/arch.png new file mode 100644 index 0000000..418deca Binary files /dev/null and b/doc/arch.png differ diff --git a/doc/konzept.html b/doc/konzept.html new file mode 100644 index 0000000..5e4110d --- /dev/null +++ b/doc/konzept.html @@ -0,0 +1,357 @@ + + + + + +
+ ++ Die Anforderungen ergeben sich im Wesentlichen aus den + Erfahrungen am WSR in den letzten Jahren: +
++ Nicht benötigt werden folgende Features: +
++ Das System besteht aus mehreren "Agents", die jeweils bestimmte + Aufgaben haben. Die Abbildung zeigt einen Client (d.h., ein + System, von dem Backups erstellt werden sollen) und einen + Backup-Server, der die Backups verwaltet. +
++ Die Zentrale Komponente bildet der "Collection Agent", der in + regelmäßigen Abständen (typischerweise täglich), Kontakt zu + den Clients aufnimmt, den aktuellen Filebestand festellt, neue + bzw. geänderte Files vom Client anfordert und im FS Cache + sowie im Catalog speichert. +
++ Der FS Cache hat die von + rsync-snapshot + bekannte Struktur: +
++ Da jeder Subtree des FS Cache eine vollständige Kopie des + entsprechenden Subtrees am Client ist, kann der FS Cache + einfach über Samba oder ein anderes Netzwerk-Filesystem + read-only export werden. Restores erfolgen einfach durch + Kopieren der Files auf den Client. +
++ Der Catalog enthält die Metadaten aller Files in einer + relationalen Datenbank. Das dient einerseits der schnelleren + Suche, andererseits dazu, Informationen über bereits auf Band + ausgelagerte Dateien zu halten, die nicht mehr im FS Cache + vorhanden sind. +
++ Der Disk Agent muss auf jedem Client installiert werden. Er + dient dazu, Informationen über das lokale Filesystem des + Clients an den Collection Agent zu übertragen. Im wesentlichen + sind das: +
++ Der Disk-Agent kann konfiguriert werden, dass er bestimmte + Directories, von denen kein Backup gewünscht ist (z.B. /proc + und /sys auf Linux-Systemen, aber auch z.B. Directories mit + Datenbankfiles) ausspart. +
++ Im aktuellen Prototyp wird der DA über SSH gestartet, die + Authentifikation erfolgt über Public-Keys. Sollte sich das als + zu langsam erweisen, kann Agent auch über eine "nackte" + TCP-Verbindung kommunizieren, die dafür notwendige + Authentifikation ist aber im aktuellen Prototyp noch nicht + implementiert. +
++ Directorylistings und Filedaten werden über unterschiedliche + Verbindungen übertragen, was effektives Streaming erleichtert. +
++ Der Disk-Agent übersetzt systemspezifische Daten in ein + "allgemeines" Format. Z.B. werden Filenamen vom lokalen + Encoding nach UTF-8 übersetzt, und ACLs werden im + POSIX-Textformat dargestellt. +
++ Es wäre möglich, statt eines Disk-Agents, der auf ein + Filesystem zugreift, einen zu implementieren, der beliebige + andere Daten (Datenbanken, etc.) exportiert. + Z.B. könnte ein Disk-Agent für Online-Backups einer + Oracle-Datenbank folgendes Interface implementieren: +
++ In diesem Fall + ist das einfache Restore über ein Netzwerkfilesystem natürlich + nicht möglich. +
++ Der Media Agent dient dazu, Files auf Bänder (oder andere + Wechselmedien) auszulagern. +
++ Er liest Daten über den aktuellen Stand aus dem Catalog, + bestimmt anhand seines Regelwerks, welche Files auf welches + Band geschrieben werden müssen, und führt das durch. +
++ Aus Performance-Gründen werden Files nicht direkt aus dem + FS Cache auf Band kopiert. Speziell bei vielen kleinen Files + wäre so nicht sicherzustellen, dass die zum Streamen + erforderliche Transferrate erreicht wird. Statt dessen werden + in der Media Queue Files sinnvoller Größe (1GB dürfte + bauchgefühlmäßig für LTO-3 angemessen sein) im + Standard-PAX-Format erzeugt. Diese Files werden dann 1:1 auf + Band kopiert. Wahrscheinlich ist es sinnvoll, für die Media + Queue eine eigene Disk (bzw. ein RAID-1-Paar) zu reservieren. +
++ Der Media Agent besteht aus zumindest zwei Prozessen mit + unterschiedlichen Aufgaben. Wahrscheinlich ist es sinnvoll, + ihn in zwei Programme zu splitten ("Archiving Agent" schreibt + in die Media Queue, "Media Agent" kopiert von dort auf + Wechselmedium). +
++ Prinzipiell können die Auslagerungsregeln beliebig komplex + werden, wobei folgende Daten zur Verfügung stehen: +
++ Folgende Regeln könnten unsere aktuellen Bedürfnisse abdecken: +
++ Das Archiv dient dazu, alle Files, für die das sinnvoll ist + (in erster Näherung alle außer Oracle-Datenbanken, + tmp-Directories, etc.), "ewig" aufzubewahren. Das kann wie + folgt erreicht werden: +
++ Erstelle eine Liste aller Files im aktuellen FS Cache. +
++ Exkludiere ev. Files, die nicht archiviert werden sollen + (Anm.: Die meisten solchen Files sind vermutlich gar nicht im + FS Cache, da sie bereits vom DA ausgeschlossen werden können). +
++ Exkludiere ev. Files, die nur während eines CA-Runs existiert + haben (wahrscheinlich temporäre Files). +
++ Bestimme alle Fileversionen, die noch nicht auf Band gesichert + wurden. +
++ Wenn sich alle existierenden Fileversionen am gleichen Band + befinden, aber nicht auf dem Band, das gerade geschrieben + werden soll, selektiere auch die aktuelle Version. +
++ Ein volles Backup sollte sich off-site befinden, um im Fall + eines Komplettausfalls ein Ersatzrechenzentrum aufbauen zu + können. Austausch erfolgt (derzeit) wöchentlich. +
++ Erstelle eine Liste aller Files im aktuellen FS Cache. +
++ Exkludiere ev. Files, die für ein Offsite-Backup nicht + benötigt werden. + (Anm.: Das ist gefährlich - das Offsite-Backup wird nicht + regelmäßig getestet, und wenn im Ernstfall wichtige Files + fehlen, hat man ein Problem). +
++ Bestimme die aktuelle Fileversion, aber nur wenn diese + noch nicht auf ein Band in diesem Pool gesichert wurde, oder + wenn sie sich auf einem Band befindet, das recycelt werden + soll. +
++ Man kann entweder immer das älteste Band, das sich off-site + befindet, zum Recyclen markieren, oder einen intelligenteren + Algorithmus verwenden - z.B. das Band, auf dem sich die + wenigsten noch-aktuellen Fileversionen befinden. +
++ Die sinnvolle Lebensdauer von Datenbank-Backups ist begrenzt + (spätestens nach einem Versionsupgrade sind sie nicht mehr + brauchbar), Datenbank-Backups (in ihrer aktuellen Form) werden + daher hauptsächlich für Desaster-Recovery und Migrationstests + gemacht, eine Archivierung ist nicht sinnvoll. + (Anm.: Dieses Szenario geht von unseren aktuellen Cold-Backups + aus) +
++ Erstelle eine Liste der aktuellen Fileversionen der + entsprechenden Datenbank. +
++ Jeder Pool enthält eine fixe Anzahl von Bändern, das jeweils + älteste wird recycelt. +
+