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:
unknown 2006-01-11 11:35:25 +01:00
parent 2c0f53d69c
commit 641ce5e97e
138 changed files with 9336 additions and 3311 deletions

View File

@ -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 \

View 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;

View File

@ -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

View 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;

View File

@ -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 \

View File

@ -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
};

View File

@ -57,6 +57,7 @@ handlerton blackhole_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_CAN_RECREATE
};

View File

@ -394,6 +394,7 @@ handlerton federated_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_ALTER_NOT_SUPPORTED
};

View File

@ -54,6 +54,7 @@ handlerton heap_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_CAN_RECREATE
};

View File

@ -86,6 +86,7 @@ handlerton myisam_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_CAN_RECREATE
};

View File

@ -64,6 +64,7 @@ handlerton myisammrg_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_CAN_RECREATE
};

View File

@ -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 */

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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)},

View File

@ -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
};

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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
View 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);
}

View File

@ -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 {}

View File

@ -88,6 +88,7 @@ handlerton tina_hton= {
NULL, /* Start Consistent Snapshot */
NULL, /* Flush logs */
NULL, /* Show status */
NULL, /* Alter Tablespace */
HTON_CAN_RECREATE
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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
};
};

View File

@ -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;

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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;

View File

@ -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:

View File

@ -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)

View File

@ -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){

View File

@ -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)
};

View File

@ -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;
}

View File

@ -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: ");

View File

@ -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" }

View File

@ -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
}

View File

@ -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

View 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

View File

@ -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

View File

@ -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);

View File

@ -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
};
/**

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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
};

View File

@ -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

View File

@ -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
/* ---------------------------------------------------------------------- */

View File

@ -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&copy);
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&

View File

@ -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, &regOperPtr->m_tuple_location, tabPtr.p);
Uint32 *ptr = 0;
if (!regOperPtr->m_tuple_location.isNull())
{
PagePtr tmp;
ptr= get_ptr(&tmp, &regOperPtr->m_tuple_location, tabPtr.p);
}
removeActiveOpList(regOperPtr, (Tuple_header*)ptr);
initOpConnection(regOperPtr);
send_TUPKEYREF(signal, regOperPtr);

View File

@ -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, &regOperPtr.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);
}

View File

@ -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]

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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. */
/* ---------------------------------------------------------------- */

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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>;

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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);
}

View File

@ -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
{

View File

@ -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){

View File

@ -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
}
}

View File

@ -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
};
/**

View File

@ -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)
<< "]";

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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 {

View File

@ -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;
}

View File

@ -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

View File

@ -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

View 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