package com.tesora.dve.variables;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.EnumSet;
import java.util.Locale;
import com.tesora.dve.charset.*;
import com.tesora.dve.clock.TimingServiceConfiguration;
import com.tesora.dve.common.PEStringUtils;
import com.tesora.dve.common.catalog.AutoIncrementTracker;
import com.tesora.dve.common.catalog.CatalogDAO;
import com.tesora.dve.common.catalog.CatalogDAO.CatalogDAOFactory;
import com.tesora.dve.common.catalog.TemplateMode;
import com.tesora.dve.db.DBNative;
import com.tesora.dve.db.mysql.MySQLTransactionIsolation;
import com.tesora.dve.errmap.AvailableErrors;
import com.tesora.dve.errmap.ErrorInfo;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.groupmanager.GroupManager;
import com.tesora.dve.server.connectionmanager.ConnectionSemaphore;
import com.tesora.dve.server.connectionmanager.SSConnection;
import com.tesora.dve.server.connectionmanager.SlowQueryLogger;
import com.tesora.dve.server.global.BootstrapHostService;
import com.tesora.dve.server.global.HostService;
import com.tesora.dve.server.global.MySqlPortalService;
import com.tesora.dve.singleton.Singletons;
import com.tesora.dve.sql.SchemaException;
import com.tesora.dve.sql.parser.InvokeParser;
import com.tesora.dve.sql.parser.TimestampVariableUtils;
import com.tesora.dve.sql.schema.SQLMode;
import com.tesora.dve.sql.schema.VariableScopeKind;
import com.tesora.dve.sql.schema.cache.CacheSegment;
import com.tesora.dve.sql.schema.cache.SchemaSourceFactory;
import com.tesora.dve.sql.schema.modifiers.EngineTableModifier.EngineTag;
import com.tesora.dve.variable.VariableConstants;
import com.tesora.dve.variables.BooleanValueConverter.BooleanToStringConverter;
public class KnownVariables implements VariableConstants {
public static final ValueMetadata<Long> integralConverter = new IntegralValueConverter();
public static final ValueMetadata<Boolean> booleanConverter = new BooleanValueConverter(BooleanToStringConverter.YES_NO_CONVERTER);
public static final ValueMetadata<Double> floatingPointConverter = new FloatingPointValueConverter();
public static final ValueMetadata<String> stringConverter = new StringValueConverter();
public static final ValueMetadata<String> literalConverter = new LiteralValueConverter();
public static final EnumSet<VariableScopeKind> globalScope = EnumSet.of(VariableScopeKind.GLOBAL);
public static final EnumSet<VariableScopeKind> sessionScope = EnumSet.of(VariableScopeKind.SESSION);
public static final EnumSet<VariableScopeKind> bothScope = EnumSet.of(VariableScopeKind.GLOBAL, VariableScopeKind.SESSION);
// normally emulated variables are just passed through
public static final EnumSet<VariableOption> emulated = EnumSet.of(VariableOption.EMULATED, VariableOption.PASSTHROUGH);
public static final EnumSet<VariableOption> emulatedOnly = EnumSet.of(VariableOption.EMULATED);
public static final EnumSet<VariableOption> dveOnly = EnumSet.noneOf(VariableOption.class);
public static final EnumSet<VariableOption> nullable = EnumSet.of(VariableOption.NULLABLE);
public static final EnumSet<VariableOption> readonly = EnumSet.of(VariableOption.READONLY);
@SuppressWarnings("rawtypes")
static final ValueMetadata[] defaultConverters = new ValueMetadata[] {
integralConverter,
booleanConverter,
floatingPointConverter,
stringConverter,
literalConverter
};
public static final VariableHandler<Long> LARGE_INSERT_CUTOFF =
new VariableHandler<Long>(LARGE_INSERT_THRESHOLD_NAME,
integralConverter,
globalScope,
InvokeParser.defaultLargeInsertThreshold,
dveOnly,
"How many characters to process at a time for long insert commands");
public static final VariableHandler<Long> CACHED_PLAN_LITERALS_MAX =
new VariableHandler<Long>(MAX_CACHED_LITERALS_NAME,
integralConverter,
globalScope,
100L,
dveOnly,
"Maximum number of literals per cached plan in plan cache");
public static final VariableHandler<Boolean> SLOW_QUERY_LOG =
new VariableHandler<Boolean>(SLOW_QUERY_LOG_NAME,
booleanConverter,
globalScope,
Boolean.FALSE,
emulatedOnly) {
@Override
public void onGlobalValueChange(Boolean newValue) throws PEException {
SlowQueryLogger.enableSlowQueryLogger(newValue);
}
};
public static final VariableHandler<Double> LONG_PLAN_STEP_TIME =
new VariableHandler<Double>(LONG_PLAN_STEP_TIME_NAME,
floatingPointConverter,
globalScope,
new Double(3.0),
dveOnly,
"Minimum per step trigger duration for slow query log");
public static final VariableHandler<Double> LONG_QUERY_TIME =
new VariableHandler<Double>(LONG_QUERY_TIME_NAME,
floatingPointConverter,
bothScope,
new Double(10.0),
emulatedOnly);
public static final VariableHandler<Boolean> EMULATE_MYSQL_LIMIT =
new VariableHandler<Boolean>(LIMIT_ORDERBY_EMULATION_NAME,
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Emulate mysql's limit behavior (add order by primary key if unspecified)");
public static final VariableHandler<Boolean> BALANCE_PERSISTENT_GROUPS =
new VariableHandler<Boolean>(BALANCE_PERSISTENT_GROUPS_NAME,
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Enable balanced group allocation");
public static final VariableHandler<String> BALANCE_PERSISTENT_GROUPS_PREFIX =
new VariableHandler<String>(BALANCE_PERSISTENT_GROUPS_PREFIX_NAME,
stringConverter,
globalScope,
"",
dveOnly,
"Balanced group prefix");
public static final VariableHandler<String> DYNAMIC_POLICY =
new VariableHandler<String>(DYNAMIC_POLICY_NAME,
new StringValueConverter() {
@Override
public String convertToInternal(String varName, String in) throws PEException {
String raw = stringConverter.convertToInternal(varName, in);
CatalogDAO c = CatalogDAOFactory.newInstance();
try {
c.findDynamicPolicy(raw, true);
} finally {
c.close();
}
return raw;
}
},
bothScope,
null,
nullable,
"Dynamic policy name");
public static final VariableHandler<Boolean> STEPWISE_STATISTICS =
new VariableHandler<Boolean>(STEPWISE_STATISTICS_NAME,
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Track per step execution statistics in plan cache");
public static final VariableHandler<Boolean> COST_BASED_PLANNING =
new VariableHandler<Boolean>(CARDINALITY_COSTING_NAME,
booleanConverter,
globalScope,
Boolean.TRUE,
dveOnly,
"Enable cost based planning");
public static final VariableHandler<TemplateMode> TEMPLATE_MODE =
new VariableHandler<TemplateMode>(TEMPLATE_MODE_NAME,
new EnumValueConverter<TemplateMode>(TemplateMode.values()),
globalScope,
TemplateMode.REQUIRED,
dveOnly,
"Specify behavior on missing distribution metadata injection");
public static final VariableHandler<Boolean> SHOW_METADATA_EXTENSIONS =
new VariableHandler<Boolean>(SHOW_METADATA_EXTENSIONS_NAME,
booleanConverter,
sessionScope,
Boolean.FALSE,
dveOnly,
"Show DVE specific metadata for show commands");
public static final VariableHandler<Boolean> OMIT_DIST_COMMENTS =
new VariableHandler<Boolean>(OMIT_DIST_COMMENTS_NAME,
booleanConverter,
sessionScope,
Boolean.FALSE,
dveOnly,
"Inhibit distribution declarations on show create table");
public static final VariableHandler<Long> SELECT_LIMIT =
new VariableHandler<Long>(SQL_SELECT_LIMIT_NAME,
new IntegralValueConverter() {
@Override
public Long convertToInternal(String varName, String in) throws PEException {
return super.convertToInternal(varName, in);
}
@Override
public String convertToExternal(Long in) {
if (in == null)
return VariableHandler.DEFAULT_KEYWORD;
return Long.toString(in);
}
},
sessionScope,
null,
EnumSet.of(VariableOption.NULLABLE, VariableOption.EMULATED)) {
};
public static final VariableHandler<Boolean> FOREIGN_KEY_CHECKS =
new VariableHandler<Boolean>(FOREIGN_KEY_CHECKS_NAME,
booleanConverter,
bothScope,
Boolean.TRUE,
emulated);
public static final VariableHandler<EngineTag> STORAGE_ENGINE =
new VariableHandler<EngineTag>(STORAGE_ENGINE_NAME,
new EnumValueConverter<EngineTag>(EngineTag.values()) {
@Override
public String convertToExternal(EngineTag in) {
return String.format("'%s'", in.getSQL());
}
@Override
public EngineTag convertToInternal(String varName, String in) throws PEException {
String deq = PEStringUtils.dequote(in);
String uc = deq.toUpperCase(Locale.ENGLISH);
return super.convertToInternal(varName, uc);
}
},
bothScope,
EngineTag.INNODB,
emulated);
public static final VariableHandler<Long> REPL_INSERT_ID =
new VariableHandler<Long>(REPL_SLAVE_INSERT_ID_NAME,
integralConverter,
sessionScope,
null,
EnumSet.of(VariableOption.NULLABLE),
"Replication slave last insert id");
public static final VariableHandler<Long> TIMESTAMP = new VariableHandler<Long>("timestamp",
/* As of MySQL 5.6.4, timestamp is a DOUBLE. */ new IntegralValueConverter() {
@Override
public Long convertToInternal(String varName, String in) throws PEException {
return super.convertToInternal(varName, in);
}
},
sessionScope,
0L,
EnumSet.of(VariableOption.EMULATED)) {
@Override
public Long getValue(VariableStoreSource source, VariableScopeKind vs) {
final Long currentSessionValue = super.getValue(source, vs);
if (currentSessionValue == 0) {
return TimestampVariableUtils.getCurrentSystemTime();
}
return currentSessionValue;
}
};
public static final VariableHandler<Long> REPL_TIMESTAMP =
new VariableHandler<Long>(REPL_SLAVE_TIMESTAMP_NAME,
integralConverter,
sessionScope,
null,
EnumSet.of(VariableOption.NULLABLE),
"Replication slave last timestamp");
public static final VariableHandler<SQLMode> SQL_MODE =
new VariableHandler<SQLMode>("sql_mode",
new ValueMetadata<SQLMode>() {
@Override
public SQLMode convertToInternal(String varName, String in)
throws PEException {
String raw = stringConverter.convertToInternal(varName, in);
return new SQLMode(raw);
}
@Override
public String convertToExternal(SQLMode in) {
return String.format("'%s'", in.toString());
}
@Override
public boolean isNumeric() {
return false;
}
@Override
public String getTypeName() {
return "varchar";
}
@Override
public String toRow(SQLMode in) {
return in.toString();
}
},
bothScope,
new SQLMode("NO_ENGINE_SUBSTITUTION"),
emulated) {
@Override
public void onGlobalValueChange(SQLMode newValue) throws PEException {
super.onGlobalValueChange(newValue);
}
@Override
public void setGlobalValue(VariableStoreSource conn, String value) throws PEException {
final SQLMode newModes = combineSQLMode(conn, value);
super.setGlobalValue(conn, newModes.toString());
}
@Override
public void onSessionValueChange(VariableStoreSource conn, SQLMode newValue) throws PEException {
super.onSessionValueChange(conn, newValue);
}
@Override
public void setSessionValue(VariableStoreSource conn, String value) throws PEException {
final SQLMode newModes = combineSQLMode(conn, value);
super.setSessionValue(conn, newModes.toString());
}
/**
* Combine given SQL MODEs with the ones required by DVE.
* Make sure the global values required by DVE are always
* included.
*/
private SQLMode combineSQLMode(final VariableStoreSource conn, final String value) throws PEException {
final SQLMode globalValues = getGlobalValue(conn);
final String raw = stringConverter.convertToInternal(getName(), value);
if (DEFAULT_KEYWORD.equalsIgnoreCase(raw)) {
// return the required global values
return globalValues;
}
// append new modes to the defaults
final SQLMode myValues = new SQLMode(raw);
final SQLMode combined = globalValues.add(myValues);
return combined;
}
};
public static final VariableHandler<String> COLLATION_CONNECTION =
new VariableHandler<String>(COLLATION_CONNECTION_NAME,
new LiteralValueConverter() {
@Override
public String convertToInternal(String varName, String in) throws PEException {
Singletons.require(DBNative.class).assertValidCollation(in);
return in;
}
},
bothScope,
"utf8_general_ci",
emulated) {
@Override
public void setGlobalValue(VariableStoreSource conn, String value) throws PEException {
final NativeCharSet parentCharSet =
Singletons.require(NativeCharSetCatalog.class).findCharSetByCollation(PEStringUtils.dequote(value));
if (parentCharSet != null) {
super.setGlobalValue(conn, value);
final String parentCharSetValue = parentCharSet.getName();
if (!parentCharSetValue.equals(CHARACTER_SET_CONNECTION.getGlobalValue(conn))) {
CHARACTER_SET_CONNECTION.setGlobalValue(conn, parentCharSetValue);
}
} else {
throw new SchemaException(new ErrorInfo(AvailableErrors.UNKNOWN_COLLATION, value));
}
}
@Override
public void setSessionValue(VariableStoreSource conn, String value) throws PEException {
final NativeCharSet parentCharSet =
Singletons.require(NativeCharSetCatalog.class).findCharSetByCollation(PEStringUtils.dequote(value));
if (parentCharSet != null) {
super.setSessionValue(conn, value);
final String parentCharSetValue = parentCharSet.getName();
if (!parentCharSetValue.equals(CHARACTER_SET_CONNECTION.getSessionValue(conn))) {
CHARACTER_SET_CONNECTION.setSessionValue(conn, parentCharSetValue);
}
} else {
throw new SchemaException(new ErrorInfo(AvailableErrors.UNKNOWN_COLLATION, value));
}
}
};
public static final VariableHandler<String> CHARACTER_SET_CONNECTION =
new VariableHandler<String>("character_set_connection",
stringConverter,
bothScope,
"utf8",
emulated) {
@Override
public void setGlobalValue(VariableStoreSource conn, String value) throws PEException {
final NativeCollation defaultCollation =
Singletons.require(NativeCollationCatalog.class).findDefaultCollationForCharSet(PEStringUtils.dequote(value));
if (defaultCollation != null) {
super.setGlobalValue(conn, value);
final String defaultCollationValue = defaultCollation.getName();
if (!defaultCollationValue.equals(COLLATION_CONNECTION.getGlobalValue(conn))) {
COLLATION_CONNECTION.setGlobalValue(conn, defaultCollationValue);
}
} else {
throw new SchemaException(new ErrorInfo(AvailableErrors.UNKNOWN_CHARACTER_SET, value));
}
}
@Override
public void setSessionValue(VariableStoreSource conn, String value) throws PEException {
final NativeCollation defaultCollation =
Singletons.require(NativeCollationCatalog.class).findDefaultCollationForCharSet(PEStringUtils.dequote(value));
if (defaultCollation != null) {
super.setSessionValue(conn, value);
final String defaultCollationValue = defaultCollation.getName();
if (!defaultCollationValue.equals(COLLATION_CONNECTION.getSessionValue(conn))) {
COLLATION_CONNECTION.setSessionValue(conn, defaultCollationValue);
}
} else {
throw new SchemaException(new ErrorInfo(AvailableErrors.UNKNOWN_CHARACTER_SET, value));
}
}
};
public static final VariableHandler<String> CHARACTER_SET_RESULTS =
new VariableHandler<String>("character_set_results",
stringConverter,
bothScope,
"utf8",
EnumSet.of(VariableOption.EMULATED, VariableOption.PASSTHROUGH, VariableOption.NULLABLE));
public static final VariableHandler<NativeCharSet> CHARACTER_SET_CLIENT =
new VariableHandler<NativeCharSet>(CHARACTER_SET_CLIENT_NAME,
new ValueMetadata<NativeCharSet>() {
@Override
public NativeCharSet convertToInternal(String varName,
String in) throws PEException {
final NativeCharSet charSet = MysqlNativeCharSetCatalog.DEFAULT_CATALOG.findCharSetByName(in);
if (charSet == null) {
throw new PEException(String.format("Unsupported charset for '%s': %s", varName, in));
}
return charSet;
}
@Override
public String convertToExternal(NativeCharSet in) {
return in.getName();
}
@Override
public String toRow(NativeCharSet in) {
return in.getName();
}
@Override
public boolean isNumeric() {
return false;
}
@Override
public String getTypeName() {
return "varchar";
}
},
bothScope,
MysqlNativeCharSet.UTF8,
emulated) {
public void onSessionValueChange(VariableStoreSource conn, NativeCharSet in) throws PEException {
if (conn instanceof SSConnection) {
SSConnection ssconn = (SSConnection) conn;
ssconn.setClientCharSet(in);
}
super.onSessionValueChange(conn, in);
}
};
public static final VariableHandler<Long> CACHE_LIMIT =
new VariableHandler<Long>("cache_limit",
integralConverter,
globalScope,
10000L,
dveOnly,
"Maximum uncategorized cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> SCOPE_CACHE_LIMIT =
new VariableHandler<Long>("scope_cache_limit",
integralConverter,
globalScope,
10000L,
dveOnly,
"Maximum scope cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> TENANT_CACHE_LIMIT =
new VariableHandler<Long>("tenant_cache_limit",
integralConverter,
globalScope,
500L,
dveOnly,
"Maximum tenant cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> TABLE_CACHE_LIMIT =
new VariableHandler<Long>("table_cache_limit",
integralConverter,
globalScope,
400L,
dveOnly,
"Maximum table cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final long DEFAULT_PLAN_CACHE_LIMIT = 400L;
public static final VariableHandler<Long> PLAN_CACHE_LIMIT =
new VariableHandler<Long>("plan_cache_limit",
integralConverter,
globalScope,
DEFAULT_PLAN_CACHE_LIMIT,
dveOnly,
"Maximum plan cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> RAW_PLAN_CACHE_LIMIT =
new VariableHandler<Long>("raw_plan_cache_limit",
integralConverter,
globalScope,
0L,
dveOnly,
"Maximum raw plan cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> TEMPLATE_CACHE_LIMIT =
new VariableHandler<Long>("template_cache_limit",
integralConverter,
globalScope,
100L,
dveOnly,
"Maximum template cache size (in entries)") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
// we don't push down the max_prepared_stmt_count so as to avoid issues with redist
public static final VariableHandler<Long> MAX_PREPARED_STMT_COUNT =
new VariableHandler<Long>("max_prepared_stmt_count",
integralConverter,
globalScope,
16382L,
emulatedOnly) {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
SchemaSourceFactory.setCacheSegmentLimit(CacheSegment.lookupSegment(getName()), newValue.intValue());
}
};
public static final VariableHandler<Long> REDIST_MAX_COLUMNS =
new VariableHandler<Long>("redist_max_columns",
integralConverter,
bothScope,
1000L,
dveOnly,
"Maximum number of columns per redistribution insert");
public static final VariableHandler<Long> REDIST_MAX_SIZE =
new VariableHandler<Long>("redist_max_size",
integralConverter,
bothScope,
16000000L,
dveOnly,
"Maximum byte size per redistribution insert");
public static final VariableHandler<Long> WAIT_TIMEOUT =
new VariableHandler<Long>("wait_timeout",
integralConverter,
bothScope,
28800L,
emulatedOnly,
"The number of seconds the server waits for activity on a noninteractive frontend connection before closing it");
public static final VariableHandler<Long> BACKEND_WAIT_TIMEOUT =
new VariableHandler<Long>("backend_wait_timeout",
integralConverter,
bothScope,
28800L,
EnumSet.of(VariableOption.READONLY),
"The number of seconds the server waits for activity on a backend connection before closing it");
public static final VariableHandler<Boolean> AUTOCOMMIT =
new VariableHandler<Boolean>("autocommit",
booleanConverter,
bothScope,
Boolean.TRUE,
emulated) {
@Override
public void onSessionValueChange(VariableStoreSource store, Boolean newValue) throws PEException {
((SSConnection) store).setAutoCommitMode(newValue.booleanValue());
}
@Override
public String getSessionAssignmentClause(String value) {
// does not seem correct
return "autocommit = 1";
}
};
public static final VariableHandler<String> TIME_ZONE =
new VariableHandler<String>("time_zone",
stringConverter,
bothScope,
"+00:00",
emulated);
public static final VariableHandler<String> PERSISTENT_GROUP =
new VariableHandler<String>("persistent_group",
stringConverter,
bothScope,
null,
EnumSet.of(VariableOption.NULLABLE),
"Default persistent group") {
@Override
public void setSessionValue(VariableStoreSource conn, String newValue) throws PEException {
if (conn instanceof SSConnection) {
SSConnection scon = (SSConnection) conn;
scon.getCatalogDAO().findPersistentGroup(newValue,
/* check existence */ true);
}
super.setSessionValue(conn, newValue);
}
};
public static final VariableHandler<String> GROUP_SERVICE =
new VariableHandler<String>("group_service",
new StringValueConverter() {
@Override
public String convertToInternal(String varName, String in) throws PEException {
String raw = super.convertToInternal(varName, in);
if (!GroupManager.isValidServiceType(raw))
throw new PEException("Value '" + raw + "' is not valid for variable 'group_service'");
return raw;
}
},
globalScope,
"Localhost",
dveOnly,
"Enable support for multiple DVE servers");
public static final VariableHandler<Long> MAX_CONCURRENT =
new VariableHandler<Long>("max_concurrent",
new BoundedIntegralConverter(1L, 5000L),
globalScope,
100L,
dveOnly,
"Maximum number of active concurrent connections") {
@Override
public void onGlobalValueChange(Long newValue) throws PEException {
MySqlPortalService portal = Singletons.lookup(MySqlPortalService.class);
if (portal != null)
portal.setMaxConcurrent(newValue.intValue());
}
};
public static final VariableHandler<Boolean> HAVE_SSL =
new VariableHandler<Boolean>("have_ssl",
booleanConverter,
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY));
// make this nullable to avoid some issues around initialization
public static final VariableHandler<String> VERSION_COMMENT =
new VariableHandler<String>("version_comment",
stringConverter,
bothScope,
null,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY, VariableOption.NULLABLE)) {
@Override
public String getValue(VariableStoreSource source, VariableScopeKind vs) {
return Singletons.require(HostService.class).getServerVersionComment();
}
@Override
public String getDefaultOnMissing() {
return null;
}
};
public static final VariableHandler<String> VERSION =
new VariableHandler<String>("version",
stringConverter,
bothScope,
"5.5.10",
EnumSet.of(VariableOption.READONLY, VariableOption.EMULATED));
public static final VariableHandler<Boolean> SQL_LOGGING =
new VariableHandler<Boolean>("sql_logging",
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Enable sql log") {
@Override
public void onGlobalValueChange(Boolean newValue) throws PEException {
InvokeParser.enableSqlLogging(newValue.booleanValue());
}
};
public static final VariableHandler<Long> MAX_ALLOWED_PACKET =
new VariableHandler<Long>("max_allowed_packet",
integralConverter,
globalScope,
16777216L,
emulated);
public static final VariableHandler<String> CHARACTER_SET_DATABASE =
new VariableHandler<String>("character_set_database",
new LiteralValueConverter() {
@Override
public String convertToInternal(String varName, String in) throws PEException {
Singletons.require(DBNative.class).assertValidCharacterSet(in);
return in;
}
},
bothScope,
"utf8",
emulated);
public static final VariableHandler<String> COLLATION_DATABASE =
new VariableHandler<String>("collation_database",
new LiteralValueConverter() {
@Override
public String convertToInternal(String varName, String in) throws PEException {
Singletons.require(DBNative.class).assertValidCollation(in);
return in;
}
},
bothScope,
"utf8_general_ci",
emulated);
public static final VariableHandler<Boolean> ERROR_MIGRATOR =
new VariableHandler<Boolean>("verbose_error_handling",
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Enable location information in error messages");
public static final VariableHandler<Long> INNODB_STATS_TRANSIENT_SAMPLE_PAGES =
new VariableHandler<Long>("innodb_stats_transient_sample_pages",
new BoundedIntegralConverter(1L, Long.MAX_VALUE),
globalScope,
8L,
emulatedOnly);
@SuppressWarnings("rawtypes")
static VariableHandler[] namedHandlers = new VariableHandler[] {
LARGE_INSERT_CUTOFF,
CACHED_PLAN_LITERALS_MAX,
SLOW_QUERY_LOG,
LONG_PLAN_STEP_TIME,
LONG_QUERY_TIME,
EMULATE_MYSQL_LIMIT,
BALANCE_PERSISTENT_GROUPS,
BALANCE_PERSISTENT_GROUPS_PREFIX,
DYNAMIC_POLICY,
STEPWISE_STATISTICS,
COST_BASED_PLANNING,
TEMPLATE_MODE,
SHOW_METADATA_EXTENSIONS,
OMIT_DIST_COMMENTS,
SELECT_LIMIT,
FOREIGN_KEY_CHECKS,
STORAGE_ENGINE,
REPL_INSERT_ID,
TIMESTAMP,
REPL_TIMESTAMP,
SQL_MODE,
CHARACTER_SET_CONNECTION,
CHARACTER_SET_RESULTS,
COLLATION_CONNECTION,
CHARACTER_SET_CLIENT,
CACHE_LIMIT,
SCOPE_CACHE_LIMIT,
TENANT_CACHE_LIMIT,
TABLE_CACHE_LIMIT,
PLAN_CACHE_LIMIT,
RAW_PLAN_CACHE_LIMIT,
TEMPLATE_CACHE_LIMIT,
MAX_PREPARED_STMT_COUNT,
REDIST_MAX_COLUMNS,
REDIST_MAX_SIZE,
WAIT_TIMEOUT,
BACKEND_WAIT_TIMEOUT,
AUTOCOMMIT,
TIME_ZONE,
PERSISTENT_GROUP,
GROUP_SERVICE,
MAX_CONCURRENT,
HAVE_SSL,
VERSION,
VERSION_COMMENT,
SQL_LOGGING,
MAX_ALLOWED_PACKET,
CHARACTER_SET_DATABASE,
COLLATION_DATABASE,
ERROR_MIGRATOR,
INNODB_STATS_TRANSIENT_SAMPLE_PAGES
};
@SuppressWarnings("rawtypes")
static final VariableHandler[] unnamedHandlers = new VariableHandler[] {
new VariableHandler<Long>("group_concat_max_len",
integralConverter,
bothScope,
1024L,
emulated) {
},
new VariableHandler<String>("hostname",
stringConverter,
globalScope,
"",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)) {
@Override
public String getValue(VariableStoreSource source, VariableScopeKind vs) {
return Singletons.require(HostService.class).getHostName();
}
},
new VariableHandler<Long>("auto_increment_increment",
integralConverter,
bothScope,
1L,
emulated),
new VariableHandler<String>("character_set_server",
stringConverter,
bothScope,
"utf8",
emulated),
new VariableHandler<String>("collation_server",
stringConverter,
bothScope,
"utf8_general_ci",
emulated),
new VariableHandler<Long>(ADAPTIVE_CLEANUP_INTERVAL_NAME,
new BoundedIntegralConverter(-1L, 10000L),
globalScope,
10000L,
dveOnly,
"Table garbage collector execution period (multitenant mode)") {
public void onGlobalValueChange(Long newValue) throws PEException {
Singletons.require(BootstrapHostService.class).setTableCleanupInterval(newValue.intValue(), true);
}
},
new VariableHandler<Long>(STATISTICS_INTERVAL_NAME,
new BoundedIntegralConverter(-1L, 1000L),
globalScope,
0L,
dveOnly,
"Statistics rollup interval"),
new VariableHandler<Long>("max_connections",
new BoundedIntegralConverter(1L, 5000L),
globalScope,
1000L,
dveOnly,
"Maximum number of concurrent connections") {
public void onGlobalValueChange(Long newValue) throws PEException {
SSConnection.setMaxConnections(newValue.intValue());
}
},
new VariableHandler<Long>("connection_mem_requirement",
integralConverter,
globalScope,
1000000L,
dveOnly,
"Minimum amount of memory to reserve for new connections") {
public void onGlobalValueChange(Long newValue) throws PEException {
ConnectionSemaphore.adjustMinMemory(newValue.intValue());
}
},
new VariableHandler<Boolean>("debug_context",
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Enable debug tracing") {
public void onGlobalValueChange(Boolean newValue) throws PEException {
//deprecated, but I left the variable for backwards compatibility. -sgossard
// PEThreadContext.setEnabled(newValue.booleanValue());
}
},
new VariableHandler<Long>("last_insert_id",
integralConverter,
sessionScope,
0L,
emulatedOnly),
new VariableHandler<String>("charset",
literalConverter,
sessionScope,
"utf8",
emulatedOnly),
new VariableHandler<Boolean>("sql_auto_is_null",
booleanConverter,
bothScope,
Boolean.FALSE,
emulated),
new VariableHandler<MySQLTransactionIsolation>("tx_isolation",
new EnumValueConverter<MySQLTransactionIsolation>(MySQLTransactionIsolation.values()),
bothScope,
MySQLTransactionIsolation.READ_COMMITTED,
emulated),
new VariableHandler<Boolean>("performance_trace",
booleanConverter,
globalScope,
Boolean.FALSE,
dveOnly,
"Enable performance tracing") {
@Override
public void onGlobalValueChange(Boolean newValue) throws PEException {
TimingServiceConfiguration timingConfiguration = Singletons.lookup(TimingServiceConfiguration.class);
if (timingConfiguration != null)
timingConfiguration.setTimingEnabled(newValue.booleanValue());
}
},
new VariableHandler<Long>("rand_seed1",
integralConverter,
sessionScope,
0L,
emulated),
new VariableHandler<Long>("rand_seed2",
integralConverter,
sessionScope,
0L,
emulated),
new VariableHandler<Long>("insert_id",
integralConverter,
sessionScope,
0L,
emulated),
new VariableHandler<Long>(INNODB_LOCK_WAIT_TIMEOUT_NAME,
integralConverter,
bothScope,
3L,
emulated),
new VariableHandler<Boolean>("have_innodb",
booleanConverter,
bothScope,
Boolean.TRUE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("unique_checks",
booleanConverter,
bothScope,
Boolean.TRUE,
emulated),
new VariableHandler<Boolean>("big_tables",
booleanConverter,
sessionScope,
Boolean.FALSE,
emulated),
new VariableHandler<Long>(AUTO_INCREMENT_MIN_BLOCK_SIZE,
new BoundedIntegralConverter(1L, null),
globalScope,
10L,
dveOnly,
"Minimum autoincrement allocation block size") {
public void onGlobalValueChange(Long newValue) throws PEException {
AutoIncrementTracker.setMinBlockSize(newValue.intValue());
}
},
new VariableHandler<Long>(AUTO_INCREMENT_PREFETCH_THRESHOLD,
new BoundedIntegralConverter(0L, 100L),
globalScope,
50L,
dveOnly,
"Request a new autoincrement block when this percentage of the previous block is used") {
public void onGlobalValueChange(Long newValue) throws PEException {
AutoIncrementTracker.setPrefetchThreshold(newValue.intValue());
}
},
new VariableHandler<Long>(AUTO_INCREMENT_MAX_BLOCK_SIZE,
integralConverter,
globalScope,
1000L,
dveOnly,
"Maximum autoincrement allocation block size") {
public void onGlobalValueChange(Long newValue) throws PEException {
AutoIncrementTracker.setMaxBlockSize(newValue.intValue());
}
},
new VariableHandler<Long>("sql_quote_show_create",
new BoundedIntegralConverter(-1L, 2L),
bothScope,
1L,
emulated),
new VariableHandler<Long>("sql_notes",
new BoundedIntegralConverter(-1L, 2L),
bothScope,
1L,
emulated),
new VariableHandler<String>("init_connect",
stringConverter,
globalScope,
"",
emulated),
new VariableHandler<Long>("interactive_timeout",
new BoundedIntegralConverter(0L, null),
bothScope,
28800L,
emulated),
new VariableHandler<Long>("lower_case_table_names",
new BoundedIntegralConverter(-1L, 3L),
globalScope,
1L,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Long>("net_buffer_length",
new BoundedIntegralConverter(1023L, 1048577L),
bothScope,
16384L,
emulatedOnly),
new VariableHandler<Long>("net_write_timeout",
new BoundedIntegralConverter(0L, null),
bothScope,
60L,
emulated),
new VariableHandler<String>("system_time_zone",
stringConverter,
globalScope,
"EDT", // todo: change this
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Long>("query_cache_size",
new BoundedIntegralConverter(-1L, 4294967296L), // maybe not right?
globalScope,
41943040L,
emulatedOnly),
new VariableHandler<Long>("query_cache_type",
new BoundedIntegralConverter(-1L, 3L),
bothScope,
1L,
emulatedOnly),
new VariableHandler<Boolean>("have_dynamic_loading",
booleanConverter,
bothScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("version_compile_os",
stringConverter,
bothScope,
"debian-linux-gnu",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("have_geometry",
booleanConverter,
globalScope,
Boolean.TRUE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Long>("myisam_sort_buffer_size",
new BoundedIntegralConverter(4095L, Long.MAX_VALUE),
bothScope,
8388608L,
emulated),
new VariableHandler<Long>("sort_buffer_size",
new BoundedIntegralConverter(32767L, Long.MAX_VALUE),
bothScope,
2097144L,
emulated),
new VariableHandler<Boolean>("lower_case_file_system",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("have_query_cache",
booleanConverter,
globalScope,
Boolean.TRUE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("have_openssl" /* Alias for 'have_ssl'. */,
booleanConverter,
globalScope,
HAVE_SSL.getDefaultOnMissing(),
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<ThreadHandlingMode>("thread_handling",
new EnumValueConverter<ThreadHandlingMode>(ThreadHandlingMode.values()),
globalScope,
ThreadHandlingMode.ONE_THREAD_PER_CONNECTION,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("have_partitioning",
booleanConverter,
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("time_format",
stringConverter,
globalScope,
"%H:%i:%s",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Long>("thread_concurrency",
integralConverter,
globalScope,
10L,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("log_bin",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("license",
stringConverter,
globalScope,
"AGPL",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("innodb_version" /* Alias for 'version'. */,
stringConverter,
globalScope,
VERSION.getDefaultOnMissing(),
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("ignore_builtin_innodb",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("have_profiling",
booleanConverter,
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("datetime_format",
stringConverter,
globalScope,
"%Y-%m-%d %H:%i:%s",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("date_format",
stringConverter,
globalScope,
"%Y-%m-%d",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<String>("character_set_system",
stringConverter,
globalScope,
"utf8",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Long>("div_precision_increment",
new BoundedIntegralConverter(0L, 30L),
bothScope,
4L,
emulated),
new VariableHandler<Long>("default_week_format",
new BoundedIntegralConverter(0L, 7L),
bothScope,
0L,
emulated),
new VariableHandler<String>("version_compile_machine",
stringConverter,
globalScope,
"64-bit",
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("innodb_adaptive_flushing",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.TRUE,
emulatedOnly),
new VariableHandler<Long>("innodb_fast_shutdown",
new BoundedIntegralConverter(0L, 2L),
globalScope,
1L,
emulatedOnly),
new VariableHandler<Long>("innodb_mirrored_log_groups",
integralConverter,
globalScope,
1L,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<InnoDbStatsMethod>("innodb_stats_method",
new EnumValueConverter<InnoDbStatsMethod>(InnoDbStatsMethod.values()),
globalScope,
InnoDbStatsMethod.NULLS_EQUAL,
emulatedOnly),
new VariableHandler<Long>("innodb_stats_sample_pages" /* Replaced by 'innodb_stats_transient_sample_pages' in 5.6. */,
INNODB_STATS_TRANSIENT_SAMPLE_PAGES.getMetadata(),
INNODB_STATS_TRANSIENT_SAMPLE_PAGES.getScopes(),
INNODB_STATS_TRANSIENT_SAMPLE_PAGES.getDefaultOnMissing(),
INNODB_STATS_TRANSIENT_SAMPLE_PAGES.getOptions()),
new VariableHandler<Boolean>("innodb_table_locks",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
bothScope,
Boolean.TRUE,
emulated),
new VariableHandler<Boolean>("myisam_use_mmap",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.FALSE,
emulatedOnly),
new VariableHandler<Long>("tmp_table_size",
new BoundedIntegralConverter(1024L, Long.MAX_VALUE),
bothScope,
16777216L,
emulated),
new VariableHandler<Long>("protocol_version",
integralConverter,
globalScope,
10L,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY)),
new VariableHandler<Boolean>("skip_networking",
new BooleanValueConverter(BooleanToStringConverter.ON_OFF_CONVERTER),
globalScope,
Boolean.FALSE,
EnumSet.of(VariableOption.EMULATED, VariableOption.READONLY))
};
}