realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.31k stars 2.14k forks source link

Realm file initial open failed #7088

Closed ragu-pdx closed 2 years ago

ragu-pdx commented 3 years ago

!!! MANDATORY TO FILL OUT !!!

Goals

Reliably open Realm files when iOS application launches.

Expected Results

No Realm database crashes when opening a known realm within iOS app

Actual Results

Randomly on app launches, the Realm will fail to open and fail on every subsequent launch. Every call to persistentRealm fails with this same error.

Attempting to download the Realm from the device through XCode and opening in Realm Studio, it states that the persistentRealm is encrypted even though it was never set as encrypted (see code below). Transient Realm is created the exact same way, and it is able to be opened with Realm Studio.

2021-02-03 10:03:43.943 [E] (User+Realm:28) Realm error retrieving persistent realm db: Unable to open a realm at path '/var/mobile/Containers/Data/Application/BA29FDD3-4F30-4A81-9542-EFE470847FC8/Library/Application Support/Realm/A/16117745077B930912-persistent.realm': Realm file initial open failed Path:Exception backtrace:
0   Realm                               0x000000010400b6e4 _ZN5realm15InvalidDatabaseC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_ + 60
1   Realm                               0x0000000103f5025c _ZN5realm9SlabAlloc11attach_fileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERNS0_6ConfigE + 2964
2   Realm                               0x0000000103ff1b0c _ZN5realm2DB7do_openERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEbbNS_9DBOptionsE + 3156
3   Realm                               0x0000000103ff458c _ZN5realm2DB4openERNS_11ReplicationENS_9DBOptionsE + 244
4   Realm                               0x0000000103ff903c _ZN5realm2DB6createERNS_11ReplicationENS_9DBOptionsE + 392
5   Realm                               0x00000001042c0d9c _ZN5realm5_impl16RealmCoordinator7open_dbEv + 1344
6   Realm                               0x00000001042bfae0 _ZN5realm5_impl16RealmCoordinator12do_get_realmENS_5Realm6ConfigERNSt3__110shared_ptrIS2_EENS_4util8OptionalINS_9VersionIDEEERNS8_17CheckedUniqueLockE + 68
7   Realm                               0x00000001042bf91c _ZN5realm5_impl16RealmCoordinator9get_realmENS_5Realm6ConfigENS_4util8OptionalINS_9VersionIDEEE + 400
8   Realm                               0x0000000104323168 _ZN5realm5Realm16get_shared_realmENS0_6ConfigE + 120
9   Realm                               0x0000000103ec7254 +[RLMRealm realmWithConfiguration:queue:error:] + 1796
10  RealmSwift                          0x0000000104dd3e4c $sSo8RLMRealmC13configuration5queueABSo0A13ConfigurationC_So012OS_dispatch_C0CSgtKcfCTO + 156
11  RealmSwift                          0x0000000104e32ad4 $s10RealmSwift0A0V13configuration5queueA2C13ConfigurationV_So012OS_dispatch_D0CSgtKcfC + 216
12  Radiata Dev                         0x00000001008d44e4 $s11Radiata_Dev4UserC5realm33_E19C977A9CB5286F9E7FAC1154520478LL11storageType10RealmSwift0N0VSgAA15DatabaseServiceC07StorageM0O_tF + 272
13  Radiata Dev                         0x00000001008d43c8 $s11Radiata_Dev4UserC15persistentRealm0E5Swift0E0VSgvg + 28
14  Radiata Dev                         0x00000001008247f0 $s11Radiata_Dev16BluetoothServiceC10peripheral_13readerResultsySo12PBPeripheralC_10Foundation4DataVtFyycfU_ + 792
15  Radiata Dev                         0x00000001008635c0 $s11Radiata_Dev13RunLoopThreadC7execute33_7437B171BCCEFE4E3F677120770C460CLLyyAA12BlockWrapperAELLCF + 904
16  Radiata Dev                         0x000000010086366c $s11Radiata_Dev13RunLoopThreadC7execute33_7437B171BCCEFE4E3F677120770C460CLLyyAA12BlockWrapperAELLCFTo + 60
17  Foundation                          0x000000018b6e4b90 7698BF3E-0CF6-31C0-85E9-562714F01276 + 1551248
18  CoreFoundation                      0x000000018a2ca76c 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 661356
19  CoreFoundation                      0x000000018a2ca668 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 661096
20  CoreFoundation                      0x000000018a2c9960 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 657760
21  CoreFoundation                      0x000000018a2c3a8c 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 633484
22  CoreFoundation                      0x000000018a2c321c CFRunLoopRunSpecific + 600
23  Foundation                          0x000000018b572df0 7698BF3E-0CF6-31C0-85E9-562714F01276 + 36336
24  Radiata Dev                         0x0000000100861c64 $s11Radiata_Dev13RunLoopThreadC4mainyyFyyXEfU_SbyXEfU_ + 216
25  Radiata Dev                         0x0000000100861cb0 $sSbs5Error_pIgdzo_SbsAA_pIegrzo_TR + 28
26  Radiata Dev                         0x00000001008646dc $sSbs5Error_pIgdzo_SbsAA_pIegrzo_TRTA + 28
27  libswiftObjectiveC.dylib            0x00000001b017df30 $s10ObjectiveC15autoreleasepool8invokingxxyKXE_tKlF + 64
28  Radiata Dev                         0x00000001008616c4 $s11Radiata_Dev13RunLoopThreadC4mainyyFyyXEfU_ + 772
29  Radiata Dev                         0x00000001007d4814 $ss5Error_pIgzo_ytsAA_pIegrzo_TR + 24
30  Radiata Dev                         0x0000000100861f90 $ss5Error_pIgzo_ytsAA_pIegrzo_TRTA + 28
31  libswiftObjectiveC.dylib            0x00000001b017df30 $s10ObjectiveC15autoreleasepool8invokingxxyKXE_tKlF + 64
32  Radiata Dev                         0x0000000100861398 $s11Radiata_Dev13RunLoopThreadC4mainyyF + 140
33  Radiata Dev                         0x0000000100861fbc $s11Radiata_Dev13RunLoopThreadC4mainyyFTo + 32
34  Foundation                          0x000000018b6e4a34 7698BF3E-0CF6-31C0-85E9-562714F01276 + 1550900
35  libsystem_pthread.dylib             0x00000001d513bcb0 _pthread_start + 320
36  libsystem_pthread.dylib             0x00000001d5144778 thread_start + 8.. Process Id: 56015
2021-02-03 10:03:43.959 [E] (User+Realm:29) 
0   Radiata Dev                         0x00000001008d6740 $s11Radiata_Dev4UserC5realm33_E19C977A9CB5286F9E7FAC1154520478LL11storageType10RealmSwift0N0VSgAA15DatabaseServiceC07StorageM0O_tFypyXEfu0_ + 168
1   SwiftyBeaver                        0x0000000100fe67c8 $s12SwiftyBeaverAAC5error___4line7contextyypyXK_S2SSiypSgtFZypyXEfu_ + 20
2   SwiftyBeaver                        0x0000000100fe6918 $s12SwiftyBeaverAAC6custom5level7message4file8function4line7contextyAB5LevelO_ypyXKS2SSiypSgtFZypyXEfu_ + 20
3   SwiftyBeaver                        0x0000000100fe6fa8 $s12SwiftyBeaverAAC13dispatch_send5level7message6thread4file8function4line7contextyAB5LevelO_ypyXKS3SSiypSgtFZ + 1656
4   SwiftyBeaver                        0x0000000100fe68ec $s12SwiftyBeaverAAC6custom5level7message4file8function4line7contextyAB5LevelO_ypyXKS2SSiypSgtFZ + 268
5   SwiftyBeaver                        0x0000000100fe67a8 $s12SwiftyBeaverAAC5error___4line7contextyypyXK_S2SSiypSgtFZ + 208
6   Radiata Dev                         0x00000001008d4848 $s11Radiata_Dev4UserC5realm33_E19C977A9CB5286F9E7FAC1154520478LL11storageType10RealmSwift0N0VSgAA15DatabaseServiceC07StorageM0O_tF + 1140
7   Radiata Dev                         0x00000001008d43c8 $s11Radiata_Dev4UserC15persistentRealm0E5Swift0E0VSgvg + 28
2021-02-03 10:03:43.965 [D] (BluetoothService:276) User's persistent realm not accessible

Steps for others to Reproduce

Difficult to reliably reproduce as it doesn't occur on every run from a fresh application install. The application is using CoreBluetooth with background permissions to retrieve data in the background and store it to a realm db.

Code Sample

User+Realm.swift

Retrieves the proper realm; user.peristentRealm is the property called and crashing. The file definitely exists as it worked on many previous application launches, and then, suddenly on a subsequent run, it fails. Once it fails on a run, ever subsequent app launch will fail with the same error.

import RealmSwift

extension User {
    static private let accessSemaphore = DispatchSemaphore(value: 1)
    static private var configurations = [String: Realm.Configuration]()

    var persistentRealm: Realm? {
        return self.realm(storageType: .persistent)
    }

    var transientRealm: Realm? {
        return self.realm(storageType: .transient)
    }

    private func realm(storageType: DatabaseService.StorageType) -> Realm? {
        var realm: Realm?

        do {
            realm = try Realm(configuration: self.configuration(for: storageType))
        } catch let error as Realm.Error {
            log.error("Realm error retrieving \(storageType) realm db: \(error.localizedDescription). Process Id: \(ProcessInfo.processInfo.processIdentifier)")
            log.error("\n\(Thread.callStackSymbols.prefix(8).joined(separator: "\n"))")
        } catch {
            log.error("Error retrieving \(storageType) realm db: \(error.localizedDescription). Process Id: \(ProcessInfo.processInfo.processIdentifier)")
            log.error("\n\(Thread.callStackSymbols.prefix(8).joined(separator: "\n"))")
        }

        return realm
    }

