/** * Normally returns the current state of the log entry. However, this is never called during * normal (non-recovery) execution. Therefore, the overhead of having to scan all of the logs (if * it's not one we're using) is minimal. */ public int currentState(Uid objUid, String tName) throws ObjectStoreException { InputObjectState ios = new InputObjectState(); /* * TODO * * It's possible that the entry has been marked to be deleted but * that the removal entry hasn't been written yet. We could check the * async cache. However, since we really only care about this during * recovery, it's not going to cause us problems anyway. */ if (allObjUids(tName, ios, StateStatus.OS_UNKNOWN)) { Uid tempUid = new Uid(Uid.nullUid()); do { try { tempUid = UidHelper.unpackFrom(ios); } catch (final Exception ex) { ex.printStackTrace(); return StateStatus.OS_UNKNOWN; } if (tempUid.equals(objUid)) return StateStatus.OS_COMMITTED; } while (tempUid.notEquals(Uid.nullUid())); return StateStatus.OS_UNKNOWN; } else return StateStatus.OS_UNKNOWN; }
public static Xid getXid(Uid uid, boolean branch, int formatId) throws IllegalStateException { XID xid; if (branch) xid = getXid(uid, new Uid(), formatId, null); else xid = getXid(uid, Uid.nullUid(), formatId, null); return new XidImple(xid); }
public InputObjectState() { if (tsLogger.logger.isTraceEnabled()) { tsLogger.logger.trace("InputObjectState::InputObjectState()"); } bufferUid = new Uid(Uid.nullUid()); super._valid = false; imageType = null; }
private final boolean supportedLog(String logID) throws ObjectStoreException, IOException { Uid id = new Uid(logID); if (id.equals(Uid.nullUid())) return false; ObjectStoreIterator iter = new ObjectStoreIterator( StoreManager.getRecoveryStore(), TransactionTypeManager.getInstance().getTransactionType(_transactionType)); Uid u; do { u = iter.iterate(); if (u.equals(id)) return true; } while (Uid.nullUid().notEquals(u)); return false; }
public static Uid getUid(XID xid) { if (xid == null || xid.formatID != FORMAT_ID) { return Uid.nullUid(); } // The Uid byte are the first in the data array, so we just pass // in the whole thing and the additional trailing data is ignored. Uid tx = new Uid(xid.data); return tx; }
private final void listLogs(String type) throws IOException { InputObjectState buff = new InputObjectState(); try { if (StoreManager.getRecoveryStore() .allObjUids(TransactionTypeManager.getInstance().getTransactionType(type), buff)) { Uid u = null; do { u = UidHelper.unpackFrom(buff); if (Uid.nullUid().notEquals(u)) { System.out.println("Log: " + u); } } while (Uid.nullUid().notEquals(u)); } } catch (final ObjectStoreException ex) { throw new IOException(); } }
private static XID getXid(Uid uid, Uid branch, int formatId, Integer eisName) throws IllegalStateException { if (uid == null) { throw new IllegalStateException(); } XID xid = new XID(); xid.formatID = formatId; // gtrid is uid byte form followed by as many chars of the node name as will fit. byte[] gtridUid = uid.getBytes(); if (gtridUid.length > XID.MAXGTRIDSIZE) { throw new IllegalStateException(); // Uid is too long!!!! } String nodeName = TxControl.getXANodeName(); int nodeNameLengthToUse = nodeName.getBytes().length; xid.gtrid_length = gtridUid.length + nodeNameLengthToUse; // src, srcPos, dest, destPos, length System.arraycopy(gtridUid, 0, xid.data, 0, gtridUid.length); System.arraycopy(nodeName.getBytes(), 0, xid.data, gtridUid.length, nodeNameLengthToUse); if (branch.notEquals(Uid.nullUid())) { // bqual is uid byte form plus EIS name. byte[] bqualUid = branch.getBytes(); if (bqualUid.length > XID.MAXBQUALSIZE) { throw new IllegalStateException(); // Uid is too long!!!! } int spareBqualBytes = XID.MAXBQUALSIZE - (bqualUid.length + 4); xid.bqual_length = bqualUid.length + 4 + 4; // src, srcPos, dest, destPos, length int offset = xid.gtrid_length; System.arraycopy(bqualUid, 0, xid.data, offset, bqualUid.length); setEisName(xid, eisName); } else { /* * Note: for some dbs we seem to be able to get * away with setting the size field to the size * of the actual branch. However, for Oracle, * it appears as though it must always be 64. * (At least for zero branches.) */ xid.data[xid.gtrid_length] = (byte) 0; xid.bqual_length = 64; } return xid; }
public static Uid getBranchUid(XID xid) { if (xid == null || xid.formatID != FORMAT_ID) { return Uid.nullUid(); } byte[] bqual = new byte[xid.bqual_length]; System.arraycopy(xid.data, xid.gtrid_length, bqual, 0, xid.bqual_length); // The Uid byte are the first in the data array, so we just pass // in the whole thing and the additional trailing data is ignored. Uid tx = new Uid(bqual); return tx; }
public final InputObjectState allObjUids() throws ObjectStoreException { OutputObjectState state = new OutputObjectState(); Iterator<Uid> iter = _ids.keySet().iterator(); try { while (iter.hasNext()) { UidHelper.packInto(iter.next(), state); } // don't forget to null terminate UidHelper.packInto(Uid.nullUid(), state); } catch (final IOException ex) { throw new ObjectStoreException(ex); } return new InputObjectState(state); }
protected static OSRecordHolder readObjectStoreRecord(String type) { try { RecoveryStore recoveryStore = StoreManager.getRecoveryStore(); InputObjectState states = new InputObjectState(); if (recoveryStore.allObjUids(type, states) && states.notempty()) { Uid uid = UidHelper.unpackFrom(states); if (uid.notEquals(Uid.nullUid())) { InputObjectState ios = recoveryStore.read_committed(uid, type); return new OSRecordHolder(uid, type, ios); } } } catch (Exception e) { e.printStackTrace(); } return null; }
private static void clearObjectStore(String type) { try { RecoveryStore recoveryStore = StoreManager.getRecoveryStore(); InputObjectState states = new InputObjectState(); if (recoveryStore.allObjUids(type, states) && states.notempty()) { boolean finished = false; do { Uid uid = UidHelper.unpackFrom(states); if (uid.notEquals(Uid.nullUid())) { recoveryStore.remove_committed(uid, type); } else { finished = true; } } while (!finished); } } catch (Exception e) { e.printStackTrace(); } }
/** * This is a recovery-only method and should not be called during normal execution. As such we * need to load in all of the logs we can find that aren't already loaded (or activated). */ public boolean allObjUids(String tName, InputObjectState state, int match) throws ObjectStoreException { /* * match will always be OS_COMMITTED since that's all we ever write for * the logs. */ // in case of asynchronous removals trigger the purger now. _purger.trigger(); /* * Get a list of logs. Load them in to memory if we aren't already * working on them/it. But we can prune the entry once we're * finished or the memory footprint will grow. We should do this * for all frozen entries eventually too. */ InputObjectState logs = new InputObjectState(); OutputObjectState objUids = new OutputObjectState(); /* * We never call this method except during recovery. As such we shouldn't * need to worry about optimizations such as checking whether or not the * log is in current working memory. */ if (!super.allObjUids(tName, logs, match)) return false; else { /* * Now we have all of the log names let's attach to each one * and locate the committed instances (not deleted.) */ Uid logName = new Uid(Uid.nullUid()); try { do { logName = UidHelper.unpackFrom(logs); if (logName.notEquals(Uid.nullUid())) { /* * Could check to see if log is in current working memory. */ /* * TODO * * First purge the log if we can, but we need to know that * we're not playing with an instance that is being manipulated * from another VM instance. */ ArrayList<InputObjectState> txs = scanLog(logName, tName); if (txs.size() > 0) { for (int i = 0; i < txs.size(); i++) { UidHelper.packInto(txs.get(i).stateUid(), objUids); } } } } while (logName.notEquals(Uid.nullUid())); // remember null terminator UidHelper.packInto(Uid.nullUid(), objUids); state.setBuffer(objUids.buffer()); } catch (final IOException ex) { ex.printStackTrace(); return false; } return true; } }
static XID getXid(Uid uid, boolean branch, Integer eisName) throws IllegalStateException { if (branch) return getXid(uid, new Uid(), FORMAT_ID, eisName); else return getXid(uid, Uid.nullUid(), FORMAT_ID, eisName); }