~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: lbieber
  • Date: 2010-10-01 12:16:18 UTC
  • mfrom: (1802.1.1 fix-bug-651256)
  • Revision ID: lbieber@orisndriz08-20101001121618-uqcboygpjwbiglem
Merge Vijay - fix bug 651256 - Remove --help-extended

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.
4
 
Copyright (C) 2008, 2009 Google Inc.
5
 
Copyright (C) 2009, Percona Inc.
 
3
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, 2009 Google 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
60
78
#include "drizzled/table.h"
61
79
#include "drizzled/field/blob.h"
62
80
#include "drizzled/field/varstring.h"
 
81
#include "drizzled/field/timestamp.h"
63
82
#include "drizzled/plugin/xa_storage_engine.h"
64
83
#include "drizzled/plugin/daemon.h"
65
84
#include "drizzled/memory/multi_malloc.h"
71
90
 
72
91
#include <boost/algorithm/string.hpp>
73
92
#include <boost/program_options.hpp>
74
 
#include <boost/scoped_array.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 */
84
100
 
85
101
/* Include necessary InnoDB headers */
 
102
extern "C" {
86
103
#include "univ.i"
87
 
#include "buf0lru.h"
88
104
#include "btr0sea.h"
89
105
#include "os0file.h"
90
106
#include "os0thread.h"
101
117
#include "log0log.h"
102
118
#include "lock0lock.h"
103
119
#include "dict0crea.h"
104
 
#include "create_replication.h"
105
120
#include "btr0cur.h"
106
121
#include "btr0btr.h"
107
122
#include "fsp0fsp.h"
114
129
#include "ha_prototypes.h"
115
130
#include "ut0mem.h"
116
131
#include "ibuf0ibuf.h"
 
132
#include "mysql_addons.h"
 
133
}
117
134
 
118
135
#include "ha_innodb.h"
119
136
#include "data_dictionary.h"
120
 
#include "replication_dictionary.h"
121
137
#include "internal_dictionary.h"
122
138
#include "handler0vars.h"
123
139
 
126
142
#include <string>
127
143
 
128
144
#include "plugin/innobase/handler/status_function.h"
129
 
#include "plugin/innobase/handler/replication_log.h"
130
 
 
131
 
#include <google/protobuf/io/zero_copy_stream.h>
132
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
 
#include <google/protobuf/io/coded_stream.h>
134
 
#include <google/protobuf/text_format.h>
135
 
 
136
 
#include <boost/thread/mutex.hpp>
137
145
 
138
146
using namespace std;
139
147
using namespace drizzled;
140
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
 
141
156
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
157
static pthread_mutex_t innobase_share_mutex;
144
158
/** to force correct commit order in binlog */
 
159
static pthread_mutex_t prepare_commit_mutex;
145
160
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
161
static pthread_mutex_t commit_threads_m;
 
162
static pthread_cond_t commit_cond;
 
163
static pthread_mutex_t commit_cond_m;
148
164
static bool innodb_inited = 0;
149
165
 
150
166
#define INSIDE_HA_INNOBASE_CC
160
176
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
177
 
162
178
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
164
 
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
 
static open_files_constraint innobase_open_files;
166
 
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
167
 
static mirrored_log_groups_constraint innobase_mirrored_log_groups;
168
 
typedef constrained_check<uint32_t, 100, 2> log_files_in_group_constraint;
169
 
static log_files_in_group_constraint innobase_log_files_in_group;
170
 
typedef constrained_check<uint32_t, 6, 0> force_recovery_constraint;
171
 
force_recovery_constraint innobase_force_recovery;
172
 
typedef constrained_check<size_t, SIZE_MAX, 256*1024, 1024> log_buffer_constraint;
173
 
static log_buffer_constraint innobase_log_buffer_size;
174
 
typedef constrained_check<size_t, SIZE_MAX, 512*1024, 1024> additional_mem_pool_constraint;
175
 
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
176
 
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
177
 
static autoextend_constraint innodb_auto_extend_increment;
178
 
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
179
 
static buffer_pool_constraint innobase_buffer_pool_size;
180
 
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
181
 
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
182
 
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
183
 
static io_capacity_constraint innodb_io_capacity;
184
 
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
185
 
static purge_batch_constraint innodb_purge_batch_size;
186
 
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
187
 
static purge_threads_constraint innodb_n_purge_threads;
188
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
189
 
static trinary_constraint innodb_flush_log_at_trx_commit;
190
 
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
191
 
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
192
 
static uint64_constraint innodb_max_purge_lag;
193
 
static uint64_nonzero_constraint innodb_stats_sample_pages;
194
 
typedef constrained_check<uint32_t, 64, 1> io_threads_constraint;
195
 
static io_threads_constraint innobase_read_io_threads;
196
 
static io_threads_constraint innobase_write_io_threads;
197
 
 
198
 
typedef constrained_check<uint32_t, 1000, 0> concurrency_constraint;
199
 
static concurrency_constraint innobase_commit_concurrency;
200
 
static concurrency_constraint innobase_thread_concurrency;
201
 
static uint32_nonzero_constraint innodb_concurrency_tickets;
202
 
 
203
 
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
204
 
static log_file_constraint innobase_log_file_size;
205
 
 
206
 
static uint64_constraint innodb_replication_delay;
207
 
 
208
 
/** Percentage of the buffer pool to reserve for 'old' blocks.
209
 
Connected to buf_LRU_old_ratio. */
210
 
typedef constrained_check<uint32_t, 95, 5> old_blocks_constraint;
211
 
static old_blocks_constraint innobase_old_blocks_pct;
212
 
 
213
 
static uint32_constraint innodb_sync_spin_loops;
214
 
static uint32_constraint innodb_spin_wait_delay;
215
 
static uint32_constraint innodb_thread_sleep_delay;
216
 
 
217
 
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
218
 
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
 
179
static plugin::TableFunction* status_table_function_ptr= NULL;
 
180
static plugin::TableFunction* cmp_tool= NULL;
 
181
static plugin::TableFunction* cmp_reset_tool= NULL;
 
182
static plugin::TableFunction* cmp_mem_tool= NULL;
 
183
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
 
184
static plugin::TableFunction* innodb_trx_tool= NULL;
 
185
static plugin::TableFunction* innodb_locks_tool= NULL;
 
186
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
187
 
 
188
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
189
  innobase_log_buffer_size,
 
190
  innobase_force_recovery, innobase_open_files;
 
191
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
192
static ulong innobase_commit_concurrency = 0;
 
193
static ulong innobase_read_io_threads;
 
194
static ulong innobase_write_io_threads;
 
195
 
 
196
/**
 
197
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
198
 */
 
199
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
200
static int64_t innobase_log_file_size;
219
201
 
220
202
/* The default values for the following char* start-up parameters
221
203
are determined in innobase_init below: */
222
204
 
223
 
std::string innobase_data_home_dir;
224
 
std::string innobase_data_file_path;
225
 
std::string innobase_log_group_home_dir;
226
 
static string innobase_file_format_name;
227
 
static string innobase_change_buffering;
228
 
 
229
 
/* The highest file format being used in the database. The value can be
230
 
set by user, however, it will be adjusted to the newer file format if
231
 
a table of such format is created/opened. */
232
 
static string innobase_file_format_max;
 
205
static char*  innobase_data_home_dir      = NULL;
 
206
static char*  innobase_data_file_path     = NULL;
 
207
static char*  innobase_log_group_home_dir   = NULL;
 
208
static char*  innobase_file_format_name   = NULL;
 
209
static char*  innobase_change_buffering   = NULL;
 
210
 
 
211
/* Note: This variable can be set to on/off and any of the supported
 
212
file formats in the configuration file, but can only be set to any
 
213
of the supported file formats during runtime. */
 
214
static char*  innobase_file_format_check    = NULL;
 
215
 
 
216
/* The following has a misleading name: starting from 4.0.5, this also
 
217
affects Windows: */
 
218
static char*  innobase_unix_file_flush_method   = NULL;
233
219
 
234
220
/* Below we have boolean-valued start-up parameters, and their default
235
221
values */
236
222
 
237
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
238
 
static trinary_constraint innobase_fast_shutdown;
239
 
 
240
 
/* "innobase_file_format_check" decides whether we would continue
241
 
booting the server if the file format stamped on the system
242
 
table space exceeds the maximum file format supported
243
 
by the server. Can be set during server startup at command
244
 
line or configure file, and a read only variable after
245
 
server startup */
246
 
 
247
 
/* If a new file format is introduced, the file format
248
 
name needs to be updated accordingly. Please refer to
249
 
file_format_name_map[] defined in trx0sys.c for the next
250
 
file format name. */
251
 
 
252
 
static my_bool  innobase_file_format_check = TRUE;
 
223
static ulong  innobase_fast_shutdown      = 1;
 
224
#ifdef UNIV_LOG_ARCHIVE
 
225
static my_bool  innobase_log_archive      = FALSE;
 
226
static char*  innobase_log_arch_dir     = NULL;
 
227
#endif /* UNIV_LOG_ARCHIVE */
253
228
static my_bool  innobase_use_doublewrite    = TRUE;
254
229
static my_bool  innobase_use_checksums      = TRUE;
255
230
static my_bool  innobase_rollback_on_timeout    = FALSE;
256
231
static my_bool  innobase_create_status_file   = FALSE;
257
 
static bool innobase_use_replication_log;
258
 
static bool support_xa;
259
 
static bool strict_mode;
260
 
typedef constrained_check<uint32_t, 1024*1024*1024, 1> lock_wait_constraint;
261
 
static lock_wait_constraint lock_wait_timeout;
 
232
static my_bool  innobase_stats_on_metadata    = TRUE;
262
233
 
263
234
static char*  internal_innobase_data_file_path  = NULL;
264
235
 
 
236
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
237
 
265
238
/* The following counter is used to convey information to InnoDB
266
239
about server activity: in selects it is not sensible to call
267
240
srv_active_wake_master_thread after each fetch or search, we only do
279
252
/** Allowed values of innodb_change_buffering */
280
253
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
281
254
  "none",   /* IBUF_USE_NONE */
282
 
  "inserts",    /* IBUF_USE_INSERT */
283
 
  "deletes",    /* IBUF_USE_DELETE_MARK */
284
 
  "changes",    /* IBUF_USE_INSERT_DELETE_MARK */
285
 
  "purges",     /* IBUF_USE_DELETE */
286
 
  "all"         /* IBUF_USE_ALL */
 
255
  "inserts" /* IBUF_USE_INSERT */
287
256
};
288
257
 
289
 
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
290
 
system primary index. */
291
 
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
292
 
 
293
258
/********************************************************************
294
259
Gives the file extension of an InnoDB single-table tablespace. */
295
260
static const char* ha_innobase_exts[] = {
333
298
      srv_free_paths_and_sizes();
334
299
      if (internal_innobase_data_file_path)
335
300
        free(internal_innobase_data_file_path);
 
301
      pthread_mutex_destroy(&innobase_share_mutex);
 
302
      pthread_mutex_destroy(&prepare_commit_mutex);
 
303
      pthread_mutex_destroy(&commit_threads_m);
 
304
      pthread_mutex_destroy(&commit_cond_m);
 
305
      pthread_cond_destroy(&commit_cond);
336
306
    }
337
307
    
338
308
    /* These get strdup'd from vm variables */
 
309
    free(innobase_data_home_dir);
339
310
 
340
311
  }
341
312
 
366
337
  {
367
338
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
368
339
  }
369
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
370
 
  virtual uint64_t doGetNewTransactionId(Session *session);
371
340
  virtual int doCommit(Session* session, bool all);
372
341
  virtual int doRollback(Session* session, bool all);
373
342
 
411
380
        /* out: 0 or error number */
412
381
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
413
382
 
414
 
  virtual Cursor *create(Table &table)
 
383
  virtual Cursor *create(TableShare &table)
415
384
  {
416
385
    return new ha_innobase(*this, table);
417
386
  }
422
391
  doDropSchema(
423
392
  /*===================*/
424
393
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
394
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
395
        of the last directory in the path is used as
427
396
        the database name: for example, in 'mysql/data/test'
428
397
        the database name is 'test' */
461
430
 
462
431
  UNIV_INTERN int doCreateTable(Session &session,
463
432
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
433
                                const TableIdentifier &identifier,
465
434
                                message::Table&);
466
 
  UNIV_INTERN int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
467
 
  UNIV_INTERN int doDropTable(Session &session, const identifier::Table &identifier);
 
435
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
436
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
437
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
438
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
439
 
471
440
  UNIV_INTERN uint32_t max_supported_keys() const;
472
441
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
452
  }
484
453
 
485
454
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
455
                           const TableIdentifier &identifier,
487
456
                           drizzled::message::Table &table_proto);
488
457
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
458
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
459
 
491
460
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
461
                             const drizzled::SchemaIdentifier &schema_identifier,
 
462
                             drizzled::TableIdentifiers &set_of_identifiers);
494
463
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
464
  void dropTemporarySchema();
496
465
 
518
487
}
519
488
 
520
489
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
490
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
491
                                           drizzled::TableIdentifiers &set_of_identifiers)
523
492
{
524
493
  CachedDirectory::Entries entries= directory.getEntries();
525
494
 
526
 
  std::string search_string(schema_identifier.getSchemaName());
527
 
 
528
 
  boost::algorithm::to_lower(search_string);
529
 
 
530
 
  if (search_string.compare("data_dictionary") == 0)
531
 
  {
532
 
    set_of_identifiers.push_back(identifier::Table(schema_identifier.getSchemaName(), "SYS_REPLICATION_LOG"));
533
 
  }
534
 
 
535
495
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
496
       entry_iter != entries.end(); ++entry_iter)
537
497
  {
547
507
    { }
548
508
    else
549
509
    {
550
 
      std::string path;
551
 
      path+= directory.getPath();
552
 
      path+= FN_LIBCHAR;
553
 
      path+= entry->filename;
554
 
 
555
 
      message::Table definition;
556
 
      if (StorageEngine::readTableFile(path, definition))
557
 
      {
558
 
        /* 
559
 
           Using schema_identifier here to stop unused warning, could use
560
 
           definition.schema() instead
561
 
        */
562
 
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
563
 
        set_of_identifiers.push_back(identifier);
564
 
      }
 
510
      char uname[NAME_LEN + 1];
 
511
      uint32_t file_name_len;
 
512
 
 
513
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
514
      // TODO: Remove need for memory copy here
 
515
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
516
 
 
517
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
565
518
    }
566
519
  }
567
520
}
568
521
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
522
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
523
{
571
524
  string proto_path(identifier.getPath());
572
525
  proto_path.append(DEFAULT_FILE_EXTENSION);
573
526
 
574
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
 
    return true;
576
 
 
577
 
  std::string search_string(identifier.getPath());
578
 
  boost::algorithm::to_lower(search_string);
579
 
 
580
 
  if (search_string.compare("data_dictionary/sys_replication_log") == 0)
 
527
  if (session.doesTableMessageExist(identifier))
581
528
    return true;
582
529
 
583
530
  if (access(proto_path.c_str(), F_OK))
589
536
}
590
537
 
591
538
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
539
                                         const TableIdentifier &identifier,
593
540
                                         message::Table &table_proto)
594
541
{
595
542
  string proto_path(identifier.getPath());
596
543
  proto_path.append(DEFAULT_FILE_EXTENSION);
597
544
 
598
545
  // First we check the temporary tables.
599
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
 
    return EEXIST;
601
 
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
 
546
  if (session.getTableMessage(identifier, table_proto))
603
547
    return EEXIST;
604
548
 
605
549
  if (access(proto_path.c_str(), F_OK))
613
557
  return ENOENT;
614
558
}
615
559
 
 
560
/** @brief Initialize the default value of innodb_commit_concurrency.
 
561
 
 
562
Once InnoDB is running, the innodb_commit_concurrency must not change
 
563
from zero to nonzero. (Bug #42101)
 
564
 
 
565
The initial default value is 0, and without this extra initialization,
 
566
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
567
to 0, even if it was initially set to nonzero at the command line
 
568
or configuration file. */
 
569
static
 
570
void
 
571
innobase_commit_concurrency_init_default(void);
 
572
/*==========================================*/
616
573
 
617
574
/************************************************************//**
618
575
Validate the file format name and return its corresponding id.
625
582
            name */
626
583
/************************************************************//**
627
584
Validate the file format check config parameters, as a side effect it
628
 
sets the srv_max_file_format_at_startup variable.
629
 
@return the format_id if valid config value, otherwise, return -1 */
630
 
static
631
 
int
632
 
innobase_file_format_validate_and_set(
 
585
sets the srv_check_file_format_at_startup variable.
 
586
@return true if one of  "on" or "off" */
 
587
static
 
588
bool
 
589
innobase_file_format_check_on_off(
 
590
/*==============================*/
 
591
  const char* format_check);    /*!< in: parameter value */
 
592
/************************************************************//**
 
593
Validate the file format check config parameters, as a side effect it
 
594
sets the srv_check_file_format_at_startup variable.
 
595
@return true if valid config value */
 
596
static
 
597
bool
 
598
innobase_file_format_check_validate(
633
599
/*================================*/
634
 
  const char* format_max);    /*!< in: parameter value */
 
600
  const char* format_check);    /*!< in: parameter value */
635
601
 
636
602
static const char innobase_engine_name[]= "InnoDB";
637
603
 
 
604
/*************************************************************//**
 
605
Check for a valid value of innobase_commit_concurrency.
 
606
@return 0 for valid innodb_commit_concurrency */
 
607
static
 
608
int
 
609
innobase_commit_concurrency_validate(
 
610
/*=================================*/
 
611
  Session*      , /*!< in: thread handle */
 
612
  drizzle_sys_var*  , /*!< in: pointer to system
 
613
            variable */
 
614
  void*       save, /*!< out: immediate result
 
615
            for update function */
 
616
  drizzle_value*    value)  /*!< in: incoming string */
 
617
{
 
618
  int64_t   intbuf;
 
619
  ulong   commit_concurrency;
 
620
 
 
621
  if (value->val_int(value, &intbuf)) {
 
622
    /* The value is NULL. That is invalid. */
 
623
    return(1);
 
624
  }
 
625
 
 
626
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
627
    = static_cast<ulong>(intbuf);
 
628
 
 
629
  /* Allow the value to be updated, as long as it remains zero
 
630
  or nonzero. */
 
631
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
632
}
 
633
 
 
634
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
635
  "Enable InnoDB support for the XA two-phase commit",
 
636
  /* check_func */ NULL, /* update_func */ NULL,
 
637
  /* default */ TRUE);
 
638
 
 
639
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
640
  "Enable InnoDB locking in LOCK TABLES",
 
641
  /* check_func */ NULL, /* update_func */ NULL,
 
642
  /* default */ TRUE);
 
643
 
 
644
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
645
  "Use strict mode when evaluating create options.",
 
646
  NULL, NULL, FALSE);
 
647
 
 
648
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
649
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
650
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
651
 
638
652
 
639
653
/*****************************************************************//**
640
654
Commits a transaction in an InnoDB database. */
661
675
  (char*) &export_vars.innodb_buffer_pool_pages_misc,   SHOW_LONG},
662
676
  {"buffer_pool_pages_total",
663
677
  (char*) &export_vars.innodb_buffer_pool_pages_total,    SHOW_LONG},
664
 
  {"buffer_pool_read_ahead",
665
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
666
 
  {"buffer_pool_read_ahead_evicted",
667
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
 
678
  {"buffer_pool_read_ahead_rnd",
 
679
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
 
680
  {"buffer_pool_read_ahead_seq",
 
681
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
668
682
  {"buffer_pool_read_requests",
669
683
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
670
684
  {"buffer_pool_reads",
798
812
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
813
         in non-Cursor code.
800
814
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
815
extern "C" UNIV_INTERN
802
816
ibool
803
817
thd_is_replication_slave_thread(
804
818
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
819
  void* ) /*!< in: thread handle (Session*) */
806
820
{
807
821
  return false;
808
822
}
872
886
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
887
         in non-Cursor code.
874
888
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
889
extern "C" UNIV_INTERN
876
890
ibool
877
891
thd_has_edited_nontrans_tables(
878
892
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
893
  void*   session)  /*!< in: thread handle (Session*) */
880
894
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
895
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
896
}
883
897
 
884
898
/******************************************************************//**
885
899
Returns true if the thread is executing a SELECT statement.
886
900
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
901
extern "C" UNIV_INTERN
888
902
ibool
889
903
thd_is_select(
890
904
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
905
  const void* session)  /*!< in: thread handle (Session*) */
892
906
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
907
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
908
}
895
909
 
896
910
/******************************************************************//**
897
911
Returns true if the thread supports XA,
898
912
global value of innodb_supports_xa if session is NULL.
899
913
@return true if session has XA support */
900
 
UNIV_INTERN
 
914
extern "C" UNIV_INTERN
901
915
ibool
902
916
thd_supports_xa(
903
917
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
918
  void* session)  /*!< in: thread handle (Session*), or NULL to query
905
919
        the global innodb_supports_xa */
906
920
{
907
 
  /* TODO: Add support here for per-session value */
908
 
  return(support_xa);
 
921
  return(SessionVAR((Session*) session, support_xa));
909
922
}
910
923
 
911
924
/******************************************************************//**
912
925
Returns the lock wait timeout for the current connection.
913
926
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
927
extern "C" UNIV_INTERN
915
928
ulong
916
929
thd_lock_wait_timeout(
917
930
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
931
  void* session)  /*!< in: thread handle (Session*), or NULL to query
919
932
      the global innodb_lock_wait_timeout */
920
933
{
921
 
  /* TODO: Add support here for per-session value */
922
934
  /* According to <drizzle/plugin.h>, passing session == NULL
923
935
  returns the global value of the session variable. */
924
 
  return((ulong)lock_wait_timeout.get());
925
 
}
926
 
 
927
 
/******************************************************************//**
928
 
Set the time waited for the lock for the current query. */
929
 
UNIV_INTERN
930
 
void
931
 
thd_set_lock_wait_time(
932
 
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
934
 
        ulint   value)  /*!< in: time waited for the lock */
935
 
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
936
  return(SessionVAR((Session*) session, lock_wait_timeout));
938
937
}
939
938
 
940
939
/********************************************************************//**
949
948
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
950
949
}
951
950
 
952
 
 
953
 
plugin::ReplicationReturnCode ReplicationLog::apply(Session &session,
954
 
                                                    const message::Transaction &message)
955
 
{
956
 
  char *data= new char[message.ByteSize()];
957
 
 
958
 
  message.SerializeToArray(data, message.ByteSize());
959
 
 
960
 
  trx_t *trx= session_to_trx(&session);
961
 
 
962
 
  uint64_t trx_id= message.transaction_context().transaction_id();
963
 
  uint32_t seg_id= message.segment_id();
964
 
  uint64_t end_timestamp= message.transaction_context().end_timestamp();
965
 
  bool is_end_segment= message.end_segment();
966
 
  trx->log_commit_id= TRUE;
967
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id,
968
 
               end_timestamp, is_end_segment, seg_id);
969
 
  (void)error;
970
 
 
971
 
  delete[] data;
972
 
 
973
 
  return plugin::SUCCESS;
974
 
}
975
 
 
976
951
/********************************************************************//**
977
952
Call this function when mysqld passes control to the client. That is to
978
953
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1022
997
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
998
timeout or a deadlock.
1024
999
@return MySQL error code */
1025
 
UNIV_INTERN
 
1000
extern "C" UNIV_INTERN
1026
1001
int
1027
1002
convert_error_code_to_mysql(
1028
1003
/*========================*/
1034
1009
  case DB_SUCCESS:
1035
1010
    return(0);
1036
1011
 
1037
 
  case DB_INTERRUPTED:
1038
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1039
 
    /* fall through */
1040
 
 
1041
 
  case DB_FOREIGN_EXCEED_MAX_CASCADE:
1042
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1043
 
                        HA_ERR_ROW_IS_REFERENCED,
1044
 
                        "InnoDB: Cannot delete/update "
1045
 
                        "rows with cascading foreign key "
1046
 
                        "constraints that exceed max "
1047
 
                        "depth of %d. Please "
1048
 
                        "drop extra constraints and try "
1049
 
                        "again", DICT_FK_MAX_RECURSIVE_LOAD);
1050
 
    /* fall through */
1051
 
 
1052
1012
  case DB_ERROR:
1053
1013
  default:
1054
1014
    return(-1); /* unspecified error */
1055
1015
 
1056
1016
  case DB_DUPLICATE_KEY:
1057
 
    /* Be cautious with returning this error, since
1058
 
       mysql could re-enter the storage layer to get
1059
 
       duplicated key info, the operation requires a
1060
 
       valid table handle and/or transaction information,
1061
 
       which might not always be available in the error
1062
 
       handling stage. */
1063
1017
    return(HA_ERR_FOUND_DUPP_KEY);
1064
1018
 
1065
1019
  case DB_FOREIGN_DUPLICATE_KEY:
1076
1030
    tell it also to MySQL so that MySQL knows to empty the
1077
1031
    cached binlog for this transaction */
1078
1032
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1033
    mark_transaction_to_rollback(session, TRUE);
1080
1034
 
1081
1035
    return(HA_ERR_LOCK_DEADLOCK);
1082
1036
 
1085
1039
    latest SQL statement in a lock wait timeout. Previously, we
1086
1040
    rolled back the whole transaction. */
1087
1041
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1042
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1043
 
1090
1044
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1045
 
1096
1050
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1051
 
1098
1052
  case DB_CANNOT_ADD_CONSTRAINT:
1099
 
  case DB_CHILD_NO_INDEX:
1100
 
  case DB_PARENT_NO_INDEX:
1101
1053
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1054
 
1103
1055
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1073
 
1122
1074
  case DB_TOO_BIG_RECORD:
1123
1075
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1076
       page_get_free_space_of_empty(flags
 
1077
                  & DICT_TF_COMPACT) / 2);
1125
1078
    return(HA_ERR_TO_BIG_ROW);
1126
1079
 
1127
1080
  case DB_NO_SAVEPOINT:
1132
1085
    tell it also to MySQL so that MySQL knows to empty the
1133
1086
    cached binlog for this transaction */
1134
1087
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1088
    mark_transaction_to_rollback(session, TRUE);
1136
1089
 
1137
1090
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1091
 
1147
1100
    and the actual error code name could very well be different.
1148
1101
    This will require some monitoring, ie. the status
1149
1102
    of this request on our part.*/
1150
 
 
1151
 
    /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
1152
 
       available in 5.1.38 and later, but the plugin should still
1153
 
       work with previous versions of MySQL.
1154
 
       In Drizzle we seem to not have this yet.
1155
 
    */
1156
 
#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
1157
 
    return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
1158
 
#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1103
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
 
1104
    return(ER_TOO_MANY_CONCURRENT_TRXS);
 
1105
#else
1159
1106
    return(HA_ERR_RECORD_FILE_FULL);
1160
 
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1107
#endif
1161
1108
  case DB_UNSUPPORTED:
1162
1109
    return(HA_ERR_UNSUPPORTED);
1163
1110
  }
1164
1111
}
1165
1112
 
