예제 #1
0
 public void checkMinVersion() throws Exception {
   // For this test to make sense, we must be at version 4.7 or higher
   //
   int major = Environment.getVersionMajor();
   int minor = Environment.getVersionMinor();
   assertTrue(major > 4 || (major == 4 && minor >= 7));
 }
  /** Opens the database and creates the Map. */
  private void open() throws Exception {

    // use a generic database configuration
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    if (create) {
      dbConfig.setAllowCreate(true);
      dbConfig.setType(DatabaseType.BTREE);
    }

    // catalog is needed for serial bindings (java serialization)
    Database catalogDb = env.openDatabase(null, "catalog", null, dbConfig);
    catalog = new StoredClassCatalog(catalogDb);

    // use Integer tuple binding for key entries
    TupleBinding keyBinding = TupleBinding.getPrimitiveBinding(Integer.class);

    // use String serial binding for data entries
    SerialBinding dataBinding = new SerialBinding(catalog, String.class);

    this.db = env.openDatabase(null, "helloworld", null, dbConfig);

    // create a map view of the database
    this.map = new StoredSortedMap(db, keyBinding, dataBinding, true);
  }
예제 #3
0
  public void restart(int siteId) throws Exception {
    EnvironmentConfig ec = makeBasicConfig();

    int p = config.getMyPort(siteId);
    ReplicationManagerSiteConfig dbsite = new ReplicationManagerSiteConfig("localhost", p);
    dbsite.setLocalSite(true);
    dbsite.setLegacy(true);
    ec.addReplicationManagerSite(dbsite);

    p = config.getOtherPort(siteId);
    dbsite = new ReplicationManagerSiteConfig("localhost", p);
    dbsite.setLegacy(true);
    ec.addReplicationManagerSite(dbsite);

    MyEventHandler monitor = new MyEventHandler();
    ec.setEventHandler(monitor);
    File clientDir = new File(config.getBaseDir(), "dir" + siteId);
    assertTrue(clientDir.exists());
    Environment client = new Environment(clientDir, ec);
    client.setReplicationConfig(ReplicationConfig.STRICT_2SITE, false);

    envs[siteId] = client;
    monitors[siteId] = monitor;
    // we want to make sure we don't retry from here after the
    // initial failure, because we want to make the old master
    // connect to us.
    client.setReplicationTimeout(ReplicationTimeoutType.CONNECTION_RETRY, Integer.MAX_VALUE);
    client.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_CLIENT);
  }
예제 #4
0
  public void checkpoint(int site) throws Exception {
    assertNull(envs[site]);

    EnvironmentConfig ec = makeBasicConfig();
    File dir = new File(config.getBaseDir(), "dir" + site);
    assertTrue(dir.exists());
    Environment e = new Environment(dir, ec);
    e.setReplicationConfig(ReplicationConfig.STRICT_2SITE, false);
    CheckpointConfig cc = new CheckpointConfig();
    cc.setForce(true);
    e.checkpoint(cc);
    e.close();
  }
예제 #5
0
  /**
   * Inserts an entity and returns null, or updates it if the primary key already exists and returns
   * the existing entity.
   *
   * <p>If a {@link PrimaryKey#sequence} is used and the primary key field of the given entity is
   * null or zero, this method will assign the next value from the sequence to the primary key field
   * of the given entity.
   *
   * @param txn the transaction used to protect this operation, null to use auto-commit, or null if
   *     the store is non-transactional.
   * @param entity the entity to be inserted or updated.
   * @return the existing entity that was updated, or null if the entity was inserted.
   * @throws DatabaseException the base class for all BDB exceptions.
   */
  public E put(Transaction txn, E entity) throws DatabaseException {

    DatabaseEntry keyEntry = new DatabaseEntry();
    DatabaseEntry dataEntry = new DatabaseEntry();
    assignKey(entity, keyEntry);

    boolean autoCommit = false;
    Environment env = db.getEnvironment();
    if (transactional && txn == null && DbCompat.getThreadTransaction(env) == null) {
      txn = env.beginTransaction(null, getAutoCommitTransactionConfig());
      autoCommit = true;
    }

    CursorConfig cursorConfig = null;
    if (concurrentDB) {
      cursorConfig = new CursorConfig();
      DbCompat.setWriteCursor(cursorConfig, true);
    }
    boolean failed = true;
    Cursor cursor = db.openCursor(txn, cursorConfig);
    LockMode lockMode = locking ? LockMode.RMW : null;
    try {
      while (true) {
        OperationStatus status = cursor.getSearchKey(keyEntry, dataEntry, lockMode);
        if (status == OperationStatus.SUCCESS) {
          E existing = entityBinding.entryToObject(keyEntry, dataEntry);
          entityBinding.objectToData(entity, dataEntry);
          cursor.put(keyEntry, dataEntry);
          failed = false;
          return existing;
        } else {
          entityBinding.objectToData(entity, dataEntry);
          status = cursor.putNoOverwrite(keyEntry, dataEntry);
          if (status != OperationStatus.KEYEXIST) {
            failed = false;
            return null;
          }
        }
      }
    } finally {
      cursor.close();
      if (autoCommit) {
        if (failed) {
          txn.abort();
        } else {
          txn.commit();
        }
      }
    }
  }
예제 #6
0
  void closeEnv() throws DatabaseException {

    if (env != null) {
      env.close();
      env = null;
    }
  }
예제 #7
0
  public void close() throws DatabaseException {

    try {
      if (dbenv != null) dbenv.close();
    } finally {
      dbenv = null;
    }
  }
예제 #8
0
  public void joinExistingClient(int site, boolean useHB) throws Exception {
    EnvironmentConfig ec = makeBasicConfig();

    int p = config.getMyPort(site);
    ReplicationManagerSiteConfig dbsite = new ReplicationManagerSiteConfig("localhost", p);
    dbsite.setLocalSite(true);
    dbsite.setLegacy(true);
    ec.addReplicationManagerSite(dbsite);

    p = config.getOtherPort(site);
    dbsite = new ReplicationManagerSiteConfig("localhost", p);
    dbsite.setLegacy(true);
    ec.addReplicationManagerSite(dbsite);

    MyEventHandler monitor = new MyEventHandler();
    monitors[site] = monitor;
    ec.setEventHandler(monitor);
    File clientDir = new File(config.getBaseDir(), "dir" + site);
    assertTrue(clientDir.exists());
    Environment client = new Environment(clientDir, ec);
    client.setReplicationConfig(ReplicationConfig.STRICT_2SITE, false);

    if (useHB) {
      client.setReplicationTimeout(ReplicationTimeoutType.HEARTBEAT_SEND, 3000000);
      client.setReplicationTimeout(ReplicationTimeoutType.HEARTBEAT_MONITOR, 6000000);
    }

    envs[site] = client;
    client.setReplicationTimeout(ReplicationTimeoutType.CONNECTION_RETRY, 1000000); // be impatient
    client.replicationManagerStart(3, ReplicationManagerStartPolicy.REP_CLIENT);
    monitor.await();

    assertTrue(client.getReplicationStats(StatsConfig.DEFAULT).getStartupComplete());
  }
예제 #9
0
  /** Close all stores (closing a store automatically closes its indices). */
  public void close() throws DatabaseException {

    // Close secondary databases, then primary databases.
    supplierByCityDb.close();
    shipmentByPartDb.close();
    shipmentBySupplierDb.close();
    partDb.close();
    supplierDb.close();
    shipmentDb.close();
    // And don't forget to close the catalog and the environment.
    javaCatalog.close();
    env.close();
  }
예제 #10
0
 /**
  * Creates an instance of this class.
  *
  * @param env the Berkeley DB environment
  * @param timeout the number of milliseconds the transaction should be allowed to run
  * @throws IllegalArgumentException if timeout is less than {@code 1}
  * @throws DbDatabaseException if an unexpected database problem occurs
  */
 BdbTransaction(Environment env, long timeout) {
   if (timeout <= 0) {
     throw new IllegalArgumentException("Timeout must be greater than 0");
   }
   try {
     txn = env.beginTransaction(null, null);
     /* Avoid overflow -- BDB treats 0 as unlimited */
     long timeoutMicros = (timeout < (Long.MAX_VALUE / 1000)) ? 1000 * timeout : 0;
     txn.setTxnTimeout(timeoutMicros);
   } catch (DatabaseException e) {
     throw BdbEnvironment.convertException(e, false);
   }
 }
예제 #11
0
  @Override
  public void tearDown() {

    try {
      if (env != null) {
        env.close();
      }
    } catch (Exception e) {
      System.out.println("Ignored exception during tearDown: " + e);
    } finally {
      /* Ensure that GC can cleanup. */
      env = null;
    }
  }
  /** Closes the database. */
  private void close() throws Exception {

    if (catalog != null) {
      catalog.close();
      catalog = null;
    }
    if (db != null) {
      db.close();
      db = null;
    }
    if (env != null) {
      env.close();
      env = null;
    }
  }
예제 #13
0
  private void run() throws DatabaseException {

    Random rand = new Random();

    /*
     * Create a set of events. Each insertion is a separate, auto-commit
     * transaction.
     */
    System.out.println("-> Inserting 4 events");
    eventByTime.put(new Event(makeDate(1), 100, "Company_A"));
    eventByTime.put(new Event(makeDate(2), 2, "Company_B"));
    eventByTime.put(new Event(makeDate(3), 20, "Company_C"));
    eventByTime.put(new Event(makeDate(4), 40, "CompanyD"));

    /* Load a whole set of events transactionally. */
    Transaction txn = env.beginTransaction(null, null);
    int maxPrice = 50;
    System.out.println("-> Inserting some randomly generated events");
    for (int i = 0; i < 25; i++) {
      Event e = new Event(makeDate(rand.nextInt(365)), rand.nextInt(maxPrice), "Company_X");
      if ((i % 2) == 0) {
        e.addRep("Bob");
        e.addRep("Nikunj");
      } else {
        e.addRep("Yongmin");
      }
      eventByTime.put(e);
    }
    txn.commitWriteNoSync();

    /*
     * Windows of events - display the events between June 1 and Aug 31
     */
    System.out.println("\n-> Display the events between June 1 and Aug 31");
    Date startDate = makeDate(Calendar.JUNE, 1);
    Date endDate = makeDate(Calendar.AUGUST, 31);

    EntityCursor<Event> eventWindow = eventByTime.entities(startDate, true, endDate, true);
    printEvents(eventWindow);

    /*
     * Display all events, ordered by a secondary index on price.
     */
    System.out.println("\n-> Display all events, ordered by price");
    EntityCursor<Event> byPriceEvents = eventByPrice.entities();
    printEvents(byPriceEvents);
  }
예제 #14
0
    synchronized void awaitNewmaster(Environment site, long deadline) throws Exception {
      long now;

      for (; ; ) {
        ReplicationStats s = site.getReplicationStats(StatsConfig.DEFAULT);

        // am I the master?
        //
        if (s.getEnvId() == s.getMaster()) {
          break;
        }

        if ((now = System.currentTimeMillis()) >= deadline)
          throw new Exception("aborted by timeout");
        long waitTime = deadline - now;
        wait(waitTime);
        if (panic) throw new Exception("aborted by panic in DB");
      }
    }
예제 #15
0
  @After
  public void tearDown() {

    try {
      if (index1 != null) {
        index1.close();
      }
      if (index2 != null) {
        index2.close();
      }
      if (store1 != null) {
        store1.close();
      }
      if (store2 != null) {
        store2.close();
      }
      if (catalog != null) {
        catalog.close();
      }
      if (env != null) {
        env.close();
      }
    } catch (Exception e) {
      System.out.println("Ignored exception during tearDown: " + e);
    } finally {
      /* Ensure that GC can cleanup. */
      env = null;
      testEnv = null;
      catalog = null;
      store1 = null;
      store2 = null;
      index1 = null;
      index2 = null;
      factory = null;
      storeMap1 = null;
      storeMap2 = null;
      indexMap1 = null;
      indexMap2 = null;
    }
  }
예제 #16
0
 private void setTimeouts(Environment e) throws Exception {
   e.setReplicationTimeout(ReplicationTimeoutType.ACK_TIMEOUT, 30000000);
 }
예제 #17
0
  private void close() throws DatabaseException {

    store.close();
    env.close();
  }
