summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <holyfoot/hf@mysql.com/hfmain.(none)>2007-09-07 18:41:49 +0500
committerunknown <holyfoot/hf@mysql.com/hfmain.(none)>2007-09-07 18:41:49 +0500
commitafd34c69be22a45a85799297894d5725637d1dd5 (patch)
treee185e8a3f93c15c79cf45d5b9438585bc3dda5aa
parenta3dc9569e983db92ca1ace1f3fe66428cd8098e2 (diff)
downloadmariadb-git-afd34c69be22a45a85799297894d5725637d1dd5.tar.gz
Bug #28430 Failure in replication of innodb partitioned tables on row/mixed format.
In the ha_partition::position() we don't calculate the number of the partition of the record, but use m_last_part value instead, relying on that it's previously set by some other call like ::write_row(). Delete_rows_log_event::do_exec_row() calls find_and_fetch_row(), where we used position() + rnd_pos() call for the InnoDB-based PARTITION-ed table as there HA_PRIMARY_KEY_REQUIRED_FOR_POSITION enabled. fixed by introducing new handler::rnd_pos_by_record() method to be used for random record-based positioning sql/ha_partition.cc: Bug #28430 Failure in replication of innodb partitioned tables on row/mixed format. ha_partition::rnd_pos_by_record() implemented sql/ha_partition.h: Bug #28430 Failure in replication of innodb partitioned tables on row/mixed format. ha_partition::rnd_pos_by_record() declared sql/handler.h: Bug #28430 Failure in replication of innodb partitioned tables on row/mixed format. handler::rnd_pos_by_record() introduced sql/log_event.cc: Bug #28430 Failure in replication of innodb partitioned tables on row/mixed format. handler::rnd_pos_by_record used instead of position() + rnd_pos() call
-rw-r--r--sql/ha_partition.cc38
-rw-r--r--sql/ha_partition.h1
-rw-r--r--sql/handler.h11
-rw-r--r--sql/log_event.cc3
4 files changed, 45 insertions, 8 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index bff94da63bb..88e5eecc94f 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3235,14 +3235,9 @@ end_dont_reset_start_part:
void ha_partition::position(const uchar *record)
{
- handler *file;
+ handler *file= m_file[m_last_part];
DBUG_ENTER("ha_partition::position");
- if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part)))
- m_last_part= 0;
-
- file= m_file[m_last_part];
-
file->position(record);
int2store(ref, m_last_part);
memcpy((ref + PARTITION_BYTES_IN_POS), file->ref,
@@ -3257,6 +3252,7 @@ void ha_partition::position(const uchar *record)
DBUG_VOID_RETURN;
}
+
/*
Read row using position
@@ -3292,6 +3288,36 @@ int ha_partition::rnd_pos(uchar * buf, uchar *pos)
}
+/*
+ Read row using position using given record to find
+
+ SYNOPSIS
+ rnd_pos_by_record()
+ record Current record in MySQL Row Format
+
+ RETURN VALUE
+ >0 Error code
+ 0 Success
+
+ DESCRIPTION
+ this works as position()+rnd_pos() functions, but does some extra work,
+ calculating m_last_part - the partition to where the 'record'
+ should go.
+
+ called from replication (log_event.cc)
+*/
+
+int ha_partition::rnd_pos_by_record(uchar *record)
+{
+ DBUG_ENTER("ha_partition::rnd_pos_by_record");
+
+ if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part)))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(handler::rnd_pos_by_record(record));
+}
+
+
/****************************************************************************
MODULE index scan
****************************************************************************/
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 434d90a4487..8fe512fadb3 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -353,6 +353,7 @@ public:
virtual int rnd_end();
virtual int rnd_next(uchar * buf);
virtual int rnd_pos(uchar * buf, uchar * pos);
+ virtual int rnd_pos_by_record(uchar *record);
virtual void position(const uchar * record);
/*
diff --git a/sql/handler.h b/sql/handler.h
index 557b9fd7887..b91d8a39b88 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1343,6 +1343,17 @@ public:
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
+ /*
+ one has to use this method when to find
+ random position by record as the plain
+ position() call doesn't work for some
+ handlers for random position
+ */
+ virtual int rnd_pos_by_record(uchar *record)
+ {
+ position(record);
+ return rnd_pos(record, ref);
+ }
virtual int read_first_row(uchar *buf, uint primary_key);
/*
The following function is only needed for tables that may be temporary
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 7d9c7c69574..14936495c2b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -7509,8 +7509,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
table->s->reclength) == 0);
*/
- table->file->position(table->record[0]);
- int error= table->file->rnd_pos(table->record[0], table->file->ref);
+ int error= table->file->rnd_pos_by_record(table->record[0]);
/*
rnd_pos() returns the record in table->record[0], so we have to
move it to table->record[1].