~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Lee Bieber
  • Date: 2010-11-14 23:15:42 UTC
  • mfrom: (1929.1.42 warning-stack-frame)
  • Revision ID: kalebral@gmail.com-20101114231542-fnnu6ydd2p17n582
Merge Monty - fix bug 672372: some functions use > 32k stack

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, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, 2009 Google Inc.
 
5
Copyright (c) 2009, Percona Inc.
6
6
 
7
7
Portions of this file contain modifications contributed and copyrighted by
8
8
Google, Inc. Those modifications are gratefully acknowledged and are described
60
60
#include "drizzled/table.h"
61
61
#include "drizzled/field/blob.h"
62
62
#include "drizzled/field/varstring.h"
 
63
#include "drizzled/field/timestamp.h"
63
64
#include "drizzled/plugin/xa_storage_engine.h"
64
65
#include "drizzled/plugin/daemon.h"
65
66
#include "drizzled/memory/multi_malloc.h"
71
72
 
72
73
#include <boost/algorithm/string.hpp>
73
74
#include <boost/program_options.hpp>
74
 
#include <boost/scoped_array.hpp>
75
75
#include <boost/filesystem.hpp>
76
76
#include <drizzled/module/option_map.h>
77
77
#include <iostream>
83
83
/** @file ha_innodb.cc */
84
84
 
85
85
/* Include necessary InnoDB headers */
 
86
extern "C" {
86
87
#include "univ.i"
87
88
#include "buf0lru.h"
88
89
#include "btr0sea.h"
101
102
#include "log0log.h"
102
103
#include "lock0lock.h"
103
104
#include "dict0crea.h"
104
 
#include "create_replication.h"
105
105
#include "btr0cur.h"
106
106
#include "btr0btr.h"
107
107
#include "fsp0fsp.h"
114
114
#include "ha_prototypes.h"
115
115
#include "ut0mem.h"
116
116
#include "ibuf0ibuf.h"
 
117
#include "mysql_addons.h"
 
118
}
117
119
 
118
120
#include "ha_innodb.h"
119
121
#include "data_dictionary.h"
120
 
#include "replication_dictionary.h"
121
122
#include "internal_dictionary.h"
122
123
#include "handler0vars.h"
123
124
 
126
127
#include <string>
127
128
 
128
129
#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
130
 
138
131
using namespace std;
139
132
using namespace drizzled;
140
133
 
141
134
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
135
static pthread_mutex_t innobase_share_mutex;
144
136
/** to force correct commit order in binlog */
 
137
static pthread_mutex_t prepare_commit_mutex;
145
138
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
139
static pthread_mutex_t commit_threads_m;
 
140
static pthread_cond_t commit_cond;
 
141
static pthread_mutex_t commit_cond_m;
148
142
static bool innodb_inited = 0;
149
143
 
150
144
#define INSIDE_HA_INNOBASE_CC
160
154
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
155
 
162
156
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;
 
157
static plugin::TableFunction* status_table_function_ptr= NULL;
 
158
static plugin::TableFunction* cmp_tool= NULL;
 
159
static plugin::TableFunction* cmp_reset_tool= NULL;
 
160
static plugin::TableFunction* cmp_mem_tool= NULL;
 
161
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
 
162
static plugin::TableFunction* innodb_trx_tool= NULL;
 
163
static plugin::TableFunction* innodb_locks_tool= NULL;
 
164
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
165
 
 
166
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
167
  innobase_log_buffer_size,
 
168
  innobase_force_recovery, innobase_open_files;
 
169
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
170
static ulong innobase_commit_concurrency = 0;
 
171
static ulong innobase_read_io_threads;
 
172
static ulong innobase_write_io_threads;
 
173
 
 
174
/**
 
175
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
176
 */
 
177
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
178
static int64_t innobase_log_file_size;
207
179
 
208
180
/** Percentage of the buffer pool to reserve for 'old' blocks.
209
181
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;
 
182
static uint innobase_old_blocks_pct;
219
183
 
220
184
/* The default values for the following char* start-up parameters
221
185
are determined in innobase_init below: */
222
186
 
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;
 
187
static char*  innobase_data_home_dir      = NULL;
 
188
static char*  innobase_data_file_path     = NULL;
 
189
static char*  innobase_log_group_home_dir   = NULL;
 
190
static char*  innobase_file_format_name   = NULL;
 
191
static char*  innobase_change_buffering   = NULL;
 
192
 
 
193
/* Note: This variable can be set to on/off and any of the supported
 
194
file formats in the configuration file, but can only be set to any
 
195
of the supported file formats during runtime. */
 
196
static char*  innobase_file_format_check    = NULL;
 
197
 
 
198
static char*  innobase_file_flush_method   = NULL;
233
199
 
234
200
/* Below we have boolean-valued start-up parameters, and their default
235
201
values */
236
202
 
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;
 
203
static ulong  innobase_fast_shutdown      = 1;
 
204
#ifdef UNIV_LOG_ARCHIVE
 
205
static my_bool  innobase_log_archive      = FALSE;
 
206
static char*  innobase_log_arch_dir     = NULL;
 
207
#endif /* UNIV_LOG_ARCHIVE */
253
208
static my_bool  innobase_use_doublewrite    = TRUE;
254
209
static my_bool  innobase_use_checksums      = TRUE;
255
210
static my_bool  innobase_rollback_on_timeout    = FALSE;
256
211
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
212
 
263
213
static char*  internal_innobase_data_file_path  = NULL;
264
214
 
 
215
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
216
 
265
217
/* The following counter is used to convey information to InnoDB
266
218
about server activity: in selects it is not sensible to call
267
219
srv_active_wake_master_thread after each fetch or search, we only do
279
231
/** Allowed values of innodb_change_buffering */
280
232
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
281
233
  "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 */
 
234
  "inserts" /* IBUF_USE_INSERT */
287
235
};
288
236
 
289
237
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
333
281
      srv_free_paths_and_sizes();
334
282
      if (internal_innobase_data_file_path)
335
283
        free(internal_innobase_data_file_path);
 
284
      pthread_mutex_destroy(&innobase_share_mutex);
 
285
      pthread_mutex_destroy(&prepare_commit_mutex);
 
286
      pthread_mutex_destroy(&commit_threads_m);
 
287
      pthread_mutex_destroy(&commit_cond_m);
 
288
      pthread_cond_destroy(&commit_cond);
336
289
    }
337
290
    
338
291
    /* These get strdup'd from vm variables */
 
292
    free(innobase_data_home_dir);
 
293
    free(innobase_log_group_home_dir);
339
294
 
340
295
  }
341
296
 
422
377
  doDropSchema(
423
378
  /*===================*/
424
379
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
380
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
381
        of the last directory in the path is used as
427
382
        the database name: for example, in 'mysql/data/test'
428
383
        the database name is 'test' */
461
416
 
462
417
  UNIV_INTERN int doCreateTable(Session &session,
463
418
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
419
                                const TableIdentifier &identifier,
465
420
                                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);
 
421
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
422
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
423
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
424
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
425
 
471
426
  UNIV_INTERN uint32_t max_supported_keys() const;
472
427
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
438
  }
484
439
 
485
440
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
441
                           const TableIdentifier &identifier,
487
442
                           drizzled::message::Table &table_proto);
488
443
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
444
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
445
 
491
446
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
447
                             const drizzled::SchemaIdentifier &schema_identifier,
 
448
                             drizzled::TableIdentifiers &set_of_identifiers);
494
449
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
450
  void dropTemporarySchema();
496
451
 
518
473
}
519
474
 
520
475
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
476
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
477
                                           drizzled::TableIdentifiers &set_of_identifiers)
523
478
{
524
479
  CachedDirectory::Entries entries= directory.getEntries();
525
480
 
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
481
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
482
       entry_iter != entries.end(); ++entry_iter)
537
483
  {
547
493
    { }
548
494
    else
549
495
    {
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
 
      }
 
496
      char uname[NAME_LEN + 1];
 
497
      uint32_t file_name_len;
 
498
 
 
499
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
500
      // TODO: Remove need for memory copy here
 
501
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
502
 
 
503
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
565
504
    }
566
505
  }
567
506
}
568
507
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
508
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
509
{
571
510
  string proto_path(identifier.getPath());
572
511
  proto_path.append(DEFAULT_FILE_EXTENSION);
574
513
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
514
    return true;
576
515
 
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)
581
 
    return true;
582
 
 
583
516
  if (access(proto_path.c_str(), F_OK))
584
517
  {
585
518
    return false;
589
522
}
590
523
 
591
524
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
525
                                         const TableIdentifier &identifier,
593
526
                                         message::Table &table_proto)
594
527
{
595
528
  string proto_path(identifier.getPath());
599
532
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
533
    return EEXIST;
601
534
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
603
 
    return EEXIST;
604
 
 
605
535
  if (access(proto_path.c_str(), F_OK))
606
536
  {
607
537
    return errno;
613
543
  return ENOENT;
614
544
}
615
545
 
 
546
/** @brief Initialize the default value of innodb_commit_concurrency.
 
547
 
 
548
Once InnoDB is running, the innodb_commit_concurrency must not change
 
549
from zero to nonzero. (Bug #42101)
 
550
 
 
551
The initial default value is 0, and without this extra initialization,
 
552
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
553
to 0, even if it was initially set to nonzero at the command line
 
554
or configuration file. */
 
555
static
 
556
void
 
557
innobase_commit_concurrency_init_default(void);
 
558
/*==========================================*/
616
559
 
617
560
/************************************************************//**
618
561
Validate the file format name and return its corresponding id.
625
568
            name */
626
569
/************************************************************//**
627
570
Validate the file format check config parameters, as a side effect it
628
 
sets the srv_max_file_format_at_startup variable.
 
571
sets the srv_check_file_format_at_startup variable.
 
572
@return true if one of  "on" or "off" */
 
573
static
 
574
bool
 
575
innobase_file_format_check_on_off(
 
576
/*==============================*/
 
577
  const char* format_check);    /*!< in: parameter value */
 
578
/************************************************************//**
 
579
Validate the file format check config parameters, as a side effect it
 
580
sets the srv_check_file_format_at_startup variable.
629
581
@return the format_id if valid config value, otherwise, return -1 */
630
582
static
631
583
int
632
584
innobase_file_format_validate_and_set(
633
585
/*================================*/
634
 
  const char* format_max);    /*!< in: parameter value */
 
586
  const char* format_check);    /*!< in: parameter value */
635
587
 
636
588
static const char innobase_engine_name[]= "InnoDB";
637
589
 
 
590
/*************************************************************//**
 
591
Check for a valid value of innobase_commit_concurrency.
 
592
@return 0 for valid innodb_commit_concurrency */
 
593
static
 
594
int
 
595
innobase_commit_concurrency_validate(
 
596
/*=================================*/
 
597
  Session*      , /*!< in: thread handle */
 
598
  drizzle_sys_var*  , /*!< in: pointer to system
 
599
            variable */
 
600
  void*       save, /*!< out: immediate result
 
601
            for update function */
 
602
  drizzle_value*    value)  /*!< in: incoming string */
 
603
{
 
604
  int64_t   intbuf;
 
605
  ulong   commit_concurrency;
 
606
 
 
607
  if (value->val_int(value, &intbuf)) {
 
608
    /* The value is NULL. That is invalid. */
 
609
    return(1);
 
610
  }
 
611
 
 
612
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
613
    = static_cast<ulong>(intbuf);
 
614
 
 
615
  /* Allow the value to be updated, as long as it remains zero
 
616
  or nonzero. */
 
617
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
618
}
 
619
 
 
620
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
621
  "Enable InnoDB support for the XA two-phase commit",
 
622
  /* check_func */ NULL, /* update_func */ NULL,
 
623
  /* default */ TRUE);
 
624
 
 
625
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
626
  "Enable InnoDB locking in LOCK TABLES",
 
627
  /* check_func */ NULL, /* update_func */ NULL,
 
628
  /* default */ TRUE);
 
629
 
 
630
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
631
  "Use strict mode when evaluating create options.",
 
632
  NULL, NULL, FALSE);
 
633
 
 
634
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
635
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
636
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
637
 
638
638
 
639
639
/*****************************************************************//**
640
640
Commits a transaction in an InnoDB database. */
798
798
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
799
         in non-Cursor code.
800
800
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
801
extern "C" UNIV_INTERN
802
802
ibool
803
803
thd_is_replication_slave_thread(
804
804
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
805
  void* ) /*!< in: thread handle (Session*) */
806
806
{
807
807
  return false;
808
808
}
872
872
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
873
         in non-Cursor code.
874
874
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
875
extern "C" UNIV_INTERN
876
876
ibool
877
877
thd_has_edited_nontrans_tables(
878
878
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
879
  void*   session)  /*!< in: thread handle (Session*) */
880
880
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
881
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
882
}
883
883
 
884
884
/******************************************************************//**
885
885
Returns true if the thread is executing a SELECT statement.
886
886
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
887
extern "C" UNIV_INTERN
888
888
ibool
889
889
thd_is_select(
890
890
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
891
  const void* session)  /*!< in: thread handle (Session*) */
892
892
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
893
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
894
}
895
895
 
896
896
/******************************************************************//**
897
897
Returns true if the thread supports XA,
898
898
global value of innodb_supports_xa if session is NULL.
899
899
@return true if session has XA support */
900
 
UNIV_INTERN
 
900
extern "C" UNIV_INTERN
901
901
ibool
902
902
thd_supports_xa(
903
903
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
904
  void* session)  /*!< in: thread handle (Session*), or NULL to query
905
905
        the global innodb_supports_xa */
906
906
{
907
 
  /* TODO: Add support here for per-session value */
908
 
  return(support_xa);
 
907
  return(SessionVAR((Session*) session, support_xa));
909
908
}
910
909
 
911
910
/******************************************************************//**
912
911
Returns the lock wait timeout for the current connection.
913
912
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
913
extern "C" UNIV_INTERN
915
914
ulong
916
915
thd_lock_wait_timeout(
917
916
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
917
  void* session)  /*!< in: thread handle (Session*), or NULL to query
919
918
      the global innodb_lock_wait_timeout */