1166
1113
 
 
1114
 
 
1115
/*************************************************************//**
 
1116
If you want to print a session that is not associated with the current thread,
 
1117
you must call this function before reserving the InnoDB kernel_mutex, to
 
1118
protect Drizzle from setting session->query NULL. If you print a session of the
 
1119
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1120
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1121
after you release the kernel_mutex.
 
1122
 
 
1123
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1124
         in non-Cursor code.
 
1125
 */
 
1126
extern "C" UNIV_INTERN
 
1127
void
 
1128
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1129
/*============================================*/
 
1130
{
 
1131
  ut_ad(!mutex_own(&kernel_mutex));
 
1132
  LOCK_thread_count.lock();
 
1133
}
 
1134
 
 
1135
/*************************************************************//**
 
1136
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1137
In the InnoDB latching order, the mutex sits right above the
 
1138
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1139
released before this function is invoked. 
 
1140
 
 
1141
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1142
         in non-Cursor code.
 
1143
*/
 
1144
extern "C" UNIV_INTERN
 
1145
void
 
1146
innobase_mysql_end_print_arbitrary_thd(void)
 
1147
/*========================================*/
 
1148
{
 
1149
  ut_ad(!mutex_own(&kernel_mutex));
 
1150
  LOCK_thread_count.unlock();
 
1151
}
 
1152
 
1167
1153
/*************************************************************//**
1168
1154
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1155
extern "C" UNIV_INTERN
1170
1156
void
1171
1157
innobase_mysql_print_thd(
1172
1158
/*=====================*/
1173
1159
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1160
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1161
  uint  )   /*!< in: max query length to print, or 0 to
1176
1162
           use the default max length */
1177
1163
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1164
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1165
  fprintf(f,
1181
1166
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1182
 
          static_cast<uint64_t>(in_session->getSessionId()),
1183
 
          static_cast<uint64_t>(in_session->getQueryId()),
 
1167
          static_cast<uint64_t>(session->getSessionId()),
 
1168
          static_cast<uint64_t>(session->getQueryId()),
1184
1169
          glob_hostname,
1185
 
          user_identifier->address().c_str(),
1186
 
          user_identifier->username().c_str()
1187
 
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1170
          session->getSecurityContext().getIp().c_str(),
 
1171
          session->getSecurityContext().getUser().c_str()
 
1172
  );
 
1173
  fprintf(f,
 
1174
          "\n%s", session->getQueryString().c_str()
 
1175
  );
1189
1176
  putc('\n', f);
1190
1177
}
1191
1178
 
1192
1179
/******************************************************************//**
1193
1180
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1181
extern "C" UNIV_INTERN
1195
1182
void
1196
1183
innobase_get_cset_width(
1197
1184
/*====================*/
1208
1195
  if (cs) {
1209
1196
    *mbminlen = cs->mbminlen;
1210
1197
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1198
  } else {
1214
1199
    ut_a(cset == 0);
1215
1200
    *mbminlen = *mbmaxlen = 0;
1218
1203
 
1219
1204
/******************************************************************//**
1220
1205
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1206
extern "C" UNIV_INTERN
1222
1207
void
1223
1208
innobase_convert_from_table_id(
1224
1209
/*===========================*/
1232
1217
 
1233
1218
/******************************************************************//**
1234
1219
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1220
extern "C" UNIV_INTERN
1236
1221
void
1237
1222
innobase_convert_from_id(
1238
1223
/*=====================*/
1247
1232
/******************************************************************//**
1248
1233
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1234
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1235
extern "C" UNIV_INTERN
1251
1236
int
1252
1237
innobase_strcasecmp(
1253
1238
/*================*/
1259
1244
 
1260
1245
/******************************************************************//**
1261
1246
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1247
extern "C" UNIV_INTERN
1263
1248
void
1264
1249
innobase_casedn_str(
1265
1250
/*================*/
1268
1253
  my_casedn_str(system_charset_info, a);
1269
1254
}
1270
1255
 
1271
 
UNIV_INTERN
 
1256
/**********************************************************************//**
 
1257
Determines the connection character set.
 
1258
@return connection character set */
 
1259
extern "C" UNIV_INTERN
 
1260
const void*
 
1261
innobase_get_charset(
 
1262
/*=================*/
 
1263
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1264
{
 
1265
  return session_charset(static_cast<Session*>(mysql_session));
 
1266
}
 
1267
 
 
1268
extern "C" UNIV_INTERN
1272
1269
bool
1273
1270
innobase_isspace(
1274
1271
  const void *cs,
1277
1274
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1275
}
1279
1276
 
 
1277
UNIV_INTERN
 
1278
int
 
1279
innobase_fast_mutex_init(
 
1280
        os_fast_mutex_t*        fast_mutex)
 
1281
{
 
1282
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1283
}
 
1284
 
1280
1285
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1286
/*******************************************************************//**
1282
1287
Map an OS error to an errno value. The OS error number is stored in
1283
1288
_doserrno and the mapped value is stored in errno) */
 
1289
extern "C"
1284
1290
void __cdecl
1285
1291
_dosmaperr(
1286
1292
  unsigned long); /*!< in: OS error value */
1288
1294
/*********************************************************************//**
1289
1295
Creates a temporary file.
1290
1296
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1297
extern "C" UNIV_INTERN
1292
1298
int
1293
1299
innobase_mysql_tmpfile(void)
1294
1300
/*========================*/
1368
1374
/*********************************************************************//**
1369
1375
Creates a temporary file.
1370
1376
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1377
extern "C" UNIV_INTERN
1372
1378
int
1373
1379
innobase_mysql_tmpfile(void)
1374
1380
/*========================*/
1375
1381
{
1376
1382
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1383
  int fd = mysql_tmpfile("ib");
1378
1384
  if (fd >= 0) {
1379
1385
    /* Copy the file descriptor, so that the additional resources
1380
1386
    allocated by create_temp_file() can be freed by invoking
1407
1413
number of bytes that were written to "buf" is returned (including the
1408
1414
terminating NUL).
1409
1415
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1416
extern "C" UNIV_INTERN
1411
1417
ulint
1412
1418
innobase_raw_format(
1413
1419
/*================*/
1527
1533
/*********************************************************************//**
1528
1534
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1535
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1536
extern "C" UNIV_INTERN
1531
1537
trx_t*
1532
1538
innobase_trx_allocate(
1533
1539
/*==================*/
1541
1547
  trx = trx_allocate_for_mysql();
1542
1548
 
1543
1549
  trx->mysql_thd = session;
 
1550
  trx->mysql_query_str = session->query.c_str();
1544
1551
 
1545
1552
  innobase_trx_init(session, trx);
1546
1553
 
1579
1586
Construct ha_innobase Cursor. */
1580
1587
UNIV_INTERN
1581
1588
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1582
 
                         Table &table_arg)
 
1589
                         TableShare &table_arg)
1583
1590
  :Cursor(engine_arg, table_arg),
1584
1591
  primary_key(0), /* needs initialization because index_flags() may be called 
1585
1592
                     before this is set to the real value. It's ok to have any 
1631
1638
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1639
  const char* id, /*!< in: identifier to convert */
1633
1640
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1641
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1642
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1643
        FALSE=id is an UTF-8 string */
1637
1644
{
1638
1645
  char nz[NAME_LEN + 1];
1639
 
  const size_t nz2_size= NAME_LEN + 1 + srv_mysql50_table_name_prefix.size();
1640
 
  boost::scoped_array<char> nz2(new char[nz2_size]);
 
1646
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1647
 
1642
1648
  const char* s = id;
1643
1649
  int   q;
1654
1660
    memcpy(nz, id, idlen);
1655
1661
    nz[idlen] = 0;
1656
1662
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1663
    s = nz2;
 
1664
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1665
  }
1660
1666
 
1661
1667
  /* See if the identifier needs to be quoted. */
1709
1715
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1716
and quote it if needed.
1711
1717
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1718
extern "C" UNIV_INTERN
1713
1719
char*
1714
1720
innobase_convert_name(
1715
1721
/*==================*/
1717
1723
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1724
  const char* id, /*!< in: identifier to convert */
1719
1725
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1726
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1727
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1728
        FALSE=id is an index name */
1723
1729
{
1765
1771
/**********************************************************************//**
1766
1772
Determines if the currently running transaction has been interrupted.
1767
1773
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1774
extern "C" UNIV_INTERN
1769
1775
ibool
1770
1776
trx_is_interrupted(
1771
1777
/*===============*/
1772
1778
  trx_t*  trx)  /*!< in: transaction */
1773
1779
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
1775
 
}
1776
 
 
1777
 
/**********************************************************************//**
1778
 
Determines if the currently running transaction is in strict mode.
1779
 
@return TRUE if strict */
1780
 
UNIV_INTERN
1781
 
ibool
1782
 
trx_is_strict(
1783
 
/*==========*/
1784
 
        trx_t*  trx)    /*!< in: transaction */
1785
 
{
1786
 
        return(trx && trx->mysql_thd
1787
 
               && true);
 
1780
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1788
1781
}
1789
1782
 
1790
1783
/**************************************************************//**
1806
1799
  value= value - (value % align_val);
1807
1800
}
1808
1801
 
1809
 
static void auto_extend_update(Session *, sql_var_t)
1810
 
{
1811
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1812
 
}
1813
 
 
1814
 
static void io_capacity_update(Session *, sql_var_t)
1815
 
{
1816
 
  srv_io_capacity= innodb_io_capacity.get();
1817
 
}
1818
 
 
1819
 
static void purge_batch_update(Session *, sql_var_t)
1820
 
{
1821
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1822
 
}
1823
 
 
1824
 
static void purge_threads_update(Session *, sql_var_t)
1825
 
{
1826
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1827
 
}
1828
 
 
1829
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1830
 
{
1831
 
  if (btr_search_enabled)
1832
 
  {
1833
 
    btr_search_enable();
1834
 
  } else {
1835
 
    btr_search_disable();
1836
 
  }
1837
 
}
1838
 
 
1839
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1840
 
{
1841
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1842
 
}
1843
 
 
1844
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1845
 
{
1846
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1847
 
}
1848
 
 
1849
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1850
 
{
1851
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1852
 
}
1853
 
 
1854
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1855
 
{
1856
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1857
 
}
1858
 
 
1859
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1860
 
{
1861
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1862
 
}
1863
 
 
1864
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1865
 
{
1866
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1867
 
}
1868
 
 
1869
 
 
1870
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1871
 
{
1872
 
   uint64_t new_value= var->getInteger();
1873
 
 
1874
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1875
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1876
 
   {
1877
 
     push_warning_printf(session,
1878
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1879
 
                         ER_WRONG_ARGUMENTS,
1880
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1881
 
                           "must not change between zero and nonzero."));
1882
 
     return 1;
1883
 
   }
1884
 
   return 0;
1885
 
}
1886
 
 
1887
 
/*************************************************************//**
1888
 
Check if it is a valid file format. This function is registered as
1889
 
a callback with MySQL.
1890
 
@return 0 for valid file format */
1891
 
static
1892
 
int
1893
 
innodb_file_format_name_validate(
1894
 
/*=============================*/
1895
 
  Session*      , /*!< in: thread handle */
1896
 
  set_var *var)
1897
 
{
1898
 
  const char *file_format_input = var->value->str_value.ptr();
1899
 
  if (file_format_input == NULL)
1900
 
    return 1;
1901
 
 
1902
 
  if (file_format_input != NULL) {
1903
 
    uint  format_id;
1904
 
 
1905
 
    format_id = innobase_file_format_name_lookup(
1906
 
      file_format_input);
1907
 
 
1908
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1909
 
      innobase_file_format_name =
1910
 
        trx_sys_file_format_id_to_name(format_id);
1911
 
 
1912
 
      return(0);
1913
 
    }
1914
 
  }
1915
 
 
1916
 
  return(1);
1917
 
}
1918
 
 
1919
 
/*************************************************************//**
1920
 
Check if it is a valid value of innodb_change_buffering. This function is
1921
 
registered as a callback with MySQL.
1922
 
@return 0 for valid innodb_change_buffering */
1923
 
static
1924
 
int
1925
 
innodb_change_buffering_validate(
1926
 
/*=============================*/
1927
 
  Session*      , /*!< in: thread handle */
1928
 
  set_var *var)
1929
 
{
1930
 
  const char *change_buffering_input = var->value->str_value.ptr();
1931
 
 
1932
 
  if (change_buffering_input == NULL)
1933
 
    return 1;
1934
 
 
1935
 
  ulint use;
1936
 
 
1937
 
  for (use = 0;
1938
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1939
 
       ++use) {
1940
 
    if (!innobase_strcasecmp(change_buffering_input,
1941
 
                             innobase_change_buffering_values[use]))
1942
 
    {
1943
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1944
 
      return 0;
1945
 
    }
1946
 
  }
1947
 
 
1948
 
  return 1;
1949
 
}
1950
 
 
1951
 
 
1952
 
/*************************************************************//**
1953
 
Check if valid argument to innodb_file_format_max. This function
1954
 
is registered as a callback with MySQL.
1955
 
@return 0 for valid file format */
1956
 
static
1957
 
int
1958
 
innodb_file_format_max_validate(
1959
 
/*==============================*/
1960
 
  Session*   session, /*!< in: thread handle */
1961
 
  set_var *var)
1962
 
{
1963
 
  const char *file_format_input = var->value->str_value.ptr();
1964
 
  if (file_format_input == NULL)
1965
 
    return 1;
1966
 
 
1967
 
  if (file_format_input != NULL) {
1968
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
1969
 
 
1970
 
    if (format_id > DICT_TF_FORMAT_MAX) {
1971
 
      /* DEFAULT is "on", which is invalid at runtime. */
1972
 
      return 1;
1973
 
    }
1974
 
 
1975
 
    if (format_id >= 0) {
1976
 
      innobase_file_format_max.assign(
1977
 
                             trx_sys_file_format_id_to_name((uint)format_id));
1978
 
 
1979
 
      /* Update the max format id in the system tablespace. */
1980
 
      const char *name_buff;
1981
 
 
1982
 
      if (trx_sys_file_format_max_set(format_id, &name_buff))
1983
 
      {
1984
 
        errmsg_printf(error::WARN,
1985
 
                      " [Info] InnoDB: the file format in the system "
1986
 
                      "tablespace is now set to %s.\n", name_buff);
1987
 
        innobase_file_format_max= name_buff;
1988
 
      }
1989
 
      return(0);
1990
 
 
1991
 
    } else {
1992
 
      push_warning_printf(session,
1993
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
1994
 
                          ER_WRONG_ARGUMENTS,
1995
 
                          "InnoDB: invalid innodb_file_format_max "
1996
 
                          "value; can be any format up to %s "
1997
 
                          "or equivalent id of %d",
1998
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
1999
 
                          DICT_TF_FORMAT_MAX);
2000
 
    }
2001
 
  }
2002
 
 
2003
 
  return(1);
2004
 
}
2005
 
 
2006
 
 
2007
1802
/*********************************************************************//**
2008
1803
Opens an InnoDB database.
2009
1804
@return 0 on success, error code on failure */
2019
1814
  InnobaseEngine *actuall_engine_ptr;
2020
1815
  const module::option_map &vm= context.getOptions();
2021
1816
 
2022
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2023
 
  srv_io_capacity= innodb_io_capacity.get();
2024
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2025
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2026
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2027
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2028
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2029
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2030
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2031
 
  srv_replication_delay= innodb_replication_delay.get();
2032
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2033
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2034
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2035
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2036
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2037
 
 
2038
1817
  /* Inverted Booleans */
2039
1818
 
2040
1819
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2041
1820
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
1821
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
 
1822
  innobase_stats_on_metadata= (vm.count("disable-stats-on-metadata")) ? false : true;
2043
1823
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2044
 
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2045
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2046
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2047
 
 
2048
 
 
2049
 
  /* Hafta do this here because we need to late-bind the default value */
 
1824
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1825
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1826
 
 
1827
  if (vm.count("io-capacity"))
 
1828
  {
 
1829
    if (srv_io_capacity < 100)
 
1830
    {
 
1831
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1832
      exit(-1);
 
1833
    }
 
1834
  }
 
1835
 
2050
1836
  if (vm.count("data-home-dir"))
2051
1837
  {
2052
 
    innobase_data_home_dir= vm["data-home-dir"].as<string>();
2053
 
  }
2054
 
  else
2055
 
  {
2056
 
    innobase_data_home_dir= getDataHome().file_string();
2057
 
  }
2058
 
 
 
1838
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1839
  }
 
1840
  else
 
1841
  {
 
1842
    innobase_data_home_dir= strdup(getDataHome().c_str());
 
1843
  }
 
1844
 
 
1845
  if (vm.count("fast-shutdown"))
 
1846
  {
 
1847
    if (innobase_fast_shutdown > 2)
 
1848
    {
 
1849
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1850
      exit(-1);
 
1851
    }
 
1852
  }
 
1853
 
 
1854
  if (vm.count("file-format-check"))
 
1855
  {
 
1856
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1857
  }
 
1858
 
 
1859
  if (vm.count("flush-log-at-trx-commit"))
 
1860
  {
 
1861
    if (srv_flush_log_at_trx_commit > 2)
 
1862
    {
 
1863
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1864
      exit(-1);
 
1865
    }
 
1866
  }
 
1867
 
 
1868
  if (vm.count("flush-method"))
 
1869
  {
 
1870
    innobase_unix_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1871
  }
 
1872
  else
 
1873
  {
 
1874
    innobase_unix_file_flush_method= NULL;
 
1875
  }
 
1876
 
 
1877
#ifdef UNIV_LOG_ARCHIVE
 
1878
  if (vm.count("log-arch-dir"))
 
1879
  {
 
1880
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1881
  }
 
1882
 
 
1883
  else
 
1884
  {
 
1885
    innobase_log_arch_dir= NULL;
 
1886
  }
 
1887
#endif /* UNIV_LOG_ARCHIVE */
 
1888
 
 
1889
  if (vm.count("max-dirty-pages-pct"))
 
1890
  {
 
1891
    if (srv_max_buf_pool_modified_pct > 99)
 
1892
    {
 
1893
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1894
      exit(-1);
 
1895
    }
 
1896
  }
 
1897
 
 
1898
  if (vm.count("stats-sample-pages"))
 
1899
  {
 
1900
    if (srv_stats_sample_pages < 8)
 
1901
    {
 
1902
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1903
      exit(-1);
 
1904
    }
 
1905
  }
 
1906
 
 
1907
  if (vm.count("additional-mem-pool-size"))
 
1908
  {
 
1909
    align_value(innobase_additional_mem_pool_size);
 
1910
 
 
1911
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1912
    {
 
1913
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1914
      exit(-1);
 
1915
    }
 
1916
 
 
1917
  }
 
1918
 
 
1919
  if (vm.count("autoextend-increment"))
 
1920
  {
 
1921
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1922
    {
 
1923
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1924
      exit(-1);
 
1925
    }
 
1926
  }
 
1927
 
 
1928
  if (vm.count("buffer-pool-size"))
 
1929
  {
 
1930
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1931
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1932
    {
 
1933
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1934
      exit(-1);
 
1935
    }
 
1936
    
 
1937
  }
 
1938
 
 
1939
  if (vm.count("commit-concurrency"))
 
1940
  {
 
1941
    if (srv_replication_delay > 1000)
 
1942
    {
 
1943
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1944
      exit(-1);
 
1945
    }
 
1946
  }
 
1947
 
 
1948
  if (vm.count("concurrency-tickets"))
 
1949
  {
 
1950
    if (srv_n_free_tickets_to_enter < 1)
 
1951
    {
 
1952
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1953
      exit(-1);
 
1954
    }
 
1955
  }
 
1956
 
 
1957
  if (vm.count("read-io-threads"))
 
1958
  {
 
1959
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1960
    {
 
1961
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1962
      exit(-1);
 
1963
    }
 
1964
  }
 
1965
 
 
1966
  if (vm.count("write-io-threads"))
 
1967
  {
 
1968
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1969
    {
 
1970
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1971
      exit(-1);
 
1972
    }
 
1973
  }
 
1974
 
 
1975
  if (vm.count("force-recovery"))
 
1976
  {
 
1977
    if (innobase_force_recovery > 6)
 
1978
    {
 
1979
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
1980
      exit(-1);
 
1981
    }
 
1982
  }
 
1983
 
 
1984
  if (vm.count("log-buffer-size"))
 
1985
  {
 
1986
    align_value(innobase_log_buffer_size);
 
1987
    if (innobase_log_buffer_size < 256*1024L)
 
1988
    {
 
1989
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1990
      exit(-1);
 
1991
    }
 
1992
  }
 
1993
 
 
1994
  if (vm.count("log-file-size"))
 
1995
  {
 
1996
    align_value(innobase_log_file_size, 1024*1024);
 
1997
    if (innobase_log_file_size < 1*1024*1024L)
 
1998
    {
 
1999
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2000
      exit(-1);
 
2001
    }
 
2002
  }
 
2003
 
 
2004
  if (vm.count("log-files-in-group"))
 
2005
  {
 
2006
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2007
    {
 
2008
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2009
      exit(-1);
 
2010
    }
 
2011
  }
 
2012
 
 
2013
  if (vm.count("mirrored-log-groups"))
 
2014
  {
 
2015
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2016
    {
 
2017
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2018
      exit(-1);
 
2019
    }
 
2020
  }
 
2021
 
 
2022
  if (vm.count("open-files"))
 
2023
  {
 
2024
    if (innobase_open_files < 10)
 
2025
    {
 
2026
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2027
      exit(-1);
 
2028
    }
 
2029
  }
 
2030
 
 
2031
  if (vm.count("thread-concurrency"))
 
2032
  {
 
2033
    if (srv_thread_concurrency > 1000)
 
2034
    {
 
2035
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2036
      exit(-1);
 
2037
    }
 
2038
  }
2059
2039
 
2060
2040
  if (vm.count("data-file-path"))
2061
2041
  {
2062
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2063
 
  }
2064
 
 
 
2042
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2043
  }
 
2044
  else
 
2045
  {
 
2046
    innobase_data_file_path= NULL;
 
2047
  }
 
2048
 
 
2049
  if (vm.count("version"))
 
2050
  {
 
2051
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2052
  }
 
2053
 
 
2054
  if (vm.count("read-ahead-threshold"))
 
2055
  {
 
2056
    if (srv_read_ahead_threshold > 64)
 
2057
    {
 
2058
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2059
      exit(-1);
 
2060
    }
 
2061
  }
 
2062
 
 
2063
  if (vm.count("strict-mode"))
 
2064
  {
 
2065
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2066
  }
 
2067
 
 
2068
  if (vm.count("lock-wait-timeout"))
 
2069
  {
 
2070
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2071
    {
 
2072
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2073
      exit(-1);
 
2074
    }
 
2075
 
 
2076
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2077
  }
2065
2078
 
2066
2079
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2067
2080
 
2069
2082
 
2070
2083
#ifdef UNIV_DEBUG
2071
2084
  static const char test_filename[] = "-@";
2072
 
  const size_t test_tablename_size= sizeof test_filename
2073
 
    + srv_mysql50_table_name_prefix.size();
2074
 
  boost::scoped_array test_tablename(new char[test_tablename_size]);
2075
 
  if ((test_tablename_size) - 1
2076
 
      != filename_to_tablename(test_filename, test_tablename.get(),
2077
 
                               test_tablename_size)
2078
 
      || strncmp(test_tablename.get(),
2079
 
                 srv_mysql50_table_name_prefix.c_str(),
2080
 
                 srv_mysql50_table_name_prefix.size())
2081
 
      || strcmp(test_tablename.get()
2082
 
                + srv_mysql50_table_name_prefix.size(),
 
2085
  char      test_tablename[sizeof test_filename
 
2086
    + sizeof srv_mysql50_table_name_prefix];
 
2087
  if ((sizeof test_tablename) - 1
 
2088
      != filename_to_tablename(test_filename, test_tablename,
 
2089
                               sizeof test_tablename)
 
2090
      || strncmp(test_tablename,
 
2091
                 srv_mysql50_table_name_prefix,
 
2092
                 sizeof srv_mysql50_table_name_prefix)
 
2093
      || strcmp(test_tablename
 
2094
                + sizeof srv_mysql50_table_name_prefix,
2083
2095
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2096
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2097
    goto error;
2086
2098
  }
2087
2099
#endif /* UNIV_DEBUG */
2088
2100
 
 
2101
  /* Check that values don't overflow on 32-bit systems. */
 
2102
  if (sizeof(ulint) == 4) {
 
2103
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2104
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2105
                    "innobase_buffer_pool_size can't be over 4GB"
 
2106
                    " on 32-bit systems");
 
2107
 
 
2108
      goto error;
 
2109
    }
 
2110
 
 
2111
    if (innobase_log_file_size > UINT32_MAX) {
 
2112
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2113
                    "innobase_log_file_size can't be over 4GB"
 
2114
                    " on 32-bit systems");
 
2115
 
 
2116
      goto error;
 
2117
    }
 
2118
  }
 
2119
 
2089
2120
  os_innodb_umask = (ulint)internal::my_umask;
2090
2121
 
2091
2122
 
2096
2127
 
2097
2128
  /* The default dir for data files is the datadir of MySQL */
2098
2129
 
2099
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2130
  srv_data_home = (char *)innobase_data_home_dir;
2100
2131
 
2101
2132
  /* Set default InnoDB data file size to 10 MB and let it be
2102
2133
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2103
2134
    to specify any startup options. */
2104
2135
 
2105
 
  if (innobase_data_file_path.empty()) 
2106
 
  {
2107
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2136
  if (!innobase_data_file_path) {
 
2137
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2108
2138
  }
2109
2139
 
2110
2140
  /* Since InnoDB edits the argument in the next call, we make another
2111
2141
    copy of it: */
2112
2142
 
2113
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2143
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2114
2144
 
2115
2145
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2146
                                                   internal_innobase_data_file_path);
