/// <summary> /// Recreate database using empty LOG file to re-write all documents with all indexes /// </summary> public long Rebuild(RebuildOptions options) { _walIndex.Checkpoint(false); if (_disk.GetLength(FileOrigin.Log) > 0) { throw new LiteException(0, "Rebuild operation requires no log file - run Checkpoint before continue"); } _locker.EnterReserved(true); var originalLength = _disk.GetLength(FileOrigin.Data); // create a savepoint in header page - restore if any error occurs var savepoint = _header.Savepoint(); // must clear all cache pages because all of them will change _disk.Cache.Clear(); try { // initialize V8 file reader using (var reader = new FileReaderV8(_header, _disk)) { // clear current header _header.FreeEmptyPageList = uint.MaxValue; _header.LastPageID = 0; _header.GetCollections().ToList().ForEach(c => _header.DeleteCollection(c.Key)); // override collation _header.Pragmas.Set("COLLATION", options.Collation.ToString(), false); // rebuild entrie database using FileReader this.RebuildContent(reader); // change password (can be a problem if any error occurs after here) _disk.ChangePassword(options.Password, _settings); // exit reserved before checkpoint _locker.ExitReserved(true); // do checkpoint _walIndex.Checkpoint(false); // get new filelength to compare var newLength = _disk.GetLength(FileOrigin.Data); return(originalLength - newLength); } } catch (Exception) { _header.Restore(savepoint); _locker.ExitReserved(true); throw; } }
/// <summary> /// Rebuild database removing all empty pages. /// </summary> public static long Shrink(string filename, string password = null, string newPassword = null) { var logFile = FileHelper.GetLogFile(filename); // first step: if there is log file, runs checkpoint first if (File.Exists(logFile)) { using (var e = new LiteEngine(new EngineSettings { Filename = filename, Password = password })) { e.Checkpoint(); } } // getting original file length var originalLength = new FileInfo(filename).Length; // create new empty log file using (var log = new FileStream(logFile, FileMode.CreateNew)) { // configure a new engine instance to works with 1 page in memory (data) and all data into log file var settings = new EngineSettings { DataStream = new MemoryStream(), LogStream = log, Password = newPassword }; // now, copy all reader into this new engine using (var e = new LiteEngine(settings)) using (var reader = new FileReaderV8(filename, password)) { e.Rebuild(reader); } // now i can shrink my data file to same size as new log using (var f = new FileStream(filename, FileMode.Open)) { f.SetLength(log.Length); } } // open again database to run last checkpoint and update all datafile using (var e = new LiteEngine(new EngineSettings { Filename = filename, Password = newPassword })) { e.Checkpoint(); } // return shrink size (in bytes) return(originalLength - (new FileInfo(filename).Length)); }
/// <summary> /// </summary> public long Shrink() { _walIndex.Checkpoint(false); if (_disk.GetLength(FileOrigin.Log) > 0) { throw new LiteException(0, "Shrink operation requires no log file - run Checkpoint before continue"); } _locker.EnterReserved(true); var originalLength = _disk.GetLength(FileOrigin.Data); // create a savepoint in header page - restore if any error occurs var savepoint = _header.Savepoint(); // must clear all cache pages because all of them will change _disk.Cache.Clear(); try { // initialize V8 file reader using (var reader = new FileReaderV8(_header, _disk)) { // clear current header _header.FreeEmptyPageID = uint.MaxValue; _header.LastPageID = 0; _header.GetCollections().ToList().ForEach(c => _header.DeleteCollection(c.Key)); // rebuild entrie database using FileReader this.Rebuild(reader); // crop data file var newLength = BasePage.GetPagePosition(_header.LastPageID); _disk.SetLength(newLength, FileOrigin.Data); return(originalLength - newLength); } } catch (Exception) { _header.Restore(savepoint); throw; } finally { _locker.ExitReserved(true); _walIndex.Checkpoint(false); } }
/// <summary> /// Recreate database using empty LOG file to re-write all documents with all indexes /// </summary> public long Rebuild(RebuildOptions options) { // enter database in exclusive mode var mustExit = _locker.EnterExclusive(); // get a header backup/savepoint before change PageBuffer savepoint = null; try { // do a checkpoint before starts _walIndex.Checkpoint(); var originalLength = _disk.GetLength(FileOrigin.Data); // create a savepoint in header page - restore if any error occurs savepoint = _header.Savepoint(); // must clear all cache pages because all of them will change _disk.Cache.Clear(); // must check if there is no data log if (_disk.GetLength(FileOrigin.Log) > 0) { throw new LiteException(0, "Rebuild operation requires no log file - run Checkpoint before continue"); } // initialize V8 file reader var reader = new FileReaderV8(_header, _disk); // clear current header _header.FreeEmptyPageList = uint.MaxValue; _header.LastPageID = 0; _header.GetCollections().ToList().ForEach(c => _header.DeleteCollection(c.Key)); // override collation pragma if (options?.Collation != null) { _header.Pragmas.Set(Pragmas.COLLATION, options.Collation.ToString(), false); } // rebuild entrie database using FileReader this.RebuildContent(reader); // change password (can be a problem if any error occurs after here) if (options != null) { _disk.ChangePassword(options.Password, _settings); } // do checkpoint _walIndex.Checkpoint(); // set new fileLength _disk.SetLength((_header.LastPageID + 1) * PAGE_SIZE, FileOrigin.Data); // get new filelength to compare var newLength = _disk.GetLength(FileOrigin.Data); return(originalLength - newLength); } catch { if (savepoint != null) { _header.Restore(savepoint); } throw; } finally { if (mustExit) { _locker.ExitExclusive(); } } }
/// <summary> /// Recreate database using empty LOG file to re-write all documents with all indexes /// </summary> public long Rebuild(RebuildOptions options) { // enter database in exclusive mode var lockWasTaken = _locker.EnterExclusive(); // get a header backup/savepoint before change PageBuffer savepoint = null; try { // do a checkpoint before starts _walIndex.Checkpoint(false, true); var originalLength = (_header.LastPageID + 1) * PAGE_SIZE; // must clear all cache pages because all of them will change _disk.Cache.Clear(); // create a savepoint in header page - restore if any error occurs savepoint = _header.Savepoint(); // initialize V8 file reader var reader = new FileReaderV8(_header, _disk); // clear current header _header.FreeEmptyPageList = uint.MaxValue; _header.LastPageID = 0; _header.GetCollections().ToList().ForEach(c => _header.DeleteCollection(c.Key)); // override collation pragma if (options?.Collation != null) { _header.Pragmas.Set(Pragmas.COLLATION, options.Collation.ToString(), false); } // rebuild entrie database using FileReader this.RebuildContent(reader); // do checkpoint _walIndex.Checkpoint(false, true); // override header page _disk.Write(new[] { _header.UpdateBuffer() }); // if options are defined, change password (if change also) if (options != null) { _disk.ChangePassword(options.Password, _settings); } // <<<<<<< HEAD // ======= // // do checkpoint // _walIndex.Checkpoint(); // // // override header page // _disk.Write(new[] { _header.UpdateBuffer() }, FileOrigin.Data); // // // set new fileLength // _disk.SetLength((_header.LastPageID + 1) * PAGE_SIZE, FileOrigin.Data); // // >>>>>>> master // get new filelength to compare var newLength = (_header.LastPageID + 1) * PAGE_SIZE; return(originalLength - newLength); } catch { if (savepoint != null) { _header.Restore(savepoint); } throw; } finally { if (lockWasTaken) { _locker.ExitExclusive(); } } }