~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Andrew Hutchings
  • Date: 2010-10-23 10:43:00 UTC
  • mto: (1874.2.1 merge)
  • mto: This revision was merged to the branch mainline in revision 1876.
  • Revision ID: andrew@linuxjedi.co.uk-20101023104300-90rgyfw2eokcvsp3
Make port 4427 the default for client apps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2000, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
4
 
Copyright (C) 2008, 2009 Google Inc.
5
 
Copyright (C) 2009, Percona Inc.
 
3
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, 2009 Google Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
13
 
Portions of this file contain modifications contributed and copyrighted
14
 
by Percona Inc.. Those modifications are
15
 
gratefully acknowledged and are described briefly in the InnoDB
16
 
documentation. The contributions by Percona Inc. are incorporated with
17
 
their permission, and subject to the conditions contained in the file
18
 
COPYING.Percona.
19
 
 
20
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
30
22
St, Fifth Floor, Boston, MA 02110-1301 USA
31
23
 
32
24
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
49
 
 
50
***********************************************************************/
33
51
 
34
52
/* TODO list for the InnoDB Cursor in 5.0:
35
53
  - fix savepoint functions to use savepoint storage area
60
78
#include "drizzled/table.h"
61
79
#include "drizzled/field/blob.h"
62
80
#include "drizzled/field/varstring.h"
 
81
#include "drizzled/field/timestamp.h"
63
82
#include "drizzled/plugin/xa_storage_engine.h"
64
83
#include "drizzled/plugin/daemon.h"
65
84
#include "drizzled/memory/multi_malloc.h"
71
90
 
72
91
#include <boost/algorithm/string.hpp>
73
92
#include <boost/program_options.hpp>
74
 
#include <boost/scoped_array.hpp>
75
93
#include <boost/filesystem.hpp>
76
94
#include <drizzled/module/option_map.h>
77
95
#include <iostream>
83
101
/** @file ha_innodb.cc */
84
102
 
85
103
/* Include necessary InnoDB headers */
 
104
extern "C" {
86
105
#include "univ.i"
87
106
#include "buf0lru.h"
88
107
#include "btr0sea.h"
101
120
#include "log0log.h"
102
121
#include "lock0lock.h"
103
122
#include "dict0crea.h"
104
 
#include "create_replication.h"
105
123
#include "btr0cur.h"
106
124
#include "btr0btr.h"
107
125
#include "fsp0fsp.h"
114
132
#include "ha_prototypes.h"
115
133
#include "ut0mem.h"
116
134
#include "ibuf0ibuf.h"
 
135
#include "mysql_addons.h"
 
136
}
117
137
 
118
138
#include "ha_innodb.h"
119
139
#include "data_dictionary.h"
120
 
#include "replication_dictionary.h"
121
140
#include "internal_dictionary.h"
122
141
#include "handler0vars.h"
123
142
 
126
145
#include <string>
127
146
 
128
147
#include "plugin/innobase/handler/status_function.h"
129
 
#include "plugin/innobase/handler/replication_log.h"
130
 
 
131
 
#include <google/protobuf/io/zero_copy_stream.h>
132
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
 
#include <google/protobuf/io/coded_stream.h>
134
 
#include <google/protobuf/text_format.h>
135
 
 
136
 
#include <boost/thread/mutex.hpp>
137
148
 
138
149
using namespace std;
139
150
using namespace drizzled;
140
151
 
 
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
 
141
159
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
160
static pthread_mutex_t innobase_share_mutex;
144
161
/** to force correct commit order in binlog */
 
162
static pthread_mutex_t prepare_commit_mutex;
145
163
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
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;
148
168
static bool innodb_inited = 0;
149
169
 
150
170
#define INSIDE_HA_INNOBASE_CC
160
180
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
181
 
162
182
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
164
 
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
 
static open_files_constraint innobase_open_files;
166
 
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
167
 
static mirrored_log_groups_constraint innobase_mirrored_log_groups;
168
 
typedef constrained_check<uint32_t, 100, 2> log_files_in_group_constraint;
169
 
static log_files_in_group_constraint innobase_log_files_in_group;
170
 
typedef constrained_check<uint32_t, 6, 0> force_recovery_constraint;
171
 
force_recovery_constraint innobase_force_recovery;
172
 
typedef constrained_check<size_t, SIZE_MAX, 256*1024, 1024> log_buffer_constraint;
173
 
static log_buffer_constraint innobase_log_buffer_size;
174
 
typedef constrained_check<size_t, SIZE_MAX, 512*1024, 1024> additional_mem_pool_constraint;
175
 
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
176
 
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
177
 
static autoextend_constraint innodb_auto_extend_increment;
178
 
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
179
 
static buffer_pool_constraint innobase_buffer_pool_size;
180
 
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
181
 
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
182
 
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
183
 
static io_capacity_constraint innodb_io_capacity;
184
 
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
185
 
static purge_batch_constraint innodb_purge_batch_size;
186
 
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
187
 
static purge_threads_constraint innodb_n_purge_threads;
188
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
189
 
static trinary_constraint innodb_flush_log_at_trx_commit;
190
 
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
191
 
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
192
 
static uint64_constraint innodb_max_purge_lag;
193
 
static uint64_nonzero_constraint innodb_stats_sample_pages;
194
 
typedef constrained_check<uint32_t, 64, 1> io_threads_constraint;
195
 
static io_threads_constraint innobase_read_io_threads;
196
 
static io_threads_constraint innobase_write_io_threads;
197
 
 
198
 
typedef constrained_check<uint32_t, 1000, 0> concurrency_constraint;
199
 
static concurrency_constraint innobase_commit_concurrency;
200
 
static concurrency_constraint innobase_thread_concurrency;
201
 
static uint32_nonzero_constraint innodb_concurrency_tickets;
202
 
 
203
 
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
204
 
static log_file_constraint innobase_log_file_size;
205
 
 
206
 
static uint64_constraint innodb_replication_delay;
 
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;
207
205
 
208
206
/** Percentage of the buffer pool to reserve for 'old' blocks.
209
207
Connected to buf_LRU_old_ratio. */
210
 
typedef constrained_check<uint32_t, 95, 5> old_blocks_constraint;
211
 
static old_blocks_constraint innobase_old_blocks_pct;
212
 
 
213
 
static uint32_constraint innodb_sync_spin_loops;
214
 
static uint32_constraint innodb_spin_wait_delay;
215
 
static uint32_constraint innodb_thread_sleep_delay;
216
 
 
217
 
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
218
 
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
 
208
static uint innobase_old_blocks_pct;
219
209
 
220
210
/* The default values for the following char* start-up parameters
221
211
are determined in innobase_init below: */
222
212
 
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;
 
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;
233
225
 
234
226
/* Below we have boolean-valued start-up parameters, and their default
235
227
values */
236
228
 
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;
 
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 */
253
234
static my_bool  innobase_use_doublewrite    = TRUE;
254
235
static my_bool  innobase_use_checksums      = TRUE;
255
236
static my_bool  innobase_rollback_on_timeout    = FALSE;
256
237
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;
262
238
 
263
239
static char*  internal_innobase_data_file_path  = NULL;
264
240
 
 
241
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
242
 
265
243
/* The following counter is used to convey information to InnoDB
266
244
about server activity: in selects it is not sensible to call
267
245
srv_active_wake_master_thread after each fetch or search, we only do
279
257
/** Allowed values of innodb_change_buffering */
280
258
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
281
259
  "none",   /* IBUF_USE_NONE */
282
 
  "inserts",    /* IBUF_USE_INSERT */
283
 
  "deletes",    /* IBUF_USE_DELETE_MARK */
284
 
  "changes",    /* IBUF_USE_INSERT_DELETE_MARK */
285
 
  "purges",     /* IBUF_USE_DELETE */
286
 
  "all"         /* IBUF_USE_ALL */
 
260
  "inserts" /* IBUF_USE_INSERT */
287
261
};
288
262
 
289
263
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
333
307
      srv_free_paths_and_sizes();
334
308
      if (internal_innobase_data_file_path)
335
309
        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);
336
316
    }
337
317
    
338
318
    /* These get strdup'd from vm variables */
 
319
    free(innobase_data_home_dir);
 
320
    free(innobase_log_group_home_dir);
339
321
 
340
322
  }
341
323
 
366
348
  {
367
349
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
368
350
  }
369
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
370
 
  virtual uint64_t doGetNewTransactionId(Session *session);
371
351
  virtual int doCommit(Session* session, bool all);
372
352
  virtual int doRollback(Session* session, bool all);
373
353
 
411
391
        /* out: 0 or error number */
412
392
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
413
393
 
414
 
  virtual Cursor *create(Table &table)
 
394
  virtual Cursor *create(TableShare &table)
415
395
  {
416
396
    return new ha_innobase(*this, table);
417
397
  }
422
402
  doDropSchema(
423
403
  /*===================*/
424
404
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
405
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
406
        of the last directory in the path is used as
427
407
        the database name: for example, in 'mysql/data/test'
428
408
        the database name is 'test' */
461
441
 
462
442
  UNIV_INTERN int doCreateTable(Session &session,
463
443
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
444
                                const TableIdentifier &identifier,
465
445
                                message::Table&);
466
 
  UNIV_INTERN int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
467
 
  UNIV_INTERN int doDropTable(Session &session, const identifier::Table &identifier);
 
446
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
447
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
448
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
449
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
450
 
471
451
  UNIV_INTERN uint32_t max_supported_keys() const;
472
452
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
463
  }
484
464
 
485
465
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
466
                           const TableIdentifier &identifier,
487
467
                           drizzled::message::Table &table_proto);
488
468
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
469
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
470
 
491
471
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
472
                             const drizzled::SchemaIdentifier &schema_identifier,
 
473
                             drizzled::TableIdentifiers &set_of_identifiers);
494
474
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
475
  void dropTemporarySchema();
496
476
 
518
498
}
519
499
 
520
500
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
501
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
502
                                           drizzled::TableIdentifiers &set_of_identifiers)
523
503
{
524
504
  CachedDirectory::Entries entries= directory.getEntries();
525
505
 
526
 
  std::string search_string(schema_identifier.getSchemaName());
527
 
 
528
 
  boost::algorithm::to_lower(search_string);
529
 
 
530
 
  if (search_string.compare("data_dictionary") == 0)
531
 
  {
532
 
    set_of_identifiers.push_back(identifier::Table(schema_identifier.getSchemaName(), "SYS_REPLICATION_LOG"));
533
 
  }
534
 
 
535
506
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
507
       entry_iter != entries.end(); ++entry_iter)
537
508
  {
547
518
    { }
548
519
    else
549
520
    {
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
 
      }
 
521
      char uname[NAME_LEN + 1];
 
522
      uint32_t file_name_len;
 
523
 
 
524
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
525
      // TODO: Remove need for memory copy here
 
526
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
527
 
 
528
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
565
529
    }
566
530
  }
567
531
}
568
532
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
533
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
534
{
571
535
  string proto_path(identifier.getPath());
572
536
  proto_path.append(DEFAULT_FILE_EXTENSION);
573
537
 
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)
 
538
  if (session.doesTableMessageExist(identifier))
581
539
    return true;
582
540
 
583
541
  if (access(proto_path.c_str(), F_OK))
589
547
}
590
548
 
591
549
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
550
                                         const TableIdentifier &identifier,
593
551
                                         message::Table &table_proto)
594
552
{
595
553
  string proto_path(identifier.getPath());
596
554
  proto_path.append(DEFAULT_FILE_EXTENSION);
597
555
 
598
556
  // First we check the temporary tables.
599
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
 
    return EEXIST;
601
 
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
 
557
  if (session.getTableMessage(identifier, table_proto))
603
558
    return EEXIST;
604
559
 
605
560
  if (access(proto_path.c_str(), F_OK))
613
568
  return ENOENT;
614
569
}
615
570
 
 
571
/** @brief Initialize the default value of innodb_commit_concurrency.
 
572
 
 
573
Once InnoDB is running, the innodb_commit_concurrency must not change
 
574
from zero to nonzero. (Bug #42101)
 
575
 
 
576
The initial default value is 0, and without this extra initialization,
 
577
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
578
to 0, even if it was initially set to nonzero at the command line
 
579
or configuration file. */
 
580
static
 
581
void
 
582
innobase_commit_concurrency_init_default(void);
 
583
/*==========================================*/
616
584
 
617
585
/************************************************************//**
618
586
Validate the file format name and return its corresponding id.
625
593
            name */
626
594
/************************************************************//**
627
595
Validate the file format check config parameters, as a side effect it
628
 
sets the srv_max_file_format_at_startup variable.
 
596
sets the srv_check_file_format_at_startup variable.
 
597
@return true if one of  "on" or "off" */
 
598
static
 
599
bool
 
600
innobase_file_format_check_on_off(
 
601
/*==============================*/
 
602
  const char* format_check);    /*!< in: parameter value */
 
603
/************************************************************//**
 
604
Validate the file format check config parameters, as a side effect it
 
605
sets the srv_check_file_format_at_startup variable.
629
606
@return the format_id if valid config value, otherwise, return -1 */
630
607
static
631
608
int
632
609
innobase_file_format_validate_and_set(
633
610
/*================================*/
634
 
  const char* format_max);    /*!< in: parameter value */
 
611
  const char* format_check);    /*!< in: parameter value */
635
612
 
636
613
static const char innobase_engine_name[]= "InnoDB";
637
614
 
 
615
/*************************************************************//**
 
616
Check for a valid value of innobase_commit_concurrency.
 
617
@return 0 for valid innodb_commit_concurrency */
 
618
static
 
619
int
 
620
innobase_commit_concurrency_validate(
 
621
/*=================================*/
 
622
  Session*      , /*!< in: thread handle */
 
623
  drizzle_sys_var*  , /*!< in: pointer to system
 
624
            variable */
 
625
  void*       save, /*!< out: immediate result
 
626
            for update function */
 
627
  drizzle_value*    value)  /*!< in: incoming string */
 
628
{
 
629
  int64_t   intbuf;
 
630
  ulong   commit_concurrency;
 
631
 
 
632
  if (value->val_int(value, &intbuf)) {
 
633
    /* The value is NULL. That is invalid. */
 
634
    return(1);
 
635
  }
 
636
 
 
637
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
638
    = static_cast<ulong>(intbuf);
 
639
 
 
640
  /* Allow the value to be updated, as long as it remains zero
 
641
  or nonzero. */
 
642
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
643
}
 
644
 
 
645
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
646
  "Enable InnoDB support for the XA two-phase commit",
 
647
  /* check_func */ NULL, /* update_func */ NULL,
 
648
  /* default */ TRUE);
 
649
 
 
650
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
651
  "Enable InnoDB locking in LOCK TABLES",
 
652
  /* check_func */ NULL, /* update_func */ NULL,
 
653
  /* default */ TRUE);
 
654
 
 
655
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
656
  "Use strict mode when evaluating create options.",
 
657
  NULL, NULL, FALSE);
 
658
 
 
659
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
660
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
661
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
662
 
638
663
 
639
664
/*****************************************************************//**
640
665
Commits a transaction in an InnoDB database. */
798
823
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
824
         in non-Cursor code.
800
825
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
826
extern "C" UNIV_INTERN
802
827
ibool
803
828
thd_is_replication_slave_thread(
804
829
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
830
  void* ) /*!< in: thread handle (Session*) */
806
831
{
807
832
  return false;
808
833
}
872
897
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
898
         in non-Cursor code.
874
899
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
900
extern "C" UNIV_INTERN
876
901
ibool
877
902
thd_has_edited_nontrans_tables(
878
903
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
904
  void*   session)  /*!< in: thread handle (Session*) */
880
905
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
906
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
907
}
883
908
 
884
909
/******************************************************************//**
885
910
Returns true if the thread is executing a SELECT statement.
886
911
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
912
extern "C" UNIV_INTERN
888
913
ibool
889
914
thd_is_select(
890
915
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
916
  const void* session)  /*!< in: thread handle (Session*) */
892
917
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
918
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
919
}
895
920
 
896
921
/******************************************************************//**
897
922
Returns true if the thread supports XA,
898
923
global value of innodb_supports_xa if session is NULL.
899
924
@return true if session has XA support */
900
 
UNIV_INTERN
 
925
extern "C" UNIV_INTERN
901
926
ibool
902
927
thd_supports_xa(
903
928
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
929
  void* session)  /*!< in: thread handle (Session*), or NULL to query
905
930
        the global innodb_supports_xa */
906
931
{
907
 
  /* TODO: Add support here for per-session value */
908
 
  return(support_xa);
 
932
  return(SessionVAR((Session*) session, support_xa));
909
933
}
910
934
 
911
935
/******************************************************************//**
912
936
Returns the lock wait timeout for the current connection.
913
937
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
938
extern "C" UNIV_INTERN
915
939
ulong
916
940
thd_lock_wait_timeout(
917
941
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
942
  void* session)  /*!< in: thread handle (Session*), or NULL to query
919
943
      the global innodb_lock_wait_timeout */
920
944
{
921
 
  /* TODO: Add support here for per-session value */
922
945
  /* According to <drizzle/plugin.h>, passing session == NULL
923
946
  returns the global value of the session variable. */
924
 
  return((ulong)lock_wait_timeout.get());
925
 
}
926
 
 
927
 
/******************************************************************//**
928
 
Set the time waited for the lock for the current query. */
929
 
UNIV_INTERN
930
 
void
931
 
thd_set_lock_wait_time(
932
 
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
934
 
        ulint   value)  /*!< in: time waited for the lock */
935
 
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
947
  return(SessionVAR((Session*) session, lock_wait_timeout));
938
948
}
939
949
 
940
950
/********************************************************************//**
949
959
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
950
960
}
951
961
 
952
 
 
953
 
plugin::ReplicationReturnCode ReplicationLog::apply(Session &session,
954
 
                                                    const message::Transaction &message)
955
 
{
956
 
  char *data= new char[message.ByteSize()];
957
 
 
958
 
  message.SerializeToArray(data, message.ByteSize());
959
 
 
960
 
  trx_t *trx= session_to_trx(&session);
961
 
 
962
 
  uint64_t trx_id= message.transaction_context().transaction_id();
963
 
  uint32_t seg_id= message.segment_id();
964
 
  uint64_t end_timestamp= message.transaction_context().end_timestamp();
965
 
  bool is_end_segment= message.end_segment();
966
 
  trx->log_commit_id= TRUE;
967
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id,
968
 
               end_timestamp, is_end_segment, seg_id);
969
 
  (void)error;
970
 
 
971
 
  delete[] data;
972
 
 
973
 
  return plugin::SUCCESS;
974
 
}
975
 
 
976
962
/********************************************************************//**
977
963
Call this function when mysqld passes control to the client. That is to
978
964
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1022
1008
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
1009
timeout or a deadlock.
1024
1010
@return MySQL error code */
1025
 
UNIV_INTERN
 
1011
extern "C" UNIV_INTERN
1026
1012
int
1027
1013
convert_error_code_to_mysql(
1028
1014
/*========================*/
1037
1023
  case DB_INTERRUPTED:
1038
1024
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1039
1025
    /* fall through */
1040
 
 
1041
 
  case DB_FOREIGN_EXCEED_MAX_CASCADE:
1042
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1043
 
                        HA_ERR_ROW_IS_REFERENCED,
1044
 
                        "InnoDB: Cannot delete/update "
1045
 
                        "rows with cascading foreign key "
1046
 
                        "constraints that exceed max "
1047
 
                        "depth of %d. Please "
1048
 
                        "drop extra constraints and try "
1049
 
                        "again", DICT_FK_MAX_RECURSIVE_LOAD);
1050
 
    /* fall through */
1051
 
 
1052
1026
  case DB_ERROR:
1053
1027
  default:
1054
1028
    return(-1); /* unspecified error */
1076
1050
    tell it also to MySQL so that MySQL knows to empty the
1077
1051
    cached binlog for this transaction */
1078
1052
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1053
    mark_transaction_to_rollback(session, TRUE);
1080
1054
 
1081
1055
    return(HA_ERR_LOCK_DEADLOCK);
1082
1056
 
1085
1059
    latest SQL statement in a lock wait timeout. Previously, we
1086
1060
    rolled back the whole transaction. */
1087
1061
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1062
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1063
 
1090
1064
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1065
 
1096
1070
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1071
 
1098
1072
  case DB_CANNOT_ADD_CONSTRAINT:
1099
 
  case DB_CHILD_NO_INDEX:
1100
 
  case DB_PARENT_NO_INDEX:
1101
1073
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1074
 
1103
1075
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1093
 
1122
1094
  case DB_TOO_BIG_RECORD:
1123
1095
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1096
       page_get_free_space_of_empty(flags
 
1097
                  & DICT_TF_COMPACT) / 2);
1125
1098
    return(HA_ERR_TO_BIG_ROW);
1126
1099
 
1127
1100
  case DB_NO_SAVEPOINT:
1132
1105
    tell it also to MySQL so that MySQL knows to empty the
1133
1106
    cached binlog for this transaction */
1134
1107
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1108
    mark_transaction_to_rollback(session, TRUE);
1136
1109
 
1137
1110
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1111
 
1164
1137
}
1165
1138
 
1166
1139
 
 
1140
 
 
1141
/*************************************************************//**
 
1142
If you want to print a session that is not associated with the current thread,
 
1143
you must call this function before reserving the InnoDB kernel_mutex, to
 
1144
protect Drizzle from setting session->query NULL. If you print a session of the
 
1145
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1146
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1147
after you release the kernel_mutex.
 
1148
 
 
1149
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1150
         in non-Cursor code.
 
1151
 */
 
1152
extern "C" UNIV_INTERN
 
1153
void
 
1154
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1155
/*============================================*/
 
1156
{
 
1157
  ut_ad(!mutex_own(&kernel_mutex));
 
1158
  LOCK_thread_count.lock();
 
1159
}
 
1160
 
 
1161
/*************************************************************//**
 
1162
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1163
In the InnoDB latching order, the mutex sits right above the
 
1164
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1165
released before this function is invoked. 
 
1166
 
 
1167
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1168
         in non-Cursor code.
 
1169
*/
 
1170
extern "C" UNIV_INTERN
 
1171
void
 
1172
innobase_mysql_end_print_arbitrary_thd(void)
 
1173
/*========================================*/
 
1174
{
 
1175
  ut_ad(!mutex_own(&kernel_mutex));
 
1176
  LOCK_thread_count.unlock();
 
1177
}
 
1178
 
1167
1179
/*************************************************************//**
1168
1180
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1181
extern "C" UNIV_INTERN
1170
1182
void
1171
1183
innobase_mysql_print_thd(
1172
1184
/*=====================*/
1173
1185
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1186
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1187
  uint  )   /*!< in: max query length to print, or 0 to
1176
1188
           use the default max length */
1177
1189
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1190
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1191
  fprintf(f,
1181
1192
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1182
 
          static_cast<uint64_t>(in_session->getSessionId()),
1183
 
          static_cast<uint64_t>(in_session->getQueryId()),
 
1193
          static_cast<uint64_t>(session->getSessionId()),
 
1194
          static_cast<uint64_t>(session->getQueryId()),
1184
1195
          glob_hostname,
1185
 
          user_identifier->address().c_str(),
1186
 
          user_identifier->username().c_str()
1187
 
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1196
          session->getSecurityContext().getIp().c_str(),
 
1197
          session->getSecurityContext().getUser().c_str()
 
1198
  );
 
1199
  fprintf(f,
 
1200
          "\n%s", session->getQueryString().c_str()
 
1201
  );
1189
1202
  putc('\n', f);
1190
1203
}
1191
1204
 
1192
1205
/******************************************************************//**
1193
1206
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1207
extern "C" UNIV_INTERN
1195
1208
void
1196
1209
innobase_get_cset_width(
1197
1210
/*====================*/
1208
1221
  if (cs) {
1209
1222
    *mbminlen = cs->mbminlen;
1210
1223
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1224
  } else {
1214
1225
    ut_a(cset == 0);
1215
1226
    *mbminlen = *mbmaxlen = 0;
1218
1229
 
1219
1230
/******************************************************************//**
1220
1231
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1232
extern "C" UNIV_INTERN
1222
1233
void
1223
1234
innobase_convert_from_table_id(
1224
1235
/*===========================*/
1232
1243
 
1233
1244
/******************************************************************//**
1234
1245
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1246
extern "C" UNIV_INTERN
1236
1247
void
1237
1248
innobase_convert_from_id(
1238
1249
/*=====================*/
1247
1258
/******************************************************************//**
1248
1259
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1260
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1261
extern "C" UNIV_INTERN
1251
1262
int
1252
1263
innobase_strcasecmp(
1253
1264
/*================*/
1259
1270
 
1260
1271
/******************************************************************//**
1261
1272
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1273
extern "C" UNIV_INTERN
1263
1274
void
1264
1275
innobase_casedn_str(
1265
1276
/*================*/
1268
1279
  my_casedn_str(system_charset_info, a);
1269
1280
}
1270
1281
 
1271
 
UNIV_INTERN
 
1282
/**********************************************************************//**
 
1283
Determines the connection character set.
 
1284
@return connection character set */
 
1285
extern "C" UNIV_INTERN
 
1286
const void*
 
1287
innobase_get_charset(
 
1288
/*=================*/
 
1289
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1290
{
 
1291
  return session_charset(static_cast<Session*>(mysql_session));
 
1292
}
 
1293
 
 
1294
extern "C" UNIV_INTERN
1272
1295
bool
1273
1296
innobase_isspace(
1274
1297
  const void *cs,
1277
1300
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1301
}
1279
1302
 
 
1303
UNIV_INTERN
 
1304
int
 
1305
innobase_fast_mutex_init(
 
1306
        os_fast_mutex_t*        fast_mutex)
 
1307
{
 
1308
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1309
}
 
1310
 
1280
1311
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1312
/*******************************************************************//**
1282
1313
Map an OS error to an errno value. The OS error number is stored in
1283
1314
_doserrno and the mapped value is stored in errno) */
 
1315
extern "C"
1284
1316
void __cdecl
1285
1317
_dosmaperr(
1286
1318
  unsigned long); /*!< in: OS error value */
1288
1320
/*********************************************************************//**
1289
1321
Creates a temporary file.
1290
1322
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1323
extern "C" UNIV_INTERN
1292
1324
int
1293
1325
innobase_mysql_tmpfile(void)
1294
1326
/*========================*/
1368
1400
/*********************************************************************//**
1369
1401
Creates a temporary file.
1370
1402
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1403
extern "C" UNIV_INTERN
1372
1404
int
1373
1405
innobase_mysql_tmpfile(void)
1374
1406
/*========================*/
1375
1407
{
1376
1408
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1409
  int fd = mysql_tmpfile("ib");
1378
1410
  if (fd >= 0) {
1379
1411
    /* Copy the file descriptor, so that the additional resources
1380
1412
    allocated by create_temp_file() can be freed by invoking
1407
1439
number of bytes that were written to "buf" is returned (including the
1408
1440
terminating NUL).
1409
1441
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1442
extern "C" UNIV_INTERN
1411
1443
ulint
1412
1444
innobase_raw_format(
1413
1445
/*================*/
1527
1559
/*********************************************************************//**
1528
1560
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1561
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1562
extern "C" UNIV_INTERN
1531
1563
trx_t*
1532
1564
innobase_trx_allocate(
1533
1565
/*==================*/
1541
1573
  trx = trx_allocate_for_mysql();
1542
1574
 
1543
1575
  trx->mysql_thd = session;
 
1576
  trx->mysql_query_str = session->query.c_str();
1544
1577
 
1545
1578
  innobase_trx_init(session, trx);
1546
1579
 
1579
1612
Construct ha_innobase Cursor. */
1580
1613
UNIV_INTERN
1581
1614
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1582
 
                         Table &table_arg)
 
1615
                         TableShare &table_arg)
1583
1616
  :Cursor(engine_arg, table_arg),
1584
1617
  primary_key(0), /* needs initialization because index_flags() may be called 
1585
1618
                     before this is set to the real value. It's ok to have any 
1631
1664
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1665
  const char* id, /*!< in: identifier to convert */
1633
1666
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1667
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1668
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1669
        FALSE=id is an UTF-8 string */
1637
1670
{
1638
1671
  char nz[NAME_LEN + 1];
1639
 
  const size_t nz2_size= NAME_LEN + 1 + srv_mysql50_table_name_prefix.size();
1640
 
  boost::scoped_array<char> nz2(new char[nz2_size]);
 
1672
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1673
 
1642
1674
  const char* s = id;
1643
1675
  int   q;
1654
1686
    memcpy(nz, id, idlen);
1655
1687
    nz[idlen] = 0;
1656
1688
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1689
    s = nz2;
 
1690
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1691
  }
1660
1692
 
1661
1693
  /* See if the identifier needs to be quoted. */
1709
1741
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1742
and quote it if needed.
1711
1743
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1744
extern "C" UNIV_INTERN
1713
1745
char*
1714
1746
innobase_convert_name(
1715
1747
/*==================*/
1717
1749
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1750
  const char* id, /*!< in: identifier to convert */
1719
1751
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1752
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1753
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1754
        FALSE=id is an index name */
1723
1755
{
1765
1797
/**********************************************************************//**
1766
1798
Determines if the currently running transaction has been interrupted.
1767
1799
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1800
extern "C" UNIV_INTERN
1769
1801
ibool
1770
1802
trx_is_interrupted(
1771
1803
/*===============*/
1772
1804
  trx_t*  trx)  /*!< in: transaction */
1773
1805
{
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);
 
1806
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1788
1807
}
1789
1808
 
1790
1809
/**************************************************************//**
1806
1825
  value= value - (value % align_val);
1807
1826
}
1808
1827
 
1809
 
static void auto_extend_update(Session *, sql_var_t)
1810
 
{
1811
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1812
 
}
1813
 
 
1814
 
static void io_capacity_update(Session *, sql_var_t)
1815
 
{
1816
 
  srv_io_capacity= innodb_io_capacity.get();
1817
 
}
1818
 
 
1819
 
static void purge_batch_update(Session *, sql_var_t)
1820
 
{
1821
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1822
 
}
1823
 
 
1824
 
static void purge_threads_update(Session *, sql_var_t)
1825
 
{
1826
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1827
 
}
1828
 
 
1829
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1830
 
{
1831
 
  if (btr_search_enabled)
1832
 
  {
1833
 
    btr_search_enable();
1834
 
  } else {
1835
 
    btr_search_disable();
1836
 
  }
1837
 
}
1838
 
 
1839
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1840
 
{
1841
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1842
 
}
1843
 
 
1844
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1845
 
{
1846
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1847
 
}
1848
 
 
1849
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1850
 
{
1851
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1852
 
}
1853
 
 
1854
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1855
 
{
1856
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1857
 
}
1858
 
 
1859
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1860
 
{
1861
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1862
 
}
1863
 
 
1864
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1865
 
{
1866
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1867
 
}
1868
 
 
1869
 
 
1870
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1871
 
{
1872
 
   uint64_t new_value= var->getInteger();
1873
 
 
1874
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1875
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1876
 
   {
1877
 
     push_warning_printf(session,
1878
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1879
 
                         ER_WRONG_ARGUMENTS,
1880
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1881
 
                           "must not change between zero and nonzero."));
1882
 
     return 1;
1883
 
   }
1884
 
   return 0;
1885
 
}
1886
 
 
1887
 
/*************************************************************//**
1888
 
Check if it is a valid file format. This function is registered as
1889
 
a callback with MySQL.
1890
 
@return 0 for valid file format */
1891
 
static
1892
 
int
1893
 
innodb_file_format_name_validate(
1894
 
/*=============================*/
1895
 
  Session*      , /*!< in: thread handle */
1896
 
  set_var *var)
1897
 
{
1898
 
  const char *file_format_input = var->value->str_value.ptr();
1899
 
  if (file_format_input == NULL)
1900
 
    return 1;
1901
 
 
1902
 
  if (file_format_input != NULL) {
1903
 
    uint  format_id;
1904
 
 
1905
 
    format_id = innobase_file_format_name_lookup(
1906
 
      file_format_input);
1907
 
 
1908
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1909
 
      innobase_file_format_name =
1910
 
        trx_sys_file_format_id_to_name(format_id);
1911
 
 
1912
 
      return(0);
1913
 
    }
1914
 
  }
1915
 
 
1916
 
  return(1);
1917
 
}
1918
 
 
1919
 
/*************************************************************//**
1920
 
Check if it is a valid value of innodb_change_buffering. This function is
1921
 
registered as a callback with MySQL.
1922
 
@return 0 for valid innodb_change_buffering */
1923
 
static
1924
 
int
1925
 
innodb_change_buffering_validate(
1926
 
/*=============================*/
1927
 
  Session*      , /*!< in: thread handle */
1928
 
  set_var *var)
1929
 
{
1930
 
  const char *change_buffering_input = var->value->str_value.ptr();
1931
 
 
1932
 
  if (change_buffering_input == NULL)
1933
 
    return 1;
1934
 
 
1935
 
  ulint use;
1936
 
 
1937
 
  for (use = 0;
1938
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1939
 
       ++use) {
1940
 
    if (!innobase_strcasecmp(change_buffering_input,
1941
 
                             innobase_change_buffering_values[use]))
1942
 
    {
1943
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1944
 
      return 0;
1945
 
    }
1946
 
  }
1947
 
 
1948
 
  return 1;
1949
 
}
1950
 
 
1951
 
 
1952
 
/*************************************************************//**
1953
 
Check if valid argument to innodb_file_format_max. This function
1954
 
is registered as a callback with MySQL.
1955
 
@return 0 for valid file format */
1956
 
static
1957
 
int
1958
 
innodb_file_format_max_validate(
1959
 
/*==============================*/
1960
 
  Session*   session, /*!< in: thread handle */
1961
 
  set_var *var)
1962
 
{
1963
 
  const char *file_format_input = var->value->str_value.ptr();
1964
 
  if (file_format_input == NULL)
1965
 
    return 1;
1966
 
 
1967
 
  if (file_format_input != NULL) {
1968
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
1969
 
 
1970
 
    if (format_id > DICT_TF_FORMAT_MAX) {
1971
 
      /* DEFAULT is "on", which is invalid at runtime. */
1972
 
      return 1;
1973
 
    }
1974
 
 
1975
 
    if (format_id >= 0) {
1976
 
      innobase_file_format_max.assign(
1977
 
                             trx_sys_file_format_id_to_name((uint)format_id));
1978
 
 
1979
 
      /* Update the max format id in the system tablespace. */
1980
 
      const char *name_buff;
1981
 
 
1982
 
      if (trx_sys_file_format_max_set(format_id, &name_buff))
1983
 
      {
1984
 
        errmsg_printf(error::WARN,
1985
 
                      " [Info] InnoDB: the file format in the system "
1986
 
                      "tablespace is now set to %s.\n", name_buff);
1987
 
        innobase_file_format_max= name_buff;
1988
 
      }
1989
 
      return(0);
1990
 
 
1991
 
    } else {
1992
 
      push_warning_printf(session,
1993
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
1994
 
                          ER_WRONG_ARGUMENTS,
1995
 
                          "InnoDB: invalid innodb_file_format_max "
1996
 
                          "value; can be any format up to %s "
1997
 
                          "or equivalent id of %d",
1998
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
1999
 
                          DICT_TF_FORMAT_MAX);
2000
 
    }
2001
 
  }
2002
 
 
2003
 
  return(1);
2004
 
}
2005
 
 
2006
 
 
2007
1828
/*********************************************************************//**
2008
1829
Opens an InnoDB database.
2009
1830
@return 0 on success, error code on failure */
2019
1840
  InnobaseEngine *actuall_engine_ptr;
2020
1841
  const module::option_map &vm= context.getOptions();
2021
1842
 
2022
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2023
 
  srv_io_capacity= innodb_io_capacity.get();
2024
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2025
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2026
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2027
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2028
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2029
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2030
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2031
 
  srv_replication_delay= innodb_replication_delay.get();
2032
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2033
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2034
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2035
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2036
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2037
 
 
2038
1843
  /* Inverted Booleans */
2039
1844
 
2040
1845
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2041
1846
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
1847
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
1848
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2044
 
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2045
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2046
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2047
 
 
2048
 
 
2049
 
  /* Hafta do this here because we need to late-bind the default value */
 
1849
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1850
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1851
 
 
1852
  if (vm.count("io-capacity"))
 
1853
  {
 
1854
    if (srv_io_capacity < 100)
 
1855
    {
 
1856
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1857
      exit(-1);
 
1858
    }
 
1859
  }
 
1860
 
2050
1861
  if (vm.count("data-home-dir"))
2051
1862
  {
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
 
 
 
1863
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1864
  }
 
1865
  else
 
1866
  {
 
1867
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
 
1868
  }
 
1869
 
 
1870
  if (vm.count("fast-shutdown"))
 
1871
  {
 
1872
    if (innobase_fast_shutdown > 2)
 
1873
    {
 
1874
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1875
      exit(-1);
 
1876
    }
 
1877
  }
 
1878
 
 
1879
  if (vm.count("file-format-check"))
 
1880
  {
 
1881
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1882
  }
 
1883
 
 
1884
  if (vm.count("flush-log-at-trx-commit"))
 
1885
  {
 
1886
    if (srv_flush_log_at_trx_commit > 2)
 
1887
    {
 
1888
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1889
      exit(-1);
 
1890
    }
 
1891
  }
 
1892
 
 
1893
  if (vm.count("flush-method"))
 
1894
  {
 
1895
    innobase_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1896
  }
 
1897
  else
 
1898
  {
 
1899
    innobase_file_flush_method= NULL;
 
1900
  }
 
1901
 
 
1902
#ifdef UNIV_LOG_ARCHIVE
 
1903
  if (vm.count("log-arch-dir"))
 
1904
  {
 
1905
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1906
  }
 
1907
 
 
1908
  else
 
1909
  {
 
1910
    innobase_log_arch_dir= NULL;
 
1911
  }
 
1912
#endif /* UNIV_LOG_ARCHIVE */
 
1913
 
 
1914
  if (vm.count("max-dirty-pages-pct"))
 
1915
  {
 
1916
    if (srv_max_buf_pool_modified_pct > 99)
 
1917
    {
 
1918
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1919
      exit(-1);
 
1920
    }
 
1921
  }
 
1922
 
 
1923
  if (vm.count("stats-sample-pages"))
 
1924
  {
 
1925
    if (srv_stats_sample_pages < 8)
 
1926
    {
 
1927
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1928
      exit(-1);
 
1929
    }
 
1930
  }
 
1931
 
 
1932
  if (vm.count("additional-mem-pool-size"))
 
1933
  {
 
1934
    align_value(innobase_additional_mem_pool_size);
 
1935
 
 
1936
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1937
    {
 
1938
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1939
      exit(-1);
 
1940
    }
 
1941
 
 
1942
  }
 
1943
 
 
1944
  if (vm.count("autoextend-increment"))
 
1945
  {
 
1946
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1947
    {
 
1948
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1949
      exit(-1);
 
1950
    }
 
1951
  }
 
1952
 
 
1953
  if (vm.count("buffer-pool-size"))
 
1954
  {
 
1955
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1956
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1957
    {
 
1958
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1959
      exit(-1);
 
1960
    }
 
1961
    
 
1962
  }
 
1963
 
 
1964
  if (vm.count("commit-concurrency"))
 
1965
  {
 
1966
    if (srv_replication_delay > 1000)
 
1967
    {
 
1968
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1969
      exit(-1);
 
1970
    }
 
1971
  }
 
1972
 
 
1973
  if (vm.count("concurrency-tickets"))
 
1974
  {
 
1975
    if (srv_n_free_tickets_to_enter < 1)
 
1976
    {
 
1977
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1978
      exit(-1);
 
1979
    }
 
1980
  }
 
1981
 
 
1982
  if (vm.count("read-io-threads"))
 
1983
  {
 
1984
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1985
    {
 
1986
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1987
      exit(-1);
 
1988
    }
 
1989
  }
 
1990
 
 
1991
  if (vm.count("write-io-threads"))
 
1992
  {
 
1993
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1994
    {
 
1995
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1996
      exit(-1);
 
1997
    }
 
1998
  }
 
1999
 
 
2000
  if (vm.count("force-recovery"))
 
2001
  {
 
2002
    if (innobase_force_recovery > 6)
 
2003
    {
 
2004
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
2005
      exit(-1);
 
2006
    }
 
2007
  }
 
2008
 
 
2009
  if (vm.count("log-buffer-size"))
 
2010
  {
 
2011
    align_value(innobase_log_buffer_size);
 
2012
    if (innobase_log_buffer_size < 256*1024L)
 
2013
    {
 
2014
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2015
      exit(-1);
 
2016
    }
 
2017
  }
 
2018
 
 
2019
  if (vm.count("log-file-size"))
 
2020
  {
 
2021
    align_value(innobase_log_file_size, 1024*1024);
 
2022
    if (innobase_log_file_size < 1*1024*1024L)
 
2023
    {
 
2024
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2025
      exit(-1);
 
2026
    }
 
2027
  }
 
2028
 
 
2029
  if (vm.count("log-files-in-group"))
 
2030
  {
 
2031
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2032
    {
 
2033
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2034
      exit(-1);
 
2035
    }
 
2036
  }
 
2037
 
 
2038
  if (vm.count("mirrored-log-groups"))
 
2039
  {
 
2040
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2041
    {
 
2042
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2043
      exit(-1);
 
2044
    }
 
2045
  }
 
2046
 
 
2047
  if (vm.count("open-files"))
 
2048
  {
 
2049
    if (innobase_open_files < 10)
 
2050
    {
 
2051
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2052
      exit(-1);
 
2053
    }
 
2054
  }
 
2055
 
 
2056
  if (vm.count("thread-concurrency"))
 
2057
  {
 
2058
    if (srv_thread_concurrency > 1000)
 
2059
    {
 
2060
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2061
      exit(-1);
 
2062
    }
 
2063
  }
2059
2064
 
2060
2065
  if (vm.count("data-file-path"))
2061
2066
  {
2062
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2063
 
  }
2064
 
 
 
2067
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2068
  }
 
2069
  else
 
2070
  {
 
2071
    innobase_data_file_path= NULL;
 
2072
  }
 
2073
 
 
2074
  if (vm.count("version"))
 
2075
  {
 
2076
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2077
  }
 
2078
 
 
2079
  if (vm.count("read-ahead-threshold"))
 
2080
  {
 
2081
    if (srv_read_ahead_threshold > 64)
 
2082
    {
 
2083
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2084
      exit(-1);
 
2085
    }
 
2086
  }
 
2087
 
 
2088
  if (vm.count("strict-mode"))
 
2089
  {
 
2090
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2091
  }
 
2092
 
 
2093
  if (vm.count("lock-wait-timeout"))
 
2094
  {
 
2095
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2096
    {
 
2097
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2098
      exit(-1);
 
2099
    }
 
2100
 
 
2101
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2102
  }
2065
2103
 
2066
2104
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2067
2105
 
2069
2107
 
2070
2108
#ifdef UNIV_DEBUG
2071
2109
  static const char test_filename[] = "-@";
2072
 
  const size_t test_tablename_size= sizeof test_filename
2073
 
    + srv_mysql50_table_name_prefix.size();
2074
 
  boost::scoped_array test_tablename(new char[test_tablename_size]);
2075
 
  if ((test_tablename_size) - 1
2076
 
      != filename_to_tablename(test_filename, test_tablename.get(),
2077
 
                               test_tablename_size)
2078
 
      || strncmp(test_tablename.get(),
2079
 
                 srv_mysql50_table_name_prefix.c_str(),
2080
 
                 srv_mysql50_table_name_prefix.size())
2081
 
      || strcmp(test_tablename.get()
2082
 
                + srv_mysql50_table_name_prefix.size(),
 
2110
  char      test_tablename[sizeof test_filename
 
2111
    + sizeof srv_mysql50_table_name_prefix];
 
2112
  if ((sizeof test_tablename) - 1
 
2113
      != filename_to_tablename(test_filename, test_tablename,
 
2114
                               sizeof test_tablename)
 
2115
      || strncmp(test_tablename,
 
2116
                 srv_mysql50_table_name_prefix,
 
2117
                 sizeof srv_mysql50_table_name_prefix)
 
2118
      || strcmp(test_tablename
 
2119
                + sizeof srv_mysql50_table_name_prefix,
2083
2120
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2121
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2122
    goto error;
2086
2123
  }
2087
2124
#endif /* UNIV_DEBUG */
2088
2125
 
 
2126
  /* Check that values don't overflow on 32-bit systems. */
 
2127
  if (sizeof(ulint) == 4) {
 
2128
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2129
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2130
                    "innobase_buffer_pool_size can't be over 4GB"
 
2131
                    " on 32-bit systems");
 
2132
 
 
2133
      goto error;
 
2134
    }
 
2135
 
 
2136
    if (innobase_log_file_size > UINT32_MAX) {
 
2137
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2138
                    "innobase_log_file_size can't be over 4GB"
 
2139
                    " on 32-bit systems");
 
2140
 
 
2141
      goto error;
 
2142
    }
 
2143
  }
 
2144
 
2089
2145
  os_innodb_umask = (ulint)internal::my_umask;
2090
2146
 
2091
2147
 
2096
2152
 
2097
2153
  /* The default dir for data files is the datadir of MySQL */
2098
2154
 
2099
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2155
  srv_data_home = (char *)innobase_data_home_dir;
2100
2156
 
2101
2157
  /* Set default InnoDB data file size to 10 MB and let it be
2102
2158
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2103
2159
    to specify any startup options. */
2104
2160
 
2105
 
  if (innobase_data_file_path.empty()) 
2106
 
  {
2107
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2161
  if (!innobase_data_file_path) {
 
2162
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2108
2163
  }
2109
2164
 
2110
2165
  /* Since InnoDB edits the argument in the next call, we make another
2111
2166
    copy of it: */
2112
2167
 
2113
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2168
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2114
2169
 
2115
2170
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2171
                                                   internal_innobase_data_file_path);
2117
2172
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2173
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2174
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2175
mem_free_and_error:
2121
2176
    srv_free_paths_and_sizes();
2122
2177
    if (internal_innobase_data_file_path)
2130
2185
 
2131
2186
  if (vm.count("log-group-home-dir"))
2132
2187
  {
2133
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2188
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
2134
2189
  }
2135
2190
  else
2136
2191
  {
2137
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2192
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
2138
2193
  }
2139
2194
 
 
2195
#ifdef UNIV_LOG_ARCHIVE
 
2196
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2197
    starting from 4.0.6 we always set it the same as
 
2198
innodb_log_group_home_dir: */
 
2199
 
 
2200
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2201
 
 
2202
  srv_arch_dir = innobase_log_arch_dir;
 
2203
#endif /* UNIG_LOG_ARCHIVE */
 
2204
 
2140
2205
  ret = (bool)
2141
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2206
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2142
2207
 
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"));
 
2208
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2209
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2210
                  "wrong number of mirrored log groups");
2146
2211
 
2147
2212
    goto mem_free_and_error;
2148
2213
  }
2156
2221
 
2157
2222
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2223
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2224
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2225
 
2161
2226
      goto mem_free_and_error;
2162
2227
    }
2167
2232
 
2168
2233
  srv_file_format = format_id;
2169
2234
 
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;
 
2235
  /* Given the type of innobase_file_format_name we have little
 
2236
    choice but to cast away the constness from the returned name.
 
2237
    innobase_file_format_name is used in the MySQL set variable
 
2238
    interface and so can't be const. */
 
2239
 
 
2240
  innobase_file_format_name = 
 
2241
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2242
 
 
2243
  /* Process innobase_file_format_check variable */
 
2244
  ut_a(innobase_file_format_check != NULL);
 
2245
 
 
2246
  /* As a side effect it will set srv_check_file_format_at_startup
 
2247
    on valid input. First we check for "on"/"off". */
 
2248
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2249
 
 
2250
    /* Did the user specify a format name that we support ?
 
2251
      As a side effect it will update the variable
 
2252
      srv_check_file_format_at_startup */
 
2253
    if (innobase_file_format_validate_and_set(
 
2254
                                innobase_file_format_check) < 0) {
 
2255
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2256
                    "innodb_file_format_check value: "
 
2257
                    "should be either 'on' or 'off' or "
 
2258
                    "any value up to %s or its "
 
2259
                    "equivalent numeric id",
 
2260
                    trx_sys_file_format_id_to_name(
 
2261
                                                   DICT_TF_FORMAT_MAX));
 
2262
 
 
2263
      goto mem_free_and_error;
 
2264
    }
2192
2265
  }
2193
2266
 
2194
2267
  if (vm.count("change-buffering"))
2199
2272
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2200
2273
         use++) {
2201
2274
      if (!innobase_strcasecmp(
2202
 
                               innobase_change_buffering.c_str(),
 
2275
                               vm["change-buffering"].as<string>().c_str(),
2203
2276
                               innobase_change_buffering_values[use])) {
2204
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2277
        ibuf_use = (ibuf_use_t) use;
2205
2278
        goto innobase_change_buffering_inited_ok;
2206
2279
      }
2207
2280
    }
2208
2281
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2282
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2283
                  "InnoDB: invalid value "
 
2284
                  "innodb_file_format_check=%s",
2210
2285
                  vm["change-buffering"].as<string>().c_str());
2211
2286
    goto mem_free_and_error;
2212
2287
  }
2213
2288
 
2214
2289
innobase_change_buffering_inited_ok:
2215
2290
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2216
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2291
  innobase_change_buffering = (char*)
 
2292
    innobase_change_buffering_values[ibuf_use];
2217
2293
 
2218
2294
  /* --------------------------------------------------*/
2219
2295
 
2220
 
  if (vm.count("flush-method") != 0)
2221
 
  {
2222
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2223
 
  }
 
2296
  srv_file_flush_method_str = innobase_file_flush_method;
2224
2297
 
2225
2298
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2226
2299
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2227
2300
  srv_log_file_size = (ulint) innobase_log_file_size;
2228
2301
 
 
2302
#ifdef UNIV_LOG_ARCHIVE
 
2303
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2304
#endif /* UNIV_LOG_ARCHIVE */
2229
2305
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2230
2306
 
2231
2307
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2232
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2233
2308
 
2234
2309
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2235
2310
 
2260
2335
 
2261
2336
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2262
2337
 
 
2338
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct,
 
2339
                                                     FALSE);
 
2340
 
 
2341
  innobase_commit_concurrency_init_default();
 
2342
 
2263
2343
  /* Since we in this module access directly the fields of a trx
2264
2344
    struct, and due to different headers and flags it might happen that
2265
2345
    mutex_t has a different size in this module and in InnoDB
2268
2348
 
2269
2349
  err = innobase_start_or_create_for_mysql();
2270
2350
 
2271
 
  if (err != DB_SUCCESS)
2272
 
  {
2273
 
    goto mem_free_and_error;
2274
 
  }
2275
 
 
2276
 
  err = dict_create_sys_replication_log();
2277
 
 
2278
2351
  if (err != DB_SUCCESS) {
2279
2352
    goto mem_free_and_error;
2280
2353
  }
2281
2354
 
2282
 
 
2283
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2284
 
                                                     TRUE);
2285
 
 
2286
2355
  innobase_open_tables = hash_create(200);
 
2356
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2357
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2358
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2359
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2360
  pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
 
2361
  pthread_cond_init(&commit_cond, NULL);
2287
2362
  innodb_inited= 1;
2288
2363
 
2289
2364
  actuall_engine_ptr->dropTemporarySchema();
2290
2365
 
2291
 
  context.add(new InnodbStatusTool);
 
2366
  status_table_function_ptr= new InnodbStatusTool;
2292
2367
 
2293
2368
  context.add(innodb_engine_ptr);
2294
2369
 
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());
 
2370
  context.add(status_table_function_ptr);
 
2371
 
 
2372
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2373
  context.add(cmp_tool);
 
2374
 
 
2375
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2376
  context.add(cmp_reset_tool);
 
2377
 
 
2378
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2379
  context.add(cmp_mem_tool);
 
2380
 
 
2381
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2382
  context.add(cmp_mem_reset_tool);
 
2383
 
 
2384
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2385
  context.add(innodb_trx_tool);
 
2386
 
 
2387
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2388
  context.add(innodb_locks_tool);
 
2389
 
 
2390
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2391
  context.add(innodb_lock_waits_tool);
2322
2392
 
2323
2393
  context.add(new(std::nothrow)InnodbInternalTables());
2324
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
 
 
2326
 
  if (innobase_use_replication_log)
2327
 
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2329
 
    context.add(replication_logger);
2330
 
    ReplicationLog::setup(replication_logger);
2331
 
  }
2332
 
 
2333
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2334
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2335
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2336
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2337
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2338
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2339
 
 
2340
 
 
2341
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2342
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2343
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2344
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2345
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2346
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2347
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2348
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2349
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2350
 
 
2351
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2352
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2353
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2354
 
 
2355
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2356
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2357
 
                                                                   innodb_auto_extend_increment,
2358
 
                                                                   auto_extend_update));
2359
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2360
 
                                                                   innodb_io_capacity,
2361
 
                                                                   io_capacity_update));
2362
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2363
 
                                                                   innodb_purge_batch_size,
2364
 
                                                                   purge_batch_update));
2365
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2366
 
                                                                   innodb_n_purge_threads,
2367
 
                                                                   purge_threads_update));
2368
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
2369
 
  context.registerVariable(new sys_var_std_string("file_format",
2370
 
                                                  innobase_file_format_name,
2371
 
                                                  innodb_file_format_name_validate));
2372
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2373
 
                                                  innobase_change_buffering,
2374
 
                                                  innodb_change_buffering_validate));
2375
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2376
 
                                                  innobase_file_format_max,
2377
 
                                                  innodb_file_format_max_validate));
2378
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2379
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2380
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush_log_at_trx_commit",
2381
 
                                                  innodb_flush_log_at_trx_commit));
2382
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2383
 
                                                  innodb_max_dirty_pages_pct));
2384
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2385
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2386
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2387
 
 
2388
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2389
 
                                                                   innobase_commit_concurrency,
2390
 
                                                                   innodb_commit_concurrency_validate));
2391
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2392
 
                                                                   innodb_concurrency_tickets));
2393
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2394
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2395
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2396
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2397
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2398
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2399
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2400
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2401
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2402
 
                                                                   innobase_old_blocks_pct,
2403
 
                                                                   innodb_old_blocks_pct_update));
2404
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2405
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2406
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2407
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2408
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2409
 
                                                                   innobase_thread_concurrency,
2410
 
                                                                   innodb_thread_concurrency_update));
2411
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2412
 
                                                                   innodb_read_ahead_threshold,
2413
 
                                                                   innodb_read_ahead_threshold_update));
 
2394
 
2414
2395
  /* Get the current high water mark format. */
2415
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2416
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2396
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2417
2397
 
2418
2398
  return(FALSE);
2419
 
 
2420
2399
error:
2421
2400
  return(TRUE);
2422
2401
}
2513
2492
    trx_search_latch_release_if_reserved(trx);
2514
2493
  }
2515
2494
 
2516
 
  if (all)
2517
 
  {
 
2495
  if (all
 
2496
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2497
 
2518
2498
    /* We were instructed to commit the whole transaction, or
2519
2499
    this is an SQL statement end and autocommit is on */
2520
2500
 
2521
2501
    /* We need current binlog position for ibbackup to work.
2522
2502
    Note, the position is current because of
2523
2503
    prepare_commit_mutex */
2524
 
    const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2525
 
    if (commit_concurrency)
2526
 
    {
2527
 
      do 
2528
 
      {
2529
 
        boost::mutex::scoped_lock scopedLock(commit_cond_m);
2530
 
        commit_threads++;
2531
 
 
2532
 
        if (commit_threads <= commit_concurrency) 
2533
 
          break;
2534
 
 
 
2504
retry:
 
2505
    if (innobase_commit_concurrency > 0) {
 
2506
      pthread_mutex_lock(&commit_cond_m);
 
2507
      commit_threads++;
 
2508
 
 
2509
      if (commit_threads > innobase_commit_concurrency) {
2535
2510
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2511
        pthread_cond_wait(&commit_cond,
 
2512
          &commit_cond_m);
 
2513
        pthread_mutex_unlock(&commit_cond_m);
 
2514
        goto retry;
 
2515
      }
 
2516
      else {
 
2517
        pthread_mutex_unlock(&commit_cond_m);
 
2518
      }
2538
2519
    }
2539
2520
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2521
                /* Store transaction point for binlog
 
2522
    Later logic tests that this is set to _something_. We need
 
2523
    that logic to fire, even though we do not have a real name. */
 
2524
    trx->mysql_log_file_name = "UNUSED";
2541
2525
    trx->mysql_log_offset = 0;
2542
2526
 
2543
2527
    /* Don't do write + flush right now. For group commit
2547
2531
    innobase_commit_low(trx);
2548
2532
    trx->flush_log_later = FALSE;
2549
2533
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2534
    if (innobase_commit_concurrency > 0) {
 
2535
      pthread_mutex_lock(&commit_cond_m);
2553
2536
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2537
      pthread_cond_signal(&commit_cond);
 
2538
      pthread_mutex_unlock(&commit_cond_m);
2555
2539
    }
2556
2540
 
2557
2541
    /* Now do a write + flush of logs. */
2571
2555
    SQL statement */
2572
2556
 
2573
2557
    trx_mark_sql_stat_end(trx);
2574
 
 
2575
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2576
 
    {
2577
 
      if (trx->conc_state != TRX_NOT_STARTED)
2578
 
      {
2579
 
        commit(session, TRUE);
2580
 
      }
2581
 
    }
2582
2558
  }
2583
2559
 
2584
2560
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2593
2569
  threads: */
2594
2570
  srv_active_wake_master_thread();
2595
2571
 
2596
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2597
 
      trx->global_read_view)
2598
 
  {
2599
 
    /* At low transaction isolation levels we let
2600
 
       each consistent read set its own snapshot */
2601
 
    read_view_close_for_mysql(trx);
2602
 
  }
2603
 
 
2604
2572
  return(0);
2605
2573
}
2606
2574
 
2636
2604
 
2637
2605
  row_unlock_table_autoinc_for_mysql(trx);
2638
2606
 
2639
 
  if (all)
2640
 
  {
 
2607
  if (all
 
2608
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2609
 
2641
2610
    error = trx_rollback_for_mysql(trx);
2642
2611
  } else {
2643
2612
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2644
2613
  }
2645
2614
 
2646
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2647
 
      trx->global_read_view)
2648
 
  {
2649
 
    /* At low transaction isolation levels we let
2650
 
       each consistent read set its own snapshot */
2651
 
    read_view_close_for_mysql(trx);
2652
 
  }
2653
 
 
2654
2615
  return(convert_error_code_to_mysql(error, 0, NULL));
2655
2616
}
2656
2617
 
2787
2748
 
2788
2749
  ut_a(trx);
2789
2750
 
2790
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2751
  assert(session->killed != Session::NOT_KILLED ||
2791
2752
         trx->conc_state == TRX_NOT_STARTED);
2792
2753
 
2793
2754
  /* Warn if rolling back some things... */
2794
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2755
  if (session->killed != Session::NOT_KILLED &&
2795
2756
      trx->conc_state != TRX_NOT_STARTED &&
2796
 
      trx->undo_no > 0 &&
 
2757
      trx->undo_no.low > 0 &&
2797
2758
      global_system_variables.log_warnings)
2798
2759
  {
2799
 
      errmsg_printf(error::WARN,
 
2760
      errmsg_printf(ERRMSG_LVL_WARN, 
2800
2761
      "Drizzle is closing a connection during a KILL operation\n"
2801
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2762
      "that has an active InnoDB transaction.  %lu row modifications will "
2802
2763
      "roll back.\n",
2803
 
      (ullint) trx->undo_no);
 
2764
      (ulong) trx->undo_no.low);
2804
2765
  }
2805
2766
 
2806
2767
  innobase_rollback_trx(trx);
2876
2837
  return(true);
2877
2838
}
2878
2839
 
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]);
 
2840
/*****************************************************************//**
 
2841
Normalizes a table name string. A normalized name consists of the
 
2842
database name catenated to '/' and table name. An example:
 
2843
test/mytable. On Windows normalization puts both the database name and the
 
2844
table name always to lower case. */
 
2845
static
 
2846
void
 
2847
normalize_table_name(
 
2848
/*=================*/
 
2849
  char*   norm_name,  /*!< out: normalized name as a
 
2850
          null-terminated string */
 
2851
  const char* name)   /*!< in: table name string */
 
2852
{
 
2853
  const char* name_ptr;
 
2854
  const char* db_ptr;
 
2855
  const char* ptr;
 
2856
 
 
2857
  /* Scan name from the end */
 
2858
 
 
2859
  ptr = strchr(name, '\0')-1;
 
2860
 
 
2861
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2862
    ptr--;
 
2863
  }
 
2864
 
 
2865
  name_ptr = ptr + 1;
 
2866
 
 
2867
  assert(ptr > name);
 
2868
 
 
2869
  ptr--;
 
2870
 
 
2871
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2872
    ptr--;
 
2873
  }
 
2874
 
 
2875
  db_ptr = ptr + 1;
 
2876
 
 
2877
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2878
 
 
2879
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2880
 
 
2881
#ifdef __WIN__
 
2882
  innobase_casedn_str(norm_name);
 
2883
#endif
3127
2884
}
3128
2885
 
3129
2886
/********************************************************************//**
3130
2887
Set the autoinc column max value. This should only be called once from
3131
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2888
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2889
@return DB_SUCCESS or error code */
3132
2890
UNIV_INTERN
3133
 
void
 
2891
ulint
3134
2892
ha_innobase::innobase_initialize_autoinc()
3135
2893
/*======================================*/
3136
2894
{
 
2895
  dict_index_t* index;
3137
2896
  uint64_t  auto_inc;
3138
 
  const Field*  field = getTable()->found_next_number_field;
3139
 
 
3140
 
  if (field != NULL) {
3141
 
    auto_inc = innobase_get_int_col_max_value(field);
3142
 
  } else {
3143
 
    /* We have no idea what's been passed in to us as the
3144
 
       autoinc column. We set it to the 0, effectively disabling
3145
 
       updates to the table. */
3146
 
    auto_inc = 0;
3147
 
 
 
2897
  const char* col_name;
 
2898
  ulint   error;
 
2899
 
 
2900
  col_name = table->found_next_number_field->field_name;
 
2901
  index = innobase_get_index(table->getShare()->next_number_index);
 
2902
 
 
2903
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2904
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2905
 
 
2906
  switch (error) {
 
2907
  case DB_SUCCESS:
 
2908
 
 
2909
    /* At the this stage we don't know the increment
 
2910
    or the offset, so use default inrement of 1. */
 
2911
    ++auto_inc;
 
2912
    break;
 
2913
 
 
2914
  case DB_RECORD_NOT_FOUND:
3148
2915
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
3150
 
  }
3151
 
 
3152
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3153
 
    /* If the recovery level is set so high that writes
3154
 
       are disabled we force the AUTOINC counter to 0
3155
 
       value effectively disabling writes to the table.
3156
 
       Secondly, we avoid reading the table in case the read
3157
 
       results in failure due to a corrupted table/index.
3158
 
 
3159
 
       We will not return an error to the client, so that the
3160
 
       tables can be dumped with minimal hassle.  If an error
3161
 
       were returned in this case, the first attempt to read
3162
 
       the table would fail and subsequent SELECTs would succeed. */
3163
 
    auto_inc = 0;
3164
 
  } else if (field == NULL) {
3165
 
    /* This is a far more serious error, best to avoid
3166
 
       opening the table and return failure. */
3167
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3168
 
  } else {
3169
 
    dict_index_t*       index;
3170
 
    const char* col_name;
3171
 
    uint64_t    read_auto_inc;
3172
 
    ulint               err;
3173
 
 
3174
 
    update_session(getTable()->in_use);
3175
 
    col_name = field->field_name;
3176
 
 
3177
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3178
 
 
3179
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3180
 
 
3181
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3182
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3183
 
 
3184
 
    switch (err) {
3185
 
    case DB_SUCCESS: {
3186
 
      uint64_t col_max_value;
3187
 
 
3188
 
      col_max_value = innobase_get_int_col_max_value(field);
3189
 
 
3190
 
      /* At the this stage we do not know the increment
3191
 
         nor the offset, so use a default increment of 1. */
3192
 
 
3193
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3194
 
 
3195
 
      break;
3196
 
    }
3197
 
    case DB_RECORD_NOT_FOUND:
3198
 
      ut_print_timestamp(stderr);
3199
 
      errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3200
 
                    "InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3201
 
                    "InnoDB: We set the next AUTOINC column value to 0,\n"
3202
 
                    "InnoDB: in effect disabling the AUTOINC next value generation.\n"
3203
 
                    "InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3204
 
                    "InnoDB: or fix the data dictionary by recreating the table.\n",
3205
 
                    col_name, index->table->name);
3206
 
 
3207
 
      /* This will disable the AUTOINC generation. */
3208
 
      auto_inc = 0;
3209
 
 
3210
 
      /* We want the open to succeed, so that the user can
3211
 
         take corrective action. ie. reads should succeed but
3212
 
         updates should fail. */
3213
 
      err = DB_SUCCESS;
3214
 
      break;
3215
 
    default:
3216
 
      /* row_search_max_autoinc() should only return
3217
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3218
 
      ut_error;
3219
 
    }
 
2916
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2917
      "dictionaries are out of sync.\n"
 
2918
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2919
      "InnoDB table %s.\n"
 
2920
      "InnoDB: We set the next AUTOINC column value to the "
 
2921
      "maximum possible value,\n"
 
2922
      "InnoDB: in effect disabling the AUTOINC next value "
 
2923
      "generation.\n"
 
2924
      "InnoDB: You can either set the next AUTOINC value "
 
2925
      "explicitly using ALTER TABLE\n"
 
2926
      "InnoDB: or fix the data dictionary by recreating "
 
2927
      "the table.\n",
 
2928
      col_name, index->table->name);
 
2929
 
 
2930
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2931
    break;
 
2932
 
 
2933
  default:
 
2934
    return(error);
3220
2935
  }
3221
2936
 
3222
2937
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2938
 
 
2939
  return(DB_SUCCESS);
3223
2940
}
3224
2941
 
3225
2942
/*****************************************************************//**
3228
2945
@return 1 if error, 0 if success */
3229
2946
UNIV_INTERN
3230
2947
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
2948
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
2949
                    int   mode,   /*!< in: not used */
3233
2950
                    uint    test_if_locked) /*!< in: not used */
3234
2951
{
3235
2952
  dict_table_t* ib_table;
 
2953
  char    norm_name[FN_REFLEN];
3236
2954
  Session*    session;
3237
2955
 
3238
2956
  UT_NOT_USED(mode);
3239
2957
  UT_NOT_USED(test_if_locked);
3240
2958
 
3241
 
  session= getTable()->in_use;
 
2959
  session= table->in_use;
3242
2960
 
3243
2961
  /* Under some cases Drizzle seems to call this function while
3244
2962
  holding btr_search_latch. This breaks the latching order as
3247
2965
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
2966
  }
3249
2967
 
 
2968
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
2969
 
3250
2970
  user_session = NULL;
3251
2971
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
2972
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
2973
 
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
 
    }
 
2974
    return(1);
3270
2975
  }
3271
2976
 
3272
2977
  /* Create buffers for packing the fields of a record. Why
3275
2980
  stored the string length as the first byte. */
3276
2981
 
3277
2982
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
3279
 
        + getTable()->getShare()->max_key_length
 
2983
        table->getShare()->stored_rec_length
 
2984
        + table->getShare()->max_key_length
3280
2985
        + MAX_REF_PARTS * 3;
3281
2986
 
3282
2987
  upd_buff.resize(upd_and_key_val_buff_len);
3293
2998
  }
3294
2999
 
3295
3000
  /* Get pointer to a table object in InnoDB dictionary cache */
3296
 
  if (search_string.compare("data_dictionary") == 0)
3297
 
  {
3298
 
    std::string table_name(identifier.getTableName());
3299
 
    boost::algorithm::to_upper(table_name);
3300
 
    ib_table = dict_table_get(table_name.c_str(), TRUE);
3301
 
  }
3302
 
  else
3303
 
  {
3304
 
    ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3305
 
  }
 
3001
  ib_table = dict_table_get(norm_name, TRUE);
3306
3002
  
3307
3003
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3004
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3005
        "the internal data dictionary of InnoDB "
3310
3006
        "though the .frm file for the\n"
3311
3007
        "table exists. Maybe you have deleted and "
3319
3015
        "doesn't support.\n"
3320
3016
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3017
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3018
        norm_name);
3323
3019
    free_share(share);
3324
3020
    upd_buff.resize(0);
3325
3021
    key_val_buff.resize(0);
3328
3024
    return(HA_ERR_NO_SUCH_TABLE);
3329
3025
  }
3330
3026
 
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 "
 
3027
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
3028
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3029
        "the .ibd file for\ntable %s does not exist.\n"
3334
3030
        "Have you deleted the .ibd file from the "
3335
3031
        "database directory under\nthe MySQL datadir, "
3336
3032
        "or have you used DISCARD TABLESPACE?\n"
3337
3033
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3034
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3035
        norm_name);
3340
3036
    free_share(share);
3341
3037
    upd_buff.resize(0);
3342
3038
    key_val_buff.resize(0);
3348
3044
 
3349
3045
  prebuilt = row_create_prebuilt(ib_table);
3350
3046
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
3352
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3047
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3048
  prebuilt->default_rec = table->getDefaultValues();
3353
3049
  ut_ad(prebuilt->default_rec);
3354
3050
 
3355
3051
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3356
3052
 
3357
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3053
  primary_key = table->getShare()->getPrimaryKey();
3358
3054
  key_used_on_scan = primary_key;
3359
3055
 
3360
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3361
 
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3362
 
                    " Table %s failed", identifier.getKeyPath().c_str());
3363
 
  }
3364
 
 
3365
3056
  /* Allocate a buffer for a 'row reference'. A row reference is
3366
3057
  a string of bytes of length ref_length which uniquely specifies
3367
3058
  a row in our table. Note that MySQL may also compare two row
3369
3060
  of length ref_length! */
3370
3061
 
3371
3062
  if (!row_table_got_default_clust_index(ib_table)) {
 
3063
    if (primary_key >= MAX_KEY) {
 
3064
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3065
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3066
    }
3372
3067
 
3373
3068
    prebuilt->clust_index_was_generated = FALSE;
3374
3069
 
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
 
    }
 
3070
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3071
    includes space for all key columns + one byte for each column
 
3072
    that may be NULL. ref_length must be as exact as possible to
 
3073
    save space, because all row reference buffers are allocated
 
3074
    based on ref_length. */
 
3075
 
 
3076
    ref_length = table->key_info[primary_key].key_length;
3429
3077
  } else {
3430
3078
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
3432
 
                    "Table %s has no primary key in InnoDB data "
3433
 
                    "dictionary, but has one in MySQL! If you "
3434
 
                    "created the table with a MySQL version < "
3435
 
                    "3.23.54 and did not define a primary key, "
3436
 
                    "but defined a unique key with all non-NULL "
3437
 
                    "columns, then MySQL internally treats that "
3438
 
                    "key as the primary key. You can fix this "
3439
 
                    "error by dump + DROP + CREATE + reimport "
3440
 
                    "of the table.", identifier.getTableName().c_str());
3441
 
 
3442
 
      /* This mismatch could cause further problems
3443
 
         if not attended, bring this to the user attention
3444
 
         by printing a warning in addition to log a message
3445
 
         in the errorlog */
3446
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3447
 
                          ER_NO_SUCH_INDEX,
3448
 
                          "InnoDB: Table %s has no "
3449
 
                          "primary key in InnoDB data "
3450
 
                          "dictionary, but has one in "
3451
 
                          "MySQL!", identifier.getTableName().c_str());
 
3079
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3080
          "dictionary, but has one in MySQL! If you "
 
3081
          "created the table with a MySQL version < "
 
3082
          "3.23.54 and did not define a primary key, "
 
3083
          "but defined a unique key with all non-NULL "
 
3084
          "columns, then MySQL internally treats that "
 
3085
          "key as the primary key. You can fix this "
 
3086
          "error by dump + DROP + CREATE + reimport "
 
3087
          "of the table.", identifier.getTableName().c_str());
3452
3088
    }
3453
3089
 
3454
3090
    prebuilt->clust_index_was_generated = TRUE;
3464
3100
    and it will never be updated anyway. */
3465
3101
 
3466
3102
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3103
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3104
        "Table %s key_used_on_scan is %lu even "
3469
3105
        "though there is no primary key inside "
3470
3106
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3481
3117
    /* We update the highest file format in the system table
3482
3118
    space, if this table has higher file format setting. */
3483
3119
 
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,
 
3120
    trx_sys_file_format_max_upgrade(
 
3121
      (const char**) &innobase_file_format_check,
3487
3122
      dict_table_get_format(prebuilt->table));
3488
 
    innobase_file_format_max= changed_file_format_max;
3489
3123
  }
3490
3124
 
 
3125
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3126
 
3491
3127
  /* Only if the table has an AUTOINC column. */
3492
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3128
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3129
    ulint error;
3493
3130
 
3494
3131
    dict_table_autoinc_lock(prebuilt->table);
3495
3132
 
3499
3136
    autoinc value from a previous Drizzle open. */
3500
3137
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3501
3138
 
3502
 
      innobase_initialize_autoinc();
 
3139
      error = innobase_initialize_autoinc();
 
3140
      ut_a(error == DB_SUCCESS);
3503
3141
    }
3504
3142
 
3505
3143
    dict_table_autoinc_unlock(prebuilt->table);
3506
3144
  }
3507
3145
 
3508
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3509
 
 
3510
3146
  return(0);
3511
3147
}
3512
3148
 
3527
3163
{
3528
3164
  Session*  session;
3529
3165
 
3530
 
  session= getTable()->in_use;
 
3166
  session= table->in_use;
3531
3167
  if (session != NULL) {
3532
3168
    getTransactionalEngine()->releaseTemporaryLatches(session);
3533
3169
  }
3616
3252
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3253
function, remember to update the prototype there!
3618
3254
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3255
extern "C" UNIV_INTERN
 
3256
int
3620
3257
innobase_mysql_cmp(
3621
3258
/*===============*/
3622
3259
  int   mysql_type, /*!< in: MySQL type */
3663
3300
      charset = get_charset(charset_number);
3664
3301
 
3665
3302
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3303
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3304
                      "a comparison, but MySQL cannot "
3668
3305
                      "find that charset.",
3669
3306
                      (ulong) charset_number);
3698
3335
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3336
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3337
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3338
extern "C" UNIV_INTERN
3702
3339
ulint
3703
3340
get_innobase_type_from_mysql_type(
3704
3341
/*==============================*/
3747
3384
      return(DATA_VARMYSQL);
3748
3385
    }
3749
3386
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3387
    return(DATA_FIXBINARY);
3752
3388
  case DRIZZLE_TYPE_LONG:
3753
3389
  case DRIZZLE_TYPE_LONGLONG:
3754
3390
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3391
  case DRIZZLE_TYPE_DATE:
3757
3392
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3393
    return(DATA_INT);
3760
3394
  case DRIZZLE_TYPE_DOUBLE:
3761
3395
    return(DATA_DOUBLE);
3762
3396
  case DRIZZLE_TYPE_BLOB:
3763
 
    return(DATA_BLOB);
3764
 
  case DRIZZLE_TYPE_BOOLEAN:
3765
 
  case DRIZZLE_TYPE_UUID:
3766
 
    return(DATA_FIXBINARY);
3767
 
  case DRIZZLE_TYPE_NULL:
 
3397
                return(DATA_BLOB);
 
3398
  default:
3768
3399
    ut_error;
3769
3400
  }
3770
3401
 
3813
3444
  uint    buff_len,/*!< in: buffer length */
3814
3445
  const unsigned char*  record)/*!< in: row in MySQL format */
3815
3446
{
3816
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3447
  KeyInfo*    key_info  = &table->key_info[keynr];
3817
3448
  KeyPartInfo*  key_part  = key_info->key_part;
3818
3449
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3819
3450
  char*   buff_start  = buff;
3889
3520
 
3890
3521
      data = row_mysql_read_true_varchar(&len,
3891
3522
        (byte*) (record
3892
 
        + (ulint)get_field_offset(getTable(), field)),
 
3523
        + (ulint)get_field_offset(table, field)),
3893
3524
        lenlen);
3894
3525
 
3895
3526
      true_len = len;
3952
3583
 
3953
3584
      blob_data = row_mysql_read_blob_ref(&blob_len,
3954
3585
        (byte*) (record
3955
 
        + (ulint)get_field_offset(getTable(), field)),
 
3586
        + (ulint)get_field_offset(table, field)),
3956
3587
          (ulint) field->pack_length());
3957
3588
 
3958
3589
      true_len = blob_len;
3959
3590
 
3960
 
      ut_a(get_field_offset(getTable(), field)
 
3591
      ut_a(get_field_offset(table, field)
3961
3592
        == key_part->offset);
3962
3593
 
3963
3594
      /* For multi byte character sets we need to calculate
4004
3635
      ulint     key_len;
4005
3636
      const unsigned char*    src_start;
4006
3637
      enum_field_types  real_type;
4007
 
      const CHARSET_INFO* cs= field->charset();
4008
3638
 
4009
3639
      key_len = key_part->length;
4010
3640
 
4026
3656
      memcpy(buff, src_start, true_len);
4027
3657
      buff += true_len;
4028
3658
 
4029
 
      /* Pad the unused space with spaces. */
 
3659
      /* Pad the unused space with spaces. Note that no
 
3660
      padding is ever needed for UCS-2 because in MySQL,
 
3661
      all UCS2 characters are 2 bytes, as MySQL does not
 
3662
      support surrogate pairs, which are needed to represent
 
3663
      characters in the range U+10000 to U+10FFFF. */
4030
3664
 
4031
3665
      if (true_len < key_len) {
4032
 
        ulint   pad_len = key_len - true_len;
4033
 
        ut_a(!(pad_len % cs->mbminlen));
4034
 
 
4035
 
        cs->cset->fill(cs, buff, pad_len,
4036
 
                       0x20 /* space */);
 
3666
        ulint pad_len = key_len - true_len;
 
3667
        memset(buff, ' ', pad_len);
4037
3668
        buff += pad_len;
4038
3669
      }
4039
3670
    }
4141
3772
 
4142
3773
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4143
3774
  'fields'. */
4144
 
  for (i = 0; i < n_fields; i++)
 
3775
  for (i = 0; i < n_fields; i++) 
4145
3776
  {
4146
 
    const dict_col_t *col= &index->table->cols[i];
4147
3777
    templ = prebuilt->mysql_template + n_requested_fields;
4148
3778
    field = table->getField(i);
4149
3779
 
4189
3819
    n_requested_fields++;
4190
3820
 
4191
3821
    templ->col_no = i;
4192
 
    templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
4193
 
    ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4194
3822
 
4195
3823
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3824
      templ->rec_field_no = dict_col_get_clust_pos(
 
3825
        &index->table->cols[i], index);
4197
3826
    } else {
4198
3827
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
3828
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
3829
    }
 
3830
 
 
3831
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
3832
      prebuilt->need_to_access_clustered = TRUE;
4203
3833
    }
4204
3834
 
4205
3835
    if (field->null_ptr) {
4221
3851
      mysql_prefix_len = templ->mysql_col_offset
4222
3852
        + templ->mysql_col_len;
4223
3853
    }
4224
 
    templ->type = col->mtype;
 
3854
    templ->type = index->table->cols[i].mtype;
4225
3855
    templ->mysql_type = (ulint)field->type();
4226
3856
 
4227
3857
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4229
3859
        (((Field_varstring*)field)->pack_length_no_ptr());
4230
3860
    }
4231
3861
 
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;
 
3862
    templ->charset = dtype_get_charset_coll(
 
3863
      index->table->cols[i].prtype);
 
3864
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3865
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3866
    templ->is_unsigned = index->table->cols[i].prtype
 
3867
              & DATA_UNSIGNED;
4236
3868
    if (templ->type == DATA_BLOB) {
4237
3869
      prebuilt->templ_contains_blob = TRUE;
4238
3870
    }
4249
3881
    for (i = 0; i < n_requested_fields; i++) {
4250
3882
      templ = prebuilt->mysql_template + i;
4251
3883
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3884
      templ->rec_field_no = dict_col_get_clust_pos(
 
3885
        &index->table->cols[templ->col_no],
 
3886
        clust_index);
4253
3887
    }
4254
3888
  }
4255
3889
}
4256
3890
 
4257
3891
/********************************************************************//**
 
3892
Get the upper limit of the MySQL integral and floating-point type. */
 
3893
UNIV_INTERN
 
3894
uint64_t
 
3895
ha_innobase::innobase_get_int_col_max_value(
 
3896
/*========================================*/
 
3897
  const Field*  field)
 
3898
{
 
3899
  uint64_t  max_value = 0;
 
3900
 
 
3901
  switch(field->key_type()) {
 
3902
  /* TINY */
 
3903
  case HA_KEYTYPE_BINARY:
 
3904
    max_value = 0xFFULL;
 
3905
    break;
 
3906
  /* LONG */
 
3907
  case HA_KEYTYPE_ULONG_INT:
 
3908
    max_value = 0xFFFFFFFFULL;
 
3909
    break;
 
3910
  case HA_KEYTYPE_LONG_INT:
 
3911
    max_value = 0x7FFFFFFFULL;
 
3912
    break;
 
3913
  /* BIG */
 
3914
  case HA_KEYTYPE_ULONGLONG:
 
3915
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3916
    break;
 
3917
  case HA_KEYTYPE_LONGLONG:
 
3918
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3919
    break;
 
3920
  case HA_KEYTYPE_DOUBLE:
 
3921
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3922
    max_value = 0x20000000000000ULL;
 
3923
    break;
 
3924
  default:
 
3925
    ut_error;
 
3926
  }
 
3927
 
 
3928
  return(max_value);
 
3929
}
 
3930
 
 
3931
/********************************************************************//**
4258
3932
This special handling is really to overcome the limitations of MySQL's
4259
3933
binlogging. We need to eliminate the non-determinism that will arise in
4260
3934
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4323
3997
  trx_t*    trx = session_to_trx(user_session);
4324
3998
 
4325
3999
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4000
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4001
        "%p, but for the current thread it is at %p",
4328
4002
        (const void*) prebuilt->trx, (const void*) trx);
4329
4003
 
4337
4011
    ut_error;
4338
4012
  }
4339
4013
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4014
  sql_command = session_sql_command(user_session);
4341
4015
 
4342
4016
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4017
       || sql_command == SQLCOM_CREATE_INDEX
4405
4079
  num_write_row++;
4406
4080
 
4407
4081
  /* This is the case where the table has an auto-increment column */
