~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, 2009 Google Inc.
 
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.
5
6
 
6
7
Portions of this file contain modifications contributed and copyrighted by
7
8
Google, Inc. Those modifications are gratefully acknowledged and are described
9
10
incorporated with their permission, and subject to the conditions contained in
10
11
the file COPYING.Google.
11
12
 
 
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
 
12
20
This program is free software; you can redistribute it and/or modify it under
13
21
the terms of the GNU General Public License as published by the Free Software
14
22
Foundation; version 2 of the License.
22
30
St, Fifth Floor, Boston, MA 02110-1301 USA
23
31
 
24
32
*****************************************************************************/
25
 
/***********************************************************************
26
 
 
27
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
28
 
Copyright (c) 2009, Percona Inc.
29
 
 
30
 
Portions of this file contain modifications contributed and copyrighted
31
 
by Percona Inc.. Those modifications are
32
 
gratefully acknowledged and are described briefly in the InnoDB
33
 
documentation. The contributions by Percona Inc. are incorporated with
34
 
their permission, and subject to the conditions contained in the file
35
 
COPYING.Percona.
36
 
 
37
 
This program is free software; you can redistribute it and/or modify it
38
 
under the terms of the GNU General Public License as published by the
39
 
Free Software Foundation; version 2 of the License.
40
 
 
41
 
This program is distributed in the hope that it will be useful, but
42
 
WITHOUT ANY WARRANTY; without even the implied warranty of
43
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
44
 
Public License for more details.
45
 
 
46
 
You should have received a copy of the GNU General Public License along
47
 
with this program; if not, write to the Free Software Foundation, Inc.,
48
 
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
49
 
 
50
 
***********************************************************************/
51
33
 
52
34
/* TODO list for the InnoDB Cursor in 5.0:
53
35
  - fix savepoint functions to use savepoint storage area
56
38
    in Windows?
57
39
*/
58
40
 
59
 
#include "config.h"
 
41
#include <config.h>
60
42
 
61
43
#include <limits.h>
62
44
#include <fcntl.h>
63
45
 
64
 
#include "drizzled/error.h"
65
 
#include "drizzled/errmsg_print.h"
66
 
#include "drizzled/charset_info.h"
67
 
#include "drizzled/internal/m_string.h"
68
 
#include "drizzled/internal/my_sys.h"
69
 
#include "drizzled/my_hash.h"
70
 
#include "drizzled/plugin.h"
71
 
#include "drizzled/show.h"
72
 
#include "drizzled/data_home.h"
73
 
#include "drizzled/error.h"
74
 
#include "drizzled/field.h"
75
 
#include "drizzled/charset.h"
76
 
#include "drizzled/session.h"
77
 
#include "drizzled/current_session.h"
78
 
#include "drizzled/table.h"
79
 
#include "drizzled/field/blob.h"
80
 
#include "drizzled/field/varstring.h"
81
 
#include "drizzled/field/timestamp.h"
82
 
#include "drizzled/plugin/xa_storage_engine.h"
83
 
#include "drizzled/plugin/daemon.h"
84
 
#include "drizzled/memory/multi_malloc.h"
85
 
#include "drizzled/pthread_globals.h"
86
 
#include "drizzled/named_savepoint.h"
 
46
#include <drizzled/error.h>
 
47
#include <drizzled/errmsg_print.h>
 
48
#include <drizzled/charset_info.h>
 
49
#include <drizzled/internal/m_string.h>
 
50
#include <drizzled/internal/my_sys.h>
 
51
#include <drizzled/my_hash.h>
 
52
#include <drizzled/plugin.h>
 
53
#include <drizzled/show.h>
 
54
#include <drizzled/data_home.h>
 
55
#include <drizzled/error.h>
 
56
#include <drizzled/field.h>
 
57
#include <drizzled/charset.h>
 
58
#include <drizzled/session.h>
 
59
#include <drizzled/current_session.h>
 
60
#include <drizzled/table.h>
 
61
#include <drizzled/field/blob.h>
 
62
#include <drizzled/field/varstring.h>
 
63
#include <drizzled/plugin/xa_storage_engine.h>
 
64
#include <drizzled/plugin/daemon.h>
 
65
#include <drizzled/memory/multi_malloc.h>
 
66
#include <drizzled/pthread_globals.h>
 
67
#include <drizzled/named_savepoint.h>
87
68
 
88
69
#include <drizzled/transaction_services.h>
89
 
#include "drizzled/message/statement_transform.h"
 
70
#include <drizzled/message/statement_transform.h>
90
71
 
91
72
#include <boost/algorithm/string.hpp>
92
73
#include <boost/program_options.hpp>
 
74
#include <boost/scoped_array.hpp>
93
75
#include <boost/filesystem.hpp>
94
76
#include <drizzled/module/option_map.h>
95
77
#include <iostream>
101
83
/** @file ha_innodb.cc */
102
84
 
103
85
/* Include necessary InnoDB headers */
104
 
extern "C" {
105
86
#include "univ.i"
106
87
#include "buf0lru.h"
107
88
#include "btr0sea.h"
120
101
#include "log0log.h"
121
102
#include "lock0lock.h"
122
103
#include "dict0crea.h"
 
104
#include "create_replication.h"
123
105
#include "btr0cur.h"
124
106
#include "btr0btr.h"
125
107
#include "fsp0fsp.h"
132
114
#include "ha_prototypes.h"
133
115
#include "ut0mem.h"
134
116
#include "ibuf0ibuf.h"
135
 
#include "mysql_addons.h"
136
 
}
137
117
 
138
118
#include "ha_innodb.h"
139
119
#include "data_dictionary.h"
 
120
#include "replication_dictionary.h"
140
121
#include "internal_dictionary.h"
141
122
#include "handler0vars.h"
142
123
 
144
125
#include <sstream>
145
126
#include <string>
146
127
 
147
 
#include "plugin/innobase/handler/status_function.h"
 
128
#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>
148
137
 
149
138
using namespace std;
150
139
using namespace drizzled;
151
140
 
152
 
#ifndef DRIZZLE_SERVER
153
 
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
154
 
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
155
 
extern pthread_mutex_t LOCK_thread_count;
156
 
 
157
 
#endif /* DRIZZLE_SERVER */
158
 
 
159
141
/** to protect innobase_open_files */
160
 
static pthread_mutex_t innobase_share_mutex;
 
142
static boost::mutex innobase_share_mutex;
 
143
 
161
144
/** to force correct commit order in binlog */
162
 
static pthread_mutex_t prepare_commit_mutex;
163
145
static ulong commit_threads = 0;
164
 
static pthread_mutex_t commit_threads_m;
165
 
static pthread_cond_t commit_cond;
166
 
static pthread_mutex_t commit_cond_m;
167
 
static pthread_mutex_t analyze_mutex;
 
146
static boost::condition_variable commit_cond;
 
147
static boost::mutex commit_cond_m;
168
148
static bool innodb_inited = 0;
169
149
 
170
150
#define INSIDE_HA_INNOBASE_CC
180
160
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
181
161
 
182
162
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
183
 
static plugin::TableFunction* status_table_function_ptr= NULL;
184
 
static plugin::TableFunction* cmp_tool= NULL;
185
 
static plugin::TableFunction* cmp_reset_tool= NULL;
186
 
static plugin::TableFunction* cmp_mem_tool= NULL;
187
 
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
188
 
static plugin::TableFunction* innodb_trx_tool= NULL;
189
 
static plugin::TableFunction* innodb_locks_tool= NULL;
190
 
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
191
 
 
192
 
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
193
 
  innobase_log_buffer_size,
194
 
  innobase_force_recovery, innobase_open_files;
195
 
static long innobase_additional_mem_pool_size= 8*1024*1024L;
196
 
static ulong innobase_commit_concurrency = 0;
197
 
static ulong innobase_read_io_threads;
198
 
static ulong innobase_write_io_threads;
199
 
 
200
 
/**
201
 
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
202
 
 */
203
 
static int64_t innobase_buffer_pool_size= 128*1024*1024;
204
 
static int64_t innobase_log_file_size;
 
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;
205
207
 
206
208
/** Percentage of the buffer pool to reserve for 'old' blocks.
207
209
Connected to buf_LRU_old_ratio. */
208
 
static uint innobase_old_blocks_pct;
 
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;
209
219
 
210
220
/* The default values for the following char* start-up parameters
211
221
are determined in innobase_init below: */
212
222
 
213
 
static char*  innobase_data_home_dir      = NULL;
214
 
static char*  innobase_data_file_path     = NULL;
215
 
static char*  innobase_log_group_home_dir   = NULL;
216
 
static char*  innobase_file_format_name   = NULL;
217
 
static char*  innobase_change_buffering   = NULL;
218
 
 
219
 
/* Note: This variable can be set to on/off and any of the supported
220
 
file formats in the configuration file, but can only be set to any
221
 
of the supported file formats during runtime. */
222
 
static char*  innobase_file_format_check    = NULL;
223
 
 
224
 
static char*  innobase_file_flush_method   = NULL;
 
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;
225
233
 
226
234
/* Below we have boolean-valued start-up parameters, and their default
227
235
values */
228
236
 
229
 
static ulong  innobase_fast_shutdown      = 1;
230
 
#ifdef UNIV_LOG_ARCHIVE
231
 
static my_bool  innobase_log_archive      = FALSE;
232
 
static char*  innobase_log_arch_dir     = NULL;
233
 
#endif /* UNIV_LOG_ARCHIVE */
 
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;
234
253
static my_bool  innobase_use_doublewrite    = TRUE;
235
254
static my_bool  innobase_use_checksums      = TRUE;
236
255
static my_bool  innobase_rollback_on_timeout    = FALSE;
237
256
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;
238
262
 
239
263
static char*  internal_innobase_data_file_path  = NULL;
240
264
 
241
 
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
242
 
 
243
265
/* The following counter is used to convey information to InnoDB
244
266
about server activity: in selects it is not sensible to call
245
267
srv_active_wake_master_thread after each fetch or search, we only do
257
279
/** Allowed values of innodb_change_buffering */
258
280
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
259
281
  "none",   /* IBUF_USE_NONE */
260
 
  "inserts" /* IBUF_USE_INSERT */
 
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 */
261
287
};
262
288
 
263
289
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
307
333
      srv_free_paths_and_sizes();
308
334
      if (internal_innobase_data_file_path)
309
335
        free(internal_innobase_data_file_path);
310
 
      pthread_mutex_destroy(&innobase_share_mutex);
311
 
      pthread_mutex_destroy(&prepare_commit_mutex);
312
 
      pthread_mutex_destroy(&commit_threads_m);
313
 
      pthread_mutex_destroy(&commit_cond_m);
314
 
      pthread_mutex_destroy(&analyze_mutex);
315
 
      pthread_cond_destroy(&commit_cond);
316
336
    }
317
337
    
318
338
    /* These get strdup'd from vm variables */
319
 
    free(innobase_data_home_dir);
320
 
    free(innobase_log_group_home_dir);
321
339
 
322
340
  }
323
341
 
404
422
  doDropSchema(
405
423
  /*===================*/
406
424
        /* out: error number */
407
 
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
 
425
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
408
426
        of the last directory in the path is used as
409
427
        the database name: for example, in 'mysql/data/test'
410
428
        the database name is 'test' */
443
461
 
444
462
  UNIV_INTERN int doCreateTable(Session &session,
445
463
                                Table &form,
446
 
                                const TableIdentifier &identifier,
 
464
                                const identifier::Table &identifier,
447
465
                                message::Table&);
448
 
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
449
 
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
 
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);
450
468
 
451
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
 
469
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
452
470
 
453
471
  UNIV_INTERN uint32_t max_supported_keys() const;
454
472
  UNIV_INTERN uint32_t max_supported_key_length() const;
465
483
  }
466
484
 
467
485
  int doGetTableDefinition(drizzled::Session& session,
468
 
                           const TableIdentifier &identifier,
 
486
                           const identifier::Table &identifier,
469
487
                           drizzled::message::Table &table_proto);
470
488
 
471
 
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
 
489
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
472
490
 
473
491
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
474
 
                             const drizzled::SchemaIdentifier &schema_identifier,
475
 
                             drizzled::TableIdentifiers &set_of_identifiers);
 
492
                             const drizzled::identifier::Schema &schema_identifier,
 
493
                             drizzled::identifier::Table::vector &set_of_identifiers);
476
494
  bool validateCreateTableOption(const std::string &key, const std::string &state);
477
495
  void dropTemporarySchema();
478
496
 
500
518
}
501
519
 
502
520
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
503
 
                                           const drizzled::SchemaIdentifier &schema_identifier,
504
 
                                           drizzled::TableIdentifiers &set_of_identifiers)
 
521
                                           const drizzled::identifier::Schema &schema_identifier,
 
522
                                           drizzled::identifier::Table::vector &set_of_identifiers)
505
523
{
506
524
  CachedDirectory::Entries entries= directory.getEntries();
507
525
 
 
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
 
508
535
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
509
536
       entry_iter != entries.end(); ++entry_iter)
510
537
  {
520
547
    { }
521
548
    else
522
549
    {
523
 
      char uname[NAME_LEN + 1];
524
 
      uint32_t file_name_len;
525
 
 
526
 
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
527
 
      // TODO: Remove need for memory copy here
528
 
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
529
 
 
530
 
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
 
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
      }
531
565
    }
532
566
  }
533
567
}
534
568
 
535
 
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
 
569
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
536
570
{
537
571
  string proto_path(identifier.getPath());
538
572
  proto_path.append(DEFAULT_FILE_EXTENSION);
539
573
 
540
 
  if (session.doesTableMessageExist(identifier))
 
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)
541
581
    return true;
542
582
 
543
583
  if (access(proto_path.c_str(), F_OK))
549
589
}
550
590
 
551
591
int InnobaseEngine::doGetTableDefinition(Session &session,
552
 
                                         const TableIdentifier &identifier,
 
592
                                         const identifier::Table &identifier,
553
593
                                         message::Table &table_proto)
554
594
{
555
595
  string proto_path(identifier.getPath());
556
596
  proto_path.append(DEFAULT_FILE_EXTENSION);
557
597
 
558
598
  // First we check the temporary tables.
559
 
  if (session.getTableMessage(identifier, table_proto))
 
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)
560
603
    return EEXIST;
561
604
 
562
605
  if (access(proto_path.c_str(), F_OK))
570
613
  return ENOENT;
571
614
}
572
615
 
573
 
/** @brief Initialize the default value of innodb_commit_concurrency.
574
 
 
575
 
Once InnoDB is running, the innodb_commit_concurrency must not change
576
 
from zero to nonzero. (Bug #42101)
577
 
 
578
 
The initial default value is 0, and without this extra initialization,
579
 
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
580
 
to 0, even if it was initially set to nonzero at the command line
581
 
or configuration file. */
582
 
static
583
 
void
584
 
innobase_commit_concurrency_init_default(void);
585
 
/*==========================================*/
586
616
 
587
617
/************************************************************//**
588
618
Validate the file format name and return its corresponding id.
595
625
            name */
596
626
/************************************************************//**
597
627
Validate the file format check config parameters, as a side effect it
598
 
sets the srv_check_file_format_at_startup variable.
599
 
@return true if one of  "on" or "off" */
600
 
static
601
 
bool
602
 
innobase_file_format_check_on_off(
603
 
/*==============================*/
604
 
  const char* format_check);    /*!< in: parameter value */
605
 
/************************************************************//**
606
 
Validate the file format check config parameters, as a side effect it
607
 
sets the srv_check_file_format_at_startup variable.
 
628
sets the srv_max_file_format_at_startup variable.
608
629
@return the format_id if valid config value, otherwise, return -1 */
609
630
static
610
631
int
611
632
innobase_file_format_validate_and_set(
612
633
/*================================*/
613
 
  const char* format_check);    /*!< in: parameter value */
 
634
  const char* format_max);    /*!< in: parameter value */
614
635
 
615
636
static const char innobase_engine_name[]= "InnoDB";
616
637
 
617
 
/*************************************************************//**
618
 
Check for a valid value of innobase_commit_concurrency.
619
 
@return 0 for valid innodb_commit_concurrency */
620
 
static
621
 
int
622
 
innobase_commit_concurrency_validate(
623
 
/*=================================*/
624
 
  Session*      , /*!< in: thread handle */
625
 
  drizzle_sys_var*  , /*!< in: pointer to system
626
 
            variable */
627
 
  void*       save, /*!< out: immediate result
628
 
            for update function */
629
 
  drizzle_value*    value)  /*!< in: incoming string */
630
 
{
631
 
  int64_t   intbuf;
632
 
  ulong   commit_concurrency;
633
 
 
634
 
  if (value->val_int(value, &intbuf)) {
635
 
    /* The value is NULL. That is invalid. */
636
 
    return(1);
637
 
  }
638
 
 
639
 
  *reinterpret_cast<ulong*>(save) = commit_concurrency
640
 
    = static_cast<ulong>(intbuf);
641
 
 
642
 
  /* Allow the value to be updated, as long as it remains zero
643
 
  or nonzero. */
644
 
  return(!(!commit_concurrency == !innobase_commit_concurrency));
645
 
}
646
 
 
647
 
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
648
 
  "Enable InnoDB support for the XA two-phase commit",
649
 
  /* check_func */ NULL, /* update_func */ NULL,
650
 
  /* default */ TRUE);
651
 
 
652
 
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
653
 
  "Enable InnoDB locking in LOCK TABLES",
654
 
  /* check_func */ NULL, /* update_func */ NULL,
655
 
  /* default */ TRUE);
656
 
 
657
 
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
658
 
  "Use strict mode when evaluating create options.",
659
 
  NULL, NULL, FALSE);
660
 
 
661
 
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
662
 
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
663
 
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
664
 
 
665
638
 
666
639
/*****************************************************************//**
667
640
Commits a transaction in an InnoDB database. */
825
798
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
826
799
         in non-Cursor code.
827
800
@return true if session is the replication thread */
828
 
extern "C" UNIV_INTERN
 
801
UNIV_INTERN
829
802
ibool
830
803
thd_is_replication_slave_thread(
831
804
/*============================*/
832
 
  void* ) /*!< in: thread handle (Session*) */
 
805
  drizzled::Session* ) /*!< in: thread handle (Session*) */
833
806
{
834
807
  return false;
835
808
}
899
872
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
900
873
         in non-Cursor code.
901
874
@return true if non-transactional tables have been edited */
902
 
extern "C" UNIV_INTERN
 
875
UNIV_INTERN
903
876
ibool
904
877
thd_has_edited_nontrans_tables(
905
878
/*===========================*/
906
 
  void*   session)  /*!< in: thread handle (Session*) */
 
879
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
907
880
{
908
 
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
 
881
  return((ibool)session->transaction.all.hasModifiedNonTransData());
909
882
}
910
883
 
911
884
/******************************************************************//**
912
885
Returns true if the thread is executing a SELECT statement.
913
886
@return true if session is executing SELECT */
914
 
extern "C" UNIV_INTERN
 
887
UNIV_INTERN
915
888
ibool
916
889
thd_is_select(
917
890
/*==========*/
918
 
  const void* session)  /*!< in: thread handle (Session*) */
 
891
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
919
892
{
920
 
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
 
893
  return(session->getSqlCommand() == SQLCOM_SELECT);
921
894
}
922
895
 
