~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Joseph Daly
  • Date: 2010-09-12 02:04:41 UTC
  • mto: (1759.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1760.
  • Revision ID: jdaly@rx7-20100912020441-3hc8uahm6ar25i52
fix spacing

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_file_io_threads,
 
191
  innobase_force_recovery, innobase_open_files;
 
192
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
193
static ulong innobase_commit_concurrency = 0;
 
194
static ulong innobase_read_io_threads;
 
195
static ulong innobase_write_io_threads;
 
196
 
 
197
/**
 
198
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
199
 */
 
200
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
201
static int64_t innobase_log_file_size;
238
202
 
239
203
/* The default values for the following char* start-up parameters
240
204
are determined in innobase_init below: */
241
205
 
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;
 
206
static char*  innobase_data_home_dir      = NULL;
 
207
static char*  innobase_data_file_path     = NULL;
 
208
static char*  innobase_log_group_home_dir   = NULL;
 
209
static char*  innobase_file_format_name   = NULL;
 
210
static char*  innobase_change_buffering   = NULL;
 
211
 
 
212
/* Note: This variable can be set to on/off and any of the supported
 
213
file formats in the configuration file, but can only be set to any
 
214
of the supported file formats during runtime. */
 
215
static char*  innobase_file_format_check    = NULL;
 
216
 
 
217
/* The following has a misleading name: starting from 4.0.5, this also
 
218
affects Windows: */
 
219
static char*  innobase_unix_file_flush_method   = NULL;
252
220
 
253
221
/* Below we have boolean-valued start-up parameters, and their default
254
222
values */
255
223
 
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;
 
224
static ulong  innobase_fast_shutdown      = 1;
 
225
#ifdef UNIV_LOG_ARCHIVE
 
226
static my_bool  innobase_log_archive      = FALSE;
 
227
static char*  innobase_log_arch_dir     = NULL;
 
228
#endif /* UNIV_LOG_ARCHIVE */
272
229
static my_bool  innobase_use_doublewrite    = TRUE;
273
230
static my_bool  innobase_use_checksums      = TRUE;
274
231
static my_bool  innobase_rollback_on_timeout    = FALSE;
275
232
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;
 
233
static my_bool  innobase_stats_on_metadata    = TRUE;
281
234
 
282
235
static char*  internal_innobase_data_file_path  = NULL;
283
236
 
 
237
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
238
 
284
239
/* The following counter is used to convey information to InnoDB
285
240
about server activity: in selects it is not sensible to call
286
241
srv_active_wake_master_thread after each fetch or search, we only do
298
253
/** Allowed values of innodb_change_buffering */
299
254
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
300
255
  "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 */
 
256
  "inserts" /* IBUF_USE_INSERT */
306
257
};
307
258
 
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
259
/********************************************************************
313
260
Gives the file extension of an InnoDB single-table tablespace. */
314
261
static const char* ha_innobase_exts[] = {
360
307
    }
361
308
    
362
309
    /* These get strdup'd from vm variables */
 
310
    free(innobase_data_home_dir);
363
311
 
364
312
  }
365
313
 
390
338
  {
391
339
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
392
340
  }
393
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
394
 
  virtual uint64_t doGetNewTransactionId(Session *session);
395
341
  virtual int doCommit(Session* session, bool all);
396
342
  virtual int doRollback(Session* session, bool all);
397
343
 
435
381
        /* out: 0 or error number */
436
382
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
437
383
 
438
 
  virtual Cursor *create(Table &table)
 
384
  virtual Cursor *create(TableShare &table)
439
385
  {
440
386
    return new ha_innobase(*this, table);
441
387
  }
510
456
                           const TableIdentifier &identifier,
511
457
                           drizzled::message::Table &table_proto);
512
458
 
 
459
  void doGetTableNames(drizzled::CachedDirectory &directory,
 
460
                       const drizzled::SchemaIdentifier &schema_identifier,
 
461
                       std::set<std::string> &set_of_names);
 
462
 
513
463
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
514
464
 
515
465
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
466
                             const drizzled::SchemaIdentifier &schema_identifier,
517
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
467
                             drizzled::TableIdentifiers &set_of_identifiers);
518
468
  bool validateCreateTableOption(const std::string &key, const std::string &state);
519
469
  void dropTemporarySchema();
520
470
 
543
493
 
544
494
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
495
                                           const drizzled::SchemaIdentifier &schema_identifier,
546
 
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
 
496
                                           drizzled::TableIdentifiers &set_of_identifiers)
547
497
{
548
498
  CachedDirectory::Entries entries= directory.getEntries();
549
499
 
562
512
    { }
563
513
    else
564
514
    {
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
 
      }
 
515
      char uname[NAME_LEN + 1];
 
516
      uint32_t file_name_len;
 
517
 
 
518
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
519
      // TODO: Remove need for memory copy here
 
520
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
521
 
 
522
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
580
523
    }
581
524
  }
582
525
}
586
529
  string proto_path(identifier.getPath());
587
530
  proto_path.append(DEFAULT_FILE_EXTENSION);
588
531
 
589
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
 
532
  if (session.doesTableMessageExist(identifier))
590
533
    return true;
591
534
 
592
535
  if (access(proto_path.c_str(), F_OK))
605
548
  proto_path.append(DEFAULT_FILE_EXTENSION);
606
549
 
607
550
  // First we check the temporary tables.
608
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
551
  if (session.getTableMessage(identifier, table_proto))
609
552
    return EEXIST;
610
553
 
611
554
  if (access(proto_path.c_str(), F_OK))
619
562
  return ENOENT;
620
563
}
621
564
 
 
565
void InnobaseEngine::doGetTableNames(CachedDirectory &directory, const SchemaIdentifier&, set<string>& set_of_names)
 
566
{
 
567
  CachedDirectory::Entries entries= directory.getEntries();
 
568
 
 
569
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
 
570
       entry_iter != entries.end(); ++entry_iter)
 
571
  {
 
572
    CachedDirectory::Entry *entry= *entry_iter;
 
573
    const string *filename= &entry->filename;
 
574
 
 
575
    assert(filename->size());
 
576
 
 
577
    const char *ext= strchr(filename->c_str(), '.');
 
578
 
 
579
    if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_FILE_EXTENSION) ||
 
580
        (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
 
581
    { }
 
582
    else
 
583
    {
 
584
      char uname[NAME_LEN + 1];
 
585
      uint32_t file_name_len;
 
586
 
 
587
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
588
      // TODO: Remove need for memory copy here
 
589
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
590
      set_of_names.insert(uname);
 
591
    }
 
592
  }
 
593
}
 
594
 
 
595
/** @brief Initialize the default value of innodb_commit_concurrency.
 
596
 
 
597
Once InnoDB is running, the innodb_commit_concurrency must not change
 
598
from zero to nonzero. (Bug #42101)
 
599
 
 
600
The initial default value is 0, and without this extra initialization,
 
601
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
602
to 0, even if it was initially set to nonzero at the command line
 
603
or configuration file. */
 
604
static
 
605
void
 
606
innobase_commit_concurrency_init_default(void);
 
607
/*==========================================*/
622
608
 
623
609
/************************************************************//**
624
610
Validate the file format name and return its corresponding id.
631
617
            name */
632
618
/************************************************************//**
633
619
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(
 
620
sets the srv_check_file_format_at_startup variable.
 
621
@return true if one of  "on" or "off" */
 
622
static
 
623
bool
 
624
innobase_file_format_check_on_off(
 
625
/*==============================*/
 
626
  const char* format_check);    /*!< in: parameter value */
 
627
/************************************************************//**
 
628
Validate the file format check config parameters, as a side effect it
 
629
sets the srv_check_file_format_at_startup variable.
 
630
@return true if valid config value */
 
631
static
 
632
bool
 
633
innobase_file_format_check_validate(
639
634
/*================================*/
640
 
  const char* format_max);    /*!< in: parameter value */
 
635
  const char* format_check);    /*!< in: parameter value */
641
636
 
642
637
static const char innobase_engine_name[]= "InnoDB";
643
638
 
 
639
/*************************************************************//**
 
640
Check for a valid value of innobase_commit_concurrency.
 
641
@return 0 for valid innodb_commit_concurrency */
 
642
static
 
643
int
 
644
innobase_commit_concurrency_validate(
 
645
/*=================================*/
 
646
  Session*      , /*!< in: thread handle */
 
647
  drizzle_sys_var*  , /*!< in: pointer to system
 
648
            variable */
 
649
  void*       save, /*!< out: immediate result
 
650
            for update function */
 
651
  drizzle_value*    value)  /*!< in: incoming string */
 
652
{
 
653
  int64_t   intbuf;
 
654
  ulong   commit_concurrency;
 
655
 
 
656
  if (value->val_int(value, &intbuf)) {
 
657
    /* The value is NULL. That is invalid. */
 
658
    return(1);
 
659
  }
 
660
 
 
661
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
662
    = static_cast<ulong>(intbuf);
 
663
 
 
664
  /* Allow the value to be updated, as long as it remains zero
 
665
  or nonzero. */
 
666
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
667
}
 
668
 
 
669
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
670
  "Enable InnoDB support for the XA two-phase commit",
 
671
  /* check_func */ NULL, /* update_func */ NULL,
 
672
  /* default */ TRUE);
 
673
 
 
674
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
675
  "Enable InnoDB locking in LOCK TABLES",
 
676
  /* check_func */ NULL, /* update_func */ NULL,
 
677
  /* default */ TRUE);
 
678
 
 
679
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
680
  "Use strict mode when evaluating create options.",
 
681
  NULL, NULL, FALSE);
 
682
 
 
683
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
684
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
685
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
686
 
644
687
 
645
688
/*****************************************************************//**
646
689
Commits a transaction in an InnoDB database. */
667
710
  (char*) &export_vars.innodb_buffer_pool_pages_misc,   SHOW_LONG},
668
711
  {"buffer_pool_pages_total",
669
712
  (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},
 
713
  {"buffer_pool_read_ahead_rnd",
 
714
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
 
715
  {"buffer_pool_read_ahead_seq",
 
716
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
674
717
  {"buffer_pool_read_requests",
675
718
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
676
719
  {"buffer_pool_reads",
907
950
ibool
908
951
thd_supports_xa(
909
952
/*============*/
910
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
953
  void* session)  /*!< in: thread handle (Session*), or NULL to query
911
954
        the global innodb_supports_xa */
912
955
{
913
 
  /* TODO: Add support here for per-session value */
914
 
  return(support_xa);
 
956
  return(SessionVAR((Session*) session, support_xa));
915
957
}
916
958
 
917
959
/******************************************************************//**
921
963
ulong
922
964
thd_lock_wait_timeout(
923
965
/*==================*/
924
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
966
  void* session)  /*!< in: thread handle (Session*), or NULL to query
925
967
      the global innodb_lock_wait_timeout */
926
968
{
927
 
  /* TODO: Add support here for per-session value */
928
969
  /* According to <drizzle/plugin.h>, passing session == NULL
929
970
  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
 
        }
 
971
  return(SessionVAR((Session*) session, lock_wait_timeout));
945
972
}
946
973
 
947
974
/********************************************************************//**
956
983
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
957
984
}
958
985
 
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
986
/********************************************************************//**
979
987
Call this function when mysqld passes control to the client. That is to
980
988
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1036
1044
  case DB_SUCCESS:
1037
1045
    return(0);
1038
1046
 
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
1047
  case DB_ERROR:
1055
1048
  default:
1056
1049
    return(-1); /* unspecified error */
1057
1050
 
1058
1051
  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
1052
    return(HA_ERR_FOUND_DUPP_KEY);
1066
1053
 
1067
1054
  case DB_FOREIGN_DUPLICATE_KEY:
1148
1135
    and the actual error code name could very well be different.
1149
1136
    This will require some monitoring, ie. the status
1150
1137
    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 */
 
1138
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
 
1139
    return(ER_TOO_MANY_CONCURRENT_TRXS);
 
1140
#else
1160
1141
    return(HA_ERR_RECORD_FILE_FULL);
1161
 
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1142
#endif
1162
1143
  case DB_UNSUPPORTED:
1163
1144
    return(HA_ERR_UNSUPPORTED);
1164
1145
  }
1165
1146
}
1166
1147
 
1167
1148
 
 
1149
 
 
1150
/*************************************************************//**
 
1151
If you want to print a session that is not associated with the current thread,
 
1152
you must call this function before reserving the InnoDB kernel_mutex, to
 
1153
protect Drizzle from setting session->query NULL. If you print a session of the
 
1154
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1155
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1156
after you release the kernel_mutex.
 
1157
 
 
1158
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1159
         in non-Cursor code.
 
1160
 */
 
1161
extern "C" UNIV_INTERN
 
1162
void
 
1163
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1164
/*============================================*/
 
1165
{
 
1166
  ut_ad(!mutex_own(&kernel_mutex));
 
1167
  LOCK_thread_count.lock();
 
1168
}
 
1169
 
 
1170
/*************************************************************//**
 
1171
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1172
In the InnoDB latching order, the mutex sits right above the
 
1173
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1174
released before this function is invoked. 
 
1175
 
 
1176
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1177
         in non-Cursor code.
 
1178
*/
 
1179
extern "C" UNIV_INTERN
 
1180
void
 
1181
innobase_mysql_end_print_arbitrary_thd(void)
 
1182
/*========================================*/
 
1183
{
 
1184
  ut_ad(!mutex_own(&kernel_mutex));
 
1185
  LOCK_thread_count.unlock();
 
1186
}
 
1187
 
1168
1188
/*************************************************************//**
1169
1189
Prints info of a Session object (== user session thread) to the given file. */
1170
1190
extern "C" UNIV_INTERN
1177
1197
           use the default max length */
1178
1198
{
1179
1199
  Session *session= reinterpret_cast<Session *>(in_session);
1180
 
  drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
1181
 
 
1182
1200
  fprintf(f,
1183
1201
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1184
1202
          static_cast<uint64_t>(session->getSessionId()),
1185
1203
          static_cast<uint64_t>(session->getQueryId()),
1186
1204
          glob_hostname,
1187
 
          user_identifier->address().c_str(),
1188
 
          user_identifier->username().c_str()
1189
 
  );
1190
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1205
          session->getSecurityContext().getIp().c_str(),
 
1206
          session->getSecurityContext().getUser().c_str()
 
1207
  );
 
1208
  fprintf(f,
 
1209
          "\n%s", session->getQueryString().c_str()
 
1210
  );
1191
1211
  putc('\n', f);
1192
1212
}
1193
1213
 
1210
1230
  if (cs) {
1211
1231
    *mbminlen = cs->mbminlen;
1212
1232
    *mbmaxlen = cs->mbmaxlen;
1213
 
    ut_ad(*mbminlen < DATA_MBMAX);
1214
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1215
1233
  } else {
1216
1234
    ut_a(cset == 0);
1217
1235
    *mbminlen = *mbmaxlen = 0;
1279
1297
/*=================*/
1280
1298
  void* mysql_session)  /*!< in: MySQL thread handle */
1281
1299
{
1282
 
  return static_cast<Session*>(mysql_session)->charset();
 
1300
  return session_charset(static_cast<Session*>(mysql_session));
1283
1301
}
1284
1302
 
1285
1303
extern "C" UNIV_INTERN
1299
1317
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1300
1318
}
1301
1319
 
1302
 
/**********************************************************************//**
1303
 
Determines the current SQL statement.
1304
 
@return        SQL statement string */
1305
 
extern "C" UNIV_INTERN
1306
 
const char*
1307
 
innobase_get_stmt(
1308
 
/*==============*/
1309
 
       void*   session,        /*!< in: MySQL thread handle */
1310
 
       size_t* length)         /*!< out: length of the SQL statement */
1311
 
{
1312
 
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
1313
 
}
1314
 
 
1315
1320
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1316
1321
/*******************************************************************//**
1317
1322
Map an OS error to an errno value. The OS error number is stored in
1577
1582
  trx = trx_allocate_for_mysql();
1578
1583
 
1579
1584
  trx->mysql_thd = session;
 
1585
  trx->mysql_query_str = session->query.c_str();
1580
1586
 
1581
1587
  innobase_trx_init(session, trx);
1582
1588
 
1615
1621
Construct ha_innobase Cursor. */
1616
1622
UNIV_INTERN
1617
1623
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1618
 
                         Table &table_arg)
 
1624
                         TableShare &table_arg)
1619
1625
  :Cursor(engine_arg, table_arg),
1620
1626
  primary_key(0), /* needs initialization because index_flags() may be called 
1621
1627
                     before this is set to the real value. It's ok to have any 
1806
1812
/*===============*/
1807
1813
  trx_t*  trx)  /*!< in: transaction */
1808
1814
{
1809
 
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1810
 
}
1811
 
 
1812
 
/**********************************************************************//**
1813
 
Determines if the currently running transaction is in strict mode.
1814
 
@return TRUE if strict */
1815
 
extern "C" UNIV_INTERN
1816
 
ibool
1817
 
trx_is_strict(
1818
 
/*==========*/
1819
 
        trx_t*  trx)    /*!< in: transaction */
1820
 
{
1821
 
        return(trx && trx->mysql_thd
1822
 
               && true);
 
1815
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1823
1816
}
1824
1817
 
1825
1818
/**************************************************************//**
1841
1834
  value= value - (value % align_val);
1842
1835
}
1843
1836
 
1844
 
static void auto_extend_update(Session *, sql_var_t)
1845
 
{
1846
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1847
 
}
1848
 
 
1849
 
static void io_capacity_update(Session *, sql_var_t)
1850
 
{
1851
 
  srv_io_capacity= innodb_io_capacity.get();
1852
 
}
1853
 
 
1854
 
static void purge_batch_update(Session *, sql_var_t)
1855
 
{
1856
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1857
 
}
1858
 
 
1859
 
static void purge_threads_update(Session *, sql_var_t)
1860
 
{
1861
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1862
 
}
1863
 
 
1864
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1865
 
{
1866
 
  if (btr_search_enabled)
1867
 
  {
1868
 
    btr_search_enable();
1869
 
  } else {
1870
 
    btr_search_disable();
1871
 
  }
1872
 
}
1873
 
 
1874
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1875
 
{
1876
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1877
 
}
1878
 
 
1879
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1880
 
{
1881
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1882
 
}
1883
 
 
1884
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1885
 
{
1886
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1887
 
}
1888
 
 
1889
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1890
 
{
1891
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1892
 
}
1893
 
 
1894
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1895
 
{
1896
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1897
 
}
1898
 
 
1899
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1900
 
{
1901
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1902
 
}
1903
 
 
1904
 
 
1905
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1906
 
{
1907
 
   uint32_t new_value= var->save_result.uint32_t_value;
1908
 
 
1909
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1910
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1911
 
   {
1912
 
     push_warning_printf(session,
1913
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1914
 
                         ER_WRONG_ARGUMENTS,
1915
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1916
 
                           "must not change between zero and nonzero."));
1917
 
     return 1;
1918
 
   }
1919
 
   return 0;
1920
 
}
1921
 
 
1922
 
/*************************************************************//**
1923
 
Check if it is a valid file format. This function is registered as
1924
 
a callback with MySQL.
1925
 
@return 0 for valid file format */
1926
 
static
1927
 
int
1928
 
innodb_file_format_name_validate(
1929
 
/*=============================*/
1930
 
  Session*      , /*!< in: thread handle */
1931
 
  set_var *var)
1932
 
{
1933
 
  const char *file_format_input = var->value->str_value.ptr();
1934
 
  if (file_format_input == NULL)
1935
 
    return 1;
1936
 
 
1937
 
  if (file_format_input != NULL) {
1938
 
    uint  format_id;
1939
 
 
1940
 
    format_id = innobase_file_format_name_lookup(
1941
 
      file_format_input);
1942
 
 
1943
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1944
 
      innobase_file_format_name =
1945
 
        trx_sys_file_format_id_to_name(format_id);
1946
 
 
1947
 
      return(0);
1948
 
    }
1949
 
  }
1950
 
 
1951
 
  return(1);
1952
 
}
1953
 
 
1954
 
/*************************************************************//**
1955
 
Check if it is a valid value of innodb_change_buffering. This function is
1956
 
registered as a callback with MySQL.
1957
 
@return 0 for valid innodb_change_buffering */
1958
 
static
1959
 
int
1960
 
innodb_change_buffering_validate(
1961
 
/*=============================*/
1962
 
  Session*      , /*!< in: thread handle */
1963
 
  set_var *var)
1964
 
{
1965
 
  const char *change_buffering_input = var->value->str_value.ptr();
1966
 
 
1967
 
  if (change_buffering_input == NULL)
1968
 
    return 1;
1969
 
 
1970
 
  ulint use;
1971
 
 
1972
 
  for (use = 0;
1973
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1974
 
       ++use) {
1975
 
    if (!innobase_strcasecmp(change_buffering_input,
1976
 
                             innobase_change_buffering_values[use]))
1977
 
    {
1978
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1979
 
      return 0;
1980
 
    }
1981
 
  }
1982
 
 
1983
 
  return 1;
1984
 
}
1985
 
 
1986
 
 
1987
 
/*************************************************************//**
1988
 
Check if valid argument to innodb_file_format_max. This function
1989
 
is registered as a callback with MySQL.
1990
 
@return 0 for valid file format */
1991
 
static
1992
 
int
1993
 
innodb_file_format_max_validate(
1994
 
/*==============================*/
1995
 
  Session*   session, /*!< in: thread handle */
1996
 
  set_var *var)
1997
 
