MySQL and upgrade tasks AO deadlock

We have upgrade tasks that extend com.atlassian.sal.api.upgrade.PluginUpgradeTask and commonly use active objects within the upgrade task to load and save values stored in the database. We’re using AO as a key value store and it appears com.atlassian.activeobjects.external.ActiveObjectsUpgradeTask would not allow us to just update the values for a specific key.

The problem we’re facing with MySQL is that when the upgrade tasks are run and we interact with AO there is a deadlock in the upgrade task because of AO starting up and migrating objects on startup which happens after the PluginEnabledEvent.

We’re using com.atlassian.activeobjects.external.ActiveObjects#executeInTransaction to load and save the data in the upgrade task.

Unfortunately some of our customers are using MySQL and we’ve tested with MySQL version 5.6.39 on Bitbucket Server 5.0.2 which seems to be supported by Atlassian and has this issue I’ve described.

We’d like to know what we should do to mitigate this issue for MySQL?

We’ve tested with other databases like PostGres and all seems ok.

Thanks,
Adam

1 Like

UpgradeTasks looks awesome and easy on the surface. (Just be aware that they are broken and will run on every plugin start - you need to block for it) but very quickly become a pain since the system isn’t fully initialized and you’re blocking it from finishing (so be fast).

The best way is to not use them. If you can do the upgrade lazily (ie when the object is interacted with) - it avoids a lot of the issues. Second best approach is to have a ui that forces the admin to do it (has the benefit of them knowing the seriousness of things).

If none of this works - you could use lifecycleaware or the scheduler and just do things once the plugin system is initializes.

2 Likes

Thanks for sharing, Dan. You just saved me a lot of pain.

Thanks Dan and sorry for the belated reply. In our case we’d gone too far down the Active Objects route to change.

I could foresee some problems doing the upgrade lazily due to the nature of our app. Forcing the admin to do it would have required quite a bit of rework on the UI side.

In our case we didn’t want a bunch of old code lying around to support backwards compatibility, but in the future I think we’ll have to live with it.