923
896
/******************************************************************//**
924
897
Returns true if the thread supports XA,
925
898
global value of innodb_supports_xa if session is NULL.
926
899
@return true if session has XA support */
927
 
extern "C" UNIV_INTERN
 
900
UNIV_INTERN
928
901
ibool
929
902
thd_supports_xa(
930
903
/*============*/
931
 
  void* session)  /*!< in: thread handle (Session*), or NULL to query
 
904
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
932
905
        the global innodb_supports_xa */
933
906
{
934
 
  return(SessionVAR((Session*) session, support_xa));
 
907
  /* TODO: Add support here for per-session value */
 
908
  return(support_xa);
935
909
}
936
910
 
937
911
/******************************************************************//**
938
912
Returns the lock wait timeout for the current connection.
939
913
@return the lock wait timeout, in seconds */
940
 
extern "C" UNIV_INTERN
 
914
UNIV_INTERN
941
915
ulong
942
916
thd_lock_wait_timeout(
943
917
/*==================*/
944
 
  void* session)  /*!< in: thread handle (Session*), or NULL to query
 
918
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
945
919
      the global innodb_lock_wait_timeout */
946
920
{
 
921
  /* TODO: Add support here for per-session value */
947
922
  /* According to <drizzle/plugin.h>, passing session == NULL
948
923
  returns the global value of the session variable. */
949
 
  return(SessionVAR((Session*) session, lock_wait_timeout));
 
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;
950
938
}
951
939
 
952
940
/********************************************************************//**
961
949
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
962
950
}
963
951
 
 
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
 
964
976
/********************************************************************//**
965
977
Call this function when mysqld passes control to the client. That is to
966
978
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1010
1022
about a possible transaction rollback inside InnoDB caused by a lock wait
1011
1023
timeout or a deadlock.
1012
1024
@return MySQL error code */
1013
 
extern "C" UNIV_INTERN
 
1025
UNIV_INTERN
1014
1026
int
1015
1027
convert_error_code_to_mysql(
1016
1028
/*========================*/
1025
1037
  case DB_INTERRUPTED:
1026
1038
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1027
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
 
1028
1052
  case DB_ERROR:
1029
1053
  default:
1030
1054
    return(-1); /* unspecified error */
1052
1076
    tell it also to MySQL so that MySQL knows to empty the
1053
1077
    cached binlog for this transaction */
1054
1078
 
1055
 
    mark_transaction_to_rollback(session, TRUE);
 
1079
    session->markTransactionForRollback(TRUE);
1056
1080
 
1057
1081
    return(HA_ERR_LOCK_DEADLOCK);
1058
1082
 
1061
1085
    latest SQL statement in a lock wait timeout. Previously, we
1062
1086
    rolled back the whole transaction. */
1063
1087
 
1064
 
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
 
1088
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
1065
1089
 
1066
1090
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1067
1091
 
1072
1096
    return(HA_ERR_ROW_IS_REFERENCED);
1073
1097
 
1074
1098
  case DB_CANNOT_ADD_CONSTRAINT:
 
1099
  case DB_CHILD_NO_INDEX:
 
1100
  case DB_PARENT_NO_INDEX:
1075
1101
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1076
1102
 
1077
1103
  case DB_CANNOT_DROP_CONSTRAINT:
1095
1121
 
1096
1122
  case DB_TOO_BIG_RECORD:
1097
1123
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1098
 
       page_get_free_space_of_empty(flags
1099
 
                  & DICT_TF_COMPACT) / 2);
 
1124
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
1100
1125
    return(HA_ERR_TO_BIG_ROW);
1101
1126
 
1102
1127
  case DB_NO_SAVEPOINT:
1107
1132
    tell it also to MySQL so that MySQL knows to empty the
1108
1133
    cached binlog for this transaction */
1109
1134
 
1110
 
    mark_transaction_to_rollback(session, TRUE);
 
1135
    session->markTransactionForRollback(TRUE);
1111
1136
 
1112
1137
    return(HA_ERR_LOCK_TABLE_FULL);
1113
1138
 
1139
1164
}
1140
1165
 
1141
1166
 
1142
 
 
1143
 
/*************************************************************//**
1144
 
If you want to print a session that is not associated with the current thread,
1145
 
you must call this function before reserving the InnoDB kernel_mutex, to
1146
 
protect Drizzle from setting session->query NULL. If you print a session of the
1147
 
current thread, we know that Drizzle cannot modify sesion->query, and it is
1148
 
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
1149
 
after you release the kernel_mutex.
1150
 
 
1151
 
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1152
 
         in non-Cursor code.
1153
 
 */
1154
 
extern "C" UNIV_INTERN
1155
 
void
1156
 
innobase_mysql_prepare_print_arbitrary_thd(void)
1157
 
/*============================================*/
1158
 
{
1159
 
  ut_ad(!mutex_own(&kernel_mutex));
1160
 
  LOCK_thread_count.lock();
1161
 
}
1162
 
 
1163
 
/*************************************************************//**
1164
 
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
1165
 
In the InnoDB latching order, the mutex sits right above the
1166
 
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
1167
 
released before this function is invoked. 
1168
 
 
1169
 
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1170
 
         in non-Cursor code.
1171
 
*/
1172
 
extern "C" UNIV_INTERN
1173
 
void
1174
 
innobase_mysql_end_print_arbitrary_thd(void)
1175
 
/*========================================*/
1176
 
{
1177
 
  ut_ad(!mutex_own(&kernel_mutex));
1178
 
  LOCK_thread_count.unlock();
1179
 
}
1180
 
 
1181
1167
/*************************************************************//**
1182
1168
Prints info of a Session object (== user session thread) to the given file. */
1183
 
extern "C" UNIV_INTERN
 
1169
UNIV_INTERN
1184
1170
void
1185
1171
innobase_mysql_print_thd(
1186
1172
/*=====================*/
1187
1173
  FILE* f,    /*!< in: output stream */
1188
 
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
 
1174
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
1189
1175
  uint  )   /*!< in: max query length to print, or 0 to
1190
1176
           use the default max length */
1191
1177
{
1192
 
  Session *session= reinterpret_cast<Session *>(in_session);
 
1178
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
 
1179
 
1193
1180
  fprintf(f,
1194
1181
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1195
 
          static_cast<uint64_t>(session->getSessionId()),
1196
 
          static_cast<uint64_t>(session->getQueryId()),
1197
 
          glob_hostname,
1198
 
          session->getSecurityContext().getIp().c_str(),
1199
 
          session->getSecurityContext().getUser().c_str()
1200
 
  );
1201
 
  fprintf(f,
1202
 
          "\n%s", session->getQueryString().c_str()
1203
 
  );
 
1182
          static_cast<uint64_t>(in_session->getSessionId()),
 
1183
          static_cast<uint64_t>(in_session->getQueryId()),
 
1184
          getServerHostname().c_str(),
 
1185
          user_identifier->address().c_str(),
 
1186
          user_identifier->username().c_str()
 
1187
  );
 
1188
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
1204
1189
  putc('\n', f);
1205
1190
}
1206
1191
 
1207
1192
/******************************************************************//**
1208
1193
Get the variable length bounds of the given character set. */
1209
 
extern "C" UNIV_INTERN
 
1194
UNIV_INTERN
1210
1195
void
1211
1196
innobase_get_cset_width(
1212
1197
/*====================*/
1223
1208
  if (cs) {
1224
1209
    *mbminlen = cs->mbminlen;
1225
1210
    *mbmaxlen = cs->mbmaxlen;
 
1211
    ut_ad(*mbminlen < DATA_MBMAX);
 
1212
    ut_ad(*mbmaxlen < DATA_MBMAX);
1226
1213
  } else {
1227
1214
    ut_a(cset == 0);
1228
1215
    *mbminlen = *mbmaxlen = 0;
1231
1218
 
1232
1219
/******************************************************************//**
1233
1220
Converts an identifier to a table name. */
1234
 
extern "C" UNIV_INTERN
 
1221
UNIV_INTERN
1235
1222
void
1236
1223
innobase_convert_from_table_id(
1237
1224
/*===========================*/
1245
1232
 
1246
1233
/******************************************************************//**
1247
1234
Converts an identifier to UTF-8. */
1248
 
extern "C" UNIV_INTERN
 
1235
UNIV_INTERN
1249
1236
void
1250
1237
innobase_convert_from_id(
1251
1238
/*=====================*/
1260
1247
/******************************************************************//**
1261
1248
Compares NUL-terminated UTF-8 strings case insensitively.
1262
1249
@return 0 if a=b, <0 if a<b, >1 if a>b */
1263
 
extern "C" UNIV_INTERN
 
1250
UNIV_INTERN
1264
1251
int
1265
1252
innobase_strcasecmp(
1266
1253
/*================*/
1272
1259
 
1273
1260
/******************************************************************//**
1274
1261
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1275
 
extern "C" UNIV_INTERN
 
1262
UNIV_INTERN
1276
1263
void
1277
1264
innobase_casedn_str(
1278
1265
/*================*/
1281
1268
  my_casedn_str(system_charset_info, a);
1282
1269
}
1283
1270
 
1284
 
/**********************************************************************//**
1285
 
Determines the connection character set.
1286
 
@return connection character set */
1287
 
extern "C" UNIV_INTERN
1288
 
const void*
1289
 
innobase_get_charset(
1290
 
/*=================*/
1291
 
  void* mysql_session)  /*!< in: MySQL thread handle */
1292
 
{
1293
 
  return session_charset(static_cast<Session*>(mysql_session));
1294
 
}
1295
 
 
1296
 
extern "C" UNIV_INTERN
 
1271
UNIV_INTERN
1297
1272
bool
1298
1273
innobase_isspace(
1299
1274
  const void *cs,
1302
1277
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1303
1278
}
1304
1279
 
1305
 
UNIV_INTERN
1306
 
int
1307
 
innobase_fast_mutex_init(
1308
 
        os_fast_mutex_t*        fast_mutex)
1309
 
{
1310
 
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1311
 
}
1312
 
 
1313
1280
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1314
1281
/*******************************************************************//**
1315
1282
Map an OS error to an errno value. The OS error number is stored in
1316
1283
_doserrno and the mapped value is stored in errno) */
1317
 
extern "C"
1318
1284
void __cdecl
1319
1285
_dosmaperr(
1320
1286
  unsigned long); /*!< in: OS error value */
1322
1288
/*********************************************************************//**
1323
1289
Creates a temporary file.
1324
1290
@return temporary file descriptor, or < 0 on error */
1325
 
extern "C" UNIV_INTERN
 
1291
UNIV_INTERN
1326
1292
int
1327
1293
innobase_mysql_tmpfile(void)
1328
1294
/*========================*/
1402
1368
/*********************************************************************//**
1403
1369
Creates a temporary file.
1404
1370
@return temporary file descriptor, or < 0 on error */
1405
 
extern "C" UNIV_INTERN
 
1371
UNIV_INTERN
1406
1372
int
1407
1373
innobase_mysql_tmpfile(void)
1408
1374
/*========================*/
1409
1375
{
1410
1376
  int fd2 = -1;
1411
 
  int fd = mysql_tmpfile("ib");
 
1377
  int fd = ::drizzled::tmpfile("ib");
1412
1378
  if (fd >= 0) {
1413
1379
    /* Copy the file descriptor, so that the additional resources
1414
1380
    allocated by create_temp_file() can be freed by invoking
1441
1407
number of bytes that were written to "buf" is returned (including the
1442
1408
terminating NUL).
1443
1409
@return number of bytes that were written */
1444
 
extern "C" UNIV_INTERN
 
1410
UNIV_INTERN
1445
1411
ulint
1446
1412
innobase_raw_format(
1447
1413
/*================*/
1561
1527
/*********************************************************************//**
1562
1528
Allocates an InnoDB transaction for a MySQL Cursor object.
1563
1529
@return InnoDB transaction handle */
1564
 
extern "C" UNIV_INTERN
 
1530
UNIV_INTERN
1565
1531
trx_t*
1566
1532
innobase_trx_allocate(
1567
1533
/*==================*/
1575
1541
  trx = trx_allocate_for_mysql();
1576
1542
 
1577
1543
  trx->mysql_thd = session;
1578
 
  trx->mysql_query_str = session->query.c_str();
1579
1544
 
1580
1545
  innobase_trx_init(session, trx);
1581
1546
 
1666
1631
  ulint   buflen, /*!< in: length of buf, in bytes */
1667
1632
  const char* id, /*!< in: identifier to convert */
1668
1633
  ulint   idlen,  /*!< in: length of id, in bytes */
1669
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1634
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1670
1635
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1671
1636
        FALSE=id is an UTF-8 string */
1672
1637
{
1673
1638
  char nz[NAME_LEN + 1];
1674
 
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
 
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]);
1675
1641
 
1676
1642
  const char* s = id;
1677
1643
  int   q;
1688
1654
    memcpy(nz, id, idlen);
1689
1655
    nz[idlen] = 0;
1690
1656
 
1691
 
    s = nz2;
1692
 
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
 
1657
    s = nz2.get();
 
1658
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
1693
1659
  }
1694
1660
 
1695
1661
  /* See if the identifier needs to be quoted. */
1743
1709
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1744
1710
and quote it if needed.
1745
1711
@return pointer to the end of buf */
1746
 
extern "C" UNIV_INTERN
 
1712
UNIV_INTERN
1747
1713
char*
1748
1714
innobase_convert_name(
1749
1715
/*==================*/
1751
1717
  ulint   buflen, /*!< in: length of buf, in bytes */
1752
1718
  const char* id, /*!< in: identifier to convert */
1753
1719
  ulint   idlen,  /*!< in: length of id, in bytes */
1754
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1720
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1755
1721
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1756
1722
        FALSE=id is an index name */
1757
1723
{
1799
1765
/**********************************************************************//**
1800
1766
Determines if the currently running transaction has been interrupted.
1801
1767
@return TRUE if interrupted */
1802
 
extern "C" UNIV_INTERN
 
1768
UNIV_INTERN
1803
1769
ibool
1804
1770
trx_is_interrupted(
1805
1771
/*===============*/
1806
1772
  trx_t*  trx)  /*!< in: transaction */
1807
1773
{
1808
 
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
 
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);
1809
1788
}
1810
1789
 
1811
1790
/**************************************************************//**
1827
1806
  value= value - (value % align_val);
1828
1807
}
1829
1808
 
 
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
 
1830
2007
/*********************************************************************//**
1831
2008
Opens an InnoDB database.
1832
2009
@return 0 on success, error code on failure */
1842
2019
  InnobaseEngine *actuall_engine_ptr;
1843
2020
  const module::option_map &vm= context.getOptions();
1844
2021
 
 
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
 
1845
2038
  /* Inverted Booleans */
1846
2039
 
1847
2040
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
1848
2041
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
1849
2042
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
1850
2043
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
1851
 
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
1852
 
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
1853
 
 
1854
 
  if (vm.count("io-capacity"))
1855
 
  {
1856
 
    if (srv_io_capacity < 100)
1857
 
    {
1858
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
1859
 
      exit(-1);
1860
 
    }
1861
 
  }
1862
 
 
 
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 */
1863
2050
  if (vm.count("data-home-dir"))
1864
2051
  {
1865
 
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
1866
 
  }
1867
 
  else
1868
 
  {
1869
 
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
1870
 
  }
1871
 
 
1872
 
  if (vm.count("fast-shutdown"))
1873
 
  {
1874
 
    if (innobase_fast_shutdown > 2)
1875
 
    {
1876
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
1877
 
      exit(-1);
1878
 
    }
1879
 
  }
1880
 
 
1881
 
  if (vm.count("file-format-check"))
1882
 
  {
1883
 
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
1884
 
  }
1885
 
 
1886
 
  if (vm.count("flush-log-at-trx-commit"))
1887
 
  {
1888
 
    if (srv_flush_log_at_trx_commit > 2)
1889
 
    {
1890
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
1891
 
      exit(-1);
1892
 
    }
1893
 
  }
1894
 
 
1895
 
  if (vm.count("flush-method"))
1896
 
  {
1897
 
    innobase_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
1898
 
  }
1899
 
  else
1900
 
  {
1901
 
    innobase_file_flush_method= NULL;
1902
 
  }
1903
 
 
1904
 
#ifdef UNIV_LOG_ARCHIVE
1905
 
  if (vm.count("log-arch-dir"))
1906
 
  {
1907
 
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
1908
 
  }
1909
 
 
1910
 
  else
1911
 
  {
1912
 
    innobase_log_arch_dir= NULL;
1913
 
  }
1914
 
#endif /* UNIV_LOG_ARCHIVE */
1915
 
 
1916
 
  if (vm.count("max-dirty-pages-pct"))
1917
 
  {
1918
 
    if (srv_max_buf_pool_modified_pct > 99)
1919
 
    {
1920
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
1921
 
      exit(-1);
1922
 
    }
1923
 
  }
1924
 
 
1925
 
  if (vm.count("stats-sample-pages"))
1926
 
  {
1927
 
    if (srv_stats_sample_pages < 8)
1928
 
    {
1929
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
1930
 
      exit(-1);
1931
 
    }
1932
 
  }
1933
 
 
1934
 
  if (vm.count("additional-mem-pool-size"))
1935
 
  {
1936
 
    align_value(innobase_additional_mem_pool_size);
1937
 
 
1938
 
    if (innobase_additional_mem_pool_size < 512*1024L)
1939
 
    {
1940
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
1941
 
      exit(-1);
1942
 
    }
1943
 
 
1944
 
  }
1945
 
 
1946
 
  if (vm.count("autoextend-increment"))
1947
 
  {
1948
 
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
1949
 
    {
1950
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
1951
 
      exit(-1);
1952
 
    }
1953
 
  }
1954
 
 
1955
 
  if (vm.count("buffer-pool-size"))
1956
 
  {
1957
 
    align_value(innobase_buffer_pool_size, 1024*1024);
1958
 
    if (innobase_buffer_pool_size < 5*1024*1024)
1959
 
    {
1960
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
1961
 
      exit(-1);
1962
 
    }
1963
 
    
1964
 
  }
1965
 
 
1966
 
  if (vm.count("commit-concurrency"))
1967
 
  {
1968
 
    if (srv_replication_delay > 1000)
1969
 
    {
1970
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
1971
 
      exit(-1);
1972
 
    }
1973
 
  }
1974
 
 
1975
 
  if (vm.count("concurrency-tickets"))
1976
 
  {
1977
 
    if (srv_n_free_tickets_to_enter < 1)
1978
 
    {
1979
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
1980
 
      exit(-1);
1981
 
    }
1982
 
  }
1983
 
 
1984
 
  if (vm.count("read-io-threads"))
1985
 
  {
1986
 
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
1987
 
    {
1988
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
1989
 
      exit(-1);
1990
 
    }
1991
 
  }
1992
 
 
1993
 
  if (vm.count("write-io-threads"))
1994
 
  {
1995
 
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
1996
 
    {
1997
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
1998
 
      exit(-1);
1999
 
    }
2000
 
  }
2001
 
 
2002
 
  if (vm.count("force-recovery"))
2003
 
  {
2004
 
    if (innobase_force_recovery > 6)
2005
 
    {
2006
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
2007
 
      exit(-1);
2008
 
    }
2009
 
  }
2010
 
 
2011
 
  if (vm.count("log-buffer-size"))
2012
 
  {
2013
 
    align_value(innobase_log_buffer_size);
2014
 
    if (innobase_log_buffer_size < 256*1024L)
2015
 
    {
2016
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
2017
 
      exit(-1);
2018
 
    }
2019
 
  }
2020
 
 
2021
 
  if (vm.count("log-file-size"))
2022
 
  {
2023
 
    align_value(innobase_log_file_size, 1024*1024);
2024
 
    if (innobase_log_file_size < 1*1024*1024L)
2025
 
    {
2026
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
2027
 
      exit(-1);
2028
 
    }
2029
 
  }
2030
 
 
2031
 
  if (vm.count("log-files-in-group"))
2032
 
  {
2033
 
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
2034
 
    {
2035
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
2036
 
      exit(-1);
2037
 
    }
2038
 
  }
2039
 
 
2040
 
  if (vm.count("mirrored-log-groups"))
2041
 
  {
2042
 
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
2043
 
    {
2044
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
2045
 
      exit(-1);
2046
 
    }
2047
 
  }
2048
 
 
2049
 
  if (vm.count("open-files"))
2050
 
  {
2051
 
    if (innobase_open_files < 10)
2052
 
    {
2053
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
2054
 
      exit(-1);
2055
 
    }
2056
 
  }
2057
 
 
2058
 
  if (vm.count("thread-concurrency"))
2059
 
  {
2060
 
    if (srv_thread_concurrency > 1000)
2061
 
    {
2062
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
2063
 
      exit(-1);
2064
 
    }
2065
 
  }
 
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
 
2066
2059
 
2067
2060
  if (vm.count("data-file-path"))
2068
2061
  {
2069
 
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
2070
 
  }
2071
 
  else
2072
 
  {
2073
 
    innobase_data_file_path= NULL;
2074
 
  }
2075
 
 
2076
 
  if (vm.count("version"))
2077
 
  {
2078
 
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
2079
 
  }
2080
 
 
2081
 
  if (vm.count("read-ahead-threshold"))
2082
 
  {
2083
 
    if (srv_read_ahead_threshold > 64)
2084
 
    {
2085
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
2086
 
      exit(-1);
2087
 
    }
2088
 
  }
2089
 
 
2090
 
  if (vm.count("strict-mode"))
2091
 
  {
2092
 
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
2093
 
  }
2094
 
 
2095
 
  if (vm.count("lock-wait-timeout"))
2096
 
  {
2097
 
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
2098
 
    {
2099
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
2100
 
      exit(-1);
2101
 
    }
2102
 
 
2103
 
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
2104
 
  }
 
2062
    innobase_data_file_path= vm["data-file-path"].as<string>();
 
2063
  }
 
2064
 
2105
2065
 
2106
2066
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2107
2067
 
2109
2069
 
2110
2070
#ifdef UNIV_DEBUG
2111
2071
  static const char test_filename[] = "-@";
2112
 
  char      test_tablename[sizeof test_filename
2113
 
    + sizeof srv_mysql50_table_name_prefix];
2114
 
  if ((sizeof test_tablename) - 1
2115
 
      != filename_to_tablename(test_filename, test_tablename,
2116
 
                               sizeof test_tablename)
2117
 
      || strncmp(test_tablename,
2118
 
                 srv_mysql50_table_name_prefix,
2119
 
                 sizeof srv_mysql50_table_name_prefix)
2120
 
      || strcmp(test_tablename
2121
 
                + sizeof srv_mysql50_table_name_prefix,
 
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(),
2122
2083
                test_filename)) {
2123
 
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
 
2084
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
2124
2085
    goto error;
2125
2086
  }
2126
2087
#endif /* UNIV_DEBUG */
2127
2088
 
2128
 
  /* Check that values don't overflow on 32-bit systems. */
2129
 
  if (sizeof(ulint) == 4) {
2130
 
    if (innobase_buffer_pool_size > UINT32_MAX) {
2131
 
      errmsg_printf(ERRMSG_LVL_ERROR, 
2132
 
                    "innobase_buffer_pool_size can't be over 4GB"
2133
 
                    " on 32-bit systems");
2134
 
 
2135
 
      goto error;
2136
 
    }
2137
 
 
2138
 
    if (innobase_log_file_size > UINT32_MAX) {
2139
 
      errmsg_printf(ERRMSG_LVL_ERROR, 
2140
 
                    "innobase_log_file_size can't be over 4GB"
2141
 
                    " on 32-bit systems");
2142
 
 
2143
 
      goto error;
2144
 
    }
2145
 
  }
2146
 
 
2147
2089
  os_innodb_umask = (ulint)internal::my_umask;
2148
2090
 
2149
2091
 
2154
2096
 
2155
2097
  /* The default dir for data files is the datadir of MySQL */
2156
2098
 
2157
 
  srv_data_home = (char *)innobase_data_home_dir;
 
2099
  srv_data_home = (char *)innobase_data_home_dir.c_str();
2158
2100
 
2159
2101
  /* Set default InnoDB data file size to 10 MB and let it be
2160
2102
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2161
2103
    to specify any startup options. */
2162
2104
 
2163
 
  if (!innobase_data_file_path) {
2164
 
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
 
2105
  if (innobase_data_file_path.empty()) 
 
2106
  {
 
2107
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
2165
2108
  }
2166
2109
 
2167
2110
  /* Since InnoDB edits the argument in the next call, we make another
2168
2111
    copy of it: */
2169
2112
 
2170
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
 
2113
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
2171
2114
 
2172
2115
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2173
2116
                                                   internal_innobase_data_file_path);
2174
2117
  if (ret == FALSE) {
2175
 
    errmsg_printf(ERRMSG_LVL_ERROR, 
2176
 
                  "InnoDB: syntax error in innodb_data_file_path");
 
2118
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
 
2119
 
2177
2120
mem_free_and_error:
2178
2121
    srv_free_paths_and_sizes();
2179
2122
    if (internal_innobase_data_file_path)
2187
2130
 
2188
2131
  if (vm.count("log-group-home-dir"))
2189
2132
  {
2190
 
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
 
2133
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
2191
2134
  }
2192
2135
  else
2193
2136
  {
2194
 
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
 
2137
    innobase_log_group_home_dir= getDataHome().file_string();
2195
2138
  }
2196
2139
 
2197
 
#ifdef UNIV_LOG_ARCHIVE
2198
 
  /* Since innodb_log_arch_dir has no relevance under MySQL,
2199
 
    starting from 4.0.6 we always set it the same as
2200
 
innodb_log_group_home_dir: */
2201
 
 
2202
 
  innobase_log_arch_dir = innobase_log_group_home_dir;
2203
 
 
2204
 
  srv_arch_dir = innobase_log_arch_dir;
2205
 
#endif /* UNIG_LOG_ARCHIVE */
2206
 
 
2207
2140
  ret = (bool)
2208
 
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
 
2141
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2209
2142
 
2210
 
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
2211
 
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
2212
 
                  "wrong number of mirrored log groups");
 
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"));
2213
2146
 
2214
2147
    goto mem_free_and_error;
2215
2148
  }
2223
2156
 
2224
2157
    if (format_id > DICT_TF_FORMAT_MAX) {
2225
2158
 
2226
 
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
 
2159
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
2227
2160
 
2228
2161
      goto mem_free_and_error;
2229
2162
    }
2234
2167
 
2235
2168
  srv_file_format = format_id;
2236
2169
 
2237
 
  /* Given the type of innobase_file_format_name we have little
2238
 
    choice but to cast away the constness from the returned name.
2239
 
    innobase_file_format_name is used in the MySQL set variable
2240
 
    interface and so can't be const. */
2241
 
 
2242
 
  innobase_file_format_name = 
2243
 
    (char*) trx_sys_file_format_id_to_name(format_id);
2244
 
 
2245
 
  /* Process innobase_file_format_check variable */
2246
 
  ut_a(innobase_file_format_check != NULL);
2247
 
 
2248
 
  /* As a side effect it will set srv_check_file_format_at_startup
2249
 
    on valid input. First we check for "on"/"off". */
2250
 
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
2251
 
 
2252
 
    /* Did the user specify a format name that we support ?
2253
 
      As a side effect it will update the variable
2254
 
      srv_check_file_format_at_startup */
2255
 
    if (innobase_file_format_validate_and_set(
2256
 
                                innobase_file_format_check) < 0) {
2257
 
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
2258
 
                    "innodb_file_format_check value: "
2259
 
                    "should be either 'on' or 'off' or "
2260
 
                    "any value up to %s or its "
2261
 
                    "equivalent numeric id",
2262
 
                    trx_sys_file_format_id_to_name(
2263
 
                                                   DICT_TF_FORMAT_MAX));
2264
 
 
2265
 
      goto mem_free_and_error;
2266
 
    }
 
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;
2267
2192
  }
2268
2193
 
2269
2194
  if (vm.count("change-buffering"))
2274
2199
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2275
2200
         use++) {
2276
2201
      if (!innobase_strcasecmp(
2277
 
                               vm["change-buffering"].as<string>().c_str(),
 
2202
                               innobase_change_buffering.c_str(),
2278
2203
                               innobase_change_buffering_values[use])) {
2279
 
        ibuf_use = (ibuf_use_t) use;
 
2204
        ibuf_use = static_cast<ibuf_use_t>(use);
2280
2205
        goto innobase_change_buffering_inited_ok;
2281
2206
      }
2282
2207
    }
2283
2208
 
2284
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2285
 
                  "InnoDB: invalid value "
2286
 
                  "innodb_file_format_check=%s",
 
2209
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
2287
2210
                  vm["change-buffering"].as<string>().c_str());
2288
2211
    goto mem_free_and_error;
2289
2212
  }
