|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectcom.bigdata.resources.ResourceEvents
com.bigdata.resources.StoreManager
public abstract class StoreManager
Class encapsulates logic for managing the store files (journals and index segments), including the logic to compute the effective release time for the managed resources and to release those resources by deleting them from the file system.
ResourceManager or it will leave its files around., BufferMode.Temporary is not supported (verify whether the
Transient mode is supported)., If we approach the limit on free space for the dataDir then we
need to shed index partitions to other data services or potentially
become more aggressive in releasing old resources. See
#getDataDirFreeSpace(File)| Nested Class Summary | |
|---|---|
static interface |
StoreManager.IStoreManagerCounters
Performance counters for the StoreManager. |
class |
StoreManager.ManagedJournal
The StoreManager.ManagedJournal provides the backing store used to absorb
writes and retain history for the scale-out architecture. |
static interface |
StoreManager.Options
Options for the StoreManager. |
| Field Summary | |
|---|---|
protected long |
accelerateOverflowThreshold
|
protected AtomicLong |
bytesDeleted
The #of bytes that have been deleted since startup. |
protected AtomicLong |
bytesUnderManagement
The #of bytes currently under management EXCEPT those on the live journal. |
protected File |
dataDir
The directory in which the data files reside. |
protected ReentrantReadWriteLock |
indexCacheLock
In order to have atomic semantics and prevent a read-historical operation from starting concurrently that would have access to a view that is being purged, IndexManager.getIndex(String, long) and
purgeOldResources() MUST contend for a shared lock. |
protected AtomicLong |
journalBytesUnderManagement
|
protected AtomicLong |
journalDeleteCount
The #of StoreManager.ManagedJournals that have been deleted to date. |
protected AtomicLong |
journalReopenCount
The #of StoreManager.ManagedJournals that have been (re-)opened to date. |
protected File |
journalsDir
Directory containing the journal resources. |
protected long |
lastCommitTimePreserved
The last value computed by #getEffectiveReleaseTime() and ZERO(0)
until a value has been calculated. |
protected long |
lastOverflowTime
The last commit time corresponding to the last synchronous overflow event and ZERO (0L) until there has been a synchronous overflow event. |
protected AtomicReference<StoreManager.ManagedJournal> |
liveJournalRef
A atomic hard reference to the live journal. |
protected static org.apache.log4j.Logger |
log
Logger. |
protected long |
maximumJournalSizeAtOverflow
The observed maximum size of a journal (its length in bytes) as measured at each synchronous overflow event. |
protected long |
purgeResourcesMillis
The elapsed #of milliseconds in purgeOldResources() |
protected ResourceService |
resourceService
|
protected AtomicLong |
segmentBytesUnderManagement
|
protected File |
segmentsDir
Directory containing the index segment resources. |
protected AtomicLong |
segmentStoreDeleteCount
The #of IndexSegmentStores that have been deleted to date. |
protected AtomicLong |
segmentStoreReopenCount
The #of IndexSegmentStores that have been (re-)opened to date. |
protected ConcurrentWeakValueCacheWithTimeout<UUID,IRawStore> |
storeCache
A cache that is used by the to automatically close out unused IndexSegmentStores. |
protected File |
tmpDir
The directory in which the temporary files will reside. |
| Constructor Summary | |
|---|---|
protected |
StoreManager(Properties properties)
Note: This constructor starts an asynchronous thread that scans the data directory for journals and index segments and creates the initial journal if no store files are found. |
| Method Summary | |
|---|---|
protected void |
addResource(IResourceMetadata resourceMetadata,
File file)
Notify the resource manager of a new resource. |
protected void |
assertNotOpen()
|
protected void |
assertOpen()
|
protected void |
assertRunning()
Succeeds if the StoreManager isOpen() and is NOT
isStarting() (the test itself is NOT atomic). |
boolean |
awaitRunning()
Return true iff the StoreManager is running. |
protected void |
deleteResource(UUID uuid,
boolean isJournal)
Delete the resource in the file system and remove it from the storeCache and resourceFiles and either
journalIndex or segmentIndex as appropriate. |
void |
deleteResources()
Deletes all resources. |
long |
getBytesUnderManagement()
The #of bytes currently under management, including those written on the live journal. |
protected long |
getCommitTimeStrictlyGreaterThan(long releaseTime)
Finds the journal spanning the first ICommitRecord that is
strictly greater than the specified timestamp and returns the timestamp
of that ICommitRecord. |
abstract IConcurrencyManager |
getConcurrencyManager()
The object used to control access to the index resources. |
File |
getDataDir()
Note: The returned File is in canonical form. |
long |
getDataDirFreeSpace()
The #of bytes of free space remaining on the volume hosting the dataDir. |
protected abstract long |
getIndexRetentionTime()
|
File |
getIndexSegmentFile(IndexMetadata indexMetadata)
Return the file on which a new IndexSegment should be written. |
File |
getIndexSegmentFile(String scaleOutIndexName,
UUID indexUUID,
int partitionId)
Return the file on which a new IndexSegment should be written. |
AbstractJournal |
getJournal(long timestamp)
Return the reference to the journal which has the most current data for the given timestamp. |
long |
getJournalBytesUnderManagement()
The #of bytes in StoreManager.ManagedJournals, including those written on the
live journal. |
StoreManager.ManagedJournal |
getLiveJournal()
The journal on which writes are made. |
int |
getManagedJournalCount()
The #of journals on hand. |
int |
getManagedSegmentCount()
The #of index segments on hand. |
Properties |
getProperties()
An object wrapping the Properties given to the ctor. |
long |
getReleaseTime()
Return the last value set with setReleaseTime(long). |
int |
getResourceServicePort()
The port at which you can connect to the ResourceService. |
protected Set<UUID> |
getResourcesForTimestamp(long commitTimeToPreserve)
Finds all resources used by any registered index as of the commitTimeToPreserve up to and including the lastCommitTime for the live journal. |
long |
getSegmentBytesUnderManagement()
The #of bytes in managed IndexSegmentStores. |
int |
getStoreCacheSize()
The #of entries in the hard reference cache for IRawStores,
including both StoreManager.ManagedJournals and IndexSegment}s. |
DiskOnlyStrategy.StoreCounters |
getStoreCounters()
The performance counters for the IBufferStrategy backing the live
journal and any historical journals which are concurrently open with the
live journal. |
long |
getTempDirFreeSpace()
The #of bytes of free space remaining on the volume hosting the tmpDir. |
File |
getTmpDir()
The directory for temporary files. |
boolean |
isOpen()
false initially and remains false until
#start() completes successfully. |
boolean |
isRunning()
Return true iff the StoreManager is open and
startup processing has been completed. |
boolean |
isStarting()
true initially and until #start() completes
successfully. |
boolean |
isTransient()
Return true iff data can not be made restart-safe. |
static String |
munge(String s)
Munge a name index so that it is suitable for use in a filesystem. |
protected ResourceFileFilter |
newFileFilter()
Returns a filter that is used to recognize files that are managed by this class. |
protected long |
nextTimestamp()
Report the next timestamp assigned by the ITransactionService. |
IRawStore |
openStore(UUID uuid)
Opens an IRawStore. |
protected void |
overrideJournalExtent(Properties p)
When the StoreManager is relatively new (as measured by the #of
bytes under management) we discount the journal extent in order to
trigger overflow earlier. |
protected PurgeResult |
purgeOldResources()
Identify and delete resources no longer required by the index views from the current releaseTime up to the lastCommitTime. |
boolean |
purgeOldResources(long timeout,
boolean truncateJournal)
This attempts to obtain the exclusive lock for the WriteExecutorService. |
protected void |
retentionSetAdd(UUID uuid)
Add an IndexSegment to the set of IndexSegments which
have been generated but not yet incorporated into an index partition view
and hence we must take special cautions to prevent their release. |
protected void |
retentionSetRemove(UUID uuid)
Remove an IndexSegment from the retentionSet. |
abstract void |
setConcurrencyManager(IConcurrencyManager concurrencyManager)
|
void |
setReleaseTime(long releaseTime)
Updates the releaseTime. |
void |
shutdown()
The service will no longer accept new requests, but existing requests will be processed (sychronous). |
void |
shutdownNow()
The service will no longer accept new requests and will make a best effort attempt to terminate all existing requests and return ASAP. |
| Methods inherited from class com.bigdata.resources.ResourceEvents |
|---|
closeJournal, closeTx, closeUnisolatedBTree, deleteJournal, dropUnisolatedBTree, extendJournal, isolateIndex, openJournal, openTx, openUnisolatedBTree |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Methods inherited from interface com.bigdata.journal.IResourceManager |
|---|
getCounters, getDataService, getDataServiceUUID, getFederation, getIndex, getIndexPartitionGone, getIndexSources, getIndexSources, isOverflowEnabled, overflow, shouldOverflow |
| Field Detail |
|---|
protected static final org.apache.log4j.Logger log
protected final File dataDir
Note: It is a hard requirement that each resource is located by the
path relative to the dataDir.
StoreManager.Options.DATA_DIR,
IResourceMetadata.getFile()protected final File journalsDir
protected final File segmentsDir
protected final File tmpDir
Options.TMP_DIRprotected final ConcurrentWeakValueCacheWithTimeout<UUID,IRawStore> storeCache
IndexSegmentStores. An IndexSegment that is no longer
used will have its reference cleared when it is swept by the garbage
collector and will automatically release all of its buffers (node and
leaf cache, etc). However, at that point the IndexSegmentStore is
still open, and it can buffer a significant amount of data in addition to
the file handle.
When the weak reference is cleared we know that there are no longer any
hard references to the IndexSegment and hence the corresponding
IndexSegmentStore should be closed. In fact, we can immediately
remove the IndexSegmentStore from the cache of open stores and
then close the store. At this point if the store is re-opened it will be
a new object. This is easy enough to do since the UUID of the
IndexSegmentStore is the key in our map!
StoreManager.Options.STORE_CACHE_CAPACITY,
StoreManager.Options.STORE_CACHE_TIMEOUTprotected final AtomicReference<StoreManager.ManagedJournal> liveJournalRef
protected ResourceService resourceService
protected final long accelerateOverflowThreshold
StoreManager.Options.ACCELERATE_OVERFLOW_THRESHOLDprotected long purgeResourcesMillis
purgeOldResources()
protected long lastCommitTimePreserved
#getEffectiveReleaseTime() and ZERO(0)
until a value has been calculated.
protected long lastOverflowTime
protected long maximumJournalSizeAtOverflow
protected final AtomicLong journalReopenCount
StoreManager.ManagedJournals that have been (re-)opened to date.
protected final AtomicLong segmentStoreReopenCount
IndexSegmentStores that have been (re-)opened to date.
protected final AtomicLong journalDeleteCount
StoreManager.ManagedJournals that have been deleted to date.
protected final AtomicLong segmentStoreDeleteCount
IndexSegmentStores that have been deleted to date.
protected final AtomicLong bytesUnderManagement
addResource(IResourceMetadata, File) and decremented each
time a resource is deleted.
protected final AtomicLong journalBytesUnderManagement
protected final AtomicLong segmentBytesUnderManagement
protected final AtomicLong bytesDeleted
protected final ReentrantReadWriteLock indexCacheLock
IndexManager.getIndex(String, long) and
purgeOldResources() MUST contend for a shared lock.
This is a ReentrantReadWriteLock since concurrent getIndex()
requests can proceed as long as purgeOldResources()
is not running. Also note that contention is not required for
ITx.UNISOLATED index views.
| Constructor Detail |
|---|
protected StoreManager(Properties properties)
Note: The store files are NOT accessible until the asynchronous startup
is finished. Caller's MUST verify that the isOpen()
AND NOT submit tasks until isStarting() returns
false.
properties - See StoreManager.Options.Startup| Method Detail |
|---|
public final DiskOnlyStrategy.StoreCounters getStoreCounters()
IBufferStrategy backing the live
journal and any historical journals which are concurrently open with the
live journal. A single instance of this object is used, and a hard
reference to that instance is held here, so that we can track the
cumulative performance counters across the live cycles of all journal
instances used by the data service over time. The performance counters
are not themselves persistent and do not survive a restart of the
StoreManager.
protected void retentionSetAdd(UUID uuid)
IndexSegment to the set of IndexSegments which
have been generated but not yet incorporated into an index partition view
and hence we must take special cautions to prevent their release.
The - UUID of the IndexSegmentStore.retentionSetRemove(UUID),
retentionSetprotected void retentionSetRemove(UUID uuid)
IndexSegment from the retentionSet. DO NOT
invoke this until the IndexSegment has been incorporated in a
restart safe manner into an index partition view (that is, post-commit
rather than during the task that incorporates it into the view) or is
known to be no longer required (post MOVE, task failed, etc).
uuid - The UUID of the IndexSegmentStore.retentionSetAdd(UUID),
retentionSetpublic int getStoreCacheSize()
IRawStores,
including both StoreManager.ManagedJournals and IndexSegment}s. There MAY be
more IRawStores open than are reported by this method if there
are hard references held by the application to those IRawStores.
IRawStores that are not fixed by a hard reference will be
quickly finalized by the JVM.
public int getResourceServicePort()
ResourceService. This
service provides remote access to resources hosted by the owning
DataService. This is used for moving resources to other data
services in the federation, including supporting service failover.
protected void assertRunning()
StoreManager isOpen() and is NOT
isStarting() (the test itself is NOT atomic).
IllegalStateException - unless open and not starting.public boolean isRunning()
true iff the StoreManager is open and
startup processing has been completed.
protected void assertOpen()
IllegalStateException - unless open.protected void assertNotOpen()
IllegalStateException - if open.public boolean awaitRunning()
true iff the StoreManager is running. If
the StoreManager is currently starting up, then this will await
the completion of the Startup task.
true if the StoreManager is running and
false if it is shutdown.public long getBytesUnderManagement()
IllegalStateException - during startup or if the StoreManager is closed.public long getJournalBytesUnderManagement()
StoreManager.ManagedJournals, including those written on the
live journal.
IllegalStateException - during startup or if the StoreManager is closed.public long getSegmentBytesUnderManagement()
IndexSegmentStores.
IllegalStateException - during startup or if the StoreManager is closed.public long getDataDirFreeSpace()
dataDir.
-1L if
the free space could not be determined.public long getTempDirFreeSpace()
tmpDir.
-1L if
the free space could not be determined.public Properties getProperties()
Properties given to the ctor.
public boolean isTransient()
true iff data can not be made restart-safe.
public boolean isStarting()
true initially and until #start() completes
successfully.
public boolean isOpen()
false initially and remains false until
#start() completes successfully. once true this
remains true until either shutdown() or
shutdownNow() is invoked.
isOpen in interface IServiceShutdownpublic void shutdown()
IServiceShutdownIServiceShutdown.Options.SHUTDOWN_TIMEOUT. Implementations SHOULD be
synchronized. If the service is aleady shutdown, then
this method should be a NOP.
shutdown in interface IServiceShutdownpublic void shutdownNow()
IServiceShutdown
shutdownNow in interface IServiceShutdownpublic File getTmpDir()
IResourceManager
getTmpDir in interface IResourceManagerpublic File getDataDir()
File is in canonical form.
getDataDir in interface IResourceManagerpublic int getManagedJournalCount()
public int getManagedSegmentCount()
protected void addResource(IResourceMetadata resourceMetadata,
File file)
resourceFiles and to either journalIndex or
segmentIndex as appropriate. As a post-condition, you can use
openStore(UUID) to open the resource using the UUID
specified by IResourceMetadata.getUUID().
Note: This also adds the size of the store in bytes as reported by the OS
to bytesUnderManagement.
Note: Adding a resource to the store manager has no persistent effect
other than the presumed presence of the specified file in the file
system. However, error handling routines SHOULD invoke
deleteResource(UUID, boolean) in order to remove a resource that
was not built correctly or not incorporated into the view. Otherwise the
mapping from the UUID to the File will be maintained in
memory and the StoreManager will overreport the #of bytes under
management.
resourceMetadata - The metadata describing that resource.file - The file in the local file system which is the resource.
RuntimeException - if the file does not exist.
RuntimeException - if there is already a resource registered with the same UUID
as reported by IResourceMetadata.getUUID()
RuntimeException - if the journalIndex or segmentIndex already
know about that resource.
RuntimeException - if openStore(UUID) already knows about that
resource.
IllegalArgumentException - if the resourceMetadata is null.
IllegalArgumentException - if the file is null and
isTransient is false.deleteResource(UUID, boolean),
retentionSetAdd(UUID),
retentionSetRemove(UUID)protected ResourceFileFilter newFileFilter()
ResourceManager will log warnings if it sees an
unexpected file and will NOT deleteResources() files that it
does not recognize.
ResourceFileFilterResourceFileFilter would have to be a static class and we
would have to pass in the IResourceManager so that it could
get the dataDir.public abstract IConcurrencyManager getConcurrencyManager()
IllegalStateException - if the object has not been set yet using
setConcurrencyManager(IConcurrencyManager).public abstract void setConcurrencyManager(IConcurrencyManager concurrencyManager)
public StoreManager.ManagedJournal getLiveJournal()
getLiveJournal in interface IResourceManagerIllegalStateException - if the StoreManager is not open.
IllegalStateException - if the StoreManager is still starting up.public AbstractJournal getJournal(long timestamp)
IResourceManager
getJournal in interface IResourceManagertimestamp - A transaction identifier, ITx.UNISOLATED for the
unisolated index view, ITx.READ_COMMITTED, or
timestamp for a historical view no later than
the specified timestamp.
null if no journal has data for that timestamp,
including when a historical journal with data for that timestamp
has been deleted.
IllegalStateException - if the StoreManager is not open.
IllegalStateException - if the StoreManager is still starting up.public IRawStore openStore(UUID uuid)
IRawStore.
openStore in interface IResourceManageruuid - The UUID identifying that store file.
IRawStore.
IllegalStateException - if the StoreManager is not open.
IllegalStateException - if the StoreManager is still starting up.
IllegalArgumentException - if uuid is null.
NoSuchStoreException - if the UUID is not recognized.
NoSuchStoreException - if the resource for that UUID could not be found.
RuntimeException - if something else goes wrong.IResourceMetadata on hand
when we need to (re-)open a store so it might be nice to pass that
in as it would make for more informative error messages when
something goes wrong (except that I was planning to drop the file
name from that interface).protected long nextTimestamp()
ITransactionService.
public void deleteResources()
IResourceManager
deleteResources in interface IResourceManagerpublic void setReleaseTime(long releaseTime)
releaseTime.
Data services MAY release data for views whose timestamp is less than or equal to the specified release time IFF that action would be in keeping with their local history retention policy (minReleaseAge) AND if the data is not required for the most current committed state (data for the most current committed state is not releasable regardless of the release time or the minReleaseAge).
#purgeOldResources(), which is responsible for actually deleting the
old resources.public long getReleaseTime()
setReleaseTime(long).
protected abstract long getIndexRetentionTime()
IndexManager.getIndexRetentionTime()protected final PurgeResult purgeOldResources()
Note: The ability to read from a historical commit point requires the existence of the journals back until the one covering that historical commit point. This is because the distinct historical commit points for the indices are ONLY defined on the journals. The index segments carry forward the committed state of a specific index as of the commitTime of the index from which the segment was built. This means that you can substitute the index segment for the historical index state on older journals, but the index segment carries forward only a single commit point for the index so it can not be used to read from arbitrary historical commit points.
The caller MUST hold the exclusive lock on the
WriteExecutorService.
null if the
preconditions for the purge operation were not satisfied.src/architecture/purgeResourceDecisionsMatrix.xls,
purgeOldResources(long, boolean)
protected void deleteResource(UUID uuid,
boolean isJournal)
throws NoSuchStoreException
storeCache and resourceFiles and either
journalIndex or segmentIndex as appropriate.
DO NOT delete resources that are in use!
A resource that has not yet been incoporated into a view may be deleted
without futher concern. However, once a resource has been incorporated
into a view then you MUST arange for appropriate synchronization before
the resource may be deleted. For example, purgeOldResources()
imposes that constraint on the caller that they are responsible for
synchronization and is generally invoked during synchronous overflow
since we know that there are no active writers at that time.
Pre-conditions:
UUID exists and is not the
live journal.resourceFiles.storeCache.resourceFiles. resourceFiles).StoreManager have been
updated (bytes delete, bytes under management, etc).journalIndex or
the segmentIndex as appropriate.
uuid - The UUID which identifies the resource.isJournal - true if the resource is a journal.
NoSuchStoreExceptionprotected long getCommitTimeStrictlyGreaterThan(long releaseTime)
ICommitRecord that is
strictly greater than the specified timestamp and returns the timestamp
of that ICommitRecord.
releaseTime - A release time as set by setReleaseTime(long). Any
resource as of this timestamp is available for release.
IllegalArgumentException - If there is no commit point that is strictly greater than the
releaseTime. This implies that the release time is either in
the future or, if the releaseTime is equal to the last
commitTime, that you are trying to release everything in the
database.protected Set<UUID> getResourcesForTimestamp(long commitTimeToPreserve)
Note: We include all dependencies for all commit points subsequent to the probe in order to ensure that we do not accidently release dependencies required for more current views of the index.
Note: This method solely considers the index views as defined at each commit point starting with the given commit point. It DOES NOT pay attention to the release time or to any other aspect of the state of the system.
commitTimeToPreserve - The commit time corresponding to the first commit point which
must be preserved.
UUIDs required by at least one index
for any commit time GTE the specified commit time.public static String munge(String s)
s - The name of the scale-out index.
public File getIndexSegmentFile(IndexMetadata indexMetadata)
IResourceManagerIndexSegment should be written.
The file will exist but will have zero length.
getIndexSegmentFile in interface IResourceManagerindexMetadata - The index metadata.
public File getIndexSegmentFile(String scaleOutIndexName,
UUID indexUUID,
int partitionId)
IndexSegment should be written.
The file will exist but will have zero length. The file is created using
the File.createTempFile(String, String, File) mechanism within
the configured dataDir in the subdirectory for the specified
scale-out index.
Note: The index name appears in the file path above the UUID of
the scale-out index. Therefore it is not possible to have collisions
arise in the file system when given indices whose scale-out names differ
only in characters that are munged onto the same character since the
files will always be stored in a directory specific to the scale-out
index.
scaleOutIndexName - The name of the scale-out index.indexUUID - The UUID of the scale-out index.partitionId - The index partition identifier -or- -1 if the
index is not partitioned (handles the MDS which does not use
partitioned indices at this time).
File on which a IndexSegmentStore for that
index partition may be written. The file will be unique and
empty.
IllegalArgumentException - if any argument is null
IllegalArgumentException - if the partitionId is negative and not -1
public boolean purgeOldResources(long timeout,
boolean truncateJournal)
throws InterruptedException
WriteExecutorService. If successful, it purges any resources that
are no longer required based on
StoreManager.Options#MIN_RELEASE_AGE and optionally truncates the
live journal such that no free space remains in the journal.
Note: If there is heavy write activity on the service then the timeout may well expire before the exclusive write lock becomes available. Further, the acquisition of the exclusive write lock will throttle concurrent write activity and negatively impact write performance if the system is heavily loaded by write tasks.
timeout - The timeout (in milliseconds) that the method will await the
pause of the write service.truncateJournal - When true, the live journal will be truncated to
its minimum extent (all writes will be preserved but there
will be no free space left in the journal). This may be used
to force the DataService to its minimum possible
footprint for the configured history retention policy.truncateJournal - When true the live journal will be truncated such
that no free space remains in the journal. If writes are
directed to the live journal after it has been truncated then
it will transparently re-extended.
true if successful and false if the
write service could not be paused after the specified timeout.
IOException
InterruptedException
IllegalStateException - if the StoreManager is not running.protected void overrideJournalExtent(Properties p)
StoreManager is relatively new (as measured by the #of
bytes under management) we discount the journal extent in order to
trigger overflow earlier. Together with the discount applied to the split
handler by the AsynchronousOverflowTask, this helps to break
down new index partitions allocated on the new data service and
re-distribute those index partitions (if there are other data services
which have even less utilization).
p - The properties (modified as side-effect).
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||