Search in sources :

Example 1 with TxRecord

use of org.apache.ignite.internal.pagemem.wal.record.TxRecord in project ignite by apache.

the class IgniteWalSerializerVersionTest method testCheckDifferentSerializerVersionsAndLogTimestamp.

/**
 * @throws Exception If failed.
 */
public void testCheckDifferentSerializerVersionsAndLogTimestamp() throws Exception {
    IgniteCallable<List<WALRecord>> recordsFactory = new IgniteCallable<List<WALRecord>>() {

        @Override
        public List<WALRecord> call() throws Exception {
            WALRecord rec0 = new DataRecord(Collections.<DataEntry>emptyList());
            WALRecord rec1 = new TxRecord(PREPARED, null, null, null);
            return Arrays.asList(rec0, rec1);
        }
    };
    long time0 = U.currentTimeMillis();
    check(new Checker(1, RecordV1Serializer.class, recordsFactory, Arrays.asList(0L, time0)));
    long time1 = U.currentTimeMillis();
    check(new Checker(2, RecordV2Serializer.class, recordsFactory, Arrays.asList(time1, time1)));
}
Also used : WALRecord(org.apache.ignite.internal.pagemem.wal.record.WALRecord) RecordV1Serializer(org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordV1Serializer) IgniteCallable(org.apache.ignite.lang.IgniteCallable) List(java.util.List) DataRecord(org.apache.ignite.internal.pagemem.wal.record.DataRecord) TxRecord(org.apache.ignite.internal.pagemem.wal.record.TxRecord) RecordV2Serializer(org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordV2Serializer)

Example 2 with TxRecord

use of org.apache.ignite.internal.pagemem.wal.record.TxRecord in project ignite by apache.

the class IgniteWalReaderTest method iterateAndCountDataRecord.

/**
 * Iterates over data records, checks each DataRecord and its entries, finds out all transactions in WAL.
 *
 * @param walIter iterator to use.
 * @return count of data records observed for each global TX ID. Contains null for non tx updates.
 * @throws IgniteCheckedException if failure.
 */
private Map<GridCacheVersion, Integer> iterateAndCountDataRecord(final WALIterator walIter, @Nullable final IgniteBiInClosure<Object, Object> cacheObjHnd, @Nullable final IgniteInClosure<DataRecord> dataRecordHnd) throws IgniteCheckedException {
    final Map<GridCacheVersion, Integer> entriesUnderTxFound = new HashMap<>();
    try (WALIterator stIt = walIter) {
        while (stIt.hasNextX()) {
            final IgniteBiTuple<WALPointer, WALRecord> next = stIt.nextX();
            final WALRecord walRecord = next.get2();
            if (walRecord.type() == WALRecord.RecordType.DATA_RECORD && walRecord instanceof DataRecord) {
                final DataRecord dataRecord = (DataRecord) walRecord;
                if (dataRecordHnd != null)
                    dataRecordHnd.apply(dataRecord);
                final List<DataEntry> entries = dataRecord.writeEntries();
                for (DataEntry entry : entries) {
                    final GridCacheVersion globalTxId = entry.nearXidVersion();
                    Object unwrappedKeyObj;
                    Object unwrappedValObj;
                    if (entry instanceof UnwrapDataEntry) {
                        UnwrapDataEntry unwrapDataEntry = (UnwrapDataEntry) entry;
                        unwrappedKeyObj = unwrapDataEntry.unwrappedKey();
                        unwrappedValObj = unwrapDataEntry.unwrappedValue();
                    } else if (entry instanceof LazyDataEntry) {
                        unwrappedKeyObj = null;
                        unwrappedValObj = null;
                    // can't check value
                    } else {
                        final CacheObject val = entry.value();
                        unwrappedValObj = val instanceof BinaryObject ? val : val.value(null, false);
                        final CacheObject key = entry.key();
                        unwrappedKeyObj = key instanceof BinaryObject ? key : key.value(null, false);
                    }
                    if (dumpRecords)
                        log.info("//Entry operation " + entry.op() + "; cache Id" + entry.cacheId() + "; " + "under transaction: " + globalTxId + // ; entry " + entry +
                        "; Key: " + unwrappedKeyObj + "; Value: " + unwrappedValObj);
                    if (cacheObjHnd != null && (unwrappedKeyObj != null || unwrappedValObj != null))
                        cacheObjHnd.apply(unwrappedKeyObj, unwrappedValObj);
                    final Integer entriesUnderTx = entriesUnderTxFound.get(globalTxId);
                    entriesUnderTxFound.put(globalTxId, entriesUnderTx == null ? 1 : entriesUnderTx + 1);
                }
            } else if (walRecord.type() == WALRecord.RecordType.TX_RECORD && walRecord instanceof TxRecord) {
                final TxRecord txRecord = (TxRecord) walRecord;
                final GridCacheVersion globalTxId = txRecord.nearXidVersion();
                if (dumpRecords)
                    log.info("//Tx Record, state: " + txRecord.state() + "; nearTxVersion" + globalTxId);
            }
        }
    }
    return entriesUnderTxFound;
}
Also used : WALRecord(org.apache.ignite.internal.pagemem.wal.record.WALRecord) HashMap(java.util.HashMap) UnwrapDataEntry(org.apache.ignite.internal.pagemem.wal.record.UnwrapDataEntry) TxRecord(org.apache.ignite.internal.pagemem.wal.record.TxRecord) DataEntry(org.apache.ignite.internal.pagemem.wal.record.DataEntry) LazyDataEntry(org.apache.ignite.internal.pagemem.wal.record.LazyDataEntry) UnwrapDataEntry(org.apache.ignite.internal.pagemem.wal.record.UnwrapDataEntry) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) BinaryObject(org.apache.ignite.binary.BinaryObject) WALIterator(org.apache.ignite.internal.pagemem.wal.WALIterator) LazyDataEntry(org.apache.ignite.internal.pagemem.wal.record.LazyDataEntry) BinaryObject(org.apache.ignite.binary.BinaryObject) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) DataRecord(org.apache.ignite.internal.pagemem.wal.record.DataRecord) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) WALPointer(org.apache.ignite.internal.pagemem.wal.WALPointer)

