提交 73e73d4b authored 作者: Noel Grandin's avatar Noel Grandin

Merge pull request #170 from doblak/master

added SET QUERY_STATISTICS_MAX_ENTRIES
......@@ -1481,6 +1481,19 @@ Admin rights are required to execute this command, as it affects all connections
SET QUERY_STATISTICS FALSE
"
"Commands (Other)","SET QUERY_STATISTICS_MAX_ENTRIES","
SET QUERY_STATISTICS int
","
Set the maximum number of entries in query statistics meta-table.
Default value is 100.
This setting is not persistent.
This command commits an open transaction in this connection.
Admin rights are required to execute this command, as it affects all connections.
","
SET QUERY_STATISTICS_MAX_ENTRIES 500
"
"Commands (Other)","SET QUERY_TIMEOUT","
SET QUERY_TIMEOUT int
","
......
......@@ -393,6 +393,16 @@ public class Set extends Prepared {
database.setQueryStatistics(value == 1);
break;
}
case SetTypes.QUERY_STATISTICS_MAX_ENTRIES: {
session.getUser().checkAdmin();
int value = getIntValue();
if (value < 1) {
throw DbException.getInvalidValueException("QUERY_STATISTICS_MAX_ENTRIES",
getIntValue());
}
database.setQueryStatisticsMaxEntries(value);
break;
}
case SetTypes.SCHEMA: {
Schema schema = database.getSchema(stringValue);
session.setCurrentSchema(schema);
......
......@@ -218,6 +218,11 @@ public class SetTypes {
*/
public static final int QUERY_STATISTICS = 41;
/**
* The type of a SET QUERY_STATISTICS_MAX_ENTRIES statement.
*/
public static final int QUERY_STATISTICS_MAX_ENTRIES = 42;
private static final ArrayList<String> TYPES = New.arrayList();
private SetTypes() {
......@@ -268,6 +273,7 @@ public class SetTypes {
list.add(JAVA_OBJECT_SERIALIZER, "JAVA_OBJECT_SERIALIZER");
list.add(RETENTION_TIME, "RETENTION_TIME");
list.add(QUERY_STATISTICS, "QUERY_STATISTICS");
list.add(QUERY_STATISTICS_MAX_ENTRIES, "QUERY_STATISTICS_MAX_ENTRIES");
}
/**
......
......@@ -505,6 +505,11 @@ public class Constants {
*/
public static final int VIEW_INDEX_CACHE_SIZE = 64;
/**
* The maximum number of entries in query statistics.
*/
public static final int QUERY_STATISTICS_MAX_ENTRIES = 100;
private Constants() {
// utility class
}
......
......@@ -189,6 +189,7 @@ public class Database implements DataHandler {
private String javaObjectSerializerName;
private volatile boolean javaObjectSerializerInitialized;
private boolean queryStatistics;
private int queryStatisticsMaxEntries = Constants.QUERY_STATISTICS_MAX_ENTRIES;
private QueryStatisticsData queryStatisticsData;
public Database(ConnectionInfo ci, String cipher) {
......@@ -2260,6 +2261,17 @@ public class Database implements DataHandler {
return queryStatistics;
}
public void setQueryStatisticsMaxEntries(int n) {
queryStatisticsMaxEntries = n;
if (queryStatisticsData != null) {
synchronized (this) {
if (queryStatisticsData != null) {
queryStatisticsData.setMaxQueryEntries(queryStatisticsMaxEntries);
}
}
}
}
public QueryStatisticsData getQueryStatisticsData() {
if (!queryStatistics) {
return null;
......@@ -2267,7 +2279,7 @@ public class Database implements DataHandler {
if (queryStatisticsData == null) {
synchronized (this) {
if (queryStatisticsData == null) {
queryStatisticsData = new QueryStatisticsData();
queryStatisticsData = new QueryStatisticsData(queryStatisticsMaxEntries);
}
}
}
......
......@@ -19,8 +19,6 @@ import java.util.Map.Entry;
*/
public class QueryStatisticsData {
private static final int MAX_QUERY_ENTRIES = 100;
private static final Comparator<QueryEntry> QUERY_ENTRY_COMPARATOR =
new Comparator<QueryEntry>() {
@Override
......@@ -32,6 +30,16 @@ public class QueryStatisticsData {
private final HashMap<String, QueryEntry> map =
new HashMap<String, QueryEntry>();
private int maxQueryEntries;
public QueryStatisticsData(int maxQueryEntries) {
this.maxQueryEntries = maxQueryEntries;
}
public synchronized void setMaxQueryEntries(int maxQueryEntries) {
this.maxQueryEntries = maxQueryEntries;
}
public synchronized List<QueryEntry> getQueries() {
// return a copy of the map so we don't have to
// worry about external synchronization
......@@ -39,7 +47,7 @@ public class QueryStatisticsData {
list.addAll(map.values());
// only return the newest 100 entries
Collections.sort(list, QUERY_ENTRY_COMPARATOR);
return list.subList(0, Math.min(list.size(), MAX_QUERY_ENTRIES));
return list.subList(0, Math.min(list.size(), maxQueryEntries));
}
/**
......@@ -62,7 +70,7 @@ public class QueryStatisticsData {
// Age-out the oldest entries if the map gets too big.
// Test against 1.5 x max-size so we don't do this too often
if (map.size() > MAX_QUERY_ENTRIES * 1.5f) {
if (map.size() > maxQueryEntries * 1.5f) {
// Sort the entries by age
ArrayList<QueryEntry> list = new ArrayList<QueryEntry>();
list.addAll(map.values());
......
......@@ -56,6 +56,7 @@ public class TestMetaData extends TestBase {
testClientInfo();
testSessionsUncommitted();
testQueryStatistics();
testQueryStatisticsLimit();
}
private void testUnwrap() throws SQLException {
......@@ -1260,4 +1261,46 @@ public class TestMetaData extends TestBase {
conn.close();
deleteDb("metaData");
}
private void testQueryStatisticsLimit() throws SQLException {
Connection conn = getConnection("metaData");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar) as " +
"select x, space(1000) from system_range(1, 2000)");
ResultSet rs = stat.executeQuery(
"select * from INFORMATION_SCHEMA.QUERY_STATISTICS");
assertFalse(rs.next());
rs.close();
//first, test setting the limit before activating statistics
int statisticsMaxEntries = 200;
//prevent test limit being less than or equal to default limit
assertTrue(statisticsMaxEntries > Constants.QUERY_STATISTICS_MAX_ENTRIES);
stat.execute("SET QUERY_STATISTICS_MAX_ENTRIES " + statisticsMaxEntries);
stat.execute("SET QUERY_STATISTICS TRUE");
for (int i = 0; i < statisticsMaxEntries * 2; i++) {
stat.execute("select * from test where id = " + i);
}
rs = stat.executeQuery("select count(*) from INFORMATION_SCHEMA.QUERY_STATISTICS");
assertTrue(rs.next());
assertEquals(statisticsMaxEntries, rs.getInt(1));
rs.close();
//first, test changing the limit once statistics is activated
int statisticsMaxEntriesNew = 50;
//prevent new test limit being greater than or equal to default limit
assertTrue(statisticsMaxEntriesNew < Constants.QUERY_STATISTICS_MAX_ENTRIES);
stat.execute("SET QUERY_STATISTICS_MAX_ENTRIES " + statisticsMaxEntriesNew);
for (int i = 0; i < statisticsMaxEntriesNew * 2; i++) {
stat.execute("select * from test where id = " + i);
}
rs = stat.executeQuery("select count(*) from INFORMATION_SCHEMA.QUERY_STATISTICS");
assertTrue(rs.next());
assertEquals(statisticsMaxEntriesNew, rs.getInt(1));
rs.close();
conn.close();
deleteDb("metaData");
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论