Beispiel #1
0
        }         // func CompareDirectoryRoot

        #endregion

        protected override void ProcessRecord()
        {
            using (bar = Notify.CreateStatus(String.Format("Synchronize {0} -> {1}", Source, Target), String.Empty))
            {
                bar.Maximum = 0;

                // start compare
                var t = Task.Factory.StartNew(CompareDirectoryRoot);

                // copy files
                bar.StartRemaining();
                DequeueActions(true);
                if (!Stopping)
                {
                    try
                    {
                        t.Wait();
                    }
                    catch (AggregateException e)
                    {
                        WriteError(new ErrorRecord(e.InnerException, "1", ErrorCategory.OperationStopped, this));
                        throw;
                    }
                }
            }
        }         // proc ProcessRecord
Beispiel #2
0
        }         // proc DeleteSafe

        protected override void ProcessRecord()
        {
            directoriesDeleted = 0;
            filesDeleted       = 0;
            bytesDeleted       = 0;

            using (var bar = Notify.CreateStatus("Clean directory", $"Clean {Target}..."))
                CleanDirectoryPath(bar, DateTime.Now, Age.TotalMilliseconds > 0 ? Age : Age.Negate(), new DirectoryInfo(Target), String.Empty);

            WriteVerbose($"Removed: {directoriesDeleted:N0} directories, {filesDeleted:N0} files, {Stuff.FormatFileSize(bytesDeleted)}");
        }         // proc ProcessRecord
        protected override void ProcessRecord()
        {
            using (var con = new SqlConnection(Connection))
                using (var bar = Notify.CreateStatus($"Backup database {con.Database}...", "Verbinde..."))
                {
                    progress = bar;

                    con.Open();
                    con.InfoMessage += Con_InfoMessage;

                    // get index information
                    using (var cmd = con.CreateCommand())
                    {
                        cmd.CommandTimeout = 0;

                        var indexTasks = new List <Tuple <string, string> >();

                        bar.StatusDescription = $"Check indizes...";
                        cmd.CommandText       = String.Format(String.Join(Environment.NewLine,
                                                                          "SELECT s.[name], o.[name], i.[name], avg_fragmentation_in_percent, fragment_count",
                                                                          "	FROM sys.dm_db_index_physical_stats(DB_ID(N'{0}'), NULL, NULL, NULL, NULL) AS f",
                                                                          "	INNER JOIN sys.indexes AS i ON(f.object_id = i.object_id AND f.index_id = i.index_id)",
                                                                          "	INNER JOIN sys.objects AS o ON(i.object_id = o.object_id)",
                                                                          "	INNER JOIN sys.schemas s on(o.schema_id = s.schema_id)"), con.Database
                                                              );

                        using (var r = cmd.ExecuteReader())
                        {
                            while (r.Read())
                            {
                                var schemaName = r.GetString(0);
                                var tableName  = r.GetString(1);
                                var indexName  = r.GetString(2);

                                var frag      = r.GetDouble(3);
                                var fragCount = r.IsDBNull(4) ? 0 : r.GetInt64(4);

                                var action =
                                    frag >= 5.0f && frag < 30.0
                                                                        ? "REORGANIZE"
                                                                        : frag >= 30.0f
                                                                                ? "REBUILD"
                                                                                : null;
                                if (action != null)
                                {
                                    indexTasks.Add(
                                        new Tuple <string, string>(
                                            $"Index {indexName} of {schemaName}.{tableName} - {action} (fragmentation: {frag:N1})...",
                                            $"ALTER INDEX [{indexName}] ON [{schemaName}].[{tableName}] {action}"
                                            )
                                        );
                                }
                            }
                        }

                        // check indizes
                        if (indexTasks.Count > 0)
                        {
                            bar.Maximum = indexTasks.Count;
                            for (var i = 0; i < indexTasks.Count; i++)
                            {
                                bar.Position         = i;
                                bar.CurrentOperation = indexTasks[i].Item1;
                                cmd.CommandText      = indexTasks[i].Item2;
                                cmd.ExecuteNonQuery();
                            }
                        }
                        bar.CurrentOperation = null;

                        // do backup
                        bar.StatusDescription = $"Execute Backup...";
                        cmd.CommandText       = String.Format(String.Join(Environment.NewLine,
                                                                          "BACKUP DATABASE [{0}]",
                                                                          "TO DISK = N'{1}' WITH NOFORMAT, INIT, ",
                                                                          "NAME = N'{0}-Vollständig Datenbank Sichern', SKIP, NOREWIND, NOUNLOAD, COMPRESSION, ",
                                                                          "STATS = 1, CHECKSUM"
                                                                          ),
                                                              con.Database,
                                                              BackupFile
                                                              );
                        bar.Maximum = 100;
                        bar.StartRemaining();
                        cmd.ExecuteScalar();                 // ExecuteNonQuery does not fire InfoMessage
                        bar.StopRemaining();

                        // check backup state
                        bar.StatusDescription = $"Check Backup...";
                        cmd.CommandText       = String.Format("select position from msdb..backupset where database_name = N'{0}' and backup_set_id = (select max(backup_set_id) from msdb..backupset where database_name = N'{0}')", con.Database);
                        var pos = cmd.ExecuteScalar();
                        if (pos is DBNull)
                        {
                            throw new Exception("Backup information not found.");
                        }

                        // verify backup
                        bar.StatusDescription = $"Verify Backup...";
                        cmd.CommandText       = String.Format("RESTORE VERIFYONLY FROM DISK = N'{0}' WITH FILE = {1}, NOUNLOAD, NOREWIND", BackupFile, pos);
                        cmd.ExecuteScalar();
                    }
                }
        }         // proc ProcessRecord
Beispiel #4
0
        protected override void ProcessRecord()
        {
            const string zipArchivePlaceHolder = "#";

            using (var bar = Notify.CreateStatus("Erzeuge Backup", $"Sicherung von {Source}..."))
            {
                var totalBytes = 0L;
                //var position = 0L;
                var itemsModified   = 0;
                var itemsUnmodified = 0;
                var itemsZipped     = 0;
                var archiveUsed     = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);

                // Lade Index-Datei
                bar.StatusDescription = "Lese Index...";
                var targetPath  = new DirectoryInfo(Target);
                var targetIndex = Path.Combine(targetPath.FullName, "index.txt.gz");
                var index       = new FileIndex();
                if (String.IsNullOrEmpty(ShadowIndex))                 // Kein lokaler Index, also lade dem vom Target
                {
                    index.ReadIndex(Notify, targetIndex);
                }
                else
                {
                    index.ReadIndex(Notify, ShadowIndex);
                }

                // Gleiche die Daten ab und erzeuge die Statistik
                bar.StatusDescription = "Vergleiche Dateien mit Index...";
                var swFileStopWatch = Stopwatch.StartNew();
                var files           = new FileList(Notify, new DirectoryInfo(Source), Excludes);
                foreach (var c in files)
                {
                    var indexItem = index.UpdateFile(c);
                    var tmp       = 0;

                    // Gib einen zwischen Bericht
                    if (swFileStopWatch.ElapsedMilliseconds > 500)
                    {
                        bar.StatusDescription = $"Vergleiche {c.RelativePath} mit Index...";
                        swFileStopWatch       = Stopwatch.StartNew();
                    }

                    switch (indexItem.State)
                    {
                    case FileIndexState.Modified:
                        // Erzeuge den Eintrag im Index
                        if (c.FileInfo.Length < ZipArchiveBorder)
                        {
                            itemsZipped++;
                            indexItem.ArchiveName = zipArchivePlaceHolder;
                        }
                        else
                        {
                            if (String.IsNullOrEmpty(indexItem.ArchiveName))
                            {
                                indexItem.ArchiveName = Guid.NewGuid().ToString("N") + Path.GetExtension(indexItem.RelativePath) + (ZipFile(indexItem.RelativePath) ? ".gz" : ".nopack");
                            }
                        }

                        // Statistik für den Progress
                        totalBytes += c.FileInfo.Length;
                        itemsModified++;

                        // Erhöhe den Zugriff
                        if (archiveUsed.TryGetValue(indexItem.ArchiveName, out tmp))
                        {
                            archiveUsed[indexItem.ArchiveName] = tmp + 1;
                        }
                        break;

                    case FileIndexState.Unmodified:
                        // Prüfe die existens den Archives
                        if (Force || (String.IsNullOrEmpty(ShadowIndex) && !File.Exists(Path.Combine(targetPath.FullName, indexItem.ArchiveName))))
                        {
                            indexItem.Update(c.FileInfo);
                            goto case FileIndexState.Modified;
                        }
                        itemsUnmodified++;

                        // Erhöhe den Zugriff
                        if (archiveUsed.TryGetValue(indexItem.ArchiveName, out tmp))
                        {
                            archiveUsed[indexItem.ArchiveName] = tmp + 1;
                        }
                        break;

                    case FileIndexState.None:
                        if (archiveUsed.ContainsKey(indexItem.ArchiveName))
                        {
                            archiveUsed[indexItem.ArchiveName] = 0;
                        }
                        break;
                    }
                }

                // Schreibe das neue Archiv
                if (itemsModified > 0)
                {
                    string          currentArchiveName = null;
                    FileWrite       zipStream          = null;
                    ZipOutputStream zip = null;
                    try
                    {
                        bar.StartRemaining();
                        bar.Maximum = totalBytes;

                        var removeItems = new List <FileIndexItem>();
                        foreach (var c in index)
                        {
                            switch (c.State)
                            {
                            case FileIndexState.Modified:                                     // Kopiere die Datei
                                using (var src = Stuff.OpenRead(new FileInfo(Path.Combine(Source, c.RelativePath)), Notify, allowEmpty: true))
                                {
                                    if (c.ArchiveName == zipArchivePlaceHolder)
                                    {
                                        // Schließe das Archiv, wenn genug Inhalt
                                        if (zipStream != null && zipStream.Stream.Position > 512 << 20)
                                        {
                                            zipStream.Commit();
                                            CloseZipStream(zipStream, zip);
                                            currentArchiveName = null;
                                        }

                                        // Erzeuge das Archiv
                                        if (currentArchiveName == null)
                                        {
                                            currentArchiveName = Guid.NewGuid().ToString("N") + ".zip";
                                            CreateZipStream(targetPath, currentArchiveName, out zipStream, out zip);
                                        }

                                        // Kopiere die Daten
                                        ZipFileItem(Notify, bar, src, zip, c);
                                        c.ArchiveName = currentArchiveName;
                                    }
                                    else
                                    {
                                        GZipFileItem(Notify, bar, src, targetPath, c);
                                    }
                                }
                                break;

                            case FileIndexState.None:                                     // Lösche den Index
                                removeItems.Remove(c);
                                break;
                            }
                        }

                        // Entferne die Einträge aus dem Index
                        foreach (var c in removeItems)
                        {
                            index.RemoveEntry(c);
                        }

                        if (zipStream != null)
                        {
                            zipStream.Commit();
                        }
                    }
                    finally
                    {
                        CloseZipStream(zipStream, zip);
                    }

                    // Schreibe den Index
                    bar.StopRemaining();
                    bar.StatusDescription = "Schreibe Index...";
                    if (!String.IsNullOrEmpty(ShadowIndex))
                    {
                        index.WriteIndex(Notify, ShadowIndex);
                    }
                    index.WriteIndex(Notify, targetIndex);

                    // Lösche ungenutzte Archive
                    if (String.IsNullOrEmpty(ShadowIndex))
                    {
                        foreach (var c in archiveUsed)
                        {
                            if (c.Value == 0)
                            {
                                var file = new FileInfo(Path.Combine(targetPath.FullName, c.Key));
                                bar.StatusDescription = $"Nicht mehr benötigtes Archiv '{c.Key}'...";
                                Notify.SafeIO(file.Delete, bar.StatusDescription);
                            }
                        }
                    }
                    else                     // Erzeuge nur eine Löschdatei
                    {
                        bar.StatusDescription = "Nicht mehr benötigte Archive werden gelöscht...";
                        using (var sw = new StreamWriter(Stuff.OpenWrite(new FileInfo(Path.Combine(targetPath.FullName, "index_rm.txt")), Notify, CompressMode.Stored)))
                        {
                            sw.BaseStream.Position = sw.BaseStream.Length;
                            foreach (var c in archiveUsed)
                            {
                                if (c.Value == 0)
                                {
                                    sw.WriteLine(c.Key);
                                }
                            }
                        }
                    }
                }
            }
        }         // proc ProcessRecord