2117
2147
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2148
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2149
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2150
mem_free_and_error:
2121
2151
    srv_free_paths_and_sizes();
2122
2152
    if (internal_innobase_data_file_path)
2130
2160
 
2131
2161
  if (vm.count("log-group-home-dir"))
2132
2162
  {
2133
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2163
    innobase_log_group_home_dir= const_cast<char *>(vm["log-group-home-dir"].as<string>().c_str());
2134
2164
  }
2135
2165
  else
2136
2166
  {
2137
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2167
    innobase_log_group_home_dir = const_cast<char *>(getDataHome().c_str());
2138
2168
  }
2139
2169
 
 
2170
#ifdef UNIV_LOG_ARCHIVE
 
2171
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2172
    starting from 4.0.6 we always set it the same as
 
2173
innodb_log_group_home_dir: */
 
2174
 
 
2175
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2176
 
 
2177
  srv_arch_dir = innobase_log_arch_dir;
 
2178
#endif /* UNIG_LOG_ARCHIVE */
 
2179
 
2140
2180
  ret = (bool)
2141
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2181
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2142
2182
 
2143
 
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2144
 
    errmsg_printf(error::ERROR, _("syntax error in innodb_log_group_home_dir, or a "
2145
 
                                  "wrong number of mirrored log groups"));
 
2183
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2184
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2185
                  "wrong number of mirrored log groups");
2146
2186
 
2147
2187
    goto mem_free_and_error;
2148
2188
  }
2156
2196
 
2157
2197
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2198
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2199
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2200
 
2161
2201
      goto mem_free_and_error;
2162
2202
    }
2167
2207
 
2168
2208
  srv_file_format = format_id;
2169
2209
 
2170
 
  innobase_file_format_name =
2171
 
    trx_sys_file_format_id_to_name(format_id);
2172
 
 
2173
 
  /* Check innobase_file_format_check variable */
2174
 
  if (!innobase_file_format_check)
2175
 
  {
2176
 
    /* Set the value to disable checking. */
2177
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
2178
 
  } else {
2179
 
    /* Set the value to the lowest supported format. */
2180
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN;
2181
 
  }
2182
 
 
2183
 
  /* Did the user specify a format name that we support?
2184
 
     As a side effect it will update the variable
2185
 
     srv_max_file_format_at_startup */
2186
 
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2187
 
  {
2188
 
    errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
2189
 
                                  "should be any value up to %s or its equivalent numeric id"),
2190
 
                  trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2191
 
    goto mem_free_and_error;
 
2210
  /* Given the type of innobase_file_format_name we have little
 
2211
    choice but to cast away the constness from the returned name.
 
2212
    innobase_file_format_name is used in the MySQL set variable
 
2213
    interface and so can't be const. */
 
2214
 
 
2215
  innobase_file_format_name = 
 
2216
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2217
 
 
2218
  /* Process innobase_file_format_check variable */
 
2219
  ut_a(innobase_file_format_check != NULL);
 
2220
 
 
2221
  /* As a side effect it will set srv_check_file_format_at_startup
 
2222
    on valid input. First we check for "on"/"off". */
 
2223
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2224
 
 
2225
    /* Did the user specify a format name that we support ?
 
2226
      As a side effect it will update the variable
 
2227
      srv_check_file_format_at_startup */
 
2228
    if (!innobase_file_format_check_validate(
 
2229
                                             innobase_file_format_check)) {
 
2230
 
 
2231
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2232
                    "innodb_file_format_check value: "
 
2233
                    "should be either 'on' or 'off' or "
 
2234
                    "any value up to %s or its "
 
2235
                    "equivalent numeric id",
 
2236
                    trx_sys_file_format_id_to_name(
 
2237
                                                   DICT_TF_FORMAT_MAX));
 
2238
 
 
2239
      goto mem_free_and_error;
 
2240
    }
2192
2241
  }
2193
2242
 
2194
2243
  if (vm.count("change-buffering"))
2199
2248
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2200
2249
         use++) {
2201
2250
      if (!innobase_strcasecmp(
2202
 
                               innobase_change_buffering.c_str(),
 
2251
                               vm["change-buffering"].as<string>().c_str(),
2203
2252
                               innobase_change_buffering_values[use])) {
2204
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2253
        ibuf_use = (ibuf_use_t) use;
2205
2254
        goto innobase_change_buffering_inited_ok;
2206
2255
      }
2207
2256
    }
2208
2257
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2258
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2259
                  "InnoDB: invalid value "
 
2260
                  "innodb_file_format_check=%s",
2210
2261
                  vm["change-buffering"].as<string>().c_str());
2211
2262
    goto mem_free_and_error;
2212
2263
  }
2213
2264
 
2214
2265
innobase_change_buffering_inited_ok:
2215
2266
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2216
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2267
  innobase_change_buffering = (char*)
 
2268
    innobase_change_buffering_values[ibuf_use];
2217
2269
 
2218
2270
  /* --------------------------------------------------*/
2219
2271
 
2220
 
  if (vm.count("flush-method") != 0)
2221
 
  {
2222
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2223
 
  }
 
2272
  srv_file_flush_method_str = innobase_unix_file_flush_method;
2224
2273
 
2225
2274
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2226
2275
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2227
2276
  srv_log_file_size = (ulint) innobase_log_file_size;
2228
2277
 
 
2278
#ifdef UNIV_LOG_ARCHIVE
 
2279
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2280
#endif /* UNIV_LOG_ARCHIVE */
2229
2281
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2230
2282
 
2231
2283
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2232
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2233
2284
 
2234
2285
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2235
2286
 
2260
2311
 
2261
2312
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2262
2313
 
 
2314
 
 
2315
  innobase_commit_concurrency_init_default();
 
2316
 
2263
2317
  /* Since we in this module access directly the fields of a trx
2264
2318
    struct, and due to different headers and flags it might happen that
2265
2319
    mutex_t has a different size in this module and in InnoDB
2268
2322
 
2269
2323
  err = innobase_start_or_create_for_mysql();
2270
2324
 
2271
 
  if (err != DB_SUCCESS)
2272
 
  {
2273
 
    goto mem_free_and_error;
2274
 
  }
2275
 
 
2276
 
  err = dict_create_sys_replication_log();
2277
 
 
2278
2325
  if (err != DB_SUCCESS) {
2279
2326
    goto mem_free_and_error;
2280
2327
  }
2281
2328
 
2282
 
 
2283
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2284
 
                                                     TRUE);
2285
 
 
2286
2329
  innobase_open_tables = hash_create(200);
 
2330
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2331
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2332
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2333
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2334
  pthread_cond_init(&commit_cond, NULL);
2287
2335
  innodb_inited= 1;
2288
2336
 
2289
2337
  actuall_engine_ptr->dropTemporarySchema();
2290
2338
 
2291
 
  context.add(new InnodbStatusTool);
 
2339
  status_table_function_ptr= new InnodbStatusTool;
2292
2340
 
2293
2341
  context.add(innodb_engine_ptr);
2294
2342
 
2295
 
  context.add(new(std::nothrow)CmpTool(false));
2296
 
 
2297
 
  context.add(new(std::nothrow)CmpTool(true));
2298
 
 
2299
 
  context.add(new(std::nothrow)CmpmemTool(false));
2300
 
 
2301
 
  context.add(new(std::nothrow)CmpmemTool(true));
2302
 
 
2303
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_TRX"));
2304
 
 
2305
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCKS"));
2306
 
 
2307
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS"));
2308
 
 
2309
 
  context.add(new(std::nothrow)InnodbSysTablesTool());
2310
 
 
2311
 
  context.add(new(std::nothrow)InnodbSysTableStatsTool());
2312
 
 
2313
 
  context.add(new(std::nothrow)InnodbSysIndexesTool());
2314
 
 
2315
 
  context.add(new(std::nothrow)InnodbSysColumnsTool());
2316
 
 
2317
 
  context.add(new(std::nothrow)InnodbSysFieldsTool());
2318
 
 
2319
 
  context.add(new(std::nothrow)InnodbSysForeignTool());
2320
 
 
2321
 
  context.add(new(std::nothrow)InnodbSysForeignColsTool());
 
2343
  context.add(status_table_function_ptr);
 
2344
 
 
2345
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2346
  context.add(cmp_tool);
 
2347
 
 
2348
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2349
  context.add(cmp_reset_tool);
 
2350
 
 
2351
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2352
  context.add(cmp_mem_tool);
 
2353
 
 
2354
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2355
  context.add(cmp_mem_reset_tool);
 
2356
 
 
2357
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2358
  context.add(innodb_trx_tool);
 
2359
 
 
2360
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2361
  context.add(innodb_locks_tool);
 
2362
 
 
2363
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2364
  context.add(innodb_lock_waits_tool);
2322
2365
 
2323
2366
  context.add(new(std::nothrow)InnodbInternalTables());
2324
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
 
 
2326
 
  if (innobase_use_replication_log)
2327
 
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2329
 
    context.add(replication_logger);
2330
 
    ReplicationLog::setup(replication_logger);
2331
 
  }
2332
 
 
2333
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2334
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2335
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2336
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2337
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2338
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2339
 
 
2340
 
 
2341
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2342
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2343
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2344
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2345
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2346
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2347
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2348
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2349
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2350
 
 
2351
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2352
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2353
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2354
 
 
2355
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2356
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2357
 
                                                                   innodb_auto_extend_increment,
2358
 
                                                                   auto_extend_update));
2359
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2360
 
                                                                   innodb_io_capacity,
2361
 
                                                                   io_capacity_update));
2362
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2363
 
                                                                   innodb_purge_batch_size,
2364
 
                                                                   purge_batch_update));
2365
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2366
 
                                                                   innodb_n_purge_threads,
2367
 
                                                                   purge_threads_update));
2368
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
2369
 
  context.registerVariable(new sys_var_std_string("file_format",
2370
 
                                                  innobase_file_format_name,
2371
 
                                                  innodb_file_format_name_validate));
2372
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2373
 
                                                  innobase_change_buffering,
2374
 
                                                  innodb_change_buffering_validate));
2375
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2376
 
                                                  innobase_file_format_max,
2377
 
                                                  innodb_file_format_max_validate));
2378
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2379
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2380
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush_log_at_trx_commit",
2381
 
                                                  innodb_flush_log_at_trx_commit));
2382
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2383
 
                                                  innodb_max_dirty_pages_pct));
2384
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2385
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2386
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2387
 
 
2388
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2389
 
                                                                   innobase_commit_concurrency,
2390
 
                                                                   innodb_commit_concurrency_validate));
2391
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2392
 
                                                                   innodb_concurrency_tickets));
2393
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2394
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2395
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2396
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2397
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2398
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2399
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2400
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2401
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2402
 
                                                                   innobase_old_blocks_pct,
2403
 
                                                                   innodb_old_blocks_pct_update));
2404
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2405
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2406
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2407
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2408
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2409
 
                                                                   innobase_thread_concurrency,
2410
 
                                                                   innodb_thread_concurrency_update));
2411
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2412
 
                                                                   innodb_read_ahead_threshold,
2413
 
                                                                   innodb_read_ahead_threshold_update));
 
2367
 
2414
2368
  /* Get the current high water mark format. */
2415
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2416
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2369
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2417
2370
 
2418
2371
  return(FALSE);
2419
 
 
2420
2372
error:
2421
2373
  return(TRUE);
2422
2374
}
2513
2465
    trx_search_latch_release_if_reserved(trx);
2514
2466
  }
2515
2467
 
2516
 
  if (all)
2517
 
  {
 
2468
  if (all
 
2469
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2470
 
2518
2471
    /* We were instructed to commit the whole transaction, or
2519
2472
    this is an SQL statement end and autocommit is on */
2520
2473
 
2521
2474
    /* We need current binlog position for ibbackup to work.
2522
2475
    Note, the position is current because of
2523
2476
    prepare_commit_mutex */
2524
 
    const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2525
 
    if (commit_concurrency)
2526
 
    {
2527
 
      do 
2528
 
      {
2529
 
        boost::mutex::scoped_lock scopedLock(commit_cond_m);
2530
 
        commit_threads++;
2531
 
 
2532
 
        if (commit_threads <= commit_concurrency) 
2533
 
          break;
2534
 
 
 
2477
retry:
 
2478
    if (innobase_commit_concurrency > 0) {
 
2479
      pthread_mutex_lock(&commit_cond_m);
 
2480
      commit_threads++;
 
2481
 
 
2482
      if (commit_threads > innobase_commit_concurrency) {
2535
2483
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2484
        pthread_cond_wait(&commit_cond,
 
2485
          &commit_cond_m);
 
2486
        pthread_mutex_unlock(&commit_cond_m);
 
2487
        goto retry;
 
2488
      }
 
2489
      else {
 
2490
        pthread_mutex_unlock(&commit_cond_m);
 
2491
      }
2538
2492
    }
2539
2493
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2494
                /* Store transaction point for binlog
 
2495
    Later logic tests that this is set to _something_. We need
 
2496
    that logic to fire, even though we do not have a real name. */
 
2497
    trx->mysql_log_file_name = "UNUSED";
2541
2498
    trx->mysql_log_offset = 0;
2542
2499
 
2543
2500
    /* Don't do write + flush right now. For group commit
2547
2504
    innobase_commit_low(trx);
2548
2505
    trx->flush_log_later = FALSE;
2549
2506
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2507
    if (innobase_commit_concurrency > 0) {
 
2508
      pthread_mutex_lock(&commit_cond_m);
2553
2509
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2510
      pthread_cond_signal(&commit_cond);
 
2511
      pthread_mutex_unlock(&commit_cond_m);
2555
2512
    }
2556
2513
 
2557
2514
    /* Now do a write + flush of logs. */
2571
2528
    SQL statement */
2572
2529
 
2573
2530
    trx_mark_sql_stat_end(trx);
2574
 
 
2575
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2576
 
    {
2577
 
      if (trx->conc_state != TRX_NOT_STARTED)
2578
 
      {
2579
 
        commit(session, TRUE);
2580
 
      }
2581
 
    }
2582
2531
  }
2583
2532
 
2584
2533
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2593
2542
  threads: */
2594
2543
  srv_active_wake_master_thread();
2595
2544
 
2596
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2597
 
      trx->global_read_view)
2598
 
  {
2599
 
    /* At low transaction isolation levels we let
2600
 
       each consistent read set its own snapshot */
2601
 
    read_view_close_for_mysql(trx);
2602
 
  }
2603
 
 
2604
2545
  return(0);
2605
2546
}
2606
2547
 
2628
2569
 
2629
2570
  innobase_release_stat_resources(trx);
2630
2571
 
2631
 
  trx->n_autoinc_rows = 0;
2632
 
 
2633
2572
  /* If we had reserved the auto-inc lock for some table (if
2634
2573
  we come here to roll back the latest SQL statement) we
2635
2574
  release it now before a possibly lengthy rollback */
2636
2575
 
2637
2576
  row_unlock_table_autoinc_for_mysql(trx);
2638
2577
 
2639
 
  if (all)
2640
 
  {
 
2578
  if (all
 
2579
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2580
 
2641
2581
    error = trx_rollback_for_mysql(trx);
2642
2582
  } else {
2643
2583
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2644
2584
  }
2645
2585
 
2646
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2647
 
      trx->global_read_view)
2648
 
  {
2649
 
    /* At low transaction isolation levels we let
2650
 
       each consistent read set its own snapshot */
2651
 
    read_view_close_for_mysql(trx);
2652
 
  }
2653
 
 
2654
2586
  return(convert_error_code_to_mysql(error, 0, NULL));
2655
2587
}
2656
2588
 
2787
2719
 
2788
2720
  ut_a(trx);
2789
2721
 
2790
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2722
  assert(session->killed != Session::NOT_KILLED ||
2791
2723
         trx->conc_state == TRX_NOT_STARTED);
2792
2724
 
2793
2725
  /* Warn if rolling back some things... */
2794
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2726
  if (session->killed != Session::NOT_KILLED &&
2795
2727
      trx->conc_state != TRX_NOT_STARTED &&
2796
 
      trx->undo_no > 0 &&
 
2728
      trx->undo_no.low > 0 &&
2797
2729
      global_system_variables.log_warnings)
2798
2730
  {
2799
 
      errmsg_printf(error::WARN,
 
2731
      errmsg_printf(ERRMSG_LVL_WARN, 
2800
2732
      "Drizzle is closing a connection during a KILL operation\n"
2801
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2733
      "that has an active InnoDB transaction.  %lu row modifications will "
2802
2734
      "roll back.\n",
2803
 
      (ullint) trx->undo_no);
 
2735
      (ulong) trx->undo_no.low);
2804
2736
  }
2805
2737
 
2806
2738
  innobase_rollback_trx(trx);
2876
2808
  return(true);
2877
2809
}
2878
2810
 
2879
 
/********************************************************************//**
2880
 
Get the upper limit of the MySQL integral and floating-point type.
2881
 
@return maximum allowed value for the field */
2882
 
static
2883
 
uint64_t
2884
 
innobase_get_int_col_max_value(
2885
 
/*===========================*/
2886
 
        const Field*    field)  /*!< in: MySQL field */
2887
 
{
2888
 
        uint64_t        max_value = 0;
2889
 
 
2890
 
        switch(field->key_type()) {
2891
 
        /* TINY */
2892
 
        case HA_KEYTYPE_BINARY:
2893
 
                max_value = 0xFFULL;
2894
 
                break;
2895
 
        /* LONG */
2896
 
        case HA_KEYTYPE_ULONG_INT:
2897
 
                max_value = 0xFFFFFFFFULL;
2898
 
                break;
2899
 
        case HA_KEYTYPE_LONG_INT:
2900
 
                max_value = 0x7FFFFFFFULL;
2901
 
                break;
2902
 
        /* BIG */
2903
 
        case HA_KEYTYPE_ULONGLONG:
2904
 
                max_value = 0xFFFFFFFFFFFFFFFFULL;
2905
 
                break;
2906
 
        case HA_KEYTYPE_LONGLONG:
2907
 
                max_value = 0x7FFFFFFFFFFFFFFFULL;
2908
 
                break;
2909
 
        case HA_KEYTYPE_DOUBLE:
2910
 
                /* We use the maximum as per IEEE754-2008 standard, 2^53 */
2911
 
                max_value = 0x20000000000000ULL;
2912
 
                break;
2913
 
        default:
2914
 
                ut_error;
2915
 
        }
2916
 
 
2917
 
        return(max_value);
2918
 
}
2919
 
 
2920
 
/*******************************************************************//**
2921
 
This function checks whether the index column information
2922
 
is consistent between KEY info from mysql and that from innodb index.
2923
 
@return TRUE if all column types match. */
2924
 
static
2925
 
ibool
2926
 
innobase_match_index_columns(
2927
 
/*=========================*/
2928
 
        const KeyInfo*          key_info,       /*!< in: Index info
2929
 
                                                from mysql */
2930
 
        const dict_index_t*     index_info)     /*!< in: Index info
2931
 
                                                from Innodb */
2932
 
{
2933
 
        const KeyPartInfo*      key_part;
2934
 
        const KeyPartInfo*      key_end;
2935
 
        const dict_field_t*     innodb_idx_fld;
2936
 
        const dict_field_t*     innodb_idx_fld_end;
2937
 
 
2938
 
        /* Check whether user defined index column count matches */
2939
 
        if (key_info->key_parts != index_info->n_user_defined_cols) {
2940
 
                return(FALSE);
2941
 
        }
2942
 
 
2943
 
        key_part = key_info->key_part;
2944
 
        key_end = key_part + key_info->key_parts;
2945
 
        innodb_idx_fld = index_info->fields;
2946
 
        innodb_idx_fld_end = index_info->fields + index_info->n_fields;
2947
 
 
2948
 
        /* Check each index column's datatype. We do not check
2949
 
        column name because there exists case that index
2950
 
        column name got modified in mysql but such change does not
2951
 
        propagate to InnoDB.
2952
 
        One hidden assumption here is that the index column sequences
2953
 
        are matched up between those in mysql and Innodb. */
2954
 
        for (; key_part != key_end; ++key_part) {
2955
 
                ulint   col_type;
2956
 
                ibool   is_unsigned;
2957
 
                ulint   mtype = innodb_idx_fld->col->mtype;
2958
 
 
2959
 
                /* Need to translate to InnoDB column type before
2960
 
                comparison. */
2961
 
                col_type = get_innobase_type_from_mysql_type(&is_unsigned,
2962
 
                                                             key_part->field);
2963
 
 
2964
 
                /* Ignore Innodb specific system columns. */
2965
 
                while (mtype == DATA_SYS) {
2966
 
                        innodb_idx_fld++;
2967
 
 
2968
 
                        if (innodb_idx_fld >= innodb_idx_fld_end) {
2969
 
                                return(FALSE);
2970
 
                        }
2971
 
                }
2972
 
 
2973
 
                if (col_type != mtype) {
2974
 
                        /* Column Type mismatches */
2975
 
                        return(FALSE);
2976
 
                }
2977
 
 
2978
 
                innodb_idx_fld++;
2979
 
        }
2980
 
 
2981
 
        return(TRUE);
2982
 
}
2983
 
 
2984
 
/*******************************************************************//**
2985
 
This function builds a translation table in INNOBASE_SHARE
2986
 
structure for fast index location with mysql array number from its
2987
 
table->key_info structure. This also provides the necessary translation
2988
 
between the key order in mysql key_info and Innodb ib_table->indexes if
2989
 
they are not fully matched with each other.
2990
 
Note we do not have any mutex protecting the translation table
2991
 
building based on the assumption that there is no concurrent
2992
 
index creation/drop and DMLs that requires index lookup. All table
2993
 
handle will be closed before the index creation/drop.
2994
 
@return TRUE if index translation table built successfully */
2995
 
static
2996
 
ibool
2997
 
innobase_build_index_translation(
2998
 
/*=============================*/
2999
 
        const Table*            table,    /*!< in: table in MySQL data
3000
 
                                          dictionary */
3001
 
        dict_table_t*           ib_table, /*!< in: table in Innodb data
3002
 
                                          dictionary */
3003
 
        INNOBASE_SHARE*         share)    /*!< in/out: share structure
3004
 
                                          where index translation table
3005
 
                                          will be constructed in. */
3006
 
{
3007
 
        ulint           mysql_num_index;
3008
 
        ulint           ib_num_index;
3009
 
        dict_index_t**  index_mapping;
3010
 
        ibool           ret = TRUE;
3011
 
 
3012
 
        mutex_enter(&dict_sys->mutex);
3013
 
 
3014
 
        mysql_num_index = table->getShare()->keys;
3015
 
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3016
 
 
3017
 
        index_mapping = share->idx_trans_tbl.index_mapping;
3018
 
 
3019
 
        /* If there exists inconsistency between MySQL and InnoDB dictionary
3020
 
        (metadata) information, the number of index defined in MySQL
3021
 
        could exceed that in InnoDB, do not build index translation
3022
 
        table in such case */
3023
 
        if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3024
 
                ret = FALSE;
3025
 
                goto func_exit;
3026
 
        }
3027
 
 
3028
 
        /* If index entry count is non-zero, nothing has
3029
 
        changed since last update, directly return TRUE */
3030
 
        if (share->idx_trans_tbl.index_count) {
3031
 
                /* Index entry count should still match mysql_num_index */
3032
 
                ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
3033
 
                goto func_exit;
3034
 
        }
3035
 
 
3036
 
        /* The number of index increased, rebuild the mapping table */
3037
 
        if (mysql_num_index > share->idx_trans_tbl.array_size) {
3038
 
                index_mapping = (dict_index_t**) realloc(index_mapping,
3039
 
                                                        mysql_num_index *
3040
 
                                                         sizeof(*index_mapping));
3041
 
 
3042
 
                if (!index_mapping) {
3043
 
                        /* Report an error if index_mapping continues to be
3044
 
                        NULL and mysql_num_index is a non-zero value */
3045
 
                        errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
3046
 
                                      "index translation table. Number of Index:%lu, array size:%lu",
3047
 
                                        mysql_num_index,
3048
 
                                        share->idx_trans_tbl.array_size);
3049
 
                        ret = FALSE;
3050
 
                        goto func_exit;
3051
 
                }
3052
 
 
3053
 
                share->idx_trans_tbl.array_size = mysql_num_index;
3054
 
        }
3055
 
 
3056
 
        /* For each index in the mysql key_info array, fetch its
3057
 
        corresponding InnoDB index pointer into index_mapping
3058
 
        array. */
3059
 
        for (ulint count = 0; count < mysql_num_index; count++) {
3060
 
 
3061
 
                /* Fetch index pointers into index_mapping according to mysql
3062
 
                index sequence */
3063
 
                index_mapping[count] = dict_table_get_index_on_name(
3064
 
                        ib_table, table->key_info[count].name);
3065
 
 
3066
 
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
3069
 
                        ret = FALSE;
3070
 
                        goto func_exit;
3071
 
                }
3072
 
 
3073
 
                /* Double check fetched index has the same
3074
 
                column info as those in mysql key_info. */
3075
 
                if (!innobase_match_index_columns(&table->key_info[count], index_mapping[count])) {
3076
 
                  errmsg_printf(error::ERROR, "Found index %s whose column info does not match that of MySQL.",
3077
 
                                table->key_info[count].name);
3078
 
                  ret = FALSE;
3079
 
                  goto func_exit;
3080
 
                }
3081
 
        }
3082
 
 
3083
 
        /* Successfully built the translation table */
3084
 
        share->idx_trans_tbl.index_count = mysql_num_index;
3085
 
 
3086
 
func_exit:
3087
 
        if (!ret) {
3088
 
                /* Build translation table failed. */
3089
 
                free(index_mapping);
3090
 
 
3091
 
                share->idx_trans_tbl.array_size = 0;
3092
 
                share->idx_trans_tbl.index_count = 0;
3093
 
                index_mapping = NULL;
3094
 
        }
3095
 
 
3096
 
        share->idx_trans_tbl.index_mapping = index_mapping;
3097
 
 
3098
 
        mutex_exit(&dict_sys->mutex);
3099
 
 
3100
 
        return(ret);
3101
 
}
3102
 
 
3103
 
/*******************************************************************//**
3104
 
This function uses index translation table to quickly locate the
3105
 
requested index structure.
3106
 
Note we do not have mutex protection for the index translatoin table
3107
 
access, it is based on the assumption that there is no concurrent
3108
 
translation table rebuild (fter create/drop index) and DMLs that
3109
 
require index lookup.
3110
 
@return dict_index_t structure for requested index. NULL if
3111
 
fail to locate the index structure. */
3112
 
static
3113
 
dict_index_t*
3114
 
innobase_index_lookup(
3115
 
/*==================*/
3116
 
        INNOBASE_SHARE* share,  /*!< in: share structure for index
3117
 
                                translation table. */
3118
 
        uint            keynr)  /*!< in: index number for the requested
3119
 
                                index */
3120
 
{
3121
 
        if (!share->idx_trans_tbl.index_mapping
3122
 
            || keynr >= share->idx_trans_tbl.index_count) {
3123
 
                return(NULL);
3124
 
        }
3125
 
 
3126
 
        return(share->idx_trans_tbl.index_mapping[keynr]);
 
2811
/*****************************************************************//**
 
2812
Normalizes a table name string. A normalized name consists of the
 
2813
database name catenated to '/' and table name. An example:
 
2814
test/mytable. On Windows normalization puts both the database name and the
 
2815
table name always to lower case. */
 
2816
static
 
2817
void
 
2818
normalize_table_name(
 
2819
/*=================*/
 
2820
  char*   norm_name,  /*!< out: normalized name as a
 
2821
          null-terminated string */
 
2822
  const char* name)   /*!< in: table name string */
 
2823
{
 
2824
  const char* name_ptr;
 
2825
  const char* db_ptr;
 
2826
  const char* ptr;
 
2827
 
 
2828
  /* Scan name from the end */
 
2829
 
 
2830
  ptr = strchr(name, '\0')-1;
 
2831
 
 
2832
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2833
    ptr--;
 
2834
  }
 
2835
 
 
2836
  name_ptr = ptr + 1;
 
2837
 
 
2838
  assert(ptr > name);
 
2839
 
 
2840
  ptr--;
 
2841
 
 
2842
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2843
    ptr--;
 
2844
  }
 
2845
 
 
2846
  db_ptr = ptr + 1;
 
2847
 
 
2848
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2849
 
 
2850
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2851
 
 
2852
#ifdef __WIN__
 
2853
  innobase_casedn_str(norm_name);
 
2854
#endif
3127
2855
}
3128
2856
 
3129
2857
/********************************************************************//**
3130
2858
Set the autoinc column max value. This should only be called once from
3131
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2859
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2860
@return DB_SUCCESS or error code */
3132
2861
UNIV_INTERN
3133
 
void
 
2862
ulint
3134
2863
ha_innobase::innobase_initialize_autoinc()
3135
2864
/*======================================*/
3136
2865
{
 
2866
  dict_index_t* index;
3137
2867
  uint64_t  auto_inc;
3138
 
  const Field*  field = getTable()->found_next_number_field;
3139
 
 
3140
 
  if (field != NULL) {
3141
 
    auto_inc = innobase_get_int_col_max_value(field);
3142
 
  } else {
3143
 
    /* We have no idea what's been passed in to us as the
3144
 
       autoinc column. We set it to the 0, effectively disabling
3145
 
       updates to the table. */
3146
 
    auto_inc = 0;
3147
 
 
 
2868
  const char* col_name;
 
2869
  ulint   error;
 
2870
 
 
2871
  col_name = table->found_next_number_field->field_name;
 
2872
  index = innobase_get_index(table->getShare()->next_number_index);
 
2873
 
 
2874
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2875
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2876
 
 
2877
  switch (error) {
 
2878
  case DB_SUCCESS:
 
2879
 
 
2880
    /* At the this stage we don't know the increment
 
2881
    or the offset, so use default inrement of 1. */
 
2882
    ++auto_inc;
 
2883
    break;
 
2884
 
 
2885
  case DB_RECORD_NOT_FOUND:
3148
2886
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
3150
 
  }
3151
 
 
3152
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3153
 
    /* If the recovery level is set so high that writes
3154
 
       are disabled we force the AUTOINC counter to 0
3155
 
       value effectively disabling writes to the table.
3156
 
       Secondly, we avoid reading the table in case the read
3157
 
       results in failure due to a corrupted table/index.
3158
 
 
3159
 
       We will not return an error to the client, so that the
3160
 
       tables can be dumped with minimal hassle.  If an error
3161
 
       were returned in this case, the first attempt to read
3162
 
       the table would fail and subsequent SELECTs would succeed. */
3163
 
    auto_inc = 0;
3164
 
  } else if (field == NULL) {
3165
 
    /* This is a far more serious error, best to avoid
3166
 
       opening the table and return failure. */
3167
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3168
 
  } else {
3169
 
    dict_index_t*       index;
3170
 
    const char* col_name;
3171
 
    uint64_t    read_auto_inc;
3172
 
    ulint               err;
3173
 
 
3174
 
    update_session(getTable()->in_use);
3175
 
    col_name = field->field_name;
3176
 
 
3177
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3178
 
 
3179
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3180
 
 
3181
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3182
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3183
 
 
3184
 
    switch (err) {
3185
 
    case DB_SUCCESS: {
3186
 
      uint64_t col_max_value;
3187
 
 
3188
 
      col_max_value = innobase_get_int_col_max_value(field);
3189
 
 
3190
 
      /* At the this stage we do not know the increment
3191
 
         nor the offset, so use a default increment of 1. */
3192
 
 
3193
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3194
 
 
3195
 
      break;
3196
 
    }
3197
 
    case DB_RECORD_NOT_FOUND:
3198
 
      ut_print_timestamp(stderr);
3199
 
      errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3200
 
                    "InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3201
 
                    "InnoDB: We set the next AUTOINC column value to 0,\n"
3202
 
                    "InnoDB: in effect disabling the AUTOINC next value generation.\n"
3203
 
                    "InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3204
 
                    "InnoDB: or fix the data dictionary by recreating the table.\n",
3205
 
                    col_name, index->table->name);
3206
 
 
3207
 
      /* This will disable the AUTOINC generation. */
3208
 
      auto_inc = 0;
3209
 
 
3210
 
      /* We want the open to succeed, so that the user can
3211
 
         take corrective action. ie. reads should succeed but
3212
 
         updates should fail. */
3213
 
      err = DB_SUCCESS;
3214
 
      break;
3215
 
    default:
3216
 
      /* row_search_max_autoinc() should only return
3217
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3218
 
      ut_error;
3219
 
    }
 
2887
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2888
      "dictionaries are out of sync.\n"
 
2889
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2890
      "InnoDB table %s.\n"
 
2891
      "InnoDB: We set the next AUTOINC column value to the "
 
2892
      "maximum possible value,\n"
 
2893
      "InnoDB: in effect disabling the AUTOINC next value "
 
2894
      "generation.\n"
 
2895
      "InnoDB: You can either set the next AUTOINC value "
 
2896
      "explicitly using ALTER TABLE\n"
 
2897
      "InnoDB: or fix the data dictionary by recreating "
 
2898
      "the table.\n",
 
2899
      col_name, index->table->name);
 
2900
 
 
2901
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2902
    break;
 
2903
 
 
2904
  default:
 
2905
    return(error);
3220
2906
  }
3221
2907
 
3222
2908
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2909
 
 
2910
  return(DB_SUCCESS);
3223
2911
}
3224
2912
 
3225
2913
/*****************************************************************//**
3228
2916
@return 1 if error, 0 if success */
3229
2917
UNIV_INTERN
3230
2918
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
2919
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
2920
                    int   mode,   /*!< in: not used */
3233
2921
                    uint    test_if_locked) /*!< in: not used */
3234
2922
{
3235
2923
  dict_table_t* ib_table;
 
2924
  char    norm_name[FN_REFLEN];
3236
2925
  Session*    session;
3237
2926
 
3238
2927
  UT_NOT_USED(mode);
3239
2928
  UT_NOT_USED(test_if_locked);
3240
2929
 
3241
 
  session= getTable()->in_use;
 
2930
  session= table->in_use;
3242
2931
 
3243
2932
  /* Under some cases Drizzle seems to call this function while
3244
2933
  holding btr_search_latch. This breaks the latching order as
3247
2936
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
2937
  }
3249
2938
 
 
2939
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
2940
 
3250
2941
  user_session = NULL;
3251
2942
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
2943
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
2944
 
3255
 
  if (search_string.compare("data_dictionary") == 0)
3256
 
  {
3257
 
    std::string table_name(identifier.getTableName());
3258
 
    boost::algorithm::to_upper(table_name);
3259
 
    if (!(share=get_share(table_name.c_str())))
3260
 
    {
3261
 
      return 1;
3262
 
    }
3263
 
  }
3264
 
  else
3265
 
  {
3266
 
    if (!(share=get_share(identifier.getKeyPath().c_str())))
3267
 
    {
3268
 
      return(1);
3269
 
    }
 
2945
    return(1);
3270
2946
  }
3271
2947
 
3272
2948
  /* Create buffers for packing the fields of a record. Why
3275
2951
  stored the string length as the first byte. */
3276
2952
 
3277
2953
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
3279
 
        + getTable()->getShare()->max_key_length
 
2954
        table->getShare()->stored_rec_length
 
2955
        + table->getShare()->max_key_length
3280
2956
        + MAX_REF_PARTS * 3;
3281
2957
 
3282
2958
  upd_buff.resize(upd_and_key_val_buff_len);
3293
2969
  }
3294
2970
 
3295
2971
  /* Get pointer to a table object in InnoDB dictionary cache */
3296
 
  if (search_string.compare("data_dictionary") == 0)
3297
 
  {
3298
 
    std::string table_name(identifier.getTableName());
3299
 
    boost::algorithm::to_upper(table_name);
3300
 
    ib_table = dict_table_get(table_name.c_str(), TRUE);
3301
 
  }
3302
 
  else
3303
 
  {
3304
 
    ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3305
 
  }
 
2972
  ib_table = dict_table_get(norm_name, TRUE);
3306
2973
  
3307
2974
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
2975
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
2976
        "the internal data dictionary of InnoDB "
3310
2977
        "though the .frm file for the\n"
3311
2978
        "table exists. Maybe you have deleted and "
3319
2986
        "doesn't support.\n"
3320
2987
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
2988
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
2989
        norm_name);
3323
2990
    free_share(share);
3324
2991
    upd_buff.resize(0);
3325
2992
    key_val_buff.resize(0);
3328
2995
    return(HA_ERR_NO_SUCH_TABLE);
3329
2996
  }
3330
2997
 
3331
 
  if (ib_table->ibd_file_missing && ! session->doing_tablespace_operation()) {
3332
 
    errmsg_printf(error::ERROR, "MySQL is trying to open a table handle but "
 
2998
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
2999
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3000
        "the .ibd file for\ntable %s does not exist.\n"
3334
3001
        "Have you deleted the .ibd file from the "
3335
3002
        "database directory under\nthe MySQL datadir, "
3336
3003
        "or have you used DISCARD TABLESPACE?\n"
3337
3004
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3005
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3006
        norm_name);
3340
3007
    free_share(share);
3341
3008
    upd_buff.resize(0);
3342
3009
    key_val_buff.resize(0);
3348
3015
 
3349
3016
  prebuilt = row_create_prebuilt(ib_table);
3350
3017
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
3352
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3018
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3019
  prebuilt->default_rec = table->getDefaultValues();
3353
3020
  ut_ad(prebuilt->default_rec);
3354
3021
 
3355
3022
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3356
3023
 
3357
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3024
  primary_key = table->getShare()->getPrimaryKey();
3358
3025
  key_used_on_scan = primary_key;
3359
3026
 
3360
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3361
 
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3362
 
                    " Table %s failed", identifier.getKeyPath().c_str());
3363
 
  }
3364
 
 
3365
3027
  /* Allocate a buffer for a 'row reference'. A row reference is
3366
3028
  a string of bytes of length ref_length which uniquely specifies
3367
3029
  a row in our table. Note that MySQL may also compare two row
3369
3031
  of length ref_length! */
3370
3032
 
3371
3033
  if (!row_table_got_default_clust_index(ib_table)) {
 
3034
    if (primary_key >= MAX_KEY) {
 
3035
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3036
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3037
    }
3372
3038
 
3373
3039
    prebuilt->clust_index_was_generated = FALSE;
3374
3040
 
3375
 
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
3377
 
                    "InnoDB data dictionary, but not "
3378
 
                    "in MySQL!", identifier.getTableName().c_str());
3379
 
 
3380
 
      /* This mismatch could cause further problems
3381
 
         if not attended, bring this to the user's attention
3382
 
         by printing a warning in addition to log a message
3383
 
         in the errorlog */
3384
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3385
 
                          ER_NO_SUCH_INDEX,
3386
 
                          "InnoDB: Table %s has a "
3387
 
                          "primary key in InnoDB data "
3388
 
                          "dictionary, but not in "
3389
 
                          "MySQL!", identifier.getTableName().c_str());
3390
 
 
3391
 
      /* If primary_key >= MAX_KEY, its (primary_key)
3392
 
         value could be out of bound if continue to index
3393
 
         into key_info[] array. Find InnoDB primary index,
3394
 
         and assign its key_length to ref_length.
3395
 
         In addition, since MySQL indexes are sorted starting
3396
 
         with primary index, unique index etc., initialize
3397
 
         ref_length to the first index key length in
3398
 
         case we fail to find InnoDB cluster index.
3399
 
 
3400
 
         Please note, this will not resolve the primary
3401
 
         index mismatch problem, other side effects are
3402
 
         possible if users continue to use the table.
3403
 
         However, we allow this table to be opened so
3404
 
         that user can adopt necessary measures for the
3405
 
         mismatch while still being accessible to the table
3406
 
         date. */
3407
 
      ref_length = getTable()->key_info[0].key_length;
3408
 
 
3409
 
      /* Find correspoinding cluster index
3410
 
         key length in MySQL's key_info[] array */
3411
 
      for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3412
 
        dict_index_t*   index;
3413
 
        index = innobase_get_index(i);
3414
 
        if (dict_index_is_clust(index)) {
3415
 
          ref_length =
3416
 
            getTable()->key_info[i].key_length;
3417
 
        }
3418
 
      }
3419
 
    } else {
3420
 
      /* MySQL allocates the buffer for ref.
3421
 
         key_info->key_length includes space for all key
3422
 
         columns + one byte for each column that may be
3423
 
         NULL. ref_length must be as exact as possible to
3424
 
         save space, because all row reference buffers are
3425
 
         allocated based on ref_length. */
3426
 
 
3427
 
      ref_length = getTable()->key_info[primary_key].key_length;
3428
 
    }
 
3041
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3042
    includes space for all key columns + one byte for each column
 
3043
    that may be NULL. ref_length must be as exact as possible to
 
3044
    save space, because all row reference buffers are allocated
 
3045
    based on ref_length. */
 
3046
 
 
3047
    ref_length = table->key_info[primary_key].key_length;
3429
3048
  } else {
3430
3049
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
3432
 
                    "Table %s has no primary key in InnoDB data "
3433
 
                    "dictionary, but has one in MySQL! If you "
3434
 
                    "created the table with a MySQL version < "
3435
 
                    "3.23.54 and did not define a primary key, "
3436
 
                    "but defined a unique key with all non-NULL "
3437
 
                    "columns, then MySQL internally treats that "
3438
 
                    "key as the primary key. You can fix this "
3439
 
                    "error by dump + DROP + CREATE + reimport "
3440
 
                    "of the table.", identifier.getTableName().c_str());
3441
 
 
3442
 
      /* This mismatch could cause further problems
3443
 
         if not attended, bring this to the user attention
3444
 
         by printing a warning in addition to log a message
3445
 
         in the errorlog */
3446
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3447
 
                          ER_NO_SUCH_INDEX,
3448
 
                          "InnoDB: Table %s has no "
3449
 
                          "primary key in InnoDB data "
3450
 
                          "dictionary, but has one in "
3451
 
                          "MySQL!", identifier.getTableName().c_str());
 
3050
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3051
          "dictionary, but has one in MySQL! If you "
 
3052
          "created the table with a MySQL version < "
 
3053
          "3.23.54 and did not define a primary key, "
 
3054
          "but defined a unique key with all non-NULL "
 
3055
          "columns, then MySQL internally treats that "
 
3056
          "key as the primary key. You can fix this "
 
3057
          "error by dump + DROP + CREATE + reimport "
 
3058
          "of the table.", identifier.getTableName().c_str());
3452
3059
    }
3453
3060
 
3454
3061
    prebuilt->clust_index_was_generated = TRUE;
3464
3071
    and it will never be updated anyway. */
3465
3072
 
3466
3073
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3074
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3075
        "Table %s key_used_on_scan is %lu even "
3469
3076
        "though there is no primary key inside "
3470
3077
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3481
3088
    /* We update the highest file format in the system table
3482
3089
    space, if this table has higher file format setting. */
3483
3090
 
3484
 
    char changed_file_format_max[100];
3485
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3486
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
 
3091
    trx_sys_file_format_max_upgrade(
 
3092
      (const char**) &innobase_file_format_check,
3487
3093
      dict_table_get_format(prebuilt->table));
3488
 
    innobase_file_format_max= changed_file_format_max;
3489
3094
  }
3490
3095
 
 
3096
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3097
 
3491
3098
  /* Only if the table has an AUTOINC column. */
3492
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3099
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3100
    ulint error;
3493
3101
 
3494
3102
    dict_table_autoinc_lock(prebuilt->table);
3495
3103
 
3499
3107
    autoinc value from a previous Drizzle open. */
3500
3108
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3501
3109
 
3502
 
      innobase_initialize_autoinc();
 
3110
      error = innobase_initialize_autoinc();
 
3111
      ut_a(error == DB_SUCCESS);
3503
3112
    }
3504
3113
 
3505
3114
    dict_table_autoinc_unlock(prebuilt->table);
3506
3115
  }
3507
3116
 
3508
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3509
 
 
3510
3117
  return(0);
3511
3118
}
3512
3119
 
3527
3134
{
3528
3135
  Session*  session;
3529
3136
 
3530
 
  session= getTable()->in_use;
 
3137
  session= table->in_use;
3531
3138
  if (session != NULL) {
3532
3139
    getTransactionalEngine()->releaseTemporaryLatches(session);
3533
3140
  }
3616
3223
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3224
function, remember to update the prototype there!
3618
3225
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3226
extern "C" UNIV_INTERN
 
3227
int
3620
3228
innobase_mysql_cmp(
3621
3229
/*===============*/
3622
3230
  int   mysql_type, /*!< in: MySQL type */
3663
3271
      charset = get_charset(charset_number);
3664
3272
 
3665
3273
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3274
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3275
                      "a comparison, but MySQL cannot "
3668
3276
                      "find that charset.",
3669
3277
                      (ulong) charset_number);
3698
3306
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3307
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3308
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3309
extern "C" UNIV_INTERN
3702
3310
ulint
3703
3311
get_innobase_type_from_mysql_type(
3704
3312
/*==============================*/
3747
3355
      return(DATA_VARMYSQL);
3748
3356
    }
3749
3357
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3358
    return(DATA_FIXBINARY);
3752
3359
  case DRIZZLE_TYPE_LONG:
3753
3360
  case DRIZZLE_TYPE_LONGLONG:
3754
3361
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3362
  case DRIZZLE_TYPE_DATE:
3757
3363
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3364
    return(DATA_INT);
3760
3365
  case DRIZZLE_TYPE_DOUBLE:
3761
3366
    return(DATA_DOUBLE);
3762
3367
  case DRIZZLE_TYPE_BLOB:
3763
 
    return(DATA_BLOB);
3764
 
  case DRIZZLE_TYPE_BOOLEAN:
3765
 
  case DRIZZLE_TYPE_UUID:
3766
 
    return(DATA_FIXBINARY);
3767
 
  case DRIZZLE_TYPE_NULL:
 
3368
                return(DATA_BLOB);
 
3369
  default:
3768
3370
    ut_error;
3769
3371
  }
3770
3372
 
3813
3415
  uint    buff_len,/*!< in: buffer length */
3814
3416
  const unsigned char*  record)/*!< in: row in MySQL format */
3815
3417
{
3816
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3418
  KeyInfo*    key_info  = &table->key_info[keynr];
3817
3419
  KeyPartInfo*  key_part  = key_info->key_part;
3818
3420
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3819
3421
  char*   buff_start  = buff;
3889
3491
 
3890
3492
      data = row_mysql_read_true_varchar(&len,
3891
3493
        (byte*) (record
3892
 
        + (ulint)get_field_offset(getTable(), field)),
 
3494
        + (ulint)get_field_offset(table, field)),
3893
3495
        lenlen);
3894
3496
 
3895
3497
      true_len = len;
3952
3554
 
3953
3555
      blob_data = row_mysql_read_blob_ref(&blob_len,
3954
3556
        (byte*) (record
3955
 
        + (ulint)get_field_offset(getTable(), field)),
 
3557
        + (ulint)get_field_offset(table, field)),
3956
3558
          (ulint) field->pack_length());
3957
3559
 
3958
3560
      true_len = blob_len;
3959
3561
 
3960
 
      ut_a(get_field_offset(getTable(), field)
 
3562
      ut_a(get_field_offset(table, field)
3961
3563
        == key_part->offset);
3962
3564
 
3963
3565
      /* For multi byte character sets we need to calculate
4004
3606
      ulint     key_len;
4005
3607
      const unsigned char*    src_start;
4006
3608
      enum_field_types  real_type;
4007
 
      const CHARSET_INFO* cs= field->charset();
4008
3609
 
4009
3610
      key_len = key_part->length;
4010
3611
 
4026
3627
      memcpy(buff, src_start, true_len);
4027
3628
      buff += true_len;
4028
3629
 
4029
 
      /* Pad the unused space with spaces. */
 
3630
      /* Pad the unused space with spaces. Note that no
 
3631
      padding is ever needed for UCS-2 because in MySQL,
 
3632
      all UCS2 characters are 2 bytes, as MySQL does not
 
3633
      support surrogate pairs, which are needed to represent
 
3634
      characters in the range U+10000 to U+10FFFF. */
4030
3635
 
4031
3636
      if (true_len < key_len) {
4032
 
        ulint   pad_len = key_len - true_len;
4033
 
        ut_a(!(pad_len % cs->mbminlen));
4034
 
 
4035
 
        cs->cset->fill(cs, buff, pad_len,
4036
 
                       0x20 /* space */);
 
3637
        ulint pad_len = key_len - true_len;
 
3638
        memset(buff, ' ', pad_len);
4037
3639
        buff += pad_len;
4038
3640
      }
4039
3641
    }
4141
3743
 
4142
3744
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4143
3745
  'fields'. */
4144
 
  for (i = 0; i < n_fields; i++)
 
3746
  for (i = 0; i < n_fields; i++) 
4145
3747
  {
4146
 
    const dict_col_t *col= &index->table->cols[i];
4147
3748
    templ = prebuilt->mysql_template + n_requested_fields;
4148
3749
    field = table->getField(i);
4149
3750
 
4189
3790
    n_requested_fields++;
4190
3791
 
4191
3792
    templ->col_no = i;
4192
 
    templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
4193
 
    ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4194
3793
 
4195
3794
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3795
      templ->rec_field_no = dict_col_get_clust_pos(
 
3796
        &index->table->cols[i], index);
4197
3797
    } else {
4198
3798
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
3799
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
3800
    }
 
3801
 
 
3802
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
3803
      prebuilt->need_to_access_clustered = TRUE;
4203
3804
    }
4204
3805
 
4205
3806
    if (field->null_ptr) {
4221
3822
      mysql_prefix_len = templ->mysql_col_offset
4222
3823
        + templ->mysql_col_len;
4223
3824
    }
4224
 
    templ->type = col->mtype;
 
3825
    templ->type = index->table->cols[i].mtype;
4225
3826
    templ->mysql_type = (ulint)field->type();
4226
3827
 
4227
3828
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4229
3830
        (((Field_varstring*)field)->pack_length_no_ptr());
4230
3831
    }
4231
3832
 
4232
 
    templ->charset = dtype_get_charset_coll(col->prtype);
4233
 
    templ->mbminlen = dict_col_get_mbminlen(col);
4234
 
    templ->mbmaxlen = dict_col_get_mbmaxlen(col);
4235
 
    templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 
3833
    templ->charset = dtype_get_charset_coll(
 
3834
      index->table->cols[i].prtype);
 
3835
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3836
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3837
    templ->is_unsigned = index->table->cols[i].prtype
 
3838
              & DATA_UNSIGNED;
4236
3839
    if (templ->type == DATA_BLOB) {
4237
3840
      prebuilt->templ_contains_blob = TRUE;
4238
3841
    }
4249
3852
    for (i = 0; i < n_requested_fields; i++) {
4250
3853
      templ = prebuilt->mysql_template + i;
4251
3854
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3855
      templ->rec_field_no = dict_col_get_clust_pos(
 
3856
        &index->table->cols[templ->col_no],
 
3857
        clust_index);
4253
3858
    }
4254
3859
  }
4255
3860
}
4256
3861
 
4257
3862
/********************************************************************//**
 
3863
Get the upper limit of the MySQL integral and floating-point type. */
 
3864
UNIV_INTERN
 
3865
uint64_t
 
3866
ha_innobase::innobase_get_int_col_max_value(
 
3867
/*========================================*/
 
3868
  const Field*  field)
 
3869
{
 
3870
  uint64_t  max_value = 0;
 
3871
 
 
3872
  switch(field->key_type()) {
 
3873
  /* TINY */
 
3874
  case HA_KEYTYPE_BINARY:
 
3875
    max_value = 0xFFULL;
 
3876
    break;
 
3877
  /* LONG */
 
3878
  case HA_KEYTYPE_ULONG_INT:
 
3879
    max_value = 0xFFFFFFFFULL;
 
3880
    break;
 
3881
  case HA_KEYTYPE_LONG_INT:
 
3882
    max_value = 0x7FFFFFFFULL;
 
3883
    break;
 
3884
  /* BIG */
 
3885
  case HA_KEYTYPE_ULONGLONG:
 
3886
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3887
    break;
 
3888
  case HA_KEYTYPE_LONGLONG:
 
3889
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3890
    break;
 
3891
  case HA_KEYTYPE_DOUBLE:
 
3892
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3893
    max_value = 0x20000000000000ULL;
 
3894
    break;
 
3895
  default:
 
3896
    ut_error;
 
3897
  }
 
3898
 
 
3899
  return(max_value);
 
3900
}
 
