Example #1
0
        private void HandleOnRecoveryError(StorageEnvironmentWithType.StorageEnvironmentType type, string resourceName, object environment, RecoveryErrorEventArgs e)
        {
            NotificationCenter.NotificationCenter nc;
            string title;

            switch (type)
            {
            case StorageEnvironmentWithType.StorageEnvironmentType.Configuration:
            case StorageEnvironmentWithType.StorageEnvironmentType.Documents:
                nc    = _serverStore?.NotificationCenter;
                title = $"Database Recovery Error - {resourceName ?? "Unknown Database"}";

                if (type == StorageEnvironmentWithType.StorageEnvironmentType.Configuration)
                {
                    title += " (configuration storage)";
                }
                break;

            case StorageEnvironmentWithType.StorageEnvironmentType.Index:
                nc    = NotificationCenter;
                title = $"Index Recovery Error - {resourceName ?? "Unknown Index"}";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type.ToString());
            }

            nc?.Add(AlertRaised.Create(Name,
                                       title,
                                       $"{e.Message}{Environment.NewLine}{Environment.NewLine}Environment: {environment}",
                                       AlertType.RecoveryError,
                                       NotificationSeverity.Error,
                                       key: resourceName));
        }
Example #2
0
        private static StorageEnvironment OpenEnvironmentWithPossibleLayoutUpdate(StorageEnvironmentOptions.DirectoryStorageEnvironmentOptions options, StorageEnvironmentWithType.StorageEnvironmentType type)
        {
            try
            {
                var oldOwnsPager = options.OwnsPagers;
                options.OwnsPagers = false;
                try
                {
                    return(new StorageEnvironment(options));
                }
                finally
                {
                    options.OwnsPagers = oldOwnsPager;
                }
            }
            catch (InvalidJournalException e)
            {
                var basePath          = options.BasePath;
                var preRtmJournalPath = basePath.Combine("Journal");
                var journalsPath      = options.JournalPath;
                if (Directory.Exists(preRtmJournalPath.FullPath))
                {
                    TryMoveJournals(preRtmJournalPath, journalsPath);
                    Directory.Delete(preRtmJournalPath.FullPath);
                }
                else
                {
                    if (TryMoveJournals(basePath, journalsPath) == false)
                    {
                        var message =
                            $"Failed to open a storage at {options} due to invalid or missing journal files. In order to load the storage successfully we need all journals to be not corrupted. ";

                        string ravenServer = Assembly.GetAssembly(typeof(StorageLoader)).GetName().Name + (PlatformDetails.RunningOnPosix ? string.Empty : ".exe");

                        switch (type)
                        {
                        case StorageEnvironmentWithType.StorageEnvironmentType.Index:
                            message += "The recommended approach is to reset the index in order to recover from this error. Alternatively you can temporarily start the server in " +
                                       $"dangerous mode so it will ignore invalid journals on startup: {Environment.NewLine}" +
                                       $"{ravenServer} --{RavenConfiguration.GetKey(x => x.Storage.IgnoreInvalidJournalErrors)}=true{Environment.NewLine}" +
                                       "This switch is meant to be use only for recovery purposes. Please make sure that you won't use it after you manage to recover your data. " +
                                       "Eventually you should reset the index anyway to be sure you won't experience any invalid data errors in the future.";
                            break;

                        case StorageEnvironmentWithType.StorageEnvironmentType.Documents:
                            message +=
                                "You can load a database by starting the server in dangerous mode temporarily so it will ignore invalid journals on startup but you need to " +
                                $"export and import database immediately afterwards: {Environment.NewLine}" +
                                $"{ravenServer} --{RavenConfiguration.GetKey(x => x.Storage.IgnoreInvalidJournalErrors)}=true{Environment.NewLine}" +
                                "This switch is meant to be use only for recovery purposes. Please make sure that you won't use it after you manage to recover your data. " +
                                "If you won't be able to export the database successfully you need restore the database from the backup or use Voron.Recovery tool. ";
                            break;

                        case StorageEnvironmentWithType.StorageEnvironmentType.Configuration:
                            message += $"You can delete the configuration storage folder at '{basePath.FullPath}' and restart the server. It will be recreated on database startup." +
                                       "This storage contains only notifications and alerts that you see in RavenDB studio";
                            break;

                        case StorageEnvironmentWithType.StorageEnvironmentType.System:
                            message += "You can start the server in dangerous mode temporarily so it will ignore invalid journals on startup:" +
                                       $"{ravenServer} --{RavenConfiguration.GetKey(x => x.Storage.IgnoreInvalidJournalErrors)}=true{Environment.NewLine}" +
                                       "This switch is meant to be use only for recovery purposes. Please make sure that you won't use it after you manage to recover your data. " +
                                       $"Eventually you should delete the system storage at '{basePath.FullPath}', start the server and create your databases again with the usage of existing data.";
                            break;

                        default:
                            throw new ArgumentException($"Unknown storage type: {type}", nameof(type));
                        }

                        throw new InvalidJournalException($"{message}{Environment.NewLine}Error details: {e.Message}");
                    }
                }

                return(new StorageEnvironment(options));
            }
        }
Example #3
0
        public static StorageEnvironment OpenEnvironment(StorageEnvironmentOptions options, StorageEnvironmentWithType.StorageEnvironmentType type)
        {
            try
            {
                if (options is StorageEnvironmentOptions.DirectoryStorageEnvironmentOptions directoryOptions)
                {
                    return(OpenEnvironmentWithPossibleLayoutUpdate(directoryOptions, type));
                }

                return(new StorageEnvironment(options));
            }
            catch (Exception)
            {
                options.Dispose();

                throw;
            }
        }