2290
2213
 
2291
2214
innobase_change_buffering_inited_ok:
2292
2215
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2293
 
  innobase_change_buffering = (char*)
2294
 
    innobase_change_buffering_values[ibuf_use];
 
2216
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
2295
2217
 
2296
2218
  /* --------------------------------------------------*/
2297
2219
 
2298
 
  srv_file_flush_method_str = innobase_file_flush_method;
 
2220
  if (vm.count("flush-method") != 0)
 
2221
  {
 
2222
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
 
2223
  }
2299
2224
 
2300
2225
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2301
2226
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2302
2227
  srv_log_file_size = (ulint) innobase_log_file_size;
2303
2228
 
2304
 
#ifdef UNIV_LOG_ARCHIVE
2305
 
  srv_log_archive_on = (ulint) innobase_log_archive;
2306
 
#endif /* UNIV_LOG_ARCHIVE */
2307
2229
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2308
2230
 
2309
2231
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
 
2232
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2310
2233
 
2311
2234
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2312
2235
 
2337
2260
 
2338
2261
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2339
2262
 
2340
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct,
2341
 
                                                     FALSE);
2342
 
 
2343
 
  innobase_commit_concurrency_init_default();
2344
 
 
2345
2263
  /* Since we in this module access directly the fields of a trx
2346
2264
    struct, and due to different headers and flags it might happen that
2347
2265
    mutex_t has a different size in this module and in InnoDB
2350
2268
 
2351
2269
  err = innobase_start_or_create_for_mysql();
2352
2270
 
 
2271
  if (err != DB_SUCCESS)
 
2272
  {
 
2273
    goto mem_free_and_error;
 
2274
  }
 
2275
 
 
2276
  err = dict_create_sys_replication_log();
 
2277
 
2353
2278
  if (err != DB_SUCCESS) {
2354
2279
    goto mem_free_and_error;
2355
2280
  }
2356
2281
 
 
2282
 
 
2283
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
 
2284
                                                     TRUE);
 
2285
 
2357
2286
  innobase_open_tables = hash_create(200);
2358
 
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2359
 
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2360
 
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2361
 
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2362
 
  pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
2363
 
  pthread_cond_init(&commit_cond, NULL);
2364
2287
  innodb_inited= 1;
2365
2288
 
2366
2289
  actuall_engine_ptr->dropTemporarySchema();
2367
2290
 
2368
 
  status_table_function_ptr= new InnodbStatusTool;
 
2291
  context.add(new InnodbStatusTool);
2369
2292
 
2370
2293
  context.add(innodb_engine_ptr);
2371
2294
 
2372
 
  context.add(status_table_function_ptr);
2373
 
 
2374
 
  cmp_tool= new(std::nothrow)CmpTool(false);
2375
 
  context.add(cmp_tool);
2376
 
 
2377
 
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
2378
 
  context.add(cmp_reset_tool);
2379
 
 
2380
 
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2381
 
  context.add(cmp_mem_tool);
2382
 
 
2383
 
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2384
 
  context.add(cmp_mem_reset_tool);
2385
 
 
2386
 
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2387
 
  context.add(innodb_trx_tool);
2388
 
 
2389
 
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2390
 
  context.add(innodb_locks_tool);
2391
 
 
2392
 
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2393
 
  context.add(innodb_lock_waits_tool);
 
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());
2394
2322
 
2395
2323
  context.add(new(std::nothrow)InnodbInternalTables());
2396
 
 
 
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));
2397
2414
  /* Get the current high water mark format. */
2398
 
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
 
2415
  innobase_file_format_max = trx_sys_file_format_max_get();
 
2416
  btr_search_fully_disabled = (!btr_search_enabled);
2399
2417
 
2400
2418
  return(FALSE);
 
2419
 
2401
2420
error:
2402
2421
  return(TRUE);
2403
2422
}
2494
2513
    trx_search_latch_release_if_reserved(trx);
2495
2514
  }
2496
2515
 
2497
 
  if (all
2498
 
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2499
 
 
 
2516
  if (all)
 
2517
  {
2500
2518
    /* We were instructed to commit the whole transaction, or
2501
2519
    this is an SQL statement end and autocommit is on */
2502
2520
 
2503
2521
    /* We need current binlog position for ibbackup to work.
2504
2522
    Note, the position is current because of
2505
2523
    prepare_commit_mutex */
2506
 
retry:
2507
 
    if (innobase_commit_concurrency > 0) {
2508
 
      pthread_mutex_lock(&commit_cond_m);
2509
 
      commit_threads++;
2510
 
 
2511
 
      if (commit_threads > innobase_commit_concurrency) {
 
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
 
2512
2535
        commit_threads--;
2513
 
        pthread_cond_wait(&commit_cond,
2514
 
          &commit_cond_m);
2515
 
        pthread_mutex_unlock(&commit_cond_m);
2516
 
        goto retry;
2517
 
      }
2518
 
      else {
2519
 
        pthread_mutex_unlock(&commit_cond_m);
2520
 
      }
 
2536
        commit_cond.wait(scopedLock);
 
2537
      } while (1);
2521
2538
    }
2522
2539
 
2523
 
                /* Store transaction point for binlog
2524
 
    Later logic tests that this is set to _something_. We need
2525
 
    that logic to fire, even though we do not have a real name. */
2526
 
    trx->mysql_log_file_name = "UNUSED";
 
2540
    trx->mysql_log_file_name = NULL;
2527
2541
    trx->mysql_log_offset = 0;
2528
2542
 
2529
2543
    /* Don't do write + flush right now. For group commit
2533
2547
    innobase_commit_low(trx);
2534
2548
    trx->flush_log_later = FALSE;
2535
2549
 
2536
 
    if (innobase_commit_concurrency > 0) {
2537
 
      pthread_mutex_lock(&commit_cond_m);
 
2550
    if (commit_concurrency)
 
2551
    {
 
2552
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
2538
2553
      commit_threads--;
2539
 
      pthread_cond_signal(&commit_cond);
2540
 
      pthread_mutex_unlock(&commit_cond_m);
 
2554
      commit_cond.notify_one();
2541
2555
    }
2542
2556
 
2543
2557
    /* Now do a write + flush of logs. */
2622
2636
 
2623
2637
  row_unlock_table_autoinc_for_mysql(trx);
2624
2638
 
2625
 
  if (all
2626
 
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2627
 
 
 
2639
  if (all)
 
2640
  {
2628
2641
    error = trx_rollback_for_mysql(trx);
2629
2642
  } else {
2630
2643
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2774
2787
 
2775
2788
  ut_a(trx);
2776
2789
 
2777
 
  assert(session->killed != Session::NOT_KILLED ||
 
2790
  assert(session->getKilled() != Session::NOT_KILLED ||
2778
2791
         trx->conc_state == TRX_NOT_STARTED);
2779
2792
 
2780
2793
  /* Warn if rolling back some things... */
2781
 
  if (session->killed != Session::NOT_KILLED &&
 
2794
  if (session->getKilled() != Session::NOT_KILLED &&
2782
2795
      trx->conc_state != TRX_NOT_STARTED &&
2783
 
      trx->undo_no.low > 0 &&
 
2796
      trx->undo_no > 0 &&
2784
2797
      global_system_variables.log_warnings)
2785
2798
  {
2786
 
      errmsg_printf(ERRMSG_LVL_WARN, 
 
2799
      errmsg_printf(error::WARN,
2787
2800
      "Drizzle is closing a connection during a KILL operation\n"
2788
 
      "that has an active InnoDB transaction.  %lu row modifications will "
 
2801
      "that has an active InnoDB transaction.  %llu row modifications will "
2789
2802
      "roll back.\n",
2790
 
      (ulong) trx->undo_no.low);
 
2803
      (ullint) trx->undo_no);
2791
2804
  }
2792
2805
 
2793
2806
  innobase_rollback_trx(trx);
2863
2876
  return(true);
2864
2877
}
2865
2878
 
2866
 
/*****************************************************************//**
2867
 
Normalizes a table name string. A normalized name consists of the
2868
 
database name catenated to '/' and table name. An example:
2869
 
test/mytable. On Windows normalization puts both the database name and the
2870
 
table name always to lower case. */
2871
 
static
2872
 
void
2873
 
normalize_table_name(
2874
 
/*=================*/
2875
 
  char*   norm_name,  /*!< out: normalized name as a
2876
 
          null-terminated string */
2877
 
  const char* name)   /*!< in: table name string */
2878
 
{
2879
 
  const char* name_ptr;
2880
 
  const char* db_ptr;
2881
 
  const char* ptr;
2882
 
 
2883
 
  /* Scan name from the end */
2884
 
 
2885
 
  ptr = strchr(name, '\0')-1;
2886
 
 
2887
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2888
 
    ptr--;
2889
 
  }
2890
 
 
2891
 
  name_ptr = ptr + 1;
2892
 
 
2893
 
  assert(ptr > name);
2894
 
 
2895
 
  ptr--;
2896
 
 
2897
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2898
 
    ptr--;
2899
 
  }
2900
 
 
2901
 
  db_ptr = ptr + 1;
2902
 
 
2903
 
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2904
 
 
2905
 
  norm_name[name_ptr - db_ptr - 1] = '/';
2906
 
 
2907
 
#ifdef __WIN__
2908
 
  innobase_casedn_str(norm_name);
2909
 
#endif
 
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]);
2910
3127
}
2911
3128
 
2912
3129
/********************************************************************//**
2913
3130
Set the autoinc column max value. This should only be called once from
2914
 
ha_innobase::open(). Therefore there's no need for a covering lock.
2915
 
@return DB_SUCCESS or error code */
 
3131
ha_innobase::open(). Therefore there's no need for a covering lock. */
2916
3132
UNIV_INTERN
2917
 
ulint
 
3133
void
2918
3134
ha_innobase::innobase_initialize_autoinc()
2919
3135
/*======================================*/
2920
3136
{
2921
 
  dict_index_t* index;
2922
3137
  uint64_t  auto_inc;
2923
 
  const char* col_name;
2924
 
  ulint   error;
2925
 
 
2926
 
  col_name = getTable()->found_next_number_field->field_name;
2927
 
  index = innobase_get_index(getTable()->getShare()->next_number_index);
2928
 
 
2929
 
  /* Execute SELECT MAX(col_name) FROM TABLE; */
2930
 
  error = row_search_max_autoinc(index, col_name, &auto_inc);
2931
 
 
2932
 
  switch (error) {
2933
 
  case DB_SUCCESS:
2934
 
 
2935
 
    /* At the this stage we don't know the increment
2936
 
    or the offset, so use default inrement of 1. */
2937
 
    ++auto_inc;
2938
 
    break;
2939
 
 
2940
 
  case DB_RECORD_NOT_FOUND:
 
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
 
2941
3148
    ut_print_timestamp(stderr);
2942
 
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
2943
 
      "dictionaries are out of sync.\n"
2944
 
      "InnoDB: Unable to find the AUTOINC column %s in the "
2945
 
      "InnoDB table %s.\n"
2946
 
      "InnoDB: We set the next AUTOINC column value to the "
2947
 
      "maximum possible value,\n"
2948
 
      "InnoDB: in effect disabling the AUTOINC next value "
2949
 
      "generation.\n"
2950
 
      "InnoDB: You can either set the next AUTOINC value "
2951
 
      "explicitly using ALTER TABLE\n"
2952
 
      "InnoDB: or fix the data dictionary by recreating "
2953
 
      "the table.\n",
2954
 
      col_name, index->table->name);
2955
 
 
2956
 
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
2957
 
    break;
2958
 
 
2959
 
  default:
2960
 
    return(error);
 
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
    }
2961
3220
  }
2962
3221
 
2963
3222
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
2964
 
 
2965
 
  return(DB_SUCCESS);
2966
3223
}
2967
3224
 
2968
3225
/*****************************************************************//**
2971
3228
@return 1 if error, 0 if success */
2972
3229
UNIV_INTERN
2973
3230
int
2974
 
ha_innobase::doOpen(const TableIdentifier &identifier,
 
3231
ha_innobase::doOpen(const identifier::Table &identifier,
2975
3232
                    int   mode,   /*!< in: not used */
2976
3233
                    uint    test_if_locked) /*!< in: not used */
2977
3234
{
2978
3235
  dict_table_t* ib_table;
2979
 
  char    norm_name[FN_REFLEN];
2980
3236
  Session*    session;
2981
3237
 
2982
3238
  UT_NOT_USED(mode);
2991
3247
    getTransactionalEngine()->releaseTemporaryLatches(session);
2992
3248
  }
2993
3249
 
2994
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
2995
 
 
2996
3250
  user_session = NULL;
2997
3251
 
2998
 
  if (!(share=get_share(identifier.getPath().c_str()))) {
 
3252
  std::string search_string(identifier.getSchemaName());
 
3253
  boost::algorithm::to_lower(search_string);
2999
3254
 
3000
 
    return(1);
 
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
    }
3001
3270
  }
3002
3271
 
3003
3272
  /* Create buffers for packing the fields of a record. Why
3006
3275
  stored the string length as the first byte. */
3007
3276
 
3008
3277
  upd_and_key_val_buff_len =
3009
 
        getTable()->getShare()->stored_rec_length
 
3278
        getTable()->getShare()->sizeStoredRecord()
3010
3279
        + getTable()->getShare()->max_key_length
3011
3280
        + MAX_REF_PARTS * 3;
3012
3281
 
3024
3293
  }
3025
3294
 
3026
3295
  /* Get pointer to a table object in InnoDB dictionary cache */
3027
 
  ib_table = dict_table_get(norm_name, TRUE);
 
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
  }
3028
3306
  
3029
3307
  if (NULL == ib_table) {
3030
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
 
3308
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
3031
3309
        "the internal data dictionary of InnoDB "
3032
3310
        "though the .frm file for the\n"
3033
3311
        "table exists. Maybe you have deleted and "
3041
3319
        "doesn't support.\n"
3042
3320
        "See " REFMAN "innodb-troubleshooting.html\n"
3043
3321
        "how you can resolve the problem.\n",
3044
 
        norm_name);
 
3322
        identifier.getKeyPath().c_str());
3045
3323
    free_share(share);
3046
3324
    upd_buff.resize(0);
3047
3325
    key_val_buff.resize(0);
3050
3328
    return(HA_ERR_NO_SUCH_TABLE);
3051
3329
  }
3052
3330
 
3053
 
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
3054
 
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
 
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 "
3055
3333
        "the .ibd file for\ntable %s does not exist.\n"
3056
3334
        "Have you deleted the .ibd file from the "
3057
3335
        "database directory under\nthe MySQL datadir, "
3058
3336
        "or have you used DISCARD TABLESPACE?\n"
3059
3337
        "See " REFMAN "innodb-troubleshooting.html\n"
3060
3338
        "how you can resolve the problem.\n",
3061
 
        norm_name);
 
3339
        identifier.getKeyPath().c_str());
3062
3340
    free_share(share);
3063
3341
    upd_buff.resize(0);
3064
3342
    key_val_buff.resize(0);
3070
3348
 
3071
3349
  prebuilt = row_create_prebuilt(ib_table);
3072
3350
 
3073
 
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
 
3351
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
3074
3352
  prebuilt->default_rec = getTable()->getDefaultValues();
3075
3353
  ut_ad(prebuilt->default_rec);
3076
3354
 
3079
3357
  primary_key = getTable()->getShare()->getPrimaryKey();
3080
3358
  key_used_on_scan = primary_key;
3081
3359
 
 
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
 
3082
3365
  /* Allocate a buffer for a 'row reference'. A row reference is
3083
3366
  a string of bytes of length ref_length which uniquely specifies
3084
3367
  a row in our table. Note that MySQL may also compare two row
3086
3369
  of length ref_length! */
3087
3370
 
3088
3371
  if (!row_table_got_default_clust_index(ib_table)) {
3089
 
    if (primary_key >= MAX_KEY) {
3090
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
3091
 
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
3092
 
    }
3093
3372
 
3094
3373
    prebuilt->clust_index_was_generated = FALSE;
3095
3374
 
3096
 
    /* MySQL allocates the buffer for ref. key_info->key_length
3097
 
    includes space for all key columns + one byte for each column
3098
 
    that may be NULL. ref_length must be as exact as possible to
3099
 
    save space, because all row reference buffers are allocated
3100
 
    based on ref_length. */
3101
 
 
3102
 
    ref_length = getTable()->key_info[primary_key].key_length;
 
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
    }
3103
3429
  } else {
3104
3430
    if (primary_key != MAX_KEY) {
3105
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
3106
 
          "dictionary, but has one in MySQL! If you "
3107
 
          "created the table with a MySQL version < "
3108
 
          "3.23.54 and did not define a primary key, "
3109
 
          "but defined a unique key with all non-NULL "
3110
 
          "columns, then MySQL internally treats that "
3111
 
          "key as the primary key. You can fix this "
3112
 
          "error by dump + DROP + CREATE + reimport "
3113
 
          "of the table.", identifier.getTableName().c_str());
 
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());
3114
3452
    }
3115
3453
 
3116
3454
    prebuilt->clust_index_was_generated = TRUE;
3126
3464
    and it will never be updated anyway. */
3127
3465
 
3128
3466
    if (key_used_on_scan != MAX_KEY) {
3129
 
      errmsg_printf(ERRMSG_LVL_WARN, 
 
3467
      errmsg_printf(error::WARN, 
3130
3468
        "Table %s key_used_on_scan is %lu even "
3131
3469
        "though there is no primary key inside "
3132
3470
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3143
3481
    /* We update the highest file format in the system table
3144
3482
    space, if this table has higher file format setting. */
3145
3483
 
3146
 
    trx_sys_file_format_max_upgrade(
3147
 
      (const char**) &innobase_file_format_check,
 
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,
3148
3487
      dict_table_get_format(prebuilt->table));
 
3488
    innobase_file_format_max= changed_file_format_max;
3149
3489
  }
3150
3490
 
3151
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3152
 
 
3153
3491
  /* Only if the table has an AUTOINC column. */
3154
3492
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
3155
 
    ulint error;
3156
3493
 
3157
3494
    dict_table_autoinc_lock(prebuilt->table);
3158
3495
 
3162
3499
    autoinc value from a previous Drizzle open. */
3163
3500
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3164
3501
 
3165
 
      error = innobase_initialize_autoinc();
3166
 
      ut_a(error == DB_SUCCESS);
 
3502
      innobase_initialize_autoinc();
3167
3503
    }
3168
3504
 
3169
3505
    dict_table_autoinc_unlock(prebuilt->table);
3170
3506
  }
3171
3507
 
 
3508
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3509
 
3172
3510
  return(0);
3173
3511
}
3174
3512
 
3278
3616
of this function is in rem0cmp.c in InnoDB source code! If you change this
3279
3617
function, remember to update the prototype there!
3280
3618
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3281
 
extern "C" UNIV_INTERN
3282
 
int
 
3619
UNIV_INTERN int
3283
3620
innobase_mysql_cmp(
3284
3621
/*===============*/
3285
3622
  int   mysql_type, /*!< in: MySQL type */
3326
3663
      charset = get_charset(charset_number);
3327
3664
 
3328
3665
      if (charset == NULL) {
3329
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
 
3666
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
3330
3667
                      "a comparison, but MySQL cannot "
3331
3668
                      "find that charset.",
3332
3669
                      (ulong) charset_number);
3361
3698
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3362
3699
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3363
3700
@return DATA_BINARY, DATA_VARCHAR, ... */
3364
 
extern "C" UNIV_INTERN
 
3701
UNIV_INTERN
3365
3702
ulint
3366
3703
get_innobase_type_from_mysql_type(
3367
3704
/*==============================*/
3410
3747
      return(DATA_VARMYSQL);
3411
3748
    }
3412
3749
  case DRIZZLE_TYPE_DECIMAL:
 
3750
  case DRIZZLE_TYPE_MICROTIME:
3413
3751
    return(DATA_FIXBINARY);
3414
3752
  case DRIZZLE_TYPE_LONG:
3415
3753
  case DRIZZLE_TYPE_LONGLONG:
3416
3754
  case DRIZZLE_TYPE_DATETIME:
 
3755
  case DRIZZLE_TYPE_TIME:
3417
3756
  case DRIZZLE_TYPE_DATE:
3418
3757
  case DRIZZLE_TYPE_TIMESTAMP:
 
3758
  case DRIZZLE_TYPE_ENUM:
3419
3759
    return(DATA_INT);
3420
3760
  case DRIZZLE_TYPE_DOUBLE:
3421
3761
    return(DATA_DOUBLE);
3422
3762
  case DRIZZLE_TYPE_BLOB:
3423
 
                return(DATA_BLOB);
3424
 
  default:
 
3763
    return(DATA_BLOB);
 
3764
  case DRIZZLE_TYPE_BOOLEAN:
 
3765
  case DRIZZLE_TYPE_UUID:
 
3766
    return(DATA_FIXBINARY);
 
3767
  case DRIZZLE_TYPE_NULL:
3425
3768
    ut_error;
3426
3769
  }
3427
3770
 
3661
4004
      ulint     key_len;
3662
4005
      const unsigned char*    src_start;
3663
4006
      enum_field_types  real_type;
 
4007
      const CHARSET_INFO* cs= field->charset();
3664
4008
 
3665
4009
      key_len = key_part->length;
3666
4010
 
3682
4026
      memcpy(buff, src_start, true_len);
3683
4027
      buff += true_len;
3684
4028
 
3685
 
      /* Pad the unused space with spaces. Note that no
3686
 
      padding is ever needed for UCS-2 because in MySQL,
3687
 
      all UCS2 characters are 2 bytes, as MySQL does not
3688
 
      support surrogate pairs, which are needed to represent
3689
 
      characters in the range U+10000 to U+10FFFF. */
 
4029
      /* Pad the unused space with spaces. */
3690
4030
 
3691
4031
      if (true_len < key_len) {
3692
 
        ulint pad_len = key_len - true_len;
3693
 
        memset(buff, ' ', pad_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 */);
3694
4037
        buff += pad_len;
3695
4038
      }
3696
4039
    }
3798
4141
 
3799
4142
  /* Note that in InnoDB, i is the column number. MySQL calls columns
3800
4143
  'fields'. */
3801
 
  for (i = 0; i < n_fields; i++) 
 
4144
  for (i = 0; i < n_fields; i++)
3802
4145
  {
 
4146
    const dict_col_t *col= &index->table->cols[i];
3803
4147
    templ = prebuilt->mysql_template + n_requested_fields;
3804
4148
    field = table->getField(i);
3805
4149
 
3845
4189
    n_requested_fields++;
3846
4190
 
3847
4191
    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);
3848
4194
 
3849
4195
    if (index == clust_index) {
3850
 
      templ->rec_field_no = dict_col_get_clust_pos(
3851
 
        &index->table->cols[i], index);
 
4196
      templ->rec_field_no = templ->clust_rec_field_no;
3852
4197
    } else {
3853
4198
      templ->rec_field_no = dict_index_get_nth_col_pos(
3854
4199
                index, i);
3855
 
    }
3856
 
 
3857
 
    if (templ->rec_field_no == ULINT_UNDEFINED) {
3858
 
      prebuilt->need_to_access_clustered = TRUE;
 
4200
      if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4201
        prebuilt->need_to_access_clustered = TRUE;
 
4202
      }
3859
4203
    }
3860
4204
 
3861
4205
    if (field->null_ptr) {
3877
4221
      mysql_prefix_len = templ->mysql_col_offset
3878
4222
        + templ->mysql_col_len;
3879
4223
    }
3880
 
    templ->type = index->table->cols[i].mtype;
 
4224
    templ->type = col->mtype;
3881
4225
    templ->mysql_type = (ulint)field->type();
3882
4226
 
3883
4227
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
3885
4229
        (((Field_varstring*)field)->pack_length_no_ptr());
3886
4230
    }
3887
4231
 
3888
 
    templ->charset = dtype_get_charset_coll(
3889
 
      index->table->cols[i].prtype);
3890
 
    templ->mbminlen = index->table->cols[i].mbminlen;
3891
 
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
3892
 
    templ->is_unsigned = index->table->cols[i].prtype
3893
 
              & DATA_UNSIGNED;
 
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;
3894
4236
    if (templ->type == DATA_BLOB) {
3895
4237
      prebuilt->templ_contains_blob = TRUE;
3896
4238
    }
3907
4249
    for (i = 0; i < n_requested_fields; i++) {
3908
4250
      templ = prebuilt->mysql_template + i;
3909
4251
 
3910
 
      templ->rec_field_no = dict_col_get_clust_pos(
3911
 
        &index->table->cols[templ->col_no],
3912
 
        clust_index);
 
4252
      templ->rec_field_no = templ->clust_rec_field_no;
3913
4253
    }
3914
4254
  }
3915
4255
}
3916
4256
 
3917
4257
/********************************************************************//**
3918
 
Get the upper limit of the MySQL integral and floating-point type. */
3919
 
UNIV_INTERN
3920
 
uint64_t
3921
 
ha_innobase::innobase_get_int_col_max_value(
3922
 
/*========================================*/
3923
 
  const Field*  field)
3924
 
{
3925
 
  uint64_t  max_value = 0;
3926
 
 
3927
 
  switch(field->key_type()) {
3928
 
  /* TINY */
3929
 
  case HA_KEYTYPE_BINARY:
3930
 
    max_value = 0xFFULL;
3931
 
    break;
3932
 
  /* LONG */
3933
 
  case HA_KEYTYPE_ULONG_INT:
3934
 
    max_value = 0xFFFFFFFFULL;
3935
 
    break;
3936
 
  case HA_KEYTYPE_LONG_INT:
3937
 
    max_value = 0x7FFFFFFFULL;
3938
 
    break;
3939
 
  /* BIG */
3940
 
  case HA_KEYTYPE_ULONGLONG:
3941
 
    max_value = 0xFFFFFFFFFFFFFFFFULL;
3942
 
    break;
3943
 
  case HA_KEYTYPE_LONGLONG:
3944
 
    max_value = 0x7FFFFFFFFFFFFFFFULL;
3945
 
    break;
3946
 
  case HA_KEYTYPE_DOUBLE:
3947
 
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
3948
 
    max_value = 0x20000000000000ULL;
3949
 
    break;
3950
 
  default:
3951
 
    ut_error;
3952
 
  }
3953
 
 
3954
 
  return(max_value);
3955
 
}
3956
 
 
3957
 
/********************************************************************//**
3958
4258
This special handling is really to overcome the limitations of MySQL's
3959
4259
binlogging. We need to eliminate the non-determinism that will arise in
3960
4260
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4023
4323
  trx_t*    trx = session_to_trx(user_session);
4024
4324
 
4025
4325
  if (prebuilt->trx != trx) {
4026
 
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
 
4326
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
4027
4327
        "%p, but for the current thread it is at %p",
4028
4328
        (const void*) prebuilt->trx, (const void*) trx);
4029
4329
 
4037
4337
    ut_error;
4038
4338
  }
4039
4339
 
4040
 
  sql_command = session_sql_command(user_session);
 
4340
  sql_command = user_session->getSqlCommand();
4041
4341
 
4042
4342
  if ((sql_command == SQLCOM_ALTER_TABLE
4043
4343
       || sql_command == SQLCOM_CREATE_INDEX
4112
4412
    prebuilt->autoinc_error = DB_SUCCESS;
4113
4413
 
4114
4414
    if ((error = update_auto_increment())) {
4115
 
 
4116
4415
      /* We don't want to mask autoinc overflow errors. */
