~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: lbieber
  • Date: 2010-10-02 14:36:07 UTC
  • mfrom: (1799.7.7 drizzle-bug-649844)
  • mto: This revision was merged to the branch mainline in revision 1809.
  • Revision ID: lbieber@orisndriz08-20101002143607-fffgvc6l4gw9drmm
Merge Andrew - fix bug 649844 - Clean up and fix some drizzledump options along with some documentation fixes

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.
26
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27
19
 
28
20
You should have received a copy of the GNU General Public License along with
29
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
30
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
22
Place, Suite 330, Boston, MA 02111-1307 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
59 Temple Place, Suite 330, Boston, MA 02111-1307 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
72
90
 
73
91
#include <boost/algorithm/string.hpp>
74
92
#include <boost/program_options.hpp>
75
 
#include <boost/filesystem.hpp>
76
93
#include <drizzled/module/option_map.h>
77
94
#include <iostream>
78
95
 
79
96
namespace po= boost::program_options;
80
 
namespace fs=boost::filesystem;
81
97
using namespace std;
82
98
 
83
99
/** @file ha_innodb.cc */
85
101
/* Include necessary InnoDB headers */
86
102
extern "C" {
87
103
#include "univ.i"
88
 
#include "buf0lru.h"
89
104
#include "btr0sea.h"
90
105
#include "os0file.h"
91
106
#include "os0thread.h"
102
117
#include "log0log.h"
103
118
#include "lock0lock.h"
104
119
#include "dict0crea.h"
105
 
#include "create_replication.h"
106
120
#include "btr0cur.h"
107
121
#include "btr0btr.h"
108
122
#include "fsp0fsp.h"
120
134
 
121
135
#include "ha_innodb.h"
122
136
#include "data_dictionary.h"
123
 
#include "replication_dictionary.h"
124
137
#include "internal_dictionary.h"
125
138
#include "handler0vars.h"
126
139
 
129
142
#include <string>
130
143
 
131
144
#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
145
 
139
146
using namespace std;
140
147
using namespace drizzled;
141
148
 
 
149
#ifndef DRIZZLE_SERVER
 
150
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
 
151
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
 
152
extern pthread_mutex_t LOCK_thread_count;
 
153
 
 
154
#endif /* DRIZZLE_SERVER */
 
155
 
142
156
/** to protect innobase_open_files */
143
157
static pthread_mutex_t innobase_share_mutex;
144
158
/** to force correct commit order in binlog */
170
184
static plugin::TableFunction* innodb_trx_tool= NULL;
171
185
static plugin::TableFunction* innodb_locks_tool= NULL;
172
186
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;
 
187
 
 
188
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
189
  innobase_log_buffer_size,
 
190
  innobase_force_recovery, innobase_open_files;
 
191
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
192
static ulong innobase_commit_concurrency = 0;
 
193
static ulong innobase_read_io_threads;
 
194
static ulong innobase_write_io_threads;
 
195
 
 
196
/**
 
197
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
198
 */
 
199
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
200
static int64_t innobase_log_file_size;
238
201
 
239
202
/* The default values for the following char* start-up parameters
240
203
are determined in innobase_init below: */
241
204
 
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;
 
205
static char*  innobase_data_home_dir      = NULL;
 
206
static char*  innobase_data_file_path     = NULL;
 
207
static char*  innobase_log_group_home_dir   = NULL;
 
208
static char*  innobase_file_format_name   = NULL;
 
209
static char*  innobase_change_buffering   = NULL;
 
210
 
 
211
/* Note: This variable can be set to on/off and any of the supported
 
212
file formats in the configuration file, but can only be set to any
 
213
of the supported file formats during runtime. */
 
214
static char*  innobase_file_format_check    = NULL;
 
215
 
 
216
/* The following has a misleading name: starting from 4.0.5, this also
 
217
affects Windows: */
 
218
static char*  innobase_unix_file_flush_method   = NULL;
252
219
 
253
220
/* Below we have boolean-valued start-up parameters, and their default
254
221
values */
255
222
 
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;
 
223
static ulong  innobase_fast_shutdown      = 1;
 
224
#ifdef UNIV_LOG_ARCHIVE
 
225
static my_bool  innobase_log_archive      = FALSE;
 
226
static char*  innobase_log_arch_dir     = NULL;
 
227
#endif /* UNIV_LOG_ARCHIVE */
272
228
static my_bool  innobase_use_doublewrite    = TRUE;
273
229
static my_bool  innobase_use_checksums      = TRUE;
274
230
static my_bool  innobase_rollback_on_timeout    = FALSE;
275
231
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;
 
232
static my_bool  innobase_stats_on_metadata    = TRUE;
281
233
 
282
234
static char*  internal_innobase_data_file_path  = NULL;
283
235
 
 
236
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
237
 
284
238
/* The following counter is used to convey information to InnoDB
285
239
about server activity: in selects it is not sensible to call
286
240
srv_active_wake_master_thread after each fetch or search, we only do
298
252
/** Allowed values of innodb_change_buffering */
299
253
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
300
254
  "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 */
 
255
  "inserts" /* IBUF_USE_INSERT */
306
256
};
307
257
 
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
258
/********************************************************************
313
259
Gives the file extension of an InnoDB single-table tablespace. */
314
260
static const char* ha_innobase_exts[] = {
360
306
    }
361
307
    
362
308
    /* These get strdup'd from vm variables */
 
309
    free(innobase_data_home_dir);
363
310
 
364
311
  }
365
312
 
390
337
  {
391
338
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
392
339
  }
393
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
394
 
  virtual uint64_t doGetNewTransactionId(Session *session);
395
340
  virtual int doCommit(Session* session, bool all);
396
341
  virtual int doRollback(Session* session, bool all);
397
342
 
435
380
        /* out: 0 or error number */
436
381
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
437
382
 
438
 
  virtual Cursor *create(Table &table)
 
383
  virtual Cursor *create(TableShare &table)
439
384
  {
440
385
    return new ha_innobase(*this, table);
441
386
  }
514
459
 
515
460
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
461
                             const drizzled::SchemaIdentifier &schema_identifier,
517
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
462
                             drizzled::TableIdentifiers &set_of_identifiers);
518
463
  bool validateCreateTableOption(const std::string &key, const std::string &state);
519
464
  void dropTemporarySchema();
520
465
 
543
488
 
544
489
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
490
                                           const drizzled::SchemaIdentifier &schema_identifier,
546
 
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
 
491
                                           drizzled::TableIdentifiers &set_of_identifiers)
547
492
{
548
493
  CachedDirectory::Entries entries= directory.getEntries();
549
494
 
562
507
    { }
563
508
    else
564
509
    {
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
 
      }
 
510
      char uname[NAME_LEN + 1];
 
511
      uint32_t file_name_len;
 
512
 
 
513
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
514
      // TODO: Remove need for memory copy here
 
515
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
516
 
 
517
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
580
518
    }
581
519
  }
582
520
}
586
524
  string proto_path(identifier.getPath());
587
525
  proto_path.append(DEFAULT_FILE_EXTENSION);
588
526
 
589
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
 
527
  if (session.doesTableMessageExist(identifier))
590
528
    return true;
591
529
 
592
530
  if (access(proto_path.c_str(), F_OK))
605
543
  proto_path.append(DEFAULT_FILE_EXTENSION);
606
544
 
607
545
  // First we check the temporary tables.
608
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
546
  if (session.getTableMessage(identifier, table_proto))
609
547
    return EEXIST;
610
548
 
611
549
  if (access(proto_path.c_str(), F_OK))
619
557
  return ENOENT;
620
558
}
621
559
 
 
560
/** @brief Initialize the default value of innodb_commit_concurrency.
 
561
 
 
562
Once InnoDB is running, the innodb_commit_concurrency must not change
 
563
from zero to nonzero. (Bug #42101)
 
564
 
 
565
The initial default value is 0, and without this extra initialization,
 
566
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
567
to 0, even if it was initially set to nonzero at the command line
 
568
or configuration file. */
 
569
static
 
570
void
 
571
innobase_commit_concurrency_init_default(void);
 
572
/*==========================================*/
622
573
 
623
574
/************************************************************//**
624
575
Validate the file format name and return its corresponding id.
631
582
            name */
632
583
/************************************************************//**
633
584
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(
 
585
sets the srv_check_file_format_at_startup variable.
 
586
@return true if one of  "on" or "off" */
 
587
static
 
588
bool
 
589
innobase_file_format_check_on_off(
 
590
/*==============================*/
 
591
  const char* format_check);    /*!< in: parameter value */
 
592
/************************************************************//**
 
593
Validate the file format check config parameters, as a side effect it
 
594
sets the srv_check_file_format_at_startup variable.
 
595
@return true if valid config value */
 
596
static
 
597
bool
 
598
innobase_file_format_check_validate(
639
599
/*================================*/
640
 
  const char* format_max);    /*!< in: parameter value */
 
600
  const char* format_check);    /*!< in: parameter value */
641
601
 
642
602
static const char innobase_engine_name[]= "InnoDB";
643
603
 
 
604
/*************************************************************//**
 
605
Check for a valid value of innobase_commit_concurrency.
 
606
@return 0 for valid innodb_commit_concurrency */
 
607
static
 
608
int
 
609
innobase_commit_concurrency_validate(
 
610
/*=================================*/
 
611
  Session*      , /*!< in: thread handle */
 
612
  drizzle_sys_var*  , /*!< in: pointer to system
 
613
            variable */
 
614
  void*       save, /*!< out: immediate result
 
615
            for update function */
 
616
  drizzle_value*    value)  /*!< in: incoming string */
 
617
{
 
618
  int64_t   intbuf;
 
619
  ulong   commit_concurrency;
 
620
 
 
621
  if (value->val_int(value, &intbuf)) {
 
622
    /* The value is NULL. That is invalid. */
 
623
    return(1);
 
624
  }
 
625
 
 
626
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
627
    = static_cast<ulong>(intbuf);
 
628
 
 
629
  /* Allow the value to be updated, as long as it remains zero
 
630
  or nonzero. */
 
631
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
632
}
 
633
 
 
634
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
635
  "Enable InnoDB support for the XA two-phase commit",
 
636
  /* check_func */ NULL, /* update_func */ NULL,
 
637
  /* default */ TRUE);
 
638
 
 
639
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
640
  "Enable InnoDB locking in LOCK TABLES",
 
641
  /* check_func */ NULL, /* update_func */ NULL,
 
642
  /* default */ TRUE);
 
643
 
 
644
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
645
  "Use strict mode when evaluating create options.",
 
646
  NULL, NULL, FALSE);
 
647
 
 
648
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
649
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
650
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
651
 
644
652
 
645
653
/*****************************************************************//**
646
654
Commits a transaction in an InnoDB database. */
667
675
  (char*) &export_vars.innodb_buffer_pool_pages_misc,   SHOW_LONG},
668
676
  {"buffer_pool_pages_total",
669
677
  (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},
 
678
  {"buffer_pool_read_ahead_rnd",
 
679
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
 
680
  {"buffer_pool_read_ahead_seq",
 
681
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
674
682
  {"buffer_pool_read_requests",
675
683
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
676
684
  {"buffer_pool_reads",
907
915
ibool
908
916
thd_supports_xa(
909
917
/*============*/
910
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
918
  void* session)  /*!< in: thread handle (Session*), or NULL to query
911
919
        the global innodb_supports_xa */
912
920
{
913
 
  /* TODO: Add support here for per-session value */
914
 
  return(support_xa);
 
921
  return(SessionVAR((Session*) session, support_xa));
915
922
}
916
923
 
917
924
/******************************************************************//**
921
928
ulong
922
929
thd_lock_wait_timeout(
923
930
/*==================*/
924
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
931
  void* session)  /*!< in: thread handle (Session*), or NULL to query
925
932
      the global innodb_lock_wait_timeout */
926
933
{
927
 
  /* TODO: Add support here for per-session value */
928
934
  /* According to <drizzle/plugin.h>, passing session == NULL
929
935
  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
 
        }
 
936
  return(SessionVAR((Session*) session, lock_wait_timeout));
945
937
}
946
938
 
947
939
/********************************************************************//**
956
948
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
957
949
}
958
950
 
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
951
/********************************************************************//**
979
952
Call this function when mysqld passes control to the client. That is to
980
953
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1036
1009
  case DB_SUCCESS:
1037
1010
    return(0);
1038
1011
 
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
1012
  case DB_ERROR:
1055
1013
  default:
1056
1014
    return(-1); /* unspecified error */
1057
1015
 
1058
1016
  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
1017
    return(HA_ERR_FOUND_DUPP_KEY);
1066
1018
 
1067
1019
  case DB_FOREIGN_DUPLICATE_KEY:
1148
1100
    and the actual error code name could very well be different.
1149
1101
    This will require some monitoring, ie. the status
1150
1102
    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 */
 
1103
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
 
1104
    return(ER_TOO_MANY_CONCURRENT_TRXS);
 
1105
#else
1160
1106
    return(HA_ERR_RECORD_FILE_FULL);
1161
 
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1107
#endif
1162
1108
  case DB_UNSUPPORTED:
1163
1109
    return(HA_ERR_UNSUPPORTED);
1164
1110
  }
1165
1111
}
1166
1112
 
1167
1113
 
 
1114
 
 
1115
/*************************************************************//**
 
1116
If you want to print a session that is not associated with the current thread,
 
1117
you must call this function before reserving the InnoDB kernel_mutex, to
 
1118
protect Drizzle from setting session->query NULL. If you print a session of the
 
1119
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1120
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1121
after you release the kernel_mutex.
 
1122
 
 
1123
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1124
         in non-Cursor code.
 
1125
 */
 
1126
extern "C" UNIV_INTERN
 
1127
void
 
1128
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1129
/*============================================*/
 
1130
{
 
1131
  ut_ad(!mutex_own(&kernel_mutex));
 
1132
  LOCK_thread_count.lock();
 
1133
}
 
1134
 
 
1135
/*************************************************************//**
 
1136
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1137
In the InnoDB latching order, the mutex sits right above the
 
1138
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1139
released before this function is invoked. 
 
1140
 
 
1141
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1142
         in non-Cursor code.
 
1143
*/
 
1144
extern "C" UNIV_INTERN
 
1145
void
 
1146
innobase_mysql_end_print_arbitrary_thd(void)
 
1147
/*========================================*/
 
1148
{
 
1149
  ut_ad(!mutex_own(&kernel_mutex));
 
1150
  LOCK_thread_count.unlock();
 
1151
}
 
1152
 
1168
1153
/*************************************************************//**
1169
1154
Prints info of a Session object (== user session thread) to the given file. */
1170
1155
extern "C" UNIV_INTERN
1185
1170
          session->getSecurityContext().getIp().c_str(),
1186
1171
          session->getSecurityContext().getUser().c_str()
1187
1172
  );
1188
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1173
  fprintf(f,
 
1174
          "\n%s", session->getQueryString().c_str()
 
1175
  );
1189
1176
  putc('\n', f);
1190
1177
}
1191
1178
 
1208
1195
  if (cs) {
1209
1196
    *mbminlen = cs->mbminlen;
1210
1197
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1198
  } else {
1214
1199
    ut_a(cset == 0);
1215
1200
    *mbminlen = *mbmaxlen = 0;
1277
1262
/*=================*/
1278
1263
  void* mysql_session)  /*!< in: MySQL thread handle */
1279
1264
{
1280
 
  return static_cast<Session*>(mysql_session)->charset();
 
1265
  return session_charset(static_cast<Session*>(mysql_session));
1281
1266
}
1282
1267
 
1283
1268
extern "C" UNIV_INTERN
1297
1282
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1298
1283
}
1299
1284
 
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
1285
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1314
1286
/*******************************************************************//**
1315
1287
Map an OS error to an errno value. The OS error number is stored in
1575
1547
  trx = trx_allocate_for_mysql();
1576
1548
 
1577
1549
  trx->mysql_thd = session;
 
1550
  trx->mysql_query_str = session->query.c_str();
1578
1551
 
1579
1552
  innobase_trx_init(session, trx);
1580
1553
 
1613
1586
Construct ha_innobase Cursor. */
1614
1587
UNIV_INTERN
1615
1588
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1616
 
                         Table &table_arg)
 
1589
                         TableShare &table_arg)
1617
1590
  :Cursor(engine_arg, table_arg),
1618
1591
  primary_key(0), /* needs initialization because index_flags() may be called 
1619
1592
                     before this is set to the real value. It's ok to have any 
1804
1777
/*===============*/
1805
1778
  trx_t*  trx)  /*!< in: transaction */
1806
1779
{
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);
 
1780
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1821
1781
}
1822
1782
 
1823
1783
/**************************************************************//**
1839
1799
  value= value - (value % align_val);
1840
1800
}
1841
1801
 
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
1802
/*********************************************************************//**
2041
1803
Opens an InnoDB database.
2042
1804
@return 0 on success, error code on failure */
2052
1814
  InnobaseEngine *actuall_engine_ptr;
2053
1815
  const module::option_map &vm= context.getOptions();
2054
1816
 
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
1817
  /* Inverted Booleans */
2072
1818
 
2073
1819
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2074
1820
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2075
1821
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
 
1822
  innobase_stats_on_metadata= (vm.count("disable-stats-on-metadata")) ? false : true;
2076
1823
  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 */
 
1824
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1825
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1826
 
 
1827
  if (vm.count("io-capacity"))
 
1828
  {
 
1829
    if (srv_io_capacity < 100)
 
1830
    {
 
1831
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1832
      exit(-1);
 
1833
    }
 
1834
  }
 
1835
 
2082
1836
  if (vm.count("data-home-dir"))
2083
1837
  {
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
 
 
 
1838
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1839
  }
 
1840
  else
 
1841
  {
 
1842
    innobase_data_home_dir= strdup(getDataHome().c_str());
 
1843
  }
 
1844
 
 
1845
  if (vm.count("fast-shutdown"))
 
1846
  {
 
1847
    if (innobase_fast_shutdown > 2)
 
1848
    {
 
1849
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1850
      exit(-1);
 
1851
    }
 
1852
  }
 
1853
 
 
1854
  if (vm.count("file-format-check"))
 
1855
  {
 
1856
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1857
  }
 
1858
 
 
1859
  if (vm.count("flush-log-at-trx-commit"))
 
1860
  {
 
1861
    if (srv_flush_log_at_trx_commit > 2)
 
1862
    {
 
1863
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1864
      exit(-1);
 
1865
    }
 
1866
  }
 
1867
 
 
1868
  if (vm.count("flush-method"))
 
1869
  {
 
1870
    innobase_unix_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1871
  }
 
1872
  else
 
1873
  {
 
1874
    innobase_unix_file_flush_method= NULL;
 
1875
  }
 
1876
 
 
1877
#ifdef UNIV_LOG_ARCHIVE
 
1878
  if (vm.count("log-arch-dir"))
 
1879
  {
 
1880
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1881
  }
 
1882
 
 
1883
  else
 
1884
  {
 
1885
    innobase_log_arch_dir= NULL;
 
1886
  }
 
1887
#endif /* UNIV_LOG_ARCHIVE */
 
1888
 
 
1889
  if (vm.count("max-dirty-pages-pct"))
 
1890
  {
 
1891
    if (srv_max_buf_pool_modified_pct > 99)
 
1892
    {
 
1893
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1894
      exit(-1);
 
1895
    }
 
1896
  }
 
1897
 
 
1898
  if (vm.count("stats-sample-pages"))
 
1899
  {
 
1900
    if (srv_stats_sample_pages < 8)
 
1901
    {
 
1902
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1903
      exit(-1);
 
1904
    }
 
1905
  }
 
1906
 
 
1907
  if (vm.count("additional-mem-pool-size"))
 
1908
  {
 
1909
    align_value(innobase_additional_mem_pool_size);
 
1910
 
 
1911
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1912
    {
 
1913
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1914
      exit(-1);
 
1915
    }
 
1916
 
 
1917
  }
 
1918
 
 
1919
  if (vm.count("autoextend-increment"))
 
1920
  {
 
1921
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1922
    {
 
1923
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1924
      exit(-1);
 
1925
    }
 
1926
  }
 
1927
 
 
1928
  if (vm.count("buffer-pool-size"))
 
1929
  {
 
1930
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1931
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1932
    {
 
1933
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1934
      exit(-1);
 
1935
    }
 
1936
    
 
1937
  }
 
1938
 
 
1939
  if (vm.count("commit-concurrency"))
 
1940
  {
 
1941
    if (srv_replication_delay > 1000)
 
1942
    {
 
1943
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1944
      exit(-1);
 
1945
    }
 
1946
  }
 
1947
 
 
1948
  if (vm.count("concurrency-tickets"))
 
1949
  {
 
1950
    if (srv_n_free_tickets_to_enter < 1)
 
1951
    {
 
1952
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1953
      exit(-1);
 
1954
    }
 
1955
  }
 
1956
 
 
1957
  if (vm.count("read-io-threads"))
 
1958
  {
 
1959
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1960
    {
 
1961
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1962
      exit(-1);
 
1963
    }
 
1964
  }
 
1965
 
 
1966
  if (vm.count("write-io-threads"))
 
1967
  {
 
1968
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1969
    {
 
1970
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1971
      exit(-1);
 
1972
    }
 
1973
  }
 
1974
 
 
1975
  if (vm.count("force-recovery"))
 
1976
  {
 
1977
    if (innobase_force_recovery > 6)
 
1978
    {
 
1979
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
1980
      exit(-1);
 
1981
    }
 
1982
  }
 
1983
 
 
1984
  if (vm.count("log-buffer-size"))
 
1985
  {
 
1986
    align_value(innobase_log_buffer_size);
 
1987
    if (innobase_log_buffer_size < 256*1024L)
 
1988
    {
 
1989
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1990
      exit(-1);
 
1991
    }
 
1992
  }
 
1993
 
 
1994
  if (vm.count("log-file-size"))
 
1995
  {
 
1996
    align_value(innobase_log_file_size, 1024*1024);
 
1997
    if (innobase_log_file_size < 1*1024*1024L)
 
1998
    {
 
1999
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2000
      exit(-1);
 
2001
    }
 
2002
  }
 
2003
 
 
2004
  if (vm.count("log-files-in-group"))
 
2005
  {
 
2006
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2007
    {
 
2008
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2009
      exit(-1);
 
2010
    }
 
2011
  }
 
2012
 
 
2013
  if (vm.count("mirrored-log-groups"))
 
2014
  {
 
2015
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2016
    {
 
2017
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2018
      exit(-1);
 
2019
    }
 
2020
  }
 
2021
 
 
2022
  if (vm.count("open-files"))
 
2023
  {
 
2024
    if (innobase_open_files < 10)
 
2025
    {
 
2026
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2027
      exit(-1);
 
2028
    }
 
2029
  }
 
2030
 
 
2031
  if (vm.count("thread-concurrency"))
 
2032
  {
 
2033
    if (srv_thread_concurrency > 1000)
 
2034
    {
 
2035
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2036
      exit(-1);
 
2037
    }
 
2038
  }
2091
2039
 
2092
2040
  if (vm.count("data-file-path"))
2093
2041
  {
2094
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2095
 
  }
2096
 
 
 
2042
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2043
  }
 
2044
  else
 
2045
  {
 
2046
    innobase_data_file_path= NULL;
 
2047
  }
 
2048
 
 
2049
  if (vm.count("version"))
 
2050
  {
 
2051
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2052
  }
 
2053
 
 
2054
  if (vm.count("read-ahead-threshold"))
 
2055
  {
 
2056
    if (srv_read_ahead_threshold > 64)
 
2057
    {
 
2058
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2059
      exit(-1);
 
2060
    }
 
2061
  }
 
2062
 
 
2063
  if (vm.count("strict-mode"))
 
2064
  {
 
2065
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2066
  }
 
2067
 
 
2068
  if (vm.count("lock-wait-timeout"))
 
2069
  {
 
2070
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2071
    {
 
2072
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2073
      exit(-1);
 
2074
    }
 
2075
 
 
2076
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2077
  }
2097
2078
 
2098
2079
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2099
2080
 
2117
2098
  }
2118
2099
#endif /* UNIV_DEBUG */
2119
2100
 
 
2101
  /* Check that values don't overflow on 32-bit systems. */
 
2102
  if (sizeof(ulint) == 4) {
 
2103
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2104
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2105
                    "innobase_buffer_pool_size can't be over 4GB"
 
2106
                    " on 32-bit systems");
 
2107
 
 
2108
      goto error;
 
2109
    }
 
2110
 
 
2111
    if (innobase_log_file_size > UINT32_MAX) {
 
2112
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2113
                    "innobase_log_file_size can't be over 4GB"
 
2114
                    " on 32-bit systems");
 
2115
 
 
2116
      goto error;
 
2117
    }
 
2118
  }
 
2119
 
2120
2120
  os_innodb_umask = (ulint)internal::my_umask;
2121
2121
 
2122
2122
 
2127
2127
 
2128
2128
  /* The default dir for data files is the datadir of MySQL */
2129
2129
 
2130
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2130
  srv_data_home = (char *)innobase_data_home_dir;
2131
2131
 
2132
2132
  /* Set default InnoDB data file size to 10 MB and let it be
2133
2133
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2134
2134
    to specify any startup options. */
2135
2135
 
2136
 
  if (innobase_data_file_path.empty()) 
2137
 
  {
2138
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2136
  if (!innobase_data_file_path) {
 
2137
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2139
2138
  }
2140
2139
 
2141
2140
  /* Since InnoDB edits the argument in the next call, we make another
2142
2141
    copy of it: */
2143
2142
 
2144
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2143
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2145
2144
 
2146
2145
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2147
2146
                                                   internal_innobase_data_file_path);
2161
2160
 
2162
2161
  if (vm.count("log-group-home-dir"))
2163
2162
  {
2164
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2163
    innobase_log_group_home_dir= const_cast<char *>(vm["log-group-home-dir"].as<string>().c_str());
2165
2164
  }
2166
2165
  else
2167
2166
  {
2168
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2167
    innobase_log_group_home_dir = const_cast<char *>(getDataHome().c_str());
2169
2168
  }
2170
2169
 
 
2170
#ifdef UNIV_LOG_ARCHIVE
 
2171
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2172
    starting from 4.0.6 we always set it the same as
 
2173
innodb_log_group_home_dir: */
 
2174
 
 
2175
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2176
 
 
2177
  srv_arch_dir = innobase_log_arch_dir;
 
2178
#endif /* UNIG_LOG_ARCHIVE */
 
2179
 
2171
2180
  ret = (bool)
2172
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2181
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2173
2182
 
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"));
 
2183
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2184
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2185
                  "wrong number of mirrored log groups");
2178
2186
 
2179
2187
    goto mem_free_and_error;
2180
2188
  }
2199
2207
 
2200
2208
  srv_file_format = format_id;
2201
2209
 
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;
 
2210
  /* Given the type of innobase_file_format_name we have little
 
2211
    choice but to cast away the constness from the returned name.
 
2212
    innobase_file_format_name is used in the MySQL set variable
 
2213
    interface and so can't be const. */
 
2214
 
 
2215
  innobase_file_format_name = 
 
2216
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2217
 
 
2218
  /* Process innobase_file_format_check variable */
 
2219
  ut_a(innobase_file_format_check != NULL);
 
2220
 
 
2221
  /* As a side effect it will set srv_check_file_format_at_startup
 
2222
    on valid input. First we check for "on"/"off". */
 
2223
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2224
 
 
2225
    /* Did the user specify a format name that we support ?
 
2226
      As a side effect it will update the variable
 
2227
      srv_check_file_format_at_startup */
 
2228
    if (!innobase_file_format_check_validate(
 
2229
                                             innobase_file_format_check)) {
 
2230
 
 
2231
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2232
                    "innodb_file_format_check value: "
 
2233
                    "should be either 'on' or 'off' or "
 
2234
                    "any value up to %s or its "
 
2235
                    "equivalent numeric id",
 
2236
                    trx_sys_file_format_id_to_name(
 
2237
                                                   DICT_TF_FORMAT_MAX));
 
2238
 
 
2239
      goto mem_free_and_error;
 
2240
    }
2226
2241
  }
2227
2242
 
2228
2243
  if (vm.count("change-buffering"))
2233
2248
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2234
2249
         use++) {
2235
2250
      if (!innobase_strcasecmp(
2236
 
                               innobase_change_buffering.c_str(),
 
2251
                               vm["change-buffering"].as<string>().c_str(),
2237
2252
                               innobase_change_buffering_values[use])) {
2238
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2253
        ibuf_use = (ibuf_use_t) use;
2239
2254
        goto innobase_change_buffering_inited_ok;
2240
2255
      }
2241
2256
    }
2242
2257
 
2243
2258
    errmsg_printf(ERRMSG_LVL_ERROR,
2244
2259
                  "InnoDB: invalid value "
2245
 
                  "innodb_change_buffering=%s",
 
2260
                  "innodb_file_format_check=%s",
2246
2261
                  vm["change-buffering"].as<string>().c_str());
2247
2262
    goto mem_free_and_error;
2248
2263
  }
2249
2264
 
2250
2265
innobase_change_buffering_inited_ok:
2251
2266
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2252
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2267
  innobase_change_buffering = (char*)
 
2268
    innobase_change_buffering_values[ibuf_use];
2253
2269
 
2254
2270
  /* --------------------------------------------------*/
2255
2271
 
2256
 
  if (vm.count("flush-method") != 0)
2257
 
  {
2258
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2259
 
  }
 
2272
  srv_file_flush_method_str = innobase_unix_file_flush_method;
2260
2273
 
2261
2274
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2262
2275
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2263
2276
  srv_log_file_size = (ulint) innobase_log_file_size;
2264
2277
 
 
2278
#ifdef UNIV_LOG_ARCHIVE
 
2279
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2280
#endif /* UNIV_LOG_ARCHIVE */
2265
2281
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2266
2282
 
2267
2283
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2268
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2269
2284
 
2270
2285
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2271
2286
 
2296
2311
 
2297
2312
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2298
2313
 
 
2314
 
 
2315
  innobase_commit_concurrency_init_default();
 
2316
 
2299
2317
  /* Since we in this module access directly the fields of a trx
2300
2318
    struct, and due to different headers and flags it might happen that
2301
2319
    mutex_t has a different size in this module and in InnoDB
2304
2322
 
2305
2323
  err = innobase_start_or_create_for_mysql();
2306
2324
 
2307
 
  if (err != DB_SUCCESS)
2308
 
  {
2309
 
    goto mem_free_and_error;
2310
 
  }
2311
 
 
2312
 
  err = dict_create_sys_replication_log();
2313
 
 
2314
2325
  if (err != DB_SUCCESS) {
2315
2326
    goto mem_free_and_error;
2316
2327
  }
2317
2328
 
2318
 
 
2319
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2320
 
                                                     TRUE);
2321
 
 
2322
2329
  innobase_open_tables = hash_create(200);
2323
2330
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2324
2331
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2356
2363
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2357
2364
  context.add(innodb_lock_waits_tool);
2358
2365
 
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
2366
  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));
 
2367
 
2471
2368
  /* 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);
 
2369
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2474
2370
 
2475
2371
  return(FALSE);
2476
2372
error:
2579
2475
    Note, the position is current because of
2580
2476
    prepare_commit_mutex */
2581
2477
retry:
2582
 
    if (innobase_commit_concurrency.get() > 0) {
 
2478
    if (innobase_commit_concurrency > 0) {
2583
2479
      pthread_mutex_lock(&commit_cond_m);
2584
2480
      commit_threads++;
2585
2481
 
2586
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
2482
      if (commit_threads > innobase_commit_concurrency) {
2587
2483
        commit_threads--;
2588
2484
        pthread_cond_wait(&commit_cond,
2589
2485
          &commit_cond_m);
2608
2504
    innobase_commit_low(trx);
2609
2505
    trx->flush_log_later = FALSE;
2610
2506
 
2611
 
    if (innobase_commit_concurrency.get() > 0) {
 
2507
    if (innobase_commit_concurrency > 0) {
2612
2508
      pthread_mutex_lock(&commit_cond_m);
2613
2509
      commit_threads--;
2614
2510
      pthread_cond_signal(&commit_cond);
2632
2528
    SQL statement */
2633
2529
 
2634
2530
    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
2531
  }
2644
2532
 
2645
2533
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2654
2542
  threads: */
2655
2543
  srv_active_wake_master_thread();
2656
2544
 
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
2545
  return(0);
2666
2546
}
2667
2547
 
2689
2569
 
2690
2570
  innobase_release_stat_resources(trx);
2691
2571
 
2692
 
  trx->n_autoinc_rows = 0;
2693
 
 
2694
2572
  /* If we had reserved the auto-inc lock for some table (if
2695
2573
  we come here to roll back the latest SQL statement) we
2696
2574
  release it now before a possibly lengthy rollback */
2705
2583
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2706
2584
  }
2707
2585
 
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
2586
  return(convert_error_code_to_mysql(error, 0, NULL));
2717
2587
}
2718
2588
 
2849
2719
 
2850
2720
  ut_a(trx);
2851
2721
 
2852
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2722
  assert(session->killed != Session::NOT_KILLED ||
2853
2723
         trx->conc_state == TRX_NOT_STARTED);
2854
2724
 
2855
2725
  /* Warn if rolling back some things... */
2856
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2726
  if (session->killed != Session::NOT_KILLED &&
2857
2727
      trx->conc_state != TRX_NOT_STARTED &&
2858
 
      trx->undo_no > 0 &&
 
2728
      trx->undo_no.low > 0 &&
2859
2729
      global_system_variables.log_warnings)
2860
2730
  {
2861
 
      errmsg_printf(ERRMSG_LVL_WARN,
 
2731
      errmsg_printf(ERRMSG_LVL_WARN, 
2862
2732
      "Drizzle is closing a connection during a KILL operation\n"
2863
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2733
      "that has an active InnoDB transaction.  %lu row modifications will "
2864
2734
      "roll back.\n",
2865
 
      (ullint) trx->undo_no);
 
2735
      (ulong) trx->undo_no.low);
2866
2736
  }
2867
2737
 
2868
2738
  innobase_rollback_trx(trx);
2985
2855
}
2986
2856
 
2987
2857
/********************************************************************//**
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
2858
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. */
 
2859
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2860
@return DB_SUCCESS or error code */
3245
2861
UNIV_INTERN
3246
 
void
 
2862
ulint
3247
2863
ha_innobase::innobase_initialize_autoinc()
3248
2864
/*======================================*/
3249
2865
{
 
2866
  dict_index_t* index;
3250
2867
  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
 
 
 
2868
  const char* col_name;
 
2869
  ulint   error;
 
2870
 
 
2871
  col_name = table->found_next_number_field->field_name;
 
2872
  index = innobase_get_index(table->getShare()->next_number_index);
 
2873
 
 
2874
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2875
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2876
 
 
2877
  switch (error) {
 
2878
  case DB_SUCCESS:
 
2879
 
 
2880
    /* At the this stage we don't know the increment
 
2881
    or the offset, so use default inrement of 1. */
 
2882
    ++auto_inc;
 
2883
    break;
 
2884
 
 
2885
  case DB_RECORD_NOT_FOUND:
3261
2886
    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
 
    }
 
2887
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2888
      "dictionaries are out of sync.\n"
 
2889
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2890
      "InnoDB table %s.\n"
 
2891
      "InnoDB: We set the next AUTOINC column value to the "
 
2892
      "maximum possible value,\n"
 
2893
      "InnoDB: in effect disabling the AUTOINC next value "
 
2894
      "generation.\n"
 
2895
      "InnoDB: You can either set the next AUTOINC value "
 
2896
      "explicitly using ALTER TABLE\n"
 
2897
      "InnoDB: or fix the data dictionary by recreating "
 
2898
      "the table.\n",
 
2899
      col_name, index->table->name);
 
2900
 
 
2901
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2902
    break;
 
2903
 
 
2904
  default:
 
2905
    return(error);
3340
2906
  }
3341
2907
 
3342
2908
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2909
 
 
2910
  return(DB_SUCCESS);
3343
2911
}
3344
2912
 
3345
2913
/*****************************************************************//**
3359
2927
  UT_NOT_USED(mode);
3360
2928
  UT_NOT_USED(test_if_locked);
3361
2929
 
3362
 
  session= getTable()->in_use;
 
2930
  session= table->in_use;
3363
2931
 
3364
2932
  /* Under some cases Drizzle seems to call this function while
3365
2933
  holding btr_search_latch. This breaks the latching order as
3383
2951
  stored the string length as the first byte. */
3384
2952
 
3385
2953
  upd_and_key_val_buff_len =
3386
 
        getTable()->getShare()->stored_rec_length
3387
 
        + getTable()->getShare()->max_key_length
 
2954
        table->getShare()->stored_rec_length
 
2955
        + table->getShare()->max_key_length
3388
2956
        + MAX_REF_PARTS * 3;
3389
2957
 
3390
2958
  upd_buff.resize(upd_and_key_val_buff_len);
3447
3015
 
3448
3016
  prebuilt = row_create_prebuilt(ib_table);
3449
3017
 
3450
 
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3451
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3018
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3019
  prebuilt->default_rec = table->getDefaultValues();
3452
3020
  ut_ad(prebuilt->default_rec);
3453
3021
 
3454
3022
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3455
3023
 
3456
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3024
  primary_key = table->getShare()->getPrimaryKey();
3457
3025
  key_used_on_scan = primary_key;
3458
3026
 
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
3027
  /* Allocate a buffer for a 'row reference'. A row reference is
3465
3028
  a string of bytes of length ref_length which uniquely specifies
3466
3029
  a row in our table. Note that MySQL may also compare two row
3468
3031
  of length ref_length! */
3469
3032
 
3470
3033
  if (!row_table_got_default_clust_index(ib_table)) {
 
3034
    if (primary_key >= MAX_KEY) {
 
3035
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3036
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3037
    }
3471
3038
 
3472
3039
    prebuilt->clust_index_was_generated = FALSE;
3473
3040
 
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
 
    }
 
3041
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3042
    includes space for all key columns + one byte for each column
 
3043
    that may be NULL. ref_length must be as exact as possible to
 
3044
    save space, because all row reference buffers are allocated
 
3045
    based on ref_length. */
 
3046
 
 
3047
    ref_length = table->key_info[primary_key].key_length;
3528
3048
  } else {
3529
3049
    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());
 
3050
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3051
          "dictionary, but has one in MySQL! If you "
 
3052
          "created the table with a MySQL version < "
 
3053
          "3.23.54 and did not define a primary key, "
 
3054
          "but defined a unique key with all non-NULL "
 
3055
          "columns, then MySQL internally treats that "
 
3056
          "key as the primary key. You can fix this "
 
3057
          "error by dump + DROP + CREATE + reimport "
 
3058
          "of the table.", identifier.getTableName().c_str());
3551
3059
    }
3552
3060
 
3553
3061
    prebuilt->clust_index_was_generated = TRUE;
3580
3088
    /* We update the highest file format in the system table
3581
3089
    space, if this table has higher file format setting. */
3582
3090
 
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,
 
3091
    trx_sys_file_format_max_upgrade(
 
3092
      (const char**) &innobase_file_format_check,
3586
3093
      dict_table_get_format(prebuilt->table));
3587
 
    innobase_file_format_max= changed_file_format_max;
3588
3094
  }
3589
3095
 
 
3096
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3097
 
3590
3098
  /* Only if the table has an AUTOINC column. */
3591
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3099
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3100
    ulint error;
3592
3101
 
3593
3102
    dict_table_autoinc_lock(prebuilt->table);
3594
3103
 
3598
3107
    autoinc value from a previous Drizzle open. */
3599
3108
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3600
3109
 
3601
 
      innobase_initialize_autoinc();
 
3110
      error = innobase_initialize_autoinc();
 
3111
      ut_a(error == DB_SUCCESS);
3602
3112
    }
3603
3113
 
3604
3114
    dict_table_autoinc_unlock(prebuilt->table);
3605
3115
  }
3606
3116
 
3607
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3608
 
 
3609
3117
  return(0);
3610
3118
}
3611
3119
 
3626
3134
{
3627
3135
  Session*  session;
3628
3136
 
3629
 
  session= getTable()->in_use;
 
3137
  session= table->in_use;
3630
3138
  if (session != NULL) {
3631
3139
    getTransactionalEngine()->releaseTemporaryLatches(session);
3632
3140
  }
3853
3361
  case DRIZZLE_TYPE_DATETIME:
3854
3362
  case DRIZZLE_TYPE_DATE:
3855
3363
  case DRIZZLE_TYPE_TIMESTAMP:
3856
 
  case DRIZZLE_TYPE_ENUM:
3857
3364
    return(DATA_INT);
3858
3365
  case DRIZZLE_TYPE_DOUBLE:
3859
3366
    return(DATA_DOUBLE);
3860
3367
  case DRIZZLE_TYPE_BLOB:
3861
 
    return(DATA_BLOB);
3862
 
  case DRIZZLE_TYPE_UUID:
3863
 
    return(DATA_FIXBINARY);
3864
 
  case DRIZZLE_TYPE_NULL:
 
3368
                return(DATA_BLOB);
 
3369
  default:
3865
3370
    ut_error;
3866
3371
  }
3867
3372
 
3910
3415
  uint    buff_len,/*!< in: buffer length */
3911
3416
  const unsigned char*  record)/*!< in: row in MySQL format */
3912
3417
{
3913
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3418
  KeyInfo*    key_info  = &table->key_info[keynr];
3914
3419
  KeyPartInfo*  key_part  = key_info->key_part;
3915
3420
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3916
3421
  char*   buff_start  = buff;
3986
3491
 
3987
3492
      data = row_mysql_read_true_varchar(&len,
3988
3493
        (byte*) (record
3989
 
        + (ulint)get_field_offset(getTable(), field)),
 
3494
        + (ulint)get_field_offset(table, field)),
3990
3495
        lenlen);
3991
3496
 
3992
3497
      true_len = len;
4049
3554
 
4050
3555
      blob_data = row_mysql_read_blob_ref(&blob_len,
4051
3556
        (byte*) (record
4052
 
        + (ulint)get_field_offset(getTable(), field)),
 
3557
        + (ulint)get_field_offset(table, field)),
4053
3558
          (ulint) field->pack_length());
4054
3559
 
4055
3560
      true_len = blob_len;
4056
3561
 
4057
 
      ut_a(get_field_offset(getTable(), field)
 
3562
      ut_a(get_field_offset(table, field)
4058
3563
        == key_part->offset);
4059
3564
 
4060
3565
      /* For multi byte character sets we need to calculate
4101
3606
      ulint     key_len;
4102
3607
      const unsigned char*    src_start;
4103
3608
      enum_field_types  real_type;
4104
 
      const CHARSET_INFO* cs= field->charset();
4105
3609
 
4106
3610
      key_len = key_part->length;
4107
3611
 
4123
3627
      memcpy(buff, src_start, true_len);
4124
3628
      buff += true_len;
4125
3629
 
4126
 
      /* Pad the unused space with spaces. */
 
3630
      /* Pad the unused space with spaces. Note that no
 
3631
      padding is ever needed for UCS-2 because in MySQL,
 
3632
      all UCS2 characters are 2 bytes, as MySQL does not
 
3633
      support surrogate pairs, which are needed to represent
 
3634
      characters in the range U+10000 to U+10FFFF. */
4127
3635
 
4128
3636
      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 */);
 
3637
        ulint pad_len = key_len - true_len;
 
3638
        memset(buff, ' ', pad_len);
4134
3639
        buff += pad_len;
4135
3640
      }
4136
3641
    }
4238
3743
 
4239
3744
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4240
3745
  'fields'. */
4241
 
  for (i = 0; i < n_fields; i++)
 
3746
  for (i = 0; i < n_fields; i++) 
4242
3747
  {
4243
 
    const dict_col_t *col= &index->table->cols[i];
4244
3748
    templ = prebuilt->mysql_template + n_requested_fields;
4245
3749
    field = table->getField(i);
4246
3750
 
4288
3792
    templ->col_no = i;
4289
3793
 
4290
3794
    if (index == clust_index) {
4291
 
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
 
3795
      templ->rec_field_no = dict_col_get_clust_pos(
 
3796
        &index->table->cols[i], index);
4292
3797
    } else {
4293
3798
      templ->rec_field_no = dict_index_get_nth_col_pos(
4294
3799
                index, i);
4317
3822
      mysql_prefix_len = templ->mysql_col_offset
4318
3823
        + templ->mysql_col_len;
4319
3824
    }
4320
 
    templ->type = col->mtype;
 
3825
    templ->type = index->table->cols[i].mtype;
4321
3826
    templ->mysql_type = (ulint)field->type();
4322
3827
 
4323
3828
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4325
3830
        (((Field_varstring*)field)->pack_length_no_ptr());
4326
3831
    }
4327
3832
 
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;
 
3833
    templ->charset = dtype_get_charset_coll(
 
3834
      index->table->cols[i].prtype);
 
3835
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3836
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3837
    templ->is_unsigned = index->table->cols[i].prtype
 
3838
              & DATA_UNSIGNED;
4332
3839
    if (templ->type == DATA_BLOB) {
4333
3840
      prebuilt->templ_contains_blob = TRUE;
4334
3841
    }
4353
3860
}
4354
3861
 
4355
3862
/********************************************************************//**
 
3863
Get the upper limit of the MySQL integral and floating-point type. */
 
3864
UNIV_INTERN
 
3865
uint64_t
 
3866
ha_innobase::innobase_get_int_col_max_value(
 
3867
/*========================================*/
 
3868
  const Field*  field)
 
3869
{
 
3870
  uint64_t  max_value = 0;
 
3871
 
 
3872
  switch(field->key_type()) {
 
3873
  /* TINY */
 
3874
  case HA_KEYTYPE_BINARY:
 
3875
    max_value = 0xFFULL;
 
3876
    break;
 
3877
  /* LONG */
 
3878
  case HA_KEYTYPE_ULONG_INT:
 
3879
    max_value = 0xFFFFFFFFULL;
 
3880
    break;
 
3881
  case HA_KEYTYPE_LONG_INT:
 
3882
    max_value = 0x7FFFFFFFULL;
 
3883
    break;
 
3884
  /* BIG */
 
3885
  case HA_KEYTYPE_ULONGLONG:
 
3886
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3887
    break;
 
3888
  case HA_KEYTYPE_LONGLONG:
 
3889
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3890
    break;
 
3891
  case HA_KEYTYPE_DOUBLE:
 
3892
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3893
    max_value = 0x20000000000000ULL;
 
3894
    break;
 
3895
  default:
 
3896
    ut_error;
 
3897
  }
 
3898
 
 
3899
  return(max_value);
 
3900
}
 
3901
 
 
3902
/********************************************************************//**
4356
3903
This special handling is really to overcome the limitations of MySQL's
4357
3904
binlogging. We need to eliminate the non-determinism that will arise in
4358
3905
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4503
4050
  num_write_row++;
4504
4051
 
4505
4052
  /* This is the case where the table has an auto-increment column */
4506
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4053
  if (table->next_number_field && record == table->getInsertRecord()) {
4507
4054
 
4508
4055
    /* Reset the error code before calling
4509
4056
    innobase_get_auto_increment(). */
4510
4057
    prebuilt->autoinc_error = DB_SUCCESS;
4511
4058
 
4512
4059
    if ((error = update_auto_increment())) {
 
4060
 
4513
4061
      /* 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) {
 
4062
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4523
4063
        error = (int) prebuilt->autoinc_error;
4524
4064
 
4525
4065
        goto report_error;
4539
4079
    /* Build the template used in converting quickly between
4540
4080
    the two database formats */
4541
4081
 
4542
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4082
    build_template(prebuilt, NULL, table,
 
4083
             ROW_MYSQL_WHOLE_ROW);
4543
4084
  }
4544
4085
 
4545
4086
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4546
4087
 
4547
4088
  error = row_insert_for_mysql((byte*) record, prebuilt);
4548
4089
 
4549
 
  user_session->setXaId(trx->id);
4550
 
 
4551
4090
  /* Handle duplicate key errors */
4552
4091
  if (auto_inc_used) {
4553
4092
    ulint   err;
4565
4104
    /* We need the upper limit of the col type to check for
4566
4105
    whether we update the table autoinc counter or not. */
4567
4106
    col_max_value = innobase_get_int_col_max_value(
4568
 
      getTable()->next_number_field); 
 
4107
      table->next_number_field);
 
4108
 
4569
4109
    /* Get the value that MySQL attempted to store in the table.*/
4570
 
    auto_inc = getTable()->next_number_field->val_int();
 
4110
    auto_inc = table->next_number_field->val_int();
4571
4111
 
4572
4112
    switch (error) {
4573
4113
    case DB_DUPLICATE_KEY:
4603
4143
      update the table upper limit. Note: last_value
4604
4144
      will be 0 if get_auto_increment() was not called.*/
4605
4145
 
4606
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4146
      if (auto_inc <= col_max_value
 
4147
          && auto_inc >= prebuilt->autoinc_last_value) {
4607
4148
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
 
          }
 
4149
        ut_a(prebuilt->autoinc_increment > 0);
 
4150
 
 
4151
        uint64_t  need;
 
4152
        uint64_t  offset;
 
4153
 
 
4154
        offset = prebuilt->autoinc_offset;
 
4155
        need = prebuilt->autoinc_increment;
 
4156
 
 
4157
        auto_inc = innobase_next_autoinc(
 
4158
          auto_inc, need, offset, col_max_value);
 
4159
 
 
4160
        err = innobase_set_max_autoinc(auto_inc);
 
4161
 
 
4162
        if (err != DB_SUCCESS) {
 
4163
          error = err;
4629
4164
        }
4630
4165
      }
4631
4166
      break;
4822
4357
  /* Build an update vector from the modified fields in the rows
4823
4358
  (uses upd_buff of the handle) */
4824
4359
 
4825
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4360
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4826
4361
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4827
4362
      prebuilt, user_session);
4828
4363
 
4831
4366
 
4832
4367
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4833
4368
 
4834
 
  if (getTable()->found_next_number_field)
 
4369
  if (table->found_next_number_field)
4835
4370
  {
4836
4371
    uint64_t  auto_inc;
4837
4372
    uint64_t  col_max_value;
4838
4373
 
4839
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4374
    auto_inc = table->found_next_number_field->val_int();
4840
4375
 
4841
4376
    /* We need the upper limit of the col type to check for
4842
4377
    whether we update the table autoinc counter or not. */
4843
4378
    col_max_value = innobase_get_int_col_max_value(
4844
 
      getTable()->found_next_number_field);
 
4379
      table->found_next_number_field);
4845
4380
 
4846
4381
    uint64_t current_autoinc;
4847
4382
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4869
4404
 
4870
4405
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4871
4406
 
4872
 
  user_session->setXaId(trx->id);
4873
 
 
4874
4407
  /* We need to do some special AUTOINC handling for the following case:
4875
4408
 
4876
4409
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4880
4413
  value used in the INSERT statement.*/
4881
4414
 
4882
4415
  if (error == DB_SUCCESS
4883
 
      && getTable()->next_number_field
4884
 
      && new_row == getTable()->getInsertRecord()
 
4416
      && table->next_number_field
 
4417
      && new_row == table->getInsertRecord()
4885
4418
      && session_sql_command(user_session) == SQLCOM_INSERT
4886
4419
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4887
4420
    == TRX_DUP_IGNORE)  {
4889
4422
    uint64_t  auto_inc;
4890
4423
    uint64_t  col_max_value;
4891
4424
 
4892
 
    auto_inc = getTable()->next_number_field->val_int();
 
4425
    auto_inc = table->next_number_field->val_int();
4893
4426
 
4894
4427
    /* We need the upper limit of the col type to check for
4895
4428
    whether we update the table autoinc counter or not. */
4896
4429
    col_max_value = innobase_get_int_col_max_value(
4897
 
      getTable()->next_number_field);
 
4430
      table->next_number_field);
4898
4431
 
4899
4432
    if (auto_inc <= col_max_value && auto_inc != 0) {
4900
4433
 
4961
4494
 
4962
4495
  error = row_update_for_mysql((byte*) record, prebuilt);
4963
4496
 
4964
 
  user_session->setXaId(trx->id);
4965
 
 
4966
4497
  innodb_srv_conc_exit_innodb(trx);
4967
4498
 
4968
4499
  error = convert_error_code_to_mysql(
4996
4527
  case ROW_READ_WITH_LOCKS:
4997
4528
    if (!srv_locks_unsafe_for_binlog
4998
4529
        && prebuilt->trx->isolation_level
4999
 
        > TRX_ISO_READ_COMMITTED) {
 
4530
        != TRX_ISO_READ_COMMITTED) {
5000
4531
      break;
5001
4532
    }
5002
4533
    /* fall through */
5026
4557
ha_innobase::try_semi_consistent_read(bool yes)
5027
4558
/*===========================================*/
5028
4559
{
5029
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4560
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5030
4561
 
5031
4562
  /* Row read type is set to semi consistent read if this was
5032
4563
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
5035
4566
 
5036
4567
  if (yes
5037
4568
      && (srv_locks_unsafe_for_binlog
5038
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4569
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
5039
4570
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
5040
4571
  } else {
5041
4572
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5216
4747
 
5217
4748
  index = prebuilt->index;
5218
4749
 
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
4750
  /* Note that if the index for which the search template is built is not
5229
4751
  necessarily prebuilt->index, but can also be the clustered index */
5230
4752
 
5231
4753
  if (prebuilt->sql_stat_start) {
5232
 
    build_template(prebuilt, user_session, getTable(),
 
4754
    build_template(prebuilt, user_session, table,
5233
4755
             ROW_MYSQL_REC_FIELDS);
5234
4756
  }
5235
4757
 
5284
4806
  switch (ret) {
5285
4807
  case DB_SUCCESS:
5286
4808
    error = 0;
5287
 
    getTable()->status = 0;
 
4809
    table->status = 0;
5288
4810
    break;
5289
4811
  case DB_RECORD_NOT_FOUND:
5290
4812
    error = HA_ERR_KEY_NOT_FOUND;
5291
 
    getTable()->status = STATUS_NOT_FOUND;
 
4813
    table->status = STATUS_NOT_FOUND;
5292
4814
    break;
5293
4815
  case DB_END_OF_INDEX:
5294
4816
    error = HA_ERR_KEY_NOT_FOUND;
5295
 
    getTable()->status = STATUS_NOT_FOUND;
 
4817
    table->status = STATUS_NOT_FOUND;
5296
4818
    break;
5297
4819
  default:
5298
4820
    error = convert_error_code_to_mysql((int) ret,
5299
4821
                prebuilt->table->flags,
5300
4822
                user_session);
5301
 
    getTable()->status = STATUS_NOT_FOUND;
 
4823
    table->status = STATUS_NOT_FOUND;
5302
4824
    break;
5303
4825
  }
5304
4826
 
5337
4859
 
5338
4860
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5339
4861
 
5340
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4862
  ut_ad(user_session == table->in_use);
 
4863
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4864
 
 
4865
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5341
4866
  {
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
 
    }
 
4867
    index = dict_table_get_index_on_name(prebuilt->table,
 
4868
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5365
4869
  } else {
5366
4870
    index = dict_table_get_first_index(prebuilt->table);
5367
4871
  }
5370
4874
    errmsg_printf(ERRMSG_LVL_ERROR, 
5371
4875
      "Innodb could not find key n:o %u with name %s "
5372
4876
      "from dict cache for table %s",
5373
 
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
 
4877
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5374
4878
      prebuilt->table->name);
5375
4879
  }
5376
4880
 
5398
4902
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5399
4903
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5400
4904
          keynr);
5401
 
    prebuilt->index_usable = FALSE;
5402
4905
    return(1);
5403
4906
  }
5404
4907
 
5406
4909
                 prebuilt->index);
5407
4910
 
5408
4911
  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);
 
4912
    errmsg_printf(ERRMSG_LVL_WARN,
 
4913
         "InnoDB: insufficient history for index %u",
 
4914
          keynr);
5413
4915
    /* The caller seems to ignore this.  Thus, we must check
5414
4916
    this again in row_search_for_mysql(). */
5415
4917
    return(2);
5428
4930
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5429
4931
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5430
4932
 
5431
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
4933
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5432
4934
 
5433
4935
  return(0);
5434
4936
}
5488
4990
  switch (ret) {
5489
4991
  case DB_SUCCESS:
5490
4992
    error = 0;
5491
 
    getTable()->status = 0;
 
4993
    table->status = 0;
5492
4994
    break;
5493
4995
  case DB_RECORD_NOT_FOUND:
5494
4996
    error = HA_ERR_END_OF_FILE;
5495
 
    getTable()->status = STATUS_NOT_FOUND;
 
4997
    table->status = STATUS_NOT_FOUND;
5496
4998
    break;
5497
4999
  case DB_END_OF_INDEX:
5498
5000
    error = HA_ERR_END_OF_FILE;
5499
 
    getTable()->status = STATUS_NOT_FOUND;
 
5001
    table->status = STATUS_NOT_FOUND;
5500
5002
    break;
5501
5003
  default:
5502
5004
    error = convert_error_code_to_mysql(
5503
5005
      (int) ret, prebuilt->table->flags, user_session);
5504
 
    getTable()->status = STATUS_NOT_FOUND;
 
5006
    table->status = STATUS_NOT_FOUND;
5505
5007
    break;
5506
5008
  }
5507
5009
 
5696
5198
 
5697
5199
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5698
5200
 
5699
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5201
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5700
5202
 
5701
5203
  if (prebuilt->clust_index_was_generated) {
5702
5204
    /* No primary key was defined for the table and we
5742
5244
{
5743
5245
  uint    len;
5744
5246
 
5745
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5247
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5746
5248
 
5747
5249
  if (prebuilt->clust_index_was_generated) {
5748
5250
    /* No primary key was defined for the table and we
5818
5320
 
5819
5321
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5820
5322
                  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
5323
    if (field->null_ptr) {
5837
5324
      nulls_allowed = 0;
5838
5325
    } else {
5885
5372
      }
5886
5373
    }
5887
5374
 
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
5375
    dict_mem_table_add_col(table, table->heap,
5902
5376
      (char*) field->field_name,
5903
5377
      col_type,
5911
5385
 
5912
5386
  error = row_create_table_for_mysql(table, trx);
5913
5387
 
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
5388
  error = convert_error_code_to_mysql(error, flags, NULL);
5926
5389
 
5927
5390
  return(error);
5958
5421
 
5959
5422
  n_fields = key->key_parts;
5960
5423
 
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
5424
  ind_type = 0;
5965
5425
 
5966
5426
  if (key_num == form->getShare()->getPrimaryKey()) {
6070
5530
  /* We pass 0 as the space id, and determine at a lower level the space
6071
5531
  id where to store the table */
6072
5532
 
6073
 
  index = dict_mem_index_create(table_name,
6074
 
                                innobase_index_reserve_name,
6075
 
                                0, DICT_CLUSTERED, 0);
 
5533
  index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
 
5534
              0, DICT_CLUSTERED, 0);
6076
5535
 
6077
5536
  error = row_create_index_for_mysql(index, trx, NULL);
6078
5537
 
6138
5597
    modified by another thread while the table is being created. */
6139
5598
  const ulint file_format = srv_file_format;
6140
5599
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6141
 
  const char* stmt;
6142
 
  size_t stmt_len;
6143
5600
 
6144
5601
  const char *table_name= identifier.getPath().c_str();
6145
5602
 
6232
5689
# error "DICT_TF_ZSSIZE_MAX < 1"
6233
5690
#endif
6234
5691
 
6235
 
    if (strict_mode)
 
5692
    if (SessionVAR(&session, strict_mode))
6236
5693
    {
6237
5694
      if (! srv_file_per_table)
6238
5695
      {
6251
5708
                            "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6252
5709
      }
6253
5710
    }
 
5711
 
 
5712
    error= create_table_def(trx, &form, norm_name,
 
5713
                            lex_identified_temp_table ? name2 : NULL,
 
5714
                            iflags);
 
5715
  }
 
5716
 
 
5717
  if (error) {
 
5718
    goto cleanup;
6254
5719
  }
6255
5720
 
6256
5721
  /* Look for a primary key */
6259
5724
                   (int) form.getShare()->getPrimaryKey() :
6260
5725
                   -1);
6261
5726
 
6262
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5727
  /* Our function row_get_mysql_key_number_for_index assumes
6263
5728
    the primary key is always number 0, if it exists */
6264
5729
 
6265
5730
  assert(primary_key_no == -1 || primary_key_no == 0);
6266
5731
 
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
5732
  /* Create the keys */
6289
5733
 
6290
5734
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6316
5760
    }
6317
5761
  }
6318
5762
 
6319
 
  stmt = innobase_get_stmt(&session, &stmt_len);
6320
 
 
6321
 
  if (stmt) {
 
5763
  if (trx->mysql_query_str) {
6322
5764
    string generated_create_table;
6323
 
    const char *query= stmt;
 
5765
    const char *query= trx->mysql_query_str;
6324
5766
 
6325
5767
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6326
5768
    {
6331
5773
    }
6332
5774
 
6333
5775
    error = row_table_add_foreign_constraints(trx,
6334
 
                                              query, strlen(query),
 
5776
                                              query,
6335
5777
                                              norm_name,
6336
5778
                                              lex_identified_temp_table);
6337
5779
 
6360
5802
    /* We update the highest file format in the system table
6361
5803
      space, if this table has higher file format setting. */
6362
5804
 
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;
 
5805
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5806
                                    dict_table_get_format(innobase_table));
6368
5807
  }
6369
5808
 
6370
5809
  /* Note: We can't call update_session() as prebuilt will not be
6371
5810
    setup at this stage and so we use session. */
6372
5811
 
6373
5812
  /* 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. */
 
5813
    this is an ALTER TABLE. */
6376
5814
 
6377
5815
  if ((create_proto.options().has_auto_increment_value()
6378
 
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
6379
 
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
 
5816
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
6380
5817
      && create_proto.options().auto_increment_value() != 0) {
6381
5818
 
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. */
 
5819
    /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 
5820
      CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
 
5821
      definition from the dictionary and get the current value
 
5822
      of the auto increment field. Set a new value to the
 
5823
      auto increment field if the value is greater than the
 
5824
      maximum value in the column. */
6390
5825
 
6391
5826
    auto_inc_value = create_proto.options().auto_increment_value();
6392
5827
 
6404
5839
 
6405
5840
  if (lex_identified_temp_table)
6406
5841
  {
6407
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5842
    session.storeTableMessage(identifier, create_proto);
6408
5843
  }
6409
5844
  else
6410
5845
  {
6438
5873
 
6439
5874
  ut_a(prebuilt->trx);
6440
5875
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6441
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5876
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6442
5877
 
6443
5878
  dict_table = prebuilt->table;
6444
5879
  trx = prebuilt->trx;
6467
5902
  /* Get the transaction associated with the current session, or create one
6468
5903
  if not yet created, and update prebuilt->trx */
6469
5904
 
6470
 
  update_session(getTable()->in_use);
 
5905
  update_session(table->in_use);
6471
5906
 
6472
5907
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6473
5908
  fallback:
6536
5971
                                   session_sql_command(&session)
6537
5972
                                   == SQLCOM_DROP_DB);
6538
5973
 
6539
 
  session.setXaId(trx->id);
6540
 
 
6541
5974
  /* Flush the log to reduce probability that the .frm files and
6542
5975
    the InnoDB data dictionary get out-of-sync if the user runs
6543
5976
    with innodb_flush_log_at_trx_commit = 0 */
6560
5993
  {
6561
5994
    if (identifier.getType() == message::Table::TEMPORARY)
6562
5995
    {
6563
 
      session.getMessageCache().removeTableMessage(identifier);
 
5996
      session.removeTableMessage(identifier);
6564
5997
      ulint sql_command = session_sql_command(&session);
6565
5998
 
6566
5999
      // If this was the final removal to an alter table then we will need
6653
6086
  trx = trx_allocate_for_mysql();
6654
6087
 
6655
6088
  trx->mysql_thd = NULL;
 
6089
  trx->mysql_query_str = NULL;
6656
6090
 
6657
6091
  trx->check_foreigns = false;
6658
6092
  trx->check_unique_secondary = false;
6736
6170
  // definition needs to be updated.
6737
6171
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6738
6172
  {
6739
 
    session.getMessageCache().renameTableMessage(from, to);
 
6173
    session.renameTableMessage(from, to);
6740
6174
    return 0;
6741
6175
  }
6742
6176
 
6758
6192
 
6759
6193
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6760
6194
 
6761
 
  session.setXaId(trx->id);
6762
 
 
6763
6195
  /* Tell the InnoDB server that there might be work for
6764
6196
    utility threads: */
6765
6197
 
6768
6200
  innobase_commit_low(trx);
6769
6201
  trx_free_for_mysql(trx);
6770
6202
 
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
6203
  error = convert_error_code_to_mysql(error, 0, NULL);
6789
6204
 
6790
6205
  if (not error)
6812
6227
  KeyInfo*    key;
6813
6228
  dict_index_t* index;
6814
6229
  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;
 
6230
              table->getShare()->stored_rec_length
 
6231
          + table->getShare()->max_key_length + 100);
 
6232
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6233
          + table->getShare()->max_key_length + 100;
6819
6234
  dtuple_t* range_start;
6820
6235
  dtuple_t* range_end;
6821
6236
  ib_int64_t  n_rows;
6823
6238
  ulint   mode2;
6824
6239
  mem_heap_t* heap;
6825
6240
 
6826
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6241
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6827
6242
 
6828
6243
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6829
6244
 
6834
6249
 
6835
6250
  active_index = keynr;
6836
6251
 
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
 
  }
 
6252
  key = &table->key_info[active_index];
 
6253
 
 
6254
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6255
 
 
6256
  /* MySQL knows about this index and so we must be able to find it.*/
 
6257
  ut_a(index);
6853
6258
 
6854
6259
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6855
6260
            + sizeof(dtuple_t)));
6894
6299
 
6895
6300
  mem_heap_free(heap);
6896
6301
 
6897
 
func_exit:
6898
6302
  free(key_val_buff2);
6899
6303
 
6900
6304
  prebuilt->trx->op_info = (char*)"";
6929
6333
  external_lock(). To be safe, update the session of the current table
6930
6334
  handle. */
6931
6335
 
6932
 
  update_session(getTable()->in_use);
 
6336
  update_session(table->in_use);
6933
6337
 
6934
6338
  prebuilt->trx->op_info = (char*)
6935
6339
         "calculating upper bound for table rows";
6993
6397
  ha_rows total_rows;
6994
6398
  double  time_for_scan;
6995
6399
 
6996
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6400
  if (index != table->getShare()->getPrimaryKey()) {
6997
6401
    /* Not clustered */
6998
6402
    return(Cursor::read_time(index, ranges, rows));
6999
6403
  }
7017
6421
}
7018
6422
 
7019
6423
/*********************************************************************//**
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
6424
Returns statistics information of the table to the MySQL interpreter,
7122
6425
in various fields of the handle object. */
7123
6426
UNIV_INTERN
7130
6433
  dict_index_t* index;
7131
6434
  ha_rows   rec_per_key;
7132
6435
  ib_int64_t  n_rows;
 
6436
  ulong   j;
 
6437
  ulong   i;
 
6438
  char    path[FN_REFLEN];
7133
6439
  os_file_stat_t  stat_info;
7134
6440
 
7135
6441
  /* If we are forcing recovery at a high level, we will suppress
7136
6442
  statistics calculation on tables, because that may crash the
7137
6443
  server if an index is badly corrupted. */
7138
6444
 
 
6445
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6446
 
 
6447
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6448
    because we want MySQL to process this query and not
 
6449
    stop, like it would do if it received the error code
 
6450
    HA_ERR_CRASHED. */
 
6451
 
 
6452
    return(0);
 
6453
  }
 
6454
 
7139
6455
  /* We do not know if MySQL can call this function before calling
7140
6456
  external_lock(). To be safe, update the session of the current table
7141
6457
  handle. */
7142
6458
 
7143
 
  update_session(getTable()->in_use);
 
6459
  update_session(table->in_use);
7144
6460
 
7145
6461
  /* In case MySQL calls this in the middle of a SELECT query, release
7146
6462
  possible adaptive hash latch to avoid deadlocks of threads */
7152
6468
  ib_table = prebuilt->table;
7153
6469
 
7154
6470
  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";
7163
 
 
7164
 
    fs::path get_status_path(getDataHomeCatalog());
7165
 
    get_status_path /= ib_table->name;
7166
 
    fs::change_extension(get_status_path, "dfe");
 
6471
    if (innobase_stats_on_metadata) {
 
6472
      /* In sql_show we call with this flag: update
 
6473
      then statistics so that they are up-to-date */
 
6474
 
 
6475
      prebuilt->trx->op_info = "updating table statistics";
 
6476
 
 
6477
      dict_update_statistics(ib_table);
 
6478
 
 
6479
      prebuilt->trx->op_info = "returning various info to MySQL";
 
6480
    }
 
6481
 
 
6482
    snprintf(path, sizeof(path), "%s/%s%s",
 
6483
             getDataHomeCatalog().c_str(), ib_table->name, ".dfe");
 
6484
 
 
6485
    internal::unpack_filename(path,path);
7167
6486
 
7168
6487
    /* Note that we do not know the access time of the table,
7169
6488
    nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
7170
6489
 
7171
 
    if (os_file_get_status(get_status_path.file_string().c_str(), &stat_info)) {
 
6490
    if (os_file_get_status(path,&stat_info)) {
7172
6491
      stats.create_time = (ulong) stat_info.ctime;
7173
6492
    }
7174
6493
  }
7227
6546
    acquiring latches inside InnoDB, we do not call it if we
7228
6547
    are asked by MySQL to avoid locking. Another reason to
7229
6548
    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 {
 
6549
    See Bug#38185.
 
6550
    We do not update delete_length if no locking is requested
 
6551
    so the "old" value can remain. delete_length is initialized
 
6552
    to 0 in the ha_statistics' constructor. */
 
6553
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6554
 
7242
6555
      /* lock the data dictionary to avoid races with
7243
6556
      ibd_file_missing and tablespace_discarded */
7244
6557
      row_mysql_lock_data_dictionary(prebuilt->trx);
7254
6567
 
7255
6568
        Session*  session;
7256
6569
 
7257
 
        session= getTable()->in_use;
 
6570
        session= table->in_use;
7258
6571
        assert(session);
7259
6572
 
7260
6573
        push_warning_printf(
7284
6597
  }
7285
6598
 
7286
6599
  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;
 
6600
    index = dict_table_get_first_index(ib_table);
7292
6601
 
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);
 
6602
    if (prebuilt->clust_index_was_generated) {
 
6603
      index = dict_table_get_next_index(index);
7300
6604
    }
7301
6605
 
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
 
 
 
6606
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7311
6607
      if (index == NULL) {
7312
6608
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7313
6609
            "indexes inside InnoDB than "
7321
6617
        break;
7322
6618
      }
7323
6619
 
7324
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6620
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7325
6621
 
7326
6622
        if (j + 1 > index->n_uniq) {
7327
6623
          errmsg_printf(ERRMSG_LVL_ERROR, 
7336
6632
          break;
7337
6633
        }
7338
6634
 
7339
 
        dict_index_stat_mutex_enter(index);
7340
 
 
7341
6635
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7342
6636
 
7343
6637
          rec_per_key = stats.records;
7346
6640
           index->stat_n_diff_key_vals[j + 1]);
7347
6641
        }
7348
6642
 
7349
 
        dict_index_stat_mutex_exit(index);
7350
 
 
7351
6643
        /* Since MySQL seems to favor table scans
7352
6644
        too much over index searches, we pretend
7353
6645
        index selectivity is 2 times better than
7359
6651
          rec_per_key = 1;
7360
6652
        }
7361
6653
 
7362
 
        getTable()->key_info[i].rec_per_key[j]=
 
6654
        table->key_info[i].rec_per_key[j]=
7363
6655
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7364
6656
          (ulong) rec_per_key;
7365
6657
      }
 
6658
 
 
6659
      index = dict_table_get_next_index(index);
7366
6660
    }
7367
6661
  }
7368
6662
 
7369
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7370
 
    goto func_exit;
7371
 
  }
7372
 
 
7373
6663
  if (flag & HA_STATUS_ERRKEY) {
7374
6664
    const dict_index_t* err_index;
7375
6665
 
7380
6670
 
7381
6671
    if (err_index) {
7382
6672
      errkey = (unsigned int)
7383
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7384
 
                                                err_index);
 
6673
        row_get_mysql_key_number_for_index(err_index);
7385
6674
    } else {
7386
6675
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7387
6676
    }
7388
6677
  }
7389
6678
 
7390
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6679
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7391
6680
    stats.auto_increment_value = innobase_peek_autoinc();
7392
6681
  }
7393
6682
 
7394
 
func_exit:
7395
6683
  prebuilt->trx->op_info = (char*)"";
7396
6684
 
7397
6685
  return(0);
7424
6712
/*===============*/
7425
6713
  Session*  session)  /*!< in: user thread handle */
7426
6714
{
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;
 
6715
  ulint   ret;
7432
6716
 
7433
 
  assert(session == getTable()->in_use);
 
6717
  assert(session == table->in_use);
7434
6718
  ut_a(prebuilt->trx);
7435
6719
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7436
6720
  ut_a(prebuilt->trx == session_to_trx(session));
7439
6723
    /* Build the template; we will use a dummy template
7440
6724
    in index scans done in checking */
7441
6725
 
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);
 
6726
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
 
6727
  }
 
6728
 
 
6729
  ret = row_check_table_for_mysql(prebuilt);
 
6730
 
 
6731
  if (ret == DB_SUCCESS) {
 
6732
    return(HA_ADMIN_OK);
 
6733
  }
 
6734
 
 
6735
  return(HA_ADMIN_CORRUPT);
7579
6736
}
7580
6737
 
7581
6738
/*************************************************************//**
7601
6758
    return((char*)comment); /* string too long */
7602
6759
  }
7603
6760
 
7604
 
  update_session(getTable()->in_use);
 
6761
  update_session(table->in_use);
7605
6762
 
7606
6763
  prebuilt->trx->op_info = (char*)"returning table comment";
7607
6764
 
7672
6829
  external_lock(). To be safe, update the session of the current table
7673
6830
  handle. */
7674
6831
 
7675
 
  update_session(getTable()->in_use);
 
6832
  update_session(table->in_use);
7676
6833
 
7677
6834
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7678
6835
 
7721
6878
  dict_foreign_t* foreign;
7722
6879
 
7723
6880
  ut_a(prebuilt != NULL);
7724
 
  update_session(getTable()->in_use);
 
6881
  update_session(table->in_use);
7725
6882
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7726
6883
  trx_search_latch_release_if_reserved(prebuilt->trx);
7727
6884
  mutex_enter(&(dict_sys->mutex));
7859
7016
{
7860
7017
  bool  can_switch;
7861
7018
 
7862
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7019
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7863
7020
 
7864
7021
  prebuilt->trx->op_info =
7865
7022
      "determining if there are foreign key constraints";
7947
7104
      either, because the calling threads may change.
7948
7105
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7949
7106
    case HA_EXTRA_IGNORE_DUP_KEY:
7950
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7107
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7951
7108
      break;
7952
7109
    case HA_EXTRA_WRITE_CAN_REPLACE:
7953
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7110
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7954
7111
      break;
7955
7112
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7956
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7113
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7957
7114
      break;
7958
7115
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7959
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7116
      session_to_trx(table->in_use)->duplicates &=
7960
7117
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7961
7118
      break;
7962
7119
    default:/* Do nothing */
8092
7249
{
8093
7250
  trx_t*      trx;
8094
7251
  static const char truncated_msg[] = "... truncated...\n";
8095
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7252
  const long    MAX_STATUS_SIZE = 64000;
8096
7253
  ulint     trx_list_start = ULINT_UNDEFINED;
8097
7254
  ulint     trx_list_end = ULINT_UNDEFINED;
8098
7255
 
8110
7267
 
8111
7268
  mutex_enter(&srv_monitor_file_mutex);
8112
7269
  rewind(srv_monitor_file);
8113
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7270
  srv_printf_innodb_monitor(srv_monitor_file,
8114
7271
        &trx_list_start, &trx_list_end);
8115
7272
  flen = ftell(srv_monitor_file);
8116
7273
  os_file_set_eof(srv_monitor_file);
8121
7278
 
8122
7279
  if (flen > MAX_STATUS_SIZE) {
8123
7280
    usable_len = MAX_STATUS_SIZE;
8124
 
    srv_truncated_status_writes++;
8125
7281
  } else {
8126
7282
    usable_len = flen;
8127
7283
  }
8157
7313
 
8158
7314
  mutex_exit(&srv_monitor_file_mutex);
8159
7315
 
8160
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8161
 
             STRING_WITH_LEN(""), str, flen);
 
7316
  bool result = FALSE;
8162
7317
 
 
7318
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7319
      STRING_WITH_LEN(""), str, flen)) {
 
7320
    result= TRUE;
 
7321
  }
8163
7322
  free(str);
8164
7323
 
8165
7324
  return(FALSE);
8166
7325
}
8167
7326
 
8168
7327
/************************************************************************//**
8169
 
Implements the SHOW MUTEX STATUS command.
8170
 
@return true on failure false on success*/
 
7328
Implements the SHOW MUTEX STATUS command. . */
8171
7329
static
8172
7330
bool
8173
7331
innodb_mutex_show_status(
8175
7333
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8176
7334
  Session*  session,  /*!< in: the MySQL query thread of the
8177
7335
          caller */
8178
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8179
 
                                        statistics */
 
7336
  stat_print_fn*  stat_print)
8180
7337
{
8181
7338
  char buf1[IO_SIZE], buf2[IO_SIZE];
8182
7339
  mutex_t*  mutex;
8183
7340
  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
7341
#ifdef UNIV_DEBUG
8189
7342
  ulint   rw_lock_count= 0;
8190
7343
  ulint   rw_lock_count_spin_loop= 0;
8198
7351
 
8199
7352
  mutex_enter(&mutex_list_mutex);
8200
7353
 
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;
 
7354
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7355
 
 
7356
  while (mutex != NULL) {
 
7357
    if (mutex->count_os_wait == 0
 
7358
        || buf_pool_is_block_mutex(mutex)) {
 
7359
      goto next_mutex;
8212
7360
    }
8213
7361
#ifdef UNIV_DEBUG
8214
7362
    if (mutex->mutex_type != 1) {
8235
7383
          return(1);
8236
7384
        }
8237
7385
      }
8238
 
    } else {
 
7386
    }
 
7387
    else {
8239
7388
      rw_lock_count += mutex->count_using;
8240
7389
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8241
7390
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8247
7396
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8248
7397
          mutex->cfile_name, (ulong) mutex->cline);
8249
7398
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8250
 
                      (ulong) mutex->count_os_wait);
 
7399
          mutex->count_os_wait);
8251
7400
 
8252
7401
    if (stat_print(session, innobase_engine_name,
8253
7402
             engine_name_len, buf1, buf1len,
8256
7405
      return(1);
8257
7406
    }
8258
7407
#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
 
    }
 
7408
 
 
7409
next_mutex:
 
7410
    mutex = UT_LIST_GET_NEXT(list, mutex);
8276
7411
  }
8277
7412
 
8278
7413
  mutex_exit(&mutex_list_mutex);
8279
7414
 
8280
7415
  mutex_enter(&rw_lock_list_mutex);
8281
7416
 
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
 
    }
 
7417
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7418
 
 
7419
  while (lock != NULL) {
 
7420
    if (lock->count_os_wait
 
7421
                    && !buf_pool_is_block_lock(lock)) {
 
7422
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7423
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7424
      buf2len= snprintf(buf2, sizeof(buf2),
 
7425
                                    "os_waits=%lu", lock->count_os_wait);
 
7426
 
 
7427
      if (stat_print(session, innobase_engine_name,
 
7428
               engine_name_len, buf1, buf1len,
 
7429
               buf2, buf2len)) {
 
7430
        mutex_exit(&rw_lock_list_mutex);
 
7431
        return(1);
 
7432
      }
 
7433
    }
 
7434
    lock = UT_LIST_GET_NEXT(list, lock);
8322
7435
  }
8323
7436
 
8324
7437
  mutex_exit(&rw_lock_list_mutex);
8325
7438
 
8326
7439
#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));
 
7440
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7441
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7442
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7443
    rw_lock_count, rw_lock_count_spin_loop,
 
7444
    rw_lock_count_spin_rounds,
 
7445
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7446
    (ulong) (rw_lock_wait_time/1000));
8336
7447
 
8337
7448
  if (stat_print(session, innobase_engine_name, engine_name_len,
8338
7449
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8386
7497
          innobase_open_tables, fold, share);
8387
7498
 
8388
7499
    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
7500
  }
8395
7501
 
8396
7502
  share->use_count++;
8421
7527
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8422
7528
          innobase_open_tables, fold, share);
8423
7529
    share->lock.deinit();
8424
 
 
8425
 
    /* Free any memory from index translation table */
8426
 
    free(share->idx_trans_tbl.index_mapping);
8427
 
 
8428
7530
    delete share;
8429
7531
 
8430
7532
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8502
7604
    isolation_level = trx->isolation_level;
8503
7605
 
8504
7606
    if ((srv_locks_unsafe_for_binlog
8505
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7607
         || isolation_level == TRX_ISO_READ_COMMITTED)
8506
7608
        && isolation_level != TRX_ISO_SERIALIZABLE
8507
7609
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8508
7610
        && (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)) {
 
7611
      || sql_command == SQLCOM_UPDATE
 
7612
      || sql_command == SQLCOM_CREATE_TABLE)) {
8513
7613
 
8514
7614
      /* If we either have innobase_locks_unsafe_for_binlog
8515
7615
      option set or this session is using READ COMMITTED
8516
7616
      isolation level and isolation level of the transaction
8517
7617
      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. */
 
7618
      INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
 
7619
      CREATE  ... SELECT... without FOR UPDATE or
 
7620
      IN SHARE MODE in select, then we use consistent
 
7621
      read for select. */
8523
7622
 
8524
7623
      prebuilt->select_lock_type = LOCK_NONE;
8525
7624
      prebuilt->stored_select_lock_type = LOCK_NONE;
8598
7697
  *value = dict_table_autoinc_read(prebuilt->table);
8599
7698
 
8600
7699
  /* 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
 
  }
 
7700
  ut_a(*value != 0);
8605
7701
 
8606
7702
  return(DB_SUCCESS);
8607
7703
}
8608
7704
 
8609
7705
/*******************************************************************//**
8610
 
This function reads the global auto-inc counter. It doesn't use the
 
7706
This function reads the global auto-inc counter. It doesn't use the 
8611
7707
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8612
7708
@return the autoinc value */
8613
7709
UNIV_INTERN
8627
7723
 
8628
7724
  auto_inc = dict_table_autoinc_read(innodb_table);
8629
7725
 
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
 
  }
 
7726
  ut_a(auto_inc > 0);
8635
7727
 
8636
7728
  dict_table_autoinc_unlock(innodb_table);
8637
7729
 
8660
7752
  uint64_t  autoinc = 0;
8661
7753
 
8662
7754
  /* Prepare prebuilt->trx in the table handle */
8663
 
  update_session(getTable()->in_use);
 
7755
  update_session(table->in_use);
8664
7756
 
8665
7757
  error = innobase_get_autoinc(&autoinc);
8666
7758
 
8684
7776
  invoking this method. So we are not sure if it's guaranteed to
8685
7777
  be 0 or not. */
8686
7778
 
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
7779
  /* Called for the first time ? */
8692
7780
  if (trx->n_autoinc_rows == 0) {
8693
7781
 
8704
7792
  /* Not in the middle of a mult-row INSERT. */
8705
7793
  } else if (prebuilt->autoinc_last_value == 0) {
8706
7794
    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
7795
  }
8713
7796
 
8714
7797
  *nb_reserved_values = trx->n_autoinc_rows;
8716
7799
  /* This all current style autoinc. */
8717
7800
  {
8718
7801
    uint64_t  need;
8719
 
    uint64_t  current;
8720
7802
    uint64_t  next_value;
8721
 
 
8722
 
    current = *first_value > col_max_value ? autoinc : *first_value;
 
7803
    uint64_t  col_max_value;
 
7804
 
 
7805
    /* We need the upper limit of the col type to check for
 
7806
    whether we update the table autoinc counter or not. */
 
7807
    col_max_value = innobase_get_int_col_max_value(
 
7808
      table->next_number_field);
 
7809
 
8723
7810
    need = *nb_reserved_values * increment;
8724
7811
 
8725
7812
    /* Compute the last value in the interval */
8726
 
    next_value = innobase_next_autoinc(current, need, offset, col_max_value);
 
7813
    next_value = innobase_next_autoinc(
 
7814
      *first_value, need, offset, col_max_value);
8727
7815
 
8728
7816
    prebuilt->autoinc_last_value = next_value;
8729
7817
 
8760
7848
{
8761
7849
  int error;
8762
7850
 
8763
 
  update_session(getTable()->in_use);
 
7851
  update_session(table->in_use);
8764
7852
 
8765
7853
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8766
7854
 
8826
7914
  /* Do a type-aware comparison of primary key fields. PK fields
8827
7915
  are always NOT NULL, so no checks for NULL are performed. */
8828
7916
 
8829
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
7917
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8830
7918
 
8831
7919
  key_part_end = key_part
8832
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
7920
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8833
7921
 
8834
7922
  for (; key_part != key_part_end; ++key_part) {
8835
7923
    field = key_part->field;
8977
8065
 
8978
8066
  innobase_release_stat_resources(trx);
8979
8067
 
 
8068
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8069
  {
 
8070
    if (trx->conc_state != TRX_NOT_STARTED)
 
8071
    {
 
8072
      commit(session, TRUE);
 
8073
    }
 
8074
  }
 
8075
  else
 
8076
  {
 
8077
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8078
        trx->global_read_view)
 
8079
    {
 
8080
      /* At low transaction isolation levels we let
 
8081
      each consistent read set its own snapshot */
 
8082
      read_view_close_for_mysql(trx);
 
8083
    }
 
8084
  }
8980
8085
}
8981
8086
 
8982
8087
/*******************************************************************//**
9046
8151
  return(error);
9047
8152
}
9048
8153
 
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
8154
/*******************************************************************//**
9076
8155
This function is used to recover X/Open XA distributed transactions.
9077
8156
@return number of prepared transactions stored in xid_list */
9183
8262
}
9184
8263
 
9185
8264
/************************************************************//**
 
8265
Validate the file format check value, is it one of "on" or "off",
 
8266
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8267
@return true if config value one of "on" or  "off" */
 
8268
static
 
8269
bool
 
8270
innobase_file_format_check_on_off(
 
8271
/*==============================*/
 
8272
  const char* format_check) /*!< in: parameter value */
 
8273
{
 
8274
  bool    ret = true;
 
8275
 
 
8276
  if (!innobase_strcasecmp(format_check, "off")) {
 
8277
 
 
8278
    /* Set the value to disable checking. */
 
8279
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8280
 
 
8281
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8282
 
 
8283
    /* Set the value to the lowest supported format. */
 
8284
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8285
  } else {
 
8286
    ret = FALSE;
 
8287
  }
 
8288
 
 
8289
  return(ret);
 
8290
}
 
8291
 
 
8292
/************************************************************//**
9186
8293
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 */
 
8294
sets the srv_check_file_format_at_startup variable.
 
8295
@return true if valid config value */
9189
8296
static
9190
 
int
9191
 
innobase_file_format_validate_and_set(
 
8297
bool
 
8298
innobase_file_format_check_validate(
9192
8299
/*================================*/
9193
 
  const char* format_max) /*!< in: parameter value */
 
8300
  const char* format_check) /*!< in: parameter value */
9194
8301
{
9195
8302
  uint    format_id;
 
8303
  bool    ret = true;
9196
8304
 
9197
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8305
  format_id = innobase_file_format_name_lookup(format_check);
9198
8306
 
9199
8307
  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
 
 
 
8308
    srv_check_file_format_at_startup = format_id;
 
8309
  } else {
 
8310
    ret = false;
 
8311
  }
 
8312
 
 
8313
  return(ret);
 
8314
}
 
8315
 
 
8316
/*************************************************************//**
 
8317
Check if it is a valid file format. This function is registered as
 
8318
a callback with MySQL.
 
8319
@return 0 for valid file format */
 
8320
static
 
8321
int
 
8322
innodb_file_format_name_validate(
 
8323
/*=============================*/
 
8324
  Session*      , /*!< in: thread handle */
 
8325
  drizzle_sys_var*  , /*!< in: pointer to system
 
8326
            variable */
 
8327
  void*       save, /*!< out: immediate result
 
8328
            for update function */
 
8329
  drizzle_value*    value)  /*!< in: incoming string */
 
8330
{
 
8331
  const char* file_format_input;
 
8332
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8333
  int   len = sizeof(buff);
 
8334
 
 
8335
  ut_a(save != NULL);
 
8336
  ut_a(value != NULL);
 
8337
 
 
8338
  file_format_input = value->val_str(value, buff, &len);
 
8339
 
 
8340
  if (file_format_input != NULL) {
 
8341
    uint  format_id;
 
8342
 
 
8343
    format_id = innobase_file_format_name_lookup(
 
8344
      file_format_input);
 
8345
 
 
8346
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8347
 
 
8348
      *static_cast<const char**>(save) = file_format_input;
 
8349
      return(0);
 
8350
    }
 
8351
  }
 
8352
 
 
8353
  *static_cast<const char**>(save) = NULL;
 
8354
  return(1);
 
8355
}
 
8356
 
 
8357
/****************************************************************//**
 
8358
Update the system variable innodb_file_format using the "saved"
 
8359
value. This function is registered as a callback with MySQL. */
 
8360
static
 
8361
void
 
8362
innodb_file_format_name_update(
 
8363
/*===========================*/
 
8364
  Session*      ,   /*!< in: thread handle */
 
8365
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8366
              system variable */
 
8367
  void*       var_ptr,  /*!< out: where the
 
8368
              formal string goes */
 
8369
  const void*     save)   /*!< in: immediate result
 
8370
              from check function */
 
8371
{
 
8372
  const char* format_name;
 
8373
 
 
8374
  ut_a(var_ptr != NULL);
 
8375
  ut_a(save != NULL);
 
8376
 
 
8377
  format_name = *static_cast<const char*const*>(save);
 
8378
 
 
8379
  if (format_name) {
 
8380
    uint  format_id;
 
8381
 
 
8382
    format_id = innobase_file_format_name_lookup(format_name);
 
8383
 
 
8384
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8385
      srv_file_format = format_id;
 
8386
    }
 
8387
  }
 
8388
 
 
8389
  *static_cast<const char**>(var_ptr)
 
8390
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8391
}
 
8392
 
 
8393
/*************************************************************//**
 
8394
Check if valid argument to innodb_file_format_check. This
 
8395
function is registered as a callback with MySQL.
 
8396
@return 0 for valid file format */
 
8397
static
 
8398
int
 
8399
innodb_file_format_check_validate(
 
8400
/*==============================*/
 
8401
  Session*      , /*!< in: thread handle */
 
8402
  drizzle_sys_var*  , /*!< in: pointer to system
 
8403
            variable */
 
8404
  void*       save, /*!< out: immediate result
 
8405
            for update function */
 
8406
  drizzle_value*    value)  /*!< in: incoming string */
 
8407
{
 
8408
  const char* file_format_input;
 
8409
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8410
  int   len = sizeof(buff);
 
8411
 
 
8412
  ut_a(save != NULL);
 
8413
  ut_a(value != NULL);
 
8414
 
 
8415
  file_format_input = value->val_str(value, buff, &len);
 
8416
 
 
8417
  if (file_format_input != NULL) {
 
8418
 
 
8419
    /* Check if user set on/off, we want to print a suitable
 
8420
    message if they did so. */
 
8421
 
 
8422
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8423
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8424
        "InnoDB: invalid innodb_file_format_check "
 
8425
        "value; on/off can only be set at startup or "
 
8426
        "in the configuration file");
 
8427
    } else if (innobase_file_format_check_validate(
 
8428
        file_format_input)) {
 
8429
 
 
8430
      *static_cast<const char**>(save) = file_format_input;
 
8431
 
 
8432
      return(0);
 
8433
 
 
8434
    } else {
 
8435
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8436
        "InnoDB: invalid innodb_file_format_check "
 
8437
        "value; can be any format up to %s "
 
8438
        "or its equivalent numeric id",
 
8439
        trx_sys_file_format_id_to_name(
 
8440
          DICT_TF_FORMAT_MAX));
 
8441
    }
 
8442
  }
 
8443
 
 
8444
  *static_cast<const char**>(save) = NULL;
 
8445
  return(1);
 
8446
}
 
8447
 
 
8448
/****************************************************************//**
 
8449
Update the system variable innodb_file_format_check using the "saved"
 
8450
value. This function is registered as a callback with MySQL. */
 
8451
static
 
8452
void
 
8453
innodb_file_format_check_update(
 
8454
/*============================*/
 
8455
  Session*      session,  /*!< in: thread handle */
 
8456
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8457
              system variable */
 
8458
  void*       var_ptr,  /*!< out: where the
 
8459
              formal string goes */
 
8460
  const void*     save)   /*!< in: immediate result
 
8461
              from check function */
 
8462
{
 
8463
  const char* format_name_in;
 
8464
  const char**  format_name_out;
 
8465
  uint    format_id;
 
8466
 
 
8467
  ut_a(save != NULL);
 
8468
  ut_a(var_ptr != NULL);
 
8469
 
 
8470
  format_name_in = *static_cast<const char*const*>(save);
 
8471
 
 
8472
  if (!format_name_in) {
 
8473
 
 
8474
    return;
 
8475
  }
 
8476
 
 
8477
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8478
 
 
8479
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8480
    /* DEFAULT is "on", which is invalid at runtime. */
 
8481
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8482
            ER_WRONG_ARGUMENTS,
 
8483
            "Ignoring SET innodb_file_format=%s",
 
8484
            format_name_in);
 
8485
    return;
 
8486
  }
 
8487
 
 
8488
  format_name_out = static_cast<const char**>(var_ptr);
 
8489
 
 
8490
  /* Update the max format id in the system tablespace. */
 
8491
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8492
    ut_print_timestamp(stderr);
 
8493
    fprintf(stderr,
 
8494
      " [Info] InnoDB: the file format in the system "
 
8495
      "tablespace is now set to %s.\n", *format_name_out);
 
8496
  }
 
8497
}
 
8498
 
 
8499
/****************************************************************//**
 
8500
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8501
value. This function is registered as a callback with MySQL. */
 
8502
static
 
8503
void
 
8504
innodb_adaptive_hash_index_update(
 
8505
/*==============================*/
 
8506
  Session*      ,   /*!< in: thread handle */
 
8507
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8508
              system variable */
 
8509
  void*       , /*!< out: where the
 
8510
              formal string goes */
 
8511
  const void*     save)   /*!< in: immediate result
 
8512
              from check function */
 
8513
{
 
8514
  if (*(bool*) save) {
 
8515
    btr_search_enable();
 
8516
  } else {
 
8517
    btr_search_disable();
 
8518
  }
 
8519
}
 
8520
 
 
8521
/*************************************************************//**
 
8522
Check if it is a valid value of innodb_change_buffering.  This function is
 
8523
registered as a callback with MySQL.
 
8524
@return 0 for valid innodb_change_buffering */
 
8525
static
 
8526
int
 
8527
innodb_change_buffering_validate(
 
8528
/*=============================*/
 
8529
  Session*      , /*!< in: thread handle */
 
8530
  drizzle_sys_var*  , /*!< in: pointer to system
 
8531
            variable */
 
8532
  void*       save, /*!< out: immediate result
 
8533
            for update function */
 
8534
  drizzle_value*    value)  /*!< in: incoming string */
 
8535
{
 
8536
  const char* change_buffering_input;
 
8537
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8538
  int   len = sizeof(buff);
 
8539
 
 
8540
  ut_a(save != NULL);
 
8541
  ut_a(value != NULL);
 
8542
 
 
8543
  change_buffering_input = value->val_str(value, buff, &len);
 
8544
 
 
8545
  if (change_buffering_input != NULL) {
 
8546
    ulint use;
 
8547
 
 
8548
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8549
         use++) {
 
8550
      if (!innobase_strcasecmp(
 
8551
            change_buffering_input,
 
8552
            innobase_change_buffering_values[use])) {
 
8553
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8554
        return(0);
 
8555
      }
 
8556
    }
 
8557
  }
 
8558
 
 
8559
  return(1);
 
8560
}
 
8561
 
 
8562
/****************************************************************//**
 
8563
Update the system variable innodb_change_buffering using the "saved"
 
8564
value. This function is registered as a callback with MySQL. */
 
8565
static
 
8566
void
 
8567
innodb_change_buffering_update(
 
8568
/*===========================*/
 
8569
  Session*      ,   /*!< in: thread handle */
 
8570
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8571
              system variable */
 
8572
  void*       var_ptr,  /*!< out: where the
 
8573
              formal string goes */
 
8574
  const void*     save)   /*!< in: immediate result
 
8575
              from check function */
 
8576
{
 
8577
  ut_a(var_ptr != NULL);
 
8578
  ut_a(save != NULL);
 
8579
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8580
 
 
8581
  ibuf_use = *(const ibuf_use_t*) save;
 
8582
 
 
8583
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8584
}
 
8585
 
 
8586
/* plugin options */
 
8587
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8588
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8589
  "Enable InnoDB checksums validation (enabled by default). ",
 
8590
  NULL, NULL, TRUE);
 
8591
 
 
8592
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8593
  PLUGIN_VAR_READONLY,
 
8594
  "The common part for InnoDB table spaces.",
 
8595
  NULL, NULL, NULL);
 
8596
 
 
8597
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8598
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8599
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8600
  NULL, NULL, TRUE);
 
8601
 
 
8602
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8603
  PLUGIN_VAR_RQCMDARG,
 
8604
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8605
  NULL, NULL, 200, 100, ~0L, 0);
 
8606
 
 
8607
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8608
  PLUGIN_VAR_OPCMDARG,
 
8609
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8610
  "values are 0, 1 (faster)"
 
8611
  " or 2 (fastest - crash-like)"
 
8612
  ".",
 
8613
  NULL, NULL, 1, 0, 2, 0);
 
8614
 
 
8615
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8616
  PLUGIN_VAR_NOCMDARG,
 
8617
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8618
  NULL, NULL, FALSE);
 
8619
 
 
8620
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8621
  PLUGIN_VAR_RQCMDARG,
 
8622
  "File format to use for new tables in .ibd files.",
 
8623
  innodb_file_format_name_validate,
 
8624
  innodb_file_format_name_update, "Antelope");
 
8625
 
 
8626
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8627
  PLUGIN_VAR_OPCMDARG,
 
8628
  "The highest file format in the tablespace.",
 
8629
  innodb_file_format_check_validate,
 
8630
  innodb_file_format_check_update,
 
8631
  "on");
 
8632
 
 
8633
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8634
  PLUGIN_VAR_OPCMDARG,
 
8635
  "Set to 0 (write and flush once per second),"
 
8636
  " 1 (write and flush at each commit)"
 
8637
  " or 2 (write at commit, flush once per second).",
 
8638
  NULL, NULL, 1, 0, 2, 0);
 
8639
 
 
8640
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
 
8641
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8642
  "With which method to flush data.", NULL, NULL, NULL);
 
8643
 
 
8644
#ifdef UNIV_LOG_ARCHIVE
 
8645
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8646
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8647
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8648
 
 
8649
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8650
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8651
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8652
#endif /* UNIV_LOG_ARCHIVE */
 
8653
 
 
8654
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8655
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8656
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8657
 
 
8658
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8659
  PLUGIN_VAR_RQCMDARG,
 
8660
  "Percentage of dirty pages allowed in bufferpool.",
 
8661
  NULL, NULL, 75, 0, 99, 0);
 
8662
 
 
8663
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8664
  PLUGIN_VAR_NOCMDARG,
 
8665
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8666
  NULL, NULL, TRUE);
 
8667
 
 
8668
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8669
  PLUGIN_VAR_RQCMDARG,
 
8670
  "Desired maximum length of the purge queue (0 = no limit)",
 
8671
  NULL, NULL, 0, 0, ~0L, 0);
 
8672
 
 
8673
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8674
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8675
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8676
  NULL, NULL, FALSE);
 
8677
 
 
8678
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
 
8679
  PLUGIN_VAR_OPCMDARG,
 
8680
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
 
8681
  NULL, NULL, TRUE);
 
8682
 
 
8683
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8684
  PLUGIN_VAR_RQCMDARG,
 
8685
  "The number of index pages to sample when calculating statistics (default 8)",
 
8686
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8687
 
 
8688
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8689
  PLUGIN_VAR_OPCMDARG,
 
8690
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8691
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8692
 
 
8693
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8694
  PLUGIN_VAR_RQCMDARG,
 
8695
  "Replication thread delay (ms) on the slave server if "
 
8696
  "innodb_thread_concurrency is reached (0 by default)",
 
8697
  NULL, NULL, 0, 0, ~0UL, 0);
 
8698
 
 
8699
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8700
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8701
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8702
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8703
 
 
8704
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8705
  PLUGIN_VAR_RQCMDARG,
 
8706
  "Data file autoextend increment in megabytes",
 
8707
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8708
 
 
8709
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8710
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8711
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8712
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8713
 
 
8714
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8715
  PLUGIN_VAR_RQCMDARG,
 
8716
  "Helps in performance tuning in heavily concurrent environments.",
 
8717
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8718
 
 
8719
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8720
  PLUGIN_VAR_RQCMDARG,
 
8721
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8722
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8723
 
 
8724
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8725
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8726
  "Number of background read I/O threads in InnoDB.",
 
8727
  NULL, NULL, 4, 1, 64, 0);
 
8728
 
 
8729
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8730
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8731
  "Number of background write I/O threads in InnoDB.",
 
8732
  NULL, NULL, 4, 1, 64, 0);
 
8733
 
 
8734
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8735
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8736
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8737
  NULL, NULL, 0, 0, 6, 0);
 
8738
 
 
8739
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8740
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8741
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8742
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8743
 
 
8744
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8745
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8746
  "Size of each log file in a log group.",
 
8747
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8748
 
 
8749
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8750
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8751
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8752
  NULL, NULL, 2, 2, 100, 0);
 
8753
 
 
8754
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8755
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8756
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8757
  NULL, NULL, 1, 1, 10, 0);
 
8758
 
 
8759
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8760
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8761
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8762
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8763
 
 
8764
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8765
  PLUGIN_VAR_RQCMDARG,
 
8766
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8767
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8768
 
 
8769
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8770
  PLUGIN_VAR_OPCMDARG,
 
8771
  "Maximum delay between polling for a spin lock (6 by default)",
 
8772
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8773
 
 
8774
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8775
  PLUGIN_VAR_RQCMDARG,
 
8776
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8777
  NULL, NULL, 0, 0, 1000, 0);
 
8778
 
 
8779
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8780
  PLUGIN_VAR_RQCMDARG,
 
8781
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8782
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8783
 
 
8784
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8785
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8786
  "Path to individual files and their sizes.",
 
8787
  NULL, NULL, NULL);
 
8788
 
 
8789
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8790
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8791
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8792
 
 
8793
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8794
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8795
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8796
  NULL, NULL, TRUE);
 
8797
 
 
8798
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8799
  PLUGIN_VAR_RQCMDARG,
 
8800
  "Buffer changes to reduce random access: "
 
8801
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8802
  innodb_change_buffering_validate,
 
8803
  innodb_change_buffering_update, NULL);
 
8804
 
 
8805
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8806
  PLUGIN_VAR_RQCMDARG,
 
8807
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8808
  "trigger a readahead.",
 
8809
  NULL, NULL, 56, 0, 64, 0);
9208
8810
 
9209
8811
static void init_options(drizzled::module::option_context &context)
9210
8812
{
9216
8818
  context("disable-doublewrite",
9217
8819
          "Disable InnoDB doublewrite buffer.");
9218
8820
  context("io-capacity",
9219
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8821
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9220
8822
          "Number of IOPs the server can do. Tunes the background IO rate");
9221
8823
  context("fast-shutdown",
9222
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8824
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9223
8825
          "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
8826
  context("file-per-table",
9232
8827
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9233
8828
          "Stores each InnoDB table to an .ibd file in the database dir.");
9234
8829
  context("file-format",
9235
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8830
          po::value<string>()->default_value("Antelope"),
9236
8831
          "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"),
 
8832
  context("file-format-check",
 
8833
          po::value<string>()->default_value("on"),
9239
8834
          "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
8835
  context("flush-log-at-trx-commit",
9244
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8836
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9245
8837
          "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
8838
  context("flush-method",
9247
8839
          po::value<string>(),
9248
8840
          "With which method to flush data.");
 
8841
#ifdef UNIV_LOG_ARCHIVE
 
8842
  context("log-arch-dir",
 
8843
          po::value<string>(),
 
8844
          "Where full logs should be archived.");
 
8845
  context("log-archive",
 
8846
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8847
          "Set to 1 if you want to have logs archived.");
 
8848
#endif /* UNIV_LOG_ARCHIVE */
9249
8849
  context("log-group-home-dir",
9250
8850
          po::value<string>(),
9251
8851
          "Path to InnoDB log files.");
9252
8852
  context("max-dirty-pages-pct",
9253
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8853
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9254
8854
          "Percentage of dirty pages allowed in bufferpool.");
9255
8855
  context("disable-adaptive-flushing",
9256
8856
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9257
8857
  context("max-purge-lag",
9258
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8858
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9259
8859
          "Desired maximum length of the purge queue (0 = no limit)");
9260
8860
  context("status-file",
9261
8861
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9263
8863
  context("disable-stats-on-metadata",
9264
8864
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9265
8865
  context("stats-sample-pages",
9266
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
8866
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9267
8867
          "The number of index pages to sample when calculating statistics (default 8)");
9268
8868
  context("disable-adaptive-hash-index",
9269
8869
          "Enable InnoDB adaptive hash index (enabled by default)");
9270
8870
  context("replication-delay",
9271
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
8871
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9272
8872
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9273
8873
  context("additional-mem-pool-size",
9274
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
8874
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9275
8875
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9276
8876
  context("autoextend-increment",
9277
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
 
8877
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9278
8878
          "Data file autoextend increment in megabytes");
9279
8879
  context("buffer-pool-size",
9280
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
8880
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9281
8881
          "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
8882
  context("commit-concurrency",
9287
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
8883
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9288
8884
          "Helps in performance tuning in heavily concurrent environments.");
9289
8885
  context("concurrency-tickets",
9290
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
8886
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9291
8887
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9292
8888
  context("read-io-threads",
9293
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
8889
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9294
8890
          "Number of background read I/O threads in InnoDB.");
9295
8891
  context("write-io-threads",
9296
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
8892
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9297
8893
          "Number of background write I/O threads in InnoDB.");
9298
8894
  context("force-recovery",
9299
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
8895
          po::value<long>(&innobase_force_recovery)->default_value(0),
9300
8896
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9301
8897
  context("log-buffer-size",
9302
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
8898
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9303
8899
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9304
8900
  context("log-file-size",
9305
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
8901
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9306
8902
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9307
8903
  context("log-files-in-group",
9308
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
8904
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9309
8905
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9310
8906
  context("mirrored-log-groups",
9311
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
8907
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9312
8908
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9313
8909
  context("open-files",
9314
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
8910
          po::value<long>(&innobase_open_files)->default_value(300L),
9315
8911
          "How many files at the maximum InnoDB keeps open at the same time.");
9316
8912
  context("sync-spin-loops",
9317
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
8913
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9318
8914
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9319
8915
  context("spin-wait-delay",
9320
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
8916
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9321
8917
          "Maximum delay between polling for a spin lock (6 by default)");
9322
8918
  context("thread-concurrency",
9323
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
8919
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9324
8920
          "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
8921
  context("thread-sleep-delay",
9326
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
8922
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9327
8923
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9328
8924
  context("data-file-path",
9329
8925
          po::value<string>(),
9334
8930
  context("use-internal-malloc",
9335
8931
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9336
8932
  context("change-buffering",
9337
 
          po::value<string>(&innobase_change_buffering),
 
8933
          po::value<string>(),
9338
8934
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9339
8935
  context("read-ahead-threshold",
9340
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
8936
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9341
8937
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9342
8938
  context("disable-xa",
9343
8939
          "Disable InnoDB support for the XA two-phase commit");
9344
8940
  context("disable-table-locks",
9345
8941
          "Disable InnoDB locking in LOCK TABLES");
9346
8942
  context("strict-mode",
9347
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
8943
          po::value<bool>()->default_value(false)->zero_tokens(),
9348
8944
          "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
8945
  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)."));
 
8946
          po::value<unsigned long>()->default_value(50),
 
8947
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9363
8948
}
9364
8949
 
9365
 
 
 
8950
static drizzle_sys_var* innobase_system_variables[]= {
 
8951
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
8952
  DRIZZLE_SYSVAR(autoextend_increment),
 
8953
  DRIZZLE_SYSVAR(buffer_pool_size),
 
8954
  DRIZZLE_SYSVAR(checksums),
 
8955
  DRIZZLE_SYSVAR(commit_concurrency),
 
8956
  DRIZZLE_SYSVAR(concurrency_tickets),
 
8957
  DRIZZLE_SYSVAR(data_file_path),
 
8958
  DRIZZLE_SYSVAR(data_home_dir),
 
8959
  DRIZZLE_SYSVAR(doublewrite),
 
8960
  DRIZZLE_SYSVAR(fast_shutdown),
 
8961
  DRIZZLE_SYSVAR(read_io_threads),
 
8962
  DRIZZLE_SYSVAR(write_io_threads),
 
8963
  DRIZZLE_SYSVAR(file_per_table),
 
8964
  DRIZZLE_SYSVAR(file_format),
 
8965
  DRIZZLE_SYSVAR(file_format_check),
 
8966
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
8967
  DRIZZLE_SYSVAR(flush_method),
 
8968
  DRIZZLE_SYSVAR(force_recovery),
 
8969
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
8970
#ifdef UNIV_LOG_ARCHIVE
 
8971
  DRIZZLE_SYSVAR(log_arch_dir),
 
8972
  DRIZZLE_SYSVAR(log_archive),
 
8973
#endif /* UNIV_LOG_ARCHIVE */
 
8974
  DRIZZLE_SYSVAR(log_buffer_size),
 
8975
  DRIZZLE_SYSVAR(log_file_size),
 
8976
  DRIZZLE_SYSVAR(log_files_in_group),
 
8977
  DRIZZLE_SYSVAR(log_group_home_dir),
 
8978
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
8979
  DRIZZLE_SYSVAR(max_purge_lag),
 
8980
  DRIZZLE_SYSVAR(adaptive_flushing),
 
8981
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
8982
  DRIZZLE_SYSVAR(open_files),
 
8983
  DRIZZLE_SYSVAR(stats_on_metadata),
 
8984
  DRIZZLE_SYSVAR(stats_sample_pages),
 
8985
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
8986
  DRIZZLE_SYSVAR(replication_delay),
 
8987
  DRIZZLE_SYSVAR(status_file),
 
8988
  DRIZZLE_SYSVAR(strict_mode),
 
8989
  DRIZZLE_SYSVAR(support_xa),
 
8990
  DRIZZLE_SYSVAR(sync_spin_loops),
 
8991
  DRIZZLE_SYSVAR(spin_wait_delay),
 
8992
  DRIZZLE_SYSVAR(table_locks),
 
8993
  DRIZZLE_SYSVAR(thread_concurrency),
 
8994
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
8995
  DRIZZLE_SYSVAR(version),
 
8996
  DRIZZLE_SYSVAR(use_sys_malloc),
 
8997
  DRIZZLE_SYSVAR(change_buffering),
 
8998
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
8999
  DRIZZLE_SYSVAR(io_capacity),
 
9000
  NULL
 
9001
};
9366
9002
 
9367
9003
DRIZZLE_DECLARE_PLUGIN
9368
9004
{
9373
9009
  "Supports transactions, row-level locking, and foreign keys",
9374
9010
  PLUGIN_LICENSE_GPL,
9375
9011
  innobase_init, /* Plugin Init */
9376
 
  NULL, /* system variables */
 
9012
  innobase_system_variables, /* system variables */
9377
9013
  init_options /* reserved */
9378
9014
}
9379
9015
DRIZZLE_DECLARE_PLUGIN_END;
9401
9037
  return res;
9402
9038
}
9403
9039
 
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. */
 
9040
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9041
 
 
9042
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9043
from zero to nonzero. (Bug #42101)
 
9044
 
 
9045
The initial default value is 0, and without this extra initialization,
 
9046
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9047
to 0, even if it was initially set to nonzero at the command line
 
9048
or configuration file. */
 
9049
static
 
9050
void
 
9051
innobase_commit_concurrency_init_default(void)
 
9052
/*==========================================*/
9418
9053
{
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);
 
9054
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9055
    = innobase_commit_concurrency;
9445
9056
}
9446
9057
 
9447
9058
#ifdef UNIV_COMPILE_TEST_FUNCS