Search in sources :

Example 1 with ReplicatedJournal

use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.

the class JournalStorageManager method startReplication.

@Override
public void startReplication(ReplicationManager replicationManager, PagingManager pagingManager, String nodeID, final boolean autoFailBack, long initialReplicationSyncTimeout) throws Exception {
    if (!started) {
        throw new IllegalStateException("JournalStorageManager must be started...");
    }
    assert replicationManager != null;
    if (!(messageJournal instanceof JournalImpl) || !(bindingsJournal instanceof JournalImpl)) {
        throw ActiveMQMessageBundle.BUNDLE.notJournalImpl();
    }
    // We first do a compact without any locks, to avoid copying unnecessary data over the network.
    // We do this without holding the storageManager lock, so the journal stays open while compact is being done
    originalMessageJournal.scheduleCompactAndBlock(-1);
    originalBindingsJournal.scheduleCompactAndBlock(-1);
    JournalFile[] messageFiles = null;
    JournalFile[] bindingsFiles = null;
    // We get a picture of the current sitaution on the large messages
    // and we send the current messages while more state is coming
    Map<Long, Pair<String, Long>> pendingLargeMessages = null;
    try {
        Map<SimpleString, Collection<Integer>> pageFilesToSync;
        storageManagerLock.writeLock().lock();
        try {
            if (isReplicated())
                throw new ActiveMQIllegalStateException("already replicating");
            replicator = replicationManager;
            if (!((JournalImpl) originalMessageJournal).flushAppendExecutor(10, TimeUnit.SECONDS)) {
                throw new Exception("Live message journal is busy");
            }
            if (!((JournalImpl) originalBindingsJournal).flushAppendExecutor(10, TimeUnit.SECONDS)) {
                throw new Exception("Live bindings journal is busy");
            }
            // Establishes lock
            originalMessageJournal.synchronizationLock();
            originalBindingsJournal.synchronizationLock();
            try {
                originalBindingsJournal.replicationSyncPreserveOldFiles();
                originalMessageJournal.replicationSyncPreserveOldFiles();
                pagingManager.lock();
                try {
                    pagingManager.disableCleanup();
                    messageFiles = prepareJournalForCopy(originalMessageJournal, JournalContent.MESSAGES, nodeID, autoFailBack);
                    bindingsFiles = prepareJournalForCopy(originalBindingsJournal, JournalContent.BINDINGS, nodeID, autoFailBack);
                    pageFilesToSync = getPageInformationForSync(pagingManager);
                    pendingLargeMessages = recoverPendingLargeMessages();
                } finally {
                    pagingManager.unlock();
                }
            } finally {
                originalMessageJournal.synchronizationUnlock();
                originalBindingsJournal.synchronizationUnlock();
            }
            bindingsJournal = new ReplicatedJournal(((byte) 0), originalBindingsJournal, replicator);
            messageJournal = new ReplicatedJournal((byte) 1, originalMessageJournal, replicator);
            // We need to send the list while locking otherwise part of the body might get sent too soon
            // it will send a list of IDs that we are allocating
            replicator.sendLargeMessageIdListMessage(pendingLargeMessages);
        } finally {
            storageManagerLock.writeLock().unlock();
        }
        sendJournalFile(messageFiles, JournalContent.MESSAGES);
        sendJournalFile(bindingsFiles, JournalContent.BINDINGS);
        sendLargeMessageFiles(pendingLargeMessages);
        sendPagesToBackup(pageFilesToSync, pagingManager);
        storageManagerLock.writeLock().lock();
        try {
            if (replicator != null) {
                replicator.sendSynchronizationDone(nodeID, initialReplicationSyncTimeout);
                performCachedLargeMessageDeletes();
            }
        } finally {
            storageManagerLock.writeLock().unlock();
        }
    } catch (Exception e) {
        ActiveMQServerLogger.LOGGER.unableToStartReplication(e);
        stopReplication();
        throw e;
    } finally {
        // Re-enable compact and reclaim of journal files
        originalBindingsJournal.replicationSyncFinished();
        originalMessageJournal.replicationSyncFinished();
        pagingManager.resumeCleanup();
    }
}
Also used : ActiveMQIllegalStateException(org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException) ActiveMQIllegalStateException(org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQIllegalStateException(org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException) ActiveMQInternalErrorException(org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException) JournalFile(org.apache.activemq.artemis.core.journal.impl.JournalFile) Collection(java.util.Collection) JournalImpl(org.apache.activemq.artemis.core.journal.impl.JournalImpl) Pair(org.apache.activemq.artemis.api.core.Pair)

Example 2 with ReplicatedJournal

use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.

the class ReplicationTest method testSendPackets.

@Test
public void testSendPackets() throws Exception {
    setupServer(true);
    JournalStorageManager storage = getStorage();
    manager = liveServer.getReplicationManager();
    waitForComponent(manager);
    Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
    replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
    replicatedJournal.appendAddRecord(1, (byte) 1, new FakeData(), false);
    replicatedJournal.appendUpdateRecord(1, (byte) 2, new FakeData(), false);
    replicatedJournal.appendDeleteRecord(1, false);
    replicatedJournal.appendAddRecordTransactional(2, 2, (byte) 1, new FakeData());
    replicatedJournal.appendUpdateRecordTransactional(2, 2, (byte) 2, new FakeData());
    replicatedJournal.appendCommitRecord(2, false);
    replicatedJournal.appendDeleteRecordTransactional(3, 4, new FakeData());
    replicatedJournal.appendPrepareRecord(3, new FakeData(), false);
    replicatedJournal.appendRollbackRecord(3, false);
    blockOnReplication(storage, manager);
    Assert.assertTrue("Expecting no active tokens:" + manager.getActiveTokens(), manager.getActiveTokens().isEmpty());
    CoreMessage msg = new CoreMessage().initBuffer(1024).setMessageID(1);
    SimpleString dummy = new SimpleString("dummy");
    msg.setAddress(dummy);
    replicatedJournal.appendAddRecordTransactional(23, 24, (byte) 1, new FakeData());
    PagedMessage pgmsg = new PagedMessageImpl(msg, new long[0]);
    manager.pageWrite(pgmsg, 1);
    manager.pageWrite(pgmsg, 2);
    manager.pageWrite(pgmsg, 3);
    manager.pageWrite(pgmsg, 4);
    blockOnReplication(storage, manager);
    PagingManager pagingManager = createPageManager(backupServer.getStorageManager(), backupServer.getConfiguration(), backupServer.getExecutorFactory(), backupServer.getAddressSettingsRepository());
    PagingStore store = pagingManager.getPageStore(dummy);
    store.start();
    Assert.assertEquals(4, store.getNumberOfPages());
    store.stop();
    manager.pageDeleted(dummy, 1);
    manager.pageDeleted(dummy, 2);
    manager.pageDeleted(dummy, 3);
    manager.pageDeleted(dummy, 4);
    manager.pageDeleted(dummy, 5);
    manager.pageDeleted(dummy, 6);
    blockOnReplication(storage, manager);
    CoreMessage serverMsg = new CoreMessage();
    serverMsg.setMessageID(500);
    serverMsg.setAddress(new SimpleString("tttt"));
    ActiveMQBuffer buffer = ActiveMQBuffers.dynamicBuffer(100);
    serverMsg.encodeHeadersAndProperties(buffer.byteBuf());
    manager.largeMessageBegin(500);
    manager.largeMessageWrite(500, new byte[1024]);
    manager.largeMessageDelete(Long.valueOf(500), storage);
    blockOnReplication(storage, manager);
    store.start();
    Assert.assertEquals(0, store.getNumberOfPages());
}
Also used : PagedMessage(org.apache.activemq.artemis.core.paging.PagedMessage) PagingManager(org.apache.activemq.artemis.core.paging.PagingManager) PagedMessageImpl(org.apache.activemq.artemis.core.paging.impl.PagedMessageImpl) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) Journal(org.apache.activemq.artemis.core.journal.Journal) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) PagingStore(org.apache.activemq.artemis.core.paging.PagingStore) CoreMessage(org.apache.activemq.artemis.core.message.impl.CoreMessage) JournalStorageManager(org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer) Test(org.junit.Test)

