我在 Azure 网站内运行 RavenDb.Embedded v2.0.2370。
除了备份之外,所有这些都按预期工作。启动的备份例程EmbeddableDocumentStore.DocumentDatabase.StartBackup(...)
曾经完美运行,直到我注意到最后一次成功的备份是在 1 月 30 日左右(不要问 :-)) UTC0 下午 6 点左右,而下一次备份是在 2 月 11 日左右启动的UTC0 上午 8 点失败,直到现在为止启动的所有其他失败。
因此,Azure 方面的这两个日期之间似乎必须进行某些更改,因为自 2013 年 5 月以来 Web 应用程序没有任何更改或部署
所以我做了一些调查,这是我的发现:
RavenDb 备份状态在每次启动备份后显示以下消息:
无法完成备份,因为:当该文件已存在时无法创建该文件
为RavenDb启用日志记录后,日志文件在运行备份时显示以下错误
2014-04-12 10:38:20.5797,Raven.Storage.Esent.Backup.BackupOperation,错误,无法完成备份,“System.ComponentModel.Win32Exception (0x80004005):当该文件已存在于 Raven 时,无法创建该文件。 Raven.Storage.Esent.Backup.BackupOperation.Execute 的 Database.Backup.DirectoryBackup.Prepare()(忽略对象)
根据Azure 网站论坛,在上次成功备份和第一次失败备份之间的这段时间里,没有计划对 Azure 网站进行维护。2013 年 12 月 9 日至 15 日和 2014 年 3 月 10 日至 14 日之间
1 月 31 日,我在Azure 服务仪表板上注意到西欧地区的网站存在问题,但该网站托管在北欧地区
在查看(甚至是最后一个版本)有故障的RavenDb代码
Raven.Database.Backup.DirectoryBackup.Prepare
时,似乎在调用时抛出了异常,CreateHardLink
这是一个定义为的外部方法[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
奇怪的是,代码实际上检查了上面显示的特定异常(0x80004005),但仍然抛出异常......
if (Marshal.GetLastWin32Error() != 0x80004005) throw new Win32Exception();
因此,为了从等式中排除 RavenDb,我创建了以下小程序来模拟 RavenDb 在其备份例程期间以及在Azure Web 上部署可执行文件并执行它(通过新的 azure 门户上的控制台功能)之后实际执行的操作网站也失败了:
using System; using System.ComponentModel; using System.IO; using System.Runtime.InteropServices; namespace HardLinkCreationTester { public class Program { [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); static void Main() { const string sourcePath = "TestSource"; const string targetPath = "TestTarget"; const string tempPath = "TestTemp"; try { Directory.CreateDirectory(sourcePath); Directory.CreateDirectory(targetPath); Directory.CreateDirectory(tempPath); File.WriteAllText(Path.Combine(sourcePath, "testfile.txt"), "Test content"); string[] sourceFilesSnapshot = Directory.GetFiles(sourcePath); for (int index = 0; index < sourceFilesSnapshot.Length; index++) { var sourceFile = sourceFilesSnapshot[index]; var destFileName = Path.Combine(tempPath, Path.GetFileName(sourceFile)); if (!CreateHardLink(destFileName, sourceFile, IntPtr.Zero)) { // 'The system cannot find the file specified' is explicitly ignored here if (Marshal.GetLastWin32Error() != 0x80004005) throw new Win32Exception(); } } } finally { Directory.Delete(sourcePath); Directory.Delete(targetPath); Directory.Delete(tempPath); } } } }
为了从等式中排除我的特定 Web 应用程序,我创建了一个新的 Azure 网站并部署了上述相同的可执行文件,但它也失败了
可以公平地假设它们尚未在 ReFS(不支持硬链接)上运行但仍在使用 NTFS?
tl;博士
Azure 网站上发生了什么变化,导致调用
[kernel32.dll]CreateHardLink
失败,而它以前可以工作?如何在 RavenDb 代码外部或 RavenDb 代码内部解决此问题...?