use of org.apache.activemq.artemis.core.persistence.impl.PageCountPending in project activemq-artemis by apache.
the class ActiveMQServerImpl method loadJournals.
private JournalLoadInformation[] loadJournals() throws Exception {
JournalLoader journalLoader = activation.createJournalLoader(postOffice, pagingManager, storageManager, queueFactory, nodeManager, managementService, groupingHandler, configuration, parentServer);
JournalLoadInformation[] journalInfo = new JournalLoadInformation[2];
List<QueueBindingInfo> queueBindingInfos = new ArrayList<>();
List<GroupingInfo> groupingInfos = new ArrayList<>();
List<AddressBindingInfo> addressBindingInfos = new ArrayList<>();
journalInfo[0] = storageManager.loadBindingJournal(queueBindingInfos, groupingInfos, addressBindingInfos);
recoverStoredConfigs();
Map<Long, AddressBindingInfo> addressBindingInfosMap = new HashMap<>();
journalLoader.initAddresses(addressBindingInfosMap, addressBindingInfos);
Map<Long, QueueBindingInfo> queueBindingInfosMap = new HashMap<>();
journalLoader.initQueues(queueBindingInfosMap, queueBindingInfos);
journalLoader.handleGroupingBindings(groupingInfos);
Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap = new HashMap<>();
HashSet<Pair<Long, Long>> pendingLargeMessages = new HashSet<>();
List<PageCountPending> pendingNonTXPageCounter = new LinkedList<>();
journalInfo[1] = storageManager.loadMessageJournal(postOffice, pagingManager, resourceManager, queueBindingInfosMap, duplicateIDMap, pendingLargeMessages, pendingNonTXPageCounter, journalLoader);
journalLoader.handleDuplicateIds(duplicateIDMap);
for (Pair<Long, Long> msgToDelete : pendingLargeMessages) {
ActiveMQServerLogger.LOGGER.deletingPendingMessage(msgToDelete);
LargeServerMessage msg = storageManager.createLargeMessage();
msg.setMessageID(msgToDelete.getB());
msg.setPendingRecordID(msgToDelete.getA());
msg.setDurable(true);
msg.deleteFile();
}
if (pendingNonTXPageCounter.size() != 0) {
try {
journalLoader.recoverPendingPageCounters(pendingNonTXPageCounter);
} catch (Throwable e) {
ActiveMQServerLogger.LOGGER.errorRecoveringPageCounter(e);
}
}
journalLoader.cleanUp();
return journalInfo;
}
use of org.apache.activemq.artemis.core.persistence.impl.PageCountPending in project activemq-artemis by apache.
the class PostOfficeJournalLoader method recoverPendingPageCounters.
/**
* This method will recover the counters after failures making sure the page counter doesn't get out of sync
*
* @param pendingNonTXPageCounter
* @throws Exception
*/
@Override
public void recoverPendingPageCounters(List<PageCountPending> pendingNonTXPageCounter) throws Exception {
// We need a structure of the following
// Address -> PageID -> QueueID -> List<PageCountPending>
// The following loop will sort the records according to the hierarchy we need
Transaction txRecoverCounter = new TransactionImpl(storageManager);
Map<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> perAddressMap = generateMapsOnPendingCount(queues, pendingNonTXPageCounter, txRecoverCounter);
for (Map.Entry<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> addressPageMapEntry : perAddressMap.entrySet()) {
PagingStore store = pagingManager.getPageStore(addressPageMapEntry.getKey());
Map<Long, Map<Long, List<PageCountPending>>> perPageMap = addressPageMapEntry.getValue();
// We have already generated this before, so it can't be null
assert (perPageMap != null);
for (Long pageId : perPageMap.keySet()) {
Map<Long, List<PageCountPending>> perQueue = perPageMap.get(pageId);
// This can't be true!
assert (perQueue != null);
if (store.checkPageFileExists(pageId.intValue())) {
// on this case we need to recalculate the records
Page pg = store.createPage(pageId.intValue());
pg.open();
List<PagedMessage> pgMessages = pg.read(storageManager);
Map<Long, AtomicInteger> countsPerQueueOnPage = new HashMap<>();
Map<Long, AtomicLong> sizePerQueueOnPage = new HashMap<>();
for (PagedMessage pgd : pgMessages) {
if (pgd.getTransactionID() <= 0) {
for (long q : pgd.getQueueIDs()) {
AtomicInteger countQ = countsPerQueueOnPage.get(q);
AtomicLong sizeQ = sizePerQueueOnPage.get(q);
if (countQ == null) {
countQ = new AtomicInteger(0);
countsPerQueueOnPage.put(q, countQ);
}
if (sizeQ == null) {
sizeQ = new AtomicLong(0);
sizePerQueueOnPage.put(q, sizeQ);
}
countQ.incrementAndGet();
if (pgd.getPersistentSize() > 0) {
sizeQ.addAndGet(pgd.getPersistentSize());
}
}
}
}
for (Map.Entry<Long, List<PageCountPending>> entry : perQueue.entrySet()) {
for (PageCountPending record : entry.getValue()) {
logger.debug("Deleting pg tempCount " + record.getID());
storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID());
}
PageSubscriptionCounter counter = store.getCursorProvider().getSubscription(entry.getKey()).getCounter();
AtomicInteger value = countsPerQueueOnPage.get(entry.getKey());
AtomicLong sizeValue = sizePerQueueOnPage.get(entry.getKey());
if (value == null) {
logger.debug("Page " + entry.getKey() + " wasn't open, so we will just ignore");
} else {
logger.debug("Replacing counter " + value.get());
counter.increment(txRecoverCounter, value.get(), sizeValue.get());
}
}
} else {
// on this case the page file didn't exist, we just remove all the records since the page is already gone
logger.debug("Page " + pageId + " didn't exist on address " + addressPageMapEntry.getKey() + ", so we are just removing records");
for (List<PageCountPending> records : perQueue.values()) {
for (PageCountPending record : records) {
logger.debug("Removing pending page counter " + record.getID());
storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID());
txRecoverCounter.setContainsPersistent();
}
}
}
}
}
txRecoverCounter.commit();
}
use of org.apache.activemq.artemis.core.persistence.impl.PageCountPending in project activemq-artemis by apache.
the class PostOfficeJournalLoader method generateMapsOnPendingCount.
/**
* This generates a map for use on the recalculation and recovery of pending maps after reloading it
*
* @param queues
* @param pendingNonTXPageCounter
* @param txRecoverCounter
* @return
* @throws Exception
*/
private Map<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> generateMapsOnPendingCount(Map<Long, Queue> queues, List<PageCountPending> pendingNonTXPageCounter, Transaction txRecoverCounter) throws Exception {
Map<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> perAddressMap = new HashMap<>();
for (PageCountPending pgCount : pendingNonTXPageCounter) {
long queueID = pgCount.getQueueID();
long pageID = pgCount.getPageID();
// We first figure what Queue is based on the queue id
Queue queue = queues.get(queueID);
if (queue == null) {
logger.debug("removing pending page counter id = " + pgCount.getID() + " as queueID=" + pgCount.getID() + " no longer exists");
// this means the queue doesn't exist any longer, we will remove it from the storage
storageManager.deletePendingPageCounter(txRecoverCounter.getID(), pgCount.getID());
txRecoverCounter.setContainsPersistent();
continue;
}
// Level 1 on the structure, per address
SimpleString address = queue.getAddress();
Map<Long, Map<Long, List<PageCountPending>>> perPageMap = perAddressMap.get(address);
if (perPageMap == null) {
perPageMap = new HashMap<>();
perAddressMap.put(address, perPageMap);
}
Map<Long, List<PageCountPending>> perQueueMap = perPageMap.get(pageID);
if (perQueueMap == null) {
perQueueMap = new HashMap<>();
perPageMap.put(pageID, perQueueMap);
}
List<PageCountPending> pendingCounters = perQueueMap.get(queueID);
if (pendingCounters == null) {
pendingCounters = new LinkedList<>();
perQueueMap.put(queueID, pendingCounters);
}
pendingCounters.add(pgCount);
perQueueMap.put(queueID, pendingCounters);
}
return perAddressMap;
}
Aggregations