From de252adadf4816b62d5e686b92b42837ae83e20a Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Sat, 15 Mar 2014 12:56:19 -0700 Subject: [PATCH] avoid mysql lock-promotion situation. --- .../src/com/cloud/host/dao/HostDaoImpl.java | 3 +- .../com/cloud/vm/dao/VMInstanceDaoImpl.java | 61 ++++++++++--------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index 426c90db69c..3a3bdf67b91 100755 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -899,7 +899,8 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao @Override public boolean updateState(Status oldStatus, Event event, Status newStatus, Host vo, Object data) { - HostVO host = findById(vo.getId()); + // lock target row from beginning to avoid lock-promotion caused deadlock + HostVO host = lockRow(vo.getId(), true); if (host == null) { if (event == Event.Remove && newStatus == Status.Removed) { host = findByIdIncludingRemoved(vo.getId()); diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 7c5949290d7..0c13ae7f7c3 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -417,41 +417,44 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public boolean updateState(State oldState, Event event, State newState, VirtualMachine vm, Object opaque) { - if (newState == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString()); - } - return false; - } + if (newState == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString()); + } + return false; + } - @SuppressWarnings("unchecked") - Pair hosts = (Pair)opaque; - Long newHostId = hosts.second(); + @SuppressWarnings("unchecked") + Pair hosts = (Pair)opaque; + Long newHostId = hosts.second(); - VMInstanceVO vmi = (VMInstanceVO)vm; - Long oldHostId = vmi.getHostId(); - Long oldUpdated = vmi.getUpdated(); - Date oldUpdateDate = vmi.getUpdateTime(); - if (newState.equals(oldState) && newHostId != null && newHostId.equals(oldHostId)) { - // state is same, don't need to update - return true; - } + VMInstanceVO vmi = (VMInstanceVO)vm; + Long oldHostId = vmi.getHostId(); + Long oldUpdated = vmi.getUpdated(); + Date oldUpdateDate = vmi.getUpdateTime(); + if ( newState.equals(oldState) && newHostId != null && newHostId.equals(oldHostId) ) { + // state is same, don't need to update + return true; + } - SearchCriteria sc = StateChangeSearch.create(); - sc.setParameters("id", vmi.getId()); - sc.setParameters("states", oldState); - sc.setParameters("host", vmi.getHostId()); - sc.setParameters("update", vmi.getUpdated()); + // lock the target row at beginning to avoid lock-promotion caused deadlock + lockRow(vm.getId(), true); + + SearchCriteria sc = StateChangeSearch.create(); + sc.setParameters("id", vmi.getId()); + sc.setParameters("states", oldState); + sc.setParameters("host", vmi.getHostId()); + sc.setParameters("update", vmi.getUpdated()); - vmi.incrUpdated(); - UpdateBuilder ub = getUpdateBuilder(vmi); + vmi.incrUpdated(); + UpdateBuilder ub = getUpdateBuilder(vmi); - ub.set(vmi, "state", newState); - ub.set(vmi, "hostId", newHostId); - ub.set(vmi, "podIdToDeployIn", vmi.getPodIdToDeployIn()); - ub.set(vmi, _updateTimeAttr, new Date()); + ub.set(vmi, "state", newState); + ub.set(vmi, "hostId", newHostId); + ub.set(vmi, "podIdToDeployIn", vmi.getPodIdToDeployIn()); + ub.set(vmi, _updateTimeAttr, new Date()); - int result = update(vmi, sc); + int result = update(vmi, sc); if (result == 0) { VMInstanceVO vo = findByIdIncludingRemoved(vm.getId());