Bug #56770 Ndb : Per-row GCIs changed after System Restart
Submitted: 14 Sep 2010 12:46 Modified: 16 Sep 2010 16:48
Reporter: Frazer Clement Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S3 (Non-critical)
Version:mysql-5.1-telco-6.3.11 OS:Any
Assigned to: Frazer Clement CPU Architecture:Any

[14 Sep 2010 12:46] Frazer Clement
Description:
Ndb stores a Global Checkpoint Index (GCI) for each row in its tables.
This value contains the GCI in which the last transaction modifying the row committed.
As such it gives a kind of coarse-grained row version.

When a cluster is shutdown or crashed, after subsequent recovery, some rows may have different, higher, GCI values.  Many rows are given similar GCI values.

Rows should keep their GCI values over a system restart. 

How to repeat:
1) Create a table 
   mysql> CREATE TABLE test.t1 (a int primary key) engine=ndb;
2) Insert a row
   mysql> INSERT INTO test.t1 VALUES (1,1);
3) Force a local checkpoint
   ndb_mgm> ALL DUMP 7099
4) Insert another row
   mysql> INSERT INTO test.t1 VALUES (2,2);
5) Examine row GCIs
   shell> ndb_select_all --gci -dtest t1
5) Restart cluster
   ndb_mgm> ALL RESTART
6) Examine row GCIs
   shell> ndb_select_all --gci -dtest t1

Row 1 (restored from LCP) will have a higher GCI than row 2 (restored from Redo).

Suggested fix:
Modify restore from LCP to avoid per-row GCI modification.
[14 Sep 2010 17:10] Frazer Clement
Problem related to change of LCP format in 6.3.11.
[14 Sep 2010 17:36] Frazer Clement
Patch against 6.3

Attachment: bug56770-6.3.patch (text/x-patch), 6.16 KiB.

[14 Sep 2010 17:43] Jonas Oreland
patch ok
comment: does testcase fail before patch ? 

if yes, ok to push
[14 Sep 2010 17:55] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118235

3293 Frazer Clement	2010-09-14
      Bug#56770 Ndb : Per-row GCIs changed after System Restart
      
      Per-row GCIs are restored in raw format from LCP files.
      The normal operation commit processing then tramples the row GCI.
      This is avoided by temporarily disabling GCI 'maintenance' during LCP
      restore in TUP.
      
      The testRestartGCI testcase is modified and extended to :
       1) Delay when inserting rows to rows with different GCIs in the DB
       2) Check that the row GCIs are exactly what they should be
       3) Restart twice
          First time (most likely) data will be restored from Redo
          Second time data will be restored from LCP as the first restart included
          an LCP step.
[14 Sep 2010 18:21] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118240

3293 Frazer Clement	2010-09-14
      Bug#56770 Ndb : Per-row GCIs changed after System Restart
      
      Per-row GCIs are restored in raw format from LCP files.
      The normal operation commit processing then tramples the row GCI.
      This is avoided by temporarily disabling GCI 'maintenance' during LCP
      restore in TUP.
      
      The testRestartGCI testcase is modified and extended to :
       1) Delay when inserting rows to rows with different GCIs in the DB
       2) Check that the row GCIs are exactly what they should be
       3) Restart twice
          First time (most likely) data will be restored from Redo
          Second time data will be restored from LCP as the first restart included
          an LCP step.
      
      Recommit with more frugal use of borrowed storage space to ease 7.0 merge.
[14 Sep 2010 18:36] Bugs System
Pushed into mysql-5.1-telco-7.0 5.1.47-ndb-7.0.19 (revid:frazer@mysql.com-20100914182652-rvfdpoqclkc0rdot) (version source revid:frazer@mysql.com-20100914182652-rvfdpoqclkc0rdot) (merge vers: 5.1.47-ndb-7.0.19) (pib:21)
[14 Sep 2010 18:38] Bugs System
Pushed into mysql-5.1-telco-6.3 5.1.47-ndb-6.3.38 (revid:frazer@mysql.com-20100914181946-gjm9fzckfnraunys) (version source revid:frazer@mysql.com-20100914181946-gjm9fzckfnraunys) (merge vers: 5.1.47-ndb-6.3.38) (pib:21)
[14 Sep 2010 18:39] Frazer Clement
Also pushed to 7.1.8.
[16 Sep 2010 16:48] Jon Stephens
Documented bugfix int he NDB-6.3.38, 7.0.19, and 7.1.8 changelogs, as follows:

        NDB stores, for each row in each NDB table, a Global Checkpoint
        Index (GCI) which identifies the last committed transaction that
        modified the row. As such, a GCI can be thought of as a
        coarse-grained row version. Due to changes in the format used by
        NDB to store local checkpoints (LCPs) in MySQL Cluster NDB
        6.3.11, it could happen that, following cluster shutdown and
        subsequent recovery, the GCI values for some rows could be
        changed unnecessarily; this could possibly, over the course of
        many node or system restarts (or both), lead to an inconsistent
        database.

Closed.
[29 Sep 2010 10:54] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/119379

3288 Martin Skold	2010-09-29 [merge]
      Merge
      removed:
        cluster_change_hist.txt
      modified:
        mysql-test/collections/default.experimental
        mysql-test/suite/ndb/r/ndb_database.result
        mysql-test/suite/ndb/t/ndb_database.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster.h
        sql/ha_ndbcluster_binlog.cc
        sql/handler.cc
        sql/handler.h
        sql/sql_show.cc
        sql/sql_table.cc
        storage/ndb/include/kernel/GlobalSignalNumbers.h
        storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp
        storage/ndb/include/mgmapi/mgmapi.h
        storage/ndb/include/ndbapi/NdbDictionary.hpp
        storage/ndb/src/kernel/blocks/ERROR_codes.txt
        storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
        storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
        storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
        storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
        storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
        storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
        storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
        storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
        storage/ndb/src/kernel/blocks/dbtux/DbtuxBuild.cpp
        storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
        storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
        storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
        storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp
        storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp
        storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
        storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp
        storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp
        storage/ndb/src/kernel/blocks/suma/Suma.cpp
        storage/ndb/src/kernel/blocks/suma/Suma.hpp
        storage/ndb/src/kernel/main.cpp
        storage/ndb/src/ndbapi/DictCache.cpp
        storage/ndb/src/ndbapi/DictCache.hpp
        storage/ndb/src/ndbapi/NdbDictionary.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
        storage/ndb/test/include/NdbRestarter.hpp
        storage/ndb/test/ndbapi/testIndex.cpp
        storage/ndb/test/ndbapi/testRestartGci.cpp
        storage/ndb/test/ndbapi/testSystemRestart.cpp
        storage/ndb/test/run-test/daily-basic-tests.txt
        storage/ndb/test/src/NdbRestarter.cpp