4408
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4082
  if (table->next_number_field && record == table->getInsertRecord()) {
4409
4083
 
4410
4084
    /* Reset the error code before calling
4411
4085
    innobase_get_auto_increment(). */
4412
4086
    prebuilt->autoinc_error = DB_SUCCESS;
4413
4087
 
4414
4088
    if ((error = update_auto_increment())) {
 
4089
 
4415
4090
      /* We don't want to mask autoinc overflow errors. */
4416
 
 
4417
 
      /* Handle the case where the AUTOINC sub-system
4418
 
         failed during initialization. */
4419
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4420
 
        error_result = ER_AUTOINC_READ_FAILED;
4421
 
        /* Set the error message to report too. */
4422
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4423
 
        goto func_exit;
4424
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4091
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4425
4092
        error = (int) prebuilt->autoinc_error;
4426
4093
 
4427
4094
        goto report_error;
4441
4108
    /* Build the template used in converting quickly between
4442
4109
    the two database formats */
4443
4110
 
4444
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4111
    build_template(prebuilt, NULL, table,
 
4112
             ROW_MYSQL_WHOLE_ROW);
4445
4113
  }
4446
4114
 
4447
4115
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4448
4116
 
4449
4117
  error = row_insert_for_mysql((byte*) record, prebuilt);
4450
4118
 
4451
 
  user_session->setXaId(trx->id);
4452
 
 
4453
4119
  /* Handle duplicate key errors */
4454
4120
  if (auto_inc_used) {
4455
4121
    ulint   err;
4467
4133
    /* We need the upper limit of the col type to check for
4468
4134
    whether we update the table autoinc counter or not. */
4469
4135
    col_max_value = innobase_get_int_col_max_value(
4470
 
      getTable()->next_number_field); 
 
4136
      table->next_number_field);
 
4137
 
4471
4138
    /* Get the value that MySQL attempted to store in the table.*/
4472
 
    auto_inc = getTable()->next_number_field->val_int();
 
4139
    auto_inc = table->next_number_field->val_int();
4473
4140
 
4474
4141
    switch (error) {
4475
4142
    case DB_DUPLICATE_KEY:
4505
4172
      update the table upper limit. Note: last_value
4506
4173
      will be 0 if get_auto_increment() was not called.*/
4507
4174
 
4508
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4175
      if (auto_inc <= col_max_value
 
4176
          && auto_inc >= prebuilt->autoinc_last_value) {
4509
4177
set_max_autoinc:
4510
 
        /* This should filter out the negative
4511
 
           values set explicitly by the user. */
4512
 
        if (auto_inc <= col_max_value) {
4513
 
          ut_a(prebuilt->autoinc_increment > 0);
4514
 
 
4515
 
          uint64_t      need;
4516
 
          uint64_t      offset;
4517
 
 
4518
 
          offset = prebuilt->autoinc_offset;
4519
 
          need = prebuilt->autoinc_increment;
4520
 
 
4521
 
          auto_inc = innobase_next_autoinc(
4522
 
                                           auto_inc,
4523
 
                                           need, offset, col_max_value);
4524
 
 
4525
 
          err = innobase_set_max_autoinc(
4526
 
                                         auto_inc);
4527
 
 
4528
 
          if (err != DB_SUCCESS) {
4529
 
            error = err;
4530
 
          }
 
4178
        ut_a(prebuilt->autoinc_increment > 0);
 
4179
 
 
4180
        uint64_t  need;
 
4181
        uint64_t  offset;
 
4182
 
 
4183
        offset = prebuilt->autoinc_offset;
 
4184
        need = prebuilt->autoinc_increment;
 
4185
 
 
4186
        auto_inc = innobase_next_autoinc(
 
4187
          auto_inc, need, offset, col_max_value);
 
4188
 
 
4189
        err = innobase_set_max_autoinc(auto_inc);
 
4190
 
 
4191
        if (err != DB_SUCCESS) {
 
4192
          error = err;
4531
4193
        }
4532
4194
      }
4533
4195
      break;
4724
4386
  /* Build an update vector from the modified fields in the rows
4725
4387
  (uses upd_buff of the handle) */
4726
4388
 
4727
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4389
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4728
4390
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4729
4391
      prebuilt, user_session);
4730
4392
 
4733
4395
 
4734
4396
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4735
4397
 
4736
 
  if (getTable()->found_next_number_field)
 
4398
  if (table->found_next_number_field)
4737
4399
  {
4738
4400
    uint64_t  auto_inc;
4739
4401
    uint64_t  col_max_value;
4740
4402
 
4741
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4403
    auto_inc = table->found_next_number_field->val_int();
4742
4404
 
4743
4405
    /* We need the upper limit of the col type to check for
4744
4406
    whether we update the table autoinc counter or not. */
4745
4407
    col_max_value = innobase_get_int_col_max_value(
4746
 
      getTable()->found_next_number_field);
 
4408
      table->found_next_number_field);
4747
4409
 
4748
4410
    uint64_t current_autoinc;
4749
4411
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4771
4433
 
4772
4434
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4773
4435
 
4774
 
  user_session->setXaId(trx->id);
4775
 
 
4776
4436
  /* We need to do some special AUTOINC handling for the following case:
4777
4437
 
4778
4438
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4782
4442
  value used in the INSERT statement.*/
4783
4443
 
4784
4444
  if (error == DB_SUCCESS
4785
 
      && getTable()->next_number_field
4786
 
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4445
      && table->next_number_field
 
4446
      && new_row == table->getInsertRecord()
 
4447
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4448
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4449
    == TRX_DUP_IGNORE)  {
4790
4450
 
4791
4451
    uint64_t  auto_inc;
4792
4452
    uint64_t  col_max_value;
4793
4453
 
4794
 
    auto_inc = getTable()->next_number_field->val_int();
 
4454
    auto_inc = table->next_number_field->val_int();
4795
4455
 
4796
4456
    /* We need the upper limit of the col type to check for
4797
4457
    whether we update the table autoinc counter or not. */
4798
4458
    col_max_value = innobase_get_int_col_max_value(
4799
 
      getTable()->next_number_field);
 
4459
      table->next_number_field);
4800
4460
 
4801
4461
    if (auto_inc <= col_max_value && auto_inc != 0) {
4802
4462
 
4863
4523
 
4864
4524
  error = row_update_for_mysql((byte*) record, prebuilt);
4865
4525
 
4866
 
  user_session->setXaId(trx->id);
4867
 
 
4868
4526
  innodb_srv_conc_exit_innodb(trx);
4869
4527
 
4870
4528
  error = convert_error_code_to_mysql(
4898
4556
  case ROW_READ_WITH_LOCKS:
4899
4557
    if (!srv_locks_unsafe_for_binlog
4900
4558
        && prebuilt->trx->isolation_level
4901
 
        > TRX_ISO_READ_COMMITTED) {
 
4559
        != TRX_ISO_READ_COMMITTED) {
4902
4560
      break;
4903
4561
    }
4904
4562
    /* fall through */
4928
4586
ha_innobase::try_semi_consistent_read(bool yes)
4929
4587
/*===========================================*/
4930
4588
{
4931
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4589
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
4932
4590
 
4933
4591
  /* Row read type is set to semi consistent read if this was
4934
4592
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
4937
4595
 
4938
4596
  if (yes
4939
4597
      && (srv_locks_unsafe_for_binlog
4940
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4598
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
4941
4599
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4942
4600
  } else {
4943
4601
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5123
4781
    return(HA_ERR_CRASHED);
5124
4782
  }
5125
4783
 
5126
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5127
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5128
 
  }
5129
4784
 
5130
4785
  /* Note that if the index for which the search template is built is not
5131
4786
  necessarily prebuilt->index, but can also be the clustered index */
5132
4787
 
5133
4788
  if (prebuilt->sql_stat_start) {
5134
 
    build_template(prebuilt, user_session, getTable(),
 
4789
    build_template(prebuilt, user_session, table,
5135
4790
             ROW_MYSQL_REC_FIELDS);
5136
4791
  }
5137
4792
 
5186
4841
  switch (ret) {
5187
4842
  case DB_SUCCESS:
5188
4843
    error = 0;
5189
 
    getTable()->status = 0;
 
4844
    table->status = 0;
5190
4845
    break;
5191
4846
  case DB_RECORD_NOT_FOUND:
5192
4847
    error = HA_ERR_KEY_NOT_FOUND;
5193
 
    getTable()->status = STATUS_NOT_FOUND;
 
4848
    table->status = STATUS_NOT_FOUND;
5194
4849
    break;
5195
4850
  case DB_END_OF_INDEX:
5196
4851
    error = HA_ERR_KEY_NOT_FOUND;
5197
 
    getTable()->status = STATUS_NOT_FOUND;
 
4852
    table->status = STATUS_NOT_FOUND;
5198
4853
    break;
5199
4854
  default:
5200
4855
    error = convert_error_code_to_mysql((int) ret,
5201
4856
                prebuilt->table->flags,
5202
4857
                user_session);
5203
 
    getTable()->status = STATUS_NOT_FOUND;
 
4858
    table->status = STATUS_NOT_FOUND;
5204
4859
    break;
5205
4860
  }
5206
4861
 
5239
4894
 
5240
4895
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5241
4896
 
5242
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4897
  ut_ad(user_session == table->in_use);
 
4898
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4899
 
 
4900
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5243
4901
  {
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
 
    }
 
4902
    index = dict_table_get_index_on_name(prebuilt->table,
 
4903
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5267
4904
  } else {
5268
4905
    index = dict_table_get_first_index(prebuilt->table);
5269
4906
  }
5270
4907
 
5271
4908
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
4909
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
4910
      "Innodb could not find key n:o %u with name %s "
5274
4911
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
4912
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
4913
      prebuilt->table->name);
5277
4914
  }
5278
4915
 
5298
4935
  prebuilt->index = innobase_get_index(keynr);
5299
4936
 
5300
4937
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
4938
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
4939
          keynr);
5303
4940
    prebuilt->index_usable = FALSE;
5304
4941
    return(1);
5330
4967
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5331
4968
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5332
4969
 
5333
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
4970
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5334
4971
 
5335
4972
  return(0);
5336
4973
}
5390
5027
  switch (ret) {
5391
5028
  case DB_SUCCESS:
5392
5029
    error = 0;
5393
 
    getTable()->status = 0;
 
5030
    table->status = 0;
5394
5031
    break;
5395
5032
  case DB_RECORD_NOT_FOUND:
5396
5033
    error = HA_ERR_END_OF_FILE;
5397
 
    getTable()->status = STATUS_NOT_FOUND;
 
5034
    table->status = STATUS_NOT_FOUND;
5398
5035
    break;
5399
5036
  case DB_END_OF_INDEX:
5400
5037
    error = HA_ERR_END_OF_FILE;
5401
 
    getTable()->status = STATUS_NOT_FOUND;
 
5038
    table->status = STATUS_NOT_FOUND;
5402
5039
    break;
5403
5040
  default:
5404
5041
    error = convert_error_code_to_mysql(
5405
5042
      (int) ret, prebuilt->table->flags, user_session);
5406
 
    getTable()->status = STATUS_NOT_FOUND;
 
5043
    table->status = STATUS_NOT_FOUND;
5407
5044
    break;
5408
5045
  }
5409
5046
 
5598
5235
 
5599
5236
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5600
5237
 
5601
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5238
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5602
5239
 
5603
5240
  if (prebuilt->clust_index_was_generated) {
5604
5241
    /* No primary key was defined for the table and we
5644
5281
{
5645
5282
  uint    len;
5646
5283
 
5647
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5284
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5648
5285
 
5649
5286
  if (prebuilt->clust_index_was_generated) {
5650
5287
    /* No primary key was defined for the table and we
5664
5301
  table. */
5665
5302
 
5666
5303
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5304
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5305
        (ulong) len, (ulong) ref_length);
5669
5306
  }
5670
5307
}
5720
5357
 
5721
5358
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5722
5359
                  field);
5723
 
 
5724
 
    if (!col_type) {
5725
 
      push_warning_printf(
5726
 
                          trx->mysql_thd,
5727
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
 
                          ER_CANT_CREATE_TABLE,
5729
 
                          "Error creating table '%s' with "
5730
 
                          "column '%s'. Please check its "
5731
 
                          "column type and try to re-create "
5732
 
                          "the table with an appropriate "
5733
 
                          "column type.",
5734
 
                          table->name, (char*) field->field_name);
5735
 
      goto err_col;
5736
 
    }
5737
 
 
5738
5360
    if (field->null_ptr) {
5739
5361
      nulls_allowed = 0;
5740
5362
    } else {
5757
5379
        /* in data0type.h we assume that the
5758
5380
        number fits in one byte in prtype */
5759
5381
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5382
          (Session*) trx->mysql_thd,
5761
5383
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5384
          ER_CANT_CREATE_TABLE,
5763
5385
          "In InnoDB, charset-collation codes"
5792
5414
    if (dict_col_name_is_reserved(field->field_name)){
5793
5415
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5794
5416
 
5795
 
  err_col:
5796
5417
      dict_mem_table_free(table);
5797
5418
      trx_commit_for_mysql(trx);
5798
5419
 
5815
5436
 
5816
5437
        if (error == DB_DUPLICATE_KEY) {
5817
5438
                char buf[100];
5818
 
                char* buf_end = innobase_convert_identifier(
5819
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5820
 
                        trx->mysql_thd, TRUE);
5821
 
 
5822
 
                *buf_end = '\0';
 
5439
                innobase_convert_identifier(buf, sizeof buf,
 
5440
                                            table_name, strlen(table_name),
 
5441
                                            trx->mysql_thd, TRUE);
5823
5442
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5824
5443
        }
5825
5444
 
5923
5542
        || col_type == DATA_FLOAT
5924
5543
        || col_type == DATA_DOUBLE
5925
5544
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
5545
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
5546
          "MySQL is trying to create a column "
5928
5547
          "prefix index field, on an "
5929
5548
          "inappropriate data type. Table "
6023
5642
/*================*/
6024
5643
  Session         &session, /*!< in: Session */
6025
5644
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
5645
        const TableIdentifier &identifier,
6027
5646
        message::Table& create_proto)
6028
5647
{
6029
5648
  int   error;
6032
5651
  trx_t*    trx;
6033
5652
  int   primary_key_no;
6034
5653
  uint    i;
 
5654
  char    name2[FN_REFLEN];
 
5655
  char    norm_name[FN_REFLEN];
6035
5656
  ib_int64_t  auto_inc_value;
6036
5657
  ulint   iflags;
6037
5658
  /* Cache the value of innodb_file_format, in case it is
6038
5659
    modified by another thread while the table is being created. */
6039
5660
  const ulint file_format = srv_file_format;
6040
5661
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6041
 
  const char* stmt;
6042
 
  size_t stmt_len;
6043
 
 
6044
 
  std::string search_string(identifier.getSchemaName());
6045
 
  boost::algorithm::to_lower(search_string);
6046
 
 
6047
 
  if (search_string.compare("data_dictionary") == 0)
6048
 
  {
6049
 
    return HA_WRONG_CREATE_OPTION;
6050
 
  }
 
5662
 
 
5663
  const char *table_name= identifier.getPath().c_str();
6051
5664
 
6052
5665
  if (form.getShare()->sizeFields() > 1000) {
6053
5666
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
5683
 
6071
5684
  srv_lower_case_table_names = TRUE;
6072
5685
 
 
5686
  strcpy(name2, table_name);
 
5687
 
 
5688
  normalize_table_name(norm_name, name2);
 
5689
 
6073
5690
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
5691
    or lock waits can happen in it during a table create operation.
6075
5692
    Drop table etc. do this latching in row0mysql.c. */
6134
5751
# error "DICT_TF_ZSSIZE_MAX < 1"
6135
5752
#endif
6136
5753
 
6137
 
    if (strict_mode)
 
5754
    if (SessionVAR(&session, strict_mode))
6138
5755
    {
6139
5756
      if (! srv_file_per_table)
6140
5757
      {
6161
5778
                   (int) form.getShare()->getPrimaryKey() :
6162
5779
                   -1);
6163
5780
 
6164
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5781
  /* Our function row_get_mysql_key_number_for_index assumes
6165
5782
    the primary key is always number 0, if it exists */
6166
5783
 
6167
5784
  assert(primary_key_no == -1 || primary_key_no == 0);
6177
5794
  if (lex_identified_temp_table)
6178
5795
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
5796
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
5797
  error= create_table_def(trx, &form, norm_name,
 
5798
                          lex_identified_temp_table ? name2 : NULL,
6182
5799
                          iflags);
6183
5800
 
6184
 
  session.setXaId(trx->id);
6185
 
 
6186
5801
  if (error) {
6187
5802
    goto cleanup;
6188
5803
  }
6194
5809
      order the rows by their row id which is internally generated
6195
5810
      by InnoDB */
6196
5811
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
5812
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
5813
    if (error) {
6199
5814
      goto cleanup;
6200
5815
    }
6202
5817
 
6203
5818
  if (primary_key_no != -1) {
6204
5819
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5820
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
5821
                              (uint) primary_key_no))) {
6207
5822
      goto cleanup;
6208
5823
    }
6211
5826
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
5827
    if (i != (uint) primary_key_no) {
6213
5828
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5829
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
5830
                                i))) {
6216
5831
        goto cleanup;
6217
5832
      }
6218
5833
    }
6219
5834
  }
6220
5835
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
6222
 
 
6223
 
  if (stmt) {
 
5836
  if (trx->mysql_query_str) {
6224
5837
    string generated_create_table;
6225
 
    const char *query= stmt;
 
5838
    const char *query= trx->mysql_query_str;
6226
5839
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
5840
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
5841
    {
6229
5842
      message::transformTableDefinitionToSql(create_proto,
6230
5843
                                             generated_create_table,
6233
5846
    }
6234
5847
 
6235
5848
    error = row_table_add_foreign_constraints(trx,
6236
 
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
5849
                                              query,
 
5850
                                              norm_name,
6238
5851
                                              lex_identified_temp_table);
6239
 
    switch (error) {
6240
 
 
6241
 
    case DB_PARENT_NO_INDEX:
6242
 
      push_warning_printf(
6243
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6244
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6245
 
                          "Create table '%s' with foreign key constraint"
6246
 
                          " failed. There is no index in the referenced"
6247
 
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6249
 
      break;
6250
 
 
6251
 
    case DB_CHILD_NO_INDEX:
6252
 
      push_warning_printf(
6253
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6254
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6255
 
                          "Create table '%s' with foreign key constraint"
6256
 
                          " failed. There is no index in the referencing"
6257
 
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6259
 
      break;
6260
 
    }
6261
5852
 
6262
5853
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
5854
 
6276
5867
 
6277
5868
  log_buffer_flush_to_disk();
6278
5869
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
5870
  innobase_table = dict_table_get(norm_name, FALSE);
6280
5871
 
6281
5872
  assert(innobase_table != 0);
6282
5873
 
6284
5875
    /* We update the highest file format in the system table
6285
5876
      space, if this table has higher file format setting. */
6286
5877
 
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;
 
5878
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5879
                                    dict_table_get_format(innobase_table));
6292
5880
  }
6293
5881
 
6294
5882
  /* Note: We can't call update_session() as prebuilt will not be
6299
5887
    does a table copy too. */
6300
5888
 
6301
5889
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
5890
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
5891
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
5892
      && create_proto.options().auto_increment_value() != 0) {
6305
5893
 
6306
5894
    /* Query was one of :
6328
5916
 
6329
5917
  if (lex_identified_temp_table)
6330
5918
  {
6331
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5919
    session.storeTableMessage(identifier, create_proto);
6332
5920
  }
6333
5921
  else
6334
5922
  {
6362
5950
 
6363
5951
  ut_a(prebuilt->trx);
6364
5952
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6365
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5953
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6366
5954
 
6367
5955
  dict_table = prebuilt->table;
6368
5956
  trx = prebuilt->trx;
6391
5979
  /* Get the transaction associated with the current session, or create one
6392
5980
  if not yet created, and update prebuilt->trx */
6393
5981
 
6394
 
  update_session(getTable()->in_use);
 
5982
  update_session(table->in_use);
6395
5983
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
5984
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
5985
  fallback:
6398
5986
    /* We only handle TRUNCATE TABLE t as a special case.
6399
5987
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6015
InnobaseEngine::doDropTable(
6428
6016
/*======================*/
6429
6017
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6018
        const TableIdentifier &identifier)
6431
6019
{
6432
6020
  int error;
6433
6021
  trx_t*  parent_trx;
6434
6022
  trx_t*  trx;
 
6023
  char  norm_name[1000];
6435
6024
 
6436
6025
  ut_a(identifier.getPath().length() < 1000);
6437
6026
 
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
 
  }
 
6027
  /* Strangely, MySQL passes the table name without the '.frm'
 
6028
    extension, in contrast to ::create */
 
6029
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6030
 
6446
6031
  /* Get the transaction associated with the current session, or create one
6447
6032
    if not yet created */
6459
6044
 
6460
6045
  /* Drop the table in InnoDB */
6461
6046
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6047
  error = row_drop_table_for_mysql(norm_name, trx,
 
6048
                                   session_sql_command(&session)
6464
6049
                                   == SQLCOM_DROP_DB);
6465
6050
 
6466
 
  session.setXaId(trx->id);
6467
 
 
6468
6051
  /* Flush the log to reduce probability that the .frm files and
6469
6052
    the InnoDB data dictionary get out-of-sync if the user runs
6470
6053
    with innodb_flush_log_at_trx_commit = 0 */
6487
6070
  {
6488
6071
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6072
    {
6490
 
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6073
      session.removeTableMessage(identifier);
 
6074
      ulint sql_command = session_sql_command(&session);
6492
6075
 
6493
6076
      // If this was the final removal to an alter table then we will need
6494
6077
      // to remove the .dfe that was left behind.
6521
6104
bool
6522
6105
InnobaseEngine::doDropSchema(
6523
6106
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6107
                             const SchemaIdentifier &identifier)
6525
6108
    /*!< in: database path; inside InnoDB the name
6526
6109
      of the last directory in the path is used as
6527
6110
      the database name: for example, in 'mysql/data/test'
6571
6154
 
6572
6155
void InnobaseEngine::dropTemporarySchema()
6573
6156
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6157
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6158
  trx_t*  trx= NULL;
6576
6159
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6160
 
6580
6163
  trx = trx_allocate_for_mysql();
6581
6164
 
6582
6165
  trx->mysql_thd = NULL;
 
6166
  trx->mysql_query_str = NULL;
6583
6167
 
6584
6168
  trx->check_foreigns = false;
6585
6169
  trx->check_unique_secondary = false;
6608
6192
innobase_rename_table(
6609
6193
/*==================*/
6610
6194
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6195
  const char* from, /*!< in: old name of the table */
 
6196
  const char* to, /*!< in: new name of the table */
6613
6197
  ibool   lock_and_commit)
6614
6198
        /*!< in: TRUE=lock data dictionary and commit */
6615
6199
{
6616
6200
  int error;
 
6201
  char norm_to[FN_REFLEN];
 
6202
  char norm_from[FN_REFLEN];
6617
6203
 
6618
6204
  srv_lower_case_table_names = TRUE;
6619
6205
 
 
6206
  normalize_table_name(norm_to, to);
 
6207
  normalize_table_name(norm_from, from);
 
6208
 
6620
6209
  /* Serialize data dictionary operations with dictionary mutex:
6621
6210
  no deadlocks can occur then in these operations */
6622
6211
 
6624
6213
    row_mysql_lock_data_dictionary(trx);
6625
6214
  }
6626
6215
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6216
  error = row_rename_table_for_mysql(
 
6217
    norm_from, norm_to, trx, lock_and_commit);
6628
6218
 
6629
6219
  if (error != DB_SUCCESS) {
6630
6220
    FILE* ef = dict_foreign_err_file;
6631
6221
 
6632
6222
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6223
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6224
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6225
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6226
    fputs(" failed!\n", ef);
6637
6227
  }
6638
6228
 
6651
6241
/*********************************************************************//**
6652
6242
Renames an InnoDB table.
6653
6243
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6244
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6245
{
6656
6246
  // A temp table alter table/rename is a shallow rename and only the
6657
6247
  // definition needs to be updated.
6658
6248
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6659
6249
  {
6660
 
    session.getMessageCache().renameTableMessage(from, to);
 
6250
    session.renameTableMessage(from, to);
6661
6251
    return 0;
6662
6252
  }
6663
6253
 
6677
6267
 
6678
6268
  trx = innobase_trx_allocate(&session);
6679
6269
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
6681
 
 
6682
 
  session.setXaId(trx->id);
 
6270
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6683
6271
 
6684
6272
  /* Tell the InnoDB server that there might be work for
6685
6273
    utility threads: */
6702
6290
     is the one we are trying to rename to) and return the generic
6703
6291
     error code. */
6704
6292
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6293
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6294
    error = DB_ERROR;
6707
6295
  }
6708
6296
 
6733
6321
  KeyInfo*    key;
6734
6322
  dict_index_t* index;
6735
6323
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
6737
 
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
6739
 
          + getTable()->getShare()->max_key_length + 100;
 
6324
              table->getShare()->stored_rec_length
 
6325
          + table->getShare()->max_key_length + 100);
 
