diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
index e38464f5df..a4b4d35d10 100644
--- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
+++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
@@ -14,6 +14,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using umbraco.interfaces;
+using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Sync
{
@@ -277,12 +278,42 @@ namespace Umbraco.Core.Sync
}
///
- /// Remove old instructions from the database.
+ /// Remove old instructions from the database
///
+ ///
+ /// Always leave the last (most recent) record in the db table, this is so that not all instructions are removed which would cause
+ /// the site to cold boot if there's been no instruction activity for more than DaysToRetainInstructions.
+ /// See: http://issues.umbraco.org/issue/U4-7643#comment=67-25085
+ ///
private void PruneOldInstructions()
{
- _appContext.DatabaseContext.Database.Delete("WHERE utcStamp < @pruneDate",
- new { pruneDate = DateTime.UtcNow.AddDays(-_options.DaysToRetainInstructions) });
+ var pruneDate = DateTime.UtcNow.AddDays(-_options.DaysToRetainInstructions);
+ var sqlSyntax = _appContext.DatabaseContext.SqlSyntax;
+
+ //NOTE: this query could work on SQL server and MySQL:
+ /*
+ SELECT id
+ FROM umbracoCacheInstruction
+ WHERE utcStamp < getdate()
+ AND id <> (SELECT MAX(id) FROM umbracoCacheInstruction)
+ */
+ // However, this will not work on SQLCE and in fact it will be slower than the query we are
+ // using if the SQL server doesn't perform it's own query optimizations (i.e. since the above
+ // query could actually execute a sub query for every row found). So we've had to go with an
+ // inner join which is faster and works on SQLCE but it's uglier to read.
+
+ var deleteQuery = new Sql().Select("cacheIns.id")
+ .From("umbracoCacheInstruction cacheIns")
+ .InnerJoin("(SELECT MAX(id) id FROM umbracoCacheInstruction) tMax")
+ .On("cacheIns.id <> tMax.id")
+ .Where("cacheIns.utcStamp < @pruneDate", new {pruneDate = pruneDate});
+
+ var deleteSql = sqlSyntax.GetDeleteSubquery(
+ "umbracoCacheInstruction",
+ "id",
+ deleteQuery);
+
+ _appContext.DatabaseContext.Database.Execute(deleteSql);
}
///
@@ -298,8 +329,9 @@ namespace Umbraco.Core.Sync
.Where(dto => dto.Id == _lastId);
var dtos = _appContext.DatabaseContext.Database.Fetch(sql);
+
if (dtos.Count == 0)
- _lastId = -1;
+ _lastId = -1;
}
///
@@ -469,4 +501,5 @@ namespace Umbraco.Core.Sync
#endregion
}
-}
\ No newline at end of file
+}
+
\ No newline at end of file