Search in sources :

Example 16 with PreparedTransactionInfo

use of org.apache.activemq.artemis.core.journal.PreparedTransactionInfo in project activemq-artemis by apache.

the class DescribeJournal method printSurvivingRecords.

public static DescribeJournal printSurvivingRecords(Journal journal, PrintStream out, boolean safe) throws Exception {
    final Map<Long, PageSubscriptionCounterImpl> counters = new HashMap<>();
    out.println("### Surviving Records Summary ###");
    List<RecordInfo> records = new LinkedList<>();
    List<PreparedTransactionInfo> preparedTransactions = new LinkedList<>();
    journal.start();
    final StringBuffer bufferFailingTransactions = new StringBuffer();
    int messageCount = 0;
    Map<Long, Integer> messageRefCounts = new HashMap<>();
    int preparedMessageCount = 0;
    Map<Long, Integer> preparedMessageRefCount = new HashMap<>();
    journal.load(records, preparedTransactions, new TransactionFailureCallback() {

        @Override
        public void failedTransaction(long transactionID, List<RecordInfo> records1, List<RecordInfo> recordsToDelete) {
            bufferFailingTransactions.append("Transaction " + transactionID + " failed with these records:\n");
            for (RecordInfo info : records1) {
                bufferFailingTransactions.append("- " + describeRecord(info, safe) + "\n");
            }
            for (RecordInfo info : recordsToDelete) {
                bufferFailingTransactions.append("- " + describeRecord(info, safe) + " <marked to delete>\n");
            }
        }
    }, false);
    for (RecordInfo info : records) {
        PageSubscriptionCounterImpl subsCounter = null;
        long queueIDForCounter = 0;
        Object o = newObjectEncoding(info);
        if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE) {
            messageCount++;
        } else if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
            ReferenceDescribe ref = (ReferenceDescribe) o;
            Integer count = messageRefCounts.get(ref.refEncoding.queueID);
            if (count == null) {
                count = 1;
                messageRefCounts.put(ref.refEncoding.queueID, count);
            } else {
                messageRefCounts.put(ref.refEncoding.queueID, count + 1);
            }
        } else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
            AckDescribe ref = (AckDescribe) o;
            Integer count = messageRefCounts.get(ref.refEncoding.queueID);
            if (count == null) {
                messageRefCounts.put(ref.refEncoding.queueID, 0);
            } else {
                messageRefCounts.put(ref.refEncoding.queueID, count - 1);
            }
        } else if (info.getUserRecordType() == JournalRecordIds.PAGE_CURSOR_COUNTER_VALUE) {
            PageCountRecord encoding = (PageCountRecord) o;
            queueIDForCounter = encoding.getQueueID();
            subsCounter = lookupCounter(counters, queueIDForCounter);
            subsCounter.loadValue(info.id, encoding.getValue(), encoding.getPersistentSize());
            subsCounter.processReload();
        } else if (info.getUserRecordType() == JournalRecordIds.PAGE_CURSOR_COUNTER_INC) {
            PageCountRecordInc encoding = (PageCountRecordInc) o;
            queueIDForCounter = encoding.getQueueID();
            subsCounter = lookupCounter(counters, queueIDForCounter);
            subsCounter.loadInc(info.id, encoding.getValue(), encoding.getPersistentSize());
            subsCounter.processReload();
        }
        out.println(describeRecord(info, o, safe));
        if (subsCounter != null) {
            out.println("##SubsCounter for queue=" + queueIDForCounter + ", value=" + subsCounter.getValue());
            out.println();
        }
    }
    if (counters.size() > 0) {
        out.println("### Page Counters");
        printCounters(out, counters);
    }
    out.println();
    out.println("### Prepared TX ###");
    for (PreparedTransactionInfo tx : preparedTransactions) {
        out.println(tx.getId());
        for (RecordInfo info : tx.getRecords()) {
            Object o = newObjectEncoding(info);
            out.println("- " + describeRecord(info, o, safe));
            if (info.getUserRecordType() == 31) {
                preparedMessageCount++;
            } else if (info.getUserRecordType() == 32) {
                ReferenceDescribe ref = (ReferenceDescribe) o;
                Integer count = preparedMessageRefCount.get(ref.refEncoding.queueID);
                if (count == null) {
                    count = 1;
                    preparedMessageRefCount.put(ref.refEncoding.queueID, count);
                } else {
                    preparedMessageRefCount.put(ref.refEncoding.queueID, count + 1);
                }
            }
        }
        for (RecordInfo info : tx.getRecordsToDelete()) {
            out.println("- " + describeRecord(info, safe) + " <marked to delete>");
        }
    }
    String missingTX = bufferFailingTransactions.toString();
    if (missingTX.length() > 0) {
        out.println();
        out.println("### Failed Transactions (Missing commit/prepare/rollback record) ###");
    }
    out.println(bufferFailingTransactions.toString());
    out.println("### Message Counts ###");
    out.println("message count=" + messageCount);
    out.println("message reference count");
    for (Map.Entry<Long, Integer> longIntegerEntry : messageRefCounts.entrySet()) {
        out.println("queue id " + longIntegerEntry.getKey() + ",count=" + longIntegerEntry.getValue());
    }
    out.println("prepared message count=" + preparedMessageCount);
    for (Map.Entry<Long, Integer> longIntegerEntry : preparedMessageRefCount.entrySet()) {
        out.println("queue id " + longIntegerEntry.getKey() + ",count=" + longIntegerEntry.getValue());
    }
    journal.stop();
    return new DescribeJournal(records, preparedTransactions);
}
Also used : PreparedTransactionInfo(org.apache.activemq.artemis.core.journal.PreparedTransactionInfo) HashMap(java.util.HashMap) RecordInfo(org.apache.activemq.artemis.core.journal.RecordInfo) TransactionFailureCallback(org.apache.activemq.artemis.core.journal.TransactionFailureCallback) LinkedList(java.util.LinkedList) PageSubscriptionCounterImpl(org.apache.activemq.artemis.core.paging.cursor.impl.PageSubscriptionCounterImpl) PageCountRecord(org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageCountRecord) PageCountRecordInc(org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageCountRecordInc) Map(java.util.Map) HashMap(java.util.HashMap)

