|
|
Configuration Guide
Contents
- Properties
- Property list
- Connect strings
- Syntax
- Connect string properties
- Cache management
- Schema cache
- Memory management
- Out of memory
- Logging
- Configuring log4j within Mondrian's test environment
- MDX and SQL Statement Logging
1. Properties
Mondrian has a properties file to allow you to configure how it executes. The
mondrian.properties file is loaded when the executing Mondrian JAR detects it
needs properties, but can also be done explicitly in your code. It looks in
several places, in the following order:
- In the directory where you started your JVM (Current working directory for
JVM process, java.exe on Win32, java on UNIX/Linux).
- If there isn't mondrian.properties under current working directory of JVM
process, Class MondrianProperties's classloader will try to locate
mondrian.properties in all of its classpaths. So you may put
mondrian.properties
under /WEB-INF/classes when you pack Mondrian into a Java web application.
The demonstration web applications have this configuration.
These properties are stored as system properties, so they can be set during
JVM startup via -D<property>=<value>.
1.1 Property list
The following properties in mondrian.properties effect the
operations of Mondrian.
Not all of the properties in this table are of interest to the end-user. For
example, those in the 'Testing' are only applicable if are running Mondrian's
suite of regression tests.
| Property |
Type |
Default value |
Description |
Miscellaneous
|
mondrian.foodmart.jdbcURL |
string |
"jdbc:odbc:Mondrian FoodMart" |
Property containing the JDBC URL of the FoodMart database. The default
value is to connect to an ODBC data source called "MondrianFoodMart". |
mondrian.query.limit |
int |
40 |
Maximum number of simultaneous queries the system will allow. Oracle
fails if you try to run more than the 'processes' parameter in init.ora,
typically 150. The throughput of Oracle and other databases will probably
reduce long before you get to their limit. |
mondrian.jdbcDrivers |
string |
mondrian.jdbcDrivers,
sun.jdbc.odbc.JdbcOdbcDriver,
org.hsqldb.jdbcDriver,
oracle.jdbc.Oracle Driver,
com.mysql.jdbc.Driver |
A list of JDBC drivers to load automatically. Must be a
comma-separated list of class names, and the classes must be on the class
path. |
mondrian.result.limit |
int |
0 |
If set to a value greater than zero, limits the maximum size of a
result set. If a query exceeds the limit, you will get an error such as:
Mondrian result limit exceeded: Mondrian Error: Size of CrossJoin
result (53,463) exceeded limit (50,000)
or
Number of members to be read exceeded limit 50,000
and Mondrian throws a
mondrian.olap.ResourceLimitExceededException. See also
limit properties. |
mondrian.rolap.evaluate.MaxEvalDepth |
int |
10 |
Maximum number of passes allowable while evaluating an MDX expression.
If evaluation exceeds this depth (for example, while evaluating a very
complex calculated member), Mondrian will throw an error. |
mondrian.rolap.LargeDimension Threshold |
int |
100 |
Determines when a dimension is considered "large". If a dimension has
more than this number of members, Mondrian uses a
smart member reader. |
mondrian.rolap.SparseSegmentValueThreshold |
int |
1,000 |
The values of the
mondrian.rolap. SparseSegment ValueThreshold (countThreshold) and
mondrian.rolap. SparseSegment DensityThreshold (densityThreshold)
properties determine whether to choose a sparse or dense representation
when storing collections of cell values in memory.
When storing
collections of cell values in memory, Mondrian has to choose between a
sparse and a dense representation, based upon the possible and
actual number of values. The density
is defined by the formula
density = actual / possible
Mondrian uses a sparse representation if
(possible - countThreshold) * densityThreshold > actual
For example, at the default values (countThreshold = 1000 and
densityThreshold = 0.5), Mondrian use a dense representation for
- (1000 possible, 0 actual), or
- (2000 possible, 500 actual), or
- (3000 possible, 1000 actual).
Any fewer actual values, or any more possible values, and Mondrian will
use a sparse representation. |
mondrian.rolap.SparseSegmentDensityThreshold |
double |
0.5 |
See mondrian.rolap.SparseSegmentValueThreshold. |
mondrian.olap.triggers.enable |
boolean |
true |
Whether to notify the Mondrian system when a property value changes.
This allows objects dependent on Mondrian properties to react (that is,
reload), when a given property changes via, say,
MondrianProperties.instance().populate(null);
or
MondrianProperties.instance().QueryLimit.set(50);
|
mondrian.olap.case.sensitive |
boolean |
false |
Controls whether the MDX parser resolves uses case-sensitive matching
when looking up identifiers. |
mondrian.rolap.compareSiblingsByOrderKey |
boolean |
false |
Controls whether sibling members are compared according to
the order key value fetched from their ordinal expression. The
default value of false means ordinal expressions are only used
for ORDER BY, and the actual values produced are ignored inside
of Mondrian. Changing this to true allows Mondrian to correctly
order members when native filtering is used, but requires that
the values produced by the DBMS are non-null instances of
java.lang.Comparable which yield the desired ordering
when their Comparable.compareTo method is called.
|
mondrian.rolap.localePropFile |
string |
null
|
Name of locale property file. Used for the
LocalizingDynamicSchemaProcessor; see
Internationalization for more details. |
mondrian.rolap.queryTimeout |
int |
0 |
If set to a value greater than zero, limits the number of seconds
a query executes before it is aborted. If a query exceeds the limit,
mondrian throws a mondrian.olap.QueryTimeoutExceptiony,
resulting in an error such as:
Query timeout of 10 seconds reached
See also
limit properties. |
mondrian.rolap.nonempty |
boolean |
false |
If true, each query axis implicit has the NON EMPTY option set (and in
fact there is no way to display empty cells). |
mondrian.rolap.ignoreInvalidMembers |
boolean |
false |
If set to true, during schema load, invalid members are ignored
and will be treated as a null member if they are later referenced in
a query. |
mondrian.rolap.ignoreInvalidMembersDuringQuery |
boolean |
false |
If set to true, during query validation, invalid members are ignored
and will be treated as a null member. |
mondrian.olap.NullMemberRepresentation |
string |
#null |
Defines how a null Member is represented in the result output.
MSAS 2000 shows empty value while MSAS 2005 shows "(null)" |
mondrian.rolap.IterationLimit |
int |
0 |
If > 0, the maximum number of iterations allowed when evaluating an
aggregate. If 0, there is no limit. If a query exceeds the limit,
mondrian throws a
mondrian.olap.ResourceLimitExceededException,
resulting in an error such as:
Number of iterations exceeded limit of 100
See also
limit properties. |
mondrian.olap.fun.crossjoin.optimizer.size |
int |
0 |
If a crossjoin input list's size is larger than this property's
value and the axis has the "NON EMPTY" qualifier, then
the crossjoin non-empty optimizer is applied.
Setting this value to '0' means that for all crossjoin
input lists in non-empty axes will have the optimizer applied.
On the other hand, if the value is set larger than any possible
list, say Integer.MAX_VALUE, then the optimizer
will never be applied.
|
mondrian.olap.NullOrZeroDenominatorProducesNull |
boolean |
false |
If a division has a non-null numerator and a null denominator,
it evaluates to "Infinity", which conforms to MSAS behavior. However,
the old semantics of evaluating this to NULL(non MSAS conforming), is
useful in some applications. This properties controls whether the
result should be NULL when denominator is NULL or zero.
|
mondrian.olap.elements.NeedDimensionPrefix
|
boolean |
false |
Property determines if elements of dimension (levels, hierarchies,
members) need to be prefixed with dimension name in MDX query.
For example when the property is true, the following queries
will error out. The same queries will work when this property
is set to false.
select {[M]} on 0 from sales
select {[USA]} on 0 from sales
select {[USA].[CA].[Santa Monica]} on 0 from sales
When the property is set to true, any query where elements are
prefixed with dimension name as below will work
select {[Gender].[F]} on 0 from sales
select {[Customers].[Santa Monica]} on 0 from sales
Please note that this property does not govern the behaviour where in
[Gender].[M]
is resolved into a fully qualified
[Gender].[All Gender].[M]
In a scenario where the schema is very large and dimensions have
large number of members a MDX query that has a invalid member in it
will cause mondrian to to go through all the dimensions, levels,
hierarchies, members and properties trying to resolve the element
name. This behaviour consumes considerable time and resources on the
server. Setting this property to true will make it fail fast in a
scenario where it is desirable
|
mondrian.olap.agg.IgnoreMeasureForNonJoiningDimension |
boolean |
false |
If there are unrelated dimensions to a measure in context during
aggregation, the measure is ignored in the evaluation context. This
behaviour kicks in only if the
CubeUsage for this
measure has
IgnoreUnrelatedDimensions
attribute set to false
For example, Gender doesn't join with [Warehouse Sales] measure.
With mondrian.olap.agg.IgnoreMeasureForNonJoiningDimension=true
Warehouse Sales gets eliminated and is ignored in the aggregate value
SUM({Product.members * Gender.members})
[Store Sales] + [Warehouse Sales] = 7,913,333.82
With mondrian.olap.agg.IgnoreMeasureForNonJoiningDimension=false
Warehouse Sales is part of the aggregate value.
SUM({Product.members * Gender.members})
[Store Sales] + [Warehouse Sales] = 9,290,730.03
On a report where Gender M, F and All members exist a user will see a
large aggregated value compared to the aggregated value that can be
arrived at by suming up values against Gender M and F. This can be
confusing to the user. This feature can be used to eliminate such a
situation.
|
Testing
|
mondrian.test.Name |
string |
null |
Property which determines which tests are run. This is a
Java regular expression. If this property is specified, only tests
whose names match the pattern in its entirety will be run. |
mondrian.test.Class |
string |
- |
Property which determines which test class to run. This is the name of
the class which either implements interface
junit.framework.Test or has a method public static
junit.framework.Test suite(). |
mondrian.test.connectString |
string |
- |
Property containing the connect string which regresssion tests should
use to connect to the database. See the
connect string specification for more details. |
mondrian.test.QueryFilePattern |
string |
- |
(not documented) |
mondrian.test.QueryFileDirectory |
string |
- |
(not documented) |
mondrian.test.Iterations |
int |
1 |
(not documented) |
mondrian.test.VUsers |
int |
1 |
(not documented) |
mondrian.test.TimeLimit |
int |
0 |
The time limit for the test run in seconds. If the test is running
after that time, it is terminated. |
mondrian.test.Warmup |
boolean |
false |
Whether this is a "warmup test". |
mondrian.catalogURL |
string |
- |
The URL of the catalog to be used by
CmdRunner and XML/A Test. |
mondrian.test.ExpDependencies |
int |
0 |
Whether to test operators' dependencies, and how much time to spend
doing it.
If this property is positive, Mondrian's test framework allocates an
expression evaluator which evaluates each expression several times, and
makes sure that the results of the expression are independent of
dimensions which the expression claims to be independent of. |
mondrian.test.random.seed |
int |
1234 |
Seed for random number generator used by some of the tests. Any
value besides 0 or -1 gives deterministic behavior. The default value is
1234: most users should use this. Setting the seed to a different value
can increase coverage, and therefore may uncover new bugs.
If you set the value to 0, the system will generate its own
pseudo-random seed.
If you set the value to -1, Mondrian uses the next seed from an
internal random-number generator. This is a little more deterministic than
setting the value to 0.
|
mondrian.test.jdbcURL |
string |
- |
Property containing the JDBC URL of a test database. There is no
default value. |
mondrian.test.jdbcUser |
string |
- |
Property containing the JDBC user of a test database. The default
value is null, to cope with DBMSs that don't need this. |
mondrian.test.jdbcPassword |
string |
- |
Property containing the JDBC password of a test database. The default
value is null, to cope with DBMSs that don't need this. |
mondrian.test.WarnIfNoPatternForDialect |
string |
NONE |
Property which controls if warning messages should be printed if a sql
comparison tests do not contain expected sqls for the specified dialect.
The tests are skipped if no expected sqls are found for the current dialect.
Possible values are the following:
- "NONE": no warning (default)
- "ANY": any dialect
- "ACCESS"
- "DERBY"
- "LUCIDDB"
- "MYSQL"
- ... and any Dialect enum in SqlPattern.Dialect
Specific tests can overwrite the default setting. The priority
between test setting and property file setting is:
Settings besides "NONE" in mondrian.properties file < Any setting in the test < "ANY"
|
Aggregate tables
|
mondrian.rolap.aggregates.Use |
boolean |
false |
Whether to use aggregate tables. If
true, then Mondrian uses aggregate tables. This property is queried prior to each
aggregate query so that changing the value of this property dynamically
(not just at startup) is meaningful.
Aggregates can be read from the
database using the mondrian.rolap. aggregates.Read property
but will not be used unless this property is set to true. |
mondrian.rolap.aggregates.optimizePredicates |
boolean |
true |
Determines whether Mondrian optimizes predicates or not
If set to true, Mondrian intelligently optimizes certain predicates.
If set to false, then predicates are optimized only when all the
members of a dimension are included.
Example:
For the in MDX query which selects all but one member of 1997 quarter:
select {[Time].[1997].[Q1],[Time].[1997].[Q2],[Time].[1997].[Q3]} on 0 from sales
predicate optimization would result in sql that retrives all 4 quarters, instead of just 3.
The fourth quarter is cached along with others for future use:
...where`time_by_day`.`the_year` = 1997 group by
`time_by_day`.`the_year`, `time_by_day`.`quarter`...
(note the where in clause involving quarters is missing)
when predicate optimization is disabled, Mondrian would retrive no more data than specified by the query,
In the above case it would retrive only data for first 3 quarters:
...`time_by_day`.`the_year` = 1997 and `time_by_day`.`quarter` in ('Q1', 'Q2', 'Q3') group by `time_by_day`.`the_year`, `time_by_day`.`quarter`...
|
mondrian.rolap.aggregates.Read |
boolean |
false |
Whether to read aggregate tables.
If set to true, then Mondrian scans the database for aggregate tables. Unless
mondrian.rolap. aggregates.Use is set to true, the aggregates found will
not be used. |
mondrian.rolap.aggregates.ChooseByVolume |
boolean |
false |
Whether to choose an aggregate tables based volume or row
count. If true, Mondrian uses the aggregate table with the smallest
volume (number of rows multiplied by number of columns); if false,
Mondrian uses the aggregate table with the fewest rows. |
mondrian.rolap.aggregates.rules |
string |
"/DefaultRules.xml"
(which is in the mondrian.rolap.aggmatcher
package in mondrian.jar) |
Name of the file which defines the rules for recognizing an aggregate
table. Can be either a resource in the Mondrian jar or a URL. See
aggregate table rules for details.
Normally, this property is not set by a user. |
mondrian.rolap.aggregates.rule.tag |
string |
default |
The AggRule element's tag value.
Normally, this property is not set by a user. |
mondrian.rolap.aggregates.generateSql |
boolean |
false |
Whether to print the SQL code
generated for aggregate tables.
If set, then as each aggregate request is processed, both the lost and
collapsed dimension create and insert sql code is printed. This is for use
in the CmdRunner allowing one to create aggregate table generation sql. |
mondrian.rolap.aggregates.jdbcFactoryClass |
string |
null |
If specified, overrides the default StdFactory factory class which
specifies the JdbcSchema class to use for determining the tables
and columns of a data source. The JdbcSchema class is used as part
aggregate table matcher algorithm.
|
Caching
|
mondrian.rolap.star.disableCaching |
boolean |
false |
Whether to clear a RolapStar's data
cache after each query. If true, RolapStar does not cache
aggregate data from one query to the next: the cache is cleared after each
query. |
mondrian.expCache.enable |
boolean |
true |
Controls whether to use a cache for the results of frequently
evaluated expressions.
With the cache disabled, an expression like:
Rank([Product]. CurrentMember,
Order([Product].MEMBERS, [Measures].[Unit Sales]))
would perform many redundant sorts. |
mondrian.rolap.RolapResult.flushAfterEachQuery |
boolean |
false |
Obsolete. |
mondrian.rolap.EnableRolapCubeMemberCache |
boolean |
true |
Determines whether to cache RolapCubeMember objects, each of which
associates a member of a shared hierarchy with a particular cube in
which it is being used. The default is true, that is, use
a cache. If you wish to use the member cache control aspects of
mondrian.olap.CacheControl
you must set this property to false. |
SQL generation
|
mondrian.native.crossjoin.enable |
boolean |
true
|
If enabled, some NON EMPTY CrossJoin
MDX statements will be computed in the database and not within Mondrian/Java |
mondrian.native.topcount.enable |
boolean |
true
|
If enabled, some TopCount
MDX statements will be computed in the database and not within Mondrian/Java |
mondrian.native.filter.enable |
boolean |
true
|
If enabled, some Filter()
MDX statements will be computed in the database and not within Mondrian/Java |
mondrian.native.nonempty.enable |
boolean |
true
|
If enabled, some NON EMPTY MDX set operations like
member.children, level.members
and member.descendants will be computed in the database and
not within Mondrian/Java |
mondrian.native.ExpandNonNative |
boolean |
false
|
If set to true, expand non native sub-expressions of a native
expression into MemberLists |
mondrian.native.unsupported.alert |
string |
OFF |
Alerting action {OFF, WARN, ERROR} to take in case
native evaluation of a function is
enabled but not supported for that function's usage in a particular
query. (No alert is ever raised in cases where native evaluation
would definitely have been wasted effort.) Currently, alerts are
only raised for the NonEmptyCrossJoin function. |
mondrian.rolap.generate.formatted.sql |
boolean |
false |
Whether to pretty-print SQL generated statements. If true, Mondrian
generates SQL strings are generated in the log or output in pretty-print
mode, formatted for ease of reading. |
mondrian.rolap.maxConstraints |
int |
500 |
Max number of constraints in a single
`IN' SQL clause. This value may be variant among database products and
their runtime settings. Oracle, for example, gives the error "ORA-01795:
maximum number of expressions in a list is 1000".
Recommended values:
- Oracle: 1,000
- DB2: 2,500
- Other: 10,000
|
mondrian.rolap.groupingsets.enable |
boolean |
false |
If enabled, some rollup queries will
be combined using group by grouping sets. Even if this
property is set to true, grouping sets will be used only on supported
Databases.
Currently grouping sets will be used only against Oracle, DB2 and
Teradata.
|
XML/A
|
mondrian.xmla.drillthroughTotalCount.enable |
boolean |
true |
If enabled, first row in the result of an XML/A drill-through request
will be filled with the total count of rows in underlying database. |
mondrian.xmla.drillthroughMaxRows |
int |
1,000 |
Limit on the number of rows returned by XML/A drill through request. |
Memory monitoring
|
mondrian.util.memoryMonitor.enable
|
boolean |
true |
If enabled and one is using Java5 or above, then Mondrian
will use the Java5 memory monitoring capability - a
MemoryLimitExceededException exception ought be throw rather than
a OutOfMemoryError when memory get low and the JVM will not
crash.
|
mondrian.util.memoryMonitor.percentage.threshold
|
int |
90 |
At what level of memory usage should Mondrian be notified that
memory is running low. |
Factories
|
mondrian.util.MemoryMonitor.class
|
string |
- |
By default this property does not have a value.
If set, then it is the class name of an implementation of
the MemoryMonitor class and is used by the
MemoryMonitorFactory to create the single instance.
|
mondrian.calc.ExpCompiler.class
|
string |
- |
By default this property does not have a value.
If set, then it is the class name of an implementation of
the ExpCompiler class and is used by the
ExpCompiler.Factory to create each instance.
|
Limit properties
Properties mondrian.result.limit, mondrian.rolap.iterationLimit
and mondrian.rolap.queryTimeout enforce runtime limits on the
time or space required to execute a query. If any of these limits are exceeded,
mondrian throws an exception which extends
mondrian.olap.ResultLimitExceededException.
Connect strings
Connect string syntax
Mondrian connect strings are a connection of property/value pairs, of the
form 'property=value;property=value;...'.
Values can be enclosed in single-quotes, which allows them to contain spaces
and punctuation. See the the
OLE DB connect string syntax specification.
The supported properties are described below.
Connect string properties
| Name |
Required? |
Description |
| Provider |
Yes |
Must have the value "Mondrian". |
| Jdbc |
Exactly one |
The URL of the JDBC database where the data is stored. You must
specify either DataSource or Jdbc. |
| DataSource |
The name of a data source loaded via JNDI. The name must be a valid JNDI name, and the object referenced must implement the
javax.sql.DataSource interface.
You must specify either
DataSource or Jdbc. |
| JdbcDrivers |
Yes |
Comma-separated list of JDBC driver classes, for example,
JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver,oracle.jdbc.OracleDriver
|
| JdbcUser |
No |
The name of the user to log on to the JDBC database. (If your JDBC
driver allows you to specify the user name in the JDBC URL, you don't
need to set this property.) |
| JdbcPassword |
No |
The name of the password to log on to the JDBC database. (If your
JDBC driver allows you to specify the password in the JDBC URL, you
don't need to set this property.) |
| Catalog |
Exactly one |
The URL of the catalog, an XML file which describes the schema: cubes, hierarchies, and so forth.
For example,
Catalog=file:demo/FoodMart.xml
Catalogs are described in the Schema Guide.
See also CatalogContent. |
| CatalogContent |
An XML string representing the schema: cubes, hierarchies, and so forth.
For example,
CatalogContent=<Schema name="MySchema"><Cube name="Cube1"> ...
</Schema>
Catalogs are described in the Schema Guide.
See also Catalog. |
| CatalogName |
No |
Not used. If, in future, Mondrian supports multiple catalogs, this property
will specify which catalog to use. See also Catalog. |
| PoolNeeded |
No |
Tells Mondrian whether to add a layer of connection pooling.
If the value "true" is specified, or no value is specified, Mondrian
assumes that:
- connections created via the
Jdbc property are not pooled,
and therefore need to be pooled;
- connections created via the
DataSource are already pooled.
If the value "false" is specified, Mondrian does not apply
connection-pooling to any connection. |
| Role |
No |
The name of the role to adopt
for access-control purposes. If not specified, the connection uses a role
which has access to every object in the schema.
This property can contain multiple role names separated by commas. If
so, queries in the connection execute with the sum of the privileges of
all of the rules; the effect is the same as running under a
union role, defined using the
<Union> element in the schema file.
If a role name contains a comma, escape the comma using an extra
comma. For example, a connection created with
Role='Pacific region manager,Europe,, Middle East and
Africa manager'
will execute with the combined privileges of the roles "Pacific
region manager", and "Europe, Middle East and Africa manager". |
| jdbc.* |
No |
Any property whose name begins with "jdbc." will be added to the JDBC
connection properties, after removing this prefix. This allows you to specify connection
properties without a URL.
For example, given the properties
jdbc.Timeout=50; jdbc.CacheSize=1m
Mondrian will create a JDBC connection using the properties
{Timeout="50", CacheSize="1m"}. |
| UseContentChecksum |
No |
Allows mondrian to work with dynamically changing schema. If this property
is set to true and schema content has changed (previous
checksum doesn't equal with current), schema would be reloaded.
The default is false.
Could be
used in combination with DynamicSchemaProcessor property. |
| UseSchemaPool |
No |
Controls whether a new connection use a schema from the schema
cache. If true, the default, a connection shares a schema
definition (and hence also a cache of aggregate data retrieved by
previous queries) with other connections which have a textually
identical schema definition.
If false, the connection has a private schema definition
and cache. |
| DynamicSchemaProcessor |
No |
The name of a class which is called at runtime in order to modify
the schema content. The class must implement the
mondrian.spi.DynamicSchemaProcessor interface. For example,
DynamicSchemaProcessor =
mondrian.i18n.LocalizingDynamicSchemaProcessor
uses the builtin schema processor class
mondrian.i18n.LocalizingDynamicSchemaProcessor to replace variables
in the schema file, according to resource files and the current locale
(see the Locale property). |
| Locale |
No |
The requested Locale for the current session. The locale determines
the formatting of numbers and date/time values, and Mondrian's error
messages.
Example values are "en" (English), "en_US"
(United States English), "hu" (Hungarian). If Locale is not specified, then the name of system's default will be used, as per
java.util.Locale#getDefault(). |
Connect string properties are also documented in the
RolapConnectionProperties class.
Cache management
Schema cache
To flush all schema definitions, use
the mondrian.olap.CacheControl.flushSchemaCache()
method:
import mondrian.olap.*;
Connection connection;
CacheControl cacheControl = connection.getCacheControl(null);
cacheControl.flushSchemaCache();
The cache is only used when creating new connections; existing connections
retain their schemas.
There are four connect string properties that control the use of the
Schema cache:
UseSchemaPool,
UseContentChecksum,
CatalogContent and
DynamicSchemaProcessor.
The UseSchemaPool property controls whether or not the cache is used
regardless of the values of any of the other properties. If UseSchemaPool
is "false", then the cache is not used; each request for a new schema
object creates a new one (entailing the re-parsing of the schema definition
and re-scanning of the database for meta data and aggregate tables -
very slow, and, in addition, there is no reuse of the in-memory aggregate
cache).
Next, if UseContentChecksum is "true", then a check sum (MD5) is created
from the schema definition content (not URL) and it is this check sum
that is used as the key to lookup previously cached versions of the
schema definition. If two schema definitions produce different check
sums, then one can safely assume that they are different schemas (of course,
it is possible that only a comment or some whitespace in the schema
definition changed in which case the two schemas would actually be the
same, but because their check sums are different, different schema
objects are used). If UseContentChecksum is "false", then no check sum
is created and used as the lookup key, rather, a combination of
the connection attributes
"catalogUrl",
"connectionKey",
"jdbcUser",
"dataSourceStr"
or
"catalogUrl",
"dataSource"
are used to create the key.
If the CatalogContent is specified, then it is used as the schema
definition content. If, in fact, it is specified, then the value of
DynamicSchemaProcessor, if any, is ignored.
Finally, the DynamicSchemaProcessor connection string property is the
class name of a class that implements the DynamicSchemaProcessor
interface. If set, an instance of the class is created for each
schema request and its "processSchema" method is called which
returns the schema definition content.
Memory management
Out Of Memory
Java OutOfMemoryError errors have always been an issue with
applications. When the JVM throws an Error as
opposed to an Exception it is telling the application
that its world has ended and it has no recourse but to die.
Prior to Java5 there was not much one could do other
than buy 64-bit machines with lots of RAM and hope for the best.
For a multi-user, Mondrian environment with potentially very large
data-sets and clients that
can generate queries requesting arbitrarily large amounts of that
data, this can be an issue. This is especially the case when
Mondrian is being hosted on some corporate web-server; applications
that kill web-servers are not looked upon favorably by IT.
With Java5 (and Java6, etc.) there is alternative. An application
cay take advantage of
a new feature in Java5 allowing the application to be notified when
memory starts running low. This allows the application to take
preemptive action prior to an OutOfMemoryError being
generated by the Java runtime.
Mondrian takes advantage of this new feature. Rather than
passing an OutOfMemoryError to its client, it
will now stop processing the present query, free up data structures
associated with the present query and return a
MemoryLimitExceededException to the client.
The MemoryLimitExceededException is one of Mondrian's
ResultLimitExceededException which are used to communicate
with clients that a limit has been exceeded, in this case, memory
usage.
By default, for Mondrian running under Java5, this feature is
enabled and the "safety limit" is set at 90 percent, when
memory usage gets to with 90 percent of the maximum possible, the
the processing of the current query is stopped and a
MemoryLimitExceededException is return to the client.
See the Memory monitoring properties above on this page
for additional information.
Lastly, the gorilla in the closet. Java5 in its wisdom only allows
for one memory threshold notification level to be registered with the JVM.
What this means is if within the same JVM, some code registers
one level, say, at 80% (here I use percentages for ease of presentation
rather than number of
bytes which is what the Java5 API actually supports)
and some other code later on registers a level of
90%, then it is the 90% that the JVM knows about - it knows nothing
of the previously registered 80%. What this means is that the code
expecting to be notified when the memory level crosses 80%, won't be notified!
For many applications that don't share their JVM with
other applications, this is not a problem, but for Mondrian is it
potentially an issue. Mondrian can be running in a Webserver and
Webservers can have more than one independent applications.
Each such application can register a different memory threshold
notification level.
In general, application-containing applications such as
web-servers or application-servers are a problem with the current
Java5 memory threshold notification approach.
At the current time, I do not know a way around this problem.
Logging
Mondrian uses log4j for all information and debug logging. When running
within an application server, Mondrian's log4j configuration is determined by
the server's or web application's log4j configuration. Please see
log4j's documentation
for a additional details.
Configuring log4j within Mondrian's test environment
When running outside an application server, log4j determines the location
of the log4j.xml file via the log4j.configuration java system property. log4j
treats this string as a URL, so to have it detect the log4j file on the file
system, you must use the syntax "file:DIR/log4j.xml". Relative paths are
acceptible, so if you have your log4j.xml file in the root directory of
mondrian, "file:log4j.xml" will load the correct file. You may specify the
log4j.configuration property in mondrian.properties, because Mondrian's ant
build file explicitly sets the property as a JVM system property when running
JUnit tests.
MDX and SQL Statement Logging
The default log4j.xml file is configured so that a separate log file is
created for both MDX and SQL statement logging. In the code, the MDX and SQL
strings are logged at the debug level, so to disable them you can set the log
level to INFO or any other level above debug. Statement logging occurs within
the log4j categories "mondrian.mdx" and "mondrian.sql". These categories log
the statements and how long they took to execute. The SQL log also records the
number of results returned in the result set.
Author: Julian Hyde; last modified January, 2008.
Version: $Id: //open/mondrian/doc/configuration.html#46 $
(log)
Copyright (C) 2006-2008 Julian Hyde
|