920
919
{
921
 
  /* TODO: Add support here for per-session value */
922
920
  /* According to <drizzle/plugin.h>, passing session == NULL
923
921
  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;
 
922
  return(SessionVAR((Session*) session, lock_wait_timeout));
938
923
}
939
924
 
940
925
/********************************************************************//**
949
934
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
950
935
}
951
936
 
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
937
/********************************************************************//**
977
938
Call this function when mysqld passes control to the client. That is to
978
939
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1022
983
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
984
timeout or a deadlock.
1024
985
@return MySQL error code */
1025
 
UNIV_INTERN
 
986
extern "C" UNIV_INTERN
1026
987
int
1027
988
convert_error_code_to_mysql(
1028
989
/*========================*/
1037
998
  case DB_INTERRUPTED:
1038
999
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1039
1000
    /* 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
1001
  case DB_ERROR:
1053
1002
  default:
1054
1003
    return(-1); /* unspecified error */
1076
1025
    tell it also to MySQL so that MySQL knows to empty the
1077
1026
    cached binlog for this transaction */
1078
1027
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1028
    mark_transaction_to_rollback(session, TRUE);
1080
1029
 
1081
1030
    return(HA_ERR_LOCK_DEADLOCK);
1082
1031
 
1085
1034
    latest SQL statement in a lock wait timeout. Previously, we
1086
1035
    rolled back the whole transaction. */
1087
1036
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1037
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1038
 
1090
1039
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1040
 
1096
1045
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1046
 
1098
1047
  case DB_CANNOT_ADD_CONSTRAINT:
1099
 
  case DB_CHILD_NO_INDEX:
1100
 
  case DB_PARENT_NO_INDEX:
1101
1048
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1049
 
1103
1050
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1068
 
1122
1069
  case DB_TOO_BIG_RECORD:
1123
1070
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1071
       page_get_free_space_of_empty(flags
 
1072
                  & DICT_TF_COMPACT) / 2);
1125
1073
    return(HA_ERR_TO_BIG_ROW);
1126
1074
 
1127
1075
  case DB_NO_SAVEPOINT:
1132
1080
    tell it also to MySQL so that MySQL knows to empty the
1133
1081
    cached binlog for this transaction */
1134
1082
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1083
    mark_transaction_to_rollback(session, TRUE);
1136
1084
 
1137
1085
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1086
 
1166
1114
 
1167
1115
/*************************************************************//**
1168
1116
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1117
extern "C" UNIV_INTERN
1170
1118
void
1171
1119
innobase_mysql_print_thd(
1172
1120
/*=====================*/
1173
1121
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1122
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1123
  uint  )   /*!< in: max query length to print, or 0 to
1176
1124
           use the default max length */
1177
1125
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1126
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1127
  fprintf(f,
1181
1128
          "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()),
 
1129
          static_cast<uint64_t>(session->getSessionId()),
 
1130
          static_cast<uint64_t>(session->getQueryId()),
1184
1131
          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());
 
1132
          session->getSecurityContext().getIp().c_str(),
 
1133
          session->getSecurityContext().getUser().c_str()
 
1134
  );
 
1135
  fprintf(f,
 
1136
          "\n%s", session->getQueryString().c_str()
 
1137
  );
1189
1138
  putc('\n', f);
1190
1139
}
1191
1140
 
1192
1141
/******************************************************************//**
1193
1142
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1143
extern "C" UNIV_INTERN
1195
1144
void
1196
1145
innobase_get_cset_width(
1197
1146
/*====================*/
1208
1157
  if (cs) {
1209
1158
    *mbminlen = cs->mbminlen;
1210
1159
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1160
  } else {
1214
1161
    ut_a(cset == 0);
1215
1162
    *mbminlen = *mbmaxlen = 0;
1218
1165
 
1219
1166
/******************************************************************//**
1220
1167
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1168
extern "C" UNIV_INTERN
1222
1169
void
1223
1170
innobase_convert_from_table_id(
1224
1171
/*===========================*/
1232
1179
 
1233
1180
/******************************************************************//**
1234
1181
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1182
extern "C" UNIV_INTERN
1236
1183
void
1237
1184
innobase_convert_from_id(
1238
1185
/*=====================*/
1247
1194
/******************************************************************//**
1248
1195
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1196
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1197
extern "C" UNIV_INTERN
1251
1198
int
1252
1199
innobase_strcasecmp(
1253
1200
/*================*/
1259
1206
 
1260
1207
/******************************************************************//**
1261
1208
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1209
extern "C" UNIV_INTERN
1263
1210
void
1264
1211
innobase_casedn_str(
1265
1212
/*================*/
1268
1215
  my_casedn_str(system_charset_info, a);
1269
1216
}
1270
1217
 
1271
 
UNIV_INTERN
 
1218
/**********************************************************************//**
 
1219
Determines the connection character set.
 
1220
@return connection character set */
 
1221
extern "C" UNIV_INTERN
 
1222
const void*
 
1223
innobase_get_charset(
 
1224
/*=================*/
 
1225
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1226
{
 
1227
  return static_cast<Session*>(mysql_session)->charset();
 
1228
}
 
1229
 
 
1230
extern "C" UNIV_INTERN
1272
1231
bool
1273
1232
innobase_isspace(
1274
1233
  const void *cs,
1277
1236
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1237
}
1279
1238
 
 
1239
UNIV_INTERN
 
1240
int
 
1241
innobase_fast_mutex_init(
 
1242
        os_fast_mutex_t*        fast_mutex)
 
1243
{
 
1244
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1245
}
 
1246
 
 
1247
/**********************************************************************//**
 
1248
Determines the current SQL statement.
 
1249
@return SQL statement string */
 
1250
extern "C" UNIV_INTERN
 
1251
const char*
 
1252
innobase_get_stmt(
 
1253
/*==============*/
 
1254
        void*   session,        /*!< in: MySQL thread handle */
 
1255
        size_t* length)         /*!< out: length of the SQL statement */
 
1256
{
 
1257
  *length= static_cast<Session*>(session)->query.length();
 
1258
  return static_cast<Session*>(session)->query.c_str();
 
1259
}
 
1260
 
1280
1261
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1262
/*******************************************************************//**
1282
1263
Map an OS error to an errno value. The OS error number is stored in
1283
1264
_doserrno and the mapped value is stored in errno) */
 
1265
extern "C"
1284
1266
void __cdecl
1285
1267
_dosmaperr(
1286
1268
  unsigned long); /*!< in: OS error value */
1288
1270
/*********************************************************************//**
1289
1271
Creates a temporary file.
1290
1272
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1273
extern "C" UNIV_INTERN
1292
1274
int
1293
1275
innobase_mysql_tmpfile(void)
1294
1276
/*========================*/
1368
1350
/*********************************************************************//**
1369
1351
Creates a temporary file.
1370
1352
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1353
extern "C" UNIV_INTERN
1372
1354
int
1373
1355
innobase_mysql_tmpfile(void)
1374
1356
/*========================*/
1375
1357
{
1376
1358
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1359
  int fd = mysql_tmpfile("ib");
1378
1360
  if (fd >= 0) {
1379
1361
    /* Copy the file descriptor, so that the additional resources
1380
1362
    allocated by create_temp_file() can be freed by invoking
1407
1389
number of bytes that were written to "buf" is returned (including the
1408
1390
terminating NUL).
1409
1391
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1392
extern "C" UNIV_INTERN
1411
1393
ulint
1412
1394
innobase_raw_format(
1413
1395
/*================*/
1527
1509
/*********************************************************************//**
1528
1510
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1511
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1512
extern "C" UNIV_INTERN
1531
1513
trx_t*
1532
1514
innobase_trx_allocate(
1533
1515
/*==================*/
1631
1613
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1614
  const char* id, /*!< in: identifier to convert */
1633
1615
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1616
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1617
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1618
        FALSE=id is an UTF-8 string */
1637
1619
{
1638
1620
  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]);
 
1621
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1622
 
1642
1623
  const char* s = id;
1643
1624
  int   q;
1654
1635
    memcpy(nz, id, idlen);
1655
1636
    nz[idlen] = 0;
1656
1637
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1638
    s = nz2;
 
1639
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1640
  }
1660
1641
 
1661
1642
  /* See if the identifier needs to be quoted. */
1709
1690
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1691
and quote it if needed.
1711
1692
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1693
extern "C" UNIV_INTERN
1713
1694
char*
1714
1695
innobase_convert_name(
1715
1696
/*==================*/
1717
1698
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1699
  const char* id, /*!< in: identifier to convert */
1719
1700
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1701
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1702
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1703
        FALSE=id is an index name */
1723
1704
{
1765
1746
/**********************************************************************//**
1766
1747
Determines if the currently running transaction has been interrupted.
1767
1748
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1749
extern "C" UNIV_INTERN
1769
1750
ibool
1770
1751
trx_is_interrupted(
1771
1752
/*===============*/
1772
1753
  trx_t*  trx)  /*!< in: transaction */
1773
1754
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
 
1755
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1775
1756
}
1776
1757
 
1777
1758
/**********************************************************************//**
1778
1759
Determines if the currently running transaction is in strict mode.
1779
1760
@return TRUE if strict */
1780
 
UNIV_INTERN
 
1761
extern "C" UNIV_INTERN
1781
1762
ibool
1782
1763
trx_is_strict(
1783
1764
/*==========*/
1784
1765
        trx_t*  trx)    /*!< in: transaction */
1785
1766
{
1786
 
        return(trx && trx->mysql_thd
1787
 
               && true);
 
1767
  return(trx && trx->mysql_thd && true);
1788
1768
}
1789
1769
 
1790
1770
/**************************************************************//**
1806
1786
  value= value - (value % align_val);
1807
1787
}
1808
1788
 
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
1789
/*********************************************************************//**
2008
1790
Opens an InnoDB database.
2009
1791
@return 0 on success, error code on failure */
2019
1801
  InnobaseEngine *actuall_engine_ptr;
2020
1802
  const module::option_map &vm= context.getOptions();
2021
1803
 
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
1804
  /* Inverted Booleans */
2039
1805
 
2040
1806
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2041
1807
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
1808
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
1809
  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 */
 
1810
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1811
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1812
 
 
1813
  if (vm.count("io-capacity"))
 
1814
  {
 
1815
    if (srv_io_capacity < 100)
 
1816
    {
 
1817
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1818
      exit(-1);
 
1819
    }
 
1820
  }
 
1821
 
2050
1822
  if (vm.count("data-home-dir"))
2051
1823
  {
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
 
 
 
1824
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1825
  }
 
1826
  else
 
1827
  {
 
1828
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
 
1829
  }
 
1830
 
 
1831
  if (vm.count("fast-shutdown"))
 
1832
  {
 
1833
    if (innobase_fast_shutdown > 2)
 
1834
    {
 
1835
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1836
      exit(-1);
 
1837
    }
 
1838
  }
 
1839
 
 
1840
  if (vm.count("file-format-check"))
 
1841
  {
 
1842
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1843
  }
 
1844
 
 
1845
  if (vm.count("flush-log-at-trx-commit"))
 
1846
  {
 
1847
    if (srv_flush_log_at_trx_commit > 2)
 
1848
    {
 
1849
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1850
      exit(-1);
 
1851
    }
 
1852
  }
 
1853
 
 
1854
  if (vm.count("flush-method"))
 
1855
  {
 
1856
    innobase_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1857
  }
 
1858
  else
 
1859
  {
 
1860
    innobase_file_flush_method= NULL;
 
1861
  }
 
1862
 
 
1863
#ifdef UNIV_LOG_ARCHIVE
 
1864
  if (vm.count("log-arch-dir"))
 
1865
  {
 
1866
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1867
  }
 
1868
 
 
1869
  else
 
1870
  {
 
1871
    innobase_log_arch_dir= NULL;
 
1872
  }
 
1873
#endif /* UNIV_LOG_ARCHIVE */
 
1874
 
 
1875
  if (vm.count("max-dirty-pages-pct"))
 
1876
  {
 
1877
    if (srv_max_buf_pool_modified_pct > 99)
 
1878
    {
 
1879
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1880
      exit(-1);
 
1881
    }
 
1882
  }
 
1883
 
 
1884
  if (vm.count("stats-sample-pages"))
 
1885
  {
 
1886
    if (srv_stats_sample_pages < 8)
 
1887
    {
 
1888
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1889
      exit(-1);
 
1890
    }
 
1891
  }
 
1892
 
 
1893
  if (vm.count("additional-mem-pool-size"))
 
1894
  {
 
1895
    align_value(innobase_additional_mem_pool_size);
 
1896
 
 
1897
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1898
    {
 
1899
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1900
      exit(-1);
 
1901
    }
 
1902
 
 
1903
  }
 
1904
 
 
1905
  if (vm.count("autoextend-increment"))
 
1906
  {
 
1907
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1908
    {
 
1909
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1910
      exit(-1);
 
1911
    }
 
1912
  }
 
1913
 
 
1914
  if (vm.count("buffer-pool-size"))
 
1915
  {
 
1916
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1917
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1918
    {
 
1919
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1920
      exit(-1);
 
1921
    }
 
1922
    
 
1923
  }
 
1924
 
 
1925
  if (vm.count("commit-concurrency"))
 
1926
  {
 
1927
    if (srv_replication_delay > 1000)
 
1928
    {
 
1929
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1930
      exit(-1);
 
1931
    }
 
1932
  }
 
1933
 
 
1934
  if (vm.count("concurrency-tickets"))
 
1935
  {
 
1936
    if (srv_n_free_tickets_to_enter < 1)
 
1937
    {
 
1938
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1939
      exit(-1);
 
1940
    }
 
1941
  }
 
1942
 
 
1943
  if (vm.count("read-io-threads"))
 
1944
  {
 
1945
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1946
    {
 
1947
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1948
      exit(-1);
 
1949
    }
 
1950
  }
 
1951
 
 
1952
  if (vm.count("write-io-threads"))
 
1953
  {
 
1954
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1955
    {
 
1956
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1957
      exit(-1);
 
1958
    }
 
1959
  }
 
1960
 
 
1961
  if (vm.count("force-recovery"))
 
1962
  {
 
1963
    if (innobase_force_recovery > 6)
 
1964
    {
 
1965
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
1966
      exit(-1);
 
1967
    }
 
1968
  }
 
1969
 
 
1970
  if (vm.count("log-buffer-size"))
 
1971
  {
 
1972
    align_value(innobase_log_buffer_size);
 
1973
    if (innobase_log_buffer_size < 256*1024L)
 
1974
    {
 
1975
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1976
      exit(-1);
 
1977
    }
 
1978
  }
 
1979
 
 
1980
  if (vm.count("log-file-size"))
 
1981
  {
 
1982
    align_value(innobase_log_file_size, 1024*1024);
 
1983
    if (innobase_log_file_size < 1*1024*1024L)
 
1984
    {
 
1985
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1986
      exit(-1);
 
1987
    }
 
1988
  }
 
1989
 
 
1990
  if (vm.count("log-files-in-group"))
 
1991
  {
 
1992
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
1993
    {
 
1994
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
1995
      exit(-1);
 
1996
    }
 
1997
  }
 
1998
 
 
1999
  if (vm.count("mirrored-log-groups"))
 
2000
  {
 
2001
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2002
    {
 
2003
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2004
      exit(-1);
 
2005
    }
 
2006
  }
 
2007
 
 
2008
  if (vm.count("open-files"))
 
2009
  {
 
2010
    if (innobase_open_files < 10)
 
2011
    {
 
2012
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2013
      exit(-1);
 
2014
    }
 
2015
  }
 
2016
 
 
2017
  if (vm.count("thread-concurrency"))
 
2018
  {
 
2019
    if (srv_thread_concurrency > 1000)
 
2020
    {
 
2021
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2022
      exit(-1);
 
2023
    }
 
2024
  }
2059
2025
 
2060
2026
  if (vm.count("data-file-path"))
2061
2027
  {
2062
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2063
 
  }
2064
 
 
 
2028
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2029
  }
 
2030
  else
 
2031
  {
 
2032
    innobase_data_file_path= NULL;
 
2033
  }
 
2034
 
 
2035
  if (vm.count("version"))
 
2036
  {
 
2037
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2038
  }
 
2039
 
 
2040
  if (vm.count("read-ahead-threshold"))
 
2041
  {
 
2042
    if (srv_read_ahead_threshold > 64)
 
2043
    {
 
2044
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2045
      exit(-1);
 
2046
    }
 
2047
  }
 
2048
 
 
2049
  if (vm.count("strict-mode"))
 
2050
  {
 
2051
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2052
  }
 
2053
 
 
2054
  if (vm.count("lock-wait-timeout"))
 
2055
  {
 
2056
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2057
    {
 
2058
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2059
      exit(-1);
 
2060
    }
 
2061
 
 
2062
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2063
  }
2065
2064
 
2066
2065
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2067
2066
 
2069
2068
 
2070
2069
#ifdef UNIV_DEBUG
2071
2070
  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(),
 
2071
  char      test_tablename[sizeof test_filename
 
2072
    + sizeof srv_mysql50_table_name_prefix];
 
2073
  if ((sizeof test_tablename) - 1
 
2074
      != filename_to_tablename(test_filename, test_tablename,
 
2075
                               sizeof test_tablename)
 
2076
      || strncmp(test_tablename,
 
2077
                 srv_mysql50_table_name_prefix,
 
2078
                 sizeof srv_mysql50_table_name_prefix)
 
2079
      || strcmp(test_tablename
 
2080
                + sizeof srv_mysql50_table_name_prefix,
2083
2081
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2082
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2083
    goto error;
2086
2084
  }
2087
2085
#endif /* UNIV_DEBUG */
2088
2086
 
 
2087
  /* Check that values don't overflow on 32-bit systems. */
 
2088
  if (sizeof(ulint) == 4) {
 
2089
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2090
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2091
                    "innobase_buffer_pool_size can't be over 4GB"
 
2092
                    " on 32-bit systems");
 
2093
 
 
2094
      goto error;
 
2095
    }
 
2096
 
 
2097
    if (innobase_log_file_size > UINT32_MAX) {
 
2098
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2099
                    "innobase_log_file_size can't be over 4GB"
 
2100
                    " on 32-bit systems");
 
2101
 
 
2102
      goto error;
 
2103
    }
 
2104
  }
 
2105
 
2089
2106
  os_innodb_umask = (ulint)internal::my_umask;
2090
2107
 
2091
2108
 
2096
2113
 
2097
2114
  /* The default dir for data files is the datadir of MySQL */
2098
2115
 
2099
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2116
  srv_data_home = (char *)innobase_data_home_dir;
2100
2117
 
2101
2118
  /* Set default InnoDB data file size to 10 MB and let it be
2102
2119
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2103
2120
    to specify any startup options. */
2104
2121
 
2105
 
  if (innobase_data_file_path.empty()) 
2106
 
  {
2107
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2122
  if (!innobase_data_file_path) {
 
2123
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2108
2124
  }
2109
2125
 
2110
2126
  /* Since InnoDB edits the argument in the next call, we make another
2111
2127
    copy of it: */
2112
2128
 
2113
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2129
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2114
2130
 
2115
2131
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2132
                                                   internal_innobase_data_file_path);
2117
2133
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2134
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2135
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2136
mem_free_and_error:
2121
2137
    srv_free_paths_and_sizes();
2122
2138
    if (internal_innobase_data_file_path)
2130
2146
 
2131
2147
  if (vm.count("log-group-home-dir"))
2132
2148
  {
2133
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2149
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
2134
2150
  }
2135
2151
  else
2136
2152
  {
2137
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2153
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
2138
2154
  }
2139
2155
 
 
2156
#ifdef UNIV_LOG_ARCHIVE
 
2157
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2158
    starting from 4.0.6 we always set it the same as
 
2159
innodb_log_group_home_dir: */
 
2160
 
 
2161
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2162
 
 
2163
  srv_arch_dir = innobase_log_arch_dir;
 
2164
#endif /* UNIG_LOG_ARCHIVE */
 
2165
 
2140
2166
  ret = (bool)
2141
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2167
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2142
2168
 
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"));
 
2169
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2170
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2171
                  "wrong number of mirrored log groups");
2146
2172
 
2147
2173
    goto mem_free_and_error;
2148
2174
  }
2156
2182
 
2157
2183
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2184
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2185
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2186
 
2161
2187
      goto mem_free_and_error;
2162
2188
    }
2167
2193
 
2168
2194
  srv_file_format = format_id;
2169
2195
 
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;
 
2196
  /* Given the type of innobase_file_format_name we have little
 
2197
    choice but to cast away the constness from the returned name.
 
2198
    innobase_file_format_name is used in the MySQL set variable
 
2199
    interface and so can't be const. */
 
2200
 
 
2201
  innobase_file_format_name = 
 
2202
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2203
 
 
2204
  /* Process innobase_file_format_check variable */
 
2205
  ut_a(innobase_file_format_check != NULL);
 
2206
 
 
2207
  /* As a side effect it will set srv_check_file_format_at_startup
 
2208
    on valid input. First we check for "on"/"off". */
 
2209
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2210
 
 
2211
    /* Did the user specify a format name that we support ?
 
2212
      As a side effect it will update the variable
 
2213
      srv_check_file_format_at_startup */
 
2214
    if (innobase_file_format_validate_and_set(
 
2215
                                innobase_file_format_check) < 0) {
 
2216
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2217
                    "innodb_file_format_check value: "
 
2218
                    "should be either 'on' or 'off' or "
 
2219
                    "any value up to %s or its "
 
2220
                    "equivalent numeric id",
 
2221
                    trx_sys_file_format_id_to_name(
 
2222
                                                   DICT_TF_FORMAT_MAX));
 
2223
 
 
2224
      goto mem_free_and_error;
 
2225
    }
2192
2226
  }
2193
2227
 
2194
2228
  if (vm.count("change-buffering"))
2199
2233
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2200
2234
         use++) {
2201
2235
      if (!innobase_strcasecmp(
2202
 
                               innobase_change_buffering.c_str(),
 
2236
                               vm["change-buffering"].as<string>().c_str(),
2203
2237
                               innobase_change_buffering_values[use])) {
2204
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2238
        ibuf_use = (ibuf_use_t) use;
2205
2239
        goto innobase_change_buffering_inited_ok;
2206
2240
      }
2207
2241
    }
2208
2242
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2243
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2244
                  "InnoDB: invalid value "
 
2245
                  "innodb_file_format_check=%s",
2210
2246
                  vm["change-buffering"].as<string>().c_str());
2211
2247
    goto mem_free_and_error;
2212
2248
  }
2213
2249
 
2214
2250
innobase_change_buffering_inited_ok:
2215
2251
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2216
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2252
  innobase_change_buffering = (char*)
 
2253
    innobase_change_buffering_values[ibuf_use];
2217
2254
 
2218
2255
  /* --------------------------------------------------*/
2219
2256
 
2220
 
  if (vm.count("flush-method") != 0)
2221
 
  {
2222
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2223
 
  }
 
2257
  srv_file_flush_method_str = innobase_file_flush_method;
2224
2258
 
2225
2259
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2226
2260
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2227
2261
  srv_log_file_size = (ulint) innobase_log_file_size;
2228
2262
 
 
2263
#ifdef UNIV_LOG_ARCHIVE
 
2264
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2265
#endif /* UNIV_LOG_ARCHIVE */
2229
2266
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2230
2267
 
2231
2268
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2232
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2233
2269
 
2234
2270
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2235
2271
 
2260
2296
 
2261
2297
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2262
2298
 
 
2299
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct,
 
2300
                                                     FALSE);
 
2301
 
 
2302
  innobase_commit_concurrency_init_default();
 
2303
 
2263
2304
  /* Since we in this module access directly the fields of a trx
2264
2305
    struct, and due to different headers and flags it might happen that
2265
2306
    mutex_t has a different size in this module and in InnoDB
2268
2309
 
2269
2310
  err = innobase_start_or_create_for_mysql();
2270
2311
 
2271
 
  if (err != DB_SUCCESS)
2272
 
  {
2273
 
    goto mem_free_and_error;
2274
 
  }
2275
 
 
2276
 
  err = dict_create_sys_replication_log();
2277
 
 
2278
2312
  if (err != DB_SUCCESS) {
2279
2313
    goto mem_free_and_error;
2280
2314
  }
2281
2315
 
2282
 
 
2283
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2284
 
                                                     TRUE);
2285
 
 
2286
2316
  innobase_open_tables = hash_create(200);
 
2317
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2318
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2319
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2320
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2321
  pthread_cond_init(&commit_cond, NULL);
2287
2322
  innodb_inited= 1;
2288
2323
 
2289
2324
  actuall_engine_ptr->dropTemporarySchema();
2290
2325
 
2291
 
  context.add(new InnodbStatusTool);
 
2326
  status_table_function_ptr= new InnodbStatusTool;
2292
2327
 
2293
2328
  context.add(innodb_engine_ptr);
2294
2329
 
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());
 
2330
  context.add(status_table_function_ptr);
 
2331
 
 
2332
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2333
  context.add(cmp_tool);
 
2334
 
 
2335
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2336
  context.add(cmp_reset_tool);
 
2337
 
 
2338
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2339
  context.add(cmp_mem_tool);
 
2340
 
 
2341
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2342
  context.add(cmp_mem_reset_tool);
 
2343
 
 
2344
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2345
  context.add(innodb_trx_tool);
 
2346
 
 
2347
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2348
  context.add(innodb_locks_tool);
 
2349
 
 
2350
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2351
  context.add(innodb_lock_waits_tool);
2322
2352
 
2323
2353
  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));
 
2354
 
2414
2355
  /* 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);
 
2356
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2417
2357
 
2418
2358
  return(FALSE);
2419
 
 
2420
2359
error:
2421
2360
  return(TRUE);
2422
2361
}
2513
2452
    trx_search_latch_release_if_reserved(trx);
2514
2453
  }
2515
2454
 
2516
 
  if (all)
2517
 
  {
 
2455
  if (all
 
2456
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2457
 
2518
2458
    /* We were instructed to commit the whole transaction, or
2519
2459
    this is an SQL statement end and autocommit is on */
2520
2460
 
2521
2461
    /* We need current binlog position for ibbackup to work.
2522
2462
    Note, the position is current because of
2523
2463
    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
 
 
 
2464
retry:
 
2465
    if (innobase_commit_concurrency > 0) {
 
2466
      pthread_mutex_lock(&commit_cond_m);
 
2467
      commit_threads++;
 
2468
 
 
2469
      if (commit_threads > innobase_commit_concurrency) {
2535
2470
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2471
        pthread_cond_wait(&commit_cond,
 
2472
          &commit_cond_m);
 
2473
        pthread_mutex_unlock(&commit_cond_m);
 
2474
        goto retry;
 
2475
      }
 
2476
      else {
 
2477
        pthread_mutex_unlock(&commit_cond_m);
 
2478
      }
2538
2479
    }
2539
2480
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2481
                /* Store transaction point for binlog
 
2482
    Later logic tests that this is set to _something_. We need
 
2483
    that logic to fire, even though we do not have a real name. */
 
2484
    trx->mysql_log_file_name = "UNUSED";
2541
2485
    trx->mysql_log_offset = 0;
2542
2486
 
2543
2487
    /* Don't do write + flush right now. For group commit
2547
2491
    innobase_commit_low(trx);
2548
2492
    trx->flush_log_later = FALSE;
2549
2493
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2494
    if (innobase_commit_concurrency > 0) {
 
2495
      pthread_mutex_lock(&commit_cond_m);
2553
2496
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2497
      pthread_cond_signal(&commit_cond);
 
2498
      pthread_mutex_unlock(&commit_cond_m);
2555
2499
    }
2556
2500
 
2557
2501
    /* Now do a write + flush of logs. */
2636
2580
 
2637
2581
  row_unlock_table_autoinc_for_mysql(trx);
2638
2582
 
2639
 
  if (all)
2640
 
  {
 
2583
  if (all
 
2584
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2585
 
2641
2586
    error = trx_rollback_for_mysql(trx);
2642
2587
  } else {
2643
2588
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2793
2738
  /* Warn if rolling back some things... */
2794
2739
  if (session->getKilled() != Session::NOT_KILLED &&
2795
2740
      trx->conc_state != TRX_NOT_STARTED &&
2796
 
      trx->undo_no > 0 &&
 
2741
      trx->undo_no.low > 0 &&
2797
2742
      global_system_variables.log_warnings)
2798
2743
  {
2799
 
      errmsg_printf(error::WARN,
 
2744
      errmsg_printf(ERRMSG_LVL_WARN, 
2800
2745
      "Drizzle is closing a connection during a KILL operation\n"
2801
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2746
      "that has an active InnoDB transaction.  %lu row modifications will "
2802
2747
      "roll back.\n",
2803
 
      (ullint) trx->undo_no);
 
2748
      (ulong) trx->undo_no.low);
2804
2749
  }
2805
2750
 
2806
2751
  innobase_rollback_trx(trx);
2876
2821
  return(true);
2877
2822
}
2878
2823
 
 
2824
/*****************************************************************//**
 
2825
Normalizes a table name string. A normalized name consists of the
 
2826
database name catenated to '/' and table name. An example:
 
2827
test/mytable. On Windows normalization puts both the database name and the
 
2828
table name always to lower case. */
 
2829
static
 
2830
void
 
2831
normalize_table_name(
 
2832
/*=================*/
 
2833
  char*   norm_name,  /*!< out: normalized name as a
 
2834
          null-terminated string */
 
2835
  const char* name)   /*!< in: table name string */
 
2836
{
 
2837
  const char* name_ptr;
 
2838
  const char* db_ptr;
 
2839
  const char* ptr;
 
2840
 
 
2841
  /* Scan name from the end */
 
2842
 
 
2843
  ptr = strchr(name, '\0')-1;
 
2844
 
 
2845
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2846
    ptr--;
 
2847
  }
 
2848
 
 
2849
  name_ptr = ptr + 1;
 
2850
 
 
2851
  assert(ptr > name);
 
2852
 
 
2853
  ptr--;
 
2854
 
 
2855
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2856
    ptr--;
 
2857
  }
 
2858
 
 
2859
  db_ptr = ptr + 1;
 
2860
 
 
2861
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2862
 
 
2863
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2864
 
 
2865
#ifdef __WIN__
 
2866
  innobase_casedn_str(norm_name);
 
2867
#endif
 
2868
}
 
2869
 
2879
2870
/********************************************************************//**
2880
2871
Get the upper limit of the MySQL integral and floating-point type.
2881
2872
@return maximum allowed value for the field */
3009
3000
        dict_index_t**  index_mapping;
3010
3001
        ibool           ret = TRUE;
3011
3002
 
3012
 
        mutex_enter(&dict_sys->mutex);
3013
 
 
3014
3003
        mysql_num_index = table->getShare()->keys;
3015
3004
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3016
3005
 
3040
3029
                                                         sizeof(*index_mapping));
3041
3030
 
3042
3031
                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
3032
                        ret = FALSE;
3050
3033
                        goto func_exit;
3051
3034
                }
3053
3036
                share->idx_trans_tbl.array_size = mysql_num_index;
3054
3037
        }
3055
3038
 
 
3039
 
3056
3040
        /* For each index in the mysql key_info array, fetch its
3057
3041
        corresponding InnoDB index pointer into index_mapping
3058
3042
        array. */
3064
3048
                        ib_table, table->key_info[count].name);
3065
3049
 
3066
3050
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
 
3051
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
 
3052
                                        "index dictionary.",
 
3053
                                        table->key_info[count].name);
3069
3054
                        ret = FALSE;
3070
3055
                        goto func_exit;
3071
3056
                }
3072
3057
 
3073
3058
                /* Double check fetched index has the same
3074
3059
                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;
 
3060
                if (!innobase_match_index_columns(&table->key_info[count],
 
3061
                                                  index_mapping[count])) {
 
3062
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
 
3063
                                        "does not match that of MySQL.",
 
3064
                                        table->key_info[count].name);
 
3065
                        ret = FALSE;
 
3066
                        goto func_exit;
3080
3067
                }
3081
3068
        }
3082
3069
 
3095
3082
 
3096
3083
        share->idx_trans_tbl.index_mapping = index_mapping;
3097
3084
 
3098
 
        mutex_exit(&dict_sys->mutex);
3099
 
 
3100
3085
        return(ret);
3101
3086
}
3102
3087
 
3146
3131
    auto_inc = 0;
3147
3132
 
3148
3133
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
 
3134
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
 
3135
            "column name\n");
3150
3136
  }
3151
3137
 
3152
3138
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3182
3168
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3183
3169
 
3184
3170
    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
 
 
 
3171
    case DB_SUCCESS:
3190
3172
      /* 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
 
 
 
3173
         or the offset, so use a default increment of 1. */
 
3174
      auto_inc = read_auto_inc + 1;
3195
3175
      break;
3196
 
    }
 
3176
 
3197
3177
    case DB_RECORD_NOT_FOUND:
3198
3178
      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);
 
3179
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
3180
              "dictionaries are out of sync.\n"
 
3181
              "InnoDB: Unable to find the AUTOINC column "
 
3182
              "%s in the InnoDB table %s.\n"
 
3183
              "InnoDB: We set the next AUTOINC column "
 
3184
              "value to 0,\n"
 
3185
              "InnoDB: in effect disabling the AUTOINC "
 
3186
              "next value generation.\n"
 
3187
              "InnoDB: You can either set the next "
 
3188
              "AUTOINC value explicitly using ALTER TABLE\n"
 
3189
              "InnoDB: or fix the data dictionary by "
 
3190
              "recreating the table.\n",
 
3191
              col_name, index->table->name);
3206
3192
 
3207
3193
      /* This will disable the AUTOINC generation. */
3208
3194
      auto_inc = 0;
3228
3214
@return 1 if error, 0 if success */
3229
3215
UNIV_INTERN
3230
3216
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
3217
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
3218
                    int   mode,   /*!< in: not used */
3233
3219
                    uint    test_if_locked) /*!< in: not used */
3234
3220
{
3235
3221
  dict_table_t* ib_table;
 
3222
  char    norm_name[FN_REFLEN];
3236
3223
  Session*    session;
3237
3224
 
3238
3225
  UT_NOT_USED(mode);
3247
3234
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3235
  }
3249
3236
 
 
3237
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3238
 
3250
3239
  user_session = NULL;
3251
3240
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3241
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3242
 
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
 
    }
 
3243
    return(1);
3270
3244
  }
3271
3245
 
3272
3246
  /* Create buffers for packing the fields of a record. Why
3275
3249
  stored the string length as the first byte. */
3276
3250
 
3277
3251
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
 
3252
        getTable()->getShare()->stored_rec_length
3279
3253
        + getTable()->getShare()->max_key_length
3280
3254
        + MAX_REF_PARTS * 3;
3281
3255
 
3293
3267
  }
3294
3268
 
3295
3269
  /* 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
 
  }
 
3270
  ib_table = dict_table_get(norm_name, TRUE);
3306
3271
  
3307
3272
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3273
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3274
        "the internal data dictionary of InnoDB "
3310
3275
        "though the .frm file for the\n"
3311
3276
        "table exists. Maybe you have deleted and "
3319
3284
        "doesn't support.\n"
3320
3285
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3286
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3287
        norm_name);
3323
3288
    free_share(share);
3324
3289
    upd_buff.resize(0);
3325
3290
    key_val_buff.resize(0);
3328
3293
    return(HA_ERR_NO_SUCH_TABLE);
3329
3294
  }
3330
3295
 
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 "
 
3296
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
3297
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3298
        "the .ibd file for\ntable %s does not exist.\n"
3334
3299
        "Have you deleted the .ibd file from the "
3335
3300
        "database directory under\nthe MySQL datadir, "
3336
3301
        "or have you used DISCARD TABLESPACE?\n"
3337
3302
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3303
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3304
        norm_name);
3340
3305
    free_share(share);
3341
3306
    upd_buff.resize(0);
3342
3307
    key_val_buff.resize(0);
3348
3313
 
3349
3314
  prebuilt = row_create_prebuilt(ib_table);
3350
3315
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
 
3316
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3352
3317
  prebuilt->default_rec = getTable()->getDefaultValues();
3353
3318
  ut_ad(prebuilt->default_rec);
3354
3319
 
3358
3323
  key_used_on_scan = primary_key;
3359
3324
 
3360
3325
  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());
 
3326
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
 
3327
                    " Table %s failed", identifier.getPath().c_str());
3363
3328
  }
3364
3329
 
3365
3330
  /* Allocate a buffer for a 'row reference'. A row reference is
3373
3338
    prebuilt->clust_index_was_generated = FALSE;
3374
3339
 
3375
3340
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
 
3341
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3377
3342
                    "InnoDB data dictionary, but not "
3378
3343
                    "in MySQL!", identifier.getTableName().c_str());
3379
3344
 
3428
3393
    }
3429
3394
  } else {
3430
3395
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
 
3396
      errmsg_printf(ERRMSG_LVL_ERROR,
3432
3397
                    "Table %s has no primary key in InnoDB data "
3433
3398
                    "dictionary, but has one in MySQL! If you "
3434
3399
                    "created the table with a MySQL version < "
3464
3429
    and it will never be updated anyway. */
3465
3430
 
3466
3431
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3432
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3433
        "Table %s key_used_on_scan is %lu even "
3469
3434
        "though there is no primary key inside "
3470
3435
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3481
3446
    /* We update the highest file format in the system table
3482
3447
    space, if this table has higher file format setting. */
3483
3448
 
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,
 
3449
    trx_sys_file_format_max_upgrade(
 
3450
      (const char**) &innobase_file_format_check,
3487
3451
      dict_table_get_format(prebuilt->table));
3488
 
    innobase_file_format_max= changed_file_format_max;
3489
3452
  }
3490
3453
 
 
3454
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3455
 
3491
3456
  /* Only if the table has an AUTOINC column. */
3492
3457
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
3493
3458
 
3505
3470
    dict_table_autoinc_unlock(prebuilt->table);
3506
3471
  }
3507
3472
 
3508
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3509
 
 
3510
3473
  return(0);
3511
3474
}
3512
3475
 
3616
3579
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3580
function, remember to update the prototype there!
3618
3581
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3582
extern "C" UNIV_INTERN
 
3583
int
3620
3584
innobase_mysql_cmp(
3621
3585
/*===============*/
3622
3586
  int   mysql_type, /*!< in: MySQL type */
3663
3627
      charset = get_charset(charset_number);
3664
3628
 
3665
3629
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3630
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3631
                      "a comparison, but MySQL cannot "
3668
3632
                      "find that charset.",
3669
3633
                      (ulong) charset_number);
3698
3662
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3663
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3664
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3665
extern "C" UNIV_INTERN
3702
3666
ulint
3703
3667
get_innobase_type_from_mysql_type(
3704
3668
/*==============================*/
3747
3711
      return(DATA_VARMYSQL);
3748
3712
    }
3749
3713
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3714
    return(DATA_FIXBINARY);
3752
3715
  case DRIZZLE_TYPE_LONG:
3753
3716
  case DRIZZLE_TYPE_LONGLONG:
3754
3717
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3718
  case DRIZZLE_TYPE_DATE:
3757
3719
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3720
    return(DATA_INT);
3760
3721
  case DRIZZLE_TYPE_DOUBLE:
3761
3722
    return(DATA_DOUBLE);
3762
3723
  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:
 
3724
                return(DATA_BLOB);
 
3725
  default:
3768
3726
    ut_error;
3769
3727
  }
3770
3728
 
4004
3962
      ulint     key_len;
4005
3963
      const unsigned char*    src_start;
4006
3964
      enum_field_types  real_type;
4007
 
      const CHARSET_INFO* cs= field->charset();
4008
3965
 
4009
3966
      key_len = key_part->length;
4010
3967
 
4026
3983
      memcpy(buff, src_start, true_len);
4027
3984
      buff += true_len;
4028
3985
 
4029
 
      /* Pad the unused space with spaces. */
 
3986
      /* Pad the unused space with spaces. Note that no
 
3987
      padding is ever needed for UCS-2 because in MySQL,
 
3988
      all UCS2 characters are 2 bytes, as MySQL does not
 
3989
      support surrogate pairs, which are needed to represent
 
3990
      characters in the range U+10000 to U+10FFFF. */
4030
3991
 
4031
3992
      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 */);
 
3993
        ulint pad_len = key_len - true_len;
 
3994
        memset(buff, ' ', pad_len);
4037
3995
        buff += pad_len;
4038
3996
      }
4039
3997
    }
4141
4099
 
4142
4100
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4143
4101
  'fields'. */
4144
 
  for (i = 0; i < n_fields; i++)
 
4102
  for (i = 0; i < n_fields; i++) 
4145
4103
  {
4146
 
    const dict_col_t *col= &index->table->cols[i];
4147
4104
    templ = prebuilt->mysql_template + n_requested_fields;
4148
4105
    field = table->getField(i);
4149
4106
 
4189
4146
    n_requested_fields++;
4190
4147
 
4191
4148
    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
4149
 
4195
4150
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4151
      templ->rec_field_no = dict_col_get_clust_pos(
 
4152
        &index->table->cols[i], index);
4197
4153
    } else {
4198
4154
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
4155
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
4156
    }
 
4157
 
 
4158
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4159
      prebuilt->need_to_access_clustered = TRUE;
4203
4160
    }
4204
4161
 
4205
4162
    if (field->null_ptr) {
4221
4178
      mysql_prefix_len = templ->mysql_col_offset
4222
4179
        + templ->mysql_col_len;
4223
4180
    }
4224
 
    templ->type = col->mtype;
 
4181
    templ->type = index->table->cols[i].mtype;
4225
4182
    templ->mysql_type = (ulint)field->type();
4226
4183
 
4227
4184
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4229
4186
        (((Field_varstring*)field)->pack_length_no_ptr());
4230
4187
    }
4231
4188
 
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;
 
4189
    templ->charset = dtype_get_charset_coll(
 
4190
      index->table->cols[i].prtype);
 
4191
    templ->mbminlen = index->table->cols[i].mbminlen;
 
4192
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
4193
    templ->is_unsigned = index->table->cols[i].prtype
 
4194
              & DATA_UNSIGNED;
4236
4195
    if (templ->type == DATA_BLOB) {
4237
4196
      prebuilt->templ_contains_blob = TRUE;
4238
4197
    }
4249
4208
    for (i = 0; i < n_requested_fields; i++) {
4250
4209
      templ = prebuilt->mysql_template + i;
4251
4210
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4211
      templ->rec_field_no = dict_col_get_clust_pos(
 
4212
        &index->table->cols[templ->col_no],
 
4213
        clust_index);
4253
4214
    }
4254
4215
  }
4255
4216
}
4323
4284
  trx_t*    trx = session_to_trx(user_session);
4324
4285
 
4325
4286
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4287
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4288
        "%p, but for the current thread it is at %p",
4328
4289
        (const void*) prebuilt->trx, (const void*) trx);
4329
4290
 
4337
4298
    ut_error;
4338
4299
  }
4339
4300
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4301
  sql_command = session_sql_command(user_session);
4341
4302
 
4342
4303
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4304
       || sql_command == SQLCOM_CREATE_INDEX
4448
4409
 
4449
4410
  error = row_insert_for_mysql((byte*) record, prebuilt);
4450
4411
 
4451
 
  user_session->setXaId(trx->id);
 
4412
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4452
4413
 
4453
4414
  /* Handle duplicate key errors */
4454
4415
  if (auto_inc_used) {
4771
4732
 
4772
4733
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4773
4734
 
4774
 
  user_session->setXaId(trx->id);
 
4735
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4775
4736
 
4776
4737
  /* We need to do some special AUTOINC handling for the following case:
4777
4738
 
4784
4745
  if (error == DB_SUCCESS
4785
4746
      && getTable()->next_number_field
4786
4747
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4748
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4749
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4750
    == TRX_DUP_IGNORE)  {
4790
4751
 
4863
4824
 
4864
4825
  error = row_update_for_mysql((byte*) record, prebuilt);
4865
4826
 
4866
 
  user_session->setXaId(trx->id);
 
4827
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4867
4828
 
4868
4829
  innodb_srv_conc_exit_innodb(trx);
4869
4830
 
5123
5084
    return(HA_ERR_CRASHED);
5124
5085
  }
5125
5086
 
5126
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5127
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5128
 
  }
5129
5087
 
5130
5088
  /* Note that if the index for which the search template is built is not
5131
5089
  necessarily prebuilt->index, but can also be the clustered index */
5251
5209
         table. Only print message if the index translation
5252
5210
         table exists */
5253
5211
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
 
5212
        errmsg_printf(ERRMSG_LVL_ERROR,
5255
5213
                      "InnoDB could not find "
5256
5214
                      "index %s key no %u for "
5257
5215
                      "table %s through its "
5269
5227
  }
5270
5228
 
5271
5229
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
5230
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
5231
      "Innodb could not find key n:o %u with name %s "
5274
5232
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
5233
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
5234
      prebuilt->table->name);
5277
5235
  }
5278
5236
 
5298
5256
  prebuilt->index = innobase_get_index(keynr);
5299
5257
 
5300
5258
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
5259
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
5260
          keynr);
5303
5261
    prebuilt->index_usable = FALSE;
5304
5262
    return(1);
5664
5622
  table. */
5665
5623
 
5666
5624
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5625
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5626
        (ulong) len, (ulong) ref_length);
5669
5627
  }
5670
5628
}
5720
5678
 
5721
5679
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5722
5680
                  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
5681
    if (field->null_ptr) {
5739
5682
      nulls_allowed = 0;
5740
5683
    } else {
5757
5700
        /* in data0type.h we assume that the
5758
5701
        number fits in one byte in prtype */
5759
5702
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5703
          (Session*) trx->mysql_thd,
5761
5704
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5705
          ER_CANT_CREATE_TABLE,
5763
5706
          "In InnoDB, charset-collation codes"
5792
5735
    if (dict_col_name_is_reserved(field->field_name)){
5793
5736
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5794
5737
 
5795
 
  err_col:
5796
5738
      dict_mem_table_free(table);
5797
5739
      trx_commit_for_mysql(trx);
5798
5740
 
5923
5865
        || col_type == DATA_FLOAT
5924
5866
        || col_type == DATA_DOUBLE
5925
5867
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
5868
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
5869
          "MySQL is trying to create a column "
5928
5870
          "prefix index field, on an "
5929
5871
          "inappropriate data type. Table "
6023
5965
/*================*/
6024
5966
  Session         &session, /*!< in: Session */
6025
5967
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
5968
        const TableIdentifier &identifier,
6027
5969
        message::Table& create_proto)
6028
5970
{
6029
5971
  int   error;
6032
5974
  trx_t*    trx;
6033
5975
  int   primary_key_no;
6034
5976
  uint    i;
 
5977
  char    name2[FN_REFLEN];
 
5978
  char    norm_name[FN_REFLEN];
6035
5979
  ib_int64_t  auto_inc_value;
6036
5980
  ulint   iflags;
6037
5981
  /* Cache the value of innodb_file_format, in case it is
6041
5985
  const char* stmt;
6042
5986
  size_t stmt_len;
6043
5987
 
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
 
  }
 
5988
  const char *table_name= identifier.getPath().c_str();
6051
5989
 
6052
5990
  if (form.getShare()->sizeFields() > 1000) {
6053
5991
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
6008
 
6071
6009
  srv_lower_case_table_names = TRUE;
6072
6010
 
 
6011
  strcpy(name2, table_name);
 
6012
 
 
6013
  normalize_table_name(norm_name, name2);
 
6014
 
6073
6015
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
6016
    or lock waits can happen in it during a table create operation.
6075
6017
    Drop table etc. do this latching in row0mysql.c. */
6134
6076
# error "DICT_TF_ZSSIZE_MAX < 1"
6135
6077
#endif
6136
6078
 
6137
 
    if (strict_mode)
 
6079
    if (SessionVAR(&session, strict_mode))
6138
6080
    {
6139
6081
      if (! srv_file_per_table)
6140
6082
      {
6177
6119
  if (lex_identified_temp_table)
6178
6120
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
6121
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
6122
  error= create_table_def(trx, &form, norm_name,
 
6123
                          lex_identified_temp_table ? name2 : NULL,
6182
6124
                          iflags);
6183
6125
 
6184
 
  session.setXaId(trx->id);
 
6126
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6185
6127
 
6186
6128
  if (error) {
6187
6129
    goto cleanup;
6194
6136
      order the rows by their row id which is internally generated
6195
6137
      by InnoDB */
6196
6138
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
6139
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
6140
    if (error) {
6199
6141
      goto cleanup;
6200
6142
    }
6202
6144
 
6203
6145
  if (primary_key_no != -1) {
6204
6146
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6147
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
6148
                              (uint) primary_key_no))) {
6207
6149
      goto cleanup;
6208
6150
    }
6211
6153
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
6154
    if (i != (uint) primary_key_no) {
6213
6155
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6156
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
6157
                                i))) {
6216
6158
        goto cleanup;
6217
6159
      }
6218
6160
    }
6219
6161
  }
6220
6162
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
 
6163
  stmt = innobase_get_stmt(&session, &stmt_len);
6222
6164
 
6223
6165
  if (stmt) {
6224
6166
    string generated_create_table;
6225
6167
    const char *query= stmt;
6226
6168
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
6169
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
6170
    {
6229
6171
      message::transformTableDefinitionToSql(create_proto,
6230
6172
                                             generated_create_table,
6234
6176
 
6235
6177
    error = row_table_add_foreign_constraints(trx,
6236
6178
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
6179
                                              norm_name,
6238
6180
                                              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
6181
 
6262
6182
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
6183
 
6276
6196
 
6277
6197
  log_buffer_flush_to_disk();
6278
6198
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
6199
  innobase_table = dict_table_get(norm_name, FALSE);
6280
6200
 
6281
6201
  assert(innobase_table != 0);
6282
6202
 
6284
6204
    /* We update the highest file format in the system table
6285
6205
      space, if this table has higher file format setting. */
6286
6206
 
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;
 
6207
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
6208
                                    dict_table_get_format(innobase_table));
6292
6209
  }
6293
6210
 
6294
6211
  /* Note: We can't call update_session() as prebuilt will not be
6299
6216
    does a table copy too. */
6300
6217
 
6301
6218
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
6219
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
6220
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
6221
      && create_proto.options().auto_increment_value() != 0) {
6305
6222
 
6306
6223
    /* Query was one of :
6393
6310
 
6394
6311
  update_session(getTable()->in_use);
6395
6312
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
6313
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
6314
  fallback:
6398
6315
    /* We only handle TRUNCATE TABLE t as a special case.
6399
6316
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6344
InnobaseEngine::doDropTable(
6428
6345
/*======================*/
6429
6346
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6347
        const TableIdentifier &identifier)
6431
6348
{
6432
6349
  int error;
6433
6350
  trx_t*  parent_trx;
6434
6351
  trx_t*  trx;
 
6352
  char  norm_name[1000];
6435
6353
 
6436
6354
  ut_a(identifier.getPath().length() < 1000);
6437
6355
 
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
 
  }
 
6356
  /* Strangely, MySQL passes the table name without the '.frm'
 
6357
    extension, in contrast to ::create */
 
6358
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6359
 
6446
6360
  /* Get the transaction associated with the current session, or create one
6447
6361
    if not yet created */
6459
6373
 
6460
6374
  /* Drop the table in InnoDB */
6461
6375
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6376
  error = row_drop_table_for_mysql(norm_name, trx,
 
6377
                                   session_sql_command(&session)
6464
6378
                                   == SQLCOM_DROP_DB);
6465
6379
 
6466
 
  session.setXaId(trx->id);
 
6380
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6467
6381
 
6468
6382
  /* Flush the log to reduce probability that the .frm files and
6469
6383
    the InnoDB data dictionary get out-of-sync if the user runs
6488
6402
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6403
    {
6490
6404
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6405
      ulint sql_command = session_sql_command(&session);
6492
6406
 
6493
6407
      // If this was the final removal to an alter table then we will need
6494
6408
      // to remove the .dfe that was left behind.
6521
6435
bool
6522
6436
InnobaseEngine::doDropSchema(
6523
6437
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6438
                             const SchemaIdentifier &identifier)
6525
6439
    /*!< in: database path; inside InnoDB the name
6526
6440
      of the last directory in the path is used as
6527
6441
      the database name: for example, in 'mysql/data/test'
6571
6485
 
6572
6486
void InnobaseEngine::dropTemporarySchema()
6573
6487
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6488
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6489
  trx_t*  trx= NULL;
6576
6490
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6491
 
6608
6522
innobase_rename_table(
6609
6523
/*==================*/
6610
6524
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6525
  const char* from, /*!< in: old name of the table */
 
6526
  const char* to, /*!< in: new name of the table */
6613
6527
  ibool   lock_and_commit)
6614
6528
        /*!< in: TRUE=lock data dictionary and commit */
6615
6529
{
6616
6530
  int error;
 
6531
  char norm_to[FN_REFLEN];
 
6532
  char norm_from[FN_REFLEN];
6617
6533
 
6618
6534
  srv_lower_case_table_names = TRUE;
6619
6535
 
 
6536
  normalize_table_name(norm_to, to);
 
6537
  normalize_table_name(norm_from, from);
 
6538
 
6620
6539
  /* Serialize data dictionary operations with dictionary mutex:
6621
6540
  no deadlocks can occur then in these operations */
6622
6541
 
6624
6543
    row_mysql_lock_data_dictionary(trx);
6625
6544
  }
6626
6545
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6546
  error = row_rename_table_for_mysql(
 
6547
    norm_from, norm_to, trx, lock_and_commit);
6628
6548
 
6629
6549
  if (error != DB_SUCCESS) {
6630
6550
    FILE* ef = dict_foreign_err_file;
6631
6551
 
6632
6552
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6553
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6554
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6555
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6556
    fputs(" failed!\n", ef);
6637
6557
  }
6638
6558
 
6651
6571
/*********************************************************************//**
6652
6572
Renames an InnoDB table.
6653
6573
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6574
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6575
{
6656
6576
  // A temp table alter table/rename is a shallow rename and only the
6657
6577
  // definition needs to be updated.
6677
6597
 
6678
6598
  trx = innobase_trx_allocate(&session);
6679
6599
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
 
6600
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6681
6601
 
6682
 
  session.setXaId(trx->id);
 
6602
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6683
6603
 
6684
6604
  /* Tell the InnoDB server that there might be work for
6685
6605
    utility threads: */
6702
6622
     is the one we are trying to rename to) and return the generic
6703
6623
     error code. */
6704
6624
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6625
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6626
    error = DB_ERROR;
6707
6627
  }
6708
6628
 
6733
6653
  KeyInfo*    key;
6734
6654
  dict_index_t* index;
6735
6655
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
 
6656
              getTable()->getShare()->stored_rec_length
6737
6657
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
 
6658
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6739
6659
          + getTable()->getShare()->max_key_length + 100;
6740
6660
  dtuple_t* range_start;
6741
6661
  dtuple_t* range_end;
6767
6687
    goto func_exit;
6768
6688
  }
6769
6689
 
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
 
  }
6774
 
 
6775
6690
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6776
6691
            + sizeof(dtuple_t)));
6777
6692
 
6845
6760
  dict_index_t* index;
6846
6761
  uint64_t  estimate;
6847
6762
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6763
 
6850
6764
  /* We do not know if MySQL can call this function before calling
6851
6765
  external_lock(). To be safe, update the session of the current table
6863
6777
 
6864
6778
  index = dict_table_get_first_index(prebuilt->table);
6865
6779
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6780
  ut_a(index->stat_n_leaf_pages > 0);
6869
6781
 
6870
6782
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6783
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6784
 
6873
6785
 
6874
6786
  /* Calculate a minimum length for a clustered index record and from
6971
6883
 
6972
6884
        /* If index does not belong to the table of share structure. Search
6973
6885
        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) {
 
6886
        if (index->table != ib_table
 
6887
            && strcmp(index->table->name, share->table_name)) {
6994
6888
                i = 0;
6995
6889
                ind = dict_table_get_first_index(index->table);
6996
6890
 
7018
6912
 
7019
6913
                /* Print an error message if we cannot find the index
7020
6914
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
 
6915
                errmsg_printf(ERRMSG_LVL_ERROR,
7022
6916
                              "Cannot find index %s in InnoDB index "
7023
6917
                                "translation table.", index->name);
7024
6918
        }
7035
6929
                }
7036
6930
        }
7037
6931
 
7038
 
                errmsg_printf(error::ERROR,
 
6932
                errmsg_printf(ERRMSG_LVL_ERROR,
7039
6933
                              "Cannot find matching index number for index %s "
7040
6934
                              "in InnoDB index list.", index->name);
7041
6935
 
7054
6948
  dict_index_t* index;
7055
6949
  ha_rows   rec_per_key;
7056
6950
  ib_int64_t  n_rows;
 
6951
  ulong   j;
 
6952
  ulong   i;
7057
6953
  os_file_stat_t  stat_info;
7058
6954
 
7059
6955
  /* If we are forcing recovery at a high level, we will suppress
7060
6956
  statistics calculation on tables, because that may crash the
7061
6957
  server if an index is badly corrupted. */
7062
6958
 
 
6959
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6960
 
 
6961
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6962
    because we want MySQL to process this query and not
 
6963
    stop, like it would do if it received the error code
 
6964
    HA_ERR_CRASHED. */
 
6965
 
 
6966
    return(0);
 
6967
  }
 
6968
 
7063
6969
  /* We do not know if MySQL can call this function before calling
7064
6970
  external_lock(). To be safe, update the session of the current table
7065
6971
  handle. */
7081
6987
 
7082
6988
    prebuilt->trx->op_info = "updating table statistics";
7083
6989
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
 
6990
    dict_update_statistics(ib_table);
7088
6991
 
7089
6992
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
6993
 
7101
7004
  }
7102
7005
 
7103
7006
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
7007
    n_rows = ib_table->stat_n_rows;
7108
7008
 
7109
7009
    /* Because we do not protect stat_n_rows by any mutex in a
7131
7031
    n_rows can not be 0 unless the table is empty, set to 1
7132
7032
    instead. The original problem of bug#29507 is actually
7133
7033
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
7034
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
7035
 
7136
7036
      n_rows = 1;
7137
7037
 
7153
7053
        ib_table->stat_sum_of_other_index_sizes)
7154
7054
          * UNIV_PAGE_SIZE;
7155
7055
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
7056
    /* Since fsp_get_available_space_in_free_extents() is
7159
7057
    acquiring latches inside InnoDB, we do not call it if we
7160
7058
    are asked by MySQL to avoid locking. Another reason to
7161
7059
    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) {
 
7060
    See Bug#38185.
 
7061
    We do not update delete_length if no locking is requested
 
7062
    so the "old" value can remain. delete_length is initialized
 
7063
    to 0 in the ha_statistics' constructor. */
 
7064
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
7065
 
 
7066
      /* lock the data dictionary to avoid races with
 
7067
      ibd_file_missing and tablespace_discarded */
 
7068
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
7069
 
 
7070
      /* ib_table->space must be an existent tablespace */
 
7071
      if (!ib_table->ibd_file_missing
 
7072
          && !ib_table->tablespace_discarded) {
 
7073
 
 
7074
        stats.delete_length =
 
7075
          fsp_get_available_space_in_free_extents(
 
7076
            ib_table->space) * 1024;
 
7077
      } else {
 
7078
 
7179
7079
        Session*  session;
7180
7080
 
7181
7081
        session= getTable()->in_use;
7193
7093
          ib_table->name);
7194
7094
 
7195
7095
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
7096
      }
 
7097
 
 
7098
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
7099
    }
7200
7100
 
7201
7101
    stats.check_time = 0;
7208
7108
  }
7209
7109
 
7210
7110
  if (flag & HA_STATUS_CONST) {
7211
 
    ulong i;
7212
7111
    /* Verify the number of index in InnoDB and MySQL
7213
7112
       matches up. If prebuilt->clust_index_was_generated
7214
7113
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7215
7114
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
7216
7115
 
7217
7116
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
 
7117
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7219
7118
                      "indexes inside InnoDB, which "
7220
7119
                      "is different from the number of "
7221
7120
                      "indexes %u defined in the MySQL ",
7223
7122
                      getTable()->getShare()->keys);
7224
7123
    }
7225
7124
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
7125
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
 
      ulong j;
7230
7126
      /* We could get index quickly through internal
7231
7127
         index mapping with the index translation table.
7232
7128
         The identity of index (match up index name with
7235
7131
      index = innobase_get_index(i);
7236
7132
 
7237
7133
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
7134
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
7135
            "indexes inside InnoDB than "
7240
7136
            "are defined in the MySQL "
7241
7137
            ".frm file. Have you mixed up "
7250
7146
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
7251
7147
 
7252
7148
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
7149
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
7150
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
7151
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
7152
"installations? "
7262
7158
          break;
7263
7159
        }
7264
7160
 
 
7161
        dict_index_stat_mutex_enter(index);
 
7162
 
7265
7163
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7266
7164
 
7267
7165
          rec_per_key = stats.records;
7270
7168
           index->stat_n_diff_key_vals[j + 1]);
7271
7169
        }
7272
7170
 
 
7171
        dict_index_stat_mutex_exit(index);
 
7172
 
7273
7173
        /* Since MySQL seems to favor table scans
7274
7174
        too much over index searches, we pretend
7275
7175
        index selectivity is 2 times better than
7286
7186
          (ulong) rec_per_key;
7287
7187
      }
7288
7188
    }
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
7189
  }
7296
7190
 
7297
7191
  if (flag & HA_STATUS_ERRKEY) {
7315
7209
    stats.auto_increment_value = innobase_peek_autoinc();
7316
7210
  }
7317
7211
 
7318
 
func_exit:
7319
7212
  prebuilt->trx->op_info = (char*)"";
7320
7213
 
7321
7214
  return(0);
7367
7260
  }
7368
7261
 
7369
7262
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
 
7263
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7371
7264
                    "InnoDB: MySQL is trying to use a table handle"
7372
7265
                    " but the .ibd file for\n"
7373
7266
                    "InnoDB: table %s does not exist.\n"
7617
7510
  flen = ftell(srv_dict_tmpfile);
7618
7511
  if (flen < 0) {
7619
7512
    flen = 0;
 
7513
  } else if (flen > 64000 - 1) {
 
7514
    flen = 64000 - 1;
7620
7515
  }
7621
7516
 
7622
7517
  /* allocate buffer for the string, and
7676
7571
      i++;
7677
7572
    }
7678
7573
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
7574
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
7575
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
7576
 
7682
7577
    /* Table name */
7683
7578
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7579
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
7580
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
7581
 
7687
7582
    /** Foreign Fields **/
7759
7654
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7655
 
7761
7656
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7657
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7658
    f_key_list->push_back(pf_key_info);
7764
7659
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7660
  }
8014
7909
{
8015
7910
  trx_t*      trx;
8016
7911
  static const char truncated_msg[] = "... truncated...\n";
8017
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7912
  const long    MAX_STATUS_SIZE = 64000;
8018
7913
  ulint     trx_list_start = ULINT_UNDEFINED;
8019
7914
  ulint     trx_list_end = ULINT_UNDEFINED;
8020
7915
 
8043
7938
 
8044
7939
  if (flen > MAX_STATUS_SIZE) {
8045
7940
    usable_len = MAX_STATUS_SIZE;
8046
 
    srv_truncated_status_writes++;
8047
7941
  } else {
8048
7942
    usable_len = flen;
8049
7943
  }
8079
7973
 
8080
7974
  mutex_exit(&srv_monitor_file_mutex);
8081
7975
 
8082
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8083
 
             STRING_WITH_LEN(""), str, flen);
 
7976
  bool result = FALSE;
8084
7977
 
 
7978
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7979
      STRING_WITH_LEN(""), str, flen)) {
 
7980
    result= TRUE;
 
7981
  }
8085
7982
  free(str);
8086
7983
 
8087
7984
  return(FALSE);
8289
8186
static INNOBASE_SHARE* get_share(const char* table_name)
8290
8187
{
8291
8188
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8189
  pthread_mutex_lock(&innobase_share_mutex);
8293
8190
 
8294
8191
  ulint fold = ut_fold_string(table_name);
8295
8192
 
8316
8213
  }
8317
8214
 
8318
8215
  share->use_count++;
 
8216
  pthread_mutex_unlock(&innobase_share_mutex);
8319
8217
 
8320
8218
  return(share);
8321
8219
}
8322
8220
 
8323
8221
static void free_share(INNOBASE_SHARE* share)
8324
8222
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8223
  pthread_mutex_lock(&innobase_share_mutex);
8326
8224
 
8327
8225
#ifdef UNIV_DEBUG
8328
8226
  INNOBASE_SHARE* share2;
8351
8249
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
8250
    shrinks too much */
8353
8251
  }
 
8252
 
 
8253
  pthread_mutex_unlock(&innobase_share_mutex);
8354
8254
}
8355
8255
 
8356
8256
/*****************************************************************//**
8385
8285
  trx = check_trx_exists(session);
8386
8286
 
8387
8287
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
8288
  const uint32_t sql_command = session_sql_command(session);
8389
8289
 
8390
8290
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
8291
 
8427
8327
        && (sql_command == SQLCOM_INSERT_SELECT
8428
8328
            || sql_command == SQLCOM_REPLACE_SELECT
8429
8329
            || sql_command == SQLCOM_UPDATE
8430
 
            || sql_command == SQLCOM_CREATE_TABLE
8431
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
8330
            || sql_command == SQLCOM_CREATE_TABLE)) {
8432
8331
 
8433
8332
      /* If we either have innobase_locks_unsafe_for_binlog
8434
8333
      option set or this session is using READ COMMITTED
8436
8335
      is not set to serializable and MySQL is doing
8437
8336
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8438
8337
      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. */
 
8338
      SELECT... without FOR UPDATE or IN SHARE
 
8339
      MODE in select, then we use consistent read
 
8340
      for select. */
8442
8341
 
8443
8342
      prebuilt->select_lock_type = LOCK_NONE;
8444
8343
      prebuilt->stored_select_lock_type = LOCK_NONE;
8471
8370
 
8472
8371
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
8372
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
8373
        && !session_tablespace_op(session)
8475
8374
        && sql_command != SQLCOM_TRUNCATE
8476
8375
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
8376
 
8526
8425
}
8527
8426
 
8528
8427
/*******************************************************************//**
8529
 
This function reads the global auto-inc counter. It doesn't use the
 
8428
This function reads the global auto-inc counter. It doesn't use the 
8530
8429
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8531
8430
@return the autoinc value */
8532
8431
UNIV_INTERN
8546
8445
 
8547
8446
  auto_inc = dict_table_autoinc_read(innodb_table);
8548
8447
 
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
 
  }
 
8448
  ut_a(auto_inc > 0);
8553
8449
 
8554
8450
  dict_table_autoinc_unlock(innodb_table);
8555
8451
 
8703
8599
/* See comment in Cursor.cc */
8704
8600
UNIV_INTERN
8705
8601
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
8602
InnobaseEngine::get_error_message(int, String *buf)
8707
8603
{
8708
8604
  trx_t*  trx = check_trx_exists(current_session);
8709
8605
 
8787
8683
finds charset information and returns length of prefix_len characters in the
8788
8684
index field in bytes.
8789
8685
@return number of bytes occupied by the first n characters */
8790
 
UNIV_INTERN
 
8686
extern "C" UNIV_INTERN
8791
8687
ulint
8792
8688
innobase_get_at_most_n_mbchars(
8793
8689
/*===========================*/
8880
8776
  trx->detailed_error[0]= '\0';
8881
8777
 
8882
8778
  /* Set the isolation level of the transaction. */
8883
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8779
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8884
8780
}
8885
8781
 
8886
8782
void
8967
8863
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8968
8864
{
8969
8865
  trx_t *trx= session_to_trx(session);
8970
 
  return (trx->id);
 
8866
  return (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
8971
8867
}
8972
8868
 
8973
8869
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8974
8870
{
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
 
  }
 
8871
  trx_t *trx= innobase_trx_allocate(session);
8983
8872
 
8984
8873
  mutex_enter(&kernel_mutex);
8985
8874
  trx->id= trx_sys_get_new_trx_id();
8986
8875
  mutex_exit(&kernel_mutex);
8987
8876
 
8988
 
  uint64_t transaction_id= trx->id;
 
8877
  uint64_t transaction_id= (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
 
8878
 
 
8879
  trx_free_for_mysql(trx);
8989
8880
 
8990
8881
  return transaction_id;
8991
8882
}
9101
8992
}
9102
8993
 
9103
8994
/************************************************************//**
 
8995
Validate the file format check value, is it one of "on" or "off",
 
8996
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8997
@return true if config value one of "on" or  "off" */
 
8998
static
 
8999
bool
 
9000
innobase_file_format_check_on_off(
 
9001
/*==============================*/
 
9002
  const char* format_check) /*!< in: parameter value */
 
9003
{
 
9004
  bool    ret = true;
 
9005
 
 
9006
  if (!innobase_strcasecmp(format_check, "off")) {
 
9007
 
 
9008
    /* Set the value to disable checking. */
 
9009
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
9010
 
 
9011
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
9012
 
 
9013
    /* Set the value to the lowest supported format. */
 
9014
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
9015
  } else {
 
9016
    ret = FALSE;
 
9017
  }
 
9018
 
 
9019
  return(ret);
 
9020
}
 
9021
 
 
9022
/************************************************************//**
9104
9023
Validate the file format check config parameters, as a side effect it
9105
 
sets the srv_max_file_format_at_startup variable.
 
9024
sets the srv_check_file_format_at_startup variable.
9106
9025
@return the format_id if valid config value, otherwise, return -1 */
9107
9026
static
9108
9027
int
9109
9028
innobase_file_format_validate_and_set(
9110
9029
/*================================*/
9111
 
  const char* format_max) /*!< in: parameter value */
 
9030
  const char* format_check) /*!< in: parameter value */
9112
9031
{
9113
9032
  uint    format_id;
9114
9033
 
9115
 
  format_id = innobase_file_format_name_lookup(format_max);
 
9034
  format_id = innobase_file_format_name_lookup(format_check);
9116
9035
 
9117
9036
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9118
 
    srv_max_file_format_at_startup = format_id;
 
9037
    srv_check_file_format_at_startup = format_id;
9119
9038
    return((int) format_id);
9120
9039
  } else {
9121
9040
    return(-1);
9122
9041
  }
9123
9042
}
9124
9043
 
9125
 
 
 
9044
/*************************************************************//**
 
9045
Check if it is a valid file format. This function is registered as
 
9046
a callback with MySQL.
 
9047
@return 0 for valid file format */
 
9048
static
 
9049
int
 
9050
innodb_file_format_name_validate(
 
9051
/*=============================*/
 
9052
  Session*      , /*!< in: thread handle */
 
9053
  drizzle_sys_var*  , /*!< in: pointer to system
 
9054
            variable */
 
9055
  void*       save, /*!< out: immediate result
 
9056
            for update function */
 
9057
  drizzle_value*    value)  /*!< in: incoming string */
 