Example 3 with ReplicatedJournal

use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.

the class ReplicationTest method testNoActions.

@Test
public void testNoActions() throws Exception {
    setupServer(true);
    StorageManager storage = getStorage();
    manager = liveServer.getReplicationManager();
    waitForComponent(manager);
    Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
    replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
    final CountDownLatch latch = new CountDownLatch(1);
    storage.afterCompleteOperations(new IOCallback() {

        @Override
        public void onError(final int errorCode, final String errorMessage) {
        }

        @Override
        public void done() {
            latch.countDown();
        }
    });
    Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
    Assert.assertEquals("should be empty " + manager.getActiveTokens(), 0, manager.getActiveTokens().size());
}
Also used : JournalStorageManager(org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager) StorageManager(org.apache.activemq.artemis.core.persistence.StorageManager) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) Journal(org.apache.activemq.artemis.core.journal.Journal) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) CountDownLatch(java.util.concurrent.CountDownLatch) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) Test(org.junit.Test)

Example 4 with ReplicatedJournal

use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.

the class ReplicationTest method testOrderOnNonPersistency.

@Test
public void testOrderOnNonPersistency() throws Exception {
    setupServer(true);
    final ArrayList<Integer> executions = new ArrayList<>();
    StorageManager storage = getStorage();
    manager = liveServer.getReplicationManager();
    Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
    int numberOfAdds = 200;
    final CountDownLatch latch = new CountDownLatch(numberOfAdds);
    OperationContext ctx = storage.getContext();
    for (int i = 0; i < numberOfAdds; i++) {
        final int nAdd = i;
        if (i % 2 == 0) {
            replicatedJournal.appendPrepareRecord(i, new FakeData(), false);
        }
        ctx.executeOnCompletion(new IOCallback() {

            @Override
            public void onError(final int errorCode, final String errorMessage) {
            }

            @Override
            public void done() {
                executions.add(nAdd);
                latch.countDown();
            }
        });
    }
    Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
    for (int i = 0; i < numberOfAdds; i++) {
        Assert.assertEquals(i, executions.get(i).intValue());
    }
    Assert.assertEquals(0, manager.getActiveTokens().size());
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext) ArrayList(java.util.ArrayList) JournalStorageManager(org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager) StorageManager(org.apache.activemq.artemis.core.persistence.StorageManager) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) Journal(org.apache.activemq.artemis.core.journal.Journal) ReplicatedJournal(org.apache.activemq.artemis.core.replication.ReplicatedJournal) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) CountDownLatch(java.util.concurrent.CountDownLatch) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test)

Aggregations

SimpleString (org.apache.activemq.artemis.api.core.SimpleString)4 ReplicatedJournal (org.apache.activemq.artemis.core.replication.ReplicatedJournal)4 Journal (org.apache.activemq.artemis.core.journal.Journal)3 JournalStorageManager (org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager)3 Test (org.junit.Test)3 CountDownLatch (java.util.concurrent.CountDownLatch)2 IOCallback (org.apache.activemq.artemis.core.io.IOCallback)2 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)2 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 ActiveMQBuffer (org.apache.activemq.artemis.api.core.ActiveMQBuffer)1 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)1 ActiveMQIllegalStateException (org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException)1 ActiveMQInternalErrorException (org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException)1 Pair (org.apache.activemq.artemis.api.core.Pair)1 JournalFile (org.apache.activemq.artemis.core.journal.impl.JournalFile)1 JournalImpl (org.apache.activemq.artemis.core.journal.impl.JournalImpl)1 CoreMessage (org.apache.activemq.artemis.core.message.impl.CoreMessage)1