mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-8423: [Xenserver] Improved the performance for processing of ClusterVMMetaDataSync command which can cause slowness in DB if there are huge number of VMs
this closes #204
This commit is contained in:
parent
f46ed59290
commit
866cc41145
|
|
@ -2558,40 +2558,58 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
if (vmMetadatum == null || vmMetadatum.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmDetails = _userVmDao.getVmsDetailByNames(vmMetadatum.keySet(), "platform");
|
||||
for (final Map.Entry<String, String> entry : vmMetadatum.entrySet()) {
|
||||
final String name = entry.getKey();
|
||||
final String platform = entry.getValue();
|
||||
if (platform == null || platform.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
final VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
|
||||
if (vm != null && vm.getType() == VirtualMachine.Type.User) {
|
||||
boolean changed = false;
|
||||
final UserVmVO userVm = _userVmDao.findById(vm.getId());
|
||||
_userVmDao.loadDetails(userVm);
|
||||
if ( userVm.details.containsKey("timeoffset")) {
|
||||
userVm.details.remove("timeoffset");
|
||||
changed = true;
|
||||
|
||||
boolean found = false;
|
||||
for(Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>> vmDetail : vmDetails ) {
|
||||
Pair<String, VirtualMachine.Type> vmNameTypePair = vmDetail.first();
|
||||
if(vmNameTypePair.first().equals(name)) {
|
||||
found = true;
|
||||
if(vmNameTypePair.second() == VirtualMachine.Type.User) {
|
||||
Pair<Long, String> detailPair = vmDetail.second();
|
||||
String platformDetail = detailPair.second();
|
||||
|
||||
if (platformDetail != null && platformDetail.equals(platform)) {
|
||||
break;
|
||||
}
|
||||
updateVmMetaData(detailPair.first(), platform);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!userVm.details.containsKey("platform") || !userVm.details.get("platform").equals(platform)) {
|
||||
userVm.setDetail("platform", platform);
|
||||
changed = true;
|
||||
}
|
||||
String pvdriver = "xenserver56";
|
||||
if ( platform.contains("device_id")) {
|
||||
pvdriver = "xenserver61";
|
||||
}
|
||||
if (!userVm.details.containsKey("hypervisortoolsversion") || !userVm.details.get("hypervisortoolsversion").equals(pvdriver)) {
|
||||
userVm.setDetail("hypervisortoolsversion", pvdriver);
|
||||
changed = true;
|
||||
}
|
||||
if ( changed ) {
|
||||
_userVmDao.saveDetails(userVm);
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
|
||||
if(vm.getType() == VirtualMachine.Type.User) {
|
||||
updateVmMetaData(vm.getId(), platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is XenServer specific
|
||||
private void updateVmMetaData(Long vmId, String platform) {
|
||||
UserVmVO userVm = _userVmDao.findById(vmId);
|
||||
_userVmDao.loadDetails(userVm);
|
||||
if ( userVm.details.containsKey("timeoffset")) {
|
||||
userVm.details.remove("timeoffset");
|
||||
}
|
||||
userVm.setDetail("platform", platform);
|
||||
String pvdriver = "xenserver56";
|
||||
if ( platform.contains("device_id")) {
|
||||
pvdriver = "xenserver61";
|
||||
}
|
||||
if (!userVm.details.containsKey("hypervisortoolsversion") || !userVm.details.get("hypervisortoolsversion").equals(pvdriver)) {
|
||||
userVm.setDetail("hypervisortoolsversion", pvdriver);
|
||||
}
|
||||
_userVmDao.saveDetails(userVm);
|
||||
}
|
||||
|
||||
private void ensureVmRunningContext(final long hostId, VMInstanceVO vm, final Event cause) throws OperationTimedoutException, ResourceUnavailableException,
|
||||
NoTransitionException, InsufficientAddressCapacityException {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@ package com.cloud.vm.dao;
|
|||
import java.util.Date;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
public interface UserVmDao extends GenericDao<UserVmVO, Long> {
|
||||
|
|
@ -80,4 +83,5 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {
|
|||
|
||||
List<UserVmVO> listByIsoId(Long isoId);
|
||||
|
||||
List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> getVmsDetailByNames(Set<String> vmNames, String detail);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ import java.util.Date;
|
|||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
|
|
@ -102,6 +104,11 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
|||
+ "left join security_group on security_group_vm_map.security_group_id=security_group.id " + "left join nics on vm_instance.id=nics.instance_id "
|
||||
+ "left join networks on nics.network_id=networks.id " + "left join user_ip_address on user_ip_address.vm_id=vm_instance.id " + "where vm_instance.id in (";
|
||||
|
||||
private static final String VMS_DETAIL_BY_NAME = "select vm_instance.instance_name, vm_instance.vm_type, vm_instance.id , user_vm_details.value, user_vm_details.name from vm_instance "
|
||||
+ "left join user_vm_details on vm_instance.id = user_vm_details.vm_id where (user_vm_details.name is null or user_vm_details.name = '";
|
||||
|
||||
private static final String VMS_DETAIL_BY_NAME2 = "') and vm_instance.instance_name in (";
|
||||
|
||||
private static final int VM_DETAILS_BATCH_SIZE = 100;
|
||||
|
||||
@Inject
|
||||
|
|
@ -631,4 +638,39 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> getVmsDetailByNames(Set<String> vmNames, String detail) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmsDetailByNames = new ArrayList<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>>();
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
pstmt = txn.prepareStatement(VMS_DETAIL_BY_NAME + detail + VMS_DETAIL_BY_NAME2 + getQueryBatchAppender(vmNames.size()));
|
||||
int i = 1;
|
||||
for(String name : vmNames) {
|
||||
pstmt.setString(i, name);
|
||||
i++;
|
||||
}
|
||||
try {
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
vmsDetailByNames.add(new Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>(new Pair<String, VirtualMachine.Type>(
|
||||
rs.getString("vm_instance.instance_name"), VirtualMachine.Type.valueOf(rs.getString("vm_type"))),
|
||||
new Pair<Long, String>(rs.getLong("vm_instance.id"), rs.getString("user_vm_details.value"))));
|
||||
}
|
||||
rs.close();
|
||||
} catch (Exception e) {
|
||||
s_logger.error("GetVmsDetailsByNames: Exception: " + e.getMessage());
|
||||
throw new CloudRuntimeException("GetVmsDetailsByNames: Exception: " + e.getMessage());
|
||||
}
|
||||
if(pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.error("GetVmsDetailsByNames: Exception in sql: " + e.getMessage());
|
||||
throw new CloudRuntimeException("GetVmsDetailsByNames: Exception: " + e.getMessage());
|
||||
}
|
||||
|
||||
return vmsDetailByNames;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -717,6 +717,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
if (record.isControlDomain || record.isASnapshot || record.isATemplate) {
|
||||
continue; // Skip DOM0
|
||||
}
|
||||
String platform = StringUtils.mapToString(record.platform);
|
||||
if (platform.isEmpty()) {
|
||||
continue; //Skip if platform is null
|
||||
}
|
||||
vmMetaDatum.put(record.nameLabel, StringUtils.mapToString(record.platform));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue