wl2723 - ndb opt. nr
mysql-test/t/rpl_multi_engine.test: merge fix libmysqld/sql_tablespace.cc: New BitKeeper file ``libmysqld/sql_tablespace.cc'' mysql-test/r/ndb_basic_disk.result: New BitKeeper file ``mysql-test/r/ndb_basic_disk.result'' mysql-test/t/ndb_basic_disk.test: New BitKeeper file ``mysql-test/t/ndb_basic_disk.test'' sql/sql_tablespace.cc: New BitKeeper file ``sql/sql_tablespace.cc'' storage/ndb/src/kernel/blocks/OptNR.txt: New BitKeeper file ``storage/ndb/src/kernel/blocks/OptNR.txt'' storage/ndb/src/kernel/vm/mem.txt: New BitKeeper file ``storage/ndb/src/kernel/vm/mem.txt'' storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp: New BitKeeper file ``storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp'' storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp: New BitKeeper file ``storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp'' storage/ndb/tools/ndb_error_reporter: New BitKeeper file ``storage/ndb/tools/ndb_error_reporter''
This commit is contained in:
parent
2c0f53d69c
commit
641ce5e97e
@ -65,7 +65,8 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
|
||||
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
|
||||
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
|
||||
item_xmlfunc.cc \
|
||||
rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc
|
||||
rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc \
|
||||
sql_tablespace.cc
|
||||
|
||||
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
|
||||
EXTRA_libmysqld_a_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \
|
||||
|
397
mysql-test/r/ndb_basic_disk.result
Normal file
397
mysql-test/r/ndb_basic_disk.result
Normal file
@ -0,0 +1,397 @@
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE LOGFILE GROUP lg1
|
||||
ADD UNDOFILE 'undofile.dat'
|
||||
INITIAL_SIZE 16M
|
||||
UNDO_BUFFER_SIZE = 1M
|
||||
ENGINE=NDB;
|
||||
alter logfile group lg1
|
||||
add undofile 'undofile02.dat'
|
||||
initial_size 4M engine=ndb;
|
||||
CREATE TABLESPACE ts1
|
||||
ADD DATAFILE 'datafile.dat'
|
||||
USE LOGFILE GROUP lg1
|
||||
INITIAL_SIZE 12M
|
||||
ENGINE NDB;
|
||||
alter tablespace ts1
|
||||
add datafile 'datafile02.dat'
|
||||
initial_size 4M engine=ndb;
|
||||
CREATE TABLE t1
|
||||
(pk1 int not null primary key, b int not null, c int not null)
|
||||
tablespace ts1 storage disk
|
||||
engine ndb;
|
||||
INSERT INTO t1 VALUES (0, 0, 0);
|
||||
SELECT * FROM t1;
|
||||
pk1 b c
|
||||
0 0 0
|
||||
INSERT INTO t1 VALUES
|
||||
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
|
||||
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10),
|
||||
(11,11,11),(12,12,12),(13,13,13),(14,14,14),(15,15,15),
|
||||
(16,16,16),(17,17,17),(18,18,18),(19,19,19),(20,20,20),
|
||||
(21,21,21),(22,22,22),(23,23,23),(24,24,24),(25,25,25),
|
||||
(26,26,26),(27,27,27),(28,28,28),(29,29,29),(30,30,30),
|
||||
(31,31,31),(32,32,32),(33,33,33),(34,34,34),(35,35,35),
|
||||
(36,36,36),(37,37,37),(38,38,38),(39,39,39),(40,40,40),
|
||||
(41,41,41),(42,42,42),(43,43,43),(44,44,44),(45,45,45),
|
||||
(46,46,46),(47,47,47),(48,48,48),(49,49,49),(50,50,50),
|
||||
(51,51,51),(52,52,52),(53,53,53),(54,54,54),(55,55,55),
|
||||
(56,56,56),(57,57,57),(58,58,58),(59,59,59),(60,60,60),
|
||||
(61,61,61),(62,62,62),(63,63,63),(64,64,64),(65,65,65),
|
||||
(66,66,66),(67,67,67),(68,68,68),(69,69,69),(70,70,70),
|
||||
(71,71,71),(72,72,72),(73,73,73),(74,74,74),(75,75,75),
|
||||
(76,76,76),(77,77,77),(78,78,78),(79,79,79),(80,80,80),
|
||||
(81,81,81),(82,82,82),(83,83,83),(84,84,84),(85,85,85),
|
||||
(86,86,86),(87,87,87),(88,88,88),(89,89,89),(90,90,90),
|
||||
(91,91,91),(92,92,92),(93,93,93),(94,94,94),(95,95,95),
|
||||
(96,96,96),(97,97,97),(98,98,98),(99,99,99),(100,100,100),
|
||||
(101,101,101),(102,102,102),(103,103,103),(104,104,104),(105,105,105),
|
||||
(106,106,106),(107,107,107),(108,108,108),(109,109,109),(110,110,110),
|
||||
(111,111,111),(112,112,112),(113,113,113),(114,114,114),(115,115,115),
|
||||
(116,116,116),(117,117,117),(118,118,118),(119,119,119),(120,120,120),
|
||||
(121,121,121),(122,122,122),(123,123,123),(124,124,124),(125,125,125),
|
||||
(126,126,126),(127,127,127),(128,128,128),(129,129,129),(130,130,130),
|
||||
(131,131,131),(132,132,132),(133,133,133),(134,134,134),(135,135,135),
|
||||
(136,136,136),(137,137,137),(138,138,138),(139,139,139),(140,140,140),
|
||||
(141,141,141),(142,142,142),(143,143,143),(144,144,144),(145,145,145),
|
||||
(146,146,146),(147,147,147),(148,148,148),(149,149,149),(150,150,150),
|
||||
(151,151,151),(152,152,152),(153,153,153),(154,154,154),(155,155,155),
|
||||
(156,156,156),(157,157,157),(158,158,158),(159,159,159),(160,160,160),
|
||||
(161,161,161),(162,162,162),(163,163,163),(164,164,164),(165,165,165),
|
||||
(166,166,166),(167,167,167),(168,168,168),(169,169,169),(170,170,170),
|
||||
(171,171,171),(172,172,172),(173,173,173),(174,174,174),(175,175,175),
|
||||
(176,176,176),(177,177,177),(178,178,178),(179,179,179),(180,180,180),
|
||||
(181,181,181),(182,182,182),(183,183,183),(184,184,184),(185,185,185),
|
||||
(186,186,186),(187,187,187),(188,188,188),(189,189,189),(190,190,190),
|
||||
(191,191,191),(192,192,192),(193,193,193),(194,194,194),(195,195,195),
|
||||
(196,196,196),(197,197,197),(198,198,198),(199,199,199),(200,200,200),
|
||||
(201,201,201),(202,202,202),(203,203,203),(204,204,204),(205,205,205),
|
||||
(206,206,206),(207,207,207),(208,208,208),(209,209,209),(210,210,210),
|
||||
(211,211,211),(212,212,212),(213,213,213),(214,214,214),(215,215,215),
|
||||
(216,216,216),(217,217,217),(218,218,218),(219,219,219),(220,220,220),
|
||||
(221,221,221),(222,222,222),(223,223,223),(224,224,224),(225,225,225),
|
||||
(226,226,226),(227,227,227),(228,228,228),(229,229,229),(230,230,230),
|
||||
(231,231,231),(232,232,232),(233,233,233),(234,234,234),(235,235,235),
|
||||
(236,236,236),(237,237,237),(238,238,238),(239,239,239),(240,240,240),
|
||||
(241,241,241),(242,242,242),(243,243,243),(244,244,244),(245,245,245),
|
||||
(246,246,246),(247,247,247),(248,248,248),(249,249,249),(250,250,250),
|
||||
(251,251,251),(252,252,252),(253,253,253),(254,254,254),(255,255,255),
|
||||
(256,256,256),(257,257,257),(258,258,258),(259,259,259),(260,260,260),
|
||||
(261,261,261),(262,262,262),(263,263,263),(264,264,264),(265,265,265),
|
||||
(266,266,266),(267,267,267),(268,268,268),(269,269,269),(270,270,270),
|
||||
(271,271,271),(272,272,272),(273,273,273),(274,274,274),(275,275,275),
|
||||
(276,276,276),(277,277,277),(278,278,278),(279,279,279),(280,280,280),
|
||||
(281,281,281),(282,282,282),(283,283,283),(284,284,284),(285,285,285),
|
||||
(286,286,286),(287,287,287),(288,288,288),(289,289,289),(290,290,290),
|
||||
(291,291,291),(292,292,292),(293,293,293),(294,294,294),(295,295,295),
|
||||
(296,296,296),(297,297,297),(298,298,298),(299,299,299),(300,300,300),
|
||||
(301,301,301),(302,302,302),(303,303,303),(304,304,304),(305,305,305),
|
||||
(306,306,306),(307,307,307),(308,308,308),(309,309,309),(310,310,310),
|
||||
(311,311,311),(312,312,312),(313,313,313),(314,314,314),(315,315,315),
|
||||
(316,316,316),(317,317,317),(318,318,318),(319,319,319),(320,320,320),
|
||||
(321,321,321),(322,322,322),(323,323,323),(324,324,324),(325,325,325),
|
||||
(326,326,326),(327,327,327),(328,328,328),(329,329,329),(330,330,330),
|
||||
(331,331,331),(332,332,332),(333,333,333),(334,334,334),(335,335,335),
|
||||
(336,336,336),(337,337,337),(338,338,338),(339,339,339),(340,340,340),
|
||||
(341,341,341),(342,342,342),(343,343,343),(344,344,344),(345,345,345),
|
||||
(346,346,346),(347,347,347),(348,348,348),(349,349,349),(350,350,350),
|
||||
(351,351,351),(352,352,352),(353,353,353),(354,354,354),(355,355,355),
|
||||
(356,356,356),(357,357,357),(358,358,358),(359,359,359),(360,360,360),
|
||||
(361,361,361),(362,362,362),(363,363,363),(364,364,364),(365,365,365),
|
||||
(366,366,366),(367,367,367),(368,368,368),(369,369,369),(370,370,370),
|
||||
(371,371,371),(372,372,372),(373,373,373),(374,374,374),(375,375,375),
|
||||
(376,376,376),(377,377,377),(378,378,378),(379,379,379),(380,380,380),
|
||||
(381,381,381),(382,382,382),(383,383,383),(384,384,384),(385,385,385),
|
||||
(386,386,386),(387,387,387),(388,388,388),(389,389,389),(390,390,390),
|
||||
(391,391,391),(392,392,392),(393,393,393),(394,394,394),(395,395,395),
|
||||
(396,396,396),(397,397,397),(398,398,398),(399,399,399),(400,400,400),
|
||||
(401,401,401),(402,402,402),(403,403,403),(404,404,404),(405,405,405),
|
||||
(406,406,406),(407,407,407),(408,408,408),(409,409,409),(410,410,410),
|
||||
(411,411,411),(412,412,412),(413,413,413),(414,414,414),(415,415,415),
|
||||
(416,416,416),(417,417,417),(418,418,418),(419,419,419),(420,420,420),
|
||||
(421,421,421),(422,422,422),(423,423,423),(424,424,424),(425,425,425),
|
||||
(426,426,426),(427,427,427),(428,428,428),(429,429,429),(430,430,430),
|
||||
(431,431,431),(432,432,432),(433,433,433),(434,434,434),(435,435,435),
|
||||
(436,436,436),(437,437,437),(438,438,438),(439,439,439),(440,440,440),
|
||||
(441,441,441),(442,442,442),(443,443,443),(444,444,444),(445,445,445),
|
||||
(446,446,446),(447,447,447),(448,448,448),(449,449,449),(450,450,450),
|
||||
(451,451,451),(452,452,452),(453,453,453),(454,454,454),(455,455,455),
|
||||
(456,456,456),(457,457,457),(458,458,458),(459,459,459),(460,460,460),
|
||||
(461,461,461),(462,462,462),(463,463,463),(464,464,464),(465,465,465),
|
||||
(466,466,466),(467,467,467),(468,468,468),(469,469,469),(470,470,470),
|
||||
(471,471,471),(472,472,472),(473,473,473),(474,474,474),(475,475,475),
|
||||
(476,476,476),(477,477,477),(478,478,478),(479,479,479),(480,480,480),
|
||||
(481,481,481),(482,482,482),(483,483,483),(484,484,484),(485,485,485),
|
||||
(486,486,486),(487,487,487),(488,488,488),(489,489,489),(490,490,490),
|
||||
(491,491,491),(492,492,492),(493,493,493),(494,494,494),(495,495,495),
|
||||
(496,496,496),(497,497,497),(498,498,498),(499,499,499),(500, 500, 500);
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
501
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10y
|
||||
engine = ndb;
|
||||
ERROR HY000: A size parameter was incorrectly specified, either number or on the form 10M
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10MB
|
||||
engine=ndb;
|
||||
ERROR HY000: A size parameter was incorrectly specified, either number or on the form 10M
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10 MB
|
||||
engine=ndb;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MB
|
||||
engine=ndb' at line 3
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10 M
|
||||
engine=ndb;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'M
|
||||
engine=ndb' at line 3
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 1000000000000K
|
||||
engine=ndb;
|
||||
ERROR HY000: The size number was correct but we don't allow the digit part to be more than 2 billion
|
||||
DROP TABLE t1;
|
||||
create table t1 (a int primary key, b char(4) not null, c char(4) not null, key(b)) tablespace ts1 storage disk engine ndb;
|
||||
insert into t1 values (1,'1','1'), (2,'2','2'), (3,'3','3');
|
||||
begin;
|
||||
update t1 set b = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
2
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 2 1
|
||||
update t1 set c = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
2
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 2 2
|
||||
update t1 set b = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
3
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 3 2
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 3 2
|
||||
2 2 2
|
||||
3 3 3
|
||||
begin;
|
||||
update t1 set c = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
3
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 3 3
|
||||
update t1 set b = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
4
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 4 3
|
||||
update t1 set c = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
4
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 4 4
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 4 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 5 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '6' where b = '5';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 6 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '7' where c = '4';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 5
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '6' where b = '7';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 6
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '7' where c = '6';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 7
|
||||
2 2 2
|
||||
3 3 3
|
||||
drop table t1;
|
||||
create table t1 (a int primary key, b varchar(4) not null, c char(4) not null, key(b)) tablespace ts1 storage disk engine ndb;
|
||||
insert into t1 values (1,'1','1'), (2,'2','2'), (3,'3','3');
|
||||
begin;
|
||||
update t1 set b = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
2
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 2 1
|
||||
update t1 set c = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
2
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 2 2
|
||||
update t1 set b = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
3
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 3 2
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 3 2
|
||||
2 2 2
|
||||
3 3 3
|
||||
begin;
|
||||
update t1 set c = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
3
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 3 3
|
||||
update t1 set b = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
4
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 4 3
|
||||
update t1 set c = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
b
|
||||
4
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 4 4
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 4 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 5 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '6' where b = '5';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 6 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set b = '7' where c = '4';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 4
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 5
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '6' where b = '7';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 6
|
||||
2 2 2
|
||||
3 3 3
|
||||
update t1 set c = '7' where c = '6';
|
||||
select * from t1 order by 1;
|
||||
a b c
|
||||
1 7 7
|
||||
2 2 2
|
||||
3 3 3
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) tablespace ts1 storage disk engine=ndbcluster;
|
||||
set @x0 = '01234567012345670123456701234567';
|
||||
set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0);
|
||||
set @b1 = 'b1';
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@x0);
|
||||
set @b2 = 'b2';
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
insert into t1 values(1,@b1);
|
||||
insert into t1 values(2,@b2);
|
||||
select a,length(b),substr(b,1+2*900,2) from t1 where a=1;
|
||||
a length(b) substr(b,1+2*900,2)
|
||||
1 2256 b1
|
||||
select a,length(b),substr(b,1+2*9000,2) from t1 where a=2;
|
||||
a length(b) substr(b,1+2*9000,2)
|
||||
2 20000 b2
|
||||
update t1 set b=@b2 where a=1;
|
||||
update t1 set b=@b1 where a=2;
|
||||
select a,length(b),substr(b,1+2*9000,2) from t1 where a=1;
|
||||
a length(b) substr(b,1+2*9000,2)
|
||||
1 20000 b2
|
||||
select a,length(b),substr(b,1+2*900,2) from t1 where a=2;
|
||||
a length(b) substr(b,1+2*900,2)
|
||||
2 2256 b1
|
||||
update t1 set b=concat(b,b) where a=1;
|
||||
update t1 set b=concat(b,b) where a=2;
|
||||
select a,length(b),substr(b,1+4*9000,2) from t1 where a=1;
|
||||
a length(b) substr(b,1+4*9000,2)
|
||||
1 40000 b2
|
||||
select a,length(b),substr(b,1+4*900,2) from t1 where a=2;
|
||||
a length(b) substr(b,1+4*900,2)
|
||||
2 4512 b1
|
||||
delete from t1 where a=1;
|
||||
delete from t1 where a=2;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
drop table t1;
|
||||
alter tablespace ts1 drop datafile 'datafile.dat' engine = ndb;
|
||||
alter tablespace ts1 drop datafile 'datafile02.dat' engine = ndb;
|
||||
drop tablespace ts1 engine = ndb;
|
||||
drop logfile group lg1 engine = ndb;
|
@ -55,6 +55,8 @@ Temporary table: no
|
||||
Number of attributes: 4
|
||||
Number of primary keys: 3
|
||||
Length of frm data: #
|
||||
Row Checksum: 1
|
||||
Row GCI: 1
|
||||
TableStatus: Retrieved
|
||||
-- Attributes --
|
||||
a Int PRIMARY KEY AT=FIXED ST=MEMORY
|
||||
|
312
mysql-test/t/ndb_basic_disk.test
Normal file
312
mysql-test/t/ndb_basic_disk.test
Normal file
@ -0,0 +1,312 @@
|
||||
-- source include/have_ndb.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# Basic test of disk tables for NDB
|
||||
#
|
||||
|
||||
#
|
||||
# Start by creating a logfile group
|
||||
#
|
||||
|
||||
CREATE LOGFILE GROUP lg1
|
||||
ADD UNDOFILE 'undofile.dat'
|
||||
INITIAL_SIZE 16M
|
||||
UNDO_BUFFER_SIZE = 1M
|
||||
ENGINE=NDB;
|
||||
|
||||
alter logfile group lg1
|
||||
add undofile 'undofile02.dat'
|
||||
initial_size 4M engine=ndb;
|
||||
|
||||
#
|
||||
# Create a tablespace connected to the logfile group
|
||||
#
|
||||
|
||||
CREATE TABLESPACE ts1
|
||||
ADD DATAFILE 'datafile.dat'
|
||||
USE LOGFILE GROUP lg1
|
||||
INITIAL_SIZE 12M
|
||||
ENGINE NDB;
|
||||
|
||||
alter tablespace ts1
|
||||
add datafile 'datafile02.dat'
|
||||
initial_size 4M engine=ndb;
|
||||
|
||||
#
|
||||
# Create a table using this tablespace
|
||||
#
|
||||
|
||||
CREATE TABLE t1
|
||||
(pk1 int not null primary key, b int not null, c int not null)
|
||||
tablespace ts1 storage disk
|
||||
engine ndb;
|
||||
|
||||
INSERT INTO t1 VALUES (0, 0, 0);
|
||||
SELECT * FROM t1;
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
|
||||
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10),
|
||||
(11,11,11),(12,12,12),(13,13,13),(14,14,14),(15,15,15),
|
||||
(16,16,16),(17,17,17),(18,18,18),(19,19,19),(20,20,20),
|
||||
(21,21,21),(22,22,22),(23,23,23),(24,24,24),(25,25,25),
|
||||
(26,26,26),(27,27,27),(28,28,28),(29,29,29),(30,30,30),
|
||||
(31,31,31),(32,32,32),(33,33,33),(34,34,34),(35,35,35),
|
||||
(36,36,36),(37,37,37),(38,38,38),(39,39,39),(40,40,40),
|
||||
(41,41,41),(42,42,42),(43,43,43),(44,44,44),(45,45,45),
|
||||
(46,46,46),(47,47,47),(48,48,48),(49,49,49),(50,50,50),
|
||||
(51,51,51),(52,52,52),(53,53,53),(54,54,54),(55,55,55),
|
||||
(56,56,56),(57,57,57),(58,58,58),(59,59,59),(60,60,60),
|
||||
(61,61,61),(62,62,62),(63,63,63),(64,64,64),(65,65,65),
|
||||
(66,66,66),(67,67,67),(68,68,68),(69,69,69),(70,70,70),
|
||||
(71,71,71),(72,72,72),(73,73,73),(74,74,74),(75,75,75),
|
||||
(76,76,76),(77,77,77),(78,78,78),(79,79,79),(80,80,80),
|
||||
(81,81,81),(82,82,82),(83,83,83),(84,84,84),(85,85,85),
|
||||
(86,86,86),(87,87,87),(88,88,88),(89,89,89),(90,90,90),
|
||||
(91,91,91),(92,92,92),(93,93,93),(94,94,94),(95,95,95),
|
||||
(96,96,96),(97,97,97),(98,98,98),(99,99,99),(100,100,100),
|
||||
(101,101,101),(102,102,102),(103,103,103),(104,104,104),(105,105,105),
|
||||
(106,106,106),(107,107,107),(108,108,108),(109,109,109),(110,110,110),
|
||||
(111,111,111),(112,112,112),(113,113,113),(114,114,114),(115,115,115),
|
||||
(116,116,116),(117,117,117),(118,118,118),(119,119,119),(120,120,120),
|
||||
(121,121,121),(122,122,122),(123,123,123),(124,124,124),(125,125,125),
|
||||
(126,126,126),(127,127,127),(128,128,128),(129,129,129),(130,130,130),
|
||||
(131,131,131),(132,132,132),(133,133,133),(134,134,134),(135,135,135),
|
||||
(136,136,136),(137,137,137),(138,138,138),(139,139,139),(140,140,140),
|
||||
(141,141,141),(142,142,142),(143,143,143),(144,144,144),(145,145,145),
|
||||
(146,146,146),(147,147,147),(148,148,148),(149,149,149),(150,150,150),
|
||||
(151,151,151),(152,152,152),(153,153,153),(154,154,154),(155,155,155),
|
||||
(156,156,156),(157,157,157),(158,158,158),(159,159,159),(160,160,160),
|
||||
(161,161,161),(162,162,162),(163,163,163),(164,164,164),(165,165,165),
|
||||
(166,166,166),(167,167,167),(168,168,168),(169,169,169),(170,170,170),
|
||||
(171,171,171),(172,172,172),(173,173,173),(174,174,174),(175,175,175),
|
||||
(176,176,176),(177,177,177),(178,178,178),(179,179,179),(180,180,180),
|
||||
(181,181,181),(182,182,182),(183,183,183),(184,184,184),(185,185,185),
|
||||
(186,186,186),(187,187,187),(188,188,188),(189,189,189),(190,190,190),
|
||||
(191,191,191),(192,192,192),(193,193,193),(194,194,194),(195,195,195),
|
||||
(196,196,196),(197,197,197),(198,198,198),(199,199,199),(200,200,200),
|
||||
(201,201,201),(202,202,202),(203,203,203),(204,204,204),(205,205,205),
|
||||
(206,206,206),(207,207,207),(208,208,208),(209,209,209),(210,210,210),
|
||||
(211,211,211),(212,212,212),(213,213,213),(214,214,214),(215,215,215),
|
||||
(216,216,216),(217,217,217),(218,218,218),(219,219,219),(220,220,220),
|
||||
(221,221,221),(222,222,222),(223,223,223),(224,224,224),(225,225,225),
|
||||
(226,226,226),(227,227,227),(228,228,228),(229,229,229),(230,230,230),
|
||||
(231,231,231),(232,232,232),(233,233,233),(234,234,234),(235,235,235),
|
||||
(236,236,236),(237,237,237),(238,238,238),(239,239,239),(240,240,240),
|
||||
(241,241,241),(242,242,242),(243,243,243),(244,244,244),(245,245,245),
|
||||
(246,246,246),(247,247,247),(248,248,248),(249,249,249),(250,250,250),
|
||||
(251,251,251),(252,252,252),(253,253,253),(254,254,254),(255,255,255),
|
||||
(256,256,256),(257,257,257),(258,258,258),(259,259,259),(260,260,260),
|
||||
(261,261,261),(262,262,262),(263,263,263),(264,264,264),(265,265,265),
|
||||
(266,266,266),(267,267,267),(268,268,268),(269,269,269),(270,270,270),
|
||||
(271,271,271),(272,272,272),(273,273,273),(274,274,274),(275,275,275),
|
||||
(276,276,276),(277,277,277),(278,278,278),(279,279,279),(280,280,280),
|
||||
(281,281,281),(282,282,282),(283,283,283),(284,284,284),(285,285,285),
|
||||
(286,286,286),(287,287,287),(288,288,288),(289,289,289),(290,290,290),
|
||||
(291,291,291),(292,292,292),(293,293,293),(294,294,294),(295,295,295),
|
||||
(296,296,296),(297,297,297),(298,298,298),(299,299,299),(300,300,300),
|
||||
(301,301,301),(302,302,302),(303,303,303),(304,304,304),(305,305,305),
|
||||
(306,306,306),(307,307,307),(308,308,308),(309,309,309),(310,310,310),
|
||||
(311,311,311),(312,312,312),(313,313,313),(314,314,314),(315,315,315),
|
||||
(316,316,316),(317,317,317),(318,318,318),(319,319,319),(320,320,320),
|
||||
(321,321,321),(322,322,322),(323,323,323),(324,324,324),(325,325,325),
|
||||
(326,326,326),(327,327,327),(328,328,328),(329,329,329),(330,330,330),
|
||||
(331,331,331),(332,332,332),(333,333,333),(334,334,334),(335,335,335),
|
||||
(336,336,336),(337,337,337),(338,338,338),(339,339,339),(340,340,340),
|
||||
(341,341,341),(342,342,342),(343,343,343),(344,344,344),(345,345,345),
|
||||
(346,346,346),(347,347,347),(348,348,348),(349,349,349),(350,350,350),
|
||||
(351,351,351),(352,352,352),(353,353,353),(354,354,354),(355,355,355),
|
||||
(356,356,356),(357,357,357),(358,358,358),(359,359,359),(360,360,360),
|
||||
(361,361,361),(362,362,362),(363,363,363),(364,364,364),(365,365,365),
|
||||
(366,366,366),(367,367,367),(368,368,368),(369,369,369),(370,370,370),
|
||||
(371,371,371),(372,372,372),(373,373,373),(374,374,374),(375,375,375),
|
||||
(376,376,376),(377,377,377),(378,378,378),(379,379,379),(380,380,380),
|
||||
(381,381,381),(382,382,382),(383,383,383),(384,384,384),(385,385,385),
|
||||
(386,386,386),(387,387,387),(388,388,388),(389,389,389),(390,390,390),
|
||||
(391,391,391),(392,392,392),(393,393,393),(394,394,394),(395,395,395),
|
||||
(396,396,396),(397,397,397),(398,398,398),(399,399,399),(400,400,400),
|
||||
(401,401,401),(402,402,402),(403,403,403),(404,404,404),(405,405,405),
|
||||
(406,406,406),(407,407,407),(408,408,408),(409,409,409),(410,410,410),
|
||||
(411,411,411),(412,412,412),(413,413,413),(414,414,414),(415,415,415),
|
||||
(416,416,416),(417,417,417),(418,418,418),(419,419,419),(420,420,420),
|
||||
(421,421,421),(422,422,422),(423,423,423),(424,424,424),(425,425,425),
|
||||
(426,426,426),(427,427,427),(428,428,428),(429,429,429),(430,430,430),
|
||||
(431,431,431),(432,432,432),(433,433,433),(434,434,434),(435,435,435),
|
||||
(436,436,436),(437,437,437),(438,438,438),(439,439,439),(440,440,440),
|
||||
(441,441,441),(442,442,442),(443,443,443),(444,444,444),(445,445,445),
|
||||
(446,446,446),(447,447,447),(448,448,448),(449,449,449),(450,450,450),
|
||||
(451,451,451),(452,452,452),(453,453,453),(454,454,454),(455,455,455),
|
||||
(456,456,456),(457,457,457),(458,458,458),(459,459,459),(460,460,460),
|
||||
(461,461,461),(462,462,462),(463,463,463),(464,464,464),(465,465,465),
|
||||
(466,466,466),(467,467,467),(468,468,468),(469,469,469),(470,470,470),
|
||||
(471,471,471),(472,472,472),(473,473,473),(474,474,474),(475,475,475),
|
||||
(476,476,476),(477,477,477),(478,478,478),(479,479,479),(480,480,480),
|
||||
(481,481,481),(482,482,482),(483,483,483),(484,484,484),(485,485,485),
|
||||
(486,486,486),(487,487,487),(488,488,488),(489,489,489),(490,490,490),
|
||||
(491,491,491),(492,492,492),(493,493,493),(494,494,494),(495,495,495),
|
||||
(496,496,496),(497,497,497),(498,498,498),(499,499,499),(500, 500, 500);
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
#
|
||||
# Test error cases with size numbers
|
||||
#
|
||||
--error ER_WRONG_SIZE_NUMBER
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10y
|
||||
engine = ndb;
|
||||
|
||||
--error ER_WRONG_SIZE_NUMBER
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10MB
|
||||
engine=ndb;
|
||||
|
||||
--error 1064
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10 MB
|
||||
engine=ndb;
|
||||
|
||||
--error 1064
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 10 M
|
||||
engine=ndb;
|
||||
|
||||
--error ER_SIZE_OVERFLOW_ERROR
|
||||
CREATE LOGFILE GROUP lg2
|
||||
ADD UNDOFILE 'x.dat'
|
||||
INITIAL_SIZE 1000000000000K
|
||||
engine=ndb;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test update of mm/dd part
|
||||
create table t1 (a int primary key, b char(4) not null, c char(4) not null, key(b)) tablespace ts1 storage disk engine ndb;
|
||||
insert into t1 values (1,'1','1'), (2,'2','2'), (3,'3','3');
|
||||
begin;
|
||||
update t1 set b = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set c = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set b = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
begin;
|
||||
update t1 set c = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set b = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set c = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '6' where b = '5';
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '7' where c = '4';
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '6' where b = '7';
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '7' where c = '6';
|
||||
select * from t1 order by 1;
|
||||
drop table t1;
|
||||
create table t1 (a int primary key, b varchar(4) not null, c char(4) not null, key(b)) tablespace ts1 storage disk engine ndb;
|
||||
insert into t1 values (1,'1','1'), (2,'2','2'), (3,'3','3');
|
||||
begin;
|
||||
update t1 set b = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set c = '2' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set b = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
begin;
|
||||
update t1 set c = '3' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set b = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
update t1 set c = '4' where a = 1;
|
||||
select b from t1 where a = 1;
|
||||
select * from t1 where a = 1;
|
||||
commit;
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '6' where b = '5';
|
||||
select * from t1 order by 1;
|
||||
update t1 set b = '7' where c = '4';
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '5' where a = 1;
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '6' where b = '7';
|
||||
select * from t1 order by 1;
|
||||
update t1 set c = '7' where c = '6';
|
||||
select * from t1 order by 1;
|
||||
drop table t1;
|
||||
|
||||
# Test for blobs...
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) tablespace ts1 storage disk engine=ndbcluster;
|
||||
|
||||
# b1 length 2000+256 (blob part aligned)
|
||||
set @x0 = '01234567012345670123456701234567';
|
||||
set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0);
|
||||
set @b1 = 'b1';
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
|
||||
set @b1 = concat(@b1,@x0);
|
||||
# b2 length 20000
|
||||
set @b2 = 'b2';
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
|
||||
|
||||
insert into t1 values(1,@b1);
|
||||
insert into t1 values(2,@b2);
|
||||
select a,length(b),substr(b,1+2*900,2) from t1 where a=1;
|
||||
select a,length(b),substr(b,1+2*9000,2) from t1 where a=2;
|
||||
update t1 set b=@b2 where a=1;
|
||||
update t1 set b=@b1 where a=2;
|
||||
select a,length(b),substr(b,1+2*9000,2) from t1 where a=1;
|
||||
select a,length(b),substr(b,1+2*900,2) from t1 where a=2;
|
||||
update t1 set b=concat(b,b) where a=1;
|
||||
update t1 set b=concat(b,b) where a=2;
|
||||
select a,length(b),substr(b,1+4*9000,2) from t1 where a=1;
|
||||
select a,length(b),substr(b,1+4*900,2) from t1 where a=2;
|
||||
delete from t1 where a=1;
|
||||
delete from t1 where a=2;
|
||||
select count(*) from t1;
|
||||
drop table t1;
|
||||
|
||||
alter tablespace ts1 drop datafile 'datafile.dat' engine = ndb;
|
||||
alter tablespace ts1 drop datafile 'datafile02.dat' engine = ndb;
|
||||
drop tablespace ts1 engine = ndb;
|
||||
|
||||
drop logfile group lg1 engine = ndb;
|
@ -98,7 +98,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
|
||||
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
|
||||
sp_cache.cc parse_file.cc sql_trigger.cc \
|
||||
sql_plugin.cc sql_binlog.cc \
|
||||
handlerton.cc
|
||||
handlerton.cc sql_tablespace.cc
|
||||
EXTRA_mysqld_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \
|
||||
ha_innodb.h ha_berkeley.h ha_archive.h \
|
||||
ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
|
||||
|
@ -149,6 +149,7 @@ handlerton berkeley_hton = {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
berkeley_flush_logs, /* Flush logs */
|
||||
berkeley_show_status, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@ handlerton blackhole_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CAN_RECREATE
|
||||
};
|
||||
|
||||
|
@ -394,6 +394,7 @@ handlerton federated_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_ALTER_NOT_SUPPORTED
|
||||
};
|
||||
|
||||
|
@ -54,6 +54,7 @@ handlerton heap_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CAN_RECREATE
|
||||
};
|
||||
|
||||
|
@ -86,6 +86,7 @@ handlerton myisam_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CAN_RECREATE
|
||||
};
|
||||
|
||||
|
@ -64,6 +64,7 @@ handlerton myisammrg_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CAN_RECREATE
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@ static int ndbcluster_close_connection(THD *thd);
|
||||
static int ndbcluster_commit(THD *thd, bool all);
|
||||
static int ndbcluster_rollback(THD *thd, bool all);
|
||||
static handler* ndbcluster_create_handler(TABLE_SHARE *table);
|
||||
static int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info);
|
||||
|
||||
handlerton ndbcluster_hton = {
|
||||
MYSQL_HANDLERTON_INTERFACE_VERSION,
|
||||
@ -86,6 +87,7 @@ handlerton ndbcluster_hton = {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
ndbcluster_show_status, /* Show status */
|
||||
ndbcluster_alter_tablespace,
|
||||
HTON_NO_FLAGS
|
||||
};
|
||||
|
||||
@ -4019,13 +4021,8 @@ int ha_ndbcluster::create(const char *name,
|
||||
field->pack_length()));
|
||||
if ((my_errno= create_ndb_column(col, field, info)))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
if (
|
||||
#ifdef NDB_DISKDATA
|
||||
info->store_on_disk ||
|
||||
#else
|
||||
getenv("NDB_DEFAULT_DISK"))
|
||||
#endif
|
||||
|
||||
if (info->store_on_disk || getenv("NDB_DEFAULT_DISK"))
|
||||
col.setStorageType(NdbDictionary::Column::StorageTypeDisk);
|
||||
else
|
||||
col.setStorageType(NdbDictionary::Column::StorageTypeMemory);
|
||||
@ -4045,14 +4042,11 @@ int ha_ndbcluster::create(const char *name,
|
||||
NdbDictionary::Column::StorageTypeMemory);
|
||||
}
|
||||
|
||||
#ifdef NDB_DISKDATA
|
||||
if (info->store_on_disk)
|
||||
if (info->tablespace)
|
||||
tab.setTablespace(info->tablespace);
|
||||
else
|
||||
tab.setTablespace("DEFAULT-TS");
|
||||
#endif
|
||||
|
||||
// No primary key, create shadow key as 64 bit, auto increment
|
||||
if (form->s->primary_key == MAX_KEY)
|
||||
{
|
||||
@ -8315,7 +8309,6 @@ bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *info,
|
||||
return COMPATIBLE_DATA_YES;
|
||||
}
|
||||
|
||||
#ifdef NDB_DISKDATA
|
||||
bool set_up_tablespace(st_alter_tablespace *info,
|
||||
NdbDictionary::Tablespace *ndb_ts)
|
||||
{
|
||||
@ -8356,21 +8349,25 @@ bool set_up_undofile(st_alter_tablespace *info,
|
||||
return false;
|
||||
}
|
||||
|
||||
int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info)
|
||||
{
|
||||
Ndb *ndb;
|
||||
NDBDICT *dict;
|
||||
int error;
|
||||
DBUG_ENTER("ha_ndbcluster::alter_tablespace");
|
||||
if (check_ndb_connection())
|
||||
|
||||
Ndb *ndb= check_ndb_in_thd(thd);
|
||||
if (ndb == NULL)
|
||||
{
|
||||
DBUG_RETURN(my_errno= HA_ERR_NO_CONNECTION);
|
||||
DBUG_RETURN(HA_ERR_NO_CONNECTION);
|
||||
}
|
||||
ndb= get_ndb();
|
||||
dict= ndb->getDictionary();
|
||||
|
||||
NDBDICT *dict = ndb->getDictionary();
|
||||
int error;
|
||||
const char * errmsg;
|
||||
|
||||
switch (info->ts_cmd_type){
|
||||
case (CREATE_TABLESPACE):
|
||||
{
|
||||
error= ER_CREATE_TABLESPACE_FAILED;
|
||||
|
||||
NdbDictionary::Tablespace ndb_ts;
|
||||
NdbDictionary::Datafile ndb_df;
|
||||
if (set_up_tablespace(info, &ndb_ts))
|
||||
@ -8381,23 +8378,24 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (error= dict->createTablespace(ndb_ts))
|
||||
errmsg= "TABLESPACE";
|
||||
if (dict->createTablespace(ndb_ts))
|
||||
{
|
||||
DBUG_PRINT("error", ("createTablespace returned %d", error));
|
||||
my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
DBUG_PRINT("info", ("Successfully created Tablespace"));
|
||||
if (error= dict->createDatafile(ndb_df))
|
||||
errmsg= "DATAFILE";
|
||||
if (dict->createDatafile(ndb_df))
|
||||
{
|
||||
DBUG_PRINT("error", ("createDatafile returned %d", error));
|
||||
my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "DATAFILE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (ALTER_TABLESPACE):
|
||||
{
|
||||
error= ER_ALTER_TABLESPACE_FAILED;
|
||||
if (info->ts_alter_tablespace_type == ALTER_TABLESPACE_ADD_FILE)
|
||||
{
|
||||
NdbDictionary::Datafile ndb_df;
|
||||
@ -8405,11 +8403,10 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (error= dict->createDatafile(ndb_df))
|
||||
errmsg= " CREATE DATAFILE";
|
||||
if (dict->createDatafile(ndb_df))
|
||||
{
|
||||
DBUG_PRINT("error", ("createDatafile returned %d", error));
|
||||
my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), "CREATE DATAFILE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
}
|
||||
else if(info->ts_alter_tablespace_type == ALTER_TABLESPACE_DROP_FILE)
|
||||
@ -8418,11 +8415,10 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
info->data_file_name);
|
||||
if (strcmp(df.getPath(), info->data_file_name) == 0)
|
||||
{
|
||||
if (error= dict->dropDatafile(df))
|
||||
errmsg= " DROP DATAFILE";
|
||||
if (dict->dropDatafile(df))
|
||||
{
|
||||
DBUG_PRINT("error", ("createDatafile returned %d", error));
|
||||
my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), " DROP DATAFILE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -8442,6 +8438,7 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
}
|
||||
case (CREATE_LOGFILE_GROUP):
|
||||
{
|
||||
error= ER_CREATE_TABLESPACE_FAILED;
|
||||
NdbDictionary::LogfileGroup ndb_lg;
|
||||
NdbDictionary::Undofile ndb_uf;
|
||||
if (info->undo_file_name == NULL)
|
||||
@ -8455,27 +8452,26 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (error= dict->createLogfileGroup(ndb_lg))
|
||||
errmsg= "LOGFILE GROUP";
|
||||
if (dict->createLogfileGroup(ndb_lg))
|
||||
{
|
||||
DBUG_PRINT("error", ("createLogfileGroup returned %d", error));
|
||||
my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
DBUG_PRINT("info", ("Successfully created Logfile Group"));
|
||||
if (set_up_undofile(info, &ndb_uf))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (error= dict->createUndofile(ndb_uf))
|
||||
errmsg= "UNDOFILE";
|
||||
if (dict->createUndofile(ndb_uf))
|
||||
{
|
||||
DBUG_PRINT("error", ("createUndofile returned %d", error));
|
||||
my_error(ER_CREATE_TABLESPACE_FAILED, MYF(0), "UNDOFILE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (ALTER_LOGFILE_GROUP):
|
||||
{
|
||||
error= ER_ALTER_TABLESPACE_FAILED;
|
||||
if (info->undo_file_name == NULL)
|
||||
{
|
||||
/*
|
||||
@ -8488,32 +8484,30 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (error= dict->createUndofile(ndb_uf))
|
||||
errmsg= "CREATE UNDOFILE";
|
||||
if (dict->createUndofile(ndb_uf))
|
||||
{
|
||||
DBUG_PRINT("error", ("createUndofile returned %d", error));
|
||||
my_error(ER_ALTER_TABLESPACE_FAILED, MYF(0), "CREATE UNDOFILE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (DROP_TABLESPACE):
|
||||
{
|
||||
if (error= dict->dropTablespace(
|
||||
dict->getTablespace(info->tablespace_name)))
|
||||
error= ER_DROP_TABLESPACE_FAILED;
|
||||
errmsg= "TABLESPACE";
|
||||
if (dict->dropTablespace(dict->getTablespace(info->tablespace_name)))
|
||||
{
|
||||
DBUG_PRINT("error", ("dropTablespace returned %d", error));
|
||||
my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "TABLESPACE");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (DROP_LOGFILE_GROUP):
|
||||
{
|
||||
if (error= dict->dropLogfileGroup(dict->getLogfileGroup(info->logfile_group_name)))
|
||||
error= ER_DROP_TABLESPACE_FAILED;
|
||||
errmsg= "LOGFILE GROUP";
|
||||
if (dict->dropLogfileGroup(dict->getLogfileGroup(info->logfile_group_name)))
|
||||
{
|
||||
DBUG_PRINT("error", ("dropLogfileGroup returned %d", error));
|
||||
my_error(ER_DROP_TABLESPACE_FAILED, MYF(0), "LOGFILE GROUP");
|
||||
DBUG_RETURN(1);
|
||||
goto ndberror;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -8531,6 +8525,13 @@ int ha_ndbcluster::alter_tablespace(st_alter_tablespace *info)
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
ndberror:
|
||||
const NdbError err= dict->getNdbError();
|
||||
ERR_PRINT(err);
|
||||
ndb_to_mysql_error(&err);
|
||||
|
||||
my_error(error, MYF(0), errmsg);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
#endif /* NDB_DISKDATA */
|
||||
|
@ -511,6 +511,7 @@ class ha_ndbcluster: public handler
|
||||
bool eq_range, bool sorted,
|
||||
byte* buf);
|
||||
int read_range_next();
|
||||
int alter_tablespace(st_alter_tablespace *info);
|
||||
|
||||
/**
|
||||
* Multi range stuff
|
||||
|
@ -96,6 +96,7 @@ handlerton partition_hton = {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
|
||||
};
|
||||
|
||||
|
@ -315,6 +315,82 @@ typedef struct xid_t XID;
|
||||
#define MAX_XID_LIST_SIZE (1024*128)
|
||||
#endif
|
||||
|
||||
/*
|
||||
These structures are used to pass information from a set of SQL commands
|
||||
on add/drop/change tablespace definitions to the proper hton.
|
||||
*/
|
||||
#define UNDEF_NODEGROUP 65535
|
||||
enum ts_command_type
|
||||
{
|
||||
TS_CMD_NOT_DEFINED = -1,
|
||||
CREATE_TABLESPACE = 0,
|
||||
ALTER_TABLESPACE = 1,
|
||||
CREATE_LOGFILE_GROUP = 2,
|
||||
ALTER_LOGFILE_GROUP = 3,
|
||||
DROP_TABLESPACE = 4,
|
||||
DROP_LOGFILE_GROUP = 5,
|
||||
CHANGE_FILE_TABLESPACE = 6,
|
||||
ALTER_ACCESS_MODE_TABLESPACE = 7
|
||||
};
|
||||
|
||||
enum ts_alter_tablespace_type
|
||||
{
|
||||
TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
|
||||
ALTER_TABLESPACE_ADD_FILE = 1,
|
||||
ALTER_TABLESPACE_DROP_FILE = 2
|
||||
};
|
||||
|
||||
enum tablespace_access_mode
|
||||
{
|
||||
TS_NOT_DEFINED= -1,
|
||||
TS_READ_ONLY = 0,
|
||||
TS_READ_WRITE = 1,
|
||||
TS_NOT_ACCESSIBLE = 2
|
||||
};
|
||||
|
||||
class st_alter_tablespace : public Sql_alloc
|
||||
{
|
||||
public:
|
||||
const char *tablespace_name;
|
||||
const char *logfile_group_name;
|
||||
enum ts_command_type ts_cmd_type;
|
||||
enum ts_alter_tablespace_type ts_alter_tablespace_type;
|
||||
const char *data_file_name;
|
||||
const char *undo_file_name;
|
||||
const char *redo_file_name;
|
||||
ulonglong extent_size;
|
||||
ulonglong undo_buffer_size;
|
||||
ulonglong redo_buffer_size;
|
||||
ulonglong initial_size;
|
||||
ulonglong autoextend_size;
|
||||
ulonglong max_size;
|
||||
uint nodegroup_id;
|
||||
enum legacy_db_type storage_engine;
|
||||
bool wait_until_completed;
|
||||
const char *ts_comment;
|
||||
enum tablespace_access_mode ts_access_mode;
|
||||
st_alter_tablespace()
|
||||
{
|
||||
tablespace_name= NULL;
|
||||
logfile_group_name= "DEFAULT_LG"; //Default log file group
|
||||
ts_cmd_type= TS_CMD_NOT_DEFINED;
|
||||
data_file_name= NULL;
|
||||
undo_file_name= NULL;
|
||||
redo_file_name= NULL;
|
||||
extent_size= 1024*1024; //Default 1 MByte
|
||||
undo_buffer_size= 8*1024*1024; //Default 8 MByte
|
||||
redo_buffer_size= 8*1024*1024; //Default 8 MByte
|
||||
initial_size= 128*1024*1024; //Default 128 MByte
|
||||
autoextend_size= 0; //No autoextension as default
|
||||
max_size= 0; //Max size == initial size => no extension
|
||||
storage_engine= DB_TYPE_UNKNOWN;
|
||||
nodegroup_id= UNDEF_NODEGROUP;
|
||||
wait_until_completed= TRUE;
|
||||
ts_comment= NULL;
|
||||
ts_access_mode= TS_NOT_DEFINED;
|
||||
}
|
||||
};
|
||||
|
||||
/* The handler for a table type. Will be included in the TABLE structure */
|
||||
|
||||
struct st_table;
|
||||
@ -434,6 +510,7 @@ typedef struct
|
||||
int (*start_consistent_snapshot)(THD *thd);
|
||||
bool (*flush_logs)();
|
||||
bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat);
|
||||
int (*alter_tablespace)(THD *thd, st_alter_tablespace *ts_info);
|
||||
uint32 flags; /* global handler flags */
|
||||
} handlerton;
|
||||
|
||||
@ -732,7 +809,7 @@ typedef struct st_ha_create_information
|
||||
{
|
||||
CHARSET_INFO *table_charset, *default_table_charset;
|
||||
LEX_STRING connect_string;
|
||||
const char *comment,*password;
|
||||
const char *comment,*password, *tablespace;
|
||||
const char *data_file_name, *index_file_name;
|
||||
const char *alias;
|
||||
ulonglong max_rows,min_rows;
|
||||
@ -752,6 +829,7 @@ typedef struct st_ha_create_information
|
||||
bool table_existed; /* 1 in create if table existed */
|
||||
bool frm_only; /* 1 if no ha_create_table() */
|
||||
bool varchar; /* 1 if table has a VARCHAR */
|
||||
bool store_on_disk; /* 1 if table stored on disk */
|
||||
} HA_CREATE_INFO;
|
||||
|
||||
|
||||
@ -830,7 +908,6 @@ typedef struct st_handler_buffer
|
||||
byte *end_of_used_area; /* End of area that was used by handler */
|
||||
} HANDLER_BUFFER;
|
||||
|
||||
|
||||
class handler :public Sql_alloc
|
||||
{
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
|
19
sql/lex.h
19
sql/lex.h
@ -59,6 +59,7 @@ static SYMBOL symbols[] = {
|
||||
{ "<<", SYM(SHIFT_LEFT)},
|
||||
{ ">>", SYM(SHIFT_RIGHT)},
|
||||
{ "<=>", SYM(EQUAL_SYM)},
|
||||
{ "ACCESSIBLE", SYM(ACCESSIBLE_SYM)},
|
||||
{ "ACTION", SYM(ACTION)},
|
||||
{ "ADD", SYM(ADD)},
|
||||
{ "AFTER", SYM(AFTER_SYM)},
|
||||
@ -76,6 +77,7 @@ static SYMBOL symbols[] = {
|
||||
{ "ASENSITIVE", SYM(ASENSITIVE_SYM)},
|
||||
{ "AUTHORS", SYM(AUTHORS_SYM)},
|
||||
{ "AUTO_INCREMENT", SYM(AUTO_INC)},
|
||||
{ "AUTOEXTEND_SIZE", SYM(AUTOEXTEND_SIZE_SYM)},
|
||||
{ "AVG", SYM(AVG_SYM)},
|
||||
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)},
|
||||
{ "BACKUP", SYM(BACKUP_SYM)},
|
||||
@ -141,6 +143,7 @@ static SYMBOL symbols[] = {
|
||||
{ "DATA", SYM(DATA_SYM)},
|
||||
{ "DATABASE", SYM(DATABASE)},
|
||||
{ "DATABASES", SYM(DATABASES)},
|
||||
{ "DATAFILE", SYM(DATAFILE_SYM)},
|
||||
{ "DATE", SYM(DATE_SYM)},
|
||||
{ "DATETIME", SYM(DATETIME)},
|
||||
{ "DAY", SYM(DAY_SYM)},
|
||||
@ -164,6 +167,7 @@ static SYMBOL symbols[] = {
|
||||
{ "DIRECTORY", SYM(DIRECTORY_SYM)},
|
||||
{ "DISABLE", SYM(DISABLE_SYM)},
|
||||
{ "DISCARD", SYM(DISCARD)},
|
||||
{ "DISK", SYM(DISK_SYM)},
|
||||
{ "DISTINCT", SYM(DISTINCT)},
|
||||
{ "DISTINCTROW", SYM(DISTINCT)}, /* Access likes this */
|
||||
{ "DIV", SYM(DIV_SYM)},
|
||||
@ -193,6 +197,7 @@ static SYMBOL symbols[] = {
|
||||
{ "EXPANSION", SYM(EXPANSION_SYM)},
|
||||
{ "EXPLAIN", SYM(DESCRIBE)},
|
||||
{ "EXTENDED", SYM(EXTENDED_SYM)},
|
||||
{ "EXTENT_SIZE", SYM(EXTENT_SIZE_SYM)},
|
||||
{ "FALSE", SYM(FALSE_SYM)},
|
||||
{ "FAST", SYM(FAST_SYM)},
|
||||
{ "FETCH", SYM(FETCH_SYM)},
|
||||
@ -241,6 +246,7 @@ static SYMBOL symbols[] = {
|
||||
{ "INDEX", SYM(INDEX_SYM)},
|
||||
{ "INDEXES", SYM(INDEXES)},
|
||||
{ "INFILE", SYM(INFILE)},
|
||||
{ "INITIAL_SIZE", SYM(INITIAL_SIZE_SYM)},
|
||||
{ "INNER", SYM(INNER_SYM)},
|
||||
{ "INNOBASE", SYM(INNOBASE_SYM)},
|
||||
{ "INNODB", SYM(INNOBASE_SYM)},
|
||||
@ -292,6 +298,7 @@ static SYMBOL symbols[] = {
|
||||
{ "LOCALTIMESTAMP", SYM(NOW_SYM)},
|
||||
{ "LOCK", SYM(LOCK_SYM)},
|
||||
{ "LOCKS", SYM(LOCKS_SYM)},
|
||||
{ "LOGFILE", SYM(LOGFILE_SYM)},
|
||||
{ "LOGS", SYM(LOGS_SYM)},
|
||||
{ "LONG", SYM(LONG_SYM)},
|
||||
{ "LONGBLOB", SYM(LONGBLOB)},
|
||||
@ -317,6 +324,7 @@ static SYMBOL symbols[] = {
|
||||
{ "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR)},
|
||||
{ "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR)},
|
||||
{ "MAX_ROWS", SYM(MAX_ROWS)},
|
||||
{ "MAX_SIZE", SYM(MAX_SIZE_SYM)},
|
||||
{ "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR)},
|
||||
{ "MAX_USER_CONNECTIONS", SYM(MAX_USER_CONNECTIONS_SYM)},
|
||||
{ "MAXVALUE", SYM(MAX_VALUE_SYM)},
|
||||
@ -324,6 +332,7 @@ static SYMBOL symbols[] = {
|
||||
{ "MEDIUMBLOB", SYM(MEDIUMBLOB)},
|
||||
{ "MEDIUMINT", SYM(MEDIUMINT)},
|
||||
{ "MEDIUMTEXT", SYM(MEDIUMTEXT)},
|
||||
{ "MEMORY", SYM(MEMORY_SYM)},
|
||||
{ "MERGE", SYM(MERGE_SYM)},
|
||||
{ "MICROSECOND", SYM(MICROSECOND_SYM)},
|
||||
{ "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */
|
||||
@ -351,7 +360,8 @@ static SYMBOL symbols[] = {
|
||||
{ "NEW", SYM(NEW_SYM)},
|
||||
{ "NEXT", SYM(NEXT_SYM)},
|
||||
{ "NO", SYM(NO_SYM)},
|
||||
{ "NODEGROUP", SYM(NODEGROUP_SYM)},
|
||||
{ "NO_WAIT", SYM(NO_WAIT_SYM)},
|
||||
{ "NODEGROUP", SYM(NODEGROUP_SYM)},
|
||||
{ "NONE", SYM(NONE_SYM)},
|
||||
{ "NOT", SYM(NOT_SYM)},
|
||||
{ "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)},
|
||||
@ -400,9 +410,13 @@ static SYMBOL symbols[] = {
|
||||
{ "RAID_TYPE", SYM(RAID_TYPE)},
|
||||
{ "RANGE", SYM(RANGE_SYM)},
|
||||
{ "READ", SYM(READ_SYM)},
|
||||
{ "READ_ONLY", SYM(READ_ONLY_SYM)},
|
||||
{ "READ_WRITE", SYM(READ_WRITE_SYM)},
|
||||
{ "READS", SYM(READS_SYM)},
|
||||
{ "REAL", SYM(REAL)},
|
||||
{ "RECOVER", SYM(RECOVER_SYM)},
|
||||
{ "REDO_BUFFER_SIZE", SYM(REDO_BUFFER_SIZE_SYM)},
|
||||
{ "REDOFILE", SYM(REDOFILE_SYM)},
|
||||
{ "REDUNDANT", SYM(REDUNDANT_SYM)},
|
||||
{ "REFERENCES", SYM(REFERENCES)},
|
||||
{ "REGEXP", SYM(REGEXP)},
|
||||
@ -522,6 +536,8 @@ static SYMBOL symbols[] = {
|
||||
{ "TYPES", SYM(TYPES_SYM)},
|
||||
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM)},
|
||||
{ "UNDEFINED", SYM(UNDEFINED_SYM)},
|
||||
{ "UNDO_BUFFER_SIZE", SYM(UNDO_BUFFER_SIZE_SYM)},
|
||||
{ "UNDOFILE", SYM(UNDOFILE_SYM)},
|
||||
{ "UNDO", SYM(UNDO_SYM)},
|
||||
{ "UNICODE", SYM(UNICODE_SYM)},
|
||||
{ "UNION", SYM(UNION_SYM)},
|
||||
@ -548,6 +564,7 @@ static SYMBOL symbols[] = {
|
||||
{ "VARCHARACTER", SYM(VARCHAR)},
|
||||
{ "VARIABLES", SYM(VARIABLES)},
|
||||
{ "VARYING", SYM(VARYING)},
|
||||
{ "WAIT", SYM(WAIT_SYM)},
|
||||
{ "WARNINGS", SYM(WARNINGS)},
|
||||
{ "WEEK", SYM(WEEK_SYM)},
|
||||
{ "WHEN", SYM(WHEN_SYM)},
|
||||
|
@ -88,6 +88,7 @@ handlerton binlog_hton = {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
|
||||
};
|
||||
|
||||
|
@ -691,6 +691,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
|
||||
bool mysql_xa_recover(THD *thd);
|
||||
|
||||
bool check_simple_select();
|
||||
int mysql_alter_tablespace(THD* thd, st_alter_tablespace *ts_info);
|
||||
|
||||
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
|
||||
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
|
@ -5727,6 +5727,20 @@ ER_WRONG_VALUE
|
||||
eng "Incorrect %-.32s value: '%-.128s'"
|
||||
ER_NO_PARTITION_FOR_GIVEN_VALUE
|
||||
eng "Table has no partition for value %ld"
|
||||
ER_TABLESPACE_OPTION_ONLY_ONCE
|
||||
eng "It is not allowed to specify %s more than once"
|
||||
ER_CREATE_TABLESPACE_FAILED
|
||||
eng "Failed to create %s"
|
||||
ER_DROP_TABLESPACE_FAILED
|
||||
eng "Failed to drop %s"
|
||||
ER_TABLESPACE_AUTO_EXTEND_ERROR
|
||||
eng "The handler doesn't support autoextend of tablespaces"
|
||||
ER_WRONG_SIZE_NUMBER
|
||||
eng "A size parameter was incorrectly specified, either number or on the form 10M"
|
||||
ER_SIZE_OVERFLOW_ERROR
|
||||
eng "The size number was correct but we don't allow the digit part to be more than 2 billion"
|
||||
ER_ALTER_TABLESPACE_FAILED
|
||||
eng "Failed to alter: %s"
|
||||
ER_BINLOG_ROW_LOGGING_FAILED
|
||||
eng "Writing one row to the row-based binary log failed"
|
||||
ER_BINLOG_ROW_WRONG_TABLE_DEF
|
||||
|
@ -25,6 +25,7 @@ class sp_head;
|
||||
class sp_name;
|
||||
class sp_instr;
|
||||
class sp_pcontext;
|
||||
class st_alter_tablespace;
|
||||
class partition_info;
|
||||
|
||||
/*
|
||||
@ -92,6 +93,7 @@ enum enum_sql_command {
|
||||
SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
|
||||
SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
|
||||
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
|
||||
SQLCOM_ALTER_TABLESPACE,
|
||||
SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
|
||||
SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT,
|
||||
SQLCOM_SHOW_PLUGINS,
|
||||
@ -952,6 +954,12 @@ typedef struct st_lex
|
||||
during replication ("LOCAL 'filename' REPLACE INTO" part).
|
||||
*/
|
||||
const uchar *fname_start, *fname_end;
|
||||
|
||||
/*
|
||||
Reference to a struct that contains information in various commands
|
||||
to add/create/drop/change table spaces.
|
||||
*/
|
||||
st_alter_tablespace *alter_tablespace_info;
|
||||
|
||||
bool escape_used;
|
||||
|
||||
|
@ -4818,6 +4818,12 @@ end_with_restore_list:
|
||||
case SQLCOM_XA_RECOVER:
|
||||
res= mysql_xa_recover(thd);
|
||||
break;
|
||||
case SQLCOM_ALTER_TABLESPACE:
|
||||
if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ? is_schema_db(thd->db) : 0))
|
||||
break;
|
||||
if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SQLCOM_INSTALL_PLUGIN:
|
||||
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
|
||||
&thd->lex->ident)))
|
||||
|
50
sql/sql_tablespace.cc
Normal file
50
sql/sql_tablespace.cc
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2000-2004 MySQL AB
|
||||
|
||||
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; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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 */
|
||||
|
||||
/* drop and alter of tablespaces */
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
||||
int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
|
||||
{
|
||||
int error= HA_ADMIN_NOT_IMPLEMENTED;
|
||||
handlerton *hton;
|
||||
|
||||
DBUG_ENTER("mysql_alter_tablespace");
|
||||
/*
|
||||
If the user haven't defined an engine, this will fallback to using the
|
||||
default storage engine.
|
||||
*/
|
||||
hton= ha_resolve_by_legacy_type(thd, ts_info->storage_engine);
|
||||
|
||||
if (hton->alter_tablespace && (error= hton->alter_tablespace(thd, ts_info)))
|
||||
{
|
||||
if (error == HA_ADMIN_NOT_IMPLEMENTED)
|
||||
{
|
||||
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "");
|
||||
}
|
||||
else if (error == 1)
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(error, MYF(0));
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
460
sql/sql_yacc.yy
460
sql/sql_yacc.yy
@ -119,6 +119,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token END_OF_INPUT
|
||||
|
||||
%token ABORT_SYM
|
||||
%token ACCESSIBLE_SYM
|
||||
%token ACTION
|
||||
%token ADD
|
||||
%token ADDDATE_SYM
|
||||
@ -139,6 +140,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token ATAN
|
||||
%token AUTHORS_SYM
|
||||
%token AUTO_INC
|
||||
%token AUTOEXTEND_SIZE_SYM
|
||||
%token AVG_ROW_LENGTH
|
||||
%token AVG_SYM
|
||||
%token BACKUP_SYM
|
||||
@ -208,6 +210,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token CURTIME
|
||||
%token DATABASE
|
||||
%token DATABASES
|
||||
%token DATAFILE_SYM
|
||||
%token DATA_SYM
|
||||
%token DATETIME
|
||||
%token DATE_ADD_INTERVAL
|
||||
@ -237,6 +240,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token DIRECTORY_SYM
|
||||
%token DISABLE_SYM
|
||||
%token DISCARD
|
||||
%token DISK_SYM
|
||||
%token DISTINCT
|
||||
%token DIV_SYM
|
||||
%token DOUBLE_SYM
|
||||
@ -269,6 +273,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token EXPANSION_SYM
|
||||
%token EXPORT_SET
|
||||
%token EXTENDED_SYM
|
||||
%token EXTENT_SIZE_SYM
|
||||
%token EXTRACT_SYM
|
||||
%token FALSE_SYM
|
||||
%token FAST_SYM
|
||||
@ -331,6 +336,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token INDEXES
|
||||
%token INDEX_SYM
|
||||
%token INFILE
|
||||
%token INITIAL_SIZE_SYM
|
||||
%token INNER_SYM
|
||||
%token INNOBASE_SYM
|
||||
%token INOUT_SYM
|
||||
@ -377,6 +383,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token LOCATOR_SYM
|
||||
%token LOCKS_SYM
|
||||
%token LOCK_SYM
|
||||
%token LOGFILE_SYM
|
||||
%token LOGS_SYM
|
||||
%token LOG_SYM
|
||||
%token LONGBLOB
|
||||
@ -407,6 +414,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token MAX_CONNECTIONS_PER_HOUR
|
||||
%token MAX_QUERIES_PER_HOUR
|
||||
%token MAX_ROWS
|
||||
%token MAX_SIZE_SYM
|
||||
%token MAX_SYM
|
||||
%token MAX_UPDATES_PER_HOUR
|
||||
%token MAX_USER_CONNECTIONS_SYM
|
||||
@ -415,6 +423,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token MEDIUMINT
|
||||
%token MEDIUMTEXT
|
||||
%token MEDIUM_SYM
|
||||
%token MEMORY_SYM
|
||||
%token MERGE_SYM
|
||||
%token MICROSECOND_SYM
|
||||
%token MIGRATE_SYM
|
||||
@ -451,6 +460,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token NOT_SYM
|
||||
%token NOW_SYM
|
||||
%token NO_SYM
|
||||
%token NO_WAIT_SYM
|
||||
%token NO_WRITE_TO_BINLOG
|
||||
%token NULL_SYM
|
||||
%token NUM
|
||||
@ -506,9 +516,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token RAND
|
||||
%token RANGE_SYM
|
||||
%token READS_SYM
|
||||
%token READ_ONLY_SYM
|
||||
%token READ_SYM
|
||||
%token READ_WRITE_SYM
|
||||
%token REAL
|
||||
%token RECOVER_SYM
|
||||
%token REDO_BUFFER_SIZE_SYM
|
||||
%token REDOFILE_SYM
|
||||
%token REDUNDANT_SYM
|
||||
%token REFERENCES
|
||||
%token REGEXP
|
||||
@ -630,6 +644,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token ULONGLONG_NUM
|
||||
%token UNCOMMITTED_SYM
|
||||
%token UNDEFINED_SYM
|
||||
%token UNDO_BUFFER_SIZE_SYM
|
||||
%token UNDOFILE_SYM
|
||||
%token UNDERSCORE_CHARSET
|
||||
%token UNDO_SYM
|
||||
%token UNICODE_SYM
|
||||
@ -660,6 +676,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token VARIANCE_SYM
|
||||
%token VARYING
|
||||
%token VIEW_SYM
|
||||
%token WAIT_SYM
|
||||
%token WARNINGS
|
||||
%token WEEK_SYM
|
||||
%token WHEN_SYM
|
||||
@ -727,7 +744,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
ulong_num raid_types merge_insert_types
|
||||
|
||||
%type <ulonglong_number>
|
||||
ulonglong_num
|
||||
ulonglong_num size_number
|
||||
|
||||
%type <longlong_number>
|
||||
part_bit_expr
|
||||
@ -1296,6 +1313,16 @@ create:
|
||||
{
|
||||
Lex->sql_command = SQLCOM_CREATE_USER;
|
||||
}
|
||||
| CREATE LOGFILE_SYM GROUP logfile_group_info
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
|
||||
}
|
||||
| CREATE TABLESPACE tablespace_info
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
|
||||
}
|
||||
;
|
||||
|
||||
clear_privileges:
|
||||
@ -2538,6 +2565,382 @@ trg_event:
|
||||
| DELETE_SYM
|
||||
{ Lex->trg_chistics.event= TRG_EVENT_DELETE; }
|
||||
;
|
||||
/*
|
||||
This part of the parser contains common code for all TABLESPACE
|
||||
commands.
|
||||
CREATE TABLESPACE name ...
|
||||
ALTER TABLESPACE name CHANGE DATAFILE ...
|
||||
ALTER TABLESPACE name ADD DATAFILE ...
|
||||
ALTER TABLESPACE name access_mode
|
||||
CREATE LOGFILE GROUP name ...
|
||||
ALTER LOGFILE GROUP name ADD UNDOFILE ..
|
||||
ALTER LOGFILE GROUP name ADD REDOFILE ..
|
||||
DROP TABLESPACE name
|
||||
DROP LOGFILE GROUP name
|
||||
*/
|
||||
change_tablespace_access:
|
||||
tablespace_name
|
||||
ts_access_mode
|
||||
;
|
||||
|
||||
change_tablespace_info:
|
||||
tablespace_name
|
||||
CHANGE ts_datafile
|
||||
change_ts_option_list
|
||||
;
|
||||
|
||||
tablespace_info:
|
||||
tablespace_name
|
||||
ADD ts_datafile
|
||||
opt_logfile_group_name
|
||||
tablespace_option_list
|
||||
;
|
||||
|
||||
opt_logfile_group_name:
|
||||
/* empty */ {}
|
||||
| USE_SYM LOGFILE_SYM GROUP ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->logfile_group_name= $4.str;
|
||||
};
|
||||
|
||||
alter_tablespace_info:
|
||||
tablespace_name
|
||||
ADD ts_datafile
|
||||
alter_tablespace_option_list
|
||||
{
|
||||
Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_ADD_FILE;
|
||||
}
|
||||
|
|
||||
tablespace_name
|
||||
DROP ts_datafile
|
||||
alter_tablespace_option_list
|
||||
{
|
||||
Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_DROP_FILE;
|
||||
};
|
||||
|
||||
logfile_group_info:
|
||||
logfile_group_name
|
||||
add_log_file
|
||||
logfile_group_option_list
|
||||
;
|
||||
|
||||
alter_logfile_group_info:
|
||||
logfile_group_name
|
||||
add_log_file
|
||||
alter_logfile_group_option_list
|
||||
;
|
||||
|
||||
add_log_file:
|
||||
ADD lg_undofile
|
||||
| ADD lg_redofile
|
||||
;
|
||||
|
||||
change_ts_option_list:
|
||||
/* empty */ {}
|
||||
change_ts_options
|
||||
;
|
||||
|
||||
change_ts_options:
|
||||
change_ts_option
|
||||
| change_ts_options change_ts_option
|
||||
| change_ts_options ',' change_ts_option
|
||||
;
|
||||
|
||||
change_ts_option:
|
||||
opt_ts_initial_size
|
||||
| opt_ts_autoextend_size
|
||||
| opt_ts_max_size
|
||||
;
|
||||
|
||||
tablespace_option_list:
|
||||
/* empty */ {}
|
||||
tablespace_options
|
||||
;
|
||||
|
||||
tablespace_options:
|
||||
tablespace_option
|
||||
| tablespace_options tablespace_option
|
||||
| tablespace_options ',' tablespace_option
|
||||
;
|
||||
|
||||
tablespace_option:
|
||||
opt_ts_initial_size
|
||||
| opt_ts_autoextend_size
|
||||
| opt_ts_max_size
|
||||
| opt_ts_extent_size
|
||||
| opt_ts_nodegroup
|
||||
| opt_ts_engine
|
||||
| ts_wait
|
||||
| opt_ts_comment
|
||||
;
|
||||
|
||||
alter_tablespace_option_list:
|
||||
/* empty */ {}
|
||||
alter_tablespace_options
|
||||
;
|
||||
|
||||
alter_tablespace_options:
|
||||
alter_tablespace_option
|
||||
| alter_tablespace_options alter_tablespace_option
|
||||
| alter_tablespace_options ',' alter_tablespace_option
|
||||
;
|
||||
|
||||
alter_tablespace_option:
|
||||
opt_ts_initial_size
|
||||
| opt_ts_autoextend_size
|
||||
| opt_ts_max_size
|
||||
| opt_ts_engine
|
||||
| ts_wait
|
||||
;
|
||||
|
||||
logfile_group_option_list:
|
||||
/* empty */ {}
|
||||
logfile_group_options
|
||||
;
|
||||
|
||||
logfile_group_options:
|
||||
logfile_group_option
|
||||
| logfile_group_options logfile_group_option
|
||||
| logfile_group_options ',' logfile_group_option
|
||||
;
|
||||
|
||||
logfile_group_option:
|
||||
opt_ts_initial_size
|
||||
| opt_ts_undo_buffer_size
|
||||
| opt_ts_redo_buffer_size
|
||||
| opt_ts_nodegroup
|
||||
| opt_ts_engine
|
||||
| ts_wait
|
||||
| opt_ts_comment
|
||||
;
|
||||
|
||||
alter_logfile_group_option_list:
|
||||
/* empty */ {}
|
||||
alter_logfile_group_options
|
||||
;
|
||||
|
||||
alter_logfile_group_options:
|
||||
alter_logfile_group_option
|
||||
| alter_logfile_group_options alter_logfile_group_option
|
||||
| alter_logfile_group_options ',' alter_logfile_group_option
|
||||
;
|
||||
|
||||
alter_logfile_group_option:
|
||||
opt_ts_initial_size
|
||||
| opt_ts_engine
|
||||
| ts_wait
|
||||
;
|
||||
|
||||
|
||||
ts_datafile:
|
||||
DATAFILE_SYM TEXT_STRING_sys
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->data_file_name= $2.str;
|
||||
};
|
||||
|
||||
lg_undofile:
|
||||
UNDOFILE_SYM TEXT_STRING_sys
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->undo_file_name= $2.str;
|
||||
};
|
||||
|
||||
lg_redofile:
|
||||
REDOFILE_SYM TEXT_STRING_sys
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->redo_file_name= $2.str;
|
||||
};
|
||||
|
||||
tablespace_name:
|
||||
ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info= new st_alter_tablespace();
|
||||
lex->alter_tablespace_info->tablespace_name= $1.str;
|
||||
lex->sql_command= SQLCOM_ALTER_TABLESPACE;
|
||||
};
|
||||
|
||||
logfile_group_name:
|
||||
ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info= new st_alter_tablespace();
|
||||
lex->alter_tablespace_info->logfile_group_name= $1.str;
|
||||
lex->sql_command= SQLCOM_ALTER_TABLESPACE;
|
||||
};
|
||||
|
||||
ts_access_mode:
|
||||
READ_ONLY_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_access_mode= TS_READ_ONLY;
|
||||
}
|
||||
| READ_WRITE_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_access_mode= TS_READ_WRITE;
|
||||
}
|
||||
| NOT_SYM ACCESSIBLE_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_access_mode= TS_NOT_ACCESSIBLE;
|
||||
};
|
||||
|
||||
opt_ts_initial_size:
|
||||
INITIAL_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->initial_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_autoextend_size:
|
||||
AUTOEXTEND_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->autoextend_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_max_size:
|
||||
MAX_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->max_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_extent_size:
|
||||
EXTENT_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->extent_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_undo_buffer_size:
|
||||
UNDO_BUFFER_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->undo_buffer_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_redo_buffer_size:
|
||||
REDO_BUFFER_SIZE_SYM opt_equal size_number
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->redo_buffer_size= $3;
|
||||
};
|
||||
|
||||
opt_ts_nodegroup:
|
||||
NODEGROUP_SYM opt_equal ulong_num
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)
|
||||
{
|
||||
my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
|
||||
YYABORT;
|
||||
}
|
||||
lex->alter_tablespace_info->nodegroup_id= $3;
|
||||
};
|
||||
|
||||
opt_ts_comment:
|
||||
COMMENT_SYM opt_equal TEXT_STRING_sys
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->alter_tablespace_info->ts_comment != NULL)
|
||||
{
|
||||
my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
|
||||
YYABORT;
|
||||
}
|
||||
lex->alter_tablespace_info->ts_comment= $3.str;
|
||||
};
|
||||
|
||||
opt_ts_engine:
|
||||
opt_storage ENGINE_SYM opt_equal storage_engines
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->alter_tablespace_info->storage_engine != DB_TYPE_UNKNOWN)
|
||||
{
|
||||
my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),
|
||||
"STORAGE ENGINE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->alter_tablespace_info->storage_engine= $4->db_type;
|
||||
};
|
||||
|
||||
opt_ts_wait:
|
||||
/* empty */
|
||||
| ts_wait
|
||||
;
|
||||
|
||||
ts_wait:
|
||||
WAIT_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->wait_until_completed= TRUE;
|
||||
}
|
||||
| NO_WAIT_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (!(lex->alter_tablespace_info->wait_until_completed))
|
||||
{
|
||||
my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
|
||||
YYABORT;
|
||||
}
|
||||
lex->alter_tablespace_info->wait_until_completed= FALSE;
|
||||
};
|
||||
|
||||
size_number:
|
||||
ulong_num { $$= $1;}
|
||||
| IDENT
|
||||
{
|
||||
ulonglong number, test_number;
|
||||
uint text_shift_number= 0;
|
||||
longlong prefix_number;
|
||||
char *end_ptr;
|
||||
char *start_ptr= $1.str;
|
||||
uint str_len= strlen(start_ptr);
|
||||
int error;
|
||||
prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
|
||||
if ((start_ptr + str_len - 1) == end_ptr)
|
||||
{
|
||||
switch (end_ptr[0])
|
||||
{
|
||||
case 'g':
|
||||
case 'G':
|
||||
text_shift_number+=10;
|
||||
case 'm':
|
||||
case 'M':
|
||||
text_shift_number+=10;
|
||||
case 'k':
|
||||
case 'K':
|
||||
text_shift_number+=10;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
if (prefix_number >> 31)
|
||||
{
|
||||
my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0));
|
||||
YYABORT;
|
||||
}
|
||||
number= prefix_number << text_shift_number;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
|
||||
YYABORT;
|
||||
}
|
||||
$$= number;
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
End tablespace part
|
||||
*/
|
||||
|
||||
create2:
|
||||
'(' create2a {}
|
||||
@ -3196,6 +3599,9 @@ create_table_option:
|
||||
| INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
|
||||
| DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; }
|
||||
| INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; }
|
||||
| TABLESPACE ident {Lex->create_info.tablespace= $2.str;}
|
||||
| STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;}
|
||||
| STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;}
|
||||
| CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; }
|
||||
;
|
||||
|
||||
@ -3954,6 +4360,26 @@ alter:
|
||||
}
|
||||
view_list_opt AS view_select view_check_option
|
||||
{}
|
||||
| ALTER TABLESPACE alter_tablespace_info
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
|
||||
}
|
||||
| ALTER LOGFILE_SYM GROUP alter_logfile_group_info
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
|
||||
}
|
||||
| ALTER TABLESPACE change_tablespace_info
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE;
|
||||
}
|
||||
| ALTER TABLESPACE change_tablespace_access
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE;
|
||||
}
|
||||
;
|
||||
|
||||
ident_or_empty:
|
||||
@ -6652,6 +7078,16 @@ drop:
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command= SQLCOM_DROP_TRIGGER;
|
||||
lex->spname= $3;
|
||||
}
|
||||
| DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE;
|
||||
}
|
||||
| DROP LOGFILE_SYM GROUP logfile_group_name opt_ts_engine opt_ts_wait
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
|
||||
}
|
||||
;
|
||||
|
||||
@ -8105,6 +8541,12 @@ TEXT_STRING_literal:
|
||||
|
||||
ident:
|
||||
IDENT_sys { $$=$1; }
|
||||
| READ_ONLY_SYM
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
$$.str= thd->strmake("read_only",9);
|
||||
$$.length= 9;
|
||||
}
|
||||
| keyword
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
@ -8227,6 +8669,7 @@ keyword_sp:
|
||||
| ALGORITHM_SYM {}
|
||||
| ANY_SYM {}
|
||||
| AUTO_INC {}
|
||||
| AUTOEXTEND_SIZE_SYM {}
|
||||
| AVG_ROW_LENGTH {}
|
||||
| AVG_SYM {}
|
||||
| BERKELEY_DB_SYM {}
|
||||
@ -8251,6 +8694,7 @@ keyword_sp:
|
||||
| CONSISTENT_SYM {}
|
||||
| CUBE_SYM {}
|
||||
| DATA_SYM {}
|
||||
| DATAFILE_SYM {}
|
||||
| DATETIME {}
|
||||
| DATE_SYM {}
|
||||
| DAY_SYM {}
|
||||
@ -8259,6 +8703,7 @@ keyword_sp:
|
||||
| DES_KEY_FILE {}
|
||||
| DIRECTORY_SYM {}
|
||||
| DISCARD {}
|
||||
| DISK_SYM {}
|
||||
| DUMPFILE {}
|
||||
| DUPLICATE_SYM {}
|
||||
| DYNAMIC_SYM {}
|
||||
@ -8270,6 +8715,7 @@ keyword_sp:
|
||||
| EVENTS_SYM {}
|
||||
| EXPANSION_SYM {}
|
||||
| EXTENDED_SYM {}
|
||||
| EXTENT_SIZE_SYM {}
|
||||
| FAST_SYM {}
|
||||
| FOUND_SYM {}
|
||||
| DISABLE_SYM {}
|
||||
@ -8291,6 +8737,7 @@ keyword_sp:
|
||||
| INVOKER_SYM {}
|
||||
| IMPORT {}
|
||||
| INDEXES {}
|
||||
| INITIAL_SIZE_SYM {}
|
||||
| ISOLATION {}
|
||||
| ISSUER_SYM {}
|
||||
| INNOBASE_SYM {}
|
||||
@ -8304,6 +8751,7 @@ keyword_sp:
|
||||
| LIST_SYM {}
|
||||
| LOCAL_SYM {}
|
||||
| LOCKS_SYM {}
|
||||
| LOGFILE_SYM {}
|
||||
| LOGS_SYM {}
|
||||
| MAX_ROWS {}
|
||||
| MASTER_SYM {}
|
||||
@ -8323,10 +8771,12 @@ keyword_sp:
|
||||
| MASTER_SSL_KEY_SYM {}
|
||||
| MAX_CONNECTIONS_PER_HOUR {}
|
||||
| MAX_QUERIES_PER_HOUR {}
|
||||
| MAX_SIZE_SYM {}
|
||||
| MAX_UPDATES_PER_HOUR {}
|
||||
| MAX_USER_CONNECTIONS_SYM {}
|
||||
| MAX_VALUE_SYM {}
|
||||
| MEDIUM_SYM {}
|
||||
| MEMORY_SYM {}
|
||||
| MERGE_SYM {}
|
||||
| MICROSECOND_SYM {}
|
||||
| MIGRATE_SYM {}
|
||||
@ -8346,7 +8796,8 @@ keyword_sp:
|
||||
| NDBCLUSTER_SYM {}
|
||||
| NEXT_SYM {}
|
||||
| NEW_SYM {}
|
||||
| NODEGROUP_SYM {}
|
||||
| NO_WAIT_SYM {}
|
||||
| NODEGROUP_SYM {}
|
||||
| NONE_SYM {}
|
||||
| NVARCHAR_SYM {}
|
||||
| OFFSET_SYM {}
|
||||
@ -8373,6 +8824,8 @@ keyword_sp:
|
||||
| RAID_STRIPED_SYM {}
|
||||
| RAID_TYPE {}
|
||||
| RECOVER_SYM {}
|
||||
| REDO_BUFFER_SIZE_SYM {}
|
||||
| REDOFILE_SYM {}
|
||||
| REDUNDANT_SYM {}
|
||||
| RELAY_LOG_FILE_SYM {}
|
||||
| RELAY_LOG_POS_SYM {}
|
||||
@ -8429,6 +8882,8 @@ keyword_sp:
|
||||
| FUNCTION_SYM {}
|
||||
| UNCOMMITTED_SYM {}
|
||||
| UNDEFINED_SYM {}
|
||||
| UNDO_BUFFER_SIZE_SYM {}
|
||||
| UNDOFILE_SYM {}
|
||||
| UNKNOWN_SYM {}
|
||||
| UNTIL_SYM {}
|
||||
| USER {}
|
||||
@ -8437,6 +8892,7 @@ keyword_sp:
|
||||
| VIEW_SYM {}
|
||||
| VALUE_SYM {}
|
||||
| WARNINGS {}
|
||||
| WAIT_SYM {}
|
||||
| WEEK_SYM {}
|
||||
| WORK_SYM {}
|
||||
| X509_SYM {}
|
||||
|
@ -88,6 +88,7 @@ handlerton tina_hton= {
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
NULL, /* Alter Tablespace */
|
||||
HTON_CAN_RECREATE
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,8 @@ public:
|
||||
|
||||
STATIC_CONST( RECORDS_IN_RANGE = 0xFFF8 );
|
||||
STATIC_CONST( DISK_REF = 0xFFF7 );
|
||||
STATIC_CONST( ROWID = 0xFFF6 );
|
||||
STATIC_CONST( ROW_GCI = 0xFFF5 );
|
||||
|
||||
// NOTE: in 5.1 ctors and init take size in bytes
|
||||
|
||||
|
@ -570,10 +570,10 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
|
||||
#define GSN_EVENT_SUBSCRIBE_REQ 458
|
||||
#define GSN_EVENT_SUBSCRIBE_CONF 459
|
||||
#define GSN_EVENT_SUBSCRIBE_REF 460
|
||||
#define GSN_ACC_COM_BLOCK 461
|
||||
#define GSN_ACC_COM_UNBLOCK 462
|
||||
#define GSN_TUP_COM_BLOCK 463
|
||||
#define GSN_TUP_COM_UNBLOCK 464
|
||||
/* 461 unused */
|
||||
/* 462 unused */
|
||||
/* 463 unused */
|
||||
/* 464 unused */
|
||||
|
||||
#define GSN_DUMP_STATE_ORD 465
|
||||
|
||||
|
@ -24,8 +24,9 @@
|
||||
* via ACCKEYCONF.
|
||||
*/
|
||||
class AccLockReq {
|
||||
friend class Dbtux;
|
||||
friend class Dbacc;
|
||||
friend class Dbtup;
|
||||
friend class Dbtux;
|
||||
friend bool printACC_LOCKREQ(FILE *, const Uint32*, Uint32, Uint16);
|
||||
public:
|
||||
enum RequestType { // first byte
|
||||
|
@ -46,7 +46,10 @@ private:
|
||||
Uint32 requestInfo;
|
||||
Uint32 transId1;
|
||||
Uint32 transId2;
|
||||
Uint32 savePointId;
|
||||
union {
|
||||
Uint32 savePointId;
|
||||
Uint32 gci;
|
||||
};
|
||||
|
||||
/**
|
||||
* Previously there where also a scan type
|
||||
@ -58,6 +61,12 @@ private:
|
||||
static void setLockMode(Uint32 & requestInfo, Uint32 lockMode);
|
||||
static void setReadCommittedFlag(Uint32 & requestInfo, Uint32 readCommitted);
|
||||
static void setDescendingFlag(Uint32 & requestInfo, Uint32 descending);
|
||||
|
||||
static Uint32 getNoDiskScanFlag(const Uint32 & requestInfo);
|
||||
static void setNoDiskScanFlag(Uint32 & requestInfo, Uint32 nodisk);
|
||||
|
||||
static Uint32 getNRScanFlag(const Uint32 & requestInfo);
|
||||
static void setNRScanFlag(Uint32 & requestInfo, Uint32 nr);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -66,15 +75,19 @@ private:
|
||||
* l = Lock Mode - 1 Bit 2
|
||||
* h = Read Committed - 1 Bit 5
|
||||
* z = Descending (TUX) - 1 Bit 6
|
||||
* d = No disk scan - 1 Bit 7
|
||||
* n = Node recovery scan - 1 Bit 8
|
||||
*
|
||||
* 1111111111222222222233
|
||||
* 01234567890123456789012345678901
|
||||
* l hz
|
||||
* l hzdn
|
||||
*/
|
||||
#define AS_LOCK_MODE_SHIFT (2)
|
||||
#define AS_LOCK_MODE_MASK (1)
|
||||
#define AS_READ_COMMITTED_SHIFT (5)
|
||||
#define AS_DESCENDING_SHIFT (6)
|
||||
#define AS_NO_DISK_SCAN (7)
|
||||
#define AS_NR_SCAN (8)
|
||||
|
||||
inline
|
||||
Uint32
|
||||
@ -115,6 +128,32 @@ AccScanReq::setDescendingFlag(UintR & requestInfo, UintR val){
|
||||
requestInfo |= (val << AS_DESCENDING_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint32
|
||||
AccScanReq::getNoDiskScanFlag(const Uint32 & requestInfo){
|
||||
return (requestInfo >> AS_NO_DISK_SCAN) & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
AccScanReq::setNoDiskScanFlag(UintR & requestInfo, UintR val){
|
||||
ASSERT_BOOL(val, "AccScanReq::setNoDiskScanFlag");
|
||||
requestInfo |= (val << AS_NO_DISK_SCAN);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint32
|
||||
AccScanReq::getNRScanFlag(const Uint32 & requestInfo){
|
||||
return (requestInfo >> AS_NR_SCAN) & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
AccScanReq::setNRScanFlag(UintR & requestInfo, UintR val){
|
||||
ASSERT_BOOL(val, "AccScanReq::setNoDiskScanFlag");
|
||||
requestInfo |= (val << AS_NR_SCAN);
|
||||
}
|
||||
|
||||
class AccScanConf {
|
||||
/**
|
||||
* Sender(s)
|
||||
|
@ -30,7 +30,7 @@ class CopyFragReq {
|
||||
*/
|
||||
friend class Dblqh;
|
||||
public:
|
||||
STATIC_CONST( SignalLength = 7 );
|
||||
STATIC_CONST( SignalLength = 8 );
|
||||
|
||||
private:
|
||||
Uint32 userPtr;
|
||||
@ -40,6 +40,7 @@ private:
|
||||
Uint32 nodeId;
|
||||
Uint32 schemaVersion;
|
||||
Uint32 distributionKey;
|
||||
Uint32 gci;
|
||||
};
|
||||
|
||||
class CopyFragConf {
|
||||
|
@ -68,9 +68,9 @@ struct CreateFilegroupImplRef {
|
||||
|
||||
enum ErrorCode {
|
||||
NoError = 0,
|
||||
FilegroupAlreadyExists = 1,
|
||||
OutOfFilegroupRecords = 2,
|
||||
OutOfLogBufferMemory = 3
|
||||
FilegroupAlreadyExists = 1502,
|
||||
OutOfFilegroupRecords = 1503,
|
||||
OutOfLogBufferMemory = 1504
|
||||
};
|
||||
|
||||
Uint32 senderData;
|
||||
@ -155,15 +155,15 @@ struct CreateFileImplRef {
|
||||
|
||||
enum ErrorCode {
|
||||
NoError = 0,
|
||||
InvalidFilegroup = 1,
|
||||
InvalidFilegroupVersion = 2,
|
||||
FileNoAlreadyExists = 3,
|
||||
OutOfFileRecords = 4,
|
||||
FileError = 5,
|
||||
InvalidFileMetadata = 6,
|
||||
OutOfMemory = 7,
|
||||
FileReadError = 8,
|
||||
FilegroupNotOnline = 9
|
||||
InvalidFilegroup = 1505,
|
||||
InvalidFilegroupVersion = 1506,
|
||||
FileNoAlreadyExists = 1507,
|
||||
OutOfFileRecords = 1508,
|
||||
FileError = 1509,
|
||||
InvalidFileMetadata = 1510,
|
||||
OutOfMemory = 1511,
|
||||
FileReadError = 1512,
|
||||
FilegroupNotOnline = 1513
|
||||
};
|
||||
|
||||
Uint32 senderData;
|
||||
|
@ -122,6 +122,10 @@ public:
|
||||
FragmentData = 130, // CREATE_FRAGMENTATION reply
|
||||
TablespaceId = 131,
|
||||
TablespaceVersion = 132,
|
||||
|
||||
RowGCIFlag = 150,
|
||||
RowChecksumFlag = 151,
|
||||
|
||||
TableEnd = 999,
|
||||
|
||||
AttributeName = 1000, // String, Mandatory
|
||||
@ -300,6 +304,9 @@ public:
|
||||
Uint32 FragmentDataLen;
|
||||
Uint16 FragmentData[(MAX_FRAGMENT_DATA_BYTES+1)/2];
|
||||
|
||||
Uint32 RowGCIFlag;
|
||||
Uint32 RowChecksumFlag;
|
||||
|
||||
void init();
|
||||
};
|
||||
|
||||
@ -609,7 +616,9 @@ struct DictFilegroupInfo {
|
||||
LF_UndoGrowSizeHi = 2001,
|
||||
LF_UndoGrowSizeLo = 2002,
|
||||
LF_UndoGrowPattern = 2003,
|
||||
LF_UndoGrowMaxSize = 2004
|
||||
LF_UndoGrowMaxSize = 2004,
|
||||
LF_UndoFreeWordsHi = 2006,
|
||||
LF_UndoFreeWordsLo = 2007
|
||||
};
|
||||
|
||||
// FragmentType constants
|
||||
@ -645,6 +654,8 @@ struct DictFilegroupInfo {
|
||||
GrowSpec LF_UndoGrow;
|
||||
};
|
||||
//GrowSpec LF_RedoGrow;
|
||||
Uint32 LF_UndoFreeWordsHi;
|
||||
Uint32 LF_UndoFreeWordsLo;
|
||||
void init();
|
||||
};
|
||||
static const Uint32 MappingSize;
|
||||
|
@ -69,7 +69,8 @@ private:
|
||||
ZSEND_END_TO = 41,
|
||||
|
||||
WAIT_DROP_TAB_WRITING_TO_FILE = 42,
|
||||
CHECK_WAIT_DROP_TAB_FAILED_LQH = 43
|
||||
CHECK_WAIT_DROP_TAB_FAILED_LQH = 43,
|
||||
ZTO_START_FRAGMENTS = 44
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -112,10 +112,14 @@ public:
|
||||
public:
|
||||
Uint32 senderData;
|
||||
Uint32 tableId;
|
||||
Uint32 gci; // For table
|
||||
union {
|
||||
Uint32 gci; // For table
|
||||
Uint32 freeWordsHi; // for logfile group m_free_file_words
|
||||
};
|
||||
union {
|
||||
Uint32 totalLen; // In words
|
||||
Uint32 freeExtents;
|
||||
Uint32 freeWordsLo; // for logfile group m_free_file_words
|
||||
};
|
||||
Uint32 tableType;
|
||||
Uint32 senderRef;
|
||||
|
@ -33,7 +33,7 @@ class AddFragReq {
|
||||
friend bool printADD_FRAG_REQ(FILE *, const Uint32 *, Uint32, Uint16);
|
||||
|
||||
public:
|
||||
STATIC_CONST( SignalLength = 9 );
|
||||
STATIC_CONST( SignalLength = 10 );
|
||||
|
||||
enum RequestInfo {
|
||||
CreateInRunning = 0x8000000,
|
||||
@ -49,6 +49,7 @@ private:
|
||||
Uint32 nodeId;
|
||||
Uint32 totalFragments;
|
||||
Uint32 startGci;
|
||||
Uint32 logPartId;
|
||||
};
|
||||
|
||||
class AddFragRef {
|
||||
@ -104,7 +105,7 @@ class LqhFragReq {
|
||||
friend bool printLQH_FRAG_REQ(FILE *, const Uint32 *, Uint32, Uint16);
|
||||
|
||||
public:
|
||||
STATIC_CONST( SignalLength = 19 );
|
||||
STATIC_CONST( SignalLength = 20 );
|
||||
|
||||
enum RequestInfo {
|
||||
CreateInRunning = 0x8000000,
|
||||
@ -137,6 +138,7 @@ private:
|
||||
Uint16 noOfKeyAttr;
|
||||
Uint8 checksumIndicator;
|
||||
Uint8 GCPIndicator;
|
||||
Uint32 logPartId;
|
||||
};
|
||||
|
||||
class LqhFragConf {
|
||||
|
@ -127,6 +127,18 @@ private:
|
||||
static void setApplicationAddressFlag(UintR & requestInfo, UintR val);
|
||||
static void setMarkerFlag(UintR & requestInfo, UintR val);
|
||||
static void setNoDiskFlag(UintR & requestInfo, UintR val);
|
||||
|
||||
static UintR getRowidFlag(const UintR & requestInfo);
|
||||
static void setRowidFlag(UintR & requestInfo, UintR val);
|
||||
|
||||
/**
|
||||
* When doing DIRTY WRITES
|
||||
*/
|
||||
static UintR getGCIFlag(const UintR & requestInfo);
|
||||
static void setGCIFlag(UintR & requestInfo, UintR val);
|
||||
|
||||
static UintR getNrCopyFlag(const UintR & requestInfo);
|
||||
static void setNrCopyFlag(UintR & requestInfo, UintR val);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -134,7 +146,9 @@ private:
|
||||
*
|
||||
* k = Key len - 10 Bits (0-9) max 1023
|
||||
* l = Last Replica No - 2 Bits -> Max 3 (10-11)
|
||||
* t = Lock type - 3 Bits -> Max 7 (12-14)
|
||||
|
||||
IF version < NDBD_ROWID_VERSION
|
||||
* t = Lock type - 3 Bits -> Max 7 (12-14)
|
||||
* p = Application Addr. Ind - 1 Bit (15)
|
||||
* d = Dirty indicator - 1 Bit (16)
|
||||
* i = Interpreted indicator - 1 Bit (17)
|
||||
@ -146,11 +160,14 @@ private:
|
||||
* u = Read Len Return Ind - 1 Bit (28)
|
||||
* m = Commit ack marker - 1 Bit (29)
|
||||
* x = No disk usage - 1 Bit (30)
|
||||
* - = Unused - 2 Bit (31)
|
||||
*
|
||||
* 1111111111222222222233
|
||||
* 01234567890123456789012345678901
|
||||
* kkkkkkkkkklltttpdisooorraaacumx-
|
||||
* z = Use rowid for insert - 1 Bit (31)
|
||||
* g = gci flag - 1 Bit (12)
|
||||
* n = NR copy - 1 Bit (13)
|
||||
|
||||
* 1111111111222222222233
|
||||
* 01234567890123456789012345678901
|
||||
* kkkkkkkkkklltttpdisooorraaacumxz
|
||||
* kkkkkkkkkkllgn pdisooorraaacumxz
|
||||
*/
|
||||
|
||||
#define RI_KEYLEN_SHIFT (0)
|
||||
@ -173,6 +190,9 @@ private:
|
||||
#define RI_RETURN_AI_SHIFT (28)
|
||||
#define RI_MARKER_SHIFT (29)
|
||||
#define RI_NODISK_SHIFT (30)
|
||||
#define RI_ROWID_SHIFT (31)
|
||||
#define RI_GCI_SHIFT (12)
|
||||
#define RI_NR_COPY_SHIFT (13)
|
||||
|
||||
/**
|
||||
* Scan Info
|
||||
@ -482,6 +502,45 @@ LqhKeyReq::getNoDiskFlag(const UintR & requestInfo){
|
||||
return (requestInfo >> RI_NODISK_SHIFT) & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
LqhKeyReq::setRowidFlag(UintR & requestInfo, UintR val){
|
||||
ASSERT_BOOL(val, "LqhKeyReq::setRowidFlag");
|
||||
requestInfo |= (val << RI_ROWID_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
UintR
|
||||
LqhKeyReq::getRowidFlag(const UintR & requestInfo){
|
||||
return (requestInfo >> RI_ROWID_SHIFT) & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
LqhKeyReq::setGCIFlag(UintR & requestInfo, UintR val){
|
||||
ASSERT_BOOL(val, "LqhKeyReq::setGciFlag");
|
||||
requestInfo |= (val << RI_GCI_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
UintR
|
||||
LqhKeyReq::getGCIFlag(const UintR & requestInfo){
|
||||
return (requestInfo >> RI_GCI_SHIFT) & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
LqhKeyReq::setNrCopyFlag(UintR & requestInfo, UintR val){
|
||||
ASSERT_BOOL(val, "LqhKeyReq::setNrCopyFlag");
|
||||
requestInfo |= (val << RI_NR_COPY_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
UintR
|
||||
LqhKeyReq::getNrCopyFlag(const UintR & requestInfo){
|
||||
return (requestInfo >> RI_NR_COPY_SHIFT) & 1;
|
||||
}
|
||||
|
||||
class LqhKeyConf {
|
||||
/**
|
||||
* Reciver(s)
|
||||
|
@ -33,14 +33,6 @@ public:
|
||||
ZSCAN_CLOSE = 6,
|
||||
ZSCAN_NEXT_ABORT = 12
|
||||
};
|
||||
enum CopyFlag {
|
||||
todo_ZCOPY_NEXT = 1,
|
||||
todo_ZCOPY_NEXT_COMMIT = 2,
|
||||
todo_ZCOPY_COMMIT = 3,
|
||||
todo_ZCOPY_REPEAT = 4,
|
||||
todo_ZCOPY_ABORT = 5,
|
||||
todo_ZCOPY_CLOSE = 6
|
||||
};
|
||||
STATIC_CONST( SignalLength = 3 );
|
||||
private:
|
||||
Uint32 accPtr; // scan record in ACC/TUX
|
||||
@ -62,8 +54,7 @@ private:
|
||||
Uint32 fragId;
|
||||
Uint32 localKey[2];
|
||||
Uint32 localKeyLength;
|
||||
Uint32 keyLength;
|
||||
Uint32 key[4];
|
||||
Uint32 gci;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@ class TupKeyReq {
|
||||
friend bool printTUPKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
|
||||
|
||||
public:
|
||||
STATIC_CONST( SignalLength = 16 );
|
||||
STATIC_CONST( SignalLength = 18 );
|
||||
|
||||
private:
|
||||
|
||||
@ -59,6 +59,8 @@ private:
|
||||
Uint32 tcOpIndex;
|
||||
Uint32 savePointId;
|
||||
Uint32 disk_page;
|
||||
Uint32 m_row_id_page_no;
|
||||
Uint32 m_row_id_page_idx;
|
||||
};
|
||||
|
||||
class TupKeyConf {
|
||||
@ -78,7 +80,7 @@ class TupKeyConf {
|
||||
friend bool printTUPKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
|
||||
|
||||
public:
|
||||
STATIC_CONST( SignalLength = 5 );
|
||||
STATIC_CONST( SignalLength = 6 );
|
||||
|
||||
private:
|
||||
|
||||
@ -90,6 +92,7 @@ private:
|
||||
Uint32 writeLength;
|
||||
Uint32 noFiredTriggers;
|
||||
Uint32 lastRow;
|
||||
Uint32 rowid;
|
||||
};
|
||||
|
||||
class TupKeyRef {
|
||||
|
@ -57,6 +57,10 @@ char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ];
|
||||
*/
|
||||
/*#define NDB_VERSION_ID 0*/
|
||||
|
||||
/**
|
||||
* From which version do we support rowid
|
||||
*/
|
||||
#define NDBD_ROWID_VERSION (MAKE_VERSION(5,1,6))
|
||||
#define NDBD_INCL_NODECONF_VERSION_4 MAKE_VERSION(4,1,17)
|
||||
#define NDBD_INCL_NODECONF_VERSION_5 MAKE_VERSION(5,0,18)
|
||||
|
||||
|
@ -93,7 +93,9 @@ public:
|
||||
* Get version of object
|
||||
*/
|
||||
virtual int getObjectVersion() const = 0;
|
||||
|
||||
|
||||
virtual int getObjectId() const = 0;
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*/
|
||||
@ -501,6 +503,8 @@ public:
|
||||
static const Column * RANGE_NO;
|
||||
static const Column * DISK_REF;
|
||||
static const Column * RECORDS_IN_RANGE;
|
||||
static const Column * ROWID;
|
||||
static const Column * ROW_GCI;
|
||||
|
||||
int getSizeInBytes() const;
|
||||
#endif
|
||||
@ -751,6 +755,7 @@ public:
|
||||
void setTablespace(const char * name);
|
||||
void setTablespace(const class Tablespace &);
|
||||
const char * getTablespace() const;
|
||||
Uint32 getTablespaceId() const;
|
||||
|
||||
/**
|
||||
* Get table object type
|
||||
@ -767,6 +772,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
/**
|
||||
* Set frm file to store with this table
|
||||
*/
|
||||
@ -784,6 +794,15 @@ public:
|
||||
|
||||
/** @} *******************************************************************/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void setRowGCIIndicator(bool value);
|
||||
bool getRowGCIIndicator() const;
|
||||
|
||||
void setRowChecksumIndicator(bool value);
|
||||
bool getRowChecksumIndicator() const;
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
const char *getMysqlName() const;
|
||||
|
||||
@ -887,6 +906,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
/** @} *******************************************************************/
|
||||
|
||||
/**
|
||||
@ -1157,6 +1181,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
void print();
|
||||
#endif
|
||||
@ -1183,6 +1212,7 @@ public:
|
||||
class LogfileGroup : public Object {
|
||||
public:
|
||||
LogfileGroup();
|
||||
LogfileGroup(const LogfileGroup&);
|
||||
virtual ~LogfileGroup();
|
||||
|
||||
void setName(const char * name);
|
||||
@ -1194,6 +1224,8 @@ public:
|
||||
void setAutoGrowSpecification(const AutoGrowSpecification&);
|
||||
const AutoGrowSpecification& getAutoGrowSpecification() const;
|
||||
|
||||
Uint64 getUndoFreeWords() const;
|
||||
|
||||
/**
|
||||
* Get object status
|
||||
*/
|
||||
@ -1204,6 +1236,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
private:
|
||||
friend class NdbDictionaryImpl;
|
||||
friend class NdbLogfileGroupImpl;
|
||||
@ -1217,6 +1254,7 @@ public:
|
||||
class Tablespace : public Object {
|
||||
public:
|
||||
Tablespace();
|
||||
Tablespace(const Tablespace&);
|
||||
virtual ~Tablespace();
|
||||
|
||||
void setName(const char * name);
|
||||
@ -1230,7 +1268,9 @@ public:
|
||||
|
||||
void setDefaultLogfileGroup(const char * name);
|
||||
void setDefaultLogfileGroup(const class LogfileGroup&);
|
||||
|
||||
const char * getDefaultLogfileGroup() const;
|
||||
Uint32 getDefaultLogfileGroupId() const;
|
||||
|
||||
/**
|
||||
* Get object status
|
||||
@ -1242,6 +1282,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
private:
|
||||
friend class NdbTablespaceImpl;
|
||||
class NdbTablespaceImpl & m_impl;
|
||||
@ -1251,6 +1296,7 @@ public:
|
||||
class Datafile : public Object {
|
||||
public:
|
||||
Datafile();
|
||||
Datafile(const Datafile&);
|
||||
virtual ~Datafile();
|
||||
|
||||
void setPath(const char * name);
|
||||
@ -1263,6 +1309,7 @@ public:
|
||||
void setTablespace(const char * name);
|
||||
void setTablespace(const class Tablespace &);
|
||||
const char * getTablespace() const;
|
||||
Uint32 getTablespaceId() const;
|
||||
|
||||
void setNode(Uint32 nodeId);
|
||||
Uint32 getNode() const;
|
||||
@ -1279,6 +1326,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
private:
|
||||
friend class NdbDatafileImpl;
|
||||
class NdbDatafileImpl & m_impl;
|
||||
@ -1288,6 +1340,7 @@ public:
|
||||
class Undofile : public Object {
|
||||
public:
|
||||
Undofile();
|
||||
Undofile(const Undofile&);
|
||||
virtual ~Undofile();
|
||||
|
||||
void setPath(const char * path);
|
||||
@ -1295,11 +1348,11 @@ public:
|
||||
|
||||
void setSize(Uint64);
|
||||
Uint64 getSize() const;
|
||||
Uint64 getFree() const;
|
||||
|
||||
void setLogfileGroup(const char * name);
|
||||
void setLogfileGroup(const class LogfileGroup &);
|
||||
const char * getLogfileGroup() const;
|
||||
Uint32 getLogfileGroupId() const;
|
||||
|
||||
void setNode(Uint32 nodeId);
|
||||
Uint32 getNode() const;
|
||||
@ -1316,6 +1369,11 @@ public:
|
||||
*/
|
||||
virtual int getObjectVersion() const;
|
||||
|
||||
/**
|
||||
* Get object id
|
||||
*/
|
||||
virtual int getObjectId() const;
|
||||
|
||||
private:
|
||||
friend class NdbUndofileImpl;
|
||||
class NdbUndofileImpl & m_impl;
|
||||
|
@ -18,6 +18,19 @@
|
||||
#ifndef CLUSTER_CONNECTION_HPP
|
||||
#define CLUSTER_CONNECTION_HPP
|
||||
|
||||
class Ndb_cluster_connection_node_iter
|
||||
{
|
||||
friend class Ndb_cluster_connection_impl;
|
||||
public:
|
||||
Ndb_cluster_connection_node_iter() : scan_state(~0),
|
||||
init_pos(0),
|
||||
cur_pos(0) {};
|
||||
private:
|
||||
unsigned char scan_state;
|
||||
unsigned char init_pos;
|
||||
unsigned char cur_pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Ndb_cluster_connection
|
||||
* @brief Represents a connection to a cluster of storage nodes.
|
||||
@ -88,6 +101,9 @@ public:
|
||||
|
||||
unsigned no_db_nodes();
|
||||
unsigned node_id();
|
||||
|
||||
void init_get_next_node(Ndb_cluster_connection_node_iter &iter);
|
||||
unsigned int get_next_node(Ndb_cluster_connection_node_iter &iter);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -47,6 +47,11 @@ public:
|
||||
*/
|
||||
static void set(unsigned size, Uint32 data[]);
|
||||
|
||||
/**
|
||||
* set bit from <em>start</em> to <em>last</em>
|
||||
*/
|
||||
static void set_range(unsigned size, Uint32 data[], unsigned start, unsigned last);
|
||||
|
||||
/**
|
||||
* assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
|
||||
*/
|
||||
@ -62,6 +67,11 @@ public:
|
||||
*/
|
||||
static void clear(unsigned size, Uint32 data[]);
|
||||
|
||||
/**
|
||||
* clear bit from <em>start</em> to <em>last</em>
|
||||
*/
|
||||
static void clear_range(unsigned size, Uint32 data[], unsigned start, unsigned last);
|
||||
|
||||
static Uint32 getWord(unsigned size, Uint32 data[], unsigned word_pos);
|
||||
static void setWord(unsigned size, Uint32 data[],
|
||||
unsigned word_pos, Uint32 new_word);
|
||||
@ -184,6 +194,34 @@ BitmaskImpl::set(unsigned size, Uint32 data[])
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
BitmaskImpl::set_range(unsigned size, Uint32 data[],
|
||||
unsigned start, unsigned last)
|
||||
{
|
||||
Uint32 *ptr = data + (start >> 5);
|
||||
Uint32 *end = data + (last >> 5);
|
||||
assert(start <= last);
|
||||
assert(last < (size << 5));
|
||||
|
||||
Uint32 tmp_word = ~(Uint32)0 << (start & 31);
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
* ptr ++ |= tmp_word;
|
||||
|
||||
for(; ptr < end; )
|
||||
{
|
||||
* ptr ++ = ~(Uint32)0;
|
||||
}
|
||||
|
||||
tmp_word = ~(Uint32)0;
|
||||
}
|
||||
|
||||
tmp_word &= ~(~(Uint32)0 << (last & 31));
|
||||
|
||||
* ptr |= tmp_word;
|
||||
}
|
||||
|
||||
inline void
|
||||
BitmaskImpl::assign(unsigned size, Uint32 dst[], const Uint32 src[])
|
||||
{
|
||||
@ -207,6 +245,34 @@ BitmaskImpl::clear(unsigned size, Uint32 data[])
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
BitmaskImpl::clear_range(unsigned size, Uint32 data[],
|
||||
unsigned start, unsigned last)
|
||||
{
|
||||
Uint32 *ptr = data + (start >> 5);
|
||||
Uint32 *end = data + (last >> 5);
|
||||
assert(start <= last);
|
||||
assert(last < (size << 5));
|
||||
|
||||
Uint32 tmp_word = ~(Uint32)0 << (start & 31);
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
* ptr ++ &= ~tmp_word;
|
||||
|
||||
for(; ptr < end; )
|
||||
{
|
||||
* ptr ++ = 0;
|
||||
}
|
||||
|
||||
tmp_word = ~(Uint32)0;
|
||||
}
|
||||
|
||||
tmp_word &= ~(~(Uint32)0 << (last & 31));
|
||||
|
||||
* ptr &= ~tmp_word;
|
||||
}
|
||||
|
||||
inline
|
||||
Uint32
|
||||
BitmaskImpl::getWord(unsigned size, Uint32 data[], unsigned word_pos)
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
unsigned size() const { return m_size; };
|
||||
|
||||
void push_back(const T &);
|
||||
void push(const T&, unsigned pos);
|
||||
T& set(T&, unsigned pos, T& fill_obj);
|
||||
T& back();
|
||||
|
||||
void erase(unsigned index);
|
||||
@ -104,6 +106,31 @@ Vector<T>::push_back(const T & t){
|
||||
m_size++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
Vector<T>::push(const T & t, unsigned pos)
|
||||
{
|
||||
push_back(t);
|
||||
if (pos < m_size - 1)
|
||||
{
|
||||
for(unsigned i = m_size - 1; i > pos; i--)
|
||||
{
|
||||
m_items[i] = m_items[i-1];
|
||||
}
|
||||
m_items[pos] = t;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T&
|
||||
Vector<T>::set(T & t, unsigned pos, T& fill_obj)
|
||||
{
|
||||
fill(pos, fill_obj);
|
||||
T& ret = m_items[pos];
|
||||
m_items[pos] = t;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
Vector<T>::erase(unsigned i){
|
||||
|
@ -49,6 +49,8 @@ DictTabInfo::TableMapping[] = {
|
||||
DTIMAPB(Table, FragmentData, FragmentData, 0, MAX_FRAGMENT_DATA_BYTES, FragmentDataLen),
|
||||
DTIMAP(Table, TablespaceId, TablespaceId),
|
||||
DTIMAP(Table, TablespaceVersion, TablespaceVersion),
|
||||
DTIMAP(Table, RowGCIFlag, RowGCIFlag),
|
||||
DTIMAP(Table, RowChecksumFlag, RowChecksumFlag),
|
||||
DTIBREAK(AttributeName)
|
||||
};
|
||||
|
||||
@ -128,6 +130,9 @@ DictTabInfo::Table::init(){
|
||||
memset(FragmentData, 0, sizeof(FragmentData));
|
||||
TablespaceId = RNIL;
|
||||
TablespaceVersion = ~0;
|
||||
|
||||
RowGCIFlag = ~0;
|
||||
RowChecksumFlag = ~0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -174,7 +179,9 @@ DictFilegroupInfo::Mapping[] = {
|
||||
DFGIMAP(Filegroup, LF_UndoGrowSizeLo, LF_UndoGrow.GrowSizeLo),
|
||||
DFGIMAPS(Filegroup, LF_UndoGrowPattern, LF_UndoGrow.GrowPattern, 0,PATH_MAX),
|
||||
DFGIMAP(Filegroup, LF_UndoGrowMaxSize, LF_UndoGrow.GrowMaxSize),
|
||||
|
||||
DFGIMAP(Filegroup, LF_UndoFreeWordsHi, LF_UndoFreeWordsHi),
|
||||
DFGIMAP(Filegroup, LF_UndoFreeWordsLo, LF_UndoFreeWordsLo),
|
||||
|
||||
DFGIBREAK(FileName)
|
||||
};
|
||||
|
||||
|
@ -36,5 +36,6 @@ printFSCLOSEREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv
|
||||
else
|
||||
fprintf(output, "Don't remove file");
|
||||
fprintf(output, "\n");
|
||||
return true;
|
||||
|
||||
return len == 4;
|
||||
}
|
||||
|
@ -51,6 +51,12 @@ printLQHKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receive
|
||||
fprintf(output, "CommitAckMarker ");
|
||||
if(LqhKeyReq::getNoDiskFlag(reqInfo))
|
||||
fprintf(output, "NoDisk ");
|
||||
if(LqhKeyReq::getRowidFlag(reqInfo))
|
||||
fprintf(output, "Rowid ");
|
||||
if(LqhKeyReq::getNrCopyFlag(reqInfo))
|
||||
fprintf(output, "NrCopy ");
|
||||
if(LqhKeyReq::getGCIFlag(reqInfo))
|
||||
fprintf(output, "GCI ");
|
||||
|
||||
fprintf(output, "ScanInfo/noFiredTriggers: H\'%x\n", sig->scanInfo);
|
||||
|
||||
@ -119,6 +125,20 @@ printLQHKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receive
|
||||
fprintf(output, "H\'%.8x ", sig->variableData[nextPos]);
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
if (LqhKeyReq::getRowidFlag(reqInfo))
|
||||
{
|
||||
fprintf(output, " Rowid: [ page: %d idx: %d ]\n",
|
||||
sig->variableData[nextPos + 0],
|
||||
sig->variableData[nextPos + 1]);
|
||||
nextPos += 2;
|
||||
}
|
||||
|
||||
if (LqhKeyReq::getGCIFlag(reqInfo))
|
||||
{
|
||||
fprintf(output, " GCI: %u", sig->variableData[nextPos + 0]);
|
||||
nextPos++;
|
||||
}
|
||||
|
||||
if(!LqhKeyReq::getInterpretedFlag(reqInfo)){
|
||||
fprintf(output, " AttrInfo: ");
|
||||
|
@ -363,10 +363,6 @@ const GsnName SignalNames [] = {
|
||||
,{ GSN_EVENT_SUBSCRIBE_REQ, "EVENT_SUBSCRIBE_REQ" }
|
||||
,{ GSN_EVENT_SUBSCRIBE_CONF, "EVENT_SUBSCRIBE_CONF" }
|
||||
,{ GSN_EVENT_SUBSCRIBE_REF, "EVENT_SUBSCRIBE_REF" }
|
||||
,{ GSN_ACC_COM_BLOCK, "ACC_COM_BLOCK" }
|
||||
,{ GSN_ACC_COM_UNBLOCK, "ACC_COM_UNBLOCK" }
|
||||
,{ GSN_TUP_COM_BLOCK, "TUP_COM_BLOCK" }
|
||||
,{ GSN_TUP_COM_UNBLOCK, "TUP_COM_UNBLOCK" }
|
||||
,{ GSN_DUMP_STATE_ORD, "DUMP_STATE_ORD" }
|
||||
|
||||
,{ GSN_START_INFOREQ, "START_INFOREQ" }
|
||||
|
@ -16,8 +16,6 @@ void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __TEST_BITMASK__
|
||||
|
||||
void
|
||||
BitmaskImpl::getFieldImpl(const Uint32 src[],
|
||||
unsigned shiftL, unsigned len, Uint32 dst[])
|
||||
@ -78,7 +76,7 @@ BitmaskImpl::setFieldImpl(Uint32 dst[],
|
||||
* dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef __TEST_BITMASK__
|
||||
|
||||
#define DEBUG 0
|
||||
#include <Vector.hpp>
|
||||
@ -342,6 +340,74 @@ do_test(int bitmask_size)
|
||||
alloc_list.push_back(a);
|
||||
}
|
||||
}
|
||||
|
||||
for(Uint32 i = 0; i<1000; i++)
|
||||
{
|
||||
Uint32 sz32 = 10+rand() % 100;
|
||||
Uint32 zero = 0;
|
||||
Vector<Uint32> map;
|
||||
map.fill(sz32, zero);
|
||||
|
||||
Uint32 sz = 32 * sz32;
|
||||
Uint32 start = (rand() % sz);
|
||||
Uint32 stop = start + ((rand() % (sz - start)) & 0xFFFFFFFF);
|
||||
|
||||
Vector<Uint32> check;
|
||||
check.fill(sz32, zero);
|
||||
|
||||
for(Uint32 j = 0; j<sz; j++)
|
||||
{
|
||||
bool expect = (j >= start && j<stop);
|
||||
if(expect)
|
||||
BitmaskImpl::set(sz32, check.getBase(), j);
|
||||
}
|
||||
|
||||
BitmaskImpl::set(sz32, map.getBase(), start, stop);
|
||||
if (!BitmaskImpl::equal(sz32, map.getBase(), check.getBase()))
|
||||
{
|
||||
ndbout_c(" FAIL sz: %d [ %d %d ]", sz, start, stop);
|
||||
printf("check: ");
|
||||
for(Uint32 j = 0; j<sz32; j++)
|
||||
printf("%.8x ", check[j]);
|
||||
printf("\n");
|
||||
|
||||
printf("map : ");
|
||||
for(Uint32 j = 0; j<sz32; j++)
|
||||
printf("%.8x ", map[j]);
|
||||
printf("\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
map.clear();
|
||||
check.clear();
|
||||
|
||||
Uint32 one = ~(Uint32)0;
|
||||
map.fill(sz32, one);
|
||||
check.fill(sz32, one);
|
||||
|
||||
for(Uint32 j = 0; j<sz; j++)
|
||||
{
|
||||
bool expect = (j >= start && j<stop);
|
||||
if(expect)
|
||||
BitmaskImpl::clear(sz32, check.getBase(), j);
|
||||
}
|
||||
|
||||
BitmaskImpl::clear(sz32, map.getBase(), start, stop);
|
||||
if (!BitmaskImpl::equal(sz32, map.getBase(), check.getBase()))
|
||||
{
|
||||
ndbout_c(" FAIL sz: %d [ %d %d ]", sz, start, stop);
|
||||
printf("check: ");
|
||||
for(Uint32 j = 0; j<sz32; j++)
|
||||
printf("%.8x ", check[j]);
|
||||
printf("\n");
|
||||
|
||||
printf("map : ");
|
||||
for(Uint32 j = 0; j<sz32; j++)
|
||||
printf("%.8x ", map[j]);
|
||||
printf("\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ Next NDBCNTR 1000
|
||||
Next NDBFS 2000
|
||||
Next DBACC 3002
|
||||
Next DBTUP 4013
|
||||
Next DBLQH 5042
|
||||
Next DBLQH 5043
|
||||
Next DBDICT 6007
|
||||
Next DBDIH 7174
|
||||
Next DBTC 8037
|
||||
@ -314,6 +314,8 @@ LQH:
|
||||
5026 Crash when receiving COPY_ACTIVEREQ
|
||||
5027 Crash when receiving STAT_RECREQ
|
||||
|
||||
5042 Crash starting node, when scan is finished on primary replica
|
||||
|
||||
Test Crashes in handling take over
|
||||
----------------------------------
|
||||
|
||||
@ -461,3 +463,13 @@ Dbdict:
|
||||
6003 Crash in participant @ CreateTabReq::Prepare
|
||||
6004 Crash in participant @ CreateTabReq::Commit
|
||||
6005 Crash in participant @ CreateTabReq::CreateDrop
|
||||
|
||||
Dbtup:
|
||||
4014 - handleInsert - Out of undo buffer
|
||||
4015 - handleInsert - Out of log space
|
||||
4016 - handleInsert - AI Inconsistency
|
||||
4017 - handleInsert - Out of memory
|
||||
4018 - handleInsert - Null check error
|
||||
4019 - handleInsert - Alloc rowid error
|
||||
4020 - handleInsert - Size change error
|
||||
4021 - handleInsert - Out of disk space
|
||||
|
49
storage/ndb/src/kernel/blocks/OptNR.txt
Normal file
49
storage/ndb/src/kernel/blocks/OptNR.txt
Normal file
@ -0,0 +1,49 @@
|
||||
*** Copy thread
|
||||
|
||||
Scan rowids with GCP > starting nodes GCP
|
||||
Cases for different ROWID combinations
|
||||
|
||||
RI Primary Starting Result
|
||||
1 A A Update A
|
||||
2 B B* Delete B* + Insert B
|
||||
3 C C* Delete C* + Delete C + Insert C
|
||||
C
|
||||
4 Deleted D Delete D
|
||||
5 E Deleted Insert E
|
||||
6 F Deleted Delete F + Insert F
|
||||
F
|
||||
7 Deleted Deleted Update GCP
|
||||
|
||||
*** Ordinary operations
|
||||
Op Starting Result
|
||||
Insert A@1 A@1 Update A
|
||||
Insert A@1 A@2 Delete A@2, Insert A@1
|
||||
Insert A@1 1 busy, A@2 Delete 1, Delete A@2, Insert A@1
|
||||
Insert A@1 1 busy Delete 1, Insert A@1
|
||||
|
||||
Delete A@1 A@1 Delete A@1
|
||||
Delete A@1 else noop
|
||||
|
||||
Update A@1 A@1 Update A
|
||||
Update A@1 else noop
|
||||
|
||||
***
|
||||
|
||||
Rationale:
|
||||
|
||||
If copy has passed rowid,
|
||||
then no ordinary operation should be a noop
|
||||
|
||||
If copy has not passed,
|
||||
then it's ok to do a noop as copy will get there sooner or later
|
||||
|
||||
Copy may not end up in lock queue, as no lock is held on primary.
|
||||
therefore ordinary ops must be noops when rowid missmatch
|
||||
|
||||
When not scanning in rowid order (e.g. disk order) one must
|
||||
1 make a second pass in rowid order
|
||||
- finding deletes and inserts (as 2)
|
||||
2 mark all inserts "earlier" than current scan pos
|
||||
so they will be found during second pass
|
||||
|
||||
Note: Dealloc is performed first on backup then on primary
|
@ -14,6 +14,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_config.h>
|
||||
#include "Backup.hpp"
|
||||
|
||||
#include <ndb_version.h>
|
||||
@ -2514,15 +2515,22 @@ Backup::execLIST_TABLES_CONF(Signal* signal)
|
||||
Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
|
||||
Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
|
||||
Uint32 state= ListTablesConf::getTableState(conf->tableData[i]);
|
||||
if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){
|
||||
|
||||
if (! (DictTabInfo::isTable(tableType) ||
|
||||
DictTabInfo::isIndex(tableType) ||
|
||||
DictTabInfo::isFilegroup(tableType) ||
|
||||
DictTabInfo::isFile(tableType)))
|
||||
{
|
||||
jam();
|
||||
continue;
|
||||
}//if
|
||||
}
|
||||
|
||||
if (state != DictTabInfo::StateOnline)
|
||||
{
|
||||
jam();
|
||||
continue;
|
||||
}//if
|
||||
}
|
||||
|
||||
TablePtr tabPtr;
|
||||
ptr.p->tables.seize(tabPtr);
|
||||
if(tabPtr.i == RNIL) {
|
||||
@ -2832,6 +2840,8 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
//const Uint32 senderRef = info->senderRef;
|
||||
const Uint32 len = conf->totalLen;
|
||||
const Uint32 senderData = conf->senderData;
|
||||
const Uint32 tableType = conf->tableType;
|
||||
const Uint32 tableId = conf->tableId;
|
||||
|
||||
BackupRecordPtr ptr;
|
||||
c_backupPool.getPtr(ptr, senderData);
|
||||
@ -2840,6 +2850,9 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
|
||||
ndbrequire(dictTabInfoPtr.sz == len);
|
||||
|
||||
TablePtr tabPtr ;
|
||||
ndbrequire(findTable(ptr, tabPtr, tableId));
|
||||
|
||||
/**
|
||||
* No of pages needed
|
||||
*/
|
||||
@ -2860,7 +2873,7 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
|
||||
FsBuffer & buf = filePtr.p->operation.dataBuffer;
|
||||
{ // Write into ctl file
|
||||
Uint32* dst, dstLen = len + 2;
|
||||
Uint32* dst, dstLen = len + 3;
|
||||
if(!buf.getWritePtr(&dst, dstLen)) {
|
||||
jam();
|
||||
ndbrequire(false);
|
||||
@ -2875,13 +2888,32 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
BackupFormat::CtlFile::TableDescription * desc =
|
||||
(BackupFormat::CtlFile::TableDescription*)dst;
|
||||
desc->SectionType = htonl(BackupFormat::TABLE_DESCRIPTION);
|
||||
desc->SectionLength = htonl(len + 2);
|
||||
dst += 2;
|
||||
|
||||
desc->SectionLength = htonl(len + 3);
|
||||
desc->TableType = htonl(tableType);
|
||||
dst += 3;
|
||||
|
||||
copy(dst, dictTabInfoPtr);
|
||||
buf.updateWritePtr(dstLen);
|
||||
}//if
|
||||
}
|
||||
|
||||
if(ptr.p->checkError()) {
|
||||
jam();
|
||||
releaseSections(signal);
|
||||
defineBackupRef(signal, ptr);
|
||||
return;
|
||||
}//if
|
||||
|
||||
if (!DictTabInfo::isTable(tabPtr.p->tableType))
|
||||
{
|
||||
jam();
|
||||
releaseSections(signal);
|
||||
|
||||
TablePtr tmp = tabPtr;
|
||||
ptr.p->tables.next(tabPtr);
|
||||
ptr.p->tables.release(tmp);
|
||||
goto next;
|
||||
}
|
||||
|
||||
ndbrequire(ptr.p->pages.getSize() >= noPages);
|
||||
Page32Ptr pagePtr;
|
||||
@ -2889,35 +2921,29 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
copy(&pagePtr.p->data[0], dictTabInfoPtr);
|
||||
releaseSections(signal);
|
||||
|
||||
if(ptr.p->checkError()) {
|
||||
jam();
|
||||
defineBackupRef(signal, ptr);
|
||||
return;
|
||||
}//if
|
||||
|
||||
TablePtr tabPtr = parseTableDescription(signal, ptr, len);
|
||||
if(tabPtr.i == RNIL) {
|
||||
jam();
|
||||
defineBackupRef(signal, ptr);
|
||||
return;
|
||||
}//if
|
||||
|
||||
TablePtr tmp = tabPtr;
|
||||
ptr.p->tables.next(tabPtr);
|
||||
if(DictTabInfo::isIndex(tmp.p->tableType))
|
||||
if (!parseTableDescription(signal, ptr, tabPtr, len))
|
||||
{
|
||||
jam();
|
||||
ptr.p->tables.release(tmp);
|
||||
defineBackupRef(signal, ptr);
|
||||
return;
|
||||
}
|
||||
else if(!ptr.p->is_lcp())
|
||||
|
||||
if(!ptr.p->is_lcp())
|
||||
{
|
||||
jam();
|
||||
signal->theData[0] = tmp.p->tableId;
|
||||
signal->theData[0] = tabPtr.p->tableId;
|
||||
signal->theData[1] = 1; // lock
|
||||
EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
|
||||
}
|
||||
|
||||
if(tabPtr.i == RNIL) {
|
||||
ptr.p->tables.next(tabPtr);
|
||||
|
||||
next:
|
||||
if(tabPtr.i == RNIL)
|
||||
{
|
||||
/**
|
||||
* Done with all tables...
|
||||
*/
|
||||
jam();
|
||||
|
||||
ptr.p->pages.release();
|
||||
@ -2936,6 +2962,9 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
return;
|
||||
}//if
|
||||
|
||||
/**
|
||||
* Fetch next table...
|
||||
*/
|
||||
signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
|
||||
signal->theData[1] = ptr.i;
|
||||
signal->theData[2] = tabPtr.i;
|
||||
@ -2943,8 +2972,11 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
|
||||
return;
|
||||
}
|
||||
|
||||
Backup::TablePtr
|
||||
Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
|
||||
bool
|
||||
Backup::parseTableDescription(Signal* signal,
|
||||
BackupRecordPtr ptr,
|
||||
TablePtr tabPtr,
|
||||
Uint32 len)
|
||||
{
|
||||
|
||||
Page32Ptr pagePtr;
|
||||
@ -2961,18 +2993,15 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
|
||||
DictTabInfo::TableMappingSize,
|
||||
true, true);
|
||||
ndbrequire(stat == SimpleProperties::Break);
|
||||
|
||||
TablePtr tabPtr;
|
||||
ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId));
|
||||
if(DictTabInfo::isIndex(tabPtr.p->tableType)){
|
||||
jam();
|
||||
return tabPtr;
|
||||
}
|
||||
|
||||
bool lcp = ptr.p->is_lcp();
|
||||
|
||||
ndbrequire(tabPtr.p->tableId == tmpTab.TableId);
|
||||
ndbrequire(lcp || (tabPtr.p->tableType == tmpTab.TableType));
|
||||
|
||||
/**
|
||||
* LCP should not save disk attributes but only mem attributes
|
||||
*/
|
||||
bool lcp = ptr.p->is_lcp();
|
||||
|
||||
/**
|
||||
* Initialize table object
|
||||
@ -3017,8 +3046,7 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
|
||||
{
|
||||
jam();
|
||||
ptr.p->setErrorCode(DefineBackupRef::FailedToAllocateAttributeRecord);
|
||||
tabPtr.i = RNIL;
|
||||
return tabPtr;
|
||||
return false;
|
||||
}
|
||||
|
||||
attrPtr.p->data.m_flags = 0;
|
||||
@ -3045,26 +3073,58 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len)
|
||||
}
|
||||
}//for
|
||||
|
||||
if(lcp && disk)
|
||||
|
||||
if(lcp)
|
||||
{
|
||||
/**
|
||||
* Remove all disk attributes, but add DISK_REF (8 bytes)
|
||||
*/
|
||||
tabPtr.p->noOfAttributes -= (disk - 1);
|
||||
|
||||
AttributePtr attrPtr;
|
||||
ndbrequire(tabPtr.p->attributes.seize(attrPtr));
|
||||
|
||||
Uint32 sz32 = 2;
|
||||
attrPtr.p->data.m_flags = 0;
|
||||
attrPtr.p->data.attrId = AttributeHeader::DISK_REF;
|
||||
attrPtr.p->data.m_flags = Attribute::COL_FIXED;
|
||||
attrPtr.p->data.sz32 = sz32;
|
||||
|
||||
attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
|
||||
tabPtr.p->sz_FixedAttributes += sz32;
|
||||
if (disk)
|
||||
{
|
||||
/**
|
||||
* Remove all disk attributes, but add DISK_REF (8 bytes)
|
||||
*/
|
||||
tabPtr.p->noOfAttributes -= (disk - 1);
|
||||
|
||||
AttributePtr attrPtr;
|
||||
ndbrequire(tabPtr.p->attributes.seize(attrPtr));
|
||||
|
||||
Uint32 sz32 = 2;
|
||||
attrPtr.p->data.attrId = AttributeHeader::DISK_REF;
|
||||
attrPtr.p->data.m_flags = Attribute::COL_FIXED;
|
||||
attrPtr.p->data.sz32 = 2;
|
||||
|
||||
attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
|
||||
tabPtr.p->sz_FixedAttributes += sz32;
|
||||
}
|
||||
|
||||
{
|
||||
AttributePtr attrPtr;
|
||||
ndbrequire(tabPtr.p->attributes.seize(attrPtr));
|
||||
|
||||
Uint32 sz32 = 2;
|
||||
attrPtr.p->data.attrId = AttributeHeader::ROWID;
|
||||
attrPtr.p->data.m_flags = Attribute::COL_FIXED;
|
||||
attrPtr.p->data.sz32 = 2;
|
||||
|
||||
attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
|
||||
tabPtr.p->sz_FixedAttributes += sz32;
|
||||
tabPtr.p->noOfAttributes ++;
|
||||
}
|
||||
|
||||
if (tmpTab.RowGCIFlag)
|
||||
{
|
||||
AttributePtr attrPtr;
|
||||
ndbrequire(tabPtr.p->attributes.seize(attrPtr));
|
||||
|
||||
Uint32 sz32 = 2;
|
||||
attrPtr.p->data.attrId = AttributeHeader::ROW_GCI;
|
||||
attrPtr.p->data.m_flags = Attribute::COL_FIXED;
|
||||
attrPtr.p->data.sz32 = 2;
|
||||
|
||||
attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
|
||||
tabPtr.p->sz_FixedAttributes += sz32;
|
||||
tabPtr.p->noOfAttributes ++;
|
||||
}
|
||||
}
|
||||
return tabPtr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -607,7 +607,7 @@ public:
|
||||
|
||||
NodeId getMasterNodeId() const { return c_masterNodeId; }
|
||||
bool findTable(const BackupRecordPtr &, TablePtr &, Uint32 tableId) const;
|
||||
TablePtr parseTableDescription(Signal*, BackupRecordPtr ptr, Uint32 len);
|
||||
bool parseTableDescription(Signal*, BackupRecordPtr ptr, TablePtr, Uint32);
|
||||
|
||||
bool insertFileHeader(BackupFormat::FileType, BackupRecord*, BackupFile*);
|
||||
void sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode);
|
||||
|
@ -115,7 +115,8 @@ struct BackupFormat {
|
||||
struct TableDescription {
|
||||
Uint32 SectionType;
|
||||
Uint32 SectionLength;
|
||||
Uint32 DictTabInfo[1]; // Length = SectionLength - 2
|
||||
Uint32 TableType;
|
||||
Uint32 DictTabInfo[1]; // Length = SectionLength - 3
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -102,12 +102,6 @@ ndbout << "Ptr: " << ptr.p->word32 << " \tIndex: " << tmp_string << " \tValue: "
|
||||
#define ZDEFAULT_LIST 3
|
||||
#define ZWORDS_IN_PAGE 2048
|
||||
#define ZADDFRAG 0
|
||||
#define ZCOPY_NEXT 1
|
||||
#define ZCOPY_NEXT_COMMIT 2
|
||||
#define ZCOPY_COMMIT 3
|
||||
#define ZCOPY_REPEAT 4
|
||||
#define ZCOPY_ABORT 5
|
||||
#define ZCOPY_CLOSE 6
|
||||
#define ZDIRARRAY 68
|
||||
#define ZDIRRANGESIZE 65
|
||||
//#define ZEMPTY_FRAGMENT 0
|
||||
@ -740,7 +734,7 @@ private:
|
||||
void releaseRightlist(Signal* signal);
|
||||
void checkoverfreelist(Signal* signal);
|
||||
void abortOperation(Signal* signal);
|
||||
void accAbortReqLab(Signal* signal, bool sendConf);
|
||||
void accAbortReqLab(Signal* signal);
|
||||
void commitOperation(Signal* signal);
|
||||
void copyOpInfo(Signal* signal);
|
||||
Uint32 executeNextOperation(Signal* signal);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <AttributeHeader.hpp>
|
||||
#include <signaldata/AccFrag.hpp>
|
||||
#include <signaldata/AccScan.hpp>
|
||||
#include <signaldata/NextScan.hpp>
|
||||
#include <signaldata/AccLock.hpp>
|
||||
#include <signaldata/EventReport.hpp>
|
||||
#include <signaldata/FsConf.hpp>
|
||||
@ -1072,7 +1073,7 @@ void Dbacc::execACCKEYREQ(Signal* signal)
|
||||
|
||||
initOpRec(signal);
|
||||
// normalize key if any char attr
|
||||
if (! operationRecPtr.p->isAccLockReq && fragrecptr.p->hasCharAttr)
|
||||
if (operationRecPtr.p->tupkeylen && fragrecptr.p->hasCharAttr)
|
||||
xfrmKeyData(signal);
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
@ -1778,12 +1779,13 @@ void Dbacc::execACC_COMMITREQ(Signal* signal)
|
||||
void Dbacc::execACC_ABORTREQ(Signal* signal)
|
||||
{
|
||||
jamEntry();
|
||||
accAbortReqLab(signal, true);
|
||||
accAbortReqLab(signal);
|
||||
}//Dbacc::execACC_ABORTREQ()
|
||||
|
||||
void Dbacc::accAbortReqLab(Signal* signal, bool sendConf)
|
||||
void Dbacc::accAbortReqLab(Signal* signal)
|
||||
{
|
||||
operationRecPtr.i = signal->theData[0];
|
||||
bool sendConf = signal->theData[1];
|
||||
ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
|
||||
tresult = 0; /* ZFALSE */
|
||||
if ((operationRecPtr.p->transactionstate == ACTIVE) ||
|
||||
@ -1847,6 +1849,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
|
||||
operationRecPtr.p->userblockref = req->userRef;
|
||||
operationRecPtr.p->operation = ZUNDEFINED_OP;
|
||||
operationRecPtr.p->transactionstate = IDLE;
|
||||
operationRecPtr.p->scanRecPtr = RNIL;
|
||||
// do read with lock via ACCKEYREQ
|
||||
Uint32 lockMode = (lockOp == AccLockReq::LockShared) ? 0 : 1;
|
||||
Uint32 opCode = ZSCAN_OP;
|
||||
@ -1854,7 +1857,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
|
||||
signal->theData[1] = fragrecptr.i;
|
||||
signal->theData[2] = opCode | (lockMode << 4) | (1u << 31);
|
||||
signal->theData[3] = req->hashValue;
|
||||
signal->theData[4] = 1; // fake primKeyLen
|
||||
signal->theData[4] = 0; // search local key
|
||||
signal->theData[5] = req->transId1;
|
||||
signal->theData[6] = req->transId2;
|
||||
// enter local key in place of PK
|
||||
@ -1896,7 +1899,8 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
|
||||
jam();
|
||||
// do abort via ACC_ABORTREQ (immediate)
|
||||
signal->theData[0] = req->accOpPtr;
|
||||
accAbortReqLab(signal, false);
|
||||
signal->theData[1] = false; // Dont send abort
|
||||
accAbortReqLab(signal);
|
||||
releaseOpRec(signal);
|
||||
req->returnCode = AccLockReq::Success;
|
||||
*sig = *req;
|
||||
@ -1906,7 +1910,8 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
|
||||
jam();
|
||||
// do abort via ACC_ABORTREQ (with conf signal)
|
||||
signal->theData[0] = req->accOpPtr;
|
||||
accAbortReqLab(signal, true);
|
||||
signal->theData[1] = true; // send abort
|
||||
accAbortReqLab(signal);
|
||||
releaseOpRec(signal);
|
||||
req->returnCode = AccLockReq::Success;
|
||||
*sig = *req;
|
||||
@ -2575,7 +2580,8 @@ Dbacc::readTablePk(Uint32 localkey1)
|
||||
memset(ckeys, 0x1f, (fragrecptr.p->keyLength * MAX_XFRM_MULTIPLY) << 2);
|
||||
#endif
|
||||
int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, ckeys, true);
|
||||
ndbrequire(ret > 0);
|
||||
jamEntry();
|
||||
ndbrequire(ret >= 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2632,7 +2638,7 @@ void Dbacc::getElement(Signal* signal)
|
||||
* - table key for ACCKEYREQ, stored in TUP
|
||||
* - local key (1 word) for ACC_LOCKREQ and UNDO, stored in ACC
|
||||
*/
|
||||
const bool searchLocalKey = operationRecPtr.p->isAccLockReq;
|
||||
const bool searchLocalKey = operationRecPtr.p->tupkeylen == 0;
|
||||
|
||||
ndbrequire(TelemLen == ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
|
||||
tgeNextptrtype = ZLEFT;
|
||||
@ -2775,16 +2781,18 @@ void Dbacc::commitdelete(Signal* signal)
|
||||
jam();
|
||||
Uint32 localKey = operationRecPtr.p->localdata[0];
|
||||
Uint32 userptr= operationRecPtr.p->userptr;
|
||||
|
||||
Uint32 scanInd = operationRecPtr.p->operation == ZSCAN_OP
|
||||
|| operationRecPtr.p->isAccLockReq;
|
||||
|
||||
signal->theData[0] = fragrecptr.p->myfid;
|
||||
signal->theData[1] = fragrecptr.p->myTableId;
|
||||
signal->theData[2] = operationRecPtr.p->localdata[0];
|
||||
Uint32 pageId = localKey >> MAX_TUPLES_BITS;
|
||||
Uint32 pageIndex = localKey & ((1 << MAX_TUPLES_BITS) - 1);
|
||||
signal->theData[2] = pageId;
|
||||
signal->theData[3] = pageIndex;
|
||||
signal->theData[4] = userptr;
|
||||
EXECUTE_DIRECT(DBTUP, GSN_TUP_DEALLOCREQ, signal, 5);
|
||||
signal->theData[5] = scanInd;
|
||||
EXECUTE_DIRECT(DBLQH, GSN_TUP_DEALLOCREQ, signal, 6);
|
||||
jamEntry();
|
||||
|
||||
getdirindex(signal);
|
||||
@ -5382,12 +5390,12 @@ void Dbacc::execNEXT_SCANREQ(Signal* signal)
|
||||
|
||||
scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
|
||||
switch (tscanNextFlag) {
|
||||
case ZCOPY_NEXT:
|
||||
case NextScanReq::ZSCAN_NEXT:
|
||||
jam();
|
||||
/*empty*/;
|
||||
break;
|
||||
case ZCOPY_NEXT_COMMIT:
|
||||
case ZCOPY_COMMIT:
|
||||
case NextScanReq::ZSCAN_NEXT_COMMIT:
|
||||
case NextScanReq::ZSCAN_COMMIT:
|
||||
jam();
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* COMMIT ACTIVE OPERATION.
|
||||
@ -5402,7 +5410,7 @@ void Dbacc::execNEXT_SCANREQ(Signal* signal)
|
||||
takeOutActiveScanOp(signal);
|
||||
releaseOpRec(signal);
|
||||
scanPtr.p->scanOpsAllocated--;
|
||||
if (tscanNextFlag == ZCOPY_COMMIT) {
|
||||
if (tscanNextFlag == NextScanReq::ZSCAN_COMMIT) {
|
||||
jam();
|
||||
signal->theData[0] = scanPtr.p->scanUserptr;
|
||||
Uint32 blockNo = refToBlock(scanPtr.p->scanUserblockref);
|
||||
@ -5410,7 +5418,7 @@ void Dbacc::execNEXT_SCANREQ(Signal* signal)
|
||||
return;
|
||||
}//if
|
||||
break;
|
||||
case ZCOPY_CLOSE:
|
||||
case NextScanReq::ZSCAN_CLOSE:
|
||||
jam();
|
||||
fragrecptr.i = scanPtr.p->activeLocalFrag;
|
||||
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
|
||||
@ -5995,6 +6003,7 @@ void Dbacc::initScanOpRec(Signal* signal)
|
||||
|
||||
scanPtr.p->scanOpsAllocated++;
|
||||
|
||||
operationRecPtr.p->userptr = RNIL;
|
||||
operationRecPtr.p->scanRecPtr = scanPtr.i;
|
||||
operationRecPtr.p->operation = ZSCAN_OP;
|
||||
operationRecPtr.p->transactionstate = ACTIVE;
|
||||
|
@ -353,7 +353,9 @@ void Dbdict::packTableIntoPages(Signal* signal)
|
||||
case DictTabInfo::LogfileGroup:{
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
|
||||
packFilegroupIntoPages(w, fg_ptr);
|
||||
const Uint32 free_hi= signal->theData[4];
|
||||
const Uint32 free_lo= signal->theData[5];
|
||||
packFilegroupIntoPages(w, fg_ptr, free_hi, free_lo);
|
||||
break;
|
||||
}
|
||||
case DictTabInfo::Datafile:{
|
||||
@ -420,7 +422,13 @@ Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
|
||||
w.add(DictTabInfo::NoOfVariable, (Uint32)0);
|
||||
w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
|
||||
|
||||
w.add(DictTabInfo::TableLoggedFlag, tablePtr.p->storedTable);
|
||||
w.add(DictTabInfo::TableLoggedFlag,
|
||||
!!(tablePtr.p->m_bits & TableRecord::TR_Logged));
|
||||
w.add(DictTabInfo::RowGCIFlag,
|
||||
!!(tablePtr.p->m_bits & TableRecord::TR_RowGCI));
|
||||
w.add(DictTabInfo::RowChecksumFlag,
|
||||
!!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum));
|
||||
|
||||
w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
|
||||
w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
|
||||
w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
|
||||
@ -532,7 +540,9 @@ Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
|
||||
|
||||
void
|
||||
Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w,
|
||||
FilegroupPtr fg_ptr){
|
||||
FilegroupPtr fg_ptr,
|
||||
const Uint32 undo_free_hi,
|
||||
const Uint32 undo_free_lo){
|
||||
|
||||
DictFilegroupInfo::Filegroup fg; fg.init();
|
||||
ConstRope r(c_rope_pool, fg_ptr.p->m_name);
|
||||
@ -553,6 +563,8 @@ Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w,
|
||||
break;
|
||||
case DictTabInfo::LogfileGroup:
|
||||
fg.LF_UndoBufferSize = fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
|
||||
fg.LF_UndoFreeWordsHi= undo_free_hi;
|
||||
fg.LF_UndoFreeWordsLo= undo_free_lo;
|
||||
//fg.LF_UndoGrow = ;
|
||||
break;
|
||||
default:
|
||||
@ -1794,7 +1806,7 @@ void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr)
|
||||
tablePtr.p->minLoadFactor = 70;
|
||||
tablePtr.p->noOfPrimkey = 1;
|
||||
tablePtr.p->tupKeyLength = 1;
|
||||
tablePtr.p->storedTable = true;
|
||||
tablePtr.p->m_bits = 0;
|
||||
tablePtr.p->tableType = DictTabInfo::UserTable;
|
||||
tablePtr.p->primaryTableId = RNIL;
|
||||
// volatile elements
|
||||
@ -2309,7 +2321,7 @@ Dbdict::rebuildIndexes(Signal* signal, Uint32 i){
|
||||
req->setParallelism(16);
|
||||
|
||||
// from file index state is not defined currently
|
||||
if (indexPtr.p->storedTable) {
|
||||
if (indexPtr.p->m_bits & TableRecord::TR_Logged) {
|
||||
// rebuild not needed
|
||||
req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
|
||||
}
|
||||
@ -2979,6 +2991,26 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){
|
||||
signal->theData[4]= free_extents;
|
||||
sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
|
||||
}
|
||||
else if(refToBlock(conf->senderRef) == LGMAN
|
||||
&& (refToNode(conf->senderRef) == 0
|
||||
|| refToNode(conf->senderRef) == getOwnNodeId()))
|
||||
{
|
||||
jam();
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, conf->tableId));
|
||||
const Uint32 free_hi= conf->freeWordsHi;
|
||||
const Uint32 free_lo= conf->freeWordsLo;
|
||||
const Uint32 id= conf->tableId;
|
||||
const Uint32 type= conf->tableType;
|
||||
const Uint32 data= conf->senderData;
|
||||
signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
|
||||
signal->theData[1]= id;
|
||||
signal->theData[2]= type;
|
||||
signal->theData[3]= data;
|
||||
signal->theData[4]= free_hi;
|
||||
signal->theData[5]= free_lo;
|
||||
sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
|
||||
}
|
||||
else
|
||||
{
|
||||
jam();
|
||||
@ -5067,7 +5099,7 @@ Dbdict::createTab_dih(Signal* signal,
|
||||
req->fragType = tabPtr.p->fragmentType;
|
||||
req->kValue = tabPtr.p->kValue;
|
||||
req->noOfReplicas = 0;
|
||||
req->storedTable = tabPtr.p->storedTable;
|
||||
req->storedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
|
||||
req->tableType = tabPtr.p->tableType;
|
||||
req->schemaVersion = tabPtr.p->tableVersion;
|
||||
req->primaryTableId = tabPtr.p->primaryTableId;
|
||||
@ -5166,6 +5198,7 @@ Dbdict::execADD_FRAGREQ(Signal* signal) {
|
||||
Uint32 fragCount = req->totalFragments;
|
||||
Uint32 requestInfo = req->requestInfo;
|
||||
Uint32 startGci = req->startGci;
|
||||
Uint32 logPart = req->logPartId;
|
||||
|
||||
ndbrequire(node == getOwnNodeId());
|
||||
|
||||
@ -5215,11 +5248,12 @@ Dbdict::execADD_FRAGREQ(Signal* signal) {
|
||||
// noOfCharsets passed to TUP in upper half
|
||||
req->noOfNewAttr |= (tabPtr.p->noOfCharsets << 16);
|
||||
req->checksumIndicator = 1;
|
||||
req->GCPIndicator = 0;
|
||||
req->GCPIndicator = 1;
|
||||
req->startGci = startGci;
|
||||
req->tableType = tabPtr.p->tableType;
|
||||
req->primaryTableId = tabPtr.p->primaryTableId;
|
||||
req->tablespace_id= tabPtr.p->m_tablespace_id;
|
||||
req->logPartId = logPart;
|
||||
sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal,
|
||||
LqhFragReq::SignalLength, JBB);
|
||||
}
|
||||
@ -5412,7 +5446,7 @@ Dbdict::execTAB_COMMITCONF(Signal* signal){
|
||||
|
||||
signal->theData[0] = tabPtr.i;
|
||||
signal->theData[1] = tabPtr.p->tableVersion;
|
||||
signal->theData[2] = (Uint32)tabPtr.p->storedTable;
|
||||
signal->theData[2] = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged);
|
||||
signal->theData[3] = reference();
|
||||
signal->theData[4] = (Uint32)tabPtr.p->tableType;
|
||||
signal->theData[5] = createTabPtr.p->key;
|
||||
@ -5816,7 +5850,12 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
|
||||
}
|
||||
|
||||
tablePtr.p->noOfAttributes = tableDesc.NoOfAttributes;
|
||||
tablePtr.p->storedTable = tableDesc.TableLoggedFlag;
|
||||
tablePtr.p->m_bits |=
|
||||
(tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0);
|
||||
tablePtr.p->m_bits |=
|
||||
(tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0);
|
||||
tablePtr.p->m_bits |=
|
||||
(tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0);
|
||||
tablePtr.p->minLoadFactor = tableDesc.MinLoadFactor;
|
||||
tablePtr.p->maxLoadFactor = tableDesc.MaxLoadFactor;
|
||||
tablePtr.p->fragmentType = (DictTabInfo::FragmentType)tableDesc.FragmentType;
|
||||
@ -5853,7 +5892,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
|
||||
tablePtr.p->buildTriggerId = RNIL;
|
||||
tablePtr.p->indexLocal = 0;
|
||||
|
||||
handleTabInfo(it, parseP, tableDesc.TablespaceVersion);
|
||||
handleTabInfo(it, parseP, tableDesc);
|
||||
|
||||
if(parseP->errorCode != 0)
|
||||
{
|
||||
@ -5866,7 +5905,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
|
||||
|
||||
void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
|
||||
ParseDictTabInfoRecord * parseP,
|
||||
Uint32 tablespaceVersion)
|
||||
DictTabInfo::Table &tableDesc)
|
||||
{
|
||||
TableRecordPtr tablePtr = parseP->tablePtr;
|
||||
|
||||
@ -6105,7 +6144,7 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
|
||||
tabRequire(false, CreateTableRef::NotATablespace);
|
||||
}
|
||||
|
||||
if(tablespacePtr.p->m_version != tablespaceVersion)
|
||||
if(tablespacePtr.p->m_version != tableDesc.TablespaceVersion)
|
||||
{
|
||||
tabRequire(false, CreateTableRef::InvalidTablespaceVersion);
|
||||
}
|
||||
@ -7061,6 +7100,18 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal)
|
||||
sendSignal(TSMAN_REF, GSN_GET_TABINFOREQ, signal,
|
||||
GetTabInfoReq::SignalLength, JBB);
|
||||
}
|
||||
else if(objEntry->m_tableType==DictTabInfo::LogfileGroup)
|
||||
{
|
||||
jam();
|
||||
GetTabInfoReq *req= (GetTabInfoReq*)signal->theData;
|
||||
req->senderData= c_retrieveRecord.retrievePage;
|
||||
req->senderRef= reference();
|
||||
req->requestType= GetTabInfoReq::RequestById;
|
||||
req->tableId= obj_id;
|
||||
|
||||
sendSignal(LGMAN_REF, GSN_GET_TABINFOREQ, signal,
|
||||
GetTabInfoReq::SignalLength, JBB);
|
||||
}
|
||||
else
|
||||
{
|
||||
jam();
|
||||
@ -7209,7 +7260,7 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal)
|
||||
}
|
||||
}
|
||||
// store
|
||||
if (! tablePtr.p->storedTable) {
|
||||
if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
|
||||
conf->setTableStore(pos, DictTabInfo::StoreTemporary);
|
||||
} else {
|
||||
conf->setTableStore(pos, DictTabInfo::StorePermanent);
|
||||
@ -7242,6 +7293,7 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal)
|
||||
conf->tableData[pos] = 0;
|
||||
conf->setTableId(pos, iter.curr.p->m_id);
|
||||
conf->setTableType(pos, type); // type
|
||||
conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
|
||||
pos++;
|
||||
}
|
||||
if (DictTabInfo::isFile(type)){
|
||||
@ -7249,6 +7301,7 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal)
|
||||
conf->tableData[pos] = 0;
|
||||
conf->setTableId(pos, iter.curr.p->m_id);
|
||||
conf->setTableType(pos, type); // type
|
||||
conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
|
||||
pos++;
|
||||
}
|
||||
|
||||
@ -7570,8 +7623,9 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
|
||||
indexPtr.i = RNIL; // invalid
|
||||
indexPtr.p = &indexRec;
|
||||
initialiseTableRecord(indexPtr);
|
||||
indexPtr.p->m_bits = TableRecord::TR_RowChecksum;
|
||||
if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
|
||||
indexPtr.p->storedTable = opPtr.p->m_storedIndex;
|
||||
indexPtr.p->m_bits |= (opPtr.p->m_storedIndex ? TableRecord::TR_Logged:0);
|
||||
indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex;
|
||||
} else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
|
||||
// first version will not supported logging
|
||||
@ -7581,7 +7635,6 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
|
||||
opPtr.p->m_errorLine = __LINE__;
|
||||
return;
|
||||
}
|
||||
indexPtr.p->storedTable = false;
|
||||
indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex;
|
||||
} else {
|
||||
jam();
|
||||
@ -7665,7 +7718,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
|
||||
indexPtr.p->noOfNullAttr = 0;
|
||||
// write index table
|
||||
w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
|
||||
w.add(DictTabInfo::TableLoggedFlag, indexPtr.p->storedTable);
|
||||
w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged));
|
||||
w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
|
||||
w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
|
||||
Rope name(c_rope_pool, tablePtr.p->tableName);
|
||||
@ -13817,6 +13870,7 @@ Dbdict::execCREATE_OBJ_REQ(Signal* signal){
|
||||
createObjPtr.p->m_obj_type = objType;
|
||||
createObjPtr.p->m_obj_version = objVersion;
|
||||
createObjPtr.p->m_obj_info_ptr_i = objInfoPtr.i;
|
||||
createObjPtr.p->m_obj_ptr_i = RNIL;
|
||||
|
||||
createObjPtr.p->m_callback.m_callbackData = key;
|
||||
createObjPtr.p->m_callback.m_callbackFunction=
|
||||
@ -14513,6 +14567,9 @@ Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
|
||||
SegmentedSectionPtr objInfoPtr;
|
||||
getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
|
||||
SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
|
||||
|
||||
Ptr<DictObject> obj_ptr; obj_ptr.setNull();
|
||||
FilegroupPtr fg_ptr; fg_ptr.setNull();
|
||||
|
||||
SimpleProperties::UnpackStatus status;
|
||||
DictFilegroupInfo::Filegroup fg; fg.init();
|
||||
@ -14552,15 +14609,12 @@ Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
|
||||
break;
|
||||
}
|
||||
|
||||
Ptr<DictObject> obj_ptr;
|
||||
if(!c_obj_pool.seize(obj_ptr)){
|
||||
op->m_errorCode = CreateTableRef::NoMoreTableRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
FilegroupPtr fg_ptr;
|
||||
if(!c_filegroup_pool.seize(fg_ptr)){
|
||||
c_obj_pool.release(obj_ptr);
|
||||
op->m_errorCode = CreateTableRef::NoMoreTableRecords;
|
||||
break;
|
||||
}
|
||||
@ -14569,8 +14623,6 @@ Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
|
||||
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
||||
if(!name.assign(fg.FilegroupName, len, hash)){
|
||||
op->m_errorCode = CreateTableRef::TableNameTooLong;
|
||||
c_obj_pool.release(obj_ptr);
|
||||
c_filegroup_pool.release(fg_ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -14618,8 +14670,24 @@ Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
|
||||
|
||||
op->m_obj_ptr_i = fg_ptr.i;
|
||||
} while(0);
|
||||
|
||||
|
||||
error:
|
||||
if (op->m_errorCode)
|
||||
{
|
||||
jam();
|
||||
if (!fg_ptr.isNull())
|
||||
{
|
||||
jam();
|
||||
c_filegroup_pool.release(fg_ptr);
|
||||
}
|
||||
|
||||
if (!obj_ptr.isNull())
|
||||
{
|
||||
jam();
|
||||
c_obj_pool.release(obj_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
|
||||
@ -14690,14 +14758,33 @@ Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal){
|
||||
|
||||
void
|
||||
Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
|
||||
execute(signal, op->m_callback, 0);
|
||||
abort();
|
||||
CreateFilegroupImplReq* req =
|
||||
(CreateFilegroupImplReq*)signal->getDataPtrSend();
|
||||
|
||||
if (op->m_obj_ptr_i != RNIL)
|
||||
{
|
||||
jam();
|
||||
send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
|
||||
return;
|
||||
}
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op){
|
||||
|
||||
if (op->m_obj_ptr_i != RNIL)
|
||||
{
|
||||
jam();
|
||||
FilegroupPtr fg_ptr;
|
||||
c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
|
||||
|
||||
release_object(fg_ptr.p->m_obj_ptr_i);
|
||||
c_filegroup_hash.release(fg_ptr);
|
||||
}
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
@ -14709,6 +14796,9 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||
getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
|
||||
SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
|
||||
|
||||
Ptr<DictObject> obj_ptr; obj_ptr.setNull();
|
||||
FilePtr filePtr; filePtr.setNull();
|
||||
|
||||
DictFilegroupInfo::File f; f.init();
|
||||
SimpleProperties::UnpackStatus status;
|
||||
status = SimpleProperties::unpack(it, &f,
|
||||
@ -14758,16 +14848,13 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||
}
|
||||
|
||||
// Loop through all filenames...
|
||||
Ptr<DictObject> obj_ptr;
|
||||
if(!c_obj_pool.seize(obj_ptr)){
|
||||
op->m_errorCode = CreateTableRef::NoMoreTableRecords;
|
||||
break;
|
||||
}
|
||||
|
||||
FilePtr filePtr;
|
||||
if (! c_file_pool.seize(filePtr)){
|
||||
op->m_errorCode = CreateFileRef::OutOfFileRecords;
|
||||
c_obj_pool.release(obj_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -14775,8 +14862,6 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
||||
if(!name.assign(f.FileName, len, hash)){
|
||||
op->m_errorCode = CreateTableRef::TableNameTooLong;
|
||||
c_obj_pool.release(obj_ptr);
|
||||
c_file_pool.release(filePtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -14813,6 +14898,22 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||
|
||||
op->m_obj_ptr_i = filePtr.i;
|
||||
} while(0);
|
||||
|
||||
if (op->m_errorCode)
|
||||
{
|
||||
jam();
|
||||
if (!filePtr.isNull())
|
||||
{
|
||||
jam();
|
||||
c_file_pool.release(filePtr);
|
||||
}
|
||||
|
||||
if (!obj_ptr.isNull())
|
||||
{
|
||||
jam();
|
||||
c_obj_pool.release(obj_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
@ -14839,8 +14940,6 @@ Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op){
|
||||
break;
|
||||
case 1:
|
||||
req->requestInfo = CreateFileImplReq::Open;
|
||||
if(getNodeState().getNodeRestartInProgress())
|
||||
req->requestInfo = CreateFileImplReq::CreateForce;
|
||||
break;
|
||||
case 2:
|
||||
req->requestInfo = CreateFileImplReq::CreateForce;
|
||||
@ -14946,60 +15045,70 @@ Dbdict::create_file_abort_start(Signal* signal, SchemaOp* op)
|
||||
{
|
||||
CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
|
||||
|
||||
FilePtr f_ptr;
|
||||
c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
|
||||
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
|
||||
|
||||
req->senderData = op->key;
|
||||
req->senderRef = reference();
|
||||
req->requestInfo = CreateFileImplReq::Abort;
|
||||
|
||||
req->file_id = f_ptr.p->key;
|
||||
req->filegroup_id = f_ptr.p->m_filegroup_id;
|
||||
req->filegroup_version = fg_ptr.p->m_version;
|
||||
|
||||
Uint32 ref= 0;
|
||||
switch(op->m_obj_type){
|
||||
case DictTabInfo::Datafile:
|
||||
ref = TSMAN_REF;
|
||||
break;
|
||||
case DictTabInfo::Undofile:
|
||||
ref = LGMAN_REF;
|
||||
break;
|
||||
default:
|
||||
ndbrequire(false);
|
||||
if (op->m_obj_ptr_i != RNIL)
|
||||
{
|
||||
FilePtr f_ptr;
|
||||
c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
|
||||
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
|
||||
|
||||
req->senderData = op->key;
|
||||
req->senderRef = reference();
|
||||
req->requestInfo = CreateFileImplReq::Abort;
|
||||
|
||||
req->file_id = f_ptr.p->key;
|
||||
req->filegroup_id = f_ptr.p->m_filegroup_id;
|
||||
req->filegroup_version = fg_ptr.p->m_version;
|
||||
|
||||
Uint32 ref= 0;
|
||||
switch(op->m_obj_type){
|
||||
case DictTabInfo::Datafile:
|
||||
ref = TSMAN_REF;
|
||||
break;
|
||||
case DictTabInfo::Undofile:
|
||||
ref = LGMAN_REF;
|
||||
break;
|
||||
default:
|
||||
ndbrequire(false);
|
||||
}
|
||||
|
||||
sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
|
||||
CreateFileImplReq::AbortLength, JBB);
|
||||
return;
|
||||
}
|
||||
|
||||
sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
|
||||
CreateFileImplReq::AbortLength, JBB);
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
|
||||
{
|
||||
FilePtr f_ptr;
|
||||
c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
|
||||
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
|
||||
|
||||
switch(fg_ptr.p->m_type){
|
||||
case DictTabInfo::Tablespace:
|
||||
decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
|
||||
break;
|
||||
case DictTabInfo::LogfileGroup:
|
||||
if (op->m_obj_ptr_i != RNIL)
|
||||
{
|
||||
LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
||||
list.remove(f_ptr);
|
||||
break;
|
||||
FilePtr f_ptr;
|
||||
c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
|
||||
|
||||
FilegroupPtr fg_ptr;
|
||||
ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
|
||||
|
||||
switch(fg_ptr.p->m_type){
|
||||
case DictTabInfo::Tablespace:
|
||||
decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
|
||||
break;
|
||||
case DictTabInfo::LogfileGroup:
|
||||
{
|
||||
LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
||||
list.remove(f_ptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ndbrequire(false);
|
||||
}
|
||||
|
||||
release_object(f_ptr.p->m_obj_ptr_i);
|
||||
c_file_pool.release(f_ptr);
|
||||
}
|
||||
default:
|
||||
ndbrequire(false);
|
||||
}
|
||||
|
||||
release_object(f_ptr.p->m_obj_ptr_i);
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
@ -15036,7 +15145,8 @@ Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
|
||||
|
||||
decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
|
||||
release_object(f_ptr.p->m_obj_ptr_i);
|
||||
|
||||
c_file_pool.release(f_ptr);
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
|
||||
@ -15223,7 +15333,8 @@ Dbdict::drop_fg_commit_complete(Signal* signal, SchemaOp* op)
|
||||
c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
|
||||
|
||||
release_object(fg_ptr.p->m_obj_ptr_i);
|
||||
|
||||
c_filegroup_hash.release(fg_ptr);
|
||||
|
||||
execute(signal, op->m_callback, 0);
|
||||
}
|
||||
|
||||
|
@ -228,6 +228,15 @@ public:
|
||||
/* Global checkpoint identity when table created */
|
||||
Uint32 gciTableCreated;
|
||||
|
||||
/* Is the table logged (i.e. data survives system restart) */
|
||||
enum Bits
|
||||
{
|
||||
TR_Logged = 0x1,
|
||||
TR_RowGCI = 0x2,
|
||||
TR_RowChecksum = 0x4
|
||||
};
|
||||
Uint16 m_bits;
|
||||
|
||||
/* Number of attibutes in table */
|
||||
Uint16 noOfAttributes;
|
||||
|
||||
@ -266,9 +275,6 @@ public:
|
||||
*/
|
||||
Uint8 minLoadFactor;
|
||||
|
||||
/* Is the table logged (i.e. data survives system restart) */
|
||||
bool storedTable;
|
||||
|
||||
/* Convenience routines */
|
||||
bool isTable() const;
|
||||
bool isIndex() const;
|
||||
@ -508,6 +514,7 @@ public:
|
||||
Uint32 m_filegroup_id;
|
||||
Uint32 m_type;
|
||||
Uint64 m_file_size;
|
||||
Uint64 m_file_free;
|
||||
RopeHandle m_path;
|
||||
|
||||
Uint32 nextList;
|
||||
@ -2001,7 +2008,10 @@ private:
|
||||
AttributeRecordPtr & attrPtr);
|
||||
void packTableIntoPages(Signal* signal);
|
||||
void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0);
|
||||
void packFilegroupIntoPages(SimpleProperties::Writer &, FilegroupPtr);
|
||||
void packFilegroupIntoPages(SimpleProperties::Writer &,
|
||||
FilegroupPtr,
|
||||
const Uint32 undo_free_hi,
|
||||
const Uint32 undo_free_lo);
|
||||
void packFileIntoPages(SimpleProperties::Writer &, FilePtr, const Uint32);
|
||||
|
||||
void sendGET_TABINFOREQ(Signal* signal,
|
||||
@ -2026,7 +2036,7 @@ private:
|
||||
ParseDictTabInfoRecord *,
|
||||
bool checkExist = true);
|
||||
void handleTabInfo(SimpleProperties::Reader & it, ParseDictTabInfoRecord *,
|
||||
Uint32 tablespaceVersion);
|
||||
DictTabInfo::Table & tableDesc);
|
||||
|
||||
void handleAddTableFailure(Signal* signal,
|
||||
Uint32 failureLine,
|
||||
|
@ -238,6 +238,8 @@ public:
|
||||
Uint32 storedReplicas; /* "ALIVE" STORED REPLICAS */
|
||||
Uint32 nextFragmentChunk;
|
||||
|
||||
Uint32 m_log_part_id;
|
||||
|
||||
Uint8 distributionKey;
|
||||
Uint8 fragReplicas;
|
||||
Uint8 noOldStoredReplicas; /* NUMBER OF "DEAD" STORED REPLICAS */
|
||||
@ -545,7 +547,9 @@ public:
|
||||
TO_END_COPY = 19,
|
||||
TO_END_COPY_ONGOING = 20,
|
||||
TO_WAIT_ENDING = 21,
|
||||
ENDING = 22
|
||||
ENDING = 22,
|
||||
|
||||
STARTING_LOCAL_FRAGMENTS = 24
|
||||
};
|
||||
enum ToSlaveStatus {
|
||||
TO_SLAVE_IDLE = 0,
|
||||
@ -974,7 +978,9 @@ private:
|
||||
void initialiseRecordsLab(Signal *, Uint32 stepNo, Uint32, Uint32);
|
||||
|
||||
void findReplica(ReplicaRecordPtr& regReplicaPtr,
|
||||
Fragmentstore* fragPtrP, Uint32 nodeId);
|
||||
Fragmentstore* fragPtrP,
|
||||
Uint32 nodeId,
|
||||
bool oldStoredReplicas = false);
|
||||
//------------------------------------
|
||||
// Node failure handling methods
|
||||
//------------------------------------
|
||||
@ -1132,6 +1138,10 @@ private:
|
||||
void setNodeCopyCompleted(Uint32 nodeId, bool newState);
|
||||
bool checkNodeAlive(Uint32 nodeId);
|
||||
|
||||
void nr_start_fragments(Signal*, TakeOverRecordPtr);
|
||||
void nr_start_fragment(Signal*, TakeOverRecordPtr, ReplicaRecordPtr);
|
||||
void nr_run_redo(Signal*, TakeOverRecordPtr);
|
||||
|
||||
// Initialisation
|
||||
void initData();
|
||||
void initRecords();
|
||||
@ -1158,7 +1168,8 @@ private:
|
||||
|
||||
Uint32 c_nextNodeGroup;
|
||||
NodeGroupRecord *nodeGroupRecord;
|
||||
|
||||
Uint32 c_nextLogPart;
|
||||
|
||||
NodeRecord *nodeRecord;
|
||||
|
||||
PageRecord *pageRecord;
|
||||
|
@ -609,6 +609,14 @@ void Dbdih::execCONTINUEB(Signal* signal)
|
||||
checkWaitDropTabFailedLqh(signal, nodeId, tableId);
|
||||
return;
|
||||
}
|
||||
case DihContinueB::ZTO_START_FRAGMENTS:
|
||||
{
|
||||
TakeOverRecordPtr takeOverPtr;
|
||||
takeOverPtr.i = signal->theData[1];
|
||||
ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
|
||||
nr_start_fragments(signal, takeOverPtr);
|
||||
return;
|
||||
}
|
||||
}//switch
|
||||
|
||||
ndbrequire(false);
|
||||
@ -1771,11 +1779,6 @@ void Dbdih::execSTART_MEREQ(Signal* signal)
|
||||
ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
|
||||
ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
|
||||
|
||||
sendSTART_RECREQ(signal, Tnodeid);
|
||||
}//Dbdih::execSTART_MEREQ()
|
||||
|
||||
void Dbdih::nodeRestartStartRecConfLab(Signal* signal)
|
||||
{
|
||||
c_nodeStartMaster.blockLcp = true;
|
||||
if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
|
||||
(c_lcpState.lcpStatus != LCP_TCGET)) {
|
||||
@ -2586,13 +2589,14 @@ void Dbdih::sendStartTo(Signal* signal, Uint32 takeOverPtrI)
|
||||
return;
|
||||
}//if
|
||||
c_startToLock = takeOverPtrI;
|
||||
|
||||
takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
|
||||
StartToReq * const req = (StartToReq *)&signal->theData[0];
|
||||
req->userPtr = takeOverPtr.i;
|
||||
req->userRef = reference();
|
||||
req->startingNodeId = takeOverPtr.p->toStartingNode;
|
||||
req->nodeTakenOver = takeOverPtr.p->toFailedNode;
|
||||
req->nodeRestart = takeOverPtr.p->toNodeRestart;
|
||||
takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
|
||||
sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
|
||||
}//Dbdih::sendStartTo()
|
||||
|
||||
@ -2636,9 +2640,153 @@ void Dbdih::execSTART_TOCONF(Signal* signal)
|
||||
CRASH_INSERTION(7134);
|
||||
c_startToLock = RNIL;
|
||||
|
||||
if (takeOverPtr.p->toNodeRestart)
|
||||
{
|
||||
jam();
|
||||
takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
|
||||
nr_start_fragments(signal, takeOverPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
startNextCopyFragment(signal, takeOverPtr.i);
|
||||
}//Dbdih::execSTART_TOCONF()
|
||||
|
||||
void
|
||||
Dbdih::nr_start_fragments(Signal* signal,
|
||||
TakeOverRecordPtr takeOverPtr)
|
||||
{
|
||||
Uint32 loopCount = 0 ;
|
||||
TabRecordPtr tabPtr;
|
||||
while (loopCount++ < 100) {
|
||||
tabPtr.i = takeOverPtr.p->toCurrentTabref;
|
||||
if (tabPtr.i >= ctabFileSize) {
|
||||
jam();
|
||||
nr_run_redo(signal, takeOverPtr);
|
||||
return;
|
||||
}//if
|
||||
ptrAss(tabPtr, tabRecord);
|
||||
if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
|
||||
jam();
|
||||
takeOverPtr.p->toCurrentFragid = 0;
|
||||
takeOverPtr.p->toCurrentTabref++;
|
||||
continue;
|
||||
}//if
|
||||
Uint32 fragId = takeOverPtr.p->toCurrentFragid;
|
||||
if (fragId >= tabPtr.p->totalfragments) {
|
||||
jam();
|
||||
takeOverPtr.p->toCurrentFragid = 0;
|
||||
takeOverPtr.p->toCurrentTabref++;
|
||||
continue;
|
||||
}//if
|
||||
FragmentstorePtr fragPtr;
|
||||
getFragstore(tabPtr.p, fragId, fragPtr);
|
||||
ReplicaRecordPtr loopReplicaPtr;
|
||||
loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
|
||||
while (loopReplicaPtr.i != RNIL) {
|
||||
ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
|
||||
if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
|
||||
jam();
|
||||
nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
|
||||
break;
|
||||
} else {
|
||||
jam();
|
||||
loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
|
||||
}//if
|
||||
}//while
|
||||
takeOverPtr.p->toCurrentFragid++;
|
||||
}//while
|
||||
signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
|
||||
signal->theData[1] = takeOverPtr.i;
|
||||
sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
|
||||
}
|
||||
|
||||
void
|
||||
Dbdih::nr_start_fragment(Signal* signal,
|
||||
TakeOverRecordPtr takeOverPtr,
|
||||
ReplicaRecordPtr replicaPtr)
|
||||
{
|
||||
Uint32 i, j = 0;
|
||||
Uint32 maxLcpId = 0;
|
||||
Uint32 maxLcpIndex = ~0;
|
||||
|
||||
Uint32 restorableGCI = 0;
|
||||
|
||||
ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
|
||||
takeOverPtr.p->toCurrentTabref,
|
||||
takeOverPtr.p->toCurrentFragid,
|
||||
replicaPtr.p->nextLcp);
|
||||
|
||||
Uint32 idx = replicaPtr.p->nextLcp;
|
||||
for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
|
||||
{
|
||||
ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
|
||||
if (replicaPtr.p->lcpStatus[idx] == ZVALID)
|
||||
{
|
||||
ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
|
||||
Uint32 startGci = replicaPtr.p->maxGciCompleted[idx];
|
||||
Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
|
||||
for (;j < replicaPtr.p->noCrashedReplicas; j++)
|
||||
{
|
||||
ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
|
||||
j,
|
||||
replicaPtr.p->noCrashedReplicas,
|
||||
replicaPtr.p->replicaLastGci[j]);
|
||||
if (replicaPtr.p->replicaLastGci[j] > stopGci)
|
||||
{
|
||||
maxLcpId = replicaPtr.p->lcpId[idx];
|
||||
maxLcpIndex = idx;
|
||||
restorableGCI = replicaPtr.p->replicaLastGci[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (maxLcpIndex == ~0)
|
||||
{
|
||||
ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
|
||||
takeOverPtr.p->toStartingNode,
|
||||
takeOverPtr.p->toCurrentTabref,
|
||||
takeOverPtr.p->toCurrentFragid);
|
||||
replicaPtr.p->lcpIdStarted = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
|
||||
maxLcpId,
|
||||
maxLcpIndex,
|
||||
replicaPtr.p->maxGciStarted[maxLcpIndex],
|
||||
replicaPtr.p->maxGciCompleted[maxLcpIndex],
|
||||
restorableGCI,
|
||||
SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
|
||||
SYSFILE->newestRestorableGCI);
|
||||
|
||||
replicaPtr.p->lcpIdStarted = restorableGCI;
|
||||
BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
|
||||
StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
|
||||
req->userPtr = 0;
|
||||
req->userRef = reference();
|
||||
req->lcpNo = maxLcpIndex;
|
||||
req->lcpId = maxLcpId;
|
||||
req->tableId = takeOverPtr.p->toCurrentTabref;
|
||||
req->fragId = takeOverPtr.p->toCurrentFragid;
|
||||
req->noOfLogNodes = 1;
|
||||
req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
|
||||
req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
|
||||
req->lastGci[0] = restorableGCI;
|
||||
sendSignal(ref, GSN_START_FRAGREQ, signal,
|
||||
StartFragReq::SignalLength, JBB);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
|
||||
{
|
||||
takeOverPtr.p->toCurrentTabref = 0;
|
||||
takeOverPtr.p->toCurrentFragid = 0;
|
||||
sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
|
||||
}
|
||||
|
||||
void Dbdih::initStartTakeOver(const StartToReq * req,
|
||||
TakeOverRecordPtr takeOverPtr)
|
||||
{
|
||||
@ -2971,6 +3119,14 @@ void Dbdih::execCREATE_FRAGCONF(Signal* signal)
|
||||
/*---------------------------------------------------------------------- */
|
||||
FragmentstorePtr fragPtr;
|
||||
getFragstore(tabPtr.p, fragId, fragPtr);
|
||||
Uint32 gci = 0;
|
||||
if (takeOverPtr.p->toNodeRestart)
|
||||
{
|
||||
ReplicaRecordPtr replicaPtr;
|
||||
findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
|
||||
gci = replicaPtr.p->lcpIdStarted;
|
||||
replicaPtr.p->lcpIdStarted = 0;
|
||||
}
|
||||
takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
|
||||
BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
|
||||
CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
|
||||
@ -2981,6 +3137,7 @@ void Dbdih::execCREATE_FRAGCONF(Signal* signal)
|
||||
copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
|
||||
copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
|
||||
copyFragReq->distributionKey = fragPtr.p->distributionKey;
|
||||
copyFragReq->gci = gci;
|
||||
sendSignal(ref, GSN_COPY_FRAGREQ, signal, CopyFragReq::SignalLength, JBB);
|
||||
} else {
|
||||
ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
|
||||
@ -4033,6 +4190,8 @@ void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
|
||||
Uint32 takeOverPtrI)
|
||||
{
|
||||
jam();
|
||||
ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
|
||||
takeOverPtrI);
|
||||
if (takeOverPtrI == RNIL) {
|
||||
jam();
|
||||
return;
|
||||
@ -4046,6 +4205,9 @@ void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
|
||||
takeOverPtr.i = takeOverPtrI;
|
||||
ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
|
||||
|
||||
ndbout_c("takeOverPtr.p->toMasterStatus: %x",
|
||||
takeOverPtr.p->toMasterStatus);
|
||||
|
||||
bool ok = false;
|
||||
switch (takeOverPtr.p->toMasterStatus) {
|
||||
case TakeOverRecord::IDLE:
|
||||
@ -4154,6 +4316,13 @@ void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
|
||||
//-----------------------------------------------------------------------
|
||||
endTakeOver(takeOverPtr.i);
|
||||
break;
|
||||
|
||||
case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
|
||||
ok = true;
|
||||
jam();
|
||||
endTakeOver(takeOverPtr.i);
|
||||
break;
|
||||
|
||||
/**
|
||||
* The following are states that it should not be possible to "be" in
|
||||
*/
|
||||
@ -6585,6 +6754,8 @@ void Dbdih::execDIADDTABREQ(Signal* signal)
|
||||
Uint32 activeIndex = 0;
|
||||
getFragstore(tabPtr.p, fragId, fragPtr);
|
||||
fragPtr.p->preferredPrimary = fragments[index];
|
||||
fragPtr.p->m_log_part_id = c_nextLogPart++;
|
||||
|
||||
for (Uint32 i = 0; i<noReplicas; i++) {
|
||||
const Uint32 nodeId = fragments[index++];
|
||||
ReplicaRecordPtr replicaPtr;
|
||||
@ -6629,9 +6800,9 @@ Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
|
||||
jam();
|
||||
const Uint32 fragCount = tabPtr.p->totalfragments;
|
||||
ReplicaRecordPtr replicaPtr; replicaPtr.i = RNIL;
|
||||
FragmentstorePtr fragPtr;
|
||||
for(; fragId<fragCount; fragId++){
|
||||
jam();
|
||||
FragmentstorePtr fragPtr;
|
||||
getFragstore(tabPtr.p, fragId, fragPtr);
|
||||
|
||||
replicaPtr.i = fragPtr.p->storedReplicas;
|
||||
@ -6689,6 +6860,7 @@ Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
|
||||
req->nodeId = getOwnNodeId();
|
||||
req->totalFragments = fragCount;
|
||||
req->startGci = SYSFILE->newestRestorableGCI;
|
||||
req->logPartId = fragPtr.p->m_log_part_id;
|
||||
sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal,
|
||||
AddFragReq::SignalLength, JBB);
|
||||
return;
|
||||
@ -8875,8 +9047,8 @@ void Dbdih::execSTART_RECCONF(Signal* signal)
|
||||
// otherwise we have a problem.
|
||||
/* --------------------------------------------------------------------- */
|
||||
jam();
|
||||
ndbrequire(senderNodeId == c_nodeStartMaster.startNode);
|
||||
nodeRestartStartRecConfLab(signal);
|
||||
ndbout_c("startNextCopyFragment");
|
||||
startNextCopyFragment(signal, findTakeOver(senderNodeId));
|
||||
return;
|
||||
} else {
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -9895,9 +10067,11 @@ Dbdih::checkLcpAllTablesDoneInLqh(){
|
||||
}
|
||||
|
||||
void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr,
|
||||
Fragmentstore* fragPtrP, Uint32 nodeId)
|
||||
Fragmentstore* fragPtrP,
|
||||
Uint32 nodeId,
|
||||
bool old)
|
||||
{
|
||||
replicaPtr.i = fragPtrP->storedReplicas;
|
||||
replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
|
||||
while(replicaPtr.i != RNIL){
|
||||
ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
|
||||
if (replicaPtr.p->procNode == nodeId) {
|
||||
@ -11168,6 +11342,7 @@ void Dbdih::initCommonData()
|
||||
currentgcp = 0;
|
||||
cverifyQueueCounter = 0;
|
||||
cwaitLcpSr = false;
|
||||
c_nextLogPart = 0;
|
||||
|
||||
nodeResetStart();
|
||||
c_nodeStartMaster.wait = ZFALSE;
|
||||
@ -11972,6 +12147,8 @@ void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
|
||||
jam();
|
||||
fragPtr.p->distributionKey = TdistKey;
|
||||
}//if
|
||||
|
||||
fragPtr.p->m_log_part_id = readPageWord(rf);
|
||||
}//Dbdih::readFragment()
|
||||
|
||||
Uint32 Dbdih::readPageWord(RWFragment* rf)
|
||||
@ -13062,6 +13239,7 @@ void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr)
|
||||
writePageWord(wf, fragPtr.p->noStoredReplicas);
|
||||
writePageWord(wf, fragPtr.p->noOldStoredReplicas);
|
||||
writePageWord(wf, fragPtr.p->distributionKey);
|
||||
writePageWord(wf, fragPtr.p->m_log_part_id);
|
||||
}//Dbdih::writeFragment()
|
||||
|
||||
void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
|
||||
|
@ -142,7 +142,7 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#define ZFD_HEADER_SIZE 3
|
||||
#define ZFD_PART_SIZE 48
|
||||
#define ZLOG_HEAD_SIZE 6
|
||||
#define ZLOG_HEAD_SIZE 8
|
||||
#define ZNEXT_LOG_SIZE 2
|
||||
#define ZABORT_LOG_SIZE 3
|
||||
#define ZCOMMIT_LOG_SIZE 9
|
||||
@ -264,15 +264,6 @@
|
||||
#define ZSTORED_PROC_SCAN 0
|
||||
#define ZSTORED_PROC_COPY 2
|
||||
#define ZDELETE_STORED_PROC_ID 3
|
||||
//#define ZSCAN_NEXT 1
|
||||
//#define ZSCAN_NEXT_COMMIT 2
|
||||
//#define ZSCAN_NEXT_ABORT 12
|
||||
#define ZCOPY_COMMIT 3
|
||||
#define ZCOPY_REPEAT 4
|
||||
#define ZCOPY_ABORT 5
|
||||
#define ZCOPY_CLOSE 6
|
||||
//#define ZSCAN_CLOSE 6
|
||||
//#define ZEMPTY_FRAGMENT 0
|
||||
#define ZWRITE_LOCK 1
|
||||
#define ZSCAN_FRAG_CLOSED 2
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -525,7 +516,7 @@ public:
|
||||
Uint32 scan_acc_index;
|
||||
Uint32 scan_acc_attr_recs;
|
||||
UintR scanApiOpPtr;
|
||||
UintR scanLocalref[2];
|
||||
Local_key m_row_id;
|
||||
|
||||
Uint32 m_max_batch_size_rows;
|
||||
Uint32 m_max_batch_size_bytes;
|
||||
@ -553,7 +544,6 @@ public:
|
||||
UintR scanAccPtr;
|
||||
UintR scanAiLength;
|
||||
UintR scanErrorCounter;
|
||||
UintR scanLocalFragid;
|
||||
UintR scanSchemaVersion;
|
||||
|
||||
/**
|
||||
@ -747,10 +737,16 @@ public:
|
||||
FragStatus fragStatus;
|
||||
|
||||
/**
|
||||
* Indicates a local checkpoint is active and thus can generate
|
||||
* UNDO log records.
|
||||
* 0 = undefined i.e fragStatus != ACTIVE_CREATION
|
||||
* 1 = yes
|
||||
* 2 = no
|
||||
*/
|
||||
UintR fragActiveStatus;
|
||||
enum ActiveCreat {
|
||||
AC_NORMAL = 0, // fragStatus != ACTIVE_CREATION
|
||||
AC_IGNORED = 1, // Operation that got ignored during NR
|
||||
AC_NR_COPY = 2 // Operation that got performed during NR
|
||||
};
|
||||
Uint8 m_copy_started_state;
|
||||
|
||||
/**
|
||||
* This flag indicates whether logging is currently activated at
|
||||
@ -889,6 +885,11 @@ public:
|
||||
* fragment in primary table.
|
||||
*/
|
||||
UintR tableFragptr;
|
||||
|
||||
/**
|
||||
* Log part
|
||||
*/
|
||||
Uint32 m_log_part_ptr_i;
|
||||
};
|
||||
typedef Ptr<Fragrecord> FragrecordPtr;
|
||||
|
||||
@ -2030,7 +2031,16 @@ public:
|
||||
Uint8 seqNoReplica;
|
||||
Uint8 tcNodeFailrec;
|
||||
Uint8 m_disk_table;
|
||||
Uint32 m_local_key;
|
||||
Uint8 m_use_rowid;
|
||||
Uint8 m_dealloc;
|
||||
Uint32 m_log_part_ptr_i;
|
||||
Local_key m_row_id;
|
||||
|
||||
struct {
|
||||
Uint32 m_cnt;
|
||||
Uint32 m_page_id[2];
|
||||
Local_key m_disk_ref[2];
|
||||
} m_nr_delete;
|
||||
}; /* p2c: size = 280 bytes */
|
||||
|
||||
typedef Ptr<TcConnectionrec> TcConnectionrecPtr;
|
||||
@ -2095,10 +2105,6 @@ private:
|
||||
void execBUILDINDXCONF(Signal*signal);
|
||||
|
||||
void execDUMP_STATE_ORD(Signal* signal);
|
||||
void execACC_COM_BLOCK(Signal* signal);
|
||||
void execACC_COM_UNBLOCK(Signal* signal);
|
||||
void execTUP_COM_BLOCK(Signal* signal);
|
||||
void execTUP_COM_UNBLOCK(Signal* signal);
|
||||
void execACC_ABORTCONF(Signal* signal);
|
||||
void execNODE_FAILREP(Signal* signal);
|
||||
void execCHECK_LCP_STOP(Signal* signal);
|
||||
@ -2181,6 +2187,7 @@ private:
|
||||
void execDROP_TAB_REQ(Signal* signal);
|
||||
|
||||
void execLQH_ALLOCREQ(Signal* signal);
|
||||
void execTUP_DEALLOCREQ(Signal* signal);
|
||||
void execLQH_WRITELOG_REQ(Signal* signal);
|
||||
|
||||
void execTUXFRAGCONF(Signal* signal);
|
||||
@ -2234,7 +2241,7 @@ private:
|
||||
Uint32 sendKeyinfo20(Signal* signal, ScanRecord *, TcConnectionrec *);
|
||||
void sendScanFragConf(Signal* signal, Uint32 scanCompleted);
|
||||
void initCopyrec(Signal* signal);
|
||||
void initCopyTc(Signal* signal);
|
||||
void initCopyTc(Signal* signal, Operation_t);
|
||||
void sendCopyActiveConf(Signal* signal,Uint32 tableId);
|
||||
void checkLcpCompleted(Signal* signal);
|
||||
void checkLcpHoldop(Signal* signal);
|
||||
@ -2277,7 +2284,7 @@ private:
|
||||
void checkReadExecSr(Signal* signal);
|
||||
void checkScanTcCompleted(Signal* signal);
|
||||
void checkSrCompleted(Signal* signal);
|
||||
void closeFile(Signal* signal, LogFileRecordPtr logFilePtr);
|
||||
void closeFile(Signal* signal, LogFileRecordPtr logFilePtr, Uint32 place);
|
||||
void completedLogPage(Signal* signal, Uint32 clpType, Uint32 place);
|
||||
void deleteFragrec(Uint32 fragId);
|
||||
void deleteTransidHash(Signal* signal);
|
||||
@ -2561,10 +2568,26 @@ private:
|
||||
|
||||
void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
|
||||
void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
|
||||
|
||||
|
||||
void handle_nr_copy(Signal*, Ptr<TcConnectionrec>);
|
||||
void exec_acckeyreq(Signal*, Ptr<TcConnectionrec>);
|
||||
int compare_key(const TcConnectionrec*, const Uint32 * ptr, Uint32 len);
|
||||
void nr_copy_delete_row(Signal*, Ptr<TcConnectionrec>, Local_key*, Uint32);
|
||||
public:
|
||||
struct Nr_op_info
|
||||
{
|
||||
Uint32 m_ptr_i;
|
||||
Uint32 m_tup_frag_ptr_i;
|
||||
Uint32 m_gci;
|
||||
Uint32 m_page_id;
|
||||
Local_key m_disk_ref;
|
||||
};
|
||||
void get_nr_op_info(Nr_op_info*, Uint32 page_id = RNIL);
|
||||
void nr_delete_complete(Signal*, Nr_op_info*);
|
||||
|
||||
public:
|
||||
void acckeyconf_load_diskpage_callback(Signal*, Uint32, Uint32);
|
||||
|
||||
|
||||
private:
|
||||
void next_scanconf_load_diskpage(Signal* signal,
|
||||
ScanRecordPtr scanPtr,
|
||||
@ -2823,11 +2846,6 @@ private:
|
||||
UintR cLqhTimeOutCount;
|
||||
UintR cLqhTimeOutCheckCount;
|
||||
UintR cnoOfLogPages;
|
||||
bool caccCommitBlocked;
|
||||
bool ctupCommitBlocked;
|
||||
bool cCommitBlocked;
|
||||
UintR cCounterAccCommitBlocked;
|
||||
UintR cCounterTupCommitBlocked;
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*THIS VARIABLE CONTAINS MY OWN PROCESSOR ID. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -2847,17 +2865,12 @@ private:
|
||||
Uint16 cpackedList[MAX_NDB_NODES];
|
||||
UintR cnodeData[MAX_NDB_NODES];
|
||||
UintR cnodeStatus[MAX_NDB_NODES];
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*THIS VARIABLE INDICATES WHETHER A CERTAIN NODE HAS SENT ALL FRAGMENTS THAT */
|
||||
/*NEED TO HAVE THE LOG EXECUTED. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
Uint8 cnodeSrState[MAX_NDB_NODES];
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*THIS VARIABLE INDICATES WHETHER A CERTAIN NODE HAVE EXECUTED THE LOG */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
Uint8 cnodeExecSrState[MAX_NDB_NODES];
|
||||
UintR cnoOfNodes;
|
||||
|
||||
NdbNodeBitmask m_sr_nodes;
|
||||
NdbNodeBitmask m_sr_exec_sr_req;
|
||||
NdbNodeBitmask m_sr_exec_sr_conf;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* THIS VARIABLE CONTAINS THE DIRECTORY OF A HASH TABLE OF ALL ACTIVE */
|
||||
/* OPERATION IN THE BLOCK. IT IS USED TO BE ABLE TO QUICKLY ABORT AN */
|
||||
@ -2985,6 +2998,10 @@ Dblqh::accminupdate(Signal* signal, Uint32 opId, const Local_key* key)
|
||||
signal->theData[0] = regTcPtr.p->accConnectrec;
|
||||
signal->theData[1] = key->m_page_no << MAX_TUPLES_BITS | key->m_page_idx;
|
||||
c_acc->execACCMINUPDATE(signal);
|
||||
|
||||
if (ERROR_INSERTED(5712))
|
||||
ndbout << " LK: " << *key;
|
||||
regTcPtr.p->m_row_id = *key;
|
||||
}
|
||||
|
||||
|
||||
|
@ -221,10 +221,6 @@ Dblqh::Dblqh(const class Configuration & conf):
|
||||
addRecSignal(GSN_DROP_TRIG_REF, &Dblqh::execDROP_TRIG_REF);
|
||||
|
||||
addRecSignal(GSN_DUMP_STATE_ORD, &Dblqh::execDUMP_STATE_ORD);
|
||||
addRecSignal(GSN_ACC_COM_BLOCK, &Dblqh::execACC_COM_BLOCK);
|
||||
addRecSignal(GSN_ACC_COM_UNBLOCK, &Dblqh::execACC_COM_UNBLOCK);
|
||||
addRecSignal(GSN_TUP_COM_BLOCK, &Dblqh::execTUP_COM_BLOCK);
|
||||
addRecSignal(GSN_TUP_COM_UNBLOCK, &Dblqh::execTUP_COM_UNBLOCK);
|
||||
addRecSignal(GSN_NODE_FAILREP, &Dblqh::execNODE_FAILREP);
|
||||
addRecSignal(GSN_CHECK_LCP_STOP, &Dblqh::execCHECK_LCP_STOP);
|
||||
addRecSignal(GSN_SEND_PACKED, &Dblqh::execSEND_PACKED);
|
||||
@ -301,6 +297,7 @@ Dblqh::Dblqh(const class Configuration & conf):
|
||||
|
||||
addRecSignal(GSN_LQH_ALLOCREQ, &Dblqh::execLQH_ALLOCREQ);
|
||||
addRecSignal(GSN_LQH_WRITELOG_REQ, &Dblqh::execLQH_WRITELOG_REQ);
|
||||
addRecSignal(GSN_TUP_DEALLOCREQ, &Dblqh::execTUP_DEALLOCREQ);
|
||||
|
||||
// TUX
|
||||
addRecSignal(GSN_TUXFRAGCONF, &Dblqh::execTUXFRAGCONF);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -128,7 +128,7 @@ bool PrepareOperationRecord::check() {
|
||||
if (m_operationType == 3 && m_attributeLength != 0)
|
||||
return false;
|
||||
|
||||
if (m_logRecordSize != (m_attributeLength + m_keyLength + 6))
|
||||
if (m_logRecordSize != (m_attributeLength + m_keyLength + 8))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -165,6 +165,8 @@ NdbOut& operator<<(NdbOut& no, const PrepareOperationRecord& por) {
|
||||
default:
|
||||
printOut("operationType:", por.m_operationType);
|
||||
}
|
||||
printOut("page_no: ", por.m_page_no);
|
||||
printOut("page_idx: ", por.m_page_idx);
|
||||
printOut("attributeLength:", por.m_attributeLength);
|
||||
printOut("keyLength:", por.m_keyLength);
|
||||
|
||||
|
@ -92,6 +92,8 @@ protected:
|
||||
Uint32 m_operationType; // 0 READ, 1 UPDATE, 2 INSERT, 3 DELETE
|
||||
Uint32 m_attributeLength;
|
||||
Uint32 m_keyLength;
|
||||
Uint32 m_page_no;
|
||||
Uint32 m_page_idx;
|
||||
Uint32 *m_keyInfo; // In this order
|
||||
Uint32 *m_attrInfo;// In this order
|
||||
};
|
||||
|
@ -892,11 +892,7 @@ public:
|
||||
*/
|
||||
Uint8 opExec;
|
||||
|
||||
/**
|
||||
* LOCK TYPE OF OPERATION IF READ OPERATION
|
||||
* 0 = READ LOCK, 1 = WRITE LOCK
|
||||
*/
|
||||
Uint8 opLock;
|
||||
Uint8 unused;
|
||||
|
||||
/**
|
||||
* IS THE OPERATION A SIMPLE TRANSACTION
|
||||
|
@ -2807,17 +2807,9 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
||||
regCachePtr->attrinfo15[2] = Tdata4;
|
||||
regCachePtr->attrinfo15[3] = Tdata5;
|
||||
|
||||
if (TOperationType == ZREAD) {
|
||||
if (TOperationType == ZREAD || TOperationType == ZREAD_EX) {
|
||||
Uint32 TreadCount = c_counters.creadCount;
|
||||
jam();
|
||||
regCachePtr->opLock = 0;
|
||||
c_counters.creadCount = TreadCount + 1;
|
||||
} else if(TOperationType == ZREAD_EX){
|
||||
Uint32 TreadCount = c_counters.creadCount;
|
||||
jam();
|
||||
TOperationType = ZREAD;
|
||||
regTcPtr->operation = ZREAD;
|
||||
regCachePtr->opLock = ZUPDATE;
|
||||
c_counters.creadCount = TreadCount + 1;
|
||||
} else {
|
||||
if(regApiPtr->commitAckMarker == RNIL){
|
||||
@ -2851,24 +2843,10 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
||||
c_counters.cwriteCount = TwriteCount + 1;
|
||||
switch (TOperationType) {
|
||||
case ZUPDATE:
|
||||
jam();
|
||||
if (TattrLen == 0) {
|
||||
//TCKEY_abort(signal, 5);
|
||||
//return;
|
||||
}//if
|
||||
/*---------------------------------------------------------------------*/
|
||||
// The missing break is intentional since we also want to set the opLock
|
||||
// variable also for updates
|
||||
/*---------------------------------------------------------------------*/
|
||||
case ZINSERT:
|
||||
case ZDELETE:
|
||||
jam();
|
||||
regCachePtr->opLock = TOperationType;
|
||||
break;
|
||||
case ZWRITE:
|
||||
jam();
|
||||
// A write operation is originally an insert operation.
|
||||
regCachePtr->opLock = ZINSERT;
|
||||
break;
|
||||
default:
|
||||
TCKEY_abort(signal, 9);
|
||||
@ -3039,7 +3017,7 @@ void Dbtc::tckeyreq050Lab(Signal* signal)
|
||||
tnoOfStandby = (tnodeinfo >> 8) & 3;
|
||||
|
||||
regCachePtr->fragmentDistributionKey = (tnodeinfo >> 16) & 255;
|
||||
if (Toperation == ZREAD) {
|
||||
if (Toperation == ZREAD || Toperation == ZREAD_EX) {
|
||||
if (Tdirty == 1) {
|
||||
jam();
|
||||
/*-------------------------------------------------------------*/
|
||||
@ -3168,6 +3146,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
|
||||
TcConnectRecord * const regTcPtr = tcConnectptr.p;
|
||||
ApiConnectRecord * const regApiPtr = apiConnectptr.p;
|
||||
CacheRecord * const regCachePtr = cachePtr.p;
|
||||
Uint32 version = getNodeInfo(refToNode(TBRef)).m_version;
|
||||
#ifdef ERROR_INSERT
|
||||
if (ERROR_INSERTED(8002)) {
|
||||
systemErrorLab(signal, __LINE__);
|
||||
@ -3207,7 +3186,12 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
|
||||
Tdata10 = 0;
|
||||
LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
|
||||
LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
|
||||
LqhKeyReq::setLockType(Tdata10, regCachePtr->opLock);
|
||||
if (unlikely(version < NDBD_ROWID_VERSION))
|
||||
{
|
||||
Uint32 op = regTcPtr->operation;
|
||||
Uint32 lock = op == ZREAD_EX ? ZUPDATE : op == ZWRITE ? ZINSERT : op;
|
||||
LqhKeyReq::setLockType(Tdata10, lock);
|
||||
}
|
||||
/* ---------------------------------------------------------------------- */
|
||||
// Indicate Application Reference is present in bit 15
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -177,7 +177,7 @@ inline const Uint32* ALIGN_WORD(const void* ptr)
|
||||
#define ZINSERT_ERROR 630
|
||||
|
||||
#define ZINVALID_CHAR_FORMAT 744
|
||||
|
||||
#define ZROWID_ALLOCATED 899
|
||||
|
||||
/* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
|
||||
|
||||
@ -235,8 +235,9 @@ inline const Uint32* ALIGN_WORD(const void* ptr)
|
||||
#define ZREL_FRAG 7
|
||||
#define ZREPORT_MEMORY_USAGE 8
|
||||
#define ZBUILD_INDEX 9
|
||||
#define ZFREE_EXTENT 10
|
||||
#define ZUNMAP_PAGES 11
|
||||
#define ZTUP_SCAN 10
|
||||
#define ZFREE_EXTENT 11
|
||||
#define ZUNMAP_PAGES 12
|
||||
|
||||
#define ZSCAN_PROCEDURE 0
|
||||
#define ZCOPY_PROCEDURE 2
|
||||
@ -336,40 +337,106 @@ struct Fragoperrec {
|
||||
};
|
||||
typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||
|
||||
// Position for use by scan
|
||||
struct PagePos {
|
||||
|
||||
typedef Tup_page Page;
|
||||
typedef Ptr<Page> PagePtr;
|
||||
|
||||
// Scan position
|
||||
struct ScanPos {
|
||||
enum Get {
|
||||
Get_undef = 0,
|
||||
Get_next_page,
|
||||
Get_page,
|
||||
Get_next_page_mm,
|
||||
Get_page_mm,
|
||||
Get_next_page_dd,
|
||||
Get_page_dd,
|
||||
Get_next_tuple,
|
||||
Get_tuple,
|
||||
Get_next_tuple_fs,
|
||||
Get_tuple_fs
|
||||
};
|
||||
Get m_get; // entry point in scanNext
|
||||
Local_key m_key; // scan position pointer MM or DD
|
||||
Page* m_page; // scanned MM or DD (cache) page
|
||||
Local_key m_key_mm; // MM local key returned
|
||||
Uint32 m_realpid_mm; // MM real page id
|
||||
Uint32 m_extent_info_ptr_i;
|
||||
Local_key m_key;
|
||||
bool m_match;
|
||||
};
|
||||
|
||||
// Tup scan op (compare Dbtux::ScanOp)
|
||||
// Scan Lock
|
||||
struct ScanLock {
|
||||
Uint32 m_accLockOp;
|
||||
union {
|
||||
Uint32 nextPool;
|
||||
Uint32 nextList;
|
||||
};
|
||||
Uint32 prevList;
|
||||
};
|
||||
typedef Ptr<ScanLock> ScanLockPtr;
|
||||
ArrayPool<ScanLock> c_scanLockPool;
|
||||
|
||||
// Tup scan, similar to Tux scan. Later some of this could
|
||||
// be moved to common superclass.
|
||||
struct ScanOp {
|
||||
ScanOp() {}
|
||||
enum { // state
|
||||
ScanOp() :
|
||||
m_state(Undef),
|
||||
m_bits(0),
|
||||
m_userPtr(RNIL),
|
||||
m_userRef(RNIL),
|
||||
m_tableId(RNIL),
|
||||
m_fragId(~(Uint32)0),
|
||||
m_fragPtrI(RNIL),
|
||||
m_transId1(0),
|
||||
m_transId2(0),
|
||||
m_savePointId(0),
|
||||
m_accLockOp(RNIL)
|
||||
{}
|
||||
|
||||
enum State {
|
||||
Undef = 0,
|
||||
First = 1, // before first entry
|
||||
Locked = 4, // at current entry (no lock needed)
|
||||
Current = 2, // at current before locking
|
||||
Blocked = 3, // at current waiting for ACC lock
|
||||
Locked = 4, // at current and locked or no lock needed
|
||||
Next = 5, // looking for next extry
|
||||
Last = 6, // after last entry
|
||||
Aborting = 7, // lock wait at scan close
|
||||
Invalid = 9 // cannot return REF to LQH currently
|
||||
};
|
||||
Uint16 m_state;
|
||||
|
||||
STATIC_CONST( SCAN_DD = 0x1 );
|
||||
STATIC_CONST( SCAN_VS = 0x2 );
|
||||
STATIC_CONST( SCAN_LCP = 0x4 );
|
||||
STATIC_CONST( SCAN_DD_VS = 0x8 );
|
||||
enum Bits {
|
||||
SCAN_DD = 0x01, // scan disk pages
|
||||
SCAN_VS = 0x02, // page format is var size
|
||||
SCAN_LCP = 0x04, // LCP mem page scan
|
||||
SCAN_LOCK_SH = 0x10, // lock mode shared
|
||||
SCAN_LOCK_EX = 0x20, // lock mode exclusive
|
||||
SCAN_LOCK_WAIT = 0x40, // lock wait
|
||||
// any lock mode
|
||||
SCAN_LOCK = SCAN_LOCK_SH | SCAN_LOCK_EX,
|
||||
SCAN_NR = 0x80 // Node recovery scan
|
||||
};
|
||||
Uint16 m_bits;
|
||||
|
||||
Uint32 m_userPtr; // scanptr.i in LQH
|
||||
Uint32 m_userRef;
|
||||
Uint32 m_tableId;
|
||||
Uint32 m_fragId; // "base" fragment id
|
||||
Uint32 m_fragId;
|
||||
Uint32 m_fragPtrI;
|
||||
Uint32 m_transId1;
|
||||
Uint32 m_transId2;
|
||||
PagePos m_scanPos;
|
||||
union {
|
||||
Uint32 m_savePointId;
|
||||
Uint32 m_scanGCI;
|
||||
};
|
||||
// lock waited for or obtained and not yet passed to LQH
|
||||
Uint32 m_accLockOp;
|
||||
|
||||
ScanPos m_scanPos;
|
||||
|
||||
DLFifoList<ScanLock>::Head m_accLockOps;
|
||||
|
||||
union {
|
||||
Uint32 nextPool;
|
||||
Uint32 nextList;
|
||||
@ -379,8 +446,18 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||
typedef Ptr<ScanOp> ScanOpPtr;
|
||||
ArrayPool<ScanOp> c_scanOpPool;
|
||||
|
||||
typedef Tup_page Page;
|
||||
typedef Ptr<Page> PagePtr;
|
||||
void scanReply(Signal*, ScanOpPtr scanPtr);
|
||||
void scanFirst(Signal*, ScanOpPtr scanPtr);
|
||||
bool scanNext(Signal*, ScanOpPtr scanPtr);
|
||||
void scanCont(Signal*, ScanOpPtr scanPtr);
|
||||
void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
|
||||
void scanClose(Signal*, ScanOpPtr scanPtr);
|
||||
void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
|
||||
void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
|
||||
void releaseScanOp(ScanOpPtr& scanPtr);
|
||||
|
||||
// for md5 of key (could maybe reuse existing temp buffer)
|
||||
Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
|
||||
|
||||
struct Page_request
|
||||
{
|
||||
@ -410,6 +487,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||
|
||||
struct Extent_info : public Extent_list_t
|
||||
{
|
||||
Uint32 m_first_page_no;
|
||||
Local_key m_key;
|
||||
Uint32 m_free_space;
|
||||
Uint32 m_free_matrix_pos;
|
||||
@ -440,6 +518,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||
Disk_alloc_info() {}
|
||||
Disk_alloc_info(const Tablerec* tabPtrP,
|
||||
Uint32 extent_size_in_pages);
|
||||
Uint32 m_extent_size;
|
||||
|
||||
/**
|
||||
* Disk allocation
|
||||
@ -510,17 +589,18 @@ struct Fragrecord {
|
||||
Uint32 currentPageRange;
|
||||
Uint32 rootPageRange;
|
||||
Uint32 noOfPages;
|
||||
Uint32 emptyPrimPage;
|
||||
|
||||
Uint32 thFreeFirst;
|
||||
DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
|
||||
DLList<Page>::Head thFreeFirst; // pages with atleast 1 free record
|
||||
SLList<Page>::Head m_empty_pages; // Empty pages not in logical/physical map
|
||||
|
||||
Uint32 m_lcp_scan_op;
|
||||
|
||||
State fragStatus;
|
||||
Uint32 fragTableId;
|
||||
Uint32 fragmentId;
|
||||
Uint32 nextfreefrag;
|
||||
Uint32 free_var_page_array[MAX_FREE_LIST];
|
||||
|
||||
DLList<Page>::Head free_var_page_array[MAX_FREE_LIST];
|
||||
|
||||
DLList<ScanOp>::Head m_scanList;
|
||||
|
||||
bool m_undo_complete;
|
||||
@ -530,11 +610,6 @@ struct Fragrecord {
|
||||
};
|
||||
typedef Ptr<Fragrecord> FragrecordPtr;
|
||||
|
||||
void scanFirst(Signal* signal, Fragrecord*, ScanOpPtr scanPtr);
|
||||
void scanNext(Signal* signal, Fragrecord*, ScanOpPtr scanPtr);
|
||||
void scanClose(Signal* signal, ScanOpPtr scanPtr);
|
||||
void releaseScanOp(ScanOpPtr& scanPtr);
|
||||
|
||||
|
||||
struct Operationrec {
|
||||
/*
|
||||
@ -796,7 +871,12 @@ ArrayPool<TupTriggerData> c_triggerPool;
|
||||
Uint32 tabDescriptor;
|
||||
Uint32 m_real_order_descriptor;
|
||||
|
||||
bool checksumIndicator;
|
||||
enum Bits
|
||||
{
|
||||
TR_Checksum = 0x1, // Need to be 1
|
||||
TR_RowGCI = 0x2
|
||||
};
|
||||
Uint16 m_bits;
|
||||
Uint16 total_rec_size; // Max total size for entire tuple in words
|
||||
|
||||
/**
|
||||
@ -1105,7 +1185,7 @@ typedef Ptr<HostBuffer> HostBufferPtr;
|
||||
STATIC_CONST( MM_GROWN = 0x00400000 ); // Has MM part grown
|
||||
STATIC_CONST( FREE = 0x00800000 ); // On free list of page
|
||||
STATIC_CONST( LCP_SKIP = 0x01000000 ); // Should not be returned in LCP
|
||||
|
||||
|
||||
Uint32 get_tuple_version() const {
|
||||
return m_header_bits & TUP_VERSION_MASK;
|
||||
}
|
||||
@ -1138,6 +1218,16 @@ typedef Ptr<HostBuffer> HostBufferPtr;
|
||||
const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
|
||||
return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
|
||||
}
|
||||
|
||||
Uint32 *get_mm_gci(const Tablerec* tabPtrP){
|
||||
assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
|
||||
return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
|
||||
}
|
||||
|
||||
Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
|
||||
assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
|
||||
return m_data;
|
||||
}
|
||||
};
|
||||
|
||||
struct KeyReqStruct {
|
||||
@ -1179,13 +1269,15 @@ struct KeyReqStruct {
|
||||
} m_var_data[2];
|
||||
|
||||
Tuple_header *m_disk_ptr;
|
||||
Page* m_page_ptr_p;
|
||||
Var_page* m_varpart_page_ptr_p;// could be same as m_page_ptr_p
|
||||
PagePtr m_page_ptr;
|
||||
PagePtr m_varpart_page_ptr; // could be same as m_page_ptr_p
|
||||
PagePtr m_disk_page_ptr; //
|
||||
|
||||
Local_key m_row_id;
|
||||
|
||||
bool dirty_op;
|
||||
bool interpreted_exec;
|
||||
bool last_row;
|
||||
bool m_use_rowid;
|
||||
|
||||
Signal* signal;
|
||||
Uint32 no_fired_triggers;
|
||||
@ -1290,8 +1382,17 @@ public:
|
||||
int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
|
||||
Uint32 local_key, Uint32 flags);
|
||||
|
||||
int alloc_page(Tablerec*, Fragrecord*, PagePtr*,Uint32 page_no);
|
||||
|
||||
void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
|
||||
void complete_restore_lcp(Uint32 tableId, Uint32 fragmentId);
|
||||
|
||||
int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool©);
|
||||
int nr_update_gci(Uint32 fragPtr, const Local_key*, Uint32 gci);
|
||||
int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
|
||||
|
||||
void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
|
||||
void nr_delete_logbuffer_callback(Signal*, Uint32 op, Uint32 page);
|
||||
private:
|
||||
BLOCK_DEFINES(Dbtup);
|
||||
|
||||
@ -1333,6 +1434,9 @@ private:
|
||||
void execACC_SCANREQ(Signal* signal);
|
||||
void execNEXT_SCANREQ(Signal* signal);
|
||||
void execACC_CHECK_SCAN(Signal* signal);
|
||||
void execACCKEYCONF(Signal* signal);
|
||||
void execACCKEYREF(Signal* signal);
|
||||
void execACC_ABORTCONF(Signal* signal);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
@ -1542,7 +1646,7 @@ private:
|
||||
void handleATTRINFOforTUPKEYREQ(Signal* signal,
|
||||
const Uint32* data,
|
||||
Uint32 length,
|
||||
Operationrec * const regOperPtr);
|
||||
Operationrec * regOperPtr);
|
||||
|
||||
// *****************************************************************
|
||||
// Setting up the environment for reads, inserts, updates and deletes.
|
||||
@ -1550,16 +1654,16 @@ private:
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
int handleReadReq(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
int handleUpdateReq(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct,
|
||||
bool disk);
|
||||
|
||||
@ -1568,23 +1672,23 @@ private:
|
||||
int handleInsertReq(Signal* signal,
|
||||
Ptr<Operationrec> regOperPtr,
|
||||
Ptr<Fragrecord>,
|
||||
Tablerec* const regTabPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
int handleDeleteReq(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
int updateStartLab(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct);
|
||||
|
||||
// *****************************************************************
|
||||
@ -1616,19 +1720,19 @@ private:
|
||||
void sendReadAttrinfo(Signal* signal,
|
||||
KeyReqStruct *req_struct,
|
||||
Uint32 TnoOfData,
|
||||
const Operationrec * const regOperPtr);
|
||||
const Operationrec * regOperPtr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
void sendLogAttrinfo(Signal* signal,
|
||||
Uint32 TlogSize,
|
||||
Operationrec * const regOperPtr);
|
||||
Operationrec * regOperPtr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
void sendTUPKEYCONF(Signal* signal,
|
||||
KeyReqStruct *req_struct,
|
||||
Operationrec * const regOperPtr);
|
||||
Operationrec * regOperPtr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
@ -1843,7 +1947,7 @@ private:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
void setUpQueryRoutines(Tablerec* const regTabPtr);
|
||||
void setUpQueryRoutines(Tablerec* regTabPtr);
|
||||
|
||||
// *****************************************************************
|
||||
// Service methods.
|
||||
@ -1863,7 +1967,7 @@ private:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
void copyAttrinfo(Operationrec * const regOperPtr, Uint32* inBuffer);
|
||||
void copyAttrinfo(Operationrec * regOperPtr, Uint32* inBuffer);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
@ -1875,7 +1979,7 @@ private:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
int initStoredOperationrec(Operationrec* const regOperPtr,
|
||||
int initStoredOperationrec(Operationrec* regOperPtr,
|
||||
KeyReqStruct* req_struct,
|
||||
Uint32 storedId);
|
||||
|
||||
@ -1905,57 +2009,57 @@ private:
|
||||
|
||||
void
|
||||
checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const tablePtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* tablePtr);
|
||||
|
||||
void
|
||||
checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const tablePtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* tablePtr);
|
||||
|
||||
void
|
||||
checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const tablePtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* tablePtr);
|
||||
|
||||
#if 0
|
||||
void checkDeferredTriggers(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const regTablePtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTablePtr);
|
||||
#endif
|
||||
void checkDetachedTriggers(KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const regTablePtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTablePtr);
|
||||
|
||||
void fireImmediateTriggers(KeyReqStruct *req_struct,
|
||||
ArrayList<TupTriggerData>& triggerList,
|
||||
Operationrec* const regOperPtr);
|
||||
Operationrec* regOperPtr);
|
||||
|
||||
void fireDeferredTriggers(KeyReqStruct *req_struct,
|
||||
ArrayList<TupTriggerData>& triggerList,
|
||||
Operationrec* const regOperPtr);
|
||||
Operationrec* regOperPtr);
|
||||
|
||||
void fireDetachedTriggers(KeyReqStruct *req_struct,
|
||||
ArrayList<TupTriggerData>& triggerList,
|
||||
Operationrec* const regOperPtr);
|
||||
Operationrec* regOperPtr);
|
||||
|
||||
void executeTriggers(KeyReqStruct *req_struct,
|
||||
ArrayList<TupTriggerData>& triggerList,
|
||||
Operationrec* const regOperPtr);
|
||||
Operationrec* regOperPtr);
|
||||
|
||||
void executeTrigger(KeyReqStruct *req_struct,
|
||||
TupTriggerData* const trigPtr,
|
||||
Operationrec* const regOperPtr);
|
||||
TupTriggerData* trigPtr,
|
||||
Operationrec* regOperPtr);
|
||||
|
||||
bool readTriggerInfo(TupTriggerData* const trigPtr,
|
||||
Operationrec* const regOperPtr,
|
||||
KeyReqStruct * const req_struct,
|
||||
Fragrecord* const regFragPtr,
|
||||
Uint32* const keyBuffer,
|
||||
bool readTriggerInfo(TupTriggerData* trigPtr,
|
||||
Operationrec* regOperPtr,
|
||||
KeyReqStruct * req_struct,
|
||||
Fragrecord* regFragPtr,
|
||||
Uint32* keyBuffer,
|
||||
Uint32& noPrimKey,
|
||||
Uint32* const afterBuffer,
|
||||
Uint32* afterBuffer,
|
||||
Uint32& noAfterWords,
|
||||
Uint32* const beforeBuffer,
|
||||
Uint32* beforeBuffer,
|
||||
Uint32& noBeforeWords);
|
||||
|
||||
void sendTrigAttrInfo(Signal* signal,
|
||||
@ -1970,8 +2074,8 @@ private:
|
||||
|
||||
void sendFireTrigOrd(Signal* signal,
|
||||
KeyReqStruct *req_struct,
|
||||
Operationrec * const regOperPtr,
|
||||
TupTriggerData* const trigPtr,
|
||||
Operationrec * regOperPtr,
|
||||
TupTriggerData* trigPtr,
|
||||
Uint32 fragmentId,
|
||||
Uint32 noPrimKeySignals,
|
||||
Uint32 noBeforeSignals,
|
||||
@ -1982,19 +2086,19 @@ private:
|
||||
// these set terrorCode and return non-zero on error
|
||||
|
||||
int executeTuxInsertTriggers(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
int executeTuxUpdateTriggers(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
int executeTuxDeleteTriggers(Signal* signal,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
int addTuxEntries(Signal* signal,
|
||||
Operationrec* regOperPtr,
|
||||
@ -2004,16 +2108,15 @@ private:
|
||||
|
||||
void executeTuxCommitTriggers(Signal* signal,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void executeTuxAbortTriggers(Signal* signal,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void removeTuxEntries(Signal* signal,
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
// *****************************************************************
|
||||
@ -2092,7 +2195,7 @@ private:
|
||||
//------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
void checkPages(Fragrecord* const regFragPtr);
|
||||
void checkPages(Fragrecord* regFragPtr);
|
||||
#endif
|
||||
Uint32 convert_byte_to_word_size(Uint32 byte_size)
|
||||
{
|
||||
@ -2106,59 +2209,53 @@ private:
|
||||
void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
|
||||
void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
|
||||
void setup_fixed_part(KeyReqStruct* req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void send_TUPKEYREF(Signal* signal,
|
||||
Operationrec* const regOperPtr);
|
||||
Operationrec* regOperPtr);
|
||||
void early_tupkey_error(Signal* signal);
|
||||
|
||||
void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
|
||||
|
||||
bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
|
||||
Uint32* updateBuffer,
|
||||
Tablerec* const regTabPtr);
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void setNullBits(Uint32*, Tablerec* const regTabPtr);
|
||||
void setNullBits(Uint32*, Tablerec* regTabPtr);
|
||||
bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
|
||||
bool setup_read(KeyReqStruct* req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
bool disk);
|
||||
|
||||
bool getPageLastCommitted(Operationrec* const regOperPtr,
|
||||
Operationrec* const leaderOpPtr);
|
||||
|
||||
bool getPageThroughSavePoint(Operationrec* const regOperPtr,
|
||||
Operationrec* const leaderOpPtr);
|
||||
|
||||
Uint32 calculateChecksum(Tuple_header*, Tablerec* const regTabPtr);
|
||||
void setChecksum(Tuple_header*, Tablerec* const regTabPtr);
|
||||
Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
|
||||
void setChecksum(Tuple_header*, Tablerec* regTabPtr);
|
||||
|
||||
void complexTrigger(Signal* signal,
|
||||
KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void setTupleStatesSetOpType(Operationrec* const regOperPtr,
|
||||
void setTupleStatesSetOpType(Operationrec* regOperPtr,
|
||||
KeyReqStruct *req_struct,
|
||||
Page* const pagePtr,
|
||||
Page* pagePtr,
|
||||
Uint32& opType,
|
||||
OperationrecPtr& firstOpPtr);
|
||||
|
||||
void findBeforeValueOperation(OperationrecPtr& befOpPtr,
|
||||
OperationrecPtr firstOpPtr);
|
||||
|
||||
void calculateChangeMask(Page* const PagePtr,
|
||||
Tablerec* const regTabPtr,
|
||||
KeyReqStruct * const req_struct);
|
||||
void calculateChangeMask(Page* PagePtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct * req_struct);
|
||||
|
||||
void updateGcpId(KeyReqStruct *req_struct,
|
||||
Operationrec* const regOperPtr,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr);
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr);
|
||||
|
||||
void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
|
||||
void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);
|
||||
@ -2170,14 +2267,14 @@ private:
|
||||
void updatePackedList(Signal* signal, Uint16 ahostIndex);
|
||||
|
||||
void setUpDescriptorReferences(Uint32 descriptorReference,
|
||||
Tablerec* const regTabPtr,
|
||||
Tablerec* regTabPtr,
|
||||
const Uint32* offset);
|
||||
void setUpKeyArray(Tablerec* const regTabPtr);
|
||||
bool addfragtotab(Tablerec* const regTabPtr, Uint32 fragId, Uint32 fragIndex);
|
||||
void deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId);
|
||||
void setUpKeyArray(Tablerec* regTabPtr);
|
||||
bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
|
||||
void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
|
||||
void abortAddFragOp(Signal* signal);
|
||||
void releaseTabDescr(Tablerec* const regTabPtr);
|
||||
void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr);
|
||||
void releaseTabDescr(Tablerec* regTabPtr);
|
||||
void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
|
||||
|
||||
void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
|
||||
void initializeAttrbufrec();
|
||||
@ -2194,7 +2291,7 @@ private:
|
||||
void initializeTabDescr();
|
||||
void initializeUndoPage();
|
||||
|
||||
void initTab(Tablerec* const regTabPtr);
|
||||
void initTab(Tablerec* regTabPtr);
|
||||
|
||||
void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2);
|
||||
|
||||
@ -2204,17 +2301,17 @@ private:
|
||||
void fragrefuse3Lab(Signal* signal,
|
||||
FragoperrecPtr fragOperPtr,
|
||||
FragrecordPtr regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Tablerec* regTabPtr,
|
||||
Uint32 fragId);
|
||||
void fragrefuse4Lab(Signal* signal,
|
||||
FragoperrecPtr fragOperPtr,
|
||||
FragrecordPtr regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Tablerec* regTabPtr,
|
||||
Uint32 fragId);
|
||||
void addattrrefuseLab(Signal* signal,
|
||||
FragrecordPtr regFragPtr,
|
||||
FragoperrecPtr fragOperPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Tablerec* regTabPtr,
|
||||
Uint32 fragId);
|
||||
|
||||
|
||||
@ -2291,24 +2388,25 @@ private:
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Public methods
|
||||
Uint32 getRealpid(Fragrecord* const regFragPtr, Uint32 logicalPageId);
|
||||
Uint32 getNoOfPages(Fragrecord* const regFragPtr);
|
||||
Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
|
||||
Uint32 getNoOfPages(Fragrecord* regFragPtr);
|
||||
void initPageRangeSize(Uint32 size);
|
||||
bool insertPageRangeTab(Fragrecord* const regFragPtr,
|
||||
bool insertPageRangeTab(Fragrecord* regFragPtr,
|
||||
Uint32 startPageId,
|
||||
Uint32 noPages);
|
||||
void releaseFragPages(Fragrecord* const regFragPtr);
|
||||
void initFragRange(Fragrecord* const regFragPtr);
|
||||
void releaseFragPages(Fragrecord* regFragPtr);
|
||||
void initFragRange(Fragrecord* regFragPtr);
|
||||
void initializePageRange();
|
||||
Uint32 getEmptyPage(Fragrecord* const regFragPtr);
|
||||
Uint32 allocFragPages(Fragrecord* const regFragPtr, Uint32 noOfPagesAllocated);
|
||||
|
||||
Uint32 getEmptyPage(Fragrecord* regFragPtr);
|
||||
Uint32 allocFragPages(Fragrecord* regFragPtr, Uint32 noOfPagesAllocated);
|
||||
Uint32 get_empty_var_page(Fragrecord* frag_ptr);
|
||||
|
||||
// Private methods
|
||||
Uint32 leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr);
|
||||
Uint32 leafPageRangeFull(Fragrecord* regFragPtr, PageRangePtr currPageRangePtr);
|
||||
void releasePagerange(PageRangePtr regPRPtr);
|
||||
void seizePagerange(PageRangePtr& regPageRangePtr);
|
||||
void errorHandler(Uint32 errorCode);
|
||||
void allocMoreFragPages(Fragrecord* const regFragPtr);
|
||||
void allocMoreFragPages(Fragrecord* regFragPtr);
|
||||
|
||||
// Private data
|
||||
Uint32 cfirstfreerange;
|
||||
@ -2328,7 +2426,7 @@ private:
|
||||
// Private methods
|
||||
|
||||
Uint32 get_alloc_page(Fragrecord* const, Uint32);
|
||||
void update_free_page_list(Fragrecord* const, Var_page*);
|
||||
void update_free_page_list(Fragrecord* const, Ptr<Page>);
|
||||
|
||||
#if 0
|
||||
Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
|
||||
@ -2346,10 +2444,11 @@ private:
|
||||
//---------------------------------------------------------------
|
||||
//
|
||||
// Public methods
|
||||
Uint32* alloc_var_rec(Fragrecord*const, Tablerec*const, Uint32, Local_key*,
|
||||
Uint32*, Uint32 base);
|
||||
void free_var_part(Fragrecord*, Tablerec*, Var_part_ref, Uint32 chain);
|
||||
void free_var_part(Fragrecord*, Tablerec*, Local_key*, Var_page*, Uint32 chain);
|
||||
Uint32* alloc_var_rec(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
|
||||
void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
|
||||
Uint32* alloc_var_part(Fragrecord*, Tablerec*, Uint32, Local_key*);
|
||||
int realloc_var_part(Fragrecord*, Tablerec*,
|
||||
PagePtr, Var_part_ref*, Uint32, Uint32);
|
||||
|
||||
void validate_page(Tablerec*, Var_page* page);
|
||||
|
||||
@ -2357,15 +2456,18 @@ private:
|
||||
Uint32*);
|
||||
void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
|
||||
|
||||
Uint32* alloc_fix_rowid(Fragrecord*, Tablerec*, Local_key*, Uint32 *);
|
||||
Uint32* alloc_var_rowid(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
|
||||
// Private methods
|
||||
void convertThPage(Uint32 Tupheadsize,
|
||||
Fix_page* const regPagePtr);
|
||||
void convertThPage(Fix_page* regPagePtr,
|
||||
Tablerec*,
|
||||
Uint32 mm);
|
||||
|
||||
/**
|
||||
* Return offset
|
||||
*/
|
||||
Uint32 alloc_tuple_from_page(Fragrecord* const regFragPtr,
|
||||
Fix_page* const regPagePtr);
|
||||
Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
|
||||
Fix_page* regPagePtr);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Temporary variables used for storing commonly used variables
|
||||
@ -2398,8 +2500,7 @@ private:
|
||||
|
||||
ArrayPool<Operationrec> c_operation_pool;
|
||||
|
||||
Page *cpage;
|
||||
Uint32 cnoOfPage;
|
||||
ArrayPool<Page> c_page_pool;
|
||||
Uint32 cnoOfAllocatedPages;
|
||||
|
||||
Tablerec *tablerec;
|
||||
@ -2437,9 +2538,6 @@ private:
|
||||
// Trigger variables
|
||||
Uint32 c_maxTriggersPerTable;
|
||||
|
||||
STATIC_CONST(MAX_PARALLELL_TUP_SRREQ = 2);
|
||||
Uint32 c_sr_free_page_0;
|
||||
|
||||
Uint32 c_errorInsert4000TableId;
|
||||
Uint32 c_min_list_size[MAX_FREE_LIST + 1];
|
||||
Uint32 c_max_list_size[MAX_FREE_LIST + 1];
|
||||
@ -2462,9 +2560,9 @@ private:
|
||||
bool disk);
|
||||
|
||||
Uint32* get_ptr(Var_part_ref);
|
||||
Uint32* get_ptr(Ptr<Var_page>*, Var_part_ref);
|
||||
Uint32* get_ptr(PagePtr*, Var_part_ref);
|
||||
Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
|
||||
Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*, Uint32 mm);
|
||||
Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
|
||||
|
||||
/**
|
||||
* prealloc space from disk
|
||||
@ -2561,7 +2659,7 @@ private:
|
||||
#endif
|
||||
|
||||
void fix_commit_order(OperationrecPtr);
|
||||
void commit_operation(Signal*, Uint32, Tuple_header*, Page*,
|
||||
void commit_operation(Signal*, Uint32, Tuple_header*, PagePtr,
|
||||
Operationrec*, Fragrecord*, Tablerec*);
|
||||
|
||||
void dealloc_tuple(Signal* signal, Uint32, Page*, Tuple_header*,
|
||||
@ -2570,8 +2668,8 @@ private:
|
||||
int handle_size_change_after_update(KeyReqStruct* req_struct,
|
||||
Tuple_header* org,
|
||||
Operationrec*,
|
||||
Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
Uint32 sizes[4]);
|
||||
|
||||
/**
|
||||
@ -2581,6 +2679,7 @@ private:
|
||||
void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
|
||||
};
|
||||
|
||||
#if 0
|
||||
inline
|
||||
Uint32
|
||||
Dbtup::get_frag_page_id(Uint32 real_page_id)
|
||||
@ -2590,17 +2689,18 @@ Dbtup::get_frag_page_id(Uint32 real_page_id)
|
||||
ptrCheckGuard(real_page_ptr, cnoOfPage, cpage);
|
||||
return real_page_ptr.p->frag_page_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline
|
||||
Dbtup::TransState
|
||||
Dbtup::get_trans_state(Operationrec * const regOperPtr)
|
||||
Dbtup::get_trans_state(Operationrec * regOperPtr)
|
||||
{
|
||||
return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
Dbtup::set_trans_state(Operationrec* const regOperPtr,
|
||||
Dbtup::set_trans_state(Operationrec* regOperPtr,
|
||||
Dbtup::TransState trans_state)
|
||||
{
|
||||
regOperPtr->op_struct.trans_state= (Uint32)trans_state;
|
||||
@ -2608,14 +2708,14 @@ Dbtup::set_trans_state(Operationrec* const regOperPtr,
|
||||
|
||||
inline
|
||||
Dbtup::TupleState
|
||||
Dbtup::get_tuple_state(Operationrec * const regOperPtr)
|
||||
Dbtup::get_tuple_state(Operationrec * regOperPtr)
|
||||
{
|
||||
return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
Dbtup::set_tuple_state(Operationrec* const regOperPtr,
|
||||
Dbtup::set_tuple_state(Operationrec* regOperPtr,
|
||||
Dbtup::TupleState tuple_state)
|
||||
{
|
||||
regOperPtr->op_struct.tuple_state= (Uint32)tuple_state;
|
||||
@ -2631,14 +2731,14 @@ Dbtup::decr_tup_version(Uint32 tup_version)
|
||||
|
||||
inline
|
||||
Dbtup::ChangeMaskState
|
||||
Dbtup::get_change_mask_state(Operationrec * const regOperPtr)
|
||||
Dbtup::get_change_mask_state(Operationrec * regOperPtr)
|
||||
{
|
||||
return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
Dbtup::set_change_mask_state(Operationrec * const regOperPtr,
|
||||
Dbtup::set_change_mask_state(Operationrec * regOperPtr,
|
||||
ChangeMaskState new_state)
|
||||
{
|
||||
regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
|
||||
@ -2646,8 +2746,8 @@ Dbtup::set_change_mask_state(Operationrec * const regOperPtr,
|
||||
|
||||
inline
|
||||
void
|
||||
Dbtup::update_change_mask_info(KeyReqStruct * const req_struct,
|
||||
Operationrec * const regOperPtr)
|
||||
Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
|
||||
Operationrec * regOperPtr)
|
||||
{
|
||||
//Save change mask
|
||||
if (req_struct->max_attr_id_updated == 0) {
|
||||
@ -2667,19 +2767,19 @@ inline
|
||||
Uint32*
|
||||
Dbtup::get_ptr(Var_part_ref ref)
|
||||
{
|
||||
Ptr<Var_page> tmp;
|
||||
Ptr<Page> tmp;
|
||||
return get_ptr(&tmp, ref);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint32*
|
||||
Dbtup::get_ptr(Ptr<Var_page>* pagePtr, Var_part_ref ref)
|
||||
Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
|
||||
{
|
||||
PagePtr tmp;
|
||||
Uint32 page_idx= ref.m_ref & MAX_TUPLES_PER_PAGE;
|
||||
tmp.i= ref.m_ref >> MAX_TUPLES_BITS;
|
||||
|
||||
ptrCheckGuard(tmp, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(tmp);
|
||||
memcpy(pagePtr, &tmp, sizeof(tmp));
|
||||
return ((Var_page*)tmp.p)->get_ptr(page_idx);
|
||||
}
|
||||
@ -2691,38 +2791,28 @@ Dbtup::get_ptr(PagePtr* pagePtr,
|
||||
{
|
||||
PagePtr tmp;
|
||||
tmp.i= key->m_page_no;
|
||||
ptrCheckGuard(tmp, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(tmp);
|
||||
memcpy(pagePtr, &tmp, sizeof(tmp));
|
||||
|
||||
if(regTabPtr->m_attributes[MM].m_no_of_varsize)
|
||||
return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
|
||||
else
|
||||
return ((Fix_page*)tmp.p)->
|
||||
get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
|
||||
return ((Fix_page*)tmp.p)->
|
||||
get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint32*
|
||||
Dbtup::get_ptr(PagePtr* pagePtr,
|
||||
const Local_key* key, const Tablerec* regTabPtr, Uint32 mm)
|
||||
Dbtup::get_dd_ptr(PagePtr* pagePtr,
|
||||
const Local_key* key, const Tablerec* regTabPtr)
|
||||
{
|
||||
PagePtr tmp;
|
||||
tmp.i= key->m_page_no;
|
||||
if(mm == MM)
|
||||
{
|
||||
ptrCheckGuard(tmp, cnoOfPage, cpage);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
|
||||
}
|
||||
tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
|
||||
memcpy(pagePtr, &tmp, sizeof(tmp));
|
||||
|
||||
if(regTabPtr->m_attributes[mm].m_no_of_varsize)
|
||||
if(regTabPtr->m_attributes[DD].m_no_of_varsize)
|
||||
return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
|
||||
else
|
||||
return ((Fix_page*)tmp.p)->
|
||||
get_ptr(key->m_page_idx, regTabPtr->m_offsets[mm].m_fix_header_size);
|
||||
get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
|
||||
}
|
||||
|
||||
NdbOut&
|
||||
|
@ -132,45 +132,48 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal)
|
||||
disk_page_abort_prealloc(signal, regFragPtr.p, &key, key.m_page_idx);
|
||||
}
|
||||
|
||||
Uint32 bits= copy->m_header_bits;
|
||||
Uint32 bits= tuple_ptr->m_header_bits;
|
||||
Uint32 copy_bits= copy->m_header_bits;
|
||||
if(! (bits & Tuple_header::ALLOC))
|
||||
{
|
||||
if(bits & Tuple_header::MM_GROWN)
|
||||
if(copy_bits & Tuple_header::MM_GROWN)
|
||||
{
|
||||
ndbout_c("abort grow");
|
||||
Var_page *pageP= (Var_page*)page.p;
|
||||
Uint32 idx= regOperPtr.p->m_tuple_location.m_page_idx, sz;
|
||||
Ptr<Page> vpage;
|
||||
Uint32 idx= regOperPtr.p->m_tuple_location.m_page_idx;
|
||||
Uint32 mm_vars= regTabPtr.p->m_attributes[MM].m_no_of_varsize;
|
||||
Uint32 *var_part;
|
||||
if(! (tuple_ptr->m_header_bits & Tuple_header::CHAINED_ROW))
|
||||
{
|
||||
var_part= tuple_ptr->get_var_part_ptr(regTabPtr.p);
|
||||
sz= Tuple_header::HeaderSize +
|
||||
regTabPtr.p->m_offsets[MM].m_fix_header_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<Var_page> vpage;
|
||||
Uint32 ref= * tuple_ptr->get_var_part_ptr(regTabPtr.p);
|
||||
Local_key tmp;
|
||||
tmp.assref(ref);
|
||||
|
||||
sz= 0;
|
||||
|
||||
ndbassert(tuple_ptr->m_header_bits & Tuple_header::CHAINED_ROW);
|
||||
|
||||
Uint32 ref= * tuple_ptr->get_var_part_ptr(regTabPtr.p);
|
||||
Local_key tmp;
|
||||
tmp.assref(ref);
|
||||
|
||||
idx= tmp.m_page_idx;
|
||||
var_part= get_ptr(&vpage, *(Var_part_ref*)&ref);
|
||||
pageP= vpage.p;
|
||||
}
|
||||
Var_page* pageP = (Var_page*)vpage.p;
|
||||
Uint32 len= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
|
||||
sz += ((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
|
||||
Uint32 sz = ((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
|
||||
ndbassert(sz <= len);
|
||||
pageP->shrink_entry(idx, sz);
|
||||
update_free_page_list(regFragPtr.p, pageP);
|
||||
update_free_page_list(regFragPtr.p, vpage);
|
||||
}
|
||||
else if(bits & Tuple_header::MM_SHRINK)
|
||||
{
|
||||
ndbout_c("abort shrink");
|
||||
}
|
||||
}
|
||||
else if (regOperPtr.p->is_first_operation() &&
|
||||
regOperPtr.p->is_last_operation())
|
||||
{
|
||||
/**
|
||||
* Aborting last operation that performed ALLOC
|
||||
*/
|
||||
ndbout_c("clearing ALLOC");
|
||||
tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
|
||||
tuple_ptr->m_header_bits |= Tuple_header::FREE;
|
||||
}
|
||||
}
|
||||
|
||||
if(regOperPtr.p->is_first_operation() && regOperPtr.p->is_last_operation())
|
||||
@ -338,9 +341,15 @@ void Dbtup::tupkeyErrorLab(Signal* signal)
|
||||
c_lgman->free_log_space(fragPtr.p->m_logfile_group_id,
|
||||
regOperPtr->m_undo_buffer_space);
|
||||
}
|
||||
|
||||
PagePtr tmp;
|
||||
Uint32 *ptr= get_ptr(&tmp, ®OperPtr->m_tuple_location, tabPtr.p);
|
||||
|
||||
Uint32 *ptr = 0;
|
||||
if (!regOperPtr->m_tuple_location.isNull())
|
||||
{
|
||||
PagePtr tmp;
|
||||
ptr= get_ptr(&tmp, ®OperPtr->m_tuple_location, tabPtr.p);
|
||||
}
|
||||
|
||||
|
||||
removeActiveOpList(regOperPtr, (Tuple_header*)ptr);
|
||||
initOpConnection(regOperPtr);
|
||||
send_TUPKEYREF(signal, regOperPtr);
|
||||
|
@ -55,14 +55,7 @@ void Dbtup::execTUP_DEALLOCREQ(Signal* signal)
|
||||
if (regTabPtr.p->m_attributes[MM].m_no_of_varsize)
|
||||
{
|
||||
ljam();
|
||||
|
||||
if(ptr->m_header_bits & Tuple_header::CHAINED_ROW)
|
||||
{
|
||||
free_var_part(regFragPtr.p, regTabPtr.p,
|
||||
*(Var_part_ref*)ptr->get_var_part_ptr(regTabPtr.p),
|
||||
Var_page::CHAIN);
|
||||
}
|
||||
free_var_part(regFragPtr.p, regTabPtr.p, &tmp, (Var_page*)pagePtr.p, 0);
|
||||
free_var_rec(regFragPtr.p, regTabPtr.p, &tmp, pagePtr);
|
||||
} else {
|
||||
free_fix_rec(regFragPtr.p, regTabPtr.p, &tmp, (Fix_page*)pagePtr.p);
|
||||
}
|
||||
@ -156,15 +149,19 @@ Dbtup::dealloc_tuple(Signal* signal,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr)
|
||||
{
|
||||
ptr->m_header_bits |= Tuple_header::FREE;
|
||||
if (ptr->m_header_bits & Tuple_header::DISK_PART)
|
||||
{
|
||||
Local_key disk;
|
||||
memcpy(&disk, ptr->get_disk_ref_ptr(regTabPtr), sizeof(disk));
|
||||
Ptr<GlobalPage> disk_page;
|
||||
m_global_page_pool.getPtr(disk_page,
|
||||
regOperPtr->m_commit_disk_callback_page);
|
||||
disk_page_free(signal, regTabPtr, regFragPtr,
|
||||
&disk, *(PagePtr*)&disk_page, gci);
|
||||
&disk, *(PagePtr*)&m_pgman.m_ptr, gci);
|
||||
}
|
||||
|
||||
if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
jam();
|
||||
* ptr->get_mm_gci(regTabPtr) = gci;
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +178,7 @@ void
|
||||
Dbtup::commit_operation(Signal* signal,
|
||||
Uint32 gci,
|
||||
Tuple_header* tuple_ptr,
|
||||
Page* page,
|
||||
PagePtr pagePtr,
|
||||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr)
|
||||
@ -197,76 +194,39 @@ Dbtup::commit_operation(Signal* signal,
|
||||
|
||||
Uint32 copy_bits= copy->m_header_bits;
|
||||
|
||||
Uint32 fix_size= regTabPtr->m_offsets[MM].m_fix_header_size;
|
||||
Uint32 fixsize= regTabPtr->m_offsets[MM].m_fix_header_size;
|
||||
Uint32 mm_vars= regTabPtr->m_attributes[MM].m_no_of_varsize;
|
||||
if(mm_vars == 0)
|
||||
{
|
||||
memcpy(tuple_ptr, copy, 4*fix_size);
|
||||
//ndbout_c("commit: memcpy %p %p %d", tuple_ptr, copy, 4*fix_size);
|
||||
disk_ptr= (Tuple_header*)(((Uint32*)copy)+fix_size);
|
||||
memcpy(tuple_ptr, copy, 4*fixsize);
|
||||
disk_ptr= (Tuple_header*)(((Uint32*)copy)+fixsize);
|
||||
}
|
||||
else if(bits & Tuple_header::CHAINED_ROW)
|
||||
else
|
||||
{
|
||||
Uint32 *ref= tuple_ptr->get_var_part_ptr(regTabPtr);
|
||||
memcpy(tuple_ptr, copy, 4*(Tuple_header::HeaderSize+fix_size));
|
||||
|
||||
memcpy(tuple_ptr, copy, 4*(Tuple_header::HeaderSize+fixsize));
|
||||
|
||||
Local_key tmp; tmp.assref(*ref);
|
||||
if(0) printf("%p %d %d (%d bytes) - ref: %x ", tuple_ptr,
|
||||
regOperPtr->m_tuple_location.m_page_no,
|
||||
regOperPtr->m_tuple_location.m_page_idx,
|
||||
4*(Tuple_header::HeaderSize+fix_size),
|
||||
*ref);
|
||||
Ptr<Var_page> vpagePtr;
|
||||
|
||||
PagePtr vpagePtr;
|
||||
Uint32 *dst= get_ptr(&vpagePtr, *(Var_part_ref*)ref);
|
||||
Var_page* vpagePtrP = (Var_page*)vpagePtr.p;
|
||||
Uint32 *src= copy->get_var_part_ptr(regTabPtr);
|
||||
Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)src)[mm_vars]);
|
||||
ndbassert(4*vpagePtr.p->get_entry_len(tmp.m_page_idx) >= sz);
|
||||
ndbassert(4*vpagePtrP->get_entry_len(tmp.m_page_idx) >= sz);
|
||||
memcpy(dst, src, sz);
|
||||
if(0) printf("ptr: %p %d ref: %x - chain commit", dst, sz, *ref);
|
||||
|
||||
copy_bits |= Tuple_header::CHAINED_ROW;
|
||||
|
||||
if(0)
|
||||
if(copy_bits & Tuple_header::MM_SHRINK)
|
||||
{
|
||||
for(Uint32 i = 0; i<((sz+3)>>2); i++)
|
||||
printf(" %.8x", src[i]);
|
||||
printf("\n");
|
||||
}
|
||||
vpagePtrP->shrink_entry(tmp.m_page_idx, (sz + 3) >> 2);
|
||||
update_free_page_list(regFragPtr, vpagePtr);
|
||||
}
|
||||
|
||||
if(copy_bits & Tuple_header::MM_SHRINK)
|
||||
{
|
||||
if(0) printf(" - shrink %d -> %d - ",
|
||||
vpagePtr.p->get_entry_len(tmp.m_page_idx), (sz + 3) >> 2);
|
||||
vpagePtr.p->shrink_entry(tmp.m_page_idx, (sz + 3) >> 2);
|
||||
if(0)ndbout_c("%p->shrink_entry(%d, %d)", vpagePtr.p, tmp.m_page_idx,
|
||||
(sz + 3) >> 2);
|
||||
update_free_page_list(regFragPtr, vpagePtr.p);
|
||||
}
|
||||
if(0) ndbout_c("");
|
||||
disk_ptr = (Tuple_header*)
|
||||
(((Uint32*)copy)+Tuple_header::HeaderSize+fix_size+((sz + 3) >> 2));
|
||||
(((Uint32*)copy)+Tuple_header::HeaderSize+fixsize+((sz + 3) >> 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint32 *var_part= copy->get_var_part_ptr(regTabPtr);
|
||||
Uint32 sz= Tuple_header::HeaderSize + fix_size +
|
||||
((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
|
||||
ndbassert(((Var_page*)page)->
|
||||
get_entry_len(regOperPtr->m_tuple_location.m_page_idx) >= sz);
|
||||
memcpy(tuple_ptr, copy, 4*sz);
|
||||
if(0) ndbout_c("%p %d %d (%d bytes)", tuple_ptr,
|
||||
regOperPtr->m_tuple_location.m_page_no,
|
||||
regOperPtr->m_tuple_location.m_page_idx,
|
||||
4*sz);
|
||||
if(copy_bits & Tuple_header::MM_SHRINK)
|
||||
{
|
||||
((Var_page*)page)->shrink_entry(regOperPtr->m_tuple_location.m_page_idx,
|
||||
sz);
|
||||
if(0)ndbout_c("%p->shrink_entry(%d, %d)",
|
||||
page, regOperPtr->m_tuple_location.m_page_idx, sz);
|
||||
update_free_page_list(regFragPtr, (Var_page*)page);
|
||||
}
|
||||
disk_ptr = (Tuple_header*)(((Uint32*)copy)+sz);
|
||||
}
|
||||
|
||||
if (regTabPtr->m_no_of_disk_attributes &&
|
||||
(copy_bits & Tuple_header::DISK_INLINE))
|
||||
@ -276,13 +236,13 @@ Dbtup::commit_operation(Signal* signal,
|
||||
Uint32 logfile_group_id= regFragPtr->m_logfile_group_id;
|
||||
Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op;
|
||||
|
||||
PagePtr pagePtr = *(PagePtr*)&m_pgman.m_ptr;
|
||||
ndbassert(pagePtr.p->m_page_no == key.m_page_no);
|
||||
ndbassert(pagePtr.p->m_file_no == key.m_file_no);
|
||||
PagePtr diskPagePtr = *(PagePtr*)&m_pgman.m_ptr;
|
||||
ndbassert(diskPagePtr.p->m_page_no == key.m_page_no);
|
||||
ndbassert(diskPagePtr.p->m_file_no == key.m_file_no);
|
||||
Uint32 sz, *dst;
|
||||
if(copy_bits & Tuple_header::DISK_ALLOC)
|
||||
{
|
||||
disk_page_alloc(signal, regTabPtr, regFragPtr, &key, pagePtr, gci);
|
||||
disk_page_alloc(signal, regTabPtr, regFragPtr, &key, diskPagePtr, gci);
|
||||
|
||||
if(lcpScan_ptr_i != RNIL)
|
||||
{
|
||||
@ -301,17 +261,18 @@ Dbtup::commit_operation(Signal* signal,
|
||||
if(regTabPtr->m_attributes[DD].m_no_of_varsize == 0)
|
||||
{
|
||||
sz= regTabPtr->m_offsets[DD].m_fix_header_size;
|
||||
dst= ((Fix_page*)pagePtr.p)->get_ptr(key.m_page_idx, sz);
|
||||
dst= ((Fix_page*)diskPagePtr.p)->get_ptr(key.m_page_idx, sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst= ((Var_page*)pagePtr.p)->get_ptr(key.m_page_idx);
|
||||
sz= ((Var_page*)pagePtr.p)->get_entry_len(key.m_page_idx);
|
||||
dst= ((Var_page*)diskPagePtr.p)->get_ptr(key.m_page_idx);
|
||||
sz= ((Var_page*)diskPagePtr.p)->get_entry_len(key.m_page_idx);
|
||||
}
|
||||
|
||||
if(! (copy_bits & Tuple_header::DISK_ALLOC))
|
||||
{
|
||||
disk_page_undo_update(pagePtr.p, &key, dst, sz, gci, logfile_group_id);
|
||||
disk_page_undo_update(diskPagePtr.p,
|
||||
&key, dst, sz, gci, logfile_group_id);
|
||||
}
|
||||
|
||||
memcpy(dst, disk_ptr, 4*sz);
|
||||
@ -320,10 +281,10 @@ Dbtup::commit_operation(Signal* signal,
|
||||
ndbassert(! (disk_ptr->m_header_bits & Tuple_header::FREE));
|
||||
copy_bits |= Tuple_header::DISK_PART;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uint32 clear=
|
||||
Tuple_header::ALLOC |
|
||||
Tuple_header::ALLOC | Tuple_header::FREE |
|
||||
Tuple_header::DISK_ALLOC | Tuple_header::DISK_INLINE |
|
||||
Tuple_header::MM_SHRINK | Tuple_header::MM_GROWN;
|
||||
copy_bits &= ~(Uint32)clear;
|
||||
@ -331,7 +292,13 @@ Dbtup::commit_operation(Signal* signal,
|
||||
tuple_ptr->m_header_bits= copy_bits;
|
||||
tuple_ptr->m_operation_ptr_i= save;
|
||||
|
||||
if (regTabPtr->checksumIndicator) {
|
||||
if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
jam();
|
||||
* tuple_ptr->get_mm_gci(regTabPtr) = gci;
|
||||
}
|
||||
|
||||
if (regTabPtr->m_bits & Tablerec::TR_Checksum) {
|
||||
jam();
|
||||
setChecksum(tuple_ptr, regTabPtr);
|
||||
}
|
||||
@ -505,8 +472,13 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal)
|
||||
req.m_callback.m_callbackFunction =
|
||||
safe_cast(&Dbtup::disk_page_commit_callback);
|
||||
|
||||
/*
|
||||
* Consider commit to be correlated. Otherwise pk op + commit makes
|
||||
* the page hot. XXX move to TUP which knows better.
|
||||
*/
|
||||
int flags= regOperPtr.p->op_struct.op_type |
|
||||
Page_cache_client::COMMIT_REQ | Page_cache_client::STRICT_ORDER;
|
||||
Page_cache_client::COMMIT_REQ | Page_cache_client::STRICT_ORDER |
|
||||
Page_cache_client::CORR_REQ;
|
||||
int res= m_pgman.get_page(signal, req, flags);
|
||||
switch(res){
|
||||
case 0:
|
||||
@ -548,9 +520,10 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal)
|
||||
|
||||
if(!tuple_ptr)
|
||||
{
|
||||
req_struct.m_tuple_ptr= tuple_ptr = (Tuple_header*)
|
||||
tuple_ptr = (Tuple_header*)
|
||||
get_ptr(&page, ®OperPtr.p->m_tuple_location,regTabPtr.p);
|
||||
}
|
||||
req_struct.m_tuple_ptr = tuple_ptr;
|
||||
|
||||
if(get_tuple_state(regOperPtr.p) == TUPLE_PREPARED)
|
||||
{
|
||||
@ -587,7 +560,7 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal)
|
||||
|
||||
if(regOperPtr.p->op_struct.op_type != ZDELETE)
|
||||
{
|
||||
commit_operation(signal, gci, tuple_ptr, page.p,
|
||||
commit_operation(signal, gci, tuple_ptr, page,
|
||||
regOperPtr.p, regFragPtr.p, regTabPtr.p);
|
||||
removeActiveOpList(regOperPtr.p, tuple_ptr);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ void Dbtup::execDEBUG_SIG(Signal* signal)
|
||||
PagePtr regPagePtr;
|
||||
ljamEntry();
|
||||
regPagePtr.i = signal->theData[0];
|
||||
ptrCheckGuard(regPagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(regPagePtr);
|
||||
}//Dbtup::execDEBUG_SIG()
|
||||
|
||||
#ifdef TEST_MR
|
||||
@ -72,7 +72,7 @@ Dbtup::reportMemoryUsage(Signal* signal, int incDec){
|
||||
signal->theData[1] = incDec;
|
||||
signal->theData[2] = sizeof(Page);
|
||||
signal->theData[3] = cnoOfAllocatedPages;
|
||||
signal->theData[4] = cnoOfPage;
|
||||
signal->theData[4] = c_page_pool.getSize();
|
||||
signal->theData[5] = DBTUP;
|
||||
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
|
||||
}
|
||||
@ -168,7 +168,7 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
|
||||
|
||||
// Case
|
||||
Uint32 c = (rand() % 3);
|
||||
const Uint32 free = cnoOfPage - cnoOfAllocatedPages;
|
||||
const Uint32 free = c_page_pool.getSize() - cnoOfAllocatedPages;
|
||||
|
||||
Uint32 alloc = 0;
|
||||
if(free <= 1){
|
||||
@ -213,7 +213,7 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
|
||||
for(Uint32 i = 0; i<chunk.pageCount; i++){
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = chunk.pageId + i;
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr);
|
||||
pagePtr.p->page_state = ~ZFREE_COMMON;
|
||||
}
|
||||
|
||||
@ -281,8 +281,7 @@ void Dbtup::printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit)
|
||||
FragrecordPtr tmpFragP;
|
||||
TablerecPtr tmpTableP;
|
||||
|
||||
tmpPageP.i = pageid;
|
||||
ptrCheckGuard(tmpPageP, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(tmpPageP, pageid);
|
||||
|
||||
tmpFragP.i = fragid;
|
||||
ptrCheckGuard(tmpFragP, cnoOfFragrec, fragrecord);
|
||||
@ -334,7 +333,7 @@ operator<<(NdbOut& out, const Dbtup::Th& th)
|
||||
out << "[Th " << hex << &th;
|
||||
out << " [op " << hex << th.data[i++] << "]";
|
||||
out << " [version " << hex << (Uint16)th.data[i++] << "]";
|
||||
if (tab.checksumIndicator)
|
||||
if (tab.m_bits & Dbtup::Tablerec::TR_Checksum)
|
||||
out << " [checksum " << hex << th.data[i++] << "]";
|
||||
out << " [nullbits";
|
||||
for (unsigned j = 0; j < tab.m_offsets[Dbtup::MM].m_null_words; j++)
|
||||
@ -381,7 +380,7 @@ NdbOut&
|
||||
operator<<(NdbOut& out, const Dbtup::Tablerec& tab)
|
||||
{
|
||||
out << "[ total_rec_size: " << tab.total_rec_size
|
||||
<< " checksum: " << tab.checksumIndicator
|
||||
<< " checksum: " << !!(tab.m_bits & Dbtup::Tablerec::TR_Checksum)
|
||||
<< " attr: " << tab.m_no_of_attributes
|
||||
<< " disk: " << tab.m_no_of_disk_attributes
|
||||
<< " mm: " << tab.m_offsets[Dbtup::MM]
|
||||
|
@ -20,7 +20,8 @@
|
||||
Dbtup::Disk_alloc_info::Disk_alloc_info(const Tablerec* tabPtrP,
|
||||
Uint32 extent_size)
|
||||
{
|
||||
m_curr_extent_info_ptr_i= RNIL;
|
||||
m_extent_size = extent_size;
|
||||
m_curr_extent_info_ptr_i = RNIL;
|
||||
if (tabPtrP->m_no_of_disk_attributes == 0)
|
||||
return;
|
||||
|
||||
@ -278,6 +279,7 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||
|
||||
int pages= err;
|
||||
ndbout << "allocated " << pages << " pages: " << ext.p->m_key << endl;
|
||||
ext.p->m_first_page_no = ext.p->m_key.m_page_no;
|
||||
bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count));
|
||||
ext.p->m_free_space= alloc.m_page_free_bits_map[0] * pages;
|
||||
ext.p->m_free_page_count[0]= pages; // All pages are "free"-est
|
||||
@ -528,8 +530,7 @@ Dbtup::disk_page_prealloc_initial_callback(Signal*signal,
|
||||
|
||||
if (tabPtr.p->m_attributes[DD].m_no_of_varsize == 0)
|
||||
{
|
||||
convertThPage(tabPtr.p->m_offsets[DD].m_fix_header_size,
|
||||
(Fix_page*)gpage.p);
|
||||
convertThPage((Fix_page*)gpage.p, tabPtr.p, DD);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1060,6 +1061,7 @@ Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
|
||||
|
||||
ext.p->m_key = *key;
|
||||
ndbout << "allocated " << pages << " pages: " << ext.p->m_key << endl;
|
||||
ext.p->m_first_page_no = ext.p->m_key.m_page_no;
|
||||
bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count));
|
||||
ext.p->m_free_space= alloc.m_page_free_bits_map[0] * pages;
|
||||
ext.p->m_free_page_count[0]= pages; // All pages are "free"-est
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,7 +73,7 @@ Dbtup::alloc_fix_rec(Fragrecord* const regFragPtr,
|
||||
/* FAILED. TRY ALLOCATING FROM NORMAL PAGE. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i= regFragPtr->thFreeFirst;
|
||||
pagePtr.i = regFragPtr->thFreeFirst.firstItem;
|
||||
if (pagePtr.i == RNIL) {
|
||||
/* ---------------------------------------------------------------- */
|
||||
// No prepared tuple header page with free entries exists.
|
||||
@ -85,14 +85,16 @@ Dbtup::alloc_fix_rec(Fragrecord* const regFragPtr,
|
||||
// We found empty pages on the fragment. Allocate an empty page and
|
||||
// convert it into a tuple header page and put it in thFreeFirst-list.
|
||||
/* ---------------------------------------------------------------- */
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr);
|
||||
|
||||
ndbassert(pagePtr.p->page_state == ZEMPTY_MM);
|
||||
|
||||
convertThPage(regTabPtr->m_offsets[MM].m_fix_header_size,
|
||||
(Fix_page*)pagePtr.p);
|
||||
convertThPage((Fix_page*)pagePtr.p, regTabPtr, MM);
|
||||
|
||||
pagePtr.p->next_page = regFragPtr->thFreeFirst;
|
||||
pagePtr.p->page_state = ZTH_MM_FREE;
|
||||
regFragPtr->thFreeFirst = pagePtr.i;
|
||||
|
||||
LocalDLList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
|
||||
free_pages.add(pagePtr);
|
||||
} else {
|
||||
ljam();
|
||||
/* ---------------------------------------------------------------- */
|
||||
@ -106,7 +108,7 @@ Dbtup::alloc_fix_rec(Fragrecord* const regFragPtr,
|
||||
/* THIS SHOULD BE THE COMMON PATH THROUGH THE CODE, FREE */
|
||||
/* COPY PAGE EXISTED. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr);
|
||||
}
|
||||
|
||||
Uint32 page_offset= alloc_tuple_from_page(regFragPtr, (Fix_page*)pagePtr.p);
|
||||
@ -117,10 +119,11 @@ Dbtup::alloc_fix_rec(Fragrecord* const regFragPtr,
|
||||
return pagePtr.p->m_data + page_offset;
|
||||
}
|
||||
|
||||
void Dbtup::convertThPage(Uint32 Tupheadsize,
|
||||
Fix_page* const regPagePtr)
|
||||
void Dbtup::convertThPage(Fix_page* regPagePtr,
|
||||
Tablerec* regTabPtr,
|
||||
Uint32 mm)
|
||||
{
|
||||
Uint32 nextTuple = Tupheadsize;
|
||||
Uint32 nextTuple = regTabPtr->m_offsets[mm].m_fix_header_size;
|
||||
Uint32 endOfList;
|
||||
/*
|
||||
ASSUMES AT LEAST ONE TUPLE HEADER FITS AND THEREFORE NO HANDLING
|
||||
@ -132,10 +135,19 @@ void Dbtup::convertThPage(Uint32 Tupheadsize,
|
||||
#ifdef VM_TRACE
|
||||
memset(regPagePtr->m_data, 0xF1, 4*Fix_page::DATA_WORDS);
|
||||
#endif
|
||||
Uint32 gci_pos = 2;
|
||||
Uint32 gci_val = 0xF1F1F1F1;
|
||||
if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
Tuple_header* ptr = 0;
|
||||
gci_pos = ptr->get_mm_gci(regTabPtr) - (Uint32*)ptr;
|
||||
gci_val = 0;
|
||||
}
|
||||
while (pos + nextTuple <= Fix_page::DATA_WORDS)
|
||||
{
|
||||
regPagePtr->m_data[pos] = (prev << 16) | (pos + nextTuple);
|
||||
regPagePtr->m_data[pos + 1] = Tuple_header::FREE;
|
||||
regPagePtr->m_data[pos + 1] = Fix_page::FREE_RECORD;
|
||||
regPagePtr->m_data[pos + gci_pos] = gci_val;
|
||||
prev = pos;
|
||||
pos += nextTuple;
|
||||
cnt ++;
|
||||
@ -151,6 +163,7 @@ Uint32
|
||||
Dbtup::alloc_tuple_from_page(Fragrecord* const regFragPtr,
|
||||
Fix_page* const regPagePtr)
|
||||
{
|
||||
ndbassert(regPagePtr->free_space);
|
||||
Uint32 idx= regPagePtr->alloc_record();
|
||||
if(regPagePtr->free_space == 0)
|
||||
{
|
||||
@ -164,8 +177,8 @@ Dbtup::alloc_tuple_from_page(Fragrecord* const regFragPtr,
|
||||
/* ARE MAINTAINED EVEN AFTER A SYSTEM CRASH. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
ndbrequire(regPagePtr->page_state == ZTH_MM_FREE);
|
||||
regFragPtr->thFreeFirst = regPagePtr->next_page;
|
||||
regPagePtr->next_page = RNIL;
|
||||
LocalDLList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
|
||||
free_pages.remove((Page*)regPagePtr);
|
||||
regPagePtr->page_state = ZTH_MM_FULL;
|
||||
}
|
||||
|
||||
@ -183,10 +196,92 @@ void Dbtup::free_fix_rec(Fragrecord* regFragPtr,
|
||||
if(free == 1)
|
||||
{
|
||||
ljam();
|
||||
PagePtr pagePtr = { (Page*)regPagePtr, key->m_page_no };
|
||||
LocalDLList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
|
||||
ndbrequire(regPagePtr->page_state == ZTH_MM_FULL);
|
||||
regPagePtr->page_state = ZTH_MM_FREE;
|
||||
regPagePtr->next_page= regFragPtr->thFreeFirst;
|
||||
regFragPtr->thFreeFirst = key->m_page_no;
|
||||
free_pages.add(pagePtr);
|
||||
}
|
||||
}//Dbtup::freeTh()
|
||||
|
||||
|
||||
int
|
||||
Dbtup::alloc_page(Tablerec* tabPtrP, Fragrecord* fragPtrP,
|
||||
PagePtr * ret, Uint32 page_no)
|
||||
{
|
||||
Uint32 pages = fragPtrP->noOfPages;
|
||||
|
||||
if (page_no >= pages)
|
||||
{
|
||||
Uint32 start = pages;
|
||||
while(page_no >= pages)
|
||||
pages += (pages >> 3) + (pages >> 4) + 2;
|
||||
allocFragPages(fragPtrP, pages - start);
|
||||
if (page_no >= (pages = fragPtrP->noOfPages))
|
||||
{
|
||||
terrorCode = ZMEM_NOMEM_ERROR;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
PagePtr pagePtr;
|
||||
c_page_pool.getPtr(pagePtr, getRealpid(fragPtrP, page_no));
|
||||
|
||||
LocalDLList<Page> alloc_pages(c_page_pool, fragPtrP->emptyPrimPage);
|
||||
LocalDLList<Page> free_pages(c_page_pool, fragPtrP->thFreeFirst);
|
||||
if (pagePtr.p->page_state == ZEMPTY_MM)
|
||||
{
|
||||
convertThPage((Fix_page*)pagePtr.p, tabPtrP, MM);
|
||||
pagePtr.p->page_state = ZTH_MM_FREE;
|
||||
alloc_pages.remove(pagePtr);
|
||||
free_pages.add(pagePtr);
|
||||
}
|
||||
|
||||
*ret = pagePtr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint32*
|
||||
Dbtup::alloc_fix_rowid(Fragrecord* const regFragPtr,
|
||||
Tablerec* const regTabPtr,
|
||||
Local_key* key,
|
||||
Uint32 * out_frag_page_id)
|
||||
{
|
||||
Uint32 page_no = key->m_page_no;
|
||||
Uint32 idx= key->m_page_idx;
|
||||
|
||||
PagePtr pagePtr;
|
||||
if (alloc_page(regTabPtr, regFragPtr, &pagePtr, page_no))
|
||||
{
|
||||
terrorCode = ZMEM_NOMEM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint32 state = pagePtr.p->page_state;
|
||||
LocalDLList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
|
||||
switch(state){
|
||||
case ZTH_MM_FREE:
|
||||
if (((Fix_page*)pagePtr.p)->alloc_record(idx) != idx)
|
||||
{
|
||||
terrorCode = ZROWID_ALLOCATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pagePtr.p->free_space == 0)
|
||||
{
|
||||
jam();
|
||||
pagePtr.p->page_state = ZTH_MM_FULL;
|
||||
free_pages.remove(pagePtr);
|
||||
}
|
||||
|
||||
*out_frag_page_id= page_no;
|
||||
key->m_page_no = pagePtr.i;
|
||||
key->m_page_idx = idx;
|
||||
return pagePtr.p->m_data + idx;
|
||||
case ZTH_MM_FULL:
|
||||
terrorCode = ZROWID_ALLOCATED;
|
||||
return 0;
|
||||
case ZEMPTY_MM:
|
||||
ndbrequire(false);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ void Dbtup::initData()
|
||||
{
|
||||
cnoOfAttrbufrec = ZNO_OF_ATTRBUFREC;
|
||||
cnoOfFragrec = MAX_FRAG_PER_NODE;
|
||||
cnoOfPage = ZNO_OF_PAGE;
|
||||
cnoOfFragoprec = MAX_FRAG_PER_NODE;
|
||||
cnoOfPageRangeRec = ZNO_OF_PAGE_RANGE_REC;
|
||||
c_maxTriggersPerTable = ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE;
|
||||
@ -55,11 +54,11 @@ void Dbtup::initData()
|
||||
Dbtup::Dbtup(const class Configuration & conf, Pgman* pgman)
|
||||
: SimulatedBlock(DBTUP, conf),
|
||||
c_lqh(0),
|
||||
m_pgman(this, pgman),
|
||||
c_extent_hash(c_extent_pool),
|
||||
c_storedProcPool(),
|
||||
c_buildIndexList(c_buildIndexPool),
|
||||
c_undo_buffer(this),
|
||||
m_pgman(this, pgman),
|
||||
c_extent_hash(c_extent_pool)
|
||||
c_undo_buffer(this)
|
||||
{
|
||||
BLOCK_CONSTRUCTOR(Dbtup);
|
||||
|
||||
@ -101,12 +100,14 @@ Dbtup::Dbtup(const class Configuration & conf, Pgman* pgman)
|
||||
addRecSignal(GSN_ACC_SCANREQ, &Dbtup::execACC_SCANREQ);
|
||||
addRecSignal(GSN_NEXT_SCANREQ, &Dbtup::execNEXT_SCANREQ);
|
||||
addRecSignal(GSN_ACC_CHECK_SCAN, &Dbtup::execACC_CHECK_SCAN);
|
||||
addRecSignal(GSN_ACCKEYCONF, &Dbtup::execACCKEYCONF);
|
||||
addRecSignal(GSN_ACCKEYREF, &Dbtup::execACCKEYREF);
|
||||
addRecSignal(GSN_ACC_ABORTCONF, &Dbtup::execACC_ABORTCONF);
|
||||
|
||||
attrbufrec = 0;
|
||||
fragoperrec = 0;
|
||||
fragrecord = 0;
|
||||
hostBuffer = 0;
|
||||
cpage = 0;
|
||||
pageRange = 0;
|
||||
tablerec = 0;
|
||||
tableDescriptor = 0;
|
||||
@ -135,10 +136,6 @@ Dbtup::~Dbtup()
|
||||
sizeof(HostBuffer),
|
||||
MAX_NODES);
|
||||
|
||||
deallocRecord((void **)&cpage,"Page",
|
||||
sizeof(Page),
|
||||
cnoOfPage);
|
||||
|
||||
deallocRecord((void **)&pageRange,"PageRange",
|
||||
sizeof(PageRange),
|
||||
cnoOfPageRangeRec);
|
||||
@ -173,7 +170,7 @@ void Dbtup::execCONTINUEB(Signal* signal)
|
||||
case ZREPORT_MEMORY_USAGE:{
|
||||
ljam();
|
||||
static int c_currentMemUsed = 0;
|
||||
int now = (cnoOfAllocatedPages * 100)/cnoOfPage;
|
||||
int now = (cnoOfAllocatedPages * 100)/c_page_pool.getSize();
|
||||
const int thresholds[] = { 100, 90, 80, 0 };
|
||||
|
||||
Uint32 i = 0;
|
||||
@ -197,6 +194,14 @@ void Dbtup::execCONTINUEB(Signal* signal)
|
||||
ljam();
|
||||
buildIndex(signal, dataPtr);
|
||||
break;
|
||||
case ZTUP_SCAN:
|
||||
ljam();
|
||||
{
|
||||
ScanOpPtr scanPtr;
|
||||
c_scanOpPool.getPtr(scanPtr, dataPtr);
|
||||
scanCont(signal, scanPtr);
|
||||
}
|
||||
return;
|
||||
case ZFREE_EXTENT:
|
||||
{
|
||||
ljam();
|
||||
@ -279,7 +284,6 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
|
||||
ndbrequire(p != 0);
|
||||
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec));
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &cnoOfPage));
|
||||
|
||||
Uint32 noOfTriggers= 0;
|
||||
|
||||
@ -310,6 +314,9 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
|
||||
Uint32 nScanOp; // use TUX config for now
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
|
||||
c_scanOpPool.setSize(nScanOp + 1);
|
||||
Uint32 nScanBatch;
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch));
|
||||
c_scanLockPool.setSize(nScanOp * nScanBatch);
|
||||
|
||||
ScanOpPtr lcp;
|
||||
ndbrequire(c_scanOpPool.seize(lcp));
|
||||
@ -326,12 +333,16 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
|
||||
void Dbtup::initRecords()
|
||||
{
|
||||
unsigned i;
|
||||
Uint32 tmp;
|
||||
const ndb_mgm_configuration_iterator * p =
|
||||
theConfiguration.getOwnConfigIterator();
|
||||
ndbrequire(p != 0);
|
||||
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp));
|
||||
|
||||
// Records with dynamic sizes
|
||||
cpage = (Page*)allocRecord("Page",
|
||||
sizeof(Page),
|
||||
cnoOfPage,
|
||||
false);
|
||||
Page* ptr =(Page*)allocRecord("Page", sizeof(Page), tmp, false);
|
||||
c_page_pool.set(ptr, tmp);
|
||||
|
||||
attrbufrec = (Attrbufrec*)allocRecord("Attrbufrec",
|
||||
sizeof(Attrbufrec),
|
||||
@ -353,10 +364,6 @@ void Dbtup::initRecords()
|
||||
sizeof(TableDescriptor),
|
||||
cnoOfTabDescrRec);
|
||||
|
||||
Uint32 tmp;
|
||||
const ndb_mgm_configuration_iterator * p =
|
||||
theConfiguration.getOwnConfigIterator();
|
||||
ndbrequire(p != 0);
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &tmp));
|
||||
c_operation_pool.setSize(tmp);
|
||||
|
||||
@ -531,6 +538,7 @@ void Dbtup::initializeFragrecord()
|
||||
for (regFragPtr.i = 0; regFragPtr.i < cnoOfFragrec; regFragPtr.i++) {
|
||||
refresh_watch_dog();
|
||||
ptrAss(regFragPtr, fragrecord);
|
||||
new (regFragPtr.p) Fragrecord();
|
||||
regFragPtr.p->nextfreefrag = regFragPtr.i + 1;
|
||||
regFragPtr.p->fragStatus = IDLE;
|
||||
}//for
|
||||
@ -582,7 +590,7 @@ Dbtup::initTab(Tablerec* const regTabPtr)
|
||||
regTabPtr->tabDescriptor = RNIL;
|
||||
regTabPtr->readKeyArray = RNIL;
|
||||
|
||||
regTabPtr->checksumIndicator = false;
|
||||
regTabPtr->m_bits = 0;
|
||||
|
||||
regTabPtr->m_no_of_attributes = 0;
|
||||
regTabPtr->noOfKeyAttr = 0;
|
||||
|
@ -37,8 +37,7 @@ Dbtup::tuxGetTupAddr(Uint32 fragPtrI,
|
||||
{
|
||||
ljamEntry();
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i= pageId;
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr, pageId);
|
||||
Uint32 fragPageId= pagePtr.p->frag_page_id;
|
||||
tupAddr= (fragPageId << MAX_TUPLES_BITS) | pageIndex;
|
||||
}
|
||||
@ -115,8 +114,7 @@ Dbtup::tuxGetNode(Uint32 fragPtrI,
|
||||
tablePtr.i= fragPtr.p->fragTableId;
|
||||
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i= pageId;
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr, pageId);
|
||||
Uint32 attrDescIndex= tablePtr.p->tabDescriptor + (0 << ZAD_LOG_SIZE);
|
||||
Uint32 attrDataOffset= AttributeOffset::getOffset(
|
||||
tableDescriptor[attrDescIndex + 1].tabDescr);
|
||||
@ -219,62 +217,88 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32* dataO
|
||||
tmpOp.m_tuple_location.m_page_idx= pageIndex;
|
||||
|
||||
KeyReqStruct req_struct;
|
||||
setup_fixed_part(&req_struct, &tmpOp, tablePtr.p);
|
||||
if(req_struct.m_tuple_ptr->m_header_bits & Tuple_header::ALLOC)
|
||||
|
||||
PagePtr page_ptr;
|
||||
Uint32* ptr= get_ptr(&page_ptr, &tmpOp.m_tuple_location, tablePtr.p);
|
||||
req_struct.m_page_ptr = page_ptr;
|
||||
req_struct.m_tuple_ptr = (Tuple_header*)ptr;
|
||||
|
||||
int ret = 0;
|
||||
if (! (req_struct.m_tuple_ptr->m_header_bits & Tuple_header::FREE))
|
||||
{
|
||||
Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
|
||||
Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
|
||||
ndbassert(!opPtrP->m_copy_tuple_location.isNull());
|
||||
req_struct.m_tuple_ptr= (Tuple_header*)
|
||||
c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
|
||||
}
|
||||
prepare_read(&req_struct, tablePtr.p, false);
|
||||
req_struct.check_offset[MM]= tablePtr.p->get_check_offset(MM);
|
||||
req_struct.check_offset[DD]= tablePtr.p->get_check_offset(DD);
|
||||
|
||||
Uint32 num_attr= tablePtr.p->m_no_of_attributes;
|
||||
Uint32 descr_start= tablePtr.p->tabDescriptor;
|
||||
TableDescriptor *tab_descr= &tableDescriptor[descr_start];
|
||||
ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
|
||||
req_struct.attr_descr= tab_descr;
|
||||
|
||||
const Uint32* attrIds= &tableDescriptor[tablePtr.p->readKeyArray].tabDescr;
|
||||
const Uint32 numAttrs= tablePtr.p->noOfKeyAttr;
|
||||
// read pk attributes from original tuple
|
||||
|
||||
// save globals
|
||||
TablerecPtr tabptr_old= tabptr;
|
||||
FragrecordPtr fragptr_old= fragptr;
|
||||
OperationrecPtr operPtr_old= operPtr;
|
||||
|
||||
// new globals
|
||||
tabptr= tablePtr;
|
||||
fragptr= fragPtr;
|
||||
operPtr.i= RNIL;
|
||||
operPtr.p= NULL;
|
||||
|
||||
// do it
|
||||
int ret = readAttributes(&req_struct,
|
||||
attrIds,
|
||||
numAttrs,
|
||||
dataOut,
|
||||
ZNIL,
|
||||
xfrmFlag);
|
||||
// restore globals
|
||||
tabptr= tabptr_old;
|
||||
fragptr= fragptr_old;
|
||||
operPtr= operPtr_old;
|
||||
// done
|
||||
if (ret != -1) {
|
||||
// remove headers
|
||||
Uint32 n= 0;
|
||||
Uint32 i= 0;
|
||||
while (n < numAttrs) {
|
||||
const AttributeHeader ah(dataOut[i]);
|
||||
Uint32 size= ah.getDataSize();
|
||||
ndbrequire(size != 0);
|
||||
for (Uint32 j= 0; j < size; j++) {
|
||||
dataOut[i + j - n]= dataOut[i + j + 1];
|
||||
}
|
||||
n+= 1;
|
||||
i+= 1 + size;
|
||||
if(req_struct.m_tuple_ptr->m_header_bits & Tuple_header::ALLOC)
|
||||
{
|
||||
Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
|
||||
Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
|
||||
ndbassert(!opPtrP->m_copy_tuple_location.isNull());
|
||||
req_struct.m_tuple_ptr= (Tuple_header*)
|
||||
c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
|
||||
}
|
||||
ndbrequire((int)i == ret);
|
||||
ret -= numAttrs;
|
||||
} else {
|
||||
ret= terrorCode ? (-(int)terrorCode) : -1;
|
||||
prepare_read(&req_struct, tablePtr.p, false);
|
||||
|
||||
const Uint32* attrIds= &tableDescriptor[tablePtr.p->readKeyArray].tabDescr;
|
||||
const Uint32 numAttrs= tablePtr.p->noOfKeyAttr;
|
||||
// read pk attributes from original tuple
|
||||
|
||||
// save globals
|
||||
TablerecPtr tabptr_old= tabptr;
|
||||
FragrecordPtr fragptr_old= fragptr;
|
||||
OperationrecPtr operPtr_old= operPtr;
|
||||
|
||||
// new globals
|
||||
tabptr= tablePtr;
|
||||
fragptr= fragPtr;
|
||||
operPtr.i= RNIL;
|
||||
operPtr.p= NULL;
|
||||
|
||||
// do it
|
||||
ret = readAttributes(&req_struct,
|
||||
attrIds,
|
||||
numAttrs,
|
||||
dataOut,
|
||||
ZNIL,
|
||||
xfrmFlag);
|
||||
// restore globals
|
||||
tabptr= tabptr_old;
|
||||
fragptr= fragptr_old;
|
||||
operPtr= operPtr_old;
|
||||
// done
|
||||
if (ret != -1) {
|
||||
// remove headers
|
||||
Uint32 n= 0;
|
||||
Uint32 i= 0;
|
||||
while (n < numAttrs) {
|
||||
const AttributeHeader ah(dataOut[i]);
|
||||
Uint32 size= ah.getDataSize();
|
||||
ndbrequire(size != 0);
|
||||
for (Uint32 j= 0; j < size; j++) {
|
||||
dataOut[i + j - n]= dataOut[i + j + 1];
|
||||
}
|
||||
n+= 1;
|
||||
i+= 1 + size;
|
||||
}
|
||||
ndbrequire((int)i == ret);
|
||||
ret -= numAttrs;
|
||||
} else {
|
||||
ret= terrorCode ? (-(int)terrorCode) : -1;
|
||||
}
|
||||
}
|
||||
if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
dataOut[ret] = *req_struct.m_tuple_ptr->get_mm_gci(tablePtr.p);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataOut[ret] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -454,7 +478,9 @@ Dbtup::buildIndex(Signal* signal, Uint32 buildPtrI)
|
||||
tablePtr.i= buildReq->getTableId();
|
||||
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
|
||||
|
||||
const Uint32 firstTupleNo = ! buildPtr.p->m_build_vs ? 0 : 1;
|
||||
const Uint32 firstTupleNo = 0;
|
||||
const Uint32 tupheadsize = tablePtr.p->m_offsets[MM].m_fix_header_size +
|
||||
(buildPtr.p->m_build_vs ? Tuple_header::HeaderSize + 1: 0);
|
||||
|
||||
#ifdef TIME_MEASUREMENT
|
||||
MicroSecondTimer start;
|
||||
@ -491,8 +517,7 @@ Dbtup::buildIndex(Signal* signal, Uint32 buildPtrI)
|
||||
break;
|
||||
}
|
||||
Uint32 realPageId= getRealpid(fragPtr.p, buildPtr.p->m_pageId);
|
||||
pagePtr.i= realPageId;
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pagePtr, realPageId);
|
||||
Uint32 pageState= pagePtr.p->page_state;
|
||||
// skip empty page
|
||||
if (pageState == ZEMPTY_MM) {
|
||||
@ -504,43 +529,19 @@ Dbtup::buildIndex(Signal* signal, Uint32 buildPtrI)
|
||||
// get tuple
|
||||
Uint32 pageIndex = ~0;
|
||||
const Tuple_header* tuple_ptr = 0;
|
||||
if (! buildPtr.p->m_build_vs) {
|
||||
Uint32 tupheadsize= tablePtr.p->m_offsets[MM].m_fix_header_size;
|
||||
pageIndex = buildPtr.p->m_tupleNo * tupheadsize;
|
||||
if (pageIndex + tupheadsize > Fix_page::DATA_WORDS) {
|
||||
ljam();
|
||||
buildPtr.p->m_pageId++;
|
||||
buildPtr.p->m_tupleNo= firstTupleNo;
|
||||
break;
|
||||
}
|
||||
tuple_ptr = (Tuple_header*)&pagePtr.p->m_data[pageIndex];
|
||||
// skip over free tuple
|
||||
if (tuple_ptr->m_header_bits & Tuple_header::FREE) {
|
||||
ljam();
|
||||
buildPtr.p->m_tupleNo++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pageIndex = buildPtr.p->m_tupleNo;
|
||||
Var_page* page_ptr = (Var_page*)pagePtr.p;
|
||||
if (pageIndex >= page_ptr->high_index) {
|
||||
ljam();
|
||||
buildPtr.p->m_pageId++;
|
||||
buildPtr.p->m_tupleNo= firstTupleNo;
|
||||
break;
|
||||
}
|
||||
Uint32 len= page_ptr->get_entry_len(pageIndex);
|
||||
if (len == 0) {
|
||||
ljam();
|
||||
buildPtr.p->m_tupleNo++;
|
||||
break;
|
||||
}
|
||||
if (len & Var_page::CHAIN) {
|
||||
ljam();
|
||||
buildPtr.p->m_tupleNo++;
|
||||
break;
|
||||
}
|
||||
tuple_ptr = (Tuple_header*)page_ptr->get_ptr(pageIndex);
|
||||
pageIndex = buildPtr.p->m_tupleNo * tupheadsize;
|
||||
if (pageIndex + tupheadsize > Fix_page::DATA_WORDS) {
|
||||
ljam();
|
||||
buildPtr.p->m_pageId++;
|
||||
buildPtr.p->m_tupleNo= firstTupleNo;
|
||||
break;
|
||||
}
|
||||
tuple_ptr = (Tuple_header*)&pagePtr.p->m_data[pageIndex];
|
||||
// skip over free tuple
|
||||
if (tuple_ptr->m_header_bits & Tuple_header::FREE) {
|
||||
ljam();
|
||||
buildPtr.p->m_tupleNo++;
|
||||
break;
|
||||
}
|
||||
Uint32 tupVersion= tuple_ptr->get_tuple_version();
|
||||
OperationrecPtr pageOperPtr;
|
||||
|
@ -61,6 +61,7 @@ void Dbtup::execTUPFRAGREQ(Signal* signal)
|
||||
//Uint32 noOfNewAttr= (signal->theData[10] & 0xFFFF);
|
||||
/* DICT sends number of character sets in upper half */
|
||||
Uint32 noOfCharsets= (signal->theData[10] >> 16);
|
||||
Uint32 gcpIndicator = signal->theData[13];
|
||||
Uint32 tablespace= signal->theData[14];
|
||||
|
||||
Uint32 checksumIndicator= signal->theData[11];
|
||||
@ -133,12 +134,6 @@ void Dbtup::execTUPFRAGREQ(Signal* signal)
|
||||
return;
|
||||
}
|
||||
|
||||
regFragPtr.p->emptyPrimPage= RNIL;
|
||||
regFragPtr.p->thFreeFirst= RNIL;
|
||||
regFragPtr.p->free_var_page_array[0]= RNIL;
|
||||
regFragPtr.p->free_var_page_array[1]= RNIL;
|
||||
regFragPtr.p->free_var_page_array[2]= RNIL;
|
||||
regFragPtr.p->free_var_page_array[3]= RNIL;
|
||||
regFragPtr.p->fragTableId= regTabPtr.i;
|
||||
regFragPtr.p->fragmentId= fragId;
|
||||
regFragPtr.p->m_tablespace_id= tablespace;
|
||||
@ -181,7 +176,9 @@ void Dbtup::execTUPFRAGREQ(Signal* signal)
|
||||
//-----------------------------------------------------------------------------
|
||||
fragOperPtr.p->definingFragment= true;
|
||||
regTabPtr.p->tableStatus= DEFINING;
|
||||
regTabPtr.p->checksumIndicator= (checksumIndicator != 0 ? true : false);
|
||||
regTabPtr.p->m_bits = 0;
|
||||
regTabPtr.p->m_bits |= (checksumIndicator ? Tablerec::TR_Checksum : 0);
|
||||
regTabPtr.p->m_bits |= (gcpIndicator ? Tablerec::TR_RowGCI : 0);
|
||||
|
||||
regTabPtr.p->m_offsets[MM].m_disk_ref_offset= 0;
|
||||
regTabPtr.p->m_offsets[MM].m_null_words= 0;
|
||||
@ -443,11 +440,17 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
|
||||
* Fix offsets
|
||||
*/
|
||||
Uint32 pos[2] = { 0, 0 };
|
||||
if(regTabPtr.p->checksumIndicator)
|
||||
if (regTabPtr.p->m_bits & Tablerec::TR_Checksum)
|
||||
{
|
||||
pos[0]= 1;
|
||||
}
|
||||
|
||||
if (regTabPtr.p->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
pos[MM]++;
|
||||
pos[DD]++;
|
||||
}
|
||||
|
||||
regTabPtr.p->m_no_of_disk_attributes=
|
||||
regTabPtr.p->m_attributes[DD].m_no_of_fixsize +
|
||||
regTabPtr.p->m_attributes[DD].m_no_of_varsize;
|
||||
|
@ -121,10 +121,10 @@ void Dbtup::initializePage()
|
||||
cfreepageList[i] = RNIL;
|
||||
}//for
|
||||
PagePtr pagePtr;
|
||||
for (pagePtr.i = 0; pagePtr.i < cnoOfPage; pagePtr.i++) {
|
||||
for (pagePtr.i = 0; pagePtr.i < c_page_pool.getSize(); pagePtr.i++) {
|
||||
ljam();
|
||||
refresh_watch_dog();
|
||||
ptrAss(pagePtr, cpage);
|
||||
c_page_pool.getPtr(pagePtr);
|
||||
pagePtr.p->physical_page_id= RNIL;
|
||||
pagePtr.p->next_page = pagePtr.i + 1;
|
||||
pagePtr.p->first_cluster_page = RNIL;
|
||||
@ -133,24 +133,20 @@ void Dbtup::initializePage()
|
||||
pagePtr.p->prev_page = RNIL;
|
||||
pagePtr.p->page_state = ZFREE_COMMON;
|
||||
}//for
|
||||
pagePtr.i = cnoOfPage - 1;
|
||||
ptrAss(pagePtr, cpage);
|
||||
pagePtr.p->next_page = RNIL;
|
||||
|
||||
/**
|
||||
* Page 0 cant be part of buddy as
|
||||
* it will scan left right when searching for bigger blocks,
|
||||
* if 0 is part of arrat, it can search to -1...which is not good
|
||||
*/
|
||||
pagePtr.i = 0;
|
||||
ptrAss(pagePtr, cpage);
|
||||
c_page_pool.getPtr(pagePtr);
|
||||
pagePtr.p->page_state = ~ZFREE_COMMON;
|
||||
|
||||
for(size_t j = 0; j<MAX_PARALLELL_TUP_SRREQ; j++){
|
||||
pagePtr.i = 1+j;
|
||||
ptrAss(pagePtr, cpage);
|
||||
pagePtr.p->page_state = ~ZFREE_COMMON;
|
||||
}
|
||||
|
||||
Uint32 tmp = 1 + MAX_PARALLELL_TUP_SRREQ;
|
||||
returnCommonArea(tmp, cnoOfPage - tmp);
|
||||
Uint32 tmp = 1;
|
||||
returnCommonArea(tmp, c_page_pool.getSize() - tmp);
|
||||
cnoOfAllocatedPages = tmp; // Is updated by returnCommonArea
|
||||
c_sr_free_page_0 = ~0;
|
||||
}//Dbtup::initializePage()
|
||||
|
||||
void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate,
|
||||
@ -234,7 +230,7 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef,
|
||||
while (allocPageRef > 0) {
|
||||
ljam();
|
||||
pageLastPtr.i = allocPageRef - 1;
|
||||
ptrCheckGuard(pageLastPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageLastPtr);
|
||||
if (pageLastPtr.p->page_state != ZFREE_COMMON) {
|
||||
ljam();
|
||||
return;
|
||||
@ -272,10 +268,10 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef,
|
||||
ljam();
|
||||
return;
|
||||
}//if
|
||||
while ((allocPageRef + noPagesAllocated) < cnoOfPage) {
|
||||
while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize()) {
|
||||
ljam();
|
||||
pageFirstPtr.i = allocPageRef + noPagesAllocated;
|
||||
ptrCheckGuard(pageFirstPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageFirstPtr);
|
||||
if (pageFirstPtr.p->page_state != ZFREE_COMMON) {
|
||||
ljam();
|
||||
return;
|
||||
@ -307,8 +303,7 @@ void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList)
|
||||
cnoOfAllocatedPages -= (1 << insList);
|
||||
PagePtr pageLastPtr, pageInsPtr;
|
||||
|
||||
pageInsPtr.i = insPageRef;
|
||||
ptrCheckGuard(pageInsPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageInsPtr, insPageRef);
|
||||
ndbrequire(insList < 16);
|
||||
pageLastPtr.i = (pageInsPtr.i + (1 << insList)) - 1;
|
||||
|
||||
@ -316,8 +311,8 @@ void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList)
|
||||
pageInsPtr.p->prev_cluster_page = RNIL;
|
||||
pageInsPtr.p->last_cluster_page = pageLastPtr.i;
|
||||
cfreepageList[insList] = pageInsPtr.i;
|
||||
|
||||
ptrCheckGuard(pageLastPtr, cnoOfPage, cpage);
|
||||
|
||||
c_page_pool.getPtr(pageLastPtr);
|
||||
pageLastPtr.p->first_cluster_page = pageInsPtr.i;
|
||||
pageLastPtr.p->next_page = RNIL;
|
||||
}//Dbtup::insertCommonArea()
|
||||
@ -327,8 +322,7 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
|
||||
cnoOfAllocatedPages += (1 << list);
|
||||
PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, pageSearchPtr, remPagePtr;
|
||||
|
||||
remPagePtr.i = remPageRef;
|
||||
ptrCheckGuard(remPagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(remPagePtr, remPageRef);
|
||||
ndbrequire(list < 16);
|
||||
if (cfreepageList[list] == remPagePtr.i) {
|
||||
ljam();
|
||||
@ -336,14 +330,14 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
|
||||
pageNextPtr.i = cfreepageList[list];
|
||||
if (pageNextPtr.i != RNIL) {
|
||||
ljam();
|
||||
ptrCheckGuard(pageNextPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageNextPtr);
|
||||
pageNextPtr.p->prev_cluster_page = RNIL;
|
||||
}//if
|
||||
} else {
|
||||
pageSearchPtr.i = cfreepageList[list];
|
||||
while (true) {
|
||||
ljam();
|
||||
ptrCheckGuard(pageSearchPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageSearchPtr);
|
||||
pagePrevPtr = pageSearchPtr;
|
||||
pageSearchPtr.i = pageSearchPtr.p->next_cluster_page;
|
||||
if (pageSearchPtr.i == remPagePtr.i) {
|
||||
@ -355,7 +349,7 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
|
||||
pagePrevPtr.p->next_cluster_page = pageNextPtr.i;
|
||||
if (pageNextPtr.i != RNIL) {
|
||||
ljam();
|
||||
ptrCheckGuard(pageNextPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageNextPtr);
|
||||
pageNextPtr.p->prev_cluster_page = pagePrevPtr.i;
|
||||
}//if
|
||||
}//if
|
||||
@ -364,6 +358,6 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
|
||||
remPagePtr.p->prev_cluster_page= RNIL;
|
||||
|
||||
pageLastPtr.i = (remPagePtr.i + (1 << list)) - 1;
|
||||
ptrCheckGuard(pageLastPtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(pageLastPtr);
|
||||
pageLastPtr.p->first_cluster_page= RNIL;
|
||||
}//Dbtup::removeCommonArea()
|
||||
|
@ -91,20 +91,20 @@
|
||||
|
||||
Uint32 Dbtup::getEmptyPage(Fragrecord* const regFragPtr)
|
||||
{
|
||||
Uint32 pageId = regFragPtr->emptyPrimPage;
|
||||
Uint32 pageId = regFragPtr->emptyPrimPage.firstItem;
|
||||
if (pageId == RNIL) {
|
||||
ljam();
|
||||
allocMoreFragPages(regFragPtr);
|
||||
pageId = regFragPtr->emptyPrimPage;
|
||||
pageId = regFragPtr->emptyPrimPage.firstItem;
|
||||
if (pageId == RNIL) {
|
||||
ljam();
|
||||
return RNIL;
|
||||
}//if
|
||||
}//if
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = pageId;
|
||||
ptrCheckGuard(pagePtr, cnoOfPage, cpage);
|
||||
regFragPtr->emptyPrimPage = pagePtr.p->next_page;
|
||||
LocalDLList<Page> alloc_pages(c_page_pool, regFragPtr->emptyPrimPage);
|
||||
alloc_pages.getPtr(pagePtr, pageId);
|
||||
alloc_pages.remove(pagePtr);
|
||||
return pageId;
|
||||
}//Dbtup::getEmptyPage()
|
||||
|
||||
@ -284,6 +284,22 @@ void Dbtup::releaseFragPages(Fragrecord* const regFragPtr)
|
||||
ljam();
|
||||
ndbrequire(regPRPtr.i == regFragPtr->rootPageRange);
|
||||
initFragRange(regFragPtr);
|
||||
for (Uint32 i = 0; i<MAX_FREE_LIST; i++)
|
||||
{
|
||||
LocalDLList<Page> tmp(c_page_pool, regFragPtr->free_var_page_array[i]);
|
||||
tmp.remove();
|
||||
}
|
||||
|
||||
{
|
||||
LocalDLList<Page> tmp(c_page_pool, regFragPtr->emptyPrimPage);
|
||||
tmp.remove();
|
||||
}
|
||||
|
||||
{
|
||||
LocalDLList<Page> tmp(c_page_pool, regFragPtr->thFreeFirst);
|
||||
tmp.remove();
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
if (regPRPtr.p->type[indexPos] == ZNON_LEAF) {
|
||||
@ -327,7 +343,6 @@ void Dbtup::initializePageRange()
|
||||
|
||||
void Dbtup::initFragRange(Fragrecord* const regFragPtr)
|
||||
{
|
||||
regFragPtr->emptyPrimPage = RNIL;
|
||||
regFragPtr->rootPageRange = RNIL;
|
||||
regFragPtr->currentPageRange = RNIL;
|
||||
regFragPtr->noOfPages = 0;
|
||||
@ -365,19 +380,32 @@ Uint32 Dbtup::allocFragPages(Fragrecord* const regFragPtr, Uint32 tafpNoAllocReq
|
||||
/* THOSE PAGES TO EMPTY_MM AND LINK THEM INTO THE EMPTY */
|
||||
/* PAGE LIST OF THE FRAGMENT. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
Uint32 prev = RNIL;
|
||||
for (loopPagePtr.i = retPageRef; loopPagePtr.i < loopLimit; loopPagePtr.i++) {
|
||||
ljam();
|
||||
ptrCheckGuard(loopPagePtr, cnoOfPage, cpage);
|
||||
c_page_pool.getPtr(loopPagePtr);
|
||||
loopPagePtr.p->page_state = ZEMPTY_MM;
|
||||
loopPagePtr.p->frag_page_id = startRange +
|
||||
(loopPagePtr.i - retPageRef);
|
||||
loopPagePtr.p->physical_page_id = loopPagePtr.i;
|
||||
loopPagePtr.p->next_page = loopPagePtr.i + 1;
|
||||
loopPagePtr.p->nextList = loopPagePtr.i + 1;
|
||||
loopPagePtr.p->prevList = prev;
|
||||
prev = loopPagePtr.i;
|
||||
}//for
|
||||
loopPagePtr.i = (retPageRef + noOfPagesAllocated) - 1;
|
||||
ptrCheckGuard(loopPagePtr, cnoOfPage, cpage);
|
||||
loopPagePtr.p->next_page = regFragPtr->emptyPrimPage;
|
||||
regFragPtr->emptyPrimPage = retPageRef;
|
||||
loopPagePtr.i--;
|
||||
ndbassert(loopPagePtr.p == c_page_pool.getPtr(loopPagePtr.i));
|
||||
loopPagePtr.p->nextList = RNIL;
|
||||
|
||||
LocalDLList<Page> alloc(c_page_pool, regFragPtr->emptyPrimPage);
|
||||
if (noOfPagesAllocated > 1)
|
||||
{
|
||||
alloc.add(retPageRef, loopPagePtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
alloc.add(loopPagePtr);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* WAS ENOUGH PAGES ALLOCATED OR ARE MORE NEEDED. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
@ -1178,6 +1178,18 @@ Dbtup::read_pseudo(Uint32 attrId,
|
||||
outBuffer[2] = signal->theData[2];
|
||||
outBuffer[3] = signal->theData[3];
|
||||
return 4;
|
||||
case AttributeHeader::ROWID:
|
||||
outBuffer[0] = req_struct->frag_page_id;
|
||||
outBuffer[1] = operPtr.p->m_tuple_location.m_page_idx;
|
||||
return 2;
|
||||
case AttributeHeader::ROW_GCI:
|
||||
if (tabptr.p->m_bits & Tablerec::TR_RowGCI)
|
||||
{
|
||||
Uint64 tmp = * req_struct->m_tuple_ptr->get_mm_gci(tabptr.p);
|
||||
memcpy(outBuffer, &tmp, sizeof(tmp));
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -580,7 +580,12 @@ Dbtup::fireDetachedTriggers(KeyReqStruct *req_struct,
|
||||
{
|
||||
regOperPtr->op_struct.op_type = ZUPDATE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set disk page
|
||||
*/
|
||||
req_struct->m_disk_page_ptr.i = m_pgman.m_ptr.i;
|
||||
|
||||
ndbrequire(regOperPtr->is_first_operation());
|
||||
triggerList.first(trigPtr);
|
||||
while (trigPtr.i != RNIL) {
|
||||
@ -817,8 +822,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
|
||||
//--------------------------------------------------------------------
|
||||
// Read Primary Key Values
|
||||
//--------------------------------------------------------------------
|
||||
if (regTabPtr->need_expand(false)) // no disk
|
||||
prepare_read(req_struct, regTabPtr, false); // setup varsize
|
||||
if (regTabPtr->need_expand())
|
||||
prepare_read(req_struct, regTabPtr, true);
|
||||
|
||||
int ret = readAttributes(req_struct,
|
||||
&tableDescriptor[regTabPtr->readKeyArray].tabDescr,
|
||||
@ -902,8 +907,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
|
||||
req_struct->m_tuple_ptr= (Tuple_header*)ptr;
|
||||
}
|
||||
|
||||
if (regTabPtr->need_expand(false)) // no disk
|
||||
prepare_read(req_struct, regTabPtr, false); // setup varsize
|
||||
if (regTabPtr->need_expand()) // no disk
|
||||
prepare_read(req_struct, regTabPtr, true);
|
||||
|
||||
int ret = readAttributes(req_struct,
|
||||
&readBuffer[0],
|
||||
@ -1168,7 +1173,7 @@ Dbtup::executeTuxCommitTriggers(Signal* signal,
|
||||
req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
|
||||
req->tupVersion = tupVersion;
|
||||
req->opInfo = TuxMaintReq::OpRemove;
|
||||
removeTuxEntries(signal, regOperPtr, regTabPtr);
|
||||
removeTuxEntries(signal, regTabPtr);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1200,12 +1205,11 @@ Dbtup::executeTuxAbortTriggers(Signal* signal,
|
||||
req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
|
||||
req->tupVersion = tupVersion;
|
||||
req->opInfo = TuxMaintReq::OpRemove;
|
||||
removeTuxEntries(signal, regOperPtr, regTabPtr);
|
||||
removeTuxEntries(signal, regTabPtr);
|
||||
}
|
||||
|
||||
void
|
||||
Dbtup::removeTuxEntries(Signal* signal,
|
||||
Operationrec* regOperPtr,
|
||||
Tablerec* regTabPtr)
|
||||
{
|
||||
TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,39 +50,34 @@ Undo_buffer::alloc_copy_tuple(Local_key* dst, Uint32 words)
|
||||
m_tup->allocConsPages(1, count, m_first_free);
|
||||
if(count == 0)
|
||||
return 0;
|
||||
page= (UndoPage*)(m_tup->cpage+m_first_free);
|
||||
page= (UndoPage*)m_tup->c_page_pool.getPtr(m_first_free);
|
||||
page->m_state= ~ZFREE_COMMON;
|
||||
page->m_words_used= 0;
|
||||
page->m_ref_count= 0;
|
||||
}
|
||||
|
||||
if(m_first_free < m_tup->cnoOfPage)
|
||||
page= (UndoPage*)m_tup->c_page_pool.getPtr(m_first_free);
|
||||
|
||||
Uint32 pos= page->m_words_used;
|
||||
if(words + pos > UndoPage::DATA_WORDS)
|
||||
{
|
||||
page= (UndoPage*)(m_tup->cpage+m_first_free);
|
||||
|
||||
Uint32 pos= page->m_words_used;
|
||||
if(words + pos > UndoPage::DATA_WORDS)
|
||||
{
|
||||
m_first_free= RNIL;
|
||||
return alloc_copy_tuple(dst, words);
|
||||
}
|
||||
|
||||
dst->m_page_no = m_first_free;
|
||||
dst->m_page_idx = pos;
|
||||
|
||||
page->m_ref_count++;
|
||||
page->m_words_used = pos + words;
|
||||
return page->m_data + pos;
|
||||
m_first_free= RNIL;
|
||||
return alloc_copy_tuple(dst, words);
|
||||
}
|
||||
assert(false);
|
||||
return 0;
|
||||
|
||||
dst->m_page_no = m_first_free;
|
||||
dst->m_page_idx = pos;
|
||||
|
||||
page->m_ref_count++;
|
||||
page->m_words_used = pos + words;
|
||||
return page->m_data + pos;
|
||||
}
|
||||
|
||||
void
|
||||
Undo_buffer::shrink_copy_tuple(Local_key* key, Uint32 words)
|
||||
{
|
||||
assert(key->m_page_no == m_first_free);
|
||||
UndoPage* page= (UndoPage*)(m_tup->cpage+key->m_page_no);
|
||||
UndoPage* page= (UndoPage*)m_tup->c_page_pool.getPtr(key->m_page_no);
|
||||
assert(page->m_words_used >= words);
|
||||
page->m_words_used -= words;
|
||||
}
|
||||
@ -90,7 +85,7 @@ Undo_buffer::shrink_copy_tuple(Local_key* key, Uint32 words)
|
||||
void
|
||||
Undo_buffer::free_copy_tuple(Local_key* key)
|
||||
{
|
||||
UndoPage* page= (UndoPage*)(m_tup->cpage+key->m_page_no);
|
||||
UndoPage* page= (UndoPage*)m_tup->c_page_pool.getPtr(key->m_page_no);
|
||||
Uint32 cnt= page->m_ref_count;
|
||||
assert(cnt);
|
||||
|
||||
@ -115,6 +110,6 @@ Undo_buffer::free_copy_tuple(Local_key* key)
|
||||
Uint32 *
|
||||
Undo_buffer::get_ptr(Local_key* key)
|
||||
{
|
||||
return ((UndoPage*)(m_tup->cpage+key->m_page_no))->m_data+key->m_page_idx;
|
||||
return ((UndoPage*)(m_tup->c_page_pool.getPtr(key->m_page_no)))->m_data+key->m_page_idx;
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,21 @@ struct Record
|
||||
Uint32* data;
|
||||
};
|
||||
|
||||
NdbOut&
|
||||
operator <<(NdbOut& out, const Record& rec)
|
||||
{
|
||||
out << "[ idx: " << rec.idx << " sz: " << rec.size << " ]";
|
||||
return out;
|
||||
}
|
||||
|
||||
#define TRACE(x) x
|
||||
|
||||
static
|
||||
void
|
||||
bool
|
||||
cmp(const Uint32 *p1, const Uint32 *p2, Uint32 words)
|
||||
{
|
||||
if(memcmp(p1, p2, 4*words) == 0)
|
||||
return;
|
||||
return true;
|
||||
|
||||
for(Uint32 i = 0; i<words; i++)
|
||||
printf(" %.8x", p1[i]);
|
||||
@ -26,13 +33,20 @@ cmp(const Uint32 *p1, const Uint32 *p2, Uint32 words)
|
||||
printf(" %.8x", p2[i]);
|
||||
printf("\n");
|
||||
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
do_test(int loops, int dist[3])
|
||||
do_test(int loops, int dist[5])
|
||||
{
|
||||
fprintf(stderr, "do_test(%d, [ %d %d %d %d %d ])\n",
|
||||
loops,
|
||||
dist[0],
|
||||
dist[1],
|
||||
dist[2],
|
||||
dist[3],
|
||||
dist[4]);
|
||||
int allocated= 0;
|
||||
Record records[8192];
|
||||
|
||||
@ -41,24 +55,39 @@ do_test(int loops, int dist[3])
|
||||
|
||||
for(int i = 0; i<loops; i++)
|
||||
{
|
||||
assert(page.high_index + page.insert_pos <= page.DATA_WORDS);
|
||||
|
||||
for(int j = 0; j<allocated; j++)
|
||||
{
|
||||
Record rec= records[j];
|
||||
Uint32* ptr= page.get_ptr(rec.idx);
|
||||
cmp(ptr, rec.data, rec.size);
|
||||
Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
|
||||
if (page.get_entry_len(rec.idx) != rec.size)
|
||||
{
|
||||
ndbout << "INVALID LEN " << j << " " << rec << " pos: " << pos << endl;
|
||||
ndbout << page << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
if(!cmp(ptr, rec.data, rec.size))
|
||||
{
|
||||
ndbout << "FAILED " << j << " " << rec << " pos: " << pos << endl;
|
||||
ndbout << page << endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
loop:
|
||||
int op;
|
||||
int rnd= rand() % 100;
|
||||
for(op= 0; op<3; op++)
|
||||
for(op= 0; op<5; op++)
|
||||
if(rnd < dist[op])
|
||||
break;
|
||||
|
||||
if(allocated == 0)
|
||||
op= 0;
|
||||
if(page.free_space <= 2 && op == 0) goto loop;
|
||||
|
||||
|
||||
switch(op){
|
||||
case 0: // Alloc
|
||||
{
|
||||
@ -69,9 +98,73 @@ loop:
|
||||
{
|
||||
rec.data[i] = rand();
|
||||
}
|
||||
ndbout << "Alloc " << rec.size << flush;
|
||||
rec.idx= page.alloc_record(rec.size, &tmp, 0);
|
||||
ndbout << " -> " << rec.idx << endl;
|
||||
ndbout << "Alloc hi: " << page.high_index << " (" <<
|
||||
((rnd < 30) ? "any" :
|
||||
(rnd < 60) ? "dir" :
|
||||
(rnd < 80) ? "exp" : "fail") << ") ";
|
||||
ndbout << rec.size << flush;
|
||||
if (rnd < 30)
|
||||
{
|
||||
rec.idx= page.alloc_record(rec.size, &tmp, 0);
|
||||
}
|
||||
else if (rnd < 60)
|
||||
{
|
||||
// Alloc with id, from directory
|
||||
Vector<Uint32> free;
|
||||
for(Uint32 i = page.high_index - 1; i > 0; i--)
|
||||
{
|
||||
if (page.get_index_word(i) & page.FREE)
|
||||
{
|
||||
free.push_back(i);
|
||||
if (free.size() > 100)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (free.size())
|
||||
{
|
||||
rec.idx = free[rand() % free.size()];
|
||||
if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rec.idx = page.high_index;
|
||||
if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
|
||||
{
|
||||
if (rec.size + 1 != page.free_space)
|
||||
abort();
|
||||
delete [] rec.data;
|
||||
ndbout_c(" FAIL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(rnd < 80)
|
||||
{
|
||||
// Alloc with id, outside of directory
|
||||
rec.idx = page.high_index + (rand() % (page.free_space - rec.size));
|
||||
if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rec.idx = page.high_index + (page.free_space - rec.size) + 1;
|
||||
if (page.alloc_record(rec.idx, rec.size, &tmp) == rec.idx)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
delete [] rec.data;
|
||||
ndbout_c(" FAIL");
|
||||
break;
|
||||
}
|
||||
|
||||
Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
|
||||
ndbout << " -> " << rec.idx
|
||||
<< " pos: " << pos << endl;
|
||||
Uint32* ptr= page.get_ptr(rec.idx);
|
||||
memcpy(ptr, rec.data, 4*rec.size);
|
||||
records[allocated++] = rec;
|
||||
@ -81,12 +174,14 @@ loop:
|
||||
{
|
||||
int no= rand() % allocated;
|
||||
Record rec= records[no];
|
||||
ndbout << "Free no: " << no << " idx: " << rec.idx << endl;
|
||||
Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
|
||||
ndbout << "Free hi: " << page.high_index << " no: " << no << " idx: " << rec.idx << " pos: " << pos << endl;
|
||||
Uint32* ptr= page.get_ptr(rec.idx);
|
||||
assert(page.get_entry_len(rec.idx) == rec.size);
|
||||
cmp(ptr, rec.data, rec.size);
|
||||
delete[] rec.data;
|
||||
page.free_record(rec.idx, 0);
|
||||
|
||||
|
||||
for (unsigned k = no; k + 1 < allocated; k++)
|
||||
records[k] = records[k+1];
|
||||
allocated--;
|
||||
@ -98,8 +193,57 @@ loop:
|
||||
page.reorg(&tmp);
|
||||
break;
|
||||
case 3:
|
||||
ndbout << "Expand" << endl;
|
||||
|
||||
{
|
||||
Uint32 free = page.free_space;
|
||||
if (free <= 2)
|
||||
{
|
||||
goto shrink;
|
||||
}
|
||||
free /= 2;
|
||||
int no = rand() % allocated;
|
||||
Record rec= records[no];
|
||||
ndbout << "Expand no: " << no << " idx: " << rec.idx
|
||||
<< " add: " << free << " reorg: "
|
||||
<< !page.is_space_behind_entry(rec.idx, free)
|
||||
<< endl;
|
||||
if (!page.is_space_behind_entry(rec.idx, free))
|
||||
{
|
||||
Uint32 buffer[8192];
|
||||
Uint32 len = page.get_entry_len(rec.idx);
|
||||
memcpy(buffer, page.get_ptr(rec.idx), 4*len);
|
||||
page.set_entry_len(rec.idx, 0);
|
||||
page.free_space += len;
|
||||
page.reorg(&tmp);
|
||||
memcpy(page.get_free_space_ptr(), buffer, 4*len);
|
||||
page.set_entry_offset(rec.idx, page.insert_pos);
|
||||
free += len;
|
||||
records[no].size = 0;
|
||||
}
|
||||
|
||||
page.grow_entry(rec.idx, free);
|
||||
records[no].size += free;
|
||||
Uint32 *ptr = page.get_ptr(rec.idx);
|
||||
Uint32 *new_data = new Uint32[records[no].size];
|
||||
for(Uint32 i= 0; i<records[no].size; i++)
|
||||
{
|
||||
ptr[i] = new_data[i] = rand();
|
||||
}
|
||||
delete []rec.data;
|
||||
records[no].data = new_data;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
shrink:
|
||||
int no = rand() % allocated;
|
||||
Record rec = records[no];
|
||||
Uint32 sz = rec.size / 2 + 1;
|
||||
ndbout << "Shrink no: " << no << " idx: " << rec.idx << " remove: "
|
||||
<< (rec.size - sz) << endl;
|
||||
page.shrink_entry(rec.idx, sz);
|
||||
records[no].size = sz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -107,19 +251,27 @@ loop:
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
ndb_init();
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
time_t seed = time(0);
|
||||
srand(seed);
|
||||
fprintf(stderr, "srand(%d)\n", seed);
|
||||
}
|
||||
// alloc, free, reorg, grow, shrink
|
||||
|
||||
int t1[] = { 30, 90, 100 };
|
||||
int t2[] = { 45, 90, 100 };
|
||||
int t3[] = { 60, 90, 100 };
|
||||
int t4[] = { 75, 90, 100 };
|
||||
int t1[] = { 10, 60, 70, 85, 100 };
|
||||
int t2[] = { 30, 60, 70, 85, 100 };
|
||||
int t3[] = { 50, 60, 70, 85, 100 };
|
||||
|
||||
do_test(10000, t1);
|
||||
do_test(10000, t2);
|
||||
do_test(10000, t3);
|
||||
do_test(10000, t4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template class Vector<Record>;
|
||||
|
@ -18,6 +18,20 @@
|
||||
#include "tuppage.hpp"
|
||||
#include "Dbtup.hpp"
|
||||
|
||||
/**
|
||||
* Fix pages maintain a double linked list of free entries
|
||||
*
|
||||
* Var pages has a directory where each entry is
|
||||
* [ C(1), F(1), L(15), P(15) ]
|
||||
* C is chain bit, (is it a full tuple or just chain)
|
||||
* F is free bit
|
||||
* If true, L is prev free entry (in directory)
|
||||
* P is next free entry (in directory)
|
||||
* else
|
||||
* L is len of entry
|
||||
* P is pos of entry
|
||||
*/
|
||||
|
||||
Uint32
|
||||
Tup_fixsize_page::alloc_record()
|
||||
{
|
||||
@ -29,7 +43,7 @@ Tup_fixsize_page::alloc_record()
|
||||
Uint32 next = m_data[page_idx] & 0xFFFF;
|
||||
|
||||
assert(prev == 0xFFFF);
|
||||
assert(m_data[page_idx + 1] == Dbtup::Tuple_header::FREE);
|
||||
assert(m_data[page_idx + 1] == FREE_RECORD);
|
||||
|
||||
m_data[page_idx + 1] = 0;
|
||||
if (next != 0xFFFF)
|
||||
@ -53,7 +67,7 @@ Uint32
|
||||
Tup_fixsize_page::alloc_record(Uint32 page_idx)
|
||||
{
|
||||
assert(page_idx + 1 < DATA_WORDS);
|
||||
if (likely(free_space && m_data[page_idx + 1] == Dbtup::Tuple_header::FREE))
|
||||
if (likely(free_space && m_data[page_idx + 1] == FREE_RECORD))
|
||||
{
|
||||
Uint32 prev = m_data[page_idx] >> 16;
|
||||
Uint32 next = m_data[page_idx] & 0xFFFF;
|
||||
@ -87,7 +101,7 @@ Tup_fixsize_page::free_record(Uint32 page_idx)
|
||||
Uint32 next = next_free_index;
|
||||
|
||||
assert(page_idx + 1 < DATA_WORDS);
|
||||
assert(m_data[page_idx + 1] != Dbtup::Tuple_header::FREE);
|
||||
assert(m_data[page_idx + 1] != FREE_RECORD);
|
||||
|
||||
if (next == 0xFFFF)
|
||||
{
|
||||
@ -100,12 +114,12 @@ Tup_fixsize_page::free_record(Uint32 page_idx)
|
||||
Uint32 nextP = m_data[next];
|
||||
assert((nextP >> 16) == 0xFFFF);
|
||||
m_data[next] = (page_idx << 16) | (nextP & 0xFFFF);
|
||||
assert(m_data[next + 1] == Dbtup::Tuple_header::FREE);
|
||||
assert(m_data[next + 1] == FREE_RECORD);
|
||||
}
|
||||
|
||||
next_free_index = page_idx;
|
||||
m_data[page_idx] = 0xFFFF0000 | next;
|
||||
m_data[page_idx + 1] = Dbtup::Tuple_header::FREE;
|
||||
m_data[page_idx + 1] = FREE_RECORD;
|
||||
|
||||
return ++free_space;
|
||||
}
|
||||
@ -116,10 +130,122 @@ Tup_varsize_page::init()
|
||||
free_space= DATA_WORDS - 1;
|
||||
high_index= 1;
|
||||
insert_pos= 0;
|
||||
next_free_index= 0xFFFF;
|
||||
next_free_index= END_OF_FREE_LIST;
|
||||
m_page_header.m_page_type = File_formats::PT_Tup_varsize_page;
|
||||
}
|
||||
|
||||
Uint32
|
||||
Tup_varsize_page::alloc_record(Uint32 page_idx, Uint32 alloc_size,
|
||||
Tup_varsize_page* temp)
|
||||
{
|
||||
assert(page_idx); // 0 is not allowed
|
||||
Uint32 free = free_space;
|
||||
Uint32 largest_size= DATA_WORDS - (insert_pos + high_index);
|
||||
Uint32 free_list = next_free_index;
|
||||
|
||||
if (page_idx < high_index)
|
||||
{
|
||||
Uint32 *ptr = get_index_ptr(page_idx);
|
||||
Uint32 word = *ptr;
|
||||
|
||||
if (unlikely((free < alloc_size) || ! (word & FREE)))
|
||||
{
|
||||
return ~0;
|
||||
}
|
||||
|
||||
if (alloc_size >= largest_size)
|
||||
{
|
||||
/*
|
||||
We can't fit this segment between the insert position and the end of
|
||||
the index entries. We will pack the page so that all free space
|
||||
exists between the insert position and the end of the index entries.
|
||||
*/
|
||||
reorg(temp);
|
||||
}
|
||||
|
||||
Uint32 next = (word & NEXT_MASK) >> NEXT_SHIFT;
|
||||
Uint32 prev = (word & PREV_MASK) >> PREV_SHIFT;
|
||||
|
||||
if (next != END_OF_FREE_LIST)
|
||||
{
|
||||
Uint32 * next_ptr = get_index_ptr(next);
|
||||
Uint32 next_word = * next_ptr;
|
||||
* next_ptr = (next_word & ~PREV_MASK) | (prev << PREV_SHIFT);
|
||||
}
|
||||
|
||||
if (prev != END_OF_FREE_LIST)
|
||||
{
|
||||
Uint32 * prev_ptr = get_index_ptr(prev);
|
||||
Uint32 prev_word = * prev_ptr;
|
||||
* prev_ptr = (prev_word & ~NEXT_MASK) | (next << NEXT_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(next_free_index == page_idx);
|
||||
next_free_index = next;
|
||||
}
|
||||
|
||||
* ptr = insert_pos + (alloc_size << LEN_SHIFT);
|
||||
free -= alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* We need to expand directory
|
||||
*/
|
||||
Uint32 hi = high_index;
|
||||
Uint32 expand = (page_idx + 1 - hi);
|
||||
Uint32 size = alloc_size + expand;
|
||||
if (unlikely(size > free))
|
||||
{
|
||||
return ~0;
|
||||
}
|
||||
|
||||
if (size >= largest_size)
|
||||
{
|
||||
/*
|
||||
We can't fit this segment between the insert position and the end of
|
||||
the index entries. We will pack the page so that all free space
|
||||
exists between the insert position and the end of the index entries.
|
||||
*/
|
||||
reorg(temp);
|
||||
}
|
||||
|
||||
Uint32 *ptr = m_data + DATA_WORDS - hi;
|
||||
if (page_idx == hi)
|
||||
{
|
||||
* ptr = insert_pos + (alloc_size << LEN_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (free_list != END_OF_FREE_LIST)
|
||||
{
|
||||
Uint32 * prev_ptr = get_index_ptr(free_list);
|
||||
Uint32 prev_word = * prev_ptr;
|
||||
* prev_ptr = (prev_word & ~PREV_MASK) | (hi << PREV_SHIFT);
|
||||
}
|
||||
|
||||
for (; hi < page_idx;)
|
||||
{
|
||||
* ptr-- = FREE | (free_list << NEXT_SHIFT) | ((hi+1) << PREV_SHIFT);
|
||||
free_list = hi++;
|
||||
}
|
||||
|
||||
* ptr++ = insert_pos + (alloc_size << LEN_SHIFT);
|
||||
* ptr = ((* ptr) & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
|
||||
|
||||
next_free_index = hi - 1;
|
||||
}
|
||||
high_index = hi + 1;
|
||||
free -= size;
|
||||
}
|
||||
|
||||
free_space = free;
|
||||
insert_pos += alloc_size;
|
||||
|
||||
return page_idx;
|
||||
}
|
||||
|
||||
Uint32
|
||||
Tup_varsize_page::alloc_record(Uint32 alloc_size,
|
||||
Tup_varsize_page* temp, Uint32 chain)
|
||||
@ -138,7 +264,7 @@ Tup_varsize_page::alloc_record(Uint32 alloc_size,
|
||||
assert(largest_size > alloc_size);
|
||||
|
||||
Uint32 page_idx;
|
||||
if (next_free_index == 0xFFFF) {
|
||||
if (next_free_index == END_OF_FREE_LIST) {
|
||||
/*
|
||||
We are out of free index slots. We will extend the array of free
|
||||
slots
|
||||
@ -148,12 +274,21 @@ Tup_varsize_page::alloc_record(Uint32 alloc_size,
|
||||
} else {
|
||||
// Pick an empty slot among the index entries
|
||||
page_idx= next_free_index;
|
||||
assert((get_index_word(page_idx) & 0xFFFF0000) == 0);
|
||||
next_free_index= get_index_word(page_idx);
|
||||
assert((get_index_word(page_idx) & FREE) == FREE);
|
||||
assert(((get_index_word(page_idx) & PREV_MASK) >> PREV_SHIFT) ==
|
||||
END_OF_FREE_LIST);
|
||||
next_free_index= (get_index_word(page_idx) & NEXT_MASK) >> NEXT_SHIFT;
|
||||
assert(next_free_index);
|
||||
if (next_free_index != END_OF_FREE_LIST)
|
||||
{
|
||||
Uint32 *ptr = get_index_ptr(next_free_index);
|
||||
Uint32 word = *ptr;
|
||||
* ptr = (word & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
assert(chain == 0 || chain == CHAIN);
|
||||
* get_index_ptr(page_idx) = insert_pos + ((chain + alloc_size) << 16);
|
||||
* get_index_ptr(page_idx) = insert_pos + chain + (alloc_size << LEN_SHIFT);
|
||||
|
||||
insert_pos += alloc_size;
|
||||
free_space -= alloc_size;
|
||||
@ -167,10 +302,10 @@ Tup_varsize_page::free_record(Uint32 page_idx, Uint32 chain)
|
||||
//ndbout_c("%p->free_record(%d%s)", this, page_idx, (chain ? " CHAIN": ""));
|
||||
Uint32 *index_ptr= get_index_ptr(page_idx);
|
||||
Uint32 index_word= * index_ptr;
|
||||
Uint32 entry_pos= index_word & 0xFFFF;
|
||||
Uint32 entry_len= (index_word >> 16) & ~CHAIN;
|
||||
Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
|
||||
Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
|
||||
assert(chain == 0 || chain == CHAIN);
|
||||
assert(!(((index_word >> 16) ^ chain) & 0x8000));
|
||||
assert((index_word & CHAIN) == chain);
|
||||
#ifdef VM_TRACE
|
||||
memset(m_data + entry_pos, 0xF2, 4*entry_len);
|
||||
#endif
|
||||
@ -183,8 +318,16 @@ Tup_varsize_page::free_record(Uint32 page_idx, Uint32 chain)
|
||||
*/
|
||||
rebuild_index(index_ptr);
|
||||
} else {
|
||||
* index_ptr= next_free_index;
|
||||
if (next_free_index != END_OF_FREE_LIST)
|
||||
{
|
||||
Uint32 *ptr = get_index_ptr(next_free_index);
|
||||
Uint32 word = *ptr;
|
||||
assert(((word & PREV_MASK) >> PREV_SHIFT) == END_OF_FREE_LIST);
|
||||
* ptr = (word & ~PREV_MASK) | (page_idx << PREV_SHIFT);
|
||||
}
|
||||
* index_ptr= FREE | next_free_index | (END_OF_FREE_LIST << PREV_SHIFT);
|
||||
next_free_index= page_idx;
|
||||
assert(next_free_index);
|
||||
}
|
||||
|
||||
free_space+= entry_len;
|
||||
@ -204,7 +347,7 @@ Tup_varsize_page::rebuild_index(Uint32* index_ptr)
|
||||
* Scan until you find first non empty index pos
|
||||
*/
|
||||
for(index_ptr++; index_ptr < end; index_ptr++)
|
||||
if((* index_ptr >> 16) == 0)
|
||||
if((* index_ptr) & FREE)
|
||||
empty++;
|
||||
else
|
||||
break;
|
||||
@ -214,23 +357,30 @@ Tup_varsize_page::rebuild_index(Uint32* index_ptr)
|
||||
// Totally free page
|
||||
high_index = 1;
|
||||
free_space += empty;
|
||||
next_free_index= 0xFFFF;
|
||||
next_free_index = END_OF_FREE_LIST;
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 next= 0xFFFF;
|
||||
high_index -= empty;
|
||||
|
||||
Uint32 next= END_OF_FREE_LIST;
|
||||
Uint32 dummy;
|
||||
Uint32 *prev_ptr = &dummy;
|
||||
for(index_ptr++; index_ptr < end; index_ptr++)
|
||||
{
|
||||
if((* index_ptr >> 16) == 0)
|
||||
if ((* index_ptr) & FREE)
|
||||
{
|
||||
* index_ptr= next;
|
||||
* index_ptr= FREE | next;
|
||||
next= (end - index_ptr);
|
||||
* prev_ptr |= (next << PREV_SHIFT);
|
||||
prev_ptr = index_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
* prev_ptr |= (END_OF_FREE_LIST << PREV_SHIFT);
|
||||
|
||||
high_index -= empty;
|
||||
free_space += empty;
|
||||
next_free_index= next;
|
||||
assert(next_free_index);
|
||||
}
|
||||
|
||||
void
|
||||
@ -247,16 +397,17 @@ Tup_varsize_page::reorg(Tup_varsize_page* copy_page)
|
||||
for (; index_ptr < end_of_page; index_ptr++)
|
||||
{
|
||||
Uint32 index_word= * index_ptr;
|
||||
Uint32 entry_len= (index_word >> 16) & ~CHAIN;
|
||||
if (entry_len != 0) {
|
||||
Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
|
||||
if (!(index_word & FREE) && entry_len)
|
||||
{
|
||||
/*
|
||||
We found an index item that needs to be packed.
|
||||
We will update the index entry and copy the data to the page.
|
||||
*/
|
||||
Uint32 entry_pos= index_word & 0xffff;
|
||||
Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
|
||||
assert(entry_pos + entry_len <= old_insert_pos);
|
||||
assert(new_insert_pos + entry_len <= old_insert_pos);
|
||||
* index_ptr= new_insert_pos + (index_word & 0xFFFF0000);
|
||||
* index_ptr= (new_insert_pos << POS_SHIFT) + (index_word & ~POS_MASK);
|
||||
memcpy(m_data+new_insert_pos, copy_page->m_data+entry_pos, 4*entry_len);
|
||||
|
||||
new_insert_pos += entry_len;
|
||||
@ -278,10 +429,10 @@ operator<< (NdbOut& out, const Tup_varsize_page& page)
|
||||
for(Uint32 i = 1; i<page.high_index; i++, index_ptr--)
|
||||
{
|
||||
out << " [ " << i;
|
||||
if(*index_ptr >> 16)
|
||||
out << " pos: " << ((*index_ptr) & 0xFFFF)
|
||||
<< " len: " << ((*index_ptr >> 16) & ~page.CHAIN)
|
||||
<< (((* index_ptr >> 16) & page.CHAIN) ? " CHAIN " : " ")
|
||||
if(! (*index_ptr & page.FREE))
|
||||
out << " pos: " << ((* index_ptr & page.POS_MASK) >> page.POS_SHIFT)
|
||||
<< " len: " << ((* index_ptr & page.LEN_MASK) >> page.LEN_SHIFT)
|
||||
<< ((* index_ptr & page.CHAIN) ? " CHAIN " : " ")
|
||||
<< "]" << flush;
|
||||
else
|
||||
out << " FREE ]" << flush;
|
||||
@ -289,10 +440,10 @@ operator<< (NdbOut& out, const Tup_varsize_page& page)
|
||||
|
||||
out << " free list: " << flush;
|
||||
Uint32 next= page.next_free_index;
|
||||
while(next != 0xFFFF)
|
||||
while(next != page.END_OF_FREE_LIST)
|
||||
{
|
||||
out << next << " " << flush;
|
||||
next= * (page.m_data+page.DATA_WORDS-next);
|
||||
next= ((* (page.m_data+page.DATA_WORDS-next)) & page.NEXT_MASK) >> page.NEXT_SHIFT;
|
||||
}
|
||||
out << "]";
|
||||
return out;
|
||||
|
@ -81,6 +81,7 @@ struct Tup_fixsize_page
|
||||
Uint32 m_extent_info_ptr;
|
||||
Uint32 unused_ph[9];
|
||||
|
||||
STATIC_CONST( FREE_RECORD = ~(Uint32)0 );
|
||||
STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
|
||||
|
||||
Uint32 m_data[DATA_WORDS];
|
||||
@ -127,7 +128,18 @@ struct Tup_varsize_page
|
||||
Uint32 unused_ph[7];
|
||||
|
||||
STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
|
||||
STATIC_CONST( CHAIN = 0x8000 );
|
||||
STATIC_CONST( CHAIN = 0x80000000 );
|
||||
STATIC_CONST( FREE = 0x40000000 );
|
||||
STATIC_CONST( LEN_MASK = 0x3FFF8000 );
|
||||
STATIC_CONST( POS_MASK = 0x00007FFF );
|
||||
STATIC_CONST( LEN_SHIFT = 15 );
|
||||
STATIC_CONST( POS_SHIFT = 0 );
|
||||
STATIC_CONST( END_OF_FREE_LIST = POS_MASK );
|
||||
|
||||
STATIC_CONST( NEXT_MASK = POS_MASK );
|
||||
STATIC_CONST( NEXT_SHIFT = POS_SHIFT );
|
||||
STATIC_CONST( PREV_MASK = LEN_MASK );
|
||||
STATIC_CONST( PREV_SHIFT = LEN_SHIFT );
|
||||
|
||||
Uint32 m_data[DATA_WORDS];
|
||||
|
||||
@ -156,6 +168,12 @@ struct Tup_varsize_page
|
||||
* temp is used when having to reorg page before allocating
|
||||
*/
|
||||
Uint32 alloc_record(Uint32 size, Tup_varsize_page* temp, Uint32 chain);
|
||||
|
||||
/**
|
||||
* Alloc page_idx from page, return page_idx
|
||||
* temp is used when having to reorg page before allocating
|
||||
*/
|
||||
Uint32 alloc_record(Uint32 page_idx, Uint32 size, Tup_varsize_page* temp);
|
||||
|
||||
/**
|
||||
* Free record from page
|
||||
@ -170,8 +188,8 @@ struct Tup_varsize_page
|
||||
*/
|
||||
bool is_space_behind_entry(Uint32 page_index, Uint32 growth_len) const {
|
||||
Uint32 idx= get_index_word(page_index);
|
||||
Uint32 pos= idx & 0xFFFF;
|
||||
Uint32 len= (idx >> 16) & ~CHAIN;
|
||||
Uint32 pos= (idx & POS_MASK) >> POS_SHIFT;
|
||||
Uint32 len= (idx & LEN_MASK) >> LEN_SHIFT;
|
||||
if ((pos + len == insert_pos) &&
|
||||
(insert_pos + growth_len < DATA_WORDS - high_index))
|
||||
return true;
|
||||
@ -180,12 +198,14 @@ struct Tup_varsize_page
|
||||
|
||||
void grow_entry(Uint32 page_index, Uint32 growth_len) {
|
||||
assert(free_space >= growth_len);
|
||||
|
||||
|
||||
Uint32 *pos= get_index_ptr(page_index);
|
||||
Uint32 idx= *pos;
|
||||
Uint32 size= (idx >> 16) + growth_len;
|
||||
*pos= (idx & 0xFFFF) + (size << 16);
|
||||
assert((idx & 0xFFFF) + ((idx >> 16) & ~CHAIN) == insert_pos);
|
||||
assert(! (idx & FREE));
|
||||
assert((((idx & POS_MASK) >> POS_SHIFT) + ((idx & LEN_MASK) >> LEN_SHIFT))
|
||||
== insert_pos);
|
||||
|
||||
* pos= idx + (growth_len << LEN_SHIFT);
|
||||
insert_pos+= growth_len;
|
||||
free_space-= growth_len;
|
||||
}
|
||||
@ -193,35 +213,42 @@ struct Tup_varsize_page
|
||||
void shrink_entry(Uint32 page_index, Uint32 new_size){
|
||||
Uint32 *pos= get_index_ptr(page_index);
|
||||
Uint32 idx= *pos;
|
||||
*pos= (idx & (CHAIN << 16 | 0xFFFF)) + (new_size << 16);
|
||||
Uint32 old_size= (idx >> 16) & ~CHAIN;
|
||||
|
||||
Uint32 old_pos = (idx & POS_MASK) >> POS_SHIFT;
|
||||
Uint32 old_size = (idx & LEN_MASK) >> LEN_SHIFT;
|
||||
|
||||
assert( ! (idx & FREE));
|
||||
assert(old_size >= new_size);
|
||||
|
||||
* pos= (idx & ~LEN_MASK) + (new_size << LEN_SHIFT);
|
||||
Uint32 shrink = old_size - new_size;
|
||||
#ifdef VM_TRACE
|
||||
memset(m_data + (idx & 0xFFFF) + new_size, 0xF1, 4 * shrink);
|
||||
memset(m_data + old_pos + new_size, 0xF1, 4 * shrink);
|
||||
#endif
|
||||
free_space+= shrink;
|
||||
if(insert_pos == ((idx & 0xFFFF) + old_size))
|
||||
if(insert_pos == (old_pos + old_size))
|
||||
insert_pos -= shrink;
|
||||
}
|
||||
|
||||
Uint32* get_ptr(Uint32 page_idx) {
|
||||
return m_data + (get_index_word(page_idx) & 0xFFFF);
|
||||
return m_data + ((get_index_word(page_idx) & POS_MASK) >> POS_SHIFT);
|
||||
}
|
||||
|
||||
void set_entry_offset(Uint32 page_idx, Uint32 offset){
|
||||
Uint32 *pos= get_index_ptr(page_idx);
|
||||
*pos = (* pos & 0xFFFF0000) + offset;
|
||||
}
|
||||
|
||||
Uint32 get_entry_len(Uint32 page_idx) const {
|
||||
return get_index_word(page_idx) >> 16;
|
||||
* pos = (* pos & ~POS_MASK) + (offset << POS_SHIFT);
|
||||
}
|
||||
|
||||
void set_entry_len(Uint32 page_idx, Uint32 len) {
|
||||
Uint32 *pos= get_index_ptr(page_idx);
|
||||
*pos = (len << 16) + (*pos & (CHAIN << 16 | 0xFFFF));
|
||||
* pos = (*pos & ~LEN_MASK) + (len << LEN_SHIFT);
|
||||
}
|
||||
|
||||
Uint32 get_entry_len(Uint32 page_idx) const {
|
||||
return (get_index_word(page_idx) & LEN_MASK) >> LEN_SHIFT;
|
||||
}
|
||||
|
||||
Uint32 get_entry_chain(Uint32 page_idx) const {
|
||||
return get_index_word(page_idx) & CHAIN;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <signaldata/LCP.hpp>
|
||||
#include <signaldata/SumaImpl.hpp>
|
||||
#include <signaldata/LgmanContinueB.hpp>
|
||||
#include <signaldata/GetTabInfo.hpp>
|
||||
#include "ndbfs/Ndbfs.hpp"
|
||||
#include "dbtup/Dbtup.hpp"
|
||||
|
||||
@ -86,7 +87,9 @@ Lgman::Lgman(const Configuration & conf) :
|
||||
addRecSignal(GSN_START_RECREQ, &Lgman::execSTART_RECREQ);
|
||||
|
||||
addRecSignal(GSN_END_LCP_CONF, &Lgman::execEND_LCP_CONF);
|
||||
|
||||
|
||||
addRecSignal(GSN_GET_TABINFOREQ, &Lgman::execGET_TABINFOREQ);
|
||||
|
||||
m_last_lsn = 0;
|
||||
m_logfile_group_pool.setSize(10);
|
||||
m_logfile_group_hash.setSize(10);
|
||||
@ -701,6 +704,7 @@ Lgman::create_file_commit(Signal* signal,
|
||||
ptr.p->m_state = Undofile::FS_SORTING;
|
||||
}
|
||||
|
||||
ptr.p->m_online.m_lsn = 0;
|
||||
ptr.p->m_online.m_outstanding = 0;
|
||||
|
||||
Uint64 add= ptr.p->m_file_size - 1;
|
||||
@ -1648,7 +1652,7 @@ Lgman::execLCP_FRAG_ORD(Signal* signal)
|
||||
sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
|
||||
}
|
||||
|
||||
if(!ptr.isNull())
|
||||
if(!ptr.isNull() && ptr.p->m_last_lsn)
|
||||
{
|
||||
Uint32 undo[3];
|
||||
undo[0] = lcp_id;
|
||||
@ -1686,24 +1690,26 @@ Lgman::execLCP_FRAG_ORD(Signal* signal)
|
||||
|
||||
while(!ptr.isNull())
|
||||
{
|
||||
/**
|
||||
* First LCP_FRAGORD for each LCP, sets tail pos
|
||||
*/
|
||||
if(m_latest_lcp != lcp_id)
|
||||
if (ptr.p->m_last_lsn)
|
||||
{
|
||||
ptr.p->m_tail_pos[0] = ptr.p->m_tail_pos[1];
|
||||
ptr.p->m_tail_pos[1] = ptr.p->m_tail_pos[2];
|
||||
ptr.p->m_tail_pos[2] = ptr.p->m_file_pos[HEAD];
|
||||
/**
|
||||
* First LCP_FRAGORD for each LCP, sets tail pos
|
||||
*/
|
||||
if(m_latest_lcp != lcp_id)
|
||||
{
|
||||
ptr.p->m_tail_pos[0] = ptr.p->m_tail_pos[1];
|
||||
ptr.p->m_tail_pos[1] = ptr.p->m_tail_pos[2];
|
||||
ptr.p->m_tail_pos[2] = ptr.p->m_file_pos[HEAD];
|
||||
}
|
||||
|
||||
if(0)
|
||||
ndbout_c
|
||||
("execLCP_FRAG_ORD (%d %d) (%d %d) (%d %d) free pages: %d",
|
||||
ptr.p->m_tail_pos[0].m_ptr_i, ptr.p->m_tail_pos[0].m_idx,
|
||||
ptr.p->m_tail_pos[1].m_ptr_i, ptr.p->m_tail_pos[1].m_idx,
|
||||
ptr.p->m_tail_pos[2].m_ptr_i, ptr.p->m_tail_pos[2].m_idx,
|
||||
(ptr.p->m_free_file_words / File_formats::UNDO_PAGE_WORDS));
|
||||
}
|
||||
|
||||
if(0)
|
||||
ndbout_c
|
||||
("execLCP_FRAG_ORD (%d %d) (%d %d) (%d %d) free pages: %d",
|
||||
ptr.p->m_tail_pos[0].m_ptr_i, ptr.p->m_tail_pos[0].m_idx,
|
||||
ptr.p->m_tail_pos[1].m_ptr_i, ptr.p->m_tail_pos[1].m_idx,
|
||||
ptr.p->m_tail_pos[2].m_ptr_i, ptr.p->m_tail_pos[2].m_idx,
|
||||
(ptr.p->m_free_file_words / File_formats::UNDO_PAGE_WORDS));
|
||||
|
||||
m_logfile_group_list.next(ptr);
|
||||
}
|
||||
|
||||
@ -1761,47 +1767,50 @@ Lgman::endlcp_callback(Signal* signal, Uint32 ptr, Uint32 res)
|
||||
void
|
||||
Lgman::cut_log_tail(Signal* signal, Ptr<Logfile_group> ptr)
|
||||
{
|
||||
Buffer_idx tmp= ptr.p->m_tail_pos[0];
|
||||
Buffer_idx tail= ptr.p->m_file_pos[TAIL];
|
||||
|
||||
Ptr<Undofile> filePtr;
|
||||
m_file_pool.getPtr(filePtr, tail.m_ptr_i);
|
||||
|
||||
bool done= true;
|
||||
if(!(tmp == tail))
|
||||
if (likely(ptr.p->m_last_lsn))
|
||||
{
|
||||
Uint32 free;
|
||||
if(tmp.m_ptr_i == tail.m_ptr_i && tail.m_idx < tmp.m_idx)
|
||||
Buffer_idx tmp= ptr.p->m_tail_pos[0];
|
||||
Buffer_idx tail= ptr.p->m_file_pos[TAIL];
|
||||
|
||||
Ptr<Undofile> filePtr;
|
||||
m_file_pool.getPtr(filePtr, tail.m_ptr_i);
|
||||
|
||||
if(!(tmp == tail))
|
||||
{
|
||||
free= tmp.m_idx - tail.m_idx;
|
||||
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
||||
ptr.p->m_file_pos[TAIL] = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
free= filePtr.p->m_file_size - tail.m_idx - 1;
|
||||
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
||||
|
||||
Ptr<Undofile> next = filePtr;
|
||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
||||
while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
|
||||
ndbassert(next.i != filePtr.i);
|
||||
if(next.isNull())
|
||||
Uint32 free;
|
||||
if(tmp.m_ptr_i == tail.m_ptr_i && tail.m_idx < tmp.m_idx)
|
||||
{
|
||||
jam();
|
||||
files.first(next);
|
||||
while((next.p->m_state & Undofile::FS_EMPTY) && files.next(next))
|
||||
ndbassert(next.i != filePtr.i);
|
||||
free= tmp.m_idx - tail.m_idx;
|
||||
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
||||
ptr.p->m_file_pos[TAIL] = tmp;
|
||||
}
|
||||
|
||||
tmp.m_idx= 0;
|
||||
tmp.m_ptr_i= next.i;
|
||||
ptr.p->m_file_pos[TAIL] = tmp;
|
||||
done= false;
|
||||
}
|
||||
}
|
||||
|
||||
validate_logfile_group(ptr, "cut log");
|
||||
else
|
||||
{
|
||||
free= filePtr.p->m_file_size - tail.m_idx - 1;
|
||||
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
||||
|
||||
Ptr<Undofile> next = filePtr;
|
||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
||||
while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
|
||||
ndbassert(next.i != filePtr.i);
|
||||
if(next.isNull())
|
||||
{
|
||||
jam();
|
||||
files.first(next);
|
||||
while((next.p->m_state & Undofile::FS_EMPTY) && files.next(next))
|
||||
ndbassert(next.i != filePtr.i);
|
||||
}
|
||||
|
||||
tmp.m_idx= 0;
|
||||
tmp.m_ptr_i= next.i;
|
||||
ptr.p->m_file_pos[TAIL] = tmp;
|
||||
done= false;
|
||||
}
|
||||
}
|
||||
|
||||
validate_logfile_group(ptr, "cut log");
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
@ -2946,3 +2955,71 @@ Lgman::validate_logfile_group(Ptr<Logfile_group> ptr, const char * heading)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Lgman::execGET_TABINFOREQ(Signal* signal)
|
||||
{
|
||||
jamEntry();
|
||||
|
||||
if(!assembleFragments(signal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
|
||||
|
||||
const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
|
||||
BlockReference retRef= req->senderRef;
|
||||
Uint32 senderData= req->senderData;
|
||||
Uint32 tableId= req->tableId;
|
||||
|
||||
if(reqType == GetTabInfoReq::RequestByName){
|
||||
jam();
|
||||
if(signal->getNoOfSections())
|
||||
releaseSections(signal);
|
||||
|
||||
sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
|
||||
return;
|
||||
}
|
||||
|
||||
Logfile_group key;
|
||||
key.m_logfile_group_id= tableId;
|
||||
Ptr<Logfile_group> ptr;
|
||||
m_logfile_group_hash.find(ptr, key);
|
||||
|
||||
if(ptr.p->m_logfile_group_id != tableId)
|
||||
{
|
||||
jam();
|
||||
if(signal->getNoOfSections())
|
||||
releaseSections(signal);
|
||||
|
||||
sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GetTabInfoConf *conf = (GetTabInfoConf *)&signal->theData[0];
|
||||
|
||||
conf->senderData= senderData;
|
||||
conf->tableId= tableId;
|
||||
conf->freeWordsHi= ptr.p->m_free_file_words >> 32;
|
||||
conf->freeWordsLo= ptr.p->m_free_file_words & 0xFFFFFFFF;
|
||||
conf->tableType= DictTabInfo::LogfileGroup;
|
||||
conf->senderRef= reference();
|
||||
sendSignal(retRef, GSN_GET_TABINFO_CONF, signal,
|
||||
GetTabInfoConf::SignalLength, JBB);
|
||||
}
|
||||
|
||||
void Lgman::sendGET_TABINFOREF(Signal* signal,
|
||||
GetTabInfoReq * req,
|
||||
GetTabInfoRef::ErrorCode errorCode)
|
||||
{
|
||||
jamEntry();
|
||||
GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
|
||||
/**
|
||||
* The format of GetTabInfo Req/Ref is the same
|
||||
*/
|
||||
BlockReference retRef = req->senderRef;
|
||||
ref->errorCode = errorCode;
|
||||
|
||||
sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <DLHashTable.hpp>
|
||||
#include <NodeBitmask.hpp>
|
||||
#include "diskpage.hpp"
|
||||
#include <signaldata/GetTabInfo.hpp>
|
||||
|
||||
class Lgman : public SimulatedBlock
|
||||
{
|
||||
@ -66,6 +67,13 @@ protected:
|
||||
|
||||
void execSTART_RECREQ(Signal*);
|
||||
void execEND_LCP_CONF(Signal*);
|
||||
|
||||
void execGET_TABINFOREQ(Signal*);
|
||||
|
||||
void sendGET_TABINFOREF(Signal* signal,
|
||||
GetTabInfoReq * req,
|
||||
GetTabInfoRef::ErrorCode errorCode);
|
||||
|
||||
public:
|
||||
struct Log_waiter
|
||||
{
|
||||
|
@ -341,11 +341,13 @@ void AsyncFile::openReq(Request* request)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NDB_NO_O_DIRECT /* to allow tmpfs */
|
||||
#ifdef O_DIRECT
|
||||
if (flags & FsOpenReq::OM_DIRECT)
|
||||
{
|
||||
new_flags |= O_DIRECT;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch(flags & 0x3){
|
||||
|
@ -1359,8 +1359,8 @@ void
|
||||
Pgman::fsreadreq(Signal* signal, Ptr<Page_entry> ptr)
|
||||
{
|
||||
File_map::ConstDataBufferIterator it;
|
||||
m_file_map.first(it);
|
||||
m_file_map.next(it, ptr.p->m_file_no);
|
||||
bool ret = m_file_map.first(it) && m_file_map.next(it, ptr.p->m_file_no);
|
||||
ndbrequire(ret);
|
||||
Uint32 fd = * it.data;
|
||||
|
||||
ndbrequire(ptr.p->m_page_no > 0);
|
||||
@ -1479,11 +1479,6 @@ Pgman::get_page(Signal* signal, Ptr<Page_entry> ptr, Page_request page_req)
|
||||
{
|
||||
busy_count = true;
|
||||
state |= Page_entry::BUSY;
|
||||
/*
|
||||
* Consider commit to be correlated. Otherwise pk op + commit makes
|
||||
* the page hot. XXX move to TUP which knows better.
|
||||
*/
|
||||
req_flags |= Page_request::CORR_REQ;
|
||||
}
|
||||
else if ((req_flags & Page_request::OP_MASK) != ZREAD)
|
||||
{
|
||||
@ -2196,11 +2191,14 @@ Pgman::execDUMP_STATE_ORD(Signal* signal)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (signal->theData[0] == 11003)
|
||||
{
|
||||
#ifdef VM_TRACE
|
||||
verify_page_lists();
|
||||
dump_page_lists();
|
||||
#else
|
||||
ndbout << "Only in VM_TRACE builds" << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -518,6 +518,7 @@ public:
|
||||
,DIRTY_REQ = Pgman::Page_request::DIRTY_REQ
|
||||
,NO_HOOK = Pgman::Page_request::NO_HOOK
|
||||
,UNLOCK_PAGE = Pgman::Page_request::UNLOCK_PAGE
|
||||
,CORR_REQ = Pgman::Page_request::CORR_REQ
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -817,7 +817,7 @@ Restore::parse_table_description(Signal* signal, FilePtr file_ptr,
|
||||
c.m_flags |= (tmp.AttributeStorageType == NDB_STORAGETYPE_DISK ?
|
||||
Column::COL_DISK : 0);
|
||||
|
||||
if(lcp && c.m_flags & Column::COL_DISK)
|
||||
if(lcp && (c.m_flags & Column::COL_DISK))
|
||||
{
|
||||
/**
|
||||
* Restore does not currently handle disk attributes
|
||||
@ -829,7 +829,6 @@ Restore::parse_table_description(Signal* signal, FilePtr file_ptr,
|
||||
|
||||
if(!tmp.AttributeNullableFlag && !varsize)
|
||||
{
|
||||
c.m_nulloffset = 0;
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, i);
|
||||
@ -838,53 +837,55 @@ Restore::parse_table_description(Signal* signal, FilePtr file_ptr,
|
||||
}
|
||||
else if (true) // null mask dropped in 5.1
|
||||
{
|
||||
c.m_nulloffset = (tmp.AttributeNullableFlag != 0);
|
||||
if (varsize)
|
||||
c.m_flags |= Column::COL_VAR;
|
||||
c.m_flags |= (varsize ? Column::COL_VAR : 0);
|
||||
c.m_flags |= (tmp.AttributeNullableFlag ? Column::COL_NULL : 0);
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
if(lcp)
|
||||
{
|
||||
if (disk)
|
||||
{
|
||||
c.m_nulloffset = 1 + null_offset++;
|
||||
c.m_flags |= Column::COL_VAR;
|
||||
if(!variable.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
c.m_id = AttributeHeader::DISK_REF;
|
||||
c.m_size = 2;
|
||||
c.m_flags = 0;
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, i);
|
||||
parse_error(signal, file_ptr, __LINE__, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
c.m_id = AttributeHeader::ROWID;
|
||||
c.m_size = 2;
|
||||
c.m_flags = 0;
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmpTab.RowGCIFlag)
|
||||
{
|
||||
c.m_id = AttributeHeader::ROW_GCI;
|
||||
c.m_size = 2;
|
||||
c.m_flags = 0;
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(lcp && disk)
|
||||
{
|
||||
c.m_id = AttributeHeader::DISK_REF;
|
||||
c.m_size = 2;
|
||||
c.m_nulloffset = 0;
|
||||
c.m_flags = 0;
|
||||
if(!columns.append(_align, sizeof(Column)/sizeof(Uint32)))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
file_ptr.p->m_table_version = tmpTab.TableVersion;
|
||||
file_ptr.p->m_null_bitmask_size = (null_offset + 31)/32;
|
||||
#if 0
|
||||
List::Iterator cols;
|
||||
for(variable.first(cols); !cols.isNull(); variable.next(cols))
|
||||
{
|
||||
if(!columns.append(cols.data, 1))
|
||||
{
|
||||
parse_error(signal, file_ptr, __LINE__, 0);
|
||||
}
|
||||
}
|
||||
return ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -927,11 +928,8 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
Uint32 * const key_start = signal->getDataPtrSend()+24;
|
||||
Uint32 * const attr_start = key_start + MAX_KEY_SIZE_IN_WORDS;
|
||||
|
||||
Uint32 nulls= file_ptr.p->m_null_bitmask_size;
|
||||
const Uint32 *null_mask= data+1;
|
||||
data += (1+nulls);
|
||||
data += 1;
|
||||
const Uint32* const dataStart = data;
|
||||
//if (file_ptr.p->m_table_id >= 2) { for (uint ii = 0; ii+1<len; ii++) ndbout << hex << dataStart[ii]; ndbout << endl; }
|
||||
|
||||
Uint32 *keyData = key_start;
|
||||
Uint32 *attrData = attr_start;
|
||||
@ -939,19 +937,36 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
Column c;
|
||||
Uint32 _align[1];
|
||||
};
|
||||
bool disk= false;
|
||||
bool disk = false;
|
||||
bool rowid = false;
|
||||
bool gci = false;
|
||||
|
||||
//if (file_ptr.p->m_table_id >= 2) { ndbout << "*** "; columns.first(it); while (!it.isNull()) { _align[0] = *it.data; columns.next(it); _align[1] = *it.data; columns.next(it); ndbout << c << " "; } ndbout << endl; }
|
||||
|
||||
Uint32 column_no = 0;
|
||||
Uint64 gci_val;
|
||||
Local_key rowid_val;
|
||||
columns.first(it);
|
||||
while(!it.isNull())
|
||||
{
|
||||
_align[0] = *it.data; ndbrequire(columns.next(it));
|
||||
_align[1] = *it.data; columns.next(it);
|
||||
|
||||
if (! (c.m_flags & Column::COL_VAR) &&
|
||||
! c.m_nulloffset)
|
||||
if (c.m_id == AttributeHeader::ROWID)
|
||||
{
|
||||
rowid_val.m_page_no = data[0];
|
||||
rowid_val.m_page_idx = data[1];
|
||||
data += 2;
|
||||
rowid = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c.m_id == AttributeHeader::ROW_GCI)
|
||||
{
|
||||
memcpy(&gci_val, data, 8);
|
||||
data += 2;
|
||||
gci = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! (c.m_flags & (Column::COL_VAR | Column::COL_NULL)))
|
||||
{
|
||||
ndbrequire(data < dataStart + len);
|
||||
|
||||
@ -965,11 +980,8 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
memcpy(attrData, data, 4*c.m_size);
|
||||
attrData += c.m_size;
|
||||
data += c.m_size;
|
||||
//if (file_ptr.p->m_table_id >= 2) ndbout << "1: " << c.m_id << " " << c.m_size << " col=" << column_no << endl;
|
||||
}
|
||||
|
||||
column_no++;
|
||||
|
||||
if(c.m_flags & Column::COL_DISK)
|
||||
disk= true;
|
||||
}
|
||||
@ -985,10 +997,9 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
_align[1] = *it.data;
|
||||
|
||||
Uint32 sz32 = (sz + 3) >> 2;
|
||||
|
||||
ndbassert(c.m_flags & (Column::COL_VAR | Column::COL_NULL));
|
||||
if(c.m_flags & Column::COL_KEY)
|
||||
{
|
||||
assert(! c.m_nulloffset && c.m_flags & Column::COL_VAR);
|
||||
memcpy(keyData, data, 4 * sz32);
|
||||
keyData += sz32;
|
||||
}
|
||||
@ -998,13 +1009,12 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
|
||||
attrData += sz32;
|
||||
data += sz32;
|
||||
//if (file_ptr.p->m_table_id >= 2) ndbout << "2: " << c.m_id << " " << sz << endl;
|
||||
}
|
||||
|
||||
ndbrequire(data == dataStart + len - 1);
|
||||
|
||||
ndbrequire(disk == false); // Not supported...
|
||||
|
||||
ndbrequire(rowid == true);
|
||||
Uint32 keyLen = keyData - key_start;
|
||||
Uint32 attrLen = attrData - attr_start;
|
||||
LqhKeyReq * req = (LqhKeyReq *)signal->getDataPtrSend();
|
||||
@ -1029,7 +1039,6 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
tmp= 0;
|
||||
LqhKeyReq::setKeyLen(tmp, keyLen);
|
||||
LqhKeyReq::setLastReplicaNo(tmp, 0);
|
||||
LqhKeyReq::setLockType(tmp, ZINSERT);
|
||||
/* ---------------------------------------------------------------------- */
|
||||
// Indicate Application Reference is present in bit 15
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -1040,7 +1049,8 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
LqhKeyReq::setSameClientAndTcFlag(tmp, 0);
|
||||
LqhKeyReq::setAIInLqhKeyReq(tmp, 0);
|
||||
LqhKeyReq::setNoDiskFlag(tmp, disk ? 0 : 1);
|
||||
//LqhKeyReq::setExecuteDirectFlag(tmp, 1);
|
||||
LqhKeyReq::setRowidFlag(tmp, 1);
|
||||
LqhKeyReq::setGCIFlag(tmp, gci);
|
||||
req->clientConnectPtr = file_ptr.i;
|
||||
req->hashValue = hashValue;
|
||||
req->requestInfo = tmp;
|
||||
@ -1053,10 +1063,15 @@ Restore::parse_record(Signal* signal, FilePtr file_ptr,
|
||||
req->transId2 = 0;
|
||||
req->scanInfo = 0;
|
||||
memcpy(req->variableData, key_start, 16);
|
||||
|
||||
Uint32 pos = keyLen > 4 ? 4 : keyLen;
|
||||
req->variableData[pos++] = rowid_val.m_page_no;
|
||||
req->variableData[pos++] = rowid_val.m_page_idx;
|
||||
if (gci)
|
||||
req->variableData[pos++] = (Uint32)gci_val;
|
||||
file_ptr.p->m_outstanding_operations++;
|
||||
EXECUTE_DIRECT(DBLQH, GSN_LQHKEYREQ, signal, 11+(keyLen > 4 ? 4 : keyLen));
|
||||
|
||||
EXECUTE_DIRECT(DBLQH, GSN_LQHKEYREQ, signal,
|
||||
LqhKeyReq::FixedSignalLength+pos);
|
||||
|
||||
if(keyLen > 4)
|
||||
{
|
||||
c_lqh->receive_keyinfo(signal,
|
||||
@ -1105,10 +1120,13 @@ Restore::reorder_key(const KeyDescriptor* desc,
|
||||
memcpy(dst, var, 4 * sz);
|
||||
var += sz;
|
||||
break;
|
||||
default:
|
||||
ndbrequire(false);
|
||||
sz = 0;
|
||||
}
|
||||
dst += sz;
|
||||
}
|
||||
assert((dst - Tmp) == len);
|
||||
ndbassert((dst - Tmp) == len);
|
||||
memcpy(data, Tmp, 4*len);
|
||||
}
|
||||
|
||||
@ -1201,9 +1219,9 @@ operator << (NdbOut& ndbout, const Restore::Column& col)
|
||||
{
|
||||
ndbout << "[ Col: id: " << col.m_id
|
||||
<< " size: " << col.m_size
|
||||
<< " nulloffset: " << col.m_nulloffset
|
||||
<< " key: " << (Uint32)(col.m_flags & Restore::Column::COL_KEY)
|
||||
<< " variable: " << (Uint32)(col.m_flags & Restore::Column::COL_VAR)
|
||||
<< " null: " << (Uint32)(col.m_flags & Restore::Column::COL_NULL)
|
||||
<< " disk: " << (Uint32)(col.m_flags & Restore::Column::COL_DISK)
|
||||
<< "]";
|
||||
|
||||
|
@ -60,14 +60,15 @@ public:
|
||||
{
|
||||
Uint16 m_id;
|
||||
Uint16 m_size;
|
||||
Uint16 m_nulloffset; // 0 = not nullable
|
||||
Uint16 m_unused;
|
||||
Uint16 m_flags;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
COL_KEY = 0x1,
|
||||
COL_VAR = 0x2,
|
||||
COL_DISK = 0x4
|
||||
COL_DISK = 0x4,
|
||||
COL_NULL = 0x8
|
||||
};
|
||||
};
|
||||
private:
|
||||
@ -98,7 +99,6 @@ private:
|
||||
Uint32 m_table_version;
|
||||
Uint32 m_fragment_id;
|
||||
List::Head m_columns;
|
||||
Uint32 m_null_bitmask_size;
|
||||
|
||||
Uint32 m_current_page_ptr_i;
|
||||
Uint32 m_current_page_pos;
|
||||
|
@ -14,6 +14,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_config.h>
|
||||
#include "Suma.hpp"
|
||||
|
||||
#include <ndb_version.h>
|
||||
@ -3149,7 +3150,8 @@ Suma::execSUB_GCP_COMPLETE_REP(Signal* signal)
|
||||
Page_pos pos= bucket->m_buffer_head;
|
||||
ndbrequire(pos.m_max_gci < gci);
|
||||
|
||||
Buffer_page* page= (Buffer_page*)(m_tup->cpage+pos.m_page_id);
|
||||
Buffer_page* page= (Buffer_page*)
|
||||
m_tup->c_page_pool.getPtr(pos.m_page_id);
|
||||
ndbout_c("takeover %d", pos.m_page_id);
|
||||
page->m_max_gci = pos.m_max_gci;
|
||||
page->m_words_used = pos.m_page_pos;
|
||||
@ -4091,7 +4093,7 @@ Suma::get_buffer_ptr(Signal* signal, Uint32 buck, Uint32 gci, Uint32 sz)
|
||||
Bucket* bucket= c_buckets+buck;
|
||||
Page_pos pos= bucket->m_buffer_head;
|
||||
|
||||
Buffer_page* page= (Buffer_page*)(m_tup->cpage+pos.m_page_id);
|
||||
Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(pos.m_page_id);
|
||||
Uint32* ptr= page->m_data + pos.m_page_pos;
|
||||
|
||||
const bool same_gci = (gci == pos.m_last_gci) && (!ERROR_INSERTED(13022));
|
||||
@ -4150,7 +4152,7 @@ loop:
|
||||
pos.m_page_pos = sz;
|
||||
pos.m_last_gci = gci;
|
||||
|
||||
page= (Buffer_page*)(m_tup->cpage+pos.m_page_id);
|
||||
page= (Buffer_page*)m_tup->c_page_pool.getPtr(pos.m_page_id);
|
||||
page->m_next_page= RNIL;
|
||||
ptr= page->m_data;
|
||||
goto loop; //
|
||||
@ -4181,7 +4183,7 @@ Suma::out_of_buffer_release(Signal* signal, Uint32 buck)
|
||||
|
||||
if(tail != RNIL)
|
||||
{
|
||||
Buffer_page* page= (Buffer_page*)(m_tup->cpage+tail);
|
||||
Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
|
||||
bucket->m_buffer_tail = page->m_next_page;
|
||||
free_page(tail, page);
|
||||
signal->theData[0] = SumaContinueB::OUT_OF_BUFFER_RELEASE;
|
||||
@ -4225,8 +4227,8 @@ loop:
|
||||
Uint32 ref= m_first_free_page;
|
||||
if(likely(ref != RNIL))
|
||||
{
|
||||
m_first_free_page = ((Buffer_page*)m_tup->cpage+ref)->m_next_page;
|
||||
Uint32 chunk = ((Buffer_page*)m_tup->cpage+ref)->m_page_chunk_ptr_i;
|
||||
m_first_free_page = ((Buffer_page*)m_tup->c_page_pool.getPtr(ref))->m_next_page;
|
||||
Uint32 chunk = ((Buffer_page*)m_tup->c_page_pool.getPtr(ref))->m_page_chunk_ptr_i;
|
||||
c_page_chunk_pool.getPtr(ptr, chunk);
|
||||
ndbassert(ptr.p->m_free);
|
||||
ptr.p->m_free--;
|
||||
@ -4249,7 +4251,7 @@ loop:
|
||||
Buffer_page* page;
|
||||
for(Uint32 i = 0; i<count; i++)
|
||||
{
|
||||
page = (Buffer_page*)(m_tup->cpage+ref);
|
||||
page = (Buffer_page*)m_tup->c_page_pool.getPtr(ref);
|
||||
page->m_page_state= SUMA_SEQUENCE;
|
||||
page->m_page_chunk_ptr_i = ptr.i;
|
||||
page->m_next_page = ++ref;
|
||||
@ -4313,7 +4315,7 @@ Suma::release_gci(Signal* signal, Uint32 buck, Uint32 gci)
|
||||
else
|
||||
{
|
||||
jam();
|
||||
Buffer_page* page= (Buffer_page*)(m_tup->cpage+tail);
|
||||
Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
|
||||
Uint32 max_gci = page->m_max_gci;
|
||||
Uint32 next_page = page->m_next_page;
|
||||
|
||||
@ -4406,7 +4408,7 @@ Suma::resend_bucket(Signal* signal, Uint32 buck, Uint32 min_gci,
|
||||
Bucket* bucket= c_buckets+buck;
|
||||
Uint32 tail= bucket->m_buffer_tail;
|
||||
|
||||
Buffer_page* page= (Buffer_page*)(m_tup->cpage+tail);
|
||||
Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
|
||||
Uint32 max_gci = page->m_max_gci;
|
||||
Uint32 next_page = page->m_next_page;
|
||||
Uint32 *ptr = page->m_data + pos;
|
||||
|
@ -390,7 +390,6 @@ Tsman::execDROP_FILEGROUP_REQ(Signal* signal){
|
||||
|
||||
if (errorCode)
|
||||
{
|
||||
ndbassert(false);
|
||||
DropFilegroupImplRef* ref =
|
||||
(DropFilegroupImplRef*)signal->getDataPtrSend();
|
||||
ref->senderRef = reference();
|
||||
@ -1084,7 +1083,9 @@ Tsman::load_extent_page_callback(Signal* signal,
|
||||
|
||||
Ptr<Tablespace> ts_ptr;
|
||||
m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i);
|
||||
if (!getNodeState().getSystemRestartInProgress())
|
||||
if (getNodeState().startLevel >= NodeState::SL_STARTED ||
|
||||
(getNodeState().getNodeRestartInProgress() &&
|
||||
getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
|
||||
{
|
||||
LocalDLList<Datafile> free(m_file_pool, ts_ptr.p->m_free_files);
|
||||
LocalDLList<Datafile> meta(m_file_pool, ts_ptr.p->m_meta_files);
|
||||
@ -1614,6 +1615,57 @@ Tsman::update_page_free_bits(Signal* signal,
|
||||
return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
|
||||
}
|
||||
|
||||
int
|
||||
Tsman::get_page_free_bits(Signal* signal, Local_key *key, unsigned* bits)
|
||||
{
|
||||
jamEntry();
|
||||
|
||||
/**
|
||||
* XXX make into subroutine
|
||||
*/
|
||||
Ptr<Datafile> file_ptr;
|
||||
Datafile file_key;
|
||||
file_key.m_file_no = key->m_file_no;
|
||||
ndbrequire(m_file_hash.find(file_ptr, file_key));
|
||||
|
||||
Uint32 size = file_ptr.p->m_extent_size;
|
||||
Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
|
||||
Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
|
||||
Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
|
||||
Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
|
||||
|
||||
Uint32 extent = (key->m_page_no - data_off) / size + per_page;
|
||||
Uint32 page_no = extent / per_page;
|
||||
Uint32 extent_no = extent % per_page;
|
||||
|
||||
Page_cache_client::Request preq;
|
||||
preq.m_page.m_page_no = page_no;
|
||||
preq.m_page.m_file_no = key->m_file_no;
|
||||
|
||||
/**
|
||||
* Handling of unmapped extent header pages is not implemented
|
||||
*/
|
||||
int flags = 0;
|
||||
int real_page_id;
|
||||
if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
|
||||
{
|
||||
GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
|
||||
|
||||
File_formats::Datafile::Extent_page* page =
|
||||
(File_formats::Datafile::Extent_page*)ptr_p;
|
||||
File_formats::Datafile::Extent_header* header =
|
||||
page->get_header(extent_no, size);
|
||||
|
||||
ndbrequire(header->m_table != RNIL);
|
||||
|
||||
Uint32 page_no_in_extent = (key->m_page_no - data_off) % size;
|
||||
*bits = header->get_free_bits(page_no_in_extent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
|
||||
}
|
||||
|
||||
int
|
||||
Tsman::unmap_page(Signal* signal, Local_key *key)
|
||||
{
|
||||
@ -2055,17 +2107,23 @@ void Tsman::execGET_TABINFOREQ(Signal* signal)
|
||||
if(reqType == GetTabInfoReq::RequestByName){
|
||||
jam();
|
||||
releaseSections(signal);
|
||||
|
||||
sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
|
||||
|
||||
sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
|
||||
return;
|
||||
}
|
||||
|
||||
DLHashTable<Datafile>::Iterator iter;
|
||||
ndbrequire(m_file_hash.first(iter));
|
||||
|
||||
while(iter.curr.p->m_file_id != tableId && m_file_hash.next(iter))
|
||||
;
|
||||
ndbrequire(iter.curr.p->m_file_id == tableId);
|
||||
|
||||
|
||||
if(iter.curr.p->m_file_id != tableId)
|
||||
{
|
||||
sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
|
||||
return;
|
||||
}
|
||||
|
||||
const Ptr<Datafile> &file_ptr= iter.curr;
|
||||
|
||||
jam();
|
||||
@ -2073,9 +2131,9 @@ void Tsman::execGET_TABINFOREQ(Signal* signal)
|
||||
Uint32 total_free_extents = file_ptr.p->m_online.m_data_pages;
|
||||
total_free_extents /= file_ptr.p->m_extent_size;
|
||||
total_free_extents -= file_ptr.p->m_online.m_used_extent_cnt;
|
||||
|
||||
|
||||
GetTabInfoConf *conf = (GetTabInfoConf *)&signal->theData[0];
|
||||
|
||||
|
||||
conf->senderData= senderData;
|
||||
conf->tableId= tableId;
|
||||
conf->freeExtents= total_free_extents;
|
||||
|
@ -196,6 +196,7 @@ private:
|
||||
void create_file_ref(Signal*, Ptr<Tablespace>, Ptr<Datafile>,
|
||||
Uint32,Uint32,Uint32);
|
||||
int update_page_free_bits(Signal*, Local_key*, unsigned bits, Uint64 lsn);
|
||||
int get_page_free_bits(Signal*, Local_key*, unsigned* bits);
|
||||
int unmap_page(Signal*, Local_key*);
|
||||
int restart_undo_page_free_bits(Signal*, Local_key*, unsigned, Uint64);
|
||||
|
||||
@ -266,6 +267,11 @@ public:
|
||||
*/
|
||||
int update_page_free_bits(Local_key*, unsigned bits, Uint64 lsn);
|
||||
|
||||
/**
|
||||
* Get page free bits
|
||||
*/
|
||||
int get_page_free_bits(Local_key*, unsigned* bits);
|
||||
|
||||
/**
|
||||
* Update unlogged page free bit
|
||||
*/
|
||||
@ -352,6 +358,13 @@ Tablespace_client::update_page_free_bits(Local_key *key,
|
||||
return m_tsman->update_page_free_bits(m_signal, key, bits, lsn);
|
||||
}
|
||||
|
||||
inline
|
||||
int
|
||||
Tablespace_client::get_page_free_bits(Local_key *key, unsigned* bits)
|
||||
{
|
||||
return m_tsman->get_page_free_bits(m_signal, key, bits);
|
||||
}
|
||||
|
||||
inline
|
||||
int
|
||||
Tablespace_client::unmap_page(Local_key *key)
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
*
|
||||
* Note, can currently only be called once
|
||||
*/
|
||||
bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true);
|
||||
bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true, bool guard = true);
|
||||
bool set(T*, Uint32 cnt, bool align = false);
|
||||
|
||||
inline Uint32 getNoOfFree() const {
|
||||
return noOfFree;
|
||||
@ -202,7 +203,8 @@ ArrayPool<T>::~ArrayPool(){
|
||||
theArray = 0;
|
||||
alloc_ptr = 0;
|
||||
#ifdef ARRAY_GUARD
|
||||
delete []theAllocatedBitmask;
|
||||
if (theAllocatedBitmask)
|
||||
delete []theAllocatedBitmask;
|
||||
theAllocatedBitmask = 0;
|
||||
#endif
|
||||
}
|
||||
@ -216,7 +218,8 @@ ArrayPool<T>::~ArrayPool(){
|
||||
template <class T>
|
||||
inline
|
||||
bool
|
||||
ArrayPool<T>::setSize(Uint32 noOfElements, bool align, bool exit_on_error){
|
||||
ArrayPool<T>::setSize(Uint32 noOfElements,
|
||||
bool align, bool exit_on_error, bool guard){
|
||||
if(size == 0){
|
||||
if(noOfElements == 0)
|
||||
return true;
|
||||
@ -257,9 +260,12 @@ ArrayPool<T>::setSize(Uint32 noOfElements, bool align, bool exit_on_error){
|
||||
firstFree = 0;
|
||||
|
||||
#ifdef ARRAY_GUARD
|
||||
bitmaskSz = (noOfElements + 31) >> 5;
|
||||
theAllocatedBitmask = new Uint32[bitmaskSz];
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask);
|
||||
if (guard)
|
||||
{
|
||||
bitmaskSz = (noOfElements + 31) >> 5;
|
||||
theAllocatedBitmask = new Uint32[bitmaskSz];
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@ -270,21 +276,56 @@ ArrayPool<T>::setSize(Uint32 noOfElements, bool align, bool exit_on_error){
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::setSize called twice", __FILE__, __LINE__);
|
||||
return false; // not reached
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
bool
|
||||
ArrayPool<T>::set(T* ptr, Uint32 cnt, bool align){
|
||||
if (size == 0)
|
||||
{
|
||||
alloc_ptr = ptr;
|
||||
if(align)
|
||||
{
|
||||
UintPtr p = (UintPtr)alloc_ptr;
|
||||
UintPtr mod = p % sizeof(T);
|
||||
if (mod)
|
||||
{
|
||||
p += sizeof(T) - mod;
|
||||
cnt --;
|
||||
}
|
||||
theArray = (T *)p;
|
||||
}
|
||||
else
|
||||
{
|
||||
theArray = (T *)alloc_ptr;
|
||||
}
|
||||
|
||||
size = cnt;
|
||||
noOfFree = 0;
|
||||
return true;
|
||||
}
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::set called twice",
|
||||
__FILE__, __LINE__);
|
||||
return false; // not reached
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(Ptr<T> & ptr){
|
||||
Uint32 i = ptr.i;
|
||||
if(i < size){
|
||||
if(likely (i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
@ -296,15 +337,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(ConstPtr<T> & ptr) const {
|
||||
Uint32 i = ptr.i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
@ -316,15 +360,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i){
|
||||
ptr.i = i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
@ -336,15 +383,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i) const {
|
||||
ptr.i = i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
@ -355,18 +405,20 @@ template <class T>
|
||||
inline
|
||||
T *
|
||||
ArrayPool<T>::getPtr(Uint32 i){
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
#else
|
||||
return &theArray[i];
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return &theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
@ -377,18 +429,20 @@ template <class T>
|
||||
inline
|
||||
const T *
|
||||
ArrayPool<T>::getConstPtr(Uint32 i) const {
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
#else
|
||||
return &theArray[i];
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return &theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
@ -400,15 +454,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(Ptr<T> & ptr, bool CrashOnBoundaryError){
|
||||
Uint32 i = ptr.i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ptr.i = RNIL;
|
||||
@ -420,15 +477,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(ConstPtr<T> & ptr, bool CrashOnBoundaryError) const {
|
||||
Uint32 i = ptr.i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ptr.i = RNIL;
|
||||
@ -440,15 +500,18 @@ inline
|
||||
void
|
||||
ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i, bool CrashOnBoundaryError){
|
||||
ptr.i = i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ptr.i = RNIL;
|
||||
@ -461,15 +524,18 @@ void
|
||||
ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i,
|
||||
bool CrashOnBoundaryError) const {
|
||||
ptr.i = i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
ptr.p = &theArray[i];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return;
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ptr.i = RNIL;
|
||||
@ -480,18 +546,20 @@ template <class T>
|
||||
inline
|
||||
T *
|
||||
ArrayPool<T>::getPtr(Uint32 i, bool CrashOnBoundaryError){
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
#else
|
||||
return &theArray[i];
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return &theArray[i];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -501,18 +569,20 @@ template <class T>
|
||||
inline
|
||||
const T *
|
||||
ArrayPool<T>::getConstPtr(Uint32 i, bool CrashOnBoundaryError) const {
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getConstPtr", __FILE__,__LINE__);
|
||||
return 0;
|
||||
#else
|
||||
return &theArray[i];
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
|
||||
return &theArray[i];
|
||||
/**
|
||||
* Getting a non-seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::getConstPtr", __FILE__,__LINE__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return &theArray[i];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -534,21 +604,23 @@ ArrayPool<T>::seize(Ptr<T> & ptr){
|
||||
ptr.i = ff;
|
||||
ptr.p = &theArray[ff];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
|
||||
noOfFree--;
|
||||
return true;
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
|
||||
return false;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
|
||||
noOfFree--;
|
||||
return true;
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
noOfFree--;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
ptr.i = RNIL;
|
||||
ptr.p = NULL;
|
||||
@ -575,21 +647,23 @@ ArrayPool<T>::seizeId(Ptr<T> & ptr, Uint32 i){
|
||||
ptr.i = ff;
|
||||
ptr.p = &theArray[ff];
|
||||
#ifdef ARRAY_GUARD
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
|
||||
noOfFree--;
|
||||
return true;
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seizeId", __FILE__, __LINE__);
|
||||
return false;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
|
||||
noOfFree--;
|
||||
return true;
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seizeId", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
noOfFree--;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
ptr.i = RNIL;
|
||||
ptr.p = NULL;
|
||||
@ -636,15 +710,18 @@ ArrayPool<T>::seizeN(Uint32 n){
|
||||
|
||||
noOfFree -= n;
|
||||
#ifdef ARRAY_GUARD
|
||||
for(Uint32 j = base; j<curr; j++){
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, j)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, j);
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
|
||||
return RNIL;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
for(Uint32 j = base; j<curr; j++){
|
||||
if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, j)){
|
||||
BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, j);
|
||||
} else {
|
||||
/**
|
||||
* Seizing an already seized element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
|
||||
return RNIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -669,14 +746,17 @@ ArrayPool<T>::releaseN(Uint32 base, Uint32 n){
|
||||
const Uint32 end = base + n;
|
||||
for(Uint32 i = base; i<end; i++){
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
} else {
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
return;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
} else {
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
theArray[i].nextPool = i + 1;
|
||||
@ -697,19 +777,22 @@ ArrayPool<T>::releaseList(Uint32 n, Uint32 first, Uint32 last){
|
||||
noOfFree += n;
|
||||
|
||||
#ifdef ARRAY_GUARD
|
||||
Uint32 tmp = first;
|
||||
for(Uint32 i = 0; i<n; i++){
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, tmp)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, tmp);
|
||||
} else {
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::releaseList",
|
||||
__FILE__, __LINE__);
|
||||
return;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
Uint32 tmp = first;
|
||||
for(Uint32 i = 0; i<n; i++){
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, tmp)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, tmp);
|
||||
} else {
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::releaseList",
|
||||
__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
tmp = theArray[tmp].nextPool;
|
||||
}
|
||||
tmp = theArray[tmp].nextPool;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
@ -725,21 +808,24 @@ inline
|
||||
void
|
||||
ArrayPool<T>::release(Uint32 _i){
|
||||
const Uint32 i = _i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
Uint32 ff = firstFree;
|
||||
theArray[i].nextPool = ff;
|
||||
firstFree = i;
|
||||
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
noOfFree++;
|
||||
return;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
noOfFree++;
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
}
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
#endif
|
||||
noOfFree++;
|
||||
return;
|
||||
@ -755,22 +841,25 @@ inline
|
||||
void
|
||||
ArrayPool<T>::release(Ptr<T> & ptr){
|
||||
Uint32 i = ptr.i;
|
||||
if(i < size){
|
||||
if(likely(i < size)){
|
||||
Uint32 ff = firstFree;
|
||||
theArray[i].nextPool = ff;
|
||||
firstFree = i;
|
||||
|
||||
#ifdef ARRAY_GUARD
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
//assert(noOfFree() == noOfFree2());
|
||||
noOfFree++;
|
||||
return;
|
||||
if (theAllocatedBitmask)
|
||||
{
|
||||
if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
|
||||
BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
|
||||
//assert(noOfFree() == noOfFree2());
|
||||
noOfFree++;
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
}
|
||||
/**
|
||||
* Relesing a already released element
|
||||
*/
|
||||
ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
|
||||
#endif
|
||||
noOfFree++;
|
||||
return;
|
||||
@ -798,7 +887,7 @@ inline
|
||||
void
|
||||
UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr){
|
||||
Uint32 i = ptr.i;
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
ptr.p = &this->theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
|
||||
@ -811,7 +900,7 @@ inline
|
||||
void
|
||||
UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr) const{
|
||||
Uint32 i = ptr.i;
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
ptr.p = &this->theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
|
||||
@ -823,7 +912,7 @@ template <class T>
|
||||
inline
|
||||
T *
|
||||
UnsafeArrayPool<T>::getPtrForce(Uint32 i){
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
return &this->theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
|
||||
@ -836,7 +925,7 @@ template <class T>
|
||||
inline
|
||||
const T *
|
||||
UnsafeArrayPool<T>::getConstPtrForce(Uint32 i) const {
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
return &this->theArray[i];
|
||||
} else {
|
||||
ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
|
||||
@ -850,7 +939,7 @@ inline
|
||||
void
|
||||
UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr, Uint32 i){
|
||||
ptr.i = i;
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
ptr.p = &this->theArray[i];
|
||||
return ;
|
||||
} else {
|
||||
@ -864,7 +953,7 @@ inline
|
||||
void
|
||||
UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr, Uint32 i) const{
|
||||
ptr.i = i;
|
||||
if(i < this->size){
|
||||
if(likely(i < this->size)){
|
||||
ptr.p = &this->theArray[i];
|
||||
return ;
|
||||
} else {
|
||||
|
@ -91,6 +91,12 @@ public:
|
||||
* @NOTE MUST be seized from correct pool
|
||||
*/
|
||||
void add(Ptr<T> &);
|
||||
|
||||
/**
|
||||
* Add a list to list
|
||||
* @NOTE all elements _must_ be correctly initilized correctly wrt next/prev
|
||||
*/
|
||||
void add(Uint32 first, Ptr<T> & last);
|
||||
|
||||
/**
|
||||
* Remove object from list
|
||||
@ -98,6 +104,13 @@ public:
|
||||
* @NOTE Does not return it to pool
|
||||
*/
|
||||
void remove(Ptr<T> &);
|
||||
|
||||
/**
|
||||
* Remove object from list
|
||||
*
|
||||
* @NOTE Does not return it to pool
|
||||
*/
|
||||
void remove(T*);
|
||||
|
||||
/**
|
||||
* Update i & p value according to <b>i</b>
|
||||
@ -253,22 +266,45 @@ DLList<T,U>::add(Ptr<T> & p){
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
void
|
||||
DLList<T,U>::add(Uint32 first, Ptr<T> & lastPtr)
|
||||
{
|
||||
Uint32 ff = head.firstItem;
|
||||
|
||||
head.firstItem = first;
|
||||
lastPtr.p->U::nextList = ff;
|
||||
|
||||
if(ff != RNIL){
|
||||
T * t2 = thePool.getPtr(ff);
|
||||
t2->U::prevList = lastPtr.i;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
void
|
||||
DLList<T,U>::remove(Ptr<T> & p){
|
||||
T * t = p.p;
|
||||
remove(p.p);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
void
|
||||
DLList<T,U>::remove(T * p){
|
||||
T * t = p;
|
||||
Uint32 ni = t->U::nextList;
|
||||
Uint32 pi = t->U::prevList;
|
||||
|
||||
if(ni != RNIL){
|
||||
T * t = thePool.getPtr(ni);
|
||||
t->U::prevList = pi;
|
||||
T * tn = thePool.getPtr(ni);
|
||||
tn->U::prevList = pi;
|
||||
}
|
||||
|
||||
if(pi != RNIL){
|
||||
T * t = thePool.getPtr(pi);
|
||||
t->U::nextList = ni;
|
||||
T * tp = thePool.getPtr(pi);
|
||||
tp->U::nextList = ni;
|
||||
} else {
|
||||
head.firstItem = ni;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ libkernel_a_SOURCES = \
|
||||
Mutex.cpp SafeCounter.cpp \
|
||||
Rope.cpp \
|
||||
SuperPool.cpp \
|
||||
ndbd_malloc.cpp
|
||||
ndbd_malloc.cpp ndbd_malloc_impl.cpp
|
||||
|
||||
INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
|
||||
|
||||
@ -43,3 +43,12 @@ libkernel.dsp: Makefile \
|
||||
@$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
|
||||
@$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
|
||||
@$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
|
||||
|
||||
EXTRA_PROGRAMS = ndbd_malloc_impl_test
|
||||
ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST
|
||||
ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp
|
||||
ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
|
||||
$(top_builddir)/storage/ndb/src/libndbclient.la \
|
||||
$(top_builddir)/mysys/libmysys.a \
|
||||
$(top_builddir)/dbug/libdbug.a \
|
||||
$(top_builddir)/strings/libmystrings.a
|
||||
|
@ -120,6 +120,19 @@ public:
|
||||
head.firstItem = p.i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list to list
|
||||
* @NOTE all elements _must_ be correctly initilized correctly wrt next/prev
|
||||
*/
|
||||
void add(Uint32 first, Ptr<T> & last);
|
||||
|
||||
/**
|
||||
* Remove object from list
|
||||
*
|
||||
* @NOTE Does not return it to pool
|
||||
*/
|
||||
bool remove_front(Ptr<T> &);
|
||||
|
||||
Uint32 noOfElements() const {
|
||||
Uint32 c = 0;
|
||||
Uint32 i = head.firstItem;
|
||||
@ -246,6 +259,28 @@ SLList<T,U>::remove(){
|
||||
head.firstItem = RNIL;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
bool
|
||||
SLList<T,U>::remove_front(Ptr<T> & p){
|
||||
p.i = head.firstItem;
|
||||
if (p.i != RNIL)
|
||||
{
|
||||
p.p = thePool.getPtr(p.i);
|
||||
head.firstItem = p.p->U::nextList;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
void
|
||||
SLList<T,U>::add(Uint32 first, Ptr<T> & last){
|
||||
last.p->U::nextList = head.firstItem;
|
||||
head.firstItem = first;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
void
|
||||
|
34
storage/ndb/src/kernel/vm/mem.txt
Normal file
34
storage/ndb/src/kernel/vm/mem.txt
Normal file
@ -0,0 +1,34 @@
|
||||
Structure
|
||||
|
||||
Ndbd_mem_allocator
|
||||
Handles allocation on 32k blocks
|
||||
Provides Buddy allocation of max 8G objects
|
||||
|
||||
SuperPool 8k (chunk size 64k)
|
||||
GroupPool - Metadata
|
||||
DICT::RopePool
|
||||
|
||||
GroupPool - Disk operations
|
||||
TUP::Page request
|
||||
PGMAN::Page request
|
||||
LGMAN::Log waiter
|
||||
LGMAN::Log syncer
|
||||
|
||||
GroupPool - Disk space
|
||||
Tsman::Datafile
|
||||
Tsman::Tablespace
|
||||
Lgman::Undofile
|
||||
Lgman::Logfilegroup
|
||||
TUP::Extent alloc info
|
||||
|
||||
SuperPool 32k
|
||||
TUP Undo buffer
|
||||
SUMA GCI buffer
|
||||
Pgman::PageEntry
|
||||
|
||||
Direct Ndbd_mem_allocator
|
||||
Pgman::GlobalPage -
|
||||
TUP PageMan
|
||||
Restore
|
||||
Backup
|
||||
Lgman::Logbuffer
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user