List:Commits« Previous MessageNext Message »
From:jonas oreland Date:October 7 2011 5:16pm
Subject:bzr push into mysql-5.1-telco-7.1 branch (jonas.oreland:4298 to 4299)
View as plain text  
 4299 jonas oreland	2011-10-07 [merge]
      ndb - merge 70 to 71

    added:
      storage/ndb/include/portlib/NdbGetRUsage.h
      storage/ndb/src/common/portlib/NdbGetRUsage.cpp
      storage/ndb/src/kernel/blocks/thrman.cpp
      storage/ndb/src/kernel/blocks/thrman.hpp
    modified:
      client/mysqlbinlog.cc
      mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
      mysql-test/suite/ndb/r/ndb_alter_table.result
      mysql-test/suite/ndb/r/ndbinfo.result
      mysql-test/suite/ndb/t/ndb_alter_table.test
      storage/ndb/include/kernel/BlockNumbers.h
      storage/ndb/include/kernel/ndb_limits.h
      storage/ndb/include/kernel/signaldata/SchemaTrans.hpp
      storage/ndb/include/mgmapi/mgmapi_config_parameters.h
      storage/ndb/src/common/debugger/BlockNames.cpp
      storage/ndb/src/common/portlib/CMakeLists.txt
      storage/ndb/src/common/portlib/Makefile.am
      storage/ndb/src/common/portlib/NdbThread.c
      storage/ndb/src/kernel/SimBlockList.cpp
      storage/ndb/src/kernel/blocks/CMakeLists.txt
      storage/ndb/src/kernel/blocks/LocalProxy.cpp
      storage/ndb/src/kernel/blocks/LocalProxy.hpp
      storage/ndb/src/kernel/blocks/Makefile.am
      storage/ndb/src/kernel/blocks/PgmanProxy.cpp
      storage/ndb/src/kernel/blocks/PgmanProxy.hpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
      storage/ndb/src/kernel/blocks/dbinfo/Dbinfo.cpp
      storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp
      storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp
      storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
      storage/ndb/src/kernel/blocks/record_types.hpp
      storage/ndb/src/kernel/ndbd.cpp
      storage/ndb/src/kernel/vm/DLFifoList.hpp
      storage/ndb/src/kernel/vm/DLHashTable.hpp
      storage/ndb/src/kernel/vm/DataBuffer2.hpp
      storage/ndb/src/kernel/vm/Ndbinfo.hpp
      storage/ndb/src/kernel/vm/NdbinfoTables.cpp
      storage/ndb/src/kernel/vm/Pool.hpp
      storage/ndb/src/kernel/vm/SimulatedBlock.hpp
      storage/ndb/src/kernel/vm/dummy_nonmt.cpp
      storage/ndb/src/kernel/vm/mt.cpp
      storage/ndb/src/kernel/vm/mt.hpp
      storage/ndb/src/kernel/vm/mt_thr_config.cpp
      storage/ndb/src/kernel/vm/mt_thr_config.hpp
      storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
      storage/ndb/src/mgmsrv/ConfigInfo.cpp
      storage/ndb/src/ndbapi/ndberror.c
      storage/ndb/tools/ndbinfo_select_all.cpp
      storage/ndb/tools/ndbinfo_sql.cpp
 4298 Jonas Oreland	2011-10-05 [merge]
      ndb - merge 70 to 71

    added:
      storage/ndb/tools/ndbinfo_select_all.cpp
    modified:
      storage/ndb/src/kernel/blocks/tsman.cpp
      storage/ndb/test/include/HugoQueryBuilder.hpp
      storage/ndb/test/run-test/atrt.hpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/run-test/daily-devel-tests.txt
      storage/ndb/test/run-test/files.cpp
      storage/ndb/test/run-test/main.cpp
      storage/ndb/test/run-test/setup.cpp
      storage/ndb/tools/CMakeLists.txt
      storage/ndb/tools/Makefile.am
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2011-06-30 15:59:25 +0000
+++ b/client/mysqlbinlog.cc	2011-10-06 14:43:17 +0000
@@ -900,6 +900,11 @@ Exit_status process_event(PRINT_EVENT_IN
     case WRITE_ROWS_EVENT:
     case DELETE_ROWS_EVENT:
     case UPDATE_ROWS_EVENT:
+#ifndef MCP_WL5353
+    case WRITE_ROWS_EVENT_V1:
+    case DELETE_ROWS_EVENT_V1:
+    case UPDATE_ROWS_EVENT_V1:
+#endif
     case PRE_GA_WRITE_ROWS_EVENT:
     case PRE_GA_DELETE_ROWS_EVENT:
     case PRE_GA_UPDATE_ROWS_EVENT:

=== modified file 'mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test'
--- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test	2009-09-30 02:31:25 +0000
+++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test	2011-10-06 14:43:17 +0000
@@ -140,6 +140,17 @@ while($i)
     -- echo **** ERROR **** Database name 'b42941' NOT FOUND in mysqlbinlog output ($flags $outfile.2).
   }
 
+  #bug #13067813
+  if (`SELECT INSTR(@b42941_output.1, 'unknown table')`)
+  {
+    -- echo **** ERROR **** Table mapping failure detected
+  }
+
+  if (`SELECT INSTR(@b42941_output.2, 'unknown table')`)
+  {
+    -- echo **** ERROR **** Table mapping failure detected
+  }
+
   dec $i;
 }
 

=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table.result	2009-07-13 10:51:28 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table.result	2011-10-07 14:28:37 +0000
@@ -283,7 +283,7 @@ c108 int(11) not null,
 c109 int(11) not null,
 primary key (ai),
 unique key tx1 (c002, c003, c004, c005)) engine=ndb;
-create index tx2 
+create index tx2
 on t1 (c010, c011, c012, c013);
 drop table t1;
 create table t1 (a int primary key auto_increment, b int) engine=ndb;
@@ -395,4 +395,136 @@ a	b
 2	200
 1	300
 drop table t1;
+create table t1 (
+ci001 int, ci002 int, ci003 int, ci004 int, ci005 int, ci006 int, ci007 int, ci008 int,
+ci009 int, ci010 int, ci011 int, ci012 int, ci013 int, ci014 int, ci015 int, ci016 int,
+ci017 int, ci018 int, ci019 int, ci020 int, ci021 int, ci022 int, ci023 int, ci024 int,
+ci025 int, ci026 int, ci027 int, ci028 int, ci029 int, ci030 int, ci031 int, ci032 int,
+ci033 int, ci034 int, ci035 int, ci036 int, ci037 int, ci038 int, ci039 int, ci040 int,
+ci041 int, ci042 int, ci043 int, ci044 int, ci045 int, ci046 int, ci047 int, ci048 int,
+ci049 int, ci050 int, ci051 int, ci052 int, ci053 int, ci054 int, ci055 int, ci056 int,
+ci057 int, ci058 int, ci059 int, ci060 int, ci061 int, ci062 int, ci063 int, ci064 int,
+ci065 int, ci066 int, ci067 int, ci068 int, ci069 int, ci070 int, ci071 int, ci072 int,
+ci073 int, ci074 int, ci075 int, ci076 int, ci077 int, ci078 int, ci079 int, ci080 int,
+ci081 int, ci082 int, ci083 int, ci084 int, ci085 int, ci086 int, ci087 int, ci088 int,
+ci089 int, ci090 int, ci091 int, ci092 int, ci093 int, ci094 int, ci095 int, ci096 int,
+ci097 int, ci098 int, ci099 int, ci100 int, ci101 int, ci102 int, ci103 int, ci104 int,
+ci105 int, ci106 int, ci107 int, ci108 int, ci109 int, ci110 int, ci111 int, ci112 int,
+ci113 int, ci114 int, ci115 int, ci116 int, ci117 int, ci118 int, ci119 int, ci120 int,
+ci121 int, ci122 int, ci123 int, ci124 int, ci125 int, ci126 int, ci127 int, ci128 int,
+ci129 int, ci130 int, ci131 int, ci132 int, ci133 int, ci134 int, ci135 int, ci136 int,
+ci137 int, ci138 int, ci139 int, ci140 int, ci141 int, ci142 int, ci143 int, ci144 int,
+ci145 int, ci146 int, ci147 int, ci148 int, ci149 int, ci150 int, ci151 int, ci152 int,
+ci153 int, ci154 int, ci155 int, ci156 int, ci157 int, ci158 int, ci159 int, ci160 int,
+ci161 int, ci162 int, ci163 int, ci164 int, ci165 int, ci166 int, ci167 int, ci168 int,
+ci169 int, ci170 int, ci171 int, ci172 int, ci173 int, ci174 int, ci175 int, ci176 int,
+ci177 int, ci178 int, ci179 int, ci180 int, ci181 int, ci182 int, ci183 int, ci184 int,
+ci185 int, ci186 int, ci187 int, ci188 int, ci189 int, ci190 int, ci191 int, ci192 int,
+ci193 int, ci194 int, ci195 int, ci196 int, ci197 int, ci198 int, ci199 int, ci200 int,
+ci201 int, ci202 int, ci203 int, ci204 int, ci205 int, ci206 int, ci207 int, ci208 int,
+ci209 int, ci210 int, ci211 int, ci212 int, ci213 int, ci214 int, ci215 int, ci216 int,
+ci217 int, ci218 int, ci219 int, ci220 int, ci221 int, ci222 int, ci223 int, ci224 int,
+ci225 int, ci226 int, ci227 int, ci228 int, ci229 int, ci230 int, ci231 int, ci232 int,
+ci233 int, ci234 int, ci235 int, ci236 int, ci237 int, ci238 int, ci239 int, ci240 int,
+ci241 int, ci242 int, ci243 int, ci244 int, ci245 int, ci246 int, ci247 int, ci248 int,
+ci249 int, ci250 int, ci251 int, ci252 int, ci253 int, ci254 int, ci255 int, ci256 int,
+ci257 int, ci258 int, ci259 int, ci260 int, ci261 int, ci262 int, ci263 int, ci264 int,
+ci265 int, ci266 int, ci267 int, ci268 int, ci269 int, ci270 int, ci271 int, ci272 int,
+ci273 int, ci274 int, ci275 int, ci276 int, ci277 int, ci278 int, ci279 int, ci280 int,
+ci281 int, ci282 int, ci283 int, ci284 int, ci285 int, ci286 int, ci287 int, ci288 int,
+ci289 int, ci290 int, ci291 int, ci292 int, ci293 int, ci294 int, ci295 int, ci296 int,
+ci297 int, ci298 int, ci299 int, ci300 int, ci301 int, ci302 int, ci303 int, ci304 int,
+ci305 int, ci306 int, ci307 int, ci308 int, ci309 int, ci310 int, ci311 int, ci312 int,
+ci313 int, ci314 int, ci315 int, ci316 int, ci317 int, ci318 int, ci319 int, ci320 int,
+ci321 int, ci322 int, ci323 int, ci324 int, ci325 int, ci326 int, ci327 int, ci328 int,
+ci329 int, ci330 int, ci331 int, ci332 int, ci333 int, ci334 int, ci335 int, ci336 int,
+ci337 int, ci338 int, ci339 int, ci340 int, ci341 int, ci342 int, ci343 int, ci344 int,
+ci345 int, ci346 int, ci347 int, ci348 int, ci349 int, ci350 int, ci351 int, ci352 int,
+ci353 int, ci354 int, ci355 int, ci356 int, ci357 int, ci358 int, ci359 int, ci360 int,
+ci361 int, ci362 int, ci363 int, ci364 int, ci365 int, ci366 int, ci367 int, ci368 int,
+ci369 int, ci370 int, ci371 int, ci372 int, ci373 int, ci374 int, ci375 int, ci376 int,
+ci377 int, ci378 int, ci379 int, ci380 int, ci381 int, ci382 int, ci383 int, ci384 int,
+ci385 int, ci386 int, ci387 int, ci388 int, ci389 int, ci390 int, ci391 int, ci392 int,
+ci393 int, ci394 int, ci395 int, ci396 int, ci397 int, ci398 int, ci399 int, ci400 int,
+ci401 int, ci402 int, ci403 int, ci404 int, ci405 int, ci406 int, ci407 int, ci408 int,
+ci409 int, ci410 int, ci411 int, ci412 int, ci413 int, ci414 int, ci415 int, ci416 int,
+ci417 int, ci418 int, ci419 int, ci420 int, ci421 int, ci422 int, ci423 int, ci424 int,
+ci425 int, ci426 int, ci427 int, ci428 int, ci429 int, ci430 int, ci431 int, ci432 int,
+ci433 int, ci434 int, ci435 int, ci436 int, ci437 int, ci438 int, ci439 int, ci440 int,
+ci441 int, ci442 int, ci443 int, ci444 int, ci445 int, ci446 int, ci447 int, ci448 int,
+ci449 int, ci450 int, ci451 int, ci452 int, ci453 int, ci454 int, ci455 int, ci456 int,
+ci457 int, ci458 int, ci459 int, ci460 int, ci461 int, ci462 int, ci463 int, ci464 int,
+ci465 int, ci466 int, ci467 int, ci468 int, ci469 int, ci470 int,
+cb471 blob, cb472 blob, cb473 blob, cb474 blob, cb475 blob, cb476 blob, cb477 blob, cb478 blob,
+cb479 blob, cb480 blob, cb481 blob, cb482 blob, cb483 blob, cb484 blob, cb485 blob, cb486 blob,
+cb487 blob, cb488 blob, cb489 blob, cb490 blob, cb491 blob, cb492 blob, cb493 blob, cb494 blob,
+cb495 blob, cb496 blob, cb497 blob, cb498 blob, cb499 blob, cb500 blob, cb501 blob, cb502 blob,
+cb503 blob, cb504 blob, cb505 blob, cb506 blob, cb507 blob, cb508 blob, cb509 blob, cb510 blob,
+cb511 blob, cb512 blob,
+primary key (ci001),
+unique i1 (ci002),
+unique i2 (ci003),
+unique i3 (ci004),
+unique i4 (ci005),
+unique i5 (ci006),
+unique i6 (ci007),
+unique i7 (ci008),
+unique i8 (ci009),
+unique i9 (ci010),
+unique i10 (ci011),
+unique i11 (ci012),
+unique i12 (ci013),
+unique i13 (ci014),
+unique i14 (ci015),
+unique i15 (ci016),
+unique i16 (ci017),
+unique i17 (ci018),
+unique i18 (ci019),
+unique i19 (ci020),
+unique i20 (ci021),
+unique i21 (ci022),
+unique i22 (ci023),
+unique i23 (ci024),
+unique i24 (ci025),
+unique i25 (ci026),
+unique i26 (ci027),
+unique i27 (ci028),
+unique i28 (ci029),
+unique i29 (ci030),
+unique i30 (ci031),
+unique i31 (ci032),
+unique i32 (ci033),
+unique i33 (ci034),
+unique i34 (ci035),
+unique i35 (ci036),
+unique i36 (ci037),
+unique i37 (ci038),
+unique i38 (ci039),
+unique i39 (ci040),
+unique i40 (ci041),
+unique i41 (ci042),
+unique i42 (ci043),
+unique i43 (ci044),
+unique i44 (ci045),
+unique i45 (ci046),
+unique i46 (ci047),
+unique i47 (ci048),
+unique i48 (ci049),
+unique i49 (ci050),
+unique i50 (ci051),
+unique i51 (ci052),
+unique i52 (ci053),
+unique i53 (ci054),
+unique i54 (ci055),
+unique i55 (ci056),
+unique i56 (ci057),
+unique i57 (ci058),
+unique i58 (ci059),
+unique i59 (ci060),
+unique i60 (ci061),
+unique i61 (ci062),
+unique i62 (ci063),
+unique i63 (ci064)
+) engine=ndb;
+drop table t1;
 End of 5.1 tests

=== modified file 'mysql-test/suite/ndb/r/ndbinfo.result'
--- a/mysql-test/suite/ndb/r/ndbinfo.result	2011-05-23 14:50:45 +0000
+++ b/mysql-test/suite/ndb/r/ndbinfo.result	2011-10-07 17:15:53 +0000
@@ -36,9 +36,12 @@ table_id	table_name	comment
 8	counters	monotonic counters
 9	nodes	node status
 10	diskpagebuffer	disk page buffer info
+11	threadblocks	which blocks are run in which threads
+12	threadstat	threadstat
+13	transactions	transactions
 SELECT COUNT(*) FROM ndb$tables;
 COUNT(*)
-11
+14
 SELECT * FROM ndb$tables WHERE table_id = 2;
 table_id	table_name	comment
 2	test	for testing
@@ -49,11 +52,14 @@ table_id	table_name	comment
 8	counters	monotonic counters
 9	nodes	node status
 10	diskpagebuffer	disk page buffer info
+11	threadblocks	which blocks are run in which threads
+12	threadstat	threadstat
+13	transactions	transactions
 SELECT * FROM ndb$tables WHERE table_name = 'LOGDESTINATION';
 table_id	table_name	comment
 SELECT COUNT(*) FROM ndb$tables t1, ndb$tables t2 WHERE t1.table_id = t1.table_id;
 COUNT(*)
-121
+196
 
 SELECT table_id, table_name, comment from ndb$tables
   WHERE table_id > 2 AND table_id <= 5 ORDER BY table_id;
@@ -76,6 +82,9 @@ table_id	table_name
 7	resources
 0	tables
 2	test
+11	threadblocks
+12	threadstat
+13	transactions
 4	transporters
 
 SELECT table_id, column_id, column_name FROM ndb$columns LIMIT 7;
@@ -123,6 +132,9 @@ table_id
 8
 9
 10
+11
+12
+13
 
 TRUNCATE ndb$tables;
 ERROR HY000: Table 'ndb$tables' is read only

=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table.test	2009-07-13 10:51:28 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table.test	2011-10-07 14:28:37 +0000
@@ -22,7 +22,7 @@ CREATE TABLE t1 (
 ) ENGINE=ndbcluster;
 
 INSERT INTO t1 VALUES (9410,9412);
-  
+
 ALTER TABLE t1 ADD COLUMN c int not null;
 SELECT * FROM t1;
 
@@ -144,7 +144,7 @@ drop table t1;
 #create table t1 ( a int primary key, b varchar(10), c varchar(10), index (b) )
 #engine=ndb;
 #insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three');
-#create index c on t1(c); 
+#create index c on t1(c);
 #connection server2;
 #select * from t1 where c = 'two';
 #connection server1;
@@ -194,7 +194,7 @@ drop table t1;
 ### This should work as transaction is ongoing...
 ##delete from t3;
 ##insert into t3 values (1);
-#commit; 
+#commit;
 
 ## This should fail as its a new transaction
 #--error 1146
@@ -318,7 +318,7 @@ c109 int(11) not null,
 primary key (ai),
 unique key tx1 (c002, c003, c004, c005)) engine=ndb;
 
-create index tx2 
+create index tx2
 on t1 (c010, c011, c012, c013);
 
 drop table t1;
@@ -384,4 +384,139 @@ alter table t1 order by b;
 select * from t1 order by b;
 drop table t1;
 
+# big table, 512 columns, 42 blob, 64x2 indices
+
+create table t1 (
+  ci001 int, ci002 int, ci003 int, ci004 int, ci005 int, ci006 int, ci007 int, ci008 int,
+  ci009 int, ci010 int, ci011 int, ci012 int, ci013 int, ci014 int, ci015 int, ci016 int,
+  ci017 int, ci018 int, ci019 int, ci020 int, ci021 int, ci022 int, ci023 int, ci024 int,
+  ci025 int, ci026 int, ci027 int, ci028 int, ci029 int, ci030 int, ci031 int, ci032 int,
+  ci033 int, ci034 int, ci035 int, ci036 int, ci037 int, ci038 int, ci039 int, ci040 int,
+  ci041 int, ci042 int, ci043 int, ci044 int, ci045 int, ci046 int, ci047 int, ci048 int,
+  ci049 int, ci050 int, ci051 int, ci052 int, ci053 int, ci054 int, ci055 int, ci056 int,
+  ci057 int, ci058 int, ci059 int, ci060 int, ci061 int, ci062 int, ci063 int, ci064 int,
+  ci065 int, ci066 int, ci067 int, ci068 int, ci069 int, ci070 int, ci071 int, ci072 int,
+  ci073 int, ci074 int, ci075 int, ci076 int, ci077 int, ci078 int, ci079 int, ci080 int,
+  ci081 int, ci082 int, ci083 int, ci084 int, ci085 int, ci086 int, ci087 int, ci088 int,
+  ci089 int, ci090 int, ci091 int, ci092 int, ci093 int, ci094 int, ci095 int, ci096 int,
+  ci097 int, ci098 int, ci099 int, ci100 int, ci101 int, ci102 int, ci103 int, ci104 int,
+  ci105 int, ci106 int, ci107 int, ci108 int, ci109 int, ci110 int, ci111 int, ci112 int,
+  ci113 int, ci114 int, ci115 int, ci116 int, ci117 int, ci118 int, ci119 int, ci120 int,
+  ci121 int, ci122 int, ci123 int, ci124 int, ci125 int, ci126 int, ci127 int, ci128 int,
+  ci129 int, ci130 int, ci131 int, ci132 int, ci133 int, ci134 int, ci135 int, ci136 int,
+  ci137 int, ci138 int, ci139 int, ci140 int, ci141 int, ci142 int, ci143 int, ci144 int,
+  ci145 int, ci146 int, ci147 int, ci148 int, ci149 int, ci150 int, ci151 int, ci152 int,
+  ci153 int, ci154 int, ci155 int, ci156 int, ci157 int, ci158 int, ci159 int, ci160 int,
+  ci161 int, ci162 int, ci163 int, ci164 int, ci165 int, ci166 int, ci167 int, ci168 int,
+  ci169 int, ci170 int, ci171 int, ci172 int, ci173 int, ci174 int, ci175 int, ci176 int,
+  ci177 int, ci178 int, ci179 int, ci180 int, ci181 int, ci182 int, ci183 int, ci184 int,
+  ci185 int, ci186 int, ci187 int, ci188 int, ci189 int, ci190 int, ci191 int, ci192 int,
+  ci193 int, ci194 int, ci195 int, ci196 int, ci197 int, ci198 int, ci199 int, ci200 int,
+  ci201 int, ci202 int, ci203 int, ci204 int, ci205 int, ci206 int, ci207 int, ci208 int,
+  ci209 int, ci210 int, ci211 int, ci212 int, ci213 int, ci214 int, ci215 int, ci216 int,
+  ci217 int, ci218 int, ci219 int, ci220 int, ci221 int, ci222 int, ci223 int, ci224 int,
+  ci225 int, ci226 int, ci227 int, ci228 int, ci229 int, ci230 int, ci231 int, ci232 int,
+  ci233 int, ci234 int, ci235 int, ci236 int, ci237 int, ci238 int, ci239 int, ci240 int,
+  ci241 int, ci242 int, ci243 int, ci244 int, ci245 int, ci246 int, ci247 int, ci248 int,
+  ci249 int, ci250 int, ci251 int, ci252 int, ci253 int, ci254 int, ci255 int, ci256 int,
+  ci257 int, ci258 int, ci259 int, ci260 int, ci261 int, ci262 int, ci263 int, ci264 int,
+  ci265 int, ci266 int, ci267 int, ci268 int, ci269 int, ci270 int, ci271 int, ci272 int,
+  ci273 int, ci274 int, ci275 int, ci276 int, ci277 int, ci278 int, ci279 int, ci280 int,
+  ci281 int, ci282 int, ci283 int, ci284 int, ci285 int, ci286 int, ci287 int, ci288 int,
+  ci289 int, ci290 int, ci291 int, ci292 int, ci293 int, ci294 int, ci295 int, ci296 int,
+  ci297 int, ci298 int, ci299 int, ci300 int, ci301 int, ci302 int, ci303 int, ci304 int,
+  ci305 int, ci306 int, ci307 int, ci308 int, ci309 int, ci310 int, ci311 int, ci312 int,
+  ci313 int, ci314 int, ci315 int, ci316 int, ci317 int, ci318 int, ci319 int, ci320 int,
+  ci321 int, ci322 int, ci323 int, ci324 int, ci325 int, ci326 int, ci327 int, ci328 int,
+  ci329 int, ci330 int, ci331 int, ci332 int, ci333 int, ci334 int, ci335 int, ci336 int,
+  ci337 int, ci338 int, ci339 int, ci340 int, ci341 int, ci342 int, ci343 int, ci344 int,
+  ci345 int, ci346 int, ci347 int, ci348 int, ci349 int, ci350 int, ci351 int, ci352 int,
+  ci353 int, ci354 int, ci355 int, ci356 int, ci357 int, ci358 int, ci359 int, ci360 int,
+  ci361 int, ci362 int, ci363 int, ci364 int, ci365 int, ci366 int, ci367 int, ci368 int,
+  ci369 int, ci370 int, ci371 int, ci372 int, ci373 int, ci374 int, ci375 int, ci376 int,
+  ci377 int, ci378 int, ci379 int, ci380 int, ci381 int, ci382 int, ci383 int, ci384 int,
+  ci385 int, ci386 int, ci387 int, ci388 int, ci389 int, ci390 int, ci391 int, ci392 int,
+  ci393 int, ci394 int, ci395 int, ci396 int, ci397 int, ci398 int, ci399 int, ci400 int,
+  ci401 int, ci402 int, ci403 int, ci404 int, ci405 int, ci406 int, ci407 int, ci408 int,
+  ci409 int, ci410 int, ci411 int, ci412 int, ci413 int, ci414 int, ci415 int, ci416 int,
+  ci417 int, ci418 int, ci419 int, ci420 int, ci421 int, ci422 int, ci423 int, ci424 int,
+  ci425 int, ci426 int, ci427 int, ci428 int, ci429 int, ci430 int, ci431 int, ci432 int,
+  ci433 int, ci434 int, ci435 int, ci436 int, ci437 int, ci438 int, ci439 int, ci440 int,
+  ci441 int, ci442 int, ci443 int, ci444 int, ci445 int, ci446 int, ci447 int, ci448 int,
+  ci449 int, ci450 int, ci451 int, ci452 int, ci453 int, ci454 int, ci455 int, ci456 int,
+  ci457 int, ci458 int, ci459 int, ci460 int, ci461 int, ci462 int, ci463 int, ci464 int,
+  ci465 int, ci466 int, ci467 int, ci468 int, ci469 int, ci470 int,
+  cb471 blob, cb472 blob, cb473 blob, cb474 blob, cb475 blob, cb476 blob, cb477 blob, cb478 blob,
+  cb479 blob, cb480 blob, cb481 blob, cb482 blob, cb483 blob, cb484 blob, cb485 blob, cb486 blob,
+  cb487 blob, cb488 blob, cb489 blob, cb490 blob, cb491 blob, cb492 blob, cb493 blob, cb494 blob,
+  cb495 blob, cb496 blob, cb497 blob, cb498 blob, cb499 blob, cb500 blob, cb501 blob, cb502 blob,
+  cb503 blob, cb504 blob, cb505 blob, cb506 blob, cb507 blob, cb508 blob, cb509 blob, cb510 blob,
+  cb511 blob, cb512 blob,
+  primary key (ci001),
+  unique i1 (ci002),
+  unique i2 (ci003),
+  unique i3 (ci004),
+  unique i4 (ci005),
+  unique i5 (ci006),
+  unique i6 (ci007),
+  unique i7 (ci008),
+  unique i8 (ci009),
+  unique i9 (ci010),
+  unique i10 (ci011),
+  unique i11 (ci012),
+  unique i12 (ci013),
+  unique i13 (ci014),
+  unique i14 (ci015),
+  unique i15 (ci016),
+  unique i16 (ci017),
+  unique i17 (ci018),
+  unique i18 (ci019),
+  unique i19 (ci020),
+  unique i20 (ci021),
+  unique i21 (ci022),
+  unique i22 (ci023),
+  unique i23 (ci024),
+  unique i24 (ci025),
+  unique i25 (ci026),
+  unique i26 (ci027),
+  unique i27 (ci028),
+  unique i28 (ci029),
+  unique i29 (ci030),
+  unique i30 (ci031),
+  unique i31 (ci032),
+  unique i32 (ci033),
+  unique i33 (ci034),
+  unique i34 (ci035),
+  unique i35 (ci036),
+  unique i36 (ci037),
+  unique i37 (ci038),
+  unique i38 (ci039),
+  unique i39 (ci040),
+  unique i40 (ci041),
+  unique i41 (ci042),
+  unique i42 (ci043),
+  unique i43 (ci044),
+  unique i44 (ci045),
+  unique i45 (ci046),
+  unique i46 (ci047),
+  unique i47 (ci048),
+  unique i48 (ci049),
+  unique i49 (ci050),
+  unique i50 (ci051),
+  unique i51 (ci052),
+  unique i52 (ci053),
+  unique i53 (ci054),
+  unique i54 (ci055),
+  unique i55 (ci056),
+  unique i56 (ci057),
+  unique i57 (ci058),
+  unique i58 (ci059),
+  unique i59 (ci060),
+  unique i60 (ci061),
+  unique i61 (ci062),
+  unique i62 (ci063),
+  unique i63 (ci064)
+) engine=ndb;
+drop table t1;
+
 --echo End of 5.1 tests

=== modified file 'storage/ndb/include/kernel/BlockNumbers.h'
--- a/storage/ndb/include/kernel/BlockNumbers.h	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/include/kernel/BlockNumbers.h	2011-10-07 08:07:21 +0000
@@ -60,6 +60,7 @@
 #define RESTORE    0x106
 #define DBINFO     0x107
 #define DBSPJ      0x108
+#define THRMAN     0x109
 
 const BlockReference BACKUP_REF  = numberToRef(BACKUP, 0);
 const BlockReference DBTC_REF    = numberToRef(DBTC, 0);
@@ -82,6 +83,7 @@ const BlockReference PGMAN_REF   = numbe
 const BlockReference RESTORE_REF = numberToRef(RESTORE, 0);
 const BlockReference DBINFO_REF  = numberToRef(DBINFO, 0);
 const BlockReference DBSPJ_REF  = numberToRef(DBSPJ, 0);
+const BlockReference THRMAN_REF  = numberToRef(THRMAN, 0);
 
 static inline void __hide_warnings_unused_ref_vars(void) {
   // Hide annoying warnings about unused variables
@@ -92,10 +94,11 @@ static inline void __hide_warnings_unuse
   (void)DBUTIL_REF;  (void)SUMA_REF;    (void)DBTUX_REF;
   (void)TSMAN_REF;   (void)LGMAN_REF;   (void)PGMAN_REF;
   (void)RESTORE_REF; (void)DBINFO_REF;  (void)DBSPJ_REF;
+  (void)THRMAN_REF;
 }
 
 const BlockNumber MIN_BLOCK_NO = BACKUP;
-const BlockNumber MAX_BLOCK_NO = DBSPJ;
+const BlockNumber MAX_BLOCK_NO = THRMAN;
 const BlockNumber NO_OF_BLOCKS = (MAX_BLOCK_NO - MIN_BLOCK_NO + 1);
 
 /**

=== modified file 'storage/ndb/include/kernel/ndb_limits.h'
--- a/storage/ndb/include/kernel/ndb_limits.h	2011-07-04 16:30:34 +0000
+++ b/storage/ndb/include/kernel/ndb_limits.h	2011-10-07 17:15:53 +0000
@@ -172,7 +172,6 @@
 /*
  * Schema transactions
  */
-#define MAX_SCHEMA_TRANSACTIONS 5
 #define MAX_SCHEMA_OPERATIONS 256
 
 /*

=== modified file 'storage/ndb/include/kernel/signaldata/SchemaTrans.hpp'
--- a/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/include/kernel/signaldata/SchemaTrans.hpp	2011-10-07 13:15:08 +0000
@@ -44,7 +44,8 @@ struct SchemaTransBeginRef {
     BusyWithNR = 711,
     TooManySchemaTrans = 780,
     IncompatibleVersions = 763,
-    Nodefailure = 786
+    Nodefailure = 786,
+    OutOfSchemaTransMemory = 796
   };
   Uint32 senderRef;
   Uint32 transId;

=== modified file 'storage/ndb/include/mgmapi/mgmapi_config_parameters.h'
--- a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2011-09-01 13:09:24 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2011-10-07 17:15:53 +0000
@@ -197,6 +197,8 @@
 #define CFG_DB_MAX_DML_OPERATIONS_PER_TRANSACTION 627
 #define CFG_DB_MT_THREAD_CONFIG          628
 
+#define CFG_DB_CRASH_ON_CORRUPTED_TUPLE  629
+
 #define CFG_NODE_ARBIT_RANK           200
 #define CFG_NODE_ARBIT_DELAY          201
 #define CFG_RESERVED_SEND_BUFFER_MEMORY 202

=== added file 'storage/ndb/include/portlib/NdbGetRUsage.h'
--- a/storage/ndb/include/portlib/NdbGetRUsage.h	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/include/portlib/NdbGetRUsage.h	2011-10-07 08:07:21 +0000
@@ -0,0 +1,46 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#ifndef NDB_GET_RUSAGE_H
+#define NDB_GET_RUSAGE_H
+
+#include <ndb_global.h>
+
+struct ndb_rusage
+{
+  Uint64 ru_utime;
+  Uint64 ru_stime;
+  Uint64 ru_minflt;
+  Uint64 ru_majflt;
+  Uint64 ru_nvcsw;
+  Uint64 ru_nivcsw;
+};
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+  /**
+   * Get resource usage for calling thread
+   */
+  int Ndb_GetRUSage(ndb_rusage * dst);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif

=== modified file 'storage/ndb/src/common/debugger/BlockNames.cpp'
--- a/storage/ndb/src/common/debugger/BlockNames.cpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/common/debugger/BlockNames.cpp	2011-10-07 08:07:21 +0000
@@ -40,6 +40,7 @@ const BlockName BlockNames[] = {
   ,{ "RESTORE", RESTORE }
   ,{ "DBINFO", DBINFO }
   ,{ "DBSPJ", DBSPJ }
+  ,{ "THRMAN", THRMAN }
 };
 
 const BlockNumber NO_OF_BLOCK_NAMES = sizeof(BlockNames) / sizeof(BlockName);