Example 3 with TxRecord

use of org.apache.ignite.internal.pagemem.wal.record.TxRecord in project ignite by apache.

the class TxRecordSerializer method read.

/**
 * Reads {@link TxRecord} from given input.
 *
 * @param in Input
 * @return TxRecord.
 * @throws IOException In case of fail.
 * @throws IgniteCheckedException In case of fail.
 */
public TxRecord read(ByteBufferBackedDataInput in) throws IOException, IgniteCheckedException {
    byte txState = in.readByte();
    TransactionState state = TransactionState.fromOrdinal(txState);
    GridCacheVersion nearXidVer = RecordV1Serializer.readVersion(in, true);
    GridCacheVersion writeVer = RecordV1Serializer.readVersion(in, true);
    int participatingNodesSize = in.readInt();
    Map<Short, Collection<Short>> participatingNodes = U.newHashMap(participatingNodesSize);
    for (int i = 0; i < participatingNodesSize; i++) {
        short primaryNode = in.readShort();
        int backupNodesSize = in.readInt();
        Collection<Short> backupNodes = new ArrayList<>(backupNodesSize);
        for (int j = 0; j < backupNodesSize; j++) {
            short backupNode = in.readShort();
            backupNodes.add(backupNode);
        }
        participatingNodes.put(primaryNode, backupNodes);
    }
    long ts = in.readLong();
    return new TxRecord(state, nearXidVer, writeVer, participatingNodes, ts);
}
Also used : TransactionState(org.apache.ignite.transactions.TransactionState) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) ArrayList(java.util.ArrayList) Collection(java.util.Collection) TxRecord(org.apache.ignite.internal.pagemem.wal.record.TxRecord)

Example 4 with TxRecord

use of org.apache.ignite.internal.pagemem.wal.record.TxRecord in project ignite by apache.

the class IgniteTxAdapter method state.

/**
 * @param state State to set.
 * @param timedOut Timeout flag.
 * @return {@code True} if state changed.
 */
