mirror of https://github.com/apache/cloudstack.git
Fix slow vm creation when large sf snapshot count (#3282)
* skip geting used bytes for volumes that are not in Ready state * updated log message * filter snapshots by state backedup * removed * import * filter templates by state 'DOWNLOADED' * refactored getUsedBytes to use O(1) queries * querying for ready volumes instead filtering in memory * make listByStoreIdInReadyState more generic ex listByStoreIdAndState * updated snapshot search criteria for listByStoreIdAndState * updated template search criteria for listByPoolIdAndState * fixed typo in search criteria for listByTemplateAndState * fixed typo in search criteria for templates in listByPoolIdAndState
This commit is contained in:
parent
67160478a6
commit
4c60a5b1ff
|
|
@ -33,6 +33,8 @@ public interface VMTemplatePoolDao extends GenericDao<VMTemplateStoragePoolVO, L
|
|||
|
||||
public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId);
|
||||
|
||||
public List<VMTemplateStoragePoolVO> listByPoolIdAndState(long poolId, ObjectInDataStoreStateMachine.State state);
|
||||
|
||||
public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState);
|
||||
|
||||
public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId);
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ import java.util.List;
|
|||
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
|
||||
|
||||
|
|
@ -55,6 +57,7 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
|||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateStatusSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplatePoolStatusSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateStatesSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplatePoolStateSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> updateStateSearch;
|
||||
|
||||
protected static final String UPDATE_TEMPLATE_HOST_REF = "UPDATE template_spool_ref SET download_state = ?, download_pct= ?, last_updated = ? "
|
||||
|
|
@ -96,6 +99,11 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
|||
TemplatePoolStatusSearch.and("download_state", TemplatePoolStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
|
||||
TemplatePoolStatusSearch.done();
|
||||
|
||||
TemplatePoolStateSearch = createSearchBuilder();
|
||||
TemplatePoolStateSearch.and("pool_id", TemplatePoolStateSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
TemplatePoolStateSearch.and("state", TemplatePoolStateSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
TemplatePoolStateSearch.done();
|
||||
|
||||
TemplateStatesSearch = createSearchBuilder();
|
||||
TemplateStatesSearch.and("template_id", TemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||
TemplateStatesSearch.and("states", TemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.IN);
|
||||
|
|
@ -138,6 +146,14 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
|||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMTemplateStoragePoolVO> listByPoolIdAndState(long poolId, ObjectInDataStoreStateMachine.State state) {
|
||||
SearchCriteria<VMTemplateStoragePoolVO> sc = TemplatePoolStateSearch.create();
|
||||
sc.setParameters("pool_id", poolId);
|
||||
sc.setParameters("state", state);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId) {
|
||||
SearchCriteria<VMTemplateStoragePoolVO> sc = TemplatePoolStatusSearch.create();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
|||
|
||||
List<VolumeVO> findByPoolId(long poolId, Volume.Type volumeType);
|
||||
|
||||
List<VolumeVO> findByPoolIdAndState(long poolid, Volume.State state);
|
||||
|
||||
List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
|
||||
|
||||
List<VolumeVO> findUsableVolumesForInstance(long instanceId);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,14 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> findByPoolIdAndState(long poolId, Volume.State state) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("poolId", poolId);
|
||||
sc.setParameters("state", state);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> findCreatedByInstance(long id) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Even
|
|||
|
||||
List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role);
|
||||
|
||||
List<SnapshotDataStoreVO> listByStoreIdAndState(long id, ObjectInDataStoreStateMachine.State state);
|
||||
|
||||
List<SnapshotDataStoreVO> listActiveOnCache(long id);
|
||||
|
||||
void deletePrimaryRecordsForStore(long id, DataStoreRole role);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import java.util.Map;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
|
||||
|
|
@ -37,8 +39,6 @@ import org.apache.log4j.Logger;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
|
|
@ -54,6 +54,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
|
||||
private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> storeSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> storeStateSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> destroyedSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> cacheSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
|
||||
|
|
@ -92,6 +93,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ);
|
||||
storeSearch.done();
|
||||
|
||||
storeStateSearch = createSearchBuilder();
|
||||
storeStateSearch.and("store_id", storeStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeStateSearch.and("state", storeStateSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
storeStateSearch.done();
|
||||
|
||||
destroyedSearch = createSearchBuilder();
|
||||
destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -221,6 +227,14 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> listByStoreIdAndState(long id, ObjectInDataStoreStateMachine.State state) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = storeStateSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
sc.setParameters("state", state);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePrimaryRecordsForStore(long id, DataStoreRole role) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
|
||||
|
|
|
|||
|
|
@ -72,10 +72,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.storage.command.CommandResult;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
|
@ -104,9 +107,10 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
@Inject private HostDao hostDao;
|
||||
@Inject private SnapshotDao snapshotDao;
|
||||
@Inject private SnapshotDetailsDao snapshotDetailsDao;
|
||||
@Inject private SnapshotDataStoreDao snapshotDataStoreDao;
|
||||
@Inject private PrimaryDataStoreDao storagePoolDao;
|
||||
@Inject private StoragePoolDetailsDao storagePoolDetailsDao;
|
||||
@Inject private VMTemplatePoolDao tmpltPoolDao;
|
||||
@Inject private VMTemplatePoolDao vmTemplatePoolDao;
|
||||
@Inject private VolumeDao volumeDao;
|
||||
@Inject private VolumeDetailsDao volumeDetailsDao;
|
||||
@Inject private VolumeDataFactory volumeFactory;
|
||||
|
|
@ -360,7 +364,7 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
private long getUsedBytes(StoragePool storagePool, long volumeIdToIgnore) {
|
||||
long usedSpace = 0;
|
||||
|
||||
List<VolumeVO> lstVolumes = volumeDao.findByPoolId(storagePool.getId(), null);
|
||||
List<VolumeVO> lstVolumes = volumeDao.findByPoolIdAndState(storagePool.getId(), Volume.State.Ready);
|
||||
|
||||
if (lstVolumes != null) {
|
||||
for (VolumeVO volume : lstVolumes) {
|
||||
|
|
@ -368,62 +372,26 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
continue;
|
||||
}
|
||||
|
||||
VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volume.getId(), SolidFireUtil.VOLUME_SIZE);
|
||||
usedSpace += getVolumeSizeIncludingHypervisorSnapshotReserve(volume.getSize(),volume.getHypervisorSnapshotReserve());
|
||||
|
||||
if (volumeDetail != null && volumeDetail.getValue() != null) {
|
||||
long volumeSize = Long.parseLong(volumeDetail.getValue());
|
||||
|
||||
usedSpace += volumeSize;
|
||||
}
|
||||
else {
|
||||
SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
|
||||
|
||||
try {
|
||||
long lVolumeId = Long.parseLong(volume.getFolder());
|
||||
|
||||
SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, lVolumeId);
|
||||
|
||||
long volumeSize = sfVolume.getTotalSize();
|
||||
|
||||
// SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
|
||||
// To be backward compatible with releases prior to 4.5, call updateVolumeDetails here.
|
||||
// That way if SolidFireUtil.VOLUME_SIZE wasn't put in the volume_details table when the
|
||||
// volume was initially created, it can be placed in volume_details here.
|
||||
updateVolumeDetails(volume.getId(), volumeSize, sfVolume.getScsiNaaDeviceId());
|
||||
|
||||
usedSpace += volumeSize;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// can be ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<SnapshotVO> lstSnapshots = snapshotDao.listAll();
|
||||
List<SnapshotDataStoreVO> snapshotDataStoreVOList = snapshotDataStoreDao.listByStoreIdAndState(storagePool.getId(), ObjectInDataStoreStateMachine.State.Ready);
|
||||
|
||||
if (lstSnapshots != null) {
|
||||
for (SnapshotVO snapshot : lstSnapshots) {
|
||||
SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.STORAGE_POOL_ID);
|
||||
if (snapshotDataStoreVOList != null) {
|
||||
for (SnapshotDataStoreVO snapshot : snapshotDataStoreVOList) {
|
||||
|
||||
// if this snapshot belongs to the storagePool that was passed in
|
||||
if (snapshotDetails != null && snapshotDetails.getValue() != null && Long.parseLong(snapshotDetails.getValue()) == storagePool.getId()) {
|
||||
snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.VOLUME_SIZE);
|
||||
usedSpace += snapshot.getPhysicalSize();
|
||||
|
||||
if (snapshotDetails != null && snapshotDetails.getValue() != null) {
|
||||
long snapshotSize = Long.parseLong(snapshotDetails.getValue());
|
||||
|
||||
usedSpace += snapshotSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
|
||||
List<VMTemplateStoragePoolVO> vmTemplateStoragePoolVOList = vmTemplatePoolDao.listByPoolIdAndState(storagePool.getId(), ObjectInDataStoreStateMachine.State.Ready);
|
||||
|
||||
if (lstTemplatePoolRefs != null) {
|
||||
for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
|
||||
usedSpace += templatePoolRef.getTemplateSize();
|
||||
if (vmTemplateStoragePoolVOList != null) {
|
||||
for (VMTemplateStoragePoolVO template : vmTemplateStoragePoolVOList) {
|
||||
usedSpace += template.getTemplateSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -487,7 +455,7 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
*/
|
||||
@Override
|
||||
public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
|
||||
List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
|
||||
List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = vmTemplatePoolDao.listByPoolId(storagePool.getId());
|
||||
|
||||
if (lstTemplatePoolRefs != null) {
|
||||
for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
|
||||
|
|
@ -740,7 +708,7 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
sfVolumeId = Long.parseLong(snapshotDetails.getValue());
|
||||
} else if (dataObjectType == DataObjectType.TEMPLATE) {
|
||||
// get the cached template on this storage
|
||||
VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
|
||||
VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
|
||||
|
||||
if (templatePoolRef != null) {
|
||||
sfVolumeId = Long.parseLong(templatePoolRef.getLocalDownloadPath());
|
||||
|
|
@ -1166,13 +1134,13 @@ public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
|
||||
String iqn = sfVolume.getIqn();
|
||||
|
||||
VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId());
|
||||
VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId());
|
||||
|
||||
templatePoolRef.setInstallPath(iqn);
|
||||
templatePoolRef.setLocalDownloadPath(Long.toString(sfVolume.getId()));
|
||||
templatePoolRef.setTemplateSize(sfVolume.getTotalSize());
|
||||
|
||||
tmpltPoolDao.update(templatePoolRef.getId(), templatePoolRef);
|
||||
vmTemplatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
|
||||
|
||||
StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue