List:Commits« Previous MessageNext Message »
From:jonas Date:May 19 2008 5:31pm
Subject:bk commit into 5.1 tree (jonas:1.2598)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jonas.  When jonas does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-05-19 17:31:04+02:00, jonas@stripped +25 -0
  ndb - wl3600++
      - introduce transaction schema entry, to handle multi-op transaction (anc schema
file batching)
      - convert DD to 3600
      - unify restart handling

  mysql-test/suite/ndb/r/ndb_dd_basic.result@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +8 -0
    test drop file abort prepare

  mysql-test/suite/ndb/t/ndb_dd_basic.test@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +11 -0
    test drop file abort prepare

  storage/ndb/include/kernel/GlobalSignalNumbers.h@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +12 -12
    remove old transaction framework and add new signals needed to fit DD into wl3600

  storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +32 -11
    adopt to wl3600

  storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +12 -8
    adopt to wl3600

  storage/ndb/include/kernel/signaldata/DictTabInfo.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +3 -1
    add schema transaction as schema object (used by transactions)

  storage/ndb/include/kernel/signaldata/DropFilegroup.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +34 -12
    adopt to wl3600

  storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +5 -2
    adopt to wl3600

  storage/ndb/include/kernel/signaldata/SchemaTrans.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +2 -1
    add transaction generic error code

  storage/ndb/src/common/debugger/signaldata/SignalNames.cpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +14 -15
    adopt to wl3600

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +2281 -3365
    wl3600++
    - introduce transaction schema entry, to handle multi-op transaction (anc schema file
batching)
    - convert DD to 3600
    - unify restart handling

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +233 -172
    wl3600++
    - introduce transaction schema entry, to handle multi-op transaction (anc schema file
batching)
    - convert DD to 3600
    - unify restart handling

  storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +33 -13
    wl3600++
    - introduce transaction schema entry, to handle multi-op transaction (anc schema file
batching)
    - convert DD to 3600
    - unify restart handling

  storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +3 -4
    wl3600++
    - introduce transaction schema entry, to handle multi-op transaction (anc schema file
batching)
    - convert DD to 3600
    - unify restart handling

  storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +5 -4
    use define for SYSTAB_0 table id

  storage/ndb/src/kernel/blocks/lgman.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +24 -21
    adopt to wl3600

  storage/ndb/src/kernel/blocks/lgman.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +4 -4
    adopt to wl3600

  storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +1 -1
    save table versions

  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +2 -1
    save table versions

  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp@stripped, 2008-05-19
17:31:02+02:00, jonas@stripped +2 -2
    save table versions

  storage/ndb/src/kernel/blocks/tsman.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +23 -23
    adopt to wl3600

  storage/ndb/src/kernel/blocks/tsman.hpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +4 -4
    adopt to wl3600

  storage/ndb/src/ndbapi/NdbDictionary.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +40 -16
    wrap DD in transactions

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +13 -1
    wrap DD in transactions

  storage/ndb/test/ndbapi/testDict.cpp@stripped, 2008-05-19 17:31:02+02:00,
jonas@stripped +2 -2
    changed error codes

diff -Nrup a/mysql-test/suite/ndb/r/ndb_dd_basic.result
b/mysql-test/suite/ndb/r/ndb_dd_basic.result
--- a/mysql-test/suite/ndb/r/ndb_dd_basic.result	2008-02-03 21:29:20 +01:00
+++ b/mysql-test/suite/ndb/r/ndb_dd_basic.result	2008-05-19 17:31:02 +02:00
@@ -204,6 +204,14 @@ PRIMARY KEY (ID)
 ) ENGINE=ndbcluster
 tablespace ts2
 storage disk;
+create table t1 (a int primary key, b int)
+engine = ndbcluster tablespace ts2 storage disk;
+insert into t1 values (1,1);
+alter tablespace ts2
+drop datafile 'datafile2_1.dat'
+engine ndb;
+ERROR HY000: Failed to alter:  DROP DATAFILE
+drop table t1;
 alter tablespace ts2
 drop datafile 'datafile2_1.dat'
 engine ndb;
