package com.taobao.tddl.repo.bdb.spi; import java.io.File; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseConfig; import com.sleepycat.je.Durability; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.rep.ReplicaWriteException; import com.taobao.tddl.common.exception.NotSupportException; import com.taobao.tddl.common.exception.TddlException; import com.taobao.tddl.common.exception.TddlNestableRuntimeException; import com.taobao.tddl.common.model.Group; import com.taobao.tddl.common.model.lifecycle.AbstractLifecycle; import com.taobao.tddl.common.properties.ConnectionProperties; import com.taobao.tddl.common.utils.GeneralUtil; import com.taobao.tddl.executor.spi.ICommandHandlerFactory; import com.taobao.tddl.executor.spi.ICursorFactory; import com.taobao.tddl.executor.spi.IGroupExecutor; import com.taobao.tddl.executor.spi.IRepository; import com.taobao.tddl.executor.spi.ITHLog; import com.taobao.tddl.executor.spi.ITable; import com.taobao.tddl.executor.spi.ITempTable; import com.taobao.tddl.optimizer.config.table.TableMeta; /** * @author jianxing <[email protected]> */ public class JE_Repository extends AbstractLifecycle implements IRepository { protected final AtomicReference<ITHLog> historyLog = new AtomicReference<ITHLog>(); protected ICommandHandlerFactory cef = null; protected BDBConfig config; protected Environment env; protected Map<String, ITable> tables = new ConcurrentHashMap<String, ITable>(); protected ICursorFactory cursorFactoryBDBImp; protected Environment env_tmp; protected Durability durability; protected Random r = new Random(); private final Map cp; public JE_Repository(Map cp){ this.cp = cp; } public void commonConfig(EnvironmentConfig envConfig, BDBConfig config) { System.setProperty("JEMonitor", "true"); envConfig.setConfigParam(EnvironmentConfig.NODE_MAX_ENTRIES, "256"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_EVICT_BYTES, (1024 * 1024 * 2) + ""); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_NODES_PER_SCAN, "10"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_LRU_ONLY, "false"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_FORCED_YIELD, "true"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_CORE_THREADS, Runtime.getRuntime().availableProcessors() + ""); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_MAX_THREADS, Runtime.getRuntime().availableProcessors() + ""); envConfig.setConfigParam(EnvironmentConfig.CHECKPOINTER_BYTES_INTERVAL, 1024 * 1024 * 200 + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_LOOK_AHEAD_CACHE_SIZE, 1024 * 8 + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_READ_SIZE, 1024 * 1024 + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_MAX_BATCH_FILES, 3 + ""); envConfig.setConfigParam(EnvironmentConfig.LOG_FILE_MAX, 1024 * 1024 * 200 + ""); envConfig.setConfigParam(EnvironmentConfig.LOG_FILE_CACHE_SIZE, "1024"); envConfig.setConfigParam(EnvironmentConfig.LOG_USE_WRITE_QUEUE, "true"); envConfig.setConfigParam(EnvironmentConfig.LOG_WRITE_QUEUE_SIZE, 1024 * 1024 * 2 + ""); // envConfig.setConfigParam(EnvironmentConfig.HALT_ON_COMMIT_AFTER_CHECKSUMEXCEPTION, // "true"); envConfig.setConfigParam(EnvironmentConfig.LOG_ITERATOR_READ_SIZE, 1024 * 8 + ""); envConfig.setConfigParam(EnvironmentConfig.LOCK_TIMEOUT, 2000 + "\tMILLISECONDS"); envConfig.setConfigParam(EnvironmentConfig.ENV_RECOVERY_FORCE_CHECKPOINT, "true"); envConfig.setConfigParam(EnvironmentConfig.CLEANER_MIN_UTILIZATION, (config.getCleaner_min_utilization())); envConfig.setConfigParam(EnvironmentConfig.CLEANER_LAZY_MIGRATION, config.getCleanerLazyMigration()); envConfig.setConfigParam(EnvironmentConfig.CLEANER_THREADS, config.getCleanerThreadCount() + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_MAX_BATCH_FILES, config.getCleanerBatchFileCount() + ""); envConfig.setConfigParam(EnvironmentConfig.ENV_RUN_CLEANER, config.getAutoClean() ? "true" : "false"); } @Override public BDBConfig getRepoConfig() { return config; } @Override public boolean isWriteAble() { return true; } @Override public ICursorFactory getCursorFactory() { return cursorFactoryBDBImp; } @Override public void init() { // EnvironmentConfig envConfig = new EnvironmentConfig(); // commonConfig(envConfig); // envConfig.setCachePercent(config.getCachePercent()); // envConfig.setAllowCreate(true); // if (config.isTransactional()) { // envConfig.setCachePercent(config.getCachePercent()); // envConfig.setTransactional(config.isTransactional()); // envConfig.setTxnTimeout(config.getTxnTimeout(), TimeUnit.SECONDS); // this.durability = config.isCommitSync() ? Durability.COMMIT_SYNC : // Durability.COMMIT_NO_SYNC; // envConfig.setDurability(this.durability); // } // File repo_dir = new File(config.getRepoDir()); // if (!repo_dir.exists()) { // repo_dir.mkdirs(); // } // this.env = new Environment(repo_dir, envConfig); cef = new CommandHandlerFactoryBDBImpl(); cursorFactoryBDBImp = new CursorFactoryBDBImp(); } public void commonConfig(EnvironmentConfig envConfig) { System.setProperty("JEMonitor", "true"); envConfig.setConfigParam(EnvironmentConfig.NODE_MAX_ENTRIES, "256"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_EVICT_BYTES, (1024 * 1024 * 2) + ""); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_NODES_PER_SCAN, "10"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_LRU_ONLY, "false"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_FORCED_YIELD, "true"); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_CORE_THREADS, Runtime.getRuntime().availableProcessors() + ""); envConfig.setConfigParam(EnvironmentConfig.EVICTOR_MAX_THREADS, Runtime.getRuntime().availableProcessors() + ""); envConfig.setConfigParam(EnvironmentConfig.CHECKPOINTER_BYTES_INTERVAL, 1024 * 1024 * 200 + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_LAZY_MIGRATION, "true"); envConfig.setConfigParam(EnvironmentConfig.CLEANER_THREADS, Runtime.getRuntime().availableProcessors() + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_LOOK_AHEAD_CACHE_SIZE, 1024 * 8 + ""); envConfig.setConfigParam(EnvironmentConfig.CLEANER_READ_SIZE, 1024 * 1024 + ""); envConfig.setConfigParam(EnvironmentConfig.LOG_FILE_MAX, 1024 * 1024 * 200 + ""); envConfig.setConfigParam(EnvironmentConfig.LOG_FILE_CACHE_SIZE, "1024"); envConfig.setConfigParam(EnvironmentConfig.LOG_USE_WRITE_QUEUE, "true"); envConfig.setConfigParam(EnvironmentConfig.LOG_WRITE_QUEUE_SIZE, 1024 * 1024 * 2 + ""); // envConfig.setConfigParam(EnvironmentConfig.HALT_ON_COMMIT_AFTER_CHECKSUMEXCEPTION, // "true"); envConfig.setConfigParam(EnvironmentConfig.LOG_ITERATOR_READ_SIZE, 1024 * 8 + ""); envConfig.setConfigParam(EnvironmentConfig.LOCK_TIMEOUT, 2000 + "\tMILLISECONDS"); envConfig.setConfigParam(EnvironmentConfig.ENV_RECOVERY_FORCE_CHECKPOINT, "true"); } @Override public ITable getTable(TableMeta table_schema, String groupNode, String actualTableName) throws TddlException { ITable table = tables.get(table_schema.getTableName()); if (table == null) { synchronized (this) { table = tables.get(table_schema.getTableName()); if (table == null) { try { table = initTable(table_schema); } catch (ReplicaWriteException ex) { throw new TddlNestableRuntimeException(ex); } if (!table_schema.isTmp()) { tables.put(table_schema.getTableName(), table); } } } } return table; } public JE_Table initTable(TableMeta table_schema) throws TddlException { return new JE_Table(table_schema, this); } public Database getDatabase(String name, boolean isTmp, boolean isSortedDuplicates) { DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setAllowCreate(true); Environment _env = env; if (isTmp) { dbConfig.setTemporary(true); dbConfig.setSortedDuplicates(isSortedDuplicates); _env = getTmpEnv(); } else { if (!config.isTransactional()) { dbConfig.setDeferredWrite(config.isCommitSync()); } else { dbConfig.setTransactional(true); } } Database database = buildPrimaryIndex(dbConfig, _env, name); return database; } public Environment getEnv() { return env; } @Override public void doDestroy() throws TddlException { for (Entry<String, ITable> t : tables.entrySet()) { t.getValue().close(); } env.close(); if (env_tmp != null) { env_tmp.close(); } } public synchronized Environment getTmpEnv() { if (env_tmp != null) { return env_tmp; } else { EnvironmentConfig envConfig = new EnvironmentConfig(); long cachePercent = GeneralUtil.getExtraCmdLong(cp, ConnectionProperties.TEMP_TABLE_CACHE_PERCENT, 20); envConfig.setCachePercent((int) cachePercent); envConfig.setAllowCreate(true); envConfig.setConfigParam(EnvironmentConfig.LOG_FILE_MAX, 1000000 + ""); String path = null; path = GeneralUtil.getExtraCmdString(cp, ConnectionProperties.TEMP_TABLE_DIR); if (path == null) { path = System.getProperty("user.dir") + "/bdbtmp/" + System.currentTimeMillis() + r.nextInt() + "requestID." + genRequestID() + "/"; } File repo_dir = new File(path); // repo_dir = new File(System.getProperty("user.dir") + "/bdbtmp/"); if (!repo_dir.exists()) { repo_dir.mkdirs(); } env_tmp = new Environment(repo_dir, envConfig); return env_tmp; } } @Override public boolean isEnhanceExecutionModel(String groupKey) { return true; } private Database buildPrimaryIndex(DatabaseConfig dbConfig, Environment _env, String dbName) { Database database = _env.openDatabase(null, dbName, dbConfig); return database; } // @Override public void cleanTempTable() { if (env_tmp != null) { env_tmp.cleanLog(); } } @Override public ICommandHandlerFactory getCommandExecutorFactory() { return cef; } public int cleanLog() { return env.cleanLog(); } @Override public IGroupExecutor getGroupExecutor(Group group) { throw new NotSupportException(); } public void setConfig(BDBConfig config) { this.config = config; } @Override public ITempTable getTempTable(TableMeta meta) throws TddlException { JE_TempTable table = new JE_TempTable(meta, this); table.tmpEv = this.getTmpEnv(); return table; } static AtomicLong currentID = new AtomicLong(0L); public static long genRequestID() { return currentID.addAndGet(1L); } }