    private func configuration(for storageType: DatabaseService.StorageType) -> Realm.Configuration {
        let filename: String
        let objectTypes: [ObjectBase.Type]
        let schemaVersion: UInt64
        let migrationBlock: MigrationBlock
        let encryptionKey: Data?

        switch storageType {
        case .transient:
            filename = "\(self.userid.components(separatedBy: "-").joined(separator: ""))" + "-transient.realm"
            encryptionKey = nil
            schemaVersion = 0
            objectTypes = [ReaderInformationObject.self, ReaderTimeObject.self, ReaderStateObject.self]
            migrationBlock = { (migration: Migration, oldSchemaVersion: UInt64) in
                log.debug("Transient Migration: \(oldSchemaVersion)")
                switch oldSchemaVersion {
                case 1:
                    break
                default:
                    break
                }
            }
        case .persistent:
            filename = "\(self.userid.components(separatedBy: "-").joined(separator: ""))" + "-persistent.realm"
            encryptionKey = nil
            schemaVersion = 0
            objectTypes = [ReaderTestResultObject.self, SystemAppObject.self, SystemCalendarObject.self, SystemDeviceObject.self, SystemLocaleObject.self, SystemTimeZoneObject.self]
            migrationBlock = { (migration: Migration, oldSchemaVersion: UInt64) in
                log.debug("Persistent Migration: \(oldSchemaVersion)")
                switch oldSchemaVersion {
                case 1:
                    break
                default:
                    break
                }
            }
        }

        User.accessSemaphore.wait()
        defer { User.accessSemaphore.signal() }

        guard User.configurations[filename] == nil else {
            return User.configurations[filename]!
        }
        log.verbose("Creating New Configuration: \(storageType)")

        let libraryPath = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
        let realmPath = libraryPath.appendingPathComponent("Realm/A")

        do {
            if !FileManager.default.fileExists(atPath: realmPath.path) {
                try FileManager.default.createDirectory(at: realmPath,
                                                        withIntermediateDirectories: true,
                                                        attributes: [FileAttributeKey.protectionKey: FileProtectionType.none])
            } else {
                try FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.none], ofItemAtPath: realmPath.path)
            }
        } catch {
            log.error("FileManager error: \(error)")
        }

        let fileURL = realmPath.appendingPathComponent(filename)
        let configuration = Realm.Configuration(fileURL: fileURL,
                                                encryptionKey: encryptionKey,
                                                schemaVersion: schemaVersion,
                                                migrationBlock: migrationBlock,
                                                shouldCompactOnLaunch: { (totalBytes: Int, usedBytes: Int) -> Bool in
                                                    return (totalBytes > (10 * 1024 * 1024))
                                                        && (Double(usedBytes) / Double(totalBytes)) < 0.5 },
                                                objectTypes: objectTypes)
        User.configurations[filename] = configuration

        return configuration
    }
}

