~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-10-12 05:21:02 UTC
  • Revision ID: brian@tangent.org-20101012052102-9yrbu1ye7n8n4b6n
Remove dead code.

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, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, 2009 Google Inc.
5
 
Copyright (c) 2009, Percona Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
13
 
Portions of this file contain modifications contributed and copyrighted
14
 
by Percona Inc.. Those modifications are
15
 
gratefully acknowledged and are described briefly in the InnoDB
16
 
documentation. The contributions by Percona Inc. are incorporated with
17
 
their permission, and subject to the conditions contained in the file
18
 
COPYING.Percona.
19
 
 
20
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
30
22
St, Fifth Floor, Boston, MA 02110-1301 USA
31
23
 
32
24
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
49
 
 
50
***********************************************************************/
33
51
 
34
52
/* TODO list for the InnoDB Cursor in 5.0:
35
53
  - fix savepoint functions to use savepoint storage area
85
103
/* Include necessary InnoDB headers */
86
104
extern "C" {
87
105
#include "univ.i"
88
 
#include "buf0lru.h"
89
106
#include "btr0sea.h"
90
107
#include "os0file.h"
91
108
#include "os0thread.h"
102
119
#include "log0log.h"
103
120
#include "lock0lock.h"
104
121
#include "dict0crea.h"
105
 
#include "create_replication.h"
106
122
#include "btr0cur.h"
107
123
#include "btr0btr.h"
108
124
#include "fsp0fsp.h"
120
136
 
121
137
#include "ha_innodb.h"
122
138
#include "data_dictionary.h"
123
 
#include "replication_dictionary.h"
124
139
#include "internal_dictionary.h"
125
140
#include "handler0vars.h"
126
141
 
129
144
#include <string>
130
145
 
131
146
#include "plugin/innobase/handler/status_function.h"
132
 
#include "plugin/innobase/handler/replication_log.h"
133
 
 
134
 
#include <google/protobuf/io/zero_copy_stream.h>
135
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
136
 
#include <google/protobuf/io/coded_stream.h>
137
 
#include <google/protobuf/text_format.h>
138
147
 
139
148
using namespace std;
140
149
using namespace drizzled;
141
150
 
 
151
#ifndef DRIZZLE_SERVER
 
152
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
 
153
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
 
154
extern pthread_mutex_t LOCK_thread_count;
 
155
 
 
156
#endif /* DRIZZLE_SERVER */
 
157
 
142
158
/** to protect innobase_open_files */
143
159
static pthread_mutex_t innobase_share_mutex;
144
160
/** to force correct commit order in binlog */
170
186
static plugin::TableFunction* innodb_trx_tool= NULL;
171
187
static plugin::TableFunction* innodb_locks_tool= NULL;
172
188
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
173
 
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
174
 
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
175
 
 
176
 
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
177
 
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
178
 
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
179
 
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
180
 
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
181
 
 
182
 
static ReplicationLog *replication_logger= NULL;
183
 
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
184
 
static open_files_constraint innobase_open_files;
185
 
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
186
 
static mirrored_log_groups_constraint innobase_mirrored_log_groups;
187
 
typedef constrained_check<uint32_t, 100, 2> log_files_in_group_constraint;
188
 
static log_files_in_group_constraint innobase_log_files_in_group;
189
 
typedef constrained_check<uint32_t, 6, 0> force_recovery_constraint;
190
 
force_recovery_constraint innobase_force_recovery;
191
 
typedef constrained_check<size_t, SIZE_MAX, 256*1024, 1024> log_buffer_constraint;
192
 
static log_buffer_constraint innobase_log_buffer_size;
193
 
typedef constrained_check<size_t, SIZE_MAX, 512*1024, 1024> additional_mem_pool_constraint;
194
 
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
195
 
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
196
 
static autoextend_constraint innodb_auto_extend_increment;
197
 
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
198
 
static buffer_pool_constraint innobase_buffer_pool_size;
199
 
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
200
 
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
201
 
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
202
 
static io_capacity_constraint innodb_io_capacity;
203
 
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
204
 
static purge_batch_constraint innodb_purge_batch_size;
205
 
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
206
 
static purge_threads_constraint innodb_n_purge_threads;
207
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
208
 
static trinary_constraint innodb_flush_log_at_trx_commit;
209
 
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
210
 
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
211
 
static uint64_constraint innodb_max_purge_lag;
212
 
static uint64_nonzero_constraint innodb_stats_sample_pages;
213
 
typedef constrained_check<uint32_t, 64, 1> io_threads_constraint;
214
 
static io_threads_constraint innobase_read_io_threads;
215
 
static io_threads_constraint innobase_write_io_threads;
216
 
 
217
 
typedef constrained_check<uint32_t, 1000, 0> concurrency_constraint;
218
 
static concurrency_constraint innobase_commit_concurrency;
219
 
static concurrency_constraint innobase_thread_concurrency;
220
 
static uint32_nonzero_constraint innodb_concurrency_tickets;
221
 
 
222
 
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
223
 
static log_file_constraint innobase_log_file_size;
224
 
 
225
 
static uint64_constraint innodb_replication_delay;
226
 
 
227
 
/** Percentage of the buffer pool to reserve for 'old' blocks.
228
 
Connected to buf_LRU_old_ratio. */
229
 
typedef constrained_check<uint32_t, 95, 5> old_blocks_constraint;
230
 
static old_blocks_constraint innobase_old_blocks_pct;
231
 
 
232
 
static uint32_constraint innodb_sync_spin_loops;
233
 
static uint32_constraint innodb_spin_wait_delay;
234
 
static uint32_constraint innodb_thread_sleep_delay;
235
 
 
236
 
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
237
 
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
 
189
 
 
190
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
191
  innobase_log_buffer_size,
 
192
  innobase_force_recovery, innobase_open_files;
 
193
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
194
static ulong innobase_commit_concurrency = 0;
 
195
static ulong innobase_read_io_threads;
 
196
static ulong innobase_write_io_threads;
 
197
 
 
198
/**
 
199
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
200
 */
 
201
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
202
static int64_t innobase_log_file_size;
238
203
 
239
204
/* The default values for the following char* start-up parameters
240
205
are determined in innobase_init below: */
241
206
 
242
 
std::string innobase_data_home_dir;
243
 
std::string innobase_data_file_path;
244
 
std::string innobase_log_group_home_dir;
245
 
static string innobase_file_format_name;
246
 
static string innobase_change_buffering;
247
 
 
248
 
/* The highest file format being used in the database. The value can be
249
 
set by user, however, it will be adjusted to the newer file format if
250
 
a table of such format is created/opened. */
251
 
static string innobase_file_format_max;
 
207
static char*  innobase_data_home_dir      = NULL;
 
208
static char*  innobase_data_file_path     = NULL;
 
209
static char*  innobase_log_group_home_dir   = NULL;
 
210
static char*  innobase_file_format_name   = NULL;
 
211
static char*  innobase_change_buffering   = NULL;
 
212
 
 
213
/* Note: This variable can be set to on/off and any of the supported
 
214
file formats in the configuration file, but can only be set to any
 
215
of the supported file formats during runtime. */
 
216
static char*  innobase_file_format_check    = NULL;
 
217
 
 
218
/* The following has a misleading name: starting from 4.0.5, this also
 
219
affects Windows: */
 
220
static char*  innobase_unix_file_flush_method   = NULL;
252
221
 
253
222
/* Below we have boolean-valued start-up parameters, and their default
254
223
values */
255
224
 
256
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
257
 
static trinary_constraint innobase_fast_shutdown;
258
 
 
259
 
/* "innobase_file_format_check" decides whether we would continue
260
 
booting the server if the file format stamped on the system
261
 
table space exceeds the maximum file format supported
262
 
by the server. Can be set during server startup at command
263
 
line or configure file, and a read only variable after
264
 
server startup */
265
 
 
266
 
/* If a new file format is introduced, the file format
267
 
name needs to be updated accordingly. Please refer to
268
 
file_format_name_map[] defined in trx0sys.c for the next
269
 
file format name. */
270
 
 
271
 
static my_bool  innobase_file_format_check = TRUE;
 
225
static ulong  innobase_fast_shutdown      = 1;
 
226
#ifdef UNIV_LOG_ARCHIVE
 
227
static my_bool  innobase_log_archive      = FALSE;
 
228
static char*  innobase_log_arch_dir     = NULL;
 
229
#endif /* UNIV_LOG_ARCHIVE */
272
230
static my_bool  innobase_use_doublewrite    = TRUE;
273
231
static my_bool  innobase_use_checksums      = TRUE;
274
232
static my_bool  innobase_rollback_on_timeout    = FALSE;
275
233
static my_bool  innobase_create_status_file   = FALSE;
276
 
static bool innobase_use_replication_log;
277
 
static bool support_xa;
278
 
static bool strict_mode;
279
 
typedef constrained_check<uint32_t, 1024*1024*1024, 1> lock_wait_constraint;
280
 
static lock_wait_constraint lock_wait_timeout;
 
234
static my_bool  innobase_stats_on_metadata    = TRUE;
281
235
 
282
236
static char*  internal_innobase_data_file_path  = NULL;
283
237
 
 
238
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
239
 
284
240
/* The following counter is used to convey information to InnoDB
285
241
about server activity: in selects it is not sensible to call
286
242
srv_active_wake_master_thread after each fetch or search, we only do
298
254
/** Allowed values of innodb_change_buffering */
299
255
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
300
256
  "none",   /* IBUF_USE_NONE */
301
 
  "inserts",    /* IBUF_USE_INSERT */
302
 
  "deletes",    /* IBUF_USE_DELETE_MARK */
303
 
  "changes",    /* IBUF_USE_INSERT_DELETE_MARK */
304
 
  "purges",     /* IBUF_USE_DELETE */
305
 
  "all"         /* IBUF_USE_ALL */
 
257
  "inserts" /* IBUF_USE_INSERT */
306
258
};
307
259
 
308
 
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
309
 
system primary index. */
310
 
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
311
 
 
312
260
/********************************************************************
313
261
Gives the file extension of an InnoDB single-table tablespace. */
314
262
static const char* ha_innobase_exts[] = {
360
308
    }
361
309
    
362
310
    /* These get strdup'd from vm variables */
 
311
    free(innobase_data_home_dir);
 
312
    free(innobase_log_group_home_dir);
363
313
 
364
314
  }
365
315
 
390
340
  {
391
341
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
392
342
  }
393
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
394
 
  virtual uint64_t doGetNewTransactionId(Session *session);
395
343
  virtual int doCommit(Session* session, bool all);
396
344
  virtual int doRollback(Session* session, bool all);
397
345
 
435
383
        /* out: 0 or error number */
436
384
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
437
385
 
438
 
  virtual Cursor *create(Table &table)
 
386
  virtual Cursor *create(TableShare &table)
439
387
  {
440
388
    return new ha_innobase(*this, table);
441
389
  }
514
462
 
515
463
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
464
                             const drizzled::SchemaIdentifier &schema_identifier,
517
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
465
                             drizzled::TableIdentifiers &set_of_identifiers);
518
466
  bool validateCreateTableOption(const std::string &key, const std::string &state);
519
467
  void dropTemporarySchema();
520
468
 
543
491
 
544
492
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
493
                                           const drizzled::SchemaIdentifier &schema_identifier,
546
 
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
 
494
                                           drizzled::TableIdentifiers &set_of_identifiers)
547
495
{
548
496
  CachedDirectory::Entries entries= directory.getEntries();
549
497
 
562
510
    { }
563
511
    else
564
512
    {
565
 
      std::string path;
566
 
      path+= directory.getPath();
567
 
      path+= FN_LIBCHAR;
568
 
      path+= entry->filename;
569
 
 
570
 
      message::Table definition;
571
 
      if (StorageEngine::readTableFile(path, definition))
572
 
      {
573
 
        /* 
574
 
           Using schema_identifier here to stop unused warning, could use
575
 
           definition.schema() instead
576
 
        */
577
 
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
578
 
        set_of_identifiers.push_back(identifier);
579
 
      }
 
513
      char uname[NAME_LEN + 1];
 
514
      uint32_t file_name_len;
 
515
 
 
516
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
517
      // TODO: Remove need for memory copy here
 
518
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
519
 
 
520
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
580
521
    }
581
522
  }
582
523
}
586
527
  string proto_path(identifier.getPath());
587
528
  proto_path.append(DEFAULT_FILE_EXTENSION);
588
529
 
589
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
 
530
  if (session.doesTableMessageExist(identifier))
590
531
    return true;
591
532
 
592
533
  if (access(proto_path.c_str(), F_OK))
605
546
  proto_path.append(DEFAULT_FILE_EXTENSION);
606
547
 
607
548
  // First we check the temporary tables.
608
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
549
  if (session.getTableMessage(identifier, table_proto))
609
550
    return EEXIST;
610
551
 
611
552
  if (access(proto_path.c_str(), F_OK))
619
560
  return ENOENT;
620
561
}
621
562
 
 
563
/** @brief Initialize the default value of innodb_commit_concurrency.
 
564
 
 
565
Once InnoDB is running, the innodb_commit_concurrency must not change
 
566
from zero to nonzero. (Bug #42101)
 
567
 
 
568
The initial default value is 0, and without this extra initialization,
 
569
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
570
to 0, even if it was initially set to nonzero at the command line
 
571
or configuration file. */
 
572
static
 
573
void
 
574
innobase_commit_concurrency_init_default(void);
 
575
/*==========================================*/
622
576
 
623
577
/************************************************************//**
624
578
Validate the file format name and return its corresponding id.
631
585
            name */
632
586
/************************************************************//**
633
587
Validate the file format check config parameters, as a side effect it
634
 
sets the srv_max_file_format_at_startup variable.
635
 
@return the format_id if valid config value, otherwise, return -1 */
636
 
static
637
 
int
638
 
innobase_file_format_validate_and_set(
 
588
sets the srv_check_file_format_at_startup variable.
 
589
@return true if one of  "on" or "off" */
 
590
static
 
591
bool
 
592
innobase_file_format_check_on_off(
 
593
/*==============================*/
 
594
  const char* format_check);    /*!< in: parameter value */
 
595
/************************************************************//**
 
596
Validate the file format check config parameters, as a side effect it
 
597
sets the srv_check_file_format_at_startup variable.
 
598
@return true if valid config value */
 
599
static
 
600
bool
 
601
innobase_file_format_check_validate(
639
602
/*================================*/
640
 
  const char* format_max);    /*!< in: parameter value */
 
603
  const char* format_check);    /*!< in: parameter value */
641
604
 
642
605
static const char innobase_engine_name[]= "InnoDB";
643
606
 
 
607
/*************************************************************//**
 
608
Check for a valid value of innobase_commit_concurrency.
 
609
@return 0 for valid innodb_commit_concurrency */
 
610
static
 
611
int
 
612
innobase_commit_concurrency_validate(
 
613
/*=================================*/
 
614
  Session*      , /*!< in: thread handle */
 
615
  drizzle_sys_var*  , /*!< in: pointer to system
 
616
            variable */
 
617
  void*       save, /*!< out: immediate result
 
618
            for update function */
 
619
  drizzle_value*    value)  /*!< in: incoming string */
 
620
{
 
621
  int64_t   intbuf;
 
622
  ulong   commit_concurrency;
 
623
 
 
624
  if (value->val_int(value, &intbuf)) {
 
625
    /* The value is NULL. That is invalid. */
 
626
    return(1);
 
627
  }
 
628
 
 
629
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
630
    = static_cast<ulong>(intbuf);
 
631
 
 
632
  /* Allow the value to be updated, as long as it remains zero
 
633
  or nonzero. */
 
634
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
635
}
 
636
 
 
637
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
638
  "Enable InnoDB support for the XA two-phase commit",
 
639
  /* check_func */ NULL, /* update_func */ NULL,
 
640
  /* default */ TRUE);
 
641
 
 
642
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
643
  "Enable InnoDB locking in LOCK TABLES",
 
644
  /* check_func */ NULL, /* update_func */ NULL,
 
645
  /* default */ TRUE);
 
646
 
 
647
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
648
  "Use strict mode when evaluating create options.",
 
649
  NULL, NULL, FALSE);
 
650
 
 
651
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
652
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
653
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
654
 
644
655
 
645
656
/*****************************************************************//**
646
657
Commits a transaction in an InnoDB database. */
667
678
  (char*) &export_vars.innodb_buffer_pool_pages_misc,   SHOW_LONG},
668
679
  {"buffer_pool_pages_total",
669
680
  (char*) &export_vars.innodb_buffer_pool_pages_total,    SHOW_LONG},
670
 
  {"buffer_pool_read_ahead",
671
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
672
 
  {"buffer_pool_read_ahead_evicted",
673
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
 
681
  {"buffer_pool_read_ahead_rnd",
 
682
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
 
683
  {"buffer_pool_read_ahead_seq",
 
684
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
674
685
  {"buffer_pool_read_requests",
675
686
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
676
687
  {"buffer_pool_reads",
907
918
ibool
908
919
thd_supports_xa(
909
920
/*============*/
910
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
921
  void* session)  /*!< in: thread handle (Session*), or NULL to query
911
922
        the global innodb_supports_xa */
912
923
{
913
 
  /* TODO: Add support here for per-session value */
914
 
  return(support_xa);
 
924
  return(SessionVAR((Session*) session, support_xa));
915
925
}
916
926
 
917
927
/******************************************************************//**
921
931
ulong
922
932
thd_lock_wait_timeout(
923
933
/*==================*/
924
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
934
  void* session)  /*!< in: thread handle (Session*), or NULL to query
925
935
      the global innodb_lock_wait_timeout */
926
936
{
927
 
  /* TODO: Add support here for per-session value */
928
937
  /* According to <drizzle/plugin.h>, passing session == NULL
929
938
  returns the global value of the session variable. */
930
 
  return((ulong)lock_wait_timeout.get());
931
 
}
932
 
 
933
 
/******************************************************************//**
934
 
Set the time waited for the lock for the current query. */
935
 
extern "C" UNIV_INTERN
936
 
void
937
 
thd_set_lock_wait_time(
938
 
/*===================*/
939
 
        void*   thd,    /*!< in: thread handle (THD*) */
940
 
        ulint   value)  /*!< in: time waited for the lock */
941
 
{
942
 
        if (thd) {
943
 
          static_cast<Session*>(thd)->utime_after_lock+= value;
944
 
        }
 
939
  return(SessionVAR((Session*) session, lock_wait_timeout));
945
940
}
946
941
 
947
942
/********************************************************************//**
956
951
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
957
952
}
958
953
 
959
 
 
960
 
plugin::ReplicationReturnCode ReplicationLog::apply(Session &session,
961
 
                                                    const message::Transaction &message)
962
 
{
963
 
  char *data= new char[message.ByteSize()];
964
 
 
965
 
  message.SerializeToArray(data, message.ByteSize());
966
 
 
967
 
  trx_t *trx= session_to_trx(&session);
968
 
 
969
 
  uint64_t trx_id= message.transaction_context().transaction_id();
970
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
971
 
  (void)error;
972
 
 
973
 
  delete[] data;
974
 
 
975
 
  return plugin::SUCCESS;
976
 
}
977
 
 
978
954
/********************************************************************//**
979
955
Call this function when mysqld passes control to the client. That is to
980
956
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1036
1012
  case DB_SUCCESS:
1037
1013
    return(0);
1038
1014
 
1039
 
  case DB_INTERRUPTED:
1040
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1041
 
    /* fall through */
1042
 
 
1043
 
  case DB_FOREIGN_EXCEED_MAX_CASCADE:
1044
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1045
 
                        HA_ERR_ROW_IS_REFERENCED,
1046
 
                        "InnoDB: Cannot delete/update "
1047
 
                        "rows with cascading foreign key "
1048
 
                        "constraints that exceed max "
1049
 
                        "depth of %d. Please "
1050
 
                        "drop extra constraints and try "
1051
 
                        "again", DICT_FK_MAX_RECURSIVE_LOAD);
1052
 
    /* fall through */
1053
 
 
1054
1015
  case DB_ERROR:
1055
1016
  default:
1056
1017
    return(-1); /* unspecified error */
1057
1018
 
1058
1019
  case DB_DUPLICATE_KEY:
1059
 
    /* Be cautious with returning this error, since
1060
 
       mysql could re-enter the storage layer to get
1061
 
       duplicated key info, the operation requires a
1062
 
       valid table handle and/or transaction information,
1063
 
       which might not always be available in the error
1064
 
       handling stage. */
1065
1020
    return(HA_ERR_FOUND_DUPP_KEY);
1066
1021
 
1067
1022
  case DB_FOREIGN_DUPLICATE_KEY:
1148
1103
    and the actual error code name could very well be different.
1149
1104
    This will require some monitoring, ie. the status
1150
1105
    of this request on our part.*/
1151
 
 
1152
 
    /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
1153
 
       available in 5.1.38 and later, but the plugin should still
1154
 
       work with previous versions of MySQL.
1155
 
       In Drizzle we seem to not have this yet.
1156
 
    */
1157
 
#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
1158
 
    return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
1159
 
#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1106
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
 
1107
    return(ER_TOO_MANY_CONCURRENT_TRXS);
 
1108
#else
1160
1109
    return(HA_ERR_RECORD_FILE_FULL);
1161
 
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1110
#endif
1162
1111
  case DB_UNSUPPORTED:
1163
1112
    return(HA_ERR_UNSUPPORTED);
1164
1113
  }
1165
1114
}
1166
1115
 
1167
1116
 
 
1117
 
 
1118
/*************************************************************//**
 
1119
If you want to print a session that is not associated with the current thread,
 
1120
you must call this function before reserving the InnoDB kernel_mutex, to
 
1121
protect Drizzle from setting session->query NULL. If you print a session of the
 
1122
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1123
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1124
after you release the kernel_mutex.
 
1125
 
 
1126
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1127
         in non-Cursor code.
 
1128
 */
 
1129
extern "C" UNIV_INTERN
 
1130
void
 
1131
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1132
/*============================================*/
 
1133
{
 
1134
  ut_ad(!mutex_own(&kernel_mutex));
 
1135
  LOCK_thread_count.lock();
 
1136
}
 
1137
 
 
1138
/*************************************************************//**
 
1139
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1140
In the InnoDB latching order, the mutex sits right above the
 
1141
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1142
released before this function is invoked. 
 
1143
 
 
1144
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1145
         in non-Cursor code.
 
1146
*/
 
1147
extern "C" UNIV_INTERN
 
1148
void
 
1149
innobase_mysql_end_print_arbitrary_thd(void)
 
1150
/*========================================*/
 
1151
{
 
1152
  ut_ad(!mutex_own(&kernel_mutex));
 
1153
  LOCK_thread_count.unlock();
 
1154
}
 
1155
 
1168
1156
/*************************************************************//**
1169
1157
Prints info of a Session object (== user session thread) to the given file. */
1170
1158
extern "C" UNIV_INTERN
1185
1173
          session->getSecurityContext().getIp().c_str(),
1186
1174
          session->getSecurityContext().getUser().c_str()
1187
1175
  );
1188
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1176
  fprintf(f,
 
1177
          "\n%s", session->getQueryString().c_str()
 
1178
  );
1189
1179
  putc('\n', f);
1190
1180
}
1191
1181
 
1208
1198
  if (cs) {
1209
1199
    *mbminlen = cs->mbminlen;
1210
1200
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1201
  } else {
1214
1202
    ut_a(cset == 0);
1215
1203
    *mbminlen = *mbmaxlen = 0;
1277
1265
/*=================*/
1278
1266
  void* mysql_session)  /*!< in: MySQL thread handle */
1279
1267
{
1280
 
  return static_cast<Session*>(mysql_session)->charset();
 
1268
  return session_charset(static_cast<Session*>(mysql_session));
1281
1269
}
1282
1270
 
1283
1271
extern "C" UNIV_INTERN
1297
1285
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1298
1286
}
1299
1287
 
1300
 
/**********************************************************************//**
1301
 
Determines the current SQL statement.
1302
 
@return        SQL statement string */
1303
 
extern "C" UNIV_INTERN
1304
 
const char*
1305
 
innobase_get_stmt(
1306
 
/*==============*/
1307
 
       void*   session,        /*!< in: MySQL thread handle */
1308
 
       size_t* length)         /*!< out: length of the SQL statement */
1309
 
{
1310
 
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
1311
 
}
1312
 
 
1313
1288
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1314
1289
/*******************************************************************//**
1315
1290
Map an OS error to an errno value. The OS error number is stored in
1575
1550
  trx = trx_allocate_for_mysql();
1576
1551
 
1577
1552
  trx->mysql_thd = session;
 
1553
  trx->mysql_query_str = session->query.c_str();
1578
1554
 
1579
1555
  innobase_trx_init(session, trx);
1580
1556
 
1613
1589
Construct ha_innobase Cursor. */
1614
1590
UNIV_INTERN
1615
1591
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1616
 
                         Table &table_arg)
 
1592
                         TableShare &table_arg)
1617
1593
  :Cursor(engine_arg, table_arg),
1618
1594
  primary_key(0), /* needs initialization because index_flags() may be called 
1619
1595
                     before this is set to the real value. It's ok to have any 
1804
1780
/*===============*/
1805
1781
  trx_t*  trx)  /*!< in: transaction */
1806
1782
{
1807
 
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1808
 
}
1809
 
 
1810
 
/**********************************************************************//**
1811
 
Determines if the currently running transaction is in strict mode.
1812
 
@return TRUE if strict */
1813
 
extern "C" UNIV_INTERN
1814
 
ibool
1815
 
trx_is_strict(
1816
 
/*==========*/
1817
 
        trx_t*  trx)    /*!< in: transaction */
1818
 
{
1819
 
        return(trx && trx->mysql_thd
1820
 
               && true);
 
1783
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1821
1784
}
1822
1785
 
1823
1786
/**************************************************************//**
1839
1802
  value= value - (value % align_val);
1840
1803
}
1841
1804
 
1842
 
static void auto_extend_update(Session *, sql_var_t)
1843
 
{
1844
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1845
 
}
1846
 
 
1847
 
static void io_capacity_update(Session *, sql_var_t)
1848
 
{
1849
 
  srv_io_capacity= innodb_io_capacity.get();
1850
 
}
1851
 
 
1852
 
static void purge_batch_update(Session *, sql_var_t)
1853
 
{
1854
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1855
 
}
1856
 
 
1857
 
static void purge_threads_update(Session *, sql_var_t)
1858
 
{
1859
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1860
 
}
1861
 
 
1862
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1863
 
{
1864
 
  if (btr_search_enabled)
1865
 
  {
1866
 
    btr_search_enable();
1867
 
  } else {
1868
 
    btr_search_disable();
1869
 
  }
1870
 
}
1871
 
 
1872
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1873
 
{
1874
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1875
 
}
1876
 
 
1877
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1878
 
{
1879
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1880
 
}
1881
 
 
1882
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1883
 
{
1884
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1885
 
}
1886
 
 
1887
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1888
 
{
1889
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1890
 
}
1891
 
 
1892
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1893
 
{
1894
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1895
 
}
1896
 
 
1897
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1898
 
{
1899
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1900
 
}
1901
 
 
1902
 
 
1903
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1904
 
{
1905
 
   uint32_t new_value= var->save_result.uint32_t_value;
1906
 
 
1907
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1908
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1909
 
   {
1910
 
     push_warning_printf(session,
1911
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1912
 
                         ER_WRONG_ARGUMENTS,
1913
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1914
 
                           "must not change between zero and nonzero."));
1915
 
     return 1;
1916
 
   }
1917
 
   return 0;
1918
 
}
1919
 
 
1920
 
/*************************************************************//**
1921
 
Check if it is a valid file format. This function is registered as
1922
 
a callback with MySQL.
1923
 
@return 0 for valid file format */
1924
 
static
1925
 
int
1926
 
innodb_file_format_name_validate(
1927
 
/*=============================*/
1928
 
  Session*      , /*!< in: thread handle */
1929
 
  set_var *var)
1930
 
{
1931
 
  const char *file_format_input = var->value->str_value.ptr();
1932
 
  if (file_format_input == NULL)
1933
 
    return 1;
1934
 
 
1935
 
  if (file_format_input != NULL) {
1936
 
    uint  format_id;
1937
 
 
1938
 
    format_id = innobase_file_format_name_lookup(
1939
 
      file_format_input);
1940
 
 
1941
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1942
 
      innobase_file_format_name =
1943
 
        trx_sys_file_format_id_to_name(format_id);
1944
 
 
1945
 
      return(0);
1946
 
    }
1947
 
  }
1948
 
 
1949
 
  return(1);
1950
 
}
1951
 
 
1952
 
/*************************************************************//**
1953
 
Check if it is a valid value of innodb_change_buffering. This function is
1954
 
registered as a callback with MySQL.
1955
 
@return 0 for valid innodb_change_buffering */
1956
 
static
1957
 
int
1958
 
innodb_change_buffering_validate(
1959
 
/*=============================*/
1960
 
  Session*      , /*!< in: thread handle */
1961
 
  set_var *var)
1962
 
{
1963
 
  const char *change_buffering_input = var->value->str_value.ptr();
1964
 
 
1965
 
  if (change_buffering_input == NULL)
1966
 
    return 1;
1967
 
 
1968
 
  ulint use;
1969
 
 
1970
 
  for (use = 0;
1971
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1972
 
       ++use) {
1973
 
    if (!innobase_strcasecmp(change_buffering_input,
1974
 
                             innobase_change_buffering_values[use]))
1975
 
    {
1976
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1977
 
      return 0;
1978
 
    }
1979
 
  }
1980
 
 
1981
 
  return 1;
1982
 
}
1983
 
 
1984
 
 
1985
 
/*************************************************************//**
1986
 
Check if valid argument to innodb_file_format_max. This function
1987
 
is registered as a callback with MySQL.
1988
 
@return 0 for valid file format */
1989
 
static
1990
 
int
1991
 
innodb_file_format_max_validate(
1992
 
/*==============================*/
1993
 
  Session*   session, /*!< in: thread handle */
1994
 
  set_var *var)
1995
 
{
1996
 
  const char *file_format_input = var->value->str_value.ptr();
1997
 
  if (file_format_input == NULL)
1998
 
    return 1;
1999
 
 
2000
 
  if (file_format_input != NULL) {
2001
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
2002
 
 
2003
 
    if (format_id > DICT_TF_FORMAT_MAX) {
2004
 
      /* DEFAULT is "on", which is invalid at runtime. */
2005
 
      return 1;
2006
 
    }
2007
 
 
2008
 
    if (format_id >= 0) {
2009
 
      innobase_file_format_max= 
2010
 
        trx_sys_file_format_id_to_name((uint)format_id);
2011
 
 
2012
 
      /* Update the max format id in the system tablespace. */
2013
 
      char name_buff[100];
2014
 
      strcpy(name_buff, innobase_file_format_max.c_str());
2015
 
      if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
2016
 
      {
2017
 
        errmsg_printf(ERRMSG_LVL_WARN,
2018
 
                      " [Info] InnoDB: the file format in the system "
2019
 
                      "tablespace is now set to %s.\n", name_buff);
2020
 
        innobase_file_format_max= name_buff;
2021
 
      }
2022
 
      return(0);
2023
 
 
2024
 
    } else {
2025
 
      push_warning_printf(session,
2026
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
2027
 
                          ER_WRONG_ARGUMENTS,
2028
 
                          "InnoDB: invalid innodb_file_format_max "
2029
 
                          "value; can be any format up to %s "
2030
 
                          "or equivalent id of %d",
2031
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
2032
 
                          DICT_TF_FORMAT_MAX);
2033
 
    }
2034
 
  }
2035
 
 
2036
 
  return(1);
2037
 
}
2038
 
 
2039
 
 
2040
1805
/*********************************************************************//**
2041
1806
Opens an InnoDB database.
2042
1807
@return 0 on success, error code on failure */
2052
1817
  InnobaseEngine *actuall_engine_ptr;
2053
1818
  const module::option_map &vm= context.getOptions();
2054
1819
 
2055
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2056
 
  srv_io_capacity= innodb_io_capacity.get();
2057
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2058
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2059
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2060
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2061
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2062
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2063
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2064
 
  srv_replication_delay= innodb_replication_delay.get();
2065
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2066
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2067
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2068
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2069
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2070
 
 
2071
1820
  /* Inverted Booleans */
2072
1821
 
2073
1822
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2074
1823
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2075
1824
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
 
1825
  innobase_stats_on_metadata= (vm.count("disable-stats-on-metadata")) ? false : true;
2076
1826
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2077
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2078
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2079
 
 
2080
 
 
2081
 
  /* Hafta do this here because we need to late-bind the default value */
 
1827
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1828
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1829
 
 
1830
  if (vm.count("io-capacity"))
 
1831
  {
 
1832
    if (srv_io_capacity < 100)
 
1833
    {
 
1834
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1835
      exit(-1);
 
1836
    }
 
1837
  }
 
1838
 
2082
1839
  if (vm.count("data-home-dir"))
2083
1840
  {
2084
 
    innobase_data_home_dir= vm["data-home-dir"].as<string>();
2085
 
  }
2086
 
  else
2087
 
  {
2088
 
    innobase_data_home_dir= getDataHome().file_string();
2089
 
  }
2090
 
 
 
1841
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1842
  }
 
1843
  else
 
1844
  {
 
1845
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
 
1846
  }
 
1847
 
 
1848
  if (vm.count("fast-shutdown"))
 
1849
  {
 
1850
    if (innobase_fast_shutdown > 2)
 
1851
    {
 
1852
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1853
      exit(-1);
 
1854
    }
 
1855
  }
 
1856
 
 
1857
  if (vm.count("file-format-check"))
 
1858
  {
 
1859
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1860
  }
 
1861
 
 
1862
  if (vm.count("flush-log-at-trx-commit"))
 
1863
  {
 
1864
    if (srv_flush_log_at_trx_commit > 2)
 
1865
    {
 
1866
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1867
      exit(-1);
 
1868
    }
 
1869
  }
 
1870
 
 
1871
  if (vm.count("flush-method"))
 
1872
  {
 
1873
    innobase_unix_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1874
  }
 
1875
  else
 
1876
  {
 
1877
    innobase_unix_file_flush_method= NULL;
 
1878
  }
 
1879
 
 
1880
#ifdef UNIV_LOG_ARCHIVE
 
1881
  if (vm.count("log-arch-dir"))
 
1882
  {
 
1883
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1884
  }
 
1885
 
 
1886
  else
 
1887
  {
 
1888
    innobase_log_arch_dir= NULL;
 
1889
  }
 
1890
#endif /* UNIV_LOG_ARCHIVE */
 
1891
 
 
1892
  if (vm.count("max-dirty-pages-pct"))
 
1893
  {
 
1894
    if (srv_max_buf_pool_modified_pct > 99)
 
1895
    {
 
1896
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1897
      exit(-1);
 
1898
    }
 
1899
  }
 
1900
 
 
1901
  if (vm.count("stats-sample-pages"))
 
1902
  {
 
1903
    if (srv_stats_sample_pages < 8)
 
1904
    {
 
1905
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1906
      exit(-1);
 
1907
    }
 
1908
  }
 
1909
 
 
1910
  if (vm.count("additional-mem-pool-size"))
 
1911
  {
 
1912
    align_value(innobase_additional_mem_pool_size);
 
1913
 
 
1914
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1915
    {
 
1916
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1917
      exit(-1);
 
1918
    }
 
1919
 
 
1920
  }
 
1921
 
 
1922
  if (vm.count("autoextend-increment"))
 
1923
  {
 
1924
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1925
    {
 
1926
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1927
      exit(-1);
 
1928
    }
 
1929
  }
 
1930
 
 
1931
  if (vm.count("buffer-pool-size"))
 
1932
  {
 
1933
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1934
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1935
    {
 
1936
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1937
      exit(-1);
 
1938
    }
 
1939
    
 
1940
  }
 
1941
 
 
1942
  if (vm.count("commit-concurrency"))
 
1943
  {
 
1944
    if (srv_replication_delay > 1000)
 
1945
    {
 
1946
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1947
      exit(-1);
 
1948
    }
 
1949
  }
 
1950
 
 
1951
  if (vm.count("concurrency-tickets"))
 
1952
  {
 
1953
    if (srv_n_free_tickets_to_enter < 1)
 
1954
    {
 
1955
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1956
      exit(-1);
 
1957
    }
 
1958
  }
 
1959
 
 
1960
  if (vm.count("read-io-threads"))
 
1961
  {
 
1962
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1963
    {
 
1964
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1965
      exit(-1);
 
1966
    }
 
1967
  }
 
1968
 
 
1969
  if (vm.count("write-io-threads"))
 
1970
  {
 
1971
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1972
    {
 
1973
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1974
      exit(-1);
 
1975
    }
 
1976
  }
 
1977
 
 
1978
  if (vm.count("force-recovery"))
 
1979
  {
 
1980
    if (innobase_force_recovery > 6)
 
1981
    {
 
1982
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
1983
      exit(-1);
 
1984
    }
 
1985
  }
 
1986
 
 
1987
  if (vm.count("log-buffer-size"))
 
1988
  {
 
1989
    align_value(innobase_log_buffer_size);
 
1990
    if (innobase_log_buffer_size < 256*1024L)
 
1991
    {
 
1992
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1993
      exit(-1);
 
1994
    }
 
1995
  }
 
1996
 
 
1997
  if (vm.count("log-file-size"))
 
1998
  {
 
1999
    align_value(innobase_log_file_size, 1024*1024);
 
2000
    if (innobase_log_file_size < 1*1024*1024L)
 
2001
    {
 
2002
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2003
      exit(-1);
 
2004
    }
 
2005
  }
 
2006
 
 
2007
  if (vm.count("log-files-in-group"))
 
2008
  {
 
2009
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2010
    {
 
2011
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2012
      exit(-1);
 
2013
    }
 
2014
  }
 
2015
 
 
2016
  if (vm.count("mirrored-log-groups"))
 
2017
  {
 
2018
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2019
    {
 
2020
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2021
      exit(-1);
 
2022
    }
 
2023
  }
 
2024
 
 
2025
  if (vm.count("open-files"))
 
2026
  {
 
2027
    if (innobase_open_files < 10)
 
2028
    {
 
2029
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2030
      exit(-1);
 
2031
    }
 
2032
  }
 
2033
 
 
2034
  if (vm.count("thread-concurrency"))
 
2035
  {
 
2036
    if (srv_thread_concurrency > 1000)
 
2037
    {
 
2038
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2039
      exit(-1);
 
2040
    }
 
2041
  }
2091
2042
 
2092
2043
  if (vm.count("data-file-path"))
2093
2044
  {
2094
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2095
 
  }
2096
 
 
 
2045
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2046
  }
 
2047
  else
 
2048
  {
 
2049
    innobase_data_file_path= NULL;
 
2050
  }
 
2051
 
 
2052
  if (vm.count("version"))
 
2053
  {
 
2054
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2055
  }
 
2056
 
 
2057
  if (vm.count("read-ahead-threshold"))
 
2058
  {
 
2059
    if (srv_read_ahead_threshold > 64)
 
2060
    {
 
2061
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2062
      exit(-1);
 
2063
    }
 
2064
  }
 
2065
 
 
2066
  if (vm.count("strict-mode"))
 
2067
  {
 
2068
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2069
  }
 
2070
 
 
2071
  if (vm.count("lock-wait-timeout"))
 
2072
  {
 
2073
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2074
    {
 
2075
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2076
      exit(-1);
 
2077
    }
 
2078
 
 
2079
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2080
  }
2097
2081
 
2098
2082
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2099
2083
 
2117
2101
  }
2118
2102
#endif /* UNIV_DEBUG */
2119
2103
 
 
2104
  /* Check that values don't overflow on 32-bit systems. */
 
2105
  if (sizeof(ulint) == 4) {
 
2106
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2107
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2108
                    "innobase_buffer_pool_size can't be over 4GB"
 
2109
                    " on 32-bit systems");
 
2110
 
 
2111
      goto error;
 
2112
    }
 
2113
 
 
2114
    if (innobase_log_file_size > UINT32_MAX) {
 
2115
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2116
                    "innobase_log_file_size can't be over 4GB"
 
2117
                    " on 32-bit systems");
 
2118
 
 
2119
      goto error;
 
2120
    }
 
2121
  }
 
2122
 
2120
2123
  os_innodb_umask = (ulint)internal::my_umask;
2121
2124
 
2122
2125
 
2127
2130
 
2128
2131
  /* The default dir for data files is the datadir of MySQL */
2129
2132
 
2130
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2133
  srv_data_home = (char *)innobase_data_home_dir;
2131
2134
 
2132
2135
  /* Set default InnoDB data file size to 10 MB and let it be
2133
2136
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2134
2137
    to specify any startup options. */
2135
2138
 
2136
 
  if (innobase_data_file_path.empty()) 
2137
 
  {
2138
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2139
  if (!innobase_data_file_path) {
 
2140
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2139
2141
  }
2140
2142
 
2141
2143
  /* Since InnoDB edits the argument in the next call, we make another
2142
2144
    copy of it: */
2143
2145
 
2144
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2146
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2145
2147
 
2146
2148
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2147
2149
                                                   internal_innobase_data_file_path);
2161
2163
 
2162
2164
  if (vm.count("log-group-home-dir"))
2163
2165
  {
2164
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2166
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
2165
2167
  }
2166
2168
  else
2167
2169
  {
2168
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2170
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
2169
2171
  }
2170
2172
 
 
2173
#ifdef UNIV_LOG_ARCHIVE
 
2174
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2175
    starting from 4.0.6 we always set it the same as
 
2176
innodb_log_group_home_dir: */
 
2177
 
 
2178
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2179
 
 
2180
  srv_arch_dir = innobase_log_arch_dir;
 
2181
#endif /* UNIG_LOG_ARCHIVE */
 
2182
 
2171
2183
  ret = (bool)
2172
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2184
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2173
2185
 
2174
 
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2175
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2176
 
                  _("syntax error in innodb_log_group_home_dir, or a "
2177
 
                  "wrong number of mirrored log groups"));
 
2186
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2187
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2188
                  "wrong number of mirrored log groups");
2178
2189
 
2179
2190
    goto mem_free_and_error;
2180
2191
  }
2199
2210
 
2200
2211
  srv_file_format = format_id;
2201
2212
 
2202
 
  innobase_file_format_name =
2203
 
    trx_sys_file_format_id_to_name(format_id);
2204
 
 
2205
 
  /* Check innobase_file_format_check variable */
2206
 
  if (!innobase_file_format_check)
2207
 
  {
2208
 
    /* Set the value to disable checking. */
2209
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
2210
 
  } else {
2211
 
    /* Set the value to the lowest supported format. */
2212
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN;
2213
 
  }
2214
 
 
2215
 
  /* Did the user specify a format name that we support?
2216
 
     As a side effect it will update the variable
2217
 
     srv_max_file_format_at_startup */
2218
 
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2219
 
  {
2220
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
2221
 
                    "innodb_file_format_max value: "
2222
 
                    "should be any value up to %s or its "
2223
 
                    "equivalent numeric id"),
2224
 
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2225
 
    goto mem_free_and_error;
 
2213
  /* Given the type of innobase_file_format_name we have little
 
2214
    choice but to cast away the constness from the returned name.
 
2215
    innobase_file_format_name is used in the MySQL set variable
 
2216
    interface and so can't be const. */
 
2217
 
 
2218
  innobase_file_format_name = 
 
2219
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2220
 
 
2221
  /* Process innobase_file_format_check variable */
 
2222
  ut_a(innobase_file_format_check != NULL);
 
2223
 
 
2224
  /* As a side effect it will set srv_check_file_format_at_startup
 
2225
    on valid input. First we check for "on"/"off". */
 
2226
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2227
 
 
2228
    /* Did the user specify a format name that we support ?
 
2229
      As a side effect it will update the variable
 
2230
      srv_check_file_format_at_startup */
 
2231
    if (!innobase_file_format_check_validate(
 
2232
                                             innobase_file_format_check)) {
 
2233
 
 
2234
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2235
                    "innodb_file_format_check value: "
 
2236
                    "should be either 'on' or 'off' or "
 
2237
                    "any value up to %s or its "
 
2238
                    "equivalent numeric id",
 
2239
                    trx_sys_file_format_id_to_name(
 
2240
                                                   DICT_TF_FORMAT_MAX));
 
2241
 
 
2242
      goto mem_free_and_error;
 
2243
    }
2226
2244
  }
2227
2245
 
2228
2246
  if (vm.count("change-buffering"))
2233
2251
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2234
2252
         use++) {
2235
2253
      if (!innobase_strcasecmp(
2236
 
                               innobase_change_buffering.c_str(),
 
2254
                               vm["change-buffering"].as<string>().c_str(),
2237
2255
                               innobase_change_buffering_values[use])) {
2238
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2256
        ibuf_use = (ibuf_use_t) use;
2239
2257
        goto innobase_change_buffering_inited_ok;
2240
2258
      }
2241
2259
    }
2242
2260
 
2243
2261
    errmsg_printf(ERRMSG_LVL_ERROR,
2244
2262
                  "InnoDB: invalid value "
2245
 
                  "innodb_change_buffering=%s",
 
2263
                  "innodb_file_format_check=%s",
2246
2264
                  vm["change-buffering"].as<string>().c_str());
2247
2265
    goto mem_free_and_error;
2248
2266
  }
2249
2267
 
2250
2268
innobase_change_buffering_inited_ok:
2251
2269
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2252
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2270
  innobase_change_buffering = (char*)
 
2271
    innobase_change_buffering_values[ibuf_use];
2253
2272
 
2254
2273
  /* --------------------------------------------------*/
2255
2274
 
2256
 
  if (vm.count("flush-method") != 0)
2257
 
  {
2258
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2259
 
  }
 
2275
  srv_file_flush_method_str = innobase_unix_file_flush_method;
2260
2276
 
2261
2277
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2262
2278
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2263
2279
  srv_log_file_size = (ulint) innobase_log_file_size;
2264
2280
 
 
2281
#ifdef UNIV_LOG_ARCHIVE
 
2282
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2283
#endif /* UNIV_LOG_ARCHIVE */
2265
2284
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2266
2285
 
2267
2286
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2268
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2269
2287
 
2270
2288
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2271
2289
 
2296
2314
 
2297
2315
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2298
2316
 
 
2317
 
 
2318
  innobase_commit_concurrency_init_default();
 
2319
 
2299
2320
  /* Since we in this module access directly the fields of a trx
2300
2321
    struct, and due to different headers and flags it might happen that
2301
2322
    mutex_t has a different size in this module and in InnoDB
2304
2325
 
2305
2326
  err = innobase_start_or_create_for_mysql();
2306
2327
 
2307
 
  if (err != DB_SUCCESS)
2308
 
  {
2309
 
    goto mem_free_and_error;
2310
 
  }
2311
 
 
2312
 
  err = dict_create_sys_replication_log();
2313
 
 
2314
2328
  if (err != DB_SUCCESS) {
2315
2329
    goto mem_free_and_error;
2316
2330
  }
2317
2331
 
2318
 
 
2319
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2320
 
                                                     TRUE);
2321
 
 
2322
2332
  innobase_open_tables = hash_create(200);
2323
2333
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2324
2334
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2356
2366
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2357
2367
  context.add(innodb_lock_waits_tool);
2358
2368
 
2359
 
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2360
 
  context.add(innodb_sys_tables_tool);
2361
 
 
2362
 
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2363
 
  context.add(innodb_sys_tablestats_tool);
2364
 
 
2365
 
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2366
 
  context.add(innodb_sys_indexes_tool);
2367
 
 
2368
 
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2369
 
  context.add(innodb_sys_columns_tool);
2370
 
 
2371
 
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2372
 
  context.add(innodb_sys_fields_tool);
2373
 
 
2374
 
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2375
 
  context.add(innodb_sys_foreign_tool);
2376
 
 
2377
 
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2378
 
  context.add(innodb_sys_foreign_cols_tool);
2379
 
 
2380
2369
  context.add(new(std::nothrow)InnodbInternalTables());
2381
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2382
 
 
2383
 
  if (innobase_use_replication_log)
2384
 
  {
2385
 
    replication_logger= new(std::nothrow)ReplicationLog();
2386
 
    context.add(replication_logger);
2387
 
    ReplicationLog::setup(replication_logger);
2388
 
  }
2389
 
 
2390
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2391
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2392
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2393
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2394
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2395
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2396
 
 
2397
 
 
2398
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2399
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2400
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2401
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2402
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2403
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2404
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2405
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2406
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2407
 
 
2408
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2409
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2410
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2411
 
 
2412
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2413
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2414
 
                                                                   innodb_auto_extend_increment,
2415
 
                                                                   auto_extend_update));
2416
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2417
 
                                                                   innodb_io_capacity,
2418
 
                                                                   io_capacity_update));
2419
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2420
 
                                                                   innodb_purge_batch_size,
2421
 
                                                                   purge_batch_update));
2422
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2423
 
                                                                   innodb_n_purge_threads,
2424
 
                                                                   purge_threads_update));
2425
 
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
2426
 
  context.registerVariable(new sys_var_std_string("file_format",
2427
 
                                                  innobase_file_format_name,
2428
 
                                                  innodb_file_format_name_validate));
2429
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2430
 
                                                  innobase_change_buffering,
2431
 
                                                  innodb_change_buffering_validate));
2432
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2433
 
                                                  innobase_file_format_max,
2434
 
                                                  innodb_file_format_max_validate));
2435
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2436
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2437
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2438
 
                                                  innodb_flush_log_at_trx_commit));
2439
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2440
 
                                                  innodb_max_dirty_pages_pct));
2441
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2442
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2443
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2444
 
 
2445
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2446
 
                                                                   innobase_commit_concurrency,
2447
 
                                                                   innodb_commit_concurrency_validate));
2448
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2449
 
                                                                   innodb_concurrency_tickets));
2450
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2451
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2452
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2453
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2454
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2455
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2456
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2457
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2458
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2459
 
                                                                   innobase_old_blocks_pct,
2460
 
                                                                   innodb_old_blocks_pct_update));
2461
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2462
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2463
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2464
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2465
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2466
 
                                                                   innobase_thread_concurrency,
2467
 
                                                                   innodb_thread_concurrency_update));
2468
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2469
 
                                                                   innodb_read_ahead_threshold,
2470
 
                                                                   innodb_read_ahead_threshold_update));
 
2370
 
2471
2371
  /* Get the current high water mark format. */
2472
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2473
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2372
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2474
2373
 
2475
2374
  return(FALSE);
2476
2375
error:
2579
2478
    Note, the position is current because of
2580
2479
    prepare_commit_mutex */
2581
2480
retry:
2582
 
    if (innobase_commit_concurrency.get() > 0) {
 
2481
    if (innobase_commit_concurrency > 0) {
2583
2482
      pthread_mutex_lock(&commit_cond_m);
2584
2483
      commit_threads++;
2585
2484
 
2586
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
2485
      if (commit_threads > innobase_commit_concurrency) {
2587
2486
        commit_threads--;
2588
2487
        pthread_cond_wait(&commit_cond,
2589
2488
          &commit_cond_m);
2608
2507
    innobase_commit_low(trx);
2609
2508
    trx->flush_log_later = FALSE;
2610
2509
 
2611
 
    if (innobase_commit_concurrency.get() > 0) {
 
2510
    if (innobase_commit_concurrency > 0) {
2612
2511
      pthread_mutex_lock(&commit_cond_m);
2613
2512
      commit_threads--;
2614
2513
      pthread_cond_signal(&commit_cond);
2632
2531
    SQL statement */
2633
2532
 
2634
2533
    trx_mark_sql_stat_end(trx);
2635
 
 
2636
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2637
 
    {
2638
 
      if (trx->conc_state != TRX_NOT_STARTED)
2639
 
      {
2640
 
        commit(session, TRUE);
2641
 
      }
2642
 
    }
2643
2534
  }
2644
2535
 
2645
2536
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2654
2545
  threads: */
2655
2546
  srv_active_wake_master_thread();
2656
2547
 
2657
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2658
 
      trx->global_read_view)
2659
 
  {
2660
 
    /* At low transaction isolation levels we let
2661
 
       each consistent read set its own snapshot */
2662
 
    read_view_close_for_mysql(trx);
2663
 
  }
2664
 
 
2665
2548
  return(0);
2666
2549
}
2667
2550
 
2689
2572
 
2690
2573
  innobase_release_stat_resources(trx);
2691
2574
 
2692
 
  trx->n_autoinc_rows = 0;
2693
 
 
2694
2575
  /* If we had reserved the auto-inc lock for some table (if
2695
2576
  we come here to roll back the latest SQL statement) we
2696
2577
  release it now before a possibly lengthy rollback */
2705
2586
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2706
2587
  }
2707
2588
 
2708
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2709
 
      trx->global_read_view)
2710
 
  {
2711
 
    /* At low transaction isolation levels we let
2712
 
       each consistent read set its own snapshot */
2713
 
    read_view_close_for_mysql(trx);
2714
 
  }
2715
 
 
2716
2589
  return(convert_error_code_to_mysql(error, 0, NULL));
2717
2590
}
2718
2591
 
2849
2722
 
2850
2723
  ut_a(trx);
2851
2724
 
2852
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2725
  assert(session->killed != Session::NOT_KILLED ||
2853
2726
         trx->conc_state == TRX_NOT_STARTED);
2854
2727
 
2855
2728
  /* Warn if rolling back some things... */
2856
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2729
  if (session->killed != Session::NOT_KILLED &&
2857
2730
      trx->conc_state != TRX_NOT_STARTED &&
2858
 
      trx->undo_no > 0 &&
 
2731
      trx->undo_no.low > 0 &&
2859
2732
      global_system_variables.log_warnings)
2860
2733
  {
2861
 
      errmsg_printf(ERRMSG_LVL_WARN,
 
2734
      errmsg_printf(ERRMSG_LVL_WARN, 
2862
2735
      "Drizzle is closing a connection during a KILL operation\n"
2863
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2736
      "that has an active InnoDB transaction.  %lu row modifications will "
2864
2737
      "roll back.\n",
2865
 
      (ullint) trx->undo_no);
 
2738
      (ulong) trx->undo_no.low);
2866
2739
  }
2867
2740
 
2868
2741
  innobase_rollback_trx(trx);
2985
2858
}
2986
2859
 
2987
2860
/********************************************************************//**
2988
 
Get the upper limit of the MySQL integral and floating-point type.
2989
 
@return maximum allowed value for the field */
2990
 
static
2991
 
uint64_t
2992
 
innobase_get_int_col_max_value(
2993
 
/*===========================*/
2994
 
        const Field*    field)  /*!< in: MySQL field */
2995
 
{
2996
 
        uint64_t        max_value = 0;
2997
 
 
2998
 
        switch(field->key_type()) {
2999
 
        /* TINY */
3000
 
        case HA_KEYTYPE_BINARY:
3001
 
                max_value = 0xFFULL;
3002
 
                break;
3003
 
        /* LONG */
3004
 
        case HA_KEYTYPE_ULONG_INT:
3005
 
                max_value = 0xFFFFFFFFULL;
3006
 
                break;
3007
 
        case HA_KEYTYPE_LONG_INT:
3008
 
                max_value = 0x7FFFFFFFULL;
3009
 
                break;
3010
 
        /* BIG */
3011
 
        case HA_KEYTYPE_ULONGLONG:
3012
 
                max_value = 0xFFFFFFFFFFFFFFFFULL;
3013
 
                break;
3014
 
        case HA_KEYTYPE_LONGLONG:
3015
 
                max_value = 0x7FFFFFFFFFFFFFFFULL;
3016
 
                break;
3017
 
        case HA_KEYTYPE_DOUBLE:
3018
 
                /* We use the maximum as per IEEE754-2008 standard, 2^53 */
3019
 
                max_value = 0x20000000000000ULL;
3020
 
                break;
3021
 
        default:
3022
 
                ut_error;
3023
 
        }
3024
 
 
3025
 
        return(max_value);
3026
 
}
3027
 
 
3028
 
/*******************************************************************//**
3029
 
This function checks whether the index column information
3030
 
is consistent between KEY info from mysql and that from innodb index.
3031
 
@return TRUE if all column types match. */
3032
 
static
3033
 
ibool
3034
 
innobase_match_index_columns(
3035
 
/*=========================*/
3036
 
        const KeyInfo*          key_info,       /*!< in: Index info
3037
 
                                                from mysql */
3038
 
        const dict_index_t*     index_info)     /*!< in: Index info
3039
 
                                                from Innodb */
3040
 
{
3041
 
        const KeyPartInfo*      key_part;
3042
 
        const KeyPartInfo*      key_end;
3043
 
        const dict_field_t*     innodb_idx_fld;
3044
 
        const dict_field_t*     innodb_idx_fld_end;
3045
 
 
3046
 
        /* Check whether user defined index column count matches */
3047
 
        if (key_info->key_parts != index_info->n_user_defined_cols) {
3048
 
                return(FALSE);
3049
 
        }
3050
 
 
3051
 
        key_part = key_info->key_part;
3052
 
        key_end = key_part + key_info->key_parts;
3053
 
        innodb_idx_fld = index_info->fields;
3054
 
        innodb_idx_fld_end = index_info->fields + index_info->n_fields;
3055
 
 
3056
 
        /* Check each index column's datatype. We do not check
3057
 
        column name because there exists case that index
3058
 
        column name got modified in mysql but such change does not
3059
 
        propagate to InnoDB.
3060
 
        One hidden assumption here is that the index column sequences
3061
 
        are matched up between those in mysql and Innodb. */
3062
 
        for (; key_part != key_end; ++key_part) {
3063
 
                ulint   col_type;
3064
 
                ibool   is_unsigned;
3065
 
                ulint   mtype = innodb_idx_fld->col->mtype;
3066
 
 
3067
 
                /* Need to translate to InnoDB column type before
3068
 
                comparison. */
3069
 
                col_type = get_innobase_type_from_mysql_type(&is_unsigned,
3070
 
                                                             key_part->field);
3071
 
 
3072
 
                /* Ignore Innodb specific system columns. */
3073
 
                while (mtype == DATA_SYS) {
3074
 
                        innodb_idx_fld++;
3075
 
 
3076
 
                        if (innodb_idx_fld >= innodb_idx_fld_end) {
3077
 
                                return(FALSE);
3078
 
                        }
3079
 
                }
3080
 
 
3081
 
                if (col_type != mtype) {
3082
 
                        /* Column Type mismatches */
3083
 
                        return(FALSE);
3084
 
                }
3085
 
 
3086
 
                innodb_idx_fld++;
3087
 
        }
3088
 
 
3089
 
        return(TRUE);
3090
 
}
3091
 
 
3092
 
/*******************************************************************//**
3093
 
This function builds a translation table in INNOBASE_SHARE
3094
 
structure for fast index location with mysql array number from its
3095
 
table->key_info structure. This also provides the necessary translation
3096
 
between the key order in mysql key_info and Innodb ib_table->indexes if
3097
 
they are not fully matched with each other.
3098
 
Note we do not have any mutex protecting the translation table
3099
 
building based on the assumption that there is no concurrent
3100
 
index creation/drop and DMLs that requires index lookup. All table
3101
 
handle will be closed before the index creation/drop.
3102
 
@return TRUE if index translation table built successfully */
3103
 
static
3104
 
ibool
3105
 
innobase_build_index_translation(
3106
 
/*=============================*/
3107
 
        const Table*            table,    /*!< in: table in MySQL data
3108
 
                                          dictionary */
3109
 
        dict_table_t*           ib_table, /*!< in: table in Innodb data
3110
 
                                          dictionary */
3111
 
        INNOBASE_SHARE*         share)    /*!< in/out: share structure
3112
 
                                          where index translation table
3113
 
                                          will be constructed in. */
3114
 
{
3115
 
        ulint           mysql_num_index;
3116
 
        ulint           ib_num_index;
3117
 
        dict_index_t**  index_mapping;
3118
 
        ibool           ret = TRUE;
3119
 
 
3120
 
        mutex_enter(&dict_sys->mutex);
3121
 
 
3122
 
        mysql_num_index = table->getShare()->keys;
3123
 
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3124
 
 
3125
 
        index_mapping = share->idx_trans_tbl.index_mapping;
3126
 
 
3127
 
        /* If there exists inconsistency between MySQL and InnoDB dictionary
3128
 
        (metadata) information, the number of index defined in MySQL
3129
 
        could exceed that in InnoDB, do not build index translation
3130
 
        table in such case */
3131
 
        if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3132
 
                ret = FALSE;
3133
 
                goto func_exit;
3134
 
        }
3135
 
 
3136
 
        /* If index entry count is non-zero, nothing has
3137
 
        changed since last update, directly return TRUE */
3138
 
        if (share->idx_trans_tbl.index_count) {
3139
 
                /* Index entry count should still match mysql_num_index */
3140
 
                ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
3141
 
                goto func_exit;
3142
 
        }
3143
 
 
3144
 
        /* The number of index increased, rebuild the mapping table */
3145
 
        if (mysql_num_index > share->idx_trans_tbl.array_size) {
3146
 
                index_mapping = (dict_index_t**) realloc(index_mapping,
3147
 
                                                        mysql_num_index *
3148
 
                                                         sizeof(*index_mapping));
3149
 
 
3150
 
                if (!index_mapping) {
3151
 
                        /* Report an error if index_mapping continues to be
3152
 
                        NULL and mysql_num_index is a non-zero value */
3153
 
                        errmsg_printf(ERRMSG_LVL_ERROR,
3154
 
                                      "InnoDB: fail to allocate memory for "
3155
 
                                        "index translation table. Number of "
3156
 
                                        "Index:%lu, array size:%lu",
3157
 
                                        mysql_num_index,
3158
 
                                        share->idx_trans_tbl.array_size);
3159
 
                        ret = FALSE;
3160
 
                        goto func_exit;
3161
 
                }
3162
 
 
3163
 
                share->idx_trans_tbl.array_size = mysql_num_index;
3164
 
        }
3165
 
 
3166
 
        /* For each index in the mysql key_info array, fetch its
3167
 
        corresponding InnoDB index pointer into index_mapping
3168
 
        array. */
3169
 
        for (ulint count = 0; count < mysql_num_index; count++) {
3170
 
 
3171
 
                /* Fetch index pointers into index_mapping according to mysql
3172
 
                index sequence */
3173
 
                index_mapping[count] = dict_table_get_index_on_name(
3174
 
                        ib_table, table->key_info[count].name);
3175
 
 
3176
 
                if (!index_mapping[count]) {
3177
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
3178
 
                                        "index dictionary.",
3179
 
                                        table->key_info[count].name);
3180
 
                        ret = FALSE;
3181
 
                        goto func_exit;
3182
 
                }
3183
 
 
3184
 
                /* Double check fetched index has the same
3185
 
                column info as those in mysql key_info. */
3186
 
                if (!innobase_match_index_columns(&table->key_info[count],
3187
 
                                                  index_mapping[count])) {
3188
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
3189
 
                                        "does not match that of MySQL.",
3190
 
                                        table->key_info[count].name);
3191
 
                        ret = FALSE;
3192
 
                        goto func_exit;
3193
 
                }
3194
 
        }
3195
 
 
3196
 
        /* Successfully built the translation table */
3197
 
        share->idx_trans_tbl.index_count = mysql_num_index;
3198
 
 
3199
 
func_exit:
3200
 
        if (!ret) {
3201
 
                /* Build translation table failed. */
3202
 
                free(index_mapping);
3203
 
 
3204
 
                share->idx_trans_tbl.array_size = 0;
3205
 
                share->idx_trans_tbl.index_count = 0;
3206
 
                index_mapping = NULL;
3207
 
        }
3208
 
 
3209
 
        share->idx_trans_tbl.index_mapping = index_mapping;
3210
 
 
3211
 
        mutex_exit(&dict_sys->mutex);
3212
 
 
3213
 
        return(ret);
3214
 
}
3215
 
 
3216
 
/*******************************************************************//**
3217
 
This function uses index translation table to quickly locate the
3218
 
requested index structure.
3219
 
Note we do not have mutex protection for the index translatoin table
3220
 
access, it is based on the assumption that there is no concurrent
3221
 
translation table rebuild (fter create/drop index) and DMLs that
3222
 
require index lookup.
3223
 
@return dict_index_t structure for requested index. NULL if
3224
 
fail to locate the index structure. */
3225
 
static
3226
 
dict_index_t*
3227
 
innobase_index_lookup(
3228
 
/*==================*/
3229
 
        INNOBASE_SHARE* share,  /*!< in: share structure for index
3230
 
                                translation table. */
3231
 
        uint            keynr)  /*!< in: index number for the requested
3232
 
                                index */
3233
 
{
3234
 
        if (!share->idx_trans_tbl.index_mapping
3235
 
            || keynr >= share->idx_trans_tbl.index_count) {
3236
 
                return(NULL);
3237
 
        }
3238
 
 
3239
 
        return(share->idx_trans_tbl.index_mapping[keynr]);
3240
 
}
3241
 
 
3242
 
/********************************************************************//**
3243
2861
Set the autoinc column max value. This should only be called once from
3244
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2862
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2863
@return DB_SUCCESS or error code */
3245
2864
UNIV_INTERN
3246
 
void
 
