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); }
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); }
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(); }
/** * 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(); } } } }
void closeEnv() throws DatabaseException { if (env != null) { env.close(); env = null; } }
public void close() throws DatabaseException { try { if (dbenv != null) dbenv.close(); } finally { dbenv = null; } }
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()); }
/** 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(); }
/** * 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); } }
@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; } }
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); }
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"); } }
@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; } }
private void setTimeouts(Environment e) throws Exception { e.setReplicationTimeout(ReplicationTimeoutType.ACK_TIMEOUT, 30000000); }
private void close() throws DatabaseException { store.close(); env.close(); }
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()); } }
/** 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); }
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(); } }
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(); } }
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(); } }
// // 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"); } }
/** 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); }
@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(); }