Commit 66c52cbd authored by pekka@mysql.com's avatar pekka@mysql.com

Merge pnousiainen@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  mysql.com:/space/pekka/ndb/version/my51
parents d955abd2 738db4f1
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
create table t1 (
a int not null primary key,
b text not null
) engine=ndb;
insert into t1 values(1, repeat('abc',10));
insert into t1 values(2, repeat('def',200));
insert into t1 values(3, repeat('ghi',3000));
select 'M', a, sha1(b) from t1
order by a;
M a sha1(b)
M 1 8a6c4cf7cf97e66c487c3e3b717e9ae13623d07d
M 2 0ccd08c0fa6ad6a4382b27b1d36586d6ceb4fffa
M 3 75e7b3299e0b776aeac2a4d1542d5b3c0ba2e05e
select 'S', a, sha1(b) from t1
order by a;
S a sha1(b)
S 1 8a6c4cf7cf97e66c487c3e3b717e9ae13623d07d
S 2 0ccd08c0fa6ad6a4382b27b1d36586d6ceb4fffa
S 3 75e7b3299e0b776aeac2a4d1542d5b3c0ba2e05e
drop table t1;
create table t1 (
a int not null primary key,
b text not null,
c int,
d longblob,
e tinyblob
) engine=ndbcluster;
insert into t1 values (
0, repeat(@s2,454), 100, repeat(@s2,345), NULL);
insert into t1 values (
1, repeat(@s0,504), NULL, repeat(@s1,732), repeat(@s1,1));
insert into t1 values (
2, '', 102, '', repeat(@s2,1));
insert into t1 values (
3, repeat(@s0,545), 103, repeat(@s2,788), repeat(@s0,1));
insert into t1 values (
4, repeat(@s1,38), 104, repeat(@s0,260), repeat(@s0,1));
insert into t1 values (
5, repeat(@s2,12), 105, repeat(@s2,40), repeat(@s1,1));
insert into t1 values (
6, repeat(@s1,242), 106, NULL, repeat(@s1,1));
insert into t1 values (
7, repeat(@s1,30), 107, repeat(@s0,161), '');
insert into t1 values (
8, repeat(@s1,719), 108, repeat(@s2,104), NULL);
insert into t1 values (
9, repeat(@s2,427), NULL, NULL, NULL);
select 'M', a, sha1(b), c, sha1(d), sha1(e)
from t1 order by a;
M a sha1(b) c sha1(d) sha1(e)
M 0 9538f61e649383c0d1054de2a2f0171188129f33 100 2b6515f29c20b8e9e17cc597527e516c0de8d612 NULL
M 1 dcb9a12ca86e718ff2564be041b7c1b3ff5ea559 NULL f23e7439d9a73c3954979b85a7ef6ef35faf4e9d abfe8ae5212b22d023aa6de84beeb1344ac5668a
M 2 da39a3ee5e6b4b0d3255bfef95601890afd80709 102 da39a3ee5e6b4b0d3255bfef95601890afd80709 33deebe47470a40e960834bffa4cdc66790845a6
M 3 ec8e06d9ac4695d6a898b519ba840590263a9bff 103 278629ad080c3c4377978c006c2e54d0992e43cc 700915801f853603510aeb67b331866d996fdbda
M 4 0392fa8c425d293c79291f0f34779d1101d13fcb 104 5084b602c7203e0e9590a163415ac605da17ac32 700915801f853603510aeb67b331866d996fdbda
M 5 0f9653f0c7a69cd1c617792d546582e974a7a24d 105 566588a04ff26d05160d61c83435292bfda2978e abfe8ae5212b22d023aa6de84beeb1344ac5668a
M 6 a37e8b0ff4fc13a42be02cdecb36186436959bae 106 NULL abfe8ae5212b22d023aa6de84beeb1344ac5668a
M 7 a6bae0cfe6b45ff8c3c12d2ce577a1cd3931190f 107 39ee712b4b9e47f2cf3ba7c9790b2bf0d8f378e8 da39a3ee5e6b4b0d3255bfef95601890afd80709
M 8 e139adcb7b2974ee7ff227fd405709e5cb7c896c 108 ba8073b0e1a281d4111bd2d82c7722b01574c00b NULL
M 9 1fc5168fe4be566b17b658d94e7813f0b5032cdb NULL NULL NULL
select 'S', a, sha1(b), c, sha1(d), sha1(e)
from t1 order by a;
S a sha1(b) c sha1(d) sha1(e)
S 0 9538f61e649383c0d1054de2a2f0171188129f33 100 2b6515f29c20b8e9e17cc597527e516c0de8d612 NULL
S 1 dcb9a12ca86e718ff2564be041b7c1b3ff5ea559 NULL f23e7439d9a73c3954979b85a7ef6ef35faf4e9d abfe8ae5212b22d023aa6de84beeb1344ac5668a
S 2 da39a3ee5e6b4b0d3255bfef95601890afd80709 102 da39a3ee5e6b4b0d3255bfef95601890afd80709 33deebe47470a40e960834bffa4cdc66790845a6
S 3 ec8e06d9ac4695d6a898b519ba840590263a9bff 103 278629ad080c3c4377978c006c2e54d0992e43cc 700915801f853603510aeb67b331866d996fdbda
S 4 0392fa8c425d293c79291f0f34779d1101d13fcb 104 5084b602c7203e0e9590a163415ac605da17ac32 700915801f853603510aeb67b331866d996fdbda
S 5 0f9653f0c7a69cd1c617792d546582e974a7a24d 105 566588a04ff26d05160d61c83435292bfda2978e abfe8ae5212b22d023aa6de84beeb1344ac5668a
S 6 a37e8b0ff4fc13a42be02cdecb36186436959bae 106 NULL abfe8ae5212b22d023aa6de84beeb1344ac5668a
S 7 a6bae0cfe6b45ff8c3c12d2ce577a1cd3931190f 107 39ee712b4b9e47f2cf3ba7c9790b2bf0d8f378e8 da39a3ee5e6b4b0d3255bfef95601890afd80709
S 8 e139adcb7b2974ee7ff227fd405709e5cb7c896c 108 ba8073b0e1a281d4111bd2d82c7722b01574c00b NULL
S 9 1fc5168fe4be566b17b658d94e7813f0b5032cdb NULL NULL NULL
drop table t1;
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
master-bin.000001 102 Query 1 239 use `test`; create table t1 (
a int not null primary key,
b text not null
) engine=ndb
master-bin.000001 239 Query 1 303 BEGIN
master-bin.000001 303 Table_map 1 65 cluster_replication.apply_status
master-bin.000001 368 Write_rows 1 107
master-bin.000001 410 Table_map 1 147 test.t1
master-bin.000001 450 Write_rows 1 818
master-bin.000001 1121 Write_rows 1 9853
master-bin.000001 10156 Query 1 10221 COMMIT
master-bin.000001 10221 Query 1 10285 BEGIN
master-bin.000001 10285 Table_map 1 65 cluster_replication.apply_status
master-bin.000001 10350 Write_rows 1 107
master-bin.000001 10392 Query 1 10457 COMMIT
master-bin.000001 10457 Query 1 10533 use `test`; drop table t1
master-bin.000001 10533 Query 1 10708 use `test`; create table t1 (
a int not null primary key,
b text not null,
c int,
d longblob,
e tinyblob
) engine=ndbcluster
master-bin.000001 10708 Query 1 10772 BEGIN
master-bin.000001 10772 Table_map 1 65 cluster_replication.apply_status
master-bin.000001 10837 Write_rows 1 107
master-bin.000001 10879 Table_map 1 150 test.t1
master-bin.000001 10922 Write_rows 1 48934
master-bin.000001 59706 Write_rows 1 124436
master-bin.000001 135208 Write_rows 1 124542
master-bin.000001 135314 Write_rows 1 205961
master-bin.000001 216733 Write_rows 1 224245
master-bin.000001 235017 Write_rows 1 227523
master-bin.000001 238295 Write_rows 1 242391
master-bin.000001 253163 Write_rows 1 254087
master-bin.000001 264859 Write_rows 1 304335
master-bin.000001 315107 Write_rows 1 330427
master-bin.000001 341199 Query 1 341264 COMMIT
master-bin.000001 341264 Query 1 341328 BEGIN
master-bin.000001 341328 Table_map 1 65 cluster_replication.apply_status
master-bin.000001 341393 Write_rows 1 107
master-bin.000001 341435 Query 1 341500 COMMIT
master-bin.000001 341500 Query 1 341576 use `test`; drop table t1
......@@ -28,7 +28,6 @@ rpl_sp : Bug #16456
#ndb_dd_disk2memory : Bug #16466
ndb_autodiscover : Needs to be fixed w.r.t binlog
ndb_autodiscover2 : Needs to be fixed w.r.t binlog
ndb_blob : BLOB replication causes core in master1 (Pekka will fix)
#ndb_alter_table_row : sometimes wrong error 1015!=1046
ndb_gis : garbled msgs from corrupt THD*
ndb_binlog_ddl_multi : Bug #17038
......
--source include/have_ndb.inc
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
#
# basic test of blob replication for NDB
#
# easy test
--connection master
create table t1 (
a int not null primary key,
b text not null
) engine=ndb;
insert into t1 values(1, repeat('abc',10));
insert into t1 values(2, repeat('def',200));
insert into t1 values(3, repeat('ghi',3000));
select 'M', a, sha1(b) from t1
order by a;
--sync_slave_with_master
--sleep 5
--connection slave
select 'S', a, sha1(b) from t1
order by a;
--connection master
drop table t1;
--sync_slave_with_master
# hard test
--connection master
create table t1 (
a int not null primary key,
b text not null,
c int,
d longblob,
e tinyblob
) engine=ndbcluster;
--disable_query_log
# length 61
set @s0 = 'rggurloniukyehuxdbfkkyzlceixzrehqhvxvxbpwizzvjzpucqmzrhzxzfau';
set @s1 = 'ykyymbzqgqlcjhlhmyqelfoaaohvtbekvifukdtnvcrrjveevfakxarxexomz';
set @s2 = 'dbnfqyzgtqxalcrwtfsqabknvtfcbpoonxsjiqvmhnfikxxhcgoexlkoezvah';
--enable_query_log
insert into t1 values (
0, repeat(@s2,454), 100, repeat(@s2,345), NULL);
insert into t1 values (
1, repeat(@s0,504), NULL, repeat(@s1,732), repeat(@s1,1));
insert into t1 values (
2, '', 102, '', repeat(@s2,1));
insert into t1 values (
3, repeat(@s0,545), 103, repeat(@s2,788), repeat(@s0,1));
insert into t1 values (
4, repeat(@s1,38), 104, repeat(@s0,260), repeat(@s0,1));
insert into t1 values (
5, repeat(@s2,12), 105, repeat(@s2,40), repeat(@s1,1));
insert into t1 values (
6, repeat(@s1,242), 106, NULL, repeat(@s1,1));
insert into t1 values (
7, repeat(@s1,30), 107, repeat(@s0,161), '');
insert into t1 values (
8, repeat(@s1,719), 108, repeat(@s2,104), NULL);
insert into t1 values (
9, repeat(@s2,427), NULL, NULL, NULL);
select 'M', a, sha1(b), c, sha1(d), sha1(e)
from t1 order by a;
--sync_slave_with_master
--sleep 5
--connection slave
select 'S', a, sha1(b), c, sha1(d), sha1(e)
from t1 order by a;
--connection master
drop table t1;
--sync_slave_with_master
#
# view the binlog
#
--connection master
let $VERSION=`select version()`;
--replace_result $VERSION VERSION
show binlog events;
......@@ -840,51 +840,51 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
{
Field *field= table->field[i];
NdbValue value= value_array[i];
if (value.ptr != NULL && (field->flags & BLOB_FLAG))
if (! (field->flags & BLOB_FLAG))
continue;
if (value.blob == NULL)
{
DBUG_PRINT("info",("[%u] skipped", i));
continue;
}
Field_blob *field_blob= (Field_blob *)field;
NdbBlob *ndb_blob= value.blob;
int isNull;
ndb_blob->getDefined(isNull);
if (isNull == 0) { // XXX -1 should be allowed only for events
Uint64 blob_len= 0;
if (ndb_blob->getLength(blob_len) != 0)
DBUG_RETURN(-1);
if (ndb_blob->getNull(isNull) != 0)
ERR_RETURN(ndb_blob->getNdbError());
if (isNull == 0) {
Uint64 len64= 0;
if (ndb_blob->getLength(len64) != 0)
ERR_RETURN(ndb_blob->getNdbError());
// Align to Uint64
uint32 blob_size= blob_len;
if (blob_size % 8 != 0)
blob_size+= 8 - blob_size % 8;
uint32 size= len64;
if (size % 8 != 0)
size+= 8 - size % 8;
if (loop == 1)
{
char *buf= buffer + offset;
uint32 len= 0xffffffff; // Max uint32
DBUG_PRINT("info", ("read blob ptr=%p len=%u",
buf, (uint) blob_len));
if (ndb_blob->readData(buf, len) != 0)
DBUG_RETURN(-1);
DBUG_PRINT("info", ("blob field %d offset=%u len=%u [ptrdiff=%d]",
i, offset, len, (int)ptrdiff));
DBUG_ASSERT(len == blob_len);
ERR_RETURN(ndb_blob->getNdbError());
DBUG_PRINT("info", ("[%u] offset=%u buf=%p len=%u [ptrdiff=%d]",
i, offset, buf, len, (int)ptrdiff));
DBUG_ASSERT(len == len64);
// Ugly hack assumes only ptr needs to be changed
field_blob->ptr+= ptrdiff;
field_blob->set_ptr(len, buf);
field_blob->ptr-= ptrdiff;
}
offset+= blob_size;
offset+= size;
}
else
{
if (loop == 1)
else if (loop == 1) // undefined or null
{
// have to set length even in this case
char *buf= buffer + offset;
char *buf= buffer + offset; // or maybe NULL
uint32 len= 0;
field_blob->ptr+= ptrdiff;
field_blob->set_ptr(len, buf);
field_blob->ptr-= ptrdiff;
DBUG_PRINT("info", ("blob field %d isNull=%d", i, isNull));
}
}
DBUG_PRINT("info", ("[%u] isNull=%d", i, isNull));
}
}
if (loop == 0 && offset > buffer_size)
......
......@@ -2084,6 +2084,20 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
DBUG_PRINT("info", ("%s blob", col_name));
attr0.blob= op->getBlobHandle(col_name);
attr1.blob= op->getPreBlobHandle(col_name);
if (attr0.blob == NULL || attr1.blob == NULL)
{
sql_print_error("NDB Binlog: Creating NdbEventOperation"
" blob field %u handles failed (code=%d) for %s",
j, op->getNdbError().code, event_name);
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
op->getNdbError().code,
op->getNdbError().message,
"NDB");
ndb->dropEventOperation(op);
pthread_mutex_unlock(&injector_mutex);
DBUG_RETURN(-1);
}
}
}
else
......
......@@ -76,8 +76,8 @@ class NdbEventOperationImpl;
* handle can be read after next event on main table has been retrieved.
* The data is available immediately. See NdbEventOperation.
*
* NdbBlob methods return -1 on error and 0 on success, and use output
* parameters when necessary.
* Non-void NdbBlob methods return -1 on error and 0 on success. Output
* parameters are used when necessary.
*
* Operation types:
* - insertTuple must use setValue if blob column is non-nullable
......@@ -116,6 +116,11 @@ public:
* Get the state of a NdbBlob object.
*/
State getState();
/**
* Returns -1 for normal statement based blob and 0/1 for event
* operation post/pre data blob. Always succeeds.
*/
void getVersion(int& version);
/**
* Inline blob header.
*/
......@@ -150,16 +155,15 @@ public:
* then the callback is invoked.
*/
int setActiveHook(ActiveHook* activeHook, void* arg);
/**
* Check if blob value is defined (NULL or not). Used as first call
* on event based blob. The argument is set to -1 for not defined.
* Unlike getNull() this does not cause error on the handle.
*/
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
int getDefined(int& isNull);
int getNull(bool& isNull);
#endif
/**
* Check if blob is null.
* Return -1, 0, 1 if blob is undefined, non-null, or null. For
* non-event blob, undefined causes a state error.
*/
int getNull(bool& isNull);
int getNull(int& isNull);
/**
* Set blob to NULL.
*/
......@@ -208,8 +212,8 @@ public:
*/
static int getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char* columnName);
/**
* Return error object. The error may be blob specific (below) or may
* be copied from a failed implicit operation.
* Return error object. The error may be blob specific or may be
* copied from a failed implicit operation.
*/
const NdbError& getNdbError() const;
/**
......
......@@ -31,7 +31,21 @@
*/
static const bool g_ndb_blob_ok_to_read_index_table = false;
// state (inline)
// get state
NdbBlob::State
NdbBlob::getState()
{
return theState;
}
void
NdbBlob::getVersion(int& version)
{
version = theEventBlobVersion;
}
// set state (inline)
inline void
NdbBlob::setState(State newState)
......@@ -608,7 +622,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
// misc operations
int
NdbBlob::getDefined(int& isNull)
NdbBlob::getDefined(int& isNull) // deprecated
{
DBUG_ENTER("NdbBlob::getDefined");
if (theState == Prepared && theSetFlag) {
......@@ -620,7 +634,7 @@ NdbBlob::getDefined(int& isNull)
}
int
NdbBlob::getNull(bool& isNull)
NdbBlob::getNull(bool& isNull) // deprecated
{
DBUG_ENTER("NdbBlob::getNull");
if (theState == Prepared && theSetFlag) {
......@@ -635,6 +649,23 @@ NdbBlob::getNull(bool& isNull)
DBUG_RETURN(0);
}
int
NdbBlob::getNull(int& isNull)
{
DBUG_ENTER("NdbBlob::getNull");
if (theState == Prepared && theSetFlag) {
isNull = (theSetBuf == NULL);
DBUG_RETURN(0);
}
isNull = theNullFlag;
if (isNull == -1 && theEventBlobVersion == -1) {
setErrorCode(NdbBlobImpl::ErrState);
DBUG_RETURN(-1);
}
DBUG_PRINT("info", ("isNull=%d", isNull));
DBUG_RETURN(0);
}
int
NdbBlob::setNull()
{
......@@ -1085,6 +1116,8 @@ NdbBlob::deletePartsUnknown(Uint32 part)
{
DBUG_ENTER("NdbBlob::deletePartsUnknown");
DBUG_PRINT("info", ("part=%u count=all", part));
if (thePartSize == 0) // tinyblob
DBUG_RETURN(0);
static const unsigned maxbat = 256;
static const unsigned minbat = 1;
unsigned bat = minbat;
......
......@@ -87,7 +87,12 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col)
m_arrayType = col.m_arrayType;
m_storageType = col.m_storageType;
m_keyInfoPos = col.m_keyInfoPos;
m_blobTable = col.m_blobTable;
if (col.m_blobTable == NULL)
m_blobTable = NULL;
else {
m_blobTable = new NdbTableImpl();
m_blobTable->assign(*col.m_blobTable);
}
m_column_no = col.m_column_no;
// Do not copy m_facade !!
......@@ -2747,13 +2752,24 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
}
int
NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl, bool lock)
{
const char * internalTableName = impl.m_internalName.c_str();
m_localHash.drop(internalTableName);
if (lock)
m_globalHash->lock();
if (impl.m_noOfBlobs != 0) {
for (uint i = 0; i < impl.m_columns.size(); i++) {
NdbColumnImpl& c = *impl.m_columns[i];
if (! c.getBlobType() || c.getPartSize() == 0)
continue;
assert(c.m_blobTable != NULL);
removeCachedObject(*c.m_blobTable, false);
}
}
m_localHash.drop(internalTableName);
m_globalHash->release(&impl);
if (lock)
m_globalHash->unlock();
return 0;
}
......
......@@ -545,7 +545,7 @@ public:
int dropTable(NdbTableImpl &);
int dropBlobTables(NdbTableImpl &);
int invalidateObject(NdbTableImpl &);
int removeCachedObject(NdbTableImpl &);
int removeCachedObject(NdbTableImpl &, bool lock = true);
int createIndex(NdbIndexImpl &ix);
int dropIndex(const char * indexName,
......
......@@ -342,15 +342,18 @@ NdbEventOperationImpl::getBlobHandle(const NdbColumnImpl *tAttrInfo, int n)
tBlobOp = tBlobOp->m_next;
}
DBUG_PRINT("info", ("%s op %s", tBlobOp ? " reuse" : " create", bename));
DBUG_PRINT("info", ("%s blob event op for %s",
tBlobOp ? " reuse" : " create", bename));
// create blob event op if not found
if (tBlobOp == NULL) {
// to hide blob op it is linked under main op, not under m_ndb
NdbEventOperation* tmp =
m_ndb->theEventBuffer->createEventOperation(bename, m_error);
if (tmp == NULL)
if (tmp == NULL) {
m_error.code = m_ndb->theEventBuffer->m_error.code;
DBUG_RETURN(NULL);
}
tBlobOp = &tmp->m_impl;
// pointer to main table op
......@@ -367,11 +370,14 @@ NdbEventOperationImpl::getBlobHandle(const NdbColumnImpl *tAttrInfo, int n)
}
tBlob = m_ndb->getNdbBlob();
if (tBlob == NULL)
if (tBlob == NULL) {
m_error.code = m_ndb->getNdbError().code;
DBUG_RETURN(NULL);
}
// calls getValue on inline and blob part
if (tBlob->atPrepare(this, tBlobOp, tAttrInfo, n) == -1) {
m_error.code = tBlob->getNdbError().code;
m_ndb->releaseNdbBlob(tBlob);
DBUG_RETURN(NULL);
}
......
......@@ -990,7 +990,7 @@ static int copy_events(Ndb *ndb)
while ((pOp= ndb->nextEvent()))
{
char buf[1024];
sprintf(buf, "%s_SHADOW", pOp->getTable()->getName());
sprintf(buf, "%s_SHADOW", pOp->getEvent()->getTable()->getName());
const NdbDictionary::Table *table= dict->getTable(buf);
if (table == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment