CS-12510: Deleting the host_details and inserting them back causes deadlocks.

Reviewed-By: Alex

Changes:
- Deleting and inserting the host_details in one transaction leads to this MySQL deadlock issue sometimes
- This fix is to use the ON DUPLICATE KEY UPDATE MySQL query that will insert the deatils if they are new or update the ones that are existing.
- This needs a UNIQUE constraint on host_details.
This commit is contained in:
prachi 2012-08-01 17:23:26 -07:00
parent 610a1749cf
commit cfd8ef8fce
4 changed files with 44 additions and 11 deletions

View File

@ -12,6 +12,8 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.host.dao;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -24,6 +26,7 @@ import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@Local(value=HostDetailsDao.class)
public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements HostDetailsDao {
@ -84,19 +87,26 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
@Override
public void persist(long hostId, Map<String, String> details) {
final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?";
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<DetailVO> sc = HostSearch.create();
sc.setParameters("hostId", hostId);
expunge(sc);
for (Map.Entry<String, String> detail : details.entrySet()) {
String value = detail.getValue();
if("password".equals(detail.getKey())){
value = DBEncryptionUtil.encrypt(value);
}
DetailVO vo = new DetailVO(hostId, detail.getKey(), value);
persist(vo);
String value = detail.getValue();
if("password".equals(detail.getKey())){
value = DBEncryptionUtil.encrypt(value);
}
try {
PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertOrUpdateSql);
pstmt.setLong(1, hostId);
pstmt.setString(2, detail.getKey());
pstmt.setString(3, value);
pstmt.setString(4, value);
pstmt.executeUpdate();
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to persist the host_details key: "+ detail.getKey() +" for host id: "+hostId, e);
}
}
txn.commit();
}

View File

@ -23,6 +23,7 @@ import org.apache.log4j.Logger;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
public class Upgrade303to304 extends Upgrade30xBase implements DbUpgrade {
final static Logger s_logger = Logger.getLogger(Upgrade303to304.class);
@ -44,7 +45,12 @@ public class Upgrade303to304 extends Upgrade30xBase implements DbUpgrade {
@Override
public File[] getPrepareScripts() {
return null;
String script = Script.findScript("", "db/schema-303to304.sql");
if (script == null) {
throw new CloudRuntimeException("Unable to find db/schema-303to304.sql");
}
return new File[] { new File(script) };
}
@Override

View File

@ -815,7 +815,8 @@ CREATE TABLE `cloud`.`host_details` (
`name` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE
CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
CONSTRAINT UNIQUE KEY (`host_id`, `name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`mshost` (

View File

@ -0,0 +1,16 @@
# Copyright 2012 Citrix Systems, Inc. Licensed under the
# Apache License, Version 2.0 (the "License"); you may not use this
# file except in compliance with the License. Citrix Systems, Inc.
# reserves all rights not expressly granted by the License.
# You may obtain a copy of the License at http:#www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#Schema upgrade from 3.0.3 to 3.0.4;
ALTER TABLE `cloud`.`host_details` ADD CONSTRAINT UNIQUE KEY (`host_id`, `name`);