List:Internals« Previous MessageNext Message »
From:Guilhem Bichot Date:October 30 2006 4:01pm
Subject:Re: Auto increment fields on 5.1.x
View as plain text  
Hello Jan, long time talked to you,

On Thu, Oct 26, 2006 at 12:53:31PM +0300, Jan Lindström wrote:
> Hello,
> 
> Consider following SQL-queries:
> 
> create table t1(a int not null auto_increment primary key)
> engine=soliddb;
> insert into t1 values (null),(3),(null);
> 
> at the moment 5.1.12-bk executes insert as follows:
> 
> Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�")
>     at ha_soliddb.cc:3750
> 3750            su_err_t* errh = NULL;
> (gdb) c
> Continuing.
> 
> Breakpoint 1, ha_soliddb::get_auto_increment (this=0x97f2b08, offset=1,
> increment=1,
>     nb_desired_values=3, first_value=0x8ffe7140,
> nb_reserved_values=0x8ffe7138)
>     at ha_soliddb.cc:10276
> 10276           DBUG_ENTER("ha_soliddb:get_auto_increment");
> (gdb) c
> Continuing.
> 
> Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�
> \003")
>     at ha_soliddb.cc:3750
> 3750            su_err_t* errh = NULL;
> (gdb) c
> Continuing.
> 
> Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�")
>     at ha_soliddb.cc:3750
> 3750            su_err_t* errh = NULL;
> (gdb) c
> Continuing.
> 
> Breakpoint 1, ha_soliddb::get_auto_increment (this=0x97f2b08, offset=1,
> increment=1,
>     nb_desired_values=3, first_value=0x8ffe7140,
> nb_reserved_values=0x8ffe7138)
>     at ha_soliddb.cc:10276
> 10276           DBUG_ENTER("ha_soliddb:get_auto_increment");
> 
> Now my question is why MySQL calls ::get_auto_increment function second
> time for a above insert? Handler has already generated exactly desired
> number of auto_increment values for the MySQL server. My implementation
> for ::get_auto_increment is as follows:


The queries are:
create table t1(a int not null auto_increment primary key)
engine=soliddb;
insert into t1 values (null),(3),(null);

the write_row() for the first NULL will ask to reserve 3 values, Solid
will probably reserve those: 1, 2 and 3. 1 is immediately consumed by
the first NULL.
Then there is write_row() of the explicitely specified value
3. handler::update_auto_increment() is called and this part of it is
executed:

  if ((nr= table->next_number_field->val_int()) != 0 ||
      auto_increment_field_not_null &&
      thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)
  {
    /*
      Update next_insert_id if we had already generated a value in this
      statement (case of INSERT VALUES(null),(3763),(null):
      the last NULL needs to insert 3764, not the value of the first NULL plus
      1).
    */
    adjust_next_insert_id_after_explicit_value(nr);
    insert_id_for_cur_row= 0; // didn't generate anything
    DBUG_RETURN(0);
  }

where nr is 3. So next_insert_id is set to 4 (the value which should
be used for a next NULL in this statement).

Then there is write_row() of the second NULL, update_auto_increment()
is called and this part of it is executed:
  if ((nr= next_insert_id) >= auto_inc_interval_for_cur_row.maximum())
  {
    /* next_insert_id is beyond what is reserved, so we reserve more. */

here next_insert_id is 4, auto_inc_interval_for_cur_row.maximum() is 3
(the maximum value reserved from the engine), so a new reservation
has to be made, hence the second call to get_auto_increment().

It could indeed be that, right after the first call to
get_auto_increment() by our connection con1, a concurrent connection
con2 reserved 3, then a concurrent connection con3 reserved 4,5,6,
then con2 rolled back. Then con1 inserted 3. Then con1 must call the
engine again for the 2nd NULL, it must not try to insert 4 (this value
is reserved by somebody else).

-- 
   __  ___     ___ ____  __
  /  |/  /_ __/ __/ __ \/ /    Mr. Guilhem Bichot <guilhem@stripped>
 / /|_/ / // /\ \/ /_/ / /__   MySQL AB, Full-Time Software Developer
/_/  /_/\_, /___/\___\_\___/   Bordeaux, France
       <___/   www.mysql.com   
Thread
Auto increment fields on 5.1.xJan Lindström26 Oct
  • Re: Auto increment fields on 5.1.xGuilhem Bichot30 Oct