Unverified 提交 c1608d05 authored 作者: Andrei Tokar's avatar Andrei Tokar 提交者: GitHub

Merge pull request #1621 from h2database/issue_1619

Issue for #1619: postpone table analysis until after transaction commit
...@@ -670,16 +670,6 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -670,16 +670,6 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
public void commit(boolean ddl) { public void commit(boolean ddl) {
checkCommitRollback(); checkCommitRollback();
int rowCount = getDatabase().getSettings().analyzeSample / 10;
if (tablesToAnalyze != null) {
for (Table table : tablesToAnalyze) {
Analyze.analyzeTable(this, table, rowCount, false);
}
// analyze can lock the meta
database.unlockMeta(this);
}
tablesToAnalyze = null;
currentTransactionName = null; currentTransactionName = null;
transactionStart = null; transactionStart = null;
if (transaction != null) { if (transaction != null) {
...@@ -717,9 +707,29 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -717,9 +707,29 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
} }
} }
if (tablesToAnalyze != null) {
if (database.isMVStore()) {
// table analysis will cause a new transaction(s) to be opened,
// so we need to commit afterwards whatever leftovers might be
analyzeTables();
commit(true);
} else {
analyzeTables();
}
}
endTransaction(); endTransaction();
} }
private void analyzeTables() {
int rowCount = getDatabase().getSettings().analyzeSample / 10;
for (Table table : tablesToAnalyze) {
Analyze.analyzeTable(this, table, rowCount, false);
}
// analyze can lock the meta
database.unlockMeta(this);
tablesToAnalyze = null;
}
private void removeTemporaryLobs(boolean onTimeout) { private void removeTemporaryLobs(boolean onTimeout) {
assert this != getDatabase().getLobSession() || Thread.holdsLock(this) || Thread.holdsLock(getDatabase()); assert this != getDatabase().getLobSession() || Thread.holdsLock(this) || Thread.holdsLock(getDatabase());
if (temporaryLobs != null) { if (temporaryLobs != null) {
......
...@@ -456,7 +456,7 @@ public class Transaction { ...@@ -456,7 +456,7 @@ public class Transaction {
if (status != STATUS_OPEN) { if (status != STATUS_OPEN) {
throw DataUtils.newIllegalStateException( throw DataUtils.newIllegalStateException(
DataUtils.ERROR_TRANSACTION_ILLEGAL_STATE, DataUtils.ERROR_TRANSACTION_ILLEGAL_STATE,
"Transaction {0} has status {1}, not open", transactionId, status); "Transaction {0} has status {1}, not OPEN", transactionId, STATUS_NAMES[status]);
} }
} }
......
...@@ -21,6 +21,7 @@ import org.h2.test.auth.TestAuthentication; ...@@ -21,6 +21,7 @@ import org.h2.test.auth.TestAuthentication;
import org.h2.test.bench.TestPerformance; import org.h2.test.bench.TestPerformance;
import org.h2.test.db.TestAlter; import org.h2.test.db.TestAlter;
import org.h2.test.db.TestAlterSchemaRename; import org.h2.test.db.TestAlterSchemaRename;
import org.h2.test.db.TestAnalyzeTableTx;
import org.h2.test.db.TestAutoRecompile; import org.h2.test.db.TestAutoRecompile;
import org.h2.test.db.TestBackup; import org.h2.test.db.TestBackup;
import org.h2.test.db.TestBigDb; import org.h2.test.db.TestBigDb;
...@@ -845,6 +846,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -845,6 +846,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestMvccMultiThreaded()); addTest(new TestMvccMultiThreaded());
addTest(new TestMvccMultiThreaded2()); addTest(new TestMvccMultiThreaded2());
addTest(new TestRowLocks()); addTest(new TestRowLocks());
addTest(new TestAnalyzeTableTx());
// synth // synth
addTest(new TestBtreeIndex()); addTest(new TestBtreeIndex());
......
/*
* Copyright 2004-2017 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.db;
import org.h2.test.TestBase;
import org.h2.test.TestDb;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestAnalyzeTableTx extends TestDb {
static final int C = 10_000;
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public boolean isEnabled() {
if (config.networked || config.big) {
return false;
}
return true;
}
@Override
public void test() throws Exception {
deleteDb(getTestName());
Connection shared = getConnection(getTestName());
Statement statement = shared.createStatement();
statement.executeUpdate("DROP TABLE IF EXISTS TEST");
statement.executeUpdate("CREATE TABLE TEST(ID INT PRIMARY KEY)");
Connection[] connections = new Connection[C];
for (int i = 0; i < C; i++) {
Connection c = getConnection(getTestName());
c.createStatement().executeUpdate("INSERT INTO TEST VALUES (" + i + ')');
connections[i] = c;
}
try (ResultSet rs = statement.executeQuery("SELECT * FROM TEST")) {
for (int i = 0; i < C; i++) {
if (!rs.next())
throw new Exception("next");
if (rs.getInt(1) != i)
throw new Exception(Integer.toString(i));
}
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论