Example #1
0
  /** Do the real work of dumpLockTableInternal. */
  void dumpLockTableInternal(StatGroup tableStats, int i, boolean clear) {
    StatGroup oneTable = new StatGroup("Single lock table", "Temporary stat group");

    IntStat totalLocks = new IntStat(oneTable, LOCK_TOTAL);
    IntStat waiters = new IntStat(oneTable, LOCK_WAITERS);
    IntStat owners = new IntStat(oneTable, LOCK_OWNERS);
    IntStat readLocks = new IntStat(oneTable, LOCK_READ_LOCKS);
    IntStat writeLocks = new IntStat(oneTable, LOCK_WRITE_LOCKS);

    Map<Long, Lock> lockTable = lockTables[i];
    totalLocks.add(lockTable.size());

    for (Lock lock : lockTable.values()) {
      waiters.add(lock.nWaiters());
      owners.add(lock.nOwners());

      /* Go through all the owners for a lock. */
      for (LockInfo info : lock.getOwnersClone()) {
        if (info.getLockType().isWriteLock()) {
          writeLocks.increment();
        } else {
          readLocks.increment();
        }
      }
    }
    tableStats.addAll(oneTable);
  }
Example #2
0
  private StringBuilder findDeadlock1(Set<Locker> ownerSet, Lock lock, Locker rootLocker) {

    Iterator<LockInfo> ownerIter = lock.getOwnersClone().iterator();
    while (ownerIter.hasNext()) {
      LockInfo info = ownerIter.next();
      Locker locker = info.getLocker();
      Lock waitsFor = locker.getWaitingFor();
      if (ownerSet.contains(locker) || locker == rootLocker) {
        /* Found a cycle. */
        StringBuilder ret = new StringBuilder();
        ret.append("Transaction ").append(locker.toString());
        ret.append(" owns LockAddr:").append(System.identityHashCode(lock));
        ret.append(" ").append(info).append("\n");
        ret.append("Transaction ").append(locker.toString());
        ret.append(" waits for");
        if (waitsFor == null) {
          ret.append(" nothing");
        } else {
          ret.append(" LockAddr:");
          ret.append(System.identityHashCode(waitsFor));
        }
        ret.append("\n");
        return ret;
      }
      if (waitsFor != null) {
        ownerSet.add(locker);
        StringBuilder sb = findDeadlock1(ownerSet, waitsFor, rootLocker);
        if (sb != null) {
          String waitInfo = "Transaction " + locker + " waits for " + waitsFor + "\n";
          sb.insert(0, waitInfo);
          return sb;
        }
        ownerSet.remove(locker); // is this necessary?
      }
    }

    return null;
  }
Example #3
0
  /** Do the real work of creating an lock or txn timeout message. */
  LockConflictException makeTimeoutMsgInternal(
      boolean isLockNotTxnTimeout,
      Locker locker,
      long nodeId,
      LockType type,
      LockGrantType grantType,
      Lock useLock,
      long timeout,
      long start,
      long now,
      DatabaseImpl database) {

    /*
     * Because we're accessing parts of the lock, need to have protected
     * access to the lock table because things can be changing out from
     * underneath us.  This is a big hammer to grab for so long while we
     * traverse the graph, but it's only when we have a deadlock and we're
     * creating a debugging message.
     *
     * The alternative would be to handle ConcurrentModificationExceptions
     * and retry until none of them happen.
     */
    if (lockTableDump) {
      System.out.println("++++++++++ begin lock table dump ++++++++++");
      for (int i = 0; i < nLockTables; i++) {
        boolean success = false;
        for (int j = 0; j < 3 && !success; j++) {
          try {
            StringBuilder sb = new StringBuilder();
            dumpToStringNoLatch(sb, i);
            System.out.println(sb.toString());
            success = true;
            break; // for j...
          } catch (ConcurrentModificationException CME) {
            continue;
          }
        }
        if (!success) {
          System.out.println("Couldn't dump locktable " + i);
        }
      }
      System.out.println("++++++++++ end lock table dump ++++++++++");
    }

    StringBuilder sb = new StringBuilder();
    sb.append(isLockNotTxnTimeout ? "Lock" : "Transaction");
    sb.append(" expired. Locker ").append(locker);
    sb.append(": waited for lock");

    if (database != null) {
      sb.append(" on database=").append(database.getDebugName());
    }
    sb.append(" LockAddr:").append(System.identityHashCode(useLock));
    sb.append(" node=").append(nodeId);
    sb.append(" type=").append(type);
    sb.append(" grant=").append(grantType);
    sb.append(" timeoutMillis=").append(timeout);
    sb.append(" startTime=").append(start);
    sb.append(" endTime=").append(now);
    Set<LockInfo> owners = useLock.getOwnersClone();
    List<LockInfo> waiters = useLock.getWaitersListClone();
    sb.append("\nOwners: ").append(owners);
    sb.append("\nWaiters: ").append(waiters).append("\n");
    StringBuilder deadlockInfo = findDeadlock(useLock, locker);
    if (deadlockInfo != null) {
      sb.append(deadlockInfo);
    }
    LockConflictException ret =
        isLockNotTxnTimeout
            ? newLockTimeoutException(locker, sb.toString())
            : newTxnTimeoutException(locker, sb.toString());

    ret.setOwnerTxnIds(getTxnIds(owners));
    ret.setWaiterTxnIds(getTxnIds(waiters));
    ret.setTimeoutMillis(timeout);
    return ret;
  }