{
1998
 
  const char *file_format_input = var->value->str_value.ptr();
1999
 
  if (file_format_input == NULL)
2000
 
    return 1;
2001
 
 
2002
 
  if (file_format_input != NULL) {
2003
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
2004
 
 
2005
 
    if (format_id > DICT_TF_FORMAT_MAX) {
2006
 
      /* DEFAULT is "on", which is invalid at runtime. */
2007
 
      return 1;
2008
 
    }
2009
 
 
2010
 
    if (format_id >= 0) {
2011
 
      innobase_file_format_max= 
2012
 
        trx_sys_file_format_id_to_name((uint)format_id);
2013
 
 
2014
 
      /* Update the max format id in the system tablespace. */
2015
 
      char name_buff[100];
2016
 
      strcpy(name_buff, innobase_file_format_max.c_str());
2017
 
      if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
2018
 
      {
2019
 
        errmsg_printf(ERRMSG_LVL_WARN,
2020
 
                      " [Info] InnoDB: the file format in the system "
2021
 
                      "tablespace is now set to %s.\n", name_buff);
2022
 
        innobase_file_format_max= name_buff;
2023
 
      }
2024
 
      return(0);
2025
 
 
2026
 
    } else {
2027
 
      push_warning_printf(session,
2028
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
2029
 
                          ER_WRONG_ARGUMENTS,
2030
 
                          "InnoDB: invalid innodb_file_format_max "
2031
 
                          "value; can be any format up to %s "
2032
 
                          "or equivalent id of %d",
2033
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
2034
 
                          DICT_TF_FORMAT_MAX);
2035
 
    }
2036
 
  }
2037
 
 
2038
 
  return(1);
2039
 
}
2040
 
 
2041
 
 
2042
1837
/*********************************************************************//**
2043
1838
Opens an InnoDB database.
2044
1839
@return 0 on success, error code on failure */
2048
1843
/*==========*/
2049
1844
  module::Context &context) /*!< in: Drizzle Plugin Context */
2050
1845
{
 
1846
  static char current_dir[3];   /*!< Set if using current lib */
2051
1847
  int   err;
2052
1848
  bool    ret;
 
1849
  char    *default_path;
2053
1850
  uint    format_id;
2054
1851
  InnobaseEngine *actuall_engine_ptr;
2055
1852
  const module::option_map &vm= context.getOptions();
2056
1853
 
2057
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2058
 
  srv_io_capacity= innodb_io_capacity.get();
2059
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2060
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2061
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2062
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2063
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2064
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2065
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2066
 
  srv_replication_delay= innodb_replication_delay.get();
2067
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2068
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2069
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2070
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2071
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2072
 
 
2073
 
  /* Inverted Booleans */
2074
 
 
2075
 
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2076
 
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2077
 
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2078
 
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2079
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2080
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2081
 
 
2082
 
 
2083
 
  /* Hafta do this here because we need to late-bind the default value */
 
1854
  if (vm.count("io-capacity"))
 
1855
  {
 
1856
    if (srv_io_capacity < 100)
 
1857
    {
 
1858
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1859
      exit(-1);
 
1860
    }
 
1861
  }
 
1862
 
2084
1863
  if (vm.count("data-home-dir"))
2085
1864
  {
2086
 
    innobase_data_home_dir= vm["data-home-dir"].as<string>();
2087
 
  }
2088
 
  else
2089
 
  {
2090
 
    innobase_data_home_dir= getDataHome().file_string();
2091
 
  }
2092
 
 
 
1865
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1866
  }
 
1867
 
 
1868
  else
 
1869
  {
 
1870
    innobase_data_home_dir= NULL;
 
1871
  }
 
1872
 
 
1873
  if (vm.count("fast-shutdown"))
 
1874
  {
 
1875
    if (innobase_fast_shutdown > 2)
 
1876
    {
 
1877
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1878
      exit(-1);
 
1879
    }
 
1880
  }
 
1881
 
 
1882
  if (vm.count("file-format-check"))
 
1883
  {
 
1884
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1885
  }
 
1886
 
 
1887
  if (vm.count("flush-log-at-trx-commit"))
 
1888
  {
 
1889
    if (srv_flush_log_at_trx_commit > 2)
 
1890
    {
 
1891
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1892
      exit(-1);
 
1893
    }
 
1894
  }
 
1895
 
 
1896
  if (vm.count("flush-method"))
 
1897
  {
 
1898
    innobase_unix_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1899
  }
 
1900
  else
 
1901
  {
 
1902
    innobase_unix_file_flush_method= NULL;
 
1903
  }
 
1904
 
 
1905
#ifdef UNIV_LOG_ARCHIVE
 
1906
  if (vm.count("log-arch-dir"))
 
1907
  {
 
1908
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1909
  }
 
1910
 
 
1911
  else
 
1912
  {
 
1913
    innobase_log_arch_dir= NULL;
 
1914
  }
 
1915
#endif /* UNIV_LOG_ARCHIVE */
 
1916
 
 
1917
  if (vm.count("max-dirty-pages-pct"))
 
1918
  {
 
1919
    if (srv_max_buf_pool_modified_pct > 99)
 
1920
    {
 
1921
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1922
      exit(-1);
 
1923
    }
 
1924
  }
 
1925
 
 
1926
  if (vm.count("stats-sample-pages"))
 
1927
  {
 
1928
    if (srv_stats_sample_pages < 8)
 
1929
    {
 
1930
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1931
      exit(-1);
 
1932
    }
 
1933
  }
 
1934
 
 
1935
  if (vm.count("additional-mem-pool-size"))
 
1936
  {
 
1937
    align_value(innobase_additional_mem_pool_size);
 
1938
 
 
1939
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1940
    {
 
1941
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1942
      exit(-1);
 
1943
    }
 
1944
 
 
1945
  }
 
1946
 
 
1947
  if (vm.count("autoextend-increment"))
 
1948
  {
 
1949
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1950
    {
 
1951
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1952
      exit(-1);
 
1953
    }
 
1954
  }
 
1955
 
 
1956
  if (vm.count("buffer-pool-size"))
 
1957
  {
 
1958
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1959
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1960
    {
 
1961
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1962
      exit(-1);
 
1963
    }
 
1964
    
 
1965
  }
 
1966
 
 
1967
  if (vm.count("commit-concurrency"))
 
1968
  {
 
1969
    if (srv_replication_delay > 1000)
 
1970
    {
 
1971
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1972
      exit(-1);
 
1973
    }
 
1974
  }
 
1975
 
 
1976
  if (vm.count("concurrency-tickets"))
 
1977
  {
 
1978
    if (srv_n_free_tickets_to_enter < 1)
 
1979
    {
 
1980
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1981
      exit(-1);
 
1982
    }
 
1983
  }
 
1984
 
 
1985
  if (vm.count("file-io-threads"))
 
1986
  {
 
1987
    if (innobase_file_io_threads < 4 || innobase_file_io_threads > 64)
 
1988
    {
 
1989
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for file-io-threads\n"));
 
1990
      exit(-1);
 
1991
    }
 
1992
  }
 
1993
 
 
1994
  if (vm.count("read-io-threads"))
 
1995
  {
 
1996
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1997
    {
 
1998
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1999
      exit(-1);
 
2000
    }
 
2001
  }
 
2002
 
 
2003
  if (vm.count("write-io-threads"))
 
2004
  {
 
2005
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
2006
    {
 
2007
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
2008
      exit(-1);
 
2009
    }
 
2010
  }
 
2011
 
 
2012
  if (vm.count("force-recovery"))
 
2013
  {
 
2014
    if (innobase_force_recovery > 6)
 
2015
    {
 
2016
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
2017
      exit(-1);
 
2018
    }
 
2019
  }
 
2020
 
 
2021
  if (vm.count("log-buffer-size"))
 
2022
  {
 
2023
    align_value(innobase_log_buffer_size);
 
2024
    if (innobase_log_buffer_size < 256*1024L)
 
2025
    {
 
2026
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2027
      exit(-1);
 
2028
    }
 
2029
  }
 
2030
 
 
2031
  if (vm.count("log-file-size"))
 
2032
  {
 
2033
    align_value(innobase_log_file_size, 1024*1024);
 
2034
    if (innobase_log_file_size < 1*1024*1024L)
 
2035
    {
 
2036
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2037
      exit(-1);
 
2038
    }
 
2039
  }
 
2040
 
 
2041
  if (vm.count("log-files-in-group"))
 
2042
  {
 
2043
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2044
    {
 
2045
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2046
      exit(-1);
 
2047
    }
 
2048
  }
 
2049
 
 
2050
  if (vm.count("mirrored-log-groups"))
 
2051
  {
 
2052
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2053
    {
 
2054
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2055
      exit(-1);
 
2056
    }
 
2057
  }
 
2058
 
 
2059
  if (vm.count("open-files"))
 
2060
  {
 
2061
    if (innobase_open_files < 10)
 
2062
    {
 
2063
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2064
      exit(-1);
 
2065
    }
 
2066
  }
 
2067
 
 
2068
  if (vm.count("thread-concurrency"))
 
2069
  {
 
2070
    if (srv_thread_concurrency > 1000)
 
2071
    {
 
2072
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2073
      exit(-1);
 
2074
    }
 
2075
  }
2093
2076
 
2094
2077
  if (vm.count("data-file-path"))
2095
2078
  {
2096
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2097
 
  }
2098
 
 
 
2079
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2080
  }
 
2081
  else
 
2082
  {
 
2083
    innobase_data_file_path= NULL;
 
2084
  }
 
2085
 
 
2086
  if (vm.count("version"))
 
2087
  {
 
2088
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2089
  }
 
2090
 
 
2091
  if (vm.count("read-ahead-threshold"))
 
2092
  {
 
2093
    if (srv_read_ahead_threshold > 64)
 
2094
    {
 
2095
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2096
      exit(-1);
 
2097
    }
 
2098
  }
 
2099
 
 
2100
  if (vm.count("support-xa"))
 
2101
  {
 
2102
    (SessionVAR(NULL,support_xa))= vm["support-xa"].as<bool>();
 
2103
  }
 
2104
 
 
2105
  if (vm.count("table-locks"))
 
2106
  {
 
2107
    (SessionVAR(NULL,table_locks))= vm["table-locks"].as<bool>();
 
2108
  }
 
2109
 
 
2110
  if (vm.count("strict-mode"))
 
2111
  {
 
2112
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2113
  }
 
2114
 
 
2115
  if (vm.count("lock-wait-timeout"))
 
2116
  {
 
2117
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2118
    {
 
2119
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2120
      exit(-1);
 
2121
    }
 
2122
 
 
2123
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2124
  }
2099
2125
 
2100
2126
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2101
2127
 
2119
2145
  }
2120
2146
#endif /* UNIV_DEBUG */
2121
2147
 
 
2148
  /* Check that values don't overflow on 32-bit systems. */
 
2149
  if (sizeof(ulint) == 4) {
 
2150
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2151
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2152
                    "innobase_buffer_pool_size can't be over 4GB"
 
2153
                    " on 32-bit systems");
 
2154
 
 
2155
      goto error;
 
2156
    }
 
2157
 
 
2158
    if (innobase_log_file_size > UINT32_MAX) {
 
2159
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2160
                    "innobase_log_file_size can't be over 4GB"
 
2161
                    " on 32-bit systems");
 
2162
 
 
2163
      goto error;
 
2164
    }
 
2165
  }
 
2166
 
2122
2167
  os_innodb_umask = (ulint)internal::my_umask;
2123
2168
 
 
2169
  /* First calculate the default path for innodb_data_home_dir etc.,
 
2170
    in case the user has not given any value.
 
2171
 
 
2172
    Note that when using the embedded server, the datadirectory is not
 
2173
    necessarily the current directory of this program. */
 
2174
 
 
2175
  /* It's better to use current lib, to keep paths short */
 
2176
  current_dir[0] = FN_CURLIB;
 
2177
  current_dir[1] = FN_LIBCHAR;
 
2178
  current_dir[2] = 0;
 
2179
  default_path = current_dir;
 
2180
 
 
2181
  ut_a(default_path);
 
2182
 
 
2183
  srv_set_thread_priorities = TRUE;
 
2184
  srv_query_thread_priority = QUERY_PRIOR;
2124
2185
 
2125
2186
  /* Set InnoDB initialization parameters according to the values
2126
2187
    read from MySQL .cnf file */
2129
2190
 
2130
2191
  /* The default dir for data files is the datadir of MySQL */
2131
2192
 
2132
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2193
  srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
 
2194
                   default_path);
2133
2195
 
2134
2196
  /* Set default InnoDB data file size to 10 MB and let it be
2135
2197
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2136
2198
    to specify any startup options. */
2137
2199
 
2138
 
  if (innobase_data_file_path.empty()) 
2139
 
  {
2140
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2200
  if (!innobase_data_file_path) {
 
2201
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2141
2202
  }
2142
2203
 
2143
2204
  /* Since InnoDB edits the argument in the next call, we make another
2144
2205
    copy of it: */
2145
2206
 
2146
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2207
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2147
2208
 
2148
2209
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2149
2210
                                                   internal_innobase_data_file_path);
2163
2224
 
2164
2225
  if (vm.count("log-group-home-dir"))
2165
2226
  {
2166
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2227
    innobase_log_group_home_dir= const_cast<char *>(vm["log-group-home-dir"].as<string>().c_str());
2167
2228
  }
2168
2229
  else
2169
2230
  {
2170
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2231
    innobase_log_group_home_dir = default_path;
2171
2232
  }
2172
2233
 
 
2234
#ifdef UNIV_LOG_ARCHIVE
 
2235
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2236
    starting from 4.0.6 we always set it the same as
 
2237
innodb_log_group_home_dir: */
 
2238
 
 
2239
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2240
 
 
2241
  srv_arch_dir = innobase_log_arch_dir;
 
2242
#endif /* UNIG_LOG_ARCHIVE */
 
2243
 
2173
2244
  ret = (bool)
2174
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2245
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2175
2246
 
2176
 
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2177
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2178
 
                  _("syntax error in innodb_log_group_home_dir, or a "
2179
 
                  "wrong number of mirrored log groups"));
 
2247
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2248
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2249
                  "wrong number of mirrored log groups");
2180
2250
 
2181
2251
    goto mem_free_and_error;
2182
2252
  }
2201
2271
 
2202
2272
  srv_file_format = format_id;
2203
2273
 
2204
 
  innobase_file_format_name =
2205
 
    trx_sys_file_format_id_to_name(format_id);
2206
 
 
2207
 
  /* Check innobase_file_format_check variable */
2208
 
  if (!innobase_file_format_check)
2209
 
  {
2210
 
    /* Set the value to disable checking. */
2211
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
2212
 
  } else {
2213
 
    /* Set the value to the lowest supported format. */
2214
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN;
2215
 
  }
2216
 
 
2217
 
  /* Did the user specify a format name that we support?
2218
 
     As a side effect it will update the variable
2219
 
     srv_max_file_format_at_startup */
2220
 
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2221
 
  {
2222
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
2223
 
                    "innodb_file_format_max value: "
2224
 
                    "should be any value up to %s or its "
2225
 
                    "equivalent numeric id"),
2226
 
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2227
 
    goto mem_free_and_error;
 
2274
  /* Given the type of innobase_file_format_name we have little
 
2275
    choice but to cast away the constness from the returned name.
 
2276
    innobase_file_format_name is used in the MySQL set variable
 
2277
    interface and so can't be const. */
 
2278
 
 
2279
  innobase_file_format_name = 
 
2280
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2281
 
 
2282
  /* Process innobase_file_format_check variable */
 
2283
  ut_a(innobase_file_format_check != NULL);
 
2284
 
 
2285
  /* As a side effect it will set srv_check_file_format_at_startup
 
2286
    on valid input. First we check for "on"/"off". */
 
2287
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2288
 
 
2289
    /* Did the user specify a format name that we support ?
 
2290
      As a side effect it will update the variable
 
2291
      srv_check_file_format_at_startup */
 
2292
    if (!innobase_file_format_check_validate(
 
2293
                                             innobase_file_format_check)) {
 
2294
 
 
2295
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2296
                    "innodb_file_format_check value: "
 
2297
                    "should be either 'on' or 'off' or "
 
2298
                    "any value up to %s or its "
 
2299
                    "equivalent numeric id",
 
2300
                    trx_sys_file_format_id_to_name(
 
2301
                                                   DICT_TF_FORMAT_MAX));
 
2302
 
 
2303
      goto mem_free_and_error;
 
2304
    }
2228
2305
  }
2229
2306
 
2230
2307
  if (vm.count("change-buffering"))
2235
2312
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2236
2313
         use++) {
2237
2314
      if (!innobase_strcasecmp(
2238
 
                               innobase_change_buffering.c_str(),
 
2315
                               vm["change-buffering"].as<string>().c_str(),
2239
2316
                               innobase_change_buffering_values[use])) {
2240
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2317
        ibuf_use = (ibuf_use_t) use;
2241
2318
        goto innobase_change_buffering_inited_ok;
2242
2319
      }
2243
2320
    }
2244
2321
 
2245
2322
    errmsg_printf(ERRMSG_LVL_ERROR,
2246
2323
                  "InnoDB: invalid value "
2247
 
                  "innodb_change_buffering=%s",
 
2324
                  "innodb_file_format_check=%s",
2248
2325
                  vm["change-buffering"].as<string>().c_str());
2249
2326
    goto mem_free_and_error;
2250
2327
  }
2251
2328
 
2252
2329
innobase_change_buffering_inited_ok:
2253
2330
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2254
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2331
  innobase_change_buffering = (char*)
 
2332
    innobase_change_buffering_values[ibuf_use];
2255
2333
 
2256
2334
  /* --------------------------------------------------*/
2257
2335
 
2258
 
  if (vm.count("flush-method") != 0)
2259
 
  {
2260
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2261
 
  }
 
2336
  srv_file_flush_method_str = innobase_unix_file_flush_method;
2262
2337
 
2263
2338
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2264
2339
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2265
2340
  srv_log_file_size = (ulint) innobase_log_file_size;
2266
2341
 
 
2342
#ifdef UNIV_LOG_ARCHIVE
 
2343
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2344
#endif /* UNIV_LOG_ARCHIVE */
2267
2345
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2268
2346
 
2269
2347
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2270
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2271
2348
 
2272
2349
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2273
2350
 
 
2351
  srv_n_file_io_threads = (ulint) innobase_file_io_threads;
2274
2352
  srv_n_read_io_threads = (ulint) innobase_read_io_threads;
2275
2353
  srv_n_write_io_threads = (ulint) innobase_write_io_threads;
2276
2354
 
2298
2376
 
2299
2377
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2300
2378
 
 
2379
 
 
2380
  innobase_commit_concurrency_init_default();
 
2381
 
2301
2382
  /* Since we in this module access directly the fields of a trx
2302
2383
    struct, and due to different headers and flags it might happen that
2303
2384
    mutex_t has a different size in this module and in InnoDB
2306
2387
 
2307
2388
  err = innobase_start_or_create_for_mysql();
2308
2389
 
2309
 
  if (err != DB_SUCCESS)
2310
 
  {
2311
 
    goto mem_free_and_error;
2312
 
  }
2313
 
 
2314
 
  err = dict_create_sys_replication_log();
2315
 
 
2316
2390
  if (err != DB_SUCCESS) {
2317
2391
    goto mem_free_and_error;
2318
2392
  }
2319
2393
 
2320
 
 
2321
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2322
 
                                                     TRUE);
2323
 
 
2324
2394
  innobase_open_tables = hash_create(200);
2325
2395
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2326
2396
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2358
2428
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2359
2429
  context.add(innodb_lock_waits_tool);
2360
2430
 
2361
 
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2362
 
  context.add(innodb_sys_tables_tool);
2363
 
 
2364
 
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2365
 
  context.add(innodb_sys_tablestats_tool);
2366
 
 
2367
 
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2368
 
  context.add(innodb_sys_indexes_tool);
2369
 
 
2370
 
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2371
 
  context.add(innodb_sys_columns_tool);
2372
 
 
2373
 
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2374
 
  context.add(innodb_sys_fields_tool);
2375
 
 
2376
 
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2377
 
  context.add(innodb_sys_foreign_tool);
2378
 
 
2379
 
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2380
 
  context.add(innodb_sys_foreign_cols_tool);
2381
 
 
2382
2431
  context.add(new(std::nothrow)InnodbInternalTables());
2383
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2384
 
 
2385
 
  if (innobase_use_replication_log)
2386
 
  {
2387
 
    replication_logger= new(std::nothrow)ReplicationLog();
2388
 
    context.add(replication_logger);
2389
 
    ReplicationLog::setup(replication_logger);
2390
 
  }
2391
 
 
2392
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2393
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2394
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2395
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2396
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2397
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2398
 
 
2399
 
 
2400
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2401
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2402
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2403
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2404
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2405
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2406
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2407
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2408
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2409
 
 
2410
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2411
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2412
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2413
 
 
2414
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2415
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2416
 
                                                                   innodb_auto_extend_increment,
2417
 
                                                                   auto_extend_update));
2418
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2419
 
                                                                   innodb_io_capacity,
2420
 
                                                                   io_capacity_update));
2421
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2422
 
                                                                   innodb_purge_batch_size,
2423
 
                                                                   purge_batch_update));
2424
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2425
 
                                                                   innodb_n_purge_threads,
2426
 
                                                                   purge_threads_update));
2427
 
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
2428
 
  context.registerVariable(new sys_var_std_string("file_format",
2429
 
                                                  innobase_file_format_name,
2430
 
                                                  innodb_file_format_name_validate));
2431
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2432
 
                                                  innobase_change_buffering,
2433
 
                                                  innodb_change_buffering_validate));
2434
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2435
 
                                                  innobase_file_format_max,
2436
 
                                                  innodb_file_format_max_validate));
2437
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2438
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2439
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2440
 
                                                  innodb_flush_log_at_trx_commit));
2441
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2442
 
                                                  innodb_max_dirty_pages_pct));
2443
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2444
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2445
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2446
 
 
2447
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2448
 
                                                                   innobase_commit_concurrency,
2449
 
                                                                   innodb_commit_concurrency_validate));
2450
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2451
 
                                                                   innodb_concurrency_tickets));
2452
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2453
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2454
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2455
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2456
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2457
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2458
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2459
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2460
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2461
 
                                                                   innobase_old_blocks_pct,
2462
 
                                                                   innodb_old_blocks_pct_update));
2463
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2464
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2465
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2466
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2467
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2468
 
                                                                   innobase_thread_concurrency,
2469
 
                                                                   innodb_thread_concurrency_update));
2470
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2471
 
                                                                   innodb_read_ahead_threshold,
2472
 
                                                                   innodb_read_ahead_threshold_update));
 
2432
 
2473
2433
  /* Get the current high water mark format. */
2474
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2475
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2434
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2476
2435
 
2477
2436
  return(FALSE);
2478
2437
error:
2581
2540
    Note, the position is current because of
2582
2541
    prepare_commit_mutex */
2583
2542
retry:
2584
 
    if (innobase_commit_concurrency.get() > 0) {
 
2543
    if (innobase_commit_concurrency > 0) {
2585
2544
      pthread_mutex_lock(&commit_cond_m);
2586
2545
      commit_threads++;
2587
2546
 
2588
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
2547
      if (commit_threads > innobase_commit_concurrency) {
2589
2548
        commit_threads--;
2590
2549
        pthread_cond_wait(&commit_cond,
2591
2550
          &commit_cond_m);
2610
2569
    innobase_commit_low(trx);
2611
2570
    trx->flush_log_later = FALSE;
2612
2571
 
2613
 
    if (innobase_commit_concurrency.get() > 0) {
 
2572
    if (innobase_commit_concurrency > 0) {
2614
2573
      pthread_mutex_lock(&commit_cond_m);
2615
2574
      commit_threads--;
2616
2575
      pthread_cond_signal(&commit_cond);
2634
2593
    SQL statement */
2635
2594
 
2636
2595
    trx_mark_sql_stat_end(trx);
2637
 
 
2638
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2639
 
    {
2640
 
      if (trx->conc_state != TRX_NOT_STARTED)
2641
 
      {
2642
 
        commit(session, TRUE);
2643
 
      }
2644
 
    }
2645
2596
  }
2646
2597
 
2647
2598
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2656
2607
  threads: */
2657
2608
  srv_active_wake_master_thread();
2658
2609
 
2659
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2660
 
      trx->global_read_view)
2661
 
  {
2662
 
    /* At low transaction isolation levels we let
2663
 
       each consistent read set its own snapshot */
2664
 
    read_view_close_for_mysql(trx);
2665
 
  }
2666
 
 
2667
2610
  return(0);
2668
2611
}
2669
2612
 
2691
2634
 
2692
2635
  innobase_release_stat_resources(trx);
2693
2636
 
2694
 
  trx->n_autoinc_rows = 0;
2695
 
 
2696
2637
  /* If we had reserved the auto-inc lock for some table (if
2697
2638
  we come here to roll back the latest SQL statement) we
2698
2639
  release it now before a possibly lengthy rollback */
2707
2648
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2708
2649
  }
2709
2650
 
2710
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2711
 
      trx->global_read_view)
2712
 
  {
2713
 
    /* At low transaction isolation levels we let
2714
 
       each consistent read set its own snapshot */
2715
 
    read_view_close_for_mysql(trx);
2716
 
  }
2717
 
 
2718
2651
  return(convert_error_code_to_mysql(error, 0, NULL));
2719
2652
}
2720
2653
 
2851
2784
 
2852
2785
  ut_a(trx);
2853
2786
 
2854
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2787
  assert(session->killed != Session::NOT_KILLED ||
2855
2788
         trx->conc_state == TRX_NOT_STARTED);
2856
2789
 
2857
2790
  /* Warn if rolling back some things... */
2858
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2791
  if (session->killed != Session::NOT_KILLED &&
2859
2792
      trx->conc_state != TRX_NOT_STARTED &&
2860
 
      trx->undo_no > 0 &&
 
2793
      trx->undo_no.low > 0 &&
2861
2794
      global_system_variables.log_warnings)
2862
2795
  {
2863
 
      errmsg_printf(ERRMSG_LVL_WARN,
 
2796
      errmsg_printf(ERRMSG_LVL_WARN, 
2864
2797
      "Drizzle is closing a connection during a KILL operation\n"
2865
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2798
      "that has an active InnoDB transaction.  %lu row modifications will "
2866
2799
      "roll back.\n",
2867
 
      (ullint) trx->undo_no);
 
2800
      (ulong) trx->undo_no.low);
2868
2801
  }
2869
2802
 
2870
2803
  innobase_rollback_trx(trx);
2987
2920
}
2988
2921
 
2989
2922
/********************************************************************//**
2990
 
Get the upper limit of the MySQL integral and floating-point type.
2991
 
@return maximum allowed value for the field */
2992
 
static
2993
 
uint64_t
2994
 
innobase_get_int_col_max_value(
2995
 
/*===========================*/
2996
 
        const Field*    field)  /*!< in: MySQL field */
2997
 
{
2998
 
        uint64_t        max_value = 0;
2999
 
 
3000
 
        switch(field->key_type()) {
3001
 
        /* TINY */
3002
 
        case HA_KEYTYPE_BINARY:
3003
 
                max_value = 0xFFULL;
3004
 
                break;
3005
 
        /* LONG */
3006
 
        case HA_KEYTYPE_ULONG_INT:
3007
 
                max_value = 0xFFFFFFFFULL;
3008
 
                break;
3009
 
        case HA_KEYTYPE_LONG_INT:
3010
 
                max_value = 0x7FFFFFFFULL;
3011
 
                break;
3012
 
        /* BIG */
3013
 
        case HA_KEYTYPE_ULONGLONG:
3014
 
                max_value = 0xFFFFFFFFFFFFFFFFULL;
3015
 
                break;
3016
 
        case HA_KEYTYPE_LONGLONG:
3017
 
                max_value = 0x7FFFFFFFFFFFFFFFULL;
3018
 
                break;
3019
 
        case HA_KEYTYPE_DOUBLE:
3020
 
                /* We use the maximum as per IEEE754-2008 standard, 2^53 */
3021
 
                max_value = 0x20000000000000ULL;
3022
 
                break;
3023
 
        default:
3024
 
                ut_error;
3025
 
        }
3026
 
 
3027
 
        return(max_value);
3028
 
}
3029
 
 
3030
 
/*******************************************************************//**
3031
 
This function checks whether the index column information
3032
 
is consistent between KEY info from mysql and that from innodb index.
3033
 
@return TRUE if all column types match. */
3034
 
static
3035
 
ibool
3036
 
innobase_match_index_columns(
3037
 
/*=========================*/
3038
 
        const KeyInfo*          key_info,       /*!< in: Index info
3039
 
                                                from mysql */
3040
 
        const dict_index_t*     index_info)     /*!< in: Index info
3041
 
                                                from Innodb */
3042
 
{
3043
 
        const KeyPartInfo*      key_part;
3044
 
        const KeyPartInfo*      key_end;
3045
 
        const dict_field_t*     innodb_idx_fld;
3046
 
        const dict_field_t*     innodb_idx_fld_end;
3047
 
 
3048
 
        /* Check whether user defined index column count matches */
3049
 
        if (key_info->key_parts != index_info->n_user_defined_cols) {
3050
 
                return(FALSE);
3051
 
        }
3052
 
 
3053
 
        key_part = key_info->key_part;
3054
 
        key_end = key_part + key_info->key_parts;
3055
 
        innodb_idx_fld = index_info->fields;
3056
 
        innodb_idx_fld_end = index_info->fields + index_info->n_fields;
3057
 
 
3058
 
        /* Check each index column's datatype. We do not check
3059
 
        column name because there exists case that index
3060
 
        column name got modified in mysql but such change does not
3061
 
        propagate to InnoDB.
3062
 
        One hidden assumption here is that the index column sequences
3063
 
        are matched up between those in mysql and Innodb. */
3064
 
        for (; key_part != key_end; ++key_part) {
3065
 
                ulint   col_type;
3066
 
                ibool   is_unsigned;
3067
 
                ulint   mtype = innodb_idx_fld->col->mtype;
3068
 
 
3069
 
                /* Need to translate to InnoDB column type before
3070
 
                comparison. */
3071
 
                col_type = get_innobase_type_from_mysql_type(&is_unsigned,
3072
 
                                                             key_part->field);
3073
 
 
3074
 
                /* Ignore Innodb specific system columns. */
3075
 
                while (mtype == DATA_SYS) {
3076
 
                        innodb_idx_fld++;
3077
 
 
3078
 
                        if (innodb_idx_fld >= innodb_idx_fld_end) {
3079
 
                                return(FALSE);
3080
 
                        }
3081
 
                }
3082
 
 
3083
 
                if (col_type != mtype) {
3084
 
                        /* Column Type mismatches */
3085
 
                        return(FALSE);
3086
 
                }
3087
 
 
3088
 
                innodb_idx_fld++;
3089
 
        }
3090
 
 
3091
 
        return(TRUE);
3092
 
}
3093
 
 
3094
 
/*******************************************************************//**
3095
 
This function builds a translation table in INNOBASE_SHARE
3096
 
structure for fast index location with mysql array number from its
3097
 
table->key_info structure. This also provides the necessary translation
3098
 
between the key order in mysql key_info and Innodb ib_table->indexes if
3099
 
they are not fully matched with each other.
3100
 
Note we do not have any mutex protecting the translation table
3101
 
building based on the assumption that there is no concurrent
3102
 
index creation/drop and DMLs that requires index lookup. All table
3103
 
handle will be closed before the index creation/drop.
3104
 
@return TRUE if index translation table built successfully */
3105
 
static
3106
 
ibool
3107
 
innobase_build_index_translation(
3108
 
/*=============================*/
3109
 
        const Table*            table,    /*!< in: table in MySQL data
3110
 
                                          dictionary */
3111
 
        dict_table_t*           ib_table, /*!< in: table in Innodb data
3112
 
                                          dictionary */
3113
 
        INNOBASE_SHARE*         share)    /*!< in/out: share structure
3114
 
                                          where index translation table
3115
 
                                          will be constructed in. */
3116
 
{
3117
 
        ulint           mysql_num_index;
3118
 
        ulint           ib_num_index;
3119
 
        dict_index_t**  index_mapping;
3120
 
        ibool           ret = TRUE;
3121
 
 
3122
 
        mutex_enter(&dict_sys->mutex);
3123
 
 
3124
 
        mysql_num_index = table->getShare()->keys;
3125
 
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3126
 
 
3127
 
        index_mapping = share->idx_trans_tbl.index_mapping;
3128
 
 
3129
 
        /* If there exists inconsistency between MySQL and InnoDB dictionary
3130
 
        (metadata) information, the number of index defined in MySQL
3131
 
        could exceed that in InnoDB, do not build index translation
3132
 
        table in such case */
3133
 
        if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3134
 
                ret = FALSE;
3135
 
                goto func_exit;
3136
 
        }
3137
 
 
3138
 
        /* If index entry count is non-zero, nothing has
3139
 
        changed since last update, directly return TRUE */
3140
 
        if (share->idx_trans_tbl.index_count) {
3141
 
                /* Index entry count should still match mysql_num_index */
3142
 
                ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
3143
 
                goto func_exit;
3144
 
        }
3145
 
 
3146
 
        /* The number of index increased, rebuild the mapping table */
3147
 
        if (mysql_num_index > share->idx_trans_tbl.array_size) {
3148
 
                index_mapping = (dict_index_t**) realloc(index_mapping,
3149
 
                                                        mysql_num_index *
3150
 
                                                         sizeof(*index_mapping));
3151
 
 
3152
 
                if (!index_mapping) {
3153
 
                        /* Report an error if index_mapping continues to be
3154
 
                        NULL and mysql_num_index is a non-zero value */
3155
 
                        errmsg_printf(ERRMSG_LVL_ERROR,
3156
 
                                      "InnoDB: fail to allocate memory for "
3157
 
                                        "index translation table. Number of "
3158
 
                                        "Index:%lu, array size:%lu",
3159
 
                                        mysql_num_index,
3160
 
                                        share->idx_trans_tbl.array_size);
3161
 
                        ret = FALSE;
3162
 
                        goto func_exit;
3163
 
                }
3164
 
 
3165
 
                share->idx_trans_tbl.array_size = mysql_num_index;
3166
 
        }
3167
 
 
3168
 
        /* For each index in the mysql key_info array, fetch its
3169
 
        corresponding InnoDB index pointer into index_mapping
3170
 
        array. */
3171
 
        for (ulint count = 0; count < mysql_num_index; count++) {
3172
 
 
3173
 
                /* Fetch index pointers into index_mapping according to mysql
3174
 
                index sequence */
3175
 
                index_mapping[count] = dict_table_get_index_on_name(
3176
 
                        ib_table, table->key_info[count].name);
3177
 
 
3178
 
                if (!index_mapping[count]) {
3179
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
3180
 
                                        "index dictionary.",
3181
 
                                        table->key_info[count].name);
3182
 
                        ret = FALSE;
3183
 
                        goto func_exit;
3184
 
                }
3185
 
 
3186
 
                /* Double check fetched index has the same
3187
 
                column info as those in mysql key_info. */
3188
 
                if (!innobase_match_index_columns(&table->key_info[count],
3189
 
                                                  index_mapping[count])) {
3190
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
3191
 
                                        "does not match that of MySQL.",
3192
 
                                        table->key_info[count].name);
3193
 
                        ret = FALSE;
3194
 
                        goto func_exit;
3195
 
                }
3196
 
        }
3197
 
 
3198
 
        /* Successfully built the translation table */
3199
 
        share->idx_trans_tbl.index_count = mysql_num_index;
3200
 
 
3201
 
func_exit:
3202
 
        if (!ret) {
3203
 
                /* Build translation table failed. */
3204
 
                free(index_mapping);
3205
 
 
3206
 
                share->idx_trans_tbl.array_size = 0;
3207
 
                share->idx_trans_tbl.index_count = 0;
3208
 
                index_mapping = NULL;
3209
 
        }
3210
 
 
3211
 
        share->idx_trans_tbl.index_mapping = index_mapping;
3212
 
 
3213
 
        mutex_exit(&dict_sys->mutex);
3214
 
 
3215
 
        return(ret);
3216
 
}
3217
 
 
3218
 
/*******************************************************************//**
3219
 
This function uses index translation table to quickly locate the
3220
 
requested index structure.
3221
 
Note we do not have mutex protection for the index translatoin table
3222
 
access, it is based on the assumption that there is no concurrent
3223
 
translation table rebuild (fter create/drop index) and DMLs that
3224
 
require index lookup.
3225
 
@return dict_index_t structure for requested index. NULL if
3226
 
fail to locate the index structure. */
3227
 
static
3228
 
dict_index_t*
3229
 
innobase_index_lookup(
3230
 
/*==================*/
3231
 
        INNOBASE_SHARE* share,  /*!< in: share structure for index
3232
 
                                translation table. */
3233
 
        uint            keynr)  /*!< in: index number for the requested
3234
 
                                index */
3235
 
{
3236
 
        if (!share->idx_trans_tbl.index_mapping
3237
 
            || keynr >= share->idx_trans_tbl.index_count) {
3238
 
                return(NULL);
3239
 
        }
3240
 
 
3241
 
        return(share->idx_trans_tbl.index_mapping[keynr]);
3242
 
}
3243
 
 
3244
 
/********************************************************************//**
3245
2923
Set the autoinc column max value. This should only be called once from
3246
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2924
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2925
@return DB_SUCCESS or error code */
3247
2926
UNIV_INTERN
3248
 
void
 
2927
ulint
3249
2928
ha_innobase::innobase_initialize_autoinc()
3250
2929
/*======================================*/
3251
2930
{
 
2931
  dict_index_t* index;
3252
2932
  uint64_t  auto_inc;
3253
 
  const Field*  field = getTable()->found_next_number_field;
3254
 
 
3255
 
  if (field != NULL) {
3256
 
    auto_inc = innobase_get_int_col_max_value(field);
3257
 
  } else {
3258
 
    /* We have no idea what's been passed in to us as the
3259
 
       autoinc column. We set it to the 0, effectively disabling
3260
 
       updates to the table. */
3261
 
    auto_inc = 0;
3262
 
 
 
2933
  const char* col_name;
 
2934
  ulint   error;
 
2935
 
 
2936
  col_name = table->found_next_number_field->field_name;
 
2937
  index = innobase_get_index(table->getShare()->next_number_index);
 
2938
 
 
2939
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2940
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2941
 
 
2942
  switch (error) {
 
2943
  case DB_SUCCESS:
 
2944
 
 
2945
    /* At the this stage we don't know the increment
 
2946
    or the offset, so use default inrement of 1. */
 
2947
    ++auto_inc;
 
2948
    break;
 
2949
 
 
2950
  case DB_RECORD_NOT_FOUND:
3263
2951
    ut_print_timestamp(stderr);
3264
 
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
3265
 
            "column name\n");
3266
 
  }
3267
 
 
3268
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3269
 
    /* If the recovery level is set so high that writes
3270
 
       are disabled we force the AUTOINC counter to 0
3271
 
       value effectively disabling writes to the table.
3272
 
       Secondly, we avoid reading the table in case the read
3273
 
       results in failure due to a corrupted table/index.
3274
 
 
3275
 
       We will not return an error to the client, so that the
3276
 
       tables can be dumped with minimal hassle.  If an error
3277
 
       were returned in this case, the first attempt to read
3278
 
       the table would fail and subsequent SELECTs would succeed. */
3279
 
    auto_inc = 0;
3280
 
  } else if (field == NULL) {
3281
 
    /* This is a far more serious error, best to avoid
3282
 
       opening the table and return failure. */
3283
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3284
 
  } else {
3285
 
    dict_index_t*       index;
3286
 
    const char* col_name;
3287
 
    uint64_t    read_auto_inc;
3288
 
    ulint               err;
3289
 
 
3290
 
    update_session(getTable()->in_use);
3291
 
    col_name = field->field_name;
3292
 
 
3293
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3294
 
 
3295
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3296
 
 
3297
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3298
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3299
 
 
3300
 
    switch (err) {
3301
 
    case DB_SUCCESS: {
3302
 
      uint64_t col_max_value;
3303
 
 
3304
 
      col_max_value = innobase_get_int_col_max_value(field);
3305
 
 
3306
 
      /* At the this stage we do not know the increment
3307
 
         nor the offset, so use a default increment of 1. */
3308
 
 
3309
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3310
 
 
3311
 
      break;
3312
 
    }
3313
 
    case DB_RECORD_NOT_FOUND:
3314
 
      ut_print_timestamp(stderr);
3315
 
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3316
 
              "dictionaries are out of sync.\n"
3317
 
              "InnoDB: Unable to find the AUTOINC column "
3318
 
              "%s in the InnoDB table %s.\n"
3319
 
              "InnoDB: We set the next AUTOINC column "
3320
 
              "value to 0,\n"
3321
 
              "InnoDB: in effect disabling the AUTOINC "
3322
 
              "next value generation.\n"
3323
 
              "InnoDB: You can either set the next "
3324
 
              "AUTOINC value explicitly using ALTER TABLE\n"
3325
 
              "InnoDB: or fix the data dictionary by "
3326
 
              "recreating the table.\n",
3327
 
              col_name, index->table->name);
3328
 
 
3329
 
      /* This will disable the AUTOINC generation. */
3330
 
      auto_inc = 0;
3331
 
 
3332
 
      /* We want the open to succeed, so that the user can
3333
 
         take corrective action. ie. reads should succeed but
3334
 
         updates should fail. */
3335
 
      err = DB_SUCCESS;
3336
 
      break;
3337
 
    default:
3338
 
      /* row_search_max_autoinc() should only return
3339
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3340
 
      ut_error;
3341
 
    }
 
2952
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2953
      "dictionaries are out of sync.\n"
 
2954
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2955
      "InnoDB table %s.\n"
 
2956
      "InnoDB: We set the next AUTOINC column value to the "
 
2957
      "maximum possible value,\n"
 
2958
      "InnoDB: in effect disabling the AUTOINC next value "
 
2959
      "generation.\n"
 
2960
      "InnoDB: You can either set the next AUTOINC value "
 
2961
      "explicitly using ALTER TABLE\n"
 
2962
      "InnoDB: or fix the data dictionary by recreating "
 
2963
      "the table.\n",
 
2964
      col_name, index->table->name);
 
2965
 
 
2966
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2967
    break;
 
2968
 
 
2969
  default:
 
2970
    return(error);
3342
2971
  }
3343
2972
 
3344
2973
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2974
 
 
2975
  return(DB_SUCCESS);
3345
2976
}
3346
2977
 
3347
2978
/*****************************************************************//**
3361
2992
  UT_NOT_USED(mode);
3362
2993
  UT_NOT_USED(test_if_locked);
3363
2994
 
3364
 
  session= getTable()->in_use;
 
2995
  session= table->in_use;
3365
2996
 
3366
2997
  /* Under some cases Drizzle seems to call this function while
3367
2998
  holding btr_search_latch. This breaks the latching order as
3385
3016
  stored the string length as the first byte. */
3386
3017
 
3387
3018
  upd_and_key_val_buff_len =
3388
 
        getTable()->getShare()->stored_rec_length
3389
 
        + getTable()->getShare()->max_key_length
 
3019
        table->getShare()->stored_rec_length
 
3020
        + table->getShare()->max_key_length
3390
3021
        + MAX_REF_PARTS * 3;
3391
3022
 
3392
3023
  upd_buff.resize(upd_and_key_val_buff_len);
3449
3080
 
3450
3081
  prebuilt = row_create_prebuilt(ib_table);
3451
3082
 
3452
 
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3453
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3083
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3084
  prebuilt->default_rec = table->getDefaultValues();
3454
3085
  ut_ad(prebuilt->default_rec);
3455
3086
 
3456
3087
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3457
3088
 
3458
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3089
  primary_key = table->getShare()->getPrimaryKey();
3459
3090
  key_used_on_scan = primary_key;
3460
3091
 
3461
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3462
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
3463
 
                    " Table %s failed", identifier.getPath().c_str());
3464
 
  }
3465
 
 
3466
3092
  /* Allocate a buffer for a 'row reference'. A row reference is
3467
3093
  a string of bytes of length ref_length which uniquely specifies
3468
3094
  a row in our table. Note that MySQL may also compare two row
3470
3096
  of length ref_length! */
3471
3097
 
3472
3098
  if (!row_table_got_default_clust_index(ib_table)) {
 
3099
    if (primary_key >= MAX_KEY) {
 
3100
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3101
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3102
    }
3473
3103
 
3474
3104
    prebuilt->clust_index_was_generated = FALSE;
3475
3105
 
3476
 
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3477
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3478
 
                    "InnoDB data dictionary, but not "
3479
 
                    "in MySQL!", identifier.getTableName().c_str());
3480
 
 
3481
 
      /* This mismatch could cause further problems
3482
 
         if not attended, bring this to the user's attention
3483
 
         by printing a warning in addition to log a message
3484
 
         in the errorlog */
3485
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3486
 
                          ER_NO_SUCH_INDEX,
3487
 
                          "InnoDB: Table %s has a "
3488
 
                          "primary key in InnoDB data "
3489
 
                          "dictionary, but not in "
3490
 
                          "MySQL!", identifier.getTableName().c_str());
3491
 
 
3492
 
      /* If primary_key >= MAX_KEY, its (primary_key)
3493
 
         value could be out of bound if continue to index
3494
 
         into key_info[] array. Find InnoDB primary index,
3495
 
         and assign its key_length to ref_length.
3496
 
         In addition, since MySQL indexes are sorted starting
3497
 
         with primary index, unique index etc., initialize
3498
 
         ref_length to the first index key length in
3499
 
         case we fail to find InnoDB cluster index.
3500
 
 
3501
 
         Please note, this will not resolve the primary
3502
 
         index mismatch problem, other side effects are
3503
 
         possible if users continue to use the table.
3504
 
         However, we allow this table to be opened so
3505
 
         that user can adopt necessary measures for the
3506
 
         mismatch while still being accessible to the table
3507
 
         date. */
3508
 
      ref_length = getTable()->key_info[0].key_length;
3509
 
 
3510
 
      /* Find correspoinding cluster index
3511
 
         key length in MySQL's key_info[] array */
3512
 
      for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3513
 
        dict_index_t*   index;
3514
 
        index = innobase_get_index(i);
3515
 
        if (dict_index_is_clust(index)) {
3516
 
          ref_length =
3517
 
            getTable()->key_info[i].key_length;
3518
 
        }
3519
 
      }
3520
 
    } else {
3521
 
      /* MySQL allocates the buffer for ref.
3522
 
         key_info->key_length includes space for all key
3523
 
         columns + one byte for each column that may be
3524
 
         NULL. ref_length must be as exact as possible to
3525
 
         save space, because all row reference buffers are
3526
 
         allocated based on ref_length. */
3527
 
 
3528
 
      ref_length = getTable()->key_info[primary_key].key_length;
3529
 
    }
 
3106
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3107
    includes space for all key columns + one byte for each column
 
3108
    that may be NULL. ref_length must be as exact as possible to
 
3109
    save space, because all row reference buffers are allocated
 
3110
    based on ref_length. */
 
3111
 
 
3112
    ref_length = table->key_info[primary_key].key_length;
3530
3113
  } else {
3531
3114
    if (primary_key != MAX_KEY) {
3532
 
      errmsg_printf(ERRMSG_LVL_ERROR,
3533
 
                    "Table %s has no primary key in InnoDB data "
3534
 
                    "dictionary, but has one in MySQL! If you "
3535
 
                    "created the table with a MySQL version < "
3536
 
                    "3.23.54 and did not define a primary key, "
3537
 
                    "but defined a unique key with all non-NULL "
3538
 
                    "columns, then MySQL internally treats that "
3539
 
                    "key as the primary key. You can fix this "
3540
 
                    "error by dump + DROP + CREATE + reimport "
3541
 
                    "of the table.", identifier.getTableName().c_str());
3542
 
 
3543
 
      /* This mismatch could cause further problems
3544
 
         if not attended, bring this to the user attention
3545
 
         by printing a warning in addition to log a message
3546
 
         in the errorlog */
3547
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3548
 
                          ER_NO_SUCH_INDEX,
3549
 
                          "InnoDB: Table %s has no "
3550
 
                          "primary key in InnoDB data "
3551
 
                          "dictionary, but has one in "
3552
 
                          "MySQL!", identifier.getTableName().c_str());
 
3115
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3116
          "dictionary, but has one in MySQL! If you "
 
3117
          "created the table with a MySQL version < "
 
3118
          "3.23.54 and did not define a primary key, "
 
3119
          "but defined a unique key with all non-NULL "
 
3120
          "columns, then MySQL internally treats that "
 
3121
          "key as the primary key. You can fix this "
 
3122
          "error by dump + DROP + CREATE + reimport "
 
3123
          "of the table.", identifier.getTableName().c_str());
3553
3124
    }
3554
3125
 
3555
3126
    prebuilt->clust_index_was_generated = TRUE;
3582
3153
    /* We update the highest file format in the system table
3583
3154
    space, if this table has higher file format setting. */
3584
3155
 
3585
 
    char changed_file_format_max[100];
3586
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3587
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
 
3156
    trx_sys_file_format_max_upgrade(
 
3157
      (const char**) &innobase_file_format_check,
3588
3158
      dict_table_get_format(prebuilt->table));
3589
 
    innobase_file_format_max= changed_file_format_max;
3590
3159
  }
3591
3160
 
 
3161
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3162
 
3592
3163
  /* Only if the table has an AUTOINC column. */
3593
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3164
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3165
    ulint error;
3594
3166
 
3595
3167
    dict_table_autoinc_lock(prebuilt->table);
3596
3168
 
3600
3172
    autoinc value from a previous Drizzle open. */
3601
3173
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3602
3174
 
3603
 
      innobase_initialize_autoinc();
 
3175
      error = innobase_initialize_autoinc();
 
3176
      ut_a(error == DB_SUCCESS);
3604
3177
    }
3605
3178
 
3606
3179
    dict_table_autoinc_unlock(prebuilt->table);
3607
3180
  }
3608
3181
 
3609
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3610
 
 
3611
3182
  return(0);
3612
3183
}
3613
3184
 
3628
3199
{
3629
3200
  Session*  session;
3630
3201
 
3631
 
  session= getTable()->in_use;
 
3202
  session= table->in_use;
3632
3203
  if (session != NULL) {
3633
3204
    getTransactionalEngine()->releaseTemporaryLatches(session);
3634
3205
  }
3855
3426
  case DRIZZLE_TYPE_DATETIME:
3856
3427
  case DRIZZLE_TYPE_DATE:
3857
3428
  case DRIZZLE_TYPE_TIMESTAMP:
3858
 
  case DRIZZLE_TYPE_ENUM:
3859
3429
    return(DATA_INT);
3860
3430
  case DRIZZLE_TYPE_DOUBLE:
3861
3431
    return(DATA_DOUBLE);
3862
3432
  case DRIZZLE_TYPE_BLOB:
3863
 
    return(DATA_BLOB);
3864
 
  case DRIZZLE_TYPE_UUID:
3865
 
    return(DATA_FIXBINARY);
3866
 
  case DRIZZLE_TYPE_NULL:
 
3433
                return(DATA_BLOB);
 
3434
  default:
3867
3435
    ut_error;
3868
3436
  }
3869
3437
 
3912
3480
  uint    buff_len,/*!< in: buffer length */
3913
3481
  const unsigned char*  record)/*!< in: row in MySQL format */
3914
3482
{
3915
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3483
  KeyInfo*    key_info  = &table->key_info[keynr];
3916
3484
  KeyPartInfo*  key_part  = key_info->key_part;
3917
3485
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3918
3486
  char*   buff_start  = buff;
3984
3552
      cs = field->charset();
3985
3553
 
3986
3554
      lenlen = (ulint)
3987
 
        (((Field_varstring*)field)->pack_length_no_ptr());
 
3555
        (((Field_varstring*)field)->length_bytes);
3988
3556
 
3989
3557
      data = row_mysql_read_true_varchar(&len,
3990
3558
        (byte*) (record
3991
 
        + (ulint)get_field_offset(getTable(), field)),
 
3559
        + (ulint)get_field_offset(table, field)),
3992
3560
        lenlen);
3993
3561
 
3994
3562
      true_len = len;
4051
3619
 
4052
3620
      blob_data = row_mysql_read_blob_ref(&blob_len,
4053
3621
        (byte*) (record
4054
 
        + (ulint)get_field_offset(getTable(), field)),
 
3622
        + (ulint)get_field_offset(table, field)),
4055
3623
          (ulint) field->pack_length());
4056
3624
 
4057
3625
      true_len = blob_len;
4058
3626
 
4059
 
      ut_a(get_field_offset(getTable(), field)
 
3627
      ut_a(get_field_offset(table, field)
4060
3628
        == key_part->offset);
4061
3629
 
4062
3630
      /* For multi byte character sets we need to calculate
4103
3671
      ulint     key_len;
4104
3672
      const unsigned char*    src_start;
4105
3673
      enum_field_types  real_type;
4106
 
      const CHARSET_INFO* cs= field->charset();
4107
3674
 
4108
3675
      key_len = key_part->length;
4109
3676
 
4125
3692
      memcpy(buff, src_start, true_len);
4126
3693
      buff += true_len;
4127
3694
 
4128
 
      /* Pad the unused space with spaces. */
 
3695
      /* Pad the unused space with spaces. Note that no
 
3696
      padding is ever needed for UCS-2 because in MySQL,
 
3697
      all UCS2 characters are 2 bytes, as MySQL does not
 
3698
      support surrogate pairs, which are needed to represent
 
3699
      characters in the range U+10000 to U+10FFFF. */
4129
3700
 
4130
3701
      if (true_len < key_len) {
4131
 
        ulint   pad_len = key_len - true_len;
4132
 
        ut_a(!(pad_len % cs->mbminlen));
4133
 
 
4134
 
        cs->cset->fill(cs, buff, pad_len,
4135
 
                       0x20 /* space */);
 
3702
        ulint pad_len = key_len - true_len;
 
3703
        memset(buff, ' ', pad_len);
4136
3704
        buff += pad_len;
4137
3705
      }
4138
3706
    }
4240
3808
 
4241
3809
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4242
3810
  'fields'. */
4243
 
  for (i = 0; i < n_fields; i++)
 
3811
  for (i = 0; i < n_fields; i++) 
4244
3812
  {
4245
 
    const dict_col_t *col= &index->table->cols[i];
4246
3813
    templ = prebuilt->mysql_template + n_requested_fields;
4247
3814
    field = table->getField(i);
4248
3815
 
4290
3857
    templ->col_no = i;
4291
3858
 
4292
3859
    if (index == clust_index) {
4293
 
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
 
3860
      templ->rec_field_no = dict_col_get_clust_pos(
 
3861
        &index->table->cols[i], index);
4294
3862
    } else {
4295
3863
      templ->rec_field_no = dict_index_get_nth_col_pos(
4296
3864
                index, i);
4319
3887
      mysql_prefix_len = templ->mysql_col_offset
4320
3888
        + templ->mysql_col_len;
4321
3889
    }
4322
 
    templ->type = col->mtype;
 
3890
    templ->type = index->table->cols[i].mtype;
4323
3891
    templ->mysql_type = (ulint)field->type();
4324
3892
 
4325
3893
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4326
3894
      templ->mysql_length_bytes = (ulint)
4327
 
        (((Field_varstring*)field)->pack_length_no_ptr());
 
3895
        (((Field_varstring*)field)->length_bytes);
4328
3896
    }
4329
3897
 
4330
 
    templ->charset = dtype_get_charset_coll(col->prtype);
4331
 
    templ->mbminlen = dict_col_get_mbminlen(col);
4332
 
    templ->mbmaxlen = dict_col_get_mbmaxlen(col);
4333
 
    templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 
3898
    templ->charset = dtype_get_charset_coll(
 
3899
      index->table->cols[i].prtype);
 
3900
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3901
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3902
    templ->is_unsigned = index->table->cols[i].prtype
 
3903
              & DATA_UNSIGNED;
4334
3904
    if (templ->type == DATA_BLOB) {
4335
3905
      prebuilt->templ_contains_blob = TRUE;
4336
3906
    }
4355
3925
}
4356
3926
 
4357
3927
/********************************************************************//**
 
3928
Get the upper limit of the MySQL integral and floating-point type. */
 
3929
UNIV_INTERN
 
3930
uint64_t
 
3931
ha_innobase::innobase_get_int_col_max_value(
 
3932
/*========================================*/
 
3933
  const Field*  field)
 
3934
{
 
3935
  uint64_t  max_value = 0;
 
3936
 
 
3937
  switch(field->key_type()) {
 
3938
  /* TINY */
 
3939
  case HA_KEYTYPE_BINARY:
 
3940
    max_value = 0xFFULL;
 
3941
    break;
 
3942
  /* MEDIUM */
 
3943
  case HA_KEYTYPE_UINT24:
 
3944
    max_value = 0xFFFFFFULL;
 
3945
    break;
 
3946
  /* LONG */
 
3947
  case HA_KEYTYPE_ULONG_INT:
 
3948
    max_value = 0xFFFFFFFFULL;
 
3949
    break;
 
3950
  case HA_KEYTYPE_LONG_INT:
 
3951
    max_value = 0x7FFFFFFFULL;
 
3952
    break;
 
3953
  /* BIG */
 
3954
  case HA_KEYTYPE_ULONGLONG:
 
3955
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3956
    break;
 
3957
  case HA_KEYTYPE_LONGLONG:
 
3958
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3959
    break;
 
3960
  case HA_KEYTYPE_DOUBLE:
 
3961
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3962
    max_value = 0x20000000000000ULL;
 
3963
    break;
 
3964
  default:
 
3965
    ut_error;
 
3966
  }
 
3967
 
 
3968
  return(max_value);
 
3969
}
 
3970
 
 
3971
/********************************************************************//**
4358
3972
This special handling is really to overcome the limitations of MySQL's
4359
3973
binlogging. We need to eliminate the non-determinism that will arise in
4360
3974
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4505
4119
  num_write_row++;
4506
4120
 
4507
4121
  /* This is the case where the table has an auto-increment column */
4508
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4122
  if (table->next_number_field && record == table->getInsertRecord()) {
4509
4123
 
4510
4124
    /* Reset the error code before calling
4511
4125
    innobase_get_auto_increment(). */
4512
4126
    prebuilt->autoinc_error = DB_SUCCESS;
4513
4127
 
4514
4128
    if ((error = update_auto_increment())) {
 
4129
 
4515
4130
      /* We don't want to mask autoinc overflow errors. */
4516
 
 
4517
 
      /* Handle the case where the AUTOINC sub-system
4518
 
         failed during initialization. */
4519
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4520
 
        error_result = ER_AUTOINC_READ_FAILED;
4521
 
        /* Set the error message to report too. */
4522
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4523
 
        goto func_exit;
4524
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4131
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4525
4132
        error = (int) prebuilt->autoinc_error;
4526
4133
 
4527
4134
        goto report_error;
4541
4148
    /* Build the template used in converting quickly between
4542
4149
    the two database formats */
4543
4150
 
4544
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4151
    build_template(prebuilt, NULL, table,
 
4152
             ROW_MYSQL_WHOLE_ROW);
4545
4153
  }
4546
4154
 
4547
4155
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4548
4156
 
4549
4157
  error = row_insert_for_mysql((byte*) record, prebuilt);
4550
4158
 
4551
 
  user_session->setXaId(trx->id);
4552
 
 
4553
4159
  /* Handle duplicate key errors */
4554
4160
  if (auto_inc_used) {
4555
4161
    ulint   err;
4567
4173
    /* We need the upper limit of the col type to check for
4568
4174
    whether we update the table autoinc counter or not. */
4569
4175
    col_max_value = innobase_get_int_col_max_value(
4570
 
      getTable()->next_number_field); 
 
4176
      table->next_number_field);
 
4177
 
4571
4178
    /* Get the value that MySQL attempted to store in the table.*/
4572
 
    auto_inc = getTable()->next_number_field->val_int();
 
4179
    auto_inc = table->next_number_field->val_int();
4573
4180
 
4574
4181
    switch (error) {
4575
4182
    case DB_DUPLICATE_KEY:
4605
4212
      update the table upper limit. Note: last_value
4606
4213
      will be 0 if get_auto_increment() was not called.*/
4607
4214
 
4608
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4215
      if (auto_inc <= col_max_value
 
4216
          && auto_inc >= prebuilt->autoinc_last_value) {
4609
4217
set_max_autoinc:
4610
 
        /* This should filter out the negative
4611
 
           values set explicitly by the user. */
4612
 
        if (auto_inc <= col_max_value) {
4613
 
          ut_a(prebuilt->autoinc_increment > 0);
4614
 
 
4615
 
          uint64_t      need;
4616
 
          uint64_t      offset;
4617
 
 
4618
 
          offset = prebuilt->autoinc_offset;
4619
 
          need = prebuilt->autoinc_increment;
4620
 
 
4621
 
          auto_inc = innobase_next_autoinc(
4622
 
                                           auto_inc,
4623
 
                                           need, offset, col_max_value);
4624
 
 
4625
 
          err = innobase_set_max_autoinc(
4626
 
                                         auto_inc);
4627
 
 
4628
 
          if (err != DB_SUCCESS) {
4629
 
            error = err;
4630
 
          }
 
4218
        ut_a(prebuilt->autoinc_increment > 0);
 
4219
 
 
4220
        uint64_t  need;
 
4221
        uint64_t  offset;
 
4222
 
 
4223
        offset = prebuilt->autoinc_offset;
 
4224
        need = prebuilt->autoinc_increment;
 
4225
 
 
4226
        auto_inc = innobase_next_autoinc(
 
4227
          auto_inc, need, offset, col_max_value);
 
4228
 
 
4229
        err = innobase_set_max_autoinc(auto_inc);
 
4230
 
 
4231
        if (err != DB_SUCCESS) {
 
4232
          error = err;
4631
4233
        }
4632
4234
      }
4633
4235
      break;
4728
4330
        o_ptr = row_mysql_read_true_varchar(
4729
4331
          &o_len, o_ptr,
4730
4332
          (ulint)
4731
 
          (((Field_varstring*)field)->pack_length_no_ptr()));
 
4333
          (((Field_varstring*)field)->length_bytes));
4732
4334
 
4733
4335
        n_ptr = row_mysql_read_true_varchar(
4734
4336
          &n_len, n_ptr,
4735
4337
          (ulint)
4736
 
          (((Field_varstring*)field)->pack_length_no_ptr()));
 
4338
          (((Field_varstring*)field)->length_bytes));
4737
4339
      }
4738
4340
 
4739
4341
      break;
4824
4426
  /* Build an update vector from the modified fields in the rows
4825
4427
  (uses upd_buff of the handle) */
4826
4428
 
4827
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4429
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4828
4430
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4829
4431
      prebuilt, user_session);
4830
4432
 
4833
4435
 
4834
4436
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4835
4437
 
4836
 
  if (getTable()->found_next_number_field)
 
4438
  if (table->found_next_number_field)
4837
4439
  {
4838
4440
    uint64_t  auto_inc;
4839
4441
    uint64_t  col_max_value;
4840
4442
 
4841
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4443
    auto_inc = table->found_next_number_field->val_int();
4842
4444
 
4843
4445
    /* We need the upper limit of the col type to check for
4844
4446
    whether we update the table autoinc counter or not. */
4845
4447
    col_max_value = innobase_get_int_col_max_value(
4846
 
      getTable()->found_next_number_field);
 
4448
      table->found_next_number_field);
4847
4449
 
4848
4450
    uint64_t current_autoinc;
4849
4451
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4871
4473
 
4872
4474
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4873
4475
 
4874
 
  user_session->setXaId(trx->id);
4875
 
 
4876
4476
  /* We need to do some special AUTOINC handling for the following case:
4877
4477
 
4878
4478
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4882
4482
  value used in the INSERT statement.*/
4883
4483
 
4884
4484
  if (error == DB_SUCCESS
4885
 
      && getTable()->next_number_field
4886
 
      && new_row == getTable()->getInsertRecord()
 
4485
      && table->next_number_field
 
4486
      && new_row == table->getInsertRecord()
4887
4487
      && session_sql_command(user_session) == SQLCOM_INSERT
4888
4488
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4889
4489
    == TRX_DUP_IGNORE)  {
4891
4491
    uint64_t  auto_inc;
4892
4492
    uint64_t  col_max_value;
4893
4493
 
4894
 
    auto_inc = getTable()->next_number_field->val_int();
 
4494
    auto_inc = table->next_number_field->val_int();
4895
4495
 
4896
4496
    /* We need the upper limit of the col type to check for
4897
4497
    whether we update the table autoinc counter or not. */
4898
4498
    col_max_value = innobase_get_int_col_max_value(
4899
 
      getTable()->next_number_field);
 
4499
      table->next_number_field);
4900
4500
 