2865
ulint
3247
2866
ha_innobase::innobase_initialize_autoinc()
3248
2867
/*======================================*/
3249
2868
{
 
2869
  dict_index_t* index;
3250
2870
  uint64_t  auto_inc;
3251
 
  const Field*  field = getTable()->found_next_number_field;
3252
 
 
3253
 
  if (field != NULL) {
3254
 
    auto_inc = innobase_get_int_col_max_value(field);
3255
 
  } else {
3256
 
    /* We have no idea what's been passed in to us as the
3257
 
       autoinc column. We set it to the 0, effectively disabling
3258
 
       updates to the table. */
3259
 
    auto_inc = 0;
3260
 
 
 
2871
  const char* col_name;
 
2872
  ulint   error;
 
2873
 
 
2874
  col_name = table->found_next_number_field->field_name;
 
2875
  index = innobase_get_index(table->getShare()->next_number_index);
 
2876
 
 
2877
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2878
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2879
 
 
2880
  switch (error) {
 
2881
  case DB_SUCCESS:
 
2882
 
 
2883
    /* At the this stage we don't know the increment
 
2884
    or the offset, so use default inrement of 1. */
 
2885
    ++auto_inc;
 
2886
    break;
 
2887
 
 
2888
  case DB_RECORD_NOT_FOUND:
3261
2889
    ut_print_timestamp(stderr);
3262
 
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
3263
 
            "column name\n");
3264
 
  }
3265
 
 
3266
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3267
 
    /* If the recovery level is set so high that writes
3268
 
       are disabled we force the AUTOINC counter to 0
3269
 
       value effectively disabling writes to the table.
3270
 
       Secondly, we avoid reading the table in case the read
3271
 
       results in failure due to a corrupted table/index.
3272
 
 
3273
 
       We will not return an error to the client, so that the
3274
 
       tables can be dumped with minimal hassle.  If an error
3275
 
       were returned in this case, the first attempt to read
3276
 
       the table would fail and subsequent SELECTs would succeed. */
3277
 
    auto_inc = 0;
3278
 
  } else if (field == NULL) {
3279
 
    /* This is a far more serious error, best to avoid
3280
 
       opening the table and return failure. */
3281
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3282
 
  } else {
3283
 
    dict_index_t*       index;
3284
 
    const char* col_name;
3285
 
    uint64_t    read_auto_inc;
3286
 
    ulint               err;
3287
 
 
3288
 
    update_session(getTable()->in_use);
3289
 
    col_name = field->field_name;
3290
 
 
3291
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3292
 
 
3293
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3294
 
 
3295
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3296
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3297
 
 
3298
 
    switch (err) {
3299
 
    case DB_SUCCESS: {
3300
 
      uint64_t col_max_value;
3301
 
 
3302
 
      col_max_value = innobase_get_int_col_max_value(field);
3303
 
 
3304
 
      /* At the this stage we do not know the increment
3305
 
         nor the offset, so use a default increment of 1. */
3306
 
 
3307
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3308
 
 
3309
 
      break;
3310
 
    }
3311
 
    case DB_RECORD_NOT_FOUND:
3312
 
      ut_print_timestamp(stderr);
3313
 
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3314
 
              "dictionaries are out of sync.\n"
3315
 
              "InnoDB: Unable to find the AUTOINC column "
3316
 
              "%s in the InnoDB table %s.\n"
3317
 
              "InnoDB: We set the next AUTOINC column "
3318
 
              "value to 0,\n"
3319
 
              "InnoDB: in effect disabling the AUTOINC "
3320
 
              "next value generation.\n"
3321
 
              "InnoDB: You can either set the next "
3322
 
              "AUTOINC value explicitly using ALTER TABLE\n"
3323
 
              "InnoDB: or fix the data dictionary by "
3324
 
              "recreating the table.\n",
3325
 
              col_name, index->table->name);
3326
 
 
3327
 
      /* This will disable the AUTOINC generation. */
3328
 
      auto_inc = 0;
3329
 
 
3330
 
      /* We want the open to succeed, so that the user can
3331
 
         take corrective action. ie. reads should succeed but
3332
 
         updates should fail. */
3333
 
      err = DB_SUCCESS;
3334
 
      break;
3335
 
    default:
3336
 
      /* row_search_max_autoinc() should only return
3337
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3338
 
      ut_error;
3339
 
    }
 
2890
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2891
      "dictionaries are out of sync.\n"
 
2892
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2893
      "InnoDB table %s.\n"
 
2894
      "InnoDB: We set the next AUTOINC column value to the "
 
2895
      "maximum possible value,\n"
 
2896
      "InnoDB: in effect disabling the AUTOINC next value "
 
2897
      "generation.\n"
 
2898
      "InnoDB: You can either set the next AUTOINC value "
 
2899
      "explicitly using ALTER TABLE\n"
 
2900
      "InnoDB: or fix the data dictionary by recreating "
 
2901
      "the table.\n",
 
2902
      col_name, index->table->name);
 
2903
 
 
2904
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2905
    break;
 
2906
 
 
2907
  default:
 
2908
    return(error);
3340
2909
  }
3341
2910
 
3342
2911
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2912
 
 
2913
  return(DB_SUCCESS);
3343
2914
}
3344
2915
 
3345
2916
/*****************************************************************//**
3359
2930
  UT_NOT_USED(mode);
3360
2931
  UT_NOT_USED(test_if_locked);
3361
2932
 
3362
 
  session= getTable()->in_use;
 
2933
  session= table->in_use;
3363
2934
 
3364
2935
  /* Under some cases Drizzle seems to call this function while
3365
2936
  holding btr_search_latch. This breaks the latching order as
3383
2954
  stored the string length as the first byte. */
3384
2955
 
3385
2956
  upd_and_key_val_buff_len =
3386
 
        getTable()->getShare()->stored_rec_length
3387
 
        + getTable()->getShare()->max_key_length
 
2957
        table->getShare()->stored_rec_length
 
2958
        + table->getShare()->max_key_length
3388
2959
        + MAX_REF_PARTS * 3;
3389
2960
 
3390
2961
  upd_buff.resize(upd_and_key_val_buff_len);
3447
3018
 
3448
3019
  prebuilt = row_create_prebuilt(ib_table);
3449
3020
 
3450
 
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3451
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3021
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3022
  prebuilt->default_rec = table->getDefaultValues();
3452
3023
  ut_ad(prebuilt->default_rec);
3453
3024
 
3454
3025
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3455
3026
 
3456
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3027
  primary_key = table->getShare()->getPrimaryKey();
3457
3028
  key_used_on_scan = primary_key;
3458
3029
 
3459
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3460
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
3461
 
                    " Table %s failed", identifier.getPath().c_str());
3462
 
  }
3463
 
 
3464
3030
  /* Allocate a buffer for a 'row reference'. A row reference is
3465
3031
  a string of bytes of length ref_length which uniquely specifies
3466
3032
  a row in our table. Note that MySQL may also compare two row
3468
3034
  of length ref_length! */
3469
3035
 
3470
3036
  if (!row_table_got_default_clust_index(ib_table)) {
 
3037
    if (primary_key >= MAX_KEY) {
 
3038
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3039
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3040
    }
3471
3041
 
3472
3042
    prebuilt->clust_index_was_generated = FALSE;
3473
3043
 
3474
 
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3475
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3476
 
                    "InnoDB data dictionary, but not "
3477
 
                    "in MySQL!", identifier.getTableName().c_str());
3478
 
 
3479
 
      /* This mismatch could cause further problems
3480
 
         if not attended, bring this to the user's attention
3481
 
         by printing a warning in addition to log a message
3482
 
         in the errorlog */
3483
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3484
 
                          ER_NO_SUCH_INDEX,
3485
 
                          "InnoDB: Table %s has a "
3486
 
                          "primary key in InnoDB data "
3487
 
                          "dictionary, but not in "
3488
 
                          "MySQL!", identifier.getTableName().c_str());
3489
 
 
3490
 
      /* If primary_key >= MAX_KEY, its (primary_key)
3491
 
         value could be out of bound if continue to index
3492
 
         into key_info[] array. Find InnoDB primary index,
3493
 
         and assign its key_length to ref_length.
3494
 
         In addition, since MySQL indexes are sorted starting
3495
 
         with primary index, unique index etc., initialize
3496
 
         ref_length to the first index key length in
3497
 
         case we fail to find InnoDB cluster index.
3498
 
 
3499
 
         Please note, this will not resolve the primary
3500
 
         index mismatch problem, other side effects are
3501
 
         possible if users continue to use the table.
3502
 
         However, we allow this table to be opened so
3503
 
         that user can adopt necessary measures for the
3504
 
         mismatch while still being accessible to the table
3505
 
         date. */
3506
 
      ref_length = getTable()->key_info[0].key_length;
3507
 
 
3508
 
      /* Find correspoinding cluster index
3509
 
         key length in MySQL's key_info[] array */
3510
 
      for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3511
 
        dict_index_t*   index;
3512
 
        index = innobase_get_index(i);
3513
 
        if (dict_index_is_clust(index)) {
3514
 
          ref_length =
3515
 
            getTable()->key_info[i].key_length;
3516
 
        }
3517
 
      }
3518
 
    } else {
3519
 
      /* MySQL allocates the buffer for ref.
3520
 
         key_info->key_length includes space for all key
3521
 
         columns + one byte for each column that may be
3522
 
         NULL. ref_length must be as exact as possible to
3523
 
         save space, because all row reference buffers are
3524
 
         allocated based on ref_length. */
3525
 
 
3526
 
      ref_length = getTable()->key_info[primary_key].key_length;
3527
 
    }
 
3044
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3045
    includes space for all key columns + one byte for each column
 
3046
    that may be NULL. ref_length must be as exact as possible to
 
3047
    save space, because all row reference buffers are allocated
 
3048
    based on ref_length. */
 
3049
 
 
3050
    ref_length = table->key_info[primary_key].key_length;
3528
3051
  } else {
3529
3052
    if (primary_key != MAX_KEY) {
3530
 
      errmsg_printf(ERRMSG_LVL_ERROR,
3531
 
                    "Table %s has no primary key in InnoDB data "
3532
 
                    "dictionary, but has one in MySQL! If you "
3533
 
                    "created the table with a MySQL version < "
3534
 
                    "3.23.54 and did not define a primary key, "
3535
 
                    "but defined a unique key with all non-NULL "
3536
 
                    "columns, then MySQL internally treats that "
3537
 
                    "key as the primary key. You can fix this "
3538
 
                    "error by dump + DROP + CREATE + reimport "
3539
 
                    "of the table.", identifier.getTableName().c_str());
3540
 
 
3541
 
      /* This mismatch could cause further problems
3542
 
         if not attended, bring this to the user attention
3543
 
         by printing a warning in addition to log a message
3544
 
         in the errorlog */
3545
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3546
 
                          ER_NO_SUCH_INDEX,
3547
 
                          "InnoDB: Table %s has no "
3548
 
                          "primary key in InnoDB data "
3549
 
                          "dictionary, but has one in "
3550
 
                          "MySQL!", identifier.getTableName().c_str());
 
3053
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3054
          "dictionary, but has one in MySQL! If you "
 
3055
          "created the table with a MySQL version < "
 
3056
          "3.23.54 and did not define a primary key, "
 
3057
          "but defined a unique key with all non-NULL "
 
3058
          "columns, then MySQL internally treats that "
 
3059
          "key as the primary key. You can fix this "
 
3060
          "error by dump + DROP + CREATE + reimport "
 
3061
          "of the table.", identifier.getTableName().c_str());
3551
3062
    }
3552
3063
 
3553
3064
    prebuilt->clust_index_was_generated = TRUE;
3580
3091
    /* We update the highest file format in the system table
3581
3092
    space, if this table has higher file format setting. */
3582
3093
 
3583
 
    char changed_file_format_max[100];
3584
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3585
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
 
3094
    trx_sys_file_format_max_upgrade(
 
3095
      (const char**) &innobase_file_format_check,
3586
3096
      dict_table_get_format(prebuilt->table));
3587
 
    innobase_file_format_max= changed_file_format_max;
3588
3097
  }
3589
3098
 
 
3099
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3100
 
3590
3101
  /* Only if the table has an AUTOINC column. */
3591
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3102
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3103
    ulint error;
3592
3104
 
3593
3105
    dict_table_autoinc_lock(prebuilt->table);
3594
3106
 
3598
3110
    autoinc value from a previous Drizzle open. */
3599
3111
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3600
3112
 
3601
 
      innobase_initialize_autoinc();
 
3113
      error = innobase_initialize_autoinc();
 
3114
      ut_a(error == DB_SUCCESS);
3602
3115
    }
3603
3116
 
3604
3117
    dict_table_autoinc_unlock(prebuilt->table);
3605
3118
  }
3606
3119
 
3607
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3608
 
 
3609
3120
  return(0);
3610
3121
}
3611
3122
 
3626
3137
{
3627
3138
  Session*  session;
3628
3139
 
3629
 
  session= getTable()->in_use;
 
3140
  session= table->in_use;
3630
3141
  if (session != NULL) {
3631
3142
    getTransactionalEngine()->releaseTemporaryLatches(session);
3632
3143
  }
3853
3364
  case DRIZZLE_TYPE_DATETIME:
3854
3365
  case DRIZZLE_TYPE_DATE:
3855
3366
  case DRIZZLE_TYPE_TIMESTAMP:
3856
 
  case DRIZZLE_TYPE_ENUM:
3857
3367
    return(DATA_INT);
3858
3368
  case DRIZZLE_TYPE_DOUBLE:
3859
3369
    return(DATA_DOUBLE);
3860
3370
  case DRIZZLE_TYPE_BLOB:
3861
 
    return(DATA_BLOB);
3862
 
  case DRIZZLE_TYPE_UUID:
3863
 
    return(DATA_FIXBINARY);
3864
 
  case DRIZZLE_TYPE_NULL:
 
3371
                return(DATA_BLOB);
 
3372
  default:
3865
3373
    ut_error;
3866
3374
  }
3867
3375
 
3910
3418
  uint    buff_len,/*!< in: buffer length */
3911
3419
  const unsigned char*  record)/*!< in: row in MySQL format */
3912
3420
{
3913
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3421
  KeyInfo*    key_info  = &table->key_info[keynr];
3914
3422
  KeyPartInfo*  key_part  = key_info->key_part;
3915
3423
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3916
3424
  char*   buff_start  = buff;
3986
3494
 
3987
3495
      data = row_mysql_read_true_varchar(&len,
3988
3496
        (byte*) (record
3989
 
        + (ulint)get_field_offset(getTable(), field)),
 
3497
        + (ulint)get_field_offset(table, field)),
3990
3498
        lenlen);
3991
3499
 
3992
3500
      true_len = len;
4049
3557
 
4050
3558
      blob_data = row_mysql_read_blob_ref(&blob_len,
4051
3559
        (byte*) (record
4052
 
        + (ulint)get_field_offset(getTable(), field)),
 
3560
        + (ulint)get_field_offset(table, field)),
4053
3561
          (ulint) field->pack_length());
4054
3562
 
4055
3563
      true_len = blob_len;
4056
3564
 
4057
 
      ut_a(get_field_offset(getTable(), field)
 
3565
      ut_a(get_field_offset(table, field)
4058
3566
        == key_part->offset);
4059
3567
 
4060
3568
      /* For multi byte character sets we need to calculate
4101
3609
      ulint     key_len;
4102
3610
      const unsigned char*    src_start;
4103
3611
      enum_field_types  real_type;
4104
 
      const CHARSET_INFO* cs= field->charset();
4105
3612
 
4106
3613
      key_len = key_part->length;
4107
3614
 
4123
3630
      memcpy(buff, src_start, true_len);
4124
3631
      buff += true_len;
4125
3632
 
4126
 
      /* Pad the unused space with spaces. */
 
3633
      /* Pad the unused space with spaces. Note that no
 
3634
      padding is ever needed for UCS-2 because in MySQL,
 
3635
      all UCS2 characters are 2 bytes, as MySQL does not
 
3636
      support surrogate pairs, which are needed to represent
 
3637
      characters in the range U+10000 to U+10FFFF. */
4127
3638
 
4128
3639
      if (true_len < key_len) {
4129
 
        ulint   pad_len = key_len - true_len;
4130
 
        ut_a(!(pad_len % cs->mbminlen));
4131
 
 
4132
 
        cs->cset->fill(cs, buff, pad_len,
4133
 
                       0x20 /* space */);
 
3640
        ulint pad_len = key_len - true_len;
 
3641
        memset(buff, ' ', pad_len);
4134
3642
        buff += pad_len;
4135
3643
      }
4136
3644
    }
4238
3746
 
4239
3747
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4240
3748
  'fields'. */
4241
 
  for (i = 0; i < n_fields; i++)
 
3749
  for (i = 0; i < n_fields; i++) 
4242
3750
  {
4243
 
    const dict_col_t *col= &index->table->cols[i];
4244
3751
    templ = prebuilt->mysql_template + n_requested_fields;
4245
3752
    field = table->getField(i);
4246
3753
 
4288
3795
    templ->col_no = i;
4289
3796
 
4290
3797
    if (index == clust_index) {
4291
 
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
 
3798
      templ->rec_field_no = dict_col_get_clust_pos(
 
3799
        &index->table->cols[i], index);
4292
3800
    } else {
4293
3801
      templ->rec_field_no = dict_index_get_nth_col_pos(
4294
3802
                index, i);
4317
3825
      mysql_prefix_len = templ->mysql_col_offset
4318
3826
        + templ->mysql_col_len;
4319
3827
    }
4320
 
    templ->type = col->mtype;
 
3828
    templ->type = index->table->cols[i].mtype;
4321
3829
    templ->mysql_type = (ulint)field->type();
4322
3830
 
4323
3831
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4325
3833
        (((Field_varstring*)field)->pack_length_no_ptr());
4326
3834
    }
4327
3835
 
4328
 
    templ->charset = dtype_get_charset_coll(col->prtype);
4329
 
    templ->mbminlen = dict_col_get_mbminlen(col);
4330
 
    templ->mbmaxlen = dict_col_get_mbmaxlen(col);
4331
 
    templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 
3836
    templ->charset = dtype_get_charset_coll(
 
3837
      index->table->cols[i].prtype);
 
3838
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3839
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3840
    templ->is_unsigned = index->table->cols[i].prtype
 
3841
              & DATA_UNSIGNED;
4332
3842
    if (templ->type == DATA_BLOB) {
4333
3843
      prebuilt->templ_contains_blob = TRUE;
4334
3844
    }
4353
3863
}
4354
3864
 
4355
3865
/********************************************************************//**
 
3866
Get the upper limit of the MySQL integral and floating-point type. */
 
3867
UNIV_INTERN
 
3868
uint64_t
 
3869
ha_innobase::innobase_get_int_col_max_value(
 
3870
/*========================================*/
 
3871
  const Field*  field)
 
3872
{
 
3873
  uint64_t  max_value = 0;
 
3874
 
 
3875
  switch(field->key_type()) {
 
3876
  /* TINY */
 
3877
  case HA_KEYTYPE_BINARY:
 
3878
    max_value = 0xFFULL;
 
3879
    break;
 
3880
  /* LONG */
 
3881
  case HA_KEYTYPE_ULONG_INT:
 
3882
    max_value = 0xFFFFFFFFULL;
 
3883
    break;
 
3884
  case HA_KEYTYPE_LONG_INT:
 
3885
    max_value = 0x7FFFFFFFULL;
 
3886
    break;
 
3887
  /* BIG */
 
3888
  case HA_KEYTYPE_ULONGLONG:
 
3889
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3890
    break;
 
3891
  case HA_KEYTYPE_LONGLONG:
 
3892
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3893
    break;
 
3894
  case HA_KEYTYPE_DOUBLE:
 
3895
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3896
    max_value = 0x20000000000000ULL;
 
3897
    break;
 
3898
  default:
 
3899
    ut_error;
 
3900
  }
 
3901
 
 
3902
  return(max_value);
 
3903
}
 
3904
 
 
3905
/********************************************************************//**
4356
3906
This special handling is really to overcome the limitations of MySQL's
4357
3907
binlogging. We need to eliminate the non-determinism that will arise in
4358
3908
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4503
4053
  num_write_row++;
4504
4054
 
4505
4055
  /* This is the case where the table has an auto-increment column */
4506
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4056
  if (table->next_number_field && record == table->getInsertRecord()) {
4507
4057
 
4508
4058
    /* Reset the error code before calling
4509
4059
    innobase_get_auto_increment(). */
4510
4060
    prebuilt->autoinc_error = DB_SUCCESS;
4511
4061
 
4512
4062
    if ((error = update_auto_increment())) {
 
4063
 
4513
4064
      /* We don't want to mask autoinc overflow errors. */
4514
 
 
4515
 
      /* Handle the case where the AUTOINC sub-system
4516
 
         failed during initialization. */
4517
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4518
 
        error_result = ER_AUTOINC_READ_FAILED;
4519
 
        /* Set the error message to report too. */
4520
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4521
 
        goto func_exit;
4522
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4065
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4523
4066
        error = (int) prebuilt->autoinc_error;
4524
4067
 
4525
4068
        goto report_error;
4539
4082
    /* Build the template used in converting quickly between
4540
4083
    the two database formats */
4541
4084
 
4542
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4085
    build_template(prebuilt, NULL, table,
 
4086
             ROW_MYSQL_WHOLE_ROW);
4543
4087
  }
4544
4088
 
4545
4089
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4546
4090
 
4547
4091
  error = row_insert_for_mysql((byte*) record, prebuilt);
4548
4092
 
4549
 
  user_session->setXaId(trx->id);
4550
 
 
4551
4093
  /* Handle duplicate key errors */
4552
4094
  if (auto_inc_used) {
4553
4095
    ulint   err;
4565
4107
    /* We need the upper limit of the col type to check for
4566
4108
    whether we update the table autoinc counter or not. */
4567
4109
    col_max_value = innobase_get_int_col_max_value(
4568
 
      getTable()->next_number_field); 
 
4110
      table->next_number_field);
 
4111
 
4569
4112
    /* Get the value that MySQL attempted to store in the table.*/
4570
 
    auto_inc = getTable()->next_number_field->val_int();
 
4113
    auto_inc = table->next_number_field->val_int();
4571
4114
 
4572
4115
    switch (error) {
4573
4116
    case DB_DUPLICATE_KEY:
4603
4146
      update the table upper limit. Note: last_value
4604
4147
      will be 0 if get_auto_increment() was not called.*/
4605
4148
 
4606
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4149
      if (auto_inc <= col_max_value
 
4150
          && auto_inc >= prebuilt->autoinc_last_value) {
4607
4151
set_max_autoinc:
4608
 
        /* This should filter out the negative
4609
 
           values set explicitly by the user. */
4610
 
        if (auto_inc <= col_max_value) {
4611
 
          ut_a(prebuilt->autoinc_increment > 0);
4612
 
 
4613
 
          uint64_t      need;
4614
 
          uint64_t      offset;
4615
 
 
4616
 
          offset = prebuilt->autoinc_offset;
4617
 
          need = prebuilt->autoinc_increment;
4618
 
 
4619
 
          auto_inc = innobase_next_autoinc(
4620
 
                                           auto_inc,
4621
 
                                           need, offset, col_max_value);
4622
 
 
4623
 
          err = innobase_set_max_autoinc(
4624
 
                                         auto_inc);
4625
 
 
4626
 
          if (err != DB_SUCCESS) {
4627
 
            error = err;
4628
 
          }
 
4152
        ut_a(prebuilt->autoinc_increment > 0);
 
4153
 
 
4154
        uint64_t  need;
 
4155
        uint64_t  offset;
 
4156
 
 
4157
        offset = prebuilt->autoinc_offset;
 
4158
        need = prebuilt->autoinc_increment;
 
4159
 
 
4160
        auto_inc = innobase_next_autoinc(
 
4161
          auto_inc, need, offset, col_max_value);
 
4162
 
 
4163
        err = innobase_set_max_autoinc(auto_inc);
 
4164
 
 
4165
        if (err != DB_SUCCESS) {
 
4166
          error = err;
4629
4167
        }
4630
4168
      }
4631
4169
      break;
4822
4360
  /* Build an update vector from the modified fields in the rows
4823
4361
  (uses upd_buff of the handle) */
4824
4362
 
4825
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4363
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4826
4364
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4827
4365
      prebuilt, user_session);
4828
4366
 
4831
4369
 
4832
4370
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4833
4371
 
4834
 
  if (getTable()->found_next_number_field)
 
4372
  if (table->found_next_number_field)
4835
4373
  {
4836
4374
    uint64_t  auto_inc;
4837
4375
    uint64_t  col_max_value;
4838
4376
 
4839
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4377
    auto_inc = table->found_next_number_field->val_int();
4840
4378
 
4841
4379
    /* We need the upper limit of the col type to check for
4842
4380
    whether we update the table autoinc counter or not. */
4843
4381
    col_max_value = innobase_get_int_col_max_value(
4844
 
      getTable()->found_next_number_field);
 
4382
      table->found_next_number_field);
4845
4383
 
4846
4384
    uint64_t current_autoinc;
4847
4385
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4869
4407
 
4870
4408
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4871
4409
 
4872
 
  user_session->setXaId(trx->id);
4873
 
 
4874
4410
  /* We need to do some special AUTOINC handling for the following case:
4875
4411
 
4876
4412
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4880
4416
  value used in the INSERT statement.*/
4881
4417
 
4882
4418
  if (error == DB_SUCCESS
4883
 
      && getTable()->next_number_field
4884
 
      && new_row == getTable()->getInsertRecord()
 
4419
      && table->next_number_field
 
4420
      && new_row == table->getInsertRecord()
4885
4421
      && session_sql_command(user_session) == SQLCOM_INSERT
4886
4422
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4887
4423
    == TRX_DUP_IGNORE)  {
4889
4425
    uint64_t  auto_inc;
4890
4426
    uint64_t  col_max_value;
4891
4427
 
4892
 
    auto_inc = getTable()->next_number_field->val_int();
 
4428
    auto_inc = table->next_number_field->val_int();
4893
4429
 
4894
4430
    /* We need the upper limit of the col type to check for
4895
4431
    whether we update the table autoinc counter or not. */
4896
4432
    col_max_value = innobase_get_int_col_max_value(
4897
 
      getTable()->next_number_field);
 
4433
      table->next_number_field);
4898
4434
 
4899
4435
    if (auto_inc <= col_max_value && auto_inc != 0) {
4900
4436
 
4961
4497
 
4962
4498
  error = row_update_for_mysql((byte*) record, prebuilt);
4963
4499
 
4964
 
  user_session->setXaId(trx->id);
4965
 
 
4966
4500
  innodb_srv_conc_exit_innodb(trx);
4967
4501
 
4968
4502
  error = convert_error_code_to_mysql(
4996
4530
  case ROW_READ_WITH_LOCKS:
4997
4531
    if (!srv_locks_unsafe_for_binlog
4998
4532
        && prebuilt->trx->isolation_level
4999
 
        > TRX_ISO_READ_COMMITTED) {
 
4533
        != TRX_ISO_READ_COMMITTED) {
5000
4534
      break;
5001
4535
    }
5002
4536
    /* fall through */
5026
4560
ha_innobase::try_semi_consistent_read(bool yes)
5027
4561
/*===========================================*/
5028
4562
{
5029
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4563
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5030
4564
 
5031
4565
  /* Row read type is set to semi consistent read if this was
5032
4566
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
5035
4569
 
5036
4570
  if (yes
5037
4571
      && (srv_locks_unsafe_for_binlog
5038
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4572
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
5039
4573
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
5040
4574
  } else {
5041
4575
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5216
4750
 
5217
4751
  index = prebuilt->index;
5218
4752
 
5219
 
  if (UNIV_UNLIKELY(index == NULL)) {
5220
 
    prebuilt->index_usable = FALSE;
5221
 
    return(HA_ERR_CRASHED);
5222
 
  }
5223
 
 
5224
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5225
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5226
 
  }
5227
 
 
5228
4753
  /* Note that if the index for which the search template is built is not
5229
4754
  necessarily prebuilt->index, but can also be the clustered index */
5230
4755
 
5231
4756
  if (prebuilt->sql_stat_start) {
5232
 
    build_template(prebuilt, user_session, getTable(),
 
4757
    build_template(prebuilt, user_session, table,
5233
4758
             ROW_MYSQL_REC_FIELDS);
5234
4759
  }
5235
4760
 
5284
4809
  switch (ret) {
5285
4810
  case DB_SUCCESS:
5286
4811
    error = 0;
5287
 
    getTable()->status = 0;
 
4812
    table->status = 0;
5288
4813
    break;
5289
4814
  case DB_RECORD_NOT_FOUND:
5290
4815
    error = HA_ERR_KEY_NOT_FOUND;
5291
 
    getTable()->status = STATUS_NOT_FOUND;
 
4816
    table->status = STATUS_NOT_FOUND;
5292
4817
    break;
5293
4818
  case DB_END_OF_INDEX:
5294
4819
    error = HA_ERR_KEY_NOT_FOUND;
5295
 
    getTable()->status = STATUS_NOT_FOUND;
 
4820
    table->status = STATUS_NOT_FOUND;
5296
4821
    break;
5297
4822
  default:
5298
4823
    error = convert_error_code_to_mysql((int) ret,
5299
4824
                prebuilt->table->flags,
5300
4825
                user_session);
5301
 
    getTable()->status = STATUS_NOT_FOUND;
 
4826
    table->status = STATUS_NOT_FOUND;
5302
4827
    break;
5303
4828
  }
5304
4829
 
5337
4862
 
5338
4863
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5339
4864
 
5340
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4865
  ut_ad(user_session == table->in_use);
 
4866
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4867
 
 
4868
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5341
4869
  {
5342
 
    KeyInfo *key = getTable()->key_info + keynr;
5343
 
    index = innobase_index_lookup(share, keynr);
5344
 
 
5345
 
    if (index) {
5346
 
      ut_a(ut_strcmp(index->name, key->name) == 0);
5347
 
    } else {
5348
 
      /* Can't find index with keynr in the translation
5349
 
         table. Only print message if the index translation
5350
 
         table exists */
5351
 
      if (share->idx_trans_tbl.index_mapping) {
5352
 
        errmsg_printf(ERRMSG_LVL_ERROR,
5353
 
                      "InnoDB could not find "
5354
 
                      "index %s key no %u for "
5355
 
                      "table %s through its "
5356
 
                      "index translation table",
5357
 
                      key ? key->name : "NULL",
5358
 
                      keynr,
5359
 
                      prebuilt->table->name);
5360
 
      }
5361
 
 
5362
 
      index = dict_table_get_index_on_name(prebuilt->table,
5363
 
                                           key->name);
5364
 
    }
 
4870
    index = dict_table_get_index_on_name(prebuilt->table,
 
4871
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5365
4872
  } else {
5366
4873
    index = dict_table_get_first_index(prebuilt->table);
5367
4874
  }
5370
4877
    errmsg_printf(ERRMSG_LVL_ERROR, 
5371
4878
      "Innodb could not find key n:o %u with name %s "
5372
4879
      "from dict cache for table %s",
5373
 
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
 
4880
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5374
4881
      prebuilt->table->name);
5375
4882
  }
5376
4883
 
5398
4905
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5399
4906
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5400
4907
          keynr);
5401
 
    prebuilt->index_usable = FALSE;
5402
4908
    return(1);
5403
4909
  }
5404
4910
 
5406
4912
                 prebuilt->index);
5407
4913
 
5408
4914
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5409
 
    push_warning_printf(user_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5410
 
                        HA_ERR_TABLE_DEF_CHANGED,
5411
 
                        "InnoDB: insufficient history for index %u",
5412
 
                        keynr);
 
4915
    errmsg_printf(ERRMSG_LVL_WARN,
 
4916
         "InnoDB: insufficient history for index %u",
 
4917
          keynr);
5413
4918
    /* The caller seems to ignore this.  Thus, we must check
5414
4919
    this again in row_search_for_mysql(). */
5415
4920
    return(2);
5428
4933
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5429
4934
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5430
4935
 
5431
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
4936
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5432
4937
 
5433
4938
  return(0);
5434
4939
}
5488
4993
  switch (ret) {
5489
4994
  case DB_SUCCESS:
5490
4995
    error = 0;
5491
 
    getTable()->status = 0;
 
4996
    table->status = 0;
5492
4997
    break;
5493
4998
  case DB_RECORD_NOT_FOUND:
5494
4999
    error = HA_ERR_END_OF_FILE;
5495
 
    getTable()->status = STATUS_NOT_FOUND;
 
5000
    table->status = STATUS_NOT_FOUND;
5496
5001
    break;
5497
5002
  case DB_END_OF_INDEX:
5498
5003
    error = HA_ERR_END_OF_FILE;
5499
 
    getTable()->status = STATUS_NOT_FOUND;
 
5004
    table->status = STATUS_NOT_FOUND;
5500
5005
    break;
5501
5006
  default:
5502
5007
    error = convert_error_code_to_mysql(
5503
5008
      (int) ret, prebuilt->table->flags, user_session);
5504
 
    getTable()->status = STATUS_NOT_FOUND;
 
5009
    table->status = STATUS_NOT_FOUND;
5505
5010
    break;
5506
5011
  }
5507
5012
 
5696
5201
 
5697
5202
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5698
5203
 
5699
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5204
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5700
5205
 
5701
5206
  if (prebuilt->clust_index_was_generated) {
5702
5207
    /* No primary key was defined for the table and we
5742
5247
{
5743
5248
  uint    len;
5744
5249
 
5745
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5250
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5746
5251
 
5747
5252
  if (prebuilt->clust_index_was_generated) {
5748
5253
    /* No primary key was defined for the table and we
5818
5323
 
5819
5324
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5820
5325
                  field);
5821
 
 
5822
 
    if (!col_type) {
5823
 
      push_warning_printf(
5824
 
                          (Session*) trx->mysql_thd,
5825
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5826
 
                          ER_CANT_CREATE_TABLE,
5827
 
                          "Error creating table '%s' with "
5828
 
                          "column '%s'. Please check its "
5829
 
                          "column type and try to re-create "
5830
 
                          "the table with an appropriate "
5831
 
                          "column type.",
5832
 
                          table->name, (char*) field->field_name);
5833
 
      goto err_col;
5834
 
    }
5835
 
 
5836
5326
    if (field->null_ptr) {
5837
5327
      nulls_allowed = 0;
5838
5328
    } else {
5885
5375
      }
5886
5376
    }
5887
5377
 
5888
 
    /* First check whether the column to be added has a
5889
 
       system reserved name. */
5890
 
    if (dict_col_name_is_reserved(field->field_name)){
5891
 
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5892
 
 
5893
 
  err_col:
5894
 
      dict_mem_table_free(table);
5895
 
      trx_commit_for_mysql(trx);
5896
 
 
5897
 
      error = DB_ERROR;
5898
 
      goto error_ret;
5899
 
    }
5900
 
 
5901
5378
    dict_mem_table_add_col(table, table->heap,
5902
5379
      (char*) field->field_name,
5903
5380
      col_type,
5911
5388
 
5912
5389
  error = row_create_table_for_mysql(table, trx);
5913
5390
 
5914
 
        if (error == DB_DUPLICATE_KEY) {
5915
 
                char buf[100];
5916
 
                char* buf_end = innobase_convert_identifier(
5917
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5918
 
                        trx->mysql_thd, TRUE);
5919
 
 
5920
 
                *buf_end = '\0';
5921
 
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5922
 
        }
5923
 
 
5924
 
error_ret:
5925
5391
  error = convert_error_code_to_mysql(error, flags, NULL);
5926
5392
 
5927
5393
  return(error);
5958
5424
 
5959
5425
  n_fields = key->key_parts;
5960
5426
 
5961
 
  /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
5962
 
  ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
5963
 
 
5964
5427
  ind_type = 0;
5965
5428
 
5966
5429
  if (key_num == form->getShare()->getPrimaryKey()) {
6070
5533
  /* We pass 0 as the space id, and determine at a lower level the space
6071
5534
  id where to store the table */
6072
5535
 
6073
 
  index = dict_mem_index_create(table_name,
6074
 
                                innobase_index_reserve_name,
6075
 
                                0, DICT_CLUSTERED, 0);
 
5536
  index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
 
5537
              0, DICT_CLUSTERED, 0);
6076
5538
 
6077
5539
  error = row_create_index_for_mysql(index, trx, NULL);
6078
5540
 
6138
5600
    modified by another thread while the table is being created. */
6139
5601
  const ulint file_format = srv_file_format;
6140
5602
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6141
 
  const char* stmt;
6142
 
  size_t stmt_len;
6143
5603
 
6144
5604
  const char *table_name= identifier.getPath().c_str();
6145
5605
 
6232
5692
# error "DICT_TF_ZSSIZE_MAX < 1"
6233
5693
#endif
6234
5694
 
6235
 
    if (strict_mode)
 
5695
    if (SessionVAR(&session, strict_mode))
6236
5696
    {
6237
5697
      if (! srv_file_per_table)
6238
5698
      {
6251
5711
                            "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6252
5712
      }
6253
5713
    }
 
5714
 
 
5715
    error= create_table_def(trx, &form, norm_name,
 
5716
                            lex_identified_temp_table ? name2 : NULL,
 
5717
                            iflags);
 
5718
  }
 
5719
 
 
5720
  if (error) {
 
5721
    goto cleanup;
6254
5722
  }
6255
5723
 
6256
5724
  /* Look for a primary key */
6259
5727
                   (int) form.getShare()->getPrimaryKey() :
6260
5728
                   -1);
6261
5729
 
6262
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5730
  /* Our function row_get_mysql_key_number_for_index assumes
6263
5731
    the primary key is always number 0, if it exists */
6264
5732
 
6265
5733
  assert(primary_key_no == -1 || primary_key_no == 0);
6266
5734
 
6267
 
  /* Check for name conflicts (with reserved name) for
6268
 
     any user indices to be created. */
6269
 
  if (innobase_index_name_is_reserved(trx, form.key_info,
6270
 
                                      form.getShare()->keys)) {
6271
 
    error = -1;
6272
 
    goto cleanup;
6273
 
  }
6274
 
 
6275
 
  if (lex_identified_temp_table)
6276
 
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6277
 
 
6278
 
  error= create_table_def(trx, &form, norm_name,
6279
 
                          lex_identified_temp_table ? name2 : NULL,
6280
 
                          iflags);
6281
 
 
6282
 
  session.setXaId(trx->id);
6283
 
 
6284
 
  if (error) {
6285
 
    goto cleanup;
6286
 
  }
6287
 
 
6288
5735
  /* Create the keys */
6289
5736
 
6290
5737
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6316
5763
    }
6317
5764
  }
6318
5765
 
6319
 
  stmt = innobase_get_stmt(&session, &stmt_len);
6320
 
 
6321
 
  if (stmt) {
 
5766
  if (trx->mysql_query_str) {
6322
5767
    string generated_create_table;
6323
 
    const char *query= stmt;
 
5768
    const char *query= trx->mysql_query_str;
6324
5769
 
6325
5770
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6326
5771
    {
6331
5776
    }
6332
5777
 
6333
5778
    error = row_table_add_foreign_constraints(trx,
6334
 
                                              query, strlen(query),
 
5779
                                              query,
6335
5780
                                              norm_name,
6336
5781
                                              lex_identified_temp_table);
6337
5782
 
6360
5805
    /* We update the highest file format in the system table
6361
5806
      space, if this table has higher file format setting. */
6362
5807
 
6363
 
    char changed_file_format_max[100];
6364
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6365
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
6366
 
      dict_table_get_format(innobase_table));
6367
 
    innobase_file_format_max= changed_file_format_max;
 
5808
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5809
                                    dict_table_get_format(innobase_table));
6368
5810
  }
6369
5811
 
6370
5812
  /* Note: We can't call update_session() as prebuilt will not be
6371
5813
    setup at this stage and so we use session. */
6372
5814
 
6373
5815
  /* We need to copy the AUTOINC value from the old table if
6374
 
    this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
6375
 
    does a table copy too. */
 
5816
    this is an ALTER TABLE. */
6376
5817
 
6377
5818
  if ((create_proto.options().has_auto_increment_value()
6378
 
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
6379
 
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
 
5819
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
6380
5820
      && create_proto.options().auto_increment_value() != 0) {
6381
5821
 
6382
 
    /* Query was one of :
6383
 
       CREATE TABLE ...AUTO_INCREMENT = x; or
6384
 
       ALTER TABLE...AUTO_INCREMENT = x;   or
6385
 
       CREATE INDEX x on t(...);
6386
 
       Find out a table definition from the dictionary and get
6387
 
       the current value of the auto increment field. Set a new
6388
 
       value to the auto increment field if the value is greater
6389
 
       than the maximum value in the column. */
 
5822
    /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 
5823
      CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
 
5824
      definition from the dictionary and get the current value
 
5825
      of the auto increment field. Set a new value to the
 
5826
      auto increment field if the value is greater than the
 
5827
      maximum value in the column. */
6390
5828
 
6391
5829
    auto_inc_value = create_proto.options().auto_increment_value();
6392
5830
 
6404
5842
 
6405
5843
  if (lex_identified_temp_table)
6406
5844
  {
6407
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5845
    session.storeTableMessage(identifier, create_proto);
6408
5846
  }
6409
5847
  else
6410
5848
  {
6438
5876
 
6439
5877
  ut_a(prebuilt->trx);
6440
5878
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6441
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5879
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6442
5880
 
6443
5881
  dict_table = prebuilt->table;
6444
5882
  trx = prebuilt->trx;
6467
5905
  /* Get the transaction associated with the current session, or create one
6468
5906
  if not yet created, and update prebuilt->trx */
6469
5907
 
6470
 
  update_session(getTable()->in_use);
 
5908
  update_session(table->in_use);
6471
5909
 
6472
5910
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6473
5911
  fallback:
6536
5974
                                   session_sql_command(&session)
6537
5975
                                   == SQLCOM_DROP_DB);
6538
5976
 
6539
 
  session.setXaId(trx->id);
6540
 
 
6541
5977
  /* Flush the log to reduce probability that the .frm files and
6542
5978
    the InnoDB data dictionary get out-of-sync if the user runs
6543
5979
    with innodb_flush_log_at_trx_commit = 0 */
6560
5996
  {
6561
5997
    if (identifier.getType() == message::Table::TEMPORARY)
6562
5998
    {
6563
 
      session.getMessageCache().removeTableMessage(identifier);
 
5999
      session.removeTableMessage(identifier);
6564
6000
      ulint sql_command = session_sql_command(&session);
6565
6001
 
6566
6002
      // If this was the final removal to an alter table then we will need
6653
6089
  trx = trx_allocate_for_mysql();
6654
6090
 
6655
6091
  trx->mysql_thd = NULL;
 
6092
  trx->mysql_query_str = NULL;
6656
6093
 
6657
6094
  trx->check_foreigns = false;
6658
6095
  trx->check_unique_secondary = false;
6736
6173
  // definition needs to be updated.
6737
6174
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6738
6175
  {
6739
 
    session.getMessageCache().renameTableMessage(from, to);
 
6176
    session.renameTableMessage(from, to);
6740
6177
    return 0;
6741
6178
  }
6742
6179
 
6758
6195
 
6759
6196
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6760
6197
 
6761
 
  session.setXaId(trx->id);
6762
 
 
6763
6198
  /* Tell the InnoDB server that there might be work for
6764
6199
    utility threads: */
6765
6200
 
6768
6203
  innobase_commit_low(trx);
6769
6204
  trx_free_for_mysql(trx);
6770
6205
 
6771
 
  /* Add a special case to handle the Duplicated Key error
6772
 
     and return DB_ERROR instead.
6773
 
     This is to avoid a possible SIGSEGV error from mysql error
6774
 
     handling code. Currently, mysql handles the Duplicated Key
6775
 
     error by re-entering the storage layer and getting dup key
6776
 
     info by calling get_dup_key(). This operation requires a valid
6777
 
     table handle ('row_prebuilt_t' structure) which could no
6778
 
     longer be available in the error handling stage. The suggested
6779
 
     solution is to report a 'table exists' error message (since
6780
 
     the dup key error here is due to an existing table whose name
6781
 
     is the one we are trying to rename to) and return the generic
6782
 
     error code. */
6783
 
  if (error == (int) DB_DUPLICATE_KEY) {
6784
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6785
 
    error = DB_ERROR;
6786
 
  }
6787
 
 
6788
6206
  error = convert_error_code_to_mysql(error, 0, NULL);
6789
6207
 
6790
6208
  if (not error)
6812
6230
  KeyInfo*    key;
6813
6231
  dict_index_t* index;
6814
6232
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6815
 
              getTable()->getShare()->stored_rec_length
6816
 
          + getTable()->getShare()->max_key_length + 100);
6817
 
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6818
 
          + getTable()->getShare()->max_key_length + 100;
 
6233
              table->getShare()->stored_rec_length
 
6234
          + table->getShare()->max_key_length + 100);
 
6235
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6236
          + table->getShare()->max_key_length + 100;
6819
6237
  dtuple_t* range_start;
6820
6238
  dtuple_t* range_end;
6821
6239
  ib_int64_t  n_rows;
6823
6241
  ulint   mode2;
6824
6242
  mem_heap_t* heap;
6825
6243
 
6826
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6244
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6827
6245
 
6828
6246
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6829
6247
 
6834
6252
 
6835
6253
  active_index = keynr;
6836
6254
 
6837
 
  key = &getTable()->key_info[active_index];
6838
 
 
6839
 
  index = innobase_get_index(keynr);
6840
 
 
6841
 
  /* There exists possibility of not being able to find requested
6842
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6843
 
     Necessary message should have been printed in innobase_get_index() */
6844
 
  if (UNIV_UNLIKELY(!index)) {
6845
 
    n_rows = HA_POS_ERROR;
6846
 
    goto func_exit;
6847
 
  }
6848
 
 
6849
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6850
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6851
 
    goto func_exit;
6852
 
  }
 
6255
  key = &table->key_info[active_index];
 
6256
 
 
6257
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6258
 
 
6259
  /* MySQL knows about this index and so we must be able to find it.*/
 
6260
  ut_a(index);
6853
6261
 
6854
6262
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6855
6263
            + sizeof(dtuple_t)));
6894
6302
 
6895
6303
  mem_heap_free(heap);
6896
6304
 
6897
 
func_exit:
6898
6305
  free(key_val_buff2);
6899
6306
 
6900
6307
  prebuilt->trx->op_info = (char*)"";
6929
6336
  external_lock(). To be safe, update the session of the current table
6930
6337
  handle. */
6931
6338
 
6932
 
  update_session(getTable()->in_use);
 
6339
  update_session(table->in_use);
6933
6340
 
6934
6341
  prebuilt->trx->op_info = (char*)
6935
6342
         "calculating upper bound for table rows";
6993
6400
  ha_rows total_rows;
6994
6401
  double  time_for_scan;
6995
6402
 
6996
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6403
  if (index != table->getShare()->getPrimaryKey()) {
6997
6404
    /* Not clustered */
6998
6405
    return(Cursor::read_time(index, ranges, rows));
6999
6406
  }
7017
6424
}
7018
6425
 
7019
6426
/*********************************************************************//**
7020
 
Calculates the key number used inside MySQL for an Innobase index. We will
7021
 
first check the "index translation table" for a match of the index to get
7022
 
the index number. If there does not exist an "index translation table",
7023
 
or not able to find the index in the translation table, then we will fall back
7024
 
to the traditional way of looping through dict_index_t list to find a
7025
 
match. In this case, we have to take into account if we generated a
7026
 
default clustered index for the table
7027
 
@return the key number used inside MySQL */
7028
 
static
7029
 
unsigned int
7030
 
innobase_get_mysql_key_number_for_index(
7031
 
/*====================================*/
7032
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
7033
 
                                        translation table. */
7034
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
7035
 
                                        dictionary */
7036
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
7037
 
                                        dictionary */
7038
 
        const dict_index_t*     index)  /*!< in: index */
7039
 
{
7040
 
        const dict_index_t*     ind;
7041
 
        unsigned int            i;
7042
 
 
7043
 
        ut_ad(index);
7044
 
        ut_ad(ib_table);
7045
 
        ut_ad(table);
7046
 
        ut_ad(share);
7047
 
 
7048
 
        /* If index does not belong to the table of share structure. Search
7049
 
        index->table instead */
7050
 
        if (index->table != ib_table) {
7051
 
                i = 0;
7052
 
                ind = dict_table_get_first_index(index->table);
7053
 
 
7054
 
                while (index != ind) {
7055
 
                        ind = dict_table_get_next_index(ind);
7056
 
                        i++;
7057
 
                }
7058
 
 
7059
 
                if (row_table_got_default_clust_index(index->table)) {
7060
 
                        ut_a(i > 0);
7061
 
                        i--;
7062
 
                }
7063
 
 
7064
 
                return(i);
7065
 
        }
7066
 
 
7067
 
        /* If index does not belong to the table of share structure. Search
7068
 
        index->table instead */
7069
 
        if (index->table != ib_table) {
7070
 
                i = 0;
7071
 
                ind = dict_table_get_first_index(index->table);
7072
 
 
7073
 
                while (index != ind) {
7074
 
                        ind = dict_table_get_next_index(ind);
7075
 
                        i++;
7076
 
                }
7077
 
 
7078
 
                if (row_table_got_default_clust_index(index->table)) {
7079
 
                        ut_a(i > 0);
7080
 
                        i--;
7081
 
                }
7082
 
 
7083
 
                return(i);
7084
 
        }
7085
 
 
7086
 
        /* If index translation table exists, we will first check
7087
 
        the index through index translation table for a match. */
7088
 
        if (share->idx_trans_tbl.index_mapping) {
7089
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7090
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7091
 
                                return(i);
7092
 
                        }
7093
 
                }
7094
 
 
7095
 
                /* Print an error message if we cannot find the index
7096
 
                ** in the "index translation table". */
7097
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7098
 
                              "Cannot find index %s in InnoDB index "
7099
 
                                "translation table.", index->name);
7100
 
        }
7101
 
 
7102
 
        /* If we do not have an "index translation table", or not able
7103
 
        to find the index in the translation table, we'll directly find
7104
 
        matching index in the dict_index_t list */
7105
 
        for (i = 0; i < table->getShare()->keys; i++) {
7106
 
                ind = dict_table_get_index_on_name(
7107
 
                        ib_table, table->key_info[i].name);
7108
 
 
7109
 
                if (index == ind) {
7110
 
                        return(i);
7111
 
                }
7112
 
        }
7113
 
 
7114
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7115
 
                              "Cannot find matching index number for index %s "
7116
 
                              "in InnoDB index list.", index->name);
7117
 
 
7118
 
        return(0);
7119
 
}
7120
 
/*********************************************************************//**
7121
6427
Returns statistics information of the table to the MySQL interpreter,
7122
6428
in various fields of the handle object. */
7123
6429
UNIV_INTERN
7130
6436
  dict_index_t* index;
7131
6437
  ha_rows   rec_per_key;
7132
6438
  ib_int64_t  n_rows;
 
6439
  ulong   j;
 
6440
  ulong   i;
7133
6441
  os_file_stat_t  stat_info;
7134
6442
 
7135
6443
  /* If we are forcing recovery at a high level, we will suppress
7136
6444
  statistics calculation on tables, because that may crash the
7137
6445
  server if an index is badly corrupted. */
7138
6446
 
 
6447
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6448
 
 
6449
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6450
    because we want MySQL to process this query and not
 
6451
    stop, like it would do if it received the error code
 
6452
    HA_ERR_CRASHED. */
 
6453
 
 
6454
    return(0);
 
6455
  }
 
6456
 
7139
6457
  /* We do not know if MySQL can call this function before calling
7140
6458
  external_lock(). To be safe, update the session of the current table
7141
6459
  handle. */
7142
6460
 
7143
 
  update_session(getTable()->in_use);
 
6461
  update_session(table->in_use);
7144
6462
 
7145
6463
  /* In case MySQL calls this in the middle of a SELECT query, release
7146
6464
  possible adaptive hash latch to avoid deadlocks of threads */
7152
6470
  ib_table = prebuilt->table;
7153
6471
 
7154
6472
  if (flag & HA_STATUS_TIME) {
7155
 
    /* In Analyze we call with this flag: update
7156
 
       then statistics so that they are up-to-date */
7157
 
 
7158
 
    prebuilt->trx->op_info = "updating table statistics";
7159
 
 
7160
 
    dict_update_statistics(ib_table);
7161
 
 
7162
 
    prebuilt->trx->op_info = "returning various info to MySQL";
 
6473
    if (innobase_stats_on_metadata) {
 
6474
      /* In sql_show we call with this flag: update
 
6475
      then statistics so that they are up-to-date */
 
6476
 
 
6477
      prebuilt->trx->op_info = "updating table statistics";
 
6478
 
 
6479
      dict_update_statistics(ib_table);
 
6480
 
 
6481
      prebuilt->trx->op_info = "returning various info to MySQL";
 
6482
    }
7163
6483
 
7164
6484
    fs::path get_status_path(getDataHomeCatalog());
7165
6485
    get_status_path /= ib_table->name;
7227
6547
    acquiring latches inside InnoDB, we do not call it if we
7228
6548
    are asked by MySQL to avoid locking. Another reason to
7229
6549
    avoid the call is that it uses quite a lot of CPU.
7230
 
    See Bug#38185. */
7231
 
    if (flag & HA_STATUS_NO_LOCK) {
7232
 
      /* We do not update delete_length if no
7233
 
         locking is requested so the "old" value can
7234
 
         remain. delete_length is initialized to 0 in
7235
 
         the ha_statistics' constructor. */
7236
 
    } else if (UNIV_UNLIKELY
7237
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7238
 
      /* Avoid accessing the tablespace if
7239
 
         innodb_crash_recovery is set to a high value. */
7240
 
      stats.delete_length = 0;
7241
 
    } else {
 
6550
    See Bug#38185.
 
6551
    We do not update delete_length if no locking is requested
 
6552
    so the "old" value can remain. delete_length is initialized
 
6553
    to 0 in the ha_statistics' constructor. */
 
6554
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6555
 
7242
6556
      /* lock the data dictionary to avoid races with
7243
6557
      ibd_file_missing and tablespace_discarded */
7244
6558
      row_mysql_lock_data_dictionary(prebuilt->trx);
7254
6568
 
7255
6569
        Session*  session;
7256
6570
 
7257
 
        session= getTable()->in_use;
 
6571
        session= table->in_use;
7258
6572
        assert(session);
7259
6573
 
7260
6574
        push_warning_printf(
7284
6598
  }
7285
6599
 
7286
6600
  if (flag & HA_STATUS_CONST) {
7287
 
    ulong i;
7288
 
    /* Verify the number of index in InnoDB and MySQL
7289
 
       matches up. If prebuilt->clust_index_was_generated
7290
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7291
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6601
    index = dict_table_get_first_index(ib_table);
7292
6602
 
7293
 
    if (getTable()->getShare()->keys != num_innodb_index) {
7294
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7295
 
                      "indexes inside InnoDB, which "
7296
 
                      "is different from the number of "
7297
 
                      "indexes %u defined in the MySQL ",
7298
 
                      ib_table->name, num_innodb_index,
7299
 
                      getTable()->getShare()->keys);
 
6603
    if (prebuilt->clust_index_was_generated) {
 
6604
      index = dict_table_get_next_index(index);
7300
6605
    }
7301
6606
 
7302
 
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7303
 
      ulong j;
7304
 
      /* We could get index quickly through internal
7305
 
         index mapping with the index translation table.
7306
 
         The identity of index (match up index name with
7307
 
         that of table->key_info[i]) is already verified in
7308
 
         innobase_get_index().  */
7309
 
      index = innobase_get_index(i);
7310
 
 
 
6607
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7311
6608
      if (index == NULL) {
7312
6609
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7313
6610
            "indexes inside InnoDB than "
7321
6618
        break;
7322
6619
      }
7323
6620
 
7324
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6621
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7325
6622
 
7326
6623
        if (j + 1 > index->n_uniq) {
7327
6624
          errmsg_printf(ERRMSG_LVL_ERROR, 
7336
6633
          break;
7337
6634
        }
7338
6635
 
7339
 
        dict_index_stat_mutex_enter(index);
7340
 
 
7341
6636
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7342
6637
 
7343
6638
          rec_per_key = stats.records;
7346
6641
           index->stat_n_diff_key_vals[j + 1]);
7347
6642
        }
7348
6643
 
7349
 
        dict_index_stat_mutex_exit(index);
7350
 
 
7351
6644
        /* Since MySQL seems to favor table scans
7352
6645
        too much over index searches, we pretend
7353
6646
        index selectivity is 2 times better than
7359
6652
          rec_per_key = 1;
7360
6653
        }
7361
6654
 
7362
 
        getTable()->key_info[i].rec_per_key[j]=
 
6655
        table->key_info[i].rec_per_key[j]=
7363
6656
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7364
6657
          (ulong) rec_per_key;
7365
6658
      }
 
6659
 
 
6660
      index = dict_table_get_next_index(index);
7366
6661
    }
7367
6662
  }
7368
6663
 
7369
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7370
 
    goto func_exit;
7371
 
  }
7372
 
 
7373
6664
  if (flag & HA_STATUS_ERRKEY) {
7374
6665
    const dict_index_t* err_index;
7375
6666
 
7380
6671
 
7381
6672
    if (err_index) {
7382
6673
      errkey = (unsigned int)
7383
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7384
 
                                                err_index);
 
6674
        row_get_mysql_key_number_for_index(err_index);
7385
6675
    } else {
7386
6676
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7387
6677
    }
7388
6678
  }
7389
6679
 
7390
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6680
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7391
6681
    stats.auto_increment_value = innobase_peek_autoinc();
7392
6682
  }
7393
6683
 
7394
 
func_exit:
7395
6684
  prebuilt->trx->op_info = (char*)"";
7396
6685
 
7397
6686
  return(0);
7424
6713
/*===============*/
7425
6714
  Session*  session)  /*!< in: user thread handle */
7426
6715
{
7427
 
  dict_index_t* index;
7428
 
  ulint         n_rows;
7429
 
  ulint         n_rows_in_table = ULINT_UNDEFINED;
7430
 
  ibool         is_ok           = TRUE;
7431
 
  ulint         old_isolation_level;
 
6716
  ulint   ret;
7432
6717
 
7433
 
  assert(session == getTable()->in_use);
 
6718
  assert(session == table->in_use);
7434
6719
  ut_a(prebuilt->trx);
7435
6720
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7436
6721
  ut_a(prebuilt->trx == session_to_trx(session));
7439
6724
    /* Build the template; we will use a dummy template
7440
6725
    in index scans done in checking */
7441
6726
 
7442
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
7443
 
  }
7444
 
 
7445
 
  if (prebuilt->table->ibd_file_missing) {
7446
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7447
 
                    "InnoDB: MySQL is trying to use a table handle"
7448
 
                    " but the .ibd file for\n"
7449
 
                    "InnoDB: table %s does not exist.\n"
7450
 
                    "InnoDB: Have you deleted the .ibd file"
7451
 
                    " from the database directory under\n"
7452
 
                    "InnoDB: the MySQL datadir, or have you"
7453
 
                    " used DISCARD TABLESPACE?\n"
7454
 
                    "InnoDB: Please refer to\n"
7455
 
                    "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
7456
 
                    "InnoDB: how you can resolve the problem.\n",
7457
 
                    prebuilt->table->name);
7458
 
    return(HA_ADMIN_CORRUPT);
7459
 
  }
7460
 
 
7461
 
  prebuilt->trx->op_info = "checking table";
7462
 
 
7463
 
  old_isolation_level = prebuilt->trx->isolation_level;
7464
 
 
7465
 
  /* We must run the index record counts at an isolation level
7466
 
     >= READ COMMITTED, because a dirty read can see a wrong number
7467
 
     of records in some index; to play safe, we use always
7468
 
     REPEATABLE READ here */
7469
 
 
7470
 
  prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7471
 
 
7472
 
  /* Enlarge the fatal lock wait timeout during CHECK TABLE. */
7473
 
  mutex_enter(&kernel_mutex);
7474
 
  srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
7475
 
  mutex_exit(&kernel_mutex);
7476
 
 
7477
 
  for (index = dict_table_get_first_index(prebuilt->table);
7478
 
       index != NULL;
7479
 
       index = dict_table_get_next_index(index)) {
7480
 
#if 0
7481
 
    fputs("Validating index ", stderr);
7482
 
    ut_print_name(stderr, trx, FALSE, index->name);
7483
 
    putc('\n', stderr);
7484
 
#endif
7485
 
 
7486
 
    if (!btr_validate_index(index, prebuilt->trx)) {
7487
 
      is_ok = FALSE;
7488
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7489
 
                          ER_NOT_KEYFILE,
7490
 
                          "InnoDB: The B-tree of"
7491
 
                          " index '%-.200s' is corrupted.",
7492
 
                          index->name);
7493
 
      continue;
7494
 
    }
7495
 
 
7496
 
    /* Instead of invoking change_active_index(), set up
7497
 
       a dummy template for non-locking reads, disabling
7498
 
       access to the clustered index. */
7499
 
    prebuilt->index = index;
7500
 
 
7501
 
    prebuilt->index_usable = row_merge_is_index_usable(
7502
 
                        prebuilt->trx, prebuilt->index);
7503
 
 
7504
 
    if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
7505
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7506
 
                          HA_ERR_TABLE_DEF_CHANGED,
7507
 
                          "InnoDB: Insufficient history for"
7508
 
                          " index '%-.200s'",
7509
 
                          index->name);
7510
 
      continue;
7511
 
    }
7512
 
 
7513
 
    prebuilt->sql_stat_start = TRUE;
7514
 
    prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
7515
 
    prebuilt->n_template = 0;
7516
 
    prebuilt->need_to_access_clustered = FALSE;
7517
 
 
7518
 
    dtuple_set_n_fields(prebuilt->search_tuple, 0);
7519
 
 
7520
 
    prebuilt->select_lock_type = LOCK_NONE;
7521
 
 
7522
 
    if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
7523
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7524
 
                          ER_NOT_KEYFILE,
7525
 
                          "InnoDB: The B-tree of"
7526
 
                          " index '%-.200s' is corrupted.",
7527
 
                          index->name);
7528
 
      is_ok = FALSE;
7529
 
    }
7530
 
 
7531
 
    if (user_session->getKilled()) {
7532
 
      break;
7533
 
    }
7534
 
 
7535
 
#if 0
7536
 
    fprintf(stderr, "%lu entries in index %s\n", n_rows,
7537
 
            index->name);
7538
 
#endif
7539
 
 
7540
 
    if (index == dict_table_get_first_index(prebuilt->table)) {
7541
 
      n_rows_in_table = n_rows;
7542
 
    } else if (n_rows != n_rows_in_table) {
7543
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7544
 
                          ER_NOT_KEYFILE,
7545
 
                          "InnoDB: Index '%-.200s'"
7546
 
                          " contains %lu entries,"
7547
 
                          " should be %lu.",
7548
 
                          index->name,
7549
 
                          (ulong) n_rows,
7550
 
                          (ulong) n_rows_in_table);
7551
 
      is_ok = FALSE;
7552
 
    }
7553
 
  }
7554
 
 
7555
 
  /* Restore the original isolation level */
7556
 
  prebuilt->trx->isolation_level = old_isolation_level;
7557
 
 
7558
 
  /* We validate also the whole adaptive hash index for all tables
7559
 
     at every CHECK TABLE */
7560
 
 
7561
 
  if (!btr_search_validate()) {
7562
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7563
 
                 ER_NOT_KEYFILE,
7564
 
                 "InnoDB: The adaptive hash index is corrupted.");
7565
 
    is_ok = FALSE;
7566
 
  }
7567
 
 
7568
 
  /* Restore the fatal lock wait timeout after CHECK TABLE. */
7569
 
  mutex_enter(&kernel_mutex);
7570
 
  srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
7571
 
  mutex_exit(&kernel_mutex);
7572
 
 
7573
 
  prebuilt->trx->op_info = "";
7574
 
  if (user_session->getKilled()) {
7575
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
7576
 
  }
7577
 
 
7578
 
  return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
 
6727
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
 
6728
  }
 
6729
 
 
6730
  ret = row_check_table_for_mysql(prebuilt);
 
6731
 
 
6732
  if (ret == DB_SUCCESS) {
 
6733
    return(HA_ADMIN_OK);
 
6734
  }
 
6735
 
 
6736
  return(HA_ADMIN_CORRUPT);
7579
6737
}
7580
6738
 
7581
6739
/*************************************************************//**
7601
6759
    return((char*)comment); /* string too long */
7602
6760
  }
7603
6761
 
7604
 
  update_session(getTable()->in_use);
 
6762
  update_session(table->in_use);
7605
6763
 
7606
6764
  prebuilt->trx->op_info = (char*)"returning table comment";
7607
6765
 
7672
6830
  external_lock(). To be safe, update the session of the current table
7673
6831
  handle. */
7674
6832
 
7675
 
  update_session(getTable()->in_use);
 
6833
  update_session(table->in_use);
7676
6834
 
7677
6835
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7678
6836
 
7721
6879
  dict_foreign_t* foreign;
7722
6880
 
7723
6881
  ut_a(prebuilt != NULL);
7724
 
  update_session(getTable()->in_use);
 
6882
  update_session(table->in_use);
7725
6883
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7726
6884
  trx_search_latch_release_if_reserved(prebuilt->trx);
7727
6885
  mutex_enter(&(dict_sys->mutex));
7859
7017
{
7860
7018
  bool  can_switch;
7861
7019
 
7862
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7020
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7863
7021
 
7864
7022
  prebuilt->trx->op_info =
7865
7023
      "determining if there are foreign key constraints";
7947
7105
      either, because the calling threads may change.
7948
7106
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7949
7107
    case HA_EXTRA_IGNORE_DUP_KEY:
7950
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7108
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7951
7109
      break;
7952
7110
    case HA_EXTRA_WRITE_CAN_REPLACE:
7953
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7111
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7954
7112
      break;
7955
7113
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7956
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7114
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7957
7115
      break;
7958
7116
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7959
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7117
      session_to_trx(table->in_use)->duplicates &=
7960
7118
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7961
7119
      break;
7962
7120
    default:/* Do nothing */
8092
7250
{
8093
7251
  trx_t*      trx;
8094
7252
  static const char truncated_msg[] = "... truncated...\n";
8095
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7253
  const long    MAX_STATUS_SIZE = 64000;
8096
7254
  ulint     trx_list_start = ULINT_UNDEFINED;
8097
7255
  ulint     trx_list_end = ULINT_UNDEFINED;
8098
7256
 
8110
7268
 
8111
7269
  mutex_enter(&srv_monitor_file_mutex);
8112
7270
  rewind(srv_monitor_file);
8113
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7271
  srv_printf_innodb_monitor(srv_monitor_file,
8114
7272
        &trx_list_start, &trx_list_end);
8115
7273
  flen = ftell(srv_monitor_file);
8116
7274
  os_file_set_eof(srv_monitor_file);
8121
7279
 
8122
7280
  if (flen > MAX_STATUS_SIZE) {
8123
7281
    usable_len = MAX_STATUS_SIZE;
8124
 
    srv_truncated_status_writes++;
8125
7282
  } else {
8126
7283
    usable_len = flen;
8127
7284
  }
8157
7314
 
8158
7315
  mutex_exit(&srv_monitor_file_mutex);
8159
7316
 
8160
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8161
 
             STRING_WITH_LEN(""), str, flen);
 
7317
  bool result = FALSE;
8162
7318
 
 
7319
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7320
      STRING_WITH_LEN(""), str, flen)) {
 
7321
    result= TRUE;
 
7322
  }
8163
7323
  free(str);
8164
7324
 
8165
7325
  return(FALSE);
8166
7326
}
8167
7327
 
8168
7328
/************************************************************************//**
8169
 
Implements the SHOW MUTEX STATUS command.
8170
 
@return true on failure false on success*/
 
7329
Implements the SHOW MUTEX STATUS command. . */
8171
7330
static
8172
7331
bool
8173
7332
innodb_mutex_show_status(
8175
7334
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8176
7335
  Session*  session,  /*!< in: the MySQL query thread of the
8177
7336
          caller */
8178
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8179
 
                                        statistics */
 
7337
  stat_print_fn*  stat_print)