4117
 
      if (prebuilt->autoinc_error != DB_SUCCESS) {
 
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) {
4118
4425
        error = (int) prebuilt->autoinc_error;
4119
4426
 
4120
4427
        goto report_error;
4141
4448
 
4142
4449
  error = row_insert_for_mysql((byte*) record, prebuilt);
4143
4450
 
4144
 
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
4451
  user_session->setXaId(trx->id);
4145
4452
 
4146
4453
  /* Handle duplicate key errors */
4147
4454
  if (auto_inc_used) {
4198
4505
      update the table upper limit. Note: last_value
4199
4506
      will be 0 if get_auto_increment() was not called.*/
4200
4507
 
4201
 
      if (auto_inc <= col_max_value
4202
 
          && auto_inc >= prebuilt->autoinc_last_value) {
 
4508
      if (auto_inc >= prebuilt->autoinc_last_value) {
4203
4509
set_max_autoinc:
4204
 
        ut_a(prebuilt->autoinc_increment > 0);
4205
 
 
4206
 
        uint64_t  need;
4207
 
        uint64_t  offset;
4208
 
 
4209
 
        offset = prebuilt->autoinc_offset;
4210
 
        need = prebuilt->autoinc_increment;
4211
 
 
4212
 
        auto_inc = innobase_next_autoinc(
4213
 
          auto_inc, need, offset, col_max_value);
4214
 
 
4215
 
        err = innobase_set_max_autoinc(auto_inc);
4216
 
 
4217
 
        if (err != DB_SUCCESS) {
4218
 
          error = err;
 
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
          }
4219
4531
        }
4220
4532
      }
4221
4533
      break;
4459
4771
 
4460
4772
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4461
4773
 
4462
 
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
4774
  user_session->setXaId(trx->id);
4463
4775
 
4464
4776
  /* We need to do some special AUTOINC handling for the following case:
4465
4777
 
4472
4784
  if (error == DB_SUCCESS
4473
4785
      && getTable()->next_number_field
4474
4786
      && new_row == getTable()->getInsertRecord()
4475
 
      && session_sql_command(user_session) == SQLCOM_INSERT
 
4787
      && user_session->getSqlCommand() == SQLCOM_INSERT
4476
4788
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4477
4789
    == TRX_DUP_IGNORE)  {
4478
4790
 
4551
4863
 
4552
4864
  error = row_update_for_mysql((byte*) record, prebuilt);
4553
4865
 
4554
 
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
4866
  user_session->setXaId(trx->id);
4555
4867
 
4556
4868
  innodb_srv_conc_exit_innodb(trx);
4557
4869
 
4586
4898
  case ROW_READ_WITH_LOCKS:
4587
4899
    if (!srv_locks_unsafe_for_binlog
4588
4900
        && prebuilt->trx->isolation_level
4589
 
        != TRX_ISO_READ_COMMITTED) {
 
4901
        > TRX_ISO_READ_COMMITTED) {
4590
4902
      break;
4591
4903
    }
4592
4904
    /* fall through */
4625
4937
 
4626
4938
  if (yes
4627
4939
      && (srv_locks_unsafe_for_binlog
4628
 
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
 
4940
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
4629
4941
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4630
4942
  } else {
4631
4943
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
4811
5123
    return(HA_ERR_CRASHED);
4812
5124
  }
4813
5125
 
 
5126
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
 
5127
    return(HA_ERR_TABLE_DEF_CHANGED);
 
5128
  }
4814
5129
 
4815
5130
  /* Note that if the index for which the search template is built is not
4816
5131
  necessarily prebuilt->index, but can also be the clustered index */
4924
5239
 
4925
5240
  ha_statistic_increment(&system_status_var::ha_read_key_count);
4926
5241
 
4927
 
  ut_ad(user_session == table->in_use);
4928
 
  ut_a(prebuilt->trx == session_to_trx(user_session));
4929
 
 
4930
5242
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
4931
5243
  {
4932
 
    index = dict_table_get_index_on_name(prebuilt->table,
4933
 
                                         getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str());
 
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
    }
4934
5267
  } else {
4935
5268
    index = dict_table_get_first_index(prebuilt->table);
4936
5269
  }
4937
5270
 
4938
5271
  if (!index) {
4939
 
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
5272
    errmsg_printf(error::ERROR, 
4940
5273
      "Innodb could not find key n:o %u with name %s "
4941
5274
      "from dict cache for table %s",
4942
 
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
 
5275
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
4943
5276
      prebuilt->table->name);
4944
5277
  }
4945
5278
 
4965
5298
  prebuilt->index = innobase_get_index(keynr);
4966
5299
 
4967
5300
  if (UNIV_UNLIKELY(!prebuilt->index)) {
4968
 
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
 
5301
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
4969
5302
          keynr);
4970
5303
    prebuilt->index_usable = FALSE;
4971
5304
    return(1);
5331
5664
  table. */
5332
5665
 
5333
5666
  if (len != ref_length) {
5334
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5667
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
5335
5668
        (ulong) len, (ulong) ref_length);
5336
5669
  }
5337
5670
}
5387
5720
 
5388
5721
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5389
5722
                  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
 
5390
5738
    if (field->null_ptr) {
5391
5739
      nulls_allowed = 0;
5392
5740
    } else {
5409
5757
        /* in data0type.h we assume that the
5410
5758
        number fits in one byte in prtype */
5411
5759
        push_warning_printf(
5412
 
          (Session*) trx->mysql_thd,
 
5760
          trx->mysql_thd,
5413
5761
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5414
5762
          ER_CANT_CREATE_TABLE,
5415
5763
          "In InnoDB, charset-collation codes"
5444
5792
    if (dict_col_name_is_reserved(field->field_name)){
5445
5793
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5446
5794
 
 
5795
  err_col:
5447
5796
      dict_mem_table_free(table);
5448
5797
      trx_commit_for_mysql(trx);
5449
5798
 
5466
5815
 
5467
5816
        if (error == DB_DUPLICATE_KEY) {
5468
5817
                char buf[100];
5469
 
                innobase_convert_identifier(buf, sizeof buf,
5470
 
                                            table_name, strlen(table_name),
5471
 
                                            trx->mysql_thd, TRUE);
 
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';
5472
5823
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5473
5824
        }
5474
5825
 
5572
5923
        || col_type == DATA_FLOAT
5573
5924
        || col_type == DATA_DOUBLE
5574
5925
        || col_type == DATA_DECIMAL) {
5575
 
        errmsg_printf(ERRMSG_LVL_ERROR, 
 
5926
        errmsg_printf(error::ERROR, 
5576
5927
          "MySQL is trying to create a column "
5577
5928
          "prefix index field, on an "
5578
5929
          "inappropriate data type. Table "
5672
6023
/*================*/
5673
6024
  Session         &session, /*!< in: Session */
5674
6025
  Table&    form,   /*!< in: information on table columns and indexes */
5675
 
        const TableIdentifier &identifier,
 
6026
        const identifier::Table &identifier,
5676
6027
        message::Table& create_proto)
5677
6028
{
5678
6029
  int   error;
5681
6032
  trx_t*    trx;
5682
6033
  int   primary_key_no;
5683
6034
  uint    i;
5684
 
  char    name2[FN_REFLEN];
5685
 
  char    norm_name[FN_REFLEN];
5686
6035
  ib_int64_t  auto_inc_value;
5687
6036
  ulint   iflags;
5688
6037
  /* Cache the value of innodb_file_format, in case it is
5689
6038
    modified by another thread while the table is being created. */
5690
6039
  const ulint file_format = srv_file_format;
5691
6040
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
5692
 
 
5693
 
  const char *table_name= identifier.getPath().c_str();
 
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
  }
5694
6051
 
5695
6052
  if (form.getShare()->sizeFields() > 1000) {
5696
6053
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
5713
6070
 
5714
6071
  srv_lower_case_table_names = TRUE;
5715
6072
 
5716
 
  strcpy(name2, table_name);
5717
 
 
5718
 
  normalize_table_name(norm_name, name2);
5719
 
 
5720
6073
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
5721
6074
    or lock waits can happen in it during a table create operation.
5722
6075
    Drop table etc. do this latching in row0mysql.c. */
5781
6134
# error "DICT_TF_ZSSIZE_MAX < 1"
5782
6135
#endif
5783
6136
 
5784
 
    if (SessionVAR(&session, strict_mode))
 
6137
    if (strict_mode)
5785
6138
    {
5786
6139
      if (! srv_file_per_table)
5787
6140
      {
5808
6161
                   (int) form.getShare()->getPrimaryKey() :
5809
6162
                   -1);
5810
6163
 
5811
 
  /* Our function row_get_mysql_key_number_for_index assumes
 
6164
  /* Our function innobase_get_mysql_key_number_for_index assumes
5812
6165
    the primary key is always number 0, if it exists */
5813
6166
 
5814
6167
  assert(primary_key_no == -1 || primary_key_no == 0);
5824
6177
  if (lex_identified_temp_table)
5825
6178
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
5826
6179
 
5827
 
  error= create_table_def(trx, &form, norm_name,
5828
 
                          lex_identified_temp_table ? name2 : NULL,
 
6180
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
 
6181
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
5829
6182
                          iflags);
5830
6183
 
5831
 
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
6184
  session.setXaId(trx->id);
5832
6185
 
5833
6186
  if (error) {
5834
6187
    goto cleanup;
5841
6194
      order the rows by their row id which is internally generated
5842
6195
      by InnoDB */
5843
6196
 
5844
 
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
 
6197
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
5845
6198
    if (error) {
5846
6199
      goto cleanup;
5847
6200
    }
5849
6202
 
5850
6203
  if (primary_key_no != -1) {
5851
6204
    /* In InnoDB the clustered index must always be created first */
5852
 
    if ((error = create_index(trx, &form, iflags, norm_name,
 
6205
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
5853
6206
                              (uint) primary_key_no))) {
5854
6207
      goto cleanup;
5855
6208
    }
5858
6211
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
5859
6212
    if (i != (uint) primary_key_no) {
5860
6213
 
5861
 
      if ((error = create_index(trx, &form, iflags, norm_name,
 
6214
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
5862
6215
                                i))) {
5863
6216
        goto cleanup;
5864
6217
      }
5865
6218
    }
5866
6219
  }
5867
6220
 
5868
 
  if (trx->mysql_query_str) {
 
6221
  stmt= session.getQueryStringCopy(stmt_len);
 
6222
 
 
6223
  if (stmt) {
5869
6224
    string generated_create_table;
5870
 
    const char *query= trx->mysql_query_str;
 
6225
    const char *query= stmt;
5871
6226
 
5872
 
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
 
6227
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
5873
6228
    {
5874
6229
      message::transformTableDefinitionToSql(create_proto,
5875
6230
                                             generated_create_table,
5878
6233
    }
5879
6234
 
5880
6235
    error = row_table_add_foreign_constraints(trx,
5881
 
                                              query,
5882
 
                                              norm_name,
 
6236
                                              query, strlen(query),
 
6237
                                              identifier.getKeyPath().c_str(),
5883
6238
                                              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
    }
5884
6261
 
5885
6262
    error = convert_error_code_to_mysql(error, iflags, NULL);
5886
6263
 
5899
6276
 
5900
6277
  log_buffer_flush_to_disk();
5901
6278
 
5902
 
  innobase_table = dict_table_get(norm_name, FALSE);
 
6279
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
5903
6280
 
5904
6281
  assert(innobase_table != 0);
5905
6282
 
5907
6284
    /* We update the highest file format in the system table
5908
6285
      space, if this table has higher file format setting. */
5909
6286
 
5910
 
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
5911
 
                                    dict_table_get_format(innobase_table));
 
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;
5912
6292
  }
5913
6293
 
5914
6294
  /* Note: We can't call update_session() as prebuilt will not be
5919
6299
    does a table copy too. */
5920
6300
 
5921
6301
  if ((create_proto.options().has_auto_increment_value()
5922
 
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
5923
 
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
 
6302
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
 
6303
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
5924
6304
      && create_proto.options().auto_increment_value() != 0) {
5925
6305
 
5926
6306
    /* Query was one of :
5948
6328
 
5949
6329
  if (lex_identified_temp_table)
5950
6330
  {
5951
 
    session.storeTableMessage(identifier, create_proto);
 
6331
    session.getMessageCache().storeTableMessage(identifier, create_proto);
5952
6332
  }
5953
6333
  else
5954
6334
  {
6013
6393
 
6014
6394
  update_session(getTable()->in_use);
6015
6395
 
6016
 
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
 
6396
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
6017
6397
  fallback:
6018
6398
    /* We only handle TRUNCATE TABLE t as a special case.
6019
6399
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6047
6427
InnobaseEngine::doDropTable(
6048
6428
/*======================*/
6049
6429
        Session &session,
6050
 
        const TableIdentifier &identifier)
 
6430
        const identifier::Table &identifier)
6051
6431
{
6052
6432
  int error;
6053
6433
  trx_t*  parent_trx;
6054
6434
  trx_t*  trx;
6055
 
  char  norm_name[1000];
6056
6435
 
6057
6436
  ut_a(identifier.getPath().length() < 1000);
6058
6437
 
6059
 
  /* Strangely, MySQL passes the table name without the '.frm'
6060
 
    extension, in contrast to ::create */
6061
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
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
  }
6062
6445
 
6063
6446
  /* Get the transaction associated with the current session, or create one
6064
6447
    if not yet created */
6076
6459
 
6077
6460
  /* Drop the table in InnoDB */
6078
6461
 
6079
 
  error = row_drop_table_for_mysql(norm_name, trx,
6080
 
                                   session_sql_command(&session)
 
6462
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
 
6463
                                   session.getSqlCommand()
6081
6464
                                   == SQLCOM_DROP_DB);
6082
6465
 
6083
 
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
6466
  session.setXaId(trx->id);
6084
6467
 
6085
6468
  /* Flush the log to reduce probability that the .frm files and
6086
6469
    the InnoDB data dictionary get out-of-sync if the user runs
6104
6487
  {
6105
6488
    if (identifier.getType() == message::Table::TEMPORARY)
6106
6489
    {
6107
 
      session.removeTableMessage(identifier);
6108
 
      ulint sql_command = session_sql_command(&session);
 
6490
      session.getMessageCache().removeTableMessage(identifier);
 
6491
      ulint sql_command = session.getSqlCommand();
6109
6492
 
6110
6493
      // If this was the final removal to an alter table then we will need
6111
6494
      // to remove the .dfe that was left behind.
6138
6521
bool
6139
6522
InnobaseEngine::doDropSchema(
6140
6523
/*===================*/
6141
 
                             const SchemaIdentifier &identifier)
 
6524
                             const identifier::Schema &identifier)
6142
6525
    /*!< in: database path; inside InnoDB the name
6143
6526
      of the last directory in the path is used as
6144
6527
      the database name: for example, in 'mysql/data/test'
6188
6571
 
6189
6572
void InnobaseEngine::dropTemporarySchema()
6190
6573
{
6191
 
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6574
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
6192
6575
  trx_t*  trx= NULL;
6193
6576
  string schema_path(GLOBAL_TEMPORARY_EXT);
6194
6577
 
6197
6580
  trx = trx_allocate_for_mysql();
6198
6581
 
6199
6582
  trx->mysql_thd = NULL;
6200
 
  trx->mysql_query_str = NULL;
6201
6583
 
6202
6584
  trx->check_foreigns = false;
6203
6585
  trx->check_unique_secondary = false;
6226
6608
innobase_rename_table(
6227
6609
/*==================*/
6228
6610
  trx_t*    trx,  /*!< in: transaction */
6229
 
  const char* from, /*!< in: old name of the table */
6230
 
  const char* to, /*!< in: new name of the table */
 
6611
  const identifier::Table &from,
 
6612
  const identifier::Table &to,
6231
6613
  ibool   lock_and_commit)
6232
6614
        /*!< in: TRUE=lock data dictionary and commit */
6233
6615
{
6234
6616
  int error;
6235
 
  char norm_to[FN_REFLEN];
6236
 
  char norm_from[FN_REFLEN];
6237
6617
 
6238
6618
  srv_lower_case_table_names = TRUE;
6239
6619
 
6240
 
  normalize_table_name(norm_to, to);
6241
 
  normalize_table_name(norm_from, from);
6242
 
 
6243
6620
  /* Serialize data dictionary operations with dictionary mutex:
6244
6621
  no deadlocks can occur then in these operations */
6245
6622
 
6247
6624
    row_mysql_lock_data_dictionary(trx);
6248
6625
  }
6249
6626
 
6250
 
  error = row_rename_table_for_mysql(
6251
 
    norm_from, norm_to, trx, lock_and_commit);
 
6627
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
6252
6628
 
6253
6629
  if (error != DB_SUCCESS) {
6254
6630
    FILE* ef = dict_foreign_err_file;
6255
6631
 
6256
6632
    fputs("InnoDB: Renaming table ", ef);
6257
 
    ut_print_name(ef, trx, TRUE, norm_from);
 
6633
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
6258
6634
    fputs(" to ", ef);
6259
 
    ut_print_name(ef, trx, TRUE, norm_to);
 
6635
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
6260
6636
    fputs(" failed!\n", ef);
6261
6637
  }
6262
6638
 
6275
6651
/*********************************************************************//**
6276
6652
Renames an InnoDB table.
6277
6653
@return 0 or error code */
6278
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
 
6654
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
6279
6655
{
6280
6656
  // A temp table alter table/rename is a shallow rename and only the
6281
6657
  // definition needs to be updated.
6282
6658
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6283
6659
  {
6284
 
    session.renameTableMessage(from, to);
 
6660
    session.getMessageCache().renameTableMessage(from, to);
6285
6661
    return 0;
6286
6662
  }
6287
6663
 
6301
6677
 
6302
6678
  trx = innobase_trx_allocate(&session);
6303
6679
 
6304
 
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
 
6680
  error = innobase_rename_table(trx, from, to, TRUE);
6305
6681
 
6306
 
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
 
6682
  session.setXaId(trx->id);
6307
6683
 
6308
6684
  /* Tell the InnoDB server that there might be work for
6309
6685
    utility threads: */
6326
6702
     is the one we are trying to rename to) and return the generic
6327
6703
     error code. */
6328
6704
  if (error == (int) DB_DUPLICATE_KEY) {
6329
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
 
6705
    my_error(ER_TABLE_EXISTS_ERROR, to);
6330
6706
    error = DB_ERROR;
6331
6707
  }
6332
6708
 
6357
6733
  KeyInfo*    key;
6358
6734
  dict_index_t* index;
6359
6735
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6360
 
              getTable()->getShare()->stored_rec_length
 
6736
              getTable()->getShare()->sizeStoredRecord()
6361
6737
          + getTable()->getShare()->max_key_length + 100);
6362
 
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
 
6738
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
6363
6739
          + getTable()->getShare()->max_key_length + 100;
6364
6740
  dtuple_t* range_start;
6365
6741
  dtuple_t* range_end;
6381
6757
 
6382
6758
  key = &getTable()->key_info[active_index];
6383
6759
 
6384
 
  index = dict_table_get_index_on_name(prebuilt->table, getTable()->getShare()->getTableProto()->indexes(active_index).name().c_str());
6385
 
 
6386
 
  /* MySQL knows about this index and so we must be able to find it.*/
6387
 
  ut_a(index);
 
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
  }
6388
6774
 
6389
6775
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6390
6776
            + sizeof(dtuple_t)));
6429
6815
 
6430
6816
  mem_heap_free(heap);
6431
6817
 
 
6818
func_exit:
6432
6819
  free(key_val_buff2);
6433
6820
 
6434
6821
  prebuilt->trx->op_info = (char*)"";
6458
6845
  dict_index_t* index;
6459
6846
  uint64_t  estimate;
6460
6847
  uint64_t  local_data_file_length;
 
6848
  ulint stat_n_leaf_pages;
6461
6849
 
6462
6850
  /* We do not know if MySQL can call this function before calling
6463
6851
  external_lock(). To be safe, update the session of the current table
6475
6863
 
6476
6864
  index = dict_table_get_first_index(prebuilt->table);
6477
6865
 
6478
 
  ut_a(index->stat_n_leaf_pages > 0);
 
6866
  stat_n_leaf_pages = index->stat_n_leaf_pages;
 
6867
 
 
6868
  ut_a(stat_n_leaf_pages > 0);
6479
6869
 
6480
6870
  local_data_file_length =
6481
 
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6871
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6482
6872
 
6483
6873
 
6484
6874
  /* Calculate a minimum length for a clustered index record and from
6551
6941
}
6552
6942
 
6553
6943
/*********************************************************************//**
 
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
/*********************************************************************//**
6554
7045
Returns statistics information of the table to the MySQL interpreter,
6555
7046
in various fields of the handle object. */
6556
7047
UNIV_INTERN
6563
7054
  dict_index_t* index;
6564
7055
  ha_rows   rec_per_key;
6565
7056
  ib_int64_t  n_rows;
6566
 
  ulong   j;
6567
 
  ulong   i;
6568
7057
  os_file_stat_t  stat_info;
6569
7058
 
6570
7059
  /* If we are forcing recovery at a high level, we will suppress
6571
7060
  statistics calculation on tables, because that may crash the
6572
7061
  server if an index is badly corrupted. */
6573
7062
 
6574
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
6575
 
 
6576
 
    /* We return success (0) instead of HA_ERR_CRASHED,
6577
 
    because we want MySQL to process this query and not
6578
 
    stop, like it would do if it received the error code
6579
 
    HA_ERR_CRASHED. */
6580
 
 
6581
 
    return(0);
6582
 
  }