Example 17 with PreparedTransactionInfo

use of org.apache.activemq.artemis.core.journal.PreparedTransactionInfo in project activemq-artemis by apache.

the class AbstractJournalStorageManager method loadBindingJournal.

@Override
public JournalLoadInformation loadBindingJournal(final List<QueueBindingInfo> queueBindingInfos, final List<GroupingInfo> groupingInfos, final List<AddressBindingInfo> addressBindingInfos) throws Exception {
    List<RecordInfo> records = new ArrayList<>();
    List<PreparedTransactionInfo> preparedTransactions = new ArrayList<>();
    JournalLoadInformation bindingsInfo = bindingsJournal.load(records, preparedTransactions, null);
    HashMap<Long, PersistentQueueBindingEncoding> mapBindings = new HashMap<>();
    for (RecordInfo record : records) {
        long id = record.id;
        ActiveMQBuffer buffer = ActiveMQBuffers.wrappedBuffer(record.data);
        byte rec = record.getUserRecordType();
        if (rec == JournalRecordIds.QUEUE_BINDING_RECORD) {
            PersistentQueueBindingEncoding bindingEncoding = newQueueBindingEncoding(id, buffer);
            mapBindings.put(bindingEncoding.getId(), bindingEncoding);
        } else if (rec == JournalRecordIds.ID_COUNTER_RECORD) {
            idGenerator.loadState(record.id, buffer);
        } else if (rec == JournalRecordIds.ADDRESS_BINDING_RECORD) {
            PersistentAddressBindingEncoding bindingEncoding = newAddressBindingEncoding(id, buffer);
            addressBindingInfos.add(bindingEncoding);
        } else if (rec == JournalRecordIds.GROUP_RECORD) {
            GroupingEncoding encoding = newGroupEncoding(id, buffer);
            groupingInfos.add(encoding);
        } else if (rec == JournalRecordIds.ADDRESS_SETTING_RECORD) {
            PersistedAddressSetting setting = newAddressEncoding(id, buffer);
            mapPersistedAddressSettings.put(setting.getAddressMatch(), setting);
        } else if (rec == JournalRecordIds.SECURITY_RECORD) {
            PersistedRoles roles = newSecurityRecord(id, buffer);
            mapPersistedRoles.put(roles.getAddressMatch(), roles);
        } else if (rec == JournalRecordIds.QUEUE_STATUS_RECORD) {
            QueueStatusEncoding statusEncoding = newQueueStatusEncoding(id, buffer);
            PersistentQueueBindingEncoding queueBindingEncoding = mapBindings.get(statusEncoding.queueID);
            if (queueBindingEncoding != null) {
                queueBindingEncoding.addQueueStatusEncoding(statusEncoding);
            } else {
                // unlikely to happen, so I didn't bother about the Logger method
                ActiveMQServerLogger.LOGGER.infoNoQueueWithID(statusEncoding.queueID, statusEncoding.getId());
                this.deleteQueueStatus(statusEncoding.getId());
            }
        } else {
            // unlikely to happen
            ActiveMQServerLogger.LOGGER.invalidRecordType(rec, new Exception("invalid record type " + rec));
        }
    }
    for (PersistentQueueBindingEncoding queue : mapBindings.values()) {
        queueBindingInfos.add(queue);
    }
    // just to give a hand to GC
    mapBindings.clear();
    // This will instruct the IDGenerator to beforeStop old records
    idGenerator.cleanup();
    return bindingsInfo;
}
Also used : PreparedTransactionInfo(org.apache.activemq.artemis.core.journal.PreparedTransactionInfo) QueueStatusEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.QueueStatusEncoding) RecordInfo(org.apache.activemq.artemis.core.journal.RecordInfo) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) PersistedRoles(org.apache.activemq.artemis.core.persistence.config.PersistedRoles) PersistedAddressSetting(org.apache.activemq.artemis.core.persistence.config.PersistedAddressSetting) ArrayList(java.util.ArrayList) InvalidParameterException(java.security.InvalidParameterException) JournalLoadInformation(org.apache.activemq.artemis.core.journal.JournalLoadInformation) PersistentAddressBindingEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentAddressBindingEncoding) GroupingEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.GroupingEncoding) PersistentQueueBindingEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.PersistentQueueBindingEncoding) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer)

