Exemple #1
0
 private void BackupLogs(OperationContext context, string instancePath, string name)
 {
     if (_logManager != null)
     {
         _logManager.BackupAsync(context, new AbsolutePath(instancePath), name).Result.IgnoreFailure();
         Task.Run(() => _logManager.GarbageCollect(context)).FireAndForget(context, severityOnException: Severity.Error);
     }
 }
Exemple #2
0
        private BoolResult Load(OperationContext context, StoreSlot activeSlot, bool clean)
        {
            try
            {
                var storeLocation = GetStoreLocation(activeSlot);

                if (Directory.Exists(storeLocation))
                {
                    // We backup right before loading. This means we should never loose any logs, but it also means
                    // the backup directory will only hold logs for DBs that have already been overwritten.
                    if (_logManager != null)
                    {
                        _logManager.BackupAsync(context, new AbsolutePath(storeLocation), activeSlot.ToString()).Result.IgnoreFailure();
                        Task.Run(() => _logManager.GarbageCollect(context)).FireAndForget(context, severityOnException: Severity.Error);
                    }

                    if (clean)
                    {
                        FileUtilities.DeleteDirectoryContents(storeLocation, deleteRootDirectory: true);
                    }
                }

                Directory.CreateDirectory(storeLocation);

                Tracer.Info(context, $"Creating RocksDb store at '{storeLocation}'.");

                var possibleStore = KeyValueStoreAccessor.Open(
                    new KeyValueStoreAccessor.RocksDbStoreArguments()
                {
                    StoreDirectory    = storeLocation,
                    AdditionalColumns = new[] { nameof(Columns.ClusterState), nameof(Columns.Metadata) },
                    RotateLogs        = true,
                    EnableStatistics  = true,
                    FastOpen          = true,
                },
                    // When an exception is caught from within methods using the database, this handler is called to
                    // decide whether the exception should be rethrown in user code, and the database invalidated. Our
                    // policy is to only invalidate if it is an exception coming from RocksDb, but not from our code.
                    failureHandler: failureEvent =>
                {
                    // By default, rethrow is true iff it is a user error. We invalidate only if it isn't
                    failureEvent.Invalidate = !failureEvent.Rethrow;
                },
                    // The database may be invalidated for a number of reasons, all related to latent bugs in our code.
                    // For example, exceptions thrown from methods that are operating on the DB. If that happens, we
                    // call a user-defined handler. This is because the instance is invalid after this happens.
                    invalidationHandler: failure => OnDatabaseInvalidated(context, failure),
                    // It is possible we may fail to open an already existing database. This can happen (most commonly)
                    // due to corruption, among others. If this happens, then we want to recreate it from empty. This
                    // only helps for the memoization store.
                    onFailureDeleteExistingStoreAndRetry: _configuration.OnFailureDeleteExistingStoreAndRetry,
                    // If the previous flag is true, and it does happen that we invalidate the database, we want to log
                    // it explicitly.
                    onStoreReset: failure =>
                {
                    Tracer.Error(context, $"RocksDb critical error caused store to reset: {failure.DescribeIncludingInnerFailures()}");
                });

                if (possibleStore.Succeeded)
                {
                    var oldKeyValueStore = _keyValueStore;
                    var store            = possibleStore.Result;

                    if (oldKeyValueStore == null)
                    {
                        _keyValueStore = new KeyValueStoreGuard(store);
                    }
                    else
                    {
                        // Just replace the inner accessor
                        oldKeyValueStore.Replace(store);
                    }

                    _activeSlot    = activeSlot;
                    _storeLocation = storeLocation;
                }

                return(possibleStore.Succeeded ? BoolResult.Success : new BoolResult($"Failed to initialize a RocksDb store at {_storeLocation}:", possibleStore.Failure.DescribeIncludingInnerFailures()));
            }
            catch (Exception ex) when(ex.IsRecoverableIoException())
            {
                return(new BoolResult(ex));
            }
        }