6583
 
 
6584
7063
  /* We do not know if MySQL can call this function before calling
6585
7064
  external_lock(). To be safe, update the session of the current table
6586
7065
  handle. */
6602
7081
 
6603
7082
    prebuilt->trx->op_info = "updating table statistics";
6604
7083
 
6605
 
    dict_update_statistics(ib_table);
 
7084
    dict_update_statistics(ib_table,
 
7085
                           FALSE /* update even if stats
 
7086
                                    are initialized */);
 
7087
 
6606
7088
 
6607
7089
    prebuilt->trx->op_info = "returning various info to MySQL";
6608
7090
 
6619
7101
  }
6620
7102
 
6621
7103
  if (flag & HA_STATUS_VARIABLE) {
 
7104
 
 
7105
    dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7106
 
6622
7107
    n_rows = ib_table->stat_n_rows;
6623
7108
 
6624
7109
    /* Because we do not protect stat_n_rows by any mutex in a
6646
7131
    n_rows can not be 0 unless the table is empty, set to 1
6647
7132
    instead. The original problem of bug#29507 is actually
6648
7133
    fixed in the server code. */
6649
 
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
 
7134
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
6650
7135
 
6651
7136
      n_rows = 1;
6652
7137
 
6668
7153
        ib_table->stat_sum_of_other_index_sizes)
6669
7154
          * UNIV_PAGE_SIZE;
6670
7155
 
 
7156
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
 
7157
 
6671
7158
    /* Since fsp_get_available_space_in_free_extents() is
6672
7159
    acquiring latches inside InnoDB, we do not call it if we
6673
7160
    are asked by MySQL to avoid locking. Another reason to
6674
7161
    avoid the call is that it uses quite a lot of CPU.
6675
 
    See Bug#38185.
6676
 
    We do not update delete_length if no locking is requested
6677
 
    so the "old" value can remain. delete_length is initialized
6678
 
    to 0 in the ha_statistics' constructor. */
6679
 
    if (!(flag & HA_STATUS_NO_LOCK)) {
6680
 
 
6681
 
      /* lock the data dictionary to avoid races with
6682
 
      ibd_file_missing and tablespace_discarded */
6683
 
      row_mysql_lock_data_dictionary(prebuilt->trx);
6684
 
 
6685
 
      /* ib_table->space must be an existent tablespace */
6686
 
      if (!ib_table->ibd_file_missing
6687
 
          && !ib_table->tablespace_discarded) {
6688
 
 
6689
 
        stats.delete_length =
6690
 
          fsp_get_available_space_in_free_extents(
6691
 
            ib_table->space) * 1024;
6692
 
      } else {
6693
 
 
 
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) {
6694
7179
        Session*  session;
6695
7180
 
6696
7181
        session= getTable()->in_use;
6708
7193
          ib_table->name);
6709
7194
 
6710
7195
        stats.delete_length = 0;
 
7196
      } else {
 
7197
        stats.delete_length = avail_space * 1024;
6711
7198
      }
6712
 
 
6713
 
      row_mysql_unlock_data_dictionary(prebuilt->trx);
6714
7199
    }
6715
7200
 
6716
7201
    stats.check_time = 0;
6723
7208
  }
6724
7209
 
6725
7210
  if (flag & HA_STATUS_CONST) {
6726
 
    index = dict_table_get_first_index(ib_table);
 
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;
6727
7216
 
6728
 
    if (prebuilt->clust_index_was_generated) {
6729
 
      index = dict_table_get_next_index(index);
 
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);
6730
7224
    }
6731
7225
 
 
7226
    dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7227
 
6732
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
 
6733
7237
      if (index == NULL) {
6734
 
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
 
7238
        errmsg_printf(error::ERROR, "Table %s contains fewer "
6735
7239
            "indexes inside InnoDB than "
6736
7240
            "are defined in the MySQL "
6737
7241
            ".frm file. Have you mixed up "
6746
7250
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
6747
7251
 
6748
7252
        if (j + 1 > index->n_uniq) {
6749
 
          errmsg_printf(ERRMSG_LVL_ERROR, 
 
7253
          errmsg_printf(error::ERROR, 
6750
7254
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
6751
7255
"statistics for %lu columns. Have you mixed up .frm files from different "
6752
7256
"installations? "
6781
7285
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
6782
7286
          (ulong) rec_per_key;
6783
7287
      }
6784
 
 
6785
 
      index = dict_table_get_next_index(index);
6786
7288
    }
 
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;
6787
7295
  }
6788
7296
 
6789
7297
  if (flag & HA_STATUS_ERRKEY) {
6796
7304
 
6797
7305
    if (err_index) {
6798
7306
      errkey = (unsigned int)
6799
 
        row_get_mysql_key_number_for_index(err_index);
 
7307
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
 
7308
                                                err_index);
6800
7309
    } else {
6801
7310
      errkey = (unsigned int) prebuilt->trx->error_key_num;
6802
7311
    }
6806
7315
    stats.auto_increment_value = innobase_peek_autoinc();
6807
7316
  }
6808
7317
 
 
7318
func_exit:
6809
7319
  prebuilt->trx->op_info = (char*)"";
6810
7320
 
6811
7321
  return(0);
6821
7331
/*=================*/
6822
7332
  Session*)   /*!< in: connection thread handle */
6823
7333
{
6824
 
  /* Serialize ANALYZE TABLE inside InnoDB, see
6825
 
     Bug#38996 Race condition in ANALYZE TABLE */
6826
 
  pthread_mutex_lock(&analyze_mutex);
6827
 
 
6828
7334
  /* Simply call ::info() with all the flags */
6829
7335
  info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
6830
7336
 
6831
 
  pthread_mutex_unlock(&analyze_mutex);
6832
 
 
6833
7337
  return(0);
6834
7338
}
6835
7339
 
6844
7348
/*===============*/
6845
7349
  Session*  session)  /*!< in: user thread handle */
6846
7350
{
6847
 
  ulint   ret;
 
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;
6848
7356
 
6849
7357
  assert(session == getTable()->in_use);
6850
7358
  ut_a(prebuilt->trx);
6858
7366
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
6859
7367
  }
6860
7368
 
6861
 
  ret = row_check_table_for_mysql(prebuilt);
6862
 
 
6863
 
  switch (ret) {
6864
 
  case DB_SUCCESS:
6865
 
    return(HA_ADMIN_OK);
6866
 
  case DB_INTERRUPTED:
6867
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
6868
 
    return(-1);
6869
 
  default:
 
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);
6870
7382
    return(HA_ADMIN_CORRUPT);
6871
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);
6872
7503
}
6873
7504
 
6874
7505
/*************************************************************//**
6986
7617
  flen = ftell(srv_dict_tmpfile);
6987
7618
  if (flen < 0) {
6988
7619
    flen = 0;
6989
 
  } else if (flen > 64000 - 1) {
6990
 
    flen = 64000 - 1;
6991
7620
  }
6992
7621
 
6993
7622
  /* allocate buffer for the string, and
7047
7676
      i++;
7048
7677
    }
7049
7678
    db_name[i] = 0;
7050
 
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
 
7679
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
7051
7680
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7052
7681
 
7053
7682
    /* Table name */
7054
7683
    tmp_buff += i + 1;
7055
 
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7684
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7056
7685
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7057
7686
 
7058
7687
    /** Foreign Fields **/
7130
7759
                              tmp_foreign_fields, tmp_referenced_fields);
7131
7760
 
7132
7761
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7133
 
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
 
7762
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
7134
7763
    f_key_list->push_back(pf_key_info);
7135
7764
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7136
7765
  }
7385
8014
{
7386
8015
  trx_t*      trx;
7387
8016
  static const char truncated_msg[] = "... truncated...\n";
7388
 
  const long    MAX_STATUS_SIZE = 64000;
 
8017
  const long    MAX_STATUS_SIZE = 1048576;
7389
8018
  ulint     trx_list_start = ULINT_UNDEFINED;
7390
8019
  ulint     trx_list_end = ULINT_UNDEFINED;
7391
8020
 
7403
8032
 
7404
8033
  mutex_enter(&srv_monitor_file_mutex);
7405
8034
  rewind(srv_monitor_file);
7406
 
  srv_printf_innodb_monitor(srv_monitor_file,
 
8035
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
7407
8036
        &trx_list_start, &trx_list_end);
7408
8037
  flen = ftell(srv_monitor_file);
7409
8038
  os_file_set_eof(srv_monitor_file);
7414
8043
 
7415
8044
  if (flen > MAX_STATUS_SIZE) {
7416
8045
    usable_len = MAX_STATUS_SIZE;
 
8046
    srv_truncated_status_writes++;
7417
8047
  } else {
7418
8048
    usable_len = flen;
7419
8049
  }
7449
8079
 
7450
8080
  mutex_exit(&srv_monitor_file_mutex);
7451
8081
 
7452
 
  bool result = FALSE;
 
8082
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
8083
             STRING_WITH_LEN(""), str, flen);
7453
8084
 
7454
 
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
7455
 
      STRING_WITH_LEN(""), str, flen)) {
7456
 
    result= TRUE;
7457
 
  }
7458
8085
  free(str);
7459
8086
 
7460
8087
  return(FALSE);
7461
8088
}
7462
8089
 
7463
8090
/************************************************************************//**
7464
 
Implements the SHOW MUTEX STATUS command. . */
 
8091
Implements the SHOW MUTEX STATUS command.
 
8092
@return true on failure false on success*/
7465
8093
static
7466
8094
bool
7467
8095
innodb_mutex_show_status(
7469
8097
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
7470
8098
  Session*  session,  /*!< in: the MySQL query thread of the
7471
8099
          caller */
7472
 
  stat_print_fn*  stat_print)
 
8100
  stat_print_fn*  stat_print)   /*!< in: function for printing
 
8101
                                        statistics */
7473
8102
{
7474
8103
  char buf1[IO_SIZE], buf2[IO_SIZE];
7475
8104
  mutex_t*  mutex;
7476
8105
  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;
7477
8110
#ifdef UNIV_DEBUG
7478
8111
  ulint   rw_lock_count= 0;
7479
8112
  ulint   rw_lock_count_spin_loop= 0;
7487
8120
 
7488
8121
  mutex_enter(&mutex_list_mutex);
7489
8122
 
7490
 
  mutex = UT_LIST_GET_FIRST(mutex_list);
7491
 
 
7492
 
  while (mutex != NULL) {
7493
 
    if (mutex->count_os_wait == 0
7494
 
        || buf_pool_is_block_mutex(mutex)) {
7495
 
      goto next_mutex;
 
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;
7496
8134
    }
7497
8135
#ifdef UNIV_DEBUG
7498
8136
    if (mutex->mutex_type != 1) {
7519
8157
          return(1);
7520
8158
        }
7521
8159
      }
7522
 
    }
7523
 
    else {
 
8160
    } else {
7524
8161
      rw_lock_count += mutex->count_using;
7525
8162
      rw_lock_count_spin_loop += mutex->count_spin_loop;
7526
8163
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
7532
8169
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
7533
8170
          mutex->cfile_name, (ulong) mutex->cline);
7534
8171
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
7535
 
          mutex->count_os_wait);
 
8172
                      (ulong) mutex->count_os_wait);
7536
8173
 
7537
8174
    if (stat_print(session, innobase_engine_name,
7538
8175
             engine_name_len, buf1, buf1len,
7541
8178
      return(1);
7542
8179
    }
7543
8180
#endif /* UNIV_DEBUG */
7544
 
 
7545
 
next_mutex:
7546
 
    mutex = UT_LIST_GET_NEXT(list, mutex);
 
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
    }
7547
8198
  }
7548
8199
 
7549
8200
  mutex_exit(&mutex_list_mutex);
7550
8201
 
7551
8202
  mutex_enter(&rw_lock_list_mutex);
7552
8203
 
7553
 
  lock = UT_LIST_GET_FIRST(rw_lock_list);
7554
 
 
7555
 
  while (lock != NULL) {
7556
 
    if (lock->count_os_wait
7557
 
                    && !buf_pool_is_block_lock(lock)) {
7558
 
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
7559
 
                                    lock->cfile_name, (unsigned long) lock->cline);
7560
 
      buf2len= snprintf(buf2, sizeof(buf2),
7561
 
                                    "os_waits=%lu", lock->count_os_wait);
7562
 
 
7563
 
      if (stat_print(session, innobase_engine_name,
7564
 
               engine_name_len, buf1, buf1len,
7565
 
               buf2, buf2len)) {
7566
 
        mutex_exit(&rw_lock_list_mutex);
7567
 
        return(1);
7568
 
      }
7569
 
    }
7570
 
    lock = UT_LIST_GET_NEXT(list, lock);
 
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
    }
7571
8244
  }
7572
8245
 
7573
8246
  mutex_exit(&rw_lock_list_mutex);
7574
8247
 
7575
8248
#ifdef UNIV_DEBUG
7576
 
  buf2len= my_snprintf(buf2, sizeof(buf2),
7577
 
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
7578
 
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
7579
 
    rw_lock_count, rw_lock_count_spin_loop,
7580
 
    rw_lock_count_spin_rounds,
7581
 
    rw_lock_count_os_wait, rw_lock_count_os_yield,
7582
 
    (ulong) (rw_lock_wait_time/1000));
 
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));
7583
8258
 
7584
8259
  if (stat_print(session, innobase_engine_name, engine_name_len,
7585
8260
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
7614
8289
static INNOBASE_SHARE* get_share(const char* table_name)
7615
8290
{
7616
8291
  INNOBASE_SHARE *share;
7617
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8292
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
7618
8293
 
7619
8294
  ulint fold = ut_fold_string(table_name);
7620
8295
 
7633
8308
          innobase_open_tables, fold, share);
7634
8309
 
7635
8310
    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;
7636
8316
  }
7637
8317
 
7638
8318
  share->use_count++;
7639
 
  pthread_mutex_unlock(&innobase_share_mutex);
7640
8319
 
7641
8320
  return(share);
7642
8321
}
7643
8322
 
7644
8323
static void free_share(INNOBASE_SHARE* share)
7645
8324
{
7646
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8325
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
7647
8326
 
7648
8327
#ifdef UNIV_DEBUG
7649
8328
  INNOBASE_SHARE* share2;
7663
8342
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
7664
8343
          innobase_open_tables, fold, share);
7665
8344
    share->lock.deinit();
 
8345
 
 
8346
    /* Free any memory from index translation table */
 
8347
    free(share->idx_trans_tbl.index_mapping);
 
8348
 
7666
8349
    delete share;
7667
8350
 
7668
8351
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
7669
8352
    shrinks too much */
7670
8353
  }
7671
 
 
7672
 
  pthread_mutex_unlock(&innobase_share_mutex);
7673
8354
}
7674
8355
 
7675
8356
/*****************************************************************//**
7704
8385
  trx = check_trx_exists(session);
7705
8386
 
7706
8387
  assert(EQ_CURRENT_SESSION(session));
7707
 
  const uint32_t sql_command = session_sql_command(session);
 
8388
  const uint32_t sql_command = session->getSqlCommand();
7708
8389
 
7709
8390
  if (sql_command == SQLCOM_DROP_TABLE) {
7710
8391
 
7740
8421
    isolation_level = trx->isolation_level;
7741
8422
 
7742
8423
    if ((srv_locks_unsafe_for_binlog
7743
 
         || isolation_level == TRX_ISO_READ_COMMITTED)
 
8424
         || isolation_level <= TRX_ISO_READ_COMMITTED)
7744
8425
        && isolation_level != TRX_ISO_SERIALIZABLE
7745
8426
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
7746
8427
        && (sql_command == SQLCOM_INSERT_SELECT
7747
8428
            || sql_command == SQLCOM_REPLACE_SELECT
7748
8429
            || sql_command == SQLCOM_UPDATE
7749
 
            || sql_command == SQLCOM_CREATE_TABLE)) {
 
8430
            || sql_command == SQLCOM_CREATE_TABLE
 
8431
            || sql_command == SQLCOM_SET_OPTION)) {
7750
8432
 
7751
8433
      /* If we either have innobase_locks_unsafe_for_binlog
7752
8434
      option set or this session is using READ COMMITTED
7754
8436
      is not set to serializable and MySQL is doing
7755
8437
      INSERT INTO...SELECT or REPLACE INTO...SELECT
7756
8438
      or UPDATE ... = (SELECT ...) or CREATE  ...
7757
 
      SELECT... without FOR UPDATE or IN SHARE
7758
 
      MODE in select, then we use consistent read
7759
 
      for select. */
 
8439
      SELECT... or SET ... = (SELECT ...) without
 
8440
      FOR UPDATE or IN SHARE MODE in select,
 
8441
      then we use consistent read for select. */
7760
8442
 
7761
8443
      prebuilt->select_lock_type = LOCK_NONE;
7762
8444
      prebuilt->stored_select_lock_type = LOCK_NONE;
7789
8471
 
7790
8472
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
7791
8473
         && lock_type <= TL_WRITE)
7792
 
        && !session_tablespace_op(session)
 
8474
        && ! session->doing_tablespace_operation()
7793
8475
        && sql_command != SQLCOM_TRUNCATE
7794
8476
        && sql_command != SQLCOM_CREATE_TABLE) {
7795
8477
 
7835
8517
  *value = dict_table_autoinc_read(prebuilt->table);
7836
8518
 
7837
8519
  /* It should have been initialized during open. */
7838
 
  ut_a(*value != 0);
 
8520
  if (*value == 0) {
 
8521
    prebuilt->autoinc_error = DB_UNSUPPORTED;
 
8522
    dict_table_autoinc_unlock(prebuilt->table);
 
8523
  }
7839
8524
 
7840
8525
  return(DB_SUCCESS);
7841
8526
}
7842
8527
 
7843
8528
/*******************************************************************//**
7844
 
This function reads the global auto-inc counter. It doesn't use the 
 
8529
This function reads the global auto-inc counter. It doesn't use the
7845
8530
AUTOINC lock even if the lock mode is set to TRADITIONAL.
7846
8531
@return the autoinc value */
7847
8532
UNIV_INTERN
7861
8546
 
7862
8547
  auto_inc = dict_table_autoinc_read(innodb_table);
7863
8548
 
7864
 
  ut_a(auto_inc > 0);
 
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
  }
7865
8553
 
7866
8554
  dict_table_autoinc_unlock(innodb_table);
7867
8555
 
7914
8602
  invoking this method. So we are not sure if it's guaranteed to
7915
8603
  be 0 or not. */
7916
8604
 
 
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
 
7917
8609
  /* Called for the first time ? */
7918
8610
  if (trx->n_autoinc_rows == 0) {
7919
8611
 
7930
8622
  /* Not in the middle of a mult-row INSERT. */
7931
8623
  } else if (prebuilt->autoinc_last_value == 0) {
7932
8624
    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;
7933
8630
  }
7934
8631
 
7935
8632
  *nb_reserved_values = trx->n_autoinc_rows;
7939
8636
    uint64_t  need;
7940
8637
    uint64_t  current;
7941
8638
    uint64_t  next_value;
7942
 
    uint64_t  col_max_value;
7943
 
 
7944
 
    /* We need the upper limit of the col type to check for
7945
 
    whether we update the table autoinc counter or not. */
7946
 
    col_max_value = innobase_get_int_col_max_value(
7947
 
      getTable()->next_number_field);
7948
8639
 
7949
8640
    current = *first_value > col_max_value ? autoinc : *first_value;
7950
8641
    need = *nb_reserved_values * increment;
8012
8703
/* See comment in Cursor.cc */
8013
8704
UNIV_INTERN
8014
8705
bool
8015
 
InnobaseEngine::get_error_message(int, String *buf)
 
8706
InnobaseEngine::get_error_message(int, String *buf) const
8016
8707
{
8017
8708
  trx_t*  trx = check_trx_exists(current_session);
8018
8709
 
8096
8787
finds charset information and returns length of prefix_len characters in the
8097
8788
index field in bytes.
8098
8789
@return number of bytes occupied by the first n characters */
8099
 
extern "C" UNIV_INTERN
8100
 
ulint
8101
 
innobase_get_at_most_n_mbchars(
8102
 
/*===========================*/
8103
 
  ulint charset_id, /*!< in: character set id */
8104
 
  ulint prefix_len, /*!< in: prefix length in bytes of the index
8105
 
        (this has to be divided by mbmaxlen to get the
8106
 
        number of CHARACTERS n in the prefix) */
8107
 
  ulint data_len,   /*!< in: length of the string in bytes */
8108
 
  const char* str); /*!< in: character string */
8109
8790
 
8110
8791
ulint
8111
8792
innobase_get_at_most_n_mbchars(
8189
8870
  trx->detailed_error[0]= '\0';
8190
8871
 
8191
8872
  /* Set the isolation level of the transaction. */
8192
 
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
 
8873
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
8193
8874
}
8194
8875
 
8195
8876
void
8232
8913
    return(0);
8233
8914
  }
8234
8915
 
8235
 
  session->get_xid(reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
 
8916
  session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->xid));
8236
8917
 
8237
8918
  /* Release a possible FIFO ticket and search latch. Since we will
8238
8919
  reserve the kernel mutex, we have to release the search system latch
8276
8957
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8277
8958
{
8278
8959
  trx_t *trx= session_to_trx(session);
8279
 
  return (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
 
8960
  return (trx->id);
8280
8961
}
8281
8962
 
8282
8963
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8283
8964
{
8284
 
  trx_t *trx= innobase_trx_allocate(session);
 
8965
  trx_t*& trx = session_to_trx(session);
 
8966
 
 
8967
  if (trx == NULL)
 
8968
  {
 
8969
    trx = innobase_trx_allocate(session);
 
8970
 
 
8971
    innobase_trx_init(session, trx);
 
8972
  }
8285
8973
 
8286
8974
  mutex_enter(&kernel_mutex);
8287
8975
  trx->id= trx_sys_get_new_trx_id();
8288
8976
  mutex_exit(&kernel_mutex);
8289
8977
 
8290
 
  return (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
 
8978
  uint64_t transaction_id= trx->id;
 
8979
 
 
8980
  return transaction_id;
8291
8981
}
8292
8982
 
8293
8983
/*******************************************************************//**
8401
9091
}
8402
9092
 
8403
9093
/************************************************************//**
8404
 
Validate the file format check value, is it one of "on" or "off",
8405
 
as a side effect it sets the srv_check_file_format_at_startup variable.
8406
 
@return true if config value one of "on" or  "off" */
8407
 
static
8408
 
bool
8409
 
innobase_file_format_check_on_off(
8410
 
/*==============================*/
8411
 
  const char* format_check) /*!< in: parameter value */
8412
 
{
8413
 
  bool    ret = true;
8414
 
 
8415
 
  if (!innobase_strcasecmp(format_check, "off")) {
8416
 
 
8417
 
    /* Set the value to disable checking. */
8418
 
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
8419
 
 
8420
 
  } else if (!innobase_strcasecmp(format_check, "on")) {
8421
 
 
8422
 
    /* Set the value to the lowest supported format. */
8423
 
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
8424
 
  } else {
8425
 
    ret = FALSE;
8426
 
  }
8427
 
 
8428
 
  return(ret);
8429
 
}
8430
 
 
8431
 
/************************************************************//**
8432
9094
Validate the file format check config parameters, as a side effect it
8433
 
sets the srv_check_file_format_at_startup variable.
 
9095
sets the srv_max_file_format_at_startup variable.
8434
9096
@return the format_id if valid config value, otherwise, return -1 */
8435
9097
static
8436
9098
int
8437
9099
innobase_file_format_validate_and_set(
8438
9100
/*================================*/
8439
 
  const char* format_check) /*!< in: parameter value */
 
9101
  const char* format_max) /*!< in: parameter value */
8440
9102
{
8441
9103
  uint    format_id;
8442
9104
 
8443
 
  format_id = innobase_file_format_name_lookup(format_check);
 
9105
  format_id = innobase_file_format_name_lookup(format_max);
8444
9106
 
8445
9107
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
8446
 
    srv_check_file_format_at_startup = format_id;
 
9108
    srv_max_file_format_at_startup = format_id;
8447
9109
    return((int) format_id);
8448
9110
  } else {
8449
9111
    return(-1);
8450
9112
  }
8451
9113
}
8452
9114
 
8453
 
/*************************************************************//**
8454
 
Check if it is a valid file format. This function is registered as
8455
 
a callback with MySQL.
8456
 
@return 0 for valid file format */
8457
 
static
8458
 
int
8459
 
innodb_file_format_name_validate(
8460
 
/*=============================*/
8461
 
  Session*      , /*!< in: thread handle */
8462
 
  drizzle_sys_var*  , /*!< in: pointer to system
8463
 
            variable */
8464
 
  void*       save, /*!< out: immediate result
8465
 
            for update function */
8466
 
  drizzle_value*    value)  /*!< in: incoming string */
8467
 
{
8468
 
  const char* file_format_input;
8469
 
  char    buff[STRING_BUFFER_USUAL_SIZE];
8470
 
  int   len = sizeof(buff);
8471
 
 
8472
 
  ut_a(save != NULL);
8473
 
  ut_a(value != NULL);
8474
 
 
8475
 
  file_format_input = value->val_str(value, buff, &len);
8476
 
 
8477
 
  if (file_format_input != NULL) {
8478
 
    uint  format_id;
8479
 
 
8480
 
    format_id = innobase_file_format_name_lookup(
8481
 
      file_format_input);
8482
 
 
8483
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
8484
 
      /* Save a pointer to the name in the
8485
 
         'file_format_name_map' constant array. */
8486
 
      *static_cast<const char**>(save) =
8487
 
        trx_sys_file_format_id_to_name(format_id);
8488
 
 
8489
 
      return(0);
8490
 
    }
8491
 
  }
8492
 
 
8493
 
  *static_cast<const char**>(save) = NULL;
8494
 
  return(1);
8495
 
}
8496
 
 
8497
 
/****************************************************************//**
8498
 
Update the system variable innodb_file_format using the "saved"
8499
 
value. This function is registered as a callback with MySQL. */
8500
 
static
8501
 
void
8502
 
innodb_file_format_name_update(
8503
 
/*===========================*/
8504
 
  Session*      ,   /*!< in: thread handle */
8505
 
  drizzle_sys_var*  ,   /*!< in: pointer to
8506
 
              system variable */
8507
 
  void*       var_ptr,  /*!< out: where the
8508
 
              formal string goes */
8509
 
  const void*     save)   /*!< in: immediate result
8510
 
              from check function */
8511
 
{
8512
 
  const char* format_name;
8513
 
 
8514
 
  ut_a(var_ptr != NULL);
8515
 
  ut_a(save != NULL);
8516
 
 
8517
 
  format_name = *static_cast<const char*const*>(save);
8518
 
 
8519
 
  if (format_name) {
8520
 
    uint  format_id;
8521
 
 
8522
 
    format_id = innobase_file_format_name_lookup(format_name);
8523
 
 
8524
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
8525
 
      srv_file_format = format_id;
8526
 
    }
8527
 
  }
8528
 
 
8529
 
  *static_cast<const char**>(var_ptr)
8530
 
    = trx_sys_file_format_id_to_name(srv_file_format);
8531
 
}
8532
 
 
8533
 
/*************************************************************//**
8534
 
Check if valid argument to innodb_file_format_check. This
8535
 
function is registered as a callback with MySQL.
8536
 
@return 0 for valid file format */
8537
 
static
8538
 
int
8539
 
innodb_file_format_check_validate(
8540
 
/*==============================*/
8541
 
  Session*      session, /*!< in: thread handle */
8542
 
  drizzle_sys_var*  , /*!< in: pointer to system
8543
 
            variable */
8544
 
  void*       save, /*!< out: immediate result
8545
 
            for update function */
8546
 
  drizzle_value*    value)  /*!< in: incoming string */
8547
 
{
8548
 
  const char* file_format_input;
8549
 
  char    buff[STRING_BUFFER_USUAL_SIZE];
8550
 
  int   len = sizeof(buff);
8551
 
  int   format_id;
8552
 
 
8553
 
  ut_a(save != NULL);
8554
 
  ut_a(value != NULL);
8555
 
 
8556
 
  file_format_input = value->val_str(value, buff, &len);
8557
 
 
8558
 
  if (file_format_input != NULL) {
8559
 
 
8560
 
    /* Check if user set on/off, we want to print a suitable
8561
 
    message if they did so. */
8562
 
 
8563
 
    if (innobase_file_format_check_on_off(file_format_input)) {
8564
 
      push_warning_printf(session,
8565
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
8566
 
                          ER_WRONG_ARGUMENTS,
8567
 
        "InnoDB: invalid innodb_file_format_check "
8568
 
        "value; on/off can only be set at startup or "
8569
 
        "in the configuration file");
8570
 
    } else {
8571
 
      format_id = innobase_file_format_validate_and_set(file_format_input);
8572
 
      if (format_id >= 0) {
8573
 
        /* Save a pointer to the name in the
8574
 
           'file_format_name_map' constant array. */
8575
 
        *static_cast<const char**>(save) =
8576
 
          trx_sys_file_format_id_to_name(
8577
 
                                         (uint)format_id);
8578
 
 
8579
 
        return(0);
8580
 
 
8581
 
      } else {
8582
 
        push_warning_printf(session,
8583
 
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
8584
 
                            ER_WRONG_ARGUMENTS,
8585
 
                            "InnoDB: invalid innodb_file_format_check "
8586
 
                            "value; can be any format up to %s "
8587
 
                            "or its equivalent numeric id",
8588
 
                            trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
8589
 
      }
8590
 
    }
8591
 
  }
8592
 
 
8593
 
  *static_cast<const char**>(save) = NULL;
8594
 
  return(1);
8595
 
}
8596
 
 
8597
 
/****************************************************************//**
8598
 
Update the system variable innodb_file_format_check using the "saved"
8599
 
value. This function is registered as a callback with MySQL. */
8600
 
static
8601
 
void
8602
 
innodb_file_format_check_update(
8603
 
/*============================*/
8604
 
  Session*      session,  /*!< in: thread handle */
8605
 
  drizzle_sys_var*  ,   /*!< in: pointer to
8606
 
              system variable */
8607
 
  void*       var_ptr,  /*!< out: where the
8608
 
              formal string goes */
8609
 
  const void*     save)   /*!< in: immediate result
8610
 
              from check function */
8611
 
{
8612
 
  const char* format_name_in;
8613
 
  const char**  format_name_out;
8614
 
  uint    format_id;
8615
 
 
8616
 
  ut_a(save != NULL);
8617
 
  ut_a(var_ptr != NULL);
8618
 
 
8619
 
  format_name_in = *static_cast<const char*const*>(save);
8620
 
 
8621
 
  if (!format_name_in) {
8622
 
 
8623
 
    return;
8624
 
  }
8625
 
 
8626
 
  format_id = innobase_file_format_name_lookup(format_name_in);
8627
 
 
8628
 
  if (format_id > DICT_TF_FORMAT_MAX) {
8629
 
    /* DEFAULT is "on", which is invalid at runtime. */
8630
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
8631
 
            ER_WRONG_ARGUMENTS,
8632
 
            "Ignoring SET innodb_file_format=%s",
8633
 
            format_name_in);
8634
 
    return;
8635
 
  }
8636
 
 
8637
 
  format_name_out = static_cast<const char**>(var_ptr);
8638
 
 
8639
 
  /* Update the max format id in the system tablespace. */
8640
 
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
8641
 
    ut_print_timestamp(stderr);
8642
 
    fprintf(stderr,
8643
 
      " [Info] InnoDB: the file format in the system "
8644
 
      "tablespace is now set to %s.\n", *format_name_out);
8645
 
  }
8646
 
}
8647
 
 
8648
 
/****************************************************************//**
8649
 
Update the system variable innodb_adaptive_hash_index using the "saved"
8650
 
value. This function is registered as a callback with MySQL. */
8651
 
static
8652
 
void
8653
 
innodb_adaptive_hash_index_update(
8654
 
/*==============================*/
8655
 
  Session*      ,   /*!< in: thread handle */
8656
 
  drizzle_sys_var*  ,   /*!< in: pointer to
8657
 
              system variable */
8658
 
  void*       , /*!< out: where the
8659
 
              formal string goes */
8660
 
  const void*     save)   /*!< in: immediate result
8661
 
              from check function */
8662
 
{
8663
 
  if (*(bool*) save) {
8664
 
    btr_search_enable();
8665
 
  } else {
8666
 
    btr_search_disable();
8667
 
  }
8668
 
}
8669
 
 
8670
 
/****************************************************************//**
8671
 
Update the system variable innodb_old_blocks_pct using the "saved"
8672
 
value. This function is registered as a callback with MySQL. */
8673
 
static
8674
 
void
8675
 
innodb_old_blocks_pct_update(
8676
 
/*=========================*/
8677
 
        Session*                        ,       /*!< in: thread handle */
8678
 
        drizzle_sys_var*        ,       /*!< in: pointer to
8679
 
                                                system variable */
8680
 
        void*                           ,/*!< out: where the
8681
 
                                                formal string goes */
8682
 
        const void*                     save)   /*!< in: immediate result
8683
 
                                                from check function */
8684
 
{
8685
 
        innobase_old_blocks_pct = buf_LRU_old_ratio_update(
8686
 
                *static_cast<const uint*>(save), TRUE);
8687
 
}
8688
 
 
8689
 
/*************************************************************//**
8690
 
Check if it is a valid value of innodb_change_buffering.  This function is
8691
 
registered as a callback with MySQL.
8692
 
@return 0 for valid innodb_change_buffering */
8693
 
static
8694
 
int
8695
 
innodb_change_buffering_validate(
8696
 
/*=============================*/
8697
 
  Session*      , /*!< in: thread handle */
8698
 
  drizzle_sys_var*  , /*!< in: pointer to system
8699
 
            variable */
8700
 
  void*       save, /*!< out: immediate result
8701
 
            for update function */
8702
 
  drizzle_value*    value)  /*!< in: incoming string */
8703
 
{
8704
 
  const char* change_buffering_input;
8705
 
  char    buff[STRING_BUFFER_USUAL_SIZE];
8706
 
  int   len = sizeof(buff);
8707
 
 
8708
 
  ut_a(save != NULL);
8709
 
  ut_a(value != NULL);
8710
 
 
8711
 
  change_buffering_input = value->val_str(value, buff, &len);
8712
 
 
8713
 
  if (change_buffering_input != NULL) {
8714
 
    ulint use;
8715
 
 
8716
 
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
8717
 
         use++) {
8718
 
      if (!innobase_strcasecmp(
8719
 
            change_buffering_input,
8720
 
            innobase_change_buffering_values[use])) {
8721
 
        *(ibuf_use_t*) save = (ibuf_use_t) use;
8722
 
        return(0);
8723
 
      }
8724
 
    }
8725
 
  }
8726
 
 
8727
 
  return(1);
8728
 
}
8729
 
 
8730
 
/****************************************************************//**
8731
 
Update the system variable innodb_change_buffering using the "saved"
8732
 
value. This function is registered as a callback with MySQL. */
8733
 
static
8734
 
void
8735
 
innodb_change_buffering_update(
8736
 
/*===========================*/
8737
 
  Session*      ,   /*!< in: thread handle */
8738
 
  drizzle_sys_var*  ,   /*!< in: pointer to
8739
 
              system variable */
8740
 
  void*       var_ptr,  /*!< out: where the
8741
 
              formal string goes */
8742
 
  const void*     save)   /*!< in: immediate result
8743
 
              from check function */
8744
 
{
8745
 
  ut_a(var_ptr != NULL);
8746
 
  ut_a(save != NULL);
8747
 
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
8748
 
 
8749
 
  ibuf_use = *(const ibuf_use_t*) save;
8750
 
 
8751
 
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
8752
 
}
8753
 
 
8754
 
/* plugin options */
8755
 
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
8756
 
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8757
 
  "Enable InnoDB checksums validation (enabled by default). ",
8758
 
  NULL, NULL, TRUE);
8759
 
 
8760
 
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
8761
 
  PLUGIN_VAR_READONLY,
8762
 
  "The common part for InnoDB table spaces.",
8763
 
  NULL, NULL, NULL);
8764
 
 
8765
 
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
8766
 
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8767
 
  "Enable InnoDB doublewrite buffer (enabled by default). ",
8768
 
  NULL, NULL, TRUE);
8769
 
 
8770
 
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
8771
 
  PLUGIN_VAR_RQCMDARG,
8772
 
  "Number of IOPs the server can do. Tunes the background IO rate",
8773
 
  NULL, NULL, 200, 100, ~0L, 0);
8774
 
 
8775
 
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
8776
 
  PLUGIN_VAR_OPCMDARG,
8777
 
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
8778
 
  "values are 0, 1 (faster)"
8779
 
  " or 2 (fastest - crash-like)"
8780
 
  ".",
8781
 
  NULL, NULL, 1, 0, 2, 0);
8782
 
 
8783
 
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
8784
 
  PLUGIN_VAR_NOCMDARG,
8785
 
  "Stores each InnoDB table to an .ibd file in the database dir.",
8786
 
  NULL, NULL, FALSE);
8787
 
 
8788
 
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
8789
 
  PLUGIN_VAR_RQCMDARG,
8790
 
  "File format to use for new tables in .ibd files.",
8791
 
  innodb_file_format_name_validate,
8792
 
  innodb_file_format_name_update, "Antelope");
8793
 
 
8794
 
/* If a new file format is introduced, the file format
8795
 
name needs to be updated accordingly. Please refer to
8796
 
file_format_name_map[] defined in trx0sys.c for the next
8797
 
file format name. */
8798
 
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
8799
 
  PLUGIN_VAR_OPCMDARG,
8800
 
  "The highest file format in the tablespace.",
8801
 
  innodb_file_format_check_validate,
8802
 
  innodb_file_format_check_update,
8803
 
  "Barracuda");
8804
 
 
8805
 
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
8806
 
  PLUGIN_VAR_OPCMDARG,
8807
 
  "Set to 0 (write and flush once per second),"
8808
 
  " 1 (write and flush at each commit)"
