Add auto vacuum interval option
This commit is contained in:
@@ -142,6 +142,7 @@ namespace Duplicati.Library.Interface
|
||||
bool Dryrun { get; }
|
||||
|
||||
ICompactResults CompactResults { get; }
|
||||
IVacuumResults VacuumResults { get; }
|
||||
IDeleteResults DeleteResults { get; }
|
||||
IRepairResults RepairResults { get; }
|
||||
}
|
||||
@@ -178,6 +179,8 @@ namespace Duplicati.Library.Interface
|
||||
long DownloadedFileSize { get; }
|
||||
long UploadedFileSize { get; }
|
||||
bool Dryrun { get; }
|
||||
|
||||
IVacuumResults VacuumResults { get; }
|
||||
}
|
||||
|
||||
public interface ICreateLogDatabaseResults : IBasicResults
|
||||
|
||||
@@ -112,11 +112,8 @@ namespace Duplicati.Library.Main
|
||||
Library.UsageReporter.Reporter.Report("USE_COMPRESSION", m_options.CompressionModule);
|
||||
Library.UsageReporter.Reporter.Report("USE_ENCRYPTION", m_options.EncryptionModule);
|
||||
|
||||
if (!m_options.NoAutoCompact && (LastCompact > DateTime.MinValue) && (LastCompact.Add(m_options.AutoCompactInterval) > DateTime.Now))
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "CompactResults", "Skipping auto compaction until {0}", LastCompact.Add(m_options.AutoCompactInterval));
|
||||
m_options.RawOptions["no-auto-compact"] = "true";
|
||||
}
|
||||
CheckAutoCompactInterval();
|
||||
CheckAutoVacuumInterval();
|
||||
|
||||
return RunAction(new BackupResults(), ref inputsources, ref filter, (result) => {
|
||||
|
||||
@@ -233,6 +230,8 @@ namespace Duplicati.Library.Main
|
||||
|
||||
public Duplicati.Library.Interface.ICompactResults Compact()
|
||||
{
|
||||
CheckAutoVacuumInterval();
|
||||
|
||||
return RunAction(new CompactResults(), (result) => {
|
||||
new Operation.CompactHandler(m_backend, m_options, result).Run();
|
||||
});
|
||||
@@ -362,7 +361,7 @@ namespace Duplicati.Library.Main
|
||||
|
||||
public Library.Interface.IVacuumResults Vacuum()
|
||||
{
|
||||
return RunAction(new VacuumResult(), result => {
|
||||
return RunAction(new VacuumResults(), result => {
|
||||
new Operation.VacuumHandler(m_options, result).Run();
|
||||
});
|
||||
}
|
||||
@@ -1108,6 +1107,29 @@ namespace Duplicati.Library.Main
|
||||
/// </summary>
|
||||
public DateTime LastCompact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time of last vacuum operation
|
||||
/// </summary>
|
||||
public DateTime LastVacuum { get; set; }
|
||||
|
||||
private void CheckAutoCompactInterval()
|
||||
{
|
||||
if (!m_options.NoAutoCompact && (LastCompact > DateTime.MinValue) && (LastCompact.Add(m_options.AutoCompactInterval) > DateTime.Now))
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "CompactResults", "Skipping auto compaction until {0}", LastCompact.Add(m_options.AutoCompactInterval));
|
||||
m_options.RawOptions["no-auto-compact"] = "true";
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAutoVacuumInterval()
|
||||
{
|
||||
if (m_options.AutoVacuum && (LastVacuum > DateTime.MinValue) && (LastVacuum.Add(m_options.AutoVacuumInterval) > DateTime.Now))
|
||||
{
|
||||
Logging.Log.WriteInformationMessage(LOGTAG, "VacuumResults", "Skipping auto vacuum until {0}", LastVacuum.Add(m_options.AutoVacuumInterval));
|
||||
m_options.RawOptions["auto-vacuum"] = "false";
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -536,8 +536,8 @@ namespace Duplicati.Library.Main.Operation
|
||||
m_database.PurgeLogData(m_options.LogRetention);
|
||||
if (m_options.AutoVacuum)
|
||||
{
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Vacuum_Running);
|
||||
m_database.Vacuum();
|
||||
m_result.VacuumResults = new VacuumResults(m_result);
|
||||
new VacuumHandler(m_options, (VacuumResults)m_result.VacuumResults).Run();
|
||||
}
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_Complete);
|
||||
return;
|
||||
|
||||
@@ -69,7 +69,8 @@ namespace Duplicati.Library.Main.Operation
|
||||
db.WriteResults();
|
||||
if (m_options.AutoVacuum)
|
||||
{
|
||||
db.Vacuum();
|
||||
m_result.VacuumResults = new VacuumResults(m_result);
|
||||
new VacuumHandler(m_options, (VacuumResults)m_result.VacuumResults).Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ namespace Duplicati.Library.Main.Operation
|
||||
internal class VacuumHandler
|
||||
{
|
||||
private readonly Options m_options;
|
||||
private readonly VacuumResult m_result;
|
||||
private readonly VacuumResults m_result;
|
||||
|
||||
public VacuumHandler(Options options, VacuumResult result)
|
||||
public VacuumHandler(Options options, VacuumResults result)
|
||||
{
|
||||
m_options = options;
|
||||
m_result = result;
|
||||
@@ -24,6 +24,7 @@ namespace Duplicati.Library.Main.Operation
|
||||
m_result.SetDatabase(db);
|
||||
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Vacuum_Running);
|
||||
db.Vacuum();
|
||||
m_result.EndTime = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +406,7 @@ namespace Duplicati.Library.Main
|
||||
new CommandLineArgument("rebuild-missing-dblock-files", CommandLineArgument.ArgumentType.Boolean, Strings.Options.RebuildmissingdblockfilesShort, Strings.Options.RebuildmissingdblockfilesLong, "false"),
|
||||
|
||||
new CommandLineArgument("auto-compact-interval", CommandLineArgument.ArgumentType.Timespan, Strings.Options.AutoCompactIntervalShort, Strings.Options.AutoCompactIntervalLong, "0m"),
|
||||
new CommandLineArgument("auto-vacuum-interval", CommandLineArgument.ArgumentType.Timespan, Strings.Options.AutoVacuumIntervalShort, Strings.Options.AutoVacuumIntervalLong, "0m"),
|
||||
});
|
||||
|
||||
return lst;
|
||||
@@ -1805,6 +1806,20 @@ namespace Duplicati.Library.Main
|
||||
get { return GetBool("auto-vacuum"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum time that must elapse after last vacuum before running next automatic vacuum
|
||||
/// </summary>
|
||||
public TimeSpan AutoVacuumInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!m_options.ContainsKey("auto-vacuum-interval") || string.IsNullOrEmpty(m_options["auto-vacuum-interval"]))
|
||||
return TimeSpan.Zero;
|
||||
else
|
||||
return Library.Utility.Timeparser.ParseTimeSpan(m_options["auto-vacuum-interval"]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating if the local filescanner should be disabled
|
||||
/// </summary>
|
||||
|
||||
@@ -579,6 +579,7 @@ namespace Duplicati.Library.Main
|
||||
public override OperationMode MainOperation { get { return OperationMode.Backup; } }
|
||||
|
||||
public ICompactResults CompactResults { get; internal set; }
|
||||
public IVacuumResults VacuumResults { get; internal set; }
|
||||
public IDeleteResults DeleteResults { get; internal set; }
|
||||
public IRepairResults RepairResults { get; internal set; }
|
||||
public ITestResults TestResults { get; internal set; }
|
||||
@@ -588,6 +589,7 @@ namespace Duplicati.Library.Main
|
||||
get
|
||||
{
|
||||
if ((CompactResults != null && CompactResults.ParsedResult == ParsedResultType.Error) ||
|
||||
(VacuumResults != null && VacuumResults.ParsedResult == ParsedResultType.Error) ||
|
||||
(DeleteResults != null && DeleteResults.ParsedResult == ParsedResultType.Error) ||
|
||||
(RepairResults != null && RepairResults.ParsedResult == ParsedResultType.Error) ||
|
||||
(TestResults != null && TestResults.ParsedResult == ParsedResultType.Error) ||
|
||||
@@ -596,6 +598,7 @@ namespace Duplicati.Library.Main
|
||||
return ParsedResultType.Error;
|
||||
}
|
||||
else if ((CompactResults != null && CompactResults.ParsedResult == ParsedResultType.Warning) ||
|
||||
(VacuumResults != null && VacuumResults.ParsedResult == ParsedResultType.Warning) ||
|
||||
(DeleteResults != null && DeleteResults.ParsedResult == ParsedResultType.Warning) ||
|
||||
(RepairResults != null && RepairResults.ParsedResult == ParsedResultType.Warning) ||
|
||||
(TestResults != null && TestResults.ParsedResult == ParsedResultType.Warning) ||
|
||||
@@ -829,6 +832,8 @@ namespace Duplicati.Library.Main
|
||||
public long UploadedFileSize { get; internal set; }
|
||||
public bool Dryrun { get; internal set; }
|
||||
|
||||
public IVacuumResults VacuumResults { get; internal set; }
|
||||
|
||||
public override OperationMode MainOperation { get { return OperationMode.Compact; } }
|
||||
|
||||
public CompactResults() : base() { }
|
||||
@@ -969,8 +974,11 @@ namespace Duplicati.Library.Main
|
||||
public IEnumerable<string> Lines { get; set; }
|
||||
}
|
||||
|
||||
internal class VacuumResult : BasicResults, IVacuumResults
|
||||
internal class VacuumResults : BasicResults, IVacuumResults
|
||||
{
|
||||
public VacuumResults() : base() { }
|
||||
public VacuumResults(BasicResults p) : base(p) { }
|
||||
|
||||
public override OperationMode MainOperation { get { return OperationMode.Vacuum; } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +282,8 @@ namespace Duplicati.Library.Main.Strings
|
||||
|
||||
public static string AutoCompactIntervalShort { get { return "Minimum time between auto compactions"; } }
|
||||
public static string AutoCompactIntervalLong { get { return "The minimum amount of time that must elapse after the last compaction before another will be automatically triggered at the end of a backup job. Automatic compaction can be a long-running process and may not be desirable to run after every single backup."; } }
|
||||
public static string AutoVacuumIntervalShort { get { return "Minimum time between auto vacuums"; } }
|
||||
public static string AutoVacuumIntervalLong { get { return "The minimum amount of time that must elapse after the last vacuum before another will be automatically triggered at the end of a backup job. Automatic vacuum can be a long-running process and may not be desirable to run after every single backup."; } }
|
||||
}
|
||||
|
||||
internal static class Common
|
||||
|
||||
@@ -492,6 +492,12 @@ namespace Duplicati.Server
|
||||
((RunnerData)data).Controller = controller;
|
||||
data.UpdateThrottleSpeed();
|
||||
|
||||
if (backup.Metadata.ContainsKey("LastCompactFinished"))
|
||||
controller.LastCompact = Library.Utility.Utility.DeserializeDateTime(backup.Metadata["LastCompactFinished"]);
|
||||
|
||||
if (backup.Metadata.ContainsKey("LastVacuumFinished"))
|
||||
controller.LastVacuum = Library.Utility.Utility.DeserializeDateTime(backup.Metadata["LastVacuumFinished"]);
|
||||
|
||||
switch (data.Operation)
|
||||
{
|
||||
case DuplicatiOperation.Backup:
|
||||
@@ -503,9 +509,6 @@ namespace Duplicati.Server
|
||||
where !string.IsNullOrWhiteSpace(p)
|
||||
select p).ToArray();
|
||||
|
||||
if (backup.Metadata.ContainsKey("LastCompactFinished"))
|
||||
controller.LastCompact = Library.Utility.Utility.DeserializeDateTime(backup.Metadata["LastCompactFinished"]);
|
||||
|
||||
var r = controller.Backup(sources, filter);
|
||||
UpdateMetadata(backup, r);
|
||||
return r;
|
||||
@@ -701,7 +704,7 @@ namespace Duplicati.Server
|
||||
);
|
||||
}
|
||||
|
||||
private static void UpdateLastCompactMetadata(Duplicati.Server.Serialization.Interface.IBackup backup, Duplicati.Library.Interface.ICompactResults r)
|
||||
private static void UpdateMetadataLastCompact(Duplicati.Server.Serialization.Interface.IBackup backup, Duplicati.Library.Interface.ICompactResults r)
|
||||
{
|
||||
if (r != null)
|
||||
{
|
||||
@@ -711,6 +714,16 @@ namespace Duplicati.Server
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMetadataLastVacuum(Duplicati.Server.Serialization.Interface.IBackup backup, Duplicati.Library.Interface.IVacuumResults r)
|
||||
{
|
||||
if (r != null)
|
||||
{
|
||||
backup.Metadata["LastVacuumDuration"] = r.Duration.ToString();
|
||||
backup.Metadata["LastVacuumStarted"] = Library.Utility.Utility.SerializeDateTime(r.BeginTime.ToUniversalTime());
|
||||
backup.Metadata["LastVacuumFinished"] = Library.Utility.Utility.SerializeDateTime(r.EndTime.ToUniversalTime());
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMetadata(Duplicati.Server.Serialization.Interface.IBackup backup, Duplicati.Library.Interface.IParsedBackendStatistics r)
|
||||
{
|
||||
if (r != null)
|
||||
@@ -751,7 +764,19 @@ namespace Duplicati.Server
|
||||
}
|
||||
|
||||
if (result is Duplicati.Library.Interface.ICompactResults)
|
||||
UpdateLastCompactMetadata(backup, (Duplicati.Library.Interface.ICompactResults)result);
|
||||
{
|
||||
var r = (Duplicati.Library.Interface.ICompactResults)result;
|
||||
UpdateMetadataLastCompact(backup, r);
|
||||
|
||||
if (r.VacuumResults != null)
|
||||
UpdateMetadataLastVacuum(backup, r.VacuumResults);
|
||||
}
|
||||
|
||||
if (result is Duplicati.Library.Interface.IVacuumResults)
|
||||
{
|
||||
var r = (Duplicati.Library.Interface.IVacuumResults)result;
|
||||
UpdateMetadataLastVacuum(backup, r);
|
||||
}
|
||||
|
||||
if (result is Duplicati.Library.Interface.IBackupResults)
|
||||
{
|
||||
@@ -764,7 +789,10 @@ namespace Duplicati.Server
|
||||
backup.Metadata["LastBackupDuration"] = r.Duration.ToString();
|
||||
|
||||
if (r.CompactResults != null)
|
||||
UpdateLastCompactMetadata(backup, r.CompactResults);
|
||||
UpdateMetadataLastCompact(backup, r.CompactResults);
|
||||
|
||||
if (r.VacuumResults != null)
|
||||
UpdateMetadataLastVacuum(backup, r.VacuumResults);
|
||||
|
||||
if (r.FilesWithError > 0 || r.Warnings.Any() || r.Errors.Any())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user