Below is the list of changes that have just been committed into a local
5.1 repository of jonas. When jonas does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-03-19 13:57:01+01:00, jonas@stripped +14 -0
ndb - bug#35208
remove "common-case" 64 bit changemask
and replace by general anybit-changemask
mysql-test/suite/rpl_ndb/r/rpl_ndb_basic.result@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +20 -0
new testcase
mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +29 -0
new testcase
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +68 -60
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +2 -2
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +20 -56
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +33 -31
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +4 -4
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +4 -0
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +0 -7
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +8 -8
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +1 -1
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +1 -1
remove changemask state (and value from op-rec)
and put it on copy-tuple instead
storage/ndb/test/ndbapi/test_event.cpp@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +173 -0
new testcase
storage/ndb/test/run-test/daily-basic-tests.txt@stripped, 2008-03-19 13:56:57+01:00, jonas@stripped +4 -0
new testcase
diff -Nrup a/mysql-test/suite/rpl_ndb/r/rpl_ndb_basic.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_basic.result
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_basic.result 2007-11-28 11:54:27 +01:00
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_basic.result 2008-03-19 13:56:57 +01:00
@@ -248,3 +248,23 @@ c1
104
105
DROP TABLE t1;
+create table t1 (a int primary key,
+b00 int,b01 int,b02 int,b03 int,b04 int,b05 int,b06 int,b07 int,
+b08 int,b09 int,b10 int,b11 int,b12 int,b13 int,b14 int,b15 int,
+b16 int,b17 int,b18 int,b19 int,b20 int,b21 int,b22 int,b23 int,
+b24 int,b25 int,b26 int,b27 int,b28 int,b29 int,b30 int,b31 int,
+b32 int,b33 int,b34 int,b35 int,b36 int,b37 int,b38 int,b39 int,
+b40 int,b41 int,b42 int,b43 int,b44 int,b45 int,b46 int,b47 int,
+b48 int,b49 int,b50 int,b51 int,b52 int,b53 int,b54 int,b55 int,
+b56 int,b57 int,b58 int,b59 int,b60 int,b61 int,b62 int,b63 int,
+b64 int,b65 int,b66 int,b67 int,b68 int,b69 int,b70 int) engine=ndb;
+insert into t1 (a,b00) values (1,1);
+update t1 set b00 = 2 where a = 1;
+update t1 set b66 = 1 where a = 1;
+select b00 from t1;
+b00
+1
+select b00 from t1;
+b00
+2
+DROP TABLE t1;
diff -Nrup a/mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test 2007-09-06 06:45:47 +02:00
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_basic.test 2008-03-19 13:56:57 +01:00
@@ -267,4 +267,33 @@ SELECT c1 FROM t1 ORDER BY c1 LIMIT 5;
# cleanup
--connection master
DROP TABLE t1;
+
+# bug#35208
+# NOTE: should use ndb_log_updated_only
+create table t1 (a int primary key,
+b00 int,b01 int,b02 int,b03 int,b04 int,b05 int,b06 int,b07 int,
+b08 int,b09 int,b10 int,b11 int,b12 int,b13 int,b14 int,b15 int,
+b16 int,b17 int,b18 int,b19 int,b20 int,b21 int,b22 int,b23 int,
+b24 int,b25 int,b26 int,b27 int,b28 int,b29 int,b30 int,b31 int,
+b32 int,b33 int,b34 int,b35 int,b36 int,b37 int,b38 int,b39 int,
+b40 int,b41 int,b42 int,b43 int,b44 int,b45 int,b46 int,b47 int,
+b48 int,b49 int,b50 int,b51 int,b52 int,b53 int,b54 int,b55 int,
+b56 int,b57 int,b58 int,b59 int,b60 int,b61 int,b62 int,b63 int,
+b64 int,b65 int,b66 int,b67 int,b68 int,b69 int,b70 int) engine=ndb;
+
+insert into t1 (a,b00) values (1,1);
+--sync_slave_with_master
+--connection slave
+update t1 set b00 = 2 where a = 1;
+--connection master
+update t1 set b66 = 1 where a = 1;
+--sync_slave_with_master
+# after bug fix result *should* be different on master/slave
+--connection master
+select b00 from t1;
+--connection slave
+select b00 from t1;
+
+DROP TABLE t1;
+
-- source include/master-slave-end.inc
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2008-02-06 13:08:29 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2008-03-19 13:56:57 +01:00
@@ -365,14 +365,6 @@ public:
Lgman* c_lgman;
Page_cache_client m_pgman;
-// State values
-enum ChangeMaskState {
- DELETE_CHANGES = 0,
- SET_ALL_MASK = 1,
- USE_SAVED_CHANGE_MASK = 2,
- RECALCULATE_CHANGE_MASK = 3
-};
-
enum TransState {
TRANS_IDLE = 0,
TRANS_STARTED = 1,
@@ -818,11 +810,6 @@ struct Operationrec {
};
/*
- * We use 64 bits to save change mask for the most common cases.
- */
- Uint32 saved_change_mask[2];
-
- /*
* State variables on connection.
* State variable on tuple after multi-updates
* Is operation undo logged or not
@@ -840,7 +827,7 @@ struct Operationrec {
unsigned int op_type : 3;
unsigned int delete_insert_flag : 1;
unsigned int primary_replica : 1;
- unsigned int change_mask_state : 2;
+ unsigned int unused : 2;
unsigned int m_disk_preallocated : 1;
unsigned int m_load_diskpage_on_commit : 1;
unsigned int m_wait_log_buffer : 1;
@@ -1586,11 +1573,9 @@ struct KeyReqStruct {
Uint32 trans_id2;
Uint32 TC_index;
// next 2 apply only to attrids >= 64 (zero otherwise)
- Uint32 max_attr_id_updated;
- Uint32 no_changed_attrs;
BlockReference TC_ref;
BlockReference rec_blockref;
- bool change_mask_calculated;
+
/*
* A bit mask where a bit set means that the update or insert
* was updating this record.
@@ -2437,10 +2422,13 @@ private:
Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);
Uint32 decr_tup_version(Uint32 tuple_version);
- void set_change_mask_state(Operationrec * const, ChangeMaskState);
- ChangeMaskState get_change_mask_state(Operationrec * const);
- void update_change_mask_info(KeyReqStruct * const, Operationrec * const);
- void set_change_mask_info(KeyReqStruct * const, Operationrec * const);
+ void update_change_mask_info(const Tablerec*, Uint32* dst, const Uint32*src);
+ void set_change_mask_info(const Tablerec*, Uint32* dst);
+ void clear_change_mask_info(const Tablerec*, Uint32* dst);
+ void copy_change_mask_info(const Tablerec*, Uint32* dst, const Uint32* src);
+ void set_commit_change_mask_info(const Tablerec*,
+ KeyReqStruct*,
+ const Operationrec*);
//------------------------------------------------------------------
//------------------------------------------------------------------
@@ -2738,10 +2726,6 @@ private:
void findBeforeValueOperation(OperationrecPtr& befOpPtr,
OperationrecPtr firstOpPtr);
- void calculateChangeMask(Page* PagePtr,
- Tablerec* regTabPtr,
- KeyReqStruct * req_struct);
-
void updateGcpId(KeyReqStruct *req_struct,
Operationrec* regOperPtr,
Fragrecord* regFragPtr,
@@ -3060,6 +3044,25 @@ private:
Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
Uint32 get_len(Ptr<Page>* pagePtr, Var_part_ref ref);
+ Tuple_header* alloc_copy_tuple(const Tablerec* tabPtrP, Local_key* ptr){
+ Uint32 * dst = c_undo_buffer.alloc_copy_tuple(ptr, tabPtrP->total_rec_size);
+ if (unlikely(dst == 0))
+ return 0;
+ dst += ((tabPtrP->m_no_of_attributes + 31) >> 5);
+ return (Tuple_header*)dst;
+ }
+
+ Tuple_header* get_copy_tuple(const Tablerec* tabPtrP, const Local_key* ptr){
+ Uint32 mask = (tabPtrP->m_no_of_attributes + 31) >> 5;
+ return (Tuple_header*)(c_undo_buffer.get_ptr(ptr) + mask);
+ }
+
+ Uint32* get_change_mask_ptr(const Tablerec* tabP, Tuple_header* copy_tuple){
+ Uint32 * tmp = (Uint32*)copy_tuple;
+ tmp -= ((tabP->m_no_of_attributes + 31) >> 5);
+ return tmp;
+ }
+
/**
* prealloc space from disk
* key.m_file_no contains file no
@@ -3236,41 +3239,6 @@ Dbtup::decr_tup_version(Uint32 tup_versi
}
inline
-Dbtup::ChangeMaskState
-Dbtup::get_change_mask_state(Operationrec * regOperPtr)
-{
- return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
-}
-
-inline
-void
-Dbtup::set_change_mask_state(Operationrec * regOperPtr,
- ChangeMaskState new_state)
-{
- regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
-}
-
-inline
-void
-Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
- Operationrec * regOperPtr)
-{
- if (req_struct->max_attr_id_updated == 0) {
- if (get_change_mask_state(regOperPtr) == USE_SAVED_CHANGE_MASK) {
- // add new changes
- regOperPtr->saved_change_mask[0] |= req_struct->changeMask.getWord(0);
- regOperPtr->saved_change_mask[1] |= req_struct->changeMask.getWord(1);
- }
- } else {
- if (req_struct->no_changed_attrs < 16) {
- set_change_mask_state(regOperPtr, RECALCULATE_CHANGE_MASK);
- } else {
- set_change_mask_state(regOperPtr, SET_ALL_MASK);
- }
- }
-}
-
-inline
Uint32*
Dbtup::get_ptr(Var_part_ref ref)
{
@@ -3354,6 +3322,46 @@ bool Dbtup::find_savepoint(OperationrecP
c_operation_pool.getPtr(loopOpPtr);
}
return false;
+}
+
+inline
+void
+Dbtup::update_change_mask_info(const Tablerec* tablePtrP,
+ Uint32* dst,
+ const Uint32 * src)
+{
+ Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
+ for (Uint32 i = 0; i<len; i++)
+ {
+ * dst |= *src;
+ dst++;
+ src++;
+ }
+}
+
+inline
+void
+Dbtup::set_change_mask_info(const Tablerec* tablePtrP, Uint32* dst)
+{
+ Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
+ BitmaskImpl::set(len, dst);
+}
+
+inline
+void
+Dbtup::clear_change_mask_info(const Tablerec* tablePtrP, Uint32* dst)
+{
+ Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
+ BitmaskImpl::clear(len, dst);
+}
+
+inline
+void
+Dbtup::copy_change_mask_info(const Tablerec* tablePtrP,
+ Uint32* dst, const Uint32* src)
+{
+ Uint32 len = (tablePtrP->m_no_of_attributes + 31) >> 5;
+ memcpy(dst, src, 4*len);
}
#endif
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp 2008-02-06 13:08:29 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp 2008-03-19 13:56:57 +01:00
@@ -128,8 +128,8 @@ void Dbtup::do_tup_abortreq(Signal* sign
Uint32 bits= tuple_ptr->m_header_bits;
if(regOperPtr.p->op_struct.op_type != ZDELETE)
{
- Tuple_header *copy= (Tuple_header*)
- c_undo_buffer.get_ptr(®OperPtr.p->m_copy_tuple_location);
+ Tuple_header *copy=
+ get_copy_tuple(regTabPtr.p, ®OperPtr.p->m_copy_tuple_location);
if(regOperPtr.p->op_struct.m_disk_preallocated)
{
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp 2008-02-06 13:16:50 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp 2008-03-19 13:56:57 +01:00
@@ -211,8 +211,8 @@ Dbtup::commit_operation(Signal* signal,
Uint32 bits= tuple_ptr->m_header_bits;
Tuple_header *disk_ptr= 0;
- Tuple_header *copy= (Tuple_header*)
- c_undo_buffer.get_ptr(®OperPtr->m_copy_tuple_location);
+ Tuple_header *copy=
+ get_copy_tuple(regTabPtr, ®OperPtr->m_copy_tuple_location);
Uint32 copy_bits= copy->m_header_bits;
@@ -576,8 +576,8 @@ void Dbtup::execTUP_COMMITREQ(Signal* si
if(!regOperPtr.p->m_copy_tuple_location.isNull())
{
jam();
- Tuple_header* tmp= (Tuple_header*)
- c_undo_buffer.get_ptr(®OperPtr.p->m_copy_tuple_location);
+ Tuple_header* tmp=
+ get_copy_tuple(regTabPtr.p, ®OperPtr.p->m_copy_tuple_location);
memcpy(&req.m_page,
tmp->get_disk_ref_ptr(regTabPtr.p), sizeof(Local_key));
@@ -704,7 +704,7 @@ skip_disk:
* Perform "real" commit
*/
Uint32 disk = regOperPtr.p->m_commit_disk_callback_page;
- set_change_mask_info(&req_struct, regOperPtr.p);
+ set_commit_change_mask_info(regTabPtr.p, &req_struct, regOperPtr.p);
checkDetachedTriggers(&req_struct, regOperPtr.p, regTabPtr.p,
disk != RNIL);
@@ -747,58 +747,22 @@ skip_disk:
}
void
-Dbtup::set_change_mask_info(KeyReqStruct * const req_struct,
- Operationrec * const regOperPtr)
+Dbtup::set_commit_change_mask_info(const Tablerec* regTabPtr,
+ KeyReqStruct * req_struct,
+ const Operationrec * regOperPtr)
{
- ChangeMaskState state = get_change_mask_state(regOperPtr);
- if (state == USE_SAVED_CHANGE_MASK) {
- jam();
- req_struct->changeMask.setWord(0, regOperPtr->saved_change_mask[0]);
- req_struct->changeMask.setWord(1, regOperPtr->saved_change_mask[1]);
- } else if (state == RECALCULATE_CHANGE_MASK) {
- jam();
- // Recompute change mask, for now set all bits
- req_struct->changeMask.set();
- } else if (state == SET_ALL_MASK) {
- jam();
- req_struct->changeMask.set();
- } else {
- jam();
- ndbrequire(state == DELETE_CHANGES);
+ Uint32 masklen = (regTabPtr->m_no_of_attributes + 31) >> 5;
+ if (regOperPtr->m_copy_tuple_location.isNull())
+ {
+ ndbassert(regOperPtr->op_struct.op_type == ZDELETE);
req_struct->changeMask.set();
}
-}
-
-void
-Dbtup::calculateChangeMask(Page* const pagePtr,
- Tablerec* const regTabPtr,
- KeyReqStruct * const req_struct)
-{
- OperationrecPtr loopOpPtr;
- Uint32 saved_word1= 0;
- Uint32 saved_word2= 0;
- loopOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
- do {
- c_operation_pool.getPtr(loopOpPtr);
- ndbrequire(loopOpPtr.p->op_struct.op_type == ZUPDATE);
- ChangeMaskState change_mask= get_change_mask_state(loopOpPtr.p);
- if (change_mask == USE_SAVED_CHANGE_MASK) {
- jam();
- saved_word1|= loopOpPtr.p->saved_change_mask[0];
- saved_word2|= loopOpPtr.p->saved_change_mask[1];
- } else if (change_mask == RECALCULATE_CHANGE_MASK) {
- jam();
- //Recompute change mask, for now set all bits
- req_struct->changeMask.set();
- return;
- } else {
- ndbrequire(change_mask == SET_ALL_MASK);
- jam();
- req_struct->changeMask.set();
- return;
- }
- loopOpPtr.i= loopOpPtr.p->prevActiveOp;
- } while (loopOpPtr.i != RNIL);
- req_struct->changeMask.setWord(0, saved_word1);
- req_struct->changeMask.setWord(1, saved_word2);
+ else
+ {
+ Uint32 * dst = req_struct->changeMask.rep.data;
+ Tuple_header* ptr = get_copy_tuple(regTabPtr,
+ ®OperPtr->m_copy_tuple_location);
+ const Uint32 * maskptr = get_change_mask_ptr(regTabPtr, ptr);
+ memcpy(dst, maskptr, 4*masklen);
+ }
}
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-02-06 13:08:29 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-03-19 13:56:57 +01:00
@@ -299,9 +299,6 @@ Dbtup::insertActiveOpList(OperationrecPt
regOperPtr.p->m_undo_buffer_space= 0;
req_struct->m_tuple_ptr->m_operation_ptr_i= regOperPtr.i;
if (prevOpPtr.i == RNIL) {
- set_change_mask_state(regOperPtr.p, USE_SAVED_CHANGE_MASK);
- regOperPtr.p->saved_change_mask[0] = 0;
- regOperPtr.p->saved_change_mask[1] = 0;
return true;
} else {
req_struct->prevOpPtr.p= prevOpPtr.p= c_operation_pool.getPtr(prevOpPtr.i);
@@ -313,9 +310,6 @@ Dbtup::insertActiveOpList(OperationrecPt
prevOpPtr.p->op_struct.m_load_diskpage_on_commit;
regOperPtr.p->m_undo_buffer_space= prevOpPtr.p->m_undo_buffer_space;
// start with prev mask (matters only for UPD o UPD)
- set_change_mask_state(regOperPtr.p, get_change_mask_state(prevOpPtr.p));
- regOperPtr.p->saved_change_mask[0] = prevOpPtr.p->saved_change_mask[0];
- regOperPtr.p->saved_change_mask[1] = prevOpPtr.p->saved_change_mask[1];
regOperPtr.p->m_any_value = prevOpPtr.p->m_any_value;
@@ -408,9 +402,9 @@ Dbtup::setup_read(KeyReqStruct *req_stru
}
else
{
- req_struct->m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&currOpPtr.p->m_copy_tuple_location);
- }
+ req_struct->m_tuple_ptr=
+ get_copy_tuple(regTabPtr, &currOpPtr.p->m_copy_tuple_location);
+ }
if (regTabPtr->need_expand(disk))
prepare_read(req_struct, regTabPtr, disk);
@@ -622,8 +616,6 @@ void Dbtup::execTUPKEYREQ(Signal* signal
req_struct.interpreted_exec= (TrequestInfo >> 10) & 1;
req_struct.no_fired_triggers= 0;
req_struct.read_length= 0;
- req_struct.max_attr_id_updated= 0;
- req_struct.no_changed_attrs= 0;
req_struct.last_row= false;
req_struct.changeMask.clear();
@@ -784,7 +776,6 @@ void Dbtup::execTUPKEYREQ(Signal* signal
regOperPtr,
regTabPtr,
disk_page != RNIL);
- set_change_mask_state(regOperPtr, SET_ALL_MASK);
sendTUPKEYCONF(signal, &req_struct, regOperPtr);
return;
}
@@ -824,7 +815,6 @@ void Dbtup::execTUPKEYREQ(Signal* signal
tupkeyErrorLab(signal);
return;
}
- update_change_mask_info(&req_struct, regOperPtr);
sendTUPKEYCONF(signal, &req_struct, regOperPtr);
return;
}
@@ -850,7 +840,6 @@ void Dbtup::execTUPKEYREQ(Signal* signal
regOperPtr,
regTabPtr,
disk_page != RNIL);
- set_change_mask_state(regOperPtr, DELETE_CHANGES);
sendTUPKEYCONF(signal, &req_struct, regOperPtr);
return;
}
@@ -991,26 +980,31 @@ int Dbtup::handleUpdateReq(Signal* signa
KeyReqStruct* req_struct,
bool disk)
{
- Uint32 *dst;
+ Tuple_header *dst;
Tuple_header *base= req_struct->m_tuple_ptr, *org;
- if ((dst= c_undo_buffer.alloc_copy_tuple(&operPtrP->m_copy_tuple_location,
- regTabPtr->total_rec_size)) == 0)
+ Uint32 * change_mask_ptr;
+ if ((dst= alloc_copy_tuple(regTabPtr, &operPtrP->m_copy_tuple_location))== 0)
{
terrorCode= ZMEM_NOMEM_ERROR;
goto error;
}
Uint32 tup_version;
+ change_mask_ptr = get_change_mask_ptr(regTabPtr, dst);
if(operPtrP->is_first_operation())
{
org= req_struct->m_tuple_ptr;
tup_version= org->get_tuple_version();
+ clear_change_mask_info(regTabPtr, change_mask_ptr);
}
else
{
Operationrec* prevOp= req_struct->prevOpPtr.p;
tup_version= prevOp->tupVersion;
- org= (Tuple_header*)c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
+ org= get_copy_tuple(regTabPtr, &prevOp->m_copy_tuple_location);
+ copy_change_mask_info(regTabPtr,
+ change_mask_ptr,
+ get_change_mask_ptr(regTabPtr, org));
}
/**
@@ -1024,7 +1018,7 @@ int Dbtup::handleUpdateReq(Signal* signa
goto error;
}
- req_struct->m_tuple_ptr= (Tuple_header*)dst;
+ req_struct->m_tuple_ptr= dst;
union {
Uint32 sizes[4];
@@ -1073,6 +1067,10 @@ int Dbtup::handleUpdateReq(Signal* signa
return -1;
}
+ update_change_mask_info(regTabPtr,
+ change_mask_ptr,
+ req_struct->changeMask.rep.data);
+
if (regTabPtr->need_shrink())
{
shrink_tuple(req_struct, sizes+2, regTabPtr, disk);
@@ -1327,7 +1325,8 @@ int Dbtup::handleInsertReq(Signal* signa
{
Uint32 tup_version = 1;
Fragrecord* regFragPtr = fragPtr.p;
- Uint32 *dst, *ptr= 0;
+ Uint32 *ptr= 0;
+ Tuple_header *dst;
Tuple_header *base= req_struct->m_tuple_ptr, *org= base;
Tuple_header *tuple_ptr;
@@ -1353,13 +1352,14 @@ int Dbtup::handleInsertReq(Signal* signa
goto undo_buffer_error;
}
- dst= c_undo_buffer.alloc_copy_tuple(®OperPtr.p->m_copy_tuple_location,
- regTabPtr->total_rec_size);
+ dst= alloc_copy_tuple(regTabPtr, ®OperPtr.p->m_copy_tuple_location);
+
if (unlikely(dst == 0))
{
goto undo_buffer_error;
}
- tuple_ptr= req_struct->m_tuple_ptr= (Tuple_header*)dst;
+ tuple_ptr= req_struct->m_tuple_ptr= dst;
+ set_change_mask_info(regTabPtr, get_change_mask_ptr(regTabPtr, dst));
if(mem_insert)
{
@@ -1373,7 +1373,7 @@ int Dbtup::handleInsertReq(Signal* signa
tup_version= prevOp->tupVersion + 1;
if(!prevOp->is_first_operation())
- org= (Tuple_header*)c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
+ org= get_copy_tuple(regTabPtr, &prevOp->m_copy_tuple_location);
if (regTabPtr->need_expand())
{
expand_tuple(req_struct, sizes, org, regTabPtr, !disk_insert);
@@ -1675,16 +1675,18 @@ int Dbtup::handleDeleteReq(Signal* signa
Operationrec* prevOp= req_struct->prevOpPtr.p;
regOperPtr->tupVersion= prevOp->tupVersion;
// make copy since previous op is committed before this one
- const Uint32* org = c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
- Uint32* dst = c_undo_buffer.alloc_copy_tuple(
- ®OperPtr->m_copy_tuple_location, regTabPtr->total_rec_size);
+ const Tuple_header* org = get_copy_tuple(regTabPtr,
+ &prevOp->m_copy_tuple_location);
+ Tuple_header* dst = alloc_copy_tuple(regTabPtr,
+ ®OperPtr->m_copy_tuple_location);
if (dst == 0) {
terrorCode = ZMEM_NOMEM_ERROR;
goto error;
}
memcpy(dst, org, regTabPtr->total_rec_size << 2);
- req_struct->m_tuple_ptr = (Tuple_header*)dst;
- }
+ req_struct->m_tuple_ptr = dst;
+ set_change_mask_info(regTabPtr, get_change_mask_ptr(regTabPtr, dst));
+ }
else
{
regOperPtr->tupVersion= req_struct->m_tuple_ptr->get_tuple_version();
@@ -3495,8 +3497,8 @@ Dbtup::nr_read_pk(Uint32 fragPtrI,
Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
ndbassert(!opPtrP->m_copy_tuple_location.isNull());
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
+ req_struct.m_tuple_ptr=
+ get_copy_tuple(tablePtr.p, &opPtrP->m_copy_tuple_location);
copy = true;
}
req_struct.check_offset[MM]= tablePtr.p->get_check_offset(MM);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp 2008-01-30 12:26:26 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp 2008-03-19 13:56:57 +01:00
@@ -158,8 +158,8 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI,
if (opPtr.p->tupVersion == tupVersion) {
jam();
if (!opPtr.p->m_copy_tuple_location.isNull()) {
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtr.p->m_copy_tuple_location);
+ req_struct.m_tuple_ptr=
+ get_copy_tuple(tablePtr.p, &opPtr.p->m_copy_tuple_location);
}
break;
}
@@ -238,8 +238,8 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32
Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
ndbassert(!opPtrP->m_copy_tuple_location.isNull());
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
+ req_struct.m_tuple_ptr=
+ get_copy_tuple(tablePtr.p, &opPtrP->m_copy_tuple_location);
}
prepare_read(&req_struct, tablePtr.p, false);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2007-10-23 11:29:27 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2008-03-19 13:56:57 +01:00
@@ -1161,6 +1161,10 @@ Dbtup::computeTableMetaData(Tablerec *re
total_rec_size+= Tuple_header::HeaderSize;
if(regTabPtr->m_no_of_disk_attributes)
total_rec_size+= Tuple_header::HeaderSize;
+
+ /* Room for changemask */
+ total_rec_size += (regTabPtr->m_no_of_attributes + 31) >> 5;
+
regTabPtr->total_rec_size= total_rec_size;
setUpQueryRoutines(regTabPtr);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp 2007-10-26 12:07:12 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp 2008-03-19 13:56:57 +01:00
@@ -1510,13 +1510,6 @@ int Dbtup::updateAttributes(KeyReqStruct
jam();
req_struct->attr_descriptor= attrDescriptor;
req_struct->changeMask.set(attributeId);
- if (attributeId >= 64) {
- if (req_struct->max_attr_id_updated < attributeId) {
- Uint32 no_changed_attrs= req_struct->no_changed_attrs;
- req_struct->max_attr_id_updated= attributeId;
- req_struct->no_changed_attrs= no_changed_attrs + 1;
- }
- }
if ((this->*f)(inBuffer,
req_struct,
attributeOffset)) {
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2008-01-30 12:26:26 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2008-03-19 13:56:57 +01:00
@@ -475,8 +475,8 @@ void Dbtup::checkDetachedTriggers(KeyReq
switch (save_type) {
case ZUPDATE:
case ZINSERT:
- req_struct->m_tuple_ptr = (Tuple_header*)
- c_undo_buffer.get_ptr(®OperPtr->m_copy_tuple_location);
+ req_struct->m_tuple_ptr =
+ get_copy_tuple(regTablePtr, ®OperPtr->m_copy_tuple_location);
break;
}
@@ -853,8 +853,9 @@ bool Dbtup::readTriggerInfo(TupTriggerDa
!regOperPtr->is_first_operation())
{
jam();
- req_struct->m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&req_struct->prevOpPtr.p->m_copy_tuple_location);
+ req_struct->m_tuple_ptr=
+ get_copy_tuple(regTabPtr,
+ &req_struct->prevOpPtr.p->m_copy_tuple_location);
}
if (regTabPtr->need_expand(disk))
@@ -947,10 +948,9 @@ bool Dbtup::readTriggerInfo(TupTriggerDa
}
else
{
- Uint32 *ptr=
- c_undo_buffer.get_ptr(&req_struct->prevOpPtr.p->m_copy_tuple_location);
-
- req_struct->m_tuple_ptr= (Tuple_header*)ptr;
+ req_struct->m_tuple_ptr =
+ get_copy_tuple(regTabPtr,
+ &req_struct->prevOpPtr.p->m_copy_tuple_location);
}
if (regTabPtr->need_expand(disk))
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp 2008-02-08 15:24:49 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp 2008-03-19 13:56:57 +01:00
@@ -115,7 +115,7 @@ Undo_buffer::free_copy_tuple(Local_key*
}
Uint32 *
-Undo_buffer::get_ptr(Local_key* key)
+Undo_buffer::get_ptr(const Local_key* key)
{
return get_page(m_mm, key->m_page_no)->m_data+key->m_page_idx;
}
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp
--- a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp 2007-02-02 17:22:34 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp 2008-03-19 13:56:57 +01:00
@@ -46,7 +46,7 @@ struct Undo_buffer
/**
* Get pointer to copy tuple
*/
- Uint32 * get_ptr(Local_key* key);
+ Uint32 * get_ptr(const Local_key* key);
private:
class Ndbd_mem_manager* m_mm;
diff -Nrup a/storage/ndb/test/ndbapi/test_event.cpp b/storage/ndb/test/ndbapi/test_event.cpp
--- a/storage/ndb/test/ndbapi/test_event.cpp 2008-02-20 15:08:18 +01:00
+++ b/storage/ndb/test/ndbapi/test_event.cpp 2008-03-19 13:56:57 +01:00
@@ -2173,6 +2173,169 @@ runNFSubscribe(NDBT_Context* ctx, NDBT_S
return NDBT_OK;
}
+int
+runBug35208_createTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbDictionary::Table tab = *ctx->getTab();
+
+ while (tab.getNoOfColumns() < 100)
+ {
+ BaseString name;
+ NdbDictionary::Column col;
+ name.assfmt("COL_%d", tab.getNoOfColumns());
+ col.setName(name.c_str());
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setLength(1);
+ col.setNullable(false);
+ col.setPrimaryKey(false);
+ tab.addColumn(col);
+ }
+
+ NdbDictionary::Dictionary* dict = GETNDB(step)->getDictionary();
+ dict->dropTable(tab.getName());
+ dict->createTable(tab);
+
+ const NdbDictionary::Table* pTab = dict->getTable(tab.getName());
+ ctx->setTab(pTab);
+
+ return NDBT_OK;
+}
+
+#define UPDATE_COL 66
+
+int
+runBug35208(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* ndb= GETNDB(step);
+ const NdbDictionary::Table * table= ctx->getTab();
+
+ char buf[1024];
+ sprintf(buf, "%s_EVENT", table->getName());
+ NdbEventOperation *pOp = ndb->createEventOperation(buf);
+ if ( pOp == NULL ) {
+ g_err << "Event operation creation failed on %s" << buf << endl;
+ return NDBT_FAILED;
+ }
+
+ int result = NDBT_OK;
+ HugoTransactions hugoTrans(* table);
+
+ char col[100];
+ BaseString::snprintf(col, sizeof(col), "COL_%u", UPDATE_COL);
+
+ int i;
+ int n_columns= table->getNoOfColumns();
+ NdbRecAttr* recAttr[1024];
+ NdbRecAttr* recAttrPre[1024];
+ for (i = 0; i < n_columns; i++) {
+ recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
+ recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+ }
+
+ if (pOp->execute())
+ { // This starts changes to "start flowing"
+ g_err << "execute operation execution failed: \n";
+ g_err << pOp->getNdbError().code << " "
+ << pOp->getNdbError().message << endl;
+ goto err;
+ }
+
+ hugoTrans.loadTable(GETNDB(step), ctx->getNumRecords());
+
+ for (int i = 0; i<ctx->getNumLoops(); i++)
+ {
+ ndbout_c("testing %u updates", (i + 1));
+ NdbTransaction* pTrans = ndb->startTransaction();
+ for (int m = 0; m<(i+1); m++)
+ {
+ for (int r = 0; r<ctx->getNumRecords(); r++)
+ {
+ NdbOperation* pOp = pTrans->getNdbOperation(table->getName());
+ pOp->updateTuple();
+ HugoOperations hop(* table);
+ hop.equalForRow(pOp, r);
+ pOp->setValue(col, rand());
+ }
+ if (pTrans->execute(NoCommit) != 0)
+ {
+ ndbout << pTrans->getNdbError() << endl;
+ goto err;
+ }
+ }
+ if (pTrans->execute(Commit) != 0)
+ {
+ ndbout << pTrans->getNdbError() << endl;
+ goto err;
+ }
+
+ Uint64 gci;
+ pTrans->getGCI(&gci);
+ ndbout_c("set(LastGCI_hi): %u/%u",
+ Uint32(gci >> 32),
+ Uint32(gci));
+ ctx->setProperty("LastGCI_lo", Uint32(gci));
+ ctx->setProperty("LastGCI_hi", Uint32(gci >> 32));
+ if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
+ {
+ g_err << "FAIL " << __LINE__ << endl;
+ goto err;
+ }
+
+ Uint32 bug = 0;
+ Uint32 cnt = 0;
+ Uint64 curr_gci = 0;
+ while(curr_gci <= gci)
+ {
+ ndb->pollEvents(100, &curr_gci);
+ NdbEventOperation* tmp = 0;
+ while ((tmp= ndb->nextEvent()) != 0)
+ {
+ if (tmp->getEventType() == NdbDictionary::Event::TE_UPDATE)
+ {
+ cnt++;
+ bool first = true;
+ for (int c = 0; c<table->getNoOfColumns(); c++)
+ {
+ if (recAttr[c]->isNULL() >= 0)
+ {
+ /**
+ * Column has value...it should be PK or column we updated
+ */
+ if (c != UPDATE_COL &&
+ table->getColumn(c)->getPrimaryKey() == false)
+ {
+ bug++;
+ if (first)
+ {
+ first = false;
+ printf("Detect (incorrect) update value for: ");
+ }
+ printf("%u ", c);
+ result = NDBT_FAILED;
+ }
+ }
+ }
+ if (!first)
+ printf("\n");
+ }
+ }
+ }
+ ndbout_c("found %u updates bugs: %u", cnt, bug);
+ }
+
+ ndb->dropEventOperation(pOp);
+ ctx->stopTest();
+
+ return result;
+
+err:
+ ndb->dropEventOperation(pOp);
+
+ return NDBT_FAILED;
+}
+
+
+
/** Telco 6.3 **/
NDBT_TESTSUITE(test_event);
@@ -2338,6 +2501,16 @@ TESTCASE("Bug33793", ""){
STEP(runEventListenerUntilStopped);
STEP(runBug33793);
FINALIZER(runDropEvent);
+}
+TESTCASE("Bug35208", ""){
+ INITIALIZER(runBug35208_createTable);
+ INITIALIZER(runCreateEvent);
+ INITIALIZER(runCreateShadowTable);
+ STEP(runBug35208);
+ STEP(runEventApplier);
+ FINALIZER(runDropEvent);
+ FINALIZER(runVerify);
+ FINALIZER(runDropShadowTable);
}
NDBT_TESTSUITE_END(test_event);
diff -Nrup a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2008-03-09 10:50:03 +01:00
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2008-03-19 13:56:57 +01:00
@@ -1102,3 +1102,7 @@ max-time: 300
cmd: testNodeRestart
args: -n Bug34702 T1
+max-time: 600
+cmd: test_event
+args: -n Bug35208 T1
+
| Thread |
|---|
| • bk commit into 5.1 tree (jonas:1.2561) BUG#35208 | jonas | 19 Mar |