~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/ha_innodb.cc

Merged Drizzle's Trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
178
178
static plugin::TableFunction* innodb_locks_tool= NULL;
179
179
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
180
180
 
181
 
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
182
 
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
183
 
static const long AUTOINC_NO_LOCKING = 2;
184
 
 
185
181
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
186
182
  innobase_log_buffer_size,
187
183
  innobase_additional_mem_pool_size, innobase_file_io_threads,
188
 
  innobase_force_recovery, innobase_open_files,
189
 
  innobase_autoinc_lock_mode;
 
184
  innobase_force_recovery, innobase_open_files;
190
185
static ulong innobase_commit_concurrency = 0;
191
186
static ulong innobase_read_io_threads;
192
187
static ulong innobase_write_io_threads;
1471
1466
  INSERT INTO T VALUES(), (), ();
1472
1467
 
1473
1468
innobase_next_autoinc() will be called with increment set to
1474
 
n * 3 where autoinc_lock_mode != TRADITIONAL because we want
1475
1469
to reserve 3 values for the multi-value INSERT above.
1476
1470
@return the next value */
1477
1471
static
2842
2836
  prebuilt = row_create_prebuilt(ib_table);
2843
2837
 
2844
2838
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
2845
 
  prebuilt->default_rec = table->getShare()->default_values;
 
2839
  prebuilt->default_rec = table->getDefaultValues();
2846
2840
  ut_ad(prebuilt->default_rec);
2847
2841
 
2848
2842
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3241
3235
  uint    buff_len,/*!< in: buffer length */
3242
3236
  const unsigned char*  record)/*!< in: row in MySQL format */
3243
3237
{
3244
 
  KeyInfo*    key_info  = table->key_info + keynr;
 
3238
  KeyInfo*    key_info  = &table->key_info[keynr];
3245
3239
  KeyPartInfo*  key_part  = key_info->key_part;
3246
3240
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3247
3241
  char*   buff_start  = buff;
3555
3549
    the clustered index */
3556
3550
  }
3557
3551
 
3558
 
  n_fields = (ulint)table->getShare()->fields; /* number of columns */
 
3552
  n_fields = (ulint)table->getShare()->sizeFields(); /* number of columns */
3559
3553
 
3560
3554
  if (!prebuilt->mysql_template) {
3561
3555
    prebuilt->mysql_template = (mysql_row_templ_t*)
3569
3563
 
3570
3564
  /* Note that in InnoDB, i is the column number. MySQL calls columns
3571
3565
  'fields'. */
3572
 
  for (i = 0; i < n_fields; i++) {
 
3566
  for (i = 0; i < n_fields; i++) 
 
3567
  {
3573
3568
    templ = prebuilt->mysql_template + n_requested_fields;
3574
 
    field = table->field[i];
 
3569
    field = table->getField(i);
3575
3570
 
3576
3571
    if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
3577
3572
      /* Decide which columns we should fetch
3742
3737
{
3743
3738
  ulint   error = DB_SUCCESS;
3744
3739
 
3745
 
  switch (innobase_autoinc_lock_mode) {
3746
 
  case AUTOINC_NO_LOCKING:
3747
 
    /* Acquire only the AUTOINC mutex. */
3748
 
    dict_table_autoinc_lock(prebuilt->table);
3749
 
    break;
3750
 
 
3751
 
  case AUTOINC_NEW_STYLE_LOCKING:
3752
 
    /* For simple (single/multi) row INSERTs, we fallback to the
3753
 
    old style only if another transaction has already acquired
3754
 
    the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
3755
 
    etc. type of statement. */
3756
 
    if (session_sql_command(user_session) == SQLCOM_INSERT
3757
 
        || session_sql_command(user_session) == SQLCOM_REPLACE) {
3758
 
      dict_table_t* d_table = prebuilt->table;
3759
 
 
3760
 
      /* Acquire the AUTOINC mutex. */
3761
 
      dict_table_autoinc_lock(d_table);
3762
 
 
3763
 
      /* We need to check that another transaction isn't
3764
 
      already holding the AUTOINC lock on the table. */
3765
 
      if (d_table->n_waiting_or_granted_auto_inc_locks) {
3766
 
        /* Release the mutex to avoid deadlocks. */
3767
 
        dict_table_autoinc_unlock(d_table);
3768
 
      } else {
3769
 
        break;
3770
 
      }
3771
 
    }
3772
 
    /* Fall through to old style locking. */
3773
 
 
3774
 
  case AUTOINC_OLD_STYLE_LOCKING:
3775
 
    error = row_lock_table_autoinc_for_mysql(prebuilt);
3776
 
 
3777
 
    if (error == DB_SUCCESS) {
3778
 
 
3779
 
      /* Acquire the AUTOINC mutex. */
3780
 
      dict_table_autoinc_lock(prebuilt->table);
3781
 
    }
3782
 
    break;
3783
 
 
3784
 
  default:
3785
 
    ut_error;
3786
 
  }
 
3740
  dict_table_autoinc_lock(prebuilt->table);
3787
3741
 
3788
3742
  return(ulong(error));
3789
3743
}
3797
3751
/*================================*/
3798
3752
  uint64_t  autoinc)  /*!< in: value to store */
