Skip to content

Commit b7fc717

Browse files
authored
Add batch deletion support to removeRawUsageRecords (apache#12522)
* Add batch deletion support to `removeRawUsageRecords` * Remove ORDER BY from batch expunge
1 parent 243872a commit b7fc717

File tree

6 files changed

+29
-22
lines changed

6 files changed

+29
-22
lines changed

engine/schema/src/main/java/com/cloud/usage/dao/UsageDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public interface UsageDao extends GenericDao<UsageVO, Long> {
6262

6363
void saveUsageRecords(List<UsageVO> usageRecords);
6464

65-
void removeOldUsageRecords(int days);
65+
void expungeAllOlderThan(int days, long limitPerQuery);
6666

6767
UsageVO persistUsage(final UsageVO usage);
6868

engine/schema/src/main/java/com/cloud/usage/dao/UsageDaoImpl.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@
2626
import com.cloud.utils.db.Filter;
2727
import com.cloud.utils.db.GenericDaoBase;
2828
import com.cloud.utils.db.QueryBuilder;
29+
import com.cloud.utils.db.SearchBuilder;
2930
import com.cloud.utils.db.SearchCriteria;
3031
import com.cloud.utils.db.Transaction;
3132
import com.cloud.utils.db.TransactionCallback;
32-
import com.cloud.utils.db.TransactionCallbackNoReturn;
3333
import com.cloud.utils.db.TransactionLegacy;
3434
import com.cloud.utils.db.TransactionStatus;
3535
import com.cloud.utils.exception.CloudRuntimeException;
3636

3737
import org.apache.cloudstack.acl.RoleType;
38+
import org.apache.commons.lang3.time.DateUtils;
3839
import org.springframework.stereotype.Component;
3940

4041
import java.sql.PreparedStatement;
@@ -51,7 +52,6 @@
5152
public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements UsageDao {
5253
private static final String DELETE_ALL = "DELETE FROM cloud_usage";
5354
private static final String DELETE_ALL_BY_ACCOUNTID = "DELETE FROM cloud_usage WHERE account_id = ?";
54-
private static final String DELETE_ALL_BY_INTERVAL = "DELETE FROM cloud_usage WHERE end_date < DATE_SUB(CURRENT_DATE(), INTERVAL ? DAY)";
5555
private static final String INSERT_ACCOUNT = "INSERT INTO cloud_usage.account (id, account_name, uuid, type, role_id, domain_id, removed, cleanup_needed) VALUES (?,?,?,?,?,?,?,?)";
5656
private static final String INSERT_USER_STATS = "INSERT INTO cloud_usage.user_statistics (id, data_center_id, account_id, public_ip_address, device_id, device_type, network_id, net_bytes_received,"
5757
+ " net_bytes_sent, current_bytes_received, current_bytes_sent, agg_bytes_received, agg_bytes_sent) VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?)";
@@ -88,8 +88,12 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
8888

8989
private static final String UPDATE_BUCKET_STATS = "UPDATE cloud_usage.bucket_statistics SET size=? WHERE id=?";
9090

91+
protected SearchBuilder<UsageVO> endDateLessThanSearch;
9192

9293
public UsageDaoImpl() {
94+
endDateLessThanSearch = createSearchBuilder();
95+
endDateLessThanSearch.and("endDate", endDateLessThanSearch.entity().getEndDate(), SearchCriteria.Op.LT);
96+
endDateLessThanSearch.done();
9397
}
9498

9599
@Override
@@ -539,21 +543,20 @@ public void saveUsageRecords(List<UsageVO> usageRecords) {
539543
}
540544

541545
@Override
542-
public void removeOldUsageRecords(int days) {
543-
Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallbackNoReturn() {
544-
@Override
545-
public void doInTransactionWithoutResult(TransactionStatus status) {
546-
TransactionLegacy txn = TransactionLegacy.currentTxn();
547-
PreparedStatement pstmt = null;
548-
try {
549-
pstmt = txn.prepareAutoCloseStatement(DELETE_ALL_BY_INTERVAL);
550-
pstmt.setLong(1, days);
551-
pstmt.executeUpdate();
552-
} catch (Exception ex) {
553-
logger.error("error removing old cloud_usage records for interval: " + days);
554-
}
555-
}
556-
});
546+
public void expungeAllOlderThan(int days, long limitPerQuery) {
547+
SearchCriteria<UsageVO> sc = endDateLessThanSearch.create();
548+
549+
Date limit = DateUtils.addDays(new Date(), -days);
550+
sc.setParameters("endDate", limit);
551+
552+
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
553+
try {
554+
logger.debug("Removing all cloud_usage records older than [{}].", limit);
555+
int totalExpunged = batchExpunge(sc, limitPerQuery);
556+
logger.info("Removed a total of [{}] cloud_usage records older than [{}].", totalExpunged, limit);
557+
} finally {
558+
txn.close();
559+
}
557560
}
558561

559562
public UsageVO persistUsage(final UsageVO usage) {

framework/db/src/main/java/com/cloud/utils/db/Filter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public Filter(Class<?> clazz, String field, boolean ascending) {
5757
}
5858

5959
public Filter(long limit) {
60-
_orderBy = " ORDER BY RAND() LIMIT " + limit;
60+
_orderBy = " ORDER BY RAND()";
61+
_limit = limit;
6162
}
6263

6364
public Filter(Long offset, Long limit) {

framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,8 @@ protected void addFilter(final StringBuilder sql, final Filter filter) {
11611161
if (filter.getLimit() != null) {
11621162
sql.append(", ").append(filter.getLimit());
11631163
}
1164+
} else if (filter.getLimit() != null) {
1165+
sql.append(" LIMIT ").append(filter.getLimit());
11641166
}
11651167
}
11661168
}
@@ -1322,7 +1324,7 @@ public int batchExpunge(final SearchCriteria<T> sc, final Long batchSize) {
13221324
Filter filter = null;
13231325
final long batchSizeFinal = ObjectUtils.defaultIfNull(batchSize, 0L);
13241326
if (batchSizeFinal > 0) {
1325-
filter = new Filter(batchSizeFinal);
1327+
filter = new Filter(null, batchSizeFinal);
13261328
}
13271329
int expunged = 0;
13281330
int currentExpunged = 0;

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
527527
public static final ConfigKey<Long> DELETE_QUERY_BATCH_SIZE = new ConfigKey<>("Advanced", Long.class, "delete.query.batch.size", "0",
528528
"Indicates the limit applied while deleting entries in bulk. With this, the delete query will apply the limit as many times as necessary," +
529529
" to delete all the entries. This is advised when retaining several days of records, which can lead to slowness. <= 0 means that no limit will " +
530-
"be applied. Default value is 0. For now, this is used for deletion of vm & volume stats only.", true);
530+
"be applied. Default value is 0. For now, this is used for deletion of VM stats, volume stats, and usage records.", true);
531531

532532
private static final String IOPS_READ_RATE = "IOPS Read";
533533
private static final String IOPS_WRITE_RATE = "IOPS Write";

server/src/main/java/com/cloud/usage/UsageServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import javax.inject.Inject;
2727
import javax.naming.ConfigurationException;
2828

29+
import com.cloud.configuration.ConfigurationManagerImpl;
2930
import org.apache.cloudstack.api.command.admin.usage.GenerateUsageRecordsCmd;
3031
import org.apache.cloudstack.api.command.admin.usage.ListUsageRecordsCmd;
3132
import org.apache.cloudstack.api.command.admin.usage.RemoveRawUsageRecordsCmd;
@@ -489,7 +490,7 @@ public boolean removeRawUsageRecords(RemoveRawUsageRecordsCmd cmd) throws Invali
489490
}
490491
}
491492
}
492-
_usageDao.removeOldUsageRecords(interval);
493+
_usageDao.expungeAllOlderThan(interval, ConfigurationManagerImpl.DELETE_QUERY_BATCH_SIZE.value());
493494
} else {
494495
throw new InvalidParameterValueException("Invalid interval value. Interval to remove cloud_usage records should be greater than 0");
495496
}

0 commit comments

Comments
 (0)