예제 #18
0
  public void run() {
    String homedirName = baseDirName + threadNumber;
    TestUtils.removeDir(homedirName);

    try {
      homedir = new File(homedirName);
      homedir.mkdir();
    } catch (Exception e) {
      TestUtils.DEBUGOUT(
          2, "Warning: initialization had a problem creating a clean directory.\n" + e);
    }
    try {
      homedir = new File(homedirName);
    } catch (NullPointerException npe) {
      // can't really happen :)
    }

    TestUtils.DEBUGOUT(1, "Creating worker: " + threadNumber);

    envConfig = new EnvironmentConfig();
    envConfig.setErrorStream(TestUtils.getErrorStream());
    envConfig.setErrorPrefix("RepmgrElectionTest test(" + threadNumber + ")");
    envConfig.setAllowCreate(true);
    envConfig.setRunRecovery(true);
    envConfig.setThreaded(true);
    envConfig.setInitializeLocking(true);
    envConfig.setInitializeLogging(true);
    envConfig.setInitializeCache(true);
    envConfig.setTransactional(true);
    envConfig.setTxnNoSync(true);
    envConfig.setInitializeReplication(true);
    envConfig.setVerboseReplication(false);

    ReplicationManagerSiteConfig localConfig =
        new ReplicationManagerSiteConfig(address, basePort + threadNumber);
    localConfig.setLocalSite(true);
    envConfig.addReplicationManagerSite(localConfig);

    envConfig.setReplicationPriority(priorities[threadNumber]);
    envConfig.setEventHandler(this);
    envConfig.setReplicationManagerAckPolicy(ReplicationManagerAckPolicy.ALL);

    if (masterThreadIndex >= 0) {
      // If we already have the master, then set it as the bootstrap helper,
      // otherwise, set local site as new master.
      ReplicationManagerSiteConfig remoteConfig =
          new ReplicationManagerSiteConfig(address, basePort + masterThreadIndex);
      remoteConfig.setBootstrapHelper(true);
      envConfig.addReplicationManagerSite(remoteConfig);
    }

    try {
      dbenv = new Environment(homedir, envConfig);

    } catch (FileNotFoundException e) {
      fail("Unexpected FNFE in standard environment creation." + e);
    } catch (DatabaseException dbe) {
      fail("Unexpected database exception came from environment create." + dbe);
    }

    try {
      // If we do not have master, then set local site as new master.
      if (masterThreadIndex == -1)
        dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_MASTER);
      else
        dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_CLIENT);
    } catch (DatabaseException dbe) {
      fail("Unexpected database exception came from replicationManagerStart." + dbe);
    }

    TestUtils.DEBUGOUT(1, "Started replication site: " + threadNumber);
    lastSiteStarted = true;

    try {
      java.lang.Thread.sleep(1000 * (1 + threadNumber));
    } catch (InterruptedException ie) {
    }

    if (masterThreadIndex != -1) {
      // Wait for "Start-up done" for each client, then add next client.
      ReplicationStats rs = null;
      int i = 0;
      do {
        try {
          java.lang.Thread.sleep(2000);
        } catch (InterruptedException e) {
        }

        try {
          rs = dbenv.getReplicationStats(StatsConfig.DEFAULT);
        } catch (DatabaseException dbe) {
          dbe.printStackTrace();
          fail("Unexpected database exception came from getReplicationStats." + dbe);
        }
      } while (!rs.getStartupComplete() && i++ < maxLoopWait);
      assertTrue(rs.getStartupComplete());
    }
  }
예제 #19
0
 /** Passively waits to be chosen as new master in an election. */
 public void becomeMaster(int siteId) throws Exception {
   Environment site = envs[siteId];
   MyEventHandler monitor = (MyEventHandler) site.getConfig().getEventHandler();
   long deadline = System.currentTimeMillis() + 5000;
   monitor.awaitNewmaster(site, deadline);
 }
예제 #20
0
  ObjectStore(
      String facet,
      String facetType,
      boolean createDb,
      EvictorI evictor,
      java.util.List<Index> indices,
      boolean populateEmptyIndices) {
    _cache = new Cache(this);

    _facet = facet;

    _evictor = evictor;
    _indices = indices;
    _communicator = evictor.communicator();
    _encoding = evictor.encoding();
    _keepStats = false;

    if (facet.equals("")) {
      _dbName = EvictorI.defaultDb;
    } else {
      _dbName = facet;
    }

    if (facetType != null) {
      //
      // Create a sample servant with this type
      //
      Ice.ValueFactory factory = _communicator.getValueFactoryManager().find(facetType);
      if (factory == null) {
        throw new DatabaseException(
            _evictor.errorPrefix() + "No value factory registered for type-id '" + facetType + "'");
      }

      _sampleServant = factory.create(facetType);
    }

    Connection connection = Util.createConnection(_communicator, evictor.dbEnv().getEnvName());

    try {
      Catalog catalog = new Catalog(connection, Util.catalogName(), true);
      CatalogData catalogData = catalog.get(evictor.filename());

      if (catalogData != null) {
        if (catalogData.evictor) {
          _keepStats = catalogData.value.isEmpty();
        } else {
          DatabaseException ex = new DatabaseException();
          ex.message = _evictor.errorPrefix() + evictor.filename() + " is not an evictor database";
          throw ex;
        }
      }

      com.sleepycat.db.Environment dbEnv = evictor.dbEnv().getEnv();

      //
      // TODO: FREEZE_DB_MODE
      //
      com.sleepycat.db.DatabaseConfig config = new com.sleepycat.db.DatabaseConfig();
      config.setType(com.sleepycat.db.DatabaseType.BTREE);
      config.setAllowCreate(createDb);

      Ice.Properties properties = _evictor.communicator().getProperties();
      String propPrefix = "Freeze.Evictor." + _evictor.filename() + ".";

      int btreeMinKey = properties.getPropertyAsInt(propPrefix + _dbName + ".BtreeMinKey");
      if (btreeMinKey > 2) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace(
                  "Freeze.Evictor",
                  "Setting \""
                      + _evictor.filename()
                      + "."
                      + _dbName
                      + "\"'s btree minkey to "
                      + btreeMinKey);
        }
        config.setBtreeMinKey(btreeMinKey);
      }

      boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
      if (checksum) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace("Freeze.Evictor", "Turning checksum on for \"" + _evictor.filename() + "\"");
        }

        config.setChecksum(true);
      }

      int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
      if (pageSize > 0) {
        if (_evictor.trace() >= 1) {
          _evictor
              .communicator()
              .getLogger()
              .trace(
                  "Freeze.Evictor",
                  "Setting \"" + _evictor.filename() + "\"'s pagesize to " + pageSize);
        }
        config.setPageSize(pageSize);
      }

      try {
        Transaction tx = connection.beginTransaction();
        com.sleepycat.db.Transaction txn = Util.getTxn(tx);

        _db = dbEnv.openDatabase(txn, evictor.filename(), _dbName, config);

        for (Index index : _indices) {
          index.associate(this, txn, createDb, populateEmptyIndices);
        }

        if (catalogData == null) {
          catalogData = new CatalogData(true, "::Ice::Identity", "Object");
          catalog.put(evictor.filename(), catalogData);
        }

        tx.commit();
      } catch (java.io.FileNotFoundException dx) {
        throw new NotFoundException(_evictor.errorPrefix() + "Db.open: " + dx.getMessage(), dx);
      } catch (com.sleepycat.db.DatabaseException dx) {
        throw new DatabaseException(_evictor.errorPrefix() + "Db.open: " + dx.getMessage(), dx);
      } finally {
        Transaction tx = connection.currentTransaction();
        if (tx != null) {
          try {
            tx.rollback();
          } catch (DatabaseException de) {
          }
        }
      }
    } finally {
      connection.close();
    }
  }
