Merge lp:~paul-mccullagh/maria/pbxt-1.0.11-7 into lp:maria/5.3

Proposed by Paul McCullagh
Status: Rejected
Rejected by: Sergei Golubchik
Proposed branch: lp:~paul-mccullagh/maria/pbxt-1.0.11-7
Merge into: lp:maria/5.3
Diff against target: 1570 lines (+652/-100)
21 files modified
mysql-test/suite/pbxt/r/negation_elimination.result (+1/-1)
mysql-test/suite/pbxt/r/select.result (+19/-19)
storage/pbxt/ChangeLog (+43/-1)
storage/pbxt/src/cache_xt.cc (+20/-1)
storage/pbxt/src/cache_xt.h (+8/-0)
storage/pbxt/src/database_xt.h (+1/-0)
storage/pbxt/src/datadic_xt.cc (+2/-7)
storage/pbxt/src/datalog_xt.cc (+4/-4)
storage/pbxt/src/discover_xt.cc (+14/-2)
storage/pbxt/src/ha_pbxt.cc (+99/-6)
storage/pbxt/src/index_xt.cc (+94/-32)
storage/pbxt/src/index_xt.h (+1/-1)
storage/pbxt/src/myxt_xt.cc (+6/-2)
storage/pbxt/src/myxt_xt.h (+6/-6)
storage/pbxt/src/restart_xt.cc (+58/-0)
storage/pbxt/src/strutil_xt.cc (+1/-1)
storage/pbxt/src/table_xt.cc (+239/-12)
storage/pbxt/src/table_xt.h (+2/-0)
storage/pbxt/src/thread_xt.cc (+7/-2)
storage/pbxt/src/xaction_xt.cc (+3/-1)
storage/pbxt/src/xt_defs.h (+24/-2)
To merge this branch: bzr merge lp:~paul-mccullagh/maria/pbxt-1.0.11-7
Reviewer Review Type Date Requested Status
Maria-captains Pending
Review via email: mp+35794@code.launchpad.net

Description of the change

This is the latest version of the PBXT Pre-GA, version 1.0.11-7. Details of changes are in the release notes (storage/pbxt/ChangeLog).

I have updated the 2 test results as required. In this version, PBXT once again estimates the number of rows in the table correctly. This changes the output of some EXPLAIN commands.

To post a comment you must log in.
Revision history for this message
Michael Widenius (monty) wrote :

Hi!

>>>>> "Paul" == Paul McCullagh <email address hidden> writes:

Paul> Paul McCullagh has proposed merging lp:~paul-mccullagh/maria/pbxt-1.0.11-7 into lp:maria.
Paul> Requested reviews:
Paul> Maria-captains (maria-captains)

Paul> This is the latest version of the PBXT Pre-GA, version 1.0.11-7. Details of changes are in the release notes (storage/pbxt/ChangeLog).

Paul> I have updated the 2 test results as required. In this version, PBXT once again estimates the number of rows in the table correctly. This changes the output of some EXPLAIN commands.

I will start the merge today. Thanks!

By the way, I don't know if you noticed but I have fixed some compiler
warnings in the pbxt code in MariaDB; Feel free to backport those that
makes sence for you :)

Regards,
Monty

Revision history for this message
Michael Widenius (monty) wrote :

Hi!

>>>>> "Paul" == Paul McCullagh <email address hidden> writes:

Paul> Paul McCullagh has proposed merging lp:~paul-mccullagh/maria/pbxt-1.0.11-7 into lp:maria.
Paul> Requested reviews:
Paul> Maria-captains (maria-captains)

Paul> This is the latest version of the PBXT Pre-GA, version 1.0.11-7. Details of changes are in the release notes (storage/pbxt/ChangeLog).

<cut>

I have now merged this into MariaDB 5.1; I changed a couple of ifdefs to
make the code work both for MariaDB 5.1 and MariaDB 5.2.

Will push shortly into 5.1. Next merge pass will take this to MariaDB
5.2 and 5.3.

Regards,
Monty

Revision history for this message
Sergei Golubchik (sergii) wrote :

done as a patch. as far as I understand.

Unmerged revisions

2820. By Paul McCullagh

Added release notes

2819. By Paul McCullagh

Updated PBXT test suite results

2818. By Paul McCullagh

Merged with 1.0 trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'mysql-test/suite/pbxt/r/negation_elimination.result'
--- mysql-test/suite/pbxt/r/negation_elimination.result 2010-06-26 10:05:41 +0000
+++ mysql-test/suite/pbxt/r/negation_elimination.result 2010-09-17 10:32:54 +0000
@@ -388,7 +388,7 @@
388test.t1 analyze status OK388test.t1 analyze status OK
389explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));389explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
390id select_type table type possible_keys key key_len ref rows filtered Extra390id select_type table type possible_keys key key_len ref rows filtered Extra
3911 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index3911 SIMPLE t1 index NULL a 5 NULL 5 100.00 Using where; Using index
392Warnings:392Warnings:
393Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`393Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`
394drop table t1;394drop table t1;
395395
=== modified file 'mysql-test/suite/pbxt/r/select.result'
--- mysql-test/suite/pbxt/r/select.result 2010-06-26 19:33:16 +0000
+++ mysql-test/suite/pbxt/r/select.result 2010-09-17 10:32:54 +0000
@@ -1384,52 +1384,52 @@
1384test.t2 analyze status OK1384test.t2 analyze status OK
1385explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;1385explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
1386id select_type table type possible_keys key key_len ref rows Extra1386id select_type table type possible_keys key key_len ref rows Extra
13871 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where13871 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
13881 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 13881 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
1389explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;1389explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
1390id select_type table type possible_keys key key_len ref rows Extra1390id select_type table type possible_keys key key_len ref rows Extra
13911 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where13911 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
13921 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 13921 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
1393explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;1393explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
1394id select_type table type possible_keys key key_len ref rows Extra1394id select_type table type possible_keys key key_len ref rows Extra
13951 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where13951 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
13961 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 13961 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
1397explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;1397explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
1398id select_type table type possible_keys key key_len ref rows Extra1398id select_type table type possible_keys key key_len ref rows Extra
13991 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where13991 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
14001 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14001 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1401explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;1401explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
1402id select_type table type possible_keys key key_len ref rows Extra1402id select_type table type possible_keys key key_len ref rows Extra
14031 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where14031 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
14041 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14041 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1405explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;1405explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
1406id select_type table type possible_keys key key_len ref rows Extra1406id select_type table type possible_keys key key_len ref rows Extra
14071 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where14071 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
14081 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14081 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1409explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;1409explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
1410id select_type table type possible_keys key key_len ref rows Extra1410id select_type table type possible_keys key key_len ref rows Extra
14111 SIMPLE t4 ALL NULL NULL NULL NULL 12 14111 SIMPLE t4 ALL NULL NULL NULL NULL 12
14121 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14121 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1413explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;1413explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
1414id select_type table type possible_keys key key_len ref rows Extra1414id select_type table type possible_keys key key_len ref rows Extra
14151 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 14151 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
14161 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14161 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1417explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;1417explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
1418id select_type table type possible_keys key key_len ref rows Extra1418id select_type table type possible_keys key key_len ref rows Extra
14191 SIMPLE t4 ALL NULL NULL NULL NULL 12 14191 SIMPLE t4 ALL NULL NULL NULL NULL 12
14201 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14201 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1421explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;1421explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
1422id select_type table type possible_keys key key_len ref rows Extra1422id select_type table type possible_keys key key_len ref rows Extra
14231 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where14231 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
14241 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14241 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1425explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;1425explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
1426id select_type table type possible_keys key key_len ref rows Extra1426id select_type table type possible_keys key key_len ref rows Extra
14271 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where14271 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
14281 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14281 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1429explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;1429explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
1430id select_type table type possible_keys key key_len ref rows Extra1430id select_type table type possible_keys key key_len ref rows Extra
14311 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where14311 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
14321 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where14321 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
1433select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;1433select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
1434companynr companynr1434companynr companynr
143537 36143537 36
@@ -1437,7 +1437,7 @@
1437explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;1437explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
1438id select_type table type possible_keys key key_len ref rows Extra1438id select_type table type possible_keys key key_len ref rows Extra
14391 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary14391 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
14401 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Using join buffer14401 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer
1441select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;1441select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
1442fld1 companynr fld3 period1442fld1 companynr fld3 period
1443038008 37 reporters 10081443038008 37 reporters 1008
@@ -1511,7 +1511,7 @@
151170 absentee vest 17788966 254128.0857 3272.5940 10709871.3069151170 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
1512explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";1512explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
1513id select_type table type possible_keys key key_len ref rows filtered Extra1513id select_type table type possible_keys key key_len ref rows filtered Extra
15141 SIMPLE t2 ALL NULL NULL NULL NULL 1200 100.00 Using where15141 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
1515Warnings:1515Warnings:
1516Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))1516Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
1517select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;1517select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
@@ -1955,7 +1955,7 @@
19551 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE19551 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
1956explain select fld3 from t2 where fld1=fld1;1956explain select fld3 from t2 where fld1=fld1;
1957id select_type table type possible_keys key key_len ref rows Extra1957id select_type table type possible_keys key key_len ref rows Extra
19581 SIMPLE t2 ALL NULL NULL NULL NULL 1200 19581 SIMPLE t2 ALL NULL NULL NULL NULL 1199
1959select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;1959select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
1960companynr fld11960companynr fld1
196134 250501196134 250501
@@ -2007,7 +2007,7 @@
2007418120074181
2008explain select min(fld1),max(fld1),count(*) from t2;2008explain select min(fld1),max(fld1),count(*) from t2;
2009id select_type table type possible_keys key key_len ref rows Extra2009id select_type table type possible_keys key key_len ref rows Extra
20101 SIMPLE t2 index NULL fld1 4 NULL 1200 Using index20101 SIMPLE t2 index NULL fld1 4 NULL 1199 Using index
2011select min(fld1),max(fld1),count(*) from t2;2011select min(fld1),max(fld1),count(*) from t2;
2012min(fld1) max(fld1) count(*)2012min(fld1) max(fld1) count(*)
20130 1232609 119920130 1232609 1199
@@ -2093,9 +2093,9 @@
2093Field Type Collation Null Key Default Extra Privileges Comment2093Field Type Collation Null Key Default Extra Privileges Comment
2094show keys from t2;2094show keys from t2;
2095Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment2095Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
2096t2 0 PRIMARY 1 auto A 1200 NULL NULL BTREE 2096t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
2097t2 0 fld1 1 fld1 A 1200 NULL NULL BTREE 2097t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
2098t2 1 fld3 1 fld3 A 1200 NULL NULL BTREE 2098t2 1 fld3 1 fld3 A 1199 NULL NULL BTREE
2099drop table t4, t3, t2, t1;2099drop table t4, t3, t2, t1;
2100DO 1;2100DO 1;
2101DO benchmark(100,1+1),1,1;2101DO benchmark(100,1+1),1,1;
21022102
=== modified file 'storage/pbxt/ChangeLog'
--- storage/pbxt/ChangeLog 2010-05-06 16:33:54 +0000
+++ storage/pbxt/ChangeLog 2010-09-17 10:32:54 +0000
@@ -1,7 +1,49 @@
1PBXT Release Notes1PBXT Release Notes
2==================2==================
33
4+------- 1.0.11 Pre-GA - 2010-05-114------- 1.0.11-7 Pre-GA - 2010-09-09
5
6RN336: Compiled and tested with MySQL 5.1.50.
7
8RN335: Fixed bug #523994: Deleting all records does not update table statistics.
9
10RN334: Made a change to reduce the time that only temporary tables exist during the ALTER TABLE and REPAIR TABLE statements. This increases the chance of recovery if a crash occurs during these operations.
11
12RN333: Log name of table when PBXT recovers an index on startup. If an error occurs during index recovery, the index is set to "repair pending".
13
14RN332: Fixed an inifinite loop when a record in a row is corrupt. Added logging and set the table to "repair pending" in this case.
15
16RN331: Fixed bug #626890: Crash on truncate table operation.
17
18RN330: Added additional checks for corruption of the index free list.
19
20------- 1.0.11-6 Pre-GA - 2010-07-08
21
22RN329: Fixed bug #601245: make fails. PBXT did not compile if the partition engine was disabled in the MySQL build.
23
24------- 1.0.11-5 Pre-GA - 2010-06-18
25
26RN328: Fixed bug #595478: Compile fails (1.0.11-4).
27
28------- 1.0.11-4 Pre-GA - 2010-06-15
29
30RN327: Fixed a bug that caused a crash during delete on the index. The crash occurred due to memory overwrite when a long key is promoted after a shorter key is deleted, and the difference causes a node size overflow.
31
32------- 1.0.11-3 Pre-GA - 2010-06-11
33
34RN326: Fixed bug #587740: pbxt-1.0.11-pre2-ga first time create partition table error. This was not a new bug. The problem was the PBXT system table's .frm files are corrupted when the first PBXT table created is a partition table.
35
36RN325: Fixed the "to-sweep" column output in xtstat.
37
38------- 1.0.11-2 Pre-GA - 2010-05-26
39
40RN324: Fixed bug #584070:pbxt-1.0.11-pre-ga does not work with mysql 5.1.47. This bug fix removes a hack which was done to avoid running into the LOCK_plugin lock.
41
42------- 1.0.11-1 Pre-GA - 2010-05-19
43
44RN323: Detect corruption of a key length in an index page. This bug fix avoids a possible crash due to index page corruption.
45
46------- 1.0.11 Pre-GA - 2010-05-11
547
6RN322: Creating a table the references a non-existing table can now only be done if you set: foreign_key_checks = 0. Also fixed a failure when creating tables with recursive foreign key declarations.48RN322: Creating a table the references a non-existing table can now only be done if you set: foreign_key_checks = 0. Also fixed a failure when creating tables with recursive foreign key declarations.
749
850
=== modified file 'storage/pbxt/src/cache_xt.cc'
--- storage/pbxt/src/cache_xt.cc 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/cache_xt.cc 2010-09-17 10:32:54 +0000
@@ -668,6 +668,9 @@
668 block->cb_data = buffer;668 block->cb_data = buffer;
669 buffer += XT_INDEX_PAGE_SIZE;669 buffer += XT_INDEX_PAGE_SIZE;
670#endif670#endif
671#ifdef CHECK_BLOCK_TRAILERS
672 XT_SET_DISK_4(block->cp_check, 0xDEADBEEF);
673#endif
671 ind_cac_globals.cg_free_list = block;674 ind_cac_globals.cg_free_list = block;
672 block++;675 block++;
673 }676 }
@@ -684,6 +687,19 @@
684 cont_(a);687 cont_(a);
685}688}
686689
690#ifdef CHECK_BLOCK_TRAILERS
691xtPublic void check_block_trailers()
692{
693 XTIndBlockPtr block;
694
695 block = ind_cac_globals.cg_blocks;
696 for (u_int i=0; i<ind_cac_globals.cg_block_count; i++) {
697 ASSERT_NS(XT_GET_DISK_4(block->cp_check) == 0xDEADBEEF);
698 block++;
699 }
700}
701#endif
702
687xtPublic void xt_ind_exit(XTThreadPtr self)703xtPublic void xt_ind_exit(XTThreadPtr self)
688{704{
689#ifdef XT_USE_MYSYS705#ifdef XT_USE_MYSYS
@@ -1283,7 +1299,7 @@
1283 * Conditionally count the number of deleted entries in the index:1299 * Conditionally count the number of deleted entries in the index:
1284 * We do this before other threads can read the block.1300 * We do this before other threads can read the block.
1285 */1301 */
1286 if (ind->mi_lazy_delete && read_data)1302 if (ind && ind->mi_lazy_delete && read_data)
1287 xt_ind_count_deleted_items(ot->ot_table, ind, block);1303 xt_ind_count_deleted_items(ot->ot_table, ind, block);
12881304
1289 /* Add to the hash table: */1305 /* Add to the hash table: */
@@ -1358,6 +1374,9 @@
1358#ifdef XT_TRACK_INDEX_UPDATES1374#ifdef XT_TRACK_INDEX_UPDATES
1359 ot->ot_ind_changed++;1375 ot->ot_ind_changed++;
1360#endif1376#endif
1377#ifdef CHECK_BLOCK_TRAILERS
1378 check_block_trailers();
1379#endif
1361 return OK;1380 return OK;
1362}1381}
13631382
13641383
=== modified file 'storage/pbxt/src/cache_xt.h'
--- storage/pbxt/src/cache_xt.h 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/cache_xt.h 2010-09-17 10:32:54 +0000
@@ -33,6 +33,7 @@
3333
34#ifdef DEBUG34#ifdef DEBUG
35//#define XT_USE_CACHE_DEBUG_SIZES35//#define XT_USE_CACHE_DEBUG_SIZES
36//#define CHECK_BLOCK_TRAILERS
36#endif37#endif
3738
38#ifdef XT_USE_CACHE_DEBUG_SIZES39#ifdef XT_USE_CACHE_DEBUG_SIZES
@@ -116,6 +117,9 @@
116#else117#else
117 xtWord1 cb_data[XT_INDEX_PAGE_SIZE];118 xtWord1 cb_data[XT_INDEX_PAGE_SIZE];
118#endif119#endif
120#ifdef CHECK_BLOCK_TRAILERS
121 xtWord1 cp_check[4];
122#endif
119} XTIndBlockRec, *XTIndBlockPtr;123} XTIndBlockRec, *XTIndBlockPtr;
120124
121typedef struct XTIndReference {125typedef struct XTIndReference {
@@ -177,6 +181,10 @@
177XTIndHandlePtr xt_ind_get_handle(struct XTOpenTable *ot, XTIndexPtr ind, XTIndReferencePtr iref);181XTIndHandlePtr xt_ind_get_handle(struct XTOpenTable *ot, XTIndexPtr ind, XTIndReferencePtr iref);
178void xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTThreadPtr thread);182void xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTThreadPtr thread);
179183
184#ifdef CHECK_BLOCK_TRAILERS
185extern void check_block_trailers();
186#endif
187
180#ifdef DEBUG188#ifdef DEBUG
181//#define DEBUG_CHECK_IND_CACHE189//#define DEBUG_CHECK_IND_CACHE
182#endif190#endif
183191
=== modified file 'storage/pbxt/src/database_xt.h'
--- storage/pbxt/src/database_xt.h 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/database_xt.h 2010-09-17 10:32:54 +0000
@@ -117,6 +117,7 @@
117 XTSortedListPtr db_table_by_id;117 XTSortedListPtr db_table_by_id;
118 XTSortedListPtr db_table_paths; /* A list of table paths used by this database. */118 XTSortedListPtr db_table_paths; /* A list of table paths used by this database. */
119 xtBool db_multi_path;119 xtBool db_multi_path;
120 XTSortedListPtr db_error_list; /* A list of errors already reported. */
120121
121 /* The open table pool: */122 /* The open table pool: */
122 XTAllTablePoolsRec db_ot_pool;123 XTAllTablePoolsRec db_ot_pool;
123124
=== modified file 'storage/pbxt/src/datadic_xt.cc'
--- storage/pbxt/src/datadic_xt.cc 2010-06-01 19:52:20 +0000
+++ storage/pbxt/src/datadic_xt.cc 2010-09-17 10:32:54 +0000
@@ -396,7 +396,7 @@
396struct charset_info_st;396struct charset_info_st;
397397
398class XTTokenizer {398class XTTokenizer {
399 const struct charset_info_st *tkn_charset;399 MX_CONST_CHARSET_INFO *tkn_charset;
400 char *tkn_cstring;400 char *tkn_cstring;
401 char *tkn_curr_pos;401 char *tkn_curr_pos;
402 XTToken *tkn_current;402 XTToken *tkn_current;
@@ -1324,7 +1324,7 @@
1324class XTCreateTable : public XTParseTable {1324class XTCreateTable : public XTParseTable {
1325 public:1325 public:
1326 bool ct_convert;1326 bool ct_convert;
1327 const struct charset_info_st *ct_charset;1327 MX_CONST_CHARSET_INFO *ct_charset;
1328 XTPathStrPtr ct_tab_path;1328 XTPathStrPtr ct_tab_path;
1329 u_int ct_contraint_no;1329 u_int ct_contraint_no;
1330 XTDDTable *ct_curr_table;1330 XTDDTable *ct_curr_table;
@@ -2039,11 +2039,6 @@
2039 if (!(ot = xt_db_open_table_using_tab(tr_fkey->co_table->dt_table, self)))2039 if (!(ot = xt_db_open_table_using_tab(tr_fkey->co_table->dt_table, self)))
2040 xt_throw(self);2040 xt_throw(self);
20412041
2042 /* {FREE-ROWS-BAD} */
2043 /*
2044 row_count = ((xtInt8) ot->ot_table->tab_row_eof_id) - 1;
2045 row_count -= (xtInt8) ot->ot_table->tab_row_fnum;
2046 */
2047 /* Check if there are any rows in the referencing table: */2042 /* Check if there are any rows in the referencing table: */
2048 if (!xt_tab_seq_init(ot))2043 if (!xt_tab_seq_init(ot))
2049 goto failed;2044 goto failed;
20502045
=== modified file 'storage/pbxt/src/datalog_xt.cc'
--- storage/pbxt/src/datalog_xt.cc 2010-05-14 11:56:14 +0000
+++ storage/pbxt/src/datalog_xt.cc 2010-09-17 10:32:54 +0000
@@ -1249,7 +1249,7 @@
1249 */1249 */
1250 dlb_data_log->dlf_log_eof += size;1250 dlb_data_log->dlf_log_eof += size;
1251#ifdef DEBUG1251#ifdef DEBUG
1252 if ((ulonglong) (log_offset + size) > (ulonglong) dlb_max_write_offset)1252 if (log_offset + (xtLogOffset) size > (xtLogOffset) dlb_max_write_offset)
1253 dlb_max_write_offset = log_offset + size;1253 dlb_max_write_offset = log_offset + size;
1254#endif1254#endif
1255 dlb_flush_required = TRUE;1255 dlb_flush_required = TRUE;
@@ -1291,7 +1291,7 @@
1291 if (!xt_pwrite_file(dlb_data_log->dlf_log_file, log_offset, size, data, &thread->st_statistics.st_data, thread))1291 if (!xt_pwrite_file(dlb_data_log->dlf_log_file, log_offset, size, data, &thread->st_statistics.st_data, thread))
1292 return FAILED;1292 return FAILED;
1293#ifdef DEBUG1293#ifdef DEBUG
1294 if ((ulonglong) (log_offset + size) > (ulonglong) dlb_max_write_offset)1294 if (log_offset + (xtLogOffset) size > (xtLogOffset) dlb_max_write_offset)
1295 dlb_max_write_offset = log_offset + size;1295 dlb_max_write_offset = log_offset + size;
1296#endif1296#endif
1297 dlb_flush_required = TRUE;1297 dlb_flush_required = TRUE;
@@ -1734,8 +1734,8 @@
1734 xtLogOffset src_log_offset;1734 xtLogOffset src_log_offset;
1735 xtLogID curr_log_id;1735 xtLogID curr_log_id;
1736 xtLogOffset curr_log_offset;1736 xtLogOffset curr_log_offset;
1737 xtLogID dest_log_id= 0;1737 xtLogID dest_log_id = 0;
1738 xtLogOffset dest_log_offset= 0;1738 xtLogOffset dest_log_offset = 0;
1739 off_t garbage_count = 0;1739 off_t garbage_count = 0;
17401740
1741 memset(&cs, 0, sizeof(XTCompactorStateRec));1741 memset(&cs, 0, sizeof(XTCompactorStateRec));
17421742
=== modified file 'storage/pbxt/src/discover_xt.cc'
--- storage/pbxt/src/discover_xt.cc 2010-04-08 12:10:05 +0000
+++ storage/pbxt/src/discover_xt.cc 2010-09-17 10:32:54 +0000
@@ -1622,8 +1622,11 @@
1622 COLUMN_FORMAT_TYPE_FIXED,1622 COLUMN_FORMAT_TYPE_FIXED,
1623#endif1623#endif
1624 NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/, 1624 NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
1625 NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/, 1625 NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/
1626 NULL /*vcol_info*/, NULL /* create options */))1626#ifdef MARIADB_BASE_VERSION
1627 , NULL /*vcol_info*/, NULL /* create options */
1628#endif
1629 ))
1627#endif1630#endif
1628 goto error;1631 goto error;
16291632
@@ -1655,8 +1658,17 @@
1655 if (mysql_create_table_no_lock(thd, db, name, &create_info, &table_proto, &stmt->alter_info, 1, 0)) 1658 if (mysql_create_table_no_lock(thd, db, name, &create_info, &table_proto, &stmt->alter_info, 1, 0))
1656 goto error;1659 goto error;
1657#else1660#else
1661#ifdef WITH_PARTITION_STORAGE_ENGINE
1662 partition_info *part_info;
1663
1664 part_info = thd->work_part_info;
1665 thd->work_part_info = NULL;
1666#endif
1658 if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0)) 1667 if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0))
1659 goto error;1668 goto error;
1669#ifdef WITH_PARTITION_STORAGE_ENGINE
1670 thd->work_part_info = part_info;
1671#endif
1660#endif1672#endif
16611673
1662 noerror:1674 noerror:
16631675
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- storage/pbxt/src/ha_pbxt.cc 2010-06-01 19:52:20 +0000
+++ storage/pbxt/src/ha_pbxt.cc 2010-09-17 10:32:54 +0000
@@ -1232,6 +1232,11 @@
1232 THD *thd = NULL;1232 THD *thd = NULL;
12331233
1234#ifndef DRIZZLED1234#ifndef DRIZZLED
1235#if MYSQL_VERSION_ID < 50147
1236 /* A hack which is no longer required after 5.1.46 */
1237 extern myxt_mutex_t LOCK_plugin;
1238#endif
1239
1235 /* {MYSQL QUIRK}1240 /* {MYSQL QUIRK}
1236 * I have to release this lock for PBXT recovery to1241 * I have to release this lock for PBXT recovery to
1237 * work, because it needs to open .frm files.1242 * work, because it needs to open .frm files.
@@ -1248,6 +1253,9 @@
1248 * Only real problem, 2 threads try to load the same1253 * Only real problem, 2 threads try to load the same
1249 * plugin at the same time.1254 * plugin at the same time.
1250 */1255 */
1256#if MYSQL_VERSION_ID < 50147
1257 myxt_mutex_unlock(&LOCK_plugin);
1258#endif
1251#endif1259#endif
12521260
1253 /* Can't do this here yet, because I need a THD! */1261 /* Can't do this here yet, because I need a THD! */
@@ -1281,6 +1289,11 @@
12811289
1282 if (thd)1290 if (thd)
1283 myxt_destroy_thread(thd, FALSE);1291 myxt_destroy_thread(thd, FALSE);
1292#ifndef DRIZZLED
1293#if MYSQL_VERSION_ID < 50147
1294 myxt_mutex_lock(&LOCK_plugin);
1295#endif
1296#endif
1284 }1297 }
1285#endif1298#endif
1286 }1299 }
@@ -1941,8 +1954,13 @@
1941 * selectity of the indices, as soon as the number of rows1954 * selectity of the indices, as soon as the number of rows
1942 * exceeds 200 (see [**])1955 * exceeds 200 (see [**])
1943 */1956 */
1957#ifdef XT_ROW_COUNT_CORRECTED
1958 /* {CORRECTED-ROW-COUNT} */
1959 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150;
1960#else
1944 /* {FREE-ROWS-BAD} */1961 /* {FREE-ROWS-BAD} */
1945 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;1962 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;
1963#endif
1946 }1964 }
19471965
1948 /* I am not doing this anymore because it was only required1966 /* I am not doing this anymore because it was only required
@@ -2289,6 +2307,36 @@
2289 */2307 */
2290 if (!thd || thd_sql_command(thd) == SQLCOM_FLUSH) // FLUSH TABLES2308 if (!thd || thd_sql_command(thd) == SQLCOM_FLUSH) // FLUSH TABLES
2291 xt_sync_flush_table(self, ot);2309 xt_sync_flush_table(self, ot);
2310 else {
2311 /* This change is a result of a problem mentioned by Arjen.
2312 * REPAIR and ALTER lead to the following sequence:
2313 * 1. tab -- copy --> tmp1
2314 * 2. tab -- rename --> tmp2
2315 * 3. tmp1 -- rename --> tab
2316 * 4. delete tmp2
2317 *
2318 * PBXT flushes a table before rename.
2319 * In the sequence above results in a table flush in step 3 which can
2320 * take a very long time.
2321 *
2322 * The problem is, during this time frame we have only temp tables.
2323 * A crash in this state leaves the database in a bad state.
2324 *
2325 * To reduce the time in this state, the flush needs to be done
2326 * elsewhere. The code below causes the flish to occur after
2327 * step 1:
2328 */
2329 switch (thd_sql_command(thd)) {
2330 case SQLCOM_REPAIR:
2331 case SQLCOM_RENAME_TABLE:
2332 case SQLCOM_OPTIMIZE:
2333 case SQLCOM_ANALYZE:
2334 case SQLCOM_ALTER_TABLE:
2335 case SQLCOM_CREATE_INDEX:
2336 xt_sync_flush_table(self, ot);
2337 break;
2338 }
2339 }
2292 }2340 }
2293 freer_(); // xt_db_return_table_to_pool(ot);2341 freer_(); // xt_db_return_table_to_pool(ot);
2294 }2342 }
@@ -2349,9 +2397,15 @@
2349#else2397#else
2350 xt_tab_load_row_pointers(self, pb_open_tab);2398 xt_tab_load_row_pointers(self, pb_open_tab);
2351#endif2399#endif
2400
2352 xt_ind_set_index_selectivity(pb_open_tab, self);2401 xt_ind_set_index_selectivity(pb_open_tab, self);
2402#ifdef XT_ROW_COUNT_CORRECTED
2403 /* {CORRECTED-ROW-COUNT} */
2404 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150;
2405#else
2353 /* {FREE-ROWS-BAD} */2406 /* {FREE-ROWS-BAD} */
2354 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;2407 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;
2408#endif
2355 }2409 }
23562410
2357 init_auto_increment(0);2411 init_auto_increment(0);
@@ -3922,6 +3976,8 @@
39223976
3923 if ((ot = pb_open_tab)) {3977 if ((ot = pb_open_tab)) {
3924 if (flag & HA_STATUS_VARIABLE) {3978 if (flag & HA_STATUS_VARIABLE) {
3979 register XTTableHPtr tab = ot->ot_table;
3980
3925 /* {FREE-ROWS-BAD}3981 /* {FREE-ROWS-BAD}
3926 * Free row count is not reliable, so ignore it.3982 * Free row count is not reliable, so ignore it.
3927 * The problem is if tab_row_fnum > tab_row_eof_id - 1 then3983 * The problem is if tab_row_fnum > tab_row_eof_id - 1 then
@@ -3948,11 +4004,26 @@
3948 * the actual number of vectors. But it must assume that it has at4004 * the actual number of vectors. But it must assume that it has at
3949 * least EXTRA_RECORDS vectors.4005 * least EXTRA_RECORDS vectors.
3950 */4006 */
3951 stats.deleted = /* ot->ot_table->tab_row_fnum */ 0;4007#ifdef XT_ROW_COUNT_CORRECTED
3952 stats.records = (ha_rows) (ot->ot_table->tab_row_eof_id - 1 /* - stats.deleted */);4008 if (tab->tab_row_eof_id <= tab->tab_row_fnum ||
3953 stats.data_file_length = xt_rec_id_to_rec_offset(ot->ot_table, ot->ot_table->tab_rec_eof_id);4009 (!tab->tab_row_free_id && tab->tab_row_fnum))
3954 stats.index_file_length = xt_ind_node_to_offset(ot->ot_table, ot->ot_table->tab_ind_eof);4010 xt_tab_check_free_lists(NULL, ot, false, true);
3955 stats.delete_length = ot->ot_table->tab_rec_fnum * ot->ot_rec_size;4011 stats.records = (ha_rows) tab->tab_row_eof_id - 1;
4012 if (stats.records >= tab->tab_row_fnum) {
4013 stats.deleted = tab->tab_row_fnum;
4014 stats.records -= stats.deleted;
4015 }
4016 else {
4017 stats.deleted = 0;
4018 stats.records = 2;
4019 }
4020#else
4021 stats.deleted = /* tab->tab_row_fnum */ 0;
4022 stats.records = (ha_rows) (tab->tab_row_eof_id - 1 /* - stats.deleted */);
4023#endif
4024 stats.data_file_length = xt_rec_id_to_rec_offset(tab, tab->tab_rec_eof_id);
4025 stats.index_file_length = xt_ind_node_to_offset(tab, tab->tab_ind_eof);
4026 stats.delete_length = tab->tab_rec_fnum * ot->ot_rec_size;
3956 //check_time = info.check_time;4027 //check_time = info.check_time;
3957 stats.mean_rec_length = (ulong) ot->ot_rec_size;4028 stats.mean_rec_length = (ulong) ot->ot_rec_size;
3958 }4029 }
@@ -4577,13 +4648,24 @@
4577 }4648 }
45784649
4579 if (pb_share->sh_recalc_selectivity) {4650 if (pb_share->sh_recalc_selectivity) {
4651#ifdef XT_ROW_COUNT_CORRECTED
4652 /* {CORRECTED-ROW-COUNT} */
4653 if ((pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) >= 200)
4654#else
4580 /* {FREE-ROWS-BAD} */4655 /* {FREE-ROWS-BAD} */
4581 if ((pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) >= 200) {4656 if ((pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) >= 200)
4657#endif
4658 {
4582 /* [**] */4659 /* [**] */
4583 pb_share->sh_recalc_selectivity = FALSE;4660 pb_share->sh_recalc_selectivity = FALSE;
4584 xt_ind_set_index_selectivity(pb_open_tab, self);4661 xt_ind_set_index_selectivity(pb_open_tab, self);
4662#ifdef XT_ROW_COUNT_CORRECTED
4663 /* {CORRECTED-ROW-COUNT} */
4664 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 - pb_share->sh_table->tab_row_fnum) < 150;
4665#else
4585 /* {FREE-ROWS-BAD} */4666 /* {FREE-ROWS-BAD} */
4586 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;4667 pb_share->sh_recalc_selectivity = (pb_share->sh_table->tab_row_eof_id - 1 /* - pb_share->sh_table->tab_row_fnum */) < 150;
4668#endif
4587 }4669 }
4588 }4670 }
4589 }4671 }
@@ -4631,6 +4713,17 @@
4631 goto complete;4713 goto complete;
4632 }4714 }
4633 cont_(a);4715 cont_(a);
4716
4717 /* Occurs if you do:
4718 * truncate table t1;
4719 * truncate table t1;
4720 */
4721 if (!pb_open_tab) {
4722 if ((err = reopen())) {
4723 pb_ex_in_use = 0;
4724 goto complete;
4725 }
4726 }
4634 }4727 }
4635 else {4728 else {
4636 pb_ex_in_use = 1;4729 pb_ex_in_use = 1;
46374730
=== modified file 'storage/pbxt/src/index_xt.cc'
--- storage/pbxt/src/index_xt.cc 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/index_xt.cc 2010-09-17 10:32:54 +0000
@@ -272,10 +272,17 @@
272 }272 }
273273
274 if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) {274 if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) {
275 xtIndexNodeID next_node;
276
275 /* Use the block on the free list: */277 /* Use the block on the free list: */
276 if (!xt_ind_read_bytes(ot, ind, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block))278 if (!xt_ind_read_bytes(ot, NULL, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block))
277 goto failed;279 goto failed;
278 XT_NODE_ID(tab->tab_ind_free) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8);280 XT_NODE_ID(next_node) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8);
281 if (XT_NODE_ID(next_node) >= XT_NODE_ID(tab->tab_ind_eof)) {
282 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, tab->tab_name);
283 goto failed;
284 }
285 XT_NODE_ID(tab->tab_ind_free) = XT_NODE_ID(next_node);
279 xt_unlock_mutex_ns(&tab->tab_ind_lock);286 xt_unlock_mutex_ns(&tab->tab_ind_lock);
280 *address = wrote_pos;287 *address = wrote_pos;
281 TRACK_BLOCK_ALLOC(wrote_pos);288 TRACK_BLOCK_ALLOC(wrote_pos);
@@ -1415,30 +1422,45 @@
1415 if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))1422 if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1416 iref.ir_block->cp_del_count--;1423 iref.ir_block->cp_del_count--;
1417 }1424 }
1418 memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size],1425
1419 &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],1426 if (item->i_pos.i_total_size + item_size - item->i_pos.i_item_size <= XT_INDEX_PAGE_DATA_SIZE) {
1420 item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);1427 /* The new item is larger than the old, this can result
1421 memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset],1428 * in overflow of the node!
1422 item_buf, item_size);1429 */
1423 if (ind->mi_lazy_delete) {1430 memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size],
1424 if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))1431 &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],
1425 iref.ir_block->cp_del_count++;1432 item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);
1426 }1433 memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset],
1427 item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size;1434 item_buf, item_size);
1428 XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size));1435 if (ind->mi_lazy_delete) {
1429 IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));1436 if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1430 iref.ir_updated = TRUE;1437 iref.ir_block->cp_del_count++;
1438 }
1439 item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size;
1440 XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size));
1441 IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));
1442 iref.ir_updated = TRUE;
14311443
1432#ifdef DEBUG1444#ifdef DEBUG
1433 if (ind->mi_lazy_delete)
1434 ASSERT_NS(item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE);1445 ASSERT_NS(item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE);
1435#endif1446#endif
1436 if (item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE)
1437 return xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);1447 return xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);
1448 }
14381449
1439 /* The node has overflowed!! */1450 /* The node has overflowed!! */
1440 result.sr_item = item->i_pos;1451 result.sr_item = item->i_pos;
14411452
1453 memcpy(ot->ot_ind_wbuf.tb_data, iref.ir_branch->tb_data, item->i_pos.i_item_offset); // First part of the buffer
1454 memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset], item_buf, item_size); // The new item
1455 memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset + item_size],
1456 &iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],
1457 item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);
1458 item->i_pos.i_total_size += item_size - item->i_pos.i_item_size;
1459 item->i_pos.i_item_size = item_size;
1460 XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_LEAF_SIZE(item->i_pos.i_total_size));
1461 IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2));
1462 ASSERT_NS(item->i_pos.i_total_size > XT_INDEX_PAGE_DATA_SIZE && item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE*2);
1463
1442 /* Adjust the stack (we want the parents of the delete node): */1464 /* Adjust the stack (we want the parents of the delete node): */
1443 for (;;) {1465 for (;;) {
1444 if (idx_pop(stack) == item)1466 if (idx_pop(stack) == item)
@@ -1448,7 +1470,7 @@
1448 /* We assume that value can be overwritten (which is the case) */1470 /* We assume that value can be overwritten (which is the case) */
1449 key_value.sv_flags = XT_SEARCH_WHOLE_KEY;1471 key_value.sv_flags = XT_SEARCH_WHOLE_KEY;
1450 key_value.sv_key = key_buf;1472 key_value.sv_key = key_buf;
1451 if (!idx_get_middle_branch_item(ot, ind, iref.ir_branch, &key_value, &result))1473 if (!idx_get_middle_branch_item(ot, ind, &ot->ot_ind_wbuf, &key_value, &result))
1452 goto failed_1;1474 goto failed_1;
14531475
1454 if (!idx_new_branch(ot, ind, &new_branch))1476 if (!idx_new_branch(ot, ind, &new_branch))
@@ -1456,7 +1478,6 @@
14561478
1457 /* Split the node: */1479 /* Split the node: */
1458 new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;1480 new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;
1459 // TODO: Are 2 buffers now required?
1460 new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];1481 new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];
1461 memmove(new_branch_ptr->tb_data, &iref.ir_branch->tb_data[result.sr_item.i_item_offset + result.sr_item.i_item_size], new_size);1482 memmove(new_branch_ptr->tb_data, &iref.ir_branch->tb_data[result.sr_item.i_item_offset + result.sr_item.i_item_size], new_size);
14621483
@@ -1466,10 +1487,10 @@
1466 goto failed_2;1487 goto failed_2;
14671488
1468 /* Change the size of the old branch: */1489 /* Change the size of the old branch: */
1469 XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset));1490 XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset));
1470 IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));1491 IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2));
1492 memcpy(iref.ir_branch, &ot->ot_ind_wbuf, offsetof(XTIdxBranchDRec, tb_data) + result.sr_item.i_item_offset);
1471 iref.ir_updated = TRUE;1493 iref.ir_updated = TRUE;
1472
1473 xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);1494 xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);
14741495
1475 /* Insert the new branch into the parent node, using the new middle key value: */1496 /* Insert the new branch into the parent node, using the new middle key value: */
@@ -2071,6 +2092,11 @@
2071 if (!idx_new_branch(ot, ind, &new_branch))2092 if (!idx_new_branch(ot, ind, &new_branch))
2072 goto failed_1;2093 goto failed_1;
20732094
2095 if (XT_NODE_ID(current) == XT_NODE_ID(new_branch)) {
2096 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
2097 goto failed_1;
2098 }
2099
2074 /* Copy and write the rest of the data to the new node: */2100 /* Copy and write the rest of the data to the new node: */
2075 new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;2101 new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;
2076 new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];2102 new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];
@@ -2723,6 +2749,10 @@
2723#endif2749#endif
2724 ASSERT_NS(iref.ir_xlock == 2);2750 ASSERT_NS(iref.ir_xlock == 2);
2725 ASSERT_NS(iref.ir_updated == 2);2751 ASSERT_NS(iref.ir_updated == 2);
2752 if (ind->mi_key_corrupted) {
2753 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
2754 return FAILED;
2755 }
2726 return OK;2756 return OK;
27272757
2728 failed:2758 failed:
@@ -2874,6 +2904,10 @@
2874 //idx_check_index(ot, ind, TRUE);2904 //idx_check_index(ot, ind, TRUE);
2875 //idx_check_on_key(ot);2905 //idx_check_on_key(ot);
2876#endif2906#endif
2907 if (ind->mi_key_corrupted) {
2908 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
2909 return FAILED;
2910 }
2877 return OK;2911 return OK;
28782912
2879 failed:2913 failed:
@@ -2964,6 +2998,10 @@
29642998
2965 if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {2999 if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {
2966 XT_INDEX_UNLOCK(ind, ot);3000 XT_INDEX_UNLOCK(ind, ot);
3001 if (ind->mi_key_corrupted) {
3002 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3003 return FAILED;
3004 }
2967 return OK;3005 return OK;
2968 }3006 }
29693007
@@ -3071,6 +3109,10 @@
3071 ot->ot_curr_rec_id = 0;3109 ot->ot_curr_rec_id = 0;
3072 ot->ot_curr_row_id = 0;3110 ot->ot_curr_row_id = 0;
3073 XT_INDEX_UNLOCK(ind, ot);3111 XT_INDEX_UNLOCK(ind, ot);
3112 if (ind->mi_key_corrupted) {
3113 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3114 return FAILED;
3115 }
3074 return OK;3116 return OK;
3075 }3117 }
30763118
@@ -3112,6 +3154,10 @@
3112 ot->ot_curr_row_id = result.sr_row_id;3154 ot->ot_curr_row_id = result.sr_row_id;
3113 ot->ot_ind_state = result.sr_item;3155 ot->ot_ind_state = result.sr_item;
31143156
3157 if (ind->mi_key_corrupted) {
3158 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3159 return FAILED;
3160 }
3115 return OK;3161 return OK;
31163162
3117 failed:3163 failed:
@@ -3178,6 +3224,10 @@
31783224
3179 if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {3225 if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {
3180 XT_INDEX_UNLOCK(ind, ot);3226 XT_INDEX_UNLOCK(ind, ot);
3227 if (ind->mi_key_corrupted) {
3228 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3229 return FAILED;
3230 }
3181 return OK;3231 return OK;
3182 }3232 }
31833233
@@ -3274,6 +3324,10 @@
3274 ot->ot_curr_row_id = 0;3324 ot->ot_curr_row_id = 0;
32753325
3276 XT_INDEX_UNLOCK(ind, ot);3326 XT_INDEX_UNLOCK(ind, ot);
3327 if (ind->mi_key_corrupted) {
3328 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3329 return FAILED;
3330 }
3277 return OK;3331 return OK;
32783332
3279 unlock_check_on_key:3333 unlock_check_on_key:
@@ -3302,6 +3356,10 @@
3302 ot->ot_curr_rec_id = result.sr_rec_id;3356 ot->ot_curr_rec_id = result.sr_rec_id;
3303 ot->ot_curr_row_id = result.sr_row_id;3357 ot->ot_curr_row_id = result.sr_row_id;
3304 ot->ot_ind_state = result.sr_item;3358 ot->ot_ind_state = result.sr_item;
3359 if (ind->mi_key_corrupted) {
3360 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
3361 return FAILED;
3362 }
3305 return OK;3363 return OK;
33063364
3307 failed:3365 failed:
@@ -3648,7 +3706,7 @@
3648 track_block_exists(current);3706 track_block_exists(current);
3649#endif3707#endif
3650 printf("%d ", (int) XT_NODE_ID(current));3708 printf("%d ", (int) XT_NODE_ID(current));
3651 if (!xt_ind_read_bytes(ot, *ind, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {3709 if (!xt_ind_read_bytes(ot, NULL, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {
3652 xt_log_and_clear_exception_ns();3710 xt_log_and_clear_exception_ns();
3653 break;3711 break;
3654 }3712 }
@@ -4141,11 +4199,18 @@
4141 if (!ilp_open_log(&il, log_id, FALSE, self))4199 if (!ilp_open_log(&il, log_id, FALSE, self))
4142 goto failed;4200 goto failed;
4143 if (il->il_tab_id && il->il_log_eof) {4201 if (il->il_tab_id && il->il_log_eof) {
4202 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
4203
4144 if (!il->il_open_table(&ot))4204 if (!il->il_open_table(&ot))
4145 goto failed;4205 goto failed;
4146 if (ot) {4206 if (ot) {
4147 if (!il->il_apply_log(ot))4207 xt_tab_make_table_name(ot->ot_table, table_name, sizeof(table_name));
4148 goto failed;4208 xt_logf(XT_NT_INFO, "PBXT: Recovering index, table: %s, bytes to read: %llu\n", table_name, (u_llong) il->il_log_eof);
4209 if (!il->il_apply_log(ot)) {
4210 /* If recovery of an index fails, then it is corrupt! */
4211 xt_tab_disable_index(ot->ot_table, XT_INDEX_CORRUPTED);
4212 xt_log_and_clear_exception_ns();
4213 }
4149 ot->ot_thread = self;4214 ot->ot_thread = self;
4150 il->il_close_table(ot);4215 il->il_close_table(ot);
4151 }4216 }
@@ -4468,8 +4533,7 @@
4468 /* Corrupt log?! */4533 /* Corrupt log?! */
4469 if (il_buffer_len < req_size) {4534 if (il_buffer_len < req_size) {
4470 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));4535 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
4471 xt_log_and_clear_exception_ns();4536 return FAILED;
4472 return OK;
4473 }4537 }
4474 if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))4538 if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))
4475 return FAILED;4539 return FAILED;
@@ -4548,8 +4612,7 @@
4548 /* Corrupt log?! */4612 /* Corrupt log?! */
4549 if (il_buffer_len < req_size) {4613 if (il_buffer_len < req_size) {
4550 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));4614 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
4551 xt_log_and_clear_exception_ns();4615 return FAILED;
4552 return OK;
4553 }4616 }
4554 if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))4617 if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))
4555 return FAILED;4618 return FAILED;
@@ -4597,8 +4660,7 @@
4597 break;4660 break;
4598 default:4661 default:
4599 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));4662 xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
4600 xt_log_and_clear_exception_ns();4663 return FAILED;
4601 return OK;
4602 }4664 }
4603 }4665 }
46044666
46054667
=== modified file 'storage/pbxt/src/index_xt.h'
--- storage/pbxt/src/index_xt.h 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/index_xt.h 2010-09-17 10:32:54 +0000
@@ -312,7 +312,7 @@
312 u_int mi_flags;312 u_int mi_flags;
313 u_int mi_key_size;313 u_int mi_key_size;
314 u_int mi_max_items; /* The maximum number of items that can fit in a leaf node. */314 u_int mi_max_items; /* The maximum number of items that can fit in a leaf node. */
315 xtBool mi_low_byte_first;315 xtBool mi_key_corrupted; /* Set to TRUE if a currupted index key is detected. */
316 xtBool mi_fix_key;316 xtBool mi_fix_key;
317 xtBool mi_lazy_delete; /* TRUE if index entries are "lazy deleted". */317 xtBool mi_lazy_delete; /* TRUE if index entries are "lazy deleted". */
318 u_int mi_single_type; /* Used when the index contains a single field. */318 u_int mi_single_type; /* Used when the index contains a single field. */
319319
=== modified file 'storage/pbxt/src/myxt_xt.cc'
--- storage/pbxt/src/myxt_xt.cc 2010-05-12 14:27:18 +0000
+++ storage/pbxt/src/myxt_xt.cc 2010-09-17 10:32:54 +0000
@@ -1088,7 +1088,10 @@
1088 }1088 }
10891089
1090 end:1090 end:
1091 return (xtWord1 *) key_data - key_buf;1091 u_int ilen = (xtWord1 *) key_data - key_buf;
1092 if (ilen > XT_INDEX_MAX_KEY_SIZE)
1093 ind->mi_key_corrupted = TRUE;
1094 return ilen;
1092}1095}
10931096
1094/* Derived from ha_key_cmp */1097/* Derived from ha_key_cmp */
@@ -2183,7 +2186,8 @@
2183 xt_spinlock_init_with_autoname(self, &ind->mi_dirty_lock);2186 xt_spinlock_init_with_autoname(self, &ind->mi_dirty_lock);
2184 ind->mi_index_no = idx;2187 ind->mi_index_no = idx;
2185 ind->mi_flags = (index->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL | HA_UNIQUE_CHECK));2188 ind->mi_flags = (index->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL | HA_UNIQUE_CHECK));
2186 ind->mi_low_byte_first = TS(table_arg)->db_low_byte_first;2189 //ind->mi_low_byte_first = TS(table_arg)->db_low_byte_first;
2190 ind->mi_key_corrupted = FALSE;
2187 ind->mi_fix_key = TRUE;2191 ind->mi_fix_key = TRUE;
2188 ind->mi_select_total = 0;2192 ind->mi_select_total = 0;
2189 ind->mi_subset_of = 0;2193 ind->mi_subset_of = 0;
21902194
=== modified file 'storage/pbxt/src/myxt_xt.h'
--- storage/pbxt/src/myxt_xt.h 2010-01-06 19:20:16 +0000
+++ storage/pbxt/src/myxt_xt.h 2010-09-17 10:32:54 +0000
@@ -69,17 +69,17 @@
69void myxt_move_dictionary(XTDictionaryPtr dic, XTDictionaryPtr source_dic);69void myxt_move_dictionary(XTDictionaryPtr dic, XTDictionaryPtr source_dic);
70XTDDTable *myxt_create_table_from_table(XTThreadPtr self, STRUCT_TABLE *my_tab);70XTDDTable *myxt_create_table_from_table(XTThreadPtr self, STRUCT_TABLE *my_tab);
7171
72void myxt_static_convert_identifier(XTThreadPtr self, const struct charset_info_st *cs, char *from, char *to, size_t to_len);72void myxt_static_convert_identifier(XTThreadPtr self, MX_CONST_CHARSET_INFO *cs, char *from, char *to, size_t to_len);
73char *myxt_convert_identifier(XTThreadPtr self, const struct charset_info_st *cs, char *from);73char *myxt_convert_identifier(XTThreadPtr self, MX_CONST_CHARSET_INFO *cs, char *from);
74void myxt_static_convert_table_name(XTThreadPtr self, char *from, char *to, size_t to_len);74void myxt_static_convert_table_name(XTThreadPtr self, char *from, char *to, size_t to_len);
75void myxt_static_convert_file_name(char *from, char *to, size_t to_len);75void myxt_static_convert_file_name(char *from, char *to, size_t to_len);
76char *myxt_convert_table_name(XTThreadPtr self, char *from);76char *myxt_convert_table_name(XTThreadPtr self, char *from);
77int myxt_strcasecmp(char * a, char *b);77int myxt_strcasecmp(char * a, char *b);
78int myxt_isspace(const struct charset_info_st *cs, char a);78int myxt_isspace(MX_CONST_CHARSET_INFO *cs, char a);
79int myxt_ispunct(const struct charset_info_st *cs, char a);79int myxt_ispunct(MX_CONST_CHARSET_INFO *cs, char a);
80int myxt_isdigit(const struct charset_info_st *cs, char a);80int myxt_isdigit(MX_CONST_CHARSET_INFO *cs, char a);
8181
82const struct charset_info_st *myxt_getcharset(bool convert);82MX_CONST_CHARSET_INFO *myxt_getcharset(bool convert);
8383
84void *myxt_create_thread();84void *myxt_create_thread();
85void myxt_destroy_thread(void *thread, xtBool end_threads);85void myxt_destroy_thread(void *thread, xtBool end_threads);
8686
=== modified file 'storage/pbxt/src/restart_xt.cc'
--- storage/pbxt/src/restart_xt.cc 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/restart_xt.cc 2010-09-17 10:32:54 +0000
@@ -1359,6 +1359,57 @@
1359 return op_synced;1359 return op_synced;
1360}1360}
13611361
1362#ifdef XT_CORRECT_TABLE_FREE_COUNT
1363#define CORRECT_COUNT TRUE
1364#else
1365#define CORRECT_COUNT FALSE
1366#endif
1367#ifdef XT_CHECK_RECORD_FREE_COUNT
1368#define CHECK_RECS TRUE
1369#else
1370#define CHECK_RECS FALSE
1371#endif
1372#if defined(XT_CHECK_RECORD_FREE_COUNT) || defined(XT_CHECK_ROW_FREE_COUNT)
1373#define RECOVER_FREE_COUNTS
1374#endif
1375
1376#ifdef RECOVER_FREE_COUNTS
1377/* {CORRECTED-ROW-COUNT}
1378 * This error can be repeated by crashing the server during
1379 * high activitity, after flush table writes the table header
1380 *
1381 * On recovery, the free count "from the future" is used as
1382 * the starting point for subsequent allocation and frees.
1383 * The count is wrong after that point.
1384 *
1385 * The recovery of the count only works correctly if a
1386 * checkpoint is complete successfully after that table
1387 * header is flushed. Basically the writing of the table
1388 * header should be synchronsized with the writing of the
1389 * end of the checkpoint.
1390 *
1391 * Another solution would be to log the count, along with
1392 * the allocate and free commannds.
1393 *
1394 * The 3rd solution is the one used here. The count is corrected
1395 * after recovery.
1396 */
1397static void xres_recover_table_free_counts(XTThreadPtr self, XTDatabaseHPtr db, XTWriterStatePtr ws)
1398{
1399 u_int edx;
1400 XTTableEntryPtr te_ptr;
1401 XTTableHPtr tab;
1402
1403 xt_enum_tables_init(&edx);
1404 while ((te_ptr = xt_enum_tables_next(self, db, &edx))) {
1405 if ((tab = te_ptr->te_table)) {
1406 if (xres_open_table(self, ws, te_ptr->te_tab_id))
1407 xt_tab_check_free_lists(self, ws->ws_ot, CHECK_RECS, CORRECT_COUNT);
1408 }
1409 }
1410}
1411#endif
1412
1362/*1413/*
1363 * Operations from the log are applied in sequence order.1414 * Operations from the log are applied in sequence order.
1364 * If the operations are out of sequence, they are buffered1415 * If the operations are out of sequence, they are buffered
@@ -2175,6 +2226,13 @@
2175 /* This is true because if no transaction was placed in RAM then2226 /* This is true because if no transaction was placed in RAM then
2176 * the next transaction in RAM will have the next ID: */2227 * the next transaction in RAM will have the next ID: */
2177 db->db_xn_min_ram_id = db->db_xn_curr_id + 1;2228 db->db_xn_min_ram_id = db->db_xn_curr_id + 1;
2229
2230#ifdef RECOVER_FREE_COUNTS
2231 if (xres_cp_log_id != *log_id || xres_cp_log_offset != *log_offset) {
2232 /* Recovery took place, correct the row count! */
2233 xres_recover_table_free_counts(self, db, &ws);
2234 }
2235#endif
2178 }2236 }
21792237
2180 failed:2238 failed:
21812239
=== modified file 'storage/pbxt/src/strutil_xt.cc'
--- storage/pbxt/src/strutil_xt.cc 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/strutil_xt.cc 2010-09-17 10:32:54 +0000
@@ -380,7 +380,7 @@
380/* Version number must also be set in configure.in! */380/* Version number must also be set in configure.in! */
381xtPublic c_char *xt_get_version(void)381xtPublic c_char *xt_get_version(void)
382{382{
383 return "1.0.11 Pre-GA";383 return "1.0.11-7 Pre-GA";
384}384}
385385
386/* Copy and URL decode! */386/* Copy and URL decode! */
387387
=== modified file 'storage/pbxt/src/table_xt.cc'
--- storage/pbxt/src/table_xt.cc 2010-05-14 11:56:14 +0000
+++ storage/pbxt/src/table_xt.cc 2010-09-17 10:32:54 +0000
@@ -80,6 +80,65 @@
8080
81/*81/*
82 * -----------------------------------------------------------------------82 * -----------------------------------------------------------------------
83 * Handle Error Detected in a Table
84 */
85
86struct XTTableError {
87 xtTableID ter_tab_id;
88 xtRecordID ter_rec_id;
89};
90
91static int tab_comp_tab_error(XTThreadPtr XT_UNUSED(self), register const void *XT_UNUSED(thunk), register const void *a, register const void *b)
92{
93 XTTableError *ter_a = ((XTTableError *) a);
94 XTTableError *ter_b = (XTTableError *) b;
95
96 if (ter_a->ter_tab_id < ter_b->ter_tab_id)
97 return -1;
98 if (ter_a->ter_tab_id == ter_b->ter_tab_id) {
99 if (ter_a->ter_rec_id < ter_b->ter_rec_id)
100 return -1;
101 if (ter_a->ter_rec_id == ter_b->ter_rec_id)
102 return 0;
103 return 1;
104 }
105 return 1;
106}
107
108static xtBool tab_record_corrupt(XTOpenTablePtr ot, xtRowID row_id, xtRecordID rec_id, bool not_valid, int where)
109{
110 XTTableHPtr tab = ot->ot_table;
111 XTDatabaseHPtr db = tab->tab_db;
112 XTTableError ter;
113 XTTableError *ter_ptr;
114
115 ter.ter_tab_id = tab->tab_id;
116 ter.ter_rec_id = rec_id;
117
118 xt_sl_lock_ns(db->db_error_list, ot->ot_thread);
119 if (!(ter_ptr = (XTTableError *) xt_sl_find(NULL, db->db_error_list, &ter))) {
120 xtBool ok;
121 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
122
123 ok = xt_sl_insert(NULL, db->db_error_list, &ter, &ter);
124 xt_sl_unlock_ns(db->db_error_list);
125 if (!ok)
126 return FAILED;
127 xt_tab_set_table_repair_pending(tab);
128 xt_tab_make_table_name(tab, table_name, sizeof(table_name));
129 xt_logf(XT_NT_ERROR, "#%d Table %s: row %llu, record %llu, is %s, REPAIR TABLE required.\n", where,
130 table_name,
131 (u_llong) row_id,
132 (u_llong) rec_id,
133 not_valid ? "not valid" : "free");
134 }
135 else
136 xt_sl_unlock_ns(db->db_error_list);
137 return OK;
138}
139
140/*
141 * -----------------------------------------------------------------------
83 * Compare paths:142 * Compare paths:
84 */143 */
85144
@@ -425,6 +484,7 @@
425 db->db_tables = xt_new_hashtable(self, tab_list_comp, tab_list_hash, tab_list_free, TRUE, TRUE);484 db->db_tables = xt_new_hashtable(self, tab_list_comp, tab_list_hash, tab_list_free, TRUE, TRUE);
426 db->db_table_by_id = xt_new_sortedlist(self, sizeof(XTTableEntryRec), 20, 20, tab_comp_by_id, db, tab_free_by_id, FALSE, FALSE);485 db->db_table_by_id = xt_new_sortedlist(self, sizeof(XTTableEntryRec), 20, 20, tab_comp_by_id, db, tab_free_by_id, FALSE, FALSE);
427 db->db_table_paths = xt_new_sortedlist(self, sizeof(XTTablePathPtr), 20, 20, tab_comp_path, db, tab_free_path, FALSE, FALSE);486 db->db_table_paths = xt_new_sortedlist(self, sizeof(XTTablePathPtr), 20, 20, tab_comp_path, db, tab_free_path, FALSE, FALSE);
487 db->db_error_list = xt_new_sortedlist(self, sizeof(XTTableError), 20, 20, tab_comp_tab_error, db, NULL, TRUE, FALSE);
428488
429 if (db->db_multi_path) {489 if (db->db_multi_path) {
430 XTOpenFilePtr of;490 XTOpenFilePtr of;
@@ -649,6 +709,10 @@
649 xt_free_sortedlist(self, db->db_table_paths);709 xt_free_sortedlist(self, db->db_table_paths);
650 db->db_table_paths = NULL;710 db->db_table_paths = NULL;
651 }711 }
712 if (db->db_error_list) {
713 xt_free_sortedlist(self, db->db_error_list);
714 db->db_error_list = NULL;
715 }
652}716}
653717
654static void tab_check_table(XTThreadPtr self, XTTableHPtr XT_UNUSED(tab))718static void tab_check_table(XTThreadPtr self, XTTableHPtr XT_UNUSED(tab))
@@ -1713,6 +1777,116 @@
1713 exit_();1777 exit_();
1714}1778}
17151779
1780xtPublic void xt_tab_check_free_lists(XTThreadPtr self, XTOpenTablePtr ot, bool check_recs, bool correct_count)
1781{
1782 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
1783 register XTTableHPtr tab = ot->ot_table;
1784 xtRowID prev_row_id;
1785 xtRowID row_id;
1786 xtRefID next_row_id;
1787 u_llong free_count;
1788
1789 xt_tab_make_table_name(tab, table_name, sizeof(table_name));
1790 if (check_recs) {
1791 xtRecordID prev_rec_id;
1792 xtRecordID rec_id;
1793 XTTabRecExtDRec rec_buf;
1794
1795 xt_lock_mutex_ns(&tab->tab_rec_lock);
1796 /* Checking the free list: */
1797 prev_rec_id = 0;
1798 free_count = 0;
1799 rec_id = tab->tab_rec_free_id;
1800 while (rec_id) {
1801 if (rec_id >= tab->tab_rec_eof_id) {
1802 xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free list: %llu, ", table_name, (u_llong) rec_id);
1803 if (prev_rec_id)
1804 xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_rec_id);
1805 else
1806 xt_logf(XT_NT_ERROR, "reference by list head pointer\n");
1807 xt_tab_set_table_repair_pending(tab);
1808 break;
1809 }
1810 if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_FIX_HEADER_SIZE, (xtWord1 *) &rec_buf)) {
1811 if (self)
1812 xt_throw(self);
1813 else
1814 xt_log_and_clear_warning(ot->ot_thread);
1815 break;
1816 }
1817 if ((rec_buf.tr_rec_type_1 & XT_TAB_STATUS_MASK) != XT_TAB_STATUS_FREED)
1818 xt_logf(XT_NT_INFO, "Table %s: record, %llu, on free list is not free\n", table_name, (u_llong) rec_id);
1819 free_count++;
1820 prev_rec_id = rec_id;
1821 rec_id = XT_GET_DISK_4(rec_buf.tr_prev_rec_id_4);
1822 }
1823 if (free_count != tab->tab_rec_fnum) {
1824 if (correct_count) {
1825 tab->tab_rec_fnum = free_count;
1826 tab->tab_head_rec_fnum = free_count;
1827 tab->tab_flush_pending = TRUE;
1828 xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) has been set to the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count);
1829 }
1830 else
1831 xt_logf(XT_NT_INFO, "Table %s: free record count (%llu) differs from the number of records on the list: %llu\n", table_name, (u_llong) tab->tab_rec_fnum, (u_llong) free_count);
1832 }
1833 xt_unlock_mutex_ns(&tab->tab_rec_lock);
1834 }
1835
1836 /* Check the row free list: */
1837 xt_lock_mutex_ns(&tab->tab_row_lock);
1838
1839 prev_row_id = 0;
1840 free_count = 0;
1841 row_id = tab->tab_row_free_id;
1842 while (row_id) {
1843 if (row_id >= tab->tab_row_eof_id) {
1844 xt_logf(XT_NT_ERROR, "Table %s: invalid reference on free row: %llu, ", table_name, (u_llong) row_id);
1845 if (prev_row_id)
1846 xt_logf(XT_NT_ERROR, "reference by: %llu\n", (u_llong) prev_row_id);
1847 else
1848 xt_logf(XT_NT_ERROR, "reference by list head pointer\n");
1849 xt_tab_set_table_repair_pending(tab);
1850 break;
1851 }
1852 if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &next_row_id, ot->ot_thread)) {
1853 if (self)
1854 xt_throw(self);
1855 else
1856 xt_log_and_clear_warning(ot->ot_thread);
1857 break;
1858 }
1859 free_count++;
1860 prev_row_id = row_id;
1861 row_id = next_row_id;
1862 }
1863 if (free_count != tab->tab_row_fnum) {
1864 if (correct_count) {
1865 /* tab_row_fnum is the current value, and tab_head_row_fnum is the value on
1866 * disk. tab_head_row_fnum is set by the writer as the changes are applied
1867 * to the database.
1868 *
1869 * This is the value then stored in the header of the file. This value
1870 * is in sync with other changes to the file.
1871 *
1872 * So the fact that I am setting both value means this will not work at
1873 * runtime, unless all changes have been applied by the writer.
1874 *
1875 * The correct way to do this at run time would be to add the change to the
1876 * transaction log, so that it is applied by the writer.
1877 */
1878 tab->tab_row_fnum = free_count;
1879 tab->tab_head_row_fnum = free_count;
1880 tab->tab_flush_pending = TRUE;
1881 xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) has been set to the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count);
1882 }
1883 else
1884 xt_logf(XT_NT_INFO, "Table %s: free row count (%llu) differs from the number of rows on the list: %llu\n", table_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count);
1885 }
1886
1887 xt_unlock_mutex_ns(&tab->tab_row_lock);
1888}
1889
1716/*1890/*
1717 * Record buffer size:1891 * Record buffer size:
1718 * -------------------1892 * -------------------
@@ -2010,7 +2184,7 @@
2010 prec_id = rec_id;2184 prec_id = rec_id;
2011 rec_id = XT_GET_DISK_4(rec_buf->tr_prev_rec_id_4);2185 rec_id = XT_GET_DISK_4(rec_buf->tr_prev_rec_id_4);
2012 }2186 }
2013 if (free_count2 < free_rec_count)2187 if (free_count2 != free_rec_count)
2014 xt_logf(XT_INFO, "Table %s: not all free blocks (%llu) on free list: %llu\n", tab->tab_name, (u_llong) free_rec_count, (u_llong) free_count2);2188 xt_logf(XT_INFO, "Table %s: not all free blocks (%llu) on free list: %llu\n", tab->tab_name, (u_llong) free_rec_count, (u_llong) free_count2);
20152189
2016 freer_(); // xt_unlock_mutex_ns(&tab->tab_rec_lock);2190 freer_(); // xt_unlock_mutex_ns(&tab->tab_rec_lock);
@@ -2042,6 +2216,29 @@
2042 rec_id++;2216 rec_id++;
2043 }2217 }
20442218
2219 prec_id = 0;
2220 free_count2 = 0;
2221 row_id = tab->tab_row_free_id;
2222 while (row_id) {
2223 if (row_id >= tab->tab_row_eof_id) {
2224 xt_logf(XT_INFO, "Table %s: invalid reference on free row: %llu, ", tab->tab_name, (u_llong) row_id);
2225 if (prec_id)
2226 xt_logf(XT_INFO, "reference by: %llu\n", (u_llong) prec_id);
2227 else
2228 xt_logf(XT_INFO, "reference by list head pointer\n");
2229 break;
2230 }
2231 if (!tab->tab_rows.xt_tc_read_4(ot->ot_row_file, row_id, &ref_id, self)) {
2232 xt_log_and_clear_exception(self);
2233 break;
2234 }
2235 free_count2++;
2236 prec_id = row_id;
2237 row_id = ref_id;
2238 }
2239 if (free_count2 != tab->tab_row_fnum)
2240 xt_logf(XT_INFO, "Table %s: free row count (%llu) differs from the number of row on the list: %llu\n", tab->tab_name, (u_llong) tab->tab_row_fnum, (u_llong) free_count2);
2241
2045 freer_(); // xt_unlock_mutex(&tab->tab_row_lock);2242 freer_(); // xt_unlock_mutex(&tab->tab_row_lock);
20462243
2047#ifdef CHECK_INDEX_ON_CHECK_TABLE2244#ifdef CHECK_INDEX_ON_CHECK_TABLE
@@ -3117,10 +3314,18 @@
3117#endif3314#endif
3118 break;3315 break;
3119 case XT_XN_REREAD:3316 case XT_XN_REREAD:
3317 /* {RETRY-READ}
3318 * TODO: This is not as "correct" as it could be.
3319 * Such records should be considered to be aborted,
3320 * and removed from the list.
3321 */
3120 if (invalid_rec != var_rec_id) {3322 if (invalid_rec != var_rec_id) {
3121 invalid_rec = var_rec_id;3323 invalid_rec = var_rec_id;
3122 goto retry_3;3324 goto retry_3;
3123 }3325 }
3326 if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 1))
3327 goto failed;
3328
3124 /* Assume end of list. */3329 /* Assume end of list. */
3125#ifdef XT_CRASH_DEBUG3330#ifdef XT_CRASH_DEBUG
3126 /* Should not happen! */3331 /* Should not happen! */
@@ -3308,6 +3513,8 @@
3308 /* Avoid infinite loop: */3513 /* Avoid infinite loop: */
3309 if (read_again) {3514 if (read_again) {
3310 /* Should not happen! */3515 /* Should not happen! */
3516 if (!tab_record_corrupt(ot, row_id, ot->ot_curr_rec_id, true, 2))
3517 return XT_ERR;
3311#ifdef XT_CRASH_DEBUG3518#ifdef XT_CRASH_DEBUG
3312 /* Generate a core dump! */3519 /* Generate a core dump! */
3313 xt_crash_me();3520 xt_crash_me();
@@ -3364,6 +3571,8 @@
3364 /* Avoid infinite loop: */3571 /* Avoid infinite loop: */
3365 if (read_again) {3572 if (read_again) {
3366 /* Should not happen! */3573 /* Should not happen! */
3574 if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) ot->ot_row_rbuffer)->tr_row_id_4), ot->ot_curr_rec_id, true, 3))
3575 return XT_ERR;
3367#ifdef XT_CRASH_DEBUG3576#ifdef XT_CRASH_DEBUG
3368 /* Generate a core dump! */3577 /* Generate a core dump! */
3369 xt_crash_me();3578 xt_crash_me();
@@ -3580,6 +3789,7 @@
3580 }3789 }
3581 tab->tab_row_free_id = row_id;3790 tab->tab_row_free_id = row_id;
3582 tab->tab_row_fnum++;3791 tab->tab_row_fnum++;
3792 ASSERT_NS(tab->tab_row_fnum < tab->tab_row_eof_id);
3583 xt_unlock_mutex_ns(&tab->tab_row_lock);3793 xt_unlock_mutex_ns(&tab->tab_row_lock);
35843794
3585 if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_ROW_FREED, op_seq, 0, row_id, sizeof(XTTabRowRefDRec), (xtWord1 *) &free_row, ot->ot_thread))3795 if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_ROW_FREED, op_seq, 0, row_id, sizeof(XTTabRowRefDRec), (xtWord1 *) &free_row, ot->ot_thread))
@@ -3776,7 +3986,7 @@
3776 xt_lock_mutex_ns(&tab->tab_db->db_co_ext_lock);3986 xt_lock_mutex_ns(&tab->tab_db->db_co_ext_lock);
3777 if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_EXT_HEADER_SIZE, ot->ot_row_rbuffer)) {3987 if (!xt_tab_get_rec_data(ot, rec_id, XT_REC_EXT_HEADER_SIZE, ot->ot_row_rbuffer)) {
3778 xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);3988 xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);
3779 return FAILED;3989 return XT_ERR;
3780 }3990 }
3781 xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);3991 xt_unlock_mutex_ns(&tab->tab_db->db_co_ext_lock);
37823992
@@ -3824,7 +4034,7 @@
3824 XT_SET_DISK_4(free_rec->rf_next_rec_id_4, prev_rec_id);4034 XT_SET_DISK_4(free_rec->rf_next_rec_id_4, prev_rec_id);
3825 if (!xt_tab_put_rec_data(ot, rec_id, sizeof(XTTabRecFreeDRec), ot->ot_row_rbuffer, &op_seq)) {4035 if (!xt_tab_put_rec_data(ot, rec_id, sizeof(XTTabRecFreeDRec), ot->ot_row_rbuffer, &op_seq)) {
3826 xt_unlock_mutex_ns(&tab->tab_rec_lock);4036 xt_unlock_mutex_ns(&tab->tab_rec_lock);
3827 return FAILED;4037 return XT_ERR;
3828 }4038 }
3829 tab->tab_rec_free_id = rec_id;4039 tab->tab_rec_free_id = rec_id;
3830 ASSERT_NS(tab->tab_rec_free_id < tab->tab_rec_eof_id);4040 ASSERT_NS(tab->tab_rec_free_id < tab->tab_rec_eof_id);
@@ -3832,7 +4042,9 @@
3832 xt_unlock_mutex_ns(&tab->tab_rec_lock);4042 xt_unlock_mutex_ns(&tab->tab_rec_lock);
38334043
3834 free_rec->rf_rec_type_1 = old_rec_type;4044 free_rec->rf_rec_type_1 = old_rec_type;
3835 return xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_REC_REMOVED_BI, op_seq, (xtRecordID) new_rec_type, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread);4045 if (!xt_xlog_modify_table(tab->tab_id, XT_LOG_ENT_REC_REMOVED_BI, op_seq, (xtRecordID) new_rec_type, rec_id, rec_size, ot->ot_row_rbuffer, ot->ot_thread))
4046 return XT_ERR;
4047 return OK;
3836}4048}
38374049
3838static xtRowID tab_new_row(XTOpenTablePtr ot, XTTableHPtr tab)4050static xtRowID tab_new_row(XTOpenTablePtr ot, XTTableHPtr tab)
@@ -3851,6 +4063,7 @@
3851 return 0;4063 return 0;
3852 }4064 }
3853 tab->tab_row_free_id = next_row_id;4065 tab->tab_row_free_id = next_row_id;
4066 ASSERT_NS(tab->tab_row_fnum > 0);
3854 tab->tab_row_fnum--;4067 tab->tab_row_fnum--;
3855 }4068 }
3856 else {4069 else {
@@ -4170,9 +4383,12 @@
4170 return FAILED;4383 return FAILED;
4171 if (XT_REC_IS_CLEAN(var_head.tr_rec_type_1))4384 if (XT_REC_IS_CLEAN(var_head.tr_rec_type_1))
4172 goto locked;4385 goto locked;
4173 if (XT_REC_IS_FREE(var_head.tr_rec_type_1))4386 if (XT_REC_IS_FREE(var_head.tr_rec_type_1)) {
4174 /* Should not happen: */4387 /* Should not happen: */
4388 if (!tab_record_corrupt(ot, row_id, var_rec_id, false, 4))
4389 return FAILED;
4175 goto record_invalid;4390 goto record_invalid;
4391 }
4176 xn_id = XT_GET_DISK_4(var_head.tr_xact_id_4);4392 xn_id = XT_GET_DISK_4(var_head.tr_xact_id_4);
4177 switch (xt_xn_status(ot, xn_id, var_rec_id)) {4393 switch (xt_xn_status(ot, xn_id, var_rec_id)) {
4178 case XT_XN_VISIBLE:4394 case XT_XN_VISIBLE:
@@ -4195,6 +4411,8 @@
4195 XT_TAB_ROW_WRITE_LOCK(&tab->tab_row_rwlock[row_id % XT_ROW_RWLOCKS], ot->ot_thread);4411 XT_TAB_ROW_WRITE_LOCK(&tab->tab_row_rwlock[row_id % XT_ROW_RWLOCKS], ot->ot_thread);
4196 goto retry;4412 goto retry;
4197 case XT_XN_REREAD:4413 case XT_XN_REREAD:
4414 if (!tab_record_corrupt(ot, row_id, var_rec_id, true, 5))
4415 return FAILED;
4198 goto record_invalid;4416 goto record_invalid;
4199 }4417 }
4200 var_rec_id = XT_GET_DISK_4(var_head.tr_prev_rec_id_4);4418 var_rec_id = XT_GET_DISK_4(var_head.tr_prev_rec_id_4);
@@ -4206,9 +4424,10 @@
4206 return FAILED;4424 return FAILED;
4207 4425
4208 record_invalid:4426 record_invalid:
4427 /* {RETRY-READ} */
4209 /* Prevent an infinite loop due to a bad record: */4428 /* Prevent an infinite loop due to a bad record: */
4210 if (invalid_rec != var_rec_id) {4429 if (invalid_rec != var_rec_id) {
4211 var_rec_id = invalid_rec;4430 invalid_rec = var_rec_id;
4212 goto retry;4431 goto retry;
4213 }4432 }
4214 /* The record is invalid, it will be "overwritten"... */4433 /* The record is invalid, it will be "overwritten"... */
@@ -4280,9 +4499,12 @@
4280#ifdef TRACE_VARIATIONS_IN_DUP_CHECK4499#ifdef TRACE_VARIATIONS_IN_DUP_CHECK
4281 t_type="Re-read";4500 t_type="Re-read";
4282#endif4501#endif
4502 /* {RETRY-READ} */
4283 /* Avoid infinite loop: */4503 /* Avoid infinite loop: */
4284 if (invalid_rec == rec_id) {4504 if (invalid_rec == rec_id) {
4285 /* Should not happen! */4505 /* Should not happen! */
4506 if (!tab_record_corrupt(ot, XT_GET_DISK_4(rec_head.tr_row_id_4), rec_id, true, 6))
4507 goto failed;
4286#ifdef XT_CRASH_DEBUG4508#ifdef XT_CRASH_DEBUG
4287 /* Generate a core dump! */4509 /* Generate a core dump! */
4288 xt_crash_me();4510 xt_crash_me();
@@ -4327,7 +4549,7 @@
4327 if (XT_REC_IS_FREE(rec_head.tr_rec_type_1)) {4549 if (XT_REC_IS_FREE(rec_head.tr_rec_type_1)) {
4328 /* Should not happen: */4550 /* Should not happen: */
4329 if (invalid_rec != var_rec_id) {4551 if (invalid_rec != var_rec_id) {
4330 var_rec_id = invalid_rec;4552 invalid_rec = var_rec_id;
4331 goto retry;4553 goto retry;
4332 }4554 }
4333 /* Assume end of list. */4555 /* Assume end of list. */
@@ -4364,11 +4586,14 @@
4364 }4586 }
4365 break;4587 break;
4366 case XT_XN_REREAD:4588 case XT_XN_REREAD:
4589 /* {RETRY-READ} */
4367 if (invalid_rec != var_rec_id) {4590 if (invalid_rec != var_rec_id) {
4368 var_rec_id = invalid_rec;4591 invalid_rec = var_rec_id;
4369 goto retry;4592 goto retry;
4370 }4593 }
4371 /* Assume end of list. */4594 /* Assume end of list. */
4595 if (!tab_record_corrupt(ot, row_id, invalid_rec, true, 7))
4596 goto failed;
4372#ifdef XT_CRASH_DEBUG4597#ifdef XT_CRASH_DEBUG
4373 /* Should not happen! */4598 /* Should not happen! */
4374 xt_crash_me();4599 xt_crash_me();
@@ -5068,6 +5293,8 @@
5068 ot->ot_on_page = FALSE;5293 ot->ot_on_page = FALSE;
5069 goto next_page;5294 goto next_page;
5070 }5295 }
5296 if (!tab_record_corrupt(ot, XT_GET_DISK_4(((XTTabRecHeadDPtr) buff_ptr)->tr_row_id_4), invalid_rec, true, 8))
5297 return XT_ERR;
5071#ifdef XT_CRASH_DEBUG5298#ifdef XT_CRASH_DEBUG
5072 /* Should not happen! */5299 /* Should not happen! */
5073 xt_crash_me();5300 xt_crash_me();
@@ -5240,7 +5467,7 @@
5240 return FALSE;5467 return FALSE;
5241}5468}
52425469
5243static void tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size)5470xtPublic void xt_tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size)
5244{5471{
5245 char *nptr;5472 char *nptr;
52465473
@@ -5316,7 +5543,7 @@
5316{5543{
5317 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];5544 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
53185545
5319 tab_make_table_name(tab, table_name, sizeof(table_name));5546 xt_tab_make_table_name(tab, table_name, sizeof(table_name));
5320 return tab_exec_repair_pending(tab->tab_db, REP_FIND, table_name);5547 return tab_exec_repair_pending(tab->tab_db, REP_FIND, table_name);
5321}5548}
53225549
@@ -5326,7 +5553,7 @@
5326 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];5553 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
53275554
5328 tab->tab_repair_pending = FALSE;5555 tab->tab_repair_pending = FALSE;
5329 tab_make_table_name(tab, table_name, sizeof(table_name));5556 xt_tab_make_table_name(tab, table_name, sizeof(table_name));
5330 tab_exec_repair_pending(tab->tab_db, REP_DEL, table_name);5557 tab_exec_repair_pending(tab->tab_db, REP_DEL, table_name);
5331 }5558 }
5332}5559}
@@ -5337,7 +5564,7 @@
5337 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];5564 char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
53385565
5339 tab->tab_repair_pending = TRUE;5566 tab->tab_repair_pending = TRUE;
5340 tab_make_table_name(tab, table_name, sizeof(table_name));5567 xt_tab_make_table_name(tab, table_name, sizeof(table_name));
5341 tab_exec_repair_pending(tab->tab_db, REP_ADD, table_name);5568 tab_exec_repair_pending(tab->tab_db, REP_ADD, table_name);
5342 }5569 }
5343}5570}
53445571
=== modified file 'storage/pbxt/src/table_xt.h'
--- storage/pbxt/src/table_xt.h 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/table_xt.h 2010-09-17 10:32:54 +0000
@@ -507,6 +507,7 @@
507int xt_tab_compare_paths(char *n1, char *n2);507int xt_tab_compare_paths(char *n1, char *n2);
508void xt_tab_init_db(struct XTThread *self, struct XTDatabase *db);508void xt_tab_init_db(struct XTThread *self, struct XTDatabase *db);
509void xt_tab_exit_db(struct XTThread *self, struct XTDatabase *db);509void xt_tab_exit_db(struct XTThread *self, struct XTDatabase *db);
510void xt_tab_check_free_lists(struct XTThread *self, XTOpenTablePtr ot, bool check_recs, bool correct_count);
510void xt_check_tables(struct XTThread *self);511void xt_check_tables(struct XTThread *self);
511512
512char *xt_tab_file_to_name(size_t size, char *tab_name, char *file_name);513char *xt_tab_file_to_name(size_t size, char *tab_name, char *file_name);
@@ -572,6 +573,7 @@
572void xt_tab_disable_index(XTTableHPtr tab, u_int ind_error);573void xt_tab_disable_index(XTTableHPtr tab, u_int ind_error);
573void xt_tab_set_index_error(XTTableHPtr tab);574void xt_tab_set_index_error(XTTableHPtr tab);
574575
576void xt_tab_make_table_name(XTTableHPtr tab, char *table_name, size_t size);
575xtBool xt_tab_is_table_repair_pending(XTTableHPtr tab);577xtBool xt_tab_is_table_repair_pending(XTTableHPtr tab);
576void xt_tab_table_repaired(XTTableHPtr tab);578void xt_tab_table_repaired(XTTableHPtr tab);
577void xt_tab_set_table_repair_pending(XTTableHPtr tab);579void xt_tab_set_table_repair_pending(XTTableHPtr tab);
578580
=== modified file 'storage/pbxt/src/thread_xt.cc'
--- storage/pbxt/src/thread_xt.cc 2010-05-06 12:42:28 +0000
+++ storage/pbxt/src/thread_xt.cc 2010-09-17 10:32:54 +0000
@@ -224,11 +224,16 @@
224#else224#else
225 /* Use the buffer, unless it is too small */225 /* Use the buffer, unless it is too small */
226 va_list ap2;226 va_list ap2;
227 int bufsize;
227228
228 va_copy(ap2, ap);229 va_copy(ap2, ap);
229 if (vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE, fmt, ap) >= DEFAULT_LOG_BUFFER_SIZE) {230 bufsize = vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE, fmt, ap);
230 if (vasprintf(&log_string, fmt, ap2) == -1)231 if (bufsize >= DEFAULT_LOG_BUFFER_SIZE) {
232 log_string = (char *) malloc(bufsize + 1);
233 if (vsnprintf(log_string, bufsize + 1, fmt, ap2) > bufsize) {
234 free(log_string);
231 log_string = NULL;235 log_string = NULL;
236 }
232 }237 }
233 else238 else
234 log_string = buffer;239 log_string = buffer;
235240
=== modified file 'storage/pbxt/src/xaction_xt.cc'
--- storage/pbxt/src/xaction_xt.cc 2010-05-05 10:59:57 +0000
+++ storage/pbxt/src/xaction_xt.cc 2010-09-17 10:32:54 +0000
@@ -1558,6 +1558,8 @@
1558 * Because we are only here because the record was valid but not1558 * Because we are only here because the record was valid but not
1559 * clean (you can confirm this by looking at the code that1559 * clean (you can confirm this by looking at the code that
1560 * calls this function).1560 * calls this function).
1561 *
1562 * See {RETRY-READ}
1561 */1563 */
1562 return XT_XN_REREAD;1564 return XT_XN_REREAD;
1563 }1565 }
@@ -1743,7 +1745,7 @@
1743 }1745 }
1744 else {1746 else {
1745 xn_log_id = x_log_id;1747 xn_log_id = x_log_id;
1746 x_log_offset = x_log_offset;1748 xn_log_offset = x_log_offset;
1747 }1749 }
1748 }1750 }
1749 xn_id++;1751 xn_id++;
17501752
=== modified file 'storage/pbxt/src/xt_defs.h'
--- storage/pbxt/src/xt_defs.h 2010-06-01 19:52:20 +0000
+++ storage/pbxt/src/xt_defs.h 2010-09-17 10:32:54 +0000
@@ -397,6 +397,24 @@
397 */397 */
398#define XT_XLOG_FLUSH_FREQ 1000398#define XT_XLOG_FLUSH_FREQ 1000
399399
400/*
401 * Define here if you want to check (and correct) the table free list
402 * counts. The free list counts are not durable, because they are not
403 * written to the log.
404 *
405 * The row free count is most critical because it can be used to
406 * estimate the the of rows in the record.
407 */
408#define XT_CHECK_ROW_FREE_COUNT
409#ifdef DEBUG
410#define XT_CHECK_RECORD_FREE_COUNT
411#endif
412#define XT_CORRECT_TABLE_FREE_COUNT
413
414#if defined(XT_CHECK_ROW_FREE_COUNT) && defined(XT_CORRECT_TABLE_FREE_COUNT)
415#define XT_ROW_COUNT_CORRECTED
416#endif
417
400/* ----------------------------------------------------------------------418/* ----------------------------------------------------------------------
401 * GLOBAL CONSTANTS419 * GLOBAL CONSTANTS
402 */420 */
@@ -782,7 +800,7 @@
782#define MX_ULONG_T uint32_t800#define MX_ULONG_T uint32_t
783#define MX_ULONGLONG_T uint64_t801#define MX_ULONGLONG_T uint64_t
784#define MX_LONGLONG_T uint64_t802#define MX_LONGLONG_T uint64_t
785#define MX_CHARSET_INFO const struct charset_info_st803#define MX_CHARSET_INFO struct charset_info_st
786#define MX_CONST_CHARSET_INFO const struct charset_info_st 804#define MX_CONST_CHARSET_INFO const struct charset_info_st
787#define MX_CONST const805#define MX_CONST const
788#define MX_BITMAP MyBitmap806#define MX_BITMAP MyBitmap
@@ -873,7 +891,11 @@
873#define MX_ULONGLONG_T ulonglong891#define MX_ULONGLONG_T ulonglong
874#define MX_LONGLONG_T longlong892#define MX_LONGLONG_T longlong
875#define MX_CHARSET_INFO CHARSET_INFO893#define MX_CHARSET_INFO CHARSET_INFO
876#define MX_CONST_CHARSET_INFO const struct charset_info_st 894#ifdef MARIADB_BASE_VERSION
895#define MX_CONST_CHARSET_INFO const struct charset_info_st
896#else
897#define MX_CONST_CHARSET_INFO struct charset_info_st
898#endif
877#define MX_CONST 899#define MX_CONST
878#define MX_BITMAP MY_BITMAP900#define MX_BITMAP MY_BITMAP
879#define MX_BIT_SIZE() n_bits901#define MX_BIT_SIZE() n_bits

Subscribers

People subscribed via source and target branches