Esempio n. 1
0
        public static List <string> GetDatabases(UpdateStep step)
        {
            var dbs = new List <string>();

            using (var items = step.ReadTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                using (Slice.From(step.ReadTx.Allocator, DbKey, out var loweredPrefix))
                {
                    foreach (var result in items.SeekByPrimaryKeyPrefix(loweredPrefix, Slices.Empty, 0))
                    {
                        dbs.Add(ClusterStateMachine.GetCurrentItemKey(result.Value).Substring(DbKey.Length));
                    }
                }

            return(dbs);
        }
Esempio n. 2
0
        public bool Update(UpdateStep step)
        {
            var          dbs   = new List <string>();
            const string dbKey = "db/";

            var identities = step.ReadTx.ReadTree(ClusterStateMachine.Identities);

            step.WriteTx.DeleteTree(ClusterStateMachine.Identities);

            using (var items = step.ReadTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                using (Slice.From(step.ReadTx.Allocator, dbKey, out Slice loweredPrefix))
                {
                    foreach (var result in items.SeekByPrimaryKeyPrefix(loweredPrefix, Slices.Empty, 0))
                    {
                        dbs.Add(ClusterStateMachine.GetCurrentItemKey(result.Value).Substring(dbKey.Length));
                    }
                }

            step.WriteTx.CreateTree(ClusterStateMachine.CompareExchangeIndex);

            foreach (var db in dbs)
            {
                if (identities != null)
                {
                    Slice.From(step.WriteTx.Allocator, "Identities", out var identitySlice);
                    ClusterStateMachine.IdentitiesSchema.Create(step.WriteTx, identitySlice, 32);
                    var writeTable = step.WriteTx.OpenTable(ClusterStateMachine.IdentitiesSchema, identitySlice);
                    using (Slice.From(step.ReadTx.Allocator, $"{dbKey}{db.ToLowerInvariant()}/identities/", out var identityPrefix))
                    {
                        using (var it = identities.Iterate(prefetch: false))
                        {
                            it.SetRequiredPrefix(identityPrefix);

                            if (it.Seek(identityPrefix))
                            {
                                do
                                {
                                    var key         = it.CurrentKey;
                                    var keyAsString = key.ToString();   // old identity key
                                    var value       = it.CreateReaderForCurrent().ReadLittleEndianInt64();

                                    var newKey = keyAsString.Substring(identityPrefix.ToString().Length);

                                    // write to new identities schema
                                    GetKeyAndPrefixIndexSlices(step.ReadTx.Allocator, db, $"{newKey}", 0L, out var keyTuple, out var indexTuple);
                                    using (keyTuple.Scope)
                                        using (indexTuple.Scope)
                                            using (Slice.External(step.ReadTx.Allocator, keyTuple.Buffer.Ptr, keyTuple.Buffer.Length, out var keySlice))
                                                using (Slice.External(step.ReadTx.Allocator, indexTuple.Buffer.Ptr, indexTuple.Buffer.Length, out var prefixIndexSlice))
                                                {
                                                    using (writeTable.Allocate(out var write))
                                                    {
                                                        write.Add(keySlice);
                                                        write.Add(value);
                                                        write.Add(0L);
                                                        write.Add(prefixIndexSlice);

                                                        writeTable.Set(write);
                                                    }
                                                }
                                } while (it.MoveNext());
                            }
                        }
                    }
                }

                // update db backup status
                var dbLower = db.ToLowerInvariant();
                using (var items = step.WriteTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                    using (Slice.From(step.ReadTx.Allocator, $"{dbKey}{dbLower}", out Slice lowerKey))
                        using (var ctx = JsonOperationContext.ShortTermSingleUse())
                        {
                            var(databaseRecordJson, _) = GetBjroAndIndex(ctx, items, lowerKey);
                            var databaseRecord = JsonDeserializationCluster.DatabaseRecord(databaseRecordJson);
                            if (databaseRecord == null)
                            {
                                continue;
                            }

                            foreach (var pb in databaseRecord.PeriodicBackups)
                            {
                                var pbItemName = PeriodicBackupStatus.GenerateItemName(db, pb.TaskId);
                                using (Slice.From(step.WriteTx.Allocator, pbItemName, out Slice pbsSlice))
                                    using (Slice.From(step.WriteTx.Allocator, pbItemName.ToLowerInvariant(), out Slice pbsSliceLower))
                                    {
                                        var(singleBackupStatus, index) = GetBjroAndIndex(ctx, items, pbsSlice);
                                        if (singleBackupStatus == null)
                                        {
                                            continue;
                                        }

                                        if (singleBackupStatus.TryGet(nameof(PeriodicBackupStatus.LocalBackup), out BlittableJsonReaderObject localBackup) == false ||
                                            singleBackupStatus.TryGet(nameof(PeriodicBackupStatus.LastRaftIndex), out BlittableJsonReaderObject lastRaftIndexBlittable) == false)
                                        {
                                            continue;
                                        }

                                        if (localBackup.TryGet(nameof(PeriodicBackupStatus.LastIncrementalBackup), out DateTime? lastIncrementalBackupDate) == false ||
                                            lastRaftIndexBlittable.TryGet(nameof(PeriodicBackupStatus.LastEtag), out long?lastRaftIndex) == false)
                                        {
                                            continue;
                                        }

                                        if (lastIncrementalBackupDate == null || lastRaftIndex == null)
                                        {
                                            continue;
                                        }

                                        var myLastRaftIndex = new LastRaftIndex
                                        {
                                            LastEtag = 0L
                                        };

                                        singleBackupStatus.Modifications = new DynamicJsonValue
                                        {
                                            [nameof(PeriodicBackupStatus.LastRaftIndex)] = myLastRaftIndex.ToJson()
                                        };

                                        using (var old = singleBackupStatus)
                                        {
                                            singleBackupStatus = ctx.ReadObject(singleBackupStatus, pbItemName);
                                        }

                                        using (items.Allocate(out var builder))
                                        {
                                            builder.Add(pbsSliceLower);
                                            builder.Add(pbsSlice);
                                            builder.Add(singleBackupStatus.BasePointer, singleBackupStatus.Size);
                                            builder.Add(index);

                                            items.Set(builder);
                                        }
                                    }
                            }
                        }
            }

            return(true);
        }
Esempio n. 3
0
        public bool Update(UpdateStep step)
        {
            var          ids                 = new HashSet <long>();
            var          minimal             = long.MaxValue;
            const string dbKey               = "db/";
            var          continueAfterCommit = true;
            var          skip                = 0;

            while (continueAfterCommit)
            {
                continueAfterCommit = false;
                var fixedItems = 0;

                var items = step.WriteTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items);
                using (Slice.From(step.WriteTx.Allocator, dbKey, out Slice loweredPrefix))
                {
                    foreach (var result in items.SeekByPrimaryKeyPrefix(loweredPrefix, Slices.Empty, 0))
                    {
                        var databaseName = ClusterStateMachine.GetCurrentItemKey(result.Value).Substring(3);
                        using (Slice.From(step.WriteTx.Allocator, dbKey + databaseName.ToLowerInvariant(), out var key))
                        {
                            if (items.VerifyKeyExists(key) == false)
                            {
                                continue;
                            }
                        }

                        using (Slice.From(step.WriteTx.Allocator, SubscriptionState.SubscriptionPrefix(databaseName), out var startWith))
                            using (var ctx = JsonOperationContext.ShortTermSingleUse())
                            {
                                foreach (var holder in items.SeekByPrimaryKeyPrefix(startWith, Slices.Empty, skip))
                                {
                                    skip++;
                                    var reader = holder.Value.Reader;
                                    var ptr    = reader.Read(2, out int size);
                                    using (var doc = new BlittableJsonReaderObject(ptr, size, ctx))
                                    {
                                        if (doc.TryGet(nameof(SubscriptionState.SubscriptionId), out long id) == false)
                                        {
                                            continue;
                                        }

                                        if (minimal > id)
                                        {
                                            minimal = id;
                                        }

                                        if (ids.Add(id))
                                        {
                                            continue;
                                        }

                                        minimal--;
                                        ids.Add(minimal);

                                        var subscriptionState = JsonDeserializationClient.SubscriptionState(doc);
                                        subscriptionState.SubscriptionId = minimal;
                                        var subscriptionItemName = SubscriptionState.GenerateSubscriptionItemKeyName(databaseName, subscriptionState.SubscriptionName);
                                        using (Slice.From(step.WriteTx.Allocator, subscriptionItemName, out Slice valueName))
                                            using (Slice.From(step.WriteTx.Allocator, subscriptionItemName.ToLowerInvariant(), out Slice valueNameLowered))
                                                using (var receivedSubscriptionState = ctx.ReadObject(subscriptionState.ToJson(), subscriptionState.SubscriptionName))
                                                {
                                                    ClusterStateMachine.UpdateValue(0, items, valueNameLowered, valueName, receivedSubscriptionState);
                                                }
                                    }

                                    fixedItems++;
                                    if (fixedItems < 1024)
                                    {
                                        continue;
                                    }

                                    continueAfterCommit = true;
                                    break;
                                }
                            }

                        if (continueAfterCommit)
                        {
                            break;
                        }
                    }
                }

                if (continueAfterCommit)
                {
                    step.Commit(null);
                    step.RenewTransactions();
                }
            }

            return(true);
        }
Esempio n. 4
0
        public bool Update(UpdateStep step)
        {
            var          dbs   = new List <string>();
            const string dbKey = "db/";

            var newIdentitiesSchema = new TableSchema()
                                      .DefineKey(new TableSchema.SchemaIndexDef
            {
                StartIndex = (int)ClusterStateMachine.IdentitiesTable.Key,
                Count      = 1
            }).DefineIndex(new TableSchema.SchemaIndexDef
            {
                StartIndex = (int)ClusterStateMachine.IdentitiesTable.KeyIndex,
                Count      = 1,
                IsGlobal   = true,
                Name       = ClusterStateMachine.IdentitiesIndex
            });

            using (var items = step.ReadTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                using (Slice.From(step.ReadTx.Allocator, dbKey, out Slice loweredPrefix))
                {
                    foreach (var result in items.SeekByPrimaryKeyPrefix(loweredPrefix, Slices.Empty, 0))
                    {
                        dbs.Add(ClusterStateMachine.GetCurrentItemKey(result.Value).Substring(dbKey.Length));
                    }
                }

            foreach (var db in dbs)
            {
                var dbPrefixLowered = $"{db.ToLowerInvariant()}/";

                // update IdentitiesSchema
                var readIdentitiesTable = step.ReadTx.OpenTable(ClusterStateMachine.IdentitiesSchema, ClusterStateMachine.Identities);
                if (readIdentitiesTable != null)
                {
                    using (Slice.From(step.ReadTx.Allocator, dbPrefixLowered, out var keyPrefix))
                    {
                        var writeIdentitiesTable = step.WriteTx.OpenTable(newIdentitiesSchema, ClusterStateMachine.Identities);
                        foreach (var item in readIdentitiesTable.SeekByPrimaryKeyPrefix(keyPrefix, Slices.Empty, 0))
                        {
                            var value = TableValueToLong((int)ClusterStateMachine.IdentitiesTable.Value, ref item.Value.Reader);
                            var index = TableValueToLong((int)ClusterStateMachine.IdentitiesTable.Index, ref item.Value.Reader);

                            // if value is not 0 than we come from v4.2 and could have wrong index value
                            if (index != 0)
                            {
                                using (GetPrefixIndexSlices(step.ReadTx.Allocator, db, 0L, out var buffer))
                                    using (Slice.External(step.WriteTx.Allocator, buffer.Ptr, buffer.Length, out var prefixIndexSlice))
                                        using (writeIdentitiesTable.Allocate(out TableValueBuilder write))
                                        {
                                            write.Add(item.Key);
                                            write.Add(value);
                                            write.Add(0L);
                                            write.Add(prefixIndexSlice);

                                            writeIdentitiesTable.Set(write);
                                        }
                            }
                        }
                    }
                }

                // update db backup status
                var dbLower = db.ToLowerInvariant();
                using (var items = step.WriteTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                    using (Slice.From(step.ReadTx.Allocator, $"{dbKey}{dbLower}", out Slice lowerKey))
                        using (var ctx = JsonOperationContext.ShortTermSingleUse())
                        {
                            var(databaseRecordJson, _) = GetBjroAndIndex(ctx, items, lowerKey);
                            var databaseRecord = JsonDeserializationCluster.DatabaseRecord(databaseRecordJson);
                            if (databaseRecord == null)
                            {
                                continue;
                            }

                            foreach (var pb in databaseRecord.PeriodicBackups)
                            {
                                var pbItemName = PeriodicBackupStatus.GenerateItemName(db, pb.TaskId);
                                using (Slice.From(step.WriteTx.Allocator, pbItemName, out Slice pbsSlice))
                                    using (Slice.From(step.WriteTx.Allocator, pbItemName.ToLowerInvariant(), out Slice pbsSliceLower))
                                    {
                                        var(singleBackupStatus, index) = GetBjroAndIndex(ctx, items, pbsSlice);
                                        if (singleBackupStatus == null)
                                        {
                                            continue;
                                        }

                                        if (singleBackupStatus.TryGet(nameof(PeriodicBackupStatus.LocalBackup), out BlittableJsonReaderObject localBackup) == false ||
                                            singleBackupStatus.TryGet(nameof(PeriodicBackupStatus.LastRaftIndex), out BlittableJsonReaderObject lastRaftIndexBlittable) == false)
                                        {
                                            continue;
                                        }

                                        if (localBackup.TryGet(nameof(PeriodicBackupStatus.LastIncrementalBackup), out DateTime? lastIncrementalBackupDate) == false ||
                                            lastRaftIndexBlittable.TryGet(nameof(PeriodicBackupStatus.LastEtag), out long?lastRaftIndex) == false)
                                        {
                                            continue;
                                        }

                                        if (lastIncrementalBackupDate == null || lastRaftIndex == null)
                                        {
                                            continue;
                                        }

                                        // already set in from12 before
                                        if (lastRaftIndex == 0)
                                        {
                                            continue;
                                        }

                                        var myLastRaftIndex = new LastRaftIndex
                                        {
                                            LastEtag = 0L
                                        };

                                        singleBackupStatus.Modifications = new DynamicJsonValue
                                        {
                                            [nameof(PeriodicBackupStatus.LastRaftIndex)] = myLastRaftIndex.ToJson()
                                        };

                                        using (var old = singleBackupStatus)
                                        {
                                            singleBackupStatus = ctx.ReadObject(singleBackupStatus, pbItemName);
                                        }

                                        using (items.Allocate(out var builder))
                                        {
                                            builder.Add(pbsSliceLower);
                                            builder.Add(pbsSlice);
                                            builder.Add(singleBackupStatus.BasePointer, singleBackupStatus.Size);
                                            builder.Add(index);

                                            items.Set(builder);
                                        }
                                    }
                            }
                        }
            }

            return(true);
        }
Esempio n. 5
0
        public bool Update(UpdateStep step)
        {
            var          dbs   = new List <string>();
            const string dbKey = "db/";

            var newIdentitiesSchema = new TableSchema()
                                      .DefineKey(new TableSchema.SchemaIndexDef
            {
                StartIndex = (int)ClusterStateMachine.IdentitiesTable.Key,
                Count      = 1
            }).DefineIndex(new TableSchema.SchemaIndexDef
            {
                StartIndex = (int)ClusterStateMachine.IdentitiesTable.KeyIndex,
                Count      = 1,
                IsGlobal   = true,
                Name       = ClusterStateMachine.IdentitiesIndex
            });

            using (var items = step.ReadTx.OpenTable(ClusterStateMachine.ItemsSchema, ClusterStateMachine.Items))
                using (Slice.From(step.ReadTx.Allocator, dbKey, out Slice loweredPrefix))
                {
                    foreach (var result in items.SeekByPrimaryKeyPrefix(loweredPrefix, Slices.Empty, 0))
                    {
                        dbs.Add(ClusterStateMachine.GetCurrentItemKey(result.Value).Substring(dbKey.Length));
                    }
                }

            foreach (var db in dbs)
            {
                var dbPrefixLowered = $"{db.ToLowerInvariant()}/";

                // update IdentitiesSchema
                var readIdentitiesTable = step.ReadTx.OpenTable(ClusterStateMachine.IdentitiesSchema, ClusterStateMachine.Identities);
                if (readIdentitiesTable != null)
                {
                    using (Slice.From(step.ReadTx.Allocator, dbPrefixLowered, out var keyPrefix))
                    {
                        var writeIdentitiesTable = step.WriteTx.OpenTable(newIdentitiesSchema, ClusterStateMachine.Identities);
                        foreach (var item in readIdentitiesTable.SeekByPrimaryKeyPrefix(keyPrefix, Slices.Empty, 0))
                        {
                            var indexPtr = item.Value.Reader.Read((int)ClusterStateMachine.IdentitiesTable.Index, out var size);

                            // we come from v4.2 RC1
                            if (size == sizeof(int))
                            {
                                var  indexIntValue = *(int *)indexPtr;
                                long index         = (long)indexIntValue;
                                var  value         = TableValueToLong((int)ClusterStateMachine.IdentitiesTable.Value, ref item.Value.Reader);

                                using (GetPrefixIndexSlices(step.ReadTx.Allocator, db, index, out var buffer))
                                    using (Slice.External(step.WriteTx.Allocator, buffer.Ptr, buffer.Length, out var prefixIndexSlice))
                                        using (writeIdentitiesTable.Allocate(out TableValueBuilder write))
                                        {
                                            write.Add(item.Key);
                                            write.Add(value);
                                            write.Add(index);
                                            write.Add(prefixIndexSlice);

                                            writeIdentitiesTable.Set(write);
                                        }
                            }
                        }
                    }
                }
            }

            return(true);
        }