8180
7338
{
8181
7339
  char buf1[IO_SIZE], buf2[IO_SIZE];
8182
7340
  mutex_t*  mutex;
8183
7341
  rw_lock_t*  lock;
8184
 
  ulint         block_mutex_oswait_count = 0;
8185
 
  ulint         block_lock_oswait_count = 0;
8186
 
  mutex_t*      block_mutex = NULL;
8187
 
  rw_lock_t*    block_lock = NULL;
8188
7342
#ifdef UNIV_DEBUG
8189
7343
  ulint   rw_lock_count= 0;
8190
7344
  ulint   rw_lock_count_spin_loop= 0;
8198
7352
 
8199
7353
  mutex_enter(&mutex_list_mutex);
8200
7354
 
8201
 
  for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
8202
 
       mutex = UT_LIST_GET_NEXT(list, mutex)) {
8203
 
    if (mutex->count_os_wait == 0) {
8204
 
      continue;
8205
 
    }
8206
 
 
8207
 
 
8208
 
    if (buf_pool_is_block_mutex(mutex)) {
8209
 
      block_mutex = mutex;
8210
 
      block_mutex_oswait_count += mutex->count_os_wait;
8211
 
      continue;
 
7355
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7356
 
 
7357
  while (mutex != NULL) {
 
7358
    if (mutex->count_os_wait == 0
 
7359
        || buf_pool_is_block_mutex(mutex)) {
 
7360
      goto next_mutex;
8212
7361
    }
8213
7362
#ifdef UNIV_DEBUG
8214
7363
    if (mutex->mutex_type != 1) {
8235
7384
          return(1);
8236
7385
        }
8237
7386
      }
8238
 
    } else {
 
7387
    }
 
7388
    else {
8239
7389
      rw_lock_count += mutex->count_using;
8240
7390
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8241
7391
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8247
7397
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8248
7398
          mutex->cfile_name, (ulong) mutex->cline);
8249
7399
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8250
 
                      (ulong) mutex->count_os_wait);
 
7400
          mutex->count_os_wait);
8251
7401
 
8252
7402
    if (stat_print(session, innobase_engine_name,
8253
7403
             engine_name_len, buf1, buf1len,
8256
7406
      return(1);
8257
7407
    }
8258
7408
#endif /* UNIV_DEBUG */
8259
 
  }
8260
 
 
8261
 
  if (block_mutex) {
8262
 
    buf1len = snprintf(buf1, sizeof buf1,
8263
 
                       "combined %s:%lu",
8264
 
                       block_mutex->cfile_name,
8265
 
                       (ulong) block_mutex->cline);
8266
 
    buf2len = snprintf(buf2, sizeof buf2,
8267
 
                       "os_waits=%lu",
8268
 
                       (ulong) block_mutex_oswait_count);
8269
 
 
8270
 
    if (stat_print(session, innobase_engine_name,
8271
 
                   strlen(innobase_engine_name), buf1, buf1len,
8272
 
                   buf2, buf2len)) {
8273
 
      mutex_exit(&mutex_list_mutex);
8274
 
      return(1);
8275
 
    }
 
7409
 
 
7410
next_mutex:
 
7411
    mutex = UT_LIST_GET_NEXT(list, mutex);
8276
7412
  }
8277
7413
 
8278
7414
  mutex_exit(&mutex_list_mutex);
8279
7415
 
8280
7416
  mutex_enter(&rw_lock_list_mutex);
8281
7417
 
8282
 
  for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
8283
 
       lock = UT_LIST_GET_NEXT(list, lock)) {
8284
 
    if (lock->count_os_wait == 0) {
8285
 
      continue;
8286
 
    }
8287
 
 
8288
 
    if (buf_pool_is_block_lock(lock)) {
8289
 
      block_lock = lock;
8290
 
      block_lock_oswait_count += lock->count_os_wait;
8291
 
      continue;
8292
 
    }
8293
 
 
8294
 
    buf1len = snprintf(buf1, sizeof buf1, "%s:%lu",
8295
 
                       lock->cfile_name, (ulong) lock->cline);
8296
 
    buf2len = snprintf(buf2, sizeof buf2, "os_waits=%lu",
8297
 
                       (ulong) lock->count_os_wait);
8298
 
 
8299
 
    if (stat_print(session, innobase_engine_name,
8300
 
                   strlen(innobase_engine_name), buf1, buf1len,
8301
 
                   buf2, buf2len)) {
8302
 
      mutex_exit(&rw_lock_list_mutex);
8303
 
      return(1);
8304
 
    }
8305
 
  }
8306
 
 
8307
 
  if (block_lock) {
8308
 
    buf1len = snprintf(buf1, sizeof buf1,
8309
 
                       "combined %s:%lu",
8310
 
                       block_lock->cfile_name,
8311
 
                       (ulong) block_lock->cline);
8312
 
    buf2len = snprintf(buf2, sizeof buf2,
8313
 
                       "os_waits=%lu",
8314
 
                       (ulong) block_lock_oswait_count);
8315
 
 
8316
 
    if (stat_print(session, innobase_engine_name,
8317
 
                   strlen(innobase_engine_name), buf1, buf1len,
8318
 
                   buf2, buf2len)) {
8319
 
      mutex_exit(&rw_lock_list_mutex);
8320
 
      return(1);
8321
 
    }
 
7418
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7419
 
 
7420
  while (lock != NULL) {
 
7421
    if (lock->count_os_wait
 
7422
                    && !buf_pool_is_block_lock(lock)) {
 
7423
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7424
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7425
      buf2len= snprintf(buf2, sizeof(buf2),
 
7426
                                    "os_waits=%lu", lock->count_os_wait);
 
7427
 
 
7428
      if (stat_print(session, innobase_engine_name,
 
7429
               engine_name_len, buf1, buf1len,
 
7430
               buf2, buf2len)) {
 
7431
        mutex_exit(&rw_lock_list_mutex);
 
7432
        return(1);
 
7433
      }
 
7434
    }
 
7435
    lock = UT_LIST_GET_NEXT(list, lock);
8322
7436
  }
8323
7437
 
8324
7438
  mutex_exit(&rw_lock_list_mutex);
8325
7439
 
8326
7440
#ifdef UNIV_DEBUG
8327
 
  buf2len = snprintf(buf2, sizeof buf2,
8328
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8329
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8330
 
                     (ulong) rw_lock_count,
8331
 
                     (ulong) rw_lock_count_spin_loop,
8332
 
                     (ulong) rw_lock_count_spin_rounds,
8333
 
                     (ulong) rw_lock_count_os_wait,
8334
 
                     (ulong) rw_lock_count_os_yield,
8335
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7441
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7442
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7443
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7444
    rw_lock_count, rw_lock_count_spin_loop,
 
7445
    rw_lock_count_spin_rounds,
 
7446
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7447
    (ulong) (rw_lock_wait_time/1000));
8336
7448
 
8337
7449
  if (stat_print(session, innobase_engine_name, engine_name_len,
8338
7450
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8386
7498
          innobase_open_tables, fold, share);
8387
7499
 
8388
7500
    thr_lock_init(&share->lock);
8389
 
 
8390
 
    /* Index translation table initialization */
8391
 
    share->idx_trans_tbl.index_mapping = NULL;
8392
 
    share->idx_trans_tbl.index_count = 0;
8393
 
    share->idx_trans_tbl.array_size = 0;
8394
7501
  }
8395
7502
 
8396
7503
  share->use_count++;
8421
7528
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8422
7529
          innobase_open_tables, fold, share);
8423
7530
    share->lock.deinit();
8424
 
 
8425
 
    /* Free any memory from index translation table */
8426
 
    free(share->idx_trans_tbl.index_mapping);
8427
 
 
8428
7531
    delete share;
8429
7532
 
8430
7533
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8502
7605
    isolation_level = trx->isolation_level;
8503
7606
 
8504
7607
    if ((srv_locks_unsafe_for_binlog
8505
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7608
         || isolation_level == TRX_ISO_READ_COMMITTED)
8506
7609
        && isolation_level != TRX_ISO_SERIALIZABLE
8507
7610
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8508
7611
        && (sql_command == SQLCOM_INSERT_SELECT
8509
 
            || sql_command == SQLCOM_REPLACE_SELECT
8510
 
            || sql_command == SQLCOM_UPDATE
8511
 
            || sql_command == SQLCOM_CREATE_TABLE
8512
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7612
      || sql_command == SQLCOM_UPDATE
 
7613
      || sql_command == SQLCOM_CREATE_TABLE)) {
8513
7614
 
8514
7615
      /* If we either have innobase_locks_unsafe_for_binlog
8515
7616
      option set or this session is using READ COMMITTED
8516
7617
      isolation level and isolation level of the transaction
8517
7618
      is not set to serializable and MySQL is doing
8518
 
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8519
 
      or UPDATE ... = (SELECT ...) or CREATE  ...
8520
 
      SELECT... or SET ... = (SELECT ...) without
8521
 
      FOR UPDATE or IN SHARE MODE in select,
8522
 
      then we use consistent read for select. */
 
7619
      INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
 
7620
      CREATE  ... SELECT... without FOR UPDATE or
 
7621
      IN SHARE MODE in select, then we use consistent
 
7622
      read for select. */
8523
7623
 
8524
7624
      prebuilt->select_lock_type = LOCK_NONE;
8525
7625
      prebuilt->stored_select_lock_type = LOCK_NONE;
8598
7698
  *value = dict_table_autoinc_read(prebuilt->table);
8599
7699
 
8600
7700
  /* It should have been initialized during open. */
8601
 
  if (*value == 0) {
8602
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8603
 
    dict_table_autoinc_unlock(prebuilt->table);
8604
 
  }
 
7701
  ut_a(*value != 0);
8605
7702
 
8606
7703
  return(DB_SUCCESS);
8607
7704
}
8608
7705
 
8609
7706
/*******************************************************************//**
8610
 
This function reads the global auto-inc counter. It doesn't use the
 
7707
This function reads the global auto-inc counter. It doesn't use the 
8611
7708
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8612
7709
@return the autoinc value */
8613
7710
UNIV_INTERN
8627
7724
 
8628
7725
  auto_inc = dict_table_autoinc_read(innodb_table);
8629
7726
 
8630
 
  if (auto_inc == 0) {
8631
 
    ut_print_timestamp(stderr);
8632
 
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
8633
 
            "is disabled for '%s'\n", innodb_table->name);
8634
 
  }
 
7727
  ut_a(auto_inc > 0);
8635
7728
 
8636
7729
  dict_table_autoinc_unlock(innodb_table);
8637
7730
 
8660
7753
  uint64_t  autoinc = 0;
8661
7754
 
8662
7755
  /* Prepare prebuilt->trx in the table handle */
8663
 
  update_session(getTable()->in_use);
 
7756
  update_session(table->in_use);
8664
7757
 
8665
7758
  error = innobase_get_autoinc(&autoinc);
8666
7759
 
8684
7777
  invoking this method. So we are not sure if it's guaranteed to
8685
7778
  be 0 or not. */
8686
7779
 
8687
 
  /* We need the upper limit of the col type to check for
8688
 
     whether we update the table autoinc counter or not. */
8689
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8690
 
 
8691
7780
  /* Called for the first time ? */
8692
7781
  if (trx->n_autoinc_rows == 0) {
8693
7782
 
8704
7793
  /* Not in the middle of a mult-row INSERT. */
8705
7794
  } else if (prebuilt->autoinc_last_value == 0) {
8706
7795
    set_if_bigger(*first_value, autoinc);
8707
 
    /* Check for -ve values. */
8708
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8709
 
    /* Set to next logical value. */
8710
 
    ut_a(autoinc > trx->n_autoinc_rows);
8711
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8712
7796
  }
8713
7797
 
8714
7798
  *nb_reserved_values = trx->n_autoinc_rows;
8716
7800
  /* This all current style autoinc. */
8717
7801
  {
8718
7802
    uint64_t  need;
8719
 
    uint64_t  current;
8720
7803
    uint64_t  next_value;
8721
 
 
8722
 
    current = *first_value > col_max_value ? autoinc : *first_value;
 
7804
    uint64_t  col_max_value;
 
7805
 
 
7806
    /* We need the upper limit of the col type to check for
 
7807
    whether we update the table autoinc counter or not. */
 
7808
    col_max_value = innobase_get_int_col_max_value(
 
7809
      table->next_number_field);
 
7810
 
8723
7811
    need = *nb_reserved_values * increment;
8724
7812
 
8725
7813
    /* Compute the last value in the interval */
8726
 
    next_value = innobase_next_autoinc(current, need, offset, col_max_value);
 
7814
    next_value = innobase_next_autoinc(
 
7815
      *first_value, need, offset, col_max_value);
8727
7816
 
8728
7817
    prebuilt->autoinc_last_value = next_value;
8729
7818
 
8760
7849
{
8761
7850
  int error;
8762
7851
 
8763
 
  update_session(getTable()->in_use);
 
7852
  update_session(table->in_use);
8764
7853
 
8765
7854
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8766
7855
 
8826
7915
  /* Do a type-aware comparison of primary key fields. PK fields
8827
7916
  are always NOT NULL, so no checks for NULL are performed. */
8828
7917
 
8829
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
7918
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8830
7919
 
8831
7920
  key_part_end = key_part
8832
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
7921
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8833
7922
 
8834
7923
  for (; key_part != key_part_end; ++key_part) {
8835
7924
    field = key_part->field;
8977
8066
 
8978
8067
  innobase_release_stat_resources(trx);
8979
8068
 
 
8069
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8070
  {
 
8071
    if (trx->conc_state != TRX_NOT_STARTED)
 
8072
    {
 
8073
      commit(session, TRUE);
 
8074
    }
 
8075
  }
 
8076
  else
 
8077
  {
 
8078
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8079
        trx->global_read_view)
 
8080
    {
 
8081
      /* At low transaction isolation levels we let
 
8082
      each consistent read set its own snapshot */
 
8083
      read_view_close_for_mysql(trx);
 
8084
    }
 
8085
  }
8980
8086
}
8981
8087
 
8982
8088
/*******************************************************************//**
9046
8152
  return(error);
9047
8153
}
9048
8154
 
9049
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
9050
 
{
9051
 
  trx_t *trx= session_to_trx(session);
9052
 
  return (trx->id);
9053
 
}
9054
 
 
9055
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
9056
 
{
9057
 
  trx_t*& trx = session_to_trx(session);
9058
 
 
9059
 
  if (trx == NULL)
9060
 
  {
9061
 
    trx = innobase_trx_allocate(session);
9062
 
 
9063
 
    innobase_trx_init(session, trx);
9064
 
  }
9065
 
 
9066
 
  mutex_enter(&kernel_mutex);
9067
 
  trx->id= trx_sys_get_new_trx_id();
9068
 
  mutex_exit(&kernel_mutex);
9069
 
 
9070
 
  uint64_t transaction_id= trx->id;
9071
 
 
9072
 
  return transaction_id;
9073
 
}
9074
 
 
9075
8155
/*******************************************************************//**
9076
8156
This function is used to recover X/Open XA distributed transactions.
9077
8157
@return number of prepared transactions stored in xid_list */
9183
8263
}
9184
8264
 
9185
8265
/************************************************************//**
 
8266
Validate the file format check value, is it one of "on" or "off",
 
8267
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8268
@return true if config value one of "on" or  "off" */
 
8269
static
 
8270
bool
 
8271
innobase_file_format_check_on_off(
 
8272
/*==============================*/
 
8273
  const char* format_check) /*!< in: parameter value */
 
8274
{
 
8275
  bool    ret = true;
 
8276
 
 
8277
  if (!innobase_strcasecmp(format_check, "off")) {
 
8278
 
 
8279
    /* Set the value to disable checking. */
 
8280
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8281
 
 
8282
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8283
 
 
8284
    /* Set the value to the lowest supported format. */
 
8285
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8286
  } else {
 
8287
    ret = FALSE;
 
8288
  }
 
8289
 
 
8290
  return(ret);
 
8291
}
 
8292
 
 
8293
/************************************************************//**
9186
8294
Validate the file format check config parameters, as a side effect it
9187
 
sets the srv_max_file_format_at_startup variable.
9188
 
@return the format_id if valid config value, otherwise, return -1 */
 
8295
sets the srv_check_file_format_at_startup variable.
 
8296
@return true if valid config value */
9189
8297
static
9190
 
int
9191
 
innobase_file_format_validate_and_set(
 
8298
bool
 
8299
innobase_file_format_check_validate(
9192
8300
/*================================*/
9193
 
  const char* format_max) /*!< in: parameter value */
 
8301
  const char* format_check) /*!< in: parameter value */
9194
8302
{
9195
8303
  uint    format_id;
 
8304
  bool    ret = true;
9196
8305
 
9197
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8306
  format_id = innobase_file_format_name_lookup(format_check);
9198
8307
 
9199
8308
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9200
 
    srv_max_file_format_at_startup = format_id;
9201
 
    return((int) format_id);
9202
 
  } else {
9203
 
    return(-1);
9204
 
  }
9205
 
}
9206
 
 
9207
 
 
 
8309
    srv_check_file_format_at_startup = format_id;
 
8310
  } else {
 
8311
    ret = false;
 
8312
  }
 
8313
 
 
8314
  return(ret);
 
8315
}
 
8316
 
 
8317
/*************************************************************//**
 
8318
Check if it is a valid file format. This function is registered as
 
8319
a callback with MySQL.
 
8320
@return 0 for valid file format */
 
8321
static
 
8322
int
 
8323
innodb_file_format_name_validate(
 
8324
/*=============================*/
 
8325
  Session*      , /*!< in: thread handle */
 
8326
  drizzle_sys_var*  , /*!< in: pointer to system
 
8327
            variable */
 
8328
  void*       save, /*!< out: immediate result
 
8329
            for update function */
 
8330
  drizzle_value*    value)  /*!< in: incoming string */
 
8331
{
 
8332
  const char* file_format_input;
 
8333
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8334
  int   len = sizeof(buff);
 
8335
 
 
8336
  ut_a(save != NULL);
 
8337
  ut_a(value != NULL);
 
8338
 
 
8339
  file_format_input = value->val_str(value, buff, &len);
 
8340
 
 
8341
  if (file_format_input != NULL) {
 
8342
    uint  format_id;
 
8343
 
 
8344
    format_id = innobase_file_format_name_lookup(
 
8345
      file_format_input);
 
8346
 
 
8347
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8348
 
 
8349
      *static_cast<const char**>(save) = file_format_input;
 
8350
      return(0);
 
8351
    }
 
8352
  }
 
8353
 
 
8354
  *static_cast<const char**>(save) = NULL;
 
8355
  return(1);
 
8356
}
 
8357
 
 
8358
/****************************************************************//**
 
8359
Update the system variable innodb_file_format using the "saved"
 
8360
value. This function is registered as a callback with MySQL. */
 
8361
static
 
8362
void
 
8363
innodb_file_format_name_update(
 
8364
/*===========================*/
 
8365
  Session*      ,   /*!< in: thread handle */
 
8366
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8367
              system variable */
 
8368
  void*       var_ptr,  /*!< out: where the
 
8369
              formal string goes */
 
8370
  const void*     save)   /*!< in: immediate result
 
8371
              from check function */
 
8372
{
 
8373
  const char* format_name;
 
8374
 
 
8375
  ut_a(var_ptr != NULL);
 
8376
  ut_a(save != NULL);
 
8377
 
 
8378
  format_name = *static_cast<const char*const*>(save);
 
8379
 
 
8380
  if (format_name) {
 
8381
    uint  format_id;
 
8382
 
 
8383
    format_id = innobase_file_format_name_lookup(format_name);
 
8384
 
 
8385
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8386
      srv_file_format = format_id;
 
8387
    }
 
8388
  }
 
8389
 
 
8390
  *static_cast<const char**>(var_ptr)
 
8391
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8392
}
 
8393
 
 
8394
/*************************************************************//**
 
8395
Check if valid argument to innodb_file_format_check. This
 
8396
function is registered as a callback with MySQL.
 
8397
@return 0 for valid file format */
 
8398
static
 
8399
int
 
8400
innodb_file_format_check_validate(
 
8401
/*==============================*/
 
8402
  Session*      , /*!< in: thread handle */
 
8403
  drizzle_sys_var*  , /*!< in: pointer to system
 
8404
            variable */
 
8405
  void*       save, /*!< out: immediate result
 
8406
            for update function */
 
8407
  drizzle_value*    value)  /*!< in: incoming string */
 
8408
{
 
8409
  const char* file_format_input;
 
8410
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8411
  int   len = sizeof(buff);
 
8412
 
 
8413
  ut_a(save != NULL);
 
8414
  ut_a(value != NULL);
 
8415
 
 
8416
  file_format_input = value->val_str(value, buff, &len);
 
8417
 
 
8418
  if (file_format_input != NULL) {
 
8419
 
 
8420
    /* Check if user set on/off, we want to print a suitable
 
8421
    message if they did so. */
 
8422
 
 
8423
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8424
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8425
        "InnoDB: invalid innodb_file_format_check "
 
8426
        "value; on/off can only be set at startup or "
 
8427
        "in the configuration file");
 
8428
    } else if (innobase_file_format_check_validate(
 
8429
        file_format_input)) {
 
8430
 
 
8431
      *static_cast<const char**>(save) = file_format_input;
 
8432
 
 
8433
      return(0);
 
8434
 
 
8435
    } else {
 
8436
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8437
        "InnoDB: invalid innodb_file_format_check "
 
8438
        "value; can be any format up to %s "
 
8439
        "or its equivalent numeric id",
 
8440
        trx_sys_file_format_id_to_name(
 
8441
          DICT_TF_FORMAT_MAX));
 
8442
    }
 
8443
  }
 
8444
 
 
8445
  *static_cast<const char**>(save) = NULL;
 
8446
  return(1);
 
8447
}
 
8448
 
 
8449
/****************************************************************//**
 
8450
Update the system variable innodb_file_format_check using the "saved"
 
8451
value. This function is registered as a callback with MySQL. */
 
8452
static
 
8453
void
 
8454
innodb_file_format_check_update(
 
8455
/*============================*/
 
8456
  Session*      session,  /*!< in: thread handle */
 
8457
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8458
              system variable */
 
8459
  void*       var_ptr,  /*!< out: where the
 
8460
              formal string goes */
 
8461
  const void*     save)   /*!< in: immediate result
 
8462
              from check function */
 
