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