예제 #21
0
  protected Ice.Identity[] untypedFindFirst(byte[] k, int firstN) {
    EvictorI.DeactivateController deactivateController = _store.evictor().deactivateController();
    deactivateController.lock();
    try {
      com.sleepycat.db.DatabaseEntry key = new com.sleepycat.db.DatabaseEntry(k);

      //
      // When we have a custom-comparison function, Berkeley DB returns
      // the key on-disk (when it finds one). We disable this behavior:
      // (ref Oracle SR 5925672.992)
      //
      // In DB > 5.1.x we can not set DB_DBT_PARTIAL in the key Dbt when calling
      // getSearchKey.
      //
      if (com.sleepycat.db.Environment.getVersionMajor() < 5
          || (com.sleepycat.db.Environment.getVersionMajor() == 5
              && com.sleepycat.db.Environment.getVersionMinor() <= 1)) {
        key.setPartial(true);
      }

      com.sleepycat.db.DatabaseEntry pkey = new com.sleepycat.db.DatabaseEntry();
      com.sleepycat.db.DatabaseEntry value = new com.sleepycat.db.DatabaseEntry();
      //
      // dlen is 0, so we should not retrieve any value
      //
      value.setPartial(true);

      Ice.Communicator communicator = _store.communicator();
      Ice.EncodingVersion encoding = _store.encoding();

      TransactionI transaction = _store.evictor().beforeQuery();
      com.sleepycat.db.Transaction tx = transaction == null ? null : transaction.dbTxn();

      java.util.List<Ice.Identity> identities;

      for (; ; ) {
        com.sleepycat.db.SecondaryCursor dbc = null;
        identities = new java.util.ArrayList<Ice.Identity>();

        try {
          //
          // Move to the first record
          //
          dbc = _db.openSecondaryCursor(tx, null);
          boolean first = true;

          boolean found;

          do {
            com.sleepycat.db.OperationStatus status;
            if (first) {
              status = dbc.getSearchKey(key, pkey, value, null);
            } else {
              status = dbc.getNextDup(key, pkey, value, null);
            }

            found = status == com.sleepycat.db.OperationStatus.SUCCESS;

            if (found) {
              Ice.Identity ident = ObjectStore.unmarshalKey(pkey, communicator, encoding);
              identities.add(ident);
              first = false;
            }
          } while ((firstN <= 0 || identities.size() < firstN) && found);

          break; // for(;;)
        } catch (com.sleepycat.db.DeadlockException dx) {
          if (_store.evictor().deadlockWarning()) {
            communicator
                .getLogger()
                .warning(
                    "Deadlock in Freeze.Index.untypedFindFirst while "
                        + "iterating over Db \""
                        + _store.evictor().filename()
                        + "/"
                        + _dbName
                        + "\"");
          }

          if (tx != null) {
            throw new DeadlockException(
                _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(), transaction, dx);
          }

          //
          // Otherwise retry
          //
        } catch (com.sleepycat.db.DatabaseException dx) {
          throw new DatabaseException(
              _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(), dx);
        } finally {
          if (dbc != null) {
            try {
              dbc.close();
            } catch (com.sleepycat.db.DeadlockException dx) {
              if (tx != null) {
                throw new DeadlockException(
                    _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(),
                    transaction,
                    dx);
              }
            } catch (com.sleepycat.db.DatabaseException dx) {
              //
              // Ignored
              //
            }
          }
        }
      }

      if (identities.size() != 0) {
        Ice.Identity[] result = new Ice.Identity[identities.size()];
        return identities.toArray(result);
      } else {
        return new Ice.Identity[0];
      }
    } finally {
      deactivateController.unlock();
    }
  }
