1 8 9 package com.sleepycat.je.dbi; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 import java.io.PrintStream ; 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.List ; 17 import java.util.logging.ConsoleHandler ; 18 import java.util.logging.FileHandler ; 19 import java.util.logging.Handler ; 20 import java.util.logging.Level ; 21 import java.util.logging.Logger ; 22 import java.util.logging.SimpleFormatter ; 23 24 import com.sleepycat.je.CheckpointConfig; 25 import com.sleepycat.je.Database; 26 import com.sleepycat.je.DatabaseConfig; 27 import com.sleepycat.je.DatabaseException; 28 import com.sleepycat.je.DbInternal; 29 import com.sleepycat.je.Environment; 30 import com.sleepycat.je.EnvironmentConfig; 31 import com.sleepycat.je.EnvironmentMutableConfig; 32 import com.sleepycat.je.EnvironmentStats; 33 import com.sleepycat.je.ExceptionListener; 34 import com.sleepycat.je.LockStats; 35 import com.sleepycat.je.RunRecoveryException; 36 import com.sleepycat.je.StatsConfig; 37 import com.sleepycat.je.Transaction; 38 import com.sleepycat.je.TransactionConfig; 39 import com.sleepycat.je.TransactionStats; 40 import com.sleepycat.je.VerifyConfig; 41 import com.sleepycat.je.cleaner.Cleaner; 42 import com.sleepycat.je.cleaner.UtilizationProfile; 43 import com.sleepycat.je.cleaner.UtilizationTracker; 44 import com.sleepycat.je.config.EnvironmentParams; 45 import com.sleepycat.je.evictor.Evictor; 46 import com.sleepycat.je.incomp.INCompressor; 47 import com.sleepycat.je.latch.Latch; 48 import com.sleepycat.je.latch.LatchSupport; 49 import com.sleepycat.je.latch.SharedLatch; 50 import com.sleepycat.je.log.FileManager; 51 import com.sleepycat.je.log.LatchedLogManager; 52 import com.sleepycat.je.log.LogManager; 53 import com.sleepycat.je.log.SyncedLogManager; 54 import com.sleepycat.je.log.TraceLogHandler; 55 import com.sleepycat.je.recovery.Checkpointer; 56 import com.sleepycat.je.recovery.RecoveryInfo; 57 import com.sleepycat.je.recovery.RecoveryManager; 58 import com.sleepycat.je.tree.BIN; 59 import com.sleepycat.je.tree.BINReference; 60 import com.sleepycat.je.tree.IN; 61 import com.sleepycat.je.tree.Key; 62 import com.sleepycat.je.txn.Locker; 63 import com.sleepycat.je.txn.Txn; 64 import com.sleepycat.je.txn.TxnManager; 65 import com.sleepycat.je.utilint.DbLsn; 66 import com.sleepycat.je.utilint.NotImplementedYetException; 67 import com.sleepycat.je.utilint.PropUtil; 68 import com.sleepycat.je.utilint.TestHook; 69 import com.sleepycat.je.utilint.TestHookExecute; 70 import com.sleepycat.je.utilint.Tracer; 71 72 76 public class EnvironmentImpl implements EnvConfigObserver { 77 78 82 private static final boolean TEST_NO_LOCKING_MODE = false; 83 84 85 private DbEnvState envState; 86 private boolean closing; private File envHome; 88 private int referenceCount; private boolean isTransactional; private boolean isNoLocking; private boolean isReadOnly; private boolean isMemOnly; private boolean directNIO; private static boolean fairLatches; private static boolean useSharedLatchesForINs; 96 97 private boolean deferredWriteTemp; 98 99 private MemoryBudget memoryBudget; 100 private static int adler32ChunkSize; 101 102 103 private long lockTimeout; 104 private long txnTimeout; 105 106 107 private DbTree dbMapTree; 108 private long mapTreeRootLsn = DbLsn.NULL_LSN; 109 private Latch mapTreeRootLatch; 110 private INList inMemoryINs; 111 112 113 private DbConfigManager configManager; 114 private List configObservers; 115 private Logger envLogger; 116 protected LogManager logManager; 117 private FileManager fileManager; 118 private TxnManager txnManager; 119 120 121 private Evictor evictor; 122 private INCompressor inCompressor; 123 private Checkpointer checkpointer; 124 private Cleaner cleaner; 125 126 127 private boolean isReplicated; 128 private ReplicatorInstance repInstance; 129 130 131 private RecoveryInfo lastRecoveryInfo; 132 private RunRecoveryException savedInvalidatingException; 133 134 135 private static boolean forcedYield = false; 136 137 141 private SharedLatch triggerLatch; 142 143 146 private ExceptionListener exceptionListener = null; 147 148 156 private volatile int backgroundSleepBacklog; 157 private volatile int backgroundReadLimit; 158 private volatile int backgroundWriteLimit; 159 private long backgroundSleepInterval; 160 private int backgroundReadCount; 161 private long backgroundWriteBytes; 162 private TestHook backgroundSleepHook; 163 private Object backgroundTrackingMutex = new Object (); 164 private Object backgroundSleepMutex = new Object (); 165 166 174 private static int threadLocalReferenceCount = 0; 175 176 181 private static boolean noComparators = false; 182 183 188 public final RunRecoveryException SAVED_RRE = DbInternal.makeNoArgsRRE(); 189 190 public static final boolean JAVA5_AVAILABLE; 191 192 private static final String DISABLE_JAVA_ADLER32 = 193 "je.disable.java.adler32"; 194 195 static { 196 boolean ret = false; 197 if (System.getProperty(DISABLE_JAVA_ADLER32) == null) { 198 199 202 String javaVersion = System.getProperty("java.version"); 203 if (javaVersion != null && 204 !javaVersion.startsWith("1.4.")) { 205 ret = true; 206 } 207 } 208 JAVA5_AVAILABLE = ret; 209 } 210 211 224 public EnvironmentImpl(File envHome, EnvironmentConfig envConfig) 225 throws DatabaseException { 226 227 try { 228 this.envHome = envHome; 229 envState = DbEnvState.INIT; 230 mapTreeRootLatch = LatchSupport.makeLatch("MapTreeRoot", this); 231 232 233 configManager = new DbConfigManager(envConfig); 234 configObservers = new ArrayList (); 235 addConfigObserver(this); 236 237 241 memoryBudget = new MemoryBudget(this, configManager); 242 243 247 envLogger = initLogger(envHome); 248 249 252 forcedYield = 253 configManager.getBoolean(EnvironmentParams.ENV_FORCED_YIELD); 254 isTransactional = 255 configManager.getBoolean(EnvironmentParams.ENV_INIT_TXN); 256 isNoLocking = !(configManager.getBoolean 257 (EnvironmentParams.ENV_INIT_LOCKING)); 258 if (isTransactional && isNoLocking) { 259 if (TEST_NO_LOCKING_MODE) { 260 isNoLocking = !isTransactional; 261 } else { 262 throw new IllegalArgumentException 263 ("Can't set 'je.env.isNoLocking' and " + 264 "'je.env.isTransactional';"); 265 } 266 } 267 268 directNIO = 269 configManager.getBoolean(EnvironmentParams.LOG_DIRECT_NIO); 270 fairLatches = 271 configManager.getBoolean(EnvironmentParams.ENV_FAIR_LATCHES); 272 isReadOnly = 273 configManager.getBoolean(EnvironmentParams.ENV_RDONLY); 274 isMemOnly = 275 configManager.getBoolean(EnvironmentParams.LOG_MEMORY_ONLY); 276 useSharedLatchesForINs = 277 configManager.getBoolean(EnvironmentParams.ENV_SHARED_LATCHES); 278 adler32ChunkSize = 279 configManager.getInt(EnvironmentParams.ADLER32_CHUNK_SIZE); 280 281 exceptionListener = envConfig.getExceptionListener(); 282 283 288 deferredWriteTemp = 289 configManager.getBoolean( 290 EnvironmentParams.LOG_DEFERREDWRITE_TEMP); 291 292 fileManager = new FileManager(this, envHome, isReadOnly); 293 if (!envConfig.getAllowCreate() && !fileManager.filesExist()) { 294 throw new DatabaseException 295 ("Environment.setAllowCreate is false so environment " + 296 " creation is not permitted, but there is no " + 297 " pre-existing environment in " + envHome); 298 } 299 300 if (fairLatches) { 301 logManager = new LatchedLogManager(this, isReadOnly); 302 } else { 303 logManager = new SyncedLogManager(this, isReadOnly); 304 } 305 306 inMemoryINs = new INList(this); 307 txnManager = new TxnManager(this); 308 309 314 createDaemons(); 315 316 319 dbMapTree = new DbTree(this); 320 321 referenceCount = 0; 322 323 triggerLatch = LatchSupport.makeSharedLatch("TriggerLatch", this); 324 325 329 if (configManager.getBoolean(EnvironmentParams.ENV_RECOVERY)) { 330 331 335 try { 336 RecoveryManager recoveryManager = 337 new RecoveryManager(this); 338 lastRecoveryInfo = recoveryManager.recover(isReadOnly); 339 } finally { 340 try { 341 342 logManager.flush(); 343 fileManager.clear(); 344 } catch (IOException e) { 345 throw new DatabaseException(e.getMessage()); 346 } 347 } 348 } else { 349 isReadOnly = true; 350 noComparators = true; 351 } 352 353 354 envConfigUpdate(configManager); 355 356 360 lockTimeout = 361 PropUtil.microsToMillis(configManager.getLong 362 (EnvironmentParams.LOCK_TIMEOUT)); 363 txnTimeout = 364 PropUtil.microsToMillis(configManager.getLong 365 (EnvironmentParams.TXN_TIMEOUT)); 366 367 368 memoryBudget.initCacheMemoryUsage(); 369 370 371 open(); 372 } catch (DatabaseException e) { 373 374 375 if (fileManager != null) { 376 try { 377 381 fileManager.clear(); 382 fileManager.close(); 383 } catch (IOException IOE) { 384 385 389 } 390 } 391 throw e; 392 } 393 } 394 395 398 public void envConfigUpdate(DbConfigManager mgr) 399 throws DatabaseException { 400 401 runOrPauseDaemons(mgr); 402 403 backgroundReadLimit = mgr.getInt 404 (EnvironmentParams.ENV_BACKGROUND_READ_LIMIT); 405 backgroundWriteLimit = mgr.getInt 406 (EnvironmentParams.ENV_BACKGROUND_WRITE_LIMIT); 407 backgroundSleepInterval = PropUtil.microsToMillis(mgr.getLong 408 (EnvironmentParams.ENV_BACKGROUND_SLEEP_INTERVAL)); 409 } 410 411 414 private void createDaemons() 415 throws DatabaseException { 416 417 418 evictor = new Evictor(this, "Evictor"); 419 420 421 422 426 long checkpointerWakeupTime = 427 Checkpointer.getWakeupPeriod(configManager); 428 checkpointer = new Checkpointer(this, 429 checkpointerWakeupTime, 430 Environment.CHECKPOINTER_NAME); 431 432 433 long compressorWakeupInterval = 434 PropUtil.microsToMillis 435 (configManager.getLong 436 (EnvironmentParams.COMPRESSOR_WAKEUP_INTERVAL)); 437 inCompressor = new INCompressor(this, compressorWakeupInterval, 438 Environment.INCOMP_NAME); 439 440 441 cleaner = new Cleaner(this, Environment.CLEANER_NAME); 442 } 443 444 447 private void runOrPauseDaemons(DbConfigManager mgr) 448 throws DatabaseException { 449 450 if (!isReadOnly) { 451 452 inCompressor.runOrPause 453 (mgr.getBoolean(EnvironmentParams.ENV_RUN_INCOMPRESSOR)); 454 455 456 cleaner.runOrPause 457 (mgr.getBoolean(EnvironmentParams.ENV_RUN_CLEANER) && 458 !isMemOnly); 459 460 464 checkpointer.runOrPause 465 (mgr.getBoolean(EnvironmentParams.ENV_RUN_CHECKPOINTER)); 466 } 467 468 469 evictor.runOrPause 470 (mgr.getBoolean(EnvironmentParams.ENV_RUN_EVICTOR)); 471 } 472 473 479 public INCompressor getINCompressor() { 480 return inCompressor; 481 } 482 483 486 public UtilizationTracker getUtilizationTracker() { 487 return cleaner.getUtilizationTracker(); 488 } 489 490 493 public UtilizationProfile getUtilizationProfile() { 494 return cleaner.getUtilizationProfile(); 495 } 496 497 506 public void updateBackgroundReads(int nReads) { 507 508 512 int limit = backgroundReadLimit; 513 if (limit > 0) { 514 synchronized (backgroundTrackingMutex) { 515 backgroundReadCount += nReads; 516 if (backgroundReadCount >= limit) { 517 backgroundSleepBacklog += 1; 518 519 backgroundReadCount -= limit; 520 assert backgroundReadCount >= 0; 521 } 522 } 523 } 524 } 525 526 539 public void updateBackgroundWrites(int writeSize, int logBufferSize) { 540 541 545 int limit = backgroundWriteLimit; 546 if (limit > 0) { 547 synchronized (backgroundTrackingMutex) { 548 backgroundWriteBytes += writeSize; 549 int writeCount = (int) (backgroundWriteBytes / logBufferSize); 550 if (writeCount >= limit) { 551 backgroundSleepBacklog += 1; 552 553 backgroundWriteBytes -= (limit * logBufferSize); 554 assert backgroundWriteBytes >= 0; 555 } 556 } 557 } 558 } 559 560 573 public void sleepAfterBackgroundIO() { 574 if (backgroundSleepBacklog > 0) { 575 synchronized (backgroundSleepMutex) { 576 577 try { 578 579 Thread.sleep(backgroundSleepInterval); 580 } catch (InterruptedException e) { 581 Thread.currentThread().interrupt(); 582 } 583 584 assert TestHookExecute.doHookIfSet(backgroundSleepHook); 585 } 586 synchronized (backgroundTrackingMutex) { 587 588 if (backgroundSleepBacklog > 0) { 589 backgroundSleepBacklog -= 1; 590 } 591 } 592 } 593 } 594 595 596 public void setBackgroundSleepHook(TestHook hook) { 597 backgroundSleepHook = hook; 598 } 599 600 603 public void logMapTreeRoot() 604 throws DatabaseException { 605 606 mapTreeRootLatch.acquire(); 607 try { 608 mapTreeRootLsn = logManager.log(dbMapTree); 609 } finally { 610 mapTreeRootLatch.release(); 611 } 612 } 613 614 617 public void rewriteMapTreeRoot(long cleanerTargetLsn) 618 throws DatabaseException { 619 620 mapTreeRootLatch.acquire(); 621 try { 622 if (DbLsn.compareTo(cleanerTargetLsn, mapTreeRootLsn) == 0) { 623 624 628 mapTreeRootLsn = logManager.log(dbMapTree); 629 } 630 } finally { 631 mapTreeRootLatch.release(); 632 } 633 } 634 635 638 public long getRootLsn() { 639 return mapTreeRootLsn; 640 } 641 642 645 public void readMapTreeFromLog(long rootLsn) 646 throws DatabaseException { 647 648 dbMapTree = (DbTree) logManager.get(rootLsn); 649 dbMapTree.setEnvironmentImpl(this); 650 651 652 mapTreeRootLatch.acquire(); 653 try { 654 mapTreeRootLsn = rootLsn; 655 } finally { 656 mapTreeRootLatch.release(); 657 } 658 } 659 660 664 public void addToCompressorQueue(BIN bin, 665 Key deletedKey, 666 boolean doWakeup) 667 throws DatabaseException { 668 669 673 if (inCompressor != null) { 674 inCompressor.addBinKeyToQueue(bin, deletedKey, doWakeup); 675 } 676 } 677 678 682 public void addToCompressorQueue(BINReference binRef, 683 boolean doWakeup) 684 throws DatabaseException { 685 686 690 if (inCompressor != null) { 691 inCompressor.addBinRefToQueue(binRef, doWakeup); 692 } 693 } 694 695 699 public void addToCompressorQueue(Collection binRefs, 700 boolean doWakeup) 701 throws DatabaseException { 702 703 707 if (inCompressor != null) { 708 inCompressor.addMultipleBinRefsToQueue(binRefs, doWakeup); 709 } 710 } 711 712 715 public void lazyCompress(IN in) 716 throws DatabaseException { 717 718 722 if (inCompressor != null) { 723 inCompressor.lazyCompress(in); 724 } 725 } 726 727 732 private Logger initLogger(File envHome) 733 throws DatabaseException { 734 735 738 Logger logger = Logger.getAnonymousLogger(); 739 740 744 logger.setUseParentHandlers(false); 745 746 747 Level level = 748 Tracer.parseLevel(this, EnvironmentParams.JE_LOGGING_LEVEL); 749 logger.setLevel(level); 750 751 752 if (configManager.getBoolean(EnvironmentParams.JE_LOGGING_CONSOLE)) { 753 Handler consoleHandler = new ConsoleHandler (); 754 consoleHandler.setLevel(level); 755 logger.addHandler(consoleHandler); 756 } 757 758 759 Handler fileHandler = null; 760 try { 761 if (configManager.getBoolean(EnvironmentParams.JE_LOGGING_FILE)) { 762 763 764 int limit = 765 configManager.getInt(EnvironmentParams. 766 JE_LOGGING_FILE_LIMIT); 767 int count = 768 configManager.getInt(EnvironmentParams. 769 JE_LOGGING_FILE_COUNT); 770 String logFilePattern = envHome + "/" + Tracer.INFO_FILES; 771 772 fileHandler = new FileHandler (logFilePattern, 773 limit, count, true); 774 fileHandler.setFormatter(new SimpleFormatter ()); 775 fileHandler.setLevel(level); 776 logger.addHandler(fileHandler); 777 } 778 } catch (IOException e) { 779 throw new DatabaseException(e.getMessage()); 780 } 781 782 return logger; 783 } 784 785 789 public void enableDebugLoggingToDbLog() 790 throws DatabaseException { 791 792 if (configManager.getBoolean(EnvironmentParams.JE_LOGGING_DBLOG)) { 793 Handler dbLogHandler = new TraceLogHandler(this); 794 Level level = 795 Level.parse(configManager.get(EnvironmentParams. 796 JE_LOGGING_LEVEL)); 797 dbLogHandler.setLevel(level); 798 envLogger.addHandler(dbLogHandler); 799 } 800 } 801 802 805 public void closeLogger() { 806 Handler [] handlers = envLogger.getHandlers(); 807 for (int i = 0; i < handlers.length; i++) { 808 handlers[i].close(); 809 } 810 } 811 812 815 public void open() { 816 envState = DbEnvState.OPEN; 817 } 818 819 823 public void invalidate(RunRecoveryException e) { 824 825 831 savedInvalidatingException = e; 832 envState = DbEnvState.INVALID; 833 requestShutdownDaemons(); 834 } 835 836 public void invalidate(Error e) { 837 savedInvalidatingException = (RunRecoveryException) 838 SAVED_RRE.initCause(e); 839 envState = DbEnvState.INVALID; 840 requestShutdownDaemons(); 841 } 842 843 846 public boolean isOpen() { 847 return (envState == DbEnvState.OPEN); 848 } 849 850 853 public boolean isClosing() { 854 return closing; 855 } 856 857 public boolean isClosed() { 858 return (envState == DbEnvState.CLOSED); 859 } 860 861 865 public boolean mayNotWrite() { 866 return (envState == DbEnvState.INVALID) || 867 (envState == DbEnvState.CLOSED); 868 } 869 870 public void checkIfInvalid() 871 throws RunRecoveryException { 872 873 if (envState == DbEnvState.INVALID) { 874 savedInvalidatingException.setAlreadyThrown(); 875 if (savedInvalidatingException == SAVED_RRE) { 876 savedInvalidatingException.fillInStackTrace(); 877 } 878 throw savedInvalidatingException; 879 } 880 } 881 882 public void checkNotClosed() 883 throws DatabaseException { 884 885 if (envState == DbEnvState.CLOSED) { 886 throw new DatabaseException 887 ("Attempt to use a Environment that has been closed."); 888 } 889 } 890 891 public synchronized void close() 892 throws DatabaseException { 893 894 if (--referenceCount <= 0) { 895 doClose(true); 896 } 897 } 898 899 public synchronized void close(boolean doCheckpoint) 900 throws DatabaseException { 901 902 if (--referenceCount <= 0) { 903 doClose(doCheckpoint); 904 } 905 } 906 907 private void doClose(boolean doCheckpoint) 908 throws DatabaseException { 909 910 StringBuffer errors = new StringBuffer (); 911 912 try { 913 Tracer.trace(Level.FINE, this, 914 "Close of environment " + 915 envHome + " started"); 916 917 try { 918 envState.checkState(DbEnvState.VALID_FOR_CLOSE, 919 DbEnvState.CLOSED); 920 } catch (DatabaseException DBE) { 921 throw DBE; 922 } 923 924 928 requestShutdownDaemons(); 929 930 931 if (doCheckpoint && 932 !isReadOnly && 933 (envState != DbEnvState.INVALID) && 934 logManager.getLastLsnAtRecovery() != 935 fileManager.getLastUsedLsn()) { 936 937 945 CheckpointConfig ckptConfig = new CheckpointConfig(); 946 ckptConfig.setForce(true); 947 ckptConfig.setMinimizeRecoveryTime(true); 948 try { 949 invokeCheckpoint 950 (ckptConfig, 951 false, "close"); 953 } catch (DatabaseException IE) { 954 errors.append("\nException performing checkpoint: "); 955 errors.append(IE.toString()).append("\n"); 956 } 957 } 958 959 try { 960 shutdownDaemons(); 961 } catch (InterruptedException IE) { 962 errors.append("\nException shutting down daemon threads: "); 963 errors.append(IE.toString()).append("\n"); 964 } 965 966 967 Tracer.trace(Level.FINE, this, 968 "Env " + envHome + " daemons shutdown"); 969 try { 970 logManager.flush(); 971 } catch (DatabaseException DBE) { 972 errors.append("\nException flushing log manager: "); 973 errors.append(DBE.toString()).append("\n"); 974 } 975 976 try { 977 fileManager.clear(); 978 } catch (IOException IOE) { 979 errors.append("\nException clearing file manager: "); 980 errors.append(IOE.toString()).append("\n"); 981 } catch (DatabaseException DBE) { 982 errors.append("\nException clearing file manager: "); 983 errors.append(DBE.toString()).append("\n"); 984 } 985 986 try { 987 fileManager.close(); 988 } catch (IOException IOE) { 989 errors.append("\nException clearing file manager: "); 990 errors.append(IOE.toString()).append("\n"); 991 } catch (DatabaseException DBE) { 992 errors.append("\nException clearing file manager: "); 993 errors.append(DBE.toString()).append("\n"); 994 } 995 996 try { 997 inMemoryINs.clear(); 998 } catch (DatabaseException DBE) { 999 errors.append("\nException closing file manager: "); 1000 errors.append(DBE.toString()).append("\n"); 1001 } 1002 1003 closeLogger(); 1004 1005 DbEnvPool.getInstance().remove(envHome); 1006 1007 try { 1008 checkLeaks(); 1009 LatchSupport.clearNotes(); 1010 } catch (DatabaseException DBE) { 1011 errors.append("\nException performing validity checks: "); 1012 errors.append(DBE.toString()).append("\n"); 1013 } 1014 } finally { 1015 envState = DbEnvState.CLOSED; 1016 } 1017 1018 if (errors.length() > 0 && 1019 savedInvalidatingException == null) { 1020 1021 1022 throw new RunRecoveryException(this, errors.toString()); 1023 } 1024 } 1025 1026 1031 public synchronized void closeAfterRunRecovery() 1032 throws DatabaseException { 1033 1034 try { 1035 shutdownDaemons(); 1036 } catch (InterruptedException IE) { 1037 1038 } 1039 1040 try { 1041 fileManager.clear(); 1042 } catch (Exception e) { 1043 1044 } 1045 1046 try { 1047 fileManager.close(); 1048 } catch (Exception e) { 1049 1050 } 1051 1052 DbEnvPool.getInstance().remove(envHome); 1053 } 1054 1055 public synchronized void forceClose() 1056 throws DatabaseException { 1057 1058 referenceCount = 1; 1059 close(); 1060 } 1061 1062 public synchronized void incReferenceCount() { 1063 referenceCount++; 1064 } 1065 1066 public static int getThreadLocalReferenceCount() { 1067 return threadLocalReferenceCount; 1068 } 1069 1070 public static synchronized void incThreadLocalReferenceCount() { 1071 threadLocalReferenceCount++; 1072 } 1073 1074 public static synchronized void decThreadLocalReferenceCount() { 1075 threadLocalReferenceCount--; 1076 } 1077 1078 public static boolean getNoComparators() { 1079 return noComparators; 1080 } 1081 1082 1085 private void checkLeaks() 1086 throws DatabaseException { 1087 1088 1089 if (!configManager.getBoolean(EnvironmentParams.ENV_CHECK_LEAKS)) { 1090 return; 1091 } 1092 1093 boolean clean = true; 1094 StatsConfig statsConfig = new StatsConfig(); 1095 1096 1097 statsConfig.setFast(false); 1098 1099 LockStats lockStat = lockStat(statsConfig); 1100 if (lockStat.getNTotalLocks() != 0) { 1101 clean = false; 1102 System.out.println("Problem: " + lockStat.getNTotalLocks() + 1103 " locks left"); 1104 txnManager.getLockManager().dump(); 1105 } 1106 1107 TransactionStats txnStat = txnStat(statsConfig); 1108 if (txnStat.getNActive() != 0) { 1109 clean = false; 1110 System.out.println("Problem: " + txnStat.getNActive() + 1111 " txns left"); 1112 TransactionStats.Active[] active = txnStat.getActiveTxns(); 1113 if (active != null) { 1114 for (int i = 0; i < active.length; i += 1) { 1115 System.out.println(active[i]); 1116 } 1117 } 1118 } 1119 1120 if (LatchSupport.countLatchesHeld() > 0) { 1121 clean = false; 1122 System.out.println("Some latches held at env close."); 1123 LatchSupport.dumpLatchesHeld(); 1124 } 1125 1126 assert clean: 1127 "Lock, transaction, or latch left behind at environment close"; 1128 } 1129 1130 1134 public boolean invokeCheckpoint(CheckpointConfig config, 1135 boolean flushAll, 1136 String invokingSource) 1137 throws DatabaseException { 1138 1139 if (checkpointer != null) { 1140 checkpointer.doCheckpoint(config, flushAll, invokingSource); 1141 return true; 1142 } else { 1143 return false; 1144 } 1145 } 1146 1147 1151 public long forceLogFileFlip() 1152 throws DatabaseException { 1153 1154 Tracer newRec = new Tracer("File Flip"); 1155 return logManager.logForceFlip(newRec); 1156 } 1157 1158 1162 public boolean invokeCompressor() 1163 throws DatabaseException { 1164 1165 if (inCompressor != null) { 1166 inCompressor.doCompress(); 1167 return true; 1168 } else { 1169 return false; 1170 } 1171 } 1172 1173 public void invokeEvictor() 1174 throws DatabaseException { 1175 1176 if (evictor != null) { 1177 evictor.doEvict(Evictor.SOURCE_MANUAL); 1178 } 1179 } 1180 1181 public int invokeCleaner() 1182 throws DatabaseException { 1183 1184 if (cleaner != null) { 1185 return cleaner.doClean(true, false); } else { 1188 return 0; 1189 } 1190 } 1191 1192 private void requestShutdownDaemons() { 1193 1194 closing = true; 1195 1196 if (inCompressor != null) { 1197 inCompressor.requestShutdown(); 1198 } 1199 1200 if (evictor != null) { 1201 evictor.requestShutdown(); 1202 } 1203 1204 if (checkpointer != null) { 1205 checkpointer.requestShutdown(); 1206 } 1207 1208 if (cleaner != null) { 1209 cleaner.requestShutdown(); 1210 } 1211 } 1212 1213 1216 private void shutdownDaemons() 1217 throws InterruptedException { 1218 1219 shutdownINCompressor(); 1220 1221 1225 shutdownCleaner(); 1226 shutdownCheckpointer(); 1227 1228 1233 shutdownEvictor(); 1234 } 1235 1236 1239 public void shutdownINCompressor() 1240 throws InterruptedException { 1241 1242 if (inCompressor != null) { 1243 inCompressor.shutdown(); 1244 1245 1249 inCompressor.clearEnv(); 1250 inCompressor = null; 1251 } 1252 return; 1253 } 1254 1255 public void shutdownEvictor() 1256 throws InterruptedException { 1257 1258 if (evictor != null) { 1259 evictor.shutdown(); 1260 1261 1265 evictor.clearEnv(); 1266 evictor = null; 1267 } 1268 return; 1269 } 1270 1271 void shutdownCheckpointer() 1272 throws InterruptedException { 1273 1274 if (checkpointer != null) { 1275 checkpointer.shutdown(); 1276 1277 1281 checkpointer.clearEnv(); 1282 checkpointer = null; 1283 } 1284 return; 1285 } 1286 1287 1290 public void shutdownCleaner() 1291 throws InterruptedException { 1292 1293 if (cleaner != null) { 1294 cleaner.shutdown(); 1295 1296 1301 } 1302 return; 1303 } 1304 1305 public boolean isNoLocking() { 1306 return isNoLocking; 1307 } 1308 1309 public boolean isTransactional() { 1310 return isTransactional; 1311 } 1312 1313 public boolean isReadOnly() { 1314 return isReadOnly; 1315 } 1316 1317 public boolean isMemOnly() { 1318 return isMemOnly; 1319 } 1320 1321 public static boolean getFairLatches() { 1322 return fairLatches; 1323 } 1324 1325 public static boolean getSharedLatches() { 1326 return useSharedLatchesForINs; 1327 } 1328 1329 public boolean getDeferredWriteTemp() { 1330 return deferredWriteTemp; 1331 } 1332 1333 public boolean useDirectNIO() { 1334 return directNIO; 1335 } 1336 1337 public static int getAdler32ChunkSize() { 1338 return adler32ChunkSize; 1339 } 1340 1341 1342 public DatabaseImpl createDb(Locker locker, 1343 String databaseName, 1344 DatabaseConfig dbConfig, 1345 Database databaseHandle) 1346 throws DatabaseException { 1347 1348 return dbMapTree.createDb(locker, 1349 databaseName, 1350 dbConfig, 1351 databaseHandle); 1352 } 1353 1354 1361 public DatabaseImpl getDb(Locker locker, 1362 String databaseName, 1363 Database databaseHandle) 1364 throws DatabaseException { 1365 1366 return dbMapTree.getDb(locker, databaseName, databaseHandle); 1367 } 1368 1369 public List getDbNames() 1370 throws DatabaseException { 1371 1372 return dbMapTree.getDbNames(); 1373 } 1374 1375 1378 public void dumpMapTree() 1379 throws DatabaseException { 1380 1381 dbMapTree.dump(); 1382 } 1383 1384 1387 public void dbRename(Locker locker, String databaseName, String newName) 1388 throws DatabaseException { 1389 1390 dbMapTree.dbRename(locker, databaseName, newName); 1391 } 1392 1393 1396 public void dbRemove(Locker locker, String databaseName) 1397 throws DatabaseException { 1398 1399 dbMapTree.dbRemove(locker, databaseName); 1400 } 1401 1402 1407 public TruncateResult truncate(Locker locker, 1408 DatabaseImpl database) 1409 throws DatabaseException { 1410 1411 return dbMapTree.truncate(locker, database, true); 1412 } 1413 1414 1417 public long truncate(Locker locker, 1418 String databaseName, 1419 boolean returnCount) 1420 throws DatabaseException { 1421 1422 return dbMapTree.truncate(locker, databaseName, returnCount); 1423 } 1424 1425 1428 public Txn txnBegin(Transaction parent, TransactionConfig txnConfig) 1429 throws DatabaseException { 1430 1431 if (!isTransactional) { 1432 throw new DatabaseException("beginTransaction called, " + 1433 " but Environment was not opened "+ 1434 "with transactional cpabilities"); 1435 } 1436 1437 return txnManager.txnBegin(parent, txnConfig); 1438 } 1439 1440 1441 public LogManager getLogManager() { 1442 return logManager; 1443 } 1444 1445 public FileManager getFileManager() { 1446 return fileManager; 1447 } 1448 1449 public DbTree getDbMapTree() { 1450 return dbMapTree; 1451 } 1452 1453 1462 public DbConfigManager getConfigManager() { 1463 return configManager; 1464 } 1465 1466 1469 public EnvironmentConfig cloneConfig() { 1470 return DbInternal.cloneConfig(configManager.getEnvironmentConfig()); 1471 } 1472 1473 1476 public EnvironmentMutableConfig cloneMutableConfig() { 1477 return DbInternal.cloneMutableConfig 1478 (configManager.getEnvironmentConfig()); 1479 } 1480 1481 1484 public void checkImmutablePropsForEquality(EnvironmentConfig config) 1485 throws IllegalArgumentException { 1486 1487 DbInternal.checkImmutablePropsForEquality 1488 (configManager.getEnvironmentConfig(), config); 1489 } 1490 1491 1495 public synchronized void setMutableConfig(EnvironmentMutableConfig config) 1496 throws DatabaseException { 1497 1498 1499 EnvironmentConfig newConfig = 1500 DbInternal.cloneConfig(configManager.getEnvironmentConfig()); 1501 1502 1503 DbInternal.copyMutablePropsTo(config, newConfig); 1504 1505 1515 configManager = new DbConfigManager(newConfig); 1516 for (int i = configObservers.size() - 1; i >= 0; i -= 1) { 1517 EnvConfigObserver o = (EnvConfigObserver) configObservers.get(i); 1518 o.envConfigUpdate(configManager); 1519 } 1520 } 1521 1522 public void setExceptionListener(ExceptionListener exceptionListener) { 1523 1524 this.exceptionListener = exceptionListener; 1525 } 1526 1527 public ExceptionListener getExceptionListener() { 1528 return exceptionListener; 1529 } 1530 1531 1534 public synchronized void addConfigObserver(EnvConfigObserver o) { 1535 configObservers.add(o); 1536 } 1537 1538 1541 public synchronized void removeConfigObserver(EnvConfigObserver o) { 1542 configObservers.remove(o); 1543 } 1544 1545 public INList getInMemoryINs() { 1546 return inMemoryINs; 1547 } 1548 1549 public TxnManager getTxnManager() { 1550 return txnManager; 1551 } 1552 1553 public Checkpointer getCheckpointer() { 1554 return checkpointer; 1555 } 1556 1557 public Cleaner getCleaner() { 1558 return cleaner; 1559 } 1560 1561 public MemoryBudget getMemoryBudget() { 1562 return memoryBudget; 1563 } 1564 1565 1568 public Logger getLogger() { 1569 return envLogger; 1570 } 1571 1572 1575 public boolean verify(VerifyConfig config, PrintStream out) 1576 throws DatabaseException { 1577 1578 1579 return dbMapTree.verify(config, out); 1580 } 1581 1582 public void verifyCursors() 1583 throws DatabaseException { 1584 1585 inCompressor.verifyCursors(); 1586 } 1587 1588 1591 1592 1595 synchronized public EnvironmentStats loadStats(StatsConfig config) 1596 throws DatabaseException { 1597 1598 EnvironmentStats stats = new EnvironmentStats(); 1599 inCompressor.loadStats(config, stats); 1600 evictor.loadStats(config, stats); 1601 checkpointer.loadStats(config, stats); 1602 cleaner.loadStats(config, stats); 1603 logManager.loadStats(config, stats); 1604 memoryBudget.loadStats(config, stats); 1605 return stats; 1606 } 1607 1608 1611 synchronized public LockStats lockStat(StatsConfig config) 1612 throws DatabaseException { 1613 1614 return txnManager.lockStat(config); 1615 } 1616 1617 1620 synchronized public TransactionStats txnStat(StatsConfig config) 1621 throws DatabaseException { 1622 1623 return txnManager.txnStat(config); 1624 } 1625 1626 public int getINCompressorQueueSize() 1627 throws DatabaseException { 1628 1629 return inCompressor.getBinRefQueueSize(); 1630 } 1631 1632 1635 public RecoveryInfo getLastRecoveryInfo() { 1636 return lastRecoveryInfo; 1637 } 1638 1639 1642 public File getEnvironmentHome() { 1643 return envHome; 1644 } 1645 1646 public long getTxnTimeout() { 1647 return txnTimeout; 1648 } 1649 1650 public long getLockTimeout() { 1651 return lockTimeout; 1652 } 1653 1654 1657 public SharedLatch getTriggerLatch() { 1658 return triggerLatch; 1659 } 1660 1661 public Evictor getEvictor() { 1662 return evictor; 1663 } 1664 1665 void alertEvictor() { 1666 if (evictor != null) { 1667 evictor.alert(); 1668 } 1669 } 1670 1671 1674 public boolean isReplicated() { 1675 return isReplicated; 1676 } 1677 1678 public ReplicatorInstance getReplicator() { 1679 throw new NotImplementedYetException(); 1680 } 1681 1682 public void setReplicator(ReplicatorInstance repInstance) { 1683 this.repInstance = repInstance; 1684 } 1685 1686 1689 public static boolean maybeForceYield() { 1690 if (forcedYield) { 1691 Thread.yield(); 1692 } 1693 return true; } 1695} 1696 | Popular Tags |