6326
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6327
          + table->getShare()->max_key_length + 100;
6740
6328
  dtuple_t* range_start;
6741
6329
  dtuple_t* range_end;
6742
6330
  ib_int64_t  n_rows;
6744
6332
  ulint   mode2;
6745
6333
  mem_heap_t* heap;
6746
6334
 
6747
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6335
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6748
6336
 
6749
6337
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6750
6338
 
6755
6343
 
6756
6344
  active_index = keynr;
6757
6345
 
6758
 
  key = &getTable()->key_info[active_index];
6759
 
 
6760
 
  index = innobase_get_index(keynr);
6761
 
 
6762
 
  /* There exists possibility of not being able to find requested
6763
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6764
 
     Necessary message should have been printed in innobase_get_index() */
6765
 
  if (UNIV_UNLIKELY(!index)) {
6766
 
    n_rows = HA_POS_ERROR;
6767
 
    goto func_exit;
6768
 
  }
6769
 
 
6770
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6771
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6772
 
    goto func_exit;
6773
 
  }
 
6346
  key = &table->key_info[active_index];
 
6347
 
 
6348
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6349
 
 
6350
  /* MySQL knows about this index and so we must be able to find it.*/
 
6351
  ut_a(index);
6774
6352
 
6775
6353
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6776
6354
            + sizeof(dtuple_t)));
6815
6393
 
6816
6394
  mem_heap_free(heap);
6817
6395
 
6818
 
func_exit:
6819
6396
  free(key_val_buff2);
6820
6397
 
6821
6398
  prebuilt->trx->op_info = (char*)"";
6845
6422
  dict_index_t* index;
6846
6423
  uint64_t  estimate;
6847
6424
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6425
 
6850
6426
  /* We do not know if MySQL can call this function before calling
6851
6427
  external_lock(). To be safe, update the session of the current table
6852
6428
  handle. */
6853
6429
 
6854
 
  update_session(getTable()->in_use);
 
6430
  update_session(table->in_use);
6855
6431
 
6856
6432
  prebuilt->trx->op_info = (char*)
6857
6433
         "calculating upper bound for table rows";
6863
6439
 
6864
6440
  index = dict_table_get_first_index(prebuilt->table);
6865
6441
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6442
  ut_a(index->stat_n_leaf_pages > 0);
6869
6443
 
6870
6444
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6445
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6446
 
6873
6447
 
6874
6448
  /* Calculate a minimum length for a clustered index record and from
6917
6491
  ha_rows total_rows;
6918
6492
  double  time_for_scan;
6919
6493
 
6920
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6494
  if (index != table->getShare()->getPrimaryKey()) {
6921
6495
    /* Not clustered */
6922
6496
    return(Cursor::read_time(index, ranges, rows));
6923
6497
  }
6941
6515
}
6942
6516
 
6943
6517
/*********************************************************************//**
6944
 
Calculates the key number used inside MySQL for an Innobase index. We will
6945
 
first check the "index translation table" for a match of the index to get
6946
 
the index number. If there does not exist an "index translation table",
6947
 
or not able to find the index in the translation table, then we will fall back
6948
 
to the traditional way of looping through dict_index_t list to find a
6949
 
match. In this case, we have to take into account if we generated a
6950
 
default clustered index for the table
6951
 
@return the key number used inside MySQL */
6952
 
static
6953
 
unsigned int
6954
 
innobase_get_mysql_key_number_for_index(
6955
 
/*====================================*/
6956
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
6957
 
                                        translation table. */
6958
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
6959
 
                                        dictionary */
6960
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
6961
 
                                        dictionary */
6962
 
        const dict_index_t*     index)  /*!< in: index */
6963
 
{
6964
 
        const dict_index_t*     ind;
6965
 
        unsigned int            i;
6966
 
 
6967
 
        ut_ad(index);
6968
 
        ut_ad(ib_table);
6969
 
        ut_ad(table);
6970
 
        ut_ad(share);
6971
 
 
6972
 
        /* If index does not belong to the table of share structure. Search
6973
 
        index->table instead */
6974
 
        if (index->table != ib_table) {
6975
 
                i = 0;
6976
 
                ind = dict_table_get_first_index(index->table);
6977
 
 
6978
 
                while (index != ind) {
6979
 
                        ind = dict_table_get_next_index(ind);
6980
 
                        i++;
6981
 
                }
6982
 
 
6983
 
                if (row_table_got_default_clust_index(index->table)) {
6984
 
                        ut_a(i > 0);
6985
 
                        i--;
6986
 
                }
6987
 
 
6988
 
                return(i);
6989
 
        }
6990
 
 
6991
 
        /* If index does not belong to the table of share structure. Search
6992
 
        index->table instead */
6993
 
        if (index->table != ib_table) {
6994
 
                i = 0;
6995
 
                ind = dict_table_get_first_index(index->table);
6996
 
 
6997
 
                while (index != ind) {
6998
 
                        ind = dict_table_get_next_index(ind);
6999
 
                        i++;
7000
 
                }
7001
 
 
7002
 
                if (row_table_got_default_clust_index(index->table)) {
7003
 
                        ut_a(i > 0);
7004
 
                        i--;
7005
 
                }
7006
 
 
7007
 
                return(i);
7008
 
        }
7009
 
 
7010
 
        /* If index translation table exists, we will first check
7011
 
        the index through index translation table for a match. */
7012
 
        if (share->idx_trans_tbl.index_mapping) {
7013
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7014
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7015
 
                                return(i);
7016
 
                        }
7017
 
                }
7018
 
 
7019
 
                /* Print an error message if we cannot find the index
7020
 
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
7022
 
                              "Cannot find index %s in InnoDB index "
7023
 
                                "translation table.", index->name);
7024
 
        }
7025
 
 
7026
 
        /* If we do not have an "index translation table", or not able
7027
 
        to find the index in the translation table, we'll directly find
7028
 
        matching index in the dict_index_t list */
7029
 
        for (i = 0; i < table->getShare()->keys; i++) {
7030
 
                ind = dict_table_get_index_on_name(
7031
 
                        ib_table, table->key_info[i].name);
7032
 
 
7033
 
                if (index == ind) {
7034
 
                        return(i);
7035
 
                }
7036
 
        }
7037
 
 
7038
 
                errmsg_printf(error::ERROR,
7039
 
                              "Cannot find matching index number for index %s "
7040
 
                              "in InnoDB index list.", index->name);
7041
 
 
7042
 
        return(0);
7043
 
}
7044
 
/*********************************************************************//**
7045
6518
Returns statistics information of the table to the MySQL interpreter,
7046
6519
in various fields of the handle object. */
7047
6520
UNIV_INTERN
7054
6527
  dict_index_t* index;
7055
6528
  ha_rows   rec_per_key;
7056
6529
  ib_int64_t  n_rows;
 
6530
  ulong   j;
 
6531
  ulong   i;
7057
6532
  os_file_stat_t  stat_info;
7058
6533
 
7059
6534
  /* If we are forcing recovery at a high level, we will suppress
7060
6535
  statistics calculation on tables, because that may crash the
7061
6536
  server if an index is badly corrupted. */
7062
6537
 
 
6538
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6539
 
 
6540
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6541
    because we want MySQL to process this query and not
 
6542
    stop, like it would do if it received the error code
 
6543
    HA_ERR_CRASHED. */
 
6544
 
 
6545
    return(0);
 
6546
  }
 
6547
 
7063
6548
  /* We do not know if MySQL can call this function before calling
7064
6549
  external_lock(). To be safe, update the session of the current table
7065
6550
  handle. */
7066
6551
 
7067
 
  update_session(getTable()->in_use);
 
6552
  update_session(table->in_use);
7068
6553
 
7069
6554
  /* In case MySQL calls this in the middle of a SELECT query, release
7070
6555
  possible adaptive hash latch to avoid deadlocks of threads */
7081
6566
 
7082
6567
    prebuilt->trx->op_info = "updating table statistics";
7083
6568
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
 
6569
    dict_update_statistics(ib_table);
7088
6570
 
7089
6571
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
6572
 
7101
6583
  }
7102
6584
 
7103
6585
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
6586
    n_rows = ib_table->stat_n_rows;
7108
6587
 
7109
6588
    /* Because we do not protect stat_n_rows by any mutex in a
7131
6610
    n_rows can not be 0 unless the table is empty, set to 1
7132
6611
    instead. The original problem of bug#29507 is actually
7133
6612
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
6613
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
6614
 
7136
6615
      n_rows = 1;
7137
6616
 
7153
6632
        ib_table->stat_sum_of_other_index_sizes)
7154
6633
          * UNIV_PAGE_SIZE;
7155
6634
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
6635
    /* Since fsp_get_available_space_in_free_extents() is
7159
6636
    acquiring latches inside InnoDB, we do not call it if we
7160
6637
    are asked by MySQL to avoid locking. Another reason to
7161
6638
    avoid the call is that it uses quite a lot of CPU.
7162
 
    See Bug#38185. */
7163
 
    if (flag & HA_STATUS_NO_LOCK) {
7164
 
      /* We do not update delete_length if no
7165
 
         locking is requested so the "old" value can
7166
 
         remain. delete_length is initialized to 0 in
7167
 
         the ha_statistics' constructor. */
7168
 
    } else if (UNIV_UNLIKELY
7169
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7170
 
      /* Avoid accessing the tablespace if
7171
 
         innodb_crash_recovery is set to a high value. */
7172
 
      stats.delete_length = 0;
7173
 
    } else {
7174
 
      ullint    avail_space;
7175
 
 
7176
 
      avail_space = fsp_get_available_space_in_free_extents(ib_table->space);
7177
 
 
7178
 
      if (avail_space == ULLINT_UNDEFINED) {
 
6639
    See Bug#38185.
 
6640
    We do not update delete_length if no locking is requested
 
6641
    so the "old" value can remain. delete_length is initialized
 
6642
    to 0 in the ha_statistics' constructor. */
 
6643
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6644
 
 
6645
      /* lock the data dictionary to avoid races with
 
6646
      ibd_file_missing and tablespace_discarded */
 
6647
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
6648
 
 
6649
      /* ib_table->space must be an existent tablespace */
 
6650
      if (!ib_table->ibd_file_missing
 
6651
          && !ib_table->tablespace_discarded) {
 
6652
 
 
6653
        stats.delete_length =
 
6654
          fsp_get_available_space_in_free_extents(
 
6655
            ib_table->space) * 1024;
 
6656
      } else {
 
6657
 
7179
6658
        Session*  session;
7180
6659
 
7181
 
        session= getTable()->in_use;
 
6660
        session= table->in_use;
7182
6661
        assert(session);
7183
6662
 
7184
6663
        push_warning_printf(
7193
6672
          ib_table->name);
7194
6673
 
7195
6674
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
6675
      }
 
6676
 
 
6677
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
6678
    }
7200
6679
 
7201
6680
    stats.check_time = 0;
7208
6687
  }
7209
6688
 
7210
6689
  if (flag & HA_STATUS_CONST) {
7211
 
    ulong i;
7212
 
    /* Verify the number of index in InnoDB and MySQL
7213
 
       matches up. If prebuilt->clust_index_was_generated
7214
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7215
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6690
    index = dict_table_get_first_index(ib_table);
7216
6691
 
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);
 
6692
    if (prebuilt->clust_index_was_generated) {
 
6693
      index = dict_table_get_next_index(index);
7224
6694
    }
7225
6695
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
 
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
 
      ulong j;
7230
 
      /* We could get index quickly through internal
7231
 
         index mapping with the index translation table.
7232
 
         The identity of index (match up index name with
7233
 
         that of table->key_info[i]) is already verified in
7234
 
         innobase_get_index().  */
7235
 
      index = innobase_get_index(i);
7236
 
 
 
6696
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7237
6697
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
6698
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
6699
            "indexes inside InnoDB than "
7240
6700
            "are defined in the MySQL "
7241
6701
            ".frm file. Have you mixed up "
7247
6707
        break;
7248
6708
      }
7249
6709
 
7250
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6710
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7251
6711
 
7252
6712
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
6713
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
6714
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
6715
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
6716
"installations? "
7281
6741
          rec_per_key = 1;
7282
6742
        }
7283
6743
 
7284
 
        getTable()->key_info[i].rec_per_key[j]=
 
6744
        table->key_info[i].rec_per_key[j]=
7285
6745
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7286
6746
          (ulong) rec_per_key;
7287
6747
      }
 
6748
 
 
6749
      index = dict_table_get_next_index(index);
7288
6750
    }
7289
 
 
7290
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7291
 
  }
7292
 
 
7293
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7294
 
    goto func_exit;
7295
6751
  }
7296
6752
 
7297
6753
  if (flag & HA_STATUS_ERRKEY) {
7304
6760
 
7305
6761
    if (err_index) {
7306
6762
      errkey = (unsigned int)
7307
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7308
 
                                                err_index);
 
6763
        row_get_mysql_key_number_for_index(err_index);
7309
6764
    } else {
7310
6765
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7311
6766
    }
7312
6767
  }
7313
6768
 
7314
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6769
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7315
6770
    stats.auto_increment_value = innobase_peek_autoinc();
7316
6771
  }
7317
6772
 
7318
 
func_exit:
7319
6773
  prebuilt->trx->op_info = (char*)"";
7320
6774
 
7321
6775
  return(0);
7331
6785
/*=================*/
7332
6786
  Session*)   /*!< in: connection thread handle */
7333
6787
{
 
6788
  /* Serialize ANALYZE TABLE inside InnoDB, see
 
6789
     Bug#38996 Race condition in ANALYZE TABLE */
 
6790
  pthread_mutex_lock(&analyze_mutex);
 
6791
 
7334
6792
  /* Simply call ::info() with all the flags */
7335
6793
  info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
7336
6794
 
 
6795
  pthread_mutex_unlock(&analyze_mutex);
 
6796
 
7337
6797
  return(0);
7338
6798
}
7339
6799
 
7348
6808
/*===============*/
7349
6809
  Session*  session)  /*!< in: user thread handle */
7350
6810
{
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;
 
6811
  ulint   ret;
7356
6812
 
7357
 
  assert(session == getTable()->in_use);
 
6813
  assert(session == table->in_use);
7358
6814
  ut_a(prebuilt->trx);
7359
6815
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7360
6816
  ut_a(prebuilt->trx == session_to_trx(session));
7363
6819
    /* Build the template; we will use a dummy template
7364
6820
    in index scans done in checking */
7365
6821
 
7366
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
6822
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
7367
6823
  }
7368
6824
 
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);
 
6825
  ret = row_check_table_for_mysql(prebuilt);
 
6826
 
 
6827
  switch (ret) {
 
6828
  case DB_SUCCESS:
 
6829
    return(HA_ADMIN_OK);
 
6830
  case DB_INTERRUPTED:
 
6831
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
 
6832
    return(-1);
 
6833
  default:
7382
6834
    return(HA_ADMIN_CORRUPT);
7383
6835
  }
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);
7503
6836
}
7504
6837
 
7505
6838
/*************************************************************//**
7525
6858
    return((char*)comment); /* string too long */
7526
6859
  }
7527
6860
 
7528
 
  update_session(getTable()->in_use);
 
6861
  update_session(table->in_use);
7529
6862
 
7530
6863
  prebuilt->trx->op_info = (char*)"returning table comment";
7531
6864
 
7596
6929
  external_lock(). To be safe, update the session of the current table
7597
6930
  handle. */
7598
6931
 
7599
 
  update_session(getTable()->in_use);
 
6932
  update_session(table->in_use);
7600
6933
 
7601
6934
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7602
6935
 
7617
6950
  flen = ftell(srv_dict_tmpfile);
7618
6951
  if (flen < 0) {
7619
6952
    flen = 0;
 
6953
  } else if (flen > 64000 - 1) {
 
6954
    flen = 64000 - 1;
7620
6955
  }
7621
6956
 
7622
6957
  /* allocate buffer for the string, and
7643
6978
  dict_foreign_t* foreign;
7644
6979
 
7645
6980
  ut_a(prebuilt != NULL);
7646
 
  update_session(getTable()->in_use);
 
6981
  update_session(table->in_use);
7647
6982
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7648
6983
  trx_search_latch_release_if_reserved(prebuilt->trx);
7649
6984
  mutex_enter(&(dict_sys->mutex));
7676
7011
      i++;
7677
7012
    }
7678
7013
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
7014
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
7015
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
7016
 
7682
7017
    /* Table name */
7683
7018
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7019
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
7020
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
7021
 
7687
7022
    /** Foreign Fields **/
7759
7094
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7095
 
7761
7096
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7097
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7098
    f_key_list->push_back(pf_key_info);
7764
7099
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7100
  }
7781
7116
{
7782
7117
  bool  can_switch;
7783
7118
 
7784
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7119
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7785
7120
 
7786
7121
  prebuilt->trx->op_info =
7787
7122
      "determining if there are foreign key constraints";
7869
7204
      either, because the calling threads may change.
7870
7205
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7871
7206
    case HA_EXTRA_IGNORE_DUP_KEY:
7872
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7207
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7873
7208
      break;
7874
7209
    case HA_EXTRA_WRITE_CAN_REPLACE:
7875
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7210
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7876
7211
      break;
7877
7212
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7878
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7213
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7879
7214
      break;
7880
7215
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7881
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7216
      session_to_trx(table->in_use)->duplicates &=
7882
7217
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7883
7218
      break;
7884
7219
    default:/* Do nothing */
8014
7349
{
8015
7350
  trx_t*      trx;
8016
7351
  static const char truncated_msg[] = "... truncated...\n";
8017
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7352
  const long    MAX_STATUS_SIZE = 64000;
8018
7353
  ulint     trx_list_start = ULINT_UNDEFINED;
8019
7354
  ulint     trx_list_end = ULINT_UNDEFINED;
8020
7355
 
8032
7367
 
8033
7368
  mutex_enter(&srv_monitor_file_mutex);
8034
7369
  rewind(srv_monitor_file);
8035
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7370
  srv_printf_innodb_monitor(srv_monitor_file,
8036
7371
        &trx_list_start, &trx_list_end);
8037
7372
  flen = ftell(srv_monitor_file);
8038
7373
  os_file_set_eof(srv_monitor_file);
8043
7378
 
8044
7379
  if (flen > MAX_STATUS_SIZE) {
8045
7380
    usable_len = MAX_STATUS_SIZE;
8046
 
    srv_truncated_status_writes++;
8047
7381
  } else {
8048
7382
    usable_len = flen;
8049
7383
  }
8079
7413
 
8080
7414
  mutex_exit(&srv_monitor_file_mutex);
8081
7415
 
8082
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8083
 
             STRING_WITH_LEN(""), str, flen);
 
7416
  bool result = FALSE;
8084
7417
 
 
7418
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7419
      STRING_WITH_LEN(""), str, flen)) {
 
7420
    result= TRUE;
 
7421
  }
8085
7422
  free(str);
8086
7423
 
8087
7424
  return(FALSE);
8088
7425
}
8089
7426
 
8090
7427
/************************************************************************//**
8091
 
Implements the SHOW MUTEX STATUS command.
8092
 
@return true on failure false on success*/
 
7428
Implements the SHOW MUTEX STATUS command. . */
8093
7429
static
8094
7430
bool
8095
7431
innodb_mutex_show_status(
8097
7433
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8098
7434
  Session*  session,  /*!< in: the MySQL query thread of the
8099
7435
          caller */
8100
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8101
 
                                        statistics */
 
7436
  stat_print_fn*  stat_print)
8102
7437
{
8103
7438
  char buf1[IO_SIZE], buf2[IO_SIZE];
8104
7439
  mutex_t*  mutex;
8105
7440
  rw_lock_t*  lock;
8106
 
  ulint         block_mutex_oswait_count = 0;
8107
 
  ulint         block_lock_oswait_count = 0;
8108
 
  mutex_t*      block_mutex = NULL;
8109
 
  rw_lock_t*    block_lock = NULL;
8110
7441
#ifdef UNIV_DEBUG
8111
7442
  ulint   rw_lock_count= 0;
8112
7443
  ulint   rw_lock_count_spin_loop= 0;
8120
7451
 
8121
7452
  mutex_enter(&mutex_list_mutex);
8122
7453
 
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;
 
7454
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7455
 
 
7456
  while (mutex != NULL) {
 
7457
    if (mutex->count_os_wait == 0
 
7458
        || buf_pool_is_block_mutex(mutex)) {
 
7459
      goto next_mutex;
8134
7460
    }
8135
7461
#ifdef UNIV_DEBUG
8136
7462
    if (mutex->mutex_type != 1) {
8157
7483
          return(1);
8158
7484
        }
8159
7485
      }
8160
 
    } else {
 
7486
    }
 
7487
    else {
8161
7488
      rw_lock_count += mutex->count_using;
8162
7489
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8163
7490
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8169
7496
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8170
7497
          mutex->cfile_name, (ulong) mutex->cline);
8171
7498
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8172
 
                      (ulong) mutex->count_os_wait);
 
7499
          mutex->count_os_wait);
8173
7500
 
8174
7501
    if (stat_print(session, innobase_engine_name,
8175
7502
             engine_name_len, buf1, buf1len,
8178
7505
      return(1);
8179
7506
    }
8180
7507
#endif /* UNIV_DEBUG */
8181
 
  }