예제 #22
0
  protected int untypedCount(byte[] k) {
    EvictorI.DeactivateController deactivateController = _store.evictor().deactivateController();
    deactivateController.lock();
    try {
      com.sleepycat.db.DatabaseEntry key = new com.sleepycat.db.DatabaseEntry(k);

      //
      // When we have a custom-comparison function, Berkeley DB returns
      // the key on-disk (when it finds one). We disable this behavior:
      // (ref Oracle SR 5925672.992)
      //
      // In DB > 5.1.x we can not set DB_DBT_PARTIAL in the key Dbt when calling
      // getSearchKey.
      //
      if (com.sleepycat.db.Environment.getVersionMajor() < 5
          || (com.sleepycat.db.Environment.getVersionMajor() == 5
              && com.sleepycat.db.Environment.getVersionMinor() <= 1)) {
        key.setPartial(true);
      }

      com.sleepycat.db.DatabaseEntry value = new com.sleepycat.db.DatabaseEntry();
      //
      // dlen is 0, so we should not retrieve any value
      //
      value.setPartial(true);
      TransactionI transaction = _store.evictor().beforeQuery();
      com.sleepycat.db.Transaction tx = transaction == null ? null : transaction.dbTxn();

      for (; ; ) {
        com.sleepycat.db.Cursor dbc = null;
        try {
          dbc = _db.openCursor(tx, null);
          if (dbc.getSearchKey(key, value, null) == com.sleepycat.db.OperationStatus.SUCCESS) {
            return dbc.count();
          } else {
            return 0;
          }
        } catch (com.sleepycat.db.DeadlockException dx) {
          if (_store.evictor().deadlockWarning()) {
            _store
                .communicator()
                .getLogger()
                .warning(
                    "Deadlock in Freeze.Index.untypedCount while "
                        + "iterating over Db \""
                        + _store.evictor().filename()
                        + "/"
                        + _dbName
                        + "\"");
          }

          if (tx != null) {
            throw new DeadlockException(
                _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(), transaction, dx);
          }
          //
          // Otherwise retry
          //
        } catch (com.sleepycat.db.DatabaseException dx) {
          throw new DatabaseException(
              _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(), dx);
        } finally {
          if (dbc != null) {
            try {
              dbc.close();
            } catch (com.sleepycat.db.DeadlockException dx) {
              if (tx != null) {
                throw new DeadlockException(
                    _store.evictor().errorPrefix() + "Db.cursor: " + dx.getMessage(),
                    transaction,
                    dx);
              }
            } catch (com.sleepycat.db.DatabaseException dx) {
              //
              // Ignored
              //
            }
          }
        }
      }
    } finally {
      deactivateController.unlock();
    }
  }
