提交 359dfbce authored 作者: Owner's avatar Owner

Reconnecting shows persistance problem

上级 e7d335f2
...@@ -5221,6 +5221,9 @@ public class Parser { ...@@ -5221,6 +5221,9 @@ public class Parser {
ArrayList<Column> columns = New.arrayList(); ArrayList<Column> columns = New.arrayList();
String[] cols = null; String[] cols = null;
Database db = targetSession.getDatabase(); Database db = targetSession.getDatabase();
System.out.println("systemSessionId="+database.getSystemSession().getId());
System.out.println("sessionId="+session.getId());
// column names are now optional - they can be inferred from the named // column names are now optional - they can be inferred from the named
// query, if not supplied by user // query, if not supplied by user
......
...@@ -130,7 +130,9 @@ public class CreateView extends SchemaCommand { ...@@ -130,7 +130,9 @@ public class CreateView extends SchemaCommand {
view.setComment(comment); view.setComment(comment);
} }
if (old == null) { if (old == null) {
System.out.println("addSchemaObject="+view.getName()+",sessionId="+session.getId());
db.addSchemaObject(session, view); db.addSchemaObject(session, view);
db.unlockMeta(session);
} else { } else {
db.updateMeta(session, view); db.updateMeta(session, view);
} }
......
...@@ -69,10 +69,11 @@ public class DropView extends SchemaCommand { ...@@ -69,10 +69,11 @@ public class DropView extends SchemaCommand {
} }
// TODO: Where is the ConstraintReferential.CASCADE style drop processing ? It's // TODO: Where is the ConstraintReferential.CASCADE style drop processing ? It's
// supported from imported keys - but not for dependant // supported from imported keys - but not for dependent db objects
view.lock(session, true, true); view.lock(session, true, true);
session.getDatabase().removeSchemaObject(session, view); session.getDatabase().removeSchemaObject(session, view);
session.getDatabase().unlockMeta(session);
session.getDatabase().flushDeferredRemoveSchemaObject(); session.getDatabase().flushDeferredRemoveSchemaObject();
} }
return 0; return 0;
......
...@@ -927,14 +927,20 @@ public class Database implements DataHandler { ...@@ -927,14 +927,20 @@ public class Database implements DataHandler {
} else if (prev != session) { } else if (prev != session) {
metaLockDebuggingStack.get().printStackTrace(); metaLockDebuggingStack.get().printStackTrace();
throw new IllegalStateException("meta currently locked by " throw new IllegalStateException("meta currently locked by "
+ prev + prev +", sessionid="+ prev.getId()
+ " and trying to be locked by different session, " + " and trying to be locked by different session, "
+ session + " on same thread"); + session +", sessionid="+ session.getId() + " on same thread");
} }
} }
boolean wasLocked = meta.lock(session, true, true); boolean wasLocked = meta.lock(session, true, true);
return wasLocked; return wasLocked;
} }
public void traceLock(){
if(metaLockDebuggingStack.get()!=null && metaLockDebugging.get() !=null){
System.out.println("traceLock: Meta locked by sessionId="+metaLockDebugging.get().getId());
metaLockDebuggingStack.get().printStackTrace();
}
}
/** /**
* Lock the metadata table for updates - but don't wait if it's already locked... * Lock the metadata table for updates - but don't wait if it's already locked...
...@@ -1890,7 +1896,7 @@ public class Database implements DataHandler { ...@@ -1890,7 +1896,7 @@ public class Database implements DataHandler {
* @param session the session * @param session the session
* @param obj the object to be removed * @param obj the object to be removed
*/ */
public void removeSchemaObject(Session session, public boolean removeSchemaObject(Session session,
SchemaObject obj) { SchemaObject obj) {
int type = obj.getType(); int type = obj.getType();
if (type == DbObject.TABLE_OR_VIEW) { if (type == DbObject.TABLE_OR_VIEW) {
...@@ -1898,31 +1904,32 @@ public class Database implements DataHandler { ...@@ -1898,31 +1904,32 @@ public class Database implements DataHandler {
table.setBeingDropped(true); table.setBeingDropped(true);
if (table.isTemporary() && !table.isGlobalTemporary()) { if (table.isTemporary() && !table.isGlobalTemporary()) {
session.removeLocalTempTable(table); session.removeLocalTempTable(table);
return; return true;
} }
} else if (type == DbObject.INDEX) { } else if (type == DbObject.INDEX) {
Index index = (Index) obj; Index index = (Index) obj;
Table table = index.getTable(); Table table = index.getTable();
if (table.isTemporary() && !table.isGlobalTemporary()) { if (table.isTemporary() && !table.isGlobalTemporary()) {
session.removeLocalTempTableIndex(index); session.removeLocalTempTableIndex(index);
return; return true;
} }
} else if (type == DbObject.CONSTRAINT) { } else if (type == DbObject.CONSTRAINT) {
Constraint constraint = (Constraint) obj; Constraint constraint = (Constraint) obj;
Table table = constraint.getTable(); Table table = constraint.getTable();
if (table.isTemporary() && !table.isGlobalTemporary()) { if (table.isTemporary() && !table.isGlobalTemporary()) {
session.removeLocalTempTableConstraint(constraint); session.removeLocalTempTableConstraint(constraint);
return; return true;
} }
} }
checkWritingAllowed(); checkWritingAllowed();
Boolean wasLocked = lockMetaNoWait(session); Boolean wasLocked = lockMetaNoWait(session);// was
if(wasLocked==null){ if(wasLocked==null){
removeSchemaObjectQueue.put(obj,session); removeSchemaObjectQueue.put(obj,session);
System.out.println("deferred removal scheduled="+obj.getName()+",wasLocked="+wasLocked); System.out.println("deferred removal scheduled="+obj.getName()+",wasLocked="+wasLocked);
return; return false;
} }
synchronized (this) { synchronized (this) {
String savedName = obj.getName();
Comment comment = findComment(obj); Comment comment = findComment(obj);
if (comment != null) { if (comment != null) {
removeDatabaseObject(session, comment); removeDatabaseObject(session, comment);
...@@ -1937,30 +1944,41 @@ public class Database implements DataHandler { ...@@ -1937,30 +1944,41 @@ public class Database implements DataHandler {
t.getSQL()); t.getSQL());
} }
obj.removeChildrenAndResources(session); obj.removeChildrenAndResources(session);
} }
System.out.println("Removing meta lock"); System.out.println("Removing db object id - also remove meta lock from session and session lock from meta, id="+id+",sessionId="+session.getId()+",name="+savedName);
removeMeta(session, id); removeMeta(session, id);
flushDeferredRemoveSchemaObject(); flushDeferredRemoveSchemaObject();
return true;
} }
} }
public void flushDeferredRemoveSchemaObject() { public void flushDeferredRemoveSchemaObject() {
Iterator<Entry<SchemaObject, Session>> i = removeSchemaObjectQueue.entrySet().iterator(); boolean progress = true;
while(i.hasNext()){ while(progress){
Entry<SchemaObject, Session> pair = i.next(); progress = false;
i.remove(); Iterator<Entry<SchemaObject, Session>> i = removeSchemaObjectQueue.entrySet().iterator();
System.out.println("re-attempting deferred removal="+pair.getKey().getName()+",size="+removeSchemaObjectQueue.size()); while(i.hasNext()){
removeSchemaObject(pair.getValue(),pair.getKey()); Entry<SchemaObject, Session> pair = i.next();
if(!removeSchemaObjectQueue.contains(pair.getKey())){ i.remove();
System.out.println("completed deferred removal="+pair.getKey().getName()+",size="+removeSchemaObjectQueue.size()); System.out.println("re-attempting deferred removal="+pair.getKey().getName()+",size="+removeSchemaObjectQueue.size());
progress = removeSchemaObject(pair.getValue(),pair.getKey());
if(progress){
System.out.println("completed deferred removal="+pair.getKey().getName()+",size="+removeSchemaObjectQueue.size());
unlockMeta(pair.getValue());
}
} }
} }
System.out.println("flushDeferredRemoveSchemaObject.remove_q_size="+removeSchemaObjectQueue.size());
if(removeSchemaObjectQueue.size()!=0){
traceLock();
}
} }
/** /**
* Check if this database disk-based. * Check if this database is disk-based.
* *
* @return true if it is disk-based, false it it is in-memory only. * @return true if it is disk-based, false it it is in-memory only.
*/ */
......
...@@ -438,7 +438,7 @@ public class MVTable extends TableBase { ...@@ -438,7 +438,7 @@ public class MVTable extends TableBase {
} }
return localSession == session; return localSession == session;
} }
@Override @Override
public void unlock(Session s) { public void unlock(Session s) {
if (database != null) { if (database != null) {
......
...@@ -23,7 +23,7 @@ org.h2.tools.Console=Starts the H2 Console (web-) server, as well as the TCP and ...@@ -23,7 +23,7 @@ org.h2.tools.Console=Starts the H2 Console (web-) server, as well as the TCP and
org.h2.tools.Console.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url] Start a browser and connect to this URL\n[-driver] Used together with -url\: the driver\n[-user] Used together with -url\: the user name\n[-password] Used together with -url\: the password\n[-web] Start the web server with the H2 Console\n[-tool] Start the icon or window that allows to start a browser\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-pg] Start the PG server\nFor each Server, additional options are available;\n for details, see the Server tool.\nIf a service can not be started, the program\n terminates with an exit code of 1. org.h2.tools.Console.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url] Start a browser and connect to this URL\n[-driver] Used together with -url\: the driver\n[-user] Used together with -url\: the user name\n[-password] Used together with -url\: the password\n[-web] Start the web server with the H2 Console\n[-tool] Start the icon or window that allows to start a browser\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-pg] Start the PG server\nFor each Server, additional options are available;\n for details, see the Server tool.\nIf a service can not be started, the program\n terminates with an exit code of 1.
org.h2.tools.ConvertTraceFile=Converts a .trace.db file to a SQL script and Java source code.\nSQL statement statistics are listed as well. org.h2.tools.ConvertTraceFile=Converts a .trace.db file to a SQL script and Java source code.\nSQL statement statistics are listed as well.
org.h2.tools.ConvertTraceFile.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-traceFile <file>] The trace file name (default\: test.trace.db)\n[-script <file>] The script file name (default\: test.sql)\n[-javaClass <file>] The Java directory and class file name (default\: Test) org.h2.tools.ConvertTraceFile.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-traceFile <file>] The trace file name (default\: test.trace.db)\n[-script <file>] The script file name (default\: test.sql)\n[-javaClass <file>] The Java directory and class file name (default\: Test)
org.h2.tools.CreateCluster=Creates a cluster from a standalone database.\nCopies a database to another location if required. org.h2.tools.CreateCluster=Creates a cluster from a stand-alone database.\nCopies a database to another location if required.
org.h2.tools.CreateCluster.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-urlSource "<url>"] The database URL of the source database (jdbc\:h2\:...)\n[-urlTarget "<url>"] The database URL of the target database (jdbc\:h2\:...)\n[-user <user>] The user name (default\: sa)\n[-password <pwd>] The password\n[-serverList <list>] The comma separated list of host names or IP addresses org.h2.tools.CreateCluster.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-urlSource "<url>"] The database URL of the source database (jdbc\:h2\:...)\n[-urlTarget "<url>"] The database URL of the target database (jdbc\:h2\:...)\n[-user <user>] The user name (default\: sa)\n[-password <pwd>] The password\n[-serverList <list>] The comma separated list of host names or IP addresses
org.h2.tools.DeleteDbFiles=Deletes all files belonging to a database.\nThe database must be closed before calling this tool. org.h2.tools.DeleteDbFiles=Deletes all files belonging to a database.\nThe database must be closed before calling this tool.
org.h2.tools.DeleteDbFiles.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-dir <dir>] The directory (default\: .)\n[-db <database>] The database name\n[-quiet] Do not print progress information org.h2.tools.DeleteDbFiles.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-dir <dir>] The directory (default\: .)\n[-db <database>] The database name\n[-quiet] Do not print progress information
......
...@@ -701,9 +701,10 @@ public class TableView extends Table { ...@@ -701,9 +701,10 @@ public class TableView extends Table {
super.removeView(view); super.removeView(view);
// if this is a table expression and the last view to use it is // if this is a table expression and the last view to use it is
// being dropped - then remove itself from the schema // being dropped - then remove itself from the schema
if(isTableExpression() && getViews()!=null && view.isBeingDropped()){ if(isTableExpression() && getViews()!=null){
// check if any database objects are left using this view // check if any database objects are left using this view
if(getViews().size()==0){ if(getViews().size()==0 && !isBeingDropped()){
System.out.println("Detected unused CTE: Trying to remove="+this.getName()+",session="+session.toString()+",sessionId="+session.getId());
session.getDatabase().removeSchemaObject(session,this); session.getDatabase().removeSchemaObject(session,this);
} }
} }
......
...@@ -29,20 +29,23 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -29,20 +29,23 @@ public class TestGeneralCommonTableQueries extends TestBase {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
testSimpleSelect(); // testSimpleSelect();
testImpliedColumnNames(); // testImpliedColumnNames();
testChainedQuery(); // testChainedQuery();
testParameterizedQuery(); // testParameterizedQuery();
testNumberedParameterizedQuery(); // testNumberedParameterizedQuery();
testColumnNames(); // testColumnNames();
//
testInsert(); // testInsert();
testUpdate(); // testUpdate();
testDelete(); // testDelete();
testMerge(); // testMerge();
testCreateTable(); // testCreateTable();
testNestedSQL(); // testNestedSQL();
testRecursiveTable(); // testRecursiveTable();
// turn on special locking debug
System.setProperty("h2.check2", "true");
// persistent cte tests // persistent cte tests
testPersistentNonRecursiveTableInCreateView(); testPersistentNonRecursiveTableInCreateView();
...@@ -568,7 +571,7 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -568,7 +571,7 @@ public class TestGeneralCommonTableQueries extends TestBase {
String[] expectedColumnNames =new String[]{"SUB_TREE_ROOT_ID","TREE_LEVEL","PARENT_FK","CHILD_FK"}; String[] expectedColumnNames =new String[]{"SUB_TREE_ROOT_ID","TREE_LEVEL","PARENT_FK","CHILD_FK"};
int expectedNumberOfRows = 11; int expectedNumberOfRows = 11;
testRepeatedQueryWithSetup(maxRetries, expectedRowData, expectedColumnNames, expectedNumberOfRows, SETUP_SQL, testRepeatedQueryWithSetup(maxRetries, expectedRowData, expectedColumnNames, expectedNumberOfRows, SETUP_SQL,
WITH_QUERY, maxRetries-1); WITH_QUERY, 0/*maxRetries-1*/);
} }
private void testPersistentNonRecursiveTableInCreateView() throws Exception { private void testPersistentNonRecursiveTableInCreateView() throws Exception {
String SETUP_SQL = "" String SETUP_SQL = ""
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论