diff options
author | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-09-07 18:41:49 +0500 |
---|---|---|
committer | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-09-07 18:41:49 +0500 |
commit | afd34c69be22a45a85799297894d5725637d1dd5 (patch) | |
tree | e185e8a3f93c15c79cf45d5b9438585bc3dda5aa | |
parent | a3dc9569e983db92ca1ace1f3fe66428cd8098e2 (diff) | |
download | mariadb-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.cc | 38 | ||||
-rw-r--r-- | sql/ha_partition.h | 1 | ||||
-rw-r--r-- | sql/handler.h | 11 | ||||
-rw-r--r-- | sql/log_event.cc | 3 |
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]. |