3901
 
 
3902
/********************************************************************//**
4258
3903
This special handling is really to overcome the limitations of MySQL's
4259
3904
binlogging. We need to eliminate the non-determinism that will arise in
4260
3905
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4323
3968
  trx_t*    trx = session_to_trx(user_session);
4324
3969
 
4325
3970
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
3971
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
3972
        "%p, but for the current thread it is at %p",
4328
3973
        (const void*) prebuilt->trx, (const void*) trx);
4329
3974
 
4337
3982
    ut_error;
4338
3983
  }
4339
3984
 
4340
 
  sql_command = user_session->getSqlCommand();
 
3985
  sql_command = session_sql_command(user_session);
4341
3986
 
4342
3987
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
3988
       || sql_command == SQLCOM_CREATE_INDEX
4405
4050
  num_write_row++;
4406
4051
 
4407
4052
  /* This is the case where the table has an auto-increment column */
4408
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4053
  if (table->next_number_field && record == table->getInsertRecord()) {
4409
4054
 
4410
4055
    /* Reset the error code before calling
4411
4056
    innobase_get_auto_increment(). */
4412
4057
    prebuilt->autoinc_error = DB_SUCCESS;
4413
4058
 
4414
4059
    if ((error = update_auto_increment())) {
 
4060
 
4415
4061
      /* We don't want to mask autoinc overflow errors. */
4416
 
 
4417
 
      /* Handle the case where the AUTOINC sub-system
4418
 
         failed during initialization. */
4419
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4420
 
        error_result = ER_AUTOINC_READ_FAILED;
4421
 
        /* Set the error message to report too. */
4422
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4423
 
        goto func_exit;
4424
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4062
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4425
4063
        error = (int) prebuilt->autoinc_error;
4426
4064
 
4427
4065
        goto report_error;
4441
4079
    /* Build the template used in converting quickly between
4442
4080
    the two database formats */
4443
4081
 
4444
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4082
    build_template(prebuilt, NULL, table,
 
4083
             ROW_MYSQL_WHOLE_ROW);
4445
4084
  }
4446
4085
 
4447
4086
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4448
4087
 
4449
4088
  error = row_insert_for_mysql((byte*) record, prebuilt);
4450
4089
 
4451
 
  user_session->setXaId(trx->id);
4452
 
 
4453
4090
  /* Handle duplicate key errors */
4454
4091
  if (auto_inc_used) {
4455
4092
    ulint   err;
4467
4104
    /* We need the upper limit of the col type to check for
4468
4105
    whether we update the table autoinc counter or not. */
4469
4106
    col_max_value = innobase_get_int_col_max_value(
4470
 
      getTable()->next_number_field); 
 
4107
      table->next_number_field);
 
4108
 
4471
4109
    /* Get the value that MySQL attempted to store in the table.*/
4472
 
    auto_inc = getTable()->next_number_field->val_int();
 
4110
    auto_inc = table->next_number_field->val_int();
4473
4111
 
4474
4112
    switch (error) {
4475
4113
    case DB_DUPLICATE_KEY:
4505
4143
      update the table upper limit. Note: last_value
4506
4144
      will be 0 if get_auto_increment() was not called.*/
4507
4145
 
4508
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4146
      if (auto_inc <= col_max_value
 
4147
          && auto_inc >= prebuilt->autoinc_last_value) {
4509
4148
set_max_autoinc:
4510
 
        /* This should filter out the negative
4511
 
           values set explicitly by the user. */
4512
 
        if (auto_inc <= col_max_value) {
4513
 
          ut_a(prebuilt->autoinc_increment > 0);
4514
 
 
4515
 
          uint64_t      need;
4516
 
          uint64_t      offset;
4517
 
 
4518
 
          offset = prebuilt->autoinc_offset;
4519
 
          need = prebuilt->autoinc_increment;
4520
 
 
4521
 
          auto_inc = innobase_next_autoinc(
4522
 
                                           auto_inc,
4523
 
                                           need, offset, col_max_value);
4524
 
 
4525
 
          err = innobase_set_max_autoinc(
4526
 
                                         auto_inc);
4527
 
 
4528
 
          if (err != DB_SUCCESS) {
4529
 
            error = err;
4530
 
          }
 
4149
        ut_a(prebuilt->autoinc_increment > 0);
 
4150
 
 
4151
        uint64_t  need;
 
4152
        uint64_t  offset;
 
4153
 
 
4154
        offset = prebuilt->autoinc_offset;
 
4155
        need = prebuilt->autoinc_increment;
 
4156
 
 
4157
        auto_inc = innobase_next_autoinc(
 
4158
          auto_inc, need, offset, col_max_value);
 
4159
 
 
4160
        err = innobase_set_max_autoinc(auto_inc);
 
4161
 
 
4162
        if (err != DB_SUCCESS) {
 
4163
          error = err;
4531
4164
        }
4532
4165
      }
4533
4166
      break;
4724
4357
  /* Build an update vector from the modified fields in the rows
4725
4358
  (uses upd_buff of the handle) */
4726
4359
 
4727
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4360
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4728
4361
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4729
4362
      prebuilt, user_session);
4730
4363
 
4733
4366
 
4734
4367
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4735
4368
 
4736
 
  if (getTable()->found_next_number_field)
 
4369
  if (table->found_next_number_field)
4737
4370
  {
4738
4371
    uint64_t  auto_inc;
4739
4372
    uint64_t  col_max_value;
4740
4373
 
4741
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4374
    auto_inc = table->found_next_number_field->val_int();
4742
4375
 
4743
4376
    /* We need the upper limit of the col type to check for
4744
4377
    whether we update the table autoinc counter or not. */
4745
4378
    col_max_value = innobase_get_int_col_max_value(
4746
 
      getTable()->found_next_number_field);
 
4379
      table->found_next_number_field);
4747
4380
 
4748
4381
    uint64_t current_autoinc;
4749
4382
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4771
4404
 
4772
4405
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4773
4406
 
4774
 
  user_session->setXaId(trx->id);
4775
 
 
4776
4407
  /* We need to do some special AUTOINC handling for the following case:
4777
4408
 
4778
4409
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4782
4413
  value used in the INSERT statement.*/
4783
4414
 
4784
4415
  if (error == DB_SUCCESS
4785
 
      && getTable()->next_number_field
4786
 
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4416
      && table->next_number_field
 
4417
      && new_row == table->getInsertRecord()
 
4418
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4419
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4420
    == TRX_DUP_IGNORE)  {
4790
4421
 
4791
4422
    uint64_t  auto_inc;
4792
4423
    uint64_t  col_max_value;
4793
4424
 
4794
 
    auto_inc = getTable()->next_number_field->val_int();
 
4425
    auto_inc = table->next_number_field->val_int();
4795
4426
 
4796
4427
    /* We need the upper limit of the col type to check for
4797
4428
    whether we update the table autoinc counter or not. */
4798
4429
    col_max_value = innobase_get_int_col_max_value(
4799
 
      getTable()->next_number_field);
 
4430
      table->next_number_field);
4800
4431
 
4801
4432
    if (auto_inc <= col_max_value && auto_inc != 0) {
4802
4433
 
4863
4494
 
4864
4495
  error = row_update_for_mysql((byte*) record, prebuilt);
4865
4496
 
4866
 
  user_session->setXaId(trx->id);
4867
 
 
4868
4497
  innodb_srv_conc_exit_innodb(trx);
4869
4498
 
4870
4499
  error = convert_error_code_to_mysql(
4898
4527
  case ROW_READ_WITH_LOCKS:
4899
4528
    if (!srv_locks_unsafe_for_binlog
4900
4529
        && prebuilt->trx->isolation_level
4901
 
        > TRX_ISO_READ_COMMITTED) {
 
4530
        != TRX_ISO_READ_COMMITTED) {
4902
4531
      break;
4903
4532
    }
4904
4533
    /* fall through */
4928
4557
ha_innobase::try_semi_consistent_read(bool yes)
4929
4558
/*===========================================*/
4930
4559
{
4931
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4560
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
4932
4561
 
4933
4562
  /* Row read type is set to semi consistent read if this was
4934
4563
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
4937
4566
 
4938
4567
  if (yes
4939
4568
      && (srv_locks_unsafe_for_binlog
4940
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4569
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
4941
4570
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4942
4571
  } else {
4943
4572
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5118
4747
 
5119
4748
  index = prebuilt->index;
5120
4749
 
5121
 
  if (UNIV_UNLIKELY(index == NULL)) {
5122
 
    prebuilt->index_usable = FALSE;
5123
 
    return(HA_ERR_CRASHED);
5124
 
  }
5125
 
 
5126
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5127
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5128
 
  }
5129
 
 
5130
4750
  /* Note that if the index for which the search template is built is not
5131
4751
  necessarily prebuilt->index, but can also be the clustered index */
5132
4752
 
5133
4753
  if (prebuilt->sql_stat_start) {
5134
 
    build_template(prebuilt, user_session, getTable(),
 
4754
    build_template(prebuilt, user_session, table,
5135
4755
             ROW_MYSQL_REC_FIELDS);
5136
4756
  }
5137
4757
 
5186
4806
  switch (ret) {
5187
4807
  case DB_SUCCESS:
5188
4808
    error = 0;
5189
 
    getTable()->status = 0;
 
4809
    table->status = 0;
5190
4810
    break;
5191
4811
  case DB_RECORD_NOT_FOUND:
5192
4812
    error = HA_ERR_KEY_NOT_FOUND;
5193
 
    getTable()->status = STATUS_NOT_FOUND;
 
4813
    table->status = STATUS_NOT_FOUND;
5194
4814
    break;
5195
4815
  case DB_END_OF_INDEX:
5196
4816
    error = HA_ERR_KEY_NOT_FOUND;
5197
 
    getTable()->status = STATUS_NOT_FOUND;
 
4817
    table->status = STATUS_NOT_FOUND;
5198
4818
    break;
5199
4819
  default:
5200
4820
    error = convert_error_code_to_mysql((int) ret,
5201
4821
                prebuilt->table->flags,
5202
4822
                user_session);
5203
 
    getTable()->status = STATUS_NOT_FOUND;
 
4823
    table->status = STATUS_NOT_FOUND;
5204
4824
    break;
5205
4825
  }
5206
4826
 
5239
4859
 
5240
4860
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5241
4861
 
5242
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4862
  ut_ad(user_session == table->in_use);
 
4863
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4864
 
 
4865
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5243
4866
  {
5244
 
    KeyInfo *key = getTable()->key_info + keynr;
5245
 
    index = innobase_index_lookup(share, keynr);
5246
 
 
5247
 
    if (index) {
5248
 
      ut_a(ut_strcmp(index->name, key->name) == 0);
5249
 
    } else {
5250
 
      /* Can't find index with keynr in the translation
5251
 
         table. Only print message if the index translation
5252
 
         table exists */
5253
 
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
5255
 
                      "InnoDB could not find "
5256
 
                      "index %s key no %u for "
5257
 
                      "table %s through its "
5258
 
                      "index translation table",
5259
 
                      key ? key->name : "NULL",
5260
 
                      keynr,
5261
 
                      prebuilt->table->name);
5262
 
      }
5263
 
 
5264
 
      index = dict_table_get_index_on_name(prebuilt->table,
5265
 
                                           key->name);
5266
 
    }
 
4867
    index = dict_table_get_index_on_name(prebuilt->table,
 
4868
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5267
4869
  } else {
5268
4870
    index = dict_table_get_first_index(prebuilt->table);
5269
4871
  }
5270
4872
 
5271
4873
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
4874
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
4875
      "Innodb could not find key n:o %u with name %s "
5274
4876
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
4877
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
4878
      prebuilt->table->name);
5277
4879
  }
5278
4880
 
5298
4900
  prebuilt->index = innobase_get_index(keynr);
5299
4901
 
5300
4902
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
4903
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
4904
          keynr);
5303
 
    prebuilt->index_usable = FALSE;
5304
4905
    return(1);
5305
4906
  }
5306
4907
 
5308
4909
                 prebuilt->index);
5309
4910
 
5310
4911
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5311
 
    push_warning_printf(user_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5312
 
                        HA_ERR_TABLE_DEF_CHANGED,
5313
 
                        "InnoDB: insufficient history for index %u",
5314
 
                        keynr);
 
4912
    errmsg_printf(ERRMSG_LVL_WARN,
 
4913
         "InnoDB: insufficient history for index %u",
 
4914
          keynr);
5315
4915
    /* The caller seems to ignore this.  Thus, we must check
5316
4916
    this again in row_search_for_mysql(). */
5317
4917
    return(2);
5330
4930
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5331
4931
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5332
4932
 
5333
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
4933
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5334
4934
 
5335
4935
  return(0);
5336
4936
}
5390
4990
  switch (ret) {
5391
4991
  case DB_SUCCESS:
5392
4992
    error = 0;
5393
 
    getTable()->status = 0;
 
4993
    table->status = 0;
5394
4994
    break;
5395
4995
  case DB_RECORD_NOT_FOUND:
5396
4996
    error = HA_ERR_END_OF_FILE;
5397
 
    getTable()->status = STATUS_NOT_FOUND;
 
4997
    table->status = STATUS_NOT_FOUND;
5398
4998
    break;
5399
4999
  case DB_END_OF_INDEX:
5400
5000
    error = HA_ERR_END_OF_FILE;
5401
 
    getTable()->status = STATUS_NOT_FOUND;
 
5001
    table->status = STATUS_NOT_FOUND;
5402
5002
    break;
5403
5003
  default:
5404
5004
    error = convert_error_code_to_mysql(
5405
5005
      (int) ret, prebuilt->table->flags, user_session);
5406
 
    getTable()->status = STATUS_NOT_FOUND;
 
5006
    table->status = STATUS_NOT_FOUND;
5407
5007
    break;
5408
5008
  }
5409
5009
 
5598
5198
 
5599
5199
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5600
5200
 
5601
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5201
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5602
5202
 
5603
5203
  if (prebuilt->clust_index_was_generated) {
5604
5204
    /* No primary key was defined for the table and we
5644
5244
{
5645
5245
  uint    len;
5646
5246
 
5647
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5247
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5648
5248
 
5649
5249
  if (prebuilt->clust_index_was_generated) {
5650
5250
    /* No primary key was defined for the table and we
5664
5264
  table. */
5665
5265
 
5666
5266
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5267
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5268
        (ulong) len, (ulong) ref_length);
5669
5269
  }
5670
5270
}
5720
5320
 
5721
5321
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5722
5322
                  field);
5723
 
 
5724
 
    if (!col_type) {
5725
 
      push_warning_printf(
5726
 
                          trx->mysql_thd,
5727
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
 
                          ER_CANT_CREATE_TABLE,
5729
 
                          "Error creating table '%s' with "
5730
 
                          "column '%s'. Please check its "
5731
 
                          "column type and try to re-create "
5732
 
                          "the table with an appropriate "
5733
 
                          "column type.",
5734
 
                          table->name, (char*) field->field_name);
5735
 
      goto err_col;
5736
 
    }
5737
 
 
5738
5323
    if (field->null_ptr) {
5739
5324
      nulls_allowed = 0;
5740
5325
    } else {
5757
5342
        /* in data0type.h we assume that the
5758
5343
        number fits in one byte in prtype */
5759
5344
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5345
          (Session*) trx->mysql_thd,
5761
5346
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5347
          ER_CANT_CREATE_TABLE,
5763
5348
          "In InnoDB, charset-collation codes"
5787
5372
      }
5788
5373
    }
5789
5374
 
5790
 
    /* First check whether the column to be added has a
5791
 
       system reserved name. */
5792
 
    if (dict_col_name_is_reserved(field->field_name)){
5793
 
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5794
 
 
5795
 
  err_col:
5796
 
      dict_mem_table_free(table);
5797
 
      trx_commit_for_mysql(trx);
5798
 
 
5799
 
      error = DB_ERROR;
5800
 
      goto error_ret;
5801
 
    }
5802
 
 
5803
5375
    dict_mem_table_add_col(table, table->heap,
5804
5376
      (char*) field->field_name,
5805
5377
      col_type,
5813
5385
 
5814
5386
  error = row_create_table_for_mysql(table, trx);
5815
5387
 
5816
 
        if (error == DB_DUPLICATE_KEY) {
5817
 
                char buf[100];
5818
 
                char* buf_end = innobase_convert_identifier(
5819
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5820
 
                        trx->mysql_thd, TRUE);
5821
 
 
5822
 
                *buf_end = '\0';
5823
 
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5824
 
        }
5825
 
 
5826
 
error_ret:
5827
5388
  error = convert_error_code_to_mysql(error, flags, NULL);
5828
5389
 
5829
5390
  return(error);
5860
5421
 
5861
5422
  n_fields = key->key_parts;
5862
5423
 
5863
 
  /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
5864
 
  ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
5865
 
 
5866
5424
  ind_type = 0;
5867
5425
 
5868
5426
  if (key_num == form->getShare()->getPrimaryKey()) {
5923
5481
        || col_type == DATA_FLOAT
5924
5482
        || col_type == DATA_DOUBLE
5925
5483
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
5484
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
5485
          "MySQL is trying to create a column "
5928
5486
          "prefix index field, on an "
5929
5487
          "inappropriate data type. Table "
5972
5530
  /* We pass 0 as the space id, and determine at a lower level the space
5973
5531
  id where to store the table */
5974
5532
 
5975
 
  index = dict_mem_index_create(table_name,
5976
 
                                innobase_index_reserve_name,
5977
 
                                0, DICT_CLUSTERED, 0);
 
5533
  index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
 
5534
              0, DICT_CLUSTERED, 0);
5978
5535
 
5979
5536
  error = row_create_index_for_mysql(index, trx, NULL);
5980
5537
 
6023
5580
/*================*/
6024
5581
  Session         &session, /*!< in: Session */
6025
5582
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
5583
        const TableIdentifier &identifier,
6027
5584
        message::Table& create_proto)
6028
5585
{
6029
5586
  int   error;
6032
5589
  trx_t*    trx;
6033
5590
  int   primary_key_no;
6034
5591
  uint    i;
 
5592
  char    name2[FN_REFLEN];
 
5593
  char    norm_name[FN_REFLEN];
6035
5594
  ib_int64_t  auto_inc_value;
6036
5595
  ulint   iflags;
6037
5596
  /* Cache the value of innodb_file_format, in case it is
6038
5597
    modified by another thread while the table is being created. */
6039
5598
  const ulint file_format = srv_file_format;
6040
5599
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6041
 
  const char* stmt;
6042
 
  size_t stmt_len;
6043
 
 
6044
 
  std::string search_string(identifier.getSchemaName());
6045
 
  boost::algorithm::to_lower(search_string);
6046
 
 
6047
 
  if (search_string.compare("data_dictionary") == 0)
6048
 
  {
6049
 
    return HA_WRONG_CREATE_OPTION;
6050
 
  }
 
5600
 
 
5601
  const char *table_name= identifier.getPath().c_str();
6051
5602
 
6052
5603
  if (form.getShare()->sizeFields() > 1000) {
6053
5604
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
5621
 
6071
5622
  srv_lower_case_table_names = TRUE;
6072
5623
 
 
5624
  strcpy(name2, table_name);
 
5625
 
 
5626
  normalize_table_name(norm_name, name2);
 
5627
 
6073
5628
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
5629
    or lock waits can happen in it during a table create operation.
6075
5630
    Drop table etc. do this latching in row0mysql.c. */
6134
5689
# error "DICT_TF_ZSSIZE_MAX < 1"
6135
5690
#endif
6136
5691
 
6137
 
    if (strict_mode)
 
5692
    if (SessionVAR(&session, strict_mode))
6138
5693
    {
6139
5694
      if (! srv_file_per_table)
6140
5695
      {
6153
5708
                            "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6154
5709
      }
6155
5710
    }
 
5711
 
 
5712
    error= create_table_def(trx, &form, norm_name,
 
5713
                            lex_identified_temp_table ? name2 : NULL,
 
5714
                            iflags);
 
5715
  }
 
5716
 
 
5717
  if (error) {
 
5718
    goto cleanup;
6156
5719
  }
6157
5720
 
6158
5721
  /* Look for a primary key */
6161
5724
                   (int) form.getShare()->getPrimaryKey() :
6162
5725
                   -1);
6163
5726
 
6164
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5727
  /* Our function row_get_mysql_key_number_for_index assumes
6165
5728
    the primary key is always number 0, if it exists */
6166
5729
 
6167
5730
  assert(primary_key_no == -1 || primary_key_no == 0);
6168
5731
 
6169
 
  /* Check for name conflicts (with reserved name) for
6170
 
     any user indices to be created. */
6171
 
  if (innobase_index_name_is_reserved(trx, form.key_info,
6172
 
                                      form.getShare()->keys)) {
6173
 
    error = -1;
6174
 
    goto cleanup;
6175
 
  }
6176
 
 
6177
 
  if (lex_identified_temp_table)
6178
 
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
 
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6182
 
                          iflags);
6183
 
 
6184
 
  session.setXaId(trx->id);
6185
 
 
6186
 
  if (error) {
6187
 
    goto cleanup;
6188
 
  }
6189
 
 
6190
5732
  /* Create the keys */
6191
5733
 
6192
5734
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6194
5736
      order the rows by their row id which is internally generated
6195
5737
      by InnoDB */
6196
5738
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
5739
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
5740
    if (error) {
6199
5741
      goto cleanup;
6200
5742
    }
6202
5744
 
6203
5745
  if (primary_key_no != -1) {
6204
5746
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5747
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
5748
                              (uint) primary_key_no))) {
6207
5749
      goto cleanup;
6208
5750
    }
6211
5753
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
5754
    if (i != (uint) primary_key_no) {
6213
5755
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5756
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
5757
                                i))) {
6216
5758
        goto cleanup;
6217
5759
      }
6218
5760
    }
6219
5761
  }