=== modified file 'storage/ndb/src/common/portlib/CMakeLists.txt'
--- a/storage/ndb/src/common/portlib/CMakeLists.txt	2011-09-28 10:18:35 +0000
+++ b/storage/ndb/src/common/portlib/CMakeLists.txt	2011-10-07 17:15:53 +0000
@@ -27,7 +27,8 @@ ADD_CONVENIENCE_LIBRARY(ndbportlib
             NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp
             NdbMem.c NdbConfig.c NdbTick.c NdbDir.cpp
             ndb_daemon.cc ${EXTRA_SRC}
-            NdbNuma.cpp NdbMutex_DeadlockDetector.cpp)
+            NdbNuma.cpp NdbMutex_DeadlockDetector.cpp
+            NdbGetRUsage.cpp)
 TARGET_LINK_LIBRARIES(ndbportlib mysys ${LIBSOCKET})
 
 ADD_EXECUTABLE(NdbDir-t

=== modified file 'storage/ndb/src/common/portlib/Makefile.am'
--- a/storage/ndb/src/common/portlib/Makefile.am	2011-09-27 17:28:13 +0000
+++ b/storage/ndb/src/common/portlib/Makefile.am	2011-10-07 08:07:21 +0000
@@ -22,7 +22,8 @@ libportlib_la_SOURCES = \
 	NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp	    \
 	ndb_daemon.cc NdbMem.c \
 	NdbConfig.c NdbDir.cpp ndb_socket.cpp \
-        NdbMutex_DeadlockDetector.cpp
+        NdbMutex_DeadlockDetector.cpp \
+        NdbGetRUsage.cpp
 
 include $(top_srcdir)/storage/ndb/config/common.mk.am
 include $(top_srcdir)/storage/ndb/config/type_util.mk.am

=== added file 'storage/ndb/src/common/portlib/NdbGetRUsage.cpp'
--- a/storage/ndb/src/common/portlib/NdbGetRUsage.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/common/portlib/NdbGetRUsage.cpp	2011-10-07 08:07:21 +0000
@@ -0,0 +1,65 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <NdbGetRUsage.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifndef _WIN32
+static
+Uint64
+micros(struct timeval val)
+{
+  return
+    (Uint64)val.tv_sec * (Uint64)1000000 + val.tv_usec;
+}
+#endif
+
+extern "C"
+int
+Ndb_GetRUSage(ndb_rusage* dst)
+{
+  int res = -1;
+#ifdef HAVE_GETRUSAGE
+  struct rusage tmp;
+#ifdef RUSAGE_THREAD
+  res = getrusage(RUSAGE_THREAD, &tmp);
+#elif defined RUSAGE_LWP
+  res = getrusage(RUSAGE_LWP, &tmp);
+#endif
+
+  if (res == 0)
+  {
+    dst->ru_utime = micros(tmp.ru_utime);
+    dst->ru_stime = micros(tmp.ru_stime);
+    dst->ru_minflt = tmp.ru_minflt;
+    dst->ru_majflt = tmp.ru_majflt;
+    dst->ru_nvcsw = tmp.ru_nvcsw;
+    dst->ru_nivcsw = tmp.ru_nivcsw;
+  }
+#endif
+
+  if (res != 0)
+  {
+    bzero(dst, sizeof(* dst));
+  }
+  return res;
+}

=== modified file 'storage/ndb/src/common/portlib/NdbThread.c'
--- a/storage/ndb/src/common/portlib/NdbThread.c	2011-09-27 17:28:13 +0000
+++ b/storage/ndb/src/common/portlib/NdbThread.c	2011-10-07 07:37:47 +0000
@@ -176,6 +176,7 @@ NdbThread_CreateObject(const char * name
 
   if (g_main_thread != 0)
   {
+    settid(g_main_thread);
     if (name)
     {
       strnmov(g_main_thread->thread_name, name, sizeof(tmpThread->thread_name));

=== modified file 'storage/ndb/src/kernel/SimBlockList.cpp'
--- a/storage/ndb/src/kernel/SimBlockList.cpp	2011-09-23 09:13:22 +0000
+++ b/storage/ndb/src/kernel/SimBlockList.cpp	2011-10-07 08:07:21 +0000
@@ -51,6 +51,7 @@
 #include <PgmanProxy.hpp>
 #include <DbtcProxy.hpp>
 #include <DbspjProxy.hpp>
+#include <thrman.hpp>
 #include <mt.hpp>
 
 #ifndef VM_TRACE
@@ -89,6 +90,10 @@ void * operator new (size_t sz, SIMBLOCK
 void
 SimBlockList::load(EmulatorData& data){
   noOfBlocks = NO_OF_BLOCKS;
+#define THR 1
+#ifndef THR
+  noOfBlocks--;
+#endif
   theList = new SimulatedBlock * [noOfBlocks];
   if (!theList)
   {
@@ -160,7 +165,14 @@ SimBlockList::load(EmulatorData& data){
     theList[20]  = NEW_BLOCK(Dbspj)(ctx);
   else
     theList[20]  = NEW_BLOCK(DbspjProxy)(ctx);
-  assert(NO_OF_BLOCKS == 21);
+#ifdef THR
+  if (NdbIsMultiThreaded() == false)
+    theList[21] = NEW_BLOCK(Thrman)(ctx);
+  else
+    theList[21] = NEW_BLOCK(ThrmanProxy)(ctx);
+
+  assert(NO_OF_BLOCKS == 22);
+#endif
 
   // Check that all blocks could be created
   for (int i = 0; i < noOfBlocks; i++)
@@ -174,10 +186,10 @@ SimBlockList::load(EmulatorData& data){
 
   if (globalData.isNdbMt)
   {
-    add_main_thr_map();
+    mt_init_thr_map();
     for (int i = 0; i < noOfBlocks; i++)
       theList[i]->loadWorkers();
-    finalize_thr_map();
+    mt_finalize_thr_map();
   }
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/CMakeLists.txt'
--- a/storage/ndb/src/kernel/blocks/CMakeLists.txt	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/kernel/blocks/CMakeLists.txt	2011-10-07 17:15:53 +0000
@@ -72,7 +72,8 @@ ADD_LIBRARY(ndbblocks STATIC
     dblqh/DblqhCommon.cpp
     PgmanProxy.cpp
     dbtup/DbtupClient.cpp
-    ${EXTRA_SRC})
+    ${EXTRA_SRC}
+    thrman.cpp)
 
 MYSQL_ADD_EXECUTABLE(ndb_print_file
   print_file.cpp

=== modified file 'storage/ndb/src/kernel/blocks/LocalProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/LocalProxy.cpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/blocks/LocalProxy.cpp	2011-10-07 08:07:21 +0000
@@ -22,8 +22,6 @@ LocalProxy::LocalProxy(BlockNumber block
   BLOCK_CONSTRUCTOR(LocalProxy);
 
   ndbrequire(instance() == 0); // this is main block
-  c_lqhWorkers = 0;
-  c_extraWorkers = 0; // sub-class constructor can set
   c_workers = 0;
   Uint32 i;
   for (i = 0; i < MaxWorkers; i++)
@@ -187,13 +185,13 @@ LocalProxy::lastReply(const SsSequential
 }
 
 void
-LocalProxy::sendREQ(Signal* signal, SsParallel& ss)
+LocalProxy::sendREQ(Signal* signal, SsParallel& ss, bool skipLast)
 {
   ndbrequire(ss.m_sendREQ != 0);
 
   ss.m_workerMask.clear();
   ss.m_worker = 0;
-  const Uint32 count = ss.m_extraLast ? c_lqhWorkers : c_workers;
+  const Uint32 count = skipLast ? c_workers - 1 : c_workers;
   SectionHandle handle(this);
   restoreHandle(handle, ss);
   while (ss.m_worker < count) {
@@ -266,21 +264,6 @@ LocalProxy::lastReply(const SsParallel&
   return ss.m_workerMask.isclear();
 }
 
-bool
-LocalProxy::lastExtra(Signal* signal, SsParallel& ss)
-{
-  SectionHandle handle(this);
-  if (c_lqhWorkers + ss.m_extraSent < c_workers) {
-    jam();
-    ss.m_worker = c_lqhWorkers + ss.m_extraSent;
-    ss.m_workerMask.set(ss.m_worker);
-    (this->*ss.m_sendREQ)(signal, ss.m_ssId, &handle);
-    ss.m_extraSent++;
-    return false;
-  }
-  return true;
-}
-
 // used in "reverse" proxying (start with worker REQs)
 void
 LocalProxy::setMask(SsParallel& ss)
@@ -301,11 +284,9 @@ LocalProxy::setMask(SsParallel& ss, cons
 void
 LocalProxy::loadWorkers()
 {
-  c_lqhWorkers = getLqhWorkers();
-  c_workers = c_lqhWorkers + c_extraWorkers;
-
-  Uint32 i;
-  for (i = 0; i < c_workers; i++) {
+  c_workers = mt_get_instance_count(number());
+  for (Uint32 i = 0; i < c_workers; i++)
+  {
     jam();
     Uint32 instanceNo = workerInstance(i);
 
@@ -314,31 +295,7 @@ LocalProxy::loadWorkers()
     ndbrequire(this->getInstance(instanceNo) == worker);
     c_worker[i] = worker;
 
-    if (i < c_lqhWorkers) {
-      add_lqh_worker_thr_map(number(), instanceNo);
-    } else {
-      add_extra_worker_thr_map(number(), instanceNo);
-    }
-  }
-}
-
-void
-LocalProxy::tc_loadWorkers()
-{
-  c_workers = globalData.ndbMtTcThreads;
-  c_lqhWorkers = globalData.ndbMtTcThreads;
-  c_extraWorkers = 0;
-
-  Uint32 i;
-  for (i = 0; i < c_workers; i++) {
-    jam();
-    Uint32 instanceNo = workerInstance(i);
-
-    SimulatedBlock* worker = newWorker(instanceNo);
-    ndbrequire(worker->instance() == instanceNo);
-    ndbrequire(this->getInstance(instanceNo) == worker);
-    c_worker[i] = worker;
-    add_tc_worker_thr_map(number(), instanceNo);
+    mt_add_thr_map(number(), instanceNo);
   }
 }
 

=== modified file 'storage/ndb/src/kernel/blocks/LocalProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/LocalProxy.hpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/blocks/LocalProxy.hpp	2011-10-07 08:07:21 +0000
@@ -56,19 +56,14 @@ public:
   BLOCK_DEFINES(LocalProxy);
 
 protected:
-  enum { MaxLqhWorkers = MAX_NDBMT_LQH_WORKERS };
-  enum { MaxExtraWorkers = 1 };
-  enum { MaxWorkers = MaxLqhWorkers + MaxExtraWorkers };
+  enum { MaxWorkers = SimulatedBlock::MaxInstances };
   typedef Bitmask<(MaxWorkers+31)/32> WorkerMask;
-  Uint32 c_lqhWorkers;
-  Uint32 c_extraWorkers;
   Uint32 c_workers;
   // no gaps - extra worker has index c_lqhWorkers (not MaxLqhWorkers)
   SimulatedBlock* c_worker[MaxWorkers];
 
   virtual SimulatedBlock* newWorker(Uint32 instanceNo) = 0;
   virtual void loadWorkers();
-  virtual void tc_loadWorkers();
 
   // get worker block by index (not by instance)
 
@@ -78,43 +73,22 @@ protected:
     return c_worker[i];
   }
 
-  SimulatedBlock* extraWorkerBlock() {
-    return workerBlock(c_lqhWorkers);
-  }
-
   // get worker block reference by index (not by instance)
 
   BlockReference workerRef(Uint32 i) {
     return numberToRef(number(), workerInstance(i), getOwnNodeId());
   }
 
-  BlockReference extraWorkerRef() {
-    ndbrequire(c_workers == c_lqhWorkers + 1);
-    Uint32 i = c_lqhWorkers;
-    return workerRef(i);
-  }
-
   // convert between worker index and worker instance
 
   Uint32 workerInstance(Uint32 i) const {
     ndbrequire(i < c_workers);
-    Uint32 ino;
-    if (i < c_lqhWorkers)
-      ino = 1 + i;
-    else
-      ino = 1 + MaxLqhWorkers;
-    return ino;
+    return i + 1;
   }
 
   Uint32 workerIndex(Uint32 ino) const {
     ndbrequire(ino != 0);
-    Uint32 i;
-    if (ino != 1 + MaxLqhWorkers)
-      i = ino - 1;
-    else
-      i = c_lqhWorkers;
-    ndbrequire(i < c_workers);
-    return i;
+    return ino - 1;
   }
 
   // support routines and classes ("Ss" = signal state)
@@ -161,14 +135,10 @@ protected:
   // run workers in parallel
   struct SsParallel : SsCommon {
     WorkerMask m_workerMask;
-    bool m_extraLast;   // run extra after LQH workers
-    Uint32 m_extraSent;
     SsParallel() {
-      m_extraLast = false;
-      m_extraSent = 0;
     }
   };
-  void sendREQ(Signal*, SsParallel& ss);
+  void sendREQ(Signal*, SsParallel& ss, bool skipLast = false);
   void recvCONF(Signal*, SsParallel& ss);
   void recvREF(Signal*, SsParallel& ss, Uint32 error);
   // for use in sendREQ

=== modified file 'storage/ndb/src/kernel/blocks/Makefile.am'
--- a/storage/ndb/src/kernel/blocks/Makefile.am	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/Makefile.am	2011-10-07 08:07:21 +0000
@@ -68,7 +68,8 @@ libblocks_a_SOURCES = tsman.cpp lgman.cp
   dblqh/DblqhCommon.cpp \
   PgmanProxy.cpp \
   dbtup/DbtupClient.cpp \
-  dbtc/DbtcProxy.cpp
+  dbtc/DbtcProxy.cpp \
+  thrman.cpp
 
 ndbtools_PROGRAMS = ndb_print_file
 ndb_print_file_SOURCES = print_file.cpp diskpage.cpp dbtup/tuppage.cpp

=== modified file 'storage/ndb/src/kernel/blocks/PgmanProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/PgmanProxy.cpp	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/kernel/blocks/PgmanProxy.cpp	2011-10-07 08:07:21 +0000
@@ -20,8 +20,6 @@
 PgmanProxy::PgmanProxy(Block_context& ctx) :
   LocalProxy(PGMAN, ctx)
 {
-  c_extraWorkers = 1;
-
   // GSN_LCP_FRAG_ORD
   addRecSignal(GSN_LCP_FRAG_ORD, &PgmanProxy::execLCP_FRAG_ORD);
 
@@ -88,11 +86,15 @@ PgmanProxy::execEND_LCP_REQ(Signal* sign
     req->senderRef = reference();
     req->requestType = ReleasePagesReq::RT_RELEASE_UNLOCKED;
     req->requestData = 0;
-    sendSignal(extraWorkerRef(), GSN_RELEASE_PAGES_REQ,
+    // Extra worker
+    sendSignal(workerRef(c_workers - 1), GSN_RELEASE_PAGES_REQ,
                signal, ReleasePagesReq::SignalLength, JBB);
     return;
   }
-  sendREQ(signal, ss);
+  /**
+   * Send to extra PGMAN *after* all other PGMAN has completed
+   */
+  sendREQ(signal, ss, /* skip last */ true);
 }
 
 void
@@ -137,8 +139,14 @@ PgmanProxy::sendEND_LCP_CONF(Signal* sig
     return;
   }
 
-  if (!lastExtra(signal, ss)) {
+  if (!ss.m_extraLast)
+  {
     jam();
+    ss.m_extraLast = true;
+    ss.m_worker = c_workers - 1; // send to last PGMAN
+    ss.m_workerMask.set(ss.m_worker);
+    SectionHandle handle(this);
+    (this->*ss.m_sendREQ)(signal, ss.m_ssId, &handle);
     return;
   }
 
@@ -170,7 +178,7 @@ PgmanProxy::get_page(Page_cache_client&
 {
   ndbrequire(blockToInstance(caller.m_block) == 0);
   SimulatedBlock* block = globalData.getBlock(caller.m_block);
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   Page_cache_client pgman(block, worker);
   int ret = pgman.get_page(signal, req, flags);
   caller.m_ptr = pgman.m_ptr;
@@ -183,7 +191,7 @@ PgmanProxy::update_lsn(Page_cache_client
 {
   ndbrequire(blockToInstance(caller.m_block) == 0);
   SimulatedBlock* block = globalData.getBlock(caller.m_block);
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   Page_cache_client pgman(block, worker);
   pgman.update_lsn(key, lsn);
 }
@@ -194,7 +202,7 @@ PgmanProxy::drop_page(Page_cache_client&
 {
   ndbrequire(blockToInstance(caller.m_block) == 0);
   SimulatedBlock* block = globalData.getBlock(caller.m_block);
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   Page_cache_client pgman(block, worker);
   int ret = pgman.drop_page(key, page_id);
   return ret;
@@ -209,10 +217,10 @@ PgmanProxy::drop_page(Page_cache_client&
 Uint32
 PgmanProxy::create_data_file(Signal* signal)
 {
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   Uint32 ret = worker->create_data_file();
   Uint32 i;
-  for (i = 0; i < c_lqhWorkers; i++) {
+  for (i = 0; i < c_workers - 1; i++) {
     jam();
     send_data_file_ord(signal, i, ret,
                        DataFileOrd::CreateDataFile);
@@ -223,10 +231,10 @@ PgmanProxy::create_data_file(Signal* sig
 Uint32
 PgmanProxy::alloc_data_file(Signal* signal, Uint32 file_no)
 {
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   Uint32 ret = worker->alloc_data_file(file_no);
   Uint32 i;
-  for (i = 0; i < c_lqhWorkers; i++) {
+  for (i = 0; i < c_workers - 1; i++) {
     jam();
     send_data_file_ord(signal, i, ret,
                        DataFileOrd::AllocDataFile, file_no);
@@ -237,10 +245,10 @@ PgmanProxy::alloc_data_file(Signal* sign
 void
 PgmanProxy::map_file_no(Signal* signal, Uint32 file_no, Uint32 fd)
 {
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   worker->map_file_no(file_no, fd);
   Uint32 i;
-  for (i = 0; i < c_lqhWorkers; i++) {
+  for (i = 0; i < c_workers - 1; i++) {
     jam();
     send_data_file_ord(signal, i, ~(Uint32)0,
                        DataFileOrd::MapFileNo, file_no, fd);
@@ -250,10 +258,10 @@ PgmanProxy::map_file_no(Signal* signal,
 void
 PgmanProxy::free_data_file(Signal* signal, Uint32 file_no, Uint32 fd)
 {
-  Pgman* worker = (Pgman*)extraWorkerBlock();
+  Pgman* worker = (Pgman*)workerBlock(c_workers - 1); // extraWorkerBlock();
   worker->free_data_file(file_no, fd);
   Uint32 i;
-  for (i = 0; i < c_lqhWorkers; i++) {
+  for (i = 0; i < c_workers - 1; i++) {
     jam();
     send_data_file_ord(signal, i, ~(Uint32)0,
                        DataFileOrd::FreeDataFile, file_no, fd);

=== modified file 'storage/ndb/src/kernel/blocks/PgmanProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/PgmanProxy.hpp	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/src/kernel/blocks/PgmanProxy.hpp	2011-10-07 08:07:21 +0000
@@ -62,11 +62,12 @@ protected:
      */
     static const char* name() { return "END_LCP_REQ"; }
     EndLcpReq m_req;
+    bool m_extraLast;
     Ss_END_LCP_REQ() {
       m_sendREQ = (SsFUNCREQ)&PgmanProxy::sendEND_LCP_REQ;
       m_sendCONF = (SsFUNCREP)&PgmanProxy::sendEND_LCP_CONF;
       // extra worker (for extent pages) must run after others
-      m_extraLast = true;
+      m_extraLast = false;
     }
     enum { poolSize = 1 };
     static SsPool<Ss_END_LCP_REQ>& pool(LocalProxy* proxy) {

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2011-10-03 07:08:19 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2011-10-07 17:15:53 +0000
@@ -322,132 +322,18 @@ void Dbdict::execDBINFO_SCANREQ(Signal *
           CFG_DB_NO_ORDERED_INDEXES,
           CFG_DB_NO_UNIQUE_HASH_INDEXES,
           CFG_DB_NO_TRIGGERS }},
-      { "Schema Operation",
-        c_schemaOpPool.getUsed(),
-        c_schemaOpPool.getSize(),
-        c_schemaOpPool.getEntrySize(),
-        c_schemaOpPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Schema Transaction",
-        c_schemaTransPool.getUsed(),
-        c_schemaTransPool.getSize(),
-        c_schemaTransPool.getEntrySize(),
-        c_schemaTransPool.getUsedHi(),
-        { 0,0,0,0 }},
       { "Transaction Handle",
         c_txHandlePool.getUsed(),
         c_txHandlePool.getSize(),
         c_txHandlePool.getEntrySize(),
         c_txHandlePool.getUsedHi(),
         { 0,0,0,0 }},
-      { "Create Table Record",
-        c_createTableRecPool.getUsed(),
-        c_createTableRecPool.getSize(),
-        c_createTableRecPool.getEntrySize(),
-        c_createTableRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Drop Table Record",
-        c_dropTableRecPool.getUsed(),
-        c_dropTableRecPool.getSize(),
-        c_dropTableRecPool.getEntrySize(),
-        c_dropTableRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Alter Table Record",
-        c_alterTableRecPool.getUsed(),
-        c_alterTableRecPool.getSize(),
-        c_alterTableRecPool.getEntrySize(),
-        c_alterTableRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Create Index Record",
-        c_createIndexRecPool.getUsed(),
-        c_createIndexRecPool.getSize(),
-        c_createIndexRecPool.getEntrySize(),
-        c_createIndexRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Drop Index Record",
-        c_dropIndexRecPool.getUsed(),
-        c_dropIndexRecPool.getSize(),
-        c_dropIndexRecPool.getEntrySize(),
-        c_dropIndexRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Alter Index Record",
-        c_alterIndexRecPool.getUsed(),
-        c_alterIndexRecPool.getSize(),
-        c_alterIndexRecPool.getEntrySize(),
-        c_alterIndexRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Build Index Record",
-        c_buildIndexRecPool.getUsed(),
-        c_buildIndexRecPool.getSize(),
-        c_buildIndexRecPool.getEntrySize(),
-        c_buildIndexRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Index Stat Record",
-        c_indexStatRecPool.getUsed(),
-        c_indexStatRecPool.getSize(),
-        c_indexStatRecPool.getEntrySize(),
-        c_indexStatRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Create Hash Map Record",
-        c_createHashMapRecPool.getUsed(),
-        c_createHashMapRecPool.getSize(),
-        c_createHashMapRecPool.getEntrySize(),
-        c_createHashMapRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Copy Data Record",
-        c_copyDataRecPool.getUsed(),
-        c_copyDataRecPool.getSize(),
-        c_copyDataRecPool.getEntrySize(),
-        c_copyDataRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Create Trigger Record",
-        c_createTriggerRecPool.getUsed(),
-        c_createTriggerRecPool.getSize(),
-        c_createTriggerRecPool.getEntrySize(),
-        c_createTriggerRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Drop Trigger Record",
-        c_dropTriggerRecPool.getUsed(),
-        c_dropTriggerRecPool.getSize(),
-        c_dropTriggerRecPool.getEntrySize(),
-        c_dropTriggerRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Create Filegroup Record",
-        c_createFilegroupRecPool.getUsed(),
-        c_createFilegroupRecPool.getSize(),
-        c_createFilegroupRecPool.getEntrySize(),
-        c_createFilegroupRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Create File Record",
-        c_createFileRecPool.getUsed(),
-        c_createFileRecPool.getSize(),
-        c_createFileRecPool.getEntrySize(),
-        c_createFileRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Drop Filegroup Record",
-        c_dropFilegroupRecPool.getUsed(),
-        c_dropFilegroupRecPool.getSize(),
-        c_dropFilegroupRecPool.getEntrySize(),
-        c_dropFilegroupRecPool.getUsedHi(),
-        { 0,0,0,0 }},
-      { "Drop File Record",
-        c_dropFileRecPool.getUsed(),
-        c_dropFileRecPool.getSize(),
-        c_dropFileRecPool.getEntrySize(),
-        c_dropFileRecPool.getUsedHi(),
-        { 0,0,0,0 }},
       { "Operation Record",
         c_opRecordPool.getUsed(),
         c_opRecordPool.getSize(),
         c_opRecordPool.getEntrySize(),
         c_opRecordPool.getUsedHi(),
         { 0,0,0,0 }},
-      { "Operation Data",
-        c_opSectionBufferPool.getUsed(),
-        c_opSectionBufferPool.getSize(),
-        c_opSectionBufferPool.getEntrySize(),
-        c_opSectionBufferPool.getUsedHi(),
-        { 0,0,0,0 }},
       { NULL, 0,0,0,0,{0,0,0,0}}
     };
 
@@ -1036,7 +922,8 @@ Dbdict::execCREATE_FRAGMENTATION_REQ(Sig
   Uint32 *theData = &signal->theData[0];
   const OpSection& fragSection =
     getOpSection(op_ptr, CreateTabReq::FRAGMENTATION);
-  copyOut(fragSection, &theData[25], ZNIL);
+  LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena,c_opSectionBufferPool);
+  copyOut(op_sec_pool, fragSection, &theData[25], ZNIL);
   theData[0] = 0;
 }
 
@@ -1285,7 +1172,7 @@ Dbdict::writeTableFile(Signal* signal, U
 
 // SchemaTrans variant
 void
-Dbdict::writeTableFile(Signal* signal, Uint32 tableId,
+Dbdict::writeTableFile(Signal* signal, SchemaOpPtr op_ptr, Uint32 tableId,
                        OpSection tabInfoSec, Callback* callback)
 {
   ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
@@ -1306,7 +1193,8 @@ Dbdict::writeTableFile(Signal* signal, U
     Uint32* dst = &pageRecPtr.p->word[ZPAGE_HEADER_SIZE];
     Uint32 dstSize = (ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS)
       - ZPAGE_HEADER_SIZE;
-    bool ok = copyOut(tabInfoSec, dst, dstSize);
+    LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+    bool ok = copyOut(op_sec_pool, tabInfoSec, dst, dstSize);
     ndbrequire(ok);
 
     memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
@@ -2761,6 +2649,11 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
   ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_AUTO_UPDATE,
                             &c_indexStatAutoUpdate);
 
+  Pool_context pc;
+  pc.m_block = this;
+
+  c_arenaAllocator.init(796, RT_DBDICT_SCHEMA_TRANS_ARENA, pc); // TODO: set size automagical? INFO: 796 is about 1/41 of a page, and bigger than CreateIndexRec (784 bytes)
+
   c_attributeRecordPool.setSize(attributesize);
   c_attributeRecordHash.setSize(64);
   c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE);
@@ -2771,9 +2664,12 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
   g_key_descriptor_pool.setSize(tablerecSize);
   c_triggerRecordPool.setSize(c_maxNoOfTriggers);
 
-  c_opSectionBufferPool.setSize(1024); // units OpSectionSegmentSize
+  Record_info ri;
+  OpSectionBuffer::createRecordInfo(ri, RT_DBDICT_OP_SECTION_BUFFER);
+  c_opSectionBufferPool.init(&c_arenaAllocator, ri, pc);
+
   c_schemaOpHash.setSize(MAX_SCHEMA_OPERATIONS);
-  c_schemaTransPool.setSize(MAX_SCHEMA_TRANSACTIONS);
+  c_schemaTransPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_SCHEMA_TRANSACTION, pc);
   c_schemaTransHash.setSize(2);
   c_txHandlePool.setSize(2);
   c_txHandleHash.setSize(2);
@@ -2782,9 +2678,6 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
   c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
   m_dict_lock_pool.setSize(MAX_NDB_NODES);
 
-  Pool_context pc;
-  pc.m_block = this;
-
   c_file_hash.setSize(16);
   c_filegroup_hash.setSize(16);
 
@@ -2798,31 +2691,31 @@ void Dbdict::execREAD_CONFIG_REQ(Signal*
   /**
    * TODO: Use arena-allocator for schema-transactions
    */
-  c_createTableRecPool.setSize(1 + 2 * MAX_INDEXES);
-  c_dropTableRecPool.setSize(1 + 2 * MAX_INDEXES);
-  c_alterTableRecPool.setSize(32);
-  c_createTriggerRecPool.setSize(4 * 2 * MAX_INDEXES);
-  c_dropTriggerRecPool.setSize(3 * 2 * MAX_INDEXES);
-  c_createIndexRecPool.setSize(2*MAX_INDEXES);
-  c_dropIndexRecPool.setSize(2 * MAX_INDEXES);
-  c_alterIndexRecPool.setSize(2 * MAX_INDEXES);
-  c_buildIndexRecPool.setSize(2 * 2 * MAX_INDEXES);
-  c_indexStatRecPool.setSize((1 + 4) * MAX_INDEXES); //main + 4 subs
-  c_createFilegroupRecPool.setSize(32);
-  c_createFileRecPool.setSize(32);
-  c_dropFilegroupRecPool.setSize(32);
-  c_dropFileRecPool.setSize(32);
-  c_createHashMapRecPool.setSize(32);
-  c_copyDataRecPool.setSize(32);
-  c_schemaOpPool.setSize(1 + 32 * MAX_INDEXES);
+  c_createTableRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_TABLE, pc);
+  c_dropTableRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_TABLE, pc);
+  c_alterTableRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_ALTER_TABLE, pc);
+  c_createTriggerRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_TRIGGER, pc);
+  c_dropTriggerRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_TRIGGER, pc);
+  c_createIndexRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_INDEX, pc);
+  c_dropIndexRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_INDEX, pc);
+  c_alterIndexRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_ALTER_INDEX, pc);
+  c_buildIndexRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_BUILD_INDEX, pc);
+  c_indexStatRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_INDEX_STAT, pc);
+  c_createFilegroupRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_FILEGROUP, pc);
+  c_createFileRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_FILE, pc);
+  c_dropFilegroupRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_FILEGROUP, pc);
+  c_dropFileRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_FILE, pc);
+  c_createHashMapRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_HASH_MAP, pc);
+  c_copyDataRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_COPY_DATA, pc);
+  c_schemaOpPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_SCHEMA_OPERATION, pc);
 
   c_hash_map_hash.setSize(4);
   c_hash_map_pool.setSize(32);
   g_hash_map.setSize(32);
 
-  c_createNodegroupRecPool.setSize(2);
-  c_dropNodegroupRecPool.setSize(2);
-  
+  c_createNodegroupRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_CREATE_NODEGROUP, pc);
+  c_dropNodegroupRecPool.arena_pool_init(&c_arenaAllocator, RT_DBDICT_DROP_NODEGROUP, pc);
+
   c_opRecordPool.setSize(256);   // XXX need config params
   c_opCreateEvent.setSize(2);
   c_opSubEvent.setSize(2);
@@ -4016,8 +3909,11 @@ Dbdict::restart_nextOp(Signal* signal, b
 {
   c_restartRecord.m_op_cnt++;
 
-  if (OpSectionBuffer::getSegmentSize() *
-      c_opSectionBufferPool.getNoOfFree() < MAX_WORDS_META_FILE)
+  Resource_limit rl;
+  Uint32 free_words;
+  m_ctx.m_mm.get_resource_limit(RG_SCHEMA_TRANS_MEMORY, rl);
+  free_words = (rl.m_min - rl.m_curr) * GLOBAL_PAGE_SIZE_WORDS; // underestimate
+  if (free_words < 2*MAX_WORDS_META_FILE)
   {
     jam();
     /**
@@ -4385,6 +4281,12 @@ Dbdict::restartCreateObj_parse(Signal* s
   jam();
   Ptr<SchemaOp> op_ptr;
   
+  Ptr<TxHandle> tx_ptr;
+  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
+
+  Ptr<SchemaTrans> trans_ptr;
+  findSchemaTrans(trans_ptr, tx_ptr.p->m_transKey);
+
   switch(c_restartRecord.m_entry.m_tableType){
   case DictTabInfo::SystemTable:
   case DictTabInfo::UserTable:
@@ -4394,37 +4296,31 @@ Dbdict::restartCreateObj_parse(Signal* s
   case DictTabInfo::OrderedIndex:
   {
     Ptr<CreateTableRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     break;
   }
   case DictTabInfo::Undofile:
   case DictTabInfo::Datafile:
   {
     Ptr<CreateFileRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     break;
   }
   case DictTabInfo::Tablespace:
   case DictTabInfo::LogfileGroup:
   {
     Ptr<CreateFilegroupRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     break;
   }
   case DictTabInfo::HashMap:
   {
     Ptr<CreateHashMapRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     break;
   }
   }
 
-  Ptr<TxHandle> tx_ptr;
-  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
-
-  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;
   
@@ -4469,6 +4365,12 @@ Dbdict::restartDropObj(Signal* signal,
   jam();
   Ptr<SchemaOp> op_ptr;
 
+  Ptr<TxHandle> tx_ptr;
+  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
+
+  Ptr<SchemaTrans> trans_ptr;
+  findSchemaTrans(trans_ptr, tx_ptr.p->m_transKey);
+
   switch(c_restartRecord.m_entry.m_tableType){
   case DictTabInfo::SystemTable:
   case DictTabInfo::UserTable:
@@ -4477,14 +4379,14 @@ Dbdict::restartDropObj(Signal* signal,
   case DictTabInfo::UniqueOrderedIndex:
   case DictTabInfo::OrderedIndex:
     Ptr<DropTableRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     ndbrequire(false);
     break;
   case DictTabInfo::Undofile:
   case DictTabInfo::Datafile:
   {
     Ptr<DropFileRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     opRecPtr.p->m_request.file_id = tableId;
     opRecPtr.p->m_request.file_version = entry->m_tableVersion;
     break;
@@ -4493,7 +4395,7 @@ Dbdict::restartDropObj(Signal* signal,
   case DictTabInfo::LogfileGroup:
   {
     Ptr<DropFilegroupRec> opRecPtr;
-    seizeSchemaOp(op_ptr, opRecPtr);
+    seizeSchemaOp(trans_ptr, op_ptr, opRecPtr);
     opRecPtr.p->m_request.filegroup_id = tableId;
     opRecPtr.p->m_request.filegroup_version = entry->m_tableVersion;
     break;
@@ -4502,12 +4404,6 @@ Dbdict::restartDropObj(Signal* signal,
 
   ndbout_c("restartDropObj(%u)", tableId);
   
-  Ptr<TxHandle> tx_ptr;
-  c_txHandleHash.getPtr(tx_ptr, c_restartRecord.m_tx_ptr_i);
-
-  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;
   
@@ -5629,6 +5525,7 @@ void Dbdict::execWAIT_GCP_REF(Signal* si
 const Dbdict::OpInfo
 Dbdict::CreateTableRec::g_opInfo = {
   { 'C', 'T', 'a', 0 },
+  ~RT_DBDICT_CREATE_TABLE,
   GSN_CREATE_TAB_REQ,
   CreateTabReq::SignalLength,
   //
@@ -6163,7 +6060,7 @@ Dbdict::createTable_prepare(Signal* sign
     jam();
     const OpSection& tabInfoSec =
       getOpSection(op_ptr, CreateTabReq::DICT_TAB_INFO);
-    writeTableFile(signal, createTabPtr.p->m_request.tableId,
+    writeTableFile(signal, op_ptr, createTabPtr.p->m_request.tableId,
                    tabInfoSec, &cb);
   }
   else
@@ -6523,7 +6420,8 @@ Dbdict::createTab_dih(Signal* signal, Sc
     // wl3600_todo add ndbrequire on SR, NR
     if (size != 0) {
       jam();
-      bool ok = copyOut(fragSec, page, 1024);
+      LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena,c_opSectionBufferPool);
+      bool ok = copyOut(op_sec_pool, fragSec, page, 1024);
       ndbrequire(ok);
       ptr[noOfSections].sz = size;
       ptr[noOfSections].p = page;
@@ -7074,11 +6972,11 @@ Dbdict::createTable_abortPrepare(Signal*
 
   // create drop table operation  wl3600_todo must pre-allocate
 
-  SchemaOpPtr& oplnk_ptr = op_ptr.p->m_oplnk_ptr;
-  ndbrequire(oplnk_ptr.isNull());
+  SchemaOpPtr oplnk_ptr;
   DropTableRecPtr dropTabPtr;
-  seizeSchemaOp(oplnk_ptr, dropTabPtr);
-  ndbrequire(!oplnk_ptr.isNull());
+  bool ok = seizeLinkedSchemaOp(op_ptr, oplnk_ptr, dropTabPtr);
+  ndbrequire(ok);
+
   DropTabReq* aux_impl_req = &dropTabPtr.p->m_request;
 
   aux_impl_req->senderRef = impl_req->senderRef;
@@ -7087,9 +6985,6 @@ Dbdict::createTable_abortPrepare(Signal*
   aux_impl_req->tableId = impl_req->tableId;
   aux_impl_req->tableVersion = impl_req->tableVersion;
 
-  // link other way too
-  oplnk_ptr.p->m_opbck_ptr = op_ptr;
-
   // wl3600_todo use ref count
   unlinkDictObject(op_ptr);
 
@@ -7259,6 +7154,7 @@ void Dbdict::releaseTableObject(Uint32 t
 const Dbdict::OpInfo
 Dbdict::DropTableRec::g_opInfo = {
   { 'D', 'T', 'a', 0 },
+  ~RT_DBDICT_DROP_TABLE,
   GSN_DROP_TAB_REQ,
   DropTabReq::SignalLength,
   //
@@ -7888,6 +7784,7 @@ void Dbdict::execDROP_TABLE_REF(Signal*
 const Dbdict::OpInfo
 Dbdict::AlterTableRec::g_opInfo = {
   { 'A', 'T', 'a', 0 },
+  ~RT_DBDICT_ALTER_TABLE,
   GSN_ALTER_TAB_REQ,
   AlterTabReq::SignalLength,
   //
@@ -7925,6 +7822,8 @@ Dbdict::alterTable_release(SchemaOpPtr o
     Rope r(c_rope_pool, alterTabPtr.p->m_oldFrmData);
     r.erase();
   }
+  LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+  release(op_sec_pool, alterTabPtr.p->m_newAttrData);
   releaseOpRec<AlterTableRec>(op_ptr);
 }
 
@@ -8238,12 +8137,19 @@ Dbdict::alterTable_parse(Signal* signal,
     AttributeRecordPtr attrPtr;
     list.first(attrPtr);
     Uint32 i = 0;
+    LocalArenaPoolImpl op_sec_pool(trans_ptr.p->m_arena, c_opSectionBufferPool);
     for (i = 0; i < newTablePtr.p->noOfAttributes; i++) {
       if (i >= tablePtr.p->noOfAttributes) {
         jam();
-        Uint32 j = 2 * (i - tablePtr.p->noOfAttributes);
-        alterTabPtr.p->m_newAttrData[j + 0] = attrPtr.p->attributeDescriptor;
-        alterTabPtr.p->m_newAttrData[j + 1] = attrPtr.p->extPrecision & ~0xFFFF;
+        Uint32 attrData[2];
+        attrData[0] = attrPtr.p->attributeDescriptor;
+        attrData[1] = attrPtr.p->extPrecision & ~0xFFFF;
+        if(!copyIn(op_sec_pool, alterTabPtr.p->m_newAttrData, attrData, 2))
+        {
+          jam();
+          setError(error, SchemaTransBeginRef::OutOfSchemaTransMemory, __LINE__);
+          return;
+        }
       }
       list.next(attrPtr);
     }
@@ -9000,7 +8906,7 @@ Dbdict::alterTable_prepare(Signal* signa
      */
     {
       Ptr<SchemaOp> tmp = op_ptr;
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       for (list.prev(tmp); !tmp.isNull(); list.prev(tmp))
       {
         jam();
@@ -9075,7 +8981,7 @@ Dbdict::alterTable_backup_mutex_locked(S
 
   bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
   if (savetodisk) {
-    writeTableFile(signal, impl_req->tableId, tabInfoSec, &callback);
+    writeTableFile(signal, op_ptr, impl_req->tableId, tabInfoSec, &callback);
   } else {
     execute(signal, callback, 0);
   }
@@ -9153,7 +9059,14 @@ Dbdict::alterTable_toLocal(Signal* signa
   {
     jam();
     LinearSectionPtr ptr[3];
-    ptr[0].p = alterTabPtr.p->m_newAttrData;
+    Uint32 newAttrData[2 * MAX_ATTRIBUTES_IN_TABLE];
+    ndbrequire(impl_req->noOfNewAttr <= MAX_ATTRIBUTES_IN_TABLE);
+    ndbrequire(2 * impl_req->noOfNewAttr == alterTabPtr.p->m_newAttrData.getSize());
+    LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+    bool ok = copyOut(op_sec_pool, alterTabPtr.p->m_newAttrData, newAttrData, 2 * impl_req->noOfNewAttr);
+    ndbrequire(ok);
+
+    ptr[0].p = newAttrData;
     ptr[0].sz = 2 * impl_req->noOfNewAttr;
     sendSignal(blockRef, GSN_ALTER_TAB_REQ, signal,
                AlterTabReq::SignalLength, JBB, ptr, 1);
@@ -9164,7 +9077,8 @@ Dbdict::alterTable_toLocal(Signal* signa
     const OpSection& fragInfoSec =
       getOpSection(op_ptr, AlterTabReq::FRAGMENTATION);
     SegmentedSectionPtr fragInfoPtr;
-    bool ok = copyOut(fragInfoSec, fragInfoPtr);
+    LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena,c_opSectionBufferPool);
+    bool ok = copyOut(op_sec_pool, fragInfoSec, fragInfoPtr);
     ndbrequire(ok);
 
     if (AlterTableReq::getReorgFragFlag(req->changeMask))
@@ -9516,7 +9430,8 @@ Dbdict::alterTable_fromCommitComplete(Si
     const OpSection& tabInfoSec =
       getOpSection(op_ptr, AlterTabReq::DICT_TAB_INFO);
     SegmentedSectionPtr tabInfoPtr;
-    bool ok = copyOut(tabInfoSec, tabInfoPtr);
+    LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena,c_opSectionBufferPool);
+    bool ok = copyOut(op_sec_pool, tabInfoSec, tabInfoPtr);
     ndbrequire(ok);
 
     SectionHandle handle(this, tabInfoPtr.i);
@@ -10683,6 +10598,7 @@ flush:
 const Dbdict::OpInfo
 Dbdict::CreateIndexRec::g_opInfo = {
   { 'C', 'I', 'n', 0 },
+  ~RT_DBDICT_CREATE_INDEX,
   GSN_CREATE_INDX_IMPL_REQ,
   CreateIndxImplReq::SignalLength,
   //
@@ -11437,6 +11353,7 @@ Dbdict::execCREATE_INDX_IMPL_REF(Signal*
 const Dbdict::OpInfo
 Dbdict::DropIndexRec::g_opInfo = {
   { 'D', 'I', 'n', 0 },
+  ~RT_DBDICT_DROP_INDEX,
   GSN_DROP_INDX_IMPL_REQ,
   DropIndxImplReq::SignalLength,
   //
@@ -11880,6 +11797,7 @@ Dbdict::execDROP_INDX_IMPL_REF(Signal* s
 const Dbdict::OpInfo
 Dbdict::AlterIndexRec::g_opInfo = {
   { 'A', 'I', 'n', 0 },
+  ~RT_DBDICT_ALTER_INDEX,
   GSN_ALTER_INDX_IMPL_REQ,
   AlterIndxImplReq::SignalLength,
   //
@@ -12129,7 +12047,7 @@ Dbdict::alterIndex_parse(Signal* signal,
        *   (i.e recursivly, assuming that no operation can come inbetween)
        */
       Ptr<SchemaOp> baseop = op_ptr;
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       ndbrequire(list.prev(baseop));
       Uint32 sz = sizeof(baseop.p->m_oprec_ptr.p->m_opType);
       const char * opType = baseop.p->m_oprec_ptr.p->m_opType;
@@ -12828,7 +12746,8 @@ Dbdict::alterIndex_toAddPartitions(Signa
   const OpSection& fragInfoSec =
     getOpSection(base_op, AlterTabReq::FRAGMENTATION);
   SegmentedSectionPtr fragInfoPtr;
-  bool ok = copyOut(fragInfoSec, fragInfoPtr);
+  LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+  bool ok = copyOut(op_sec_pool, fragInfoSec, fragInfoPtr);
   ndbrequire(ok);
   SectionHandle handle(this, fragInfoPtr.i);
 
@@ -13100,6 +13019,7 @@ Dbdict::execALTER_INDX_IMPL_REF(Signal*
 const Dbdict::OpInfo
 Dbdict::BuildIndexRec::g_opInfo = {
   { 'B', 'I', 'n', 0 },
+  ~RT_DBDICT_BUILD_INDEX,
   GSN_BUILD_INDX_IMPL_REQ,
   BuildIndxImplReq::SignalLength,
   //
@@ -13873,6 +13793,7 @@ Dbdict::execBUILD_INDX_IMPL_REF(Signal*
 const Dbdict::OpInfo
 Dbdict::IndexStatRec::g_opInfo = {
   { 'S', 'I', 'n', 0 },
+  ~RT_DBDICT_INDEX_STAT,
   GSN_INDEX_STAT_IMPL_REQ,
   IndexStatImplReq::SignalLength,
   //
@@ -14622,6 +14543,7 @@ Dbdict::indexStatBg_sendContinueB(Signal
 const Dbdict::OpInfo
 Dbdict::CopyDataRec::g_opInfo = {
   { 'D', 'C', 'D', 0 },
+  ~RT_DBDICT_COPY_DATA,
   GSN_COPY_DATA_IMPL_REQ,
   CopyDataImplReq::SignalLength,
 
@@ -17623,6 +17545,7 @@ void Dbdict::dropEvent_sendReply(Signal*
 const Dbdict::OpInfo
 Dbdict::CreateTriggerRec::g_opInfo = {
   { 'C', 'T', 'r', 0 },
+  ~RT_DBDICT_CREATE_TRIGGER,
   GSN_CREATE_TRIG_IMPL_REQ,
   CreateTrigImplReq::SignalLength,
   //
@@ -18010,7 +17933,6 @@ Dbdict::createTrigger_create_drop_trigge
 {
   jam();
 
-  SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
   CreateTriggerRecPtr createTriggerPtr;
   getOpRec(op_ptr, createTriggerPtr);
   CreateTrigImplReq* impl_req = &createTriggerPtr.p->m_request;
@@ -18018,11 +17940,9 @@ Dbdict::createTrigger_create_drop_trigge
   /**
    * Construct a dropTrigger operation
    */
-  SchemaOpPtr& oplnk_ptr = op_ptr.p->m_oplnk_ptr;
-  ndbrequire(oplnk_ptr.isNull());
+  SchemaOpPtr oplnk_ptr;
   DropTriggerRecPtr dropTriggerPtr;
-  seizeSchemaOp(oplnk_ptr, dropTriggerPtr);
-  if (oplnk_ptr.isNull())
+  if(!seizeLinkedSchemaOp(op_ptr, oplnk_ptr, dropTriggerPtr))
   {
     jam();
     setError(error, CreateTrigRef::TooManyTriggers, __LINE__);
@@ -18042,9 +17962,6 @@ Dbdict::createTrigger_create_drop_trigge
   aux_impl_req->triggerId = impl_req->triggerId;
   aux_impl_req->triggerInfo = impl_req->triggerInfo;
 
-  // link other way too
-  oplnk_ptr.p->m_opbck_ptr = op_ptr;
-  oplnk_ptr.p->m_trans_ptr = trans_ptr;
   dropTriggerPtr.p->m_main_op = createTriggerPtr.p->m_main_op;
 
   if (createTriggerPtr.p->m_main_op)
@@ -18574,6 +18491,7 @@ Dbdict::execCREATE_TRIG_IMPL_REF(Signal*
 const Dbdict::OpInfo
 Dbdict::DropTriggerRec::g_opInfo = {
   { 'D', 'T', 'r', 0 },
+  ~RT_DBDICT_DROP_TRIGGER,
   GSN_DROP_TRIG_IMPL_REQ,
   DropTrigImplReq::SignalLength,
   //
@@ -19548,7 +19466,7 @@ Dbdict::execDICT_TAKEOVER_REQ(Signal* si
 #endif
      
      SchemaOpPtr op_ptr;
-     LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+     LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
      bool pending_op = list.first(op_ptr);
      if (pending_op &&
          (trans_ptr.p->m_state == SchemaTrans::TS_COMPLETING ||
@@ -20125,7 +20043,8 @@ void Dbdict::check_takeover_replies(Sign
               SchemaOpPtr missing_op_ptr;
               const OpInfo& info =
                 *findOpInfo(nodePtr.p->takeOverConf.highest_op_impl_req_gsn);
-              if (seizeSchemaOp(missing_op_ptr,
+              if (seizeSchemaOp(trans_ptr,
+                                missing_op_ptr,
                                 nodePtr.p->takeOverConf.highest_op,
                                 info))
               {
@@ -20133,7 +20052,6 @@ void Dbdict::check_takeover_replies(Sign
 #ifdef VM_TRACE
                 ndbout_c("Created missing operation %u, on new master", missing_op_ptr.p->op_key);
 #endif
-                addSchemaOp(trans_ptr, missing_op_ptr);
                 missing_op_ptr.p->m_state = nodePtr.p->takeOverConf.highest_op_state;
                 masterNodePtr.p->recoveryState = NodeRecord::RS_PARTIAL_ROLLBACK;
                 masterNodePtr.p->start_op = masterNodePtr.p->takeOverConf.highest_op;
@@ -20168,7 +20086,8 @@ void Dbdict::check_takeover_replies(Sign
             Uint32 op_state = nodePtr.p->takeOverConf.lowest_op_state;
             const OpInfo& info =
               *findOpInfo(nodePtr.p->takeOverConf.lowest_op_impl_req_gsn);
-            if (seizeSchemaOp(missing_op_ptr,
+            if (seizeSchemaOp(trans_ptr,
+                              missing_op_ptr,
                               op_key,
                               info))
             {
@@ -20176,7 +20095,6 @@ void Dbdict::check_takeover_replies(Sign
 #ifdef VM_TRACE
               ndbout_c("Created ressurected operation %u, on new master", op_key);
 #endif
-              addSchemaOp(trans_ptr, missing_op_ptr);
               trans_ptr.p->ressurected_op = true;
               missing_op_ptr.p->m_state = op_state;
               nodePtr.p->recoveryState = NodeRecord::RS_PARTIAL_ROLLFORWARD;
@@ -20637,6 +20555,7 @@ Dbdict::getTableEntry(const XSchemaFile
 const Dbdict::OpInfo
 Dbdict::CreateFileRec::g_opInfo = {
   { 'C', 'F', 'l', 0 },
+  ~RT_DBDICT_CREATE_FILE,
   GSN_CREATE_FILE_IMPL_REQ,
   CreateFileImplReq::SignalLength,
   //
@@ -21153,7 +21072,7 @@ Dbdict::createFile_prepare(Signal* signa
   }
 
   const OpSection& objInfoSec = getOpSection(op_ptr, 0);
-  writeTableFile(signal, impl_req->file_id, objInfoSec, &cb);
+  writeTableFile(signal, op_ptr, impl_req->file_id, objInfoSec, &cb);
 }
 
 void
@@ -21387,6 +21306,7 @@ Dbdict::execCREATE_FILE_IMPL_CONF(Signal
 const Dbdict::OpInfo
 Dbdict::CreateFilegroupRec::g_opInfo = {
   { 'C', 'F', 'G', 0 },
+  ~RT_DBDICT_CREATE_FILEGROUP,
   GSN_CREATE_FILEGROUP_IMPL_REQ,
   CreateFilegroupImplReq::SignalLength,
   //
@@ -21840,7 +21760,7 @@ Dbdict::createFilegroup_prepare(Signal*
   }
 
   const OpSection& objInfoSec = getOpSection(op_ptr, 0);
-  writeTableFile(signal, impl_req->filegroup_id, objInfoSec, &cb);
+  writeTableFile(signal, op_ptr, impl_req->filegroup_id, objInfoSec, &cb);
 }
 
 void
@@ -22000,6 +21920,7 @@ Dbdict::execCREATE_FILEGROUP_IMPL_CONF(S
 const Dbdict::OpInfo
 Dbdict::DropFileRec::g_opInfo = {
   { 'D', 'F', 'l', 0 },
+  ~RT_DBDICT_DROP_FILE,
   GSN_DROP_FILE_IMPL_REQ,
   DropFileImplReq::SignalLength,
   //
@@ -22357,6 +22278,7 @@ Dbdict::send_drop_file(Signal* signal, U
 const Dbdict::OpInfo
 Dbdict::DropFilegroupRec::g_opInfo = {
   { 'D', 'F', 'g', 0 },
+  ~RT_DBDICT_DROP_FILEGROUP,
   GSN_DROP_FILEGROUP_IMPL_REQ,
   DropFilegroupImplReq::SignalLength,
   //
@@ -22784,6 +22706,7 @@ Dbdict::send_drop_fg(Signal* signal, Uin
 const Dbdict::OpInfo
 Dbdict::CreateNodegroupRec::g_opInfo = {
   { 'C', 'N', 'G', 0 },
+  ~RT_DBDICT_CREATE_NODEGROUP,
   GSN_CREATE_NODEGROUP_IMPL_REQ,
   CreateNodegroupImplReq::SignalLength,
   //
@@ -23383,6 +23306,7 @@ Dbdict::execCREATE_HASH_MAP_CONF(Signal*
 const Dbdict::OpInfo
 Dbdict::DropNodegroupRec::g_opInfo = {
   { 'D', 'N', 'G', 0 },
+  ~RT_DBDICT_DROP_NODEGROUP,
   GSN_DROP_NODEGROUP_IMPL_REQ,
   DropNodegroupImplReq::SignalLength,
   //
@@ -24063,7 +23987,7 @@ Dbdict::findOpInfo(Uint32 gsn)
 // OpSection
 
 bool
-Dbdict::copyIn(OpSection& op_sec, const SegmentedSectionPtr& ss_ptr)
+Dbdict::copyIn(OpSectionBufferPool& pool, OpSection& op_sec, const SegmentedSectionPtr& ss_ptr)
 {
   const Uint32 size = 1024;
   Uint32 buf[size];
@@ -24075,7 +23999,7 @@ Dbdict::copyIn(OpSection& op_sec, const
   {
     jam();
     ndbrequire(reader.getWords(buf, size));
-    if (!copyIn(op_sec, buf, size))
+    if (!copyIn(pool, op_sec, buf, size))
     {
       jam();
       return false;
@@ -24084,7 +24008,7 @@ Dbdict::copyIn(OpSection& op_sec, const
   }
 
   ndbrequire(reader.getWords(buf, len));
-  if (!copyIn(op_sec, buf, len))
+  if (!copyIn(pool, op_sec, buf, len))
   {
     jam();
     return false;
@@ -24094,9 +24018,9 @@ Dbdict::copyIn(OpSection& op_sec, const
 }
 
 bool
-Dbdict::copyIn(OpSection& op_sec, const Uint32* src, Uint32 srcSize)
+Dbdict::copyIn(OpSectionBufferPool& pool, OpSection& op_sec, const Uint32* src, Uint32 srcSize)
 {
-  OpSectionBuffer buffer(c_opSectionBufferPool, op_sec.m_head);
+  OpSectionBuffer buffer(pool, op_sec.m_head);
   if (!buffer.append(src, srcSize)) {
     jam();
     return false;
@@ -24121,14 +24045,15 @@ Dbdict::copyOut(Dbdict::OpSectionBuffer
 }
 
 bool
-Dbdict::copyOut(const OpSection& op_sec, SegmentedSectionPtr& ss_ptr)
+Dbdict::copyOut(OpSectionBufferPool& pool, const OpSection& op_sec, SegmentedSectionPtr& ss_ptr)
 {
   const Uint32 size = 1024;
   Uint32 buf[size];
 
   Uint32 len = op_sec.getSize();
   OpSectionBufferHead tmp_head = op_sec.m_head;
-  OpSectionBuffer buffer(c_opSectionBufferPool, tmp_head);
+
+  OpSectionBuffer buffer(pool, tmp_head);
 
   OpSectionBufferConstIterator iter;
   buffer.first(iter);
@@ -24169,7 +24094,7 @@ fail:
 }
 
 bool
-Dbdict::copyOut(const OpSection& op_sec, Uint32* dst, Uint32 dstSize)
+Dbdict::copyOut(OpSectionBufferPool& pool, const OpSection& op_sec, Uint32* dst, Uint32 dstSize)
 {
   if (op_sec.getSize() > dstSize) {
     jam();
@@ -24178,7 +24103,7 @@ Dbdict::copyOut(const OpSection& op_sec,
 
   // there is no const version of LocalDataBuffer
   OpSectionBufferHead tmp_head = op_sec.m_head;
-  OpSectionBuffer buffer(c_opSectionBufferPool, tmp_head);
+  OpSectionBuffer buffer(pool, tmp_head);
 
   OpSectionBufferConstIterator iter;
   Uint32 n = 0;
@@ -24192,9 +24117,9 @@ Dbdict::copyOut(const OpSection& op_sec,
 }
 
 void
-Dbdict::release(OpSection& op_sec)
+Dbdict::release(OpSectionBufferPool& pool, OpSection& op_sec)
 {
-  OpSectionBuffer buffer(c_opSectionBufferPool, op_sec.m_head);
+  OpSectionBuffer buffer(pool, op_sec.m_head);
   buffer.release();
 }
 
@@ -24210,7 +24135,7 @@ Dbdict::getOpInfo(SchemaOpPtr op_ptr)
 }
 
 bool
-Dbdict::seizeSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info)
+Dbdict::seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info, bool linked)
 {
   if ((ERROR_INSERTED(6111) && 
        (info.m_impl_req_gsn == GSN_CREATE_TAB_REQ ||
@@ -24235,14 +24160,20 @@ Dbdict::seizeSchemaOp(SchemaOpPtr& op_pt
 
   if (!findSchemaOp(op_ptr, op_key)) {
     jam();
-    if (c_schemaOpHash.seize(op_ptr)) {
+    if (c_schemaOpPool.seize(trans_ptr.p->m_arena, op_ptr)) {
       jam();
       new (op_ptr.p) SchemaOp();
       op_ptr.p->op_key = op_key;
+      op_ptr.p->m_trans_ptr = trans_ptr;
       if ((this->*(info.m_seize))(op_ptr)) {
         jam();
+
+        if(!linked) {
+          jam();
+          addSchemaOp(op_ptr);
+        }
+
         c_schemaOpHash.add(op_ptr);
-        op_ptr.p->m_magic = SchemaOp::DICT_MAGIC;
         D("seizeSchemaOp" << V(op_key) << V(info.m_opType));
         return true;
       }
@@ -24294,8 +24225,9 @@ Dbdict::releaseSchemaOp(SchemaOpPtr& op_
   }
 
   ndbrequire(op_ptr.p->m_magic == SchemaOp::DICT_MAGIC);
-  op_ptr.p->m_magic = 0;
-  c_schemaOpHash.release(op_ptr);
+  c_schemaOpHash.remove(op_ptr);
+  c_schemaOpPool.release(op_ptr);
+  ndbrequire(op_ptr.p->m_magic == 0);
   op_ptr.setNull();
 }
 
@@ -24326,7 +24258,8 @@ Dbdict::saveOpSection(SchemaOpPtr op_ptr
   OpSection& op_sec = op_ptr.p->m_section[ss_no];
   op_ptr.p->m_sections++;
 
-  bool ok = copyIn(op_sec, ss_ptr);
+  LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+  bool ok =  copyIn(op_sec_pool, op_sec, ss_ptr);
   ndbrequire(ok);
   return true;
 }
@@ -24336,20 +24269,20 @@ Dbdict::releaseOpSection(SchemaOpPtr op_
 {
   ndbrequire(ss_no + 1 == op_ptr.p->m_sections);
   OpSection& op_sec = op_ptr.p->m_section[ss_no];
-  release(op_sec);
+  LocalArenaPoolImpl op_sec_pool(op_ptr.p->m_trans_ptr.p->m_arena, c_opSectionBufferPool);
+  release(op_sec_pool, op_sec);
   op_ptr.p->m_sections = ss_no;
 }
 
 // add schema op to trans during parse phase
 
 void
-Dbdict::addSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr)
+Dbdict::addSchemaOp(SchemaOpPtr op_ptr)
 {
-  LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+  SchemaTransPtr trans_ptr = op_ptr.p->m_trans_ptr;
+  LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
   list.addLast(op_ptr);
 
-  op_ptr.p->m_trans_ptr = trans_ptr;
-
   // jonas_todo REMOVE side effect
   // add global flags from trans
   const Uint32& src_info = trans_ptr.p->m_requestInfo;
@@ -24526,7 +24459,7 @@ Dbdict::findDictObjectOp(SchemaOpPtr& op
     D("found" << *trans_ptr.p);
 
     {
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       SchemaOpPtr loop_ptr;
       list.first(loop_ptr);
       while (!loop_ptr.isNull()) {
@@ -24559,17 +24492,21 @@ Dbdict::seizeSchemaTrans(SchemaTransPtr&
   }
   if (!findSchemaTrans(trans_ptr, trans_key)) {
     jam();
-    if (c_schemaTransHash.seize(trans_ptr)) {
+    ArenaHead arena;
+    bool ok = c_arenaAllocator.seize(arena);
+    ndbrequire(ok); // TODO: report error
+    if (c_schemaTransPool.seize(arena, trans_ptr)) {
       jam();
       new (trans_ptr.p) SchemaTrans();
       trans_ptr.p->trans_key = trans_key;
+      trans_ptr.p->m_arena = arena;
       c_schemaTransHash.add(trans_ptr);
       c_schemaTransList.addLast(trans_ptr);
       c_schemaTransCount++;
-      trans_ptr.p->m_magic = SchemaTrans::DICT_MAGIC;
       D("seizeSchemaTrans" << V(trans_key));
       return true;
     }
+    c_arenaAllocator.release(arena);
   }
   trans_ptr.setNull();
   return false;
@@ -24611,26 +24548,29 @@ Dbdict::releaseSchemaTrans(SchemaTransPt
 {
   D("releaseSchemaTrans" << V(trans_ptr.p->trans_key));
 
-  LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+  LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
   SchemaOpPtr op_ptr;
   while (list.first(op_ptr)) {
     list.remove(op_ptr);
     releaseSchemaOp(op_ptr);
   }
   ndbrequire(trans_ptr.p->m_magic == SchemaTrans::DICT_MAGIC);
-  trans_ptr.p->m_magic = 0;
   ndbrequire(c_schemaTransCount != 0);
   c_schemaTransCount--;
   c_schemaTransList.remove(trans_ptr);
-  c_schemaTransHash.release(trans_ptr);
+  c_schemaTransHash.remove(trans_ptr);
+  ArenaHead arena = trans_ptr.p->m_arena;
+  c_schemaTransPool.release(trans_ptr);
+  c_arenaAllocator.release(arena);
   trans_ptr.setNull();
 
   if (c_schemaTransCount == 0)
   {
     jam();
 
-    ndbrequire(c_schemaOpPool.getNoOfFree() == c_schemaOpPool.getSize());
-    ndbrequire(c_opSectionBufferPool.getNoOfFree() == c_opSectionBufferPool.getSize());
+    Resource_limit rl;
+    m_ctx.m_mm.get_resource_limit(RG_SCHEMA_TRANS_MEMORY, rl);
+    ndbrequire(rl.m_curr <= 1); // ArenaAllocator can keep one page for empty pool
 #ifdef VM_TRACE
     if (getNodeState().startLevel == NodeState::SL_STARTED)
       check_consistency();
@@ -25449,7 +25389,7 @@ Dbdict::trans_prepare_first(Signal* sign
   {
     bool first;
     {
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       first = list.first(op_ptr);
     }
     if (first)
@@ -25485,7 +25425,7 @@ Dbdict::trans_prepare_next(Signal* signa
   if (ERROR_INSERTED(6143))
   {
     jam();
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     if (!list.hasNext(op_ptr))
     {
       /*
@@ -25534,7 +25474,7 @@ Dbdict::trans_prepare_recv_reply(Signal*
   {
     bool next;
     {
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       next = list.next(op_ptr);
     }
     if (next)
@@ -25580,7 +25520,7 @@ Dbdict::trans_abort_parse_start(Signal*
   SchemaOpPtr op_ptr;
   bool last = false;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     last =  list.last(op_ptr);
   }
 
@@ -25605,7 +25545,7 @@ Dbdict::trans_abort_parse_recv_reply(Sig
     SchemaOpPtr last_op = op_ptr;
     bool prev = false;
     {
-      LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+      LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
       prev = list.prev(op_ptr);
       list.remove(last_op);         // Release aborted op
     }
@@ -25690,7 +25630,7 @@ Dbdict::trans_abort_parse_next(Signal* s
   if (ERROR_INSERTED(6144))
   {
     jam();
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     if (!list.hasNext(op_ptr))
     {
       /*
@@ -25737,7 +25677,7 @@ Dbdict::trans_abort_prepare_start(Signal
   bool last = false;
   SchemaOpPtr op_ptr;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     last = list.last(op_ptr);
   }
 
@@ -25765,7 +25705,7 @@ Dbdict::trans_abort_prepare_recv_reply(S
 
   bool prev = false;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     prev = list.prev(op_ptr);
   }
 
@@ -25879,7 +25819,7 @@ Dbdict::trans_abort_prepare_next(Signal*
   if (ERROR_INSERTED(6145))
   {
     jam();
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     if (!list.hasPrev(op_ptr))
     {
       /*
@@ -25934,7 +25874,7 @@ Dbdict::trans_rollback_sp_start(Signal*
   SchemaOpPtr op_ptr;
 
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     ndbrequire(list.last(op_ptr));
   }
 
@@ -25981,7 +25921,7 @@ Dbdict::trans_rollback_sp_recv_reply(Sig
   }
 
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
 
     SchemaOpPtr last_op = op_ptr;
     ndbrequire(list.prev(op_ptr)); // Must have prev, as not SP
@@ -26013,7 +25953,7 @@ Dbdict::trans_rollback_sp_next(Signal* s
   if (ERROR_INSERTED(6144))
   {
     jam();
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     if (!list.hasPrev(op_ptr))
     {
       /*
@@ -26055,7 +25995,7 @@ Dbdict::trans_rollback_sp_done(Signal* s
   const OpInfo info = getOpInfo(op_ptr);
   (this->*(info.m_reply))(signal, op_ptr, error);
 
-  LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+  LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
   list.remove(op_ptr);
   releaseSchemaOp(op_ptr);
 
@@ -26292,7 +26232,7 @@ Dbdict::trans_commit_mutex_locked(Signal
   bool first = false;
   SchemaOpPtr op_ptr;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     first = list.first(op_ptr);
   }
 
@@ -26383,7 +26323,7 @@ Dbdict::trans_commit_next(Signal* signal
 
   if (ERROR_INSERTED(6147))
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     if (!list.hasNext(op_ptr))
     {
       jam();
@@ -26454,7 +26394,7 @@ Dbdict::trans_commit_recv_reply(Signal*
 
   bool next = false;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     next = list.next(op_ptr);
   }
 
@@ -26630,7 +26570,7 @@ Dbdict::trans_complete_first(Signal * si
   bool first = false;
   SchemaOpPtr op_ptr;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     first = list.first(op_ptr);
   }
 
@@ -26708,7 +26648,7 @@ Dbdict::trans_complete_recv_reply(Signal
 
   bool next = false;
   {
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     next = list.next(op_ptr);
   }
   
@@ -26795,7 +26735,7 @@ Dbdict::check_partial_trans_end_recv_rep
      */
     jam();
     SchemaOpPtr op_ptr;
-    LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+    LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
     list.remove(op_ptr);
 #ifdef VM_TRACE
     ndbout_c("Releasing ressurected op %u", op_ptr.p->op_key);
@@ -27114,7 +27054,7 @@ Dbdict::execSCHEMA_TRANS_IMPL_REQ(Signal
         /**
          * Remove op (except at coordinator
          */
-        LocalDLFifoList<SchemaOp> list(c_schemaOpPool, trans_ptr.p->m_op_list);
+        LocalSchemaOp_list list(c_schemaOpPool, trans_ptr.p->m_op_list);
         list.remove(op_ptr);
         releaseSchemaOp(op_ptr);
       }
@@ -27240,7 +27180,7 @@ Dbdict::slave_run_parse(Signal *signal,
       jam();
       setError(error, AlterTableRef::SingleUser, __LINE__);
     }
-    else if (seizeSchemaOp(op_ptr, op_key, info))
+    else if (seizeSchemaOp(trans_ptr, op_ptr, op_key, info))
     {
       jam();
 
@@ -27251,7 +27191,6 @@ Dbdict::slave_run_parse(Signal *signal,
       Uint32* dst = oprec_ptr.p->m_impl_req_data;
       memcpy(dst, src, len << 2);
 
-      addSchemaOp(trans_ptr, op_ptr);
       op_ptr.p->m_state = SchemaOp::OS_PARSING;
       (this->*(info.m_parse))(signal, false, op_ptr, handle, error);
     } else {
@@ -28307,6 +28246,7 @@ ArrayPool<Hash2FragmentMap> g_hash_map;
 const Dbdict::OpInfo
 Dbdict::CreateHashMapRec::g_opInfo = {
   { 'C', 'H', 'M', 0 },
+  ~RT_DBDICT_CREATE_HASH_MAP,
   GSN_CREATE_HASH_MAP_REQ,
   CreateHashMapReq::SignalLength,
   //
@@ -28869,7 +28809,7 @@ Dbdict::createHashMap_prepare(Signal* si
   cb.m_callbackFunction = safe_cast(&Dbdict::createHashMap_writeObjConf);
 
   const OpSection& tabInfoSec = getOpSection(op_ptr, 0);
-  writeTableFile(signal, impl_req->objectId, tabInfoSec, &cb);
+  writeTableFile(signal, op_ptr, impl_req->objectId, tabInfoSec, &cb);
 }
 
 void

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2011-10-07 13:15:08 +0000
@@ -24,6 +24,8 @@
 #include <ndb_limits.h>
 #include <trigger_definitions.h>
 #include <pc.hpp>
+#include <ArenaPool.hpp>
+#include <DataBuffer2.hpp>
 #include <DLHashTable.hpp>
 #include <DLFifoList.hpp>
 #include <CArray.hpp>
@@ -1358,7 +1360,8 @@ private:
   // OpInfo
 
   struct OpInfo {
-    const char m_opType[4]; // e.g. CTa for CreateTable
+    const char m_opType[4]; // e.g. CTa for CreateTable. TODO: remove. use only m_magic?
+    Uint32 m_magic;
     Uint32 m_impl_req_gsn;
     Uint32 m_impl_req_length;
 
@@ -1389,10 +1392,12 @@ private:
 
   struct OpRec
   {
-    char m_opType[4];
+    char m_opType[4]; // TODO: remove. only use m_magic
 
     Uint32 nextPool;
 
+    Uint32 m_magic;
+
     // reference to the static member in subclass
     const OpInfo& m_opInfo;
 
@@ -1403,6 +1408,7 @@ private:
     Uint32 m_obj_ptr_i;
 
     OpRec(const OpInfo& info, Uint32* impl_req_data) :
+      m_magic(info.m_magic),
       m_opInfo(info),
       m_impl_req_data(impl_req_data) {
       m_obj_ptr_i = RNIL;
@@ -1420,19 +1426,19 @@ private:
 
   enum { OpSectionSegmentSize = 127 };
   typedef
-    LocalDataBuffer<OpSectionSegmentSize>
+    LocalDataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>
     OpSectionBuffer;
   typedef
-    OpSectionBuffer::Head
+    DataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>::Head
     OpSectionBufferHead;
   typedef
     OpSectionBuffer::DataBufferPool
     OpSectionBufferPool;
   typedef
-    DataBuffer<OpSectionSegmentSize>::ConstDataBufferIterator
+    DataBuffer2<OpSectionSegmentSize, LocalArenaPoolImpl>::ConstDataBufferIterator
     OpSectionBufferConstIterator;
 
-  OpSectionBufferPool c_opSectionBufferPool;
+  ArenaPool c_opSectionBufferPool;
 
   struct OpSection {
     OpSectionBufferHead m_head;
@@ -1441,13 +1447,13 @@ private:
     }
   };
 
-  bool copyIn(OpSection&, const SegmentedSectionPtr&);
-  bool copyIn(OpSection&, const Uint32* src, Uint32 srcSize);
-  bool copyOut(const OpSection&, SegmentedSectionPtr&);
-  bool copyOut(const OpSection&, Uint32* dst, Uint32 dstSize);
+  bool copyIn(OpSectionBufferPool&, OpSection&, const SegmentedSectionPtr&);
+  bool copyIn(OpSectionBufferPool&, OpSection&, const Uint32* src, Uint32 srcSize);
+  bool copyOut(OpSectionBufferPool&, const OpSection&, SegmentedSectionPtr&);
+  bool copyOut(OpSectionBufferPool&, const OpSection&, Uint32* dst, Uint32 dstSize);
   bool copyOut(OpSectionBuffer & buffer, OpSectionBufferConstIterator & iter,
                Uint32 * dst, Uint32 len);
-  void release(OpSection&);
+  void release(OpSectionBufferPool&, OpSection&);
 
   // SchemaOp
 
@@ -1558,7 +1564,7 @@ private:
     SchemaFile::TableEntry m_orig_entry;
 
     // magic is on when record is seized
-    enum { DICT_MAGIC = 0xd1c70001 };
+    enum { DICT_MAGIC = ~RT_DBDICT_SCHEMA_OPERATION };
     Uint32 m_magic;
 
     SchemaOp() {
@@ -1573,7 +1579,7 @@ private:
       m_callback.m_callbackData = 0;
       m_oplnk_ptr.setNull();
       m_opbck_ptr.setNull();
-      m_magic = 0;
+      m_magic = DICT_MAGIC;
       m_base_op_ptr_i = RNIL;
 
       m_orig_entry_id = RNIL;
@@ -1589,8 +1595,13 @@ private:
 #endif
   };
 
-  ArrayPool<SchemaOp> c_schemaOpPool;
-  DLHashTable<SchemaOp> c_schemaOpHash;
+  typedef RecordPool<SchemaOp,ArenaPool> SchemaOp_pool;
+  typedef LocalDLFifoList<SchemaOp,SchemaOp,SchemaOp_pool> LocalSchemaOp_list;
+  typedef DLHashTable<SchemaOp,SchemaOp,SchemaOp_pool> SchemaOp_hash;
+  typedef DLFifoList<SchemaOp,SchemaOp,SchemaOp_pool>::Head  SchemaOp_head;
+
+  SchemaOp_pool c_schemaOpPool;
+  SchemaOp_hash c_schemaOpHash;
 
   const OpInfo& getOpInfo(SchemaOpPtr op_ptr);
 
@@ -1622,9 +1633,9 @@ private:
   inline bool
   seizeOpRec(SchemaOpPtr op_ptr) {
     OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
-    ArrayPool<T>& pool = T::getPool(this);
+    RecordPool<T,ArenaPool>& pool = T::getPool(this);
     Ptr<T> t_ptr;
-    if (pool.seize(t_ptr)) {
+    if (pool.seize(op_ptr.p->m_trans_ptr.p->m_arena, t_ptr)) {
       new (t_ptr.p) T();
       setOpRec<T>(op_ptr, t_ptr);
       return true;
@@ -1637,7 +1648,7 @@ private:
   inline void
   releaseOpRec(SchemaOpPtr op_ptr) {
     OpRecPtr& oprec_ptr = op_ptr.p->m_oprec_ptr;
-    ArrayPool<T>& pool = T::getPool(this);
+    RecordPool<T,ArenaPool>& pool = T::getPool(this);
     Ptr<T> t_ptr;
     getOpRec<T>(op_ptr, t_ptr);
     pool.release(t_ptr);
@@ -1646,18 +1657,18 @@ private:
 
   // seize / find / release, atomic on op rec + data rec
 
-  bool seizeSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info);
+  bool seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Uint32 op_key, const OpInfo& info, bool linked=false);
 
   template <class T>
   inline bool
-  seizeSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key) {
-    return seizeSchemaOp(op_ptr, op_key, T::g_opInfo);
+  seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Uint32 op_key, bool linked) {
+    return seizeSchemaOp(trans_ptr, op_ptr, op_key, T::g_opInfo, linked);
   }
 
   template <class T>
   inline bool
-  seizeSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
-    if (seizeSchemaOp<T>(op_ptr, op_key)) {
+  seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, Uint32 op_key) {
+    if (seizeSchemaOp<T>(trans_ptr, op_ptr, op_key)) {
       getOpRec<T>(op_ptr, t_ptr);
       return true;
     }
@@ -1666,14 +1677,14 @@ private:
 
   template <class T>
   inline bool
-  seizeSchemaOp(SchemaOpPtr& op_ptr) {
+  seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, bool linked) {
     /*
       Store node id in high 8 bits to make op_key globally unique
      */
     Uint32 op_key = 
       (getOwnNodeId() << 24) +
       ((c_opRecordSequence + 1) & 0x00FFFFFF);
-    if (seizeSchemaOp<T>(op_ptr, op_key)) {
+    if (seizeSchemaOp<T>(trans_ptr, op_ptr, op_key, linked)) {
       c_opRecordSequence++;
       return true;
     }
@@ -1682,14 +1693,28 @@ private:
 
   template <class T>
   inline bool
-  seizeSchemaOp(SchemaOpPtr& op_ptr, Ptr<T>& t_ptr) {
-    if (seizeSchemaOp<T>(op_ptr)) {
+  seizeSchemaOp(SchemaTransPtr trans_ptr, SchemaOpPtr& op_ptr, Ptr<T>& t_ptr, bool linked=false) {
+    if (seizeSchemaOp<T>(trans_ptr, op_ptr, linked)) {
       getOpRec<T>(op_ptr, t_ptr);
       return true;
     }
     return false;
   }
 
+  template <class T>
+  inline bool
+  seizeLinkedSchemaOp(SchemaOpPtr op_ptr, SchemaOpPtr& oplnk_ptr, Ptr<T>& t_ptr) {
+    ndbrequire(op_ptr.p->m_oplnk_ptr.isNull());
+    if (seizeSchemaOp<T>(op_ptr.p->m_trans_ptr, oplnk_ptr, true)) {
+      op_ptr.p->m_oplnk_ptr = oplnk_ptr;
+      oplnk_ptr.p->m_opbck_ptr = op_ptr;
+      getOpRec<T>(oplnk_ptr, t_ptr);
+      return true;
+    }
+    oplnk_ptr.setNull();
+    return false;
+  }
+
   bool findSchemaOp(SchemaOpPtr& op_ptr, Uint32 op_key);
 
   template <class T>
@@ -1711,7 +1736,7 @@ private:
   void releaseOpSection(SchemaOpPtr, Uint32 ss_no);
 
   // add operation to transaction OpList
-  void addSchemaOp(SchemaTransPtr, SchemaOpPtr&);
+  void addSchemaOp(SchemaOpPtr);
 
   void updateSchemaOpStep(SchemaTransPtr, SchemaOpPtr);
 
@@ -1848,8 +1873,9 @@ private:
     NdbNodeBitmask m_ref_nodes;  // Nodes replying REF to req
     SafeCounterHandle m_counter; // Outstanding REQ's
 
+    ArenaHead m_arena;
     Uint32 m_curr_op_ptr_i;
-    DLFifoList<SchemaOp>::Head m_op_list;
+    SchemaOp_head m_op_list;
 
     // Master takeover
     enum TakeoverRecoveryState
@@ -1893,7 +1919,7 @@ private:
     bool m_wait_gcp_on_commit;
 
     // magic is on when record is seized
-    enum { DICT_MAGIC = 0xd1c70002 };
+    enum { DICT_MAGIC = ~RT_DBDICT_SCHEMA_TRANSACTION };
     Uint32 m_magic;
 
     SchemaTrans() {
@@ -1909,7 +1935,7 @@ private:
       bzero(&m_lockReq, sizeof(m_lockReq));
       m_callback.m_callbackFunction = 0;
       m_callback.m_callbackData = 0;
-      m_magic = 0;
+      m_magic = DICT_MAGIC;
       m_obj_id = RNIL;
       m_flush_prepare = false;
       m_flush_commit = false;
@@ -1932,9 +1958,10 @@ private:
   Uint32 check_write_obj(Uint32 objId, Uint32 transId = 0);
   Uint32 check_write_obj(Uint32, Uint32, SchemaFile::EntryState, ErrorInfo&);
 
-  ArrayPool<SchemaTrans> c_schemaTransPool;
-  DLHashTable<SchemaTrans> c_schemaTransHash;
-  DLFifoList<SchemaTrans> c_schemaTransList;
+  typedef RecordPool<SchemaTrans,ArenaPool> SchemaTrans_pool;
+  SchemaTrans_pool c_schemaTransPool;
+  DLHashTable<SchemaTrans,SchemaTrans,SchemaTrans_pool> c_schemaTransHash;
+  DLFifoList<SchemaTrans,SchemaTrans,SchemaTrans_pool> c_schemaTransList;
   Uint32 c_schemaTransCount;
 
   bool seizeSchemaTrans(SchemaTransPtr&, Uint32 trans_key);
@@ -2075,7 +2102,7 @@ private:
       return;
     }
 
-    if (!seizeSchemaOp(op_ptr, t_ptr)) {
+    if (!seizeSchemaOp(trans_ptr, op_ptr, t_ptr)) {
       jam();
       setError(error, SchemaTransImplRef::TooManySchemaOps, __LINE__);
       return;
@@ -2086,9 +2113,6 @@ private:
     DictSignal::setRequestExtra(op_ptr.p->m_requestInfo, requestExtra);
     DictSignal::addRequestFlags(op_ptr.p->m_requestInfo, requestInfo);
 
-    // add op and global flags from trans level
-    addSchemaOp(trans_ptr, op_ptr);
-
     // impl_req was passed via reference
     impl_req = &t_ptr.p->m_request;
 
@@ -2227,10 +2251,13 @@ private:
 
   // MODULE: CreateTable
 
+  struct CreateTableRec;
+  typedef RecordPool<CreateTableRec,ArenaPool> CreateTableRec_pool;
+
   struct CreateTableRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateTableRec>&
+    static CreateTableRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createTableRecPool;
     }
@@ -2270,7 +2297,7 @@ private:
   };
 
   typedef Ptr<CreateTableRec> CreateTableRecPtr;
-  ArrayPool<CreateTableRec> c_createTableRecPool;
+  CreateTableRec_pool c_createTableRecPool;
 
   // OpInfo
   bool createTable_seize(SchemaOpPtr);
@@ -2303,10 +2330,13 @@ private:
 
   // MODULE: DropTable
 
+  struct DropTableRec;
+  typedef RecordPool<DropTableRec,ArenaPool> DropTableRec_pool;
+
   struct DropTableRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropTableRec>&
+    static DropTableRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropTableRecPool;
     }
@@ -2333,7 +2363,7 @@ private:
   };
 
   typedef Ptr<DropTableRec> DropTableRecPtr;
-  ArrayPool<DropTableRec> c_dropTableRecPool;
+  DropTableRec_pool c_dropTableRecPool;
 
   // OpInfo
   bool dropTable_seize(SchemaOpPtr);
@@ -2366,10 +2396,13 @@ private:
 
   // MODULE: AlterTable
 
+  struct AlterTableRec;
+  typedef RecordPool<AlterTableRec,ArenaPool> AlterTableRec_pool;
+
   struct AlterTableRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::AlterTableRec>&
+    static AlterTableRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_alterTableRecPool;
     }
@@ -2377,7 +2410,7 @@ private:
     AlterTabReq m_request;
 
     // added attributes
-    Uint32 m_newAttrData[2 * MAX_ATTRIBUTES_IN_TABLE];
+    OpSection m_newAttrData;
 
     // wl3600_todo check mutex name and number later
     MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
@@ -2413,7 +2446,6 @@ private:
     AlterTableRec() :
       OpRec(g_opInfo, (Uint32*)&m_request) {
       memset(&m_request, 0, sizeof(m_request));
-      memset(&m_newAttrData, 0, sizeof(m_newAttrData));
       m_tablePtr.setNull();
       m_newTablePtr.setNull();
       m_dihAddFragPtr = RNIL;
@@ -2437,7 +2469,7 @@ private:
   };
 
   typedef Ptr<AlterTableRec> AlterTableRecPtr;
-  ArrayPool<AlterTableRec> c_alterTableRecPool;
+  AlterTableRec_pool c_alterTableRecPool;
 
   // OpInfo
   bool alterTable_seize(SchemaOpPtr);
@@ -2494,6 +2526,9 @@ private:
     Uint32 attr_ptr_i;
   } AttributeMap[MAX_ATTRIBUTES_IN_INDEX];
 
+  struct CreateIndexRec;
+  typedef RecordPool<CreateIndexRec,ArenaPool> CreateIndexRec_pool;
+
   struct CreateIndexRec : public OpRec {
     CreateIndxImplReq m_request;
     char m_indexName[MAX_TAB_NAME_SIZE];
@@ -2507,7 +2542,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateIndexRec>&
+    static CreateIndexRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createIndexRecPool;
     }
@@ -2535,7 +2570,7 @@ private:
   };
 
   typedef Ptr<CreateIndexRec> CreateIndexRecPtr;
-  ArrayPool<CreateIndexRec> c_createIndexRecPool;
+  CreateIndexRec_pool c_createIndexRecPool;
 
   // OpInfo
   bool createIndex_seize(SchemaOpPtr);
@@ -2561,13 +2596,16 @@ private:
 
   // MODULE: DropIndex
 
+  struct DropIndexRec;
+  typedef RecordPool<DropIndexRec,ArenaPool> DropIndexRec_pool;
+
   struct DropIndexRec : public OpRec {
     DropIndxImplReq m_request;
 
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropIndexRec>&
+    static DropIndexRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropIndexRecPool;
     }
@@ -2588,7 +2626,7 @@ private:
   };
 
   typedef Ptr<DropIndexRec> DropIndexRecPtr;
-  ArrayPool<DropIndexRec> c_dropIndexRecPool;
+  DropIndexRec_pool c_dropIndexRecPool;
 
   // OpInfo
   bool dropIndex_seize(SchemaOpPtr);
@@ -2624,6 +2662,9 @@ private:
   static const TriggerTmpl g_buildIndexConstraintTmpl[1];
   static const TriggerTmpl g_reorgTriggerTmpl[1];
 
+  struct AlterIndexRec;
+  typedef RecordPool<AlterIndexRec,ArenaPool> AlterIndexRec_pool;
+
   struct AlterIndexRec : public OpRec {
     AlterIndxImplReq m_request;
     IndexAttributeList m_attrList;
@@ -2632,7 +2673,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::AlterIndexRec>&
+    static AlterIndexRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_alterIndexRecPool;
     }
@@ -2670,7 +2711,7 @@ private:
   };
 
   typedef Ptr<AlterIndexRec> AlterIndexRecPtr;
-  ArrayPool<AlterIndexRec> c_alterIndexRecPool;
+  AlterIndexRec_pool c_alterIndexRecPool;
 
   // OpInfo
   bool alterIndex_seize(SchemaOpPtr);
@@ -2719,10 +2760,13 @@ private:
   // this prepends 1 column used for FRAGMENT in hash index table key
   typedef Id_array<1 + MAX_ATTRIBUTES_IN_INDEX> FragAttributeList;
 
+  struct BuildIndexRec;
+  typedef RecordPool<BuildIndexRec,ArenaPool> BuildIndexRec_pool;
+
   struct BuildIndexRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::BuildIndexRec>&
+    static BuildIndexRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_buildIndexRecPool;
     }
@@ -2755,7 +2799,7 @@ private:
   };
 
   typedef Ptr<BuildIndexRec> BuildIndexRecPtr;
-  ArrayPool<BuildIndexRec> c_buildIndexRecPool;
+  BuildIndexRec_pool c_buildIndexRecPool;
 
   // OpInfo
   bool buildIndex_seize(SchemaOpPtr);
@@ -2795,10 +2839,13 @@ private:
 
   // MODULE: IndexStat
 
+  struct IndexStatRec;
+  typedef RecordPool<IndexStatRec,ArenaPool> IndexStatRec_pool;
+
   struct IndexStatRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::IndexStatRec>&
+    static IndexStatRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_indexStatRecPool;
     }
@@ -2819,7 +2866,7 @@ private:
   };
 
   typedef Ptr<IndexStatRec> IndexStatRecPtr;
-  ArrayPool<IndexStatRec> c_indexStatRecPool;
+  IndexStatRec_pool c_indexStatRecPool;
 
   Uint32 c_indexStatAutoCreate;
   Uint32 c_indexStatAutoUpdate;
@@ -2894,10 +2941,13 @@ private:
   RSS_AP_SNAPSHOT(c_hash_map_pool);
   RSS_AP_SNAPSHOT(g_hash_map);
 
+  struct CreateHashMapRec;
+  typedef RecordPool<CreateHashMapRec,ArenaPool> CreateHashMapRec_pool;
+
   struct CreateHashMapRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateHashMapRec>&
+    static CreateHashMapRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createHashMapRecPool;
     }
@@ -2911,7 +2961,7 @@ private:
   };
 
   typedef Ptr<CreateHashMapRec> CreateHashMapRecPtr;
-  ArrayPool<CreateHashMapRec> c_createHashMapRecPool;
+  CreateHashMapRec_pool c_createHashMapRecPool;
   void execCREATE_HASH_MAP_REQ(Signal* signal);
 
   // OpInfo
@@ -2935,10 +2985,13 @@ private:
 
   // MODULE: CopyData
 
+  struct CopyDataRec;
+  typedef RecordPool<CopyDataRec,ArenaPool> CopyDataRec_pool;
+
   struct CopyDataRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CopyDataRec>&
+    static CopyDataRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_copyDataRecPool;
     }
@@ -2952,7 +3005,7 @@ private:
   };
 
   typedef Ptr<CopyDataRec> CopyDataRecPtr;
-  ArrayPool<CopyDataRec> c_copyDataRecPool;
+  CopyDataRec_pool c_copyDataRecPool;
   void execCOPY_DATA_REQ(Signal* signal);
   void execCOPY_DATA_REF(Signal* signal);
   void execCOPY_DATA_CONF(Signal* signal);
@@ -3097,10 +3150,14 @@ private:
   typedef Ptr<OpDropEvent> OpDropEventPtr;
 
   // MODULE: CreateTrigger
+
+  struct CreateTriggerRec;
+  typedef RecordPool<CreateTriggerRec,ArenaPool> CreateTriggerRec_pool;
+
   struct CreateTriggerRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateTriggerRec>&
+    static CreateTriggerRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createTriggerRecPool;
     }
@@ -3127,7 +3184,7 @@ private:
   };
 
   typedef Ptr<CreateTriggerRec> CreateTriggerRecPtr;
-  ArrayPool<CreateTriggerRec> c_createTriggerRecPool;
+  CreateTriggerRec_pool c_createTriggerRecPool;
 
   // OpInfo
   bool createTrigger_seize(SchemaOpPtr);
@@ -3158,10 +3215,13 @@ private:
 
   // MODULE: DropTrigger
 
+  struct DropTriggerRec;
+  typedef RecordPool<DropTriggerRec,ArenaPool> DropTriggerRec_pool;
+
   struct DropTriggerRec : public OpRec {
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropTriggerRec>&
+    static DropTriggerRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropTriggerRecPool;
     }
@@ -3186,7 +3246,7 @@ private:
   };
 
   typedef Ptr<DropTriggerRec> DropTriggerRecPtr;
-  ArrayPool<DropTriggerRec> c_dropTriggerRecPool;
+  DropTriggerRec_pool c_dropTriggerRecPool;
 
   // OpInfo
   bool dropTrigger_seize(SchemaOpPtr);
@@ -3214,6 +3274,9 @@ private:
 
   // MODULE: CreateFilegroup
 
+  struct CreateFilegroupRec;
+  typedef RecordPool<CreateFilegroupRec,ArenaPool> CreateFilegroupRec_pool;
+
   struct CreateFilegroupRec : public OpRec {
     bool m_parsed, m_prepared;
     CreateFilegroupImplReq m_request;
@@ -3222,7 +3285,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateFilegroupRec>&
+    static CreateFilegroupRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createFilegroupRecPool;
     }
@@ -3236,7 +3299,7 @@ private:
   };
 
   typedef Ptr<CreateFilegroupRec> CreateFilegroupRecPtr;
-  ArrayPool<CreateFilegroupRec> c_createFilegroupRecPool;
+  CreateFilegroupRec_pool c_createFilegroupRecPool;
 
   // OpInfo
   bool createFilegroup_seize(SchemaOpPtr);
@@ -3259,6 +3322,9 @@ private:
 
   // MODULE: CreateFile
 
+  struct CreateFileRec;
+  typedef RecordPool<CreateFileRec,ArenaPool> CreateFileRec_pool;
+
   struct CreateFileRec : public OpRec {
     bool m_parsed, m_prepared;
     CreateFileImplReq m_request;
@@ -3267,7 +3333,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateFileRec>&
+    static CreateFileRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createFileRecPool;
     }
@@ -3281,7 +3347,7 @@ private:
   };
 
   typedef Ptr<CreateFileRec> CreateFileRecPtr;
-  ArrayPool<CreateFileRec> c_createFileRecPool;
+  CreateFileRec_pool c_createFileRecPool;
 
   // OpInfo
   bool createFile_seize(SchemaOpPtr);
@@ -3304,6 +3370,9 @@ private:
 
   // MODULE: DropFilegroup
 
+  struct DropFilegroupRec;
+  typedef RecordPool<DropFilegroupRec,ArenaPool> DropFilegroupRec_pool;
+
   struct DropFilegroupRec : public OpRec {
     bool m_parsed, m_prepared;
     DropFilegroupImplReq m_request;
@@ -3311,7 +3380,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropFilegroupRec>&
+    static DropFilegroupRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropFilegroupRecPool;
     }
@@ -3324,7 +3393,7 @@ private:
   };
 
   typedef Ptr<DropFilegroupRec> DropFilegroupRecPtr;
-  ArrayPool<DropFilegroupRec> c_dropFilegroupRecPool;
+  DropFilegroupRec_pool c_dropFilegroupRecPool;
 
   // OpInfo
   bool dropFilegroup_seize(SchemaOpPtr);
@@ -3346,6 +3415,9 @@ private:
 
   // MODULE: DropFile
 
+  struct DropFileRec;
+  typedef RecordPool<DropFileRec,ArenaPool> DropFileRec_pool;
+
   struct DropFileRec : public OpRec {
     bool m_parsed, m_prepared;
     DropFileImplReq m_request;
@@ -3353,7 +3425,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropFileRec>&
+    static DropFileRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropFileRecPool;
     }
@@ -3366,7 +3438,7 @@ private:
   };
 
   typedef Ptr<DropFileRec> DropFileRecPtr;
-  ArrayPool<DropFileRec> c_dropFileRecPool;
+  DropFileRec_pool c_dropFileRecPool;
 
   // OpInfo
   bool dropFile_seize(SchemaOpPtr);
@@ -3388,6 +3460,9 @@ private:
 
   // MODULE: CreateNodegroup
 
+  struct CreateNodegroupRec;
+  typedef RecordPool<CreateNodegroupRec,ArenaPool> CreateNodegroupRec_pool;
+
   struct CreateNodegroupRec : public OpRec {
     bool m_map_created;
     CreateNodegroupImplReq m_request;
@@ -3395,7 +3470,7 @@ private:
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::CreateNodegroupRec>&
+    static CreateNodegroupRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_createNodegroupRecPool;
     }
@@ -3423,7 +3498,7 @@ private:
   };
 
   typedef Ptr<CreateNodegroupRec> CreateNodegroupRecPtr;
-  ArrayPool<CreateNodegroupRec> c_createNodegroupRecPool;
+  CreateNodegroupRec_pool c_createNodegroupRecPool;
 
   // OpInfo
   void execCREATE_NODEGROUP_REQ(Signal*);
@@ -3456,13 +3531,16 @@ private:
 
   // MODULE: DropNodegroup
 
+  struct DropNodegroupRec;
+  typedef RecordPool<DropNodegroupRec,ArenaPool> DropNodegroupRec_pool;
+
   struct DropNodegroupRec : public OpRec {
     DropNodegroupImplReq m_request;
 
     // reflection
     static const OpInfo g_opInfo;
 
-    static ArrayPool<Dbdict::DropNodegroupRec>&
+    static DropNodegroupRec_pool&
     getPool(Dbdict* dict) {
       return dict->c_dropNodegroupRecPool;
     }
@@ -3489,7 +3567,7 @@ private:
   };
 
   typedef Ptr<DropNodegroupRec> DropNodegroupRecPtr;
-  ArrayPool<DropNodegroupRec> c_dropNodegroupRecPool;
+  DropNodegroupRec_pool c_dropNodegroupRecPool;
 
   // OpInfo
   void execDROP_NODEGROUP_REQ(Signal*);
@@ -3637,7 +3715,7 @@ private:
   
   void writeTableFile(Signal* signal, Uint32 tableId, 
 		      SegmentedSectionPtr tabInfo, Callback*);
-  void writeTableFile(Signal* signal, Uint32 tableId,
+  void writeTableFile(Signal* signal, SchemaOpPtr op_ptr, Uint32 tableId,
 		      OpSection opSection, Callback*);
   void startWriteTableFile(Signal* signal, Uint32 tableId);
   void openTableFile(Signal* signal, 
@@ -3930,6 +4008,8 @@ public:
 
 protected:
   virtual bool getParam(const char * param, Uint32 * retVal);
+private:
+  ArenaAllocator c_arenaAllocator;
 };
 
 inline bool

=== modified file 'storage/ndb/src/kernel/blocks/dbinfo/Dbinfo.cpp'
--- a/storage/ndb/src/kernel/blocks/dbinfo/Dbinfo.cpp	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/kernel/blocks/dbinfo/Dbinfo.cpp	2011-10-07 17:15:53 +0000
@@ -29,7 +29,7 @@
 
 Uint32 dbinfo_blocks[] = { DBACC, DBTUP, BACKUP, DBTC, SUMA, DBUTIL,
                            TRIX, DBTUX, DBDICT, CMVMI, DBLQH, LGMAN,
-                           PGMAN, DBSPJ, 0};
+                           PGMAN, DBSPJ, THRMAN, 0};
 
 Dbinfo::Dbinfo(Block_context& ctx) :
   SimulatedBlock(DBINFO, ctx)

=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhProxy.cpp	2011-10-07 08:07:21 +0000
@@ -690,7 +690,7 @@ DblqhProxy::completeLCP_2(Signal* signal
    *   that will checkpoint extent-pages
    */
   // NOTE: ugly to use MaxLqhWorkers directly
-  Uint32 instance = MaxLqhWorkers + 1;
+  Uint32 instance = c_workers + 1;
   sendSignal(numberToRef(PGMAN, instance, getOwnNodeId()),
              GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength, JBB);
 }

=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjProxy.hpp	2011-10-07 08:07:21 +0000
@@ -24,7 +24,6 @@ public:
   virtual ~DbspjProxy();
   BLOCK_DEFINES(DbspjProxy);
 
-  virtual void loadWorkers() { tc_loadWorkers(); }
 protected:
   virtual SimulatedBlock* newWorker(Uint32 instanceNo);
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2011-07-04 16:30:34 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2011-10-07 17:15:53 +0000
@@ -157,9 +157,6 @@ public:
     CS_DISCONNECTED = 1,
     CS_STARTED = 2,
     CS_RECEIVING = 3,
-    CS_PREPARED = 4,
-    CS_START_PREPARING = 5,
-    CS_REC_PREPARING = 6,
     CS_RESTART = 7,
     CS_ABORTING = 8,
     CS_COMPLETING = 9,
@@ -1989,6 +1986,10 @@ private:
 
   bool validate_filter(Signal*);
   bool match_and_print(Signal*, ApiConnectRecordPtr);
+  void ndbinfo_write_trans(Signal* signal,
+                           DbinfoScanReq * req,
+                           Ndbinfo::Ratelimit * rl,
+                           ApiConnectRecordPtr transPtr);
 
 #ifdef ERROR_INSERT
   bool testFragmentDrop(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-09-15 15:14:16 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-10-07 17:15:53 +0000
@@ -106,9 +106,6 @@ operator<<(NdbOut& out, Dbtc::Connection
   case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break;
   case Dbtc::CS_STARTED: out << "CS_STARTED"; break;
   case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break;
-  case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break;
-  case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break;
-  case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break;
   case Dbtc::CS_RESTART: out << "CS_RESTART"; break;
   case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break;
   case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break;
@@ -1055,17 +1052,6 @@ Dbtc::handleFailedApiNode(Signal* signal
         abort010Lab(signal);
         TloopCount = 256;
         break;
-      case CS_PREPARED:
-        jam();
-      case CS_REC_PREPARING:
-        jam();
-      case CS_START_PREPARING:
-        jam();
-        /*********************************************************************/
-        // Not implemented yet.
-        /*********************************************************************/
-        systemErrorLab(signal, __LINE__);
-        break;
       case CS_RESTART:
         jam();
       case CS_COMPLETING:
@@ -6582,16 +6568,6 @@ void Dbtc::execTC_COMMITREQ(Signal* sign
       /***********************************************************************/
       errorCode = ZSCANINPROGRESS;
       break;
-    case CS_PREPARED:
-      jam();
-      return;
-    case CS_START_PREPARING:
-      jam();
-      return;
-    case CS_REC_PREPARING:
-      jam();
-      return;
-      break;
     default:
       warningHandlerLab(signal, __LINE__);
       return;
@@ -6709,12 +6685,6 @@ void Dbtc::execTCROLLBACKREQ(Signal* sig
     jam();
     apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
     break;
-  case CS_START_PREPARING:
-    jam();
-  case CS_PREPARED:
-    jam();
-  case CS_REC_PREPARING:
-    jam();
   default:
     goto TC_ROLL_system_error;
     break;
@@ -7739,12 +7709,6 @@ void Dbtc::timeOutFoundLab(Signal* signa
     jam();
   case CS_FAIL_COMMITTED:
     jam();
-  case CS_REC_PREPARING:
-    jam();
-  case CS_START_PREPARING:
-    jam();
-  case CS_PREPARED:
-    jam();
   case CS_RESTART:
     jam();
   case CS_FAIL_ABORTED:
@@ -13324,14 +13288,125 @@ void Dbtc::execDBINFO_SCANREQ(Signal *si
 
     break;
   }
+  case Ndbinfo::TRANSACTIONS_TABLEID:{
+    ApiConnectRecordPtr ptr;
+    ptr.i = cursor->data[0];
+    const Uint32 maxloop = 256;
+    for (Uint32 i = 0; i < maxloop; i++)
+    {
+      ptrCheckGuard(ptr, capiConnectFilesize, apiConnectRecord);
+      ndbinfo_write_trans(signal, &req, &rl, ptr);
 
+      ptr.i ++;
+      if (ptr.i == capiConnectFilesize)
+      {
+        goto done;
+      }
+      else if (rl.need_break(req))
+      {
+        break;
+      }
+    }
+    ndbinfo_send_scan_break(signal, req, rl, ptr.i);
+    return;
+  }
   default:
     break;
   }
 
+done:
   ndbinfo_send_scan_conf(signal, req, rl);
 }
 
+void
+Dbtc::ndbinfo_write_trans(Signal* signal,
+                          DbinfoScanReq * req,
+                          Ndbinfo::Ratelimit * rl,
+                          ApiConnectRecordPtr transPtr)
+{
+  Uint32 conState = transPtr.p->apiConnectstate;
+
+  if (conState == CS_ABORTING && transPtr.p->abortState == AS_IDLE)
+  {
+    /**
+     * These is for all practical purposes equal
+     */
+    conState = CS_CONNECTED;
+  }
+
+  if (conState == CS_CONNECTED ||
+      conState == CS_DISCONNECTED ||
+      conState == CS_RESTART)
+  {
+    return;
+  }
+
+  char transid[64];
+  BaseString::snprintf(transid, sizeof(transid),
+                       "%.8x.%.8x",
+                       transPtr.p->transid[0],
+                       transPtr.p->transid[1]);
+
+  Ndbinfo::Row row(signal, *req);
+  row.write_uint32(getOwnNodeId());
+  row.write_uint32(instance());   // block instance
+  row.write_uint32(transPtr.i);
+  row.write_uint32(transPtr.p->ndbapiBlockref);
+  row.write_string(transid);
+  row.write_uint32(conState);
+  row.write_uint32(transPtr.p->m_flags);
+  row.write_uint32(transPtr.p->lqhkeyreqrec);
+  Uint32 outstanding = 0;
+  switch((ConnectionState)conState) {
+  case CS_CONNECTED:
+  case CS_DISCONNECTED:
+    break;
+  case CS_STARTED:
+  case CS_RECEIVING:
+  case CS_REC_COMMITTING:
+  case CS_START_COMMITTING:
+  case CS_SEND_FIRE_TRIG_REQ:
+  case CS_WAIT_FIRE_TRIG_REQ:
+    outstanding = transPtr.p->lqhkeyreqrec - transPtr.p->lqhkeyconfrec;
+    break;
+  case CS_COMMITTING:
+  case CS_COMPLETING:
+  case CS_COMMIT_SENT:
+  case CS_COMPLETE_SENT:
+  case CS_ABORTING:
+    outstanding = transPtr.p->counter;
+    break;
+  case CS_PREPARE_TO_COMMIT:
+    break;
+  case CS_START_SCAN:
+    // TODO
+    break;
+  case CS_WAIT_ABORT_CONF:
+  case CS_WAIT_COMMIT_CONF:
+  case CS_WAIT_COMPLETE_CONF:
+    // not easily computed :-(
+    break;
+  case CS_FAIL_PREPARED:
+  case CS_FAIL_ABORTED:
+    // we're assembling a state...
+    break;
+  case CS_FAIL_COMMITTING:
+  case CS_FAIL_COMMITTED:
+  case CS_FAIL_ABORTING:
+  case CS_FAIL_COMPLETED:
+    // not easily computed :_(
+    break;
+  case CS_RESTART:
+    break;
+  }
+
+  row.write_uint32(outstanding);
+
+  Uint32 apiTimer = getApiConTimer(transPtr.i);
+  row.write_uint32(apiTimer ? (ctcTimer - apiTimer) / 100 : 0);
+  ndbinfo_send_row(signal, *req, row, *rl);
+}
+
 bool
 Dbtc::validate_filter(Signal* signal)
 {
@@ -13464,9 +13539,6 @@ Dbtc::match_and_print(Signal* signal, Ap
   case CS_FAIL_PREPARED:
   case CS_FAIL_COMMITTING:
   case CS_FAIL_COMMITTED:
-  case CS_REC_PREPARING:
-  case CS_START_PREPARING:
-  case CS_PREPARED:
   case CS_RESTART:
   case CS_FAIL_ABORTED:
   case CS_DISCONNECTED:

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcProxy.hpp	2011-10-07 08:07:21 +0000
@@ -37,7 +37,6 @@ public:
   virtual ~DbtcProxy();
   BLOCK_DEFINES(DbtcProxy);
 
-  virtual void loadWorkers() { tc_loadWorkers(); }
 protected:
   virtual SimulatedBlock* newWorker(Uint32 instanceNo);
 

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-09-01 18:42:31 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2011-10-07 16:12:13 +0000
@@ -579,6 +579,9 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
   // for md5 of key (could maybe reuse existing temp buffer)
   Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
 
+  // Crash the node when a tuple got corrupted
+  bool c_crashOnCorruptedTuple;
+
   struct Page_request 
   {
     Page_request() {}
@@ -2894,6 +2897,7 @@ private:
   
   Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
   void setChecksum(Tuple_header*, Tablerec* regTabPtr);
+  int corruptedTupleDetected(KeyReqStruct*);
 
   void complexTrigger(Signal* signal,
                       KeyReqStruct *req_struct,

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-05-25 13:19:02 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-10-07 16:12:13 +0000
@@ -166,6 +166,20 @@ Dbtup::calculateChecksum(Tuple_header* t
   return checksum;
 }
 
+int
+Dbtup::corruptedTupleDetected(KeyReqStruct *req_struct)
+{
+  ndbout_c("Tuple corruption detected."); 
+  if (c_crashOnCorruptedTuple)
+  {
+    ndbout_c(" Exiting."); 
+    ndbrequire(false);
+  }
+  terrorCode= ZTUPLE_CORRUPTED_ERROR;
+  tupkeyErrorLab(req_struct);
+  return -1;
+}
+
 /* ----------------------------------------------------------------- */
 /* -----------       INSERT_ACTIVE_OP_LIST            -------------- */
 /* ----------------------------------------------------------------- */
@@ -1014,10 +1028,7 @@ int Dbtup::handleReadReq(Signal* signal,
   if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
       (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0)) {
     jam();
-    ndbout_c("here2");
-    terrorCode= ZTUPLE_CORRUPTED_ERROR;
-    tupkeyErrorLab(req_struct);
-    return -1;
+    return corruptedTupleDetected(req_struct);
   }
 
   const Uint32 node = refToNode(sendBref);
@@ -1139,8 +1150,8 @@ int Dbtup::handleUpdateReq(Signal* signa
   if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
       (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0)) 
   {
-    terrorCode= ZTUPLE_CORRUPTED_ERROR;
-    goto error;
+    jam();
+    return corruptedTupleDetected(req_struct);
   }
 
   req_struct->m_tuple_ptr= dst;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2011-05-17 23:29:55 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp	2011-10-07 16:12:13 +0000
@@ -497,6 +497,14 @@ void Dbtup::execREAD_CONFIG_REQ(Signal*
   }
   
   initialiseRecordsLab(signal, 0, ref, senderData);
+
+  {
+    Uint32 val = 0;
+    ndb_mgm_get_int_parameter(p, CFG_DB_CRASH_ON_CORRUPTED_TUPLE,
+                              &val);
+    c_crashOnCorruptedTuple = val ? true : false;
+  }
+
 }//Dbtup::execSIZEALT_REP()
 
 void Dbtup::initRecords() 

=== modified file 'storage/ndb/src/kernel/blocks/record_types.hpp'
--- a/storage/ndb/src/kernel/blocks/record_types.hpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/record_types.hpp	2011-10-07 13:15:08 +0000
@@ -67,10 +67,15 @@
 #define RG_QUERY_MEMORY         8
 
 /**
+ * Schema transaction memory
+ */
+#define RG_SCHEMA_TRANS_MEMORY  9
+
+/**
  * 
  */
 #define RG_RESERVED             0
-#define RG_COUNT                9
+#define RG_COUNT                10
 
 /**
  * Record types
@@ -100,4 +105,27 @@
 #define RT_SPJ_DATABUFFER          MAKE_TID( 4, RG_QUERY_MEMORY)
 #define RT_SPJ_SCANFRAG            MAKE_TID( 5, RG_QUERY_MEMORY)
 
+#define RT_DBDICT_SCHEMA_TRANS_ARENA MAKE_TID( 1, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_SCHEMA_TRANSACTION MAKE_TID( 2, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_SCHEMA_OPERATION   MAKE_TID( 3, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_TABLE       MAKE_TID( 4, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_TABLE         MAKE_TID( 5, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_ALTER_TABLE        MAKE_TID( 6, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_TRIGGER     MAKE_TID( 7, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_TRIGGER       MAKE_TID( 8, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_INDEX       MAKE_TID( 9, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_INDEX         MAKE_TID( 10, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_ALTER_INDEX        MAKE_TID( 11, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_BUILD_INDEX        MAKE_TID( 12, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_INDEX_STAT         MAKE_TID( 13, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_FILEGROUP   MAKE_TID( 14, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_FILE        MAKE_TID( 15, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_FILEGROUP     MAKE_TID( 16, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_FILE          MAKE_TID( 17, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_HASH_MAP    MAKE_TID( 18, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_COPY_DATA          MAKE_TID( 19, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_CREATE_NODEGROUP   MAKE_TID( 20, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_DROP_NODEGROUP     MAKE_TID( 21, RG_SCHEMA_TRANS_MEMORY)
+#define RT_DBDICT_OP_SECTION_BUFFER  MAKE_TID( 22, RG_SCHEMA_TRANS_MEMORY)
+
 #endif

=== added file 'storage/ndb/src/kernel/blocks/thrman.cpp'
--- a/storage/ndb/src/kernel/blocks/thrman.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/blocks/thrman.cpp	2011-10-07 09:28:24 +0000
@@ -0,0 +1,129 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#include "thrman.hpp"
+#include <mt.hpp>
+#include <signaldata/DbinfoScan.hpp>
+#include <NdbGetRUsage.h>
+
+#include <EventLogger.hpp>
+extern EventLogger * g_eventLogger;
+
+Thrman::Thrman(Block_context & ctx, Uint32 instanceno) :
+  SimulatedBlock(THRMAN, ctx, instanceno)
+{
+  BLOCK_CONSTRUCTOR(Thrman);
+
+  addRecSignal(GSN_DBINFO_SCANREQ, &Thrman::execDBINFO_SCANREQ);
+}
+
+Thrman::~Thrman()
+{
+}
+
+BLOCK_FUNCTIONS(Thrman)
+
+void
+Thrman::execDBINFO_SCANREQ(Signal* signal)
+{
+  jamEntry();
+
+  DbinfoScanReq req= *(DbinfoScanReq*)signal->theData;
+  const Ndbinfo::ScanCursor* cursor =
+    CAST_CONSTPTR(Ndbinfo::ScanCursor, DbinfoScan::getCursorPtr(&req));
+  Ndbinfo::Ratelimit rl;
+
+  switch(req.tableId) {
+  case Ndbinfo::THREADBLOCKS_TABLEID: {
+    Uint32 arr[NO_OF_BLOCKS];
+    Uint32 len = mt_get_blocklist(this, arr, NDB_ARRAY_SIZE(arr));
+    Uint32 pos = cursor->data[0];
+    for (; ; )
+    {
+      Ndbinfo::Row row(signal, req);
+      row.write_uint32(getOwnNodeId());
+      row.write_uint32(getThreadId());             // thr_no
+      row.write_uint32(blockToMain(arr[pos]));     // block_number
+      row.write_uint32(blockToInstance(arr[pos])); // block_instance
+      ndbinfo_send_row(signal, req, row, rl);
+
+      pos++;
+      if (pos == len)
+      {
+        jam();
+        break;
+      }
+      else if (rl.need_break(req))
+      {
+        jam();
+        ndbinfo_send_scan_break(signal, req, rl, pos);
+        return;
+      }
+    }
+    break;
+  }
+  case Ndbinfo::THREADSTAT_TABLEID:{
+    ndb_thr_stat stat;
+    mt_get_thr_stat(this, &stat);
+    Ndbinfo::Row row(signal, req);
+    row.write_uint32(getOwnNodeId());
+    row.write_uint32(getThreadId());  // thr_no
+    row.write_string(stat.name);
+    row.write_uint64(stat.loop_cnt);
+    row.write_uint64(stat.exec_cnt);
+    row.write_uint64(stat.wait_cnt);
+    row.write_uint64(stat.local_sent_prioa);
+    row.write_uint64(stat.local_sent_priob);
+    row.write_uint64(stat.remote_sent_prioa);
+    row.write_uint64(stat.remote_sent_priob);
+
+    row.write_uint64(stat.os_tid);
+    row.write_uint64(NdbTick_CurrentMillisecond());
+
+    struct ndb_rusage os_rusage;
+    Ndb_GetRUSage(&os_rusage);
+    row.write_uint64(os_rusage.ru_utime);
+    row.write_uint64(os_rusage.ru_stime);
+    row.write_uint64(os_rusage.ru_minflt);
+    row.write_uint64(os_rusage.ru_majflt);
+    row.write_uint64(os_rusage.ru_nvcsw);
+    row.write_uint64(os_rusage.ru_nivcsw);
+    ndbinfo_send_row(signal, req, row, rl);
+    break;
+  }
+  default:
+    break;
+  }
+
+  ndbinfo_send_scan_conf(signal, req, rl);
+}
+
+ThrmanProxy::ThrmanProxy(Block_context & ctx) :
+  LocalProxy(THRMAN, ctx)
+{
+}
+
+ThrmanProxy::~ThrmanProxy()
+{
+}
+
+SimulatedBlock*
+ThrmanProxy::newWorker(Uint32 instanceNo)
+{
+  return new Thrman(m_ctx, instanceNo);
+}
+

=== added file 'storage/ndb/src/kernel/blocks/thrman.hpp'
--- a/storage/ndb/src/kernel/blocks/thrman.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/blocks/thrman.hpp	2011-10-07 08:07:21 +0000
@@ -0,0 +1,48 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#ifndef THRMAN_H
+#define THRMAN_H
+
+#include <SimulatedBlock.hpp>
+#include <LocalProxy.hpp>
+
+class Thrman : public SimulatedBlock
+{
+public:
+  Thrman(Block_context& ctx, Uint32 instanceNumber = 0);
+  virtual ~Thrman();
+  BLOCK_DEFINES(Thrman);
+
+  void execDBINFO_SCANREQ(Signal*);
+protected:
+
+};
+
+class ThrmanProxy : public LocalProxy
+{
+public:
+  ThrmanProxy(Block_context& ctx);
+  virtual ~ThrmanProxy();
+  BLOCK_DEFINES(ThrmanProxy);
+
+protected:
+  virtual SimulatedBlock* newWorker(Uint32 instanceNo);
+
+};
+
+#endif

=== modified file 'storage/ndb/src/kernel/ndbd.cpp'
--- a/storage/ndb/src/kernel/ndbd.cpp	2011-09-23 09:13:22 +0000
+++ b/storage/ndb/src/kernel/ndbd.cpp	2011-10-07 13:15:08 +0000
@@ -239,8 +239,17 @@ init_global_memory_manager(EmulatorData
     ed.m_mem_manager->set_resource_limit(rl);
   }
 
+  Uint32 stpages = 64;
+  {
+    Resource_limit rl;
+    rl.m_min = stpages;
+    rl.m_max = 0;
+    rl.m_resource_id = RG_SCHEMA_TRANS_MEMORY;
+    ed.m_mem_manager->set_resource_limit(rl);
+  }
+
   Uint32 sum = shared_pages + tupmem + filepages + jbpages + sbpages +
-    pgman_pages;
+    pgman_pages + stpages;
 
   if (sum)
   {

=== modified file 'storage/ndb/src/kernel/vm/DLFifoList.hpp'
--- a/storage/ndb/src/kernel/vm/DLFifoList.hpp	2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/DLFifoList.hpp	2011-10-07 11:46:40 +0000
@@ -465,18 +465,18 @@ DLFifoListImpl<P,T,U>::hasPrev(const Ptr
 
 // Specializations
 
-template <typename T, typename U = T>
-class DLFifoList : public DLFifoListImpl<ArrayPool<T>, T, U>
+template <typename T, typename U = T, typename P = ArrayPool<T> >
+class DLFifoList : public DLFifoListImpl<P, T, U>
 {
 public:
-  DLFifoList(ArrayPool<T> & p) : DLFifoListImpl<ArrayPool<T>, T, U>(p) {}
+  DLFifoList(P & p) : DLFifoListImpl<P, T, U>(p) {}
 };
 
-template <typename T, typename U = T>
-class LocalDLFifoList : public LocalDLFifoListImpl<ArrayPool<T>,T,U> {
+template <typename T, typename U = T, typename P = ArrayPool<T> >
+class LocalDLFifoList : public LocalDLFifoListImpl<P,T,U> {
 public:
-  LocalDLFifoList(ArrayPool<T> & p, typename DLFifoList<T,U>::Head & _src)
-    : LocalDLFifoListImpl<ArrayPool<T>,T,U>(p, _src) {}
+  LocalDLFifoList(P & p, typename DLFifoList<T,U,P>::Head & _src)
+    : LocalDLFifoListImpl<P,T,U>(p, _src) {}
 };
 
 #endif

=== modified file 'storage/ndb/src/kernel/vm/DLHashTable.hpp'
--- a/storage/ndb/src/kernel/vm/DLHashTable.hpp	2011-06-30 15:55:35 +0000
+++ b/storage/ndb/src/kernel/vm/DLHashTable.hpp	2011-10-07 11:46:40 +0000
@@ -517,11 +517,11 @@ DLHashTableImpl<P, T, U>::find(Ptr<T> &
 
 // Specializations
 
-template <typename T, typename U = T>
-class DLHashTable : public DLHashTableImpl<ArrayPool<T>, T, U>
+template <typename T, typename U = T, typename P = ArrayPool<T> >
+class DLHashTable : public DLHashTableImpl<P, T, U>
 {
 public:
-  DLHashTable(ArrayPool<T> & p) : DLHashTableImpl<ArrayPool<T>, T, U>(p) {}
+  DLHashTable(P & p) : DLHashTableImpl<P, T, U>(p) {}
 };
 
 #endif

=== modified file 'storage/ndb/src/kernel/vm/DataBuffer2.hpp'
--- a/storage/ndb/src/kernel/vm/DataBuffer2.hpp	2010-10-27 06:54:54 +0000
+++ b/storage/ndb/src/kernel/vm/DataBuffer2.hpp	2011-10-07 11:46:40 +0000
@@ -18,6 +18,8 @@
 #ifndef DATA_BUFFER2_HPP
 #define DATA_BUFFER2_HPP
 
+#include <ErrorReporter.hpp>
+
 /**
  * @class  DataBuffer
  * @brief  Buffer of data words

=== modified file 'storage/ndb/src/kernel/vm/Ndbinfo.hpp'
--- a/storage/ndb/src/kernel/vm/Ndbinfo.hpp	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/kernel/vm/Ndbinfo.hpp	2011-10-07 17:15:53 +0000
@@ -46,7 +46,10 @@ public:
     RESOURCES_TABLEID =          7,
     COUNTERS_TABLEID =           8,
     NODES_TABLEID =              9,
-    DISKPAGEBUFFER_TABLEID =     10
+    DISKPAGEBUFFER_TABLEID =     10,
+    THREADBLOCKS_TABLEID =       11,
+    THREADSTAT_TABLEID =         12,
+    TRANSACTIONS_TABLEID =       13
   };
 
   struct Table {

=== modified file 'storage/ndb/src/kernel/vm/NdbinfoTables.cpp'
--- a/storage/ndb/src/kernel/vm/NdbinfoTables.cpp	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/src/kernel/vm/NdbinfoTables.cpp	2011-10-07 17:15:53 +0000
@@ -169,6 +169,57 @@ DECLARE_NDBINFO_TABLE(DISKPAGEBUFFER, 9)
   }
 };
 
+DECLARE_NDBINFO_TABLE(THREADBLOCKS, 4) =
+{ { "threadblocks", 4, 0, "which blocks are run in which threads" },
+  {
+    {"node_id",                     Ndbinfo::Number, ""},
+    {"thr_no",                      Ndbinfo::Number, ""},
+    {"block_number",                Ndbinfo::Number, ""},
+    {"block_instance",              Ndbinfo::Number, ""},
+  }
+};
+
+DECLARE_NDBINFO_TABLE(THREADSTAT, 18) =
+{ { "threadstat", 18, 0, "threadstat" },
+  {
+    //{"0123456701234567"}
+    {"node_id",             Ndbinfo::Number, ""},
+    {"thr_no",              Ndbinfo::Number, ""},
+    {"thr_nm",              Ndbinfo::String, ""},
+    {"c_loop",              Ndbinfo::Number64,""},
+    {"c_exec",              Ndbinfo::Number64,""},
+    {"c_wait",              Ndbinfo::Number64,""},
+    {"c_l_sent_prioa",      Ndbinfo::Number64,""},
+    {"c_l_sent_priob",      Ndbinfo::Number64,""},
+    {"c_r_sent_prioa",      Ndbinfo::Number64,""},
+    {"c_r_sent_priob",      Ndbinfo::Number64,""},
+    {"os_tid",              Ndbinfo::Number64,""},
+    {"os_now",              Ndbinfo::Number64,""},
+    {"os_ru_utime",         Ndbinfo::Number64,""},
+    {"os_ru_stime",         Ndbinfo::Number64,""},
+    {"os_ru_minflt",        Ndbinfo::Number64,""},
+    {"os_ru_majflt",        Ndbinfo::Number64,""},
+    {"os_ru_nvcsw",         Ndbinfo::Number64,""},
+    {"os_ru_nivcsw",        Ndbinfo::Number64,""}
+  }
+};
+
+DECLARE_NDBINFO_TABLE(TRANSACTIONS, 10) =
+{ { "transactions", 10, 0, "transactions" },
+  {
+    {"node_id",             Ndbinfo::Number, ""},
+    {"block_instance",      Ndbinfo::Number, ""},
+    {"objid",               Ndbinfo::Number, ""},
+    {"apiref",              Ndbinfo::Number, ""},
+    {"transid",             Ndbinfo::String, ""},
+    {"state",               Ndbinfo::Number, ""},
+    {"flags",               Ndbinfo::Number, ""},
+    {"c_ops",               Ndbinfo::Number, "No of operations" },
+    {"outstanding",         Ndbinfo::Number, "Outstanding request" },
+    {"timer",               Ndbinfo::Number, "(in seconds)"},
+  }
+};
+
 #define DBINFOTBL(x) { Ndbinfo::x##_TABLEID, (Ndbinfo::Table*)&ndbinfo_##x }
 
 static
@@ -188,7 +239,10 @@ struct ndbinfo_table_list_entry {
   DBINFOTBL(RESOURCES),
   DBINFOTBL(COUNTERS),
   DBINFOTBL(NODES),
-  DBINFOTBL(DISKPAGEBUFFER)
+  DBINFOTBL(DISKPAGEBUFFER),
+  DBINFOTBL(THREADBLOCKS),
+  DBINFOTBL(THREADSTAT),
+  DBINFOTBL(TRANSACTIONS)
 };
 
 static int no_ndbinfo_tables =

=== modified file 'storage/ndb/src/kernel/vm/Pool.hpp'
--- a/storage/ndb/src/kernel/vm/Pool.hpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/vm/Pool.hpp	2011-10-07 11:46:40 +0000
@@ -33,7 +33,7 @@
  */
 #define RG_BITS 5
 #define RG_MASK ((1 << RG_BITS) - 1)
-#define MAKE_TID(TID,RG) ((TID << RG_BITS) | RG)
+#define MAKE_TID(TID,RG) Uint32((TID << RG_BITS) | RG)
 
 /**
  * Page bits

=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.hpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2011-08-27 06:06:02 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2011-10-07 08:07:21 +0000
@@ -634,7 +634,9 @@ private:
    * In MT LQH main instance is the LQH proxy and the others ("workers")
    * are real LQHs run by multiple threads.
    */
-  enum { MaxInstances = 1 + MAX_NDBMT_LQH_WORKERS + 1 }; // main+lqh+extra
+protected:
+  enum { MaxInstances = 3 + MAX_NDBMT_TC_THREADS + MAX_NDBMT_LQH_WORKERS + 1 };
+private:
   SimulatedBlock** theInstanceList; // set in main, indexed by instance
   SimulatedBlock* theMainInstance;  // set in all
   /*

=== modified file 'storage/ndb/src/kernel/vm/dummy_nonmt.cpp'
--- a/storage/ndb/src/kernel/vm/dummy_nonmt.cpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/vm/dummy_nonmt.cpp	2011-10-07 08:07:21 +0000
@@ -20,49 +20,62 @@
 #include <ndb_types.h>
 
 void
-add_thr_map(Uint32, Uint32, Uint32)
+mt_init_thr_map()
 {
   assert(false);
 }
 
 void
-add_main_thr_map()
+mt_add_thr_map(Uint32, Uint32)
 {
   assert(false);
 }
 
 void
-add_lqh_worker_thr_map(Uint32, Uint32)
+mt_finalize_thr_map()
 {
   assert(false);
 }
 
-void
-add_extra_worker_thr_map(Uint32, Uint32)
+Uint32
+mt_get_instance_count(Uint32 block)
 {
   assert(false);
+  return 0;
 }
 
-void
-add_tc_worker_thr_map(Uint32, Uint32)
+Uint32
+compute_jb_pages(struct EmulatorData*)
 {
-  assert(false);
+  return 0;
 }
 
-void
-finalize_thr_map()
+
+bool
+NdbIsMultiThreaded()
 {
-  assert(false);
+  return false;
 }
 
+#include <BlockNumbers.h>
+
 Uint32
-compute_jb_pages(struct EmulatorData*)
+mt_get_blocklist(class SimulatedBlock * block, Uint32 arr[], Uint32 len)
 {
-  return 0;
+  (void)block;
+  for (Uint32 i = 0; i<NO_OF_BLOCKS; i++)
+  {
+    arr[i] = numberToBlock(MIN_BLOCK_NO + i, 0);
+  }
+  return NO_OF_BLOCKS;
 }
 
-bool
-NdbIsMultiThreaded()
+#include "mt.hpp"
+
+void
+mt_get_thr_stat(class SimulatedBlock *, ndb_thr_stat* dst)
 {
-  return false;
+  bzero(dst, sizeof(* dst));
+  dst->name = "main";
 }
+

=== modified file 'storage/ndb/src/kernel/vm/mt.cpp'
--- a/storage/ndb/src/kernel/vm/mt.cpp	2011-09-16 14:40:22 +0000
+++ b/storage/ndb/src/kernel/vm/mt.cpp	2011-10-07 17:15:53 +0000
@@ -72,11 +72,11 @@ static const Uint32 MAX_SIGNALS_BEFORE_W
 
 //#define NDB_MT_LOCK_TO_CPU
 
-#define MAX_BLOCK_INSTANCES (1 + MAX_NDBMT_LQH_WORKERS + 1) //main+lqh+extra
 #define NUM_MAIN_THREADS 2 // except receiver
 #define MAX_THREADS (NUM_MAIN_THREADS +       \
                      MAX_NDBMT_LQH_THREADS +  \
                      MAX_NDBMT_TC_THREADS + 1)
+#define MAX_BLOCK_INSTANCES (MAX_THREADS)
 
 /* If this is too small it crashes before first signal. */
 #define MAX_INSTANCES_PER_THREAD (16 + 8 * MAX_NDBMT_LQH_THREADS)
@@ -876,10 +876,16 @@ struct thr_data
   /* Watchdog counter for this thread. */
   Uint32 m_watchdog_counter;
   /* Signal delivery statistics. */
-  Uint32 m_prioa_count;
-  Uint32 m_prioa_size;
-  Uint32 m_priob_count;
-  Uint32 m_priob_size;
+  struct
+  {
+    Uint64 m_loop_cnt;
+    Uint64 m_exec_cnt;
+    Uint64 m_wait_cnt;
+    Uint64 m_prioa_count;
+    Uint64 m_prioa_size;
+    Uint64 m_priob_count;
+    Uint64 m_priob_size;
+  } m_stat;
 
   /* Array of node ids with pending remote send data. */
   Uint8 m_pending_send_nodes[MAX_NTRANSPORTERS];
@@ -2592,7 +2598,7 @@ add_thr_map(Uint32 main, Uint32 instance
 
 /* Static assignment of main instances (before first signal). */
 void
-add_main_thr_map()
+mt_init_thr_map()
 {
   /* Keep mt-classic assignments in MT LQH. */
   const Uint32 thr_GLOBAL = 0;
@@ -2620,33 +2626,72 @@ add_main_thr_map()
   add_thr_map(RESTORE, 0, thr_LOCAL);
   add_thr_map(DBINFO, 0, thr_LOCAL);
   add_thr_map(DBSPJ, 0, thr_GLOBAL);
+  add_thr_map(THRMAN, 0, thr_GLOBAL);
 }
 
-/* Workers added by LocalProxy (before first signal). */
-void
-add_lqh_worker_thr_map(Uint32 block, Uint32 instance)
+Uint32
+mt_get_instance_count(Uint32 block)
 {
-  require(instance != 0);
-  Uint32 i = instance - 1;
-  Uint32 thr_no = NUM_MAIN_THREADS + i % num_lqh_threads;
-  add_thr_map(block, instance, thr_no);
+  switch(block){
+  case DBLQH:
+  case DBACC:
+  case DBTUP:
+  case DBTUX:
+  case BACKUP:
+  case RESTORE:
+    return globalData.ndbMtLqhWorkers;
+    break;
+  case PGMAN:
+    return globalData.ndbMtLqhWorkers + 1;
+    break;
+  case DBTC:
+  case DBSPJ:
+    return globalData.ndbMtTcThreads;
+    break;
+  case THRMAN:
+    return num_threads;
+  default:
+    require(false);
+  }
+  return 0;
 }
 
 void
-add_tc_worker_thr_map(Uint32 block, Uint32 instance)
+mt_add_thr_map(Uint32 block, Uint32 instance)
 {
   require(instance != 0);
-  Uint32 i = instance - 1;
-  Uint32 thr_no = NUM_MAIN_THREADS + num_lqh_threads + i;
-  add_thr_map(block, instance, thr_no);
-}
+  Uint32 thr_no = NUM_MAIN_THREADS;
+  switch(block){
+  case DBLQH:
+  case DBACC:
+  case DBTUP:
+  case DBTUX:
+  case BACKUP:
+  case RESTORE:
+    thr_no += (instance - 1) % num_lqh_threads;
+    break;
+  case PGMAN:
+    if (instance == num_lqh_threads + 1)
+    {
+      // Put extra PGMAN together with it's Proxy
+      thr_no = block2ThreadId(block, 0);
+    }
+    else
+    {
+      thr_no += (instance - 1) % num_lqh_threads;
+    }
+    break;
+  case DBTC:
+  case DBSPJ:
+    thr_no += num_lqh_threads + (instance - 1);
+    break;
+  case THRMAN:
+    thr_no = instance - 1;
+    break;
+  default:
+    require(false);
+  }
 
-/* Extra workers run`in proxy thread. */
-void
-add_extra_worker_thr_map(Uint32 block, Uint32 instance)
-{
-  require(instance != 0);
-  Uint32 thr_no = block2ThreadId(block, 0);
   add_thr_map(block, instance, thr_no);
 }
 
@@ -2661,7 +2706,7 @@ add_extra_worker_thr_map(Uint32 block, U
  * NOTE: extra pgman worker is instance 5
  */
 void
-finalize_thr_map()
+mt_finalize_thr_map()
 {
   for (Uint32 b = 0; b < NO_OF_BLOCKS; b++)
   {
@@ -2694,60 +2739,6 @@ finalize_thr_map()
   }
 }
 
-static void reportSignalStats(Uint32 self, Uint32 a_count, Uint32 a_size,
-                              Uint32 b_count, Uint32 b_size)
-{
-  SignalT<6> sT;
-  Signal *s= new (&sT) Signal(0);
-
-  memset(&s->header, 0, sizeof(s->header));
-  s->header.theLength = 6;
-  s->header.theSendersSignalId = 0;
-  s->header.theSendersBlockRef = numberToRef(0, 0);
-  s->header.theVerId_signalNumber = GSN_EVENT_REP;
-  s->header.theReceiversBlockNumber = CMVMI;
-  s->theData[0] = NDB_LE_MTSignalStatistics;
-  s->theData[1] = self;
-  s->theData[2] = a_count;
-  s->theData[3] = a_size;
-  s->theData[4] = b_count;
-  s->theData[5] = b_size;
-  /* ToDo: need this really be prio A like in old code? */
-  sendlocal(self, &s->header, s->theData,
-            NULL);
-}
-
-static inline void
-update_sched_stats(thr_data *selfptr)
-{
-  if(selfptr->m_prioa_count + selfptr->m_priob_count >= 2000000)
-  {
-    reportSignalStats(selfptr->m_thr_no,
-                      selfptr->m_prioa_count,
-                      selfptr->m_prioa_size,
-                      selfptr->m_priob_count,
-                      selfptr->m_priob_size);
-    selfptr->m_prioa_count = 0;
-    selfptr->m_prioa_size = 0;
-    selfptr->m_priob_count = 0;
-    selfptr->m_priob_size = 0;
-
-#if 0
-    Uint32 thr_no = selfptr->m_thr_no;
-    ndbout_c("--- %u fifo: %u jba: %u global: %u",
-             thr_no,
-             fifo_used_pages(selfptr),
-             selfptr->m_jba_head.used(),
-             g_thr_repository.m_free_list.m_cnt);
-    for (Uint32 i = 0; i<num_threads; i++)
-    {
-      ndbout_c("  %u-%u : %u",
-               thr_no, i, selfptr->m_in_queue_head[i].used());
-    }
-#endif
-  }
-}
-
 static void
 init_thread(thr_data *selfptr)
 {
@@ -2854,8 +2845,6 @@ mt_receiver_thread_main(void *thr_arg)
   { 
     static int cnt = 0;
 
-    update_sched_stats(selfptr);
-
     if (cnt == 0)
     {
       watchDogCounter = 5;
@@ -2892,6 +2881,8 @@ mt_receiver_thread_main(void *thr_arg)
         has_received = true;
       }
     }
+    selfptr->m_stat.m_loop_cnt++;
+    selfptr->m_stat.m_exec_cnt += sum;
   }
 
   globalEmulatorData.theWatchDog->unregisterWatchedThread(thr_no);
@@ -3028,14 +3019,14 @@ mt_job_thread_main(void *thr_arg)
 
   Uint32 pending_send = 0;
   Uint32 send_sum = 0;
-  int loops = 0;
-  int maxloops = 10;/* Loops before reading clock, fuzzy adapted to 1ms freq. */
+  Uint32 loops = 0;
+  Uint32 maxloops = 10;/* Loops before reading clock, fuzzy adapted to 1ms freq. */
+  Uint32 waits = 0;
   NDB_TICKS now = selfptr->m_time;
 
   while (globalData.theRestartFlag != perform_stop)
   { 
     loops++;
-    update_sched_stats(selfptr);
 
     watchDogCounter = 2;
     scan_time_queues(selfptr, now);
@@ -3080,9 +3071,12 @@ mt_job_thread_main(void *thr_arg)
                             selfptr);
         if (waited)
         {
+          waits++;
           /* Update current time after sleeping */
           now = NdbTick_CurrentMillisecond();
-          loops = 0;
+          selfptr->m_stat.m_wait_cnt += waits;
+          selfptr->m_stat.m_loop_cnt += loops;
+          waits = loops = 0;
         }
       }
     }
@@ -3097,7 +3091,9 @@ mt_job_thread_main(void *thr_arg)
       {
         /* Update current time after sleeping */
         now = NdbTick_CurrentMillisecond();
-        loops = 0;
+        selfptr->m_stat.m_wait_cnt += waits;
+        selfptr->m_stat.m_loop_cnt += loops;
+        waits = loops = 0;
       }
     }
     else
@@ -3120,8 +3116,11 @@ mt_job_thread_main(void *thr_arg)
       else if (diff > 1 && maxloops > 1)
         maxloops -= ((maxloops/10) + 1); /* Overslept: Need more frequent read*/
 
-      loops = 0;
+      selfptr->m_stat.m_wait_cnt += waits;
+      selfptr->m_stat.m_loop_cnt += loops;
+      waits = loops = 0;
     }
+    selfptr->m_stat.m_exec_cnt += sum;
   }
 
   globalEmulatorData.theWatchDog->unregisterWatchedThread(thr_no);
@@ -3150,9 +3149,9 @@ sendlocal(Uint32 self, const SignalHeade
   assert(pthread_equal(selfptr->m_thr_id, pthread_self()));
   struct thr_data * dstptr = rep->m_thread + dst;
 
-  selfptr->m_priob_count++;
+  selfptr->m_stat.m_priob_count++;
   Uint32 siglen = (sizeof(*s) >> 2) + s->theLength + s->m_noOfSections;
-  selfptr->m_priob_size += siglen;
+  selfptr->m_stat.m_priob_size += siglen;
 
   thr_job_queue *q = dstptr->m_in_queue + self;
   thr_jb_write_state *w = selfptr->m_write_states + dst;
@@ -3178,9 +3177,9 @@ sendprioa(Uint32 self, const SignalHeade
          pthread_equal(selfptr->m_thr_id, pthread_self()));
   struct thr_data *dstptr = rep->m_thread + dst;
 
-  selfptr->m_prioa_count++;
+  selfptr->m_stat.m_prioa_count++;
   Uint32 siglen = (sizeof(*s) >> 2) + s->theLength + s->m_noOfSections;
-  selfptr->m_prioa_size += siglen;  
+  selfptr->m_stat.m_prioa_size += siglen;
 
   thr_job_queue *q = &(dstptr->m_jba);
   thr_jb_write_state w;
@@ -3359,10 +3358,7 @@ thr_init(struct thr_repository* rep, str
   }
   queue_init(&selfptr->m_tq);
 
-  selfptr->m_prioa_count = 0;
-  selfptr->m_prioa_size = 0;
-  selfptr->m_priob_count = 0;
-  selfptr->m_priob_size = 0;
+  bzero(&selfptr->m_stat, sizeof(selfptr->m_stat));
 
   selfptr->m_pending_send_count = 0;
   selfptr->m_pending_send_mask.clear();
@@ -4086,6 +4082,40 @@ mt_assert_own_thread(SimulatedBlock* blo
 }
 #endif
 
+
+Uint32
+mt_get_blocklist(SimulatedBlock * block, Uint32 arr[], Uint32 len)
+{
+  Uint32 thr_no = block->getThreadId();
+  thr_data *thr_ptr = g_thr_repository.m_thread + thr_no;
+
+  for (Uint32 i = 0; i < thr_ptr->m_instance_count; i++)
+  {
+    arr[i] = thr_ptr->m_instance_list[i];
+  }
+
+  return thr_ptr->m_instance_count;
+}
+
+void
+mt_get_thr_stat(class SimulatedBlock * block, ndb_thr_stat* dst)
+{
+  bzero(dst, sizeof(* dst));
+  Uint32 thr_no = block->getThreadId();
+  thr_data *selfptr = g_thr_repository.m_thread + thr_no;
+
+  THRConfigApplier & conf = globalEmulatorData.theConfiguration->m_thr_config;
+  dst->thr_no = thr_no;
+  dst->name = conf.getName(selfptr->m_instance_list, selfptr->m_instance_count);
+  dst->os_tid = NdbThread_GetTid(selfptr->m_thread);
+  dst->loop_cnt = selfptr->m_stat.m_loop_cnt;
+  dst->exec_cnt = selfptr->m_stat.m_exec_cnt;
+  dst->wait_cnt = selfptr->m_stat.m_wait_cnt;
+  dst->local_sent_prioa = selfptr->m_stat.m_prioa_count;
+  dst->local_sent_priob = selfptr->m_stat.m_priob_count;
+}
+
+
 /**
  * Global data
  */

=== modified file 'storage/ndb/src/kernel/vm/mt.hpp'
--- a/storage/ndb/src/kernel/vm/mt.hpp	2011-09-15 20:21:59 +0000
+++ b/storage/ndb/src/kernel/vm/mt.hpp	2011-10-07 08:07:21 +0000
@@ -29,13 +29,12 @@
 */
 extern Uint32 receiverThreadId;
 
+Uint32 mt_get_instance_count(Uint32 block);
+
 /* Assign block instances to thread */
-void add_thr_map(Uint32 block, Uint32 instance, Uint32 thr_no);
-void add_main_thr_map();
-void add_lqh_worker_thr_map(Uint32 block, Uint32 instance);
-void add_tc_worker_thr_map(Uint32 block, Uint32 instance);
-void add_extra_worker_thr_map(Uint32 block, Uint32 instance);
-void finalize_thr_map();
+void mt_init_thr_map();
+void mt_add_thr_map(Uint32 block, Uint32 instance);
+void mt_finalize_thr_map();
 
 void sendlocal(Uint32 self, const struct SignalHeader *s,
                const Uint32 *data, const Uint32 secPtr[3]);
@@ -87,4 +86,28 @@ void mt_wakeup(class SimulatedBlock*);
 void mt_assert_own_thread(class SimulatedBlock*);
 #endif
 
+/**
+ * return list of references running in this thread
+ */
+Uint32
+mt_get_blocklist(class SimulatedBlock*, Uint32 dst[], Uint32 len);
+
+
+struct ndb_thr_stat
+{
+  Uint32 thr_no;
+  Uint64 os_tid;
+  const char * name;
+  Uint64 loop_cnt;
+  Uint64 exec_cnt;
+  Uint64 wait_cnt;
+  Uint64 local_sent_prioa;
+  Uint64 local_sent_priob;
+  Uint64 remote_sent_prioa;
+  Uint64 remote_sent_priob;
+};
+
+void
+mt_get_thr_stat(class SimulatedBlock *, ndb_thr_stat* dst);
+
 #endif

=== modified file 'storage/ndb/src/kernel/vm/mt_thr_config.cpp'
--- a/storage/ndb/src/kernel/vm/mt_thr_config.cpp	2011-09-23 09:13:22 +0000
+++ b/storage/ndb/src/kernel/vm/mt_thr_config.cpp	2011-10-07 08:07:21 +0000
@@ -964,6 +964,14 @@ THRConfigApplier::appendInfo(BaseString&
   }
 }
 
+const char *
+THRConfigApplier::getName(const unsigned short list[], unsigned cnt) const
+{
+  const T_Thread* thr = find_thread(list, cnt);
+  assert(thr != 0);
+  return getEntryName(thr->m_type);
+}
+
 int
 THRConfigApplier::create_cpusets()
 {

=== modified file 'storage/ndb/src/kernel/vm/mt_thr_config.hpp'
--- a/storage/ndb/src/kernel/vm/mt_thr_config.hpp	2011-09-23 09:13:22 +0000
+++ b/storage/ndb/src/kernel/vm/mt_thr_config.hpp	2011-10-07 08:07:21 +0000
@@ -124,6 +124,7 @@ class THRConfigApplier : public THRConfi
 public:
   int create_cpusets();
 
+  const char * getName(const unsigned short list[], unsigned cnt) const;
   void appendInfo(BaseString&, const unsigned short list[], unsigned cnt) const;
   int do_bind(NdbThread*, const unsigned short list[], unsigned cnt);
   int do_bind_io(NdbThread*);

=== modified file 'storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp'
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp	2011-08-16 08:27:14 +0000
+++ b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp	2011-10-07 13:15:08 +0000
@@ -94,7 +94,7 @@ public:
 private:
   void grow(Uint32 start, Uint32 cnt);
 
-#define XX_RL_COUNT 9
+#define XX_RL_COUNT 10
   /**
    * Return pointer to free page data on page
    */

=== modified file 'storage/ndb/src/mgmsrv/ConfigInfo.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2011-09-04 17:04:25 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2011-10-07 17:15:53 +0000
@@ -2122,6 +2122,22 @@ const ConfigInfo::ParamInfo ConfigInfo::
     STR_VALUE(MAX_INT_RNIL)
   },
 
+  {
+    CFG_DB_CRASH_ON_CORRUPTED_TUPLE,
+    "CrashOnCorruptedTuple",
+    DB_TOKEN,
+    "To be failfast or not, when checksum indicates corruption.",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_BOOL,
+#if NDB_VERSION_D < NDB_MAKE_VERSION(7,2,1)
+    "false",
+#else
+    "true",
+#endif
+    "false",
+    "true"},
+
   /***************************************************************************
    * API
    ***************************************************************************/

=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c	2011-09-22 17:00:01 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c	2011-10-07 17:15:53 +0000
@@ -493,7 +493,8 @@ ErrorBundle ErrorCodes[] = {
   { 786,  DMEC, NR, "Schema transaction aborted due to node-failure" },
   { 792,  DMEC, SE, "Default value for primary key column not supported" },
   { 794,  DMEC, AE, "Schema feature requires data node upgrade" },
-  
+  { 796,  DMEC, SE, "Out of schema transaction memory" },
+
   /**
    * FunctionNotImplemented
    */

=== modified file 'storage/ndb/tools/ndbinfo_select_all.cpp'
--- a/storage/ndb/tools/ndbinfo_select_all.cpp	2011-10-05 11:21:23 +0000
+++ b/storage/ndb/tools/ndbinfo_select_all.cpp	2011-10-07 09:17:10 +0000
@@ -21,18 +21,25 @@
 
 #include <NdbApi.hpp>
 #include <NdbOut.hpp>
-#include <NDBT.hpp>
 #include "../src/ndbapi/NdbInfo.hpp"
+#include <NdbSleep.h>
 
+static int loops = 1;
+static int delay = 5;
 const char *load_default_groups[]= { "mysql_cluster",0 };
 
 static struct my_option my_long_options[] =
 {
   NDB_STD_OPTS("ndbinfo_select_all"),
+  { "loops", 'l', "Run same select several times",
+    (uchar**) &loops, (uchar**) &loops, 0,
+    GET_INT, REQUIRED_ARG, loops, 0, 0, 0, 0, 0 },
+  { "delay", 256, "Delay between loops (in seconds)",
+    (uchar**) &delay, (uchar**) &delay, 0,
+    GET_INT, REQUIRED_ARG, delay, 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
-
 static void short_usage_sub(void)
 {
   ndb_short_usage_sub(NULL);
@@ -85,90 +92,97 @@ main(int argc, char** argv)
 
   const Uint32 batchsizerows = 32;
 
-  for (int ii = 0; argv[ii] != 0; ii++)
+  for (int ll = 0; loops == 0 || ll < loops; ll++)
   {
-    ndbout << "== " << argv[ii] << " ==" << endl;
-
-    const NdbInfo::Table * pTab = 0;
-    int res = info.openTable(argv[ii], &pTab);
-    if (res != 0)
+    for (int ii = 0; argv[ii] != 0; ii++)
     {
-      ndbout << "Failed to open: " << argv[ii] << ", res: " << res << endl;
-      continue;
-    }
+      ndbout << "== " << argv[ii] << " ==" << endl;
 
-    unsigned cols = pTab->columns();
-    for (unsigned i = 0; i<cols; i++)
-    {
-      const NdbInfo::Column * pCol = pTab->getColumn(i);
-      ndbout << pCol->m_name.c_str() << "\t";
-    }
-    ndbout << endl;
+      const NdbInfo::Table * pTab = 0;
+      int res = info.openTable(argv[ii], &pTab);
+      if (res != 0)
+      {
+        ndbout << "Failed to open: " << argv[ii] << ", res: " << res << endl;
+        continue;
+      }
 
-    NdbInfoScanOperation * pScan = 0;
-    res= info.createScanOperation(pTab, &pScan, batchsizerows);
-    if (res != 0)
-    {
-      ndbout << "Failed to createScan: " << argv[ii] << ", res: " << res<< endl;
-      info.closeTable(pTab);
-      continue;
-    }
+      unsigned cols = pTab->columns();
+      for (unsigned i = 0; i<cols; i++)
+      {
+        const NdbInfo::Column * pCol = pTab->getColumn(i);
+        ndbout << pCol->m_name.c_str() << "\t";
+      }
+      ndbout << endl;
 
-    if (pScan->readTuples() != 0)
-    {
-      ndbout << "scanOp->readTuples failed" << endl;
-      return 1;
-    }
+      NdbInfoScanOperation * pScan = 0;
+      res= info.createScanOperation(pTab, &pScan, batchsizerows);
+      if (res != 0)
+      {
+        ndbout << "Failed to createScan: " << argv[ii] << ", res: " << res<< endl;
+        info.closeTable(pTab);
+        continue;
+      }
 
-    Vector<const NdbInfoRecAttr*> recAttrs;
-    for (unsigned i = 0; i<cols; i++)
-    {
-      const NdbInfoRecAttr* pRec = pScan->getValue(i);
-      if (pRec == 0)
+      if (pScan->readTuples() != 0)
       {
-        ndbout << "Failed to getValue(" << i << ")" << endl;
+        ndbout << "scanOp->readTuples failed" << endl;
         return 1;
       }
-      recAttrs.push_back(pRec);
-    }
 
-    if(pScan->execute() != 0)
-    {
-      ndbout << "scanOp->execute failed" << endl;
-      return 1;
-    }
-
-    while(pScan->nextResult() == 1)
-    {
+      Vector<const NdbInfoRecAttr*> recAttrs;
       for (unsigned i = 0; i<cols; i++)
       {
-        if (recAttrs[i]->isNULL())
+        const NdbInfoRecAttr* pRec = pScan->getValue(i);
+        if (pRec == 0)
         {
-          ndbout << "NULL";
+          ndbout << "Failed to getValue(" << i << ")" << endl;
+          return 1;
         }
-        else
+        recAttrs.push_back(pRec);
+      }
+
+      if(pScan->execute() != 0)
+      {
+        ndbout << "scanOp->execute failed" << endl;
+        return 1;
+      }
+
+      while(pScan->nextResult() == 1)
+      {
+        for (unsigned i = 0; i<cols; i++)
         {
-          switch(pTab->getColumn(i)->m_type){
-          case NdbInfo::Column::String:
-            ndbout << recAttrs[i]->c_str();
-            break;
-          case NdbInfo::Column::Number:
-            ndbout << recAttrs[i]->u_32_value();
-            break;
-          case NdbInfo::Column::Number64:
-            ndbout << recAttrs[i]->u_64_value();
-            break;
+          if (recAttrs[i]->isNULL())
+          {
+            ndbout << "NULL";
+          }
+          else
+          {
+            switch(pTab->getColumn(i)->m_type){
+            case NdbInfo::Column::String:
+              ndbout << recAttrs[i]->c_str();
+              break;
+            case NdbInfo::Column::Number:
+              ndbout << recAttrs[i]->u_32_value();
+              break;
+            case NdbInfo::Column::Number64:
+              ndbout << recAttrs[i]->u_64_value();
+              break;
+            }
           }
+          ndbout << "\t";
         }
-        ndbout << "\t";
+        ndbout << endl;
       }
-      ndbout << endl;
+
+      info.releaseScanOperation(pScan);
+      info.closeTable(pTab);
     }
 
-    info.releaseScanOperation(pScan);
-    info.closeTable(pTab);
+    if ((loops == 0 || ll + 1 != loops) && delay > 0)
+    {
+      NdbSleep_SecSleep(delay);
+    }
   }
-
   return 0;
 }
 

=== modified file 'storage/ndb/tools/ndbinfo_sql.cpp'
--- a/storage/ndb/tools/ndbinfo_sql.cpp	2011-06-30 16:04:23 +0000
+++ b/storage/ndb/tools/ndbinfo_sql.cpp	2011-10-07 17:15:53 +0000
@@ -99,6 +99,9 @@ struct view {
     "  WHEN 4 THEN \"JOBBUFFER\""
     "  WHEN 5 THEN \"FILE_BUFFERS\""
     "  WHEN 6 THEN \"TRANSPORTER_BUFFERS\""
+    "  WHEN 7 THEN \"DISK_PAGE_BUFFER\""
+    "  WHEN 8 THEN \"QUERY_MEMORY\""
+    "  WHEN 9 THEN \"SCHEMA_TRANS_MEMORY\""
     "  ELSE \"<unknown>\" "
     " END AS resource_name, "
     "reserved, used, max "

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.1 branch (jonas.oreland:4298 to 4299) jonas oreland10 Oct