diff -Nrup a/mysql-test/suite/ndb/t/ndb_dd_basic.test
b/mysql-test/suite/ndb/t/ndb_dd_basic.test
--- a/mysql-test/suite/ndb/t/ndb_dd_basic.test	2008-02-03 21:29:20 +01:00
+++ b/mysql-test/suite/ndb/t/ndb_dd_basic.test	2008-05-19 17:31:02 +02:00
@@ -243,6 +243,17 @@ CREATE TABLE City (
 tablespace ts2
 storage disk;
 
+create table t1 (a int primary key, b int)
+engine = ndbcluster tablespace ts2 storage disk;
+insert into t1 values (1,1);
+
+--error ER_ALTER_FILEGROUP_FAILED
+alter tablespace ts2
+drop datafile 'datafile2_1.dat'
+engine ndb;
+
+drop table t1;
+
 alter tablespace ts2
 drop datafile 'datafile2_1.dat'
 engine ndb;
diff -Nrup a/storage/ndb/include/kernel/GlobalSignalNumbers.h
b/storage/ndb/include/kernel/GlobalSignalNumbers.h
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h	2008-02-06 21:00:08 +01:00
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h	2008-05-19 17:31:02 +02:00
@@ -979,24 +979,24 @@ extern const GlobalSignalNumber NO_OF_SI
 #define GSN_DROP_FILE_REF               723
 #define GSN_DROP_FILE_CONF              724
 
-#define GSN_CREATE_OBJ_REQ              725
-#define GSN_CREATE_OBJ_REF              726
-#define GSN_CREATE_OBJ_CONF             727
+#define GSN_CREATE_FILEGROUP_IMPL_REQ   725
+#define GSN_CREATE_FILEGROUP_IMPL_REF   726
+#define GSN_CREATE_FILEGROUP_IMPL_CONF  727
 
-#define GSN_DROP_OBJ_REQ                728
-#define GSN_DROP_OBJ_REF                729
-#define GSN_DROP_OBJ_CONF               730
+#define GSN_CREATE_FILE_IMPL_REQ        728
+#define GSN_CREATE_FILE_IMPL_REF        729
+#define GSN_CREATE_FILE_IMPL_CONF       730
 
 #define GSN_ALLOC_EXTENT_REQ             68
 #define GSN_FREE_EXTENT_REQ              69
 
-#define GSN_DICT_COMMIT_REQ             664
-#define GSN_DICT_COMMIT_REF             665
-#define GSN_DICT_COMMIT_CONF            666
+#define GSN_DROP_FILEGROUP_IMPL_REQ     664
+#define GSN_DROP_FILEGROUP_IMPL_REF     665
+#define GSN_DROP_FILEGROUP_IMPL_CONF    666
 
-#define GSN_DICT_ABORT_REQ              667
-#define GSN_DICT_ABORT_REF              668
-#define GSN_DICT_ABORT_CONF             669
+#define GSN_DROP_FILE_IMPL_REQ          667
+#define GSN_DROP_FILE_IMPL_REF          668
+#define GSN_DROP_FILE_IMPL_CONF         669
 
 /* DICT LOCK signals */
 #define GSN_DICT_LOCK_REQ               410
diff -Nrup a/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp
b/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp
--- a/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp	2007-04-16 19:17:19 +02:00
+++ b/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp	2008-05-19 17:31:02 +02:00
@@ -30,11 +30,20 @@ struct CreateFilegroupReq {
    */
   friend bool printCREATE_FILEGROUP_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( SignalLength = 6 );
   
-  Uint32 senderData;
-  Uint32 senderRef;
+  union {
+    Uint32 senderData;
+    Uint32 clientData;
+  };
+  union {
+    Uint32 senderRef;
+    Uint32 clientRef;
+  };
   Uint32 objType;
+  Uint32 requestInfo;
+  Uint32 transId;
+  Uint32 transKey;
   SECTION( FILEGROUP_INFO = 0 );
 };
 
@@ -75,8 +84,8 @@ struct CreateFilegroupRef {
   Uint32 masterNodeId;
   Uint32 errorCode;
   Uint32 errorLine; 
-  Uint32 errorKey;
-  Uint32 status;
+  Uint32 errorNodeId;
+  Uint32 transId;
 };
 
 struct CreateFilegroupConf {
@@ -95,12 +104,13 @@ struct CreateFilegroupConf {
    */
   friend bool printCREATE_FILEGROUP_CONF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 5 );
 
   Uint32 senderData;
   Uint32 senderRef;
   Uint32 filegroupId;
   Uint32 filegroupVersion;
+  Uint32 transId;
 };
 
 struct CreateFileReq {
@@ -116,12 +126,20 @@ struct CreateFileReq {
    */
   friend bool printCREATE_FILE_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 6 );
   
-  Uint32 senderData;
-  Uint32 senderRef;
+  union {
+    Uint32 senderData;
+    Uint32 clientData;
+  };
+  union {
+    Uint32 senderRef;
+    Uint32 clientRef;
+  };
   Uint32 objType;
   Uint32 requestInfo;
+  Uint32 transId;
+  Uint32 transKey;
   
   enum RequstInfo 
   {
@@ -147,7 +165,7 @@ struct CreateFileRef {
    */
   friend bool printCREATE_FILE_REF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 7 );
+  STATIC_CONST( SignalLength = 8 );
 
   enum ErrorCode {
     NoError = 0,
@@ -171,6 +189,8 @@ struct CreateFileRef {
   Uint32 errorLine; 
   Uint32 errorKey;
   Uint32 status;
+  Uint32 errorNodeId;
+  Uint32 transId;
 };
 
 struct CreateFileConf {
@@ -190,12 +210,13 @@ struct CreateFileConf {
    */
   friend bool printCREATE_FILE_CONF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 5 );
 
   Uint32 senderData;
   Uint32 senderRef;
   Uint32 fileId;
   Uint32 fileVersion;
+  Uint32 transId;
 };
 
 #endif
diff -Nrup a/storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp
b/storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp
--- a/storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp	2007-11-12 15:53:18
+01:00
+++ b/storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp	2008-05-19 17:31:02
+02:00
@@ -31,13 +31,15 @@ struct CreateFilegroupImplReq {
    */
   friend bool printCREATE_FILEGROUP_IMPL_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( TablespaceLength = 6 );
-  STATIC_CONST( LogfileGroupLength = 5 );
+  STATIC_CONST( SignalLength = 5 ); // DICT2DICT
+  STATIC_CONST( TablespaceLength = 7 );
+  STATIC_CONST( LogfileGroupLength = 6 );
   
   Uint32 senderData;
   Uint32 senderRef;  
   Uint32 filegroup_id;
   Uint32 filegroup_version;
+  Uint32 requestType;
   
   union {
     struct {
@@ -109,11 +111,12 @@ struct CreateFileImplReq {
    * For printing
    */
   friend bool printCREATE_FILE_IMPL_REQ(FILE*, const Uint32*, Uint32, Uint16);
-  
-  STATIC_CONST( DatafileLength = 9 );
-  STATIC_CONST( UndofileLength = 8 );
-  STATIC_CONST( CommitLength = 6 );
-  STATIC_CONST( AbortLength = 6 );
+
+  STATIC_CONST( SignalLength = 11 ); // DICT2DICT
+  STATIC_CONST( DatafileLength = 10 );
+  STATIC_CONST( UndofileLength = 9 );
+  STATIC_CONST( CommitLength = 7 );
+  STATIC_CONST( AbortLength = 7 );
   SECTION( FILENAME = 0 );
   
   enum RequestInfo {
@@ -126,9 +129,9 @@ struct CreateFileImplReq {
   
   Uint32 senderData;
   Uint32 senderRef;
-
   Uint32 requestInfo;
   Uint32 file_id;
+  Uint32 file_version;
   Uint32 filegroup_id;
   Uint32 filegroup_version;
   Uint32 file_size_hi;
@@ -139,6 +142,7 @@ struct CreateFileImplReq {
       Uint32 extent_size;
     } tablespace;
   };
+  Uint32 requestType;
 };
 
 struct CreateFileImplRef {
diff -Nrup a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
--- a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2007-04-26 14:04:28 +02:00
+++ b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2008-05-19 17:31:02 +02:00
@@ -202,7 +202,9 @@ public:
     Tablespace = 20,        ///< Tablespace
     LogfileGroup = 21,      ///< Logfile group
     Datafile = 22,          ///< Datafile
-    Undofile = 23           ///< Undofile
+    Undofile = 23,          ///< Undofile
+
+    SchemaTransaction = 30
   };
 
   // used 1) until type BlobTable added 2) in upgrade code
diff -Nrup a/storage/ndb/include/kernel/signaldata/DropFilegroup.hpp
b/storage/ndb/include/kernel/signaldata/DropFilegroup.hpp
--- a/storage/ndb/include/kernel/signaldata/DropFilegroup.hpp	2007-04-16 11:43:12 +02:00
+++ b/storage/ndb/include/kernel/signaldata/DropFilegroup.hpp	2008-05-19 17:31:02 +02:00
@@ -31,13 +31,22 @@ struct DropFilegroupReq {
    */
   friend bool printDROP_FILEGROUP_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 7 );
   STATIC_CONST( GSN = GSN_DROP_FILEGROUP_REQ );
   
-  Uint32 senderData;
-  Uint32 senderRef;
+  union {
+    Uint32 senderData;
+    Uint32 clientData;
+  };
+  union {
+    Uint32 senderRef;
+    Uint32 clientRef;
+  };
   Uint32 filegroup_id;
   Uint32 filegroup_version;
+  Uint32 requestInfo;
+  Uint32 transKey;
+  Uint32 transId;
 };
 
 struct DropFilegroupRef {
@@ -57,7 +66,7 @@ struct DropFilegroupRef {
    */
   friend bool printDROP_FILEGROUP_REF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 7 );
+  STATIC_CONST( SignalLength = 9 );
   STATIC_CONST( GSN = GSN_DROP_FILEGROUP_REF );
 
   enum ErrorCode {
@@ -76,7 +85,8 @@ struct DropFilegroupRef {
   Uint32 errorCode;
   Uint32 errorLine; 
   Uint32 errorKey;
-
+  Uint32 errorNodeId;
+  Uint32 transId;
 };
 
 struct DropFilegroupConf {
@@ -96,13 +106,14 @@ struct DropFilegroupConf {
    */
   friend bool printDROP_FILEGROUP_CONF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 5 );
   STATIC_CONST( GSN = GSN_DROP_FILEGROUP_CONF );
 
   Uint32 senderData;
   Uint32 senderRef;
   Uint32 filegroupId;
   Uint32 filegroupVersion;
+  Uint32 transId;
 };
 
 struct DropFileReq {
@@ -118,13 +129,22 @@ struct DropFileReq {
    */
   friend bool printDROP_FILE_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 7 );
   STATIC_CONST( GSN = GSN_DROP_FILE_REQ );
   
-  Uint32 senderData;
-  Uint32 senderRef;
+  union {
+    Uint32 senderData;
+    Uint32 clientData;
+  };
+  union {
+    Uint32 senderRef;
+    Uint32 clientRef;
+  };
   Uint32 file_id;
   Uint32 file_version;
+  Uint32 requestInfo;
+  Uint32 transKey;
+  Uint32 transId;
 };
 
 struct DropFileRef {
@@ -144,7 +164,7 @@ struct DropFileRef {
    */
   friend bool printDROP_FILE_REF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 7 );
+  STATIC_CONST( SignalLength = 9 );
   STATIC_CONST( GSN = GSN_DROP_FILE_REF );
 
   enum ErrorCode {
@@ -163,7 +183,8 @@ struct DropFileRef {
   Uint32 errorCode;
   Uint32 errorLine; 
   Uint32 errorKey;
-
+  Uint32 errorNodeId;
+  Uint32 transId;
 };
 
 struct DropFileConf {
@@ -183,13 +204,14 @@ struct DropFileConf {
    */
   friend bool printDROP_FILE_CONF(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 4 );
+  STATIC_CONST( SignalLength = 5 );
   STATIC_CONST( GSN = GSN_DROP_FILE_CONF );
 
   Uint32 senderData;
   Uint32 senderRef;
   Uint32 fileId;
   Uint32 fileVersion;
+  Uint32 transId;
 };
 
 #endif
diff -Nrup a/storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp
b/storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp
--- a/storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp	2006-12-23 20:33:29
+01:00
+++ b/storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp	2008-05-19 17:31:02
+02:00
@@ -31,7 +31,7 @@ struct DropFilegroupImplReq {
    */
   friend bool printDROP_FILEGROUP_IMPL_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 5 );
+  STATIC_CONST( SignalLength = 6 );
   
   enum RequestInfo {
     Prepare = 0x1,
@@ -45,6 +45,7 @@ struct DropFilegroupImplReq {
   Uint32 requestInfo;
   Uint32 filegroup_id;
   Uint32 filegroup_version;
+  Uint32 requestType;
 };
 
 struct DropFilegroupImplRef {
@@ -106,7 +107,7 @@ struct DropFileImplReq {
    */
   friend bool printDROP_FILE_IMPL_REQ(FILE*, const Uint32*, Uint32, Uint16);
   
-  STATIC_CONST( SignalLength = 6 );
+  STATIC_CONST( SignalLength = 8 );
   
   enum RequestInfo {
     Prepare = 0x1,
@@ -119,8 +120,10 @@ struct DropFileImplReq {
   
   Uint32 requestInfo;
   Uint32 file_id;
+  Uint32 file_version;
   Uint32 filegroup_id;
   Uint32 filegroup_version;
+  Uint32 requestType;
 };
 
 struct DropFileImplRef {
diff -Nrup a/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp
b/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp
--- a/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp	2008-02-06 21:15:12 +01:00
+++ b/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp	2008-05-19 17:31:02 +02:00
@@ -41,7 +41,8 @@ struct SchemaTransBeginRef {
     NotMaster = 702,
     Busy = 701,
     BusyWithNR = 711,
-    TooManySchemaTrans = 780
+    TooManySchemaTrans = 780,
+    IncompatibleVersions = 763
   };
   Uint32 senderRef;
   Uint32 transId;
diff -Nrup a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2008-02-06 21:00:08
+01:00
+++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2008-05-19 17:31:02
+02:00
@@ -609,26 +609,26 @@ const GsnName SignalNames [] = {
   ,{ GSN_DROP_FILE_REF,  "DROP_FILE_REF" }
   ,{ GSN_DROP_FILE_CONF, "DROP_FILE_CONF" }
   
-  ,{ GSN_CREATE_OBJ_REQ,  "CREATE_OBJ_REQ" }
-  ,{ GSN_CREATE_OBJ_REF,  "CREATE_OBJ_REF" }
-  ,{ GSN_CREATE_OBJ_CONF, "CREATE_OBJ_CONF" }
+  ,{ GSN_CREATE_FILEGROUP_IMPL_REQ, "CREATE_FILEGROUP_IMPL_REQ" }
+  ,{ GSN_CREATE_FILEGROUP_IMPL_REF, "CREATE_FILEGROUP_IMPL_REF" }
+  ,{ GSN_CREATE_FILEGROUP_IMPL_CONF, "CREATE_FILEGROUP_IMPL_CONF" }
   
-  ,{ GSN_DROP_OBJ_REQ,  "DROP_OBJ_REQ" }
-  ,{ GSN_DROP_OBJ_REF,  "DROP_OBJ_REF" }
-  ,{ GSN_DROP_OBJ_CONF, "DROP_OBJ_CONF" }
+  ,{ GSN_CREATE_FILE_IMPL_REQ,  "CREATE_FILE_IMPL_REQ" }
+  ,{ GSN_CREATE_FILE_IMPL_REF,  "CREATE_FILE_IMPL_REF" }
+  ,{ GSN_CREATE_FILE_IMPL_CONF, "CREATE_FILE_IMPL_CONF" }
+
+  ,{ GSN_DROP_FILEGROUP_IMPL_REQ,  "DROP_FILEGROUP_IMPL_REQ" }
+  ,{ GSN_DROP_FILEGROUP_IMPL_REF,  "DROP_FILEGROUP_IMPL_REF" }
+  ,{ GSN_DROP_FILEGROUP_IMPL_CONF, "DROP_FILEGROUP_IMPL_CONF" }
+
+  ,{ GSN_DROP_FILE_IMPL_REQ,  "DROP_FILE_IMPL_REQ" }
+  ,{ GSN_DROP_FILE_IMPL_REF,  "DROP_FILE_IMPL_REF" }
+  ,{ GSN_DROP_FILE_IMPL_CONF, "DROP_FILE_IMPL_CONF" }
   
   ,{ GSN_LCP_PREPARE_REQ,  "LCP_PREPARE_REQ" }
   ,{ GSN_LCP_PREPARE_REF,  "LCP_PREPARE_REF" }
   ,{ GSN_LCP_PREPARE_CONF, "LCP_PREPARE_CONF" }
 
-  ,{ GSN_DICT_ABORT_REQ,  "DICT_ABORT_REQ" }
-  ,{ GSN_DICT_ABORT_REF,  "DICT_ABORT_REF" }
-  ,{ GSN_DICT_ABORT_CONF, "DICT_ABORT_CONF" }
-
-  ,{ GSN_DICT_COMMIT_REQ,  "DICT_COMMIT_REQ" }
-  ,{ GSN_DICT_COMMIT_REF,  "DICT_COMMIT_REF" }
-  ,{ GSN_DICT_COMMIT_CONF, "DICT_COMMIT_CONF" }
-
   /* DICT LOCK */
   ,{ GSN_DICT_LOCK_REQ,          "DICT_LOCK_REQ" }
   ,{ GSN_DICT_LOCK_CONF,         "DICT_LOCK_CONF" }
@@ -636,7 +636,6 @@ const GsnName SignalNames [] = {
   ,{ GSN_DICT_UNLOCK_ORD,        "DICT_UNLOCK_ORD" }
 
   ,{ GSN_UPDATE_FRAG_DIST_KEY_ORD, "UPDATE_FRAG_DIST_KEY_ORD" }
-  ,{ GSN_DICT_COMMIT_REQ,  "DICT_COMMIT_REQ"}
 
   ,{ GSN_ROUTE_ORD, "ROUTE_ORD" }
   ,{ GSN_NODE_VERSION_REP, "NODE_VERSION_REP" }
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-05-19 07:49:36 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-05-19 17:31:02 +02:00
@@ -82,9 +82,6 @@
 #include <NdbSleep.h>
 #include <signaldata/ApiBroadcast.hpp>
 #include <signaldata/DictLock.hpp>
-
-#include <signaldata/DropObj.hpp>
-#include <signaldata/CreateObj.hpp>
 #include <signaldata/BackupLockTab.hpp>
 #include <SLList.hpp>
 
@@ -100,6 +97,9 @@ extern void release(SegmentedSectionPtr&
 #define ZNOT_FOUND 626
 #define ZALREADYEXIST 630
 
+#define ZRESTART_OPS_PER_TRANS 25
+#define ZRESTART_NO_WRITE_AFTER_READ 1
+
 //#define EVENT_PH2_DEBUG
 //#define EVENT_PH3_DEBUG
 //#define EVENT_DEBUG
@@ -114,110 +114,18 @@ static const char EVENT_SYSTEM_TABLE_NAM
 #include <ndb_version.h>
 
 static
-struct {
-  Uint32 m_gsn_user_req;
-  Uint32 m_gsn_req;
-  Uint32 m_gsn_ref;
-  Uint32 m_gsn_conf;
-  void (Dbdict::* m_trans_commit_start)(Signal*, Dbdict::SchemaTransaction*);
-  void (Dbdict::* m_trans_commit_complete)(Signal*,Dbdict::SchemaTransaction*);
-  void (Dbdict::* m_trans_abort_start)(Signal*, Dbdict::SchemaTransaction*);
-  void (Dbdict::* m_trans_abort_complete)(Signal*, Dbdict::SchemaTransaction*);
-
-  void (Dbdict::* m_prepare_start)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_prepare_complete)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_commit)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_commit_start)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_commit_complete)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_abort)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_abort_start)(Signal*, Dbdict::SchemaOperation*);
-  void (Dbdict::* m_abort_complete)(Signal*, Dbdict::SchemaOperation*);
-  
-} f_dict_op[] = {
-  /**
-   * Create filegroup
-   */
-  { 
-    GSN_CREATE_FILEGROUP_REQ,
-    GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
-    0, 0, 0, 0,
-    &Dbdict::create_fg_prepare_start, &Dbdict::create_fg_prepare_complete,
-    &Dbdict::createObj_commit,
-    0, 0,
-    &Dbdict::createObj_abort,
-    &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete,
-  }
-
-  /**
-   * Create file
-   */
-  ,{ 
-    GSN_CREATE_FILE_REQ,
-    GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
-    0, 0, 0, 0,
-    &Dbdict::create_file_prepare_start, &Dbdict::create_file_prepare_complete,
-    &Dbdict::createObj_commit,
-    &Dbdict::create_file_commit_start, 0,
-    &Dbdict::createObj_abort,
-    &Dbdict::create_file_abort_start, &Dbdict::create_file_abort_complete,
-  }
-
-  /**
-   * Drop file
-   */
-  ,{ 
-    GSN_DROP_FILE_REQ,
-    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
-    0, 0, 0, 0,
-    &Dbdict::drop_file_prepare_start, 0,
-    &Dbdict::dropObj_commit,
-    &Dbdict::drop_file_commit_start, &Dbdict::drop_file_commit_complete,
-    &Dbdict::dropObj_abort,
-    &Dbdict::drop_file_abort_start, 0
-  }
-
-  /**
-   * Drop filegroup
-   */
-  ,{ 
-    GSN_DROP_FILEGROUP_REQ,
-    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
-    0, 0, 0, 0,
-    &Dbdict::drop_fg_prepare_start, 0,
-    &Dbdict::dropObj_commit,
-    &Dbdict::drop_fg_commit_start, &Dbdict::drop_fg_commit_complete,
-    &Dbdict::dropObj_abort,
-    &Dbdict::drop_fg_abort_start, 0
-  }
-
-  /**
-   * Drop undofile
-   */
-  ,{ 
-    GSN_DROP_FILE_REQ,
-    GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
-    0, 0, 0, 0,
-    &Dbdict::drop_undofile_prepare_start, 0,
-    0,
-    0, &Dbdict::drop_undofile_commit_complete,
-    0, 0, 0
-  }
-};
-
 Uint32
 alter_obj_inc_schema_version(Uint32 old)
 {
    return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
 }
 
-#if 0
 static
 Uint32
 alter_obj_dec_schema_version(Uint32 old)
 {
   return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
 }
-#endif
 
 static
 Uint32
@@ -424,6 +332,7 @@ void Dbdict::packTableIntoPages(Signal* 
   case DictTabInfo::SubscriptionTrigger:
   case DictTabInfo::ReadOnlyConstraint:
   case DictTabInfo::IndexTrigger:
+  case DictTabInfo::SchemaTransaction:
     ndbrequire(false);
   }
   
@@ -1231,7 +1140,11 @@ Dbdict::updateSchemaState(Signal* signal
   D("updateSchemaState" << V(tableId));
   D("old:" << *tableEntry);
   D("new:" << *te);
-  
+
+#ifndef TODO
+  * tableEntry = * te;
+  computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
+#else
   SchemaFile::TableState newState = 
     (SchemaFile::TableState)te->m_tableState;
   SchemaFile::TableState oldState = 
@@ -1329,6 +1242,7 @@ Dbdict::updateSchemaState(Signal* signal
       execute(signal, *callback, 0);
     }
   }
+#endif
 }
 
 void Dbdict::startWriteSchemaFile(Signal* signal)
@@ -1651,8 +1565,7 @@ Dbdict::convertSchemaFileTo_5_0_6(XSchem
       if (j >= sf_old->NoOfTableEntries)
         continue;
       const SchemaFile::TableEntry_old & te_old = sf_old->TableEntries_old[j];
-      if (te_old.m_tableState == SchemaFile::INIT ||
-          te_old.m_tableState == SchemaFile::DROP_TABLE_COMMITTED ||
+      if (te_old.m_tableState == SchemaFile::SF_UNUSED ||
           te_old.m_noOfPages == 0)
         continue;
       SchemaFile * sf = &xsf->schemaPage[n];
@@ -1697,10 +1610,6 @@ Dbdict::Dbdict(Block_context& ctx):
   c_opSubEvent(c_opRecordPool),
   c_opDropEvent(c_opRecordPool),
   c_opSignalUtil(c_opRecordPool),
-  c_schemaOperation(c_opRecordPool),
-  c_Trans(c_opRecordPool),
-  c_opCreateObj(c_schemaOperation),
-  c_opDropObj(c_schemaOperation),
   c_opRecordSequence(0)
 #ifdef VM_TRACE
   ,debugOut(*new NullOutputStream())
@@ -1849,34 +1758,25 @@ Dbdict::Dbdict(Block_context& ctx):
   addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ);
 
   addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ);
-  addRecSignal(GSN_DROP_FILE_REF, &Dbdict::execDROP_FILE_REF);
-  addRecSignal(GSN_DROP_FILE_CONF, &Dbdict::execDROP_FILE_CONF);
-
   addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_REQ);
-  addRecSignal(GSN_DROP_FILEGROUP_REF, &Dbdict::execDROP_FILEGROUP_REF);
-  addRecSignal(GSN_DROP_FILEGROUP_CONF, &Dbdict::execDROP_FILEGROUP_CONF);
-  
-  addRecSignal(GSN_CREATE_OBJ_REQ, &Dbdict::execCREATE_OBJ_REQ);
-  addRecSignal(GSN_CREATE_OBJ_REF, &Dbdict::execCREATE_OBJ_REF);
-  addRecSignal(GSN_CREATE_OBJ_CONF, &Dbdict::execCREATE_OBJ_CONF);
-  addRecSignal(GSN_DROP_OBJ_REQ, &Dbdict::execDROP_OBJ_REQ);
-  addRecSignal(GSN_DROP_OBJ_REF, &Dbdict::execDROP_OBJ_REF);
-  addRecSignal(GSN_DROP_OBJ_CONF, &Dbdict::execDROP_OBJ_CONF);
-
-  addRecSignal(GSN_CREATE_FILE_REF, &Dbdict::execCREATE_FILE_REF);
-  addRecSignal(GSN_CREATE_FILE_CONF, &Dbdict::execCREATE_FILE_CONF);
-  addRecSignal(GSN_CREATE_FILEGROUP_REF, &Dbdict::execCREATE_FILEGROUP_REF);
-  addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Dbdict::execCREATE_FILEGROUP_CONF);
+
+  addRecSignal(GSN_DROP_FILE_IMPL_REF, &Dbdict::execDROP_FILE_IMPL_REF);
+  addRecSignal(GSN_DROP_FILE_IMPL_CONF, &Dbdict::execDROP_FILE_IMPL_CONF);
+
+  addRecSignal(GSN_DROP_FILEGROUP_IMPL_REF,
+               &Dbdict::execDROP_FILEGROUP_IMPL_REF);
+  addRecSignal(GSN_DROP_FILEGROUP_IMPL_CONF,
+               &Dbdict::execDROP_FILEGROUP_IMPL_CONF);
+
+  addRecSignal(GSN_CREATE_FILE_IMPL_REF, &Dbdict::execCREATE_FILE_IMPL_REF);
+  addRecSignal(GSN_CREATE_FILE_IMPL_CONF, &Dbdict::execCREATE_FILE_IMPL_CONF);
+  addRecSignal(GSN_CREATE_FILEGROUP_IMPL_REF,
+               &Dbdict::execCREATE_FILEGROUP_IMPL_REF);
+  addRecSignal(GSN_CREATE_FILEGROUP_IMPL_CONF,
+               &Dbdict::execCREATE_FILEGROUP_IMPL_CONF);
 
   addRecSignal(GSN_BACKUP_LOCK_TAB_REQ, &Dbdict::execBACKUP_LOCK_TAB_REQ);
 
-  addRecSignal(GSN_DICT_COMMIT_REQ, &Dbdict::execDICT_COMMIT_REQ);
-  addRecSignal(GSN_DICT_COMMIT_REF, &Dbdict::execDICT_COMMIT_REF);
-  addRecSignal(GSN_DICT_COMMIT_CONF, &Dbdict::execDICT_COMMIT_CONF);
-
-  addRecSignal(GSN_DICT_ABORT_REQ, &Dbdict::execDICT_ABORT_REQ);
-  addRecSignal(GSN_DICT_ABORT_REF, &Dbdict::execDICT_ABORT_REF);
-  addRecSignal(GSN_DICT_ABORT_CONF, &Dbdict::execDICT_ABORT_CONF);
   addRecSignal(GSN_SCHEMA_TRANS_BEGIN_REQ, &Dbdict::execSCHEMA_TRANS_BEGIN_REQ);
   addRecSignal(GSN_SCHEMA_TRANS_BEGIN_CONF, &Dbdict::execSCHEMA_TRANS_BEGIN_CONF);
   addRecSignal(GSN_SCHEMA_TRANS_BEGIN_REF, &Dbdict::execSCHEMA_TRANS_BEGIN_REF);
@@ -2013,6 +1913,7 @@ void Dbdict::initRestartRecord() 
   c_restartRecord.gciToRestart = 0;
   c_restartRecord.activeTable = ZNIL;
   c_restartRecord.m_pass = 0;
+  c_restartRecord.m_op_cnt = 0;
 }//Dbdict::initRestartRecord()
 
 void Dbdict::initNodeRecords() 
@@ -2139,11 +2040,13 @@ Uint32 Dbdict::getFreeObjId(Uint32 minId
     const SchemaFile * sf = &xsf->schemaPage[n];
     for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
       const SchemaFile::TableEntry& te = sf->TableEntries[i];
-      if (te.m_tableState == (Uint32)SchemaFile::INIT ||
-          te.m_tableState == (Uint32)SchemaFile::DROP_TABLE_COMMITTED) {
+      if (te.m_tableState == (Uint32)SchemaFile::SF_UNUSED)
+      {
         // minId is obsolete anyway
         if (minId <= n * NDB_SF_PAGE_ENTRIES + i)
+        {
           return n * NDB_SF_PAGE_ENTRIES + i;
+        }
       }
     }
   }
@@ -2166,6 +2069,7 @@ Uint32 Dbdict::getFreeTableRecord(Uint32
     jam();
     return RNIL;
   }
+
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, i);
   ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
@@ -2295,6 +2199,10 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
   c_dropIndexRecPool.setSize(32);
   c_alterIndexRecPool.setSize(32);
   c_buildIndexRecPool.setSize(32);
+  c_createFilegroupRecPool.setSize(32);
+  c_createFileRecPool.setSize(32);
+  c_dropFilegroupRecPool.setSize(32);
+  c_dropFileRecPool.setSize(32);
   
   c_opRecordPool.setSize(256);   // XXX need config params
   c_opCreateEvent.setSize(2);
@@ -2310,10 +2218,6 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
     (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
   c_schemaFile[1].noOfPages = 0;
 
-  c_schemaOperation.setSize(8);
-  //c_opDropObj.setSize(8);
-  c_Trans.setSize(8);
-
   Uint32 rps = 0;
   rps += tablerecSize * (MAX_TAB_NAME_SIZE + MAX_FRM_DATA_SIZE);
   rps += attributesize * (MAX_ATTR_NAME_SIZE + MAX_ATTR_DEFAULT_VALUE_SIZE);
@@ -2944,6 +2848,7 @@ void Dbdict::execDICTSTARTREQ(Signal* si
 
   c_restartRecord.m_pass = 0;
   c_restartRecord.activeTable = 0;
+  c_restartRecord.m_op_cnt = 0;
 
   /**
    * master has same new/old schema file...
@@ -2951,6 +2856,7 @@ void Dbdict::execDICTSTARTREQ(Signal* si
    */
   {
     XSchemaFile * oldxsf = &c_schemaFile[SchemaRecord::OLD_SCHEMA_FILE];
+    checkPendingSchemaTrans(oldxsf);
     XSchemaFile * newxsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
     newxsf->noOfPages = oldxsf->noOfPages;
     memcpy(&newxsf->schemaPage[0],
@@ -2958,7 +2864,22 @@ void Dbdict::execDICTSTARTREQ(Signal* si
            oldxsf->schemaPage[0].FileSize);
   }
 
-  checkSchemaStatus(signal);
+  TxHandlePtr tx_ptr;
+  seizeTxHandle(tx_ptr);
+  ndbrequire(!tx_ptr.isNull());
+
+  c_restartRecord.m_tx_ptr_i = tx_ptr.i;
+  tx_ptr.p->m_requestInfo = DictSignal::RF_LOCAL_TRANS;
+  tx_ptr.p->m_userData = 0;
+
+  Callback c = {
+    safe_cast(&Dbdict::restart_fromBeginTrans),
+    tx_ptr.p->tx_key
+  };
+  tx_ptr.p->m_callback = c;
+  beginSchemaTrans(signal, tx_ptr);
+
+  infoEvent("Starting to restore schema");
 }//execDICTSTARTREQ()
 
 void
@@ -2966,6 +2887,8 @@ Dbdict::masterRestart_checkSchemaStatusC
 						Uint32 callbackData,
 						Uint32 returnCode)
 {
+  infoEvent("Restore of schema complete");
+
   XSchemaFile * oldxsf = &c_schemaFile[SchemaRecord::OLD_SCHEMA_FILE];
   ndbrequire(oldxsf->noOfPages != 0);
 
@@ -3069,6 +2992,7 @@ void Dbdict::execSCHEMA_INFO(Signal* sig
   validateChecksum(xsf);
 
   XSchemaFile * oldxsf = &c_schemaFile[SchemaRecord::OLD_SCHEMA_FILE];
+  checkPendingSchemaTrans(oldxsf);
   resizeSchemaFile(xsf, oldxsf->noOfPages);
 
   ndbrequire(signal->getSendersBlockRef() != reference());
@@ -3084,9 +3008,27 @@ void Dbdict::execSCHEMA_INFO(Signal* sig
   c_schemaRecord.m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
 
-  c_restartRecord.m_pass= 0;
+  c_restartRecord.m_pass = 0;
   c_restartRecord.activeTable = 0;
-  checkSchemaStatus(signal);
+  c_restartRecord.m_op_cnt = 0;
+
+
+  TxHandlePtr tx_ptr;
+  seizeTxHandle(tx_ptr);
+  ndbrequire(!tx_ptr.isNull());
+
+  c_restartRecord.m_tx_ptr_i = tx_ptr.i;
+  tx_ptr.p->m_requestInfo = DictSignal::RF_LOCAL_TRANS;
+  tx_ptr.p->m_userData = 0;
+
+  Callback c = {
+    safe_cast(&Dbdict::restart_fromBeginTrans),
+    tx_ptr.p->tx_key
+  };
+  tx_ptr.p->m_callback = c;
+  beginSchemaTrans(signal, tx_ptr);
+
+  infoEvent("Starting to restore schema");
 }//execSCHEMA_INFO()
 
 void
@@ -3095,32 +3037,8 @@ Dbdict::restart_checkSchemaStatusComplet
 					  Uint32 returnCode)
 {
   jam();
-  D("restart_checkSchemaStatusComplete");
 
-  ndbrequire(c_writeSchemaRecord.inUse == false);
-  c_writeSchemaRecord.inUse = true;
-  XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
-  c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
-  c_writeSchemaRecord.newFile = true;
-  c_writeSchemaRecord.firstPage = 0;
-  c_writeSchemaRecord.noOfPages = xsf->noOfPages;
-  c_writeSchemaRecord.m_callback.m_callbackData = 0;
-  c_writeSchemaRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restart_writeSchemaConf);
-  
-  for(Uint32 i = 0; i<xsf->noOfPages; i++)
-    computeChecksum(xsf, i);  
-
-  startWriteSchemaFile(signal);
-}
-
-void
-Dbdict::restart_writeSchemaConf(Signal * signal, 
-				Uint32 callbackData,
-				Uint32 returnCode)
-{
-  jam();
-  D("restart_writeSchemaConf");
+  infoEvent("Restore of schema complete");
 
   if(c_systemRestart){
     jam();
@@ -3233,21 +3151,23 @@ void Dbdict::checkSchemaStatus(Signal* s
   const Uint32 noOfEntries = newxsf->noOfPages * NDB_SF_PAGE_ENTRIES;
 
   for (; c_restartRecord.activeTable < noOfEntries;
-       c_restartRecord.activeTable++) {
+       c_restartRecord.activeTable++)
+  {
     jam();
 
     Uint32 tableId = c_restartRecord.activeTable;
     SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId);
     SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId);
-    SchemaFile::TableState newSchemaState = 
-      (SchemaFile::TableState)newEntry->m_tableState;
-    SchemaFile::TableState oldSchemaState = 
-      (SchemaFile::TableState)oldEntry->m_tableState;
+    SchemaFile::EntryState newState =
+      (SchemaFile::EntryState)newEntry->m_tableState;
+    SchemaFile::EntryState oldState =
+      (SchemaFile::EntryState)oldEntry->m_tableState;
 
-    if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
+    if (c_restartRecord.activeTable >= c_tableRecordPool.getSize())
+    {
       jam();
-      ndbrequire(newSchemaState == SchemaFile::INIT);
-      ndbrequire(oldSchemaState == SchemaFile::INIT);
+      ndbrequire(newState == SchemaFile::SF_UNUSED);
+      ndbrequire(oldState == SchemaFile::SF_UNUSED);
       continue;
     }//if
 
@@ -3255,42 +3175,22 @@ void Dbdict::checkSchemaStatus(Signal* s
 
 //#define PRINT_SCHEMA_RESTART
 #ifdef PRINT_SCHEMA_RESTART
-    char buf[100];
-    snprintf(buf, sizeof(buf), "checkSchemaStatus: pass: %d table: %d", 
-             c_restartRecord.m_pass, tableId);
+    printf("checkSchemaStatus: pass: %d table: %d",
+           c_restartRecord.m_pass, tableId);
+    ndbout << "old: " << *oldEntry << " new: " << *newEntry;
 #endif
-    
+
     if (c_restartRecord.m_pass <= CREATE_OLD_PASS)
     {
       if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
         continue;
 
-      switch(oldSchemaState){
-      case SchemaFile::INIT: jam();
-      case SchemaFile::DROP_TABLE_COMMITTED: jam();
-      case SchemaFile::ADD_STARTED: jam();
-      case SchemaFile::DROP_TABLE_STARTED: jam();
-      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
-	continue;
-      case SchemaFile::TABLE_ADD_COMMITTED: jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
-	jam();
-#ifdef PRINT_SCHEMA_RESTART
-        ndbout_c("%s -> restartCreateTab", buf);
-        ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
-	restartCreateTab(signal, tableId, oldEntry, oldEntry, true);        
-        return;
-      case SchemaFile::CREATE_PARSED:
-        jam();
-      case SchemaFile::DROP_PARSED:
-        jam();
-      case SchemaFile::ALTER_PARSED:
-        jam();
-        // these are not disk states
-        ndbrequire(false);
+
+      if (oldState == SchemaFile::SF_UNUSED)
         continue;
-      }
+
+      restartCreateObj(signal, tableId, oldEntry, true);
+      return;
     }
 
     if (c_restartRecord.m_pass <= DROP_OLD_PASS)
@@ -3298,237 +3198,270 @@ void Dbdict::checkSchemaStatus(Signal* s
       if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
         continue;
 
-      switch(oldSchemaState){
-      case SchemaFile::INIT: jam();
-      case SchemaFile::DROP_TABLE_COMMITTED: jam();
-      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
-        continue;
-      case SchemaFile::ADD_STARTED: jam();
-      case SchemaFile::DROP_TABLE_STARTED: jam();
-#ifdef PRINT_SCHEMA_RESTART
-        ndbout_c("%s -> restartDropTab", buf);
-        ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
-	restartDropTab(signal, tableId, oldEntry, newEntry);
-        return;
-      case SchemaFile::TABLE_ADD_COMMITTED: jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
-        if (! (* oldEntry == * newEntry))
-        {
-#ifdef PRINT_SCHEMA_RESTART
-          ndbout_c("%s -> restartDropTab", buf);
-          ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
-          restartDropTab(signal, tableId, oldEntry, newEntry);
-          return;
-        }
+      if (oldState != SchemaFile::SF_IN_USE)
         continue;
-      case SchemaFile::CREATE_PARSED:
-        jam();
-      case SchemaFile::DROP_PARSED:
-        jam();
-      case SchemaFile::ALTER_PARSED:
-        jam();
-        // these are not disk states
-        ndbrequire(false);
+
+      if (* oldEntry == * newEntry)
         continue;
-      }
+
+      restartDropObj(signal, tableId, oldEntry);
+      return;
     }
 
     if (c_restartRecord.m_pass <= CREATE_NEW_PASS)
     {
       if (!::checkSchemaStatus(newEntry->m_tableType, c_restartRecord.m_pass))
         continue;
-      
-      switch(newSchemaState){
-      case SchemaFile::INIT: jam();
-      case SchemaFile::DROP_TABLE_COMMITTED: jam();
-      case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
-        * oldEntry = * newEntry;
-        continue;
-      case SchemaFile::ADD_STARTED: jam();
-      case SchemaFile::DROP_TABLE_STARTED: jam();
-        ndbrequire(DictTabInfo::isTable(newEntry->m_tableType) ||
-                   DictTabInfo::isIndex(newEntry->m_tableType));
-        newEntry->m_tableState = SchemaFile::INIT;
-        continue;
-      case SchemaFile::TABLE_ADD_COMMITTED: jam();
-      case SchemaFile::ALTER_TABLE_COMMITTED: jam();
-        if (DictTabInfo::isIndex(newEntry->m_tableType) ||
-            DictTabInfo::isTable(newEntry->m_tableType))
-        {
-          bool file = * oldEntry == *newEntry &&
-            (!DictTabInfo::isIndex(newEntry->m_tableType) || c_systemRestart);
 
-#ifdef PRINT_SCHEMA_RESTART          
-          ndbout_c("%s -> restartCreateTab (file: %d)", buf, file);
-          ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
-          restartCreateTab(signal, tableId, newEntry, newEntry, file);        
-          * oldEntry = * newEntry;
-          return;
-        }
-        else if (! (* oldEntry == *newEntry))
-        {
-#ifdef PRINT_SCHEMA_RESTART
-          ndbout_c("%s -> restartCreateTab", buf);
-          ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
-          restartCreateTab(signal, tableId, oldEntry, newEntry, false);        
-          * oldEntry = * newEntry;
-          return;
-        }
-        * oldEntry = * newEntry;
-        continue;
-      case SchemaFile::CREATE_PARSED:
-        jam();
-      case SchemaFile::DROP_PARSED:
-        jam();
-      case SchemaFile::ALTER_PARSED:
-        jam();
-        // master cannot have active transaction
-        ndbrequire(false);
+      if (newState != SchemaFile::SF_IN_USE)
         continue;
+
+      /**
+       * handle table(index) special as DIH has already copied
+       *   table (using COPY_TABREQ)
+       */
+      if (DictTabInfo::isIndex(newEntry->m_tableType) ||
+          DictTabInfo::isTable(newEntry->m_tableType))
+      {
+        bool file = * oldEntry == *newEntry &&
+          (!DictTabInfo::isIndex(newEntry->m_tableType) || c_systemRestart);
+
+        restartCreateObj(signal, tableId, newEntry, file);
+        return;
       }
+
+      if (* oldEntry == *newEntry)
+        continue;
+
+      restartCreateObj(signal, tableId, newEntry, false);
+      return;
     }
   }
-  
-  c_restartRecord.m_pass++;
-  c_restartRecord.activeTable= 0;
-  if(c_restartRecord.m_pass <= LAST_PASS)
+
+  if (c_restartRecord.m_op_cnt == 0)
   {
-    checkSchemaStatus(signal);
+    jam();
+    restartNextPass(signal);
+    return;
   }
   else
   {
-    execute(signal, c_schemaRecord.m_callback, 0);
+    jam();
+    TxHandlePtr tx_ptr;
+    c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
+
+    Callback c = {
+      safe_cast(&Dbdict::restartEndPass_fromEndTrans),
+      tx_ptr.p->tx_key
+    };
+    tx_ptr.p->m_callback = c;
+
+    Uint32 flags = 0;
+    endSchemaTrans(signal, tx_ptr, flags);
+    return;
   }
 }//checkSchemaStatus()
 
 void
-Dbdict::restartCreateTab(Signal* signal, Uint32 tableId, 
-			 const SchemaFile::TableEntry * old_entry, 
-			 const SchemaFile::TableEntry * new_entry, 
-			 bool file)
+Dbdict::checkPendingSchemaTrans(XSchemaFile* xsf)
 {
-  jam();
-  D("restartCreateTab");
+  for (Uint32 i = 0; i < xsf->noOfPages * NDB_SF_PAGE_ENTRIES; i++)
+  {
+    SchemaFile::TableEntry * transEntry = getTableEntry(xsf, i);
 
-  switch(new_entry->m_tableType){
-  case DictTabInfo::UndefTableType:
-  case DictTabInfo::HashIndexTrigger:
-  case DictTabInfo::SubscriptionTrigger:
-  case DictTabInfo::ReadOnlyConstraint:
-  case DictTabInfo::IndexTrigger:
-    ndbrequire(false);
-  case DictTabInfo::SystemTable:
-  case DictTabInfo::UserTable:
-  case DictTabInfo::UniqueHashIndex:
-  case DictTabInfo::HashIndex:
-  case DictTabInfo::UniqueOrderedIndex:
-  case DictTabInfo::OrderedIndex:
-    break;
-  case DictTabInfo::Tablespace:
-  case DictTabInfo::LogfileGroup:
-  case DictTabInfo::Datafile:
-  case DictTabInfo::Undofile:
-    restartCreateObj(signal, tableId, old_entry, new_entry, file);
-    return;
-  }
+    if (transEntry->m_tableType == DictTabInfo::SchemaTransaction &&
+        transEntry->m_transId != 0)
+    {
+      jam();
   
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;  
-  seizeSchemaOp(op_ptr, createTabPtr);
-  ndbrequire(!op_ptr.isNull());
-  CreateTabReq* impl_req = &createTabPtr.p->m_request;
-
-  impl_req->senderRef = reference();
-  impl_req->senderData = op_ptr.p->op_key;
-  impl_req->requestType = 0;
-  impl_req->tableId = tableId;
-  impl_req->tableVersion = 0;
-  impl_req->gci = 0;
+      bool commit = false;
+      switch(transEntry->m_tableState){
+      case SchemaFile::SF_STARTED:
+      case SchemaFile::SF_PREPARE:
+      case SchemaFile::SF_ABORT:
+        jam();
+        ndbout_c("Found pending trans (%u) - aborting", i);
+        break;
+      case SchemaFile::SF_COMMIT:
+      case SchemaFile::SF_COMPLETE:
+        jam();
+        commit = true;
+        ndbout_c("Found pending trans (%u) - committing", i);
+        break;
+      }
 
-  if(file && !ERROR_INSERTED(6002)){
-    jam();
-    
-    c_readTableRecord.no_of_words = old_entry->m_info_words;
-    c_readTableRecord.pageId = 0;
-    c_readTableRecord.m_callback.m_callbackData = op_ptr.p->op_key;
-    c_readTableRecord.m_callback.m_callbackFunction = 
-      safe_cast(&Dbdict::restartCreateTab_readTableConf);
-    
-    startReadTableFile(signal, tableId);
-    return;
-  } else {
-    
-    ndbrequire(c_masterNodeId != getOwnNodeId());
-    
-    /**
-     * Get from master
-     */
-    GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
-    req->senderRef = reference();
-    req->senderData = op_ptr.p->op_key;
-    req->requestType = GetTabInfoReq::RequestById |
-      GetTabInfoReq::LongSignalConf;
-    req->tableId = tableId;
-    sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
-	       GetTabInfoReq::SignalLength, JBB);
+      const Uint32 transId = transEntry->m_transId;
+      for (Uint32 j = 0; j<xsf->noOfPages * NDB_SF_PAGE_ENTRIES; j++)
+      {
+        SchemaFile::TableEntry * tmp = getTableEntry(xsf, j);
+        if (tmp->m_transId == transId &&
+            tmp->m_tableType != DictTabInfo::SchemaTransaction)
+        {
+          jam();
+          tmp->m_transId = 0;
+          switch(tmp->m_tableState){
+          case SchemaFile::SF_CREATE:
+            if (commit)
+            {
+              jam();
+              tmp->m_tableState = SchemaFile::SF_IN_USE;
+              ndbout_c("commit create %u", j);
+            }
+            else
+            {
+              jam();
+              tmp->m_tableState = SchemaFile::SF_UNUSED;
+              ndbout_c("abort create %u", j);
+            }
+            break;
+          case SchemaFile::SF_ALTER:
+            tmp->m_tableState = SchemaFile::SF_IN_USE;
+            if (commit)
+            {
+              jam();
+              ndbout_c("commit alter %u", j);
+            }
+            else
+            {
+              jam();
+              ndbout_c("abort alter %u", j);
+              tmp->m_tableVersion =
+                alter_obj_dec_schema_version(tmp->m_tableVersion);
+            }
+            break;
+          case SchemaFile::SF_DROP:
+            if (commit)
+            {
+              jam();
+              tmp->m_tableState = SchemaFile::SF_UNUSED;
+              ndbout_c("commit drop %u", j);
+            }
+            else
+            {
+              jam();
+              tmp->m_tableState = SchemaFile::SF_IN_USE;
+              ndbout_c("abort drop %u", j);
+            }
+            break;
+          }
+        }
+      }
 
-    if(ERROR_INSERTED(6002)){
-      NdbSleep_MilliSleep(10);
-      CRASH_INSERTION(6002);
+      transEntry->m_tableState = SchemaFile::SF_UNUSED;
+      transEntry->m_transId = 0;
     }
   }
 }
 
 void
-Dbdict::restartCreateTab_readTableConf(Signal* signal, 
-				       Uint32 op_key,
-				       Uint32 ret)
+Dbdict::restart_fromBeginTrans(Signal* signal, Uint32 tx_key, Uint32 ret)
 {
-  jam();
-  D("restartCreateTab_readTableConf");
+  ndbrequire(ret == 0);
   
-  PageRecordPtr pageRecPtr;
-  c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
+  TxHandlePtr tx_ptr;
+  findTxHandle(tx_ptr, tx_key);
+  ndbrequire(!tx_ptr.isNull());
+
+  checkSchemaStatus(signal);
+}
+
+void
+Dbdict::restart_fromEndTrans(Signal* signal, Uint32 tx_key, Uint32 ret)
+{
+  ndbrequire(ret == 0); //wl3600_todo
+
+  TxHandlePtr tx_ptr;
+  findTxHandle(tx_ptr, tx_key);
+  ndbrequire(!tx_ptr.isNull());
 
-  ParseDictTabInfoRecord parseRecord;
-  parseRecord.requestType = DictTabInfo::GetTabInfoConf;
-  parseRecord.errorCode = 0;
+  releaseTxHandle(tx_ptr);
+
+  c_restartRecord.activeTable++;
+
+  seizeTxHandle(tx_ptr);
+  ndbrequire(!tx_ptr.isNull());
+  c_restartRecord.m_tx_ptr_i = tx_ptr.i;
+  tx_ptr.p->m_requestInfo = DictSignal::RF_LOCAL_TRANS;
+  tx_ptr.p->m_userData = 0;
+
+  Callback c = {
+    safe_cast(&Dbdict::restart_fromBeginTrans),
+    tx_ptr.p->tx_key
+  };
+  tx_ptr.p->m_callback = c;
+  beginSchemaTrans(signal, tx_ptr);
+}
+
+void
+Dbdict::restartEndPass_fromEndTrans(Signal* signal, Uint32 tx_key, Uint32 ret)
+{
+  ndbrequire(ret == 0); //wl3600_todo
   
-  Uint32 sz = c_readTableRecord.no_of_words;
-  SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz);
-  handleTabInfoInit(r, &parseRecord);
-  if (parseRecord.errorCode != 0)
-  {
-    char buf[255];
-    BaseString::snprintf(buf, sizeof(buf), 
-                         "Failed to create table %u during restart,"
-                         " error: %u line: %u."
-			 " Most likely change of configuration",
-			 c_readTableRecord.tableId,
-			 parseRecord.errorCode,
-                         parseRecord.errorLine);
-    progError(__LINE__, 
-	      NDBD_EXIT_INVALID_CONFIG,
-	      buf);
-    ndbrequire(parseRecord.errorCode == 0);
+  TxHandlePtr tx_ptr;
+  findTxHandle(tx_ptr, tx_key);
+  ndbrequire(!tx_ptr.isNull());
+
+  releaseTxHandle(tx_ptr);
+  c_restartRecord.m_tx_ptr_i = RNIL;
+
+  restartNextPass(signal);
+}
+
+void
+Dbdict::restartNextPass(Signal* signal)
+{
+  c_restartRecord.m_pass++;
+  c_restartRecord.activeTable= 0;
+
+  if(c_restartRecord.m_pass <= LAST_PASS)
+  {
+    TxHandlePtr tx_ptr;
+    if (c_restartRecord.m_tx_ptr_i == RNIL)
+    {
+      jam();
+      seizeTxHandle(tx_ptr);
+      ndbrequire(!tx_ptr.isNull());
+      c_restartRecord.m_tx_ptr_i  = tx_ptr.i;
+      tx_ptr.p->m_requestInfo = DictSignal::RF_LOCAL_TRANS;
+      tx_ptr.p->m_userData = 0;
+
+      Callback c = {
+        safe_cast(&Dbdict::restart_fromBeginTrans),
+        tx_ptr.p->tx_key
+      };
+      tx_ptr.p->m_callback = c;
+      beginSchemaTrans(signal, tx_ptr);
+      return;
+    }
+    else
+    {
+      jam();
+      c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
+      restart_fromBeginTrans(signal, tx_ptr.p->tx_key, 0);
+      return;
+    }
   }
+  else
+  {
+    jam();
 
-  /* ---------------------------------------------------------------- */
-  // We have read the table description from disk as part of system restart.
-  // We will also write it back again to ensure that both copies are ok.
-  /* ---------------------------------------------------------------- */
-  ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
-  c_writeTableRecord.no_of_words = c_readTableRecord.no_of_words;
-  c_writeTableRecord.pageId = c_readTableRecord.pageId;
-  c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
-  c_writeTableRecord.m_callback.m_callbackData = op_key;
-  c_writeTableRecord.m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateTab_writeTableConf);
-  startWriteTableFile(signal, c_readTableRecord.tableId);
+    /**
+     * Write schema file at-end of checkSchemaStatus
+     */
+    XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
+    ndbrequire(c_writeSchemaRecord.inUse == false);
+    c_writeSchemaRecord.inUse = true;
+    c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
+    c_writeSchemaRecord.newFile = false;
+    c_writeSchemaRecord.firstPage = 0;
+    c_writeSchemaRecord.noOfPages = xsf->noOfPages;
+    c_writeSchemaRecord.m_callback = c_schemaRecord.m_callback;
+
+    for(Uint32 i = 0; i<xsf->noOfPages; i++)
+      computeChecksum(xsf, i);
+
+    startWriteSchemaFile(signal);
+  }
 }
 
 void
@@ -3602,199 +3535,12 @@ Dbdict::execGET_TABINFO_CONF(Signal* sig
     else
     {
       jam();
-      restartCreateObj_getTabInfoConf(signal);
+      break;
     }
     return;
   }
-  
-  const Uint32 tableId = conf->tableId;
-  const Uint32 senderData = conf->senderData;
-
-  SectionHandle handle(this, signal);
-  SegmentedSectionPtr tabInfoPtr;
-  handle.getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
-
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;  
-  findSchemaOp(op_ptr, createTabPtr, senderData);
-  ndbrequire(!op_ptr.isNull());
-  ndbrequire(createTabPtr.p->m_request.tableId == tableId);
-
-  /**
-   * Put data into table record
-   */
-  ParseDictTabInfoRecord parseRecord;
-  parseRecord.requestType = DictTabInfo::GetTabInfoConf;
-  parseRecord.errorCode = 0;
-  
-  SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
-  handleTabInfoInit(r, &parseRecord);
-  ndbrequire(parseRecord.errorCode == 0);
-
-  // save to disk
 
-  ndbrequire(tableId < c_tableRecordPool.getSize());
-  XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
-  SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
-  tableEntry->m_info_words= tabInfoPtr.sz;
-  
-  Callback callback;
-  callback.m_callbackData = op_ptr.p->op_key;
-  callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateTab_writeTableConf);
-  
-  writeTableFile(signal, tableId, tabInfoPtr, &callback);
-
-  releaseSections(handle);
-}
-
-void
-Dbdict::restartCreateTab_writeTableConf(Signal* signal, 
-					Uint32 op_key,
-					Uint32 ret)
-{
-  jam();
-  D("restartCreateTab_writeTableConf");
-
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;  
-  findSchemaOp(op_ptr, createTabPtr, op_key);
-  ndbrequire(!op_ptr.isNull());
-
-  Callback callback;
-  callback.m_callbackData = op_key;
-  callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateTab_dihComplete);
-
-  OpSection& fragSection = op_ptr.p->m_section[CreateTabReq::FRAGMENTATION];
-  new (&fragSection) OpSection;
-  createTab_dih(signal, op_ptr, fragSection, &callback);
-}
-
-void
-Dbdict::restartCreateTab_dihComplete(Signal* signal, 
-				     Uint32 op_key,
-				     Uint32 ret)
-{
-  jam();
-  D("restartCreateTab_dihComplete");
-  
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;  
-  findSchemaOp(op_ptr, createTabPtr, op_key);
-  ndbrequire(!op_ptr.isNull());
-  const CreateTabReq* impl_req = &createTabPtr.p->m_request;
-
-  if (hasError(op_ptr.p->m_error))
-  {
-    char buf[100];
-    BaseString::snprintf(buf, sizeof(buf),
-                         "Failed to create table %u during restart,"
-                         " error: %u line: %u.",
-                         impl_req->tableId,
-                         op_ptr.p->m_error.errorCode,
-                         op_ptr.p->m_error.errorLine);
-    progError(__LINE__, NDBD_EXIT_RESOURCE_ALLOC_ERROR, buf);
-  }
-
-  Callback callback;
-  callback.m_callbackData = op_key;
-  callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateTab_activateComplete);
-  
-  createTab_activate(signal, op_ptr, &callback);
-}
-
-void
-Dbdict::restartCreateTab_activateComplete(Signal* signal, 
-					  Uint32 op_key,
-					  Uint32 ret)
-{
-  jam();
-  D("restartCreateTab_activateComplete");
-  
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;  
-  findSchemaOp(op_ptr, createTabPtr, op_key);
-  ndbrequire(!op_ptr.isNull());
-  const CreateTabReq* impl_req = &createTabPtr.p->m_request;
-
-  TableRecordPtr tabPtr;
-  c_tableRecordPool.getPtr(tabPtr, impl_req->tableId);
-  tabPtr.p->tabState = TableRecord::DEFINED;
-  
-  releaseSchemaOp(op_ptr);
-
-  c_restartRecord.activeTable++;
-  checkSchemaStatus(signal);
-}
-
-void
-Dbdict::restartDropTab(Signal* signal, Uint32 tableId,
-                       const SchemaFile::TableEntry * old_entry, 
-                       const SchemaFile::TableEntry * new_entry)
-{
-  switch(old_entry->m_tableType){
-  case DictTabInfo::UndefTableType:
-  case DictTabInfo::HashIndexTrigger:
-  case DictTabInfo::SubscriptionTrigger:
-  case DictTabInfo::ReadOnlyConstraint:
-  case DictTabInfo::IndexTrigger:
-    ndbrequire(false);
-  case DictTabInfo::SystemTable:
-  case DictTabInfo::UserTable:
-  case DictTabInfo::UniqueHashIndex:
-  case DictTabInfo::HashIndex:
-  case DictTabInfo::UniqueOrderedIndex:
-  case DictTabInfo::OrderedIndex:
-    break;
-  case DictTabInfo::Tablespace:
-  case DictTabInfo::LogfileGroup:
-  case DictTabInfo::Datafile:
-  case DictTabInfo::Undofile:
-    restartDropObj(signal, tableId, old_entry);
-    return;
-  }
-
-  SchemaOpPtr op_ptr;
-  DropTableRecPtr dropTabPtr;  
-  seizeSchemaOp(op_ptr, dropTabPtr);
-  ndbrequire(!op_ptr.isNull());
-  DropTabReq* impl_req = &dropTabPtr.p->m_request;
-
-  impl_req->senderRef = reference();
-  impl_req->senderData = op_ptr.p->op_key;
-  impl_req->requestType = DropTabReq::RestartDropTab;
-  impl_req->tableId = tableId;
-  impl_req->tableVersion = 0;
-
-  dropTabPtr.p->m_block = 0;
-  dropTabPtr.p->m_callback.m_callbackData = op_ptr.p->op_key;
-  dropTabPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartDropTab_complete);
-  dropTab_nextStep(signal, op_ptr);  
-}
-
-void
-Dbdict::restartDropTab_complete(Signal* signal, 
-				Uint32 op_key,
-				Uint32 ret)
-{
-  jam();
-
-  SchemaOpPtr op_ptr;
-  DropTableRecPtr dropTabPtr;  
-  findSchemaOp(op_ptr, dropTabPtr, op_key);
-  ndbrequire(!op_ptr.isNull());
-  //const DropTabReq* impl_req = &dropTabPtr.p->m_request;
-
-  //@todo check error
-
-  releaseTableObject(c_restartRecord.activeTable);
-  releaseSchemaOp(op_ptr);
-
-  c_restartRecord.activeTable++;
-  checkSchemaStatus(signal);
+  restartCreateObj_getTabInfoConf(signal);
 }
 
 /**
@@ -3803,51 +3549,16 @@ Dbdict::restartDropTab_complete(Signal* 
 void
 Dbdict::restartCreateObj(Signal* signal, 
 			 Uint32 tableId, 
-			 const SchemaFile::TableEntry * old_entry,
 			 const SchemaFile::TableEntry * new_entry,
 			 bool file){
   jam();
   
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.seize(createObjPtr));
-  
-  const Uint32 key = ++c_opRecordSequence;
-  createObjPtr.p->key = key;
-  c_opCreateObj.add(createObjPtr);
-  createObjPtr.p->m_errorCode = 0;
-  createObjPtr.p->m_senderRef = reference();
-  createObjPtr.p->m_senderData = tableId;
-  createObjPtr.p->m_clientRef = reference();
-  createObjPtr.p->m_clientData = tableId;
-  
-  createObjPtr.p->m_obj_id = tableId;
-  createObjPtr.p->m_obj_type = new_entry->m_tableType;
-  createObjPtr.p->m_obj_version = new_entry->m_tableVersion;
-
-  createObjPtr.p->m_callback.m_callbackData = key;
-  createObjPtr.p->m_callback.m_callbackFunction= 
-    safe_cast(&Dbdict::restartCreateObj_prepare_start_done);
-  
-  createObjPtr.p->m_restart= file ? 1 : 2;
-  switch(new_entry->m_tableType){
-  case DictTabInfo::Tablespace:
-  case DictTabInfo::LogfileGroup:
-    createObjPtr.p->m_vt_index = 0;
-    break;
-  case DictTabInfo::Datafile:
-  case DictTabInfo::Undofile:
-    createObjPtr.p->m_vt_index = 1;
-    break;
-  default:
-    ndbrequire(false);
-  }
-  
-  createObjPtr.p->m_obj_info_ptr_i = RNIL;
+  c_restartRecord.m_entry = *new_entry;
   if(file)
   {
-    c_readTableRecord.no_of_words = old_entry->m_info_words;
+    c_readTableRecord.no_of_words = new_entry->m_info_words;
     c_readTableRecord.pageId = 0;
-    c_readTableRecord.m_callback.m_callbackData = key;
+    c_readTableRecord.m_callback.m_callbackData = tableId;
     c_readTableRecord.m_callback.m_callbackFunction = 
       safe_cast(&Dbdict::restartCreateObj_readConf);
     
@@ -3860,7 +3571,7 @@ Dbdict::restartCreateObj(Signal* signal,
      */
     GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
     req->senderRef = reference();
-    req->senderData = key;
+    req->senderData = tableId;
     req->requestType = GetTabInfoReq::RequestById |
       GetTabInfoReq::LongSignalConf;
     req->tableId = tableId;
@@ -3874,24 +3585,12 @@ Dbdict::restartCreateObj_getTabInfoConf(
 {
   jam();
 
-  GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
-
-  const Uint32 objId = conf->tableId;
-  const Uint32 senderData = conf->senderData;
-
   SectionHandle handle(this, signal);
   SegmentedSectionPtr objInfoPtr;
   handle.getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
   handle.clear();
 
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, senderData));
-  ndbrequire(createObjPtr.p->m_obj_id == objId);
-  
-  createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i;
-  
-  (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
-    (signal, createObjPtr.p);
+  restartCreateObj_parse(signal, objInfoPtr, false);
 }
 
 void
@@ -3901,9 +3600,6 @@ Dbdict::restartCreateObj_readConf(Signal
 {
   jam();
   ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
 
   PageRecordPtr pageRecPtr;
   c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
@@ -3912,119 +3608,85 @@ Dbdict::restartCreateObj_readConf(Signal
 
   Ptr<SectionSegment> ptr;
   ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz));
-  createObjPtr.p->m_obj_info_ptr_i= ptr.i;  
-  
-  if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
-    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
-      (signal, createObjPtr.p);
-  else
-    execute(signal, createObjPtr.p->m_callback, 0);
+  SegmentedSectionPtr tmp(sz, ptr.i, ptr.p);
+  restartCreateObj_parse(signal, tmp, true);
 }
 
 void
-Dbdict::restartCreateObj_prepare_start_done(Signal* signal,
-					    Uint32 callbackData, 
-					    Uint32 returnCode)
+Dbdict::restartCreateObj_parse(Signal* signal,
+                               SegmentedSectionPtr ptr,
+                               bool file)
 {
   jam();
-  ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
-
-  Callback callback;
-  callback.m_callbackData = callbackData;
-  callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateObj_write_complete);
+  Ptr<SchemaOp> op_ptr;
   
-  SegmentedSectionPtr objInfoPtr;
-  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
+  switch(c_restartRecord.m_entry.m_tableType){
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+  {
+    Ptr<CreateTableRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
+    break;
+  }
+  case DictTabInfo::Undofile:
+  case DictTabInfo::Datafile:
+  {
+    Ptr<CreateFileRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
+    break;
+  }
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  {
+    Ptr<CreateFilegroupRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
+    break;
+  }
+  }
 
-  writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
-}
+  Ptr<TxHandle> tx_ptr;
+  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
 
-void
-Dbdict::restartCreateObj_write_complete(Signal* signal,
-					Uint32 callbackData, 
-					Uint32 returnCode)
-{
-  ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
+  Ptr<SchemaTrans> trans_ptr;
+  findSchemaTrans(trans_ptr, tx_ptr.p->m_transKey);
+  addSchemaOp(trans_ptr, op_ptr);
+  op_ptr.p->m_restart = file ? 1 : 2;
+  op_ptr.p->m_state = SchemaOp::OS_PARSE_MASTER;
   
-  SectionHandle handle(this, createObjPtr.p->m_obj_info_ptr_i);
+  SectionHandle handle(this, ptr.i);
+  ErrorInfo error;
+  const OpInfo& info = getOpInfo(op_ptr);
+  (this->*(info.m_parse))(signal, false, op_ptr, handle, error);
+  ndbrequire(!hasError(error));
   releaseSections(handle);
-  createObjPtr.p->m_obj_info_ptr_i = RNIL;
-  
-  createObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateObj_prepare_complete_done);
-  
-  if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
-    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
-      (signal, createObjPtr.p);
-  else
-    execute(signal, createObjPtr.p->m_callback, 0);
-}
+  ndbrequire(!hasError(error));
 
-void
-Dbdict::restartCreateObj_prepare_complete_done(Signal* signal,
-					       Uint32 callbackData, 
-					       Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
-
-  createObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateObj_commit_start_done);
-
-  if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
-    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
-      (signal, createObjPtr.p);
-  else
-    execute(signal, createObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartCreateObj_commit_start_done(Signal* signal,
-					   Uint32 callbackData, 
-					   Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
-
-  createObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartCreateObj_commit_complete_done);
-
-  if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
-    (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
-      (signal, createObjPtr.p);
-  else
-    execute(signal, createObjPtr.p->m_callback, 0);
-}  
+  c_restartRecord.m_op_cnt++;
 
+  if (c_restartRecord.m_op_cnt >= ZRESTART_OPS_PER_TRANS)
+  {
+    jam();
+    c_restartRecord.m_op_cnt = 0;
 
-void
-Dbdict::restartCreateObj_commit_complete_done(Signal* signal,
-					      Uint32 callbackData, 
-					      Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  ndbrequire(createObjPtr.p->m_errorCode == 0);
-  
-  c_opCreateObj.release(createObjPtr);
+    Callback c = {
+      safe_cast(&Dbdict::restart_fromEndTrans),
+      tx_ptr.p->tx_key
+    };
+    tx_ptr.p->m_callback = c;
 
-  c_restartRecord.activeTable++;
-  checkSchemaStatus(signal);
+    Uint32 flags = 0;
+    endSchemaTrans(signal, tx_ptr, flags);
+  }
+  else
+  {
+    jam();
+    c_restartRecord.activeTable++;
+    checkSchemaStatus(signal);
+  }
 }
 
 /**
@@ -4036,159 +3698,75 @@ Dbdict::restartDropObj(Signal* signal, 
                        const SchemaFile::TableEntry * entry)
 {
   jam();
-  
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.seize(dropObjPtr));
-  
-  const Uint32 key = ++c_opRecordSequence;
-  dropObjPtr.p->key = key;
-  c_opDropObj.add(dropObjPtr);
-  dropObjPtr.p->m_errorCode = 0;
-  dropObjPtr.p->m_senderRef = reference();
-  dropObjPtr.p->m_senderData = tableId;
-  dropObjPtr.p->m_clientRef = reference();
-  dropObjPtr.p->m_clientData = tableId;
-  
-  dropObjPtr.p->m_obj_id = tableId;
-  dropObjPtr.p->m_obj_type = entry->m_tableType;
-  dropObjPtr.p->m_obj_version = entry->m_tableVersion;
-
-  dropObjPtr.p->m_callback.m_callbackData = key;
-  dropObjPtr.p->m_callback.m_callbackFunction= 
-    safe_cast(&Dbdict::restartDropObj_prepare_start_done);
+  c_restartRecord.m_entry = *entry;
 
-  ndbout_c("Dropping %d %d", tableId, entry->m_tableType);
-  switch(entry->m_tableType){
-  case DictTabInfo::Tablespace:
-  case DictTabInfo::LogfileGroup:{
-    jam();
-    Ptr<Filegroup> fg_ptr;
-    ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
-    dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
-    dropObjPtr.p->m_vt_index = 3;
+  jam();
+  Ptr<SchemaOp> op_ptr;
+
+  switch(c_restartRecord.m_entry.m_tableType){
+  case DictTabInfo::SystemTable:
+  case DictTabInfo::UserTable:
+  case DictTabInfo::UniqueHashIndex:
+  case DictTabInfo::HashIndex:
+  case DictTabInfo::UniqueOrderedIndex:
+  case DictTabInfo::OrderedIndex:
+    Ptr<DropTableRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
     break;
-  }
-  case DictTabInfo::Datafile:{
-    jam();
-    Ptr<File> file_ptr;
-    dropObjPtr.p->m_vt_index = 2;
-    ndbrequire(c_file_hash.find(file_ptr, tableId));
-    dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
+  case DictTabInfo::Undofile:
+  case DictTabInfo::Datafile:
+  {
+    Ptr<DropFileRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
     break;
   }
-  case DictTabInfo::Undofile:{
-    jam();    
-    Ptr<File> file_ptr;
-    dropObjPtr.p->m_vt_index = 4;
-    ndbrequire(c_file_hash.find(file_ptr, tableId));
-    dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
-
-    /**
-     * Undofiles are only removed from logfile groups file list
-     *   as drop undofile is currently not supported...
-     *   file will be dropped by lgman when dropping filegroup
-     */
-    dropObjPtr.p->m_callback.m_callbackFunction= 
-      safe_cast(&Dbdict::restartDropObj_commit_complete_done);
-    
-    if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
-      (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
-        (signal, dropObjPtr.p);
-    else
-      execute(signal, dropObjPtr.p->m_callback, 0);
-    return;
+  case DictTabInfo::Tablespace:
+  case DictTabInfo::LogfileGroup:
+  {
+    Ptr<DropFilegroupRec> opRecPtr;
+    seizeSchemaOp(op_ptr, opRecPtr);
+    break;
   }
-  default:
-    jamLine(entry->m_tableType);
-    ndbrequire(false);
   }
   
-  if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
-    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
-      (signal, dropObjPtr.p);
-  else
-    execute(signal, dropObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartDropObj_prepare_start_done(Signal* signal,
-                                          Uint32 callbackData, 
-                                          Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  ndbrequire(dropObjPtr.p->m_errorCode == 0);
-  
-  dropObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartDropObj_prepare_complete_done);
-  
-  if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
-    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
-      (signal, dropObjPtr.p);
-  else
-    execute(signal, dropObjPtr.p->m_callback, 0);
-}
+  Ptr<TxHandle> tx_ptr;
+  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
 
-void
-Dbdict::restartDropObj_prepare_complete_done(Signal* signal,
-                                             Uint32 callbackData, 
-                                             Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  ndbrequire(dropObjPtr.p->m_errorCode == 0);
-  
-  dropObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartDropObj_commit_start_done);
-  
-  if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
-    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
-      (signal, dropObjPtr.p);
-  else
-    execute(signal, dropObjPtr.p->m_callback, 0);
-}
+  Ptr<SchemaTrans> trans_ptr;
+  findSchemaTrans(trans_ptr, tx_ptr.p->m_transKey);
+  addSchemaOp(trans_ptr, op_ptr);
+  op_ptr.p->m_restart = 1; //
+  op_ptr.p->m_state = SchemaOp::OS_PARSE_MASTER;
+  
+  SectionHandle handle(this);
+  ErrorInfo error;
+  const OpInfo& info = getOpInfo(op_ptr);
+  (this->*(info.m_parse))(signal, false, op_ptr, handle, error);
+  releaseSections(handle);
+  ndbrequire(!hasError(error));
 
-void
-Dbdict::restartDropObj_commit_start_done(Signal* signal,
-                                         Uint32 callbackData, 
-                                         Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  ndbrequire(dropObjPtr.p->m_errorCode == 0);
-  
-  dropObjPtr.p->m_callback.m_callbackFunction = 
-    safe_cast(&Dbdict::restartDropObj_commit_complete_done);
-
-  if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
-    (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
-      (signal, dropObjPtr.p);
-  else
-    execute(signal, dropObjPtr.p->m_callback, 0);
-}  
+  c_restartRecord.m_op_cnt++;
 
+  if (c_restartRecord.m_op_cnt >= ZRESTART_OPS_PER_TRANS)
+  {
+    jam();
+    c_restartRecord.m_op_cnt = 0;
 
-void
-Dbdict::restartDropObj_commit_complete_done(Signal* signal,
-                                            Uint32 callbackData, 
-                                            Uint32 returnCode)
-{
-  jam();
-  ndbrequire(returnCode == 0);
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  ndbrequire(dropObjPtr.p->m_errorCode == 0);
-  
-  c_opDropObj.release(dropObjPtr);
+    Callback c = {
+      safe_cast(&Dbdict::restart_fromEndTrans),
+      tx_ptr.p->tx_key
+    };
+    tx_ptr.p->m_callback = c;
 
-  c_restartRecord.activeTable++;
-  checkSchemaStatus(signal);
+    Uint32 flags = 0;
+    endSchemaTrans(signal, tx_ptr, flags);
+  }
+  else
+  {
+    jam();
+    c_restartRecord.activeTable++;
+    checkSchemaStatus(signal);
+  }
 }
 
 /* **************************************************************** */
@@ -5035,12 +4613,6 @@ Dbdict::createTable_parse(Signal* signal
   getOpRec(op_ptr, createTabPtr);
   CreateTabReq* impl_req = &createTabPtr.p->m_request;
 
-  if (checkSingleUserMode(trans_ptr.p->m_clientRef)) {
-    jam();
-    setError(error, CreateTableRef::SingleUser, __LINE__);
-    return;
-  }
-
   /*
    * Master parses client DictTabInfo (sec 0) into new table record.
    * DIH is called to create fragmentation.  The table record is
@@ -5085,6 +4657,11 @@ Dbdict::createTable_parse(Signal* signal
       ndbrequire(ok);
     }
 
+    {
+      Uint32 version = getTableEntry(tabPtr.i)->m_tableVersion;
+      tabPtr.p->tableVersion = create_obj_inc_schema_version(version);
+    }
+
     // fill in table id and version
     impl_req->tableId = tabPtr.i;
     impl_req->tableVersion = tabPtr.p->tableVersion;
@@ -5150,16 +4727,6 @@ Dbdict::createTable_parse(Signal* signal
       tabPtr.p->fragmentCount = frag_data[1];
     }
 
-    // update table version
-    {
-      XSchemaFile * xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
-      SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i);
-
-      impl_req->tableVersion =
-        tabPtr.p->tableVersion =
-        create_obj_inc_schema_version(tabEntry->m_tableVersion);
-    }
-
     // dump table record back into DictTabInfo
     {
       SimplePropertiesSectionWriter w(getSectionSegmentPool());
@@ -5188,6 +4755,13 @@ Dbdict::createTable_parse(Signal* signal
       createTabPtr.p->m_fragmentsPtrI = RNIL;
     }
   }
+  else if (op_ptr.p->m_restart)
+  {
+    jam();
+    impl_req->tableId = c_restartRecord.activeTable;
+    impl_req->tableVersion = c_restartRecord.m_entry.m_tableVersion;
+    impl_req->gci = c_restartRecord.m_entry.m_gcp;
+  }
 
   const Uint32 gci = impl_req->gci;
   const Uint32 tableId = impl_req->tableId;
@@ -5234,7 +4808,11 @@ Dbdict::createTable_parse(Signal* signal
 
   // save sections to DICT memory
   saveOpSection(op_ptr, handle, CreateTabReq::DICT_TAB_INFO);
-  saveOpSection(op_ptr, handle, CreateTabReq::FRAGMENTATION);
+  if (op_ptr.p->m_restart == 0)
+  {
+    jam();
+    saveOpSection(op_ptr, handle, CreateTabReq::FRAGMENTATION);
+  }
 
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, tableId);
@@ -5250,28 +4828,21 @@ Dbdict::createTable_parse(Signal* signal
     return;
   }
 
-  // save original schema file entry
-  {
-    XSchemaFile* xsf = &c_schemaFile[SchemaRecord::NEW_SCHEMA_FILE];
-    SchemaFile::TableEntry* tableEntry = getTableEntry(xsf, tableId);
-    createTabPtr.p->m_orig_entry = *tableEntry;
-  }
-
-  // update schema file entry in memory
-  {
-    SchemaFile::TableEntry& te = createTabPtr.p->m_curr_entry;
-    te.init();
-    te.m_tableState = SchemaFile::CREATE_PARSED;
-    te.m_tableVersion = tableVersion;
-    te.m_tableType = tabPtr.p->tableType;
-    te.m_info_words = tabInfoPtr.sz;
-    te.m_gcp = gci;
-    te.m_transId = trans_ptr.p->m_transId;
+  SchemaFile::TableEntry te; te.init();
+  te.m_tableState = SchemaFile::SF_CREATE;
+  te.m_tableVersion = tableVersion;
+  te.m_tableType = tabPtr.p->tableType;
+  te.m_info_words = tabInfoPtr.sz;
+  te.m_gcp = gci;
+  te.m_transId = trans_ptr.p->m_transId;
 
-    bool savetodisk = false;
-    updateSchemaState(signal, tableId, &te, (Callback*)0, savetodisk, 1);
+  Uint32 err = trans_log_schema_op(op_ptr, tableId, &te);
+  if (err)
+  {
+    jam();
+    setError(error, err, __LINE__);
+    return;
   }
-
   D("createTable_parse: "
     << copyRope<MAX_TAB_NAME_SIZE>(tabPtr.p->tableName)
     << V(tabPtr.p->tableVersion));
@@ -5339,51 +4910,33 @@ Dbdict::createTable_prepare(Signal* sign
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, tableId);
 
-  D("createTable_prepare" << *op_ptr.p);
-
-  // update schema file entry on disk
-  SchemaFile::TableEntry& te = createTabPtr.p->m_curr_entry;
-  te.m_tableState = SchemaFile::ADD_STARTED;
-
-  Callback callback;
-  callback.m_callbackData = op_ptr.p->op_key;
-  callback.m_callbackFunction =
-    safe_cast(&Dbdict::createTab_writeSchemaConf1);
-
-  bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
-  updateSchemaState(signal, tableId, &te, &callback, savetodisk, 1);
-}
-
-void
-Dbdict::createTab_writeSchemaConf1(Signal* signal,
-                                   Uint32 op_key,
-                                   Uint32 ret)
-{
-  jam();
-
-  SchemaOpPtr op_ptr;
-  CreateTableRecPtr createTabPtr;
-  findSchemaOp(op_ptr, createTabPtr, op_key);
-  ndbrequire(!op_ptr.isNull());
+  Callback cb;
+  cb.m_callbackData = op_ptr.p->op_key;
+  cb.m_callbackFunction = safe_cast(&Dbdict::createTab_writeTableConf);
 
-  Callback callback;
-  callback.m_callbackData = op_ptr.p->op_key;
-  callback.m_callbackFunction =
-    safe_cast(&Dbdict::createTab_writeTableConf);
+  if (ZRESTART_NO_WRITE_AFTER_READ && op_ptr.p->m_restart == 1)
+  {
+    jam();
+    /**
+     * We read obj from disk, no need to rewrite it
+     */
+    execute(signal, cb, 0);
+    return;
+  }
 
-  TableRecordPtr tabPtr;
-  c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_request.tableId);
   bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
   if (savetodisk)
   {
+    jam();
     const OpSection& tabInfoSec =
       getOpSection(op_ptr, CreateTabReq::DICT_TAB_INFO);
     writeTableFile(signal, createTabPtr.p->m_request.tableId,
-                   tabInfoSec, &callback);
+                   tabInfoSec, &cb);
   }
   else
   {
-    execute(signal, callback, 0);
+    jam();