6220
5762
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
6222
 
 
6223
 
  if (stmt) {
 
5763
  if (trx->mysql_query_str) {
6224
5764
    string generated_create_table;
6225
 
    const char *query= stmt;
 
5765
    const char *query= trx->mysql_query_str;
6226
5766
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
5767
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
5768
    {
6229
5769
      message::transformTableDefinitionToSql(create_proto,
6230
5770
                                             generated_create_table,
6233
5773
    }
6234
5774
 
6235
5775
    error = row_table_add_foreign_constraints(trx,
6236
 
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
5776
                                              query,
 
5777
                                              norm_name,
6238
5778
                                              lex_identified_temp_table);
6239
 
    switch (error) {
6240
 
 
6241
 
    case DB_PARENT_NO_INDEX:
6242
 
      push_warning_printf(
6243
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6244
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6245
 
                          "Create table '%s' with foreign key constraint"
6246
 
                          " failed. There is no index in the referenced"
6247
 
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6249
 
      break;
6250
 
 
6251
 
    case DB_CHILD_NO_INDEX:
6252
 
      push_warning_printf(
6253
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6254
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6255
 
                          "Create table '%s' with foreign key constraint"
6256
 
                          " failed. There is no index in the referencing"
6257
 
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6259
 
      break;
6260
 
    }
6261
5779
 
6262
5780
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
5781
 
6276
5794
 
6277
5795
  log_buffer_flush_to_disk();
6278
5796
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
5797
  innobase_table = dict_table_get(norm_name, FALSE);
6280
5798
 
6281
5799
  assert(innobase_table != 0);
6282
5800
 
6284
5802
    /* We update the highest file format in the system table
6285
5803
      space, if this table has higher file format setting. */
6286
5804
 
6287
 
    char changed_file_format_max[100];
6288
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6289
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
6290
 
      dict_table_get_format(innobase_table));
6291
 
    innobase_file_format_max= changed_file_format_max;
 
5805
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5806
                                    dict_table_get_format(innobase_table));
6292
5807
  }
6293
5808
 
6294
5809
  /* Note: We can't call update_session() as prebuilt will not be
6295
5810
    setup at this stage and so we use session. */
6296
5811
 
6297
5812
  /* We need to copy the AUTOINC value from the old table if
6298
 
    this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
6299
 
    does a table copy too. */
 
5813
    this is an ALTER TABLE. */
6300
5814
 
6301
5815
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
5816
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
6304
5817
      && create_proto.options().auto_increment_value() != 0) {
6305
5818
 
6306
 
    /* Query was one of :
6307
 
       CREATE TABLE ...AUTO_INCREMENT = x; or
6308
 
       ALTER TABLE...AUTO_INCREMENT = x;   or
6309
 
       CREATE INDEX x on t(...);
6310
 
       Find out a table definition from the dictionary and get
6311
 
       the current value of the auto increment field. Set a new
6312
 
       value to the auto increment field if the value is greater
6313
 
       than the maximum value in the column. */
 
5819
    /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 
5820
      CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
 
5821
      definition from the dictionary and get the current value
 
5822
      of the auto increment field. Set a new value to the
 
5823
      auto increment field if the value is greater than the
 
5824
      maximum value in the column. */
6314
5825
 
6315
5826
    auto_inc_value = create_proto.options().auto_increment_value();
6316
5827
 
6328
5839
 
6329
5840
  if (lex_identified_temp_table)
6330
5841
  {
6331
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5842
    session.storeTableMessage(identifier, create_proto);
6332
5843
  }
6333
5844
  else
6334
5845
  {
6362
5873
 
6363
5874
  ut_a(prebuilt->trx);
6364
5875
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6365
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5876
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6366
5877
 
6367
5878
  dict_table = prebuilt->table;
6368
5879
  trx = prebuilt->trx;
6391
5902
  /* Get the transaction associated with the current session, or create one
6392
5903
  if not yet created, and update prebuilt->trx */
6393
5904
 
6394
 
  update_session(getTable()->in_use);
 
5905
  update_session(table->in_use);
6395
5906
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
5907
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
5908
  fallback:
6398
5909
    /* We only handle TRUNCATE TABLE t as a special case.
6399
5910
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
5938
InnobaseEngine::doDropTable(
6428
5939
/*======================*/
6429
5940
        Session &session,
6430
 
        const identifier::Table &identifier)
 
5941
        const TableIdentifier &identifier)
6431
5942
{
6432
5943
  int error;
6433
5944
  trx_t*  parent_trx;
6434
5945
  trx_t*  trx;
 
5946
  char  norm_name[1000];
6435
5947
 
6436
5948
  ut_a(identifier.getPath().length() < 1000);
6437
5949
 
6438
 
  std::string search_string(identifier.getSchemaName());
6439
 
  boost::algorithm::to_lower(search_string);
6440
 
 
6441
 
  if (search_string.compare("data_dictionary") == 0)
6442
 
  {
6443
 
    return HA_ERR_TABLE_READONLY;
6444
 
  }
 
5950
  /* Strangely, MySQL passes the table name without the '.frm'
 
5951
    extension, in contrast to ::create */
 
5952
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
5953
 
6446
5954
  /* Get the transaction associated with the current session, or create one
6447
5955
    if not yet created */
6459
5967
 
6460
5968
  /* Drop the table in InnoDB */
6461
5969
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
5970
  error = row_drop_table_for_mysql(norm_name, trx,
 
5971
                                   session_sql_command(&session)
6464
5972
                                   == SQLCOM_DROP_DB);
6465
5973
 
6466
 
  session.setXaId(trx->id);
6467
 
 
6468
5974
  /* Flush the log to reduce probability that the .frm files and
6469
5975
    the InnoDB data dictionary get out-of-sync if the user runs
6470
5976
    with innodb_flush_log_at_trx_commit = 0 */
6487
5993
  {
6488
5994
    if (identifier.getType() == message::Table::TEMPORARY)
6489
5995
    {
6490
 
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
5996
      session.removeTableMessage(identifier);
 
5997
      ulint sql_command = session_sql_command(&session);
6492
5998
 
6493
5999
      // If this was the final removal to an alter table then we will need
6494
6000
      // to remove the .dfe that was left behind.
6521
6027
bool
6522
6028
InnobaseEngine::doDropSchema(
6523
6029
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6030
                             const SchemaIdentifier &identifier)
6525
6031
    /*!< in: database path; inside InnoDB the name
6526
6032
      of the last directory in the path is used as
6527
6033
      the database name: for example, in 'mysql/data/test'
6571
6077
 
6572
6078
void InnobaseEngine::dropTemporarySchema()
6573
6079
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6080
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6081
  trx_t*  trx= NULL;
6576
6082
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6083
 
6580
6086
  trx = trx_allocate_for_mysql();
6581
6087
 
6582
6088
  trx->mysql_thd = NULL;
 
6089
  trx->mysql_query_str = NULL;
6583
6090
 
6584
6091
  trx->check_foreigns = false;
6585
6092
  trx->check_unique_secondary = false;
6608
6115
innobase_rename_table(
6609
6116
/*==================*/
6610
6117
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6118
  const char* from, /*!< in: old name of the table */
 
6119
  const char* to, /*!< in: new name of the table */
6613
6120
  ibool   lock_and_commit)
6614
6121
        /*!< in: TRUE=lock data dictionary and commit */
6615
6122
{
6616
6123
  int error;
 
6124
  char norm_to[FN_REFLEN];
 
6125
  char norm_from[FN_REFLEN];
6617
6126
 
6618
6127
  srv_lower_case_table_names = TRUE;
6619
6128
 
 
6129
  normalize_table_name(norm_to, to);
 
6130
  normalize_table_name(norm_from, from);
 
6131
 
6620
6132
  /* Serialize data dictionary operations with dictionary mutex:
6621
6133
  no deadlocks can occur then in these operations */
6622
6134
 
6624
6136
    row_mysql_lock_data_dictionary(trx);
6625
6137
  }
6626
6138
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6139
  error = row_rename_table_for_mysql(
 
6140
    norm_from, norm_to, trx, lock_and_commit);
6628
6141
 
6629
6142
  if (error != DB_SUCCESS) {
6630
6143
    FILE* ef = dict_foreign_err_file;
6631
6144
 
6632
6145
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6146
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6147
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6148
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6149
    fputs(" failed!\n", ef);
6637
6150
  }
6638
6151
 
6651
6164
/*********************************************************************//**
6652
6165
Renames an InnoDB table.
6653
6166
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6167
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6168
{
6656
6169
  // A temp table alter table/rename is a shallow rename and only the
6657
6170
  // definition needs to be updated.
6658
6171
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6659
6172
  {
6660
 
    session.getMessageCache().renameTableMessage(from, to);
 
6173
    session.renameTableMessage(from, to);
6661
6174
    return 0;
6662
6175
  }
6663
6176
 
6677
6190
 
6678
6191
  trx = innobase_trx_allocate(&session);
6679
6192
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
6681
 
 
6682
 
  session.setXaId(trx->id);
 
6193
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6683
6194
 
6684
6195
  /* Tell the InnoDB server that there might be work for
6685
6196
    utility threads: */
6689
6200
  innobase_commit_low(trx);
6690
6201
  trx_free_for_mysql(trx);
6691
6202
 
6692
 
  /* Add a special case to handle the Duplicated Key error
6693
 
     and return DB_ERROR instead.
6694
 
     This is to avoid a possible SIGSEGV error from mysql error
6695
 
     handling code. Currently, mysql handles the Duplicated Key
6696
 
     error by re-entering the storage layer and getting dup key
6697
 
     info by calling get_dup_key(). This operation requires a valid
6698
 
     table handle ('row_prebuilt_t' structure) which could no
6699
 
     longer be available in the error handling stage. The suggested
6700
 
     solution is to report a 'table exists' error message (since
6701
 
     the dup key error here is due to an existing table whose name
6702
 
     is the one we are trying to rename to) and return the generic
6703
 
     error code. */
6704
 
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
6706
 
    error = DB_ERROR;
6707
 
  }
6708
 
 
6709
6203
  error = convert_error_code_to_mysql(error, 0, NULL);
6710
6204
 
6711
6205
  if (not error)
6733
6227
  KeyInfo*    key;
6734
6228
  dict_index_t* index;
6735
6229
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
6737
 
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
6739
 
          + getTable()->getShare()->max_key_length + 100;
 
6230
              table->getShare()->stored_rec_length
 
6231
          + table->getShare()->max_key_length + 100);
 
6232
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6233
          + table->getShare()->max_key_length + 100;
6740
6234
  dtuple_t* range_start;
6741
6235
  dtuple_t* range_end;
6742
6236
  ib_int64_t  n_rows;
6744
6238
  ulint   mode2;
6745
6239
  mem_heap_t* heap;
6746
6240
 
6747
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6241
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6748
6242
 
6749
6243
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6750
6244
 
6755
6249
 
6756
6250
  active_index = keynr;
6757
6251
 
6758
 
  key = &getTable()->key_info[active_index];
6759
 
 
6760
 
  index = innobase_get_index(keynr);
6761
 
 
6762
 
  /* There exists possibility of not being able to find requested
6763
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6764
 
     Necessary message should have been printed in innobase_get_index() */
6765
 
  if (UNIV_UNLIKELY(!index)) {
6766
 
    n_rows = HA_POS_ERROR;
6767
 
    goto func_exit;
6768
 
  }
6769
 
 
6770
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6771
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6772
 
    goto func_exit;
6773
 
  }
 
6252
  key = &table->key_info[active_index];
 
6253
 
 
6254
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6255
 
 
6256
  /* MySQL knows about this index and so we must be able to find it.*/
 
6257
  ut_a(index);
6774
6258
 
6775
6259
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6776
6260
            + sizeof(dtuple_t)));
6815
6299
 
6816
6300
  mem_heap_free(heap);
6817
6301
 
6818
 
func_exit:
6819
6302
  free(key_val_buff2);
6820
6303
 
6821
6304
  prebuilt->trx->op_info = (char*)"";
6845
6328
  dict_index_t* index;
6846
6329
  uint64_t  estimate;
6847
6330
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6331
 
6850
6332
  /* We do not know if MySQL can call this function before calling
6851
6333
  external_lock(). To be safe, update the session of the current table
6852
6334
  handle. */
6853
6335
 
6854
 
  update_session(getTable()->in_use);
 
6336
  update_session(table->in_use);
6855
6337
 
6856
6338
  prebuilt->trx->op_info = (char*)
6857
6339
         "calculating upper bound for table rows";
6863
6345
 
6864
6346
  index = dict_table_get_first_index(prebuilt->table);
6865
6347
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6348
  ut_a(index->stat_n_leaf_pages > 0);
6869
6349
 
6870
6350
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6351
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6352
 
6873
6353
 
6874
6354
  /* Calculate a minimum length for a clustered index record and from
6917
6397
  ha_rows total_rows;
6918
6398
  double  time_for_scan;
6919
6399
 
6920
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6400
  if (index != table->getShare()->getPrimaryKey()) {
6921
6401
    /* Not clustered */
6922
6402
    return(Cursor::read_time(index, ranges, rows));
6923
6403
  }
6941
6421
}
6942
6422
 
6943
6423
/*********************************************************************//**
6944
 
Calculates the key number used inside MySQL for an Innobase index. We will
6945
 
first check the "index translation table" for a match of the index to get
6946
 
the index number. If there does not exist an "index translation table",
6947
 
or not able to find the index in the translation table, then we will fall back
6948
 
to the traditional way of looping through dict_index_t list to find a
6949
 
match. In this case, we have to take into account if we generated a
6950
 
default clustered index for the table
6951
 
@return the key number used inside MySQL */
6952
 
static
6953
 
unsigned int
6954
 
innobase_get_mysql_key_number_for_index(
6955
 
/*====================================*/
6956
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
6957
 
                                        translation table. */
6958
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
6959
 
                                        dictionary */
6960
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
6961
 
                                        dictionary */
6962
 
        const dict_index_t*     index)  /*!< in: index */
6963
 
{
6964
 
        const dict_index_t*     ind;
6965
 
        unsigned int            i;
6966
 
 
6967
 
        ut_ad(index);
6968
 
        ut_ad(ib_table);
6969
 
        ut_ad(table);
6970
 
        ut_ad(share);
6971
 
 
6972
 
        /* If index does not belong to the table of share structure. Search
6973
 
        index->table instead */
6974
 
        if (index->table != ib_table) {
6975
 
                i = 0;
6976
 
                ind = dict_table_get_first_index(index->table);
6977
 
 
6978
 
                while (index != ind) {
6979
 
                        ind = dict_table_get_next_index(ind);
6980
 
                        i++;
6981
 
                }
6982
 
 
6983
 
                if (row_table_got_default_clust_index(index->table)) {
6984
 
                        ut_a(i > 0);
6985
 
                        i--;
6986
 
                }
6987
 
 
6988
 
                return(i);
6989
 
        }
6990
 
 
6991
 
        /* If index does not belong to the table of share structure. Search
6992
 
        index->table instead */
6993
 
        if (index->table != ib_table) {
6994
 
                i = 0;
6995
 
                ind = dict_table_get_first_index(index->table);
6996
 
 
6997
 
                while (index != ind) {
6998
 
                        ind = dict_table_get_next_index(ind);
6999
 
                        i++;
7000
 
                }
7001
 
 
7002
 
                if (row_table_got_default_clust_index(index->table)) {
7003
 
                        ut_a(i > 0);
7004
 
                        i--;
7005
 
                }
7006
 
 
7007
 
                return(i);
7008
 
        }
7009
 
 
7010
 
        /* If index translation table exists, we will first check
7011
 
        the index through index translation table for a match. */
7012
 
        if (share->idx_trans_tbl.index_mapping) {
7013
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7014
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7015
 
                                return(i);
7016
 
                        }
7017
 
                }
7018
 
 
7019
 
                /* Print an error message if we cannot find the index
7020
 
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
7022
 
                              "Cannot find index %s in InnoDB index "
7023
 
                                "translation table.", index->name);
7024
 
        }
7025
 
 
7026
 
        /* If we do not have an "index translation table", or not able
7027
 
        to find the index in the translation table, we'll directly find
7028
 
        matching index in the dict_index_t list */
7029
 
        for (i = 0; i < table->getShare()->keys; i++) {
7030
 
                ind = dict_table_get_index_on_name(
7031
 
                        ib_table, table->key_info[i].name);
7032
 
 
7033
 
                if (index == ind) {
7034
 
                        return(i);
7035
 
                }
7036
 
        }
7037
 
 
7038
 
                errmsg_printf(error::ERROR,
7039
 
                              "Cannot find matching index number for index %s "
7040
 
                              "in InnoDB index list.", index->name);
7041
 
 
7042
 
        return(0);
7043
 
}
7044
 
/*********************************************************************//**
7045
6424
Returns statistics information of the table to the MySQL interpreter,
7046
6425
in various fields of the handle object. */
7047
6426
UNIV_INTERN
7054
6433
  dict_index_t* index;
7055
6434
  ha_rows   rec_per_key;
7056
6435
  ib_int64_t  n_rows;
 
6436
  ulong   j;
 
6437
  ulong   i;
 
6438
  char    path[FN_REFLEN];
7057
6439
  os_file_stat_t  stat_info;
7058
6440
 
7059
6441
  /* If we are forcing recovery at a high level, we will suppress
7060
6442
  statistics calculation on tables, because that may crash the
7061
6443
  server if an index is badly corrupted. */
7062
6444
 
 
6445
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6446
 
 
6447
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6448
    because we want MySQL to process this query and not
 
6449
    stop, like it would do if it received the error code
 
6450
    HA_ERR_CRASHED. */
 
6451
 
 
6452
    return(0);
 
6453
  }
 
6454
 
7063
6455
  /* We do not know if MySQL can call this function before calling
7064
6456
  external_lock(). To be safe, update the session of the current table
7065
6457
  handle. */
7066
6458
 
7067
 
  update_session(getTable()->in_use);
 
6459
  update_session(table->in_use);
7068
6460
 
7069
6461
  /* In case MySQL calls this in the middle of a SELECT query, release
7070
6462
  possible adaptive hash latch to avoid deadlocks of threads */
7076
6468
  ib_table = prebuilt->table;
7077
6469
 
7078
6470
  if (flag & HA_STATUS_TIME) {
7079
 
    /* In Analyze we call with this flag: update
7080
 
       then statistics so that they are up-to-date */
7081
 
 
7082
 
    prebuilt->trx->op_info = "updating table statistics";
7083
 
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
7088
 
 
7089
 
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
 
 
7091
 
    fs::path get_status_path(getDataHomeCatalog());
7092
 
    get_status_path /= ib_table->name;
7093
 
    fs::change_extension(get_status_path, "dfe");
 
6471
    if (innobase_stats_on_metadata) {
 
6472
      /* In sql_show we call with this flag: update
 
6473
      then statistics so that they are up-to-date */
 
6474
 
 
6475
      prebuilt->trx->op_info = "updating table statistics";
 
6476
 
 
6477
      dict_update_statistics(ib_table);
 
6478
 
 
6479
      prebuilt->trx->op_info = "returning various info to MySQL";
 
6480
    }
 
6481
 
 
6482
    snprintf(path, sizeof(path), "%s/%s%s",
 
6483
             getDataHomeCatalog().c_str(), ib_table->name, ".dfe");
 
6484
 
 
6485
    internal::unpack_filename(path,path);
7094
6486
 
7095
6487
    /* Note that we do not know the access time of the table,
7096
6488
    nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
7097
6489
 
7098
 
    if (os_file_get_status(get_status_path.file_string().c_str(), &stat_info)) {
 
6490
    if (os_file_get_status(path,&stat_info)) {
7099
6491
      stats.create_time = (ulong) stat_info.ctime;
7100
6492
    }
7101
6493
  }
7102
6494
 
7103
6495
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
6496
    n_rows = ib_table->stat_n_rows;
7108
6497
 
7109
6498
    /* Because we do not protect stat_n_rows by any mutex in a
7131
6520
    n_rows can not be 0 unless the table is empty, set to 1
7132
6521
    instead. The original problem of bug#29507 is actually
7133
6522
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
6523
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
6524
 
7136
6525
      n_rows = 1;
7137
6526
 
7153
6542
        ib_table->stat_sum_of_other_index_sizes)
7154
6543
          * UNIV_PAGE_SIZE;
7155
6544
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
6545
    /* Since fsp_get_available_space_in_free_extents() is
7159
6546
    acquiring latches inside InnoDB, we do not call it if we
7160
6547
    are asked by MySQL to avoid locking. Another reason to
7161
6548
    avoid the call is that it uses quite a lot of CPU.
7162
 
    See Bug#38185. */
7163
 
    if (flag & HA_STATUS_NO_LOCK) {
7164
 
      /* We do not update delete_length if no
7165
 
         locking is requested so the "old" value can
7166
 
         remain. delete_length is initialized to 0 in
7167
 
         the ha_statistics' constructor. */
7168
 
    } else if (UNIV_UNLIKELY
7169
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7170
 
      /* Avoid accessing the tablespace if
7171
 
         innodb_crash_recovery is set to a high value. */
7172
 
      stats.delete_length = 0;
7173
 
    } else {
7174
 
      ullint    avail_space;
7175
 
 
7176
 
      avail_space = fsp_get_available_space_in_free_extents(ib_table->space);
7177
 
 
7178
 
      if (avail_space == ULLINT_UNDEFINED) {
 
6549
    See Bug#38185.
 
6550
    We do not update delete_length if no locking is requested
 
6551
    so the "old" value can remain. delete_length is initialized
 
6552
    to 0 in the ha_statistics' constructor. */
 
6553
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6554
 
 
6555
      /* lock the data dictionary to avoid races with
 
6556
      ibd_file_missing and tablespace_discarded */
 
6557
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
6558
 
 
6559
      /* ib_table->space must be an existent tablespace */
 
6560
      if (!ib_table->ibd_file_missing
 
6561
          && !ib_table->tablespace_discarded) {
 
6562
 
 
6563
        stats.delete_length =
 
6564
          fsp_get_available_space_in_free_extents(
 
6565
            ib_table->space) * 1024;
 
6566
      } else {
 
6567
 
7179
6568
        Session*  session;
7180
6569
 
7181
 
        session= getTable()->in_use;
 
6570
        session= table->in_use;
7182
6571
        assert(session);
7183
6572
 
7184
6573
        push_warning_printf(
7193
6582
          ib_table->name);
7194
6583
 
7195
6584
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
6585
      }
 
6586
 
 
6587
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
6588
    }
7200
6589
 
7201
6590
    stats.check_time = 0;
7208
6597
  }
7209
6598
 
7210
6599
  if (flag & HA_STATUS_CONST) {
7211
 
    ulong i;
7212
 
    /* Verify the number of index in InnoDB and MySQL
7213
 
       matches up. If prebuilt->clust_index_was_generated
7214
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7215
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6600
    index = dict_table_get_first_index(ib_table);
7216
6601
 
7217
 
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
7219
 
                      "indexes inside InnoDB, which "
7220
 
                      "is different from the number of "
7221
 
                      "indexes %u defined in the MySQL ",
7222
 
                      ib_table->name, num_innodb_index,
7223
 
                      getTable()->getShare()->keys);
 
6602
    if (prebuilt->clust_index_was_generated) {
 
6603
      index = dict_table_get_next_index(index);
7224
6604
    }
7225
6605
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
 
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
 
      ulong j;
7230
 
      /* We could get index quickly through internal
7231
 
         index mapping with the index translation table.
7232
 
         The identity of index (match up index name with
7233
 
         that of table->key_info[i]) is already verified in
7234
 
         innobase_get_index().  */
7235
 
      index = innobase_get_index(i);
7236
 
 
 
6606
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7237
6607
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
6608
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
6609
            "indexes inside InnoDB than "
7240
6610
            "are defined in the MySQL "
7241
6611
            ".frm file. Have you mixed up "
7247
6617
        break;
7248
6618
      }
7249
6619
 
7250
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6620
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7251
6621
 
7252
6622
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
6623
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
6624
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
6625
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
6626
"installations? "
7281
6651
          rec_per_key = 1;
7282
6652
        }
7283
6653
 
7284
 
        getTable()->key_info[i].rec_per_key[j]=
 
6654
        table->key_info[i].rec_per_key[j]=
7285
6655
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7286
6656
          (ulong) rec_per_key;
7287
6657
      }
 
6658
 
 
6659
      index = dict_table_get_next_index(index);
7288
6660
    }
7289
 
 
7290
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7291
 
  }
7292
 
 
7293
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7294
 
    goto func_exit;
7295
6661
  }
7296
6662
 
7297
6663
  if (flag & HA_STATUS_ERRKEY) {
7304
6670
 
7305
6671
    if (err_index) {
7306
6672
      errkey = (unsigned int)
7307
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7308
 
                                                err_index);
 
6673
        row_get_mysql_key_number_for_index(err_index);
7309
6674
    } else {
7310
6675
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7311
6676
    }
7312
6677
  }
7313
6678
 
7314
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6679
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7315
6680
    stats.auto_increment_value = innobase_peek_autoinc();
7316
6681
  }
7317
6682
 
7318
 
func_exit:
7319
6683
  prebuilt->trx->op_info = (char*)"";
7320
6684
 
7321
6685
  return(0);
7348
6712
/*===============*/
7349
6713
  Session*  session)  /*!< in: user thread handle */
7350
6714
{
7351
 
  dict_index_t* index;
7352
 
  ulint         n_rows;
7353
 
  ulint         n_rows_in_table = ULINT_UNDEFINED;
7354
 
  ibool         is_ok           = TRUE;
7355
 
  ulint         old_isolation_level;
 
6715
  ulint   ret;
7356
6716
 
7357
 
  assert(session == getTable()->in_use);
 
6717
  assert(session == table->in_use);
7358
6718
  ut_a(prebuilt->trx);
7359
6719
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7360
6720
  ut_a(prebuilt->trx == session_to_trx(session));
7363
6723
    /* Build the template; we will use a dummy template
7364
6724
    in index scans done in checking */
7365
6725
 
7366
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
7367
 
  }
7368
 
 
7369
 
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
7371
 
                    "InnoDB: MySQL is trying to use a table handle"
7372
 
                    " but the .ibd file for\n"
7373
 
                    "InnoDB: table %s does not exist.\n"
7374
 
                    "InnoDB: Have you deleted the .ibd file"
7375
 
                    " from the database directory under\n"
7376
 
                    "InnoDB: the MySQL datadir, or have you"
7377
 
                    " used DISCARD TABLESPACE?\n"
7378
 
                    "InnoDB: Please refer to\n"
7379
 
                    "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
7380
 
                    "InnoDB: how you can resolve the problem.\n",
7381
 
                    prebuilt->table->name);
7382
 
    return(HA_ADMIN_CORRUPT);
7383
 
  }
7384
 
 
7385
 
  prebuilt->trx->op_info = "checking table";
7386
 
 
7387
 
  old_isolation_level = prebuilt->trx->isolation_level;
7388
 
 
7389
 
  /* We must run the index record counts at an isolation level
7390
 
     >= READ COMMITTED, because a dirty read can see a wrong number
7391
 
     of records in some index; to play safe, we use always
7392
 
     REPEATABLE READ here */
7393
 
 
7394
 
  prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7395
 
 
7396
 
  /* Enlarge the fatal lock wait timeout during CHECK TABLE. */
7397
 
  mutex_enter(&kernel_mutex);
7398
 
  srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
7399
 
  mutex_exit(&kernel_mutex);
7400
 
 
7401
 
  for (index = dict_table_get_first_index(prebuilt->table);
7402
 
       index != NULL;
7403
 
       index = dict_table_get_next_index(index)) {
7404
 
#if 0
7405
 
    fputs("Validating index ", stderr);
7406
 
    ut_print_name(stderr, trx, FALSE, index->name);
7407
 
    putc('\n', stderr);
7408
 
#endif
7409
 
 
7410
 
    if (!btr_validate_index(index, prebuilt->trx)) {
7411
 
      is_ok = FALSE;
7412
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7413
 
                          ER_NOT_KEYFILE,
7414
 
                          "InnoDB: The B-tree of"
7415
 
                          " index '%-.200s' is corrupted.",
7416
 
                          index->name);
7417
 
      continue;
7418
 
    }
7419
 
 
7420
 
    /* Instead of invoking change_active_index(), set up
7421
 
       a dummy template for non-locking reads, disabling
7422
 
       access to the clustered index. */
7423
 
    prebuilt->index = index;
7424
 
 
7425
 
    prebuilt->index_usable = row_merge_is_index_usable(
7426
 
                        prebuilt->trx, prebuilt->index);
7427
 
 
7428
 
    if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
7429
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7430
 
                          HA_ERR_TABLE_DEF_CHANGED,
7431
 
                          "InnoDB: Insufficient history for"
7432
 
                          " index '%-.200s'",
7433
 
                          index->name);
7434
 
      continue;
7435
 
    }
7436
 
 
7437
 
    prebuilt->sql_stat_start = TRUE;
7438
 
    prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
7439
 
    prebuilt->n_template = 0;
7440
 
    prebuilt->need_to_access_clustered = FALSE;
7441
 
 
7442
 
    dtuple_set_n_fields(prebuilt->search_tuple, 0);
7443
 
 
7444
 
    prebuilt->select_lock_type = LOCK_NONE;
7445
 
 
7446
 
    if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
7447
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7448
 
                          ER_NOT_KEYFILE,
7449
 
                          "InnoDB: The B-tree of"
7450
 
                          " index '%-.200s' is corrupted.",
7451
 
                          index->name);
7452
 
      is_ok = FALSE;
7453
 
    }
7454
 
 
7455
 
    if (user_session->getKilled()) {
7456
 
      break;
7457
 
    }
7458
 
 
7459
 
#if 0
7460
 
    fprintf(stderr, "%lu entries in index %s\n", n_rows,
7461
 
            index->name);
7462
 
#endif
7463
 
 
7464
 
    if (index == dict_table_get_first_index(prebuilt->table)) {
7465
 
      n_rows_in_table = n_rows;
7466
 
    } else if (n_rows != n_rows_in_table) {
7467
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7468
 
                          ER_NOT_KEYFILE,
7469
 
                          "InnoDB: Index '%-.200s'"
7470
 
                          " contains %lu entries,"
7471
 
                          " should be %lu.",
7472
 
                          index->name,
7473
 
                          (ulong) n_rows,
7474
 
                          (ulong) n_rows_in_table);
7475
 
      is_ok = FALSE;
7476
 
    }
7477
 
  }
7478
 
 
7479
 
  /* Restore the original isolation level */
7480
 
  prebuilt->trx->isolation_level = old_isolation_level;
7481
 
 
7482
 
  /* We validate also the whole adaptive hash index for all tables
7483
 
     at every CHECK TABLE */
7484
 
 
7485
 
  if (!btr_search_validate()) {
7486
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7487
 
                 ER_NOT_KEYFILE,
7488
 
                 "InnoDB: The adaptive hash index is corrupted.");
7489
 
    is_ok = FALSE;
7490
 
  }
7491
 
 
7492
 
  /* Restore the fatal lock wait timeout after CHECK TABLE. */
