Example #1
0
        public static Tree GetTree(this StorageEnvironmentState state, Transaction tx, string treeName)
        {
            if (String.IsNullOrEmpty(treeName))
            {
                throw new InvalidOperationException("Cannot fetch tree with empty name");
            }

            if (treeName.Equals(Constants.RootTreeName, StringComparison.InvariantCultureIgnoreCase))
            {
                return(state.Root);
            }

            if (treeName.Equals(Constants.FreeSpaceTreeName, StringComparison.InvariantCultureIgnoreCase))
            {
                return(state.FreeSpaceRoot);
            }


            Tree tree = tx.ReadTree(treeName);

            if (tree != null)
            {
                return(tree);
            }

            if (tx.Flags == TransactionFlags.ReadWrite)
            {
                return(tx.Environment.CreateTree(tx, treeName));
            }

            throw new InvalidOperationException("No such tree: " + treeName);
        }
        private unsafe void LoadExistingDatabase()
        {
            var  header             = stackalloc TransactionHeader[1];
            bool hadIntegrityIssues = _journal.RecoverDatabase(header);

            if (hadIntegrityIssues)
            {
                var message = _journal.Files.Count == 0 ? "Unrecoverable database" : "Database recovered partially. Some data was lost.";

                _options.InvokeRecoveryError(this, message, null);
            }

            var entry          = _headerAccessor.CopyHeader();
            var nextPageNumber = (header->TransactionId == 0 ? entry.LastPageNumber : header->LastPageNumber) + 1;

            State = new StorageEnvironmentState(null, null, nextPageNumber)
            {
                NextPageNumber = nextPageNumber
            };

            _transactionsCounter = (header->TransactionId == 0 ? entry.TransactionId : header->TransactionId);

            using (var tx = NewTransaction(TransactionFlags.ReadWrite))
            {
                var root      = Tree.Open(tx, header->TransactionId == 0 ? &entry.Root : &header->Root);
                var freeSpace = Tree.Open(tx, header->TransactionId == 0 ? &entry.FreeSpace : &header->FreeSpace);

                tx.UpdateRootsIfNeeded(root, freeSpace);
                tx.Commit();
            }
        }
Example #3
0
        private void CreateNewDatabase()
        {
            const int initialNextPageNumber = 0;

            State = new StorageEnvironmentState(null, initialNextPageNumber)
            {
                Options = Options
            };

            var transactionPersistentContext = new TransactionPersistentContext();

            using (var tx = NewLowLevelTransaction(transactionPersistentContext, TransactionFlags.ReadWrite))
                using (var root = Tree.Create(tx, null, Constants.RootTreeNameSlice))
                {
                    // important to first create the root trees, then set them on the env
                    tx.UpdateRootsIfNeeded(root);

                    using (var treesTx = new Transaction(tx))
                    {
                        DbId = Guid.NewGuid();
                        FillBase64Id(DbId);

                        var metadataTree = treesTx.CreateTree(Constants.MetadataTreeNameSlice);
                        metadataTree.Add("db-id", DbId.ToByteArray());
                        metadataTree.Add("schema-version", EndianBitConverter.Little.GetBytes(Options.SchemaVersion));

                        treesTx.PrepareForCommit();

                        tx.Commit();
                    }
                }
        }
Example #4
0
        private unsafe void CreateNewDatabase()
        {
            const int initialNextPageNumber = 0;

            State = new StorageEnvironmentState(null, null, initialNextPageNumber);
            using (var tx = NewTransaction(TransactionFlags.ReadWrite))
            {
                var root      = Tree.Create(tx, _sliceComparer);
                var freeSpace = Tree.Create(tx, _sliceComparer);

                // important to first create the two trees, then set them on the env
                tx.UpdateRootsIfNeeded(root, freeSpace);

                tx.Commit();
            }
        }
        private void CreateNewDatabase()
        {
            const int initialNextPageNumber = 0;

            State = new StorageEnvironmentState(null, null, initialNextPageNumber);
            using (var tx = NewTransaction(TransactionFlags.ReadWrite))
            {
                var root      = Tree.Create(tx, false);
                var freeSpace = Tree.Create(tx, false);

                // important to first create the two trees, then set them on the env
                tx.UpdateRootsIfNeeded(root, freeSpace);

                tx.Commit();

                //since this transaction is never shipped, this is the first previous transaction
                //when applying shipped logs
            }
        }
