mirror of https://github.com/apache/cloudstack.git
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:
parent
610a1749cf
commit
cfd8ef8fce
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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` (
|
||||
|
|
|
|||
|
|
@ -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`);
|
||||
Loading…
Reference in New Issue