Applied Dimensionality

Another reason for TM1 10.2.2 to PA memory growth: Preloading Public views and ALL subsets

Posted at — Jul 16, 2019
Another reason for TM1 10.2.2 to PA memory growth: Preloading Public views and ALL subsets

Do you have a red circle around 30th of September in your calendars as TM1 10.2.2 end of support? As we’re going through the upgrades for our customers, it’s mostly smooth sailing (if you ignore PaW) and we mostly see 3 main types of ‘issues’:

  1. Memory growth – it’s reasonable to expect a 20% increase
  2. Temporary View names persistence – temporary objects persist in execution chain starting from TM1 version 11.3 which is awesome as it allows you to use the “library” processes to create temporary views and pass them back to calling process, but can cause issues if you’re not using unique object names (you should)
  3. Locking – if you’re doing anything ‘fancy’ around parallelisation/thread control, some of these assumptions can change or not work as expected.

There’s a fair bit of consensus in the community that main memory growth driver is MUN pre-caching, as discussed at length on TM1Forums. It’s easy to identify such case: just copy .dim files into an empty server and if it’s massively bigger in PA vs 10.2.2 – you might want to look into splitting all those ‘alternate hierarchies’ via consolidations into proper hierarchies.

But we recently had a project where massive memory growth wasn’t coming from dimensions/hierarchies at all and it took us & IBM a fair bit to figure that out.

Summary

Takeaway:

If you’re keen to check your server for this issue, here’s how we ‘fixed’ it:

  1. Checked the subset used in views on the large dimensions to see where ALL was used – this is more for making sure that the problem wouldn’t come back later
  2. Replaced ALL subsets in the views with a named ‘ALL-ALL’ subset that would be shared & cached

Code samples

Prolog:

# List of dimensions we're updating
dimensionList = 'a,b,c,d';
allSubsetName = '}ALL_generated_for_memory_optimisation';
numSubsetsChanged = 0;

Data:

IF (Subset@='ALL');
		IF (SCAN(Dimension, dimensionList) <> 0);
			# Check if our special subset exists
			IF (SubsetExists (Dimension, allSubsetName ) = 0);
				ASCIIOUTPUT('subset_change_log.txt', 'Creating special ALL subset for  ' | Dimension );
				# Create special subset
				SubsetCreate(Dimension, allSubsetName);
				SubsetIsAllSet( Dimension, allSubsetName, 1 );
			ENDIF;
			ViewSubsetAssign(Cube, View, Dimension, allSubsetName);
			ASCIIOUTPUT('subset_change_log.txt', 'Adjusted subset for ' | Cube | '.' | View | ' dimension ' | Dimension);
			numSubsetsChanged = numSubsetsChanged + 1;
		ENDIF;
	ENDIF;
comments powered by Disqus