[kernel32.dll]CreateHardLink den Fehler "kann Nicht erstellen Sie eine Datei, wenn diese Datei bereits vorhanden ist" auf der Azure-Webseite während der RavenDb Embedded backup

StackOverflow https://stackoverflow.com//questions/23041289

Frage

Ich bin mit RavenDb.Embedded v2.0.2370 innerhalb einer Azure-Website.

All dies funktioniert wie erwartet, außer für die Sicherung.Die backup-routine eingeleitet mit EmbeddableDocumentStore.DocumentDatabase.StartBackup(...) verwendet, um die Arbeit perfekt bis ich bemerkte, dass die Letzte erfolgreiche Sicherung, Termine rund um den 30. Januar (nicht Fragen :-)) um 6 Uhr UTC0 und dass die nächste Sicherung gestartet wurde am 11. Februar um 8 UHR UTC0 gescheitert, wie alle die anderen, eingeleitet, danach bis heute.

Es scheint also, dass sich etwas geändert haben zwischen diesen 2 Termine auf der Seite Azure, da es keine änderungen oder Implementierungen der web-Anwendung, die seit Mai 2013

So habe ich einige Untersuchungen und hier sind meine Ergebnisse:

  • Die RavenDb-backup-status zeigt die folgende Meldung nach jedem initiierten Backups:

    Fehler beim vollständigen backup, denn:Kann nicht erstellen Sie eine Datei, wenn diese Datei bereits vorhanden ist

  • Nach aktivieren der Protokollierung für RavenDb die Protokolldatei enthält den folgenden Fehler beim ausführen der Sicherung

    2014-04-12 10:38:20.5797,Raven.Storage.Esent.Sicherung.BackupOperation,Fehler,Failed to complete backup" - System.ComponentModel.Win32Exception (0 x 80004005):Kann nicht erstellen Sie eine Datei, wenn diese Datei bereits vorhanden ist bei Raven.Datenbank.Sicherung.DirectoryBackup.Vorbereiten() bei Raven.Storage.Esent.Sicherung.BackupOperation.Execute(Object ignored)

  • Nach der Azure-Web-Sites-forum es wurden keine geplant Wartung der Azure-Web-Sites in der Zeit zwischen dem letzten erfolgreichen und dem ersten Versagen backup.Es wurden zwischen 9-15 Dezember 2013 und zwischen 10-14 März 2014

  • Ich habe bemerkt, auf der Azure Service Dashboard ein Problem mit der Web-Seiten, auf die 31ten Januar im Westen der europäischen Region, aber Sie die Website gehostet wird, in der nordeuropäischen Region

  • Wenn Suche (auch in der letzten version) am Fehler RavenDb-code Raven.Database.Backup.DirectoryBackup.Prepare es scheint, dass die Ausnahme wird ausgelöst, wenn Aufruf CreateHardLink was ist eine externe Methode definiert als

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
    

    Das merkwürdige ist, dass der code tatsächlich überprüft, für die spezifische Ausnahme, die oben gezeigt (0 x 80004005), doch die Ausnahme ist immer noch geworfen...

    if (Marshal.GetLastWin32Error() != 0x80004005)
      throw new Win32Exception();
    
  • So ausschließen, dass RavenDb aus der Gleichung, ich habe das folgende kleine Programm simuliert, dass RavenDb tatsächlich tun, während der backup-routine, und nach bereitstellen der ausführbaren Datei und ausführen (über die Console-Funktion finden Sie auf der neue azure-portal), die auf der Azure-Website es fehlschlägt:

    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);
                }
            }
        }
    }
    
  • Ausschließen meiner web-Anwendung aus der Gleichung als gut, ich habe eine neue Azure-Website und implementiert die gleiche ausführbare Datei, die oben erwähnt und es fehlschlägt

  • Es ist fair zu übernehmen, dass Sie noch nicht laufen auf ReFS (die nicht Unterstützung von hard links), sondern sind noch mit NTFS?

tl;dr

  • Was hat sich geändert auf Azure-Websites, die einen Aufruf von [kernel32.dll]CreateHardLink nicht während es verwendet, um die Arbeit vor?

  • Wie kann dies behoben werden außerhalb RavenDb-code oder innerhalb RavenDb-code...?

War es hilfreich?

Lösung

Update: dieses Problem ist nun behoben. CreateHardLink sollte Arbeit mit D:\home Pfade.

Ich denke, dass es ein Problem mit Azure-Websites.Im Grunde, wenn Sie versuchen, erstellen Sie einen relativen Pfad standardmäßig D:\home\.Dieser Ordner eigentlich nicht auf dem Computer vorhanden, aber Azure Websites fakes es für die Bequemlichkeit.Aber hier scheint es die Ursache des Problems mit CreateHardLink Funktion.

wenn Sie ändern Sie einfach diese Zeile in Ihrem Beispiel oben

const string tempPath = "TestTemp";

zu diesem

const string tempPath = @"C:\DWASFiles\Sites\<sitename>\VirtualDirectory0\site\TestTemp";

ersetzen <sitename> mit Ihren site-Namen

es wird funktionieren.

Ich bin nicht wirklich vertraut mit RavenDb, aber als Problemumgehung können Sie versuchen, ändern Sie diese Verzeichnisse in der vollständigen Pfade, die Aussehen wie die oben.Ich werde berichten, die Fehler in der Zwischenzeit.Lassen Sie mich wissen, ob das für Sie funktioniert

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top