📄 basedatafilefactory.java
字号:
//lock still we send out a warning. int exLockStatus = StorageFile.NO_FILE_LOCK_SUPPORT ; //If user has chosen to force lock option don't bother //about applying exclusive file lock mechanism if(!throwDBlckException) { exFileLock = storageFactory.newStorageFile( DB_EX_LOCKFILE_NAME); exLockStatus = exFileLock.getExclusiveFileLock(); } if(exLockStatus == StorageFile.NO_FILE_LOCK_SUPPORT) { if (fileLockExisted && !throwDBlckException) { StandardException multipleJBMSWarning = StandardException.newException( SQLState.DATA_MULTIPLE_JBMS_WARNING, args); String warningMsg = MessageService.getCompleteMessage(SQLState.DATA_MULTIPLE_JBMS_WARNING, args); logMsg(warningMsg); // RESOLVE - need warning support. Output to // system.err.println rather than just send warning message to db2j.LOG System.err.println(warningMsg); } } // filelock is unreliable, but we should at least leave a file // there to warn the next person try { // the existing fileLockOnDB file descriptor may already be // deleted by the delete call, close it and create the file again if(fileLockOnDB != null) fileLockOnDB.close(); fileLockOnDB = fileLock.getRandomAccessFile( "rw"); fileLockOnDB.writeUTF(myUUID.toString()); // write it out for future reference fileLockOnDB.sync( false); fileLockOnDB.close(); } catch (IOException ioe) { try { fileLockOnDB.close(); } catch (IOException ioe2) { /* did the best I could */ } } finally { fileLockOnDB = null; } if (fileLockExisted && throwDBlckException) { // user has chosen that we always throw exception, throw it // now that we have reinstated the lock file. throw StandardException.newException( SQLState.DATA_MULTIPLE_JBMS_FORCE_LOCK, args); } if(exLockStatus == StorageFile.EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE) { throw StandardException.newException( SQLState.DATA_MULTIPLE_JBMS_ON_DB, databaseDirectory); } } } // end of privGetJBMSLockOnDB private void releaseJBMSLockOnDB() { if (isReadOnly()) return; synchronized( this) { actionCode = RELEASE_LOCK_ON_DB_ACTION; try { AccessController.doPrivileged( this); } catch (PrivilegedActionException pae) { // do nothing - it may be read only medium, who knows what the // problem is } finally { fileLockOnDB = null; } } } private void privReleaseJBMSLockOnDB() throws IOException { if (fileLockOnDB != null) fileLockOnDB.close(); if( storageFactory != null) { StorageFile fileLock = storageFactory.newStorageFile(DB_LOCKFILE_NAME); fileLock.delete(); } //release the lock that is acquired using tryLock() to prevent //multiple jvm booting the same database on Unix environments. if(exFileLock != null) exFileLock.releaseExclusiveFileLock(); return; } // end of privReleaseJBMSLockOnDB private void logMsg(String msg) { if (istream == null) { istream = Monitor.getStream(); } istream.println(msg); } public final boolean databaseEncrypted() { return databaseEncrypted; } public int encrypt(byte[] cleartext, int offset, int length, byte[] ciphertext, int outputOffset) throws StandardException { return rawStoreFactory.encrypt(cleartext, offset, length, ciphertext, outputOffset); } public int decrypt(byte[] ciphertext, int offset, int length, byte[] cleartext, int outputOffset) throws StandardException { return rawStoreFactory.decrypt(ciphertext, offset, length, cleartext, outputOffset); } /** Returns the encryption block size used by the algorithm at time of creation of an encrypted database */ public int getEncryptionBlockSize() { return rawStoreFactory.getEncryptionBlockSize(); } public String getVersionedName(String name, long generationId) { return name.concat(".G".concat(Long.toString(generationId))); } /** * Return an id which can be used to create a container. * <p> * Return an id number with is greater than any existing container * in the current database. Caller will use this to allocate future * container numbers - most likely caching the value and then incrementing * it as it is used. * <p> * * @return The an id which can be used to create a container. * * @exception StandardException Standard exception policy. **/ public long getMaxContainerId() throws StandardException { return(findMaxContainerId()); } synchronized long getNextId() { return nextContainerId++; } /** return a secure random number */ int random() { return databaseEncrypted ? rawStoreFactory.random() : 0; } /** Add a file to the list of files to be removed post recovery. */ void fileToRemove( StorageFile file, boolean remove) { if (postRecoveryRemovedFiles == null) postRecoveryRemovedFiles = new Hashtable(); String path = null; synchronized( this) { actionCode = GET_PATH_ACTION; actionFile = file; try { path = (String) AccessController.doPrivileged( this); } catch( PrivilegedActionException pae) {} // GET_PATH does not throw an exception finally { actionFile = null; } } if (remove) // to be removed postRecoveryRemovedFiles.put(path, file); else postRecoveryRemovedFiles.remove(path); } /** Called after recovery is performed. @exception StandardException Standard Cloudscape Error Policy */ public void postRecovery() throws StandardException { // hook up the cache cleaner daemon after recovery is finished DaemonService daemon = rawStoreFactory.getDaemon(); if (daemon == null) return; containerCache.useDaemonService(daemon); pageCache.useDaemonService(daemon); if (postRecoveryRemovedFiles != null) { synchronized( this) { actionCode = POST_RECOVERY_REMOVE_ACTION; try { AccessController.doPrivileged( this); } catch( PrivilegedActionException pae){} // POST_RECOVERY_REMOVE does not throw an exception } postRecoveryRemovedFiles = null; } } public void freezePersistentStore() throws StandardException { synchronized(freezeSemaphore) { if (isFrozen) { throw StandardException.newException( SQLState.RAWSTORE_NESTED_FREEZE); } // set this to true first to stop all writes from starting after // this. isFrozen = true; // wait for all in progress write to finish try { while(writersInProgress > 0) { try { freezeSemaphore.wait(); } catch (InterruptedException ie) { // make sure we are not stuck in frozen state if we // caught an interrupt exception and the calling // thread may not have a chance to call unfreeze isFrozen = false; freezeSemaphore.notifyAll(); throw StandardException.interrupt(ie); } } } catch (RuntimeException rte) { // make sure we are not stuck in frozen state if we // caught a run time exception and the calling thread may not // have a chance to call unfreeze isFrozen = false; freezeSemaphore.notifyAll(); throw rte; // rethrow run time exception } if (SanityManager.DEBUG) SanityManager.ASSERT(writersInProgress == 0 && isFrozen == true, "data store is not properly frozen"); } } public void unfreezePersistentStore() { synchronized(freezeSemaphore) { isFrozen = false; freezeSemaphore.notifyAll(); } } public void writeInProgress() throws StandardException { synchronized(freezeSemaphore) { // do not start write, the persistent store is frozen while(isFrozen) { try { freezeSemaphore.wait(); } catch (InterruptedException ie) { throw StandardException.interrupt(ie); } } // store is not frozen, proceed to write - do this last writersInProgress++; } } public void writeFinished() { synchronized(freezeSemaphore) { if (SanityManager.DEBUG) SanityManager.ASSERT(writersInProgress > 0, "no writers in progress"); writersInProgress--; freezeSemaphore.notifyAll(); // wake up the freezer } } /** * removes the data directory(seg*) from database home directory and * restores it from backup location. * This function gets called only when any of the folling attributes * are specified on connection URL: * Attribute.CREATE_FROM (Create database from backup if it does not exist) * Attribute.RESTORE_FROM (Delete the whole database if it exists and then restore * it from backup) * Attribute.ROLL_FORWARD_RECOVERY_FROM:(Perform Rollforward Recovery; * except for the log directory everthing else is replced by the copy from * backup. log files in the backup are copied to the existing online log directory. * * In all the cases, data directory(seg*) is replaced by the data directory * directory from backup when this function is called. */ private void restoreDataDirectory(String backupPath) throws StandardException { File bsegdir; //segment directory in the backup File backupRoot = new java.io.File(backupPath); //root dir of backup db /* To be safe we first check if the backup directory exist and it has * atleast one seg* directory before removing the current data directory. * * This will fail with a security exception unless the database engine and all * its callers have permission to read the backup directory. */ String[] bfilelist = backupRoot.list(); if(bfilelist !=null) { boolean segmentexist = false; for (int i = 0; i < bfilelist.length; i++) { //check if it is a seg* directory if(bfilelist[i].startsWith("seg")) { bsegdir = new File(backupRoot , bfilelist[i]); if(bsegdir.exists() && bsegdir.isDirectory()) { segmentexist = true; break; } } } if(!segmentexist) throw StandardException.newException(SQLState.DATA_DIRECTORY_NOT_FOUND_IN_BACKUP, backupRoot); }else{ throw StandardException.newException(SQLState.DATA_DIRECTORY_NOT_FOUND_IN_BACKUP, backupRoot); } synchronized( this) { actionCode = RESTORE_DATA_DIRECTORY_ACTION; this.backupPath = backupPath; this.backupRoot = backupRoot; this.bfilelist = bfilelist; try { AccessController.doPrivileged( this); } catch( PrivilegedActionException pae){ throw (StandardException) pae.getException();} finally { this.backupPath = null; this.backupRoot = null; this.bfilelist = null; } } } private void privRestoreDataDirectory() throws StandardException { StorageFile csegdir; //segement directory in th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -