Commit 7bf78e09 authored by pekka@sama.ndb.mysql.com's avatar pekka@sama.ndb.mysql.com
Browse files

Merge sama.ndb.mysql.com:/export/space/pekka/ndb/version/my50-ndb

into  sama.ndb.mysql.com:/export/space/pekka/ndb/version/my50-bug31477
parents 18735828 bf5c1848
Loading
Loading
Loading
Loading
+98 −0
Original line number Diff line number Diff line
drop table if exists t1;
create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
begin;
update t1 set c = 2 where b = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
rollback;
drop table t1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
begin;
update t1 set c = 2 where b = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
rollback;
drop table t1;
--con1
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (1,1,1);
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--con1 c=30
select * from t1 where b >= 1 order by b;
a	b	c
1	1	30
2	2	2
3	3	3
4	4	4
--con2 c=1
select * from t1 where b >= 1 order by b;
a	b	c
1	1	1
2	2	2
3	3	3
4	4	4
--con1
delete from t1 where a = 1;
--con1 c=none
select * from t1 where b >= 1 order by b;
a	b	c
2	2	2
3	3	3
4	4	4
--con2 c=1
select * from t1 where b >= 1 order by b;
a	b	c
1	1	1
2	2	2
3	3	3
4	4	4
--con1
commit;
--con1 c=none
select * from t1 where b >= 1 order by b;
a	b	c
2	2	2
3	3	3
4	4	4
--con2 c=none
select * from t1 where b >= 1 order by b;
a	b	c
2	2	2
3	3	3
4	4	4
--con1
begin;
insert into t1 values (1,1,1);
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--con1 c=30
select * from t1 where b >= 1 order by b;
a	b	c
1	1	30
2	2	2
3	3	3
4	4	4
--con2 c=none
select * from t1 where b >= 1 order by b;
a	b	c
2	2	2
3	3	3
4	4	4
drop table t1;
+109 −0
Original line number Diff line number Diff line
--source include/have_ndb.inc

--disable_warnings
drop table if exists t1;
--enable_warnings

# setup

connect (con1,localhost,root,,test);
connect (con2,localhost,root,,test);

# unique index
connection con1;
create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);

begin;
insert into t1 values (1,1,1);

connection con2;
begin;
--error 1205
update t1 set c = 2 where b = 1;
rollback;

connection con1;
rollback;
drop table t1;
# ordered index

connection con1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);

begin;
insert into t1 values (1,1,1);

connection con2;
begin;
--error 1205
update t1 set c = 2 where b = 1;
rollback;

connection con1;
rollback;
drop table t1;

# multiple versions

--echo --con1
connection con1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (1,1,1);
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);

begin;
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;

--echo --con1 c=30
select * from t1 where b >= 1 order by b;
--echo --con2 c=1
connection con2;
select * from t1 where b >= 1 order by b;

--echo --con1
connection con1;
delete from t1 where a = 1;

--echo --con1 c=none
select * from t1 where b >= 1 order by b;
--echo --con2 c=1
connection con2;
select * from t1 where b >= 1 order by b;

--echo --con1
connection con1;
commit;

--echo --con1 c=none
select * from t1 where b >= 1 order by b;
--echo --con2 c=none
connection con2;
select * from t1 where b >= 1 order by b;

--echo --con1
connection con1;
begin;
insert into t1 values (1,1,1);
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;

--echo --con1 c=30
select * from t1 where b >= 1 order by b;
--echo --con2 c=none
connection con2;
select * from t1 where b >= 1 order by b;

# this fails with "no such table" via con2 ???
connection con1;
drop table t1;
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ static const char * fms[] = {
  "%d", "0x%08x",      // Int32
  "%u", "0x%08x",      // Uint32
  "%lld", "0x%016llx", // Int64
  "%llu", "0x%016llx"  // Uint64
  "%llu", "0x%016llx", // Uint64
  "%llu", "0x%016llx"  // UintPtr
};

+21 −1
Original line number Diff line number Diff line
@@ -1085,7 +1085,7 @@ public:
  /*
   * TUX checks if tuple is visible to scan.
   */
  bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId);
  bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId);

private:
  BLOCK_DEFINES(Dbtup);
@@ -1942,6 +1942,8 @@ private:
  bool getPageThroughSavePoint(Operationrec* const regOperPtr,
                               Operationrec* const leaderOpPtr);

  bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);

  Uint32 calculateChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);
  void setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);

@@ -2467,4 +2469,22 @@ bool Dbtup::isPageUndoLogged(Fragrecord* const regFragPtr,
  return false;
}//Dbtup::isUndoLoggingNeeded()

inline
bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
{
  while (true) {
    if (savepointId > loopOpPtr.p->savePointId) {
      jam();
      return true;
    }
    // note 5.0 has reversed next/prev pointers
    loopOpPtr.i = loopOpPtr.p->nextActiveOp;
    if (loopOpPtr.i == RNIL) {
      break;
    }
    ptrCheckGuard(loopOpPtr, cnoOfOprec, operationrec);
  }
  return false;
}

#endif
+73 −23
Original line number Diff line number Diff line
@@ -246,8 +246,18 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn
  return ret;
}

/*
 * TUX index contains all tuple versions.  A scan in TUX has scanned
 * one of them and asks if it can be returned as scan result.  This
 * depends on trans id, dirty read flag, and savepoint within trans.
 *
 * Previously this faked a ZREAD operation and used getPage().
 * In TUP getPage() is run after ACC locking, but TUX comes here
 * before ACC access.  Instead of modifying getPage() it is more
 * clear to do the full check here.
 */
bool
Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId)
Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId)
{
  ljamEntry();
  FragrecordPtr fragPtr;
@@ -256,33 +266,73 @@ Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 tra
  TablerecPtr tablePtr;
  tablePtr.i = fragPtr.p->fragTableId;
  ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
  // get page
  PagePtr pagePtr;
  Uint32 fragPageId = tupAddr >> MAX_TUPLES_BITS;
  Uint32 pageIndex = tupAddr & ((1 << MAX_TUPLES_BITS ) - 1);
  // use temp op rec
  Operationrec tempOp;
  tempOp.fragPageId = fragPageId;
  tempOp.pageIndex = pageIndex;
  tempOp.transid1 = transId1;
  tempOp.transid2 = transId2;
  tempOp.savePointId = savePointId;
  tempOp.optype = ZREAD;
  tempOp.dirtyOp = 1;
  if (getPage(pagePtr, &tempOp, fragPtr.p, tablePtr.p)) {
    /*
    * We use the normal getPage which will return the tuple to be used
    * for this transaction and savepoint id.  If its tuple version
    * equals the requested then we have a visible tuple otherwise not.
    */
    ljam();
    Uint32 read_tupVersion = pagePtr.p->pageWord[tempOp.pageOffset + 1];
    if (read_tupVersion == tupVersion) {
  pagePtr.i = pageId;
  ptrCheckGuard(pagePtr, cnoOfPage, page);

  OperationrecPtr currOpPtr;
  currOpPtr.i = pagePtr.p->pageWord[pageOffset];
  if (currOpPtr.i == RNIL) {
    ljam();
    // tuple has no operation, any scan can see it
    return true;
  }
  ptrCheckGuard(currOpPtr, cnoOfOprec, operationrec);

  const bool sameTrans =
    transId1 == currOpPtr.p->transid1 &&
    transId2 == currOpPtr.p->transid2;

  bool res = false;
  OperationrecPtr loopOpPtr = currOpPtr;

  if (!sameTrans) {
    ljam();
    if (!dirty) {
      ljam();
      if (currOpPtr.p->prevActiveOp == RNIL) {
        ljam();
        // last op - TUX makes ACC lock request in same timeslice
        res = true;
      }
    }
    else {
      // loop to first op (returns false)
      find_savepoint(loopOpPtr, 0);
      const Uint32 op_type = loopOpPtr.p->optype;

      if (op_type != ZINSERT) {
        ljam();
        // read committed version from the page
        const Uint32 origVersion = pagePtr.p->pageWord[pageOffset + 1];
        if (origVersion == tupVersion) {
          ljam();
          res = true;
        }
      }
    }
  return false;
  }
  else {
    ljam();
    // for own trans, ignore dirty flag

    if (find_savepoint(loopOpPtr, savePointId)) {
      ljam();
      const Uint32 op_type = loopOpPtr.p->optype;

      if (op_type != ZDELETE) {
        ljam();
        // check if this op has produced the scanned version
        Uint32 loopVersion = loopOpPtr.p->tupVersion;
        if (loopVersion == tupVersion) {
          ljam();
          res = true;
        }
      }
    }
  }

  return res;
}

// ordered index build
Loading