Version of Realm and Tooling

Realm framework version: 10.5.1

Realm Object Server version: None

Xcode version: 12.4

iOS/OSX version: 14.4

Dependency manager + version: Cocoapods 1.10.0

leemaguire commented 3 years ago

@ragu-pth it looks like your check to see if the file exists should come before guard User.configurations[filename] == nil

ragu-pdx commented 3 years ago

@leemaguire That is the check to see if the file exists, and if so, return the existing configuration file.

private func configuration(for storageType: DatabaseService.StorageType) -> Realm.Configuration is responsible for only retrieving the configuration being requested (transient or persistent) from the internal cache configurations. If the configuration doesn't exist (the line you pointed out), it creates the configuration with all the local variable parameters and saves it to the dictionary cache.

As mentioned in the ticket, this code works perfectly on many runs of the app, but then suddenly, on the (N+1)th run, it will fail with the above error and then proceed to throw that error on every subsequent run unless the app is deleted. Pulling realm files off via XCode, the persistent realm can't be opened by the Realm Browser, saying it needs an encryption key, despite never being set up with an encryption key and not needing one on previous runs. The transient realm opened just fine, despite it being created in the exact same manner since both realm configurations are created in the code snipped I sent.

ragu-pdx commented 3 years ago

Just got the error again after several successful runs with the app.

