public override IVirtualPager OpenJournalPager(long journalNumber) { var name = JournalName(journalNumber); var path = Path.Combine(_journalPath, name); var fileInfo = new FileInfo(path); if (fileInfo.Exists == false) { throw new InvalidOperationException("No such journal " + path); } if (fileInfo.Length < InitialLogFileSize) { EnsureMinimumSize(fileInfo, path); } if (RunningOnPosix) { return(new PosixMemoryMapPager(path)); } var win32MemoryMapPager = new Win32MemoryMapPager(path, access: Win32NativeFileAccess.GenericRead, options: Win32NativeFileAttributes.SequentialScan); win32MemoryMapPager.TryPrefetchingWholeFile(); return(win32MemoryMapPager); }
public override AbstractPager OpenJournalPager(long journalNumber) { var name = JournalName(journalNumber); var path = Path.Combine(_journalPath, name); if (File.Exists(path) == false) { throw new InvalidOperationException("No such journal " + path); } if (RunningOnPosix) { return(new PosixMemoryMapPager(PageSize, path)); } var win32MemoryMapPager = new Win32MemoryMapPager(PageSize, path, access: Win32NativeFileAccess.GenericRead, options: Win32NativeFileAttributes.SequentialScan); win32MemoryMapPager.TryPrefetchingWholeFile(); return(win32MemoryMapPager); }
private void Restore(StorageEnvironment env, string singleBackupFile) { using (env.Journal.Applicator.TakeFlushingLock()) { using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { using (env.Options.AllowManualFlushing()) { env.FlushLogToDataFile(txw); } using (var package = ZipFile.Open(singleBackupFile, ZipArchiveMode.Read)) { if (package.Entries.Count == 0) { return; } var toDispose = new List <IDisposable>(); var tempDir = Directory.CreateDirectory(Path.GetTempPath() + Guid.NewGuid()).FullName; try { TransactionHeader *lastTxHeader = null; var pagesToWrite = new Dictionary <long, Func <Page> >(); long journalNumber = -1; foreach (var entry in package.Entries) { switch (Path.GetExtension(entry.Name)) { case ".journal": var jounalFileName = Path.Combine(tempDir, entry.Name); using (var output = new FileStream(jounalFileName, FileMode.Create)) using (var input = entry.Open()) { output.Position = output.Length; input.CopyTo(output); } var pager = new Win32MemoryMapPager(jounalFileName); toDispose.Add(pager); if (long.TryParse(Path.GetFileNameWithoutExtension(entry.Name), out journalNumber) == false) { throw new InvalidOperationException("Cannot parse journal file number"); } var recoveryPager = new Win32MemoryMapPager(Path.Combine(tempDir, StorageEnvironmentOptions.JournalRecoveryName(journalNumber))); toDispose.Add(recoveryPager); var reader = new JournalReader(pager, recoveryPager, 0, lastTxHeader); while (reader.ReadOneTransaction(env.Options)) { lastTxHeader = reader.LastTransactionHeader; } foreach (var translation in reader.TransactionPageTranslation) { var pageInJournal = translation.Value.JournalPos; pagesToWrite[translation.Key] = () => recoveryPager.Read(pageInJournal); } break; default: throw new InvalidOperationException("Unknown file, cannot restore: " + entry); } } var sortedPages = pagesToWrite.OrderBy(x => x.Key) .Select(x => x.Value()) .ToList(); if (sortedPages.Count == 0) { return; } var last = sortedPages.Last(); env.Options.DataPager.EnsureContinuous(txw, last.PageNumber, last.IsOverflow ? env.Options.DataPager.GetNumberOfOverflowPages( last.OverflowSize) : 1); foreach (var page in sortedPages) { env.Options.DataPager.Write(page); } env.Options.DataPager.Sync(); txw.State.Root = Tree.Open(txw, &lastTxHeader->Root); txw.State.FreeSpaceRoot = Tree.Open(txw, &lastTxHeader->FreeSpace); txw.State.FreeSpaceRoot.Name = Constants.FreeSpaceTreeName; txw.State.Root.Name = Constants.RootTreeName; txw.State.NextPageNumber = lastTxHeader->LastPageNumber + 1; env.Journal.Clear(txw); txw.Commit(); env.HeaderAccessor.Modify(header => { header->TransactionId = lastTxHeader->TransactionId; header->LastPageNumber = lastTxHeader->LastPageNumber; header->Journal.LastSyncedJournal = journalNumber; header->Journal.LastSyncedTransactionId = lastTxHeader->TransactionId; header->Root = lastTxHeader->Root; header->FreeSpace = lastTxHeader->FreeSpace; header->Journal.CurrentJournal = journalNumber + 1; header->Journal.JournalFilesCount = 0; }); } finally { toDispose.ForEach(x => x.Dispose()); try { Directory.Delete(tempDir, true); } catch (Exception) { // just temp dir - ignore it } } } } } }
private void Restore(StorageEnvironment env, string backupPath) { using (env.Journal.Applicator.TakeFlushingLock()) { using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { using (env.Options.AllowManualFlushing()) { env.FlushLogToDataFile(txw); } List <string> journalNames; using (var package = ZipFile.Open(backupPath, ZipArchiveMode.Read)) { journalNames = package.Entries.Select(x => x.Name).ToList(); } if (journalNames.Count == 0) { return; } var tempDir = Directory.CreateDirectory(Path.GetTempPath() + Guid.NewGuid()).FullName; var toDispose = new List <IDisposable>(); try { ZipFile.ExtractToDirectory(backupPath, tempDir); TransactionHeader *lastTxHeader = null; var pagesToWrite = new Dictionary <long, Func <Page> >(); long journalNumber = -1; foreach (var journalName in journalNames) { var pager = new Win32MemoryMapPager(Path.Combine(tempDir, journalName)); toDispose.Add(pager); if (long.TryParse(journalName.Replace(".journal", string.Empty), out journalNumber) == false) { throw new InvalidOperationException("Cannot parse journal file number"); } var recoveryPager = new Win32MemoryMapPager(Path.Combine(tempDir, StorageEnvironmentOptions.JournalRecoveryName(journalNumber))); toDispose.Add(recoveryPager); var reader = new JournalReader(pager, recoveryPager, 0, lastTxHeader); while (reader.ReadOneTransaction(env.Options)) { lastTxHeader = reader.LastTransactionHeader; } foreach (var translation in reader.TransactionPageTranslation) { var pageInJournal = translation.Value.JournalPos; pagesToWrite[translation.Key] = () => recoveryPager.Read(pageInJournal); } } var sortedPages = pagesToWrite.OrderBy(x => x.Key) .Select(x => x.Value()) .ToList(); var last = sortedPages.Last(); env.Options.DataPager.EnsureContinuous(txw, last.PageNumber, last.IsOverflow ? env.Options.DataPager.GetNumberOfOverflowPages( last.OverflowSize) : 1); foreach (var page in sortedPages) { env.Options.DataPager.Write(page); } env.Options.DataPager.Sync(); txw.State.Root = Tree.Open(txw, env._sliceComparer, &lastTxHeader->Root); txw.State.FreeSpaceRoot = Tree.Open(txw, env._sliceComparer, &lastTxHeader->FreeSpace); txw.State.FreeSpaceRoot.Name = Constants.FreeSpaceTreeName; txw.State.Root.Name = Constants.RootTreeName; txw.State.NextPageNumber = lastTxHeader->LastPageNumber + 1; env.Journal.Clear(txw); txw.Commit(); env.HeaderAccessor.Modify(header => { header->TransactionId = lastTxHeader->TransactionId; header->LastPageNumber = lastTxHeader->LastPageNumber; header->Journal.LastSyncedJournal = journalNumber; header->Journal.LastSyncedTransactionId = lastTxHeader->TransactionId; header->Root = lastTxHeader->Root; header->FreeSpace = lastTxHeader->FreeSpace; header->Journal.CurrentJournal = journalNumber + 1; header->Journal.JournalFilesCount = 0; }); } finally { toDispose.ForEach(x => x.Dispose()); Directory.Delete(tempDir, true); } } } }
private void Restore(StorageEnvironment env, string singleBackupFile) { using (env.Journal.Applicator.TakeFlushingLock()) { using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { using (env.Options.AllowManualFlushing()) { env.FlushLogToDataFile(txw); } using (var package = ZipFile.Open(singleBackupFile, ZipArchiveMode.Read)) { if (package.Entries.Count == 0) return; var toDispose = new List<IDisposable>(); var tempDir = Directory.CreateDirectory(Path.GetTempPath() + Guid.NewGuid()).FullName; try { TransactionHeader* lastTxHeader = null; var pagesToWrite = new Dictionary<long, Page>(); long journalNumber = -1; foreach (var entry in package.Entries) { switch (Path.GetExtension(entry.Name)) { case ".journal": var jounalFileName = Path.Combine(tempDir, entry.Name); using (var output = new FileStream(jounalFileName, FileMode.Create)) using (var input = entry.Open()) { output.Position = output.Length; input.CopyTo(output); } var pager = new Win32MemoryMapPager(jounalFileName); toDispose.Add(pager); if (long.TryParse(Path.GetFileNameWithoutExtension(entry.Name), out journalNumber) == false) { throw new InvalidOperationException("Cannot parse journal file number"); } var recoveryPager = new Win32MemoryMapPager(Path.Combine(tempDir, StorageEnvironmentOptions.JournalRecoveryName(journalNumber))); toDispose.Add(recoveryPager); var reader = new JournalReader(pager, recoveryPager, 0, lastTxHeader); while (reader.ReadOneTransaction(env.Options)) { lastTxHeader = reader.LastTransactionHeader; } foreach (var translation in reader.TransactionPageTranslation) { var pageInJournal = translation.Value.JournalPos; var page = recoveryPager.Read(pageInJournal); pagesToWrite[translation.Key] = page; if (page.IsOverflow) { var numberOfOverflowPages = recoveryPager.GetNumberOfOverflowPages(page.OverflowSize); for (int i = 1; i < numberOfOverflowPages; i++) { pagesToWrite.Remove(translation.Key + i); } } } break; default: throw new InvalidOperationException("Unknown file, cannot restore: " + entry); } } var sortedPages = pagesToWrite.OrderBy(x => x.Key) .Select(x => x.Value) .ToList(); if (sortedPages.Count == 0) { return; } var last = sortedPages.Last(); env.Options.DataPager.EnsureContinuous(txw, last.PageNumber, last.IsOverflow ? env.Options.DataPager.GetNumberOfOverflowPages( last.OverflowSize) : 1); foreach (var page in sortedPages) { env.Options.DataPager.Write(page); } env.Options.DataPager.Sync(); txw.State.Root = Tree.Open(txw, &lastTxHeader->Root); txw.State.FreeSpaceRoot = Tree.Open(txw, &lastTxHeader->FreeSpace); txw.State.FreeSpaceRoot.Name = Constants.FreeSpaceTreeName; txw.State.Root.Name = Constants.RootTreeName; txw.State.NextPageNumber = lastTxHeader->LastPageNumber + 1; env.Journal.Clear(txw); txw.Commit(); env.HeaderAccessor.Modify(header => { header->TransactionId = lastTxHeader->TransactionId; header->LastPageNumber = lastTxHeader->LastPageNumber; header->Journal.LastSyncedJournal = journalNumber; header->Journal.LastSyncedTransactionId = lastTxHeader->TransactionId; header->Root = lastTxHeader->Root; header->FreeSpace = lastTxHeader->FreeSpace; header->Journal.CurrentJournal = journalNumber + 1; header->Journal.JournalFilesCount = 0; }); } finally { toDispose.ForEach(x => x.Dispose()); try { Directory.Delete(tempDir, true); } catch (Exception) { // just temp dir - ignore it } } } } } }
public static void Main() { var basePath = @"C:\Work\ravendb-3.0\Raven.Voron\Voron.Tryout\bin\Debug\v4"; var win = new Win32MemoryMapPager(Path.Combine(basePath, "v2", "Raven.voron")); var lin = new Win32MemoryMapPager(Path.Combine(basePath, "v2l", "Raven.voron")); var winPage = (PageHeader *)win.AcquirePagePointer(0); var linPage = (PageHeader *)lin.AcquirePagePointer(0); return; var path = "v4"; if (Directory.Exists(path)) { Directory.Delete(path, true); } Console.WriteLine(Process.GetCurrentProcess().Id); using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(path))) { var batch = new WriteBatch(); batch.Add("*****@*****.**", "Oren Eini", "Names"); env.Writer.Write(batch); using (var snp = env.CreateSnapshot()) { var reader = snp.Read("Names", "*****@*****.**"); if (reader == null) { Console.WriteLine("Couldn't find it"); } else { Console.WriteLine(reader.Reader.ToStringValue()); } } } using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(path))) { // using (var snp = env.CreateSnapshot()) // { // var reader = snp.Read ("Names", "*****@*****.**"); // if (reader == null) // { // Console.WriteLine ("Couldn't find it"); // } // else // { // Console.WriteLine (reader.Reader.ToStringValue()); // } // } } using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(path))) { using (var snp = env.CreateSnapshot()) { var reader = snp.Read("Names", "*****@*****.**"); if (reader == null) { Console.WriteLine("Couldn't find it"); } else { Console.WriteLine(reader.Reader.ToStringValue()); } } } Console.WriteLine("Done"); }
public override IVirtualPager OpenJournalPager(long journalNumber) { var name = JournalName(journalNumber); var path = Path.Combine(_journalPath, name); if (File.Exists(path) == false) throw new InvalidOperationException("No such journal " + path); if (RunningOnPosix) return new PosixMemoryMapPager(path); var win32MemoryMapPager = new Win32MemoryMapPager(path, access: Win32NativeFileAccess.GenericRead, options:Win32NativeFileAttributes.SequentialScan); win32MemoryMapPager.TryPrefetchingWholeFile(); return win32MemoryMapPager; }