3799
3753
{
3800
 
  ulint   error;
3801
 
 
3802
 
  error = innobase_lock_autoinc();
3803
 
 
3804
 
  if (error == DB_SUCCESS) {
3805
 
 
3806
 
    dict_table_autoinc_initialize(prebuilt->table, autoinc);
3807
 
 
3808
 
    dict_table_autoinc_unlock(prebuilt->table);
3809
 
  }
3810
 
 
3811
 
  return(ulong(error));
 
3754
  dict_table_autoinc_lock(prebuilt->table);
 
3755
  dict_table_autoinc_initialize(prebuilt->table, autoinc);
 
3756
  dict_table_autoinc_unlock(prebuilt->table);
 
3757
 
 
3758
  return(ulong(DB_SUCCESS));
3812
3759
}
3813
3760
 
3814
3761
/********************************************************************//**
3821
3768
/*==================================*/
3822
3769
  uint64_t  auto_inc) /*!< in: value to store */
3823
3770
{
3824
 
  ulint   error;
3825
 
 
3826
 
  error = innobase_lock_autoinc();
3827
 
 
3828
 
  if (error == DB_SUCCESS) {
3829
 
 
3830
 
    dict_table_autoinc_update_if_greater(prebuilt->table, auto_inc);
3831
 
 
3832
 
    dict_table_autoinc_unlock(prebuilt->table);
3833
 
  }
3834
 
 
3835
 
  return(ulong(error));
 
3771
  dict_table_autoinc_lock(prebuilt->table);
 
3772
  dict_table_autoinc_update_if_greater(prebuilt->table, auto_inc);
 
3773
  dict_table_autoinc_unlock(prebuilt->table);
 
3774
 
 
3775
  return(ulong(DB_SUCCESS));
3836
3776
}
3837
3777
 
3838
3778
/********************************************************************//**
4085
4025
  Session*  )   /*!< in: user thread */