9058
{
 
9059
  const char* file_format_input;
 
9060
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9061
  int   len = sizeof(buff);
 
9062
 
 
9063
  ut_a(save != NULL);
 
9064
  ut_a(value != NULL);
 
9065
 
 
9066
  file_format_input = value->val_str(value, buff, &len);
 
9067
 
 
9068
  if (file_format_input != NULL) {
 
9069
    uint  format_id;
 
9070
 
 
9071
    format_id = innobase_file_format_name_lookup(
 
9072
      file_format_input);
 
9073
 
 
9074
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
9075
      /* Save a pointer to the name in the
 
9076
         'file_format_name_map' constant array. */
 
9077
      *static_cast<const char**>(save) =
 
9078
        trx_sys_file_format_id_to_name(format_id);
 
9079
 
 
9080
      return(0);
 
9081
    }
 
9082
  }
 
9083
 
 
9084
  *static_cast<const char**>(save) = NULL;
 
9085
  return(1);
 
9086
}
 
9087
 
 
9088
/****************************************************************//**
 
9089
Update the system variable innodb_file_format using the "saved"
 
9090
value. This function is registered as a callback with MySQL. */
 
9091
static
 
9092
void
 
9093
innodb_file_format_name_update(
 
9094
/*===========================*/
 
9095
  Session*      ,   /*!< in: thread handle */
 
9096
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9097
              system variable */
 
9098
  void*       var_ptr,  /*!< out: where the
 
9099
              formal string goes */
 
9100
  const void*     save)   /*!< in: immediate result
 
9101
              from check function */
 
9102
{
 
9103
  const char* format_name;
 
9104
 
 
9105
  ut_a(var_ptr != NULL);
 
9106
  ut_a(save != NULL);
 
9107
 
 
9108
  format_name = *static_cast<const char*const*>(save);
 
9109
 
 
9110
  if (format_name) {
 
9111
    uint  format_id;
 
9112
 
 
9113
    format_id = innobase_file_format_name_lookup(format_name);
 
9114
 
 
9115
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
9116
      srv_file_format = format_id;
 
9117
    }
 
9118
  }
 
9119
 
 
9120
  *static_cast<const char**>(var_ptr)
 
9121
    = trx_sys_file_format_id_to_name(srv_file_format);
 
9122
}
 
9123
 
 
9124
/*************************************************************//**
 
9125
Check if valid argument to innodb_file_format_check. This
 
9126
function is registered as a callback with MySQL.
 
9127
@return 0 for valid file format */
 
9128
static
 
9129
int
 
9130
innodb_file_format_check_validate(
 
9131
/*==============================*/
 
9132
  Session*      session, /*!< in: thread handle */
 
9133
  drizzle_sys_var*  , /*!< in: pointer to system
 
9134
            variable */
 
9135
  void*       save, /*!< out: immediate result
 
9136
            for update function */
 
9137
  drizzle_value*    value)  /*!< in: incoming string */
 
9138
{
 
9139
  const char* file_format_input;
 
9140
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9141
  int   len = sizeof(buff);
 
9142
  int   format_id;
 
9143
 
 
9144
  ut_a(save != NULL);
 
9145
  ut_a(value != NULL);
 
9146
 
 
9147
  file_format_input = value->val_str(value, buff, &len);
 
9148
 
 
9149
  if (file_format_input != NULL) {
 
9150
 
 
9151
    /* Check if user set on/off, we want to print a suitable
 
9152
    message if they did so. */
 
9153
 
 
9154
    if (innobase_file_format_check_on_off(file_format_input)) {
 
9155
      push_warning_printf(session,
 
9156
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9157
                          ER_WRONG_ARGUMENTS,
 
9158
        "InnoDB: invalid innodb_file_format_check "
 
9159
        "value; on/off can only be set at startup or "
 
9160
        "in the configuration file");
 
9161
    } else {
 
9162
      format_id = innobase_file_format_validate_and_set(file_format_input);
 
9163
      if (format_id >= 0) {
 
9164
        /* Save a pointer to the name in the
 
9165
           'file_format_name_map' constant array. */
 
9166
        *static_cast<const char**>(save) =
 
9167
          trx_sys_file_format_id_to_name(
 
9168
                                         (uint)format_id);
 
9169
 
 
9170
        return(0);
 
9171
 
 
9172
      } else {
 
9173
        push_warning_printf(session,
 
9174
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9175
                            ER_WRONG_ARGUMENTS,
 
9176
                            "InnoDB: invalid innodb_file_format_check "
 
9177
                            "value; can be any format up to %s "
 
9178
                            "or its equivalent numeric id",
 
9179
                            trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
9180
      }
 
9181
    }
 
9182
  }
 
9183
 
 
9184
  *static_cast<const char**>(save) = NULL;
 
9185
  return(1);
 
9186
}
 
9187
 
 
9188
/****************************************************************//**
 
9189
Update the system variable innodb_file_format_check using the "saved"
 
9190
value. This function is registered as a callback with MySQL. */
 
9191
static
 
9192
void
 
9193
innodb_file_format_check_update(
 
9194
/*============================*/
 
9195
  Session*      session,  /*!< in: thread handle */
 
9196
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9197
              system variable */
 
9198
  void*       var_ptr,  /*!< out: where the
 
9199
              formal string goes */
 
9200
  const void*     save)   /*!< in: immediate result
 
9201
              from check function */
 
9202
{
 
9203
  const char* format_name_in;
 
9204
  const char**  format_name_out;
 
9205
  uint    format_id;
 
9206
 
 
9207
  ut_a(save != NULL);
 
9208
  ut_a(var_ptr != NULL);
 
9209
 
 
9210
  format_name_in = *static_cast<const char*const*>(save);
 
9211
 
 
9212
  if (!format_name_in) {
 
9213
 
 
9214
    return;
 
9215
  }
 
9216
 
 
9217
  format_id = innobase_file_format_name_lookup(format_name_in);
 
9218
 
 
9219
  if (format_id > DICT_TF_FORMAT_MAX) {
 
9220
    /* DEFAULT is "on", which is invalid at runtime. */
 
9221
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9222
            ER_WRONG_ARGUMENTS,
 
9223
            "Ignoring SET innodb_file_format=%s",
 
9224
            format_name_in);
 
9225
    return;
 
9226
  }
 
9227
 
 
9228
  format_name_out = static_cast<const char**>(var_ptr);
 
9229
 
 
9230
  /* Update the max format id in the system tablespace. */
 
9231
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
9232
    ut_print_timestamp(stderr);
 
9233
    fprintf(stderr,
 
9234
      " [Info] InnoDB: the file format in the system "
 
9235
      "tablespace is now set to %s.\n", *format_name_out);
 
9236
  }
 
9237
}
 
9238
 
 
9239
/****************************************************************//**
 
9240
Update the system variable innodb_adaptive_hash_index using the "saved"
 
9241
value. This function is registered as a callback with MySQL. */
 
9242
static
 
9243
void
 
9244
innodb_adaptive_hash_index_update(
 
9245
/*==============================*/
 
9246
  Session*      ,   /*!< in: thread handle */
 
9247
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9248
              system variable */
 
9249
  void*       , /*!< out: where the
 
9250
              formal string goes */
 
9251
  const void*     save)   /*!< in: immediate result
 
9252
              from check function */
 
9253
{
 
9254
  if (*(bool*) save) {
 
9255
    btr_search_enable();
 
9256
  } else {
 
9257
    btr_search_disable();
 
9258
  }
 
9259
}
 
9260
 
 
9261
/****************************************************************//**
 
9262
Update the system variable innodb_old_blocks_pct using the "saved"
 
9263
value. This function is registered as a callback with MySQL. */
 
9264
static
 
9265
void
 
9266
innodb_old_blocks_pct_update(
 
9267
/*=========================*/
 
9268
        Session*                        ,       /*!< in: thread handle */
 
9269
        drizzle_sys_var*        ,       /*!< in: pointer to
 
9270
                                                system variable */
 
9271
        void*                           ,/*!< out: where the
 
9272
                                                formal string goes */
 
9273
        const void*                     save)   /*!< in: immediate result
 
9274
                                                from check function */
 
9275
{
 
9276
        innobase_old_blocks_pct = buf_LRU_old_ratio_update(
 
9277
                *static_cast<const uint*>(save), TRUE);
 
9278
}
 
9279
 
 
9280
/*************************************************************//**
 
9281
Check if it is a valid value of innodb_change_buffering.  This function is
 
9282
registered as a callback with MySQL.
 
9283
@return 0 for valid innodb_change_buffering */
 
9284
static
 
9285
int
 
9286
innodb_change_buffering_validate(
 
9287
/*=============================*/
 
9288
  Session*      , /*!< in: thread handle */
 
9289
  drizzle_sys_var*  , /*!< in: pointer to system
 
9290
            variable */
 
9291
  void*       save, /*!< out: immediate result
 
9292
            for update function */
 
9293
  drizzle_value*    value)  /*!< in: incoming string */
 
9294
{
 
9295
  const char* change_buffering_input;
 
9296
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9297
  int   len = sizeof(buff);
 
9298
 
 
9299
  ut_a(save != NULL);
 
9300
  ut_a(value != NULL);
 
9301
 
 
9302
  change_buffering_input = value->val_str(value, buff, &len);
 
9303
 
 
9304
  if (change_buffering_input != NULL) {
 
9305
    ulint use;
 
9306
 
 
9307
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
9308
         use++) {
 
9309
      if (!innobase_strcasecmp(
 
9310
            change_buffering_input,
 
9311
            innobase_change_buffering_values[use])) {
 
9312
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
9313
        return(0);
 
9314
      }
 
9315
    }
 
9316
  }
 
9317
 
 
9318
  return(1);
 
9319
}
 
9320
 
 
9321
/****************************************************************//**
 
9322
Update the system variable innodb_change_buffering using the "saved"
 
9323
value. This function is registered as a callback with MySQL. */
 
9324
static
 
9325
void
 
9326
innodb_change_buffering_update(
 
9327
/*===========================*/
 
9328
  Session*      ,   /*!< in: thread handle */
 
9329
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9330
              system variable */
 
9331
  void*       var_ptr,  /*!< out: where the
 
9332
              formal string goes */
 
9333
  const void*     save)   /*!< in: immediate result
 
9334
              from check function */
 
9335
{
 
9336
  ut_a(var_ptr != NULL);
 
9337
  ut_a(save != NULL);
 
9338
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
9339
 
 
9340
  ibuf_use = *(const ibuf_use_t*) save;
 
9341
 
 
9342
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
9343
}
 
9344
 
 
9345
/* plugin options */
 
9346
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
9347
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9348
  "Enable InnoDB checksums validation (enabled by default). ",
 
9349
  NULL, NULL, TRUE);
 
9350
 
 
9351
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
9352
  PLUGIN_VAR_READONLY,
 
9353
  "The common part for InnoDB table spaces.",
 
9354
  NULL, NULL, NULL);
 
9355
 
 
9356
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
9357
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9358
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
9359
  NULL, NULL, TRUE);
 
9360
 
 
9361
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
9362
  PLUGIN_VAR_RQCMDARG,
 
9363
  "Number of IOPs the server can do. Tunes the background IO rate",
 
9364
  NULL, NULL, 200, 100, ~0L, 0);
 
9365
 
 
9366
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
9367
  PLUGIN_VAR_OPCMDARG,
 
9368
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
9369
  "values are 0, 1 (faster)"
 
9370
  " or 2 (fastest - crash-like)"
 
9371
  ".",
 
9372
  NULL, NULL, 1, 0, 2, 0);
 
9373
 
 
9374
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
9375
  PLUGIN_VAR_NOCMDARG,
 
9376
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
9377
  NULL, NULL, FALSE);
 
9378
 
 
9379
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
9380
  PLUGIN_VAR_RQCMDARG,
 
9381
  "File format to use for new tables in .ibd files.",
 
9382
  innodb_file_format_name_validate,
 
9383
  innodb_file_format_name_update, "Antelope");
 
9384
 
 
9385
/* If a new file format is introduced, the file format
 
9386
name needs to be updated accordingly. Please refer to
 
9387
file_format_name_map[] defined in trx0sys.c for the next
 
9388
file format name. */
 
9389
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
9390
  PLUGIN_VAR_OPCMDARG,
 
9391
  "The highest file format in the tablespace.",
 
9392
  innodb_file_format_check_validate,
 
9393
  innodb_file_format_check_update,
 
9394
  "Barracuda");
 
9395
 
 
9396
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
9397
  PLUGIN_VAR_OPCMDARG,
 
9398
  "Set to 0 (write and flush once per second),"
 
9399
  " 1 (write and flush at each commit)"
 
9400
  " or 2 (write at commit, flush once per second).",
 
9401
  NULL, NULL, 1, 0, 2, 0);
 
9402
 
 
9403
static DRIZZLE_SYSVAR_STR(flush_method, innobase_file_flush_method,
 
9404
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9405
  "With which method to flush data.", NULL, NULL, NULL);
 
9406
 
 
9407
#ifdef UNIV_LOG_ARCHIVE
 
9408
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
9409
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9410
  "Where full logs should be archived.", NULL, NULL, NULL);
 
9411
 
 
9412
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
9413
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
9414
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
9415
#endif /* UNIV_LOG_ARCHIVE */
 
9416
 
 
9417
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
9418
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9419
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
9420
 
 
9421
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
9422
  PLUGIN_VAR_RQCMDARG,
 
9423
  "Percentage of dirty pages allowed in bufferpool.",
 
9424
  NULL, NULL, 75, 0, 99, 0);
 
9425
 
 
9426
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
9427
  PLUGIN_VAR_NOCMDARG,
 
9428
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
9429
  NULL, NULL, TRUE);
 
9430
 
 
9431
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
9432
  PLUGIN_VAR_RQCMDARG,
 
9433
  "Desired maximum length of the purge queue (0 = no limit)",
 
9434
  NULL, NULL, 0, 0, ~0L, 0);
 
9435
 
 
9436
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
9437
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
9438
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
9439
  NULL, NULL, FALSE);
 
9440
 
 
9441
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
9442
  PLUGIN_VAR_RQCMDARG,
 
9443
  "The number of index pages to sample when calculating statistics (default 8)",
 
9444
  NULL, NULL, 8, 1, ~0ULL, 0);
 
9445
 
 
9446
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
9447
  PLUGIN_VAR_OPCMDARG,
 
