diff options
author | Monty <monty@mariadb.org> | 2017-05-23 17:18:31 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-05-23 21:12:27 +0300 |
commit | 6a779a6d28fa69be4c89b72205a11398859f07ca (patch) | |
tree | 3989411d5e69eca72359ab909c10e37cf778378e /sql/ha_sequence.cc | |
parent | d9304914bed2d6d45dbc9f43aa1e2f7ea3bbeb13 (diff) | |
download | mariadb-git-6a779a6d28fa69be4c89b72205a11398859f07ca.tar.gz |
Make SEQUENCE working with replication
- Old sequence code forced row based replication for any statements that
refered to a sequence table. What is new is that row based replication
is now sequence aware:
- NEXT VALUE is now generating a short row based event with only
next_value and round being replicated.
- Short row based events are now on the slave updated as trough
SET_VALUE(sequence_name)
- Full row based events are on the slave updated with a full insert,
which is practically same as ALTER SEQUENCE.
- INSERT on a SEQUENCE table does now a EXCLUSIVE LOCK to ensure that
it is logged in binary log before any following NEXT VALUE calls.
- Enable all sequence tests and fixed found bugs
- ALTER SEQUENCE doesn't anymore allow changes that makes the next_value
outside of allowed range
- SEQUENCE changes are done with TL_WRITE_ALLOW_WRITE. Because of this
one can generate a statement for MyISAM with both
TL_WRITE_CONCURRENT_INSERT and TL_WRITE_ALLOW_WRITE. To fix a warning
I had to add an extra test in thr_lock.c for this.
- Removed UPDATE of SEQUENCE (no need to support this as we
have ALTER SEQUENCE, which takes the EXCLUSIVE lock properly.
- Removed DBUG_ASSERT() in MDL_context::upgrade_shared_lock. This was
removed upstream in MySQL 5.6 in 72f823de453.
- Simplified test in decided_logging_format() by using sql_command_flags()
- Fix that we log DROP SEQUENCE correctly.
- Fixed that Aria works with SEQUENCE
Diffstat (limited to 'sql/ha_sequence.cc')
-rw-r--r-- | sql/ha_sequence.cc | 70 |
1 files changed, 28 insertions, 42 deletions
diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc index a918da92be2..279e7801b2d 100644 --- a/sql/ha_sequence.cc +++ b/sql/ha_sequence.cc @@ -187,6 +187,7 @@ int ha_sequence::create(const char *name, TABLE *form, int ha_sequence::write_row(uchar *buf) { int error; + sequence_definition tmp_seq; DBUG_ENTER("ha_sequence::write_row"); DBUG_ASSERT(table->record[0] == buf); @@ -199,16 +200,31 @@ int ha_sequence::write_row(uchar *buf) if (unlikely(sequence->initialized != SEQUENCE::SEQ_READY_TO_USE)) DBUG_RETURN(HA_ERR_WRONG_COMMAND); - /* - User tries to write a row - - Check that the new row is an accurate object - - Update the first row in the table - */ + if (!sequence_locked) // If not from next_value() + { + /* + User tries to write a full row directly to the sequence table with + INSERT or LOAD DATA. + + - Get an exclusive lock for the table. This is needed to ensure that + we excute all full inserts (same as ALTER SEQUENCE) in same order + on master and slaves + - Check that we are only using one table. + This is to avoid deadlock problems when upgrading lock to exlusive. + - Check that the new row is an accurate SEQUENCE object + */ - sequence_definition tmp_seq; - tmp_seq.read_fields(table); - if (tmp_seq.check_and_adjust()) - DBUG_RETURN(HA_ERR_SEQUENCE_INVALID_DATA); + THD *thd= table->in_use; + if (thd->lock->table_count != 1) + DBUG_RETURN(ER_WRONG_INSERT_INTO_SEQUENCE); + if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE, + thd->variables.lock_wait_timeout)) + DBUG_RETURN(ER_LOCK_WAIT_TIMEOUT); + + tmp_seq.read_fields(table); + if (tmp_seq.check_and_adjust(0)) + DBUG_RETURN(HA_ERR_SEQUENCE_INVALID_DATA); + } /* Lock sequence to ensure that no one can come in between @@ -235,39 +251,6 @@ int ha_sequence::write_row(uchar *buf) } -int ha_sequence::update_row(const uchar *old_data, const uchar *new_data) -{ - int error; - sequence_definition tmp_seq; - DBUG_ENTER("ha_sequence::update_row"); - DBUG_ASSERT(new_data == table->record[0]); - - row_already_logged= 0; - - tmp_seq.read_fields(table); - if (tmp_seq.check_and_adjust()) - DBUG_RETURN(HA_ERR_SEQUENCE_INVALID_DATA); - - /* - Lock sequence to ensure that no one can come in between - while sequence, table and binary log is updated. - */ - sequence->lock(); - if (!(error= file->update_row(old_data, new_data))) - { - sequence->copy(&tmp_seq); - rows_changed++; - /* We have to do the logging while we hold the sequence mutex */ - error= binlog_log_row(table, old_data, new_data, - Update_rows_log_event::binlog_row_logging_function); - row_already_logged= 1; - } - sequence->all_values_used= 0; - sequence->unlock(); - DBUG_RETURN(error); -} - - /* Inherit the sequence base table flags. */ @@ -346,6 +329,9 @@ void ha_sequence::print_error(int error, myf errflag) case HA_ERR_WRONG_COMMAND: my_error(ER_ILLEGAL_HA, MYF(0), "SEQUENCE", sequence_db, sequence_name); DBUG_VOID_RETURN; + case ER_WRONG_INSERT_INTO_SEQUENCE: + my_error(error, MYF(0)); + DBUG_VOID_RETURN; } file->print_error(error, errflag); DBUG_VOID_RETURN; |