realm-kotlin icon indicating copy to clipboard operation
realm-kotlin copied to clipboard

Realms file grows "infinitely"

Open astatio opened this issue 3 years ago • 1 comments

I have a realms file that grows "infinitely" (theoretically). I update this file around 5 times a second and I get the latest version using a write transaction (doing the query outside a write transaction and then updating inside of it will throw an exception so this is the only way possible) and I always put each one of these write transactions inside a try-with-resources.

The logic is looking up an ID and getting a long field and add a quantity to it everytime the function is triggered.

The file grows immensity big and within a month the file grew to 23GB! When I open it with Realm Studio and export as a new realm file the resulting size is a mere 705KB - far more accurate when taking into account the small amount of data inside. I was unable to find anything in the documentation that could justify this behaviour but it's really bad to have a file grow this large unnecessarily. Why does this happen?

astatio avatar Sep 15 '22 12:09 astatio

Hi @astatio

Sorry for the late reply.

This normally happens due to something called "version pinning", which happens when you are holding a reference to an object while other writes are happening. Realm is an MVCC database, so we track all live versions of the Realm. You can read more about this here: https://www.mongodb.com/docs/realm/sdk/swift/crud/threading/#realm-s-threading-model-in-depth

In Kotlin you can try to enable this setting https://www.mongodb.com/docs/realm-sdks/kotlin/1.0.2/library-base/-realm%20-kotlin%20-s-d-k/io.realm.kotlin/-configuration/max-number-of-active-versions.html which will catch it if this happens.

We are also in the process of making some internal changes, so the chance of this happening is much lower. See https://github.com/realm/realm-core/pull/5440

For now, if you hit this, you need to ensure that you are not holding on to objects for longer than you strictly need them. Perhaps copying their data in memory and releasing the object.

I hope that clarifies things.

cmelchior avatar Sep 20 '22 11:09 cmelchior

@cmelchior I have the same issue here. What do you mean in practice to "Perhaps copying their data in memory and releasing the object." Is there a method we should call to release the object? Also when using frozen objects through flows, this should not be an issue because the object is not managed, right?

Also I tried logging getNumberOfActiveVersions, and it looks like it increments at each transaction, even if there is no observer at all.

Just using the exemple code :

class MainActivity : AppCompatActivity() {

    private val binding by viewBinding(ActivityMainBinding::inflate)

    private val config = RealmConfiguration.Builder(schema = setOf(Item::class)).maxNumberOfActiveVersions().build()
    private val realm: Realm = Realm.open(config)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        binding.btnWriteTransaction.setOnClickListener {
            Log.v("MainActivity", "Number of active versions: ${realm.getNumberOfActiveVersions()}")
            realm.writeBlocking {
                copyToRealm(Item().apply {
                    summary = "Do the laundry"
                    isComplete = false
                })
            }
        }
    }
}

class Item() : RealmObject {
    @PrimaryKey
    var _id: ObjectId = ObjectId.create()
    var isComplete: Boolean = false
    var summary: String = ""
    var owner_id: String = ""

    constructor(ownerId: String = "") : this() {
        owner_id = ownerId
    }
}

See the logs :

2022-10-21 10:28:16.875 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 1
2022-10-21 10:28:17.502 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 2
2022-10-21 10:28:17.669 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 3
2022-10-21 10:28:20.188 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 4
2022-10-21 10:28:20.336 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 5
2022-10-21 10:28:20.503 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 6
2022-10-21 10:28:20.636 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 7
2022-10-21 10:28:20.786 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 8
2022-10-21 10:28:20.920 25322-25322 MainActivity            com...ple.realmkotlinactivesessions  V  Number of active versions: 9
2022-10-21 10:40:59.078 28723-28723 AndroidRuntime          com...ple.realmkotlinactivesessions  E  FATAL EXCEPTION: main
                                                                                                    Process: com.example.realmkotlinactivesessions, PID: 28723
                                                                                                    java.lang.IllegalStateException: Cannot begin the write transaction: RealmCoreException([5]: Number of active versions (9) in the Realm exceeded the limit of 8)

Closing/Opening the realm instance between each transaction keep the number of version to 1, but the doc clearly indicates to keep a global singleton instance.

ganfra avatar Oct 20 '22 17:10 ganfra

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

github-actions[bot] avatar Jan 11 '23 00:01 github-actions[bot]

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

github-actions[bot] avatar Jan 12 '23 00:01 github-actions[bot]

I would like to state that this was finally fixed with 1.6.0 Amazing!

astatio avatar Jan 30 '23 14:01 astatio

Despite the bot reopening, i will close it as its fixed now.

astatio avatar Jan 30 '23 14:01 astatio