9448
  "Enable InnoDB adaptive hash index (enabled by default).",
 
9449
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
9450
 
 
9451
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
9452
  PLUGIN_VAR_RQCMDARG,
 
9453
  "Replication thread delay (ms) on the slave server if "
 
9454
  "innodb_thread_concurrency is reached (0 by default)",
 
9455
  NULL, NULL, 0, 0, ~0UL, 0);
 
9456
 
 
9457
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
9458
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9459
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
9460
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
9461
 
 
9462
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
9463
  PLUGIN_VAR_RQCMDARG,
 
9464
  "Data file autoextend increment in megabytes",
 
9465
  NULL, NULL, 8L, 1L, 1000L, 0);
 
9466
 
 
9467
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
9468
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9469
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
9470
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
9471
 
 
9472
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
9473
  PLUGIN_VAR_RQCMDARG,
 
9474
  "Helps in performance tuning in heavily concurrent environments.",
 
9475
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
9476
 
 
9477
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
9478
  PLUGIN_VAR_RQCMDARG,
 
9479
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
9480
  NULL, NULL, 500L, 1L, ~0L, 0);
 
9481
 
 
9482
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
9483
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9484
  "Number of background read I/O threads in InnoDB.",
 
9485
  NULL, NULL, 4, 1, 64, 0);
 
9486
 
 
9487
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
9488
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9489
  "Number of background write I/O threads in InnoDB.",
 
9490
  NULL, NULL, 4, 1, 64, 0);
 
9491
 
 
9492
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
9493
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9494
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
9495
  NULL, NULL, 0, 0, 6, 0);
 
9496
 
 
9497
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
9498
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9499
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
9500
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
9501
 
 
9502
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
9503
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9504
  "Size of each log file in a log group.",
 
9505
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
9506
 
 
9507
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
9508
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9509
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
9510
  NULL, NULL, 2, 2, 100, 0);
 
9511
 
 
9512
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
9513
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9514
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
9515
  NULL, NULL, 1, 1, 10, 0);
 
9516
 
 
9517
static DRIZZLE_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
 
9518
  PLUGIN_VAR_RQCMDARG,
 
9519
  "Percentage of the buffer pool to reserve for 'old' blocks.",
 
9520
  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
 
9521
 
 
9522
static DRIZZLE_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
 
9523
  PLUGIN_VAR_RQCMDARG,
 
9524
  "Move blocks to the 'new' end of the buffer pool if the first access"
 
9525
  " was at least this many milliseconds ago."
 
9526
  " The timeout is disabled if 0 (the default).",
 
9527
  NULL, NULL, 0, 0, UINT32_MAX, 0);
 
9528
 
 
9529
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
9530
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9531
  "How many files at the maximum InnoDB keeps open at the same time.",
 
9532
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
9533
 
 
9534
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
9535
  PLUGIN_VAR_RQCMDARG,
 
9536
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
9537
  NULL, NULL, 30L, 0L, ~0L, 0);
 
9538
 
 
9539
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
9540
  PLUGIN_VAR_OPCMDARG,
 
9541
  "Maximum delay between polling for a spin lock (6 by default)",
 
9542
  NULL, NULL, 6L, 0L, ~0L, 0);
 
9543
 
 
9544
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
9545
  PLUGIN_VAR_RQCMDARG,
 
9546
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
9547
  NULL, NULL, 0, 0, 1000, 0);
 
9548
 
 
9549
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
9550
  PLUGIN_VAR_RQCMDARG,
 
9551
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
9552
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
9553
 
 
9554
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
9555
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9556
  "Path to individual files and their sizes.",
 
9557
  NULL, NULL, NULL);
 
9558
 
 
9559
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
9560
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
9561
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
9562
 
 
9563
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
9564
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9565
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
9566
  NULL, NULL, TRUE);
 
9567
 
 
9568
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
9569
  PLUGIN_VAR_RQCMDARG,
 
9570
  "Buffer changes to reduce random access: "
 
9571
  "OFF, ON, none, inserts.",
 
9572
  innodb_change_buffering_validate,
 
9573
  innodb_change_buffering_update, NULL);
 
9574
 
 
9575
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
9576
  PLUGIN_VAR_RQCMDARG,
 
9577
  "Number of pages that must be accessed sequentially for InnoDB to "
 
9578
  "trigger a readahead.",
 
9579
  NULL, NULL, 56, 0, 64, 0);
9126
9580
 
9127
9581
static void init_options(drizzled::module::option_context &context)
9128
9582
{
9134
9588
  context("disable-doublewrite",
9135
9589
          "Disable InnoDB doublewrite buffer.");
9136
9590
  context("io-capacity",
9137
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
9591
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9138
9592
          "Number of IOPs the server can do. Tunes the background IO rate");
9139
9593
  context("fast-shutdown",
9140
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
9594
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9141
9595
          "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
9596
  context("file-per-table",
9150
9597
          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.");
 
9598
          "Stores each InnoDB table to an .ibd file in the database dir.");
9158
9599
  context("file-format",
9159
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
9600
          po::value<string>()->default_value("Antelope"),
9160
9601
          "File format to use for new tables in .ibd files.");
 
9602
  context("file-format-check",
 
9603
          po::value<string>()->default_value("on"),
 
9604
          "The highest file format in the tablespace.");
9161
9605
  context("flush-log-at-trx-commit",
9162
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
9606
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9163
9607
          "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
9608
  context("flush-method",
9165
9609
          po::value<string>(),
9166
9610
          "With which method to flush data.");
 
9611
#ifdef UNIV_LOG_ARCHIVE
 
9612
  context("log-arch-dir",
 
9613
          po::value<string>(),
 
9614
          "Where full logs should be archived.");
 
9615
  context("log-archive",
 
9616
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
9617
          "Set to 1 if you want to have logs archived.");
 
9618
#endif /* UNIV_LOG_ARCHIVE */
9167
9619
  context("log-group-home-dir",
9168
9620
          po::value<string>(),
9169
9621
          "Path to InnoDB log files.");
9170
9622
  context("max-dirty-pages-pct",
9171
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
9623
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9172
9624
          "Percentage of dirty pages allowed in bufferpool.");
9173
9625
  context("disable-adaptive-flushing",
9174
9626
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9175
9627
  context("max-purge-lag",
9176
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
9628
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9177
9629
          "Desired maximum length of the purge queue (0 = no limit)");
9178
9630
  context("status-file",
9179
9631
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9181
9633
  context("disable-stats-on-metadata",
9182
9634
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9183
9635
  context("stats-sample-pages",
9184
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
9636
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9185
9637
          "The number of index pages to sample when calculating statistics (default 8)");
9186
9638
  context("disable-adaptive-hash-index",
9187
9639
          "Enable InnoDB adaptive hash index (enabled by default)");
9188
9640
  context("replication-delay",
9189
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
9641
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9190
9642
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9191
9643
  context("additional-mem-pool-size",
9192
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
9644
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9193
9645
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9194
9646
  context("autoextend-increment",
9195
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
9647
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9196
9648
          "Data file autoextend increment in megabytes");
9197
9649
  context("buffer-pool-size",
9198
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
9650
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9199
9651
          "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
9652
  context("commit-concurrency",
9205
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
9653
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9206
9654
          "Helps in performance tuning in heavily concurrent environments.");
9207
9655
  context("concurrency-tickets",
9208
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
9656
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9209
9657
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9210
9658
  context("read-io-threads",
9211
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
9659
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9212
9660
          "Number of background read I/O threads in InnoDB.");
9213
9661
  context("write-io-threads",
9214
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
9662
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9215
9663
          "Number of background write I/O threads in InnoDB.");
9216
9664
  context("force-recovery",
9217
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
9665
          po::value<long>(&innobase_force_recovery)->default_value(0),
9218
9666
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9219
9667
  context("log-buffer-size",
9220
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
9668
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9221
9669
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9222
9670
  context("log-file-size",
9223
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
9671
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9224
9672
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9225
9673
  context("log-files-in-group",
9226
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
9674
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9227
9675
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9228
9676
  context("mirrored-log-groups",
9229
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
9677
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9230
9678
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9231
9679
  context("open-files",
9232
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
9680
          po::value<long>(&innobase_open_files)->default_value(300L),
9233
9681
          "How many files at the maximum InnoDB keeps open at the same time.");
9234
9682
  context("sync-spin-loops",
9235
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9683
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9236
9684
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9237
9685
  context("spin-wait-delay",
9238
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9686
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9239
9687
          "Maximum delay between polling for a spin lock (6 by default)");
9240
9688
  context("thread-concurrency",
9241
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9689
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9242
9690
          "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
9691
  context("thread-sleep-delay",
9244
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9692
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9245
9693
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9246
9694
  context("data-file-path",
9247
9695
          po::value<string>(),
9251
9699
          "InnoDB version");
9252
9700
  context("use-internal-malloc",
9253
9701
          "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
9702
  context("change-buffering",
9257
 
          po::value<string>(&innobase_change_buffering),
 
9703
          po::value<string>(),
9258
9704
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9259
9705
  context("read-ahead-threshold",
9260
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9706
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9261
9707
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9262
9708
  context("disable-xa",
9263
9709
          "Disable InnoDB support for the XA two-phase commit");
9264
9710
  context("disable-table-locks",
9265
9711
          "Disable InnoDB locking in LOCK TABLES");
9266
9712
  context("strict-mode",
9267
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9713
          po::value<bool>()->default_value(false)->zero_tokens(),
9268
9714
          "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
9715
  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)."));
 
9716
          po::value<unsigned long>()->default_value(50),
 
9717
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9283
9718
}
9284
9719
 
9285
 
 
 
9720
static drizzle_sys_var* innobase_system_variables[]= {
 
9721
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9722
  DRIZZLE_SYSVAR(autoextend_increment),
 
9723
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9724
  DRIZZLE_SYSVAR(checksums),
 
9725
  DRIZZLE_SYSVAR(commit_concurrency),
 
9726
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9727
  DRIZZLE_SYSVAR(data_file_path),
 
9728
  DRIZZLE_SYSVAR(data_home_dir),
 
9729
  DRIZZLE_SYSVAR(doublewrite),
 
9730
  DRIZZLE_SYSVAR(fast_shutdown),
 
9731
  DRIZZLE_SYSVAR(read_io_threads),
 
9732
  DRIZZLE_SYSVAR(write_io_threads),
 
9733
  DRIZZLE_SYSVAR(file_per_table),
 
9734
  DRIZZLE_SYSVAR(file_format),
 
9735
  DRIZZLE_SYSVAR(file_format_check),
 
9736
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9737
  DRIZZLE_SYSVAR(flush_method),
 
9738
  DRIZZLE_SYSVAR(force_recovery),
 
9739
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9740
#ifdef UNIV_LOG_ARCHIVE
 
9741
  DRIZZLE_SYSVAR(log_arch_dir),
 
9742
  DRIZZLE_SYSVAR(log_archive),
 
9743
#endif /* UNIV_LOG_ARCHIVE */
 
9744
  DRIZZLE_SYSVAR(log_buffer_size),
 
9745
  DRIZZLE_SYSVAR(log_file_size),
 
9746
  DRIZZLE_SYSVAR(log_files_in_group),
 
9747
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9748
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9749
  DRIZZLE_SYSVAR(max_purge_lag),
 
9750
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9751
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9752
  DRIZZLE_SYSVAR(old_blocks_pct),
 
9753
  DRIZZLE_SYSVAR(old_blocks_time),
 
9754
  DRIZZLE_SYSVAR(open_files),
 
9755
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9756
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9757
  DRIZZLE_SYSVAR(replication_delay),
 
9758
  DRIZZLE_SYSVAR(status_file),
 
9759
  DRIZZLE_SYSVAR(strict_mode),
 
9760
  DRIZZLE_SYSVAR(support_xa),
 
9761
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9762
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9763
  DRIZZLE_SYSVAR(table_locks),
 
9764
  DRIZZLE_SYSVAR(thread_concurrency),
 
9765
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9766
  DRIZZLE_SYSVAR(version),
 
9767
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9768
  DRIZZLE_SYSVAR(change_buffering),
 
9769
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9770
  DRIZZLE_SYSVAR(io_capacity),
 
9771
  NULL
 
9772
};
9286
9773
 
9287
9774
DRIZZLE_DECLARE_PLUGIN
9288
9775
{
9293
9780
  "Supports transactions, row-level locking, and foreign keys",
9294
9781
  PLUGIN_LICENSE_GPL,
9295
9782
  innobase_init, /* Plugin Init */
9296
 
  NULL, /* depends */
 
9783
  innobase_system_variables, /* system variables */
9297
9784
  init_options /* reserved */
9298
9785
}
9299
9786
DRIZZLE_DECLARE_PLUGIN_END;
9321
9808
  return res;
9322
9809
}
9323
9810
 
 
9811
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9812
 
 
9813
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9814
from zero to nonzero. (Bug #42101)
 
9815
 
 
9816
The initial default value is 0, and without this extra initialization,
 
9817
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9818
to 0, even if it was initially set to nonzero at the command line
 
9819
or configuration file. */
 
9820
static
 
9821
void
 
9822
innobase_commit_concurrency_init_default(void)
 
9823
/*==========================================*/
 
9824
{
 
9825
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9826
    = innobase_commit_concurrency;
 
9827
}
 
9828
 
9324
9829
/***********************************************************************
9325
9830
This function checks each index name for a table against reserved
9326
9831
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9327
9832
this function pushes an warning message to the client, and returns true. */
9328
 
UNIV_INTERN
 
9833
extern "C" UNIV_INTERN
9329
9834
bool
9330
9835
innobase_index_name_is_reserved(
9331
9836
/*============================*/
9345
9850
    if (innobase_strcasecmp(key->name,
9346
9851
                            innobase_index_reserve_name) == 0) {
9347
9852
      /* Push warning to drizzle */
9348
 
      push_warning_printf(trx->mysql_thd,
 
9853
      push_warning_printf((Session*)trx->mysql_thd,
9349
9854
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9350
9855
                          ER_WRONG_NAME_FOR_INDEX,
9351
9856
                          "Cannot Create Index with name "
9371
9876
  ulint   buflen;
9372
9877
  const char* id;
9373
9878
  ulint   idlen;
9374
 
  drizzled::Session *session;
 
9879
  void*   session;
9375
9880
  ibool   file_id;
9376
9881
 
9377
9882
  const char* expected;