예제 #23
0
  //
  // Initialize the database to the number of accounts, branches,
  // history records, and tellers given to the constructor.
  //
  public void populate() {
    Database dbp = null;

    int err;
    int balance, idnum;
    int end_anum, end_bnum, end_tnum;
    int start_anum, start_bnum, start_tnum;
    int h_nelem;

    idnum = BEGID;
    balance = 500000;

    h_nelem = accounts;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "account", null, config);
    } catch (Exception e1) {
      // can be DatabaseException or FileNotFoundException
      errExit(e1, "Open of account file failed");
    }

    start_anum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "account");
    idnum += h_nelem;
    end_anum = idnum - 1;
    try {
      dbp.close();
    } catch (DatabaseException e2) {
      errExit(e2, "Account file close failed");
    }

    if (verbose)
      System.out.println(
          "Populated accounts: " + String.valueOf(start_anum) + " - " + String.valueOf(end_anum));

    //
    // Since the number of branches is very small, we want to use very
    // small pages and only 1 key per page.  This is the poor-man's way
    // of getting key locking instead of page locking.
    //
    h_nelem = (int) branches;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(1);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "branch", null, config);
    } catch (Exception e3) {
      // can be DatabaseException or FileNotFoundException
      errExit(e3, "Branch file create failed");
    }

    start_bnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "branch");
    idnum += h_nelem;
    end_bnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException dbe4) {
      errExit(dbe4, "Close of branch file failed");
    }

    if (verbose)
      System.out.println(
          "Populated branches: " + String.valueOf(start_bnum) + " - " + String.valueOf(end_bnum));

    //
    // In the case of tellers, we also want small pages, but we'll let
    // the fill factor dynamically adjust itself.
    //
    h_nelem = (int) tellers;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(0);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "teller", null, config);
    } catch (Exception e5) {
      // can be DatabaseException or FileNotFoundException
      errExit(e5, "Teller file create failed");
    }

    start_tnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "teller");
    idnum += h_nelem;
    end_tnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException e6) {
      errExit(e6, "Close of teller file failed");
    }

    if (verbose)
      System.out.println(
          "Populated tellers: " + String.valueOf(start_tnum) + " - " + String.valueOf(end_tnum));

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.RECNO);
      config.setRecordLength(HISTORY_LEN);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "history", null, config);
    } catch (Exception e7) {
      // can be DatabaseException or FileNotFoundException
      errExit(e7, "Create of history file failed");
    }

    populateHistory(dbp);

    try {
      dbp.close();
    } catch (DatabaseException e8) {
      errExit(e8, "Close of history file failed");
    }
  }
예제 #24
0
  /** Open all storage containers, indices, and catalogs. */
  public SampleDatabase(String homeDirectory) throws DatabaseException, FileNotFoundException {

    // Open the Berkeley DB environment in transactional mode.
    //
    System.out.println("Opening environment in: " + homeDirectory);
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);
    envConfig.setInitializeCache(true);
    envConfig.setInitializeLocking(true);
    env = new Environment(new File(homeDirectory), envConfig);

    // Set the Berkeley DB config for opening all stores.
    //
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setAllowCreate(true);
    dbConfig.setType(DatabaseType.BTREE);

    // Create the Serial class catalog.  This holds the serialized class
    // format for all database records of serial format.
    //
    Database catalogDb = env.openDatabase(null, CLASS_CATALOG, null, dbConfig);
    javaCatalog = new StoredClassCatalog(catalogDb);

    // Open the Berkeley DB database for the part, supplier and shipment
    // stores.  The stores are opened with no duplicate keys allowed.
    //
    partDb = env.openDatabase(null, PART_STORE, null, dbConfig);

    supplierDb = env.openDatabase(null, SUPPLIER_STORE, null, dbConfig);

    shipmentDb = env.openDatabase(null, SHIPMENT_STORE, null, dbConfig);

    // Open the SecondaryDatabase for the city index of the supplier store,
    // and for the part and supplier indices of the shipment store.
    // Duplicate keys are allowed since more than one supplier may be in
    // the same city, and more than one shipment may exist for the same
    // supplier or part.  A foreign key constraint is defined for the
    // supplier and part indices to ensure that a shipment only refers to
    // existing part and supplier keys.  The CASCADE delete action means
    // that shipments will be deleted if their associated part or supplier
    // is deleted.
    //
    SecondaryConfig secConfig = new SecondaryConfig();
    secConfig.setTransactional(true);
    secConfig.setAllowCreate(true);
    secConfig.setType(DatabaseType.BTREE);
    secConfig.setSortedDuplicates(true);

    secConfig.setKeyCreator(
        new SupplierByCityKeyCreator(
            javaCatalog, SupplierKey.class, SupplierData.class, String.class));
    supplierByCityDb =
        env.openSecondaryDatabase(null, SUPPLIER_CITY_INDEX, null, supplierDb, secConfig);

    secConfig.setForeignKeyDatabase(partDb);
    secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
    secConfig.setKeyCreator(
        new ShipmentByPartKeyCreator(
            javaCatalog, ShipmentKey.class, ShipmentData.class, PartKey.class));
    shipmentByPartDb =
        env.openSecondaryDatabase(null, SHIPMENT_PART_INDEX, null, shipmentDb, secConfig);

    secConfig.setForeignKeyDatabase(supplierDb);
    secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE);
    secConfig.setKeyCreator(
        new ShipmentBySupplierKeyCreator(
            javaCatalog, ShipmentKey.class, ShipmentData.class, SupplierKey.class));
    shipmentBySupplierDb =
        env.openSecondaryDatabase(null, SHIPMENT_SUPPLIER_INDEX, null, shipmentDb, secConfig);
  }