7493
 
  mutex_enter(&kernel_mutex);
7494
 
  srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
7495
 
  mutex_exit(&kernel_mutex);
7496
 
 
7497
 
  prebuilt->trx->op_info = "";
7498
 
  if (user_session->getKilled()) {
7499
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
7500
 
  }
7501
 
 
7502
 
  return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
 
6726
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
 
6727
  }
 
6728
 
 
6729
  ret = row_check_table_for_mysql(prebuilt);
 
6730
 
 
6731
  if (ret == DB_SUCCESS) {
 
6732
    return(HA_ADMIN_OK);
 
6733
  }
 
6734
 
 
6735
  return(HA_ADMIN_CORRUPT);
7503
6736
}
7504
6737
 
7505
6738
/*************************************************************//**
7525
6758
    return((char*)comment); /* string too long */
7526
6759
  }
7527
6760
 
7528
 
  update_session(getTable()->in_use);
 
6761
  update_session(table->in_use);
7529
6762
 
7530
6763
  prebuilt->trx->op_info = (char*)"returning table comment";
7531
6764
 
7596
6829
  external_lock(). To be safe, update the session of the current table
7597
6830
  handle. */
7598
6831
 
7599
 
  update_session(getTable()->in_use);
 
6832
  update_session(table->in_use);
7600
6833
 
7601
6834
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7602
6835
 
7617
6850
  flen = ftell(srv_dict_tmpfile);
7618
6851
  if (flen < 0) {
7619
6852
    flen = 0;
 
6853
  } else if (flen > 64000 - 1) {
 
6854
    flen = 64000 - 1;
7620
6855
  }
7621
6856
 
7622
6857
  /* allocate buffer for the string, and
7643
6878
  dict_foreign_t* foreign;
7644
6879
 
7645
6880
  ut_a(prebuilt != NULL);
7646
 
  update_session(getTable()->in_use);
 
6881
  update_session(table->in_use);
7647
6882
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7648
6883
  trx_search_latch_release_if_reserved(prebuilt->trx);
7649
6884
  mutex_enter(&(dict_sys->mutex));
7676
6911
      i++;
7677
6912
    }
7678
6913
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
6914
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
6915
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
6916
 
7682
6917
    /* Table name */
7683
6918
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
6919
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
6920
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
6921
 
7687
6922
    /** Foreign Fields **/
7759
6994
                              tmp_foreign_fields, tmp_referenced_fields);
7760
6995
 
7761
6996
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
6997
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
6998
    f_key_list->push_back(pf_key_info);
7764
6999
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7000
  }
7781
7016
{
7782
7017
  bool  can_switch;
7783
7018
 
7784
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7019
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7785
7020
 
7786
7021
  prebuilt->trx->op_info =
7787
7022
      "determining if there are foreign key constraints";
7869
7104
      either, because the calling threads may change.
7870
7105
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7871
7106
    case HA_EXTRA_IGNORE_DUP_KEY:
7872
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7107
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7873
7108
      break;
7874
7109
    case HA_EXTRA_WRITE_CAN_REPLACE:
7875
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7110
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7876
7111
      break;
7877
7112
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7878
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7113
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7879
7114
      break;
7880
7115
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7881
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7116
      session_to_trx(table->in_use)->duplicates &=
7882
7117
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7883
7118
      break;
7884
7119
    default:/* Do nothing */
8014
7249
{
8015
7250
  trx_t*      trx;
8016
7251
  static const char truncated_msg[] = "... truncated...\n";
8017
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7252
  const long    MAX_STATUS_SIZE = 64000;
8018
7253
  ulint     trx_list_start = ULINT_UNDEFINED;
8019
7254
  ulint     trx_list_end = ULINT_UNDEFINED;
8020
7255
 
8032
7267
 
8033
7268
  mutex_enter(&srv_monitor_file_mutex);
8034
7269
  rewind(srv_monitor_file);
8035
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7270
  srv_printf_innodb_monitor(srv_monitor_file,
8036
7271
        &trx_list_start, &trx_list_end);
8037
7272
  flen = ftell(srv_monitor_file);
8038
7273
  os_file_set_eof(srv_monitor_file);
8043
7278
 
8044
7279
  if (flen > MAX_STATUS_SIZE) {
8045
7280
    usable_len = MAX_STATUS_SIZE;
8046
 
    srv_truncated_status_writes++;
8047
7281
  } else {
8048
7282
    usable_len = flen;
8049
7283
  }
8079
7313
 
8080
7314
  mutex_exit(&srv_monitor_file_mutex);
8081
7315
 
8082
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8083
 
             STRING_WITH_LEN(""), str, flen);
 
7316
  bool result = FALSE;
8084
7317
 
 
7318
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7319
      STRING_WITH_LEN(""), str, flen)) {
 
7320
    result= TRUE;
 
7321
  }
8085
7322
  free(str);
8086
7323
 
8087
7324
  return(FALSE);
8088
7325
}
8089
7326
 
8090
7327
/************************************************************************//**
8091
 
Implements the SHOW MUTEX STATUS command.
8092
 
@return true on failure false on success*/
 
7328
Implements the SHOW MUTEX STATUS command. . */
8093
7329
static
8094
7330
bool
8095
7331
innodb_mutex_show_status(
8097
7333
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8098
7334
  Session*  session,  /*!< in: the MySQL query thread of the
8099
7335
          caller */
8100
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8101
 
                                        statistics */
 
7336
  stat_print_fn*  stat_print)
8102
7337
{
8103
7338
  char buf1[IO_SIZE], buf2[IO_SIZE];
8104
7339
  mutex_t*  mutex;
8105
7340
  rw_lock_t*  lock;
8106
 
  ulint         block_mutex_oswait_count = 0;
8107
 
  ulint         block_lock_oswait_count = 0;
8108
 
  mutex_t*      block_mutex = NULL;
8109
 
  rw_lock_t*    block_lock = NULL;
8110
7341
#ifdef UNIV_DEBUG
8111
7342
  ulint   rw_lock_count= 0;
8112
7343
  ulint   rw_lock_count_spin_loop= 0;
8120
7351
 
8121
7352
  mutex_enter(&mutex_list_mutex);
8122
7353
 
8123
 
  for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
8124
 
       mutex = UT_LIST_GET_NEXT(list, mutex)) {
8125
 
    if (mutex->count_os_wait == 0) {
8126
 
      continue;
8127
 
    }
8128
 
 
8129
 
 
8130
 
    if (buf_pool_is_block_mutex(mutex)) {
8131
 
      block_mutex = mutex;
8132
 
      block_mutex_oswait_count += mutex->count_os_wait;
8133
 
      continue;
 
7354
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7355
 
 
7356
  while (mutex != NULL) {
 
7357
    if (mutex->count_os_wait == 0
 
7358
        || buf_pool_is_block_mutex(mutex)) {
 
7359
      goto next_mutex;
8134
7360
    }
8135
7361
#ifdef UNIV_DEBUG
8136
7362
    if (mutex->mutex_type != 1) {
8157
7383
          return(1);
8158
7384
        }
8159
7385
      }
8160
 
    } else {
 
7386
    }
 
7387
    else {
8161
7388
      rw_lock_count += mutex->count_using;
8162
7389
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8163
7390
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8169
7396
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8170
7397
          mutex->cfile_name, (ulong) mutex->cline);
8171
7398
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8172
 
                      (ulong) mutex->count_os_wait);
 
7399
          mutex->count_os_wait);
8173
7400
 
8174
7401
    if (stat_print(session, innobase_engine_name,
8175
7402
             engine_name_len, buf1, buf1len,
8178
7405
      return(1);
8179
7406
    }
8180
7407
#endif /* UNIV_DEBUG */
8181
 
  }
8182
 
 
8183
 
  if (block_mutex) {
8184
 
    buf1len = snprintf(buf1, sizeof buf1,
8185
 
                       "combined %s:%lu",
8186
 
                       block_mutex->cfile_name,
8187
 
                       (ulong) block_mutex->cline);
8188
 
    buf2len = snprintf(buf2, sizeof buf2,
8189
 
                       "os_waits=%lu",
8190
 
                       (ulong) block_mutex_oswait_count);
8191
 
 
8192
 
    if (stat_print(session, innobase_engine_name,
8193
 
                   strlen(innobase_engine_name), buf1, buf1len,
8194
 
                   buf2, buf2len)) {
8195
 
      mutex_exit(&mutex_list_mutex);
8196
 
      return(1);
8197
 
    }
 
7408
 
 
7409
next_mutex:
 
7410
    mutex = UT_LIST_GET_NEXT(list, mutex);
8198
7411
  }
8199
7412
 
8200
7413
  mutex_exit(&mutex_list_mutex);
8201
7414
 
8202
7415
  mutex_enter(&rw_lock_list_mutex);
8203
7416
 
8204
 
  for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
8205
 
       lock = UT_LIST_GET_NEXT(list, lock)) {
8206
 
    if (lock->count_os_wait == 0) {
8207
 
      continue;
8208
 
    }
8209
 
 
8210
 
    if (buf_pool_is_block_lock(lock)) {
8211
 
      block_lock = lock;
8212
 
      block_lock_oswait_count += lock->count_os_wait;
8213
 
      continue;
8214
 
    }
8215
 
 
8216
 
    buf1len = snprintf(buf1, sizeof buf1, "%s:%lu",
8217
 
                       lock->cfile_name, (ulong) lock->cline);
8218
 
    buf2len = snprintf(buf2, sizeof buf2, "os_waits=%lu",
8219
 
                       (ulong) lock->count_os_wait);
8220
 
 
8221
 
    if (stat_print(session, innobase_engine_name,
8222
 
                   strlen(innobase_engine_name), buf1, buf1len,
8223
 
                   buf2, buf2len)) {
8224
 
      mutex_exit(&rw_lock_list_mutex);
8225
 
      return(1);
8226
 
    }
8227
 
  }
8228
 
 
8229
 
  if (block_lock) {
8230
 
    buf1len = snprintf(buf1, sizeof buf1,
8231
 
                       "combined %s:%lu",
8232
 
                       block_lock->cfile_name,
8233
 
                       (ulong) block_lock->cline);
8234
 
    buf2len = snprintf(buf2, sizeof buf2,
8235
 
                       "os_waits=%lu",
8236
 
                       (ulong) block_lock_oswait_count);
8237
 
 
8238
 
    if (stat_print(session, innobase_engine_name,
8239
 
                   strlen(innobase_engine_name), buf1, buf1len,
8240
 
                   buf2, buf2len)) {
8241
 
      mutex_exit(&rw_lock_list_mutex);
8242
 
      return(1);
8243
 
    }
 
7417
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7418
 
 
7419
  while (lock != NULL) {
 
7420
    if (lock->count_os_wait
 
7421
                    && !buf_pool_is_block_lock(lock)) {
 
7422
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7423
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7424
      buf2len= snprintf(buf2, sizeof(buf2),
 
7425
                                    "os_waits=%lu", lock->count_os_wait);
 
7426
 
 
7427
      if (stat_print(session, innobase_engine_name,
 
7428
               engine_name_len, buf1, buf1len,
 
7429
               buf2, buf2len)) {
 
7430
        mutex_exit(&rw_lock_list_mutex);
 
7431
        return(1);
 
7432
      }
 
7433
    }
 
7434
    lock = UT_LIST_GET_NEXT(list, lock);
8244
7435
  }
8245
7436
 
8246
7437
  mutex_exit(&rw_lock_list_mutex);
8247
7438
 
8248
7439
#ifdef UNIV_DEBUG
8249
 
  buf2len = snprintf(buf2, sizeof buf2,
8250
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8251
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8252
 
                     (ulong) rw_lock_count,
8253
 
                     (ulong) rw_lock_count_spin_loop,
8254
 
                     (ulong) rw_lock_count_spin_rounds,
8255
 
                     (ulong) rw_lock_count_os_wait,
8256
 
                     (ulong) rw_lock_count_os_yield,
8257
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7440
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7441
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7442
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7443
    rw_lock_count, rw_lock_count_spin_loop,
 
7444
    rw_lock_count_spin_rounds,
 
7445
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7446
    (ulong) (rw_lock_wait_time/1000));
8258
7447
 
8259
7448
  if (stat_print(session, innobase_engine_name, engine_name_len,
8260
7449
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8289
7478
static INNOBASE_SHARE* get_share(const char* table_name)
8290
7479
{
8291
7480
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7481
  pthread_mutex_lock(&innobase_share_mutex);
8293
7482
 
8294
7483
  ulint fold = ut_fold_string(table_name);
8295
7484
 
8308
7497
          innobase_open_tables, fold, share);
8309
7498
 
8310
7499
    thr_lock_init(&share->lock);
8311
 
 
8312
 
    /* Index translation table initialization */
8313
 
    share->idx_trans_tbl.index_mapping = NULL;
8314
 
    share->idx_trans_tbl.index_count = 0;
8315
 
    share->idx_trans_tbl.array_size = 0;
8316
7500
  }
8317
7501
 
8318
7502
  share->use_count++;
 
7503
  pthread_mutex_unlock(&innobase_share_mutex);
8319
7504
 
8320
7505
  return(share);
8321
7506
}
8322
7507
 
8323
7508
static void free_share(INNOBASE_SHARE* share)
8324
7509
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7510
  pthread_mutex_lock(&innobase_share_mutex);
8326
7511
 
8327
7512
#ifdef UNIV_DEBUG
8328
7513
  INNOBASE_SHARE* share2;
8342
7527
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8343
7528
          innobase_open_tables, fold, share);
8344
7529
    share->lock.deinit();
8345
 
 
8346
 
    /* Free any memory from index translation table */
8347
 
    free(share->idx_trans_tbl.index_mapping);
8348
 
 
8349
7530
    delete share;
8350
7531
 
8351
7532
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
7533
    shrinks too much */
8353
7534
  }
 
7535
 
 
7536
  pthread_mutex_unlock(&innobase_share_mutex);
8354
7537
}
8355
7538
 
8356
7539
/*****************************************************************//**
8385
7568
  trx = check_trx_exists(session);
8386
7569
 
8387
7570
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
7571
  const uint32_t sql_command = session_sql_command(session);
8389
7572
 
8390
7573
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
7574
 
8421
7604
    isolation_level = trx->isolation_level;
8422
7605
 
8423
7606
    if ((srv_locks_unsafe_for_binlog
8424
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7607
         || isolation_level == TRX_ISO_READ_COMMITTED)
8425
7608
        && isolation_level != TRX_ISO_SERIALIZABLE
8426
7609
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8427
7610
        && (sql_command == SQLCOM_INSERT_SELECT
8428
 
            || sql_command == SQLCOM_REPLACE_SELECT
8429
 
            || sql_command == SQLCOM_UPDATE
8430
 
            || sql_command == SQLCOM_CREATE_TABLE
8431
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7611
      || sql_command == SQLCOM_UPDATE
 
7612
      || sql_command == SQLCOM_CREATE_TABLE)) {
8432
7613
 
8433
7614
      /* If we either have innobase_locks_unsafe_for_binlog
8434
7615
      option set or this session is using READ COMMITTED
8435
7616
      isolation level and isolation level of the transaction
8436
7617
      is not set to serializable and MySQL is doing
8437
 
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8438
 
      or UPDATE ... = (SELECT ...) or CREATE  ...
8439
 
      SELECT... or SET ... = (SELECT ...) without
8440
 
      FOR UPDATE or IN SHARE MODE in select,
8441
 
      then we use consistent read for select. */
 
7618
      INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
 
7619
      CREATE  ... SELECT... without FOR UPDATE or
 
7620
      IN SHARE MODE in select, then we use consistent
 
7621
      read for select. */
8442
7622
 
8443
7623
      prebuilt->select_lock_type = LOCK_NONE;
8444
7624
      prebuilt->stored_select_lock_type = LOCK_NONE;
8471
7651
 
8472
7652
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
7653
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
7654
        && !session_tablespace_op(session)
8475
7655
        && sql_command != SQLCOM_TRUNCATE
8476
7656
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
7657
 
8517
7697
  *value = dict_table_autoinc_read(prebuilt->table);
8518
7698
 
8519
7699
  /* It should have been initialized during open. */
8520
 
  if (*value == 0) {
8521
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8522
 
    dict_table_autoinc_unlock(prebuilt->table);
8523
 
  }
 
7700
  ut_a(*value != 0);
8524
7701
 
8525
7702
  return(DB_SUCCESS);
8526
7703
}
8527
7704
 
8528
7705
/*******************************************************************//**
8529
 
This function reads the global auto-inc counter. It doesn't use the
 
7706
This function reads the global auto-inc counter. It doesn't use the 
8530
7707
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8531
7708
@return the autoinc value */
8532
7709
UNIV_INTERN
8546
7723
 
8547
7724
  auto_inc = dict_table_autoinc_read(innodb_table);
8548
7725
 
8549
 
  if (auto_inc == 0) {
8550
 
    ut_print_timestamp(stderr);
8551
 
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
8552
 
  }
 
7726
  ut_a(auto_inc > 0);
8553
7727
 
8554
7728
  dict_table_autoinc_unlock(innodb_table);
8555
7729
 
8578
7752
  uint64_t  autoinc = 0;
8579
7753
 
8580
7754
  /* Prepare prebuilt->trx in the table handle */
8581
 
  update_session(getTable()->in_use);
 
7755
  update_session(table->in_use);
8582
7756
 
8583
7757
  error = innobase_get_autoinc(&autoinc);
8584
7758
 
8602
7776
  invoking this method. So we are not sure if it's guaranteed to
8603
7777
  be 0 or not. */
8604
7778
 
8605
 
  /* We need the upper limit of the col type to check for
8606
 
     whether we update the table autoinc counter or not. */
8607
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8608
 
 
8609
7779
  /* Called for the first time ? */
8610
7780
  if (trx->n_autoinc_rows == 0) {
8611
7781
 
8622
7792
  /* Not in the middle of a mult-row INSERT. */
8623
7793
  } else if (prebuilt->autoinc_last_value == 0) {
8624
7794
    set_if_bigger(*first_value, autoinc);
8625
 
    /* Check for -ve values. */
8626
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8627
 
    /* Set to next logical value. */
8628
 
    ut_a(autoinc > trx->n_autoinc_rows);
8629
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8630
7795
  }
8631
7796
 
8632
7797
  *nb_reserved_values = trx->n_autoinc_rows;
8634
7799
  /* This all current style autoinc. */
8635
7800
  {
8636
7801
    uint64_t  need;
8637
 
    uint64_t  current;
8638
7802
    uint64_t  next_value;
8639
 
 
8640
 
    current = *first_value > col_max_value ? autoinc : *first_value;
 
7803
    uint64_t  col_max_value;
 
7804
 
 
7805
    /* We need the upper limit of the col type to check for
 
7806
    whether we update the table autoinc counter or not. */
 
7807
    col_max_value = innobase_get_int_col_max_value(
 
7808
      table->next_number_field);
 
7809
 
8641
7810
    need = *nb_reserved_values * increment;
8642
7811
 
8643
7812
    /* Compute the last value in the interval */
8644
 
    next_value = innobase_next_autoinc(current, need, offset, col_max_value);
 
7813
    next_value = innobase_next_autoinc(
 
7814
      *first_value, need, offset, col_max_value);
8645
7815
 
8646
7816
    prebuilt->autoinc_last_value = next_value;
8647
7817
 
8678
7848
{
8679
7849
  int error;
8680
7850
 
8681
 
  update_session(getTable()->in_use);
 
7851
  update_session(table->in_use);
8682
7852
 
8683
7853
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8684
7854
 
8703
7873
/* See comment in Cursor.cc */
8704
7874
UNIV_INTERN
8705
7875
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
7876
InnobaseEngine::get_error_message(int, String *buf)
8707
7877
{
8708
7878
  trx_t*  trx = check_trx_exists(current_session);
8709
7879
 
8744
7914
  /* Do a type-aware comparison of primary key fields. PK fields
8745
7915
  are always NOT NULL, so no checks for NULL are performed. */
8746
7916
 
8747
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
7917
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8748
7918
 
8749
7919
  key_part_end = key_part
8750
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
7920
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8751
7921
 
8752
7922
  for (; key_part != key_part_end; ++key_part) {
8753
7923
    field = key_part->field;
8787
7957
finds charset information and returns length of prefix_len characters in the
8788
7958
index field in bytes.
8789
7959
@return number of bytes occupied by the first n characters */
8790
 
UNIV_INTERN
 
7960
extern "C" UNIV_INTERN
8791
7961
ulint
8792
7962
innobase_get_at_most_n_mbchars(
8793
7963
/*===========================*/
8880
8050
  trx->detailed_error[0]= '\0';
8881
8051
 
8882
8052
  /* Set the isolation level of the transaction. */
8883
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8053
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8884
8054
}
8885
8055
 
8886
8056
void
8895
8065
 
8896
8066
  innobase_release_stat_resources(trx);
8897
8067
 
 
8068
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8069
  {
 
8070
    if (trx->conc_state != TRX_NOT_STARTED)
 
8071
    {
 
8072
      commit(session, TRUE);
 
8073
    }
 
8074
  }
 
8075
  else
 
8076
  {
 
8077
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8078
        trx->global_read_view)
 
8079
    {
 
8080
      /* At low transaction isolation levels we let
 
8081
      each consistent read set its own snapshot */
 
8082
      read_view_close_for_mysql(trx);
 
8083
    }
 
8084
  }
8898
8085
}
8899
8086
 
8900
8087
/*******************************************************************//**
8964
8151
  return(error);
8965
8152
}
8966
8153
 
8967
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8968
 
{
8969
 
  trx_t *trx= session_to_trx(session);
8970
 
  return (trx->id);
8971
 
}
8972
 
 
8973
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8974
 
{
8975
 
  trx_t*& trx = session_to_trx(session);
8976
 
 
8977
 
  if (trx == NULL)
8978
 
  {
8979
 
    trx = innobase_trx_allocate(session);
8980
 
 
8981
 
    innobase_trx_init(session, trx);
8982
 
  }
8983
 
 
8984
 
  mutex_enter(&kernel_mutex);
8985
 
  trx->id= trx_sys_get_new_trx_id();
8986
 
  mutex_exit(&kernel_mutex);
8987
 
 
8988
 
  uint64_t transaction_id= trx->id;
8989
 
 
8990
 
  return transaction_id;
8991
 
}
8992
 
 
8993
8154
/*******************************************************************//**
8994
8155
This function is used to recover X/Open XA distributed transactions.
8995
8156
@return number of prepared transactions stored in xid_list */
9101
8262
}
9102
8263
 
9103
8264
/************************************************************//**
 
8265
Validate the file format check value, is it one of "on" or "off",
 
8266
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8267
@return true if config value one of "on" or  "off" */
 
8268
static
 
8269
bool
 
8270
innobase_file_format_check_on_off(
 
8271
/*==============================*/
 
8272
  const char* format_check) /*!< in: parameter value */
 
8273
{
 
8274
  bool    ret = true;
 
8275
 
 
8276
  if (!innobase_strcasecmp(format_check, "off")) {
 
8277
 
 
8278
    /* Set the value to disable checking. */
 
8279
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8280
 
 
8281
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8282
 
 
8283
    /* Set the value to the lowest supported format. */
 
8284
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8285
  } else {
 
8286
    ret = FALSE;
 
8287
  }
 
8288
 
 
8289
  return(ret);
 
8290
}
 
8291
 
 
8292
/************************************************************//**
9104
8293
Validate the file format check config parameters, as a side effect it
9105
 
sets the srv_max_file_format_at_startup variable.
9106
 
@return the format_id if valid config value, otherwise, return -1 */
 
8294
sets the srv_check_file_format_at_startup variable.
 
8295
@return true if valid config value */
9107
8296
static
9108
 
int
9109
 
innobase_file_format_validate_and_set(
 
8297
bool
 
8298
innobase_file_format_check_validate(
9110
8299
/*================================*/
9111
 
  const char* format_max) /*!< in: parameter value */
 
8300
  const char* format_check) /*!< in: parameter value */
9112
8301
{
9113
8302
  uint    format_id;
 
8303
  bool    ret = true;
9114
8304
 
9115
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8305
  format_id = innobase_file_format_name_lookup(format_check);
9116
8306
 
9117
8307
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9118
 
    srv_max_file_format_at_startup = format_id;
9119
 
    return((int) format_id);
9120
 
  } else {
9121
 
    return(-1);
9122
 
  }
9123
 
}
9124
 
 
9125
 
 
 
8308
    srv_check_file_format_at_startup = format_id;
 
8309
  } else {
 
8310
    ret = false;
 
8311
  }
 
8312
 
 
8313
  return(ret);
 
8314
}
 
8315
 
 
8316
/*************************************************************//**
 
8317
Check if it is a valid file format. This function is registered as
 
8318
a callback with MySQL.
 
8319
@return 0 for valid file format */
 
8320
static
 
8321
int
 
8322
innodb_file_format_name_validate(
 
8323
/*=============================*/
 
8324
  Session*      , /*!< in: thread handle */
 
8325
  drizzle_sys_var*  , /*!< in: pointer to system
 
8326
            variable */
 
8327
  void*       save, /*!< out: immediate result
 
8328
            for update function */
 
8329
  drizzle_value*    value)  /*!< in: incoming string */
 
8330
{
 
8331
  const char* file_format_input;
 
8332
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8333
  int   len = sizeof(buff);
 
8334
 
 
8335
  ut_a(save != NULL);
 
8336
  ut_a(value != NULL);
 
8337
 
 
8338
  file_format_input = value->val_str(value, buff, &len);
 
8339
 
 
8340
  if (file_format_input != NULL) {
 
8341
    uint  format_id;
 
8342
 
 
8343
    format_id = innobase_file_format_name_lookup(
 
8344
      file_format_input);
 
8345
 
 
8346
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8347
 
 
8348
      *static_cast<const char**>(save) = file_format_input;
 
8349
      return(0);
 
8350
    }
 
8351
  }
 
8352
 
 
8353
  *static_cast<const char**>(save) = NULL;
 
8354
  return(1);
 
8355
}
 
8356
 
 
8357
/****************************************************************//**
 
8358
Update the system variable innodb_file_format using the "saved"
 
8359
value. This function is registered as a callback with MySQL. */
 
8360
static
 
8361
void
 
8362
innodb_file_format_name_update(
 
8363
/*===========================*/
 
8364
  Session*      ,   /*!< in: thread handle */
 
8365
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8366
              system variable */
 
8367
  void*       var_ptr,  /*!< out: where the
 
8368
              formal string goes */
 
8369
  const void*     save)   /*!< in: immediate result
 
8370
              from check function */
 
