Question
· Jul 4, 2022

Cleaning up CacheStream Global

Hi there have been various posts around how to clean up globals without parent data but none have gone into how you solve these issues. 

Our database is approaching 600gb in size so i am looking into how to reduce this. 

We use standard purge tasks. 

Our cache stream class has a global size of 2463243 from running global size so it is what i would like to tackle first. 

1) is there any way i can find based on my oldest message session for where most of these globals 

2) in the class where these are created what can be done to ensure purping. Basically we have 

set sIn=##class(%GlobalBinaryStream).%New()

set sc=writer.OutputToStream(sIn)

 

it seems to store

^CacheStream

^CacheStream(1)

^CacheStren (1,0-3)

^CacheStream(2)

ect. 

Product version: Caché 2017.1
Discussion (3)2
Log in or sign up to continue

From your description, it is obvious that you write ALL global streams just to default ^CacheStream.

To separate them you may set individual Globals for streaming (e.g depending on use-case)

Class %Library.GlobalBinaryStream has this parameter + property:

/// Default location: can be overridden at run-time
Parameter STOREGLOBALNAME = "^CacheStream"; /// Root is Global Location (name and top subscripts)

Property StoreRoot As %String(MAXLEN = 5000) [ InitialExpression = {..#STOREGLOBALNAME}, Private ]; Property rollback As %String [ MultiDimensional, Private ];


You can change this default using the method
Method %LocationSet(value As %String) As %Status
{
 Do ..Clear()
 Set ..StoreRoot=value,i%%Location=value
 Quit $$$OK
}

 

Hi,

Two years ago, I analyzed the behaviours using stream and %Persistent class.  

Class Test.Stream1 Extends %Persistent
{

Property st As %GlobalBinaryStream;

ClassMethod add1() As %Status
{
	; write stream in ^Test.Stream1S
	Set o = ..%New()
	Do o.st.Write("azeruiop")
	Quit o.%Save()
}

ClassMethod add2() As %Status
{
	; write stream in ^CacheStream
	Set o = ..%New()
	Set st = ##class(%GlobalBinaryStream).%New()
	Do st.Write("azeruiop")
	Set o.st = st
	Quit o.%Save()
}

Storage Default
{
<Data name="Stream1DefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>st</Value>
</Value>
</Data>
<DataLocation>^Test.Stream1D</DataLocation>
<DefaultData>Stream1DefaultData</DefaultData>
<IdLocation>^Test.Stream1D</IdLocation>
<IndexLocation>^Test.Stream1I</IndexLocation>
<StreamLocation>^Test.Stream1S</StreamLocation>
<Type>%Storage.Persistent</Type>
}

}

The method add2 use ^CacheStream due to the default storage usage (as described by @Robert Cemper ).  

However, We can force the storage in ^Test.Stream1S with :
Do st.%LocationSet("^Test.Stream1S")

When using the old stream classes (%Library.GlobalXXXXStream) you should never set a stream property A to the oref from another stream B, as the Location value of stream B will be copied into stream A. You should use CopyFrom to avoid this Location change.

Taking @Lorenzo Scalese  sample method add2(), it should be rewriiten as:

ClassMethod add2() As %Status
{
   Set = ..%New()
   Set st = ##class(%GlobalBinaryStream).%New()
   Do st.Write("azeruiop")
   //Set o.st = st
   Do o.st.CopyFrom(st)
   Quit o.%Save()
}
 

If you use the new stream classes %Stream,GlobalXXXX, the original code from method add2() will keep the Location from stream property:

ClassMethod add2() As %Status
{
Set = ..%New()
Set st = ##class(%Stream.GlobalBinary).%New()
Do st.Write("azeruiop")
Set o.st = st
Quit o.%Save()
}