Example 18 with PreparedTransactionInfo

use of org.apache.activemq.artemis.core.journal.PreparedTransactionInfo in project activemq-artemis by apache.

the class XmlDataExporter method processMessageJournal.

/**
 * Read through the message journal and stuff all the events/data we care about into local data structures.  We'll
 * use this data later to print all the right information.
 *
 * @throws Exception will be thrown if anything goes wrong reading the journal
 */
private void processMessageJournal() throws Exception {
    ArrayList<RecordInfo> acks = new ArrayList<>();
    List<RecordInfo> records = new LinkedList<>();
    // We load these, but don't use them.
    List<PreparedTransactionInfo> preparedTransactions = new LinkedList<>();
    Journal messageJournal = storageManager.getMessageJournal();
    ActiveMQServerLogger.LOGGER.debug("Reading journal from " + config.getJournalDirectory());
    messageJournal.start();
    // Just logging these, no action necessary
    TransactionFailureCallback transactionFailureCallback = new TransactionFailureCallback() {

        @Override
        public void failedTransaction(long transactionID, List<RecordInfo> records1, List<RecordInfo> recordsToDelete) {
            StringBuilder message = new StringBuilder();
            message.append("Encountered failed journal transaction: ").append(transactionID);
            for (int i = 0; i < records1.size(); i++) {
                if (i == 0) {
                    message.append("; Records: ");
                }
                message.append(records1.get(i));
                if (i != (records1.size() - 1)) {
                    message.append(", ");
                }
            }
            for (int i = 0; i < recordsToDelete.size(); i++) {
                if (i == 0) {
                    message.append("; RecordsToDelete: ");
                }
                message.append(recordsToDelete.get(i));
                if (i != (recordsToDelete.size() - 1)) {
                    message.append(", ");
                }
            }
            ActiveMQServerLogger.LOGGER.debug(message.toString());
        }
    };
    messageJournal.load(records, preparedTransactions, transactionFailureCallback, false);
    // Since we don't use these nullify the reference so that the garbage collector can clean them up
    preparedTransactions = null;
    for (RecordInfo info : records) {
        byte[] data = info.data;
        ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(data);
        Object o = DescribeJournal.newObjectEncoding(info, storageManager);
        if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE) {
            messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
        } else if (info.getUserRecordType() == JournalRecordIds.ADD_MESSAGE_PROTOCOL) {
            messages.put(info.id, ((MessageDescribe) o).getMsg().toCore());
        } else if (info.getUserRecordType() == JournalRecordIds.ADD_LARGE_MESSAGE) {
            messages.put(info.id, ((MessageDescribe) o).getMsg());
        } else if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
            ReferenceDescribe ref = (ReferenceDescribe) o;
            HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
            if (map == null) {
                HashMap<Long, ReferenceDescribe> newMap = new HashMap<>();
                newMap.put(ref.refEncoding.queueID, ref);
                messageRefs.put(info.id, newMap);
            } else {
                map.put(ref.refEncoding.queueID, ref);
            }
        } else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
            acks.add(info);
        } else if (info.userRecordType == JournalRecordIds.ACKNOWLEDGE_CURSOR) {
            CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
            encoding.decode(buff);
            Set<PagePosition> set = cursorRecords.get(encoding.queueID);
            if (set == null) {
                set = new HashSet<>();
                cursorRecords.put(encoding.queueID, set);
            }
            set.add(encoding.position);
        } else if (info.userRecordType == JournalRecordIds.PAGE_TRANSACTION) {
            if (info.isUpdate) {
                PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
                pageUpdate.decode(buff);
                pgTXs.add(pageUpdate.pageTX);
            } else {
                PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
                pageTransactionInfo.decode(buff);
                pageTransactionInfo.setRecordID(info.id);
                pgTXs.add(pageTransactionInfo.getTransactionID());
            }
        }
    }
    messageJournal.stop();
    removeAcked(acks);
}
Also used : PreparedTransactionInfo(org.apache.activemq.artemis.core.journal.PreparedTransactionInfo) Set(java.util.Set) HashSet(java.util.HashSet) RecordInfo(org.apache.activemq.artemis.core.journal.RecordInfo) HashMap(java.util.HashMap) PageTransactionInfoImpl(org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl) ArrayList(java.util.ArrayList) Journal(org.apache.activemq.artemis.core.journal.Journal) DescribeJournal(org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal) TransactionFailureCallback(org.apache.activemq.artemis.core.journal.TransactionFailureCallback) LinkedList(java.util.LinkedList) PageUpdateTXEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageUpdateTXEncoding) MessageDescribe(org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.MessageDescribe) CursorAckRecordEncoding(org.apache.activemq.artemis.core.persistence.impl.journal.codec.CursorAckRecordEncoding) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ReferenceDescribe(org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.ReferenceDescribe) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer) HashSet(java.util.HashSet)

Example 19 with PreparedTransactionInfo

use of org.apache.activemq.artemis.core.journal.PreparedTransactionInfo in project activemq-artemis by apache.

the class JournalCrashTest method printJournal.

/**
 * @throws Exception
 */
private void printJournal() throws Exception {
    NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getJournalDir()), 100);
    JournalImpl journal = new JournalImpl(ActiveMQDefaultConfiguration.getDefaultJournalFileSize(), 2, 2, 0, 0, factory, "activemq-data", "amq", 100);
    ArrayList<RecordInfo> records = new ArrayList<>();
    ArrayList<PreparedTransactionInfo> transactions = new ArrayList<>();
    journal.start();
    journal.load(records, transactions, null);
    // System.out.println("===============================================");
    // System.out.println("Journal records at the end:");
    // 
    // for (RecordInfo record : records)
    // {
    // System.out.println(record.id + ", update = " + record.isUpdate);
    // }
    journal.stop();
}
Also used : PreparedTransactionInfo(org.apache.activemq.artemis.core.journal.PreparedTransactionInfo) RecordInfo(org.apache.activemq.artemis.core.journal.RecordInfo) ArrayList(java.util.ArrayList) File(java.io.File) NIOSequentialFileFactory(org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory) JournalImpl(org.apache.activemq.artemis.core.journal.impl.JournalImpl)

Example 20 with PreparedTransactionInfo

use of org.apache.activemq.artemis.core.journal.PreparedTransactionInfo in project activemq-artemis by apache.

the class JournalImplTestBase method checkTransactionsEquivalent.

protected void checkTransactionsEquivalent(final List<PreparedTransactionInfo> expected, final List<PreparedTransactionInfo> actual) {
    Assert.assertEquals("Lists not same length", expected.size(), actual.size());
    Iterator<PreparedTransactionInfo> iterExpected = expected.iterator();
    Iterator<PreparedTransactionInfo> iterActual = actual.iterator();
    while (iterExpected.hasNext()) {
        PreparedTransactionInfo rexpected = iterExpected.next();
        PreparedTransactionInfo ractual = iterActual.next();
        Assert.assertEquals("ids not same", rexpected.getId(), ractual.getId());
        checkRecordsEquivalent(rexpected.getRecords(), ractual.getRecords());
        Assert.assertEquals("deletes size not same", rexpected.getRecordsToDelete().size(), ractual.getRecordsToDelete().size());
        Iterator<RecordInfo> iterDeletesExpected = rexpected.getRecordsToDelete().iterator();
        Iterator<RecordInfo> iterDeletesActual = ractual.getRecordsToDelete().iterator();
        while (iterDeletesExpected.hasNext()) {
            long lexpected = iterDeletesExpected.next().id;
            long lactual = iterDeletesActual.next().id;
            Assert.assertEquals("Delete ids not same", lexpected, lactual);
        }
    }
}
Also used : PreparedTransactionInfo(org.apache.activemq.artemis.core.journal.PreparedTransactionInfo) RecordInfo(org.apache.activemq.artemis.core.journal.RecordInfo)

Aggregations

PreparedTransactionInfo (org.apache.activemq.artemis.core.journal.PreparedTransactionInfo)34 RecordInfo (org.apache.activemq.artemis.core.journal.RecordInfo)33 ArrayList (java.util.ArrayList)17 JournalImpl (org.apache.activemq.artemis.core.journal.impl.JournalImpl)13 Test (org.junit.Test)13 LinkedList (java.util.LinkedList)12 ActiveMQBuffer (org.apache.activemq.artemis.api.core.ActiveMQBuffer)10 TransactionFailureCallback (org.apache.activemq.artemis.core.journal.TransactionFailureCallback)8 HashMap (java.util.HashMap)7 NIOSequentialFileFactory (org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory)7 LinkedHashMap (java.util.LinkedHashMap)5 List (java.util.List)5 JournalLoadInformation (org.apache.activemq.artemis.core.journal.JournalLoadInformation)5 JournalStorageManager (org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager)5 PageCountRecordInc (org.apache.activemq.artemis.core.persistence.impl.journal.codec.PageCountRecordInc)5 File (java.io.File)4 SequentialFileFactory (org.apache.activemq.artemis.core.io.SequentialFileFactory)4 HashSet (java.util.HashSet)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3