Bug #39268 No transaction hints used to update SYSTAB_0 for autoincrement and PK-less table
Submitted: 5 Sep 2008 7:05 Modified: 22 Sep 2009 14:18
Reporter: Mikael Ronström Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S5 (Performance)
Version:mysql-5.1-telco-7.0 OS:Any
Assigned to: Martin Skold CPU Architecture:Any
Tags: (5.1.27-ndb-6.3, 16)

[5 Sep 2008 7:05] Mikael Ronström
Description:
When running the DBT2 benchmark I had severe scalability issues.
After investigating the issue I discovered that the HISTORY table
had no primary key and that there were transactions towards nodes
that should in reality be idle. This was due to two bugs, the first
being that updates of SYSTAB_0 to get a unique identifier didn't
use transaction hints and that the cache_size used was only 1, thus
each insert into the HISTORY table had to also update the SYSTAB_0
record for the HISTORY table. This meant that this record became a
"hotspot" in the DBT2 benchmark.

How to repeat:
Run inserts into a table with autoincrement which has only one partition in
nodegroup 0. Watch the load in NG1 how it goes up as more and
more although it should not need.

Suggested fix:
In the method Ndb::opTupleIdOnNdb there is a call to
startTransaction without parameters for transaction hints.
Change this to use the transaction hint variant of the
startTransaction-call. This means we will get the transaction
sent to the proper node and thus decrease the impact of
any hotspots due to creating key numbers in steps of 1
on autoincrement tables.
[4 Feb 2009 14:08] Martin Skold
http://lists.mysql.com/commits/65174
[10 Feb 2009 16:31] 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/65775

2836 Martin Skold	2009-02-10 [merge]
      Merge
[11 Feb 2009 15:17] 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/65920

3252 Martin Skold	2009-02-11 [merge]
      Merge
[11 Feb 2009 20:45] 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/65957

3257 Martin Skold	2009-02-11 [merge]
      Merge
[11 Feb 2009 21:04] Bugs System
Pushed into 5.1.31-ndb-6.4.3 (revid:martin.skold@mysql.com-20090211204523-03nx13fjekybwez2) (version source revid:martin.skold@mysql.com-20090211204523-03nx13fjekybwez2) (merge vers: 5.1.31-ndb-6.4.3) (pib:6)
[11 Feb 2009 21:06] Bugs System
Pushed into 5.1.31-ndb-6.2.17 (revid:martin.skold@mysql.com-20090210162313-g4ou3ovzoyoljaej) (version source revid:martin.skold@mysql.com-20090204135340-m9u7dfp2g3ul8ass) (merge vers: 5.1.31-ndb-6.2.17) (pib:6)
[11 Feb 2009 21:07] Bugs System
Pushed into 5.1.31-ndb-6.3.23 (revid:martin.skold@mysql.com-20090210163054-bcupy4stktagp5rt) (version source revid:martin.skold@mysql.com-20090210163054-bcupy4stktagp5rt) (merge vers: 5.1.31-ndb-6.3.23) (pib:6)
[18 Sep 2009 13:58] 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/83739

2998 Martin Skold	2009-09-18
      bug#39268  No transaction hints used to update SYSTAB_0 for autoincrement and PK-less table
      modified:
        storage/ndb/src/ndbapi/Ndb.cpp
[18 Sep 2009 14:00] Martin Skold
First patch is incorrect, hint should be against table SYSTAB_0
[21 Sep 2009 11:44] 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/83902

3053 Martin Skold	2009-09-21 [merge]
      Merge
      modified:
        mysql-test/include/restart_mysqld.inc
        storage/ndb/src/ndbapi/Ndb.cpp
[21 Sep 2009 11:46] 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/83906

3012 Martin Skold	2009-09-21 [merge]
      Merge
      modified:
        storage/ndb/src/ndbapi/Ndb.cpp
[21 Sep 2009 12:26] 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/83920

3009 Martin Skold	2009-09-21 [merge]
      Merge
      modified:
        mysql-test/suite/ndb/r/ndb_multi.result
        mysql-test/suite/ndb/t/ndb_multi.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster_binlog.cc
        sql/ha_ndbcluster_binlog.h
        storage/ndb/src/ndbapi/Ndb.cpp
[21 Sep 2009 13:52] 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/83946

3057 Martin Skold	2009-09-21 [merge]
      Merge
      modified:
        mysql-test/include/restart_mysqld.inc
        mysql-test/suite/ndb/r/ndb_multi.result
        mysql-test/suite/ndb/t/ndb_multi.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster_binlog.cc
        sql/ha_ndbcluster_binlog.h
        storage/ndb/src/ndbapi/Ndb.cpp
[21 Sep 2009 14:23] 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/83957

3024 Martin Skold	2009-09-21 [merge]
      Merge
      modified:
        mysql-test/suite/ndb/r/ndb_multi.result
        mysql-test/suite/ndb/t/ndb_multi.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster_binlog.cc
        sql/ha_ndbcluster_binlog.h
        storage/ndb/src/ndbapi/Ndb.cpp
[22 Sep 2009 6:18] 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/84025

3020 Martin Skold	2009-09-22 [merge]
      Merge
      modified:
        mysql-test/suite/ndb/r/ndb_multi.result
        mysql-test/suite/ndb/t/ndb_multi.test
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster_binlog.cc
        sql/ha_ndbcluster_binlog.h
        storage/ndb/src/ndbapi/Ndb.cpp