@SuppressWarnings({ "TooBroadScope" })
protected final boolean state(TransactionState state, boolean timedOut) {
    boolean valid = false;
    TransactionState prev;
    boolean notify = false;
    WALPointer ptr = null;
    synchronized (this) {
        prev = this.state;
        switch(state) {
            case ACTIVE:
                {
                    valid = prev == SUSPENDED;
                    break;
                }
            case PREPARING:
                {
                    valid = prev == ACTIVE;
                    break;
                }
            case PREPARED:
                {
                    valid = prev == PREPARING;
                    break;
                }
            case COMMITTING:
                {
                    valid = prev == PREPARED;
                    break;
                }
            case UNKNOWN:
                {
                    if (setDone())
                        notify = true;
                    valid = prev == ROLLING_BACK || prev == COMMITTING;
                    break;
                }
            case COMMITTED:
                {
                    if (setDone())
                        notify = true;
                    valid = prev == COMMITTING;
                    break;
                }
            case ROLLED_BACK:
                {
                    if (setDone())
                        notify = true;
                    valid = prev == ROLLING_BACK;
                    break;
                }
            case MARKED_ROLLBACK:
                {
                    valid = prev == ACTIVE || prev == PREPARING || prev == PREPARED || prev == SUSPENDED;
                    break;
                }
            case ROLLING_BACK:
                {
                    valid = prev == ACTIVE || prev == MARKED_ROLLBACK || prev == PREPARING || prev == PREPARED || prev == SUSPENDED || (prev == COMMITTING && local() && !dht());
                    break;
                }
            case SUSPENDED:
                {
                    valid = prev == ACTIVE;
                    break;
                }
        }
        if (valid) {
            this.state = state;
            if (timedOut)
                this.timedOut = true;
            if (log.isDebugEnabled())
                log.debug("Changed transaction state [prev=" + prev + ", new=" + this.state + ", tx=" + this + ']');
            notifyAll();
        } else {
            if (log.isDebugEnabled())
                log.debug("Invalid transaction state transition [invalid=" + state + ", cur=" + this.state + ", tx=" + this + ']');
        }
        if (valid) {
            // Seal transactions maps.
            if (state != ACTIVE && state != SUSPENDED)
                seal();
            if (cctx.wal() != null && cctx.tm().logTxRecords()) {
                // Log tx state change to WAL.
                if (state == PREPARED || state == COMMITTED || state == ROLLED_BACK) {
                    assert txNodes != null || state == ROLLED_BACK : "txNodes=" + txNodes + " state=" + state;
                    BaselineTopology baselineTop = cctx.kernalContext().state().clusterState().baselineTopology();
                    Map<Short, Collection<Short>> participatingNodes = consistentIdMapper.mapToCompactIds(topVer, txNodes, baselineTop);
                    TxRecord txRecord = new TxRecord(state, nearXidVersion(), writeVersion(), participatingNodes);
                    try {
                        ptr = cctx.wal().log(txRecord);
                    } catch (IgniteCheckedException e) {
                        U.error(log, "Failed to log TxRecord: " + txRecord, e);
                        throw new IgniteException("Failed to log TxRecord: " + txRecord, e);
                    }
                }
            }
        }
    }
    if (valid) {
        if (ptr != null && (state == COMMITTED || state == ROLLED_BACK))
            try {
                cctx.wal().fsync(ptr);
            } catch (IgniteCheckedException e) {
                String msg = "Failed to fsync ptr: " + ptr;
                U.error(log, msg, e);
                throw new IgniteException(msg, e);
            }
    }
    if (notify) {
        GridFutureAdapter<IgniteInternalTx> fut = finFut;
        if (fut != null)
            fut.onDone(this);
    }
    return valid;
}
Also used : TransactionState(org.apache.ignite.transactions.TransactionState) TxRecord(org.apache.ignite.internal.pagemem.wal.record.TxRecord) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) BaselineTopology(org.apache.ignite.internal.processors.cluster.BaselineTopology) Collection(java.util.Collection) WALPointer(org.apache.ignite.internal.pagemem.wal.WALPointer)

Example 5 with TxRecord

use of org.apache.ignite.internal.pagemem.wal.record.TxRecord in project ignite by apache.

the class IgniteWalRecoveryTest method testTxRecordsConsistency.

/**
 * Test that all DataRecord WAL records are within transaction boundaries - PREPARED and COMMITTED markers.
 *
 * @throws Exception If any fail.
 */