Example #6
0
        private unsafe void LoadExistingDatabase()
        {
            var  header             = stackalloc TransactionHeader[1];
            bool hadIntegrityIssues = _journal.RecoverDatabase(header);

            if (hadIntegrityIssues)
            {
                var message = _journal.Files.Count == 0 ? "Unrecoverable database" : "Database recovered partially. Some data was lost.";

                _options.InvokeRecoveryError(this, message, null);
            }

            var entry          = _headerAccessor.CopyHeader();
            var nextPageNumber = (header->TransactionId == 0 ? entry.LastPageNumber : header->LastPageNumber) + 1;

            State = new StorageEnvironmentState(null, nextPageNumber)
            {
                NextPageNumber = nextPageNumber,
                Options        = Options
            };

            _transactionsCounter = (header->TransactionId == 0 ? entry.TransactionId : header->TransactionId);

            var transactionPersistentContext = new TransactionPersistentContext(true);

            using (var tx = NewLowLevelTransaction(transactionPersistentContext, TransactionFlags.ReadWrite))
            {
                using (var root = Tree.Open(tx, null, Constants.RootTreeNameSlice, header->TransactionId == 0 ? &entry.Root : &header->Root))
                {
                    tx.UpdateRootsIfNeeded(root);

                    using (var treesTx = new Transaction(tx))
                    {
                        var metadataTree = treesTx.ReadTree(Constants.MetadataTreeNameSlice);
                        if (metadataTree == null)
                        {
                            VoronUnrecoverableErrorException.Raise(this,
                                                                   "Could not find metadata tree in database, possible mismatch / corruption?");
                        }

                        var dbId = metadataTree.Read("db-id");
                        if (dbId == null)
                        {
                            VoronUnrecoverableErrorException.Raise(this,
                                                                   "Could not find db id in metadata tree, possible mismatch / corruption?");
                        }

                        var buffer    = new byte[16];
                        var dbIdBytes = dbId.Reader.Read(buffer, 0, 16);
                        if (dbIdBytes != 16)
                        {
                            VoronUnrecoverableErrorException.Raise(this,
                                                                   "The db id value in metadata tree wasn't 16 bytes in size, possible mismatch / corruption?");
                        }

                        var databseGuidId = _options.GenerateNewDatabaseId == false ? new Guid(buffer) : Guid.NewGuid();
                        DbId = databseGuidId;

                        FillBase64Id(databseGuidId);

                        if (_options.GenerateNewDatabaseId)
                        {
                            // save the new database id
                            metadataTree.Add("db-id", DbId.ToByteArray());
                        }

                        var schemaVersion = metadataTree.Read("schema-version");
                        if (schemaVersion == null)
                        {
                            VoronUnrecoverableErrorException.Raise(this,
                                                                   "Could not find schema version in metadata tree, possible mismatch / corruption?");
                        }

                        var schemaVersionVal = schemaVersion.Reader.ReadLittleEndianInt32();
                        if (Options.SchemaVersion != 0 &&
                            schemaVersionVal != Options.SchemaVersion)
                        {
                            VoronUnrecoverableErrorException.Raise(this,
                                                                   "The schema version of this database is expected to be " +
                                                                   Options.SchemaVersion + " but is actually " + schemaVersionVal +
                                                                   ". You need to upgrade the schema.");
                        }

                        tx.Commit();
                    }
                }
            }
        }