Every Magento developer has at least once encountered situation where long lasting module upgrade script caused issue for end customers. Or even worse, fail over and over, due to being executed multiple times.
Of course, there is a very simple solution for this. And since we have encountered many sites which do not use this approach, I have decided to share it with you.
Analyzing the problem
Consider following scenario: You are performing an module upgrade of an outdated extension. During this upgrade, it is required to create few extra tables, as well as insert one or two new attributes. You have successfully deployed your code, which means that next page request will trigger those upgrades.
Before you manage to refresh page in your browser, there is already a customer waiting for those scripts to be executed. And before you know it, there is another one waiting as well. In this scenario, it is most likely that only one will get desired result, while others will most likely end up with maintenance page.
Let’s see what happened here: When script starts, Magento does not know that module is currently being processed (no in progress state). So, as far as system is concerned, module is outdated and should be update. This is true for each request, until one of them finishes all module upgrade scripts, and increments its version.
Therefore, it is possible (and most likely) for multiple requests to attempt creating same attribute, causing all but one to fail.
Finding the solution
So how can we prevent this? The answer is simple: disable automatic processing of module upgrade scripts by adding this snippet into local.xml in global node:
This line will instruct Magento to skip module upgrades during application initialization. However, keep in mind that this will be ignored if your site is in develop mode (dev server, local environment, etc.). To preserve same behavior on those environments as well, add one more line to the same place:
And there you go, Magento will no longer automatically trigger module updates. Which, of course, is another problem because now you need to find another way to do it.
Manually trigger module upgrade
Luckily for you, someone already wrote you a script for addressing this issue. You can find several variations over the internet, but first one I have encountered was one developed by Colin Mollenhour:
Copy and paste it to your shell folder, and execute it after each deployment. It will trigger upgrades for you, and recreate config cache for you. This way, your module upgrade would have minimal effect on fronted. Also you will benefit from triggering upgrades from shell when it comes to timeouts and memory allowed for PHP process (different config file, different settings).
Just one last note here, keep in mind that from now on, your changes need to be backwards compatible. You can not deploy code that depends on attribute that is yet to be created. Either place site under maintenance while install is finished, or deploy code in two stages.
I hope that you find this helpful.