public void testTxRecordsConsistency() throws Exception {
    System.setProperty(IgniteSystemProperties.IGNITE_WAL_LOG_TX_RECORDS, "true");
    IgniteEx ignite = (IgniteEx) startGrids(3);
    ignite.active(true);
    try {
        final String cacheName = "transactional";
        CacheConfiguration<Object, Object> cacheConfiguration = new CacheConfiguration<>(cacheName).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL).setAffinity(new RendezvousAffinityFunction(false, 32)).setCacheMode(CacheMode.PARTITIONED).setRebalanceMode(CacheRebalanceMode.SYNC).setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC).setBackups(0);
        ignite.createCache(cacheConfiguration);
        IgniteCache<Object, Object> cache = ignite.cache(cacheName);
        GridCacheSharedContext<Object, Object> sharedCtx = ignite.context().cache().context();
        GridCacheDatabaseSharedManager db = (GridCacheDatabaseSharedManager) sharedCtx.database();
        db.waitForCheckpoint("test");
        db.enableCheckpoints(false).get();
        // Log something to know where to start.
        WALPointer startPtr = sharedCtx.wal().log(new MemoryRecoveryRecord(U.currentTimeMillis()));
        final int transactions = 100;
        final int operationsPerTransaction = 40;
        Random random = new Random();
        for (int t = 1; t <= transactions; t++) {
            Transaction tx = ignite.transactions().txStart(TransactionConcurrency.OPTIMISTIC, TransactionIsolation.READ_COMMITTED);
            for (int op = 0; op < operationsPerTransaction; op++) {
                int key = random.nextInt(1000) + 1;
                Object value;
                if (random.nextBoolean())
                    value = randomString(random) + key;
                else
                    value = new BigObject(key);
                cache.put(key, value);
            }
            if (random.nextBoolean()) {
                tx.commit();
            } else {
                tx.rollback();
            }
            if (t % 50 == 0)
                log.info("Finished transaction " + t);
        }
        Set<GridCacheVersion> activeTransactions = new HashSet<>();
        // Check that all DataRecords are within PREPARED and COMMITTED tx records.
        try (WALIterator it = sharedCtx.wal().replay(startPtr)) {
            while (it.hasNext()) {
                IgniteBiTuple<WALPointer, WALRecord> tup = it.next();
                WALRecord rec = tup.get2();
                if (rec instanceof TxRecord) {
                    TxRecord txRecord = (TxRecord) rec;
                    GridCacheVersion txId = txRecord.nearXidVersion();
                    switch(txRecord.state()) {
                        case PREPARED:
                            assert !activeTransactions.contains(txId) : "Transaction is already present " + txRecord;
                            activeTransactions.add(txId);
                            break;
                        case COMMITTED:
                            assert activeTransactions.contains(txId) : "No PREPARE marker for transaction " + txRecord;
                            activeTransactions.remove(txId);
                            break;
                        case ROLLED_BACK:
                            activeTransactions.remove(txId);
                            break;
                        default:
                            throw new IllegalStateException("Unknown Tx state of record " + txRecord);
                    }
                } else if (rec instanceof DataRecord) {
                    DataRecord dataRecord = (DataRecord) rec;
                    for (DataEntry entry : dataRecord.writeEntries()) {
                        GridCacheVersion txId = entry.nearXidVersion();
                        assert activeTransactions.contains(txId) : "No transaction for entry " + entry;
                    }
                }
            }
        }
    } finally {
        System.clearProperty(IgniteSystemProperties.IGNITE_WAL_LOG_TX_RECORDS);
        stopAllGrids();
    }
}
Also used : WALRecord(org.apache.ignite.internal.pagemem.wal.record.WALRecord) MemoryRecoveryRecord(org.apache.ignite.internal.pagemem.wal.record.MemoryRecoveryRecord) DataEntry(org.apache.ignite.internal.pagemem.wal.record.DataEntry) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) Random(java.util.Random) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) WALIterator(org.apache.ignite.internal.pagemem.wal.WALIterator) RendezvousAffinityFunction(org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction) DataRecord(org.apache.ignite.internal.pagemem.wal.record.DataRecord) WALPointer(org.apache.ignite.internal.pagemem.wal.WALPointer) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration) HashSet(java.util.HashSet) GridCacheDatabaseSharedManager(org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager) TxRecord(org.apache.ignite.internal.pagemem.wal.record.TxRecord) Transaction(org.apache.ignite.transactions.Transaction) IgniteEx(org.apache.ignite.internal.IgniteEx)

Aggregations

TxRecord (org.apache.ignite.internal.pagemem.wal.record.TxRecord)6 WALRecord (org.apache.ignite.internal.pagemem.wal.record.WALRecord)4 WALPointer (org.apache.ignite.internal.pagemem.wal.WALPointer)3 DataRecord (org.apache.ignite.internal.pagemem.wal.record.DataRecord)3 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)3 Collection (java.util.Collection)2 WALIterator (org.apache.ignite.internal.pagemem.wal.WALIterator)2 DataEntry (org.apache.ignite.internal.pagemem.wal.record.DataEntry)2 TransactionState (org.apache.ignite.transactions.TransactionState)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Random (java.util.Random)1 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 IgniteException (org.apache.ignite.IgniteException)1 BinaryObject (org.apache.ignite.binary.BinaryObject)1 RendezvousAffinityFunction (org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction)1 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)1