8182
 
 
8183
 
  if (block_mutex) {
8184
 
    buf1len = snprintf(buf1, sizeof buf1,
8185
 
                       "combined %s:%lu",
8186
 
                       block_mutex->cfile_name,
8187
 
                       (ulong) block_mutex->cline);
8188
 
    buf2len = snprintf(buf2, sizeof buf2,
8189
 
                       "os_waits=%lu",
8190
 
                       (ulong) block_mutex_oswait_count);
8191
 
 
8192
 
    if (stat_print(session, innobase_engine_name,
8193
 
                   strlen(innobase_engine_name), buf1, buf1len,
8194
 
                   buf2, buf2len)) {
8195
 
      mutex_exit(&mutex_list_mutex);
8196
 
      return(1);
8197
 
    }
 
7508
 
 
7509
next_mutex:
 
7510
    mutex = UT_LIST_GET_NEXT(list, mutex);
8198
7511
  }
8199
7512
 
8200
7513
  mutex_exit(&mutex_list_mutex);
8201
7514
 
8202
7515
  mutex_enter(&rw_lock_list_mutex);
8203
7516
 
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
 
    }
 
7517
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7518
 
 
7519
  while (lock != NULL) {
 
7520
    if (lock->count_os_wait
 
7521
                    && !buf_pool_is_block_lock(lock)) {
 
7522
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7523
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7524
      buf2len= snprintf(buf2, sizeof(buf2),
 
7525
                                    "os_waits=%lu", lock->count_os_wait);
 
7526
 
 
7527
      if (stat_print(session, innobase_engine_name,
 
7528
               engine_name_len, buf1, buf1len,
 
7529
               buf2, buf2len)) {
 
7530
        mutex_exit(&rw_lock_list_mutex);
 
7531
        return(1);
 
7532
      }
 
7533
    }
 
7534
    lock = UT_LIST_GET_NEXT(list, lock);
8244
7535
  }
8245
7536
 
8246
7537
  mutex_exit(&rw_lock_list_mutex);
8247
7538
 
8248
7539
#ifdef UNIV_DEBUG
8249
 
  buf2len = snprintf(buf2, sizeof buf2,
8250
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8251
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8252
 
                     (ulong) rw_lock_count,
8253
 
                     (ulong) rw_lock_count_spin_loop,
8254
 
                     (ulong) rw_lock_count_spin_rounds,
8255
 
                     (ulong) rw_lock_count_os_wait,
8256
 
                     (ulong) rw_lock_count_os_yield,
8257
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7540
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7541
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7542
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7543
    rw_lock_count, rw_lock_count_spin_loop,
 
7544
    rw_lock_count_spin_rounds,
 
7545
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7546
    (ulong) (rw_lock_wait_time/1000));
8258
7547
 
8259
7548
  if (stat_print(session, innobase_engine_name, engine_name_len,
8260
7549
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8289
7578
static INNOBASE_SHARE* get_share(const char* table_name)
8290
7579
{
8291
7580
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7581
  pthread_mutex_lock(&innobase_share_mutex);
8293
7582
 
8294
7583
  ulint fold = ut_fold_string(table_name);
8295
7584
 
8308
7597
          innobase_open_tables, fold, share);
8309
7598
 
8310
7599
    thr_lock_init(&share->lock);
8311
 
 
8312
 
    /* Index translation table initialization */
8313
 
    share->idx_trans_tbl.index_mapping = NULL;
8314
 
    share->idx_trans_tbl.index_count = 0;
8315
 
    share->idx_trans_tbl.array_size = 0;
8316
7600
  }
8317
7601
 
8318
7602
  share->use_count++;
 
7603
  pthread_mutex_unlock(&innobase_share_mutex);
8319
7604
 
8320
7605
  return(share);
8321
7606
}
8322
7607
 
8323
7608
static void free_share(INNOBASE_SHARE* share)
8324
7609
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7610
  pthread_mutex_lock(&innobase_share_mutex);
8326
7611
 
8327
7612
#ifdef UNIV_DEBUG
8328
7613
  INNOBASE_SHARE* share2;
8342
7627
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8343
7628
          innobase_open_tables, fold, share);
8344
7629
    share->lock.deinit();
8345
 
 
8346
 
    /* Free any memory from index translation table */
8347
 
    free(share->idx_trans_tbl.index_mapping);
8348
 
 
8349
7630
    delete share;
8350
7631
 
8351
7632
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
7633
    shrinks too much */
8353
7634
  }
 
7635
 
 
7636
  pthread_mutex_unlock(&innobase_share_mutex);
8354
7637
}
8355
7638
 
8356
7639
/*****************************************************************//**
8385
7668
  trx = check_trx_exists(session);
8386
7669
 
8387
7670
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
7671
  const uint32_t sql_command = session_sql_command(session);
8389
7672
 
8390
7673
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
7674
 
8421
7704
    isolation_level = trx->isolation_level;
8422
7705
 
8423
7706
    if ((srv_locks_unsafe_for_binlog
8424
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7707
         || isolation_level == TRX_ISO_READ_COMMITTED)
8425
7708
        && isolation_level != TRX_ISO_SERIALIZABLE
8426
7709
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8427
7710
        && (sql_command == SQLCOM_INSERT_SELECT
8428
7711
            || sql_command == SQLCOM_REPLACE_SELECT
8429
7712
            || sql_command == SQLCOM_UPDATE
8430
 
            || sql_command == SQLCOM_CREATE_TABLE
8431
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7713
            || sql_command == SQLCOM_CREATE_TABLE)) {
8432
7714
 
8433
7715
      /* If we either have innobase_locks_unsafe_for_binlog
8434
7716
      option set or this session is using READ COMMITTED
8436
7718
      is not set to serializable and MySQL is doing
8437
7719
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8438
7720
      or UPDATE ... = (SELECT ...) or CREATE  ...
8439
 
      SELECT... or SET ... = (SELECT ...) without
8440
 
      FOR UPDATE or IN SHARE MODE in select,
8441
 
      then we use consistent read for select. */
 
7721
      SELECT... without FOR UPDATE or IN SHARE
 
7722
      MODE in select, then we use consistent read
 
7723
      for select. */
8442
7724
 
8443
7725
      prebuilt->select_lock_type = LOCK_NONE;
8444
7726
      prebuilt->stored_select_lock_type = LOCK_NONE;
8471
7753
 
8472
7754
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
7755
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
7756
        && !session_tablespace_op(session)
8475
7757
        && sql_command != SQLCOM_TRUNCATE
8476
7758
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
7759
 
8517
7799
  *value = dict_table_autoinc_read(prebuilt->table);
8518
7800
 
8519
7801
  /* It should have been initialized during open. */
8520
 
  if (*value == 0) {
8521
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8522
 
    dict_table_autoinc_unlock(prebuilt->table);
8523
 
  }
 
7802
  ut_a(*value != 0);
8524
7803
 
8525
7804
  return(DB_SUCCESS);
8526
7805
}
8527
7806
 
8528
7807
/*******************************************************************//**
8529
 
This function reads the global auto-inc counter. It doesn't use the
 
7808
This function reads the global auto-inc counter. It doesn't use the 
8530
7809
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8531
7810
@return the autoinc value */
8532
7811
UNIV_INTERN
8546
7825
 
8547
7826
  auto_inc = dict_table_autoinc_read(innodb_table);
8548
7827
 
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
 
  }
 
7828
  ut_a(auto_inc > 0);
8553
7829
 
8554
7830
  dict_table_autoinc_unlock(innodb_table);
8555
7831
 
8578
7854
  uint64_t  autoinc = 0;
8579
7855
 
8580
7856
  /* Prepare prebuilt->trx in the table handle */
8581
 
  update_session(getTable()->in_use);
 
7857
  update_session(table->in_use);
8582
7858
 
8583
7859
  error = innobase_get_autoinc(&autoinc);
8584
7860
 
8602
7878
  invoking this method. So we are not sure if it's guaranteed to
8603
7879
  be 0 or not. */
8604
7880
 
8605
 
  /* We need the upper limit of the col type to check for
8606
 
     whether we update the table autoinc counter or not. */
8607
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8608
 
 
8609
7881
  /* Called for the first time ? */
8610
7882
  if (trx->n_autoinc_rows == 0) {
8611
7883
 
8622
7894
  /* Not in the middle of a mult-row INSERT. */
8623
7895
  } else if (prebuilt->autoinc_last_value == 0) {
8624
7896
    set_if_bigger(*first_value, autoinc);
8625
 
    /* Check for -ve values. */
8626
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8627
 
    /* Set to next logical value. */
8628
 
    ut_a(autoinc > trx->n_autoinc_rows);
8629
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8630
7897
  }
8631
7898
 
8632
7899
  *nb_reserved_values = trx->n_autoinc_rows;
8636
7903
    uint64_t  need;
8637
7904
    uint64_t  current;
8638
7905
    uint64_t  next_value;
 
7906
    uint64_t  col_max_value;
 
7907
 
 
7908
    /* We need the upper limit of the col type to check for
 
7909
    whether we update the table autoinc counter or not. */
 
7910
    col_max_value = innobase_get_int_col_max_value(
 
7911
      table->next_number_field);
8639
7912
 
8640
7913
    current = *first_value > col_max_value ? autoinc : *first_value;
8641
7914
    need = *nb_reserved_values * increment;
8678
7951
{
8679
7952
  int error;
8680
7953
 
8681
 
  update_session(getTable()->in_use);
 
7954
  update_session(table->in_use);
8682
7955
 
8683
7956
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8684
7957
 
8703
7976
/* See comment in Cursor.cc */
8704
7977
UNIV_INTERN
8705
7978
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
7979
InnobaseEngine::get_error_message(int, String *buf)
8707
7980
{
8708
7981
  trx_t*  trx = check_trx_exists(current_session);
8709
7982
 
8744
8017
  /* Do a type-aware comparison of primary key fields. PK fields
8745
8018
  are always NOT NULL, so no checks for NULL are performed. */
8746
8019
 
8747
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
8020
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8748
8021
 
8749
8022
  key_part_end = key_part
8750
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
8023
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8751
8024
 
8752
8025
  for (; key_part != key_part_end; ++key_part) {
8753
8026
    field = key_part->field;
8787
8060
finds charset information and returns length of prefix_len characters in the
8788
8061
index field in bytes.
8789
8062
@return number of bytes occupied by the first n characters */
8790
 
UNIV_INTERN
 
8063
extern "C" UNIV_INTERN
8791
8064
ulint
8792
8065
innobase_get_at_most_n_mbchars(
8793
8066
/*===========================*/
8880
8153
  trx->detailed_error[0]= '\0';
8881
8154
 
8882
8155
  /* Set the isolation level of the transaction. */
8883
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8156
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8884
8157
}
8885
8158
 
8886
8159
void
8895
8168
 
8896
8169
  innobase_release_stat_resources(trx);
8897
8170
 
 
8171
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8172
  {
 
8173
    if (trx->conc_state != TRX_NOT_STARTED)
 
8174
    {
 
8175
      commit(session, TRUE);
 
8176
    }
 
8177
  }
 
8178
  else
 
8179
  {
 
8180
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8181
        trx->global_read_view)
 
8182
    {
 
8183
      /* At low transaction isolation levels we let
 
8184
      each consistent read set its own snapshot */
 
8185
      read_view_close_for_mysql(trx);
 
8186
    }
 
8187
  }
8898
8188
}
8899
8189
 
8900
8190
/*******************************************************************//**
8964
8254
  return(error);
8965
8255
}
8966
8256
 
8967
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8968
 
{
8969
 
  trx_t *trx= session_to_trx(session);
8970
 
  return (trx->id);
8971
 
}
8972
 
 
8973
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8974
 
{
8975
 
  trx_t*& trx = session_to_trx(session);
8976
 
 
8977
 
  if (trx == NULL)
8978
 
  {
8979
 
    trx = innobase_trx_allocate(session);
8980
 
 
8981
 
    innobase_trx_init(session, trx);
8982
 
  }
8983
 
 
8984
 
  mutex_enter(&kernel_mutex);
8985
 
  trx->id= trx_sys_get_new_trx_id();
8986
 
  mutex_exit(&kernel_mutex);
8987
 
 
8988
 
  uint64_t transaction_id= trx->id;
8989
 
 
8990
 
  return transaction_id;
8991
 
}
8992
 
 
8993
8257
/*******************************************************************//**
8994
8258
This function is used to recover X/Open XA distributed transactions.
8995
8259
@return number of prepared transactions stored in xid_list */
9101
8365
}
9102
8366
 
9103
8367
/************************************************************//**
 
8368
Validate the file format check value, is it one of "on" or "off",
 
8369
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8370
@return true if config value one of "on" or  "off" */
 
8371
static
 
8372
bool
 
8373
innobase_file_format_check_on_off(
 
8374
/*==============================*/
 
8375
  const char* format_check) /*!< in: parameter value */
 
8376
{
 
8377
  bool    ret = true;
 
8378
 
 
8379
  if (!innobase_strcasecmp(format_check, "off")) {
 
8380
 
 
8381
    /* Set the value to disable checking. */
 
8382
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8383
 
 
8384
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8385
 
 
8386
    /* Set the value to the lowest supported format. */
 
8387
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8388
  } else {
 
8389
    ret = FALSE;
 
8390
  }
 
8391
 
 
8392
  return(ret);
 
8393
}
 
8394
 
 
8395
/************************************************************//**
9104
8396
Validate the file format check config parameters, as a side effect it
9105
 
sets the srv_max_file_format_at_startup variable.
 
8397
sets the srv_check_file_format_at_startup variable.
9106
8398
@return the format_id if valid config value, otherwise, return -1 */
9107
8399
static
9108
8400
int
9109
8401
innobase_file_format_validate_and_set(
9110
8402
/*================================*/
9111
 
  const char* format_max) /*!< in: parameter value */
 
8403
  const char* format_check) /*!< in: parameter value */
9112
8404
{
9113
8405
  uint    format_id;
9114
8406
 
9115
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8407
  format_id = innobase_file_format_name_lookup(format_check);
9116
8408
 
9117
8409
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9118
 
    srv_max_file_format_at_startup = format_id;
 
8410
    srv_check_file_format_at_startup = format_id;
9119
8411
    return((int) format_id);
9120
8412
  } else {
9121
8413
    return(-1);
9122
8414
  }
9123
8415
}
9124
8416
 
9125
 
 
 
8417
/*************************************************************//**
 
8418
Check if it is a valid file format. This function is registered as
 
8419
a callback with MySQL.
 
8420
@return 0 for valid file format */
 
8421
static
 
8422
int
 
8423
innodb_file_format_name_validate(
 
8424
/*=============================*/
 
8425
  Session*      , /*!< in: thread handle */
 
8426
  drizzle_sys_var*  , /*!< in: pointer to system
 
8427
            variable */
 
8428
  void*       save, /*!< out: immediate result
 
8429
            for update function */
 
8430
  drizzle_value*    value)  /*!< in: incoming string */
 
8431
{
 
8432
  const char* file_format_input;
 
8433
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8434
  int   len = sizeof(buff);
 
8435
 
 
8436
  ut_a(save != NULL);
 
8437
  ut_a(value != NULL);
 
8438
 
 
8439
  file_format_input = value->val_str(value, buff, &len);
 
8440
 
 
8441
  if (file_format_input != NULL) {
 
8442
    uint  format_id;
 
8443
 
 
8444
    format_id = innobase_file_format_name_lookup(
 
8445
      file_format_input);
 
8446
 
 
8447
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8448
      /* Save a pointer to the name in the
 
8449
         'file_format_name_map' constant array. */
 
8450
      *static_cast<const char**>(save) =
 
8451
        trx_sys_file_format_id_to_name(format_id);
 
8452
 
 
8453
      return(0);
 
8454
    }
 
8455
  }
 
8456
 
 
8457
  *static_cast<const char**>(save) = NULL;
 
8458
  return(1);
 
8459
}
 
8460
 
 
8461
/****************************************************************//**
 
8462
Update the system variable innodb_file_format using the "saved"
 
8463
value. This function is registered as a callback with MySQL. */
 
8464
static
 
8465
void
 
8466
innodb_file_format_name_update(
 
8467
/*===========================*/
 
8468
  Session*      ,   /*!< in: thread handle */
 
8469
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8470
              system variable */
 
8471
  void*       var_ptr,  /*!< out: where the
 
8472
              formal string goes */
 
8473
  const void*     save)   /*!< in: immediate result
 
8474
              from check function */
 
8475
{
 
8476
  const char* format_name;
 
8477
 
 
8478
  ut_a(var_ptr != NULL);
 
8479
  ut_a(save != NULL);
 
8480
 
 
8481
  format_name = *static_cast<const char*const*>(save);
 
8482
 
 
8483
  if (format_name) {
 
8484
    uint  format_id;
 
8485
 
 
8486
    format_id = innobase_file_format_name_lookup(format_name);
 
8487
 
 
8488
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8489
      srv_file_format = format_id;
 
8490
    }
 
8491
  }
 
8492
 
 
8493
  *static_cast<const char**>(var_ptr)
 
8494
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8495
}
 
8496
 
 
8497
/*************************************************************//**
 
8498
Check if valid argument to innodb_file_format_check. This
 
8499
function is registered as a callback with MySQL.
 
8500
@return 0 for valid file format */
 
8501
static
 
8502
int
 
8503
innodb_file_format_check_validate(
 
8504
/*==============================*/
 
8505
  Session*      session, /*!< in: thread handle */
 
8506
  drizzle_sys_var*  , /*!< in: pointer to system
 
8507
            variable */
 
8508
  void*       save, /*!< out: immediate result
 
8509
            for update function */
 
8510
  drizzle_value*    value)  /*!< in: incoming string */
 
8511
{
 
8512
  const char* file_format_input;
 
8513
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8514
  int   len = sizeof(buff);
 
8515
  int   format_id;
 
8516
 
 
8517
  ut_a(save != NULL);
 
8518
  ut_a(value != NULL);
 
8519
 
 
8520
  file_format_input = value->val_str(value, buff, &len);
 
8521
 
 
8522
  if (file_format_input != NULL) {
 
8523
 
 
8524
    /* Check if user set on/off, we want to print a suitable
 
8525
    message if they did so. */
 
8526
 
 
8527
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8528
      push_warning_printf(session,
 
8529
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8530
                          ER_WRONG_ARGUMENTS,
 
8531
        "InnoDB: invalid innodb_file_format_check "
 
8532
        "value; on/off can only be set at startup or "
 
8533
        "in the configuration file");
 
8534
    } else {
 
8535
      format_id = innobase_file_format_validate_and_set(file_format_input);
 
8536
      if (format_id >= 0) {
 
8537
        /* Save a pointer to the name in the
 
8538
           'file_format_name_map' constant array. */
 
8539
        *static_cast<const char**>(save) =
 
8540
          trx_sys_file_format_id_to_name(
 
8541
                                         (uint)format_id);
 
8542
 
 
8543
        return(0);
 
8544
 
 
8545
      } else {
 
8546
        push_warning_printf(session,
 
8547
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8548
                            ER_WRONG_ARGUMENTS,
 
8549
                            "InnoDB: invalid innodb_file_format_check "
 
8550
                            "value; can be any format up to %s "
 
8551
                            "or its equivalent numeric id",
 
8552
                            trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
8553
      }
 
8554
    }
 
8555
  }
 
8556
 
 
8557
  *static_cast<const char**>(save) = NULL;
 
8558
  return(1);
 
8559
}
 
8560
 
 
8561
/****************************************************************//**
 
8562
Update the system variable innodb_file_format_check using the "saved"
 
8563
value. This function is registered as a callback with MySQL. */
 
8564
static
 
8565
void
 
8566
innodb_file_format_check_update(
 
8567
/*============================*/
 
8568
  Session*      session,  /*!< in: thread handle */
 
8569
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8570
              system variable */
 
8571
  void*       var_ptr,  /*!< out: where the
 
8572
              formal string goes */
 
8573
  const void*     save)   /*!< in: immediate result
 
8574
              from check function */
 
8575
{
 
8576
  const char* format_name_in;
 
8577
  const char**  format_name_out;
 
8578
  uint    format_id;
 
8579
 
 
8580
  ut_a(save != NULL);
 
8581
  ut_a(var_ptr != NULL);
 
8582
 
 
8583
  format_name_in = *static_cast<const char*const*>(save);
 
8584
 
 
8585
  if (!format_name_in) {
 
8586
 
 
8587
    return;
 
8588
  }
 
8589
 
 
8590
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8591
 
 
8592
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8593
    /* DEFAULT is "on", which is invalid at runtime. */
 
8594
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8595
            ER_WRONG_ARGUMENTS,
 
8596
            "Ignoring SET innodb_file_format=%s",
 
8597
            format_name_in);
 
8598
    return;
 
8599
  }
 
8600
 
 
8601
  format_name_out = static_cast<const char**>(var_ptr);
 
8602
 
 
8603
  /* Update the max format id in the system tablespace. */
 
8604
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8605
    ut_print_timestamp(stderr);
 
8606
    fprintf(stderr,
 
8607
      " [Info] InnoDB: the file format in the system "
 
8608
      "tablespace is now set to %s.\n", *format_name_out);
 
8609
  }
 
8610
}
 
8611
 
 
8612
/****************************************************************//**
 
8613
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8614
value. This function is registered as a callback with MySQL. */
 
8615
static
 
8616
void
 
8617
innodb_adaptive_hash_index_update(
 
8618
/*==============================*/
 
8619
  Session*      ,   /*!< in: thread handle */
 
8620
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8621
              system variable */
 
8622
  void*       , /*!< out: where the
 
8623
              formal string goes */
 
8624
  const void*     save)   /*!< in: immediate result
 
8625
              from check function */
 