[22 Sep 2009 14:18] Jon Stephens
Documented bugfix in the NDB-6.2.17, 6.3.23, and 6.4.3 changelogs, as follows:

        Updates of the SYSTAB_0 system table to obtain a unique
        identifier did not use transaction hints for tables having no
        primary key. In such cases the NDB kernel used a cache size of
        1. This meant that each insert into a table not having a primary
        key required an update of the corresponding SYSTAB_0 entry,
        creating a potential performance bottleneck.

        With this fix, inserts on NDB tables without primary keys can be
        under some conditions be performed up to 100% faster than 
        previously.

Closed.

(Note: Changelog entry appearing for 6.4.3 means that the fix also appears in NDB 7.0.4 and later releases.)
[30 Sep 2009 8:13] Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:frazer@mysql.com-20090929142503-sst6g3fs0vx9fgil) (version source revid:martin.skold@mysql.com-20090918135924-dr4wa8cz36yszxes) (merge vers: 5.1.37-ndb-6.2.19) (pib:11)
[30 Sep 2009 8:13] Bugs System
Pushed into 5.1.37-ndb-6.3.28 (revid:jonas@mysql.com-20090930070741-13u316s7s2l7e1ej) (version source revid:martin.skold@mysql.com-20090921135309-q77376ub6jvk10mg) (merge vers: 5.1.37-ndb-6.3.27) (pib:11)
[30 Sep 2009 8:14] Bugs System
Pushed into 5.1.37-ndb-7.0.9 (revid:jonas@mysql.com-20090930075942-1q6asjcp0gaeynmj) (version source revid:martin.skold@mysql.com-20090921142346-kg9qrq7flqgd6wum) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[30 Sep 2009 8:15] Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:jonas@mysql.com-20090930080049-1c8a8cio9qgvhq35) (version source revid:martin.skold@mysql.com-20090922061929-qjq5pztm76lwa7ri) (merge vers: 5.1.35-ndb-7.1.0) (pib:11)
[22 Feb 2011 16:07] Linhai Song
I find some similar places in mysql-cluster-gpl-6.3.20. In these places, startTransaction() is called with no parameters, and getNdbOperation() is called with a dataTable parameter. 

If we move the dataTable parameter from getNdbOperation() to startTransaction(), could we get a better performance?

The places I find include:

mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 1616
       if ((trans= ndb->startTransaction()) == 0)
mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 1649
         r|= (op= trans->getNdbOperation(ndbtab)) == 0;

while (1)
 {
    if ((trans= ndb->startTransaction()) == 0)
     goto err;
    {
     NdbOperation *op= 0;
     int r= 0;

     /* read the bitmap exlusive */
     r|= (op= trans->getNdbOperation(ndbtab)) == 0;
     DBUG_ASSERT(r == 0);
     r|= op->readTupleExclusive();
     DBUG_ASSERT(r == 0);
   

==============================================================
mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 3685
       NdbTransaction *trans= ndb->startTransaction();
mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 3703
         if ((_op= trans->getNdbOperation(reptab)) == NULL) abort();

for (;;)
 {
    NdbTransaction *trans= ndb->startTransaction();
    if (trans == NULL)
    {
     ndberror= ndb->getNdbError();
     break;
    }
    NdbRecAttr *col_binlog_type_rec_attr[2];
    NdbRecAttr *col_conflict_fn_rec_attr[2]= {NULL, NULL};
    uint32 ndb_binlog_type[2];
    const uint sz= 256;
    char ndb_conflict_fn_buf[2*sz];
    char *ndb_conflict_fn[2]= {ndb_conflict_fn_buf, ndb_conflict_fn_buf+sz};
    NdbOperation *op[2];
    uint32 i, id= 0;
    for (i= 0; i < 2; i++)
    {
     NdbOperation *_op;
     DBUG_PRINT("info", ("reading[%u]: %s,%s,%u", i, db, table_name, id));
     if ((_op= trans->getNdbOperation(reptab)) == NULL) abort();
     if (_op->readTuple(NdbOperation::LM_CommittedRead)) abort();
     ndb_pack_varchar(col_db, tmp_buf, db, strlen(db));
     if (_op->equal(col_db->getColumnNo(), tmp_buf)) abort();
     ndb_pack_varchar(col_table_name, tmp_buf, table_name, strlen(table_name));
     if (_op->equal(col_table_name->getColumnNo(), tmp_buf)) abort();
     if (_op->equal(col_server_id->getColumnNo(), id)) abort();
     if ((col_binlog_type_rec_attr[i]=
          _op->getValue(col_binlog_type, (char *)&(ndb_binlog_type[i]))) == 0) abort();
     /* optional columns */
============================================================================
mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 1957
       if ((trans= ndb->startTransaction()) == 0)
mysql-cluster-gpl-6.3.20/sql/ha_ndbcluster_binlog.cc : 1963
         r|= (op= trans->getNdbOperation(ndbtab)) == 0;

while (1)
 {
    const char *log_db= db;
    const char *log_tab= table_name;
    const char *log_subscribers= (char*)schema_subscribers.bitmap;
    uint32 log_type= (uint32)type;
    if ((trans= ndb->startTransaction()) == 0)
     goto err;
    while (1)
    {
     NdbOperation *op= 0;
     int r= 0;
     r|= (op= trans->getNdbOperation(ndbtab)) == 0;
     DBUG_ASSERT(r == 0);
     r|= op->writeTuple();