예제 #25
0
  @Test
  public void testDraining() throws Exception {
    EnvironmentConfig masterConfig = makeBasicConfig();
    masterConfig.setReplicationLimit(100000000);
    ReplicationManagerSiteConfig site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLocalSite(true);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);

    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    masterConfig.addReplicationManagerSite(site);

    Environment master = new Environment(mkdir("master"), masterConfig);
    setTimeouts(master);
    // Prevent connection retries, so that all connections
    // originate from clients
    master.setReplicationTimeout(ReplicationTimeoutType.CONNECTION_RETRY, Integer.MAX_VALUE);
    master.replicationManagerStart(2, ReplicationManagerStartPolicy.REP_MASTER);

    DatabaseConfig dc = new DatabaseConfig();
    dc.setTransactional(true);
    dc.setAllowCreate(true);
    dc.setType(DatabaseType.BTREE);
    dc.setPageSize(4096);
    Database db = master.openDatabase(null, "test.db", null, dc);

    DatabaseEntry key = new DatabaseEntry();
    DatabaseEntry value = new DatabaseEntry();
    value.setData(data);

    for (int i = 0; ((BtreeStats) db.getStats(null, null)).getPageCount() < 500; i++) {
      String k = "The record number is: " + i;
      key.setData(k.getBytes());
      db.put(null, key, value);
    }

    // tell fiddler to stop reading once it sees a PAGE message
    Socket s = new Socket("localhost", mgrPort);
    OutputStreamWriter w = new OutputStreamWriter(s.getOutputStream());

    String path1 = "{" + masterPort + "," + clientPort + "}"; // looks like {6000,6001}
    w.write("{init," + path1 + ",page_clog}\r\n");
    w.flush();
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    br.readLine();
    assertEquals("ok", br.readLine());
    // create client
    //
    EnvironmentConfig ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    Environment client = new Environment(mkdir("client"), ec);
    setTimeouts(client);
    client.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT);

    // wait til it gets stuck
    Thread.sleep(5000); // FIXME

    // Do the same for another client, because the master has 2
    // msg processing threads.  (It's no longer possible to
    // configure just 1.)
    String path2 = "{" + masterPort + "," + client2Port + "}";
    w.write("{init," + path2 + ",page_clog}\r\n");
    w.flush();
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    br.readLine();
    assertEquals("ok", br.readLine());

    ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    Environment client2 = new Environment(mkdir("client2"), ec);
    setTimeouts(client2);
    client2.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT);

    // wait til it gets stuck
    Thread.sleep(5000);

    // With the connection stuck, the master cannot write out log
    // records for new "live" transactions.  Knowing we didn't
    // write the record, we should not bother waiting for an ack
    // that cannot possibly arrive; so we should simply return
    // quickly.  The duration should be very quick, but anything
    // less than the ack timeout indicates correct behavior (in
    // case this test runs on a slow, overloaded system).
    //
    long startTime = System.currentTimeMillis();
    key.setData("one extra record".getBytes());
    db.put(null, key, value);
    long duration = System.currentTimeMillis() - startTime;
    assertTrue("txn duration: " + duration, duration < 29000);
    System.out.println("txn duration: " + duration);
    db.close();

    // Tell fiddler to close the connections.  That should trigger
    // us to abandon the timeout.  Then create another client and
    // see that it can complete its internal init quickly.  Since
    // we have limited threads at the master, this demonstrates
    // that they were abandoned.
    //
    path1 = "{" + clientPort + "," + masterPort + "}"; // looks like {6001,6000}
    w.write("{" + path1 + ",shutdown}\r\n");
    w.flush();
    assertEquals("ok", br.readLine());
    path2 = "{" + client2Port + "," + masterPort + "}"; // looks like {6001,6000}
    w.write("{" + path2 + ",shutdown}\r\n");
    w.flush();
    assertEquals("ok", br.readLine());

    ec = makeBasicConfig();
    site = new ReplicationManagerSiteConfig("localhost", client3Port);
    site.setLocalSite(true);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", masterPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", clientPort);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);
    site = new ReplicationManagerSiteConfig("localhost", client2Port);
    site.setLegacy(true);
    ec.addReplicationManagerSite(site);

    EventHandler clientMonitor = new EventHandler();
    ec.setEventHandler(clientMonitor);
    Environment client3 = new Environment(mkdir("client3"), ec);
    setTimeouts(client3);
    startTime = System.currentTimeMillis();
    client3.replicationManagerStart(2, ReplicationManagerStartPolicy.REP_CLIENT);
    clientMonitor.await();
    duration = System.currentTimeMillis() - startTime;
    assertTrue("sync duration: " + duration, duration < 20000); // 20 seconds should be plenty

    client3.close();
    master.close();

    w.write("shutdown\r\n");
    w.flush();
    assertEquals("ok", br.readLine());
    s.close();
  }