4086
4026
{
4087
4027
  unsigned char*    original_upd_buff = upd_buff;
4088
 
  Field*    field;
4089
4028
  enum_field_types field_mysql_type;
4090
4029
  uint    n_fields;
4091
4030
  ulint   o_len;
4102
4041
  dict_index_t* clust_index;
4103
4042
  uint    i= 0;
4104
4043
 
4105
 
  n_fields = table->getShare()->fields;
 
4044
  n_fields = table->getShare()->sizeFields();
4106
4045
  clust_index = dict_table_get_first_index(prebuilt->table);
4107
4046
 
4108
4047
  /* We use upd_buff to convert changed fields */
4109
4048
  buf = (byte*) upd_buff;
4110
4049
 
4111
4050
  for (i = 0; i < n_fields; i++) {
4112
 
    field = table->field[i];
 
4051
    Field *field= table->getField(i);
4113
4052
 
4114
4053
    o_ptr = (const byte*) old_row + get_field_offset(table, field);
4115
4054
    n_ptr = (const byte*) new_row + get_field_offset(table, field);
4258
4197
 
4259
4198
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4260
4199
 
 
4200
  if (table->found_next_number_field)
 
4201
  {
 
4202
    uint64_t  auto_inc;
 
4203
    uint64_t  col_max_value;
 
4204
 
 
4205
    auto_inc = table->found_next_number_field->val_int();
 
4206
 
 
4207
    /* We need the upper limit of the col type to check for
 
4208
    whether we update the table autoinc counter or not. */
 
4209
    col_max_value = innobase_get_int_col_max_value(
 
4210
      table->found_next_number_field);
 
4211
 
 
4212
    uint64_t current_autoinc;
 
4213
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
 
4214
    if (autoinc_error == DB_SUCCESS
 
4215
        && auto_inc <= col_max_value && auto_inc != 0
 
4216
        && auto_inc >= current_autoinc)
 
4217
    {
 
4218
 
 
4219
      uint64_t  need;
 
4220
      uint64_t  offset;
 
4221
 
 
4222
      offset = prebuilt->autoinc_offset;
 
4223
      need = prebuilt->autoinc_increment;
 
4224
 
 
4225
      auto_inc = innobase_next_autoinc(
 
4226
        auto_inc, need, offset, col_max_value);
 
4227
 
 
4228
      dict_table_autoinc_update_if_greater(prebuilt->table, auto_inc);
 
4229
    }
 
4230
 
 
4231
    dict_table_autoinc_unlock(prebuilt->table);
 
4232
  }
 
4233
 
4261
4234
  innodb_srv_conc_enter_innodb(trx);
4262
4235
 
4263
4236
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4715
4688
        clustered index, even if it was internally
4716
4689
        generated by InnoDB */
4717
4690
{
4718
 
  KeyInfo*    key = 0;
4719
4691
  dict_index_t* index = 0;
4720
4692
 
4721
4693
  ha_statistic_increment(&system_status_var::ha_read_key_count);
4723
4695
  ut_ad(user_session == ha_session());
4724
4696
  ut_a(prebuilt->trx == session_to_trx(user_session));
4725
4697
 
4726
 
  if (keynr != MAX_KEY && table->getShare()->keys > 0) {
4727
 
    key = table->key_info + keynr;
4728
 
 
 
4698
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
 
4699
  {
4729
4700
    index = dict_table_get_index_on_name(prebuilt->table,
4730
 
                 key->name);
 
4701
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
4731
4702
  } else {
4732
4703
    index = dict_table_get_first_index(prebuilt->table);
4733
4704
  }
4736
4707
    errmsg_printf(ERRMSG_LVL_ERROR, 
4737
4708
      "Innodb could not find key n:o %u with name %s "
4738
4709
      "from dict cache for table %s",
4739
 
      keynr, key ? key->name : "NULL",
 
4710
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
4740
4711
      prebuilt->table->name);
4741
4712
  }
4742
4713
 
5165
5136
  ulint   charset_no;
5166
5137
  ulint   i;
5167
5138
 
5168
 
  n_cols = form->getShare()->fields;
 
5139
  n_cols = form->getShare()->sizeFields();
5169
5140
 
5170
5141
  /* We pass 0 as the space id, and determine at a lower level the space
5171
5142
  id where to store the table */
5178
5149
  }
5179
5150
 
5180
5151
  for (i = 0; i < n_cols; i++) {
5181
 
    field = form->field[i];
 
5152
    field = form->getField(i);
5182
5153
 
5183
5154
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5184
5155
                  field);
5279
5250
  ulint   j;
5280
5251
  ulint*    field_lengths;
5281
5252
 
5282
 
  key = form->key_info + key_num;
 
5253
  key = &form->key_info[key_num];
5283
5254
 
5284
5255
  n_fields = key->key_parts;
5285
5256
 
5311
5282
    the length of the key part versus the column. */
5312
5283
 
5313
5284
    field = NULL;
5314
 
    for (j = 0; j < form->getShare()->fields; j++) {
 
5285
    for (j = 0; j < form->getShare()->sizeFields(); j++)
 
5286
    {
5315
5287
 
5316
 
      field = form->field[j];
 
5288
      field = form->getField(j);
5317
5289
 
5318
5290
      if (0 == innobase_strcasecmp(
5319
5291
          field->field_name,
5324
5296
      }
5325
5297
    }
5326
5298
 
5327
 
    ut_a(j < form->getShare()->fields);
 
5299
    ut_a(j < form->getShare()->sizeFields());
5328
5300
 
5329
5301
    col_type = get_innobase_type_from_mysql_type(
5330
5302
          &is_unsigned, key_part->field);
5461
5433
 
5462
5434
  const char *table_name= identifier.getPath().c_str();
5463
5435
 
5464
 
  if (form.getShare()->fields > 1000) {
 
5436
  if (form.getShare()->sizeFields() > 1000) {
5465
5437
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
5466
5438
      but we play safe here */
5467
5439
 
5592
5564
 
5593
5565
  /* Create the keys */
5594
5566
 
5595
 
  if (form.getShare()->keys == 0 || primary_key_no == -1) {
 
5567
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
5596
5568
    /* Create an index which is used as the clustered index;
5597
5569
      order the rows by their row id which is internally generated
5598
5570
      by InnoDB */
5611
5583
    }
5612
5584
  }
5613
5585
 
5614
 
  for (i = 0; i < form.getShare()->keys; i++) {
 
5586
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
5615
5587
    if (i != (uint) primary_key_no) {
5616
5588
 
5617
5589
      if ((error = create_index(trx, &form, iflags, norm_name,
5843
5815
    if (identifier.getType() == message::Table::TEMPORARY)
5844
5816
    {
5845
5817
      session.removeTableMessage(identifier);
 
5818
      ulint sql_command = session_sql_command(&session);
 
5819
 
 
5820
      // If this was the final removal to an alter table then we will need
 
5821
      // to remove the .dfe that was left behind.
 
5822
      if ((sql_command == SQLCOM_ALTER_TABLE
 
5823
       || sql_command == SQLCOM_CREATE_INDEX
 
5824
       || sql_command == SQLCOM_DROP_INDEX))
 
5825
      {
 
5826
        string path(identifier.getPath());
 
5827
 
 
5828
        path.append(DEFAULT_FILE_EXTENSION);
 
5829
 
 
5830
        (void)internal::my_delete(path.c_str(), MYF(0));
 
5831
      }
5846
5832
    }
5847
5833
    else
5848
5834
    {
6084
6070
 
6085
6071
  active_index = keynr;
6086
6072
 
6087
 
  key = table->key_info + active_index;
 
6073
  key = &table->key_info[active_index];
6088
6074
 
6089
 
  index = dict_table_get_index_on_name(prebuilt->table, key->name);
 
6075
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
6090
6076
 
6091
6077
  /* MySQL knows about this index and so we must be able to find it.*/
6092
6078
  ut_a(index);
6437
6423
      index = dict_table_get_next_index(index);
6438
6424
    }
6439
6425
 
6440
 
    for (i = 0; i < table->getShare()->keys; i++) {
 
6426
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
6441
6427
      if (index == NULL) {
6442
6428
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
6443
6429
            "indexes inside InnoDB than "
7531
7517
  uint64_t* value)    /*!< out: autoinc value */
7532
7518
{
7533
7519
  *value = 0;
7534
 
 
7535
 
  prebuilt->autoinc_error = innobase_lock_autoinc();
7536
 
 
7537
 
  if (prebuilt->autoinc_error == DB_SUCCESS) {
7538
 
 
7539
 
    /* Determine the first value of the interval */
7540
 
    *value = dict_table_autoinc_read(prebuilt->table);
7541
 
 
7542
 
    /* It should have been initialized during open. */
7543
 
    ut_a(*value != 0);
7544
 
  }
7545
 
 
7546
 
  return(prebuilt->autoinc_error);
 
7520
 
 
7521
  dict_table_autoinc_lock(prebuilt->table);
 
7522
  prebuilt->autoinc_error= DB_SUCCESS;
 
7523
  /* Determine the first value of the interval */
 
7524
  *value = dict_table_autoinc_read(prebuilt->table);
 
7525
 
 
7526
  /* It should have been initialized during open. */
 
7527
  ut_a(*value != 0);
 
7528
 
 
7529
  return(DB_SUCCESS);
7547
7530
}
7548
7531
 
7549
7532
/*******************************************************************//**
7640
7623
 
7641
7624
  *nb_reserved_values = trx->n_autoinc_rows;
7642
7625
 
7643
 
  /* With old style AUTOINC locking we only update the table's
7644
 
  AUTOINC counter after attempting to insert the row. */
7645
 
  if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
 
7626
  /* This all current style autoinc. */
 
7627
  {
7646
7628
    uint64_t  need;
7647
7629
    uint64_t  next_value;
7648
7630
    uint64_t  col_max_value;
7667
7649
      dict_table_autoinc_update_if_greater(
7668
7650
        prebuilt->table, prebuilt->autoinc_last_value);
7669
7651
    }
7670
 
  } else {
7671
 
    /* This will force doInsertRecord() into attempting an update
7672
 
    of the table's AUTOINC counter. */
7673
 
    prebuilt->autoinc_last_value = 0;
7674
7652
  }
7675
7653
 
7676
7654
  /* The increment to be used to increase the AUTOINC value, we use
8521
8499
  "Desired maximum length of the purge queue (0 = no limit)",
8522
8500
  NULL, NULL, 0, 0, ~0L, 0);
8523
8501
 
8524
 
static DRIZZLE_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
8525
 
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
8526
 
  "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
8527
 
  NULL, NULL, FALSE);
8528
 
 
8529
8502
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
8530
8503
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
8531
8504
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
8606
8579
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
8607
8580
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8608
8581
  "Size of each log file in a log group.",
8609
 
  NULL, NULL, 5*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8582
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
8610
8583
 
8611
8584
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
8612
8585
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8648
8621
  "Path to individual files and their sizes.",
8649
8622
  NULL, NULL, NULL);
8650
8623
 
8651
 
static DRIZZLE_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
8652
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8653
 
  "The AUTOINC lock modes supported by InnoDB:               "
8654
 
  "0 => Old style AUTOINC locking (for backward"
8655
 
  " compatibility)                                           "
8656
 
  "1 => New style AUTOINC locking                            "
8657
 
  "2 => No AUTOINC locking (unsafe for SBR)",
8658
 
  NULL, NULL,
8659
 
  AUTOINC_NO_LOCKING, /* Default setting */
8660
 
  AUTOINC_OLD_STYLE_LOCKING,  /* Minimum value */
8661
 
  AUTOINC_NO_LOCKING, 0); /* Maximum value */
8662
 
 
8663
8624
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
8664
8625
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
8665
8626
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
8716
8677
  DRIZZLE_SYSVAR(adaptive_flushing),
8717
8678
  DRIZZLE_SYSVAR(mirrored_log_groups),
8718
8679
  DRIZZLE_SYSVAR(open_files),
8719
 
  DRIZZLE_SYSVAR(rollback_on_timeout),
8720
8680
  DRIZZLE_SYSVAR(stats_on_metadata),
8721
8681
  DRIZZLE_SYSVAR(stats_sample_pages),
8722
8682
  DRIZZLE_SYSVAR(adaptive_hash_index),
8729
8689
  DRIZZLE_SYSVAR(table_locks),
8730
8690
  DRIZZLE_SYSVAR(thread_concurrency),
8731
8691
  DRIZZLE_SYSVAR(thread_sleep_delay),
8732
 
  DRIZZLE_SYSVAR(autoinc_lock_mode),
8733
8692
  DRIZZLE_SYSVAR(version),
8734
8693
  DRIZZLE_SYSVAR(use_sys_malloc),
8735
8694
  DRIZZLE_SYSVAR(change_buffering),