4901
4501
    if (auto_inc <= col_max_value && auto_inc != 0) {
4902
4502
 
4963
4563
 
4964
4564
  error = row_update_for_mysql((byte*) record, prebuilt);
4965
4565
 
4966
 
  user_session->setXaId(trx->id);
4967
 
 
4968
4566
  innodb_srv_conc_exit_innodb(trx);
4969
4567
 
4970
4568
  error = convert_error_code_to_mysql(
4998
4596
  case ROW_READ_WITH_LOCKS:
4999
4597
    if (!srv_locks_unsafe_for_binlog
5000
4598
        && prebuilt->trx->isolation_level
5001
 
        > TRX_ISO_READ_COMMITTED) {
 
4599
        != TRX_ISO_READ_COMMITTED) {
5002
4600
      break;
5003
4601
    }
5004
4602
    /* fall through */
5028
4626
ha_innobase::try_semi_consistent_read(bool yes)
5029
4627
/*===========================================*/
5030
4628
{
5031
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4629
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5032
4630
 
5033
4631
  /* Row read type is set to semi consistent read if this was
5034
4632
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
5037
4635
 
5038
4636
  if (yes
5039
4637
      && (srv_locks_unsafe_for_binlog
5040
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4638
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
5041
4639
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
5042
4640
  } else {
5043
4641
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5218
4816
 
5219
4817
  index = prebuilt->index;
5220
4818
 
5221
 
  if (UNIV_UNLIKELY(index == NULL)) {
5222
 
    prebuilt->index_usable = FALSE;
5223
 
    return(HA_ERR_CRASHED);
5224
 
  }
5225
 
 
5226
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5227
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5228
 
  }
5229
 
 
5230
4819
  /* Note that if the index for which the search template is built is not
5231
4820
  necessarily prebuilt->index, but can also be the clustered index */
5232
4821
 
5233
4822
  if (prebuilt->sql_stat_start) {
5234
 
    build_template(prebuilt, user_session, getTable(),
 
4823
    build_template(prebuilt, user_session, table,
5235
4824
             ROW_MYSQL_REC_FIELDS);
5236
4825
  }
5237
4826
 
5286
4875
  switch (ret) {
5287
4876
  case DB_SUCCESS:
5288
4877
    error = 0;
5289
 
    getTable()->status = 0;
 
4878
    table->status = 0;
5290
4879
    break;
5291
4880
  case DB_RECORD_NOT_FOUND:
5292
4881
    error = HA_ERR_KEY_NOT_FOUND;
5293
 
    getTable()->status = STATUS_NOT_FOUND;
 
4882
    table->status = STATUS_NOT_FOUND;
5294
4883
    break;
5295
4884
  case DB_END_OF_INDEX:
5296
4885
    error = HA_ERR_KEY_NOT_FOUND;
5297
 
    getTable()->status = STATUS_NOT_FOUND;
 
4886
    table->status = STATUS_NOT_FOUND;
5298
4887
    break;
5299
4888
  default:
5300
4889
    error = convert_error_code_to_mysql((int) ret,
5301
4890
                prebuilt->table->flags,
5302
4891
                user_session);
5303
 
    getTable()->status = STATUS_NOT_FOUND;
 
4892
    table->status = STATUS_NOT_FOUND;
5304
4893
    break;
5305
4894
  }
5306
4895
 
5339
4928
 
5340
4929
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5341
4930
 
5342
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4931
  ut_ad(user_session == table->in_use);
 
4932
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4933
 
 
4934
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5343
4935
  {
5344
 
    KeyInfo *key = getTable()->key_info + keynr;
5345
 
    index = innobase_index_lookup(share, keynr);
5346
 
 
5347
 
    if (index) {
5348
 
      ut_a(ut_strcmp(index->name, key->name) == 0);
5349
 
    } else {
5350
 
      /* Can't find index with keynr in the translation
5351
 
         table. Only print message if the index translation
5352
 
         table exists */
5353
 
      if (share->idx_trans_tbl.index_mapping) {
5354
 
        errmsg_printf(ERRMSG_LVL_ERROR,
5355
 
                      "InnoDB could not find "
5356
 
                      "index %s key no %u for "
5357
 
                      "table %s through its "
5358
 
                      "index translation table",
5359
 
                      key ? key->name : "NULL",
5360
 
                      keynr,
5361
 
                      prebuilt->table->name);
5362
 
      }
5363
 
 
5364
 
      index = dict_table_get_index_on_name(prebuilt->table,
5365
 
                                           key->name);
5366
 
    }
 
4936
    index = dict_table_get_index_on_name(prebuilt->table,
 
4937
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5367
4938
  } else {
5368
4939
    index = dict_table_get_first_index(prebuilt->table);
5369
4940
  }
5372
4943
    errmsg_printf(ERRMSG_LVL_ERROR, 
5373
4944
      "Innodb could not find key n:o %u with name %s "
5374
4945
      "from dict cache for table %s",
5375
 
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
 
4946
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5376
4947
      prebuilt->table->name);
5377
4948
  }
5378
4949
 
5400
4971
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5401
4972
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5402
4973
          keynr);
5403
 
    prebuilt->index_usable = FALSE;
5404
4974
    return(1);
5405
4975
  }
5406
4976
 
5408
4978
                 prebuilt->index);
5409
4979
 
5410
4980
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5411
 
    push_warning_printf(user_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5412
 
                        HA_ERR_TABLE_DEF_CHANGED,
5413
 
                        "InnoDB: insufficient history for index %u",
5414
 
                        keynr);
 
4981
    errmsg_printf(ERRMSG_LVL_WARN,
 
4982
         "InnoDB: insufficient history for index %u",
 
4983
          keynr);
5415
4984
    /* The caller seems to ignore this.  Thus, we must check
5416
4985
    this again in row_search_for_mysql(). */
5417
4986
    return(2);
5430
4999
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5431
5000
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5432
5001
 
5433
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
5002
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5434
5003
 
5435
5004
  return(0);
5436
5005
}
5490
5059
  switch (ret) {
5491
5060
  case DB_SUCCESS:
5492
5061
    error = 0;
5493
 
    getTable()->status = 0;
 
5062
    table->status = 0;
5494
5063
    break;
5495
5064
  case DB_RECORD_NOT_FOUND:
5496
5065
    error = HA_ERR_END_OF_FILE;
5497
 
    getTable()->status = STATUS_NOT_FOUND;
 
5066
    table->status = STATUS_NOT_FOUND;
5498
5067
    break;
5499
5068
  case DB_END_OF_INDEX:
5500
5069
    error = HA_ERR_END_OF_FILE;
5501
 
    getTable()->status = STATUS_NOT_FOUND;
 
5070
    table->status = STATUS_NOT_FOUND;
5502
5071
    break;
5503
5072
  default:
5504
5073
    error = convert_error_code_to_mysql(
5505
5074
      (int) ret, prebuilt->table->flags, user_session);
5506
 
    getTable()->status = STATUS_NOT_FOUND;
 
5075
    table->status = STATUS_NOT_FOUND;
5507
5076
    break;
5508
5077
  }
5509
5078
 
5698
5267
 
5699
5268
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5700
5269
 
5701
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5270
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5702
5271
 
5703
5272
  if (prebuilt->clust_index_was_generated) {
5704
5273
    /* No primary key was defined for the table and we
5744
5313
{
5745
5314
  uint    len;
5746
5315
 
5747
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5316
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5748
5317
 
5749
5318
  if (prebuilt->clust_index_was_generated) {
5750
5319
    /* No primary key was defined for the table and we
5820
5389
 
5821
5390
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5822
5391
                  field);
5823
 
 
5824
 
    if (!col_type) {
5825
 
      push_warning_printf(
5826
 
                          (Session*) trx->mysql_thd,
5827
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5828
 
                          ER_CANT_CREATE_TABLE,
5829
 
                          "Error creating table '%s' with "
5830
 
                          "column '%s'. Please check its "
5831
 
                          "column type and try to re-create "
5832
 
                          "the table with an appropriate "
5833
 
                          "column type.",
5834
 
                          table->name, (char*) field->field_name);
5835
 
      goto err_col;
5836
 
    }
5837
 
 
5838
5392
    if (field->null_ptr) {
5839
5393
      nulls_allowed = 0;
5840
5394
    } else {
5880
5434
    long_true_varchar = 0;
5881
5435
 
5882
5436
    if (field->type() == DRIZZLE_TYPE_VARCHAR) {
5883
 
      col_len -= ((Field_varstring*)field)->pack_length_no_ptr();
 
5437
      col_len -= ((Field_varstring*)field)->length_bytes;
5884
5438
 
5885
 
      if (((Field_varstring*)field)->pack_length_no_ptr() == 2) {
 
5439
      if (((Field_varstring*)field)->length_bytes == 2) {
5886
5440
        long_true_varchar = DATA_LONG_TRUE_VARCHAR;
5887
5441
      }
5888
5442
    }
5889
5443
 
5890
 
    /* First check whether the column to be added has a
5891
 
       system reserved name. */
5892
 
    if (dict_col_name_is_reserved(field->field_name)){
5893
 
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5894
 
 
5895
 
  err_col:
5896
 
      dict_mem_table_free(table);
5897
 
      trx_commit_for_mysql(trx);
5898
 
 
5899
 
      error = DB_ERROR;
5900
 
      goto error_ret;
5901
 
    }
5902
 
 
5903
5444
    dict_mem_table_add_col(table, table->heap,
5904
5445
      (char*) field->field_name,
5905
5446
      col_type,
5913
5454
 
5914
5455
  error = row_create_table_for_mysql(table, trx);
5915
5456
 
5916
 
        if (error == DB_DUPLICATE_KEY) {
5917
 
                char buf[100];
5918
 
                char* buf_end = innobase_convert_identifier(
5919
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5920
 
                        trx->mysql_thd, TRUE);
5921
 
 
5922
 
                *buf_end = '\0';
5923
 
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5924
 
        }
5925
 
 
5926
 
error_ret:
5927
5457
  error = convert_error_code_to_mysql(error, flags, NULL);
5928
5458
 
5929
5459
  return(error);
5960
5490
 
5961
5491
  n_fields = key->key_parts;
5962
5492
 
5963
 
  /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
5964
 
  ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
5965
 
 
5966
5493
  ind_type = 0;
5967
5494
 
5968
5495
  if (key_num == form->getShare()->getPrimaryKey()) {
6015
5542
        && field->type() != DRIZZLE_TYPE_VARCHAR)
6016
5543
      || (field->type() == DRIZZLE_TYPE_VARCHAR
6017
5544
        && key_part->length < field->pack_length()
6018
 
        - ((Field_varstring*)field)->pack_length_no_ptr())) {
 
5545
        - ((Field_varstring*)field)->length_bytes)) {
6019
5546
 
6020
5547
      prefix_len = key_part->length;
6021
5548
 
6072
5599
  /* We pass 0 as the space id, and determine at a lower level the space
6073
5600
  id where to store the table */
6074
5601
 
6075
 
  index = dict_mem_index_create(table_name,
6076
 
                                innobase_index_reserve_name,
6077
 
                                0, DICT_CLUSTERED, 0);
 
5602
  index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
 
5603
              0, DICT_CLUSTERED, 0);
6078
5604
 
6079
5605
  error = row_create_index_for_mysql(index, trx, NULL);
6080
5606
 
6140
5666
    modified by another thread while the table is being created. */
6141
5667
  const ulint file_format = srv_file_format;
6142
5668
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6143
 
  const char* stmt;
6144
 
  size_t stmt_len;
6145
5669
 
6146
5670
  const char *table_name= identifier.getPath().c_str();
6147
5671
 
6234
5758
# error "DICT_TF_ZSSIZE_MAX < 1"
6235
5759
#endif
6236
5760
 
6237
 
    if (strict_mode)
 
5761
    if (SessionVAR(&session, strict_mode))
6238
5762
    {
6239
5763
      if (! srv_file_per_table)
6240
5764
      {
6253
5777
                            "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6254
5778
      }
6255
5779
    }
 
5780
 
 
5781
    error= create_table_def(trx, &form, norm_name,
 
5782
                            lex_identified_temp_table ? name2 : NULL,
 
5783
                            iflags);
 
5784
  }
 
5785
 
 
5786
  if (error) {
 
5787
    goto cleanup;
6256
5788
  }
6257
5789
 
6258
5790
  /* Look for a primary key */
6261
5793
                   (int) form.getShare()->getPrimaryKey() :
6262
5794
                   -1);
6263
5795
 
6264
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5796
  /* Our function row_get_mysql_key_number_for_index assumes
6265
5797
    the primary key is always number 0, if it exists */
6266
5798
 
6267
5799
  assert(primary_key_no == -1 || primary_key_no == 0);
6268
5800
 
6269
 
  /* Check for name conflicts (with reserved name) for
6270
 
     any user indices to be created. */
6271
 
  if (innobase_index_name_is_reserved(trx, form.key_info,
6272
 
                                      form.getShare()->keys)) {
6273
 
    error = -1;
6274
 
    goto cleanup;
6275
 
  }
6276
 
 
6277
 
  if (lex_identified_temp_table)
6278
 
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6279
 
 
6280
 
  error= create_table_def(trx, &form, norm_name,
6281
 
                          lex_identified_temp_table ? name2 : NULL,
6282
 
                          iflags);
6283
 
 
6284
 
  session.setXaId(trx->id);
6285
 
 
6286
 
  if (error) {
6287
 
    goto cleanup;
6288
 
  }
6289
 
 
6290
5801
  /* Create the keys */
6291
5802
 
6292
5803
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6318
5829
    }
6319
5830
  }
6320
5831
 
6321
 
  stmt = innobase_get_stmt(&session, &stmt_len);
6322
 
 
6323
 
  if (stmt) {
 
5832
  if (trx->mysql_query_str) {
6324
5833
    string generated_create_table;
6325
 
    const char *query= stmt;
 
5834
    const char *query= trx->mysql_query_str;
6326
5835
 
6327
5836
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6328
5837
    {
6333
5842
    }
6334
5843
 
6335
5844
    error = row_table_add_foreign_constraints(trx,
6336
 
                                              query, strlen(query),
 
5845
                                              query,
6337
5846
                                              norm_name,
6338
5847
                                              lex_identified_temp_table);
6339
5848
 
6362
5871
    /* We update the highest file format in the system table
6363
5872
      space, if this table has higher file format setting. */
6364
5873
 
6365
 
    char changed_file_format_max[100];
6366
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6367
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
6368
 
      dict_table_get_format(innobase_table));
6369
 
    innobase_file_format_max= changed_file_format_max;
 
5874
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5875
                                    dict_table_get_format(innobase_table));
6370
5876
  }
6371
5877
 
6372
5878
  /* Note: We can't call update_session() as prebuilt will not be
6373
5879
    setup at this stage and so we use session. */
6374
5880
 
6375
5881
  /* We need to copy the AUTOINC value from the old table if
6376
 
    this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
6377
 
    does a table copy too. */
 
5882
    this is an ALTER TABLE. */
6378
5883
 
6379
5884
  if ((create_proto.options().has_auto_increment_value()
6380
 
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
6381
 
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
 
5885
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
6382
5886
      && create_proto.options().auto_increment_value() != 0) {
6383
5887
 
6384
 
    /* Query was one of :
6385
 
       CREATE TABLE ...AUTO_INCREMENT = x; or
6386
 
       ALTER TABLE...AUTO_INCREMENT = x;   or
6387
 
       CREATE INDEX x on t(...);
6388
 
       Find out a table definition from the dictionary and get
6389
 
       the current value of the auto increment field. Set a new
6390
 
       value to the auto increment field if the value is greater
6391
 
       than the maximum value in the column. */
 
5888
    /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 
5889
      CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
 
5890
      definition from the dictionary and get the current value
 
5891
      of the auto increment field. Set a new value to the
 
5892
      auto increment field if the value is greater than the
 
5893
      maximum value in the column. */
6392
5894
 
6393
5895
    auto_inc_value = create_proto.options().auto_increment_value();
6394
5896
 
6406
5908
 
6407
5909
  if (lex_identified_temp_table)
6408
5910
  {
6409
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5911
    session.storeTableMessage(identifier, create_proto);
6410
5912
  }
6411
5913
  else
6412
5914
  {
6440
5942
 
6441
5943
  ut_a(prebuilt->trx);
6442
5944
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6443
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5945
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6444
5946
 
6445
5947
  dict_table = prebuilt->table;
6446
5948
  trx = prebuilt->trx;
6469
5971
  /* Get the transaction associated with the current session, or create one
6470
5972
  if not yet created, and update prebuilt->trx */
6471
5973
 
6472
 
  update_session(getTable()->in_use);
 
5974
  update_session(table->in_use);
6473
5975
 
6474
5976
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6475
5977
  fallback:
6538
6040
                                   session_sql_command(&session)
6539
6041
                                   == SQLCOM_DROP_DB);
6540
6042
 
6541
 
  session.setXaId(trx->id);
6542
 
 
6543
6043
  /* Flush the log to reduce probability that the .frm files and
6544
6044
    the InnoDB data dictionary get out-of-sync if the user runs
6545
6045
    with innodb_flush_log_at_trx_commit = 0 */
6562
6062
  {
6563
6063
    if (identifier.getType() == message::Table::TEMPORARY)
6564
6064
    {
6565
 
      session.getMessageCache().removeTableMessage(identifier);
 
6065
      session.removeTableMessage(identifier);
6566
6066
      ulint sql_command = session_sql_command(&session);
6567
6067
 
6568
6068
      // If this was the final removal to an alter table then we will need
6655
6155
  trx = trx_allocate_for_mysql();
6656
6156
 
6657
6157
  trx->mysql_thd = NULL;
 
6158
  trx->mysql_query_str = NULL;
6658
6159
 
6659
6160
  trx->check_foreigns = false;
6660
6161
  trx->check_unique_secondary = false;
6738
6239
  // definition needs to be updated.
6739
6240
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6740
6241
  {
6741
 
    session.getMessageCache().renameTableMessage(from, to);
 
6242
    session.renameTableMessage(from, to);
6742
6243
    return 0;
6743
6244
  }
6744
6245
 
6760
6261
 
6761
6262
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6762
6263
 
6763
 
  session.setXaId(trx->id);
6764
 
 
6765
6264
  /* Tell the InnoDB server that there might be work for
6766
6265
    utility threads: */
6767
6266
 
6770
6269
  innobase_commit_low(trx);
6771
6270
  trx_free_for_mysql(trx);
6772
6271
 
6773
 
  /* Add a special case to handle the Duplicated Key error
6774
 
     and return DB_ERROR instead.
6775
 
     This is to avoid a possible SIGSEGV error from mysql error
6776
 
     handling code. Currently, mysql handles the Duplicated Key
6777
 
     error by re-entering the storage layer and getting dup key
6778
 
     info by calling get_dup_key(). This operation requires a valid
6779
 
     table handle ('row_prebuilt_t' structure) which could no
6780
 
     longer be available in the error handling stage. The suggested
6781
 
     solution is to report a 'table exists' error message (since
6782
 
     the dup key error here is due to an existing table whose name
6783
 
     is the one we are trying to rename to) and return the generic
6784
 
     error code. */
6785
 
  if (error == (int) DB_DUPLICATE_KEY) {
6786
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6787
 
    error = DB_ERROR;
6788
 
  }
6789
 
 
6790
6272
  error = convert_error_code_to_mysql(error, 0, NULL);
6791
6273
 
6792
6274
  if (not error)
6814
6296
  KeyInfo*    key;
6815
6297
  dict_index_t* index;
6816
6298
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6817
 
              getTable()->getShare()->stored_rec_length
6818
 
          + getTable()->getShare()->max_key_length + 100);
6819
 
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6820
 
          + getTable()->getShare()->max_key_length + 100;
 
6299
              table->getShare()->stored_rec_length
 
6300
          + table->getShare()->max_key_length + 100);
 
6301
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6302
          + table->getShare()->max_key_length + 100;
6821
6303
  dtuple_t* range_start;
6822
6304
  dtuple_t* range_end;
6823
6305
  ib_int64_t  n_rows;
6825
6307
  ulint   mode2;
6826
6308
  mem_heap_t* heap;
6827
6309
 
6828
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6310
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6829
6311
 
6830
6312
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6831
6313
 
6836
6318
 
6837
6319
  active_index = keynr;
6838
6320
 
6839
 
  key = &getTable()->key_info[active_index];
6840
 
 
6841
 
  index = innobase_get_index(keynr);
6842
 
 
6843
 
  /* There exists possibility of not being able to find requested
6844
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6845
 
     Necessary message should have been printed in innobase_get_index() */
6846
 
  if (UNIV_UNLIKELY(!index)) {
6847
 
    n_rows = HA_POS_ERROR;
6848
 
    goto func_exit;
6849
 
  }
6850
 
 
6851
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6852
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6853
 
    goto func_exit;
6854
 
  }
 
6321
  key = &table->key_info[active_index];
 
6322
 
 
6323
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6324
 
 
6325
  /* MySQL knows about this index and so we must be able to find it.*/
 
6326
  ut_a(index);
6855
6327
 
6856
6328
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6857
6329
            + sizeof(dtuple_t)));
6896
6368
 
6897
6369
  mem_heap_free(heap);
6898
6370
 
6899
 
func_exit:
6900
6371
  free(key_val_buff2);
6901
6372
 
6902
6373
  prebuilt->trx->op_info = (char*)"";
6931
6402
  external_lock(). To be safe, update the session of the current table
6932
6403
  handle. */
6933
6404
 
6934
 
  update_session(getTable()->in_use);
 
6405
  update_session(table->in_use);
6935
6406
 
6936
6407
  prebuilt->trx->op_info = (char*)
6937
6408
         "calculating upper bound for table rows";
6995
6466
  ha_rows total_rows;
6996
6467
  double  time_for_scan;
6997
6468
 
6998
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6469
  if (index != table->getShare()->getPrimaryKey()) {
6999
6470
    /* Not clustered */
7000
6471
    return(Cursor::read_time(index, ranges, rows));
7001
6472
  }
7019
6490
}
7020
6491
 
7021
6492
/*********************************************************************//**
7022
 
Calculates the key number used inside MySQL for an Innobase index. We will
7023
 
first check the "index translation table" for a match of the index to get
7024
 
the index number. If there does not exist an "index translation table",
7025
 
or not able to find the index in the translation table, then we will fall back
7026
 
to the traditional way of looping through dict_index_t list to find a
7027
 
match. In this case, we have to take into account if we generated a
7028
 
default clustered index for the table
7029
 
@return the key number used inside MySQL */
7030
 
static
7031
 
unsigned int
7032
 
innobase_get_mysql_key_number_for_index(
7033
 
/*====================================*/
7034
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
7035
 
                                        translation table. */
7036
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
7037
 
                                        dictionary */
7038
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
7039
 
                                        dictionary */
7040
 
        const dict_index_t*     index)  /*!< in: index */
7041
 
{
7042
 
        const dict_index_t*     ind;
7043
 
        unsigned int            i;
7044
 
 
7045
 
        ut_ad(index);
7046
 
        ut_ad(ib_table);
7047
 
        ut_ad(table);
7048
 
        ut_ad(share);
7049
 
 
7050
 
        /* If index does not belong to the table of share structure. Search
7051
 
        index->table instead */
7052
 
        if (index->table != ib_table) {
7053
 
                i = 0;
7054
 
                ind = dict_table_get_first_index(index->table);
7055
 
 
7056
 
                while (index != ind) {
7057
 
                        ind = dict_table_get_next_index(ind);
7058
 
                        i++;
7059
 
                }
7060
 
 
7061
 
                if (row_table_got_default_clust_index(index->table)) {
7062
 
                        ut_a(i > 0);
7063
 
                        i--;
7064
 
                }
7065
 
 
7066
 
                return(i);
7067
 
        }
7068
 
 
7069
 
        /* If index does not belong to the table of share structure. Search
7070
 
        index->table instead */
7071
 
        if (index->table != ib_table) {
7072
 
                i = 0;
7073
 
                ind = dict_table_get_first_index(index->table);
7074
 
 
7075
 
                while (index != ind) {
7076
 
                        ind = dict_table_get_next_index(ind);
7077
 
                        i++;
7078
 
                }
7079
 
 
7080
 
                if (row_table_got_default_clust_index(index->table)) {
7081
 
                        ut_a(i > 0);
7082
 
                        i--;
7083
 
                }
7084
 
 
7085
 
                return(i);
7086
 
        }
7087
 
 
7088
 
        /* If index translation table exists, we will first check
7089
 
        the index through index translation table for a match. */
7090
 
        if (share->idx_trans_tbl.index_mapping) {
7091
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7092
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7093
 
                                return(i);
7094
 
                        }
7095
 
                }
7096
 
 
7097
 
                /* Print an error message if we cannot find the index
7098
 
                ** in the "index translation table". */
7099
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7100
 
                              "Cannot find index %s in InnoDB index "
7101
 
                                "translation table.", index->name);
7102
 
        }
7103
 
 
7104
 
        /* If we do not have an "index translation table", or not able
7105
 
        to find the index in the translation table, we'll directly find
7106
 
        matching index in the dict_index_t list */
7107
 
        for (i = 0; i < table->getShare()->keys; i++) {
7108
 
                ind = dict_table_get_index_on_name(
7109
 
                        ib_table, table->key_info[i].name);
7110
 
 
7111
 
                if (index == ind) {
7112
 
                        return(i);
7113
 
                }
7114
 
        }
7115
 
 
7116
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7117
 
                              "Cannot find matching index number for index %s "
7118
 
                              "in InnoDB index list.", index->name);
7119
 
 
7120
 
        return(0);
7121
 
}
7122
 
/*********************************************************************//**
7123
6493
Returns statistics information of the table to the MySQL interpreter,
7124
6494
in various fields of the handle object. */
7125
6495
UNIV_INTERN
7132
6502
  dict_index_t* index;
7133
6503
  ha_rows   rec_per_key;
7134
6504
  ib_int64_t  n_rows;
 
6505
  ulong   j;
 
6506
  ulong   i;
 
6507
  char    path[FN_REFLEN];
7135
6508
  os_file_stat_t  stat_info;
7136
6509
 
7137
6510
  /* If we are forcing recovery at a high level, we will suppress
7138
6511
  statistics calculation on tables, because that may crash the
7139
6512
  server if an index is badly corrupted. */
7140
6513
 
 
6514
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6515
 
 
6516
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6517
    because we want MySQL to process this query and not
 
6518
    stop, like it would do if it received the error code
 
6519
    HA_ERR_CRASHED. */
 
6520
 
 
6521
    return(0);
 
6522
  }
 
6523
 
7141
6524
  /* We do not know if MySQL can call this function before calling
7142
6525
  external_lock(). To be safe, update the session of the current table
7143
6526
  handle. */
7144
6527
 
7145
 
  update_session(getTable()->in_use);
 
6528
  update_session(table->in_use);
7146
6529
 
7147
6530
  /* In case MySQL calls this in the middle of a SELECT query, release
7148
6531
  possible adaptive hash latch to avoid deadlocks of threads */
7154
6537
  ib_table = prebuilt->table;
7155
6538
 
7156
6539
  if (flag & HA_STATUS_TIME) {
7157
 
    /* In Analyze we call with this flag: update
7158
 
       then statistics so that they are up-to-date */
7159
 
 
7160
 
    prebuilt->trx->op_info = "updating table statistics";
7161
 
 
7162
 
    dict_update_statistics(ib_table);
7163
 
 
7164
 
    prebuilt->trx->op_info = "returning various info to MySQL";
7165
 
 
7166
 
    fs::path get_status_path(getDataHomeCatalog());
7167
 
    get_status_path /= ib_table->name;
7168
 
    fs::change_extension(get_status_path, "dfe");
 
6540
    if (innobase_stats_on_metadata) {
 
6541
      /* In sql_show we call with this flag: update
 
6542
      then statistics so that they are up-to-date */
 
6543
 
 
6544
      prebuilt->trx->op_info = "updating table statistics";
 
6545
 
 
6546
      dict_update_statistics(ib_table);
 
6547
 
 
6548
      prebuilt->trx->op_info = "returning various info to MySQL";
 
6549
    }
 
6550
 
 
6551
    snprintf(path, sizeof(path), "%s/%s%s",
 
6552
             data_home, ib_table->name, ".dfe");
 
6553
 
 
6554
    internal::unpack_filename(path,path);
7169
6555
 
7170
6556
    /* Note that we do not know the access time of the table,
7171
6557
    nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
7172
6558
 
7173
 
    if (os_file_get_status(get_status_path.file_string().c_str(), &stat_info)) {
 
6559
    if (os_file_get_status(path,&stat_info)) {
7174
6560
      stats.create_time = (ulong) stat_info.ctime;
7175
6561
    }
7176
6562
  }
7229
6615
    acquiring latches inside InnoDB, we do not call it if we
7230
6616
    are asked by MySQL to avoid locking. Another reason to
7231
6617
    avoid the call is that it uses quite a lot of CPU.
7232
 
    See Bug#38185. */
7233
 
    if (flag & HA_STATUS_NO_LOCK) {
7234
 
      /* We do not update delete_length if no
7235
 
         locking is requested so the "old" value can
7236
 
         remain. delete_length is initialized to 0 in
7237
 
         the ha_statistics' constructor. */
7238
 
    } else if (UNIV_UNLIKELY
7239
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7240
 
      /* Avoid accessing the tablespace if
7241
 
         innodb_crash_recovery is set to a high value. */
7242
 
      stats.delete_length = 0;
7243
 
    } else {
 
6618
    See Bug#38185.
 
6619
    We do not update delete_length if no locking is requested
 
6620
    so the "old" value can remain. delete_length is initialized
 
6621
    to 0 in the ha_statistics' constructor. */
 
6622
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6623
 
7244
6624
      /* lock the data dictionary to avoid races with
7245
6625
      ibd_file_missing and tablespace_discarded */
7246
6626
      row_mysql_lock_data_dictionary(prebuilt->trx);
7256
6636
 
7257
6637
        Session*  session;
7258
6638
 
7259
 
        session= getTable()->in_use;
 
6639
        session= table->in_use;
7260
6640
        assert(session);
7261
6641
 
7262
6642
        push_warning_printf(
7286
6666
  }
7287
6667
 
7288
6668
  if (flag & HA_STATUS_CONST) {
7289
 
    ulong i;
7290
 
    /* Verify the number of index in InnoDB and MySQL
7291
 
       matches up. If prebuilt->clust_index_was_generated
7292
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7293
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6669
    index = dict_table_get_first_index(ib_table);
7294
6670
 
7295
 
    if (getTable()->getShare()->keys != num_innodb_index) {
7296
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7297
 
                      "indexes inside InnoDB, which "
7298
 
                      "is different from the number of "
7299
 
                      "indexes %u defined in the MySQL ",
7300
 
                      ib_table->name, num_innodb_index,
7301
 
                      getTable()->getShare()->keys);
 
6671
    if (prebuilt->clust_index_was_generated) {
 
6672
      index = dict_table_get_next_index(index);
7302
6673
    }
7303
6674
 
7304
 
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7305
 
      ulong j;
7306
 
      /* We could get index quickly through internal
7307
 
         index mapping with the index translation table.
7308
 
         The identity of index (match up index name with
7309
 
         that of table->key_info[i]) is already verified in
7310
 
         innobase_get_index().  */
7311
 
      index = innobase_get_index(i);
7312
 
 
 
6675
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7313
6676
      if (index == NULL) {
7314
6677
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7315
6678
            "indexes inside InnoDB than "
7323
6686
        break;
7324
6687
      }
7325
6688
 
7326
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6689
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7327
6690
 
7328
6691
        if (j + 1 > index->n_uniq) {
7329
6692
          errmsg_printf(ERRMSG_LVL_ERROR, 
7338
6701
          break;
7339
6702
        }
7340
6703
 
7341
 
        dict_index_stat_mutex_enter(index);
7342
 
 
7343
6704
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7344
6705
 
7345
6706
          rec_per_key = stats.records;
7348
6709
           index->stat_n_diff_key_vals[j + 1]);
7349
6710
        }
7350
6711
 
7351
 
        dict_index_stat_mutex_exit(index);
7352
 
 
7353
6712
        /* Since MySQL seems to favor table scans
7354
6713
        too much over index searches, we pretend
7355
6714
        index selectivity is 2 times better than
7361
6720
          rec_per_key = 1;
7362
6721
        }
7363
6722
 
7364
 
        getTable()->key_info[i].rec_per_key[j]=
 
6723
        table->key_info[i].rec_per_key[j]=
7365
6724
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7366
6725
          (ulong) rec_per_key;
7367
6726
      }
 
6727
 
 
6728
      index = dict_table_get_next_index(index);
7368
6729
    }
7369
6730
  }
7370
6731
 
7371
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7372
 
    goto func_exit;
7373
 
  }
7374
 
 
7375
6732
  if (flag & HA_STATUS_ERRKEY) {
7376
6733
    const dict_index_t* err_index;
7377
6734
 
7382
6739
 
7383
6740
    if (err_index) {
7384
6741
      errkey = (unsigned int)
7385
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7386
 
                                                err_index);
 
6742
        row_get_mysql_key_number_for_index(err_index);
7387
6743
    } else {
7388
6744
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7389
6745
    }
7390
6746
  }
7391
6747
 
7392
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6748
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7393
6749
    stats.auto_increment_value = innobase_peek_autoinc();
7394
6750
  }
7395
6751
 
7396
 
func_exit:
7397
6752
  prebuilt->trx->op_info = (char*)"";
7398
6753
 
7399
6754
  return(0);
7426
6781
/*===============*/
7427
6782
  Session*  session)  /*!< in: user thread handle */
7428
6783
{
7429
 
  dict_index_t* index;
7430
 
  ulint         n_rows;
7431
 
  ulint         n_rows_in_table = ULINT_UNDEFINED;
7432
 
  ibool         is_ok           = TRUE;
7433
 
  ulint         old_isolation_level;
 
6784
  ulint   ret;
7434
6785
 
7435
 
  assert(session == getTable()->in_use);
 
6786
  assert(session == table->in_use);
7436
6787
  ut_a(prebuilt->trx);
7437
6788
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7438
6789
  ut_a(prebuilt->trx == session_to_trx(session));
7441
6792
    /* Build the template; we will use a dummy template
7442
6793
    in index scans done in checking */
7443
6794
 
7444
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
7445
 
  }
7446
 
 
7447
 
  if (prebuilt->table->ibd_file_missing) {
7448
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7449
 
                    "InnoDB: MySQL is trying to use a table handle"
7450
 
                    " but the .ibd file for\n"
7451
 
                    "InnoDB: table %s does not exist.\n"
7452
 
                    "InnoDB: Have you deleted the .ibd file"
7453
 
                    " from the database directory under\n"
7454
 
                    "InnoDB: the MySQL datadir, or have you"
7455
 
                    " used DISCARD TABLESPACE?\n"
7456
 
                    "InnoDB: Please refer to\n"
7457
 
                    "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
7458
 
                    "InnoDB: how you can resolve the problem.\n",
7459
 
                    prebuilt->table->name);
7460
 
    return(HA_ADMIN_CORRUPT);
7461
 
  }
7462
 
 
7463
 
  prebuilt->trx->op_info = "checking table";
7464
 
 
7465
 
  old_isolation_level = prebuilt->trx->isolation_level;
7466
 
 
7467
 
  /* We must run the index record counts at an isolation level
7468
 
     >= READ COMMITTED, because a dirty read can see a wrong number
7469
 
     of records in some index; to play safe, we use always
7470
 
     REPEATABLE READ here */
7471
 
 
7472
 
  prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7473
 
 
7474
 
  /* Enlarge the fatal lock wait timeout during CHECK TABLE. */
7475
 
  mutex_enter(&kernel_mutex);
7476
 
  srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
7477
 
  mutex_exit(&kernel_mutex);
7478
 
 
7479
 
  for (index = dict_table_get_first_index(prebuilt->table);
7480
 
       index != NULL;
7481
 
       index = dict_table_get_next_index(index)) {
7482
 
#if 0
7483
 
    fputs("Validating index ", stderr);
7484
 
    ut_print_name(stderr, trx, FALSE, index->name);
7485
 
    putc('\n', stderr);
7486
 
#endif
7487
 
 
7488
 
    if (!btr_validate_index(index, prebuilt->trx)) {
7489
 
      is_ok = FALSE;
7490
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7491
 
                          ER_NOT_KEYFILE,
7492
 
                          "InnoDB: The B-tree of"
7493
 
                          " index '%-.200s' is corrupted.",
7494
 
                          index->name);
7495
 
      continue;
7496
 
    }
7497
 
 
7498
 
    /* Instead of invoking change_active_index(), set up
7499
 
       a dummy template for non-locking reads, disabling
7500
 
       access to the clustered index. */
7501
 
    prebuilt->index = index;
7502
 
 
7503
 
    prebuilt->index_usable = row_merge_is_index_usable(
7504
 
                        prebuilt->trx, prebuilt->index);
7505
 
 
7506
 
    if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
7507
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7508
 
                          HA_ERR_TABLE_DEF_CHANGED,
7509
 
                          "InnoDB: Insufficient history for"
7510
 
                          " index '%-.200s'",
7511
 
                          index->name);
7512
 
      continue;
7513
 
    }
7514
 
 
7515
 
    prebuilt->sql_stat_start = TRUE;
7516
 
    prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
7517
 
    prebuilt->n_template = 0;
7518
 
    prebuilt->need_to_access_clustered = FALSE;
7519
 
 
7520
 
    dtuple_set_n_fields(prebuilt->search_tuple, 0);
7521
 
 
7522
 
    prebuilt->select_lock_type = LOCK_NONE;
7523
 
 
7524
 
    if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
7525
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7526
 
                          ER_NOT_KEYFILE,
7527
 
                          "InnoDB: The B-tree of"
7528
 
                          " index '%-.200s' is corrupted.",
7529
 
                          index->name);
7530
 
      is_ok = FALSE;
7531
 
    }
7532
 
 
7533
 
    if (user_session->getKilled()) {
7534
 
      break;
7535
 
    }
7536
 
 
7537
 
#if 0
7538
 
    fprintf(stderr, "%lu entries in index %s\n", n_rows,
7539
 
            index->name);
7540
 
#endif
7541
 
 
7542
 
    if (index == dict_table_get_first_index(prebuilt->table)) {
7543
 
      n_rows_in_table = n_rows;
7544
 
    } else if (n_rows != n_rows_in_table) {
7545
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7546
 
                          ER_NOT_KEYFILE,
7547
 
                          "InnoDB: Index '%-.200s'"
7548
 
                          " contains %lu entries,"
7549
 
                          " should be %lu.",
7550
 
                          index->name,
7551
 
                          (ulong) n_rows,
7552
 
                          (ulong) n_rows_in_table);
7553
 
      is_ok = FALSE;
7554
 
    }
7555
 
  }
7556
 
 
7557
 
  /* Restore the original isolation level */
7558
 
  prebuilt->trx->isolation_level = old_isolation_level;
7559
 
 
7560
 
  /* We validate also the whole adaptive hash index for all tables
7561
 
     at every CHECK TABLE */
7562
 
 
7563
 
  if (!btr_search_validate()) {
7564
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7565
 
                 ER_NOT_KEYFILE,
7566
 
                 "InnoDB: The adaptive hash index is corrupted.");
7567
 
    is_ok = FALSE;
7568
 
  }
7569
 
 
7570
 
  /* Restore the fatal lock wait timeout after CHECK TABLE. */
7571
 
  mutex_enter(&kernel_mutex);
7572
 
  srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
7573
 
  mutex_exit(&kernel_mutex);
7574
 
 
7575
 
  prebuilt->trx->op_info = "";
7576
 
  if (user_session->getKilled()) {
7577
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
7578
 
  }
7579
 
 
7580
 
  return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
 
6795
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
 
6796
  }
 
6797
 
 
6798
  ret = row_check_table_for_mysql(prebuilt);
 
6799
 
 
6800
  if (ret == DB_SUCCESS) {
 
6801
    return(HA_ADMIN_OK);
 
6802
  }
 
6803
 
 
6804
  return(HA_ADMIN_CORRUPT);
7581
6805
}
7582
6806
 
7583
6807
/*************************************************************//**
7603
6827
    return((char*)comment); /* string too long */
7604
6828
  }
7605
6829
 
7606
 
  update_session(getTable()->in_use);
 
6830
  update_session(table->in_use);
7607
6831
 
7608
6832
  prebuilt->trx->op_info = (char*)"returning table comment";
7609
6833
 
7674
6898
  external_lock(). To be safe, update the session of the current table
7675
6899
  handle. */
7676
6900
 
7677
 
  update_session(getTable()->in_use);
 
6901
  update_session(table->in_use);
7678
6902
 
7679
6903
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7680
6904
 
7723
6947
  dict_foreign_t* foreign;
7724
6948
 
7725
6949
  ut_a(prebuilt != NULL);
7726
 
  update_session(getTable()->in_use);
 
6950
  update_session(table->in_use);
7727
6951
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7728
6952
  trx_search_latch_release_if_reserved(prebuilt->trx);
7729
6953
  mutex_enter(&(dict_sys->mutex));
7861
7085
{
7862
7086
  bool  can_switch;
7863
7087
 
7864
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7088
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7865
7089
 
7866
7090
  prebuilt->trx->op_info =
7867
7091
      "determining if there are foreign key constraints";
7949
7173
      either, because the calling threads may change.
7950
7174
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7951
7175
    case HA_EXTRA_IGNORE_DUP_KEY:
7952
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7176
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7953
7177
      break;
7954
7178
    case HA_EXTRA_WRITE_CAN_REPLACE:
7955
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7179
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7956
7180
      break;
7957
7181
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7958
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7182
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7959
7183
      break;
7960
7184
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7961
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7185
      session_to_trx(table->in_use)->duplicates &=
7962
7186
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7963
7187
      break;
7964
7188
    default:/* Do nothing */
8094
7318
{
8095
7319
  trx_t*      trx;
8096
7320
  static const char truncated_msg[] = "... truncated...\n";
8097
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7321
  const long    MAX_STATUS_SIZE = 64000;
8098
7322
  ulint     trx_list_start = ULINT_UNDEFINED;
8099
7323
  ulint     trx_list_end = ULINT_UNDEFINED;
8100
7324
 
8112
7336
 
8113
7337
  mutex_enter(&srv_monitor_file_mutex);
8114
7338
  rewind(srv_monitor_file);
8115
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7339
  srv_printf_innodb_monitor(srv_monitor_file,
8116
7340
        &trx_list_start, &trx_list_end);
8117
7341
  flen = ftell(srv_monitor_file);
8118
7342
  os_file_set_eof(srv_monitor_file);
8123
7347
 
8124
7348
  if (flen > MAX_STATUS_SIZE) {
8125
7349
    usable_len = MAX_STATUS_SIZE;
8126
 
    srv_truncated_status_writes++;
8127
7350
  } else {
8128
7351
    usable_len = flen;
8129
7352
  }
8159
7382
 
8160
7383
  mutex_exit(&srv_monitor_file_mutex);
8161
7384
 
8162
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8163
 
             STRING_WITH_LEN(""), str, flen);
 
7385
  bool result = FALSE;
8164
7386
 
 
7387
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7388
      STRING_WITH_LEN(""), str, flen)) {
 
7389
    result= TRUE;
 
7390
  }
8165
7391
  free(str);
8166
7392
 
8167
7393
  return(FALSE);
8168
7394
}
8169
7395
 
8170
7396
/************************************************************************//**
8171
 
Implements the SHOW MUTEX STATUS command.
8172
 
@return true on failure false on success*/
 
7397
Implements the SHOW MUTEX STATUS command. . */
8173
7398
static
8174
7399
bool
8175
7400
innodb_mutex_show_status(
8177
7402
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8178
7403
  Session*  session,  /*!< in: the MySQL query thread of the
8179
7404
          caller */
8180
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8181
 
                                        statistics */
 
7405
  stat_print_fn*  stat_print)
8182
7406
{
8183
7407
  char buf1[IO_SIZE], buf2[IO_SIZE];
8184
7408
  mutex_t*  mutex;
8185
7409
  rw_lock_t*  lock;
8186
 
  ulint         block_mutex_oswait_count = 0;
8187
 
  ulint         block_lock_oswait_count = 0;
8188
 
  mutex_t*      block_mutex = NULL;
8189
 
  rw_lock_t*    block_lock = NULL;
8190
7410
#ifdef UNIV_DEBUG
8191
7411
  ulint   rw_lock_count= 0;
8192
7412
  ulint   rw_lock_count_spin_loop= 0;
8200
7420
 
8201
7421
  mutex_enter(&mutex_list_mutex);
8202
7422
 
8203
 
  for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
8204
 
       mutex = UT_LIST_GET_NEXT(list, mutex)) {
8205
 
    if (mutex->count_os_wait == 0) {
8206
 
      continue;
8207
 
    }
8208
 
 
8209
 
 
8210
 
    if (buf_pool_is_block_mutex(mutex)) {
8211
 
      block_mutex = mutex;
8212
 
      block_mutex_oswait_count += mutex->count_os_wait;
8213
 
      continue;
 
7423
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7424
 
 
7425
  while (mutex != NULL) {
 
7426
    if (mutex->count_os_wait == 0
 
7427
        || buf_pool_is_block_mutex(mutex)) {
 
7428
      goto next_mutex;
8214
7429
    }
8215
7430
#ifdef UNIV_DEBUG
8216
7431
    if (mutex->mutex_type != 1) {
8237
7452
          return(1);
8238
7453
        }
8239
7454
      }
8240
 
    } else {
 
7455
    }
 
7456
    else {
8241
7457
      rw_lock_count += mutex->count_using;
8242
7458
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8243
7459
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8249
7465
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8250
7466
          mutex->cfile_name, (ulong) mutex->cline);
8251
7467
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8252
 
                      (ulong) mutex->count_os_wait);
 
7468
          mutex->count_os_wait);
8253
7469
 
8254
7470
    if (stat_print(session, innobase_engine_name,
8255
7471
             engine_name_len, buf1, buf1len,
8258
7474
      return(1);
8259
7475
    }
8260
7476
#endif /* UNIV_DEBUG */
8261
 
  }
8262
 
 
8263
 
  if (block_mutex) {
8264
 
    buf1len = snprintf(buf1, sizeof buf1,
8265
 
                       "combined %s:%lu",
8266
 
                       block_mutex->cfile_name,
8267
 
                       (ulong) block_mutex->cline);
8268
 
    buf2len = snprintf(buf2, sizeof buf2,
8269
 
                       "os_waits=%lu",
8270
 
                       (ulong) block_mutex_oswait_count);
8271
 
 
8272
 
    if (stat_print(session, innobase_engine_name,
8273
 
                   strlen(innobase_engine_name), buf1, buf1len,
8274
 
                   buf2, buf2len)) {
8275
 
      mutex_exit(&mutex_list_mutex);
8276
 
      return(1);
8277
 
    }
 
7477
 
 
7478
next_mutex:
 
7479
    mutex = UT_LIST_GET_NEXT(list, mutex);
8278
7480
  }
8279
7481
 
8280
7482
  mutex_exit(&mutex_list_mutex);
8281
7483
 
8282
7484
  mutex_enter(&rw_lock_list_mutex);
8283
7485
 
8284
 
  for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
8285
 
       lock = UT_LIST_GET_NEXT(list, lock)) {
8286
 
    if (lock->count_os_wait == 0) {
8287
 
      continue;
8288
 
    }
8289
 
 
8290
 
    if (buf_pool_is_block_lock(lock)) {
8291
 
      block_lock = lock;
8292
 
      block_lock_oswait_count += lock->count_os_wait;
8293
 
      continue;
8294
 
    }
8295
 
 
8296
 
    buf1len = snprintf(buf1, sizeof buf1, "%s:%lu",
8297
 
                       lock->cfile_name, (ulong) lock->cline);
8298
 
    buf2len = snprintf(buf2, sizeof buf2, "os_waits=%lu",
8299
 
                       (ulong) lock->count_os_wait);
8300
 
 
8301
 
    if (stat_print(session, innobase_engine_name,
8302
 
                   strlen(innobase_engine_name), buf1, buf1len,
8303
 
                   buf2, buf2len)) {
8304
 
      mutex_exit(&rw_lock_list_mutex);
8305
 
      return(1);
8306
 
    }
8307
 
  }
8308
 
 
8309
 
  if (block_lock) {
8310
 
    buf1len = snprintf(buf1, sizeof buf1,
8311
 
                       "combined %s:%lu",
8312
 
                       block_lock->cfile_name,
8313
 
                       (ulong) block_lock->cline);
8314
 
    buf2len = snprintf(buf2, sizeof buf2,
8315
 
                       "os_waits=%lu",
8316
 
                       (ulong) block_lock_oswait_count);
8317
 
 
8318
 
    if (stat_print(session, innobase_engine_name,
8319
 
                   strlen(innobase_engine_name), buf1, buf1len,
8320
 
                   buf2, buf2len)) {
8321
 
      mutex_exit(&rw_lock_list_mutex);
8322
 
      return(1);
8323
 
    }
 
7486
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7487
 
 
7488
  while (lock != NULL) {
 
7489
    if (lock->count_os_wait
 
7490
                    && !buf_pool_is_block_lock(lock)) {
 
7491
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7492
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7493
      buf2len= snprintf(buf2, sizeof(buf2),
 
7494
                                    "os_waits=%lu", lock->count_os_wait);
 
7495
 
 
7496
      if (stat_print(session, innobase_engine_name,
 
7497
               engine_name_len, buf1, buf1len,
 
7498
               buf2, buf2len)) {
 
7499
        mutex_exit(&rw_lock_list_mutex);
 
7500
        return(1);
 
7501
      }
 
7502
    }
 
7503
    lock = UT_LIST_GET_NEXT(list, lock);
8324
7504
  }
8325
7505
 
8326
7506
  mutex_exit(&rw_lock_list_mutex);
8327
7507
 
8328
7508
#ifdef UNIV_DEBUG
8329
 
  buf2len = snprintf(buf2, sizeof buf2,
8330
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8331
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8332
 
                     (ulong) rw_lock_count,
8333
 
                     (ulong) rw_lock_count_spin_loop,
8334
 
                     (ulong) rw_lock_count_spin_rounds,
8335
 
                     (ulong) rw_lock_count_os_wait,
8336
 
                     (ulong) rw_lock_count_os_yield,
8337
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7509
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7510
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7511
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7512
    rw_lock_count, rw_lock_count_spin_loop,
 
7513
    rw_lock_count_spin_rounds,
 
7514
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7515
    (ulong) (rw_lock_wait_time/1000));
8338
7516
 
8339
7517
  if (stat_print(session, innobase_engine_name, engine_name_len,
8340
7518
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8379
7557
        !strcmp(share->table_name, table_name));
8380
7558
 
8381
7559
  if (!share) {
 
7560
 
 
7561
    uint length = (uint) strlen(table_name);
 
7562
 
8382
7563
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8383
7564
    grows too big */
8384
7565
 
8385
 
    share= new INNOBASE_SHARE(table_name);
 
7566
    share = (INNOBASE_SHARE *) malloc(sizeof(*share)+length+1);
 
7567
                memset(share, 0, sizeof(*share)+length+1);
 
7568
 
 
7569
    share->table_name = (char*) memcpy(share + 1,
 
7570
               table_name, length + 1);
8386
7571
 
8387
7572
    HASH_INSERT(INNOBASE_SHARE, table_name_hash,
8388
7573
          innobase_open_tables, fold, share);
8389
7574
 
8390
7575
    thr_lock_init(&share->lock);
8391
 
 
8392
 
    /* Index translation table initialization */
8393
 
    share->idx_trans_tbl.index_mapping = NULL;
8394
 
    share->idx_trans_tbl.index_count = 0;
8395
 
    share->idx_trans_tbl.array_size = 0;
8396
7576
  }
8397
7577
 
8398
7578
  share->use_count++;
8423
7603
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8424
7604
          innobase_open_tables, fold, share);
8425
7605
    share->lock.deinit();
8426
 
 
8427
 
    /* Free any memory from index translation table */
8428
 
    free(share->idx_trans_tbl.index_mapping);
8429
 
 
8430
 
    delete share;
 
7606
    free(share);
8431
7607
 
8432
7608
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8433
7609
    shrinks too much */
8504
7680
    isolation_level = trx->isolation_level;
8505
7681
 
8506
7682
    if ((srv_locks_unsafe_for_binlog
8507
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7683
         || isolation_level == TRX_ISO_READ_COMMITTED)
8508
7684
        && isolation_level != TRX_ISO_SERIALIZABLE
8509
7685
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8510
7686
        && (sql_command == SQLCOM_INSERT_SELECT
8511
 
            || sql_command == SQLCOM_REPLACE_SELECT
8512
 
            || sql_command == SQLCOM_UPDATE
8513
 
            || sql_command == SQLCOM_CREATE_TABLE
8514
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7687
      || sql_command == SQLCOM_UPDATE
 
7688
      || sql_command == SQLCOM_CREATE_TABLE)) {
8515
7689
 
8516
7690
      /* If we either have innobase_locks_unsafe_for_binlog
8517
7691
      option set or this session is using READ COMMITTED
8518
7692
      isolation level and isolation level of the transaction
8519
7693
      is not set to serializable and MySQL is doing
8520
 
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8521
 
      or UPDATE ... = (SELECT ...) or CREATE  ...
8522
 
      SELECT... or SET ... = (SELECT ...) without
8523
 
      FOR UPDATE or IN SHARE MODE in select,
8524
 
      then we use consistent read for select. */
 
7694
      INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
 
7695
      CREATE  ... SELECT... without FOR UPDATE or
 
7696
      IN SHARE MODE in select, then we use consistent
 
7697
      read for select. */
8525
7698
 
8526
7699
      prebuilt->select_lock_type = LOCK_NONE;
8527
7700
      prebuilt->stored_select_lock_type = LOCK_NONE;
8600
7773
  *value = dict_table_autoinc_read(prebuilt->table);
8601
7774
 
8602
7775
  /* It should have been initialized during open. */
8603
 
  if (*value == 0) {
8604
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8605
 
    dict_table_autoinc_unlock(prebuilt->table);
8606
 
  }
 
7776
  ut_a(*value != 0);
8607
7777
 
8608
7778
  return(DB_SUCCESS);
8609
7779
}
8610
7780
 
8611
7781
/*******************************************************************//**
8612
 
This function reads the global auto-inc counter. It doesn't use the
 
7782
This function reads the global auto-inc counter. It doesn't use the 
8613
7783
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8614
7784
@return the autoinc value */
8615
7785
UNIV_INTERN
8629
7799
 
8630
7800
  auto_inc = dict_table_autoinc_read(innodb_table);
8631
7801
 
8632
 
  if (auto_inc == 0) {
8633
 
    ut_print_timestamp(stderr);
8634
 
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
8635
 
            "is disabled for '%s'\n", innodb_table->name);
8636
 
  }
 
7802
  ut_a(auto_inc > 0);
8637
7803
 
8638
7804
  dict_table_autoinc_unlock(innodb_table);
8639
7805
 
8662
7828
  uint64_t  autoinc = 0;
8663
7829
 
8664
7830
  /* Prepare prebuilt->trx in the table handle */
8665
 
  update_session(getTable()->in_use);
 
7831
  update_session(table->in_use);
8666
7832
 
8667
7833
  error = innobase_get_autoinc(&autoinc);
8668
7834
 
8686
7852
  invoking this method. So we are not sure if it's guaranteed to
8687
7853
  be 0 or not. */
8688
7854
 
8689
 
  /* We need the upper limit of the col type to check for
8690
 
     whether we update the table autoinc counter or not. */
8691
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8692
 
 
8693
7855
  /* Called for the first time ? */
8694
7856
  if (trx->n_autoinc_rows == 0) {
8695
7857
 
8706
7868
  /* Not in the middle of a mult-row INSERT. */
8707
7869
  } else if (prebuilt->autoinc_last_value == 0) {
8708
7870
    set_if_bigger(*first_value, autoinc);
8709
 
    /* Check for -ve values. */
8710
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8711
 
    /* Set to next logical value. */
8712
 
    ut_a(autoinc > trx->n_autoinc_rows);
8713
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8714
7871
  }
8715
7872
 
8716
7873
  *nb_reserved_values = trx->n_autoinc_rows;
8718
7875
  /* This all current style autoinc. */
8719
7876
  {
8720
7877
    uint64_t  need;
8721
 
    uint64_t  current;
8722
7878
    uint64_t  next_value;
8723
 
 
8724
 
    current = *first_value > col_max_value ? autoinc : *first_value;
 
7879
    uint64_t  col_max_value;
 
7880
 
 
7881
    /* We need the upper limit of the col type to check for
 
7882
    whether we update the table autoinc counter or not. */
 
7883
    col_max_value = innobase_get_int_col_max_value(
 
7884
      table->next_number_field);
 
7885
 
8725
7886
    need = *nb_reserved_values * increment;
8726
7887
 
8727
7888
    /* Compute the last value in the interval */
8728
 
    next_value = innobase_next_autoinc(current, need, offset, col_max_value);
 
7889
    next_value = innobase_next_autoinc(
 
7890
      *first_value, need, offset, col_max_value);
8729
7891
 
8730
7892
    prebuilt->autoinc_last_value = next_value;
8731
7893
 
8762
7924
{
8763
7925
  int error;
8764
7926
 
8765
 
  update_session(getTable()->in_use);
 
7927
  update_session(table->in_use);
8766
7928
 
8767
7929
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8768
7930
 
8828
7990
  /* Do a type-aware comparison of primary key fields. PK fields
8829
7991
  are always NOT NULL, so no checks for NULL are performed. */
8830
7992
 
8831
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
7993
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8832
7994
 
8833
7995
  key_part_end = key_part
8834
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
7996
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8835
7997
 
8836
7998
  for (; key_part != key_part_end; ++key_part) {
8837
7999
    field = key_part->field;
8979
8141
 
8980
8142
  innobase_release_stat_resources(trx);
8981
8143
 
 
8144
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8145
  {
 
8146
    if (trx->conc_state != TRX_NOT_STARTED)
 
8147
    {
 
8148
      commit(session, TRUE);
 
8149
    }
 
8150
  }
 
8151
  else
 
8152
  {
 
8153
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8154
        trx->global_read_view)
 
8155
    {
 
8156
      /* At low transaction isolation levels we let
 
8157
      each consistent read set its own snapshot */
 
8158
      read_view_close_for_mysql(trx);
 
8159
    }
 
8160
  }
8982
8161
}
8983
8162
 
8984
8163
/*******************************************************************//**
9048
8227
  return(error);
9049
8228
}
9050
8229
 
9051
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
9052
 
{
9053
 
  trx_t *trx= session_to_trx(session);
9054
 
  return (trx->id);
9055
 
}
9056
 
 
9057
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
9058
 
{
9059
 
  trx_t*& trx = session_to_trx(session);
9060
 
 
9061
 
  if (trx == NULL)
9062
 
  {
9063
 
    trx = innobase_trx_allocate(session);
9064
 
 
9065
 
    innobase_trx_init(session, trx);
9066
 
  }
9067
 
 
9068
 
  mutex_enter(&kernel_mutex);
9069
 
  trx->id= trx_sys_get_new_trx_id();
9070
 
  mutex_exit(&kernel_mutex);
9071
 
 
9072
 
  uint64_t transaction_id= trx->id;
9073
 
 
9074
 
  return transaction_id;
9075
 
}
9076
 
 
9077
8230
/*******************************************************************//**
9078
8231
This function is used to recover X/Open XA distributed transactions.
9079
8232
@return number of prepared transactions stored in xid_list */
9185
8338
}
9186
8339
 
9187
8340
/************************************************************//**
 
8341
Validate the file format check value, is it one of "on" or "off",
 
8342
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8343
@return true if config value one of "on" or  "off" */
 
8344
static
 
8345
bool
 
8346
innobase_file_format_check_on_off(
 
8347
/*==============================*/
 
8348
  const char* format_check) /*!< in: parameter value */
 
8349
{
 
8350
  bool    ret = true;
 
8351
 
 
8352
  if (!innobase_strcasecmp(format_check, "off")) {
 
8353
 
 
8354
    /* Set the value to disable checking. */
 
8355
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8356
 
 
8357
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8358
 
 
8359
    /* Set the value to the lowest supported format. */
 
8360
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8361
  } else {
 
8362
    ret = FALSE;
 
8363
  }
 
8364
 
 
8365
  return(ret);
 
8366
}
 
8367
 
 
8368
/************************************************************//**
9188
8369
Validate the file format check config parameters, as a side effect it
9189
 
sets the srv_max_file_format_at_startup variable.
9190
 
@return the format_id if valid config value, otherwise, return -1 */
 
8370
sets the srv_check_file_format_at_startup variable.
 
8371
@return true if valid config value */
9191
8372
static
9192
 
int
9193
 
innobase_file_format_validate_and_set(
 
8373
bool
 
8374
innobase_file_format_check_validate(
9194
8375
/*================================*/
9195
 
  const char* format_max) /*!< in: parameter value */
 
8376
  const char* format_check) /*!< in: parameter value */
9196
8377
{
9197
8378
  uint    format_id;
 
8379
  bool    ret = true;
9198
8380
 
9199
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8381
  format_id = innobase_file_format_name_lookup(format_check);
9200
8382
 
9201
8383
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9202
 
    srv_max_file_format_at_startup = format_id;
9203
 
    return((int) format_id);
9204
 
  } else {
9205
 
    return(-1);
9206
 
  }
9207
 
}
9208
 
 
9209
 
 
 
8384
    srv_check_file_format_at_startup = format_id;
 
8385
  } else {
 
8386
    ret = false;
 
8387
  }
 
8388
 
 
8389
  return(ret);
 
8390
}
 
8391
 
 
8392
/*************************************************************//**
 
8393
Check if it is a valid file format. This function is registered as
 
8394
a callback with MySQL.
 
8395
@return 0 for valid file format */
 
8396
static
 
8397
int
 
8398
innodb_file_format_name_validate(
 
8399
/*=============================*/
 
8400
  Session*      , /*!< in: thread handle */
 
8401
  drizzle_sys_var*  , /*!< in: pointer to system
 
8402
            variable */
 
8403
  void*       save, /*!< out: immediate result
 
8404
            for update function */
 
8405
  drizzle_value*    value)  /*!< in: incoming string */
 
8406
{
 
8407
  const char* file_format_input;
 
8408
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8409
  int   len = sizeof(buff);
 
8410
 
 
8411
  ut_a(save != NULL);
 
8412
  ut_a(value != NULL);
 
8413
 
 
8414
  file_format_input = value->val_str(value, buff, &len);
 
8415
 
 
8416
  if (file_format_input != NULL) {
 
8417
    uint  format_id;
 
8418
 
 
8419
    format_id = innobase_file_format_name_lookup(
 
8420
      file_format_input);
 
8421
 
 
8422
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8423
 
 
8424
      *static_cast<const char**>(save) = file_format_input;
 
8425
      return(0);
 
8426
    }
 
8427
  }
 
8428
 
 
8429
  *static_cast<const char**>(save) = NULL;
 
8430
  return(1);
 
8431
}
 
8432
 
 
8433
/****************************************************************//**
 
8434
Update the system variable innodb_file_format using the "saved"
 
8435
value. This function is registered as a callback with MySQL. */
 
8436
static
 
8437
void
 
8438
innodb_file_format_name_update(
 
8439
/*===========================*/
 
8440
  Session*      ,   /*!< in: thread handle */
 
8441
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8442
              system variable */
 
8443
  void*       var_ptr,  /*!< out: where the
 
8444
              formal string goes */
 
8445
  const void*     save)   /*!< in: immediate result
 
8446
              from check function */
 
8447
{
 
8448
  const char* format_name;
 
8449
 
 
8450
  ut_a(var_ptr != NULL);
 
8451
  ut_a(save != NULL);
 
8452
 
 
8453
  format_name = *static_cast<const char*const*>(save);
 
8454
 
 
8455
  if (format_name) {
 
8456
    uint  format_id;
 
8457
 
 
8458
    format_id = innobase_file_format_name_lookup(format_name);
 
8459
 
 
8460
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8461
      srv_file_format = format_id;
 
8462
    }
 
8463
  }
 
8464
 
 
8465
  *static_cast<const char**>(var_ptr)
 
8466
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8467
}
 
8468
 
 
8469
/*************************************************************//**
 
8470
Check if valid argument to innodb_file_format_check. This
 
8471
function is registered as a callback with MySQL.
 
8472
@return 0 for valid file format */
 
8473
static
 
8474
int
 
8475
innodb_file_format_check_validate(
 
8476
/*==============================*/
 
8477
  Session*      , /*!< in: thread handle */
 
8478
  drizzle_sys_var*  , /*!< in: pointer to system
 
8479
            variable */
 
8480
  void*       save, /*!< out: immediate result
 
8481
            for update function */
 
8482
  drizzle_value*    value)  /*!< in: incoming string */
 
8483
{
 
8484
  const char* file_format_input;
 
8485
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8486
  int   len = sizeof(buff);
 
8487
 
 
8488
  ut_a(save != NULL);
 
8489
  ut_a(value != NULL);
 
8490
 
 
8491
  file_format_input = value->val_str(value, buff, &len);
 
8492
 
 
8493
  if (file_format_input != NULL) {
 
8494
 
 
8495
    /* Check if user set on/off, we want to print a suitable
 
8496
    message if they did so. */
 
8497
 
 
8498
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8499
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8500
        "InnoDB: invalid innodb_file_format_check "
 
8501
        "value; on/off can only be set at startup or "
 
8502
        "in the configuration file");
 
8503
    } else if (innobase_file_format_check_validate(
 
8504
        file_format_input)) {
 
8505
 
 
8506
      *static_cast<const char**>(save) = file_format_input;
 
8507
 
 
8508
      return(0);
 
8509
 
 
8510
    } else {
 
8511
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8512
        "InnoDB: invalid innodb_file_format_check "
 
8513
        "value; can be any format up to %s "
 
8514
        "or its equivalent numeric id",
 
8515
        trx_sys_file_format_id_to_name(
 
8516
          DICT_TF_FORMAT_MAX));
 
8517
    }
 
8518
  }
 
8519
 
 
8520
  *static_cast<const char**>(save) = NULL;
 
8521
  return(1);
 
8522
}
 
8523
 
 
8524
/****************************************************************//**
 
8525
Update the system variable innodb_file_format_check using the "saved"
 
8526
value. This function is registered as a callback with MySQL. */
 
8527
static
 
8528
void
 
8529
innodb_file_format_check_update(
 
8530
/*============================*/
 
8531
  Session*      session,  /*!< in: thread handle */
 
8532
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8533
              system variable */
 
8534
  void*       var_ptr,  /*!< out: where the
 
8535
              formal string goes */
 
8536
  const void*     save)   /*!< in: immediate result
 
8537
              from check function */
 
8538
{
 
8539
  const char* format_name_in;
 
8540
  const char**  format_name_out;
 
8541
  uint    format_id;
 
8542
 
 
8543
  ut_a(save != NULL);
 
8544
  ut_a(var_ptr != NULL);
 
8545
 
 
8546
  format_name_in = *static_cast<const char*const*>(save);
 
8547
 
 
8548
  if (!format_name_in) {
 
8549
 
 
8550
    return;
 
8551
  }
 
8552
 
 
8553
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8554
 
 
8555
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8556
    /* DEFAULT is "on", which is invalid at runtime. */
 
8557
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8558
            ER_WRONG_ARGUMENTS,
 
8559
            "Ignoring SET innodb_file_format=%s",
 
8560
            format_name_in);
 
8561
    return;
 
8562
  }
 
8563
 
 
8564
  format_name_out = static_cast<const char**>(var_ptr);
 
8565
 
 
8566
  /* Update the max format id in the system tablespace. */
 
8567
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8568
    ut_print_timestamp(stderr);
 
8569
    fprintf(stderr,
 
8570
      " [Info] InnoDB: the file format in the system "
 
8571
      "tablespace is now set to %s.\n", *format_name_out);
 
8572
  }
 
8573
}
 
8574
 
 
8575
/****************************************************************//**
 
8576
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8577
value. This function is registered as a callback with MySQL. */
 
8578
static
 
8579
void
 
8580
innodb_adaptive_hash_index_update(
 
8581
/*==============================*/
 
8582
  Session*      ,   /*!< in: thread handle */
 
8583
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8584
              system variable */
 
8585
  void*       , /*!< out: where the
 
8586
              formal string goes */
 
8587
  const void*     save)   /*!< in: immediate result
 
8588
              from check function */
 
8589
{
 
8590
  if (*(bool*) save) {
 
8591
    btr_search_enable();
 
8592
  } else {
 
8593
    btr_search_disable();
 
8594
  }
 
8595
}
 
8596
 
 
8597
/*************************************************************//**
 
8598
Check if it is a valid value of innodb_change_buffering.  This function is
 
8599
registered as a callback with MySQL.
 
8600
@return 0 for valid innodb_change_buffering */
 