8626
{
 
8627
  if (*(bool*) save) {
 
8628
    btr_search_enable();
 
8629
  } else {
 
8630
    btr_search_disable();
 
8631
  }
 
8632
}
 
8633
 
 
8634
/****************************************************************//**
 
8635
Update the system variable innodb_old_blocks_pct using the "saved"
 
8636
value. This function is registered as a callback with MySQL. */
 
8637
static
 
8638
void
 
8639
innodb_old_blocks_pct_update(
 
8640
/*=========================*/
 
8641
        Session*                        ,       /*!< in: thread handle */
 
8642
        drizzle_sys_var*        ,       /*!< in: pointer to
 
8643
                                                system variable */
 
8644
        void*                           ,/*!< out: where the
 
8645
                                                formal string goes */
 
8646
        const void*                     save)   /*!< in: immediate result
 
8647
                                                from check function */
 
8648
{
 
8649
        innobase_old_blocks_pct = buf_LRU_old_ratio_update(
 
8650
                *static_cast<const uint*>(save), TRUE);
 
8651
}
 
8652
 
 
8653
/*************************************************************//**
 
8654
Check if it is a valid value of innodb_change_buffering.  This function is
 
8655
registered as a callback with MySQL.
 
8656
@return 0 for valid innodb_change_buffering */
 
8657
static
 
8658
int
 
8659
innodb_change_buffering_validate(
 
8660
/*=============================*/
 
8661
  Session*      , /*!< in: thread handle */
 
8662
  drizzle_sys_var*  , /*!< in: pointer to system
 
8663
            variable */
 
8664
  void*       save, /*!< out: immediate result
 
8665
            for update function */
 
8666
  drizzle_value*    value)  /*!< in: incoming string */
 
8667
{
 
8668
  const char* change_buffering_input;
 
8669
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8670
  int   len = sizeof(buff);
 
8671
 
 
8672
  ut_a(save != NULL);
 
8673
  ut_a(value != NULL);
 
8674
 
 
8675
  change_buffering_input = value->val_str(value, buff, &len);
 
8676
 
 
8677
  if (change_buffering_input != NULL) {
 
8678
    ulint use;
 
8679
 
 
8680
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8681
         use++) {
 
8682
      if (!innobase_strcasecmp(
 
8683
            change_buffering_input,
 
8684
            innobase_change_buffering_values[use])) {
 
8685
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8686
        return(0);
 
8687
      }
 
8688
    }
 
8689
  }
 
8690
 
 
8691
  return(1);
 
8692
}
 
8693
 
 
8694
/****************************************************************//**
 
8695
Update the system variable innodb_change_buffering using the "saved"
 
8696
value. This function is registered as a callback with MySQL. */
 
8697
static
 
8698
void
 
8699
innodb_change_buffering_update(
 
8700
/*===========================*/
 
8701
  Session*      ,   /*!< in: thread handle */
 
8702
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8703
              system variable */
 
8704
  void*       var_ptr,  /*!< out: where the
 
8705
              formal string goes */
 
8706
  const void*     save)   /*!< in: immediate result
 
8707
              from check function */
 
8708
{
 
8709
  ut_a(var_ptr != NULL);
 
8710
  ut_a(save != NULL);
 
8711
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8712
 
 
8713
  ibuf_use = *(const ibuf_use_t*) save;
 
8714
 
 
8715
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8716
}
 
8717
 
 
8718
/* plugin options */
 
8719
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8720
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8721
  "Enable InnoDB checksums validation (enabled by default). ",
 
8722
  NULL, NULL, TRUE);
 
8723
 
 
8724
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8725
  PLUGIN_VAR_READONLY,
 
8726
  "The common part for InnoDB table spaces.",
 
8727
  NULL, NULL, NULL);
 
8728
 
 
8729
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8730
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8731
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8732
  NULL, NULL, TRUE);
 
8733
 
 
8734
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8735
  PLUGIN_VAR_RQCMDARG,
 
8736
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8737
  NULL, NULL, 200, 100, ~0L, 0);
 
8738
 
 
8739
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8740
  PLUGIN_VAR_OPCMDARG,
 
8741
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8742
  "values are 0, 1 (faster)"
 
8743
  " or 2 (fastest - crash-like)"
 
8744
  ".",
 
8745
  NULL, NULL, 1, 0, 2, 0);
 
8746
 
 
8747
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8748
  PLUGIN_VAR_NOCMDARG,
 
8749
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8750
  NULL, NULL, FALSE);
 
8751
 
 
8752
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8753
  PLUGIN_VAR_RQCMDARG,
 
8754
  "File format to use for new tables in .ibd files.",
 
8755
  innodb_file_format_name_validate,
 
8756
  innodb_file_format_name_update, "Antelope");
 
8757
 
 
8758
/* If a new file format is introduced, the file format
 
8759
name needs to be updated accordingly. Please refer to
 
8760
file_format_name_map[] defined in trx0sys.c for the next
 
8761
file format name. */
 
8762
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8763
  PLUGIN_VAR_OPCMDARG,
 
8764
  "The highest file format in the tablespace.",
 
8765
  innodb_file_format_check_validate,
 
8766
  innodb_file_format_check_update,
 
8767
  "Barracuda");
 
8768
 
 
8769
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8770
  PLUGIN_VAR_OPCMDARG,
 
8771
  "Set to 0 (write and flush once per second),"
 
8772
  " 1 (write and flush at each commit)"
 
8773
  " or 2 (write at commit, flush once per second).",
 
8774
  NULL, NULL, 1, 0, 2, 0);
 
8775
 
 
8776
static DRIZZLE_SYSVAR_STR(flush_method, innobase_file_flush_method,
 
8777
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8778
  "With which method to flush data.", NULL, NULL, NULL);
 
8779
 
 
8780
#ifdef UNIV_LOG_ARCHIVE
 
8781
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8782
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8783
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8784
 
 
8785
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8786
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8787
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8788
#endif /* UNIV_LOG_ARCHIVE */
 
8789
 
 
8790
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8791
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8792
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8793
 
 
8794
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8795
  PLUGIN_VAR_RQCMDARG,
 
8796
  "Percentage of dirty pages allowed in bufferpool.",
 
8797
  NULL, NULL, 75, 0, 99, 0);
 
8798
 
 
8799
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8800
  PLUGIN_VAR_NOCMDARG,
 
8801
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8802
  NULL, NULL, TRUE);
 
8803
 
 
8804
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8805
  PLUGIN_VAR_RQCMDARG,
 
8806
  "Desired maximum length of the purge queue (0 = no limit)",
 
8807
  NULL, NULL, 0, 0, ~0L, 0);
 
8808
 
 
8809
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8810
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8811
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8812
  NULL, NULL, FALSE);
 
8813
 
 
8814
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8815
  PLUGIN_VAR_RQCMDARG,
 
8816
  "The number of index pages to sample when calculating statistics (default 8)",
 
8817
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8818
 
 
8819
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8820
  PLUGIN_VAR_OPCMDARG,
 
8821
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8822
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8823
 
 
8824
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8825
  PLUGIN_VAR_RQCMDARG,
 
8826
  "Replication thread delay (ms) on the slave server if "
 
8827
  "innodb_thread_concurrency is reached (0 by default)",
 
8828
  NULL, NULL, 0, 0, ~0UL, 0);
 
8829
 
 
8830
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8831
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8832
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8833
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8834
 
 
8835
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8836
  PLUGIN_VAR_RQCMDARG,
 
8837
  "Data file autoextend increment in megabytes",
 
8838
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8839
 
 
8840
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8841
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8842
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8843
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8844
 
 
8845
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8846
  PLUGIN_VAR_RQCMDARG,
 
8847
  "Helps in performance tuning in heavily concurrent environments.",
 
8848
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8849
 
 
8850
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8851
  PLUGIN_VAR_RQCMDARG,
 
8852
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8853
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8854
 
 
8855
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8856
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8857
  "Number of background read I/O threads in InnoDB.",
 
8858
  NULL, NULL, 4, 1, 64, 0);
 
8859
 
 
8860
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8861
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8862
  "Number of background write I/O threads in InnoDB.",
 
8863
  NULL, NULL, 4, 1, 64, 0);
 
8864
 
 
8865
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8866
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8867
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8868
  NULL, NULL, 0, 0, 6, 0);
 
8869
 
 
8870
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8871
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8872
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8873
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8874
 
 
8875
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8876
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8877
  "Size of each log file in a log group.",
 
8878
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8879
 
 
8880
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8881
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8882
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8883
  NULL, NULL, 2, 2, 100, 0);
 
8884
 
 
8885
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8886
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8887
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8888
  NULL, NULL, 1, 1, 10, 0);
 
8889
 
 
8890
static DRIZZLE_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
 
8891
  PLUGIN_VAR_RQCMDARG,
 
8892
  "Percentage of the buffer pool to reserve for 'old' blocks.",
 
8893
  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
 
8894
 
 
8895
static DRIZZLE_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
 
8896
  PLUGIN_VAR_RQCMDARG,
 
8897
  "Move blocks to the 'new' end of the buffer pool if the first access"
 
8898
  " was at least this many milliseconds ago."
 
8899
  " The timeout is disabled if 0 (the default).",
 
8900
  NULL, NULL, 0, 0, UINT32_MAX, 0);
 
8901
 
 
8902
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8903
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8904
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8905
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8906
 
 
8907
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8908
  PLUGIN_VAR_RQCMDARG,
 
8909
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8910
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8911
 
 
8912
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8913
  PLUGIN_VAR_OPCMDARG,
 
8914
  "Maximum delay between polling for a spin lock (6 by default)",
 
8915
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8916
 
 
8917
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8918
  PLUGIN_VAR_RQCMDARG,
 
8919
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8920
  NULL, NULL, 0, 0, 1000, 0);
 
8921
 
 
8922
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8923
  PLUGIN_VAR_RQCMDARG,
 
8924
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8925
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8926
 
 
8927
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8928
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8929
  "Path to individual files and their sizes.",
 
8930
  NULL, NULL, NULL);
 
8931
 
 
8932
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8933
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8934
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8935
 
 
8936
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8937
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8938
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8939
  NULL, NULL, TRUE);
 
8940
 
 
8941
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8942
  PLUGIN_VAR_RQCMDARG,
 
8943
  "Buffer changes to reduce random access: "
 
8944
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8945
  innodb_change_buffering_validate,
 
8946
  innodb_change_buffering_update, NULL);
 
8947
 
 
8948
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8949
  PLUGIN_VAR_RQCMDARG,
 
8950
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8951
  "trigger a readahead.",
 
8952
  NULL, NULL, 56, 0, 64, 0);
9126
8953
 
9127
8954
static void init_options(drizzled::module::option_context &context)
9128
8955
{
9134
8961
  context("disable-doublewrite",
9135
8962
          "Disable InnoDB doublewrite buffer.");
9136
8963
  context("io-capacity",
9137
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8964
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9138
8965
          "Number of IOPs the server can do. Tunes the background IO rate");
9139
8966
  context("fast-shutdown",
9140
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8967
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9141
8968
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9142
 
  context("purge-batch-size",
9143
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9144
 
          "Number of UNDO logs to purge in one batch from the history list. "
9145
 
          "Default is 20.");
9146
 
  context("purge-threads",
9147
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9148
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9149
8969
  context("file-per-table",
9150
8970
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9151
 
           "Stores each InnoDB table to an .ibd file in the database dir.");
9152
 
  context("file-format-max",
9153
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9154
 
          "The highest file format in the tablespace.");
9155
 
  context("file-format-check",
9156
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9157
 
          "Whether to perform system file format check.");
 
8971
          "Stores each InnoDB table to an .ibd file in the database dir.");
9158
8972
  context("file-format",
9159
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8973
          po::value<string>()->default_value("Antelope"),
9160
8974
          "File format to use for new tables in .ibd files.");
 
8975
  context("file-format-check",
 
8976
          po::value<string>()->default_value("on"),
 
8977
          "The highest file format in the tablespace.");
9161
8978
  context("flush-log-at-trx-commit",
9162
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8979
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9163
8980
          "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).");
9164
8981
  context("flush-method",
9165
8982
          po::value<string>(),
9166
8983
          "With which method to flush data.");
 
8984
#ifdef UNIV_LOG_ARCHIVE
 
8985
  context("log-arch-dir",
 
8986
          po::value<string>(),
 
8987
          "Where full logs should be archived.");
 
8988
  context("log-archive",
 
8989
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8990
          "Set to 1 if you want to have logs archived.");
 
8991
#endif /* UNIV_LOG_ARCHIVE */
9167
8992
  context("log-group-home-dir",
9168
8993
          po::value<string>(),
9169
8994
          "Path to InnoDB log files.");
9170
8995
  context("max-dirty-pages-pct",
9171
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8996
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9172
8997
          "Percentage of dirty pages allowed in bufferpool.");
9173
8998
  context("disable-adaptive-flushing",
9174
8999
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9175
9000
  context("max-purge-lag",
9176
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
9001
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9177
9002
          "Desired maximum length of the purge queue (0 = no limit)");
9178
9003
  context("status-file",
9179
9004
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9181
9006
  context("disable-stats-on-metadata",
9182
9007
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9183
9008
  context("stats-sample-pages",
9184
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
9009
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9185
9010
          "The number of index pages to sample when calculating statistics (default 8)");
9186
9011
  context("disable-adaptive-hash-index",
9187
9012
          "Enable InnoDB adaptive hash index (enabled by default)");
9188
9013
  context("replication-delay",
9189
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
9014
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9190
9015
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9191
9016
  context("additional-mem-pool-size",
9192
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
9017
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9193
9018
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9194
9019
  context("autoextend-increment",
9195
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
9020
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9196
9021
          "Data file autoextend increment in megabytes");
9197
9022
  context("buffer-pool-size",
9198
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
9023
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9199
9024
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9200
 
  context("buffer-pool-instances",
9201
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9202
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9203
 
 
9204
9025
  context("commit-concurrency",
9205
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
9026
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9206
9027
          "Helps in performance tuning in heavily concurrent environments.");
9207
9028
  context("concurrency-tickets",
9208
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
9029
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9209
9030
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9210
9031
  context("read-io-threads",
9211
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
9032
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9212
9033
          "Number of background read I/O threads in InnoDB.");
9213
9034
  context("write-io-threads",
9214
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
9035
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9215
9036
          "Number of background write I/O threads in InnoDB.");
9216
9037
  context("force-recovery",
9217
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
9038
          po::value<long>(&innobase_force_recovery)->default_value(0),
9218
9039
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9219
9040
  context("log-buffer-size",
9220
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
9041
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9221
9042
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9222
9043
  context("log-file-size",
9223
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
9044
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9224
9045
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9225
9046
  context("log-files-in-group",
9226
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
9047
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9227
9048
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9228
9049
  context("mirrored-log-groups",
9229
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
9050
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9230
9051
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9231
9052
  context("open-files",
9232
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
9053
          po::value<long>(&innobase_open_files)->default_value(300L),
9233
9054
          "How many files at the maximum InnoDB keeps open at the same time.");
9234
9055
  context("sync-spin-loops",
9235
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9056
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9236
9057
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9237
9058
  context("spin-wait-delay",
9238
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9059
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9239
9060
          "Maximum delay between polling for a spin lock (6 by default)");
9240
9061
  context("thread-concurrency",
9241
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9062
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9242
9063
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9243
9064
  context("thread-sleep-delay",
9244
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9065
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9245
9066
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9246
9067
  context("data-file-path",
9247
9068
          po::value<string>(),
9251
9072
          "InnoDB version");
9252
9073
  context("use-internal-malloc",
9253
9074
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9254
 
  context("disable-native-aio",
9255
 
          _("Do not use Native AIO library for IO, even if available"));
9256
9075
  context("change-buffering",
9257
 
          po::value<string>(&innobase_change_buffering),
 
9076
          po::value<string>(),
9258
9077
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9259
9078
  context("read-ahead-threshold",
9260
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9079
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9261
9080
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9262
9081
  context("disable-xa",
9263
9082
          "Disable InnoDB support for the XA two-phase commit");
9264
9083
  context("disable-table-locks",
9265
9084
          "Disable InnoDB locking in LOCK TABLES");
9266
9085
  context("strict-mode",
9267
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9086
          po::value<bool>()->default_value(false)->zero_tokens(),
9268
9087
          "Use strict mode when evaluating create options.");
9269
 
  context("replication-log",
9270
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9271
 
          _("Enable internal replication log."));
9272
9088
  context("lock-wait-timeout",
9273
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9274
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9275
 
  context("old-blocks-pct",
9276
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9277
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9278
 
  context("old-blocks-time",
9279
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9280
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9281
 
            " was at least this many milliseconds ago."
9282
 
            " The timeout is disabled if 0 (the default)."));
 
9089
          po::value<unsigned long>()->default_value(50),
 
9090
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9283
9091
}
9284
9092
 
9285
 
 
 
9093
static drizzle_sys_var* innobase_system_variables[]= {
 
9094
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9095
  DRIZZLE_SYSVAR(autoextend_increment),
 
9096
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9097
  DRIZZLE_SYSVAR(checksums),
 
9098
  DRIZZLE_SYSVAR(commit_concurrency),
 
9099
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9100
  DRIZZLE_SYSVAR(data_file_path),
 
9101
  DRIZZLE_SYSVAR(data_home_dir),
 
9102
  DRIZZLE_SYSVAR(doublewrite),
 
9103
  DRIZZLE_SYSVAR(fast_shutdown),
 
9104
  DRIZZLE_SYSVAR(read_io_threads),
 
9105
  DRIZZLE_SYSVAR(write_io_threads),
 
9106
  DRIZZLE_SYSVAR(file_per_table),
 
9107
  DRIZZLE_SYSVAR(file_format),
 
9108
  DRIZZLE_SYSVAR(file_format_check),
 
9109
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9110
  DRIZZLE_SYSVAR(flush_method),
 
9111
  DRIZZLE_SYSVAR(force_recovery),
 
9112
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9113
#ifdef UNIV_LOG_ARCHIVE
 
9114
  DRIZZLE_SYSVAR(log_arch_dir),
 
9115
  DRIZZLE_SYSVAR(log_archive),
 
9116
#endif /* UNIV_LOG_ARCHIVE */
 
9117
  DRIZZLE_SYSVAR(log_buffer_size),
 
9118
  DRIZZLE_SYSVAR(log_file_size),
 
9119
  DRIZZLE_SYSVAR(log_files_in_group),
 
9120
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9121
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9122
  DRIZZLE_SYSVAR(max_purge_lag),
 
9123
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9124
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9125
  DRIZZLE_SYSVAR(old_blocks_pct),
 
9126
  DRIZZLE_SYSVAR(old_blocks_time),
 
9127
  DRIZZLE_SYSVAR(open_files),
 
9128
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9129
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9130
  DRIZZLE_SYSVAR(replication_delay),
 
9131
  DRIZZLE_SYSVAR(status_file),
 
9132
  DRIZZLE_SYSVAR(strict_mode),
 
9133
  DRIZZLE_SYSVAR(support_xa),
 
9134
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9135
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9136
  DRIZZLE_SYSVAR(table_locks),
 
9137
  DRIZZLE_SYSVAR(thread_concurrency),
 
9138
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9139
  DRIZZLE_SYSVAR(version),
 
9140
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9141
  DRIZZLE_SYSVAR(change_buffering),
 
9142
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9143
  DRIZZLE_SYSVAR(io_capacity),
 
9144
  NULL
 
9145
};
9286
9146
 
9287
9147
DRIZZLE_DECLARE_PLUGIN
9288
9148
{
9293
9153
  "Supports transactions, row-level locking, and foreign keys",
9294
9154
  PLUGIN_LICENSE_GPL,
9295
9155
  innobase_init, /* Plugin Init */
9296
 
  NULL, /* depends */
 
9156
  innobase_system_variables, /* system variables */
9297
9157
  init_options /* reserved */
9298
9158
}
9299
9159
DRIZZLE_DECLARE_PLUGIN_END;
9321
9181
  return res;
9322
9182
}
9323
9183
 
 
9184
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9185
 
 
9186
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9187
from zero to nonzero. (Bug #42101)
 
9188
 
 
9189
The initial default value is 0, and without this extra initialization,
 
9190
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9191
to 0, even if it was initially set to nonzero at the command line
 
9192
or configuration file. */
 
9193
static
 
9194
void
 
9195
innobase_commit_concurrency_init_default(void)
 
9196
/*==========================================*/
 
9197
{
 
9198
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9199
    = innobase_commit_concurrency;
 
9200
}
 
9201
 
9324
9202
/***********************************************************************
9325
9203
This function checks each index name for a table against reserved
9326
9204
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9327
9205
this function pushes an warning message to the client, and returns true. */
9328
 
UNIV_INTERN
 
9206
extern "C" UNIV_INTERN
9329
9207
bool
9330
9208
innobase_index_name_is_reserved(
9331
9209
/*============================*/
9345
9223
    if (innobase_strcasecmp(key->name,
9346
9224
                            innobase_index_reserve_name) == 0) {
9347
9225
      /* Push warning to drizzle */
9348
 
      push_warning_printf(trx->mysql_thd,
 
9226
      push_warning_printf((Session*)trx->mysql_thd,
9349
9227
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9350
9228
                          ER_WRONG_NAME_FOR_INDEX,
9351
9229
                          "Cannot Create Index with name "
9371
9249
  ulint   buflen;
9372
9250
  const char* id;
9373
9251
  ulint   idlen;
9374
 
  drizzled::Session *session;
 
9252
  void*   session;
9375
9253
  ibool   file_id;
9376
9254
 
9377
9255
  const char* expected;