8463
{
 
8464
  const char* format_name_in;
 
8465
  const char**  format_name_out;
 
8466
  uint    format_id;
 
8467
 
 
8468
  ut_a(save != NULL);
 
8469
  ut_a(var_ptr != NULL);
 
8470
 
 
8471
  format_name_in = *static_cast<const char*const*>(save);
 
8472
 
 
8473
  if (!format_name_in) {
 
8474
 
 
8475
    return;
 
8476
  }
 
8477
 
 
8478
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8479
 
 
8480
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8481
    /* DEFAULT is "on", which is invalid at runtime. */
 
8482
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8483
            ER_WRONG_ARGUMENTS,
 
8484
            "Ignoring SET innodb_file_format=%s",
 
8485
            format_name_in);
 
8486
    return;
 
8487
  }
 
8488
 
 
8489
  format_name_out = static_cast<const char**>(var_ptr);
 
8490
 
 
8491
  /* Update the max format id in the system tablespace. */
 
8492
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8493
    ut_print_timestamp(stderr);
 
8494
    fprintf(stderr,
 
8495
      " [Info] InnoDB: the file format in the system "
 
8496
      "tablespace is now set to %s.\n", *format_name_out);
 
8497
  }
 
8498
}
 
8499
 
 
8500
/****************************************************************//**
 
8501
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8502
value. This function is registered as a callback with MySQL. */
 
8503
static
 
8504
void
 
8505
innodb_adaptive_hash_index_update(
 
8506
/*==============================*/
 
8507
  Session*      ,   /*!< in: thread handle */
 
8508
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8509
              system variable */
 
8510
  void*       , /*!< out: where the
 
8511
              formal string goes */
 
8512
  const void*     save)   /*!< in: immediate result
 
8513
              from check function */
 
8514
{
 
8515
  if (*(bool*) save) {
 
8516
    btr_search_enable();
 
8517
  } else {
 
8518
    btr_search_disable();
 
8519
  }
 
8520
}
 
8521
 
 
8522
/*************************************************************//**
 
8523
Check if it is a valid value of innodb_change_buffering.  This function is
 
8524
registered as a callback with MySQL.
 
8525
@return 0 for valid innodb_change_buffering */
 
8526
static
 
8527
int
 
8528
innodb_change_buffering_validate(
 
8529
/*=============================*/
 
8530
  Session*      , /*!< in: thread handle */
 
8531
  drizzle_sys_var*  , /*!< in: pointer to system
 
8532
            variable */
 
8533
  void*       save, /*!< out: immediate result
 
8534
            for update function */
 
8535
  drizzle_value*    value)  /*!< in: incoming string */
 
8536
{
 
8537
  const char* change_buffering_input;
 
8538
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8539
  int   len = sizeof(buff);
 
8540
 
 
8541
  ut_a(save != NULL);
 
8542
  ut_a(value != NULL);
 
8543
 
 
8544
  change_buffering_input = value->val_str(value, buff, &len);
 
8545
 
 
8546
  if (change_buffering_input != NULL) {
 
8547
    ulint use;
 
8548
 
 
8549
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8550
         use++) {
 
8551
      if (!innobase_strcasecmp(
 
8552
            change_buffering_input,
 
8553
            innobase_change_buffering_values[use])) {
 
8554
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8555
        return(0);
 
8556
      }
 
8557
    }
 
8558
  }
 
8559
 
 
8560
  return(1);
 
8561
}
 
8562
 
 
8563
/****************************************************************//**
 
8564
Update the system variable innodb_change_buffering using the "saved"
 
8565
value. This function is registered as a callback with MySQL. */
 
8566
static
 
8567
void
 
8568
innodb_change_buffering_update(
 
8569
/*===========================*/
 
8570
  Session*      ,   /*!< in: thread handle */
 
8571
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8572
              system variable */
 
8573
  void*       var_ptr,  /*!< out: where the
 
8574
              formal string goes */
 
8575
  const void*     save)   /*!< in: immediate result
 
8576
              from check function */
 
8577
{
 
8578
  ut_a(var_ptr != NULL);
 
8579
  ut_a(save != NULL);
 
8580
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8581
 
 
8582
  ibuf_use = *(const ibuf_use_t*) save;
 
8583
 
 
8584
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8585
}
 
8586
 
 
8587
/* plugin options */
 
8588
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8589
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8590
  "Enable InnoDB checksums validation (enabled by default). ",
 
8591
  NULL, NULL, TRUE);
 
8592
 
 
8593
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8594
  PLUGIN_VAR_READONLY,
 
8595
  "The common part for InnoDB table spaces.",
 
8596
  NULL, NULL, NULL);
 
8597
 
 
8598
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8599
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8600
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8601
  NULL, NULL, TRUE);
 
8602
 
 
8603
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8604
  PLUGIN_VAR_RQCMDARG,
 
8605
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8606
  NULL, NULL, 200, 100, ~0L, 0);
 
8607
 
 
8608
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8609
  PLUGIN_VAR_OPCMDARG,
 
8610
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8611
  "values are 0, 1 (faster)"
 
8612
  " or 2 (fastest - crash-like)"
 
8613
  ".",
 
8614
  NULL, NULL, 1, 0, 2, 0);
 
8615
 
 
8616
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8617
  PLUGIN_VAR_NOCMDARG,
 
8618
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8619
  NULL, NULL, FALSE);
 
8620
 
 
8621
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8622
  PLUGIN_VAR_RQCMDARG,
 
8623
  "File format to use for new tables in .ibd files.",
 
8624
  innodb_file_format_name_validate,
 
8625
  innodb_file_format_name_update, "Antelope");
 
8626
 
 
8627
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8628
  PLUGIN_VAR_OPCMDARG,
 
8629
  "The highest file format in the tablespace.",
 
8630
  innodb_file_format_check_validate,
 
8631
  innodb_file_format_check_update,
 
8632
  "on");
 
8633
 
 
8634
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8635
  PLUGIN_VAR_OPCMDARG,
 
8636
  "Set to 0 (write and flush once per second),"
 
8637
  " 1 (write and flush at each commit)"
 
8638
  " or 2 (write at commit, flush once per second).",
 
8639
  NULL, NULL, 1, 0, 2, 0);
 
8640
 
 
8641
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
 
8642
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8643
  "With which method to flush data.", NULL, NULL, NULL);
 
8644
 
 
8645
#ifdef UNIV_LOG_ARCHIVE
 
8646
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8647
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8648
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8649
 
 
8650
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8651
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8652
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8653
#endif /* UNIV_LOG_ARCHIVE */
 
8654
 
 
8655
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8656
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8657
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8658
 
 
8659
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8660
  PLUGIN_VAR_RQCMDARG,
 
8661
  "Percentage of dirty pages allowed in bufferpool.",
 
8662
  NULL, NULL, 75, 0, 99, 0);
 
8663
 
 
8664
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8665
  PLUGIN_VAR_NOCMDARG,
 
8666
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8667
  NULL, NULL, TRUE);
 
8668
 
 
8669
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8670
  PLUGIN_VAR_RQCMDARG,
 
8671
  "Desired maximum length of the purge queue (0 = no limit)",
 
8672
  NULL, NULL, 0, 0, ~0L, 0);
 
8673
 
 
8674
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8675
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8676
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8677
  NULL, NULL, FALSE);
 
8678
 
 
8679
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
 
8680
  PLUGIN_VAR_OPCMDARG,
 
8681
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
 
8682
  NULL, NULL, TRUE);
 
8683
 
 
8684
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8685
  PLUGIN_VAR_RQCMDARG,
 
8686
  "The number of index pages to sample when calculating statistics (default 8)",
 
8687
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8688
 
 
8689
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8690
  PLUGIN_VAR_OPCMDARG,
 
8691
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8692
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8693
 
 
8694
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8695
  PLUGIN_VAR_RQCMDARG,
 
8696
  "Replication thread delay (ms) on the slave server if "
 
8697
  "innodb_thread_concurrency is reached (0 by default)",
 
8698
  NULL, NULL, 0, 0, ~0UL, 0);
 
8699
 
 
8700
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8701
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8702
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8703
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8704
 
 
8705
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8706
  PLUGIN_VAR_RQCMDARG,
 
8707
  "Data file autoextend increment in megabytes",
 
8708
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8709
 
 
8710
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8711
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8712
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8713
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8714
 
 
8715
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8716
  PLUGIN_VAR_RQCMDARG,
 
8717
  "Helps in performance tuning in heavily concurrent environments.",
 
8718
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8719
 
 
8720
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8721
  PLUGIN_VAR_RQCMDARG,
 
8722
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8723
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8724
 
 
8725
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8726
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8727
  "Number of background read I/O threads in InnoDB.",
 
8728
  NULL, NULL, 4, 1, 64, 0);
 
8729
 
 
8730
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8731
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8732
  "Number of background write I/O threads in InnoDB.",
 
8733
  NULL, NULL, 4, 1, 64, 0);
 
8734
 
 
8735
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8736
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8737
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8738
  NULL, NULL, 0, 0, 6, 0);
 
8739
 
 
8740
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8741
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8742
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8743
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8744
 
 
8745
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8746
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8747
  "Size of each log file in a log group.",
 
8748
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8749
 
 
8750
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8751
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8752
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8753
  NULL, NULL, 2, 2, 100, 0);
 
8754
 
 
8755
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8756
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8757
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8758
  NULL, NULL, 1, 1, 10, 0);
 
8759
 
 
8760
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8761
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8762
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8763
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8764
 
 
8765
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8766
  PLUGIN_VAR_RQCMDARG,
 
8767
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8768
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8769
 
 
8770
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8771
  PLUGIN_VAR_OPCMDARG,
 
8772
  "Maximum delay between polling for a spin lock (6 by default)",
 
8773
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8774
 
 
8775
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8776
  PLUGIN_VAR_RQCMDARG,
 
8777
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8778
  NULL, NULL, 0, 0, 1000, 0);
 
8779
 
 
8780
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8781
  PLUGIN_VAR_RQCMDARG,
 
8782
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8783
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8784
 
 
8785
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8786
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8787
  "Path to individual files and their sizes.",
 
8788
  NULL, NULL, NULL);
 
8789
 
 
8790
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8791
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8792
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8793
 
 
8794
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8795
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8796
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8797
  NULL, NULL, TRUE);
 
8798
 
 
8799
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8800
  PLUGIN_VAR_RQCMDARG,
 
8801
  "Buffer changes to reduce random access: "
 
8802
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8803
  innodb_change_buffering_validate,
 
8804
  innodb_change_buffering_update, NULL);
 
8805
 
 
8806
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8807
  PLUGIN_VAR_RQCMDARG,
 
8808
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8809
  "trigger a readahead.",
 
8810
  NULL, NULL, 56, 0, 64, 0);
9208
8811
 
9209
8812
static void init_options(drizzled::module::option_context &context)
9210
8813
{
9216
8819
  context("disable-doublewrite",
9217
8820
          "Disable InnoDB doublewrite buffer.");
9218
8821
  context("io-capacity",
9219
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8822
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9220
8823
          "Number of IOPs the server can do. Tunes the background IO rate");
9221
8824
  context("fast-shutdown",
9222
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8825
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9223
8826
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9224
 
  context("purge-batch-size",
9225
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9226
 
          "Number of UNDO logs to purge in one batch from the history list. "
9227
 
          "Default is 20.");
9228
 
  context("purge-threads",
9229
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9230
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9231
8827
  context("file-per-table",
9232
8828
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9233
8829
          "Stores each InnoDB table to an .ibd file in the database dir.");
9234
8830
  context("file-format",
9235
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8831
          po::value<string>()->default_value("Antelope"),
9236
8832
          "File format to use for new tables in .ibd files.");
9237
 
  context("file-format-max",
9238
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
 
8833
  context("file-format-check",
 
8834
          po::value<string>()->default_value("on"),
9239
8835
          "The highest file format in the tablespace.");
9240
 
  context("file-format-check",
9241
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9242
 
          "Whether to perform system file format check.");
9243
8836
  context("flush-log-at-trx-commit",
9244
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8837
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9245
8838
          "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).");
9246
8839
  context("flush-method",
9247
8840
          po::value<string>(),
9248
8841
          "With which method to flush data.");
 
8842
#ifdef UNIV_LOG_ARCHIVE
 
8843
  context("log-arch-dir",
 
8844
          po::value<string>(),
 
8845
          "Where full logs should be archived.");
 
8846
  context("log-archive",
 
8847
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8848
          "Set to 1 if you want to have logs archived.");
 
8849
#endif /* UNIV_LOG_ARCHIVE */
9249
8850
  context("log-group-home-dir",
9250
8851
          po::value<string>(),
9251
8852
          "Path to InnoDB log files.");
9252
8853
  context("max-dirty-pages-pct",
9253
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8854
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9254
8855
          "Percentage of dirty pages allowed in bufferpool.");
9255
8856
  context("disable-adaptive-flushing",
9256
8857
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9257
8858
  context("max-purge-lag",
9258
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8859
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9259
8860
          "Desired maximum length of the purge queue (0 = no limit)");
9260
8861
  context("status-file",
9261
8862
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9263
8864
  context("disable-stats-on-metadata",
9264
8865
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9265
8866
  context("stats-sample-pages",
9266
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
8867
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9267
8868
          "The number of index pages to sample when calculating statistics (default 8)");
9268
8869
  context("disable-adaptive-hash-index",
9269
8870
          "Enable InnoDB adaptive hash index (enabled by default)");
9270
8871
  context("replication-delay",
9271
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
8872
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9272
8873
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9273
8874
  context("additional-mem-pool-size",
9274
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
8875
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9275
8876
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9276
8877
  context("autoextend-increment",
9277
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
 
8878
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9278
8879
          "Data file autoextend increment in megabytes");
9279
8880
  context("buffer-pool-size",
9280
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
8881
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9281
8882
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9282
 
  context("buffer-pool-instances",
9283
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9284
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9285
 
 
9286
8883
  context("commit-concurrency",
9287
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
8884
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9288
8885
          "Helps in performance tuning in heavily concurrent environments.");
9289
8886
  context("concurrency-tickets",
9290
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
8887
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9291
8888
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9292
8889
  context("read-io-threads",
9293
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
8890
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9294
8891
          "Number of background read I/O threads in InnoDB.");
9295
8892
  context("write-io-threads",
9296
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
8893
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9297
8894
          "Number of background write I/O threads in InnoDB.");
9298
8895
  context("force-recovery",
9299
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
8896
          po::value<long>(&innobase_force_recovery)->default_value(0),
9300
8897
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9301
8898
  context("log-buffer-size",
9302
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
8899
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9303
8900
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9304
8901
  context("log-file-size",
9305
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
8902
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9306
8903
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9307
8904
  context("log-files-in-group",
9308
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
8905
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9309
8906
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9310
8907
  context("mirrored-log-groups",
9311
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
8908
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9312
8909
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9313
8910
  context("open-files",
9314
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
8911
          po::value<long>(&innobase_open_files)->default_value(300L),
9315
8912
          "How many files at the maximum InnoDB keeps open at the same time.");
9316
8913
  context("sync-spin-loops",
9317
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
8914
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9318
8915
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9319
8916
  context("spin-wait-delay",
9320
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
8917
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9321
8918
          "Maximum delay between polling for a spin lock (6 by default)");
9322
8919
  context("thread-concurrency",
9323
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
8920
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9324
8921
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9325
8922
  context("thread-sleep-delay",
9326
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
8923
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9327
8924
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9328
8925
  context("data-file-path",
9329
8926
          po::value<string>(),
9334
8931
  context("use-internal-malloc",
9335
8932
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9336
8933
  context("change-buffering",
9337
 
          po::value<string>(&innobase_change_buffering),
 
8934
          po::value<string>(),
9338
8935
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9339
8936
  context("read-ahead-threshold",
9340
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
8937
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9341
8938
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9342
8939
  context("disable-xa",
9343
8940
          "Disable InnoDB support for the XA two-phase commit");
9344
8941
  context("disable-table-locks",
9345
8942
          "Disable InnoDB locking in LOCK TABLES");
9346
8943
  context("strict-mode",
9347
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
8944
          po::value<bool>()->default_value(false)->zero_tokens(),
9348
8945
          "Use strict mode when evaluating create options.");
9349
 
  context("replication-log",
9350
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9351
 
          _("Enable internal replication log."));
9352
8946
  context("lock-wait-timeout",
9353
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9354
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9355
 
  context("old-blocks-pct",
9356
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9357
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9358
 
  context("old-blocks-time",
9359
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9360
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9361
 
            " was at least this many milliseconds ago."
9362
 
            " The timeout is disabled if 0 (the default)."));
 
8947
          po::value<unsigned long>()->default_value(50),
 
8948
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9363
8949
}
9364
8950
 
9365
 
 
 
8951
static drizzle_sys_var* innobase_system_variables[]= {
 
8952
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
8953
  DRIZZLE_SYSVAR(autoextend_increment),
 
8954
  DRIZZLE_SYSVAR(buffer_pool_size),
 
8955
  DRIZZLE_SYSVAR(checksums),
 
8956
  DRIZZLE_SYSVAR(commit_concurrency),
 
8957
  DRIZZLE_SYSVAR(concurrency_tickets),
 
8958
  DRIZZLE_SYSVAR(data_file_path),
 
8959
  DRIZZLE_SYSVAR(data_home_dir),
 
8960
  DRIZZLE_SYSVAR(doublewrite),
 
8961
  DRIZZLE_SYSVAR(fast_shutdown),
 
8962
  DRIZZLE_SYSVAR(read_io_threads),
 
8963
  DRIZZLE_SYSVAR(write_io_threads),
 
8964
  DRIZZLE_SYSVAR(file_per_table),
 
8965
  DRIZZLE_SYSVAR(file_format),
 
8966
  DRIZZLE_SYSVAR(file_format_check),
 
8967
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
8968
  DRIZZLE_SYSVAR(flush_method),
 
8969
  DRIZZLE_SYSVAR(force_recovery),
 
8970
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
8971
#ifdef UNIV_LOG_ARCHIVE
 
8972
  DRIZZLE_SYSVAR(log_arch_dir),
 
8973
  DRIZZLE_SYSVAR(log_archive),
 
8974
#endif /* UNIV_LOG_ARCHIVE */
 
8975
  DRIZZLE_SYSVAR(log_buffer_size),
 
8976
  DRIZZLE_SYSVAR(log_file_size),
 
8977
  DRIZZLE_SYSVAR(log_files_in_group),
 
8978
  DRIZZLE_SYSVAR(log_group_home_dir),
 
8979
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
8980
  DRIZZLE_SYSVAR(max_purge_lag),
 
8981
  DRIZZLE_SYSVAR(adaptive_flushing),
 
8982
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
8983
  DRIZZLE_SYSVAR(open_files),
 
8984
  DRIZZLE_SYSVAR(stats_on_metadata),
 
8985
  DRIZZLE_SYSVAR(stats_sample_pages),
 
8986
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
8987
  DRIZZLE_SYSVAR(replication_delay),
 
8988
  DRIZZLE_SYSVAR(status_file),
 
8989
  DRIZZLE_SYSVAR(strict_mode),
 
8990
  DRIZZLE_SYSVAR(support_xa),
 
8991
  DRIZZLE_SYSVAR(sync_spin_loops),
 
8992
  DRIZZLE_SYSVAR(spin_wait_delay),
 
8993
  DRIZZLE_SYSVAR(table_locks),
 
8994
  DRIZZLE_SYSVAR(thread_concurrency),
 
8995
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
8996
  DRIZZLE_SYSVAR(version),
 
8997
  DRIZZLE_SYSVAR(use_sys_malloc),
 
8998
  DRIZZLE_SYSVAR(change_buffering),
 
8999
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9000
  DRIZZLE_SYSVAR(io_capacity),
 
9001
  NULL
 
9002
};
9366
9003
 
9367
9004
DRIZZLE_DECLARE_PLUGIN
9368
9005
{
9373
9010
  "Supports transactions, row-level locking, and foreign keys",
9374
9011
  PLUGIN_LICENSE_GPL,
9375
9012
  innobase_init, /* Plugin Init */
9376
 
  NULL, /* system variables */
 
9013
  innobase_system_variables, /* system variables */
9377
9014
  init_options /* reserved */
9378
9015
}
9379
9016
DRIZZLE_DECLARE_PLUGIN_END;
9401
9038
  return res;
9402
9039
}
9403
9040
 
9404
 
/***********************************************************************
9405
 
This function checks each index name for a table against reserved
9406
 
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9407
 
this function pushes an warning message to the client, and returns true. */
9408
 
extern "C" UNIV_INTERN
9409
 
bool
9410
 
innobase_index_name_is_reserved(
9411
 
/*============================*/
9412
 
                                        /* out: true if an index name
9413
 
                                        matches the reserved name */
9414
 
        const trx_t*    trx,            /* in: InnoDB transaction handle */
9415
 
        const KeyInfo*  key_info,       /* in: Indexes to be created */
9416
 
        ulint           num_of_keys)    /* in: Number of indexes to
9417
 
                                        be created. */
 
9041
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9042
 
 
9043
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9044
from zero to nonzero. (Bug #42101)
 
9045
 
 
9046
The initial default value is 0, and without this extra initialization,
 
9047
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9048
to 0, even if it was initially set to nonzero at the command line
 
9049
or configuration file. */
 
9050
static
 
9051
void
 
9052
innobase_commit_concurrency_init_default(void)
 
9053
/*==========================================*/
9418
9054
{
9419
 
  const KeyInfo*        key;
9420
 
  uint          key_num;        /* index number */
9421
 
 
9422
 
  for (key_num = 0; key_num < num_of_keys; key_num++) {
9423
 
    key = &key_info[key_num];
9424
 
 
9425
 
    if (innobase_strcasecmp(key->name,
9426
 
                            innobase_index_reserve_name) == 0) {
9427
 
      /* Push warning to drizzle */
9428
 
      push_warning_printf((Session*)trx->mysql_thd,
9429
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9430
 
                          ER_WRONG_NAME_FOR_INDEX,
9431
 
                          "Cannot Create Index with name "
9432
 
                          "'%s'. The name is reserved "
9433
 
                          "for the system default primary "
9434
 
                          "index.",
9435
 
                          innobase_index_reserve_name);
9436
 
 
9437
 
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
9438
 
               innobase_index_reserve_name);
9439
 
 
9440
 
      return(true);
9441
 
    }
9442
 
  }
9443
 
 
9444
 
  return(false);
 
9055
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9056
    = innobase_commit_concurrency;
9445
9057
}
9446
9058
 
9447
9059
#ifdef UNIV_COMPILE_TEST_FUNCS