8601
static
 
8602
int
 
8603
innodb_change_buffering_validate(
 
8604
/*=============================*/
 
8605
  Session*      , /*!< in: thread handle */
 
8606
  drizzle_sys_var*  , /*!< in: pointer to system
 
8607
            variable */
 
8608
  void*       save, /*!< out: immediate result
 
8609
            for update function */
 
8610
  drizzle_value*    value)  /*!< in: incoming string */
 
8611
{
 
8612
  const char* change_buffering_input;
 
8613
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8614
  int   len = sizeof(buff);
 
8615
 
 
8616
  ut_a(save != NULL);
 
8617
  ut_a(value != NULL);
 
8618
 
 
8619
  change_buffering_input = value->val_str(value, buff, &len);
 
8620
 
 
8621
  if (change_buffering_input != NULL) {
 
8622
    ulint use;
 
8623
 
 
8624
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8625
         use++) {
 
8626
      if (!innobase_strcasecmp(
 
8627
            change_buffering_input,
 
8628
            innobase_change_buffering_values[use])) {
 
8629
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8630
        return(0);
 
8631
      }
 
8632
    }
 
8633
  }
 
8634
 
 
8635
  return(1);
 
8636
}
 
8637
 
 
8638
/****************************************************************//**
 
8639
Update the system variable innodb_change_buffering using the "saved"
 
8640
value. This function is registered as a callback with MySQL. */
 
8641
static
 
8642
void
 
8643
innodb_change_buffering_update(
 
8644
/*===========================*/
 
8645
  Session*      ,   /*!< in: thread handle */
 
8646
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8647
              system variable */
 
8648
  void*       var_ptr,  /*!< out: where the
 
8649
              formal string goes */
 
8650
  const void*     save)   /*!< in: immediate result
 
8651
              from check function */
 
8652
{
 
8653
  ut_a(var_ptr != NULL);
 
8654
  ut_a(save != NULL);
 
8655
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8656
 
 
8657
  ibuf_use = *(const ibuf_use_t*) save;
 
8658
 
 
8659
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8660
}
 
8661
 
 
8662
/* plugin options */
 
8663
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8664
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8665
  "Enable InnoDB checksums validation (enabled by default). ",
 
8666
  NULL, NULL, TRUE);
 
8667
 
 
8668
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8669
  PLUGIN_VAR_READONLY,
 
8670
  "The common part for InnoDB table spaces.",
 
8671
  NULL, NULL, NULL);
 
8672
 
 
8673
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8674
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8675
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8676
  NULL, NULL, TRUE);
 
8677
 
 
8678
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8679
  PLUGIN_VAR_RQCMDARG,
 
8680
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8681
  NULL, NULL, 200, 100, ~0L, 0);
 
8682
 
 
8683
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8684
  PLUGIN_VAR_OPCMDARG,
 
8685
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8686
  "values are 0, 1 (faster)"
 
8687
  " or 2 (fastest - crash-like)"
 
8688
  ".",
 
8689
  NULL, NULL, 1, 0, 2, 0);
 
8690
 
 
8691
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8692
  PLUGIN_VAR_NOCMDARG,
 
8693
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8694
  NULL, NULL, FALSE);
 
8695
 
 
8696
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8697
  PLUGIN_VAR_RQCMDARG,
 
8698
  "File format to use for new tables in .ibd files.",
 
8699
  innodb_file_format_name_validate,
 
8700
  innodb_file_format_name_update, "Antelope");
 
8701
 
 
8702
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8703
  PLUGIN_VAR_OPCMDARG,
 
8704
  "The highest file format in the tablespace.",
 
8705
  innodb_file_format_check_validate,
 
8706
  innodb_file_format_check_update,
 
8707
  "on");
 
8708
 
 
8709
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8710
  PLUGIN_VAR_OPCMDARG,
 
8711
  "Set to 0 (write and flush once per second),"
 
8712
  " 1 (write and flush at each commit)"
 
8713
  " or 2 (write at commit, flush once per second).",
 
8714
  NULL, NULL, 1, 0, 2, 0);
 
8715
 
 
8716
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
 
8717
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8718
  "With which method to flush data.", NULL, NULL, NULL);
 
8719
 
 
8720
#ifdef UNIV_LOG_ARCHIVE
 
8721
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8722
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8723
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8724
 
 
8725
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8726
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8727
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8728
#endif /* UNIV_LOG_ARCHIVE */
 
8729
 
 
8730
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8731
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8732
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8733
 
 
8734
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8735
  PLUGIN_VAR_RQCMDARG,
 
8736
  "Percentage of dirty pages allowed in bufferpool.",
 
8737
  NULL, NULL, 75, 0, 99, 0);
 
8738
 
 
8739
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8740
  PLUGIN_VAR_NOCMDARG,
 
8741
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8742
  NULL, NULL, TRUE);
 
8743
 
 
8744
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8745
  PLUGIN_VAR_RQCMDARG,
 
8746
  "Desired maximum length of the purge queue (0 = no limit)",
 
8747
  NULL, NULL, 0, 0, ~0L, 0);
 
8748
 
 
8749
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8750
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8751
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8752
  NULL, NULL, FALSE);
 
8753
 
 
8754
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
 
8755
  PLUGIN_VAR_OPCMDARG,
 
8756
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
 
8757
  NULL, NULL, TRUE);
 
8758
 
 
8759
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8760
  PLUGIN_VAR_RQCMDARG,
 
8761
  "The number of index pages to sample when calculating statistics (default 8)",
 
8762
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8763
 
 
8764
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8765
  PLUGIN_VAR_OPCMDARG,
 
8766
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8767
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8768
 
 
8769
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8770
  PLUGIN_VAR_RQCMDARG,
 
8771
  "Replication thread delay (ms) on the slave server if "
 
8772
  "innodb_thread_concurrency is reached (0 by default)",
 
8773
  NULL, NULL, 0, 0, ~0UL, 0);
 
8774
 
 
8775
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8776
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8777
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8778
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8779
 
 
8780
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8781
  PLUGIN_VAR_RQCMDARG,
 
8782
  "Data file autoextend increment in megabytes",
 
8783
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8784
 
 
8785
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8786
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8787
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8788
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8789
 
 
8790
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8791
  PLUGIN_VAR_RQCMDARG,
 
8792
  "Helps in performance tuning in heavily concurrent environments.",
 
8793
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8794
 
 
8795
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8796
  PLUGIN_VAR_RQCMDARG,
 
8797
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8798
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8799
 
 
8800
static DRIZZLE_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
 
8801
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8802
  "Number of file I/O threads in InnoDB.",
 
8803
  NULL, NULL, 4, 4, 64, 0);
 
8804
 
 
8805
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8806
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8807
  "Number of background read I/O threads in InnoDB.",
 
8808
  NULL, NULL, 4, 1, 64, 0);
 
8809
 
 
8810
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8811
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8812
  "Number of background write I/O threads in InnoDB.",
 
8813
  NULL, NULL, 4, 1, 64, 0);
 
8814
 
 
8815
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8816
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8817
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8818
  NULL, NULL, 0, 0, 6, 0);
 
8819
 
 
8820
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8821
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8822
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8823
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8824
 
 
8825
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8826
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8827
  "Size of each log file in a log group.",
 
8828
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8829
 
 
8830
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8831
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8832
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8833
  NULL, NULL, 2, 2, 100, 0);
 
8834
 
 
8835
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8836
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8837
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8838
  NULL, NULL, 1, 1, 10, 0);
 
8839
 
 
8840
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8841
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8842
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8843
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8844
 
 
8845
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8846
  PLUGIN_VAR_RQCMDARG,
 
8847
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8848
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8849
 
 
8850
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8851
  PLUGIN_VAR_OPCMDARG,
 
8852
  "Maximum delay between polling for a spin lock (6 by default)",
 
8853
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8854
 
 
8855
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8856
  PLUGIN_VAR_RQCMDARG,
 
8857
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8858
  NULL, NULL, 0, 0, 1000, 0);
 
8859
 
 
8860
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8861
  PLUGIN_VAR_RQCMDARG,
 
8862
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8863
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8864
 
 
8865
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8866
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8867
  "Path to individual files and their sizes.",
 
8868
  NULL, NULL, NULL);
 
8869
 
 
8870
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8871
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8872
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8873
 
 
8874
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8875
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8876
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8877
  NULL, NULL, TRUE);
 
8878
 
 
8879
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8880
  PLUGIN_VAR_RQCMDARG,
 
8881
  "Buffer changes to reduce random access: "
 
8882
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8883
  innodb_change_buffering_validate,
 
8884
  innodb_change_buffering_update, NULL);
 
8885
 
 
8886
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8887
  PLUGIN_VAR_RQCMDARG,
 
8888
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8889
  "trigger a readahead.",
 
8890
  NULL, NULL, 56, 0, 64, 0);
9210
8891
 
9211
8892
static void init_options(drizzled::module::option_context &context)
9212
8893
{
9213
 
  context("disable-checksums",
9214
 
          "Disable InnoDB checksums validation.");
 
8894
  context("checksums",
 
8895
          po::value<bool>(&innobase_use_checksums)->default_value(true)->zero_tokens(),
 
8896
          "Enable InnoDB checksums validation.");
9215
8897
  context("data-home-dir",
9216
8898
          po::value<string>(),
9217
8899
          "The common part for InnoDB table spaces.");
9218
 
  context("disable-doublewrite",
9219
 
          "Disable InnoDB doublewrite buffer.");
 
8900
  context("doublewrite",
 
8901
          po::value<bool>(&innobase_use_doublewrite)->default_value(true)->zero_tokens(),
 
8902
          "Enable InnoDB doublewrite buffer.");
9220
8903
  context("io-capacity",
9221
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8904
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9222
8905
          "Number of IOPs the server can do. Tunes the background IO rate");
9223
8906
  context("fast-shutdown",
9224
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8907
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9225
8908
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9226
 
  context("purge-batch-size",
9227
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9228
 
          "Number of UNDO logs to purge in one batch from the history list. "
9229
 
          "Default is 20.");
9230
 
  context("purge-threads",
9231
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9232
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9233
8909
  context("file-per-table",
9234
8910
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9235
8911
          "Stores each InnoDB table to an .ibd file in the database dir.");
9236
8912
  context("file-format",
9237
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8913
          po::value<string>()->default_value("Antelope"),
9238
8914
          "File format to use for new tables in .ibd files.");
9239
 
  context("file-format-max",
9240
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
 
8915
  context("file-format-check",
 
8916
          po::value<string>()->default_value("on"),
9241
8917
          "The highest file format in the tablespace.");
9242
 
  context("file-format-check",
9243
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9244
 
          "Whether to perform system file format check.");
9245
8918
  context("flush-log-at-trx-commit",
9246
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8919
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9247
8920
          "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).");
9248
8921
  context("flush-method",
9249
8922
          po::value<string>(),
9250
8923
          "With which method to flush data.");
 
8924
#ifdef UNIV_LOG_ARCHIVE
 
8925
  context("log-arch-dir",
 
8926
          po::value<string>(),
 
8927
          "Where full logs should be archived.");
 
8928
  context("log-archive",
 
8929
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8930
          "Set to 1 if you want to have logs archived.");
 
8931
#endif /* UNIV_LOG_ARCHIVE */
9251
8932
  context("log-group-home-dir",
9252
8933
          po::value<string>(),
9253
8934
          "Path to InnoDB log files.");
9254
8935
  context("max-dirty-pages-pct",
9255
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8936
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9256
8937
          "Percentage of dirty pages allowed in bufferpool.");
9257
 
  context("disable-adaptive-flushing",
9258
 
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
 
8938
  context("adaptive-flushing",
 
8939
          po::value<bool>(&srv_adaptive_flushing)->default_value(true)->zero_tokens(),
 
8940
          "Attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9259
8941
  context("max-purge-lag",
9260
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8942
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9261
8943
          "Desired maximum length of the purge queue (0 = no limit)");
9262
8944
  context("status-file",
9263
8945
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9264
8946
          "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file");
9265
 
  context("disable-stats-on-metadata",
9266
 
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
 
8947
  context("stats-on-metadata",
 
8948
          po::value<bool>(&innobase_stats_on_metadata)->default_value(true)->zero_tokens(),
 
8949
          "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9267
8950
  context("stats-sample-pages",
9268
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
8951
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9269
8952
          "The number of index pages to sample when calculating statistics (default 8)");
9270
 
  context("disable-adaptive-hash-index",
 
8953
  context("adaptive-hash-index",
 
8954
          po::value<bool>(&btr_search_enabled)->default_value(true)->zero_tokens(),
9271
8955
          "Enable InnoDB adaptive hash index (enabled by default)");
9272
8956
  context("replication-delay",
9273
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
8957
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9274
8958
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9275
8959
  context("additional-mem-pool-size",
9276
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
8960
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9277
8961
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9278
8962
  context("autoextend-increment",
9279
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
 
8963
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9280
8964
          "Data file autoextend increment in megabytes");
9281
8965
  context("buffer-pool-size",
9282
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
8966
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9283
8967
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9284
 
  context("buffer-pool-instances",
9285
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9286
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9287
 
 
9288
8968
  context("commit-concurrency",
9289
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
8969
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9290
8970
          "Helps in performance tuning in heavily concurrent environments.");
9291
8971
  context("concurrency-tickets",
9292
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
8972
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9293
8973
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
 
8974
  context("file-io-threads",
 
8975
          po::value<long>(&innobase_file_io_threads)->default_value(4),
 
8976
          "Number of file I/O threads in InnoDB.");
9294
8977
  context("read-io-threads",
9295
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
8978
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9296
8979
          "Number of background read I/O threads in InnoDB.");
9297
8980
  context("write-io-threads",
9298
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
8981
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9299
8982
          "Number of background write I/O threads in InnoDB.");
9300
8983
  context("force-recovery",
9301
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
8984
          po::value<long>(&innobase_force_recovery)->default_value(0),
9302
8985
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9303
8986
  context("log-buffer-size",
9304
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
8987
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9305
8988
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9306
8989
  context("log-file-size",
9307
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
8990
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9308
8991
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9309
8992
  context("log-files-in-group",
9310
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
8993
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9311
8994
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9312
8995
  context("mirrored-log-groups",
9313
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
8996
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9314
8997
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9315
8998
  context("open-files",
9316
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
8999
          po::value<long>(&innobase_open_files)->default_value(300L),
9317
9000
          "How many files at the maximum InnoDB keeps open at the same time.");
9318
9001
  context("sync-spin-loops",
9319
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9002
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9320
9003
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9321
9004
  context("spin-wait-delay",
9322
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9005
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9323
9006
          "Maximum delay between polling for a spin lock (6 by default)");
9324
9007
  context("thread-concurrency",
9325
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9008
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9326
9009
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9327
9010
  context("thread-sleep-delay",
9328
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9011
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9329
9012
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9330
9013
  context("data-file-path",
9331
9014
          po::value<string>(),
9333
9016
  context("version",
9334
9017
          po::value<string>()->default_value(INNODB_VERSION_STR),
9335
9018
          "InnoDB version");
9336
 
  context("use-internal-malloc",
9337
 
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
 
9019
  context("use-sys-malloc",
 
9020
          po::value<bool>(&srv_use_sys_malloc)->default_value(true)->zero_tokens(),
 
9021
          "Use OS memory allocator instead of InnoDB's internal memory allocator");
9338
9022
  context("change-buffering",
9339
 
          po::value<string>(&innobase_change_buffering),
 
9023
          po::value<string>(),
9340
9024
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9341
9025
  context("read-ahead-threshold",
9342
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9026
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9343
9027
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9344
 
  context("disable-xa",
9345
 
          "Disable InnoDB support for the XA two-phase commit");
9346
 
  context("disable-table-locks",
9347
 
          "Disable InnoDB locking in LOCK TABLES");
 
9028
  context("support-xa",
 
9029
          po::value<bool>()->default_value(true)->zero_tokens(),
 
9030
          "Enable InnoDB support for the XA two-phase commit");
 
9031
  context("table-locks",
 
9032
          po::value<bool>()->default_value(true)->zero_tokens(),
 
9033
          "Enable InnoDB locking in LOCK TABLES");
9348
9034
  context("strict-mode",
9349
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9035
          po::value<bool>()->default_value(false)->zero_tokens(),
9350
9036
          "Use strict mode when evaluating create options.");
9351
 
  context("replication-log",
9352
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9353
 
          _("Enable internal replication log."));
9354
9037
  context("lock-wait-timeout",
9355
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9356
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9357
 
  context("old-blocks-pct",
9358
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9359
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9360
 
  context("old-blocks-time",
9361
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9362
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9363
 
            " was at least this many milliseconds ago."
9364
 
            " The timeout is disabled if 0 (the default)."));
 
9038
          po::value<unsigned long>()->default_value(50),
 
9039
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9365
9040
}
9366
9041
 
9367
 
 
 
9042
static drizzle_sys_var* innobase_system_variables[]= {
 
9043
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9044
  DRIZZLE_SYSVAR(autoextend_increment),
 
9045
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9046
  DRIZZLE_SYSVAR(checksums),
 
9047
  DRIZZLE_SYSVAR(commit_concurrency),
 
9048
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9049
  DRIZZLE_SYSVAR(data_file_path),
 
9050
  DRIZZLE_SYSVAR(data_home_dir),
 
9051
  DRIZZLE_SYSVAR(doublewrite),
 
9052
  DRIZZLE_SYSVAR(fast_shutdown),
 
9053
  DRIZZLE_SYSVAR(file_io_threads),
 
9054
  DRIZZLE_SYSVAR(read_io_threads),
 
9055
  DRIZZLE_SYSVAR(write_io_threads),
 
9056
  DRIZZLE_SYSVAR(file_per_table),
 
9057
  DRIZZLE_SYSVAR(file_format),
 
9058
  DRIZZLE_SYSVAR(file_format_check),
 
9059
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9060
  DRIZZLE_SYSVAR(flush_method),
 
9061
  DRIZZLE_SYSVAR(force_recovery),
 
9062
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9063
#ifdef UNIV_LOG_ARCHIVE
 
9064
  DRIZZLE_SYSVAR(log_arch_dir),
 
9065
  DRIZZLE_SYSVAR(log_archive),
 
9066
#endif /* UNIV_LOG_ARCHIVE */
 
9067
  DRIZZLE_SYSVAR(log_buffer_size),
 
9068
  DRIZZLE_SYSVAR(log_file_size),
 
9069
  DRIZZLE_SYSVAR(log_files_in_group),
 
9070
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9071
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9072
  DRIZZLE_SYSVAR(max_purge_lag),
 
9073
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9074
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9075
  DRIZZLE_SYSVAR(open_files),
 
9076
  DRIZZLE_SYSVAR(stats_on_metadata),
 
9077
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9078
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9079
  DRIZZLE_SYSVAR(replication_delay),
 
9080
  DRIZZLE_SYSVAR(status_file),
 
9081
  DRIZZLE_SYSVAR(strict_mode),
 
9082
  DRIZZLE_SYSVAR(support_xa),
 
9083
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9084
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9085
  DRIZZLE_SYSVAR(table_locks),
 
9086
  DRIZZLE_SYSVAR(thread_concurrency),
 
9087
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9088
  DRIZZLE_SYSVAR(version),
 
9089
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9090
  DRIZZLE_SYSVAR(change_buffering),
 
9091
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9092
  DRIZZLE_SYSVAR(io_capacity),
 
9093
  NULL
 
9094
};
9368
9095
 
9369
9096
DRIZZLE_DECLARE_PLUGIN
9370
9097
{
9375
9102
  "Supports transactions, row-level locking, and foreign keys",
9376
9103
  PLUGIN_LICENSE_GPL,
9377
9104
  innobase_init, /* Plugin Init */
9378
 
  NULL, /* system variables */
 
9105
  innobase_system_variables, /* system variables */
9379
9106
  init_options /* reserved */
9380
9107
}
9381
9108
DRIZZLE_DECLARE_PLUGIN_END;
9403
9130
  return res;
9404
9131
}
9405
9132
 
9406
 
/***********************************************************************
9407
 
This function checks each index name for a table against reserved
9408
 
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9409
 
this function pushes an warning message to the client, and returns true. */
9410
 
extern "C" UNIV_INTERN
9411
 
bool
9412
 
innobase_index_name_is_reserved(
9413
 
/*============================*/
9414
 
                                        /* out: true if an index name
9415
 
                                        matches the reserved name */
9416
 
        const trx_t*    trx,            /* in: InnoDB transaction handle */
9417
 
        const KeyInfo*  key_info,       /* in: Indexes to be created */
9418
 
        ulint           num_of_keys)    /* in: Number of indexes to
9419
 
                                        be created. */
 
9133
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9134
 
 
9135
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9136
from zero to nonzero. (Bug #42101)
 
9137
 
 
9138
The initial default value is 0, and without this extra initialization,
 
9139
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9140
to 0, even if it was initially set to nonzero at the command line
 
9141
or configuration file. */
 
9142
static
 
9143
void
 
9144
innobase_commit_concurrency_init_default(void)
 
9145
/*==========================================*/
9420
9146
{
9421
 
  const KeyInfo*        key;
9422
 
  uint          key_num;        /* index number */
9423
 
 
9424
 
  for (key_num = 0; key_num < num_of_keys; key_num++) {
9425
 
    key = &key_info[key_num];
9426
 
 
9427
 
    if (innobase_strcasecmp(key->name,
9428
 
                            innobase_index_reserve_name) == 0) {
9429
 
      /* Push warning to drizzle */
9430
 
      push_warning_printf((Session*)trx->mysql_thd,
9431
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9432
 
                          ER_WRONG_NAME_FOR_INDEX,
9433
 
                          "Cannot Create Index with name "
9434
 
                          "'%s'. The name is reserved "
9435
 
                          "for the system default primary "
9436
 
                          "index.",
9437
 
                          innobase_index_reserve_name);
9438
 
 
9439
 
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
9440
 
               innobase_index_reserve_name);
9441
 
 
9442
 
      return(true);
9443
 
    }
9444
 
  }
9445
 
 
9446
 
  return(false);
 
9147
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9148
    = innobase_commit_concurrency;
9447
9149
}
9448
9150
 
9449
9151
#ifdef UNIV_COMPILE_TEST_FUNCS