~ubuntu-branches/ubuntu/maverick/mysql-5.1/maverick-proposed

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/handler/ha_innodb.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 14:16:05 UTC
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: package-import@ubuntu.com-20120222141605-nxlu9yzc6attylc2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 2000, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved.
4
4
Copyright (c) 2008, 2009 Google Inc.
5
5
Copyright (c) 2009, Percona Inc.
6
6
 
174
174
 
175
175
static char*    innodb_version_str = (char*) INNODB_VERSION_STR;
176
176
 
 
177
/** Possible values for system variable "innodb_stats_method". The values
 
178
are defined the same as its corresponding MyISAM system variable
 
179
"myisam_stats_method"(see "myisam_stats_method_names"), for better usability */
 
180
static const char* innodb_stats_method_names[] = {
 
181
        "nulls_equal",
 
182
        "nulls_unequal",
 
183
        "nulls_ignored",
 
184
        NullS
 
185
};
 
186
 
 
187
/** Used to define an enumerate type of the system variable innodb_stats_method.
 
188
This is the same as "myisam_stats_method_typelib" */
 
189
static TYPELIB innodb_stats_method_typelib = {
 
190
        array_elements(innodb_stats_method_names) - 1,
 
191
        "innodb_stats_method_typelib",
 
192
        innodb_stats_method_names,
 
193
        NULL
 
194
};
 
195
 
177
196
/* The following counter is used to convey information to InnoDB
178
197
about server activity: in selects it is not sensible to call
179
198
srv_active_wake_master_thread after each fetch or search, we only do
482
501
  (char*) &export_vars.innodb_buffer_pool_pages_misc,     SHOW_LONG},
483
502
  {"buffer_pool_pages_total",
484
503
  (char*) &export_vars.innodb_buffer_pool_pages_total,    SHOW_LONG},
 
504
  {"buffer_pool_read_ahead_rnd",
 
505
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
485
506
  {"buffer_pool_read_ahead",
486
507
  (char*) &export_vars.innodb_buffer_pool_read_ahead,     SHOW_LONG},
487
508
  {"buffer_pool_read_ahead_evicted",
767
788
        case DB_INTERRUPTED:
768
789
                my_error(ER_QUERY_INTERRUPTED, MYF(0));
769
790
                /* fall through */
 
791
 
 
792
        case DB_FOREIGN_EXCEED_MAX_CASCADE:
 
793
                push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
794
                                    HA_ERR_ROW_IS_REFERENCED,
 
795
                                    "InnoDB: Cannot delete/update "
 
796
                                    "rows with cascading foreign key "
 
797
                                    "constraints that exceed max "
 
798
                                    "depth of %d. Please "
 
799
                                    "drop extra constraints and try "
 
800
                                    "again", DICT_FK_MAX_RECURSIVE_LOAD);
 
801
 
 
802
                /* fall through */
 
803
 
770
804
        case DB_ERROR:
771
805
        default:
772
806
                return(-1); /* unspecified error */
3347
3381
                err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3348
3382
 
3349
3383
                switch (err) {
3350
 
                case DB_SUCCESS:
 
3384
                case DB_SUCCESS: {
 
3385
                        ulonglong       col_max_value;
 
3386
 
 
3387
                        col_max_value = innobase_get_int_col_max_value(field);
 
3388
 
3351
3389
                        /* At the this stage we do not know the increment
3352
 
                        or the offset, so use a default increment of 1. */
3353
 
                        auto_inc = read_auto_inc + 1;
 
3390
                        nor the offset, so use a default increment of 1. */
 
3391
 
 
3392
                        auto_inc = innobase_next_autoinc(
 
3393
                                read_auto_inc, 1, 1, col_max_value);
 
3394
 
3354
3395
                        break;
3355
 
 
 
3396
                }
3356
3397
                case DB_RECORD_NOT_FOUND:
3357
3398
                        ut_print_timestamp(stderr);
3358
3399
                        fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3647
3688
                        dict_table_get_format(prebuilt->table));
3648
3689
        }
3649
3690
 
3650
 
        info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3651
 
 
3652
3691
        /* Only if the table has an AUTOINC column. */
3653
3692
        if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
3654
3693
                dict_table_autoinc_lock(prebuilt->table);
3665
3704
                dict_table_autoinc_unlock(prebuilt->table);
3666
3705
        }
3667
3706
 
 
3707
        info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3708
 
3668
3709
        DBUG_RETURN(0);
3669
3710
}
3670
3711
 
3750
3791
        return(0);
3751
3792
}
3752
3793
 
3753
 
/**************************************************************//**
3754
 
Sets a field in a record to SQL NULL. Uses the record format
3755
 
information in table to track the null bit in record. */
3756
 
static inline
3757
 
void
3758
 
set_field_in_record_to_null(
3759
 
/*========================*/
3760
 
        TABLE*  table,  /*!< in: MySQL table object */
3761
 
        Field*  field,  /*!< in: MySQL field object */
3762
 
        char*   record) /*!< in: a row in MySQL format */
3763
 
{
3764
 
        int     null_offset;
3765
 
 
3766
 
        null_offset = (uint) ((char*) field->null_ptr
3767
 
                                        - (char*) table->record[0]);
3768
 
 
3769
 
        record[null_offset] = record[null_offset] | field->null_bit;
3770
 
}
3771
 
 
3772
3794
/*************************************************************//**
3773
3795
InnoDB uses this function to compare two data fields for which the data type
3774
3796
is such that we must use MySQL code to compare them. NOTE that the prototype
4411
4433
                n_requested_fields++;
4412
4434
 
4413
4435
                templ->col_no = i;
 
4436
                templ->clust_rec_field_no = dict_col_get_clust_pos(
 
4437
                        &index->table->cols[i], clust_index);
 
4438
                ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4414
4439
 
4415
4440
                if (index == clust_index) {
4416
 
                        templ->rec_field_no = dict_col_get_clust_pos(
4417
 
                                &index->table->cols[i], index);
 
4441
                        templ->rec_field_no = templ->clust_rec_field_no;
4418
4442
                } else {
4419
4443
                        templ->rec_field_no = dict_index_get_nth_col_pos(
4420
4444
                                                                index, i);
4421
 
                }
4422
 
 
4423
 
                if (templ->rec_field_no == ULINT_UNDEFINED) {
4424
 
                        prebuilt->need_to_access_clustered = TRUE;
 
4445
                        if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4446
                                prebuilt->need_to_access_clustered = TRUE;
 
4447
                        }
4425
4448
                }
4426
4449
 
4427
4450
                if (field->null_ptr) {
4473
4496
                for (i = 0; i < n_requested_fields; i++) {
4474
4497
                        templ = prebuilt->mysql_template + i;
4475
4498
 
4476
 
                        templ->rec_field_no = dict_col_get_clust_pos(
4477
 
                                &index->table->cols[templ->col_no],
4478
 
                                clust_index);
 
4499
                        templ->rec_field_no = templ->clust_rec_field_no;
4479
4500
                }
4480
4501
        }
4481
4502
}
4772
4793
 
4773
4794
                        switch (sql_command) {
4774
4795
                        case SQLCOM_LOAD:
4775
 
                                if ((trx->duplicates
4776
 
                                    & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) {
 
4796
                                if (trx->duplicates) {
4777
4797
 
4778
4798
                                        goto set_max_autoinc;
4779
4799
                                }
4950
4970
                        /* The field has changed */
4951
4971
 
4952
4972
                        ufield = uvect->fields + n_changed;
 
4973
                        UNIV_MEM_INVALID(ufield, sizeof *ufield);
4953
4974
 
4954
4975
                        /* Let us use a dummy dfield to make the conversion
4955
4976
                        from the MySQL column format to the InnoDB format */
4956
4977
 
4957
 
                        dict_col_copy_type(prebuilt->table->cols + i,
4958
 
                                           dfield_get_type(&dfield));
4959
 
 
4960
4978
                        if (n_len != UNIV_SQL_NULL) {
 
4979
                                dict_col_copy_type(prebuilt->table->cols + i,
 
4980
                                                   dfield_get_type(&dfield));
 
4981
 
4961
4982
                                buf = row_mysql_store_col_in_innobase_format(
4962
4983
                                        &dfield,
4963
4984
                                        (byte*)buf,
4965
4986
                                        new_mysql_row_col,
4966
4987
                                        col_pack_len,
4967
4988
                                        dict_table_is_comp(prebuilt->table));
4968
 
                                dfield_copy_data(&ufield->new_val, &dfield);
 
4989
                                dfield_copy(&ufield->new_val, &dfield);
4969
4990
                        } else {
4970
4991
                                dfield_set_null(&ufield->new_val);
4971
4992
                        }
5048
5069
            && table->next_number_field
5049
5070
            && new_row == table->record[0]
5050
5071
            && thd_sql_command(user_thd) == SQLCOM_INSERT
5051
 
            && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
5052
 
                == TRX_DUP_IGNORE)  {
 
5072
            && trx->duplicates)  {
5053
5073
 
5054
5074
                ulonglong       auto_inc;
5055
5075
                ulonglong       col_max_value;
5407
5427
                        (byte*) key_ptr,
5408
5428
                        (ulint) key_len,
5409
5429
                        prebuilt->trx);
 
5430
                DBUG_ASSERT(prebuilt->search_tuple->n_fields > 0);
5410
5431
        } else {
5411
5432
                /* We position the cursor to the last or the first entry
5412
5433
                in the index */
5499
5520
        dict_index_t*   index = 0;
5500
5521
 
5501
5522
        DBUG_ENTER("innobase_get_index");
5502
 
        ha_statistic_increment(&SSV::ha_read_key_count);
5503
5523
 
5504
5524
        if (keynr != MAX_KEY && table->s->keys > 0) {
5505
5525
                key = table->key_info + keynr;
5984
6004
        DBUG_PRINT("enter", ("table_name: %s", table_name));
5985
6005
 
5986
6006
        ut_a(trx->mysql_thd != NULL);
5987
 
        if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
5988
 
                                                  (THD*) trx->mysql_thd)) {
5989
 
                DBUG_RETURN(HA_ERR_GENERIC);
 
6007
 
 
6008
        /* MySQL does the name length check. But we do additional check
 
6009
        on the name length here */
 
6010
        if (strlen(table_name) > MAX_FULL_NAME_LEN) {
 
6011
                push_warning_printf(
 
6012
                        (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6013
                        ER_TABLE_NAME,
 
6014
                        "InnoDB: Table Name or Database Name is too long");
 
6015
                DBUG_RETURN(ER_TABLE_NAME);
5990
6016
        }
5991
6017
 
5992
6018
        n_cols = form->s->fields;
6097
6123
                        col_len);
6098
6124
        }
6099
6125
 
 
6126
        srv_lower_case_table_names = lower_case_table_names;
 
6127
 
6100
6128
        error = row_create_table_for_mysql(table, trx);
6101
6129
 
6102
6130
        if (error == DB_DUPLICATE_KEY) {
6271
6299
}
6272
6300
 
6273
6301
/*****************************************************************//**
 
6302
Return a display name for the row format
 
6303
@return row format name */
 
6304
UNIV_INTERN
 
6305
const char*
 
6306
get_row_format_name(
 
6307
/*================*/
 
6308
        enum row_type   row_format)             /*!< in: Row Format */
 
6309
{
 
6310
        switch (row_format) {
 
6311
        case ROW_TYPE_COMPACT:
 
6312
                return("COMPACT");
 
6313
        case ROW_TYPE_COMPRESSED:
 
6314
                return("COMPRESSED");
 
6315
        case ROW_TYPE_DYNAMIC:
 
6316
                return("DYNAMIC");
 
6317
        case ROW_TYPE_REDUNDANT:
 
6318
                return("REDUNDANT");
 
6319
        case ROW_TYPE_DEFAULT:
 
6320
                return("DEFAULT");
 
6321
        case ROW_TYPE_FIXED:
 
6322
                return("FIXED");
 
6323
        case ROW_TYPE_PAGE:
 
6324
        case ROW_TYPE_NOT_USED:
 
6325
                break;
 
6326
        }
 
6327
        return("NOT USED");
 
6328
}
 
6329
 
 
6330
/** If file-per-table is missing, issue warning and set ret false */
 
6331
#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE               \
 
6332
        if (!srv_file_per_table) {                              \
 
6333
                push_warning_printf(                            \
 
6334
                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,      \
 
6335
                        ER_ILLEGAL_HA_CREATE_OPTION,            \
 
6336
                        "InnoDB: ROW_FORMAT=%s requires"        \
 
6337
                        " innodb_file_per_table.",              \
 
6338
                        get_row_format_name(row_format));       \
 
6339
                ret = FALSE;                                    \
 
6340
        }
 
6341
 
 
6342
/** If file-format is Antelope, issue warning and set ret false */
 
6343
#define CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE                  \
 
6344
        if (srv_file_format < DICT_TF_FORMAT_ZIP) {             \
 
6345
                push_warning_printf(                            \
 
6346
                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,      \
 
6347
                        ER_ILLEGAL_HA_CREATE_OPTION,            \
 
6348
                        "InnoDB: ROW_FORMAT=%s requires"        \
 
6349
                        " innodb_file_format > Antelope.",      \
 
6350
                        get_row_format_name(row_format));       \
 
6351
                ret = FALSE;                                    \
 
6352
        }
 
6353
 
 
6354
 
 
6355
/*****************************************************************//**
6274
6356
Validates the create options. We may build on this function
6275
6357
in future. For now, it checks two specifiers:
6276
6358
KEY_BLOCK_SIZE and ROW_FORMAT
6285
6367
                                        columns and indexes */
6286
6368
        HA_CREATE_INFO* create_info)    /*!< in: create info. */
6287
6369
{
6288
 
        ibool   kbs_specified   = FALSE;
 
6370
        ibool   kbs_specified   = FALSE;
6289
6371
        ibool   ret             = TRUE;
6290
 
 
 
6372
        enum row_type   row_format      = form->s->row_type;
6291
6373
 
6292
6374
        ut_ad(thd != NULL);
6293
6375
 
6299
6381
        ut_ad(form != NULL);
6300
6382
        ut_ad(create_info != NULL);
6301
6383
 
6302
 
        /* First check if KEY_BLOCK_SIZE was specified. */
6303
 
        if (create_info->key_block_size
6304
 
            || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
6305
 
 
 
6384
        /* First check if a non-zero KEY_BLOCK_SIZE was specified. */
 
6385
        if (create_info->key_block_size) {
6306
6386
                kbs_specified = TRUE;
6307
6387
                switch (create_info->key_block_size) {
6308
6388
                case 1:
6310
6390
                case 4:
6311
6391
                case 8:
6312
6392
                case 16:
6313
 
                        /* Valid value. */
6314
 
                        break;
6315
 
                default:
6316
 
                        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6317
 
                                            ER_ILLEGAL_HA_CREATE_OPTION,
6318
 
                                            "InnoDB: invalid"
6319
 
                                            " KEY_BLOCK_SIZE = %lu."
6320
 
                                            " Valid values are"
6321
 
                                            " [1, 2, 4, 8, 16]",
6322
 
                                            create_info->key_block_size);
6323
 
                        ret = FALSE;
6324
 
                }
6325
 
        }
6326
 
        
6327
 
        /* If KEY_BLOCK_SIZE was specified, check for its
6328
 
        dependencies. */
6329
 
        if (kbs_specified && !srv_file_per_table) {
6330
 
                push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6331
 
                             ER_ILLEGAL_HA_CREATE_OPTION,
6332
 
                             "InnoDB: KEY_BLOCK_SIZE"
6333
 
                             " requires innodb_file_per_table.");
6334
 
                ret = FALSE;
6335
 
        }
6336
 
 
6337
 
        if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
6338
 
                push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6339
 
                             ER_ILLEGAL_HA_CREATE_OPTION,
6340
 
                             "InnoDB: KEY_BLOCK_SIZE"
6341
 
                             " requires innodb_file_format >"
6342
 
                             " Antelope.");
6343
 
                ret = FALSE;
6344
 
        }
6345
 
 
6346
 
        /* Now check for ROW_FORMAT specifier. */
6347
 
        if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
6348
 
                switch (form->s->row_type) {
6349
 
                        const char* row_format_name;
6350
 
                case ROW_TYPE_COMPRESSED:
6351
 
                case ROW_TYPE_DYNAMIC:
6352
 
                        row_format_name
6353
 
                                = form->s->row_type == ROW_TYPE_COMPRESSED
6354
 
                                ? "COMPRESSED"
6355
 
                                : "DYNAMIC";
6356
 
 
6357
 
                        /* These two ROW_FORMATs require
6358
 
                        srv_file_per_table and srv_file_format */
 
6393
                        /* Valid KEY_BLOCK_SIZE, check its dependencies. */
6359
6394
                        if (!srv_file_per_table) {
6360
 
                                push_warning_printf(
6361
 
                                        thd,
6362
 
                                        MYSQL_ERROR::WARN_LEVEL_WARN,
 
6395
                                push_warning(
 
6396
                                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6363
6397
                                        ER_ILLEGAL_HA_CREATE_OPTION,
6364
 
                                        "InnoDB: ROW_FORMAT=%s"
6365
 
                                        " requires innodb_file_per_table.",
6366
 
                                        row_format_name);
6367
 
                                        ret = FALSE;
6368
 
 
 
6398
                                        "InnoDB: KEY_BLOCK_SIZE requires"
 
6399
                                        " innodb_file_per_table.");
 
6400
                                ret = FALSE;
6369
6401
                        }
6370
 
 
6371
6402
                        if (srv_file_format < DICT_TF_FORMAT_ZIP) {
6372
 
                                push_warning_printf(
6373
 
                                        thd,
6374
 
                                        MYSQL_ERROR::WARN_LEVEL_WARN,
6375
 
                                        ER_ILLEGAL_HA_CREATE_OPTION,
6376
 
                                        "InnoDB: ROW_FORMAT=%s"
6377
 
                                        " requires innodb_file_format >"
6378
 
                                        " Antelope.",
6379
 
                                        row_format_name);
6380
 
                                        ret = FALSE;
6381
 
                        }
6382
 
 
6383
 
                        /* Cannot specify KEY_BLOCK_SIZE with
6384
 
                        ROW_FORMAT = DYNAMIC.
6385
 
                        However, we do allow COMPRESSED to be
6386
 
                        specified with KEY_BLOCK_SIZE. */
6387
 
                        if (kbs_specified
6388
 
                            && form->s->row_type == ROW_TYPE_DYNAMIC) {
6389
 
                                push_warning_printf(
6390
 
                                        thd,
6391
 
                                        MYSQL_ERROR::WARN_LEVEL_WARN,
6392
 
                                        ER_ILLEGAL_HA_CREATE_OPTION,
6393
 
                                        "InnoDB: cannot specify"
6394
 
                                        " ROW_FORMAT = DYNAMIC with"
6395
 
                                        " KEY_BLOCK_SIZE.");
6396
 
                                        ret = FALSE;
6397
 
                        }
6398
 
 
6399
 
                        break;
6400
 
 
6401
 
                case ROW_TYPE_REDUNDANT:
6402
 
                case ROW_TYPE_COMPACT:
6403
 
                case ROW_TYPE_DEFAULT:
6404
 
                        /* Default is COMPACT. */
6405
 
                        row_format_name
6406
 
                                = form->s->row_type == ROW_TYPE_REDUNDANT
6407
 
                                ? "REDUNDANT"
6408
 
                                : "COMPACT";
6409
 
 
6410
 
                        /* Cannot specify KEY_BLOCK_SIZE with these
6411
 
                        format specifiers. */
6412
 
                        if (kbs_specified) {
6413
 
                                push_warning_printf(
6414
 
                                        thd,
6415
 
                                        MYSQL_ERROR::WARN_LEVEL_WARN,
6416
 
                                        ER_ILLEGAL_HA_CREATE_OPTION,
6417
 
                                        "InnoDB: cannot specify"
6418
 
                                        " ROW_FORMAT = %s with"
6419
 
                                        " KEY_BLOCK_SIZE.",
6420
 
                                        row_format_name);
6421
 
                                        ret = FALSE;
6422
 
                        }
6423
 
 
6424
 
                        break;
6425
 
 
 
6403
                                push_warning(
 
6404
                                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6405
                                        ER_ILLEGAL_HA_CREATE_OPTION,
 
6406
                                        "InnoDB: KEY_BLOCK_SIZE requires"
 
6407
                                        " innodb_file_format > Antelope.");
 
6408
                                        ret = FALSE;
 
6409
                        }
 
6410
                        break;
6426
6411
                default:
6427
 
                        push_warning(thd,
6428
 
                                     MYSQL_ERROR::WARN_LEVEL_WARN,
6429
 
                                     ER_ILLEGAL_HA_CREATE_OPTION,
6430
 
                                     "InnoDB: invalid ROW_FORMAT specifier.");
6431
 
                        ret = FALSE;
6432
 
 
6433
 
                }
 
6412
                        push_warning_printf(
 
6413
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6414
                                ER_ILLEGAL_HA_CREATE_OPTION,
 
6415
                                "InnoDB: invalid KEY_BLOCK_SIZE = %lu."
 
6416
                                " Valid values are [1, 2, 4, 8, 16]",
 
6417
                                create_info->key_block_size);
 
6418
                        ret = FALSE;
 
6419
                        break;
 
6420
                }
 
6421
        }
 
6422
        
 
6423
        /* Check for a valid Innodb ROW_FORMAT specifier and
 
6424
        other incompatibilities. */
 
6425
        switch (row_format) {
 
6426
        case ROW_TYPE_COMPRESSED:
 
6427
                CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE;
 
6428
                CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE;
 
6429
                break;
 
6430
        case ROW_TYPE_DYNAMIC:
 
6431
                CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE;
 
6432
                CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE;
 
6433
                /* fall through since dynamic also shuns KBS */
 
6434
        case ROW_TYPE_COMPACT:
 
6435
        case ROW_TYPE_REDUNDANT:
 
6436
                if (kbs_specified) {
 
6437
                        push_warning_printf(
 
6438
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6439
                                ER_ILLEGAL_HA_CREATE_OPTION,
 
6440
                                "InnoDB: cannot specify ROW_FORMAT = %s"
 
6441
                                " with KEY_BLOCK_SIZE.",
 
6442
                                get_row_format_name(row_format));
 
6443
                        ret = FALSE;
 
6444
                }
 
6445
                break;
 
6446
        case ROW_TYPE_DEFAULT:
 
6447
                break;
 
6448
        case ROW_TYPE_FIXED:
 
6449
        case ROW_TYPE_PAGE:
 
6450
        case ROW_TYPE_NOT_USED:
 
6451
                push_warning(
 
6452
                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6453
                        ER_ILLEGAL_HA_CREATE_OPTION,            \
 
6454
                        "InnoDB: invalid ROW_FORMAT specifier.");
 
6455
                ret = FALSE;
 
6456
                break;
6434
6457
        }
6435
6458
 
6436
6459
        return(ret);
6480
6503
        const ulint     file_format = srv_file_format;
6481
6504
        const char*     stmt;
6482
6505
        size_t          stmt_len;
6483
 
        enum row_type   row_type;
 
6506
        enum row_type   row_format;
6484
6507
 
6485
6508
        DBUG_ENTER("ha_innobase::create");
6486
6509
 
6518
6541
                DBUG_RETURN(HA_ERR_TO_BIG_ROW);
6519
6542
        }
6520
6543
 
6521
 
        /* Get the transaction associated with the current thd, or create one
6522
 
        if not yet created */
6523
 
 
6524
 
        parent_trx = check_trx_exists(thd);
6525
 
 
6526
 
        /* In case MySQL calls this in the middle of a SELECT query, release
6527
 
        possible adaptive hash latch to avoid deadlocks of threads */
6528
 
 
6529
 
        trx_search_latch_release_if_reserved(parent_trx);
6530
 
 
6531
 
        trx = innobase_trx_allocate(thd);
6532
 
 
6533
 
        if (lower_case_table_names) {
6534
 
                srv_lower_case_table_names = TRUE;
6535
 
        } else {
6536
 
                srv_lower_case_table_names = FALSE;
6537
 
        }
6538
 
 
6539
6544
        strcpy(name2, name);
6540
6545
 
6541
6546
        normalize_table_name(norm_name, name2);
6542
6547
 
6543
 
        /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6544
 
        or lock waits can happen in it during a table create operation.
6545
 
        Drop table etc. do this latching in row0mysql.c. */
6546
 
 
6547
 
        row_mysql_lock_data_dictionary(trx);
6548
 
 
6549
6548
        /* Create the table definition in InnoDB */
6550
6549
 
6551
6550
        flags = 0;
6552
6551
 
6553
6552
        /* Validate create options if innodb_strict_mode is set. */
6554
6553
        if (!create_options_are_valid(thd, form, create_info)) {
6555
 
                error = ER_ILLEGAL_HA_CREATE_OPTION;
6556
 
                goto cleanup;
 
6554
                DBUG_RETURN(ER_ILLEGAL_HA_CREATE_OPTION);
6557
6555
        }
6558
6556
 
6559
 
        if (create_info->key_block_size
6560
 
            || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
 
6557
        if (create_info->key_block_size) {
6561
6558
                /* Determine the page_zip.ssize corresponding to the
6562
6559
                requested page size (key_block_size) in kilobytes. */
6563
6560
 
6564
6561
                ulint   ssize, ksize;
6565
6562
                ulint   key_block_size = create_info->key_block_size;
6566
6563
 
 
6564
                /*  Set 'flags' to the correct key_block_size.
 
6565
                It will be zero if key_block_size is an invalid number.*/
6567
6566
                for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX;
6568
6567
                     ssize++, ksize <<= 1) {
6569
6568
                        if (key_block_size == ksize) {
6576
6575
                }
6577
6576
 
6578
6577
                if (!srv_file_per_table) {
6579
 
                        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6580
 
                                     ER_ILLEGAL_HA_CREATE_OPTION,
6581
 
                                     "InnoDB: KEY_BLOCK_SIZE"
6582
 
                                     " requires innodb_file_per_table.");
 
6578
                        push_warning(
 
6579
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6580
                                ER_ILLEGAL_HA_CREATE_OPTION,
 
6581
                                "InnoDB: KEY_BLOCK_SIZE requires"
 
6582
                                " innodb_file_per_table.");
6583
6583
                        flags = 0;
6584
6584
                }
6585
6585
 
6586
6586
                if (file_format < DICT_TF_FORMAT_ZIP) {
6587
 
                        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6588
 
                                     ER_ILLEGAL_HA_CREATE_OPTION,
6589
 
                                     "InnoDB: KEY_BLOCK_SIZE"
6590
 
                                     " requires innodb_file_format >"
6591
 
                                     " Antelope.");
 
6587
                        push_warning(
 
6588
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6589
                                ER_ILLEGAL_HA_CREATE_OPTION,
 
6590
                                "InnoDB: KEY_BLOCK_SIZE requires"
 
6591
                                " innodb_file_format > Antelope.");
6592
6592
                        flags = 0;
6593
6593
                }
6594
6594
 
6595
6595
                if (!flags) {
6596
 
                        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6597
 
                                            ER_ILLEGAL_HA_CREATE_OPTION,
6598
 
                                            "InnoDB: ignoring"
6599
 
                                            " KEY_BLOCK_SIZE=%lu.",
6600
 
                                            create_info->key_block_size);
 
6596
                        push_warning_printf(
 
6597
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6598
                                ER_ILLEGAL_HA_CREATE_OPTION,
 
6599
                                "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.",
 
6600
                                create_info->key_block_size);
6601
6601
                }
6602
6602
        }
6603
6603
 
6604
 
        row_type = form->s->row_type;
 
6604
        row_format = form->s->row_type;
6605
6605
 
6606
6606
        if (flags) {
6607
 
                /* KEY_BLOCK_SIZE was specified. */
6608
 
                if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
6609
 
                        /* ROW_FORMAT was not specified;
6610
 
                        default to ROW_FORMAT=COMPRESSED */
6611
 
                        row_type = ROW_TYPE_COMPRESSED;
6612
 
                } else if (row_type != ROW_TYPE_COMPRESSED) {
 
6607
                /* if ROW_FORMAT is set to default,
 
6608
                automatically change it to COMPRESSED.*/
 
6609
                if (row_format == ROW_TYPE_DEFAULT) {
 
6610
                        row_format = ROW_TYPE_COMPRESSED;
 
6611
                } else if (row_format != ROW_TYPE_COMPRESSED) {
6613
6612
                        /* ROW_FORMAT other than COMPRESSED
6614
6613
                        ignores KEY_BLOCK_SIZE.  It does not
6615
6614
                        make sense to reject conflicting
6617
6616
                        such combinations can be obtained
6618
6617
                        with ALTER TABLE anyway. */
6619
6618
                        push_warning_printf(
6620
 
                                thd,
6621
 
                                MYSQL_ERROR::WARN_LEVEL_WARN,
 
6619
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6622
6620
                                ER_ILLEGAL_HA_CREATE_OPTION,
6623
6621
                                "InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
6624
6622
                                " unless ROW_FORMAT=COMPRESSED.",
6626
6624
                        flags = 0;
6627
6625
                }
6628
6626
        } else {
6629
 
                /* No KEY_BLOCK_SIZE */
6630
 
                if (row_type == ROW_TYPE_COMPRESSED) {
 
6627
                /* flags == 0 means no KEY_BLOCK_SIZE.*/
 
6628
                if (row_format == ROW_TYPE_COMPRESSED) {
6631
6629
                        /* ROW_FORMAT=COMPRESSED without
6632
6630
                        KEY_BLOCK_SIZE implies half the
6633
6631
                        maximum KEY_BLOCK_SIZE. */
6642
6640
                }
6643
6641
        }
6644
6642
 
6645
 
        switch (row_type) {
6646
 
                const char* row_format_name;
 
6643
        switch (row_format) {
6647
6644
        case ROW_TYPE_REDUNDANT:
6648
6645
                break;
6649
6646
        case ROW_TYPE_COMPRESSED:
6650
6647
        case ROW_TYPE_DYNAMIC:
6651
 
                row_format_name
6652
 
                        = row_type == ROW_TYPE_COMPRESSED
6653
 
                        ? "COMPRESSED"
6654
 
                        : "DYNAMIC";
6655
 
 
6656
6648
                if (!srv_file_per_table) {
6657
6649
                        push_warning_printf(
6658
 
                                thd,
6659
 
                                MYSQL_ERROR::WARN_LEVEL_WARN,
 
6650
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6660
6651
                                ER_ILLEGAL_HA_CREATE_OPTION,
6661
 
                                "InnoDB: ROW_FORMAT=%s"
6662
 
                                " requires innodb_file_per_table.",
6663
 
                                row_format_name);
 
6652
                                "InnoDB: ROW_FORMAT=%s requires"
 
6653
                                " innodb_file_per_table.",
 
6654
                                get_row_format_name(row_format));
6664
6655
                } else if (file_format < DICT_TF_FORMAT_ZIP) {
6665
6656
                        push_warning_printf(
6666
 
                                thd,
6667
 
                                MYSQL_ERROR::WARN_LEVEL_WARN,
 
6657
                                thd, MYSQL_ERROR::WARN_LEVEL_WARN,
6668
6658
                                ER_ILLEGAL_HA_CREATE_OPTION,
6669
 
                                "InnoDB: ROW_FORMAT=%s"
6670
 
                                " requires innodb_file_format >"
6671
 
                                " Antelope.",
6672
 
                                row_format_name);
 
6659
                                "InnoDB: ROW_FORMAT=%s requires"
 
6660
                                " innodb_file_format > Antelope.",
 
6661
                                get_row_format_name(row_format));
6673
6662
                } else {
6674
6663
                        flags |= DICT_TF_COMPACT
6675
 
                                | (DICT_TF_FORMAT_ZIP
6676
 
                                   << DICT_TF_FORMAT_SHIFT);
 
6664
                                 | (DICT_TF_FORMAT_ZIP
 
6665
                                    << DICT_TF_FORMAT_SHIFT);
6677
6666
                        break;
6678
6667
                }
6679
6668
 
6680
6669
                /* fall through */
6681
6670
        case ROW_TYPE_NOT_USED:
6682
6671
        case ROW_TYPE_FIXED:
6683
 
        default:
6684
 
                push_warning(thd,
6685
 
                             MYSQL_ERROR::WARN_LEVEL_WARN,
6686
 
                             ER_ILLEGAL_HA_CREATE_OPTION,
6687
 
                             "InnoDB: assuming ROW_FORMAT=COMPACT.");
 
6672
        case ROW_TYPE_PAGE:
 
6673
                push_warning(
 
6674
                        thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
6675
                        ER_ILLEGAL_HA_CREATE_OPTION,
 
6676
                        "InnoDB: assuming ROW_FORMAT=COMPACT.");
6688
6677
        case ROW_TYPE_DEFAULT:
6689
6678
        case ROW_TYPE_COMPACT:
6690
6679
                flags = DICT_TF_COMPACT;
6704
6693
 
6705
6694
        /* Check for name conflicts (with reserved name) for
6706
6695
        any user indices to be created. */
6707
 
        if (innobase_index_name_is_reserved(trx, form->key_info,
 
6696
        if (innobase_index_name_is_reserved(thd, form->key_info,
6708
6697
                                            form->s->keys)) {
6709
 
                error = -1;
6710
 
                goto cleanup;
 
6698
                DBUG_RETURN(-1);
 
6699
        }
 
6700
 
 
6701
        if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
 
6702
                DBUG_RETURN(HA_ERR_GENERIC);
6711
6703
        }
6712
6704
 
6713
6705
        if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
6714
6706
                flags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6715
6707
        }
6716
6708
 
 
6709
        /* Get the transaction associated with the current thd, or create one
 
6710
        if not yet created */
 
6711
 
 
6712
        parent_trx = check_trx_exists(thd);
 
6713
 
 
6714
        /* In case MySQL calls this in the middle of a SELECT query, release
 
6715
        possible adaptive hash latch to avoid deadlocks of threads */
 
6716
 
 
6717
        trx_search_latch_release_if_reserved(parent_trx);
 
6718
 
 
6719
        trx = innobase_trx_allocate(thd);
 
6720
 
 
6721
        /* Latch the InnoDB data dictionary exclusively so that no deadlocks
 
6722
        or lock waits can happen in it during a table create operation.
 
6723
        Drop table etc. do this latching in row0mysql.c. */
 
6724
 
 
6725
        row_mysql_lock_data_dictionary(trx);
 
6726
 
6717
6727
        error = create_table_def(trx, form, norm_name,
6718
6728
                create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
6719
6729
                flags);
6798
6808
        setup at this stage and so we use thd. */
6799
6809
 
6800
6810
        /* We need to copy the AUTOINC value from the old table if
6801
 
        this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
6802
 
        does a table copy too. */
 
6811
        this is an ALTER|OPTIMIZE TABLE or CREATE INDEX because CREATE INDEX
 
6812
        does a table copy too. If query was one of :
 
6813
 
 
6814
                CREATE TABLE ...AUTO_INCREMENT = x; or
 
6815
                ALTER TABLE...AUTO_INCREMENT = x;   or
 
6816
                OPTIMIZE TABLE t; or
 
6817
                CREATE INDEX x on t(...);
 
6818
 
 
6819
        Find out a table definition from the dictionary and get
 
6820
        the current value of the auto increment field. Set a new
 
6821
        value to the auto increment field if the value is greater
 
6822
        than the maximum value in the column. */
6803
6823
 
6804
6824
        if (((create_info->used_fields & HA_CREATE_USED_AUTO)
6805
6825
            || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
 
6826
            || thd_sql_command(thd) == SQLCOM_OPTIMIZE
6806
6827
            || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
6807
6828
            && create_info->auto_increment_value > 0) {
6808
6829
 
6809
 
                /* Query was one of :
6810
 
                CREATE TABLE ...AUTO_INCREMENT = x; or
6811
 
                ALTER TABLE...AUTO_INCREMENT = x;   or
6812
 
                CREATE INDEX x on t(...);
6813
 
                Find out a table definition from the dictionary and get
6814
 
                the current value of the auto increment field. Set a new
6815
 
                value to the auto increment field if the value is greater
6816
 
                than the maximum value in the column. */
6817
 
 
6818
6830
                auto_inc_value = create_info->auto_increment_value;
6819
6831
 
6820
6832
                dict_table_autoinc_lock(innobase_table);
6955
6967
 
6956
6968
        trx = innobase_trx_allocate(thd);
6957
6969
 
6958
 
        if (lower_case_table_names) {
6959
 
                srv_lower_case_table_names = TRUE;
6960
 
        } else {
6961
 
                srv_lower_case_table_names = FALSE;
6962
 
        }
6963
 
 
6964
6970
        name_len = strlen(name);
6965
6971
 
6966
6972
        ut_a(name_len < 1000);
6967
6973
 
6968
6974
        /* Drop the table in InnoDB */
6969
6975
 
 
6976
        srv_lower_case_table_names = lower_case_table_names;
 
6977
 
6970
6978
        error = row_drop_table_for_mysql(norm_name, trx,
6971
6979
                                         thd_sql_command(thd)
6972
6980
                                         == SQLCOM_DROP_DB);
7006
7014
        ulint   len             = 0;
7007
7015
        trx_t*  trx;
7008
7016
        char*   ptr;
7009
 
        int     error;
7010
7017
        char*   namebuf;
7011
7018
        THD*    thd             = current_thd;
7012
7019
 
7049
7056
#else
7050
7057
        trx = innobase_trx_allocate(thd);
7051
7058
#endif
7052
 
        error = row_drop_database_for_mysql(namebuf, trx);
 
7059
        row_drop_database_for_mysql(namebuf, trx);
7053
7060
        my_free(namebuf, MYF(0));
7054
7061
 
7055
7062
        /* Flush the log to reduce probability that the .frm files and
7083
7090
        char*   norm_to;
7084
7091
        char*   norm_from;
7085
7092
 
7086
 
        if (lower_case_table_names) {
7087
 
                srv_lower_case_table_names = TRUE;
7088
 
        } else {
7089
 
                srv_lower_case_table_names = FALSE;
7090
 
        }
7091
 
 
7092
7093
        // Magic number 64 arbitrary
7093
7094
        norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0));
7094
7095
        norm_from = (char*) my_malloc(strlen(from) + 64, MYF(0));
7103
7104
                row_mysql_lock_data_dictionary(trx);
7104
7105
        }
7105
7106
 
 
7107
        srv_lower_case_table_names = lower_case_table_names;
 
7108
 
7106
7109
        error = row_rename_table_for_mysql(
7107
7110
                norm_from, norm_to, trx, lock_and_commit);
7108
7111
 
7222
7225
        mem_heap_t*     heap;
7223
7226
 
7224
7227
        DBUG_ENTER("records_in_range");
 
7228
        DBUG_ASSERT(min_key || max_key);
7225
7229
 
7226
7230
        ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
7227
7231
 
7267
7271
                                         (const uchar*) 0),
7268
7272
                                (ulint) (min_key ? min_key->length : 0),
7269
7273
                                prebuilt->trx);
 
7274
        DBUG_ASSERT(min_key
 
7275
                    ? range_start->n_fields > 0
 
7276
                    : range_start->n_fields == 0);
7270
7277
 
7271
7278
        row_sel_convert_mysql_key_to_innobase(
7272
7279
                                range_end, (byte*) key_val_buff2,
7275
7282
                                         (const uchar*) 0),
7276
7283
                                (ulint) (max_key ? max_key->length : 0),
7277
7284
                                prebuilt->trx);
 
7285
        DBUG_ASSERT(max_key
 
7286
                    ? range_end->n_fields > 0
 
7287
                    : range_end->n_fields == 0);
7278
7288
 
7279
7289
        mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
7280
7290
                                                HA_READ_KEY_EXACT);
7323
7333
        dict_index_t*   index;
7324
7334
        ulonglong       estimate;
7325
7335
        ulonglong       local_data_file_length;
 
7336
        ulint           stat_n_leaf_pages;
7326
7337
 
7327
7338
        DBUG_ENTER("estimate_rows_upper_bound");
7328
7339
 
7342
7353
 
7343
7354
        index = dict_table_get_first_index(prebuilt->table);
7344
7355
 
7345
 
        ut_a(index->stat_n_leaf_pages > 0);
 
7356
        stat_n_leaf_pages = index->stat_n_leaf_pages;
 
7357
 
 
7358
        ut_a(stat_n_leaf_pages > 0);
7346
7359
 
7347
7360
        local_data_file_length =
7348
 
                ((ulonglong) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
7361
                ((ulonglong) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
7349
7362
 
7350
7363
 
7351
7364
        /* Calculate a minimum length for a clustered index record and from
7497
7510
 
7498
7511
        return(0);
7499
7512
}
 
7513
 
 
7514
/*********************************************************************//**
 
7515
Calculate Record Per Key value. Need to exclude the NULL value if
 
7516
innodb_stats_method is set to "nulls_ignored"
 
7517
@return estimated record per key value */
 
7518
static
 
7519
ha_rows
 
7520
innodb_rec_per_key(
 
7521
/*===============*/
 
7522
        dict_index_t*   index,          /*!< in: dict_index_t structure */
 
7523
        ulint           i,              /*!< in: the column we are
 
7524
                                        calculating rec per key */
 
7525
        ha_rows         records)        /*!< in: estimated total records */
 
7526
{
 
7527
        ha_rows         rec_per_key;
 
7528
 
 
7529
        ut_ad(i < dict_index_get_n_unique(index));
 
7530
 
 
7531
        /* Note the stat_n_diff_key_vals[] stores the diff value with
 
7532
        n-prefix indexing, so it is always stat_n_diff_key_vals[i + 1] */
 
7533
        if (index->stat_n_diff_key_vals[i + 1] == 0) {
 
7534
 
 
7535
                rec_per_key = records;
 
7536
        } else if (srv_innodb_stats_method == SRV_STATS_NULLS_IGNORED) {
 
7537
                ib_int64_t      num_null;
 
7538
 
 
7539
                /* Number of rows with NULL value in this
 
7540
                field */
 
7541
                num_null = records - index->stat_n_non_null_key_vals[i];
 
7542
 
 
7543
                /* In theory, index->stat_n_non_null_key_vals[i]
 
7544
                should always be less than the number of records.
 
7545
                Since this is statistics value, the value could
 
7546
                have slight discrepancy. But we will make sure
 
7547
                the number of null values is not a negative number. */
 
7548
                num_null = (num_null < 0) ? 0 : num_null;
 
7549
 
 
7550
                /* If the number of NULL values is the same as or
 
7551
                large than that of the distinct values, we could
 
7552
                consider that the table consists mostly of NULL value. 
 
7553
                Set rec_per_key to 1. */
 
7554
                if (index->stat_n_diff_key_vals[i + 1] <= num_null) {
 
7555
                        rec_per_key = 1;
 
7556
                } else {
 
7557
                        /* Need to exclude rows with NULL values from
 
7558
                        rec_per_key calculation */
 
7559
                        rec_per_key = (ha_rows)(
 
7560
                                (records - num_null)
 
7561
                                / (index->stat_n_diff_key_vals[i + 1]
 
7562
                                   - num_null));
 
7563
                }
 
7564
        } else {
 
7565
                rec_per_key = (ha_rows)
 
7566
                         (records / index->stat_n_diff_key_vals[i + 1]);
 
7567
        }
 
7568
 
 
7569
        return(rec_per_key);
 
7570
}
 
7571
 
7500
7572
/*********************************************************************//**
7501
7573
Returns statistics information of the table to the MySQL interpreter,
7502
7574
in various fields of the handle object. */
7503
7575
UNIV_INTERN
7504
7576
int
7505
 
ha_innobase::info(
7506
 
/*==============*/
7507
 
        uint flag)      /*!< in: what information MySQL requests */
 
7577
ha_innobase::info_low(
 
7578
/*==================*/
 
7579
        uint    flag,                   /*!< in: what information MySQL
 
7580
                                        requests */
 
7581
        bool    called_from_analyze)    /* in: TRUE if called from
 
7582
                                        ::analyze() */
7508
7583
{
7509
7584
        dict_table_t*   ib_table;
7510
7585
        dict_index_t*   index;
7511
7586
        ha_rows         rec_per_key;
7512
7587
        ib_int64_t      n_rows;
7513
 
        ulong           j;
7514
 
        ulong           i;
7515
7588
        char            path[FN_REFLEN];
7516
7589
        os_file_stat_t  stat_info;
7517
7590
 
7518
 
 
7519
7591
        DBUG_ENTER("info");
7520
7592
 
7521
7593
        /* If we are forcing recovery at a high level, we will suppress
7522
7594
        statistics calculation on tables, because that may crash the
7523
7595
        server if an index is badly corrupted. */
7524
7596
 
7525
 
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7526
 
 
7527
 
                /* We return success (0) instead of HA_ERR_CRASHED,
7528
 
                because we want MySQL to process this query and not
7529
 
                stop, like it would do if it received the error code
7530
 
                HA_ERR_CRASHED. */
7531
 
 
7532
 
                DBUG_RETURN(0);
7533
 
        }
7534
 
 
7535
7597
        /* We do not know if MySQL can call this function before calling
7536
7598
        external_lock(). To be safe, update the thd of the current table
7537
7599
        handle. */
7548
7610
        ib_table = prebuilt->table;
7549
7611
 
7550
7612
        if (flag & HA_STATUS_TIME) {
7551
 
                if (innobase_stats_on_metadata) {
 
7613
                if (called_from_analyze || innobase_stats_on_metadata) {
7552
7614
                        /* In sql_show we call with this flag: update
7553
7615
                        then statistics so that they are up-to-date */
7554
7616
 
7555
7617
                        prebuilt->trx->op_info = "updating table statistics";
7556
7618
 
7557
 
                        dict_update_statistics(ib_table);
 
7619
                        dict_update_statistics(ib_table,
 
7620
                                               FALSE /* update even if stats
 
7621
                                                     are initialized */);
7558
7622
 
7559
7623
                        prebuilt->trx->op_info = "returning various info to MySQL";
7560
7624
                }
7573
7637
        }
7574
7638
 
7575
7639
        if (flag & HA_STATUS_VARIABLE) {
 
7640
 
 
7641
                ulint   page_size;
 
7642
 
 
7643
                dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7644
 
7576
7645
                n_rows = ib_table->stat_n_rows;
7577
7646
 
7578
7647
                /* Because we do not protect stat_n_rows by any mutex in a
7613
7682
                        prebuilt->autoinc_last_value = 0;
7614
7683
                }
7615
7684
 
 
7685
                page_size = dict_table_zip_size(ib_table);
 
7686
                if (page_size == 0) {
 
7687
                        page_size = UNIV_PAGE_SIZE;
 
7688
                }
 
7689
 
7616
7690
                stats.records = (ha_rows)n_rows;
7617
7691
                stats.deleted = 0;
7618
 
                stats.data_file_length = ((ulonglong)
7619
 
                                ib_table->stat_clustered_index_size)
7620
 
                                        * UNIV_PAGE_SIZE;
7621
 
                stats.index_file_length = ((ulonglong)
7622
 
                                ib_table->stat_sum_of_other_index_sizes)
7623
 
                                        * UNIV_PAGE_SIZE;
 
7692
                stats.data_file_length
 
7693
                        = ((ulonglong) ib_table->stat_clustered_index_size)
 
7694
                        * page_size;
 
7695
                stats.index_file_length =
 
7696
                        ((ulonglong) ib_table->stat_sum_of_other_index_sizes)
 
7697
                        * page_size;
 
7698
 
 
7699
                dict_table_stats_unlock(ib_table, RW_S_LATCH);
7624
7700
 
7625
7701
                /* Since fsp_get_available_space_in_free_extents() is
7626
7702
                acquiring latches inside InnoDB, we do not call it if we
7627
7703
                are asked by MySQL to avoid locking. Another reason to
7628
7704
                avoid the call is that it uses quite a lot of CPU.
7629
 
                See Bug#38185.
7630
 
                We do not update delete_length if no locking is requested
7631
 
                so the "old" value can remain. delete_length is initialized
7632
 
                to 0 in the ha_statistics' constructor. */
7633
 
                if (!(flag & HA_STATUS_NO_LOCK)) {
7634
 
 
7635
 
                        /* lock the data dictionary to avoid races with
7636
 
                        ibd_file_missing and tablespace_discarded */
7637
 
                        row_mysql_lock_data_dictionary(prebuilt->trx);
7638
 
 
7639
 
                        /* ib_table->space must be an existent tablespace */
7640
 
                        if (!ib_table->ibd_file_missing
7641
 
                            && !ib_table->tablespace_discarded) {
7642
 
 
7643
 
                                stats.delete_length =
7644
 
                                        fsp_get_available_space_in_free_extents(
7645
 
                                                ib_table->space) * 1024;
7646
 
                        } else {
7647
 
 
 
7705
                See Bug#38185. */
 
7706
                if (flag & HA_STATUS_NO_LOCK) {
 
7707
                        /* We do not update delete_length if no
 
7708
                        locking is requested so the "old" value can
 
7709
                        remain. delete_length is initialized to 0 in
 
7710
                        the ha_statistics' constructor. */
 
7711
                } else if (UNIV_UNLIKELY
 
7712
                           (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
 
7713
                        /* Avoid accessing the tablespace if
 
7714
                        innodb_crash_recovery is set to a high value. */
 
7715
                        stats.delete_length = 0;
 
7716
                } else {
 
7717
                        ullint  avail_space;
 
7718
 
 
7719
                        avail_space = fsp_get_available_space_in_free_extents(
 
7720
                                ib_table->space);
 
7721
 
 
7722
                        if (avail_space == ULLINT_UNDEFINED) {
7648
7723
                                THD*    thd;
7649
7724
 
7650
7725
                                thd = ha_thd();
7661
7736
                                        ib_table->name);
7662
7737
 
7663
7738
                                stats.delete_length = 0;
 
7739
                        } else {
 
7740
                                stats.delete_length = avail_space * 1024;
7664
7741
                        }
7665
 
 
7666
 
                        row_mysql_unlock_data_dictionary(prebuilt->trx);
7667
7742
                }
7668
7743
 
7669
7744
                stats.check_time = 0;
7676
7751
        }
7677
7752
 
7678
7753
        if (flag & HA_STATUS_CONST) {
 
7754
                ulong   i;
7679
7755
                /* Verify the number of index in InnoDB and MySQL
7680
7756
                matches up. If prebuilt->clust_index_was_generated
7681
7757
                holds, InnoDB defines GEN_CLUST_INDEX internally */
7691
7767
                                        table->s->keys);
7692
7768
                }
7693
7769
 
 
7770
                dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7771
 
7694
7772
                for (i = 0; i < table->s->keys; i++) {
 
7773
                        ulong   j;
7695
7774
                        /* We could get index quickly through internal
7696
7775
                        index mapping with the index translation table.
7697
7776
                        The identity of index (match up index name with
7727
7806
                                        break;
7728
7807
                                }
7729
7808
 
7730
 
                                dict_index_stat_mutex_enter(index);
7731
 
 
7732
 
                                if (index->stat_n_diff_key_vals[j + 1] == 0) {
7733
 
 
7734
 
                                        rec_per_key = stats.records;
7735
 
                                } else {
7736
 
                                        rec_per_key = (ha_rows)(stats.records /
7737
 
                                         index->stat_n_diff_key_vals[j + 1]);
7738
 
                                }
7739
 
 
7740
 
                                dict_index_stat_mutex_exit(index);
 
7809
                                rec_per_key = innodb_rec_per_key(
 
7810
                                        index, j, stats.records);
7741
7811
 
7742
7812
                                /* Since MySQL seems to favor table scans
7743
7813
                                too much over index searches, we pretend
7755
7825
                                  (ulong) rec_per_key;
7756
7826
                        }
7757
7827
                }
 
7828
 
 
7829
                dict_table_stats_unlock(ib_table, RW_S_LATCH);
 
7830
        }
 
7831
 
 
7832
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
7833
 
 
7834
                goto func_exit;
7758
7835
        }
7759
7836
 
7760
7837
        if (flag & HA_STATUS_ERRKEY) {
7777
7854
                stats.auto_increment_value = innobase_peek_autoinc();
7778
7855
        }
7779
7856
 
 
7857
func_exit:
7780
7858
        prebuilt->trx->op_info = (char*)"";
7781
7859
 
7782
7860
        DBUG_RETURN(0);
7783
7861
}
7784
7862
 
 
7863
/*********************************************************************//**
 
7864
Returns statistics information of the table to the MySQL interpreter,
 
7865
in various fields of the handle object. */
 
7866
UNIV_INTERN
 
7867
int
 
7868
ha_innobase::info(
 
7869
/*==============*/
 
7870
        uint    flag)   /*!< in: what information MySQL requests */
 
7871
{
 
7872
        return(info_low(flag, false /* not called from analyze */));
 
7873
}
 
7874
 
7785
7875
/**********************************************************************//**
7786
7876
Updates index cardinalities of the table, based on 8 random dives into
7787
7877
each index tree. This does NOT calculate exact statistics on the table.
7794
7884
        HA_CHECK_OPT*   check_opt)      /*!< in: currently ignored */
7795
7885
{
7796
7886
        /* Simply call ::info() with all the flags */
7797
 
        info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
 
7887
        info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
 
7888
                 true /* called from analyze */);
7798
7889
 
7799
7890
        return(0);
7800
7891
}
8095
8186
        flen = ftell(srv_dict_tmpfile);
8096
8187
        if (flen < 0) {
8097
8188
                flen = 0;
8098
 
        } else if (flen > 64000 - 1) {
8099
 
                flen = 64000 - 1;
8100
8189
        }
8101
8190
 
8102
8191
        /* allocate buffer for the string, and
8332
8421
                        break;
8333
8422
                case HA_EXTRA_RESET_STATE:
8334
8423
                        reset_template(prebuilt);
 
8424
                        thd_to_trx(ha_thd())->duplicates = 0;
8335
8425
                        break;
8336
8426
                case HA_EXTRA_NO_KEYREAD:
8337
8427
                        prebuilt->read_just_key = 0;
8349
8439
                        parameters below.  We must not invoke update_thd()
8350
8440
                        either, because the calling threads may change.
8351
8441
                        CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
8352
 
                case HA_EXTRA_IGNORE_DUP_KEY:
 
8442
                case HA_EXTRA_INSERT_WITH_UPDATE:
8353
8443
                        thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE;
8354
8444
                        break;
 
8445
                case HA_EXTRA_NO_IGNORE_DUP_KEY:
 
8446
                        thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_IGNORE;
 
8447
                        break;
8355
8448
                case HA_EXTRA_WRITE_CAN_REPLACE:
8356
8449
                        thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE;
8357
8450
                        break;
8358
8451
                case HA_EXTRA_WRITE_CANNOT_REPLACE:
8359
8452
                        thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
8360
8453
                        break;
8361
 
                case HA_EXTRA_NO_IGNORE_DUP_KEY:
8362
 
                        thd_to_trx(ha_thd())->duplicates &=
8363
 
                                ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
8364
 
                        break;
8365
8454
                default:/* Do nothing */
8366
8455
                        ;
8367
8456
        }
8548
8637
 
8549
8638
        reset_template(prebuilt);
8550
8639
 
8551
 
        if (lock_type == F_WRLCK) {
 
8640
        if (lock_type == F_WRLCK
 
8641
            || (table->s->tmp_table
 
8642
                && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) {
8552
8643
 
8553
8644
                /* If this is a SELECT, then it is in UPDATE TABLE ...
8554
 
                or SELECT ... FOR UPDATE */
 
8645
                or SELECT ... FOR UPDATE
 
8646
 
 
8647
                For temporary tables which are locked for READ by LOCK TABLES
 
8648
                updates are still allowed by SQL-layer. In order to accomodate
 
8649
                for such a situation we always request X-lock for such table
 
8650
                at LOCK TABLES time.
 
8651
                */
8555
8652
                prebuilt->select_lock_type = LOCK_X;
8556
8653
                prebuilt->stored_select_lock_type = LOCK_X;
8557
8654
        }
8846
8943
 
8847
8944
        mutex_exit(&srv_monitor_file_mutex);
8848
8945
 
8849
 
        bool result = FALSE;
 
8946
        stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name),
 
8947
                   STRING_WITH_LEN(""), str, flen);
8850
8948
 
8851
 
        if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name),
8852
 
                        STRING_WITH_LEN(""), str, flen)) {
8853
 
                result= TRUE;
8854
 
        }
8855
8949
        my_free(str, MYF(0));
8856
8950
 
8857
8951
        DBUG_RETURN(FALSE);
9234
9328
                    && (sql_command == SQLCOM_INSERT_SELECT
9235
9329
                        || sql_command == SQLCOM_REPLACE_SELECT
9236
9330
                        || sql_command == SQLCOM_UPDATE
9237
 
                        || sql_command == SQLCOM_CREATE_TABLE)) {
 
9331
                        || sql_command == SQLCOM_CREATE_TABLE
 
9332
                        || sql_command == SQLCOM_SET_OPTION)) {
9238
9333
 
9239
9334
                        /* If we either have innobase_locks_unsafe_for_binlog
9240
9335
                        option set or this session is using READ COMMITTED
9242
9337
                        is not set to serializable and MySQL is doing
9243
9338
                        INSERT INTO...SELECT or REPLACE INTO...SELECT
9244
9339
                        or UPDATE ... = (SELECT ...) or CREATE  ...
9245
 
                        SELECT... without FOR UPDATE or IN SHARE
9246
 
                        MODE in select, then we use consistent read
9247
 
                        for select. */
 
9340
                        SELECT... or SET ... = (SELECT ...) without
 
9341
                        FOR UPDATE or IN SHARE MODE in select,
 
9342
                        then we use consistent read for select. */
9248
9343
 
9249
9344
                        prebuilt->select_lock_type = LOCK_NONE;
9250
9345
                        prebuilt->stored_select_lock_type = LOCK_NONE;
9390
9485
 
9391
9486
        auto_inc = dict_table_autoinc_read(innodb_table);
9392
9487
 
9393
 
        ut_a(auto_inc > 0);
 
9488
        if (auto_inc == 0) {
 
9489
                ut_print_timestamp(stderr);
 
9490
                fprintf(stderr, "  InnoDB: AUTOINC next value generation "
 
9491
                        "is disabled for '%s'\n", innodb_table->name);
 
9492
        }
9394
9493
 
9395
9494
        dict_table_autoinc_unlock(innodb_table);
9396
9495
 
9888
9987
 
9889
9988
        if (trx) {
9890
9989
                innobase_commit_low(trx);
9891
 
 
 
9990
                trx_free_for_background(trx);
9892
9991
                return(XA_OK);
9893
9992
        } else {
9894
9993
                return(XAER_NOTA);
9914
10013
        trx = trx_get_trx_by_xid(xid);
9915
10014
 
9916
10015
        if (trx) {
9917
 
                return(innobase_rollback_trx(trx));
 
10016
                int     ret = innobase_rollback_trx(trx);
 
10017
                trx_free_for_background(trx);
 
10018
                return(ret);
9918
10019
        } else {
9919
10020
                return(XAER_NOTA);
9920
10021
        }
10588
10689
  return 0;
10589
10690
}
10590
10691
 
10591
 
/***********************************************************************
 
10692
/*********************************************************************//**
10592
10693
This function checks each index name for a table against reserved
10593
 
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
10594
 
this function pushes an warning message to the client, and returns true. */
 
10694
system default primary index name 'GEN_CLUST_INDEX'. If a name
 
10695
matches, this function pushes an warning message to the client,
 
10696
and returns true.
 
10697
@return true if the index name matches the reserved name */
10595
10698
extern "C" UNIV_INTERN
10596
10699
bool
10597
10700
innobase_index_name_is_reserved(
10598
10701
/*============================*/
10599
 
                                        /* out: true if an index name
10600
 
                                        matches the reserved name */
10601
 
        const trx_t*    trx,            /* in: InnoDB transaction handle */
10602
 
        const KEY*      key_info,       /* in: Indexes to be created */
10603
 
        ulint           num_of_keys)    /* in: Number of indexes to
 
10702
        THD*            thd,            /*!< in/out: MySQL connection */
 
10703
        const KEY*      key_info,       /*!< in: Indexes to be created */
 
10704
        ulint           num_of_keys)    /*!< in: Number of indexes to
10604
10705
                                        be created. */
10605
10706
{
10606
10707
        const KEY*      key;
10612
10713
                if (innobase_strcasecmp(key->name,
10613
10714
                                        innobase_index_reserve_name) == 0) {
10614
10715
                        /* Push warning to mysql */
10615
 
                        push_warning_printf((THD*) trx->mysql_thd,
 
10716
                        push_warning_printf(thd,
10616
10717
                                            MYSQL_ERROR::WARN_LEVEL_WARN,
10617
10718
                                            ER_WRONG_NAME_FOR_INDEX,
10618
10719
                                            "Cannot Create Index with name "
10907
11008
  innodb_change_buffering_validate,
10908
11009
  innodb_change_buffering_update, "inserts"); 
10909
11010
 
 
11011
static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method,
 
11012
   PLUGIN_VAR_RQCMDARG,
 
11013
  "Specifies how InnoDB index statistics collection code should "
 
11014
  "treat NULLs. Possible values are NULLS_EQUAL (default), "
 
11015
  "NULLS_UNEQUAL and NULLS_IGNORED",
 
11016
   NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib);
 
11017
 
 
11018
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
 
11019
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
 
11020
  PLUGIN_VAR_RQCMDARG,
 
11021
  "Debug flags for InnoDB change buffering (0=none)",
 
11022
  NULL, NULL, 0, 0, 1, 0);
 
11023
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
 
11024
 
 
11025
static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead,
 
11026
  PLUGIN_VAR_NOCMDARG,
 
11027
  "Whether to use read ahead for random access within an extent.",
 
11028
  NULL, NULL, FALSE);
 
11029
 
10910
11030
static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
10911
11031
  PLUGIN_VAR_RQCMDARG,
10912
11032
  "Number of pages that must be accessed sequentially for InnoDB to "
10954
11074
  MYSQL_SYSVAR(stats_on_metadata),
10955
11075
  MYSQL_SYSVAR(stats_sample_pages),
10956
11076
  MYSQL_SYSVAR(adaptive_hash_index),
 
11077
  MYSQL_SYSVAR(stats_method),
10957
11078
  MYSQL_SYSVAR(replication_delay),
10958
11079
  MYSQL_SYSVAR(status_file),
10959
11080
  MYSQL_SYSVAR(strict_mode),
10967
11088
  MYSQL_SYSVAR(version),
10968
11089
  MYSQL_SYSVAR(use_sys_malloc),
10969
11090
  MYSQL_SYSVAR(change_buffering),
 
11091
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
 
11092
  MYSQL_SYSVAR(change_buffering_debug),
 
11093
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
 
11094
  MYSQL_SYSVAR(random_read_ahead),
10970
11095
  MYSQL_SYSVAR(read_ahead_threshold),
10971
11096
  MYSQL_SYSVAR(io_capacity),
10972
11097
  NULL