2021-02-09 10:20:47.690 [E] (User+Realm:28) Realm error retrieving persistent realm db: Unable to open a realm at path '/var/mobile/Containers/Data/Application/59D7ACB8-AC55-44F7-BD0A-54CAFE675FA4/Library/Application Support/Realm/A/16127254762B0095D7-persistent.realm': Realm file initial open failed Path:Exception backtrace:
0   Realm                               0x0000000105ad37dc _ZN5realm15InvalidDatabaseC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_ + 60
1   Realm                               0x0000000105a18354 _ZN5realm9SlabAlloc11attach_fileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERNS0_6ConfigE + 2964
2   Realm                               0x0000000105ab9c04 _ZN5realm2DB7do_openERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEbbNS_9DBOptionsE + 3156
3   Realm                               0x0000000105abc684 _ZN5realm2DB4openERNS_11ReplicationENS_9DBOptionsE + 244
4   Realm                               0x0000000105ac1134 _ZN5realm2DB6createERNS_11ReplicationENS_9DBOptionsE + 392
5   Realm                               0x0000000105d88e94 _ZN5realm5_impl16RealmCoordinator7open_dbEv + 1344
6   Realm                               0x0000000105d87bd8 _ZN5realm5_impl16RealmCoordinator12do_get_realmENS_5Realm6ConfigERNSt3__110shared_ptrIS2_EENS_4util8OptionalINS_9VersionIDEEERNS8_17CheckedUniqueLockE + 68
7   Realm                               0x0000000105d87a14 _ZN5realm5_impl16RealmCoordinator9get_realmENS_5Realm6ConfigENS_4util8OptionalINS_9VersionIDEEE + 400
8   Realm                               0x0000000105deb260 _ZN5realm5Realm16get_shared_realmENS0_6ConfigE + 120
9   Realm                               0x000000010598f8f8 +[RLMRealm realmWithConfiguration:queue:error:] + 1796
10  RealmSwift                          0x00000001068afe2c $sSo8RLMRealmC13configuration5queueABSo0A13ConfigurationC_So012OS_dispatch_C0CSgtKcfCTO + 156
11  RealmSwift                          0x000000010690eab4 $s10RealmSwift0A0V13configuration5queueA2C13ConfigurationV_So012OS_dispatch_D0CSgtKcfC + 216
12  Radiata Dev                         0x000000010236b6ac $s11Radiata_Dev4UserC5realm33_E19C977A9CB5286F9E7FAC1154520478LL11storageType10RealmSwift0N0VSgAA15DatabaseServiceC07StorageM0O_tF + 272
13  Radiata Dev                         0x000000010236b590 $s11Radiata_Dev4UserC15persistentRealm0E5Swift0E0VSgvg + 28
14  Radiata Dev                         0x00000001022676e0 $s11Radiata_Dev15DatabaseServiceC11application_29didFinishLaunchingWithOptionsSbSo13UIApplicationC_SDySo0k6LaunchJ3KeyaypGSgtFyAA014AuthenticationD0C_10Foundation24NSKeyValueObservedChangeVyAA4UserCSgGtcfU0_yycfU_ + 420
15  Radiata Dev                         0x00000001022f5220 $s11Radiata_Dev13RunLoopThreadC7execute33_7437B171BCCEFE4E3F677120770C460CLLyyAA12BlockWrapperAELLCF + 904
16  Radiata Dev                         0x00000001022f52cc $s11Radiata_Dev13RunLoopThreadC7execute33_7437B171BCCEFE4E3F677120770C460CLLyyAA12BlockWrapperAELLCFTo + 60
17  Foundation                          0x000000018b6e4b90 7698BF3E-0CF6-31C0-85E9-562714F01276 + 1551248
18  CoreFoundation                      0x000000018a2ca76c 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 661356
19  CoreFoundation                      0x000000018a2ca668 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 661096
20  CoreFoundation                      0x000000018a2c9960 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 657760
21  CoreFoundation                      0x000000018a2c3a8c 727F2644-EB4E-3D57-BC2E-E6803BA92366 + 633484
22  CoreFoundation                      0x000000018a2c321c CFRunLoopRunSpecific + 600
23  Foundation                          0x000000018b572df0 7698BF3E-0CF6-31C0-85E9-562714F01276 + 36336
24  Radiata Dev                         0x00000001022f38c4 $s11Radiata_Dev13RunLoopThreadC4mainyyFyyXEfU_SbyXEfU_ + 216
25  Radiata Dev                         0x00000001022f3910 $sSbs5Error_pIgdzo_SbsAA_pIegrzo_TR + 28
26  Radiata Dev                         0x00000001022f633c $sSbs5Error_pIgdzo_SbsAA_pIegrzo_TRTA + 28
27  libswiftObjectiveC.dylib            0x00000001b017df30 $s10ObjectiveC15autoreleasepool8invokingxxyKXE_tKlF + 64
28  Radiata Dev                         0x00000001022f3324 $s11Radiata_Dev13RunLoopThreadC4mainyyFyyXEfU_ + 772
29  Radiata Dev                         0x0000000102261d48 $ss5Error_pIgzo_ytsAA_pIegrzo_TR + 24
30  Radiata Dev                         0x00000001022f3bf0 $ss5Error_pIgzo_ytsAA_pIegrzo_TRTA + 28
31  libswiftObjectiveC.dylib            0x00000001b017df30 $s10ObjectiveC15autoreleasepool8invokingxxyKXE_tKlF + 64
32  Radiata Dev                         0x00000001022f2ff8 $s11Radiata_Dev13RunLoopThreadC4mainyyF + 140
33  Radiata Dev                         0x00000001022f3c1c $s11Radiata_Dev13RunLoopThreadC4mainyyFTo + 32
34  Foundation                          0x000000018b6e4a34 7698BF3E-0CF6-31C0-85E9-562714F01276 + 1550900
35  libsystem_pthread.dylib             0x00000001d513bcb0 _pthread_start + 320
36  libsystem_pthread.dylib             0x00000001d5144778 thread_start + 8.
ragu-pdx commented 3 years ago

Is there any way to get help on this issue?

leemaguire commented 3 years ago

@ragu-pdx Are you still seeing your issue with the latest version of Realm?

ragu-pdx commented 3 years ago

@leemaguire The issue is hard to reproduce, but we have seen it on newer versions of Realm. We only just installed 10.13, so it will be a little while to truly know whether it comes about or not. What explicit changes have occurred on the Realm source to address this issue, and what is your understanding / hypotheses as to the root cause of this issue?

dianaafanador3 commented 2 years ago

Hi @ragu-pdx, we haven't been able to reproduce your issue. Have you updated to our latest version?, are you still getting this error?, If that's the case can you send us the realm file which we are not able to open, this will give us a clue to what could be happening.

pavel-ship-it commented 2 years ago

Hi @ragu-pdx, we haven't been able to reproduce your issue. Have you updated to our latest version?, are you still getting this error?, If that's the case can you send us the realm file which we are not able to open, this will give us a clue to what could be happening.

dianaafanador3 commented 2 years ago

Closing this issue as there is no response from the user. @ragu-pdxif you are still experiencing this issue, you can post a message and we will reopen the issue and look more into it