8809
 
  " or 2 (write at commit, flush once per second).",
8810
 
  NULL, NULL, 1, 0, 2, 0);
8811
 
 
8812
 
static DRIZZLE_SYSVAR_STR(flush_method, innobase_file_flush_method,
8813
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8814
 
  "With which method to flush data.", NULL, NULL, NULL);
8815
 
 
8816
 
#ifdef UNIV_LOG_ARCHIVE
8817
 
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
8818
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8819
 
  "Where full logs should be archived.", NULL, NULL, NULL);
8820
 
 
8821
 
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
8822
 
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
8823
 
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
8824
 
#endif /* UNIV_LOG_ARCHIVE */
8825
 
 
8826
 
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
8827
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8828
 
  "Path to InnoDB log files.", NULL, NULL, NULL);
8829
 
 
8830
 
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
8831
 
  PLUGIN_VAR_RQCMDARG,
8832
 
  "Percentage of dirty pages allowed in bufferpool.",
8833
 
  NULL, NULL, 75, 0, 99, 0);
8834
 
 
8835
 
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
8836
 
  PLUGIN_VAR_NOCMDARG,
8837
 
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
8838
 
  NULL, NULL, TRUE);
8839
 
 
8840
 
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
8841
 
  PLUGIN_VAR_RQCMDARG,
8842
 
  "Desired maximum length of the purge queue (0 = no limit)",
8843
 
  NULL, NULL, 0, 0, ~0L, 0);
8844
 
 
8845
 
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
8846
 
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
8847
 
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
8848
 
  NULL, NULL, FALSE);
8849
 
 
8850
 
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
8851
 
  PLUGIN_VAR_RQCMDARG,
8852
 
  "The number of index pages to sample when calculating statistics (default 8)",
8853
 
  NULL, NULL, 8, 1, ~0ULL, 0);
8854
 
 
8855
 
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
8856
 
  PLUGIN_VAR_OPCMDARG,
8857
 
  "Enable InnoDB adaptive hash index (enabled by default).",
8858
 
  NULL, innodb_adaptive_hash_index_update, TRUE);
8859
 
 
8860
 
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
8861
 
  PLUGIN_VAR_RQCMDARG,
8862
 
  "Replication thread delay (ms) on the slave server if "
8863
 
  "innodb_thread_concurrency is reached (0 by default)",
8864
 
  NULL, NULL, 0, 0, ~0UL, 0);
8865
 
 
8866
 
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
8867
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8868
 
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
8869
 
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
8870
 
 
8871
 
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
8872
 
  PLUGIN_VAR_RQCMDARG,
8873
 
  "Data file autoextend increment in megabytes",
8874
 
  NULL, NULL, 8L, 1L, 1000L, 0);
8875
 
 
8876
 
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
8877
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8878
 
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
8879
 
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
8880
 
 
8881
 
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
8882
 
  PLUGIN_VAR_RQCMDARG,
8883
 
  "Helps in performance tuning in heavily concurrent environments.",
8884
 
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
8885
 
 
8886
 
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
8887
 
  PLUGIN_VAR_RQCMDARG,
8888
 
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
8889
 
  NULL, NULL, 500L, 1L, ~0L, 0);
8890
 
 
8891
 
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
8892
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8893
 
  "Number of background read I/O threads in InnoDB.",
8894
 
  NULL, NULL, 4, 1, 64, 0);
8895
 
 
8896
 
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
8897
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8898
 
  "Number of background write I/O threads in InnoDB.",
8899
 
  NULL, NULL, 4, 1, 64, 0);
8900
 
 
8901
 
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
8902
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8903
 
  "Helps to save your data in case the disk image of the database becomes corrupt.",
8904
 
  NULL, NULL, 0, 0, 6, 0);
8905
 
 
8906
 
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
8907
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8908
 
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
8909
 
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
8910
 
 
8911
 
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
8912
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8913
 
  "Size of each log file in a log group.",
8914
 
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
8915
 
 
8916
 
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
8917
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8918
 
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
8919
 
  NULL, NULL, 2, 2, 100, 0);
8920
 
 
8921
 
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
8922
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8923
 
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
8924
 
  NULL, NULL, 1, 1, 10, 0);
8925
 
 
8926
 
static DRIZZLE_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
8927
 
  PLUGIN_VAR_RQCMDARG,
8928
 
  "Percentage of the buffer pool to reserve for 'old' blocks.",
8929
 
  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
8930
 
 
8931
 
static DRIZZLE_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
8932
 
  PLUGIN_VAR_RQCMDARG,
8933
 
  "Move blocks to the 'new' end of the buffer pool if the first access"
8934
 
  " was at least this many milliseconds ago."
8935
 
  " The timeout is disabled if 0 (the default).",
8936
 
  NULL, NULL, 0, 0, UINT32_MAX, 0);
8937
 
 
8938
 
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
8939
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8940
 
  "How many files at the maximum InnoDB keeps open at the same time.",
8941
 
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
8942
 
 
8943
 
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
8944
 
  PLUGIN_VAR_RQCMDARG,
8945
 
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
8946
 
  NULL, NULL, 30L, 0L, ~0L, 0);
8947
 
 
8948
 
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
8949
 
  PLUGIN_VAR_OPCMDARG,
8950
 
  "Maximum delay between polling for a spin lock (6 by default)",
8951
 
  NULL, NULL, 6L, 0L, ~0L, 0);
8952
 
 
8953
 
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
8954
 
  PLUGIN_VAR_RQCMDARG,
8955
 
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
8956
 
  NULL, NULL, 0, 0, 1000, 0);
8957
 
 
8958
 
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
8959
 
  PLUGIN_VAR_RQCMDARG,
8960
 
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
8961
 
  NULL, NULL, 10000L, 0L, ~0L, 0);
8962
 
 
8963
 
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
8964
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8965
 
  "Path to individual files and their sizes.",
8966
 
  NULL, NULL, NULL);
8967
 
 
8968
 
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
8969
 
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
8970
 
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
8971
 
 
8972
 
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
8973
 
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8974
 
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
8975
 
  NULL, NULL, TRUE);
8976
 
 
8977
 
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
8978
 
  PLUGIN_VAR_RQCMDARG,
8979
 
  "Buffer changes to reduce random access: "
8980
 
  "OFF, ON, inserting, deleting, changing, or purging.",
8981
 
  innodb_change_buffering_validate,
8982
 
  innodb_change_buffering_update, NULL);
8983
 
 
8984
 
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
8985
 
  PLUGIN_VAR_RQCMDARG,
8986
 
  "Number of pages that must be accessed sequentially for InnoDB to"
8987
 
  "trigger a readahead.",
8988
 
  NULL, NULL, 56, 0, 64, 0);
 
9115
 
8989
9116
 
8990
9117
static void init_options(drizzled::module::option_context &context)
8991
9118
{
8997
9124
  context("disable-doublewrite",
8998
9125
          "Disable InnoDB doublewrite buffer.");
8999
9126
  context("io-capacity",
9000
 
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
 
9127
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
9001
9128
          "Number of IOPs the server can do. Tunes the background IO rate");
9002
9129
  context("fast-shutdown",
9003
 
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
 
9130
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
9004
9131
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
 
9132
  context("purge-batch-size",
 
9133
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
 
9134
          "Number of UNDO logs to purge in one batch from the history list. "
 
9135
          "Default is 20.");
 
9136
  context("purge-threads",
 
9137
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
 
9138
          "Purge threads can be either 0 or 1. Defalut is 0.");
9005
9139
  context("file-per-table",
9006
9140
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9007
 
          "Stores each InnoDB table to an .ibd file in the database dir.");
 
9141
           "Stores each InnoDB table to an .ibd file in the database dir.");
 
9142
  context("file-format-max",
 
9143
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
 
9144
          "The highest file format in the tablespace.");
 
9145
  context("file-format-check",
 
9146
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
 
9147
          "Whether to perform system file format check.");
9008
9148
  context("file-format",
9009
 
          po::value<string>()->default_value("Antelope"),
 
9149
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
9010
9150
          "File format to use for new tables in .ibd files.");
9011
 
  context("file-format-check",
9012
 
          po::value<string>()->default_value("on"),
9013
 
          "The highest file format in the tablespace.");
9014
9151
  context("flush-log-at-trx-commit",
9015
 
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
 
9152
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9016
9153
          "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).");
9017
9154
  context("flush-method",
9018
9155
          po::value<string>(),
9019
9156
          "With which method to flush data.");
9020
 
#ifdef UNIV_LOG_ARCHIVE
9021
 
  context("log-arch-dir",
9022
 
          po::value<string>(),
9023
 
          "Where full logs should be archived.");
9024
 
  context("log-archive",
9025
 
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
9026
 
          "Set to 1 if you want to have logs archived.");
9027
 
#endif /* UNIV_LOG_ARCHIVE */
9028
9157
  context("log-group-home-dir",
9029
9158
          po::value<string>(),
9030
9159
          "Path to InnoDB log files.");
9031
9160
  context("max-dirty-pages-pct",
9032
 
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
 
9161
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
9033
9162
          "Percentage of dirty pages allowed in bufferpool.");
9034
9163
  context("disable-adaptive-flushing",
9035
9164
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9036
9165
  context("max-purge-lag",
9037
 
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
 
9166
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
9038
9167
          "Desired maximum length of the purge queue (0 = no limit)");
9039
9168
  context("status-file",
9040
9169
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9042
9171
  context("disable-stats-on-metadata",
9043
9172
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9044
9173
  context("stats-sample-pages",
9045
 
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
 
9174
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
9046
9175
          "The number of index pages to sample when calculating statistics (default 8)");
9047
9176
  context("disable-adaptive-hash-index",
9048
9177
          "Enable InnoDB adaptive hash index (enabled by default)");
9049
9178
  context("replication-delay",
9050
 
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
 
9179
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
9051
9180
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9052
9181
  context("additional-mem-pool-size",
9053
 
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
9182
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9054
9183
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9055
9184
  context("autoextend-increment",
9056
 
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
 
9185
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
9057
9186
          "Data file autoextend increment in megabytes");
9058
9187
  context("buffer-pool-size",
9059
 
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
9188
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9060
9189
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
 
9190
  context("buffer-pool-instances",
 
9191
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
 
9192
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
 
9193
 
9061
9194
  context("commit-concurrency",
9062
 
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
 
9195
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
9063
9196
          "Helps in performance tuning in heavily concurrent environments.");
9064
9197
  context("concurrency-tickets",
9065
 
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
 
9198
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
9066
9199
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9067
9200
  context("read-io-threads",
9068
 
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
 
9201
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
9069
9202
          "Number of background read I/O threads in InnoDB.");
9070
9203
  context("write-io-threads",
9071
 
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
 
9204
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
9072
9205
          "Number of background write I/O threads in InnoDB.");
9073
9206
  context("force-recovery",
9074
 
          po::value<long>(&innobase_force_recovery)->default_value(0),
 
9207
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
9075
9208
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9076
9209
  context("log-buffer-size",
9077
 
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
9210
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9078
9211
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9079
9212
  context("log-file-size",
9080
 
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
9213
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
9081
9214
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9082
9215
  context("log-files-in-group",
9083
 
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
 
9216
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
9084
9217
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9085
9218
  context("mirrored-log-groups",
9086
 
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
 
9219
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
9087
9220
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9088
9221
  context("open-files",
9089
 
          po::value<long>(&innobase_open_files)->default_value(300L),
 
9222
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
9090
9223
          "How many files at the maximum InnoDB keeps open at the same time.");
9091
9224
  context("sync-spin-loops",
9092
 
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
 
9225
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
9093
9226
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9094
9227
  context("spin-wait-delay",
9095
 
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
 
9228
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
9096
9229
          "Maximum delay between polling for a spin lock (6 by default)");
9097
9230
  context("thread-concurrency",
9098
 
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
 
9231
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
9099
9232
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9100
9233
  context("thread-sleep-delay",
9101
 
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
 
9234
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
9102
9235
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9103
9236
  context("data-file-path",
9104
9237
          po::value<string>(),
9108
9241
          "InnoDB version");
9109
9242
  context("use-internal-malloc",
9110
9243
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
 
9244
  context("disable-native-aio",
 
9245
          _("Do not use Native AIO library for IO, even if available"));
9111
9246
  context("change-buffering",
9112
 
          po::value<string>(),
 
9247
          po::value<string>(&innobase_change_buffering),
9113
9248
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9114
9249
  context("read-ahead-threshold",
9115
 
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
 
9250
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
9116
9251
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9117
9252
  context("disable-xa",
9118
9253
          "Disable InnoDB support for the XA two-phase commit");
9119
9254
  context("disable-table-locks",
9120
9255
          "Disable InnoDB locking in LOCK TABLES");
9121
9256
  context("strict-mode",
9122
 
          po::value<bool>()->default_value(false)->zero_tokens(),
 
9257
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
9123
9258
          "Use strict mode when evaluating create options.");
 
9259
  context("replication-log",
 
9260
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
 
9261
          _("Enable internal replication log."));
9124
9262
  context("lock-wait-timeout",
9125
 
          po::value<unsigned long>()->default_value(50),
9126
 
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
 
9263
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
 
9264
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
 
9265
  context("old-blocks-pct",
 
9266
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
 
9267
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
 
9268
  context("old-blocks-time",
 
9269
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
 
9270
          _("ove blocks to the 'new' end of the buffer pool if the first access"
 
9271
            " was at least this many milliseconds ago."
 
9272
            " The timeout is disabled if 0 (the default)."));
9127
9273
}
9128
9274
 
9129
 
static drizzle_sys_var* innobase_system_variables[]= {
9130
 
  DRIZZLE_SYSVAR(additional_mem_pool_size),
9131
 
  DRIZZLE_SYSVAR(autoextend_increment),
9132
 
  DRIZZLE_SYSVAR(buffer_pool_size),
9133
 
  DRIZZLE_SYSVAR(checksums),
9134
 
  DRIZZLE_SYSVAR(commit_concurrency),
9135
 
  DRIZZLE_SYSVAR(concurrency_tickets),
9136
 
  DRIZZLE_SYSVAR(data_file_path),
9137
 
  DRIZZLE_SYSVAR(data_home_dir),
9138
 
  DRIZZLE_SYSVAR(doublewrite),
9139
 
  DRIZZLE_SYSVAR(fast_shutdown),
9140
 
  DRIZZLE_SYSVAR(read_io_threads),
9141
 
  DRIZZLE_SYSVAR(write_io_threads),
9142
 
  DRIZZLE_SYSVAR(file_per_table),
9143
 
  DRIZZLE_SYSVAR(file_format),
9144
 
  DRIZZLE_SYSVAR(file_format_check),
9145
 
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
9146
 
  DRIZZLE_SYSVAR(flush_method),
9147
 
  DRIZZLE_SYSVAR(force_recovery),
9148
 
  DRIZZLE_SYSVAR(lock_wait_timeout),
9149
 
#ifdef UNIV_LOG_ARCHIVE
9150
 
  DRIZZLE_SYSVAR(log_arch_dir),
9151
 
  DRIZZLE_SYSVAR(log_archive),
9152
 
#endif /* UNIV_LOG_ARCHIVE */
9153
 
  DRIZZLE_SYSVAR(log_buffer_size),
9154
 
  DRIZZLE_SYSVAR(log_file_size),
9155
 
  DRIZZLE_SYSVAR(log_files_in_group),
9156
 
  DRIZZLE_SYSVAR(log_group_home_dir),
9157
 
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
9158
 
  DRIZZLE_SYSVAR(max_purge_lag),
9159
 
  DRIZZLE_SYSVAR(adaptive_flushing),
9160
 
  DRIZZLE_SYSVAR(mirrored_log_groups),
9161
 
  DRIZZLE_SYSVAR(old_blocks_pct),
9162
 
  DRIZZLE_SYSVAR(old_blocks_time),
9163
 
  DRIZZLE_SYSVAR(open_files),
9164
 
  DRIZZLE_SYSVAR(stats_sample_pages),
9165
 
  DRIZZLE_SYSVAR(adaptive_hash_index),
9166
 
  DRIZZLE_SYSVAR(replication_delay),
9167
 
  DRIZZLE_SYSVAR(status_file),
9168
 
  DRIZZLE_SYSVAR(strict_mode),
9169
 
  DRIZZLE_SYSVAR(support_xa),
9170
 
  DRIZZLE_SYSVAR(sync_spin_loops),
9171
 
  DRIZZLE_SYSVAR(spin_wait_delay),
9172
 
  DRIZZLE_SYSVAR(table_locks),
9173
 
  DRIZZLE_SYSVAR(thread_concurrency),
9174
 
  DRIZZLE_SYSVAR(thread_sleep_delay),
9175
 
  DRIZZLE_SYSVAR(version),
9176
 
  DRIZZLE_SYSVAR(use_sys_malloc),
9177
 
  DRIZZLE_SYSVAR(change_buffering),
9178
 
  DRIZZLE_SYSVAR(read_ahead_threshold),
9179
 
  DRIZZLE_SYSVAR(io_capacity),
9180
 
  NULL
9181
 
};
 
9275
 
9182
9276
 
9183
9277
DRIZZLE_DECLARE_PLUGIN
9184
9278
{
9189
9283
  "Supports transactions, row-level locking, and foreign keys",
9190
9284
  PLUGIN_LICENSE_GPL,
9191
9285
  innobase_init, /* Plugin Init */
9192
 
  innobase_system_variables, /* system variables */
 
9286
  NULL, /* depends */
9193
9287
  init_options /* reserved */
9194
9288
}
9195
9289
DRIZZLE_DECLARE_PLUGIN_END;
9217
9311
  return res;
9218
9312
}
9219
9313
 
9220
 
/** @brief Initialize the default value of innodb_commit_concurrency.
9221
 
 
9222
 
Once InnoDB is running, the innodb_commit_concurrency must not change
9223
 
from zero to nonzero. (Bug #42101)
9224
 
 
9225
 
The initial default value is 0, and without this extra initialization,
9226
 
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
9227
 
to 0, even if it was initially set to nonzero at the command line
9228
 
or configuration file. */
9229
 
static
9230
 
void
9231
 
innobase_commit_concurrency_init_default(void)
9232
 
/*==========================================*/
9233
 
{
9234
 
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
9235
 
    = innobase_commit_concurrency;
9236
 
}
9237
 
 
9238
9314
/***********************************************************************
9239
9315
This function checks each index name for a table against reserved
9240
9316
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9241
9317
this function pushes an warning message to the client, and returns true. */
9242
 
extern "C" UNIV_INTERN
 
9318
UNIV_INTERN
9243
9319
bool
9244
9320
innobase_index_name_is_reserved(
9245
9321
/*============================*/
9259
9335
    if (innobase_strcasecmp(key->name,
9260
9336
                            innobase_index_reserve_name) == 0) {
9261
9337
      /* Push warning to drizzle */
9262
 
      push_warning_printf((Session*)trx->mysql_thd,
 
9338
      push_warning_printf(trx->mysql_thd,
9263
9339
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9264
9340
                          ER_WRONG_NAME_FOR_INDEX,
9265
9341
                          "Cannot Create Index with name "
9285
9361
  ulint   buflen;
9286
9362
  const char* id;
9287
9363
  ulint   idlen;
9288
 
  void*   session;
 
9364
  drizzled::Session *session;
9289
9365
  ibool   file_id;
9290
9366
 
9291
9367
  const char* expected;