8371
{
 
8372
  const char* format_name;
 
8373
 
 
8374
  ut_a(var_ptr != NULL);
 
8375
  ut_a(save != NULL);
 
8376
 
 
8377
  format_name = *static_cast<const char*const*>(save);
 
8378
 
 
8379
  if (format_name) {
 
8380
    uint  format_id;
 
8381
 
 
8382
    format_id = innobase_file_format_name_lookup(format_name);
 
8383
 
 
8384
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8385
      srv_file_format = format_id;
 
8386
    }
 
8387
  }
 
8388
 
 
8389
  *static_cast<const char**>(var_ptr)
 
8390
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8391
}
 
8392
 
 
8393
/*************************************************************//**
 
8394
Check if valid argument to innodb_file_format_check. This
 
8395
function is registered as a callback with MySQL.
 
8396
@return 0 for valid file format */
 
8397
static
 
8398
int
 
8399
innodb_file_format_check_validate(
 
8400
/*==============================*/
 
8401
  Session*      , /*!< in: thread handle */
 
8402
  drizzle_sys_var*  , /*!< in: pointer to system
 
8403
            variable */
 
8404
  void*       save, /*!< out: immediate result
 
8405
            for update function */
 
8406
  drizzle_value*    value)  /*!< in: incoming string */
 
8407
{
 
8408
  const char* file_format_input;
 
8409
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8410
  int   len = sizeof(buff);
 
8411
 
 
8412
  ut_a(save != NULL);
 
8413
  ut_a(value != NULL);
 
8414
 
 
8415
  file_format_input = value->val_str(value, buff, &len);
 
8416
 
 
8417
  if (file_format_input != NULL) {
 
8418
 
 
8419
    /* Check if user set on/off, we want to print a suitable
 
8420
    message if they did so. */
 
8421
 
 
8422
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8423
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8424
        "InnoDB: invalid innodb_file_format_check "
 
8425
        "value; on/off can only be set at startup or "
 
8426
        "in the configuration file");
 
8427
    } else if (innobase_file_format_check_validate(
 
8428
        file_format_input)) {
 
8429
 
 
8430
      *static_cast<const char**>(save) = file_format_input;
 
8431
 
 
8432
      return(0);
 
8433
 
 
8434
    } else {
 
8435
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8436
        "InnoDB: invalid innodb_file_format_check "
 
8437
        "value; can be any format up to %s "
 
8438
        "or its equivalent numeric id",
 
8439
        trx_sys_file_format_id_to_name(
 
8440
          DICT_TF_FORMAT_MAX));
 
8441
    }
 
8442
  }
 
8443
 
 
8444
  *static_cast<const char**>(save) = NULL;
 
8445
  return(1);
 
8446
}
 
8447
 
 
8448
/****************************************************************//**
 
8449
Update the system variable innodb_file_format_check using the "saved"
 
8450
value. This function is registered as a callback with MySQL. */
 
8451
static
 
8452
void
 
8453
innodb_file_format_check_update(
 
8454
/*============================*/
 
8455
  Session*      session,  /*!< in: thread handle */
 
8456
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8457
              system variable */
 
8458
  void*       var_ptr,  /*!< out: where the
 
8459
              formal string goes */
 
8460
  const void*     save)   /*!< in: immediate result
 
8461
              from check function */
 
8462
{
 
8463
  const char* format_name_in;
 
8464
  const char**  format_name_out;
 
8465
  uint    format_id;
 
8466
 
 
8467
  ut_a(save != NULL);
 
8468
  ut_a(var_ptr != NULL);
 
8469
 
 
8470
  format_name_in = *static_cast<const char*const*>(save);
 
8471
 
 
8472
  if (!format_name_in) {
 
8473
 
 
8474
    return;
 
8475
  }
 
8476
 
 
8477
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8478
 
 
8479
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8480
    /* DEFAULT is "on", which is invalid at runtime. */
 
8481
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8482
            ER_WRONG_ARGUMENTS,
 
8483
            "Ignoring SET innodb_file_format=%s",
 
8484
            format_name_in);
 
8485
    return;
 
8486
  }
 
8487
 
 
8488
  format_name_out = static_cast<const char**>(var_ptr);
 
8489
 
 
8490
  /* Update the max format id in the system tablespace. */
 
8491
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8492
    ut_print_timestamp(stderr);
 
8493
    fprintf(stderr,
 
8494
      " [Info] InnoDB: the file format in the system "
 
8495
      "tablespace is now set to %s.\n", *format_name_out);
 
8496
  }
 
8497
}
 
8498
 
 
8499
/****************************************************************//**
 
8500
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8501
value. This function is registered as a callback with MySQL. */
 
8502
static
 
8503
void
 
8504
innodb_adaptive_hash_index_update(
 
8505
/*==============================*/
 
8506
  Session*      ,   /*!< in: thread handle */
 
8507
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8508
              system variable */
 
8509
  void*       , /*!< out: where the
 
8510
              formal string goes */
 
8511
  const void*     save)   /*!< in: immediate result
 
8512
              from check function */
 
8513
{
 
8514
  if (*(bool*) save) {
 
8515
    btr_search_enable();
 
8516
  } else {
 
8517
    btr_search_disable();
 
8518
  }
 
8519
}
 
8520
 
 
8521
/*************************************************************//**
 
8522
Check if it is a valid value of innodb_change_buffering.  This function is
 
8523
registered as a callback with MySQL.
 
8524
@return 0 for valid innodb_change_buffering */
 
8525
static
 
8526
int
 
8527
innodb_change_buffering_validate(
 
8528
/*=============================*/
 
8529
  Session*      , /*!< in: thread handle */
 
8530
  drizzle_sys_var*  , /*!< in: pointer to system
 
8531
            variable */
 
8532
  void*       save, /*!< out: immediate result
 
8533
            for update function */
 
8534
  drizzle_value*    value)  /*!< in: incoming string */
 
8535
{
 
8536
  const char* change_buffering_input;
 
8537
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8538
  int   len = sizeof(buff);
 
8539
 
 
8540
  ut_a(save != NULL);
 
8541
  ut_a(value != NULL);
 
8542
 
 
8543
  change_buffering_input = value->val_str(value, buff, &len);
 
8544
 
 
8545
  if (change_buffering_input != NULL) {
 
8546
    ulint use;
 
8547
 
 
8548
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8549
         use++) {
 
8550
      if (!innobase_strcasecmp(
 
8551
            change_buffering_input,
 
8552
            innobase_change_buffering_values[use])) {
 
8553
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8554
        return(0);
 
8555
      }
 
8556
    }
 
8557
  }
 
8558
 
 
8559
  return(1);
 
8560
}
 
8561
 
 
8562
/****************************************************************//**
 
8563
Update the system variable innodb_change_buffering using the "saved"
 
8564
value. This function is registered as a callback with MySQL. */
 
8565
static
 
8566
void
 
8567
innodb_change_buffering_update(
 
8568
/*===========================*/
 
8569
  Session*      ,   /*!< in: thread handle */
 
8570
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8571
              system variable */
 
8572
  void*       var_ptr,  /*!< out: where the
 
8573
              formal string goes */
 
8574
  const void*     save)   /*!< in: immediate result
 
8575
              from check function */
 
8576
{
 
8577
  ut_a(var_ptr != NULL);
 
8578
  ut_a(save != NULL);
 
8579
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8580
 
 
8581
  ibuf_use = *(const ibuf_use_t*) save;
 
8582
 
 
8583
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8584
}
 
8585
 
 
8586
/* plugin options */
 
8587
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8588
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8589
  "Enable InnoDB checksums validation (enabled by default). ",
 
8590
  NULL, NULL, TRUE);
 
8591
 
 
8592
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8593
  PLUGIN_VAR_READONLY,
 
8594
  "The common part for InnoDB table spaces.",
 
8595
  NULL, NULL, NULL);
 
8596
 
 
8597
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8598
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8599
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8600
  NULL, NULL, TRUE);
 
8601
 
 
8602
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8603
  PLUGIN_VAR_RQCMDARG,
 
8604
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8605
  NULL, NULL, 200, 100, ~0L, 0);
 
8606
 
 
8607
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8608
  PLUGIN_VAR_OPCMDARG,
 
8609
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8610
  "values are 0, 1 (faster)"
 
8611
  " or 2 (fastest - crash-like)"
 
8612
  ".",
 
8613
  NULL, NULL, 1, 0, 2, 0);
 
8614
 
 
8615
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8616
  PLUGIN_VAR_NOCMDARG,
 
8617
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8618
  NULL, NULL, FALSE);
 
8619
 
 
8620
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8621
  PLUGIN_VAR_RQCMDARG,
 
8622
  "File format to use for new tables in .ibd files.",
 
8623
  innodb_file_format_name_validate,
 
8624
  innodb_file_format_name_update, "Antelope");
 
8625
 
 
8626
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8627
  PLUGIN_VAR_OPCMDARG,
 
8628
  "The highest file format in the tablespace.",
 
8629
  innodb_file_format_check_validate,
 
8630
  innodb_file_format_check_update,
 
8631
  "on");
 
8632
 
 
8633
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8634
  PLUGIN_VAR_OPCMDARG,
 
8635
  "Set to 0 (write and flush once per second),"
 
8636
  " 1 (write and flush at each commit)"
 
8637
  " or 2 (write at commit, flush once per second).",
 
8638
  NULL, NULL, 1, 0, 2, 0);
 
8639
 
 
8640
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
 
8641
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8642
  "With which method to flush data.", NULL, NULL, NULL);
 
8643
 
 
8644
#ifdef UNIV_LOG_ARCHIVE
 
8645
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8646
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8647
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8648
 
 
8649
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8650
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8651
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8652
#endif /* UNIV_LOG_ARCHIVE */
 
8653
 
 
8654
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8655
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8656
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8657
 
 
8658
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8659
  PLUGIN_VAR_RQCMDARG,
 
8660
  "Percentage of dirty pages allowed in bufferpool.",
 
8661
  NULL, NULL, 75, 0, 99, 0);
 
8662
 
 
8663
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8664
  PLUGIN_VAR_NOCMDARG,
 
8665
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8666
  NULL, NULL, TRUE);
 
8667
 
 
8668
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8669
  PLUGIN_VAR_RQCMDARG,
 
8670
  "Desired maximum length of the purge queue (0 = no limit)",
 
8671
  NULL, NULL, 0, 0, ~0L, 0);
 
8672
 
 
8673
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8674
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8675
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8676
  NULL, NULL, FALSE);
 
8677
 
 
8678
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
 
8679
  PLUGIN_VAR_OPCMDARG,
 
8680
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
 
8681
  NULL, NULL, TRUE);
 
8682
 
 
8683
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8684
  PLUGIN_VAR_RQCMDARG,
 
8685
  "The number of index pages to sample when calculating statistics (default 8)",
 
8686
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8687
 
 
8688
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8689
  PLUGIN_VAR_OPCMDARG,
 
8690
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8691
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8692
 
 
8693
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8694
  PLUGIN_VAR_RQCMDARG,
 
8695
  "Replication thread delay (ms) on the slave server if "
 
8696
  "innodb_thread_concurrency is reached (0 by default)",
 
8697
  NULL, NULL, 0, 0, ~0UL, 0);
 
8698
 
 
8699
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8700
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8701
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8702
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8703
 
 
8704
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8705
  PLUGIN_VAR_RQCMDARG,
 
8706
  "Data file autoextend increment in megabytes",
 
8707
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8708
 
 
8709
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8710
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8711
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8712
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8713
 
 
8714
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8715
  PLUGIN_VAR_RQCMDARG,
 
8716
  "Helps in performance tuning in heavily concurrent environments.",
 
8717
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8718
 
 
8719
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8720
  PLUGIN_VAR_RQCMDARG,
 
8721
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8722
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8723
 
 
8724
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8725
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8726
  "Number of background read I/O threads in InnoDB.",
 
8727
  NULL, NULL, 4, 1, 64, 0);
 
8728
 
 
8729
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8730
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8731
  "Number of background write I/O threads in InnoDB.",
 
8732
  NULL, NULL, 4, 1, 64, 0);
 
8733
 
 
8734
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8735
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8736
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8737
  NULL, NULL, 0, 0, 6, 0);
 
8738
 
 
8739
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8740
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8741
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8742
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8743
 
 
8744
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8745
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8746
  "Size of each log file in a log group.",
 
8747
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8748
 
 
8749
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8750
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8751
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8752
  NULL, NULL, 2, 2, 100, 0);
 
8753
 
 
8754
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8755
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8756
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8757
  NULL, NULL, 1, 1, 10, 0);
 
8758
 
 
8759
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8760
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8761
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8762
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8763
 
 
8764
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8765
  PLUGIN_VAR_RQCMDARG,
 
8766
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8767
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8768
 
 
8769
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8770
  PLUGIN_VAR_OPCMDARG,
 
8771
  "Maximum delay between polling for a spin lock (6 by default)",
 
8772
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8773
 
 
8774
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8775
  PLUGIN_VAR_RQCMDARG,
 
8776
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8777
  NULL, NULL, 0, 0, 1000, 0);
 
8778
 
 
8779
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8780
  PLUGIN_VAR_RQCMDARG,
 
8781
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8782
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8783
 
 
8784
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8785
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8786
  "Path to individual files and their sizes.",
 
8787
  NULL, NULL, NULL);
 
8788
 
 
8789
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8790
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8791
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8792
 
 
8793
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8794
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8795
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8796
  NULL, NULL, TRUE);
 
8797
 
 
8798
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8799
  PLUGIN_VAR_RQCMDARG,
 
8800
  "Buffer changes to reduce random access: "
 
8801
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8802
  innodb_change_buffering_validate,
 
8803
  innodb_change_buffering_update, NULL);
 
8804
 
 
8805
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8806
  PLUGIN_VAR_RQCMDARG,
 
8807
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8808
  "trigger a readahead.",
 
8809
  NULL, NULL, 56, 0, 64, 0);
9126
8810
 
9127
8811
static void init_options(drizzled::module::option_context &context)
9128
8812
{
9134
8818
  context("disable-doublewrite",
9135
8819
          "Disable InnoDB doublewrite buffer.");
9136
8820
  context("io-capacity",
9137
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8821
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9138
8822
          "Number of IOPs the server can do. Tunes the background IO rate");
9139
8823
  context("fast-shutdown",
9140
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8824
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9141
8825
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9142
 
  context("purge-batch-size",
9143
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9144
 
          "Number of UNDO logs to purge in one batch from the history list. "
9145
 
          "Default is 20.");
9146
 
  context("purge-threads",
9147
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9148
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9149
8826
  context("file-per-table",
9150
8827
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9151
 
           "Stores each InnoDB table to an .ibd file in the database dir.");
9152
 
  context("file-format-max",
9153
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9154
 
          "The highest file format in the tablespace.");
9155
 
  context("file-format-check",
9156
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9157
 
          "Whether to perform system file format check.");
 
8828
          "Stores each InnoDB table to an .ibd file in the database dir.");
9158
8829
  context("file-format",
9159
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8830
          po::value<string>()->default_value("Antelope"),
9160
8831
          "File format to use for new tables in .ibd files.");
 
8832
  context("file-format-check",
 
8833
          po::value<string>()->default_value("on"),
 
8834
          "The highest file format in the tablespace.");
9161
8835
  context("flush-log-at-trx-commit",
9162
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8836
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9163
8837
          "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).");
9164
8838
  context("flush-method",
9165
8839
          po::value<string>(),
9166
8840
          "With which method to flush data.");
 
8841
#ifdef UNIV_LOG_ARCHIVE
 
8842
  context("log-arch-dir",
 
8843
          po::value<string>(),
 
8844
          "Where full logs should be archived.");
 
8845
  context("log-archive",
 
8846
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8847
          "Set to 1 if you want to have logs archived.");
 
8848
#endif /* UNIV_LOG_ARCHIVE */
9167
8849
  context("log-group-home-dir",
9168
8850
          po::value<string>(),
9169
8851
          "Path to InnoDB log files.");
9170
8852
  context("max-dirty-pages-pct",
9171
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8853
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9172
8854
          "Percentage of dirty pages allowed in bufferpool.");
9173
8855
  context("disable-adaptive-flushing",
9174
8856
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9175
8857
  context("max-purge-lag",
9176
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8858
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9177
8859
          "Desired maximum length of the purge queue (0 = no limit)");
9178
8860
  context("status-file",
9179
8861
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9181
8863
  context("disable-stats-on-metadata",
9182
8864
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9183
8865
  context("stats-sample-pages",
9184
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
8866
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9185
8867
          "The number of index pages to sample when calculating statistics (default 8)");
9186
8868
  context("disable-adaptive-hash-index",
9187
8869
          "Enable InnoDB adaptive hash index (enabled by default)");
9188
8870
  context("replication-delay",
9189
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
8871
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9190
8872
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9191
8873
  context("additional-mem-pool-size",
9192
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
8874
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9193
8875
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9194
8876
  context("autoextend-increment",
9195
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
8877
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9196
8878
          "Data file autoextend increment in megabytes");
9197
8879
  context("buffer-pool-size",
9198
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
8880
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9199
8881
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9200
 
  context("buffer-pool-instances",
9201
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9202
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9203
 
 
9204
8882
  context("commit-concurrency",
9205
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
8883
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9206
8884
          "Helps in performance tuning in heavily concurrent environments.");
9207
8885
  context("concurrency-tickets",
9208
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
8886
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9209
8887
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9210
8888
  context("read-io-threads",
9211
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
8889
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9212
8890
          "Number of background read I/O threads in InnoDB.");
9213
8891
  context("write-io-threads",
9214
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
8892
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9215
8893
          "Number of background write I/O threads in InnoDB.");
9216
8894
  context("force-recovery",
9217
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
8895
          po::value<long>(&innobase_force_recovery)->default_value(0),
9218
8896
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9219
8897
  context("log-buffer-size",
9220
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
8898
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9221
8899
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9222
8900
  context("log-file-size",
9223
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
8901
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9224
8902
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9225
8903
  context("log-files-in-group",
9226
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
8904
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9227
8905
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9228
8906
  context("mirrored-log-groups",
9229
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
8907
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9230
8908
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9231
8909
  context("open-files",
9232
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
8910
          po::value<long>(&innobase_open_files)->default_value(300L),
9233
8911
          "How many files at the maximum InnoDB keeps open at the same time.");
9234
8912
  context("sync-spin-loops",
9235
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
8913
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9236
8914
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9237
8915
  context("spin-wait-delay",
9238
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
8916
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9239
8917
          "Maximum delay between polling for a spin lock (6 by default)");
9240
8918
  context("thread-concurrency",
9241
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
8919
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9242
8920
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9243
8921
  context("thread-sleep-delay",
9244
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
8922
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9245
8923
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9246
8924
  context("data-file-path",
9247
8925
          po::value<string>(),
9251
8929
          "InnoDB version");
9252
8930
  context("use-internal-malloc",
9253
8931
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9254
 
  context("disable-native-aio",
9255
 
          _("Do not use Native AIO library for IO, even if available"));
9256
8932
  context("change-buffering",
9257
 
          po::value<string>(&innobase_change_buffering),
 
8933
          po::value<string>(),
9258
8934
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9259
8935
  context("read-ahead-threshold",
9260
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
8936
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9261
8937
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9262
8938
  context("disable-xa",
9263
8939
          "Disable InnoDB support for the XA two-phase commit");
9264
8940
  context("disable-table-locks",
9265
8941
          "Disable InnoDB locking in LOCK TABLES");
9266
8942
  context("strict-mode",
9267
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
8943
          po::value<bool>()->default_value(false)->zero_tokens(),
9268
8944
          "Use strict mode when evaluating create options.");
9269
 
  context("replication-log",
9270
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9271
 
          _("Enable internal replication log."));
9272
8945
  context("lock-wait-timeout",
9273
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9274
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9275
 
  context("old-blocks-pct",
9276
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9277
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9278
 
  context("old-blocks-time",
9279
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9280
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9281
 
            " was at least this many milliseconds ago."
9282
 
            " The timeout is disabled if 0 (the default)."));
 
8946
          po::value<unsigned long>()->default_value(50),
 
8947
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9283
8948
}
9284
8949
 
9285
 
 
 
8950
static drizzle_sys_var* innobase_system_variables[]= {
 
8951
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
8952
  DRIZZLE_SYSVAR(autoextend_increment),
 
8953
  DRIZZLE_SYSVAR(buffer_pool_size),
 
8954
  DRIZZLE_SYSVAR(checksums),
 
8955
  DRIZZLE_SYSVAR(commit_concurrency),
 
8956
  DRIZZLE_SYSVAR(concurrency_tickets),
 
8957
  DRIZZLE_SYSVAR(data_file_path),
 
8958
  DRIZZLE_SYSVAR(data_home_dir),
 
8959
  DRIZZLE_SYSVAR(doublewrite),
 
8960
  DRIZZLE_SYSVAR(fast_shutdown),
 
8961
  DRIZZLE_SYSVAR(read_io_threads),
 
8962
  DRIZZLE_SYSVAR(write_io_threads),
 
8963
  DRIZZLE_SYSVAR(file_per_table),
 
8964
  DRIZZLE_SYSVAR(file_format),
 
8965
  DRIZZLE_SYSVAR(file_format_check),
 
8966
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
8967
  DRIZZLE_SYSVAR(flush_method),
 
8968
  DRIZZLE_SYSVAR(force_recovery),
 
8969
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
8970
#ifdef UNIV_LOG_ARCHIVE
 
8971
  DRIZZLE_SYSVAR(log_arch_dir),
 
8972
  DRIZZLE_SYSVAR(log_archive),
 
8973
#endif /* UNIV_LOG_ARCHIVE */
 
8974
  DRIZZLE_SYSVAR(log_buffer_size),
 
8975
  DRIZZLE_SYSVAR(log_file_size),
 
8976
  DRIZZLE_SYSVAR(log_files_in_group),
 
8977
  DRIZZLE_SYSVAR(log_group_home_dir),
 
8978
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
8979
  DRIZZLE_SYSVAR(max_purge_lag),
 
8980
  DRIZZLE_SYSVAR(adaptive_flushing),
 
8981
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
8982
  DRIZZLE_SYSVAR(open_files),
 
8983
  DRIZZLE_SYSVAR(stats_on_metadata),
 
8984
  DRIZZLE_SYSVAR(stats_sample_pages),
 
8985
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
8986
  DRIZZLE_SYSVAR(replication_delay),
 
8987
  DRIZZLE_SYSVAR(status_file),
 
8988
  DRIZZLE_SYSVAR(strict_mode),
 
8989
  DRIZZLE_SYSVAR(support_xa),
 
8990
  DRIZZLE_SYSVAR(sync_spin_loops),
 
8991
  DRIZZLE_SYSVAR(spin_wait_delay),
 
8992
  DRIZZLE_SYSVAR(table_locks),
 
8993
  DRIZZLE_SYSVAR(thread_concurrency),
 
8994
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
8995
  DRIZZLE_SYSVAR(version),
 
8996
  DRIZZLE_SYSVAR(use_sys_malloc),
 
8997
  DRIZZLE_SYSVAR(change_buffering),
 
8998
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
8999
  DRIZZLE_SYSVAR(io_capacity),
 
9000
  NULL
 
9001
};
9286
9002
 
9287
9003
DRIZZLE_DECLARE_PLUGIN
9288
9004
{
9293
9009
  "Supports transactions, row-level locking, and foreign keys",
9294
9010
  PLUGIN_LICENSE_GPL,
9295
9011
  innobase_init, /* Plugin Init */
9296
 
  NULL, /* depends */
 
9012
  innobase_system_variables, /* system variables */
9297
9013
  init_options /* reserved */
9298
9014
}
9299
9015
DRIZZLE_DECLARE_PLUGIN_END;
9321
9037
  return res;
9322
9038
}
9323
9039
 
9324
 
/***********************************************************************
9325
 
This function checks each index name for a table against reserved
9326
 
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9327
 
this function pushes an warning message to the client, and returns true. */
9328
 
UNIV_INTERN
9329
 
bool
9330
 
innobase_index_name_is_reserved(
9331
 
/*============================*/
9332
 
                                        /* out: true if an index name
9333
 
                                        matches the reserved name */
9334
 
        const trx_t*    trx,            /* in: InnoDB transaction handle */
9335
 
        const KeyInfo*  key_info,       /* in: Indexes to be created */
9336
 
        ulint           num_of_keys)    /* in: Number of indexes to
9337
 
                                        be created. */
 
9040
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9041
 
 
9042
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9043
from zero to nonzero. (Bug #42101)
 
9044
 
 
9045
The initial default value is 0, and without this extra initialization,
 
9046
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9047
to 0, even if it was initially set to nonzero at the command line
 
9048
or configuration file. */
 
9049
static
 
9050
void
 
9051
innobase_commit_concurrency_init_default(void)
 
9052
/*==========================================*/
9338
9053
{
9339
 
  const KeyInfo*        key;
9340
 
  uint          key_num;        /* index number */
9341
 
 
9342
 
  for (key_num = 0; key_num < num_of_keys; key_num++) {
9343
 
    key = &key_info[key_num];
9344
 
 
9345
 
    if (innobase_strcasecmp(key->name,
9346
 
                            innobase_index_reserve_name) == 0) {
9347
 
      /* Push warning to drizzle */
9348
 
      push_warning_printf(trx->mysql_thd,
9349
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9350
 
                          ER_WRONG_NAME_FOR_INDEX,
9351
 
                          "Cannot Create Index with name "
9352
 
                          "'%s'. The name is reserved "
9353
 
                          "for the system default primary "
9354
 
                          "index.",
9355
 
                          innobase_index_reserve_name);
9356
 
 
9357
 
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
9358
 
               innobase_index_reserve_name);
9359
 
 
9360
 
      return(true);
9361
 
    }
9362
 
  }
9363
 
 
9364
 
  return(false);
 
9054
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9055
    = innobase_commit_concurrency;
9365
9056
}
9366
9057
 
9367
9058
#ifdef UNIV_COMPILE_TEST_FUNCS
9371
9062
  ulint   buflen;
9372
9063
  const char* id;
9373
9064
  ulint   idlen;
9374
 
  drizzled::Session *session;
 
9065
  void*   session;
9375
9066
  ibool   file_id;
9376
9067
 
9377
9068
  const char* expected;