~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Marisa Plumb
  • Date: 2010-12-04 02:38:29 UTC
  • mto: This revision was merged to the branch mainline in revision 1984.
  • Revision ID: marisa.plumb@gmail.com-20101204023829-2khzxh30wxi256db
updates to a few sql docs 

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
38
38
    in Windows?
39
39
*/
40
40
 
41
 
#include <config.h>
 
41
#include "config.h"
42
42
 
43
43
#include <limits.h>
44
44
#include <fcntl.h>
45
45
 
46
 
#include <drizzled/error.h>
47
 
#include <drizzled/errmsg_print.h>
48
 
#include <drizzled/charset_info.h>
49
 
#include <drizzled/internal/m_string.h>
50
 
#include <drizzled/internal/my_sys.h>
51
 
#include <drizzled/my_hash.h>
52
 
#include <drizzled/plugin.h>
53
 
#include <drizzled/show.h>
54
 
#include <drizzled/data_home.h>
55
 
#include <drizzled/error.h>
56
 
#include <drizzled/field.h>
57
 
#include <drizzled/charset.h>
58
 
#include <drizzled/session.h>
59
 
#include <drizzled/current_session.h>
60
 
#include <drizzled/table.h>
61
 
#include <drizzled/field/blob.h>
62
 
#include <drizzled/field/varstring.h>
63
 
#include <drizzled/plugin/xa_storage_engine.h>
64
 
#include <drizzled/plugin/daemon.h>
65
 
#include <drizzled/memory/multi_malloc.h>
66
 
#include <drizzled/pthread_globals.h>
67
 
#include <drizzled/named_savepoint.h>
 
46
#include "drizzled/error.h"
 
47
#include "drizzled/errmsg_print.h"
 
48
#include "drizzled/charset_info.h"
 
49
#include "drizzled/internal/m_string.h"
 
50
#include "drizzled/internal/my_sys.h"
 
51
#include "drizzled/my_hash.h"
 
52
#include "drizzled/plugin.h"
 
53
#include "drizzled/show.h"
 
54
#include "drizzled/data_home.h"
 
55
#include "drizzled/error.h"
 
56
#include "drizzled/field.h"
 
57
#include "drizzled/charset.h"
 
58
#include "drizzled/session.h"
 
59
#include "drizzled/current_session.h"
 
60
#include "drizzled/table.h"
 
61
#include "drizzled/field/blob.h"
 
62
#include "drizzled/field/varstring.h"
 
63
#include "drizzled/field/timestamp.h"
 
64
#include "drizzled/plugin/xa_storage_engine.h"
 
65
#include "drizzled/plugin/daemon.h"
 
66
#include "drizzled/memory/multi_malloc.h"
 
67
#include "drizzled/pthread_globals.h"
 
68
#include "drizzled/named_savepoint.h"
68
69
 
69
70
#include <drizzled/transaction_services.h>
70
 
#include <drizzled/message/statement_transform.h>
 
71
#include "drizzled/message/statement_transform.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
 
125
126
#include <sstream>
126
127
#include <string>
127
128
 
128
 
#include <plugin/innobase/handler/status_function.h>
129
 
#include <plugin/innobase/handler/replication_log.h>
130
 
 
131
 
#include <google/protobuf/io/zero_copy_stream.h>
132
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
 
#include <google/protobuf/io/coded_stream.h>
134
 
#include <google/protobuf/text_format.h>
135
 
 
136
 
#include <boost/thread/mutex.hpp>
 
129
#include "plugin/innobase/handler/status_function.h"
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
  {
559
505
           Using schema_identifier here to stop unused warning, could use
560
506
           definition.schema() instead
561
507
        */
562
 
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
 
508
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
563
509
        set_of_identifiers.push_back(identifier);
564
510
      }
565
511
    }
566
512
  }
567
513
}
568
514
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
515
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
516
{
571
517
  string proto_path(identifier.getPath());
572
518
  proto_path.append(DEFAULT_FILE_EXTENSION);
574
520
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
521
    return true;
576
522
 
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
523
  if (access(proto_path.c_str(), F_OK))
584
524
  {
585
525
    return false;
589
529
}
590
530
 
591
531
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
532
                                         const TableIdentifier &identifier,
593
533
                                         message::Table &table_proto)
594
534
{
595
535
  string proto_path(identifier.getPath());
599
539
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
540
    return EEXIST;
601
541
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
603
 
    return EEXIST;
604
 
 
605
542
  if (access(proto_path.c_str(), F_OK))
606
543
  {
607
544
    return errno;
613
550
  return ENOENT;
614
551
}
615
552
 
 
553
/** @brief Initialize the default value of innodb_commit_concurrency.
 
554
 
 
555
Once InnoDB is running, the innodb_commit_concurrency must not change
 
556
from zero to nonzero. (Bug #42101)
 
557
 
 
558
The initial default value is 0, and without this extra initialization,
 
559
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
560
to 0, even if it was initially set to nonzero at the command line
 
561
or configuration file. */
 
562
static
 
563
void
 
564
innobase_commit_concurrency_init_default(void);
 
565
/*==========================================*/
616
566
 
617
567
/************************************************************//**
618
568
Validate the file format name and return its corresponding id.
625
575
            name */
626
576
/************************************************************//**
627
577
Validate the file format check config parameters, as a side effect it
628
 
sets the srv_max_file_format_at_startup variable.
 
578
sets the srv_check_file_format_at_startup variable.
 
579
@return true if one of  "on" or "off" */
 
580
static
 
581
bool
 
582
innobase_file_format_check_on_off(
 
583
/*==============================*/
 
584
  const char* format_check);    /*!< in: parameter value */
 
585
/************************************************************//**
 
586
Validate the file format check config parameters, as a side effect it
 
587
sets the srv_check_file_format_at_startup variable.
629
588
@return the format_id if valid config value, otherwise, return -1 */
630
589
static
631
590
int
632
591
innobase_file_format_validate_and_set(
633
592
/*================================*/
634
 
  const char* format_max);    /*!< in: parameter value */
 
593
  const char* format_check);    /*!< in: parameter value */
635
594
 
636
595
static const char innobase_engine_name[]= "InnoDB";
637
596
 
 
597
/*************************************************************//**
 
598
Check for a valid value of innobase_commit_concurrency.
 
599
@return 0 for valid innodb_commit_concurrency */
 
600
static
 
601
int
 
602
innobase_commit_concurrency_validate(
 
603
/*=================================*/
 
604
  Session*      , /*!< in: thread handle */
 
605
  drizzle_sys_var*  , /*!< in: pointer to system
 
606
            variable */
 
607
  void*       save, /*!< out: immediate result
 
608
            for update function */
 
609
  drizzle_value*    value)  /*!< in: incoming string */
 
610
{
 
611
  int64_t   intbuf;
 
612
  ulong   commit_concurrency;
 
613
 
 
614
  if (value->val_int(value, &intbuf)) {
 
615
    /* The value is NULL. That is invalid. */
 
616
    return(1);
 
617
  }
 
618
 
 
619
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
620
    = static_cast<ulong>(intbuf);
 
621
 
 
622
  /* Allow the value to be updated, as long as it remains zero
 
623
  or nonzero. */
 
624
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
625
}
 
626
 
 
627
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
628
  "Enable InnoDB support for the XA two-phase commit",
 
629
  /* check_func */ NULL, /* update_func */ NULL,
 
630
  /* default */ TRUE);
 
631
 
 
632
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
633
  "Enable InnoDB locking in LOCK TABLES",
 
634
  /* check_func */ NULL, /* update_func */ NULL,
 
635
  /* default */ TRUE);
 
636
 
 
637
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
638
  "Use strict mode when evaluating create options.",
 
639
  NULL, NULL, FALSE);
 
640
 
 
641
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
642
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
643
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
644
 
638
645
 
639
646
/*****************************************************************//**
640
647
Commits a transaction in an InnoDB database. */
798
805
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
806
         in non-Cursor code.
800
807
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
808
extern "C" UNIV_INTERN
802
809
ibool
803
810
thd_is_replication_slave_thread(
804
811
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
812
  void* ) /*!< in: thread handle (Session*) */
806
813
{
807
814
  return false;
808
815
}
872
879
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
880
         in non-Cursor code.
874
881
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
882
extern "C" UNIV_INTERN
876
883
ibool
877
884
thd_has_edited_nontrans_tables(
878
885
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
886
  void*   session)  /*!< in: thread handle (Session*) */
880
887
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
888
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
889
}
883
890
 
884
891
/******************************************************************//**
885
892
Returns true if the thread is executing a SELECT statement.
886
893
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
894
extern "C" UNIV_INTERN
888
895
ibool
889
896
thd_is_select(
890
897
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
898
  const void* session)  /*!< in: thread handle (Session*) */
892
899
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
900
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
901
}
895
902
 
896
903
/******************************************************************//**
897
904
Returns true if the thread supports XA,
898
905
global value of innodb_supports_xa if session is NULL.
899
906
@return true if session has XA support */
900
 
UNIV_INTERN
 
907
extern "C" UNIV_INTERN
901
908
ibool
902
909
thd_supports_xa(
903
910
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
911
  void* session)  /*!< in: thread handle (Session*), or NULL to query
905
912
        the global innodb_supports_xa */
906
913
{
907
 
  /* TODO: Add support here for per-session value */
908
 
  return(support_xa);
 
914
  return(SessionVAR((Session*) session, support_xa));
909
915
}
910
916
 
911
917
/******************************************************************//**
912
918
Returns the lock wait timeout for the current connection.
913
919
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
920
extern "C" UNIV_INTERN
915
921
ulong
916
922
thd_lock_wait_timeout(
917
923
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
924
  void* session)  /*!< in: thread handle (Session*), or NULL to query
919
925
      the global innodb_lock_wait_timeout */
920
926
{
921
 
  /* TODO: Add support here for per-session value */
922
927
  /* According to <drizzle/plugin.h>, passing session == NULL
923
928
  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;
 
929
  return(SessionVAR((Session*) session, lock_wait_timeout));
938
930
}
939
931
 
940
932
/********************************************************************//**
949
941
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
950
942
}
951
943
 
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
944
/********************************************************************//**
977
945
Call this function when mysqld passes control to the client. That is to
978
946
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1022
990
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
991
timeout or a deadlock.
1024
992
@return MySQL error code */
1025
 
UNIV_INTERN
 
993
extern "C" UNIV_INTERN
1026
994
int
1027
995
convert_error_code_to_mysql(
1028
996
/*========================*/
1037
1005
  case DB_INTERRUPTED:
1038
1006
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1039
1007
    /* 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
1008
  case DB_ERROR:
1053
1009
  default:
1054
1010
    return(-1); /* unspecified error */
1076
1032
    tell it also to MySQL so that MySQL knows to empty the
1077
1033
    cached binlog for this transaction */
1078
1034
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1035
    mark_transaction_to_rollback(session, TRUE);
1080
1036
 
1081
1037
    return(HA_ERR_LOCK_DEADLOCK);
1082
1038
 
1085
1041
    latest SQL statement in a lock wait timeout. Previously, we
1086
1042
    rolled back the whole transaction. */
1087
1043
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1044
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1045
 
1090
1046
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1047
 
1096
1052
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1053
 
1098
1054
  case DB_CANNOT_ADD_CONSTRAINT:
1099
 
  case DB_CHILD_NO_INDEX:
1100
 
  case DB_PARENT_NO_INDEX:
1101
1055
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1056
 
1103
1057
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1075
 
1122
1076
  case DB_TOO_BIG_RECORD:
1123
1077
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1078
       page_get_free_space_of_empty(flags
 
1079
                  & DICT_TF_COMPACT) / 2);
1125
1080
    return(HA_ERR_TO_BIG_ROW);
1126
1081
 
1127
1082
  case DB_NO_SAVEPOINT:
1132
1087
    tell it also to MySQL so that MySQL knows to empty the
1133
1088
    cached binlog for this transaction */
1134
1089
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1090
    mark_transaction_to_rollback(session, TRUE);
1136
1091
 
1137
1092
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1093
 
1166
1121
 
1167
1122
/*************************************************************//**
1168
1123
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1124
extern "C" UNIV_INTERN
1170
1125
void
1171
1126
innobase_mysql_print_thd(
1172
1127
/*=====================*/
1173
1128
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1129
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1130
  uint  )   /*!< in: max query length to print, or 0 to
1176
1131
           use the default max length */
1177
1132
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1133
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1134
  fprintf(f,
1181
1135
          "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()),
1184
 
          getServerHostname().c_str(),
1185
 
          user_identifier->address().c_str(),
1186
 
          user_identifier->username().c_str()
 
1136
          static_cast<uint64_t>(session->getSessionId()),
 
1137
          static_cast<uint64_t>(session->getQueryId()),
 
1138
          glob_hostname,
 
1139
          session->getSecurityContext().getIp().c_str(),
 
1140
          session->getSecurityContext().getUser().c_str()
1187
1141
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1142
  fprintf(f, "\n%s", session->getQueryString()->c_str());
1189
1143
  putc('\n', f);
1190
1144
}
1191
1145
 
1192
1146
/******************************************************************//**
1193
1147
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1148
extern "C" UNIV_INTERN
1195
1149
void
1196
1150
innobase_get_cset_width(
1197
1151
/*====================*/
1208
1162
  if (cs) {
1209
1163
    *mbminlen = cs->mbminlen;
1210
1164
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1165
  } else {
1214
1166
    ut_a(cset == 0);
1215
1167
    *mbminlen = *mbmaxlen = 0;
1218
1170
 
1219
1171
/******************************************************************//**
1220
1172
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1173
extern "C" UNIV_INTERN
1222
1174
void
1223
1175
innobase_convert_from_table_id(
1224
1176
/*===========================*/
1232
1184
 
1233
1185
/******************************************************************//**
1234
1186
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1187
extern "C" UNIV_INTERN
1236
1188
void
1237
1189
innobase_convert_from_id(
1238
1190
/*=====================*/
1247
1199
/******************************************************************//**
1248
1200
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1201
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1202
extern "C" UNIV_INTERN
1251
1203
int
1252
1204
innobase_strcasecmp(
1253
1205
/*================*/
1259
1211
 
1260
1212
/******************************************************************//**
1261
1213
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1214
extern "C" UNIV_INTERN
1263
1215
void
1264
1216
innobase_casedn_str(
1265
1217
/*================*/
1268
1220
  my_casedn_str(system_charset_info, a);
1269
1221
}
1270
1222
 
1271
 
UNIV_INTERN
 
1223
/**********************************************************************//**
 
1224
Determines the connection character set.
 
1225
@return connection character set */
 
1226
extern "C" UNIV_INTERN
 
1227
const void*
 
1228
innobase_get_charset(
 
1229
/*=================*/
 
1230
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1231
{
 
1232
  return static_cast<Session*>(mysql_session)->charset();
 
1233
}
 
1234
 
 
1235
extern "C" UNIV_INTERN
1272
1236
bool
1273
1237
innobase_isspace(
1274
1238
  const void *cs,
1277
1241
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1242
}
1279
1243
 
 
1244
UNIV_INTERN
 
1245
int
 
1246
innobase_fast_mutex_init(
 
1247
        os_fast_mutex_t*        fast_mutex)
 
1248
{
 
1249
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1250
}
 
1251
 
 
1252
/**********************************************************************//**
 
1253
Determines the current SQL statement.
 
1254
@return SQL statement string */
 
1255
extern "C" UNIV_INTERN
 
1256
const char*
 
1257
innobase_get_stmt(
 
1258
/*==============*/
 
1259
        void*   session,        /*!< in: MySQL thread handle */
 
1260
        size_t* length)         /*!< out: length of the SQL statement */
 
1261
{
 
1262
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
 
1263
}
 
1264
 
1280
1265
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1266
/*******************************************************************//**
1282
1267
Map an OS error to an errno value. The OS error number is stored in
1283
1268
_doserrno and the mapped value is stored in errno) */
 
1269
extern "C"
1284
1270
void __cdecl
1285
1271
_dosmaperr(
1286
1272
  unsigned long); /*!< in: OS error value */
1288
1274
/*********************************************************************//**
1289
1275
Creates a temporary file.
1290
1276
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1277
extern "C" UNIV_INTERN
1292
1278
int
1293
1279
innobase_mysql_tmpfile(void)
1294
1280
/*========================*/
1368
1354
/*********************************************************************//**
1369
1355
Creates a temporary file.
1370
1356
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1357
extern "C" UNIV_INTERN
1372
1358
int
1373
1359
innobase_mysql_tmpfile(void)
1374
1360
/*========================*/
1375
1361
{
1376
1362
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1363
  int fd = mysql_tmpfile("ib");
1378
1364
  if (fd >= 0) {
1379
1365
    /* Copy the file descriptor, so that the additional resources
1380
1366
    allocated by create_temp_file() can be freed by invoking
1407
1393
number of bytes that were written to "buf" is returned (including the
1408
1394
terminating NUL).
1409
1395
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1396
extern "C" UNIV_INTERN
1411
1397
ulint
1412
1398
innobase_raw_format(
1413
1399
/*================*/
1527
1513
/*********************************************************************//**
1528
1514
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1515
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1516
extern "C" UNIV_INTERN
1531
1517
trx_t*
1532
1518
innobase_trx_allocate(
1533
1519
/*==================*/
1631
1617
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1618
  const char* id, /*!< in: identifier to convert */
1633
1619
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1620
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1621
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1622
        FALSE=id is an UTF-8 string */
1637
1623
{
1638
1624
  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]);
 
1625
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1626
 
1642
1627
  const char* s = id;
1643
1628
  int   q;
1654
1639
    memcpy(nz, id, idlen);
1655
1640
    nz[idlen] = 0;
1656
1641
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1642
    s = nz2;
 
1643
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1644
  }
1660
1645
 
1661
1646
  /* See if the identifier needs to be quoted. */
1709
1694
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1695
and quote it if needed.
1711
1696
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1697
extern "C" UNIV_INTERN
1713
1698
char*
1714
1699
innobase_convert_name(
1715
1700
/*==================*/
1717
1702
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1703
  const char* id, /*!< in: identifier to convert */
1719
1704
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1705
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1706
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1707
        FALSE=id is an index name */
1723
1708
{
1765
1750
/**********************************************************************//**
1766
1751
Determines if the currently running transaction has been interrupted.
1767
1752
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1753
extern "C" UNIV_INTERN
1769
1754
ibool
1770
1755
trx_is_interrupted(
1771
1756
/*===============*/
1772
1757
  trx_t*  trx)  /*!< in: transaction */
1773
1758
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
 
1759
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1775
1760
}
1776
1761
 
1777
1762
/**********************************************************************//**
1778
1763
Determines if the currently running transaction is in strict mode.
1779
1764
@return TRUE if strict */
1780
 
UNIV_INTERN
 
1765
extern "C" UNIV_INTERN
1781
1766
ibool
1782
1767
trx_is_strict(
1783
1768
/*==========*/
1784
1769
        trx_t*  trx)    /*!< in: transaction */
1785
1770
{
1786
 
        return(trx && trx->mysql_thd
1787
 
               && true);
 
1771
  return(trx && trx->mysql_thd && true);
1788
1772
}
1789
1773
 
1790
1774
/**************************************************************//**
1806
1790
  value= value - (value % align_val);
1807
1791
}
1808
1792
 
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
1793
/*********************************************************************//**
2008
1794
Opens an InnoDB database.
2009
1795
@return 0 on success, error code on failure */
2019
1805
  InnobaseEngine *actuall_engine_ptr;
2020
1806
  const module::option_map &vm= context.getOptions();
2021
1807
 
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
1808
  /* Inverted Booleans */
2039
1809
 
2040
1810
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2041
1811
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
1812
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
1813
  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 */
 
1814
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1815
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1816
 
 
1817
  if (vm.count("io-capacity"))
 
1818
  {
 
1819
    if (srv_io_capacity < 100)
 
1820
    {
 
1821
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1822
      exit(-1);
 
1823
    }
 
1824
  }
 
1825
 
2050
1826
  if (vm.count("data-home-dir"))
2051
1827
  {
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
 
 
 
1828
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1829
  }
 
1830
  else
 
1831
  {
 
1832
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
 
1833
  }
 
1834
 
 
1835
  if (vm.count("fast-shutdown"))
 
1836
  {
 
1837
    if (innobase_fast_shutdown > 2)
 
1838
    {
 
1839
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1840
      exit(-1);
 
1841
    }
 
1842
  }
 
1843
 
 
1844
  if (vm.count("file-format-check"))
 
1845
  {
 
1846
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1847
  }
 
1848
 
 
1849
  if (vm.count("flush-log-at-trx-commit"))
 
1850
  {
 
1851
    if (srv_flush_log_at_trx_commit > 2)
 
1852
    {
 
1853
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1854
      exit(-1);
 
1855
    }
 
1856
  }
 
1857
 
 
1858
  if (vm.count("flush-method"))
 
1859
  {
 
1860
    innobase_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1861
  }
 
1862
  else
 
1863
  {
 
1864
    innobase_file_flush_method= NULL;
 
1865
  }
 
1866
 
 
1867
#ifdef UNIV_LOG_ARCHIVE
 
1868
  if (vm.count("log-arch-dir"))
 
1869
  {
 
1870
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1871
  }
 
1872
 
 
1873
  else
 
1874
  {
 
1875
    innobase_log_arch_dir= NULL;
 
1876
  }
 
1877
#endif /* UNIV_LOG_ARCHIVE */
 
1878
 
 
1879
  if (vm.count("max-dirty-pages-pct"))
 
1880
  {
 
1881
    if (srv_max_buf_pool_modified_pct > 99)
 
1882
    {
 
1883
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1884
      exit(-1);
 
1885
    }
 
1886
  }
 
1887
 
 
1888
  if (vm.count("stats-sample-pages"))
 
1889
  {
 
1890
    if (srv_stats_sample_pages < 8)
 
1891
    {
 
1892
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1893
      exit(-1);
 
1894
    }
 
1895
  }
 
1896
 
 
1897
  if (vm.count("additional-mem-pool-size"))
 
1898
  {
 
1899
    align_value(innobase_additional_mem_pool_size);
 
1900
 
 
1901
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1902
    {
 
1903
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1904
      exit(-1);
 
1905
    }
 
1906
 
 
1907
  }
 
1908
 
 
1909
  if (vm.count("autoextend-increment"))
 
1910
  {
 
1911
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1912
    {
 
1913
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1914
      exit(-1);
 
1915
    }
 
1916
  }
 
1917
 
 
1918
  if (vm.count("buffer-pool-size"))
 
1919
  {
 
1920
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1921
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1922
    {
 
1923
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1924
      exit(-1);
 
1925
    }
 
1926
    
 
1927
  }
 
1928
 
 
1929
  if (vm.count("commit-concurrency"))
 
1930
  {
 
1931
    if (srv_replication_delay > 1000)
 
1932
    {
 
1933
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1934
      exit(-1);
 
1935
    }
 
1936
  }
 
1937
 
 
1938
  if (vm.count("concurrency-tickets"))
 
1939
  {
 
1940
    if (srv_n_free_tickets_to_enter < 1)
 
1941
    {
 
1942
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1943
      exit(-1);
 
1944
    }
 
1945
  }
 
1946
 
 
1947
  if (vm.count("read-io-threads"))
 
1948
  {
 
1949
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1950
    {
 
1951
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1952
      exit(-1);
 
1953
    }
 
1954
  }
 
1955
 
 
1956
  if (vm.count("write-io-threads"))
 
1957
  {
 
1958
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1959
    {
 
1960
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1961
      exit(-1);
 
1962
    }
 
1963
  }
 
1964
 
 
1965
  if (vm.count("force-recovery"))
 
1966
  {
 
1967
    if (innobase_force_recovery > 6)
 
1968
    {
 
1969
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
1970
      exit(-1);
 
1971
    }
 
1972
  }
 
1973
 
 
1974
  if (vm.count("log-buffer-size"))
 
1975
  {
 
1976
    align_value(innobase_log_buffer_size);
 
1977
    if (innobase_log_buffer_size < 256*1024L)
 
1978
    {
 
1979
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1980
      exit(-1);
 
1981
    }
 
1982
  }
 
1983
 
 
1984
  if (vm.count("log-file-size"))
 
1985
  {
 
1986
    align_value(innobase_log_file_size, 1024*1024);
 
1987
    if (innobase_log_file_size < 1*1024*1024L)
 
1988
    {
 
1989
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
1990
      exit(-1);
 
1991
    }
 
1992
  }
 
1993
 
 
1994
  if (vm.count("log-files-in-group"))
 
1995
  {
 
1996
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
1997
    {
 
1998
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
1999
      exit(-1);
 
2000
    }
 
2001
  }
 
2002
 
 
2003
  if (vm.count("mirrored-log-groups"))
 
2004
  {
 
2005
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2006
    {
 
2007
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2008
      exit(-1);
 
2009
    }
 
2010
  }
 
2011
 
 
2012
  if (vm.count("open-files"))
 
2013
  {
 
2014
    if (innobase_open_files < 10)
 
2015
    {
 
2016
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2017
      exit(-1);
 
2018
    }
 
2019
  }
 
2020
 
 
2021
  if (vm.count("thread-concurrency"))
 
2022
  {
 
2023
    if (srv_thread_concurrency > 1000)
 
2024
    {
 
2025
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2026
      exit(-1);
 
2027
    }
 
2028
  }
2059
2029
 
2060
2030
  if (vm.count("data-file-path"))
2061
2031
  {
2062
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2063
 
  }
2064
 
 
 
2032
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2033
  }
 
2034
  else
 
2035
  {
 
2036
    innobase_data_file_path= NULL;
 
2037
  }
 
2038
 
 
2039
  if (vm.count("version"))
 
2040
  {
 
2041
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2042
  }
 
2043
 
 
2044
  if (vm.count("read-ahead-threshold"))
 
2045
  {
 
2046
    if (srv_read_ahead_threshold > 64)
 
2047
    {
 
2048
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2049
      exit(-1);
 
2050
    }
 
2051
  }
 
2052
 
 
2053
  if (vm.count("strict-mode"))
 
2054
  {
 
2055
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2056
  }
 
2057
 
 
2058
  if (vm.count("lock-wait-timeout"))
 
2059
  {
 
2060
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2061
    {
 
2062
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2063
      exit(-1);
 
2064
    }
 
2065
 
 
2066
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2067
  }
2065
2068
 
2066
2069
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2067
2070
 
2069
2072
 
2070
2073
#ifdef UNIV_DEBUG
2071
2074
  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(),
 
2075
  char      test_tablename[sizeof test_filename
 
2076
    + sizeof srv_mysql50_table_name_prefix];
 
2077
  if ((sizeof test_tablename) - 1
 
2078
      != filename_to_tablename(test_filename, test_tablename,
 
2079
                               sizeof test_tablename)
 
2080
      || strncmp(test_tablename,
 
2081
                 srv_mysql50_table_name_prefix,
 
2082
                 sizeof srv_mysql50_table_name_prefix)
 
2083
      || strcmp(test_tablename
 
2084
                + sizeof srv_mysql50_table_name_prefix,
2083
2085
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2086
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2087
    goto error;
2086
2088
  }
2087
2089
#endif /* UNIV_DEBUG */
2088
2090
 
 
2091
  /* Check that values don't overflow on 32-bit systems. */
 
2092
  if (sizeof(ulint) == 4) {
 
2093
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2094
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2095
                    "innobase_buffer_pool_size can't be over 4GB"
 
2096
                    " on 32-bit systems");
 
2097
 
 
2098
      goto error;
 
2099
    }
 
2100
 
 
2101
    if (innobase_log_file_size > UINT32_MAX) {
 
2102
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2103
                    "innobase_log_file_size can't be over 4GB"
 
2104
                    " on 32-bit systems");
 
2105
 
 
2106
      goto error;
 
2107
    }
 
2108
  }
 
2109
 
2089
2110
  os_innodb_umask = (ulint)internal::my_umask;
2090
2111
 
2091
2112
 
2096
2117
 
2097
2118
  /* The default dir for data files is the datadir of MySQL */
2098
2119
 
2099
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2120
  srv_data_home = (char *)innobase_data_home_dir;
2100
2121
 
2101
2122
  /* Set default InnoDB data file size to 10 MB and let it be
2102
2123
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2103
2124
    to specify any startup options. */
2104
2125
 
2105
 
  if (innobase_data_file_path.empty()) 
2106
 
  {
2107
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2126
  if (!innobase_data_file_path) {
 
2127
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2108
2128
  }
2109
2129
 
2110
2130
  /* Since InnoDB edits the argument in the next call, we make another
2111
2131
    copy of it: */
2112
2132
 
2113
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2133
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2114
2134
 
2115
2135
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2136
                                                   internal_innobase_data_file_path);
2117
2137
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2138
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2139
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2140
mem_free_and_error:
2121
2141
    srv_free_paths_and_sizes();
2122
2142
    if (internal_innobase_data_file_path)
2130
2150
 
2131
2151
  if (vm.count("log-group-home-dir"))
2132
2152
  {
2133
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2153
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
2134
2154
  }
2135
2155
  else
2136
2156
  {
2137
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2157
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
2138
2158
  }
2139
2159
 
 
2160
#ifdef UNIV_LOG_ARCHIVE
 
2161
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2162
    starting from 4.0.6 we always set it the same as
 
2163
innodb_log_group_home_dir: */
 
2164
 
 
2165
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2166
 
 
2167
  srv_arch_dir = innobase_log_arch_dir;
 
2168
#endif /* UNIG_LOG_ARCHIVE */
 
2169
 
2140
2170
  ret = (bool)
2141
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2171
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2142
2172
 
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"));
 
2173
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2174
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2175
                  "wrong number of mirrored log groups");
2146
2176
 
2147
2177
    goto mem_free_and_error;
2148
2178
  }
2156
2186
 
2157
2187
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2188
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2189
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2190
 
2161
2191
      goto mem_free_and_error;
2162
2192
    }
2167
2197
 
2168
2198
  srv_file_format = format_id;
2169
2199
 
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;
 
2200
  /* Given the type of innobase_file_format_name we have little
 
2201
    choice but to cast away the constness from the returned name.
 
2202
    innobase_file_format_name is used in the MySQL set variable
 
2203
    interface and so can't be const. */
 
2204
 
 
2205
  innobase_file_format_name = 
 
2206
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2207
 
 
2208
  /* Process innobase_file_format_check variable */
 
2209
  ut_a(innobase_file_format_check != NULL);
 
2210
 
 
2211
  /* As a side effect it will set srv_check_file_format_at_startup
 
2212
    on valid input. First we check for "on"/"off". */
 
2213
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2214
 
 
2215
    /* Did the user specify a format name that we support ?
 
2216
      As a side effect it will update the variable
 
2217
      srv_check_file_format_at_startup */
 
2218
    if (innobase_file_format_validate_and_set(
 
2219
                                innobase_file_format_check) < 0) {
 
2220
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2221
                    "innodb_file_format_check value: "
 
2222
                    "should be either 'on' or 'off' or "
 
2223
                    "any value up to %s or its "
 
2224
                    "equivalent numeric id",
 
2225
                    trx_sys_file_format_id_to_name(
 
2226
                                                   DICT_TF_FORMAT_MAX));
 
2227
 
 
2228
      goto mem_free_and_error;
 
2229
    }
2192
2230
  }
2193
2231
 
2194
2232
  if (vm.count("change-buffering"))
2199
2237
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2200
2238
         use++) {
2201
2239
      if (!innobase_strcasecmp(
2202
 
                               innobase_change_buffering.c_str(),
 
2240
                               vm["change-buffering"].as<string>().c_str(),
2203
2241
                               innobase_change_buffering_values[use])) {
2204
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2242
        ibuf_use = (ibuf_use_t) use;
2205
2243
        goto innobase_change_buffering_inited_ok;
2206
2244
      }
2207
2245
    }
2208
2246
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2247
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2248
                  "InnoDB: invalid value "
 
2249
                  "innodb_file_format_check=%s",
2210
2250
                  vm["change-buffering"].as<string>().c_str());
2211
2251
    goto mem_free_and_error;
2212
2252
  }
2213
2253
 
2214
2254
innobase_change_buffering_inited_ok:
2215
2255
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2216
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2256
  innobase_change_buffering = (char*)
 
2257
    innobase_change_buffering_values[ibuf_use];
2217
2258
 
2218
2259
  /* --------------------------------------------------*/
2219
2260
 
2220
 
  if (vm.count("flush-method") != 0)
2221
 
  {
2222
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2223
 
  }
 
2261
  srv_file_flush_method_str = innobase_file_flush_method;
2224
2262
 
2225
2263
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2226
2264
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2227
2265
  srv_log_file_size = (ulint) innobase_log_file_size;
2228
2266
 
 
2267
#ifdef UNIV_LOG_ARCHIVE
 
2268
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2269
#endif /* UNIV_LOG_ARCHIVE */
2229
2270
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2230
2271
 
2231
2272
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2232
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2233
2273
 
2234
2274
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2235
2275
 
2260
2300
 
2261
2301
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2262
2302
 
 
2303
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct,
 
2304
                                                     FALSE);
 
2305
 
 
2306
  innobase_commit_concurrency_init_default();
 
2307
 
2263
2308
  /* Since we in this module access directly the fields of a trx
2264
2309
    struct, and due to different headers and flags it might happen that
2265
2310
    mutex_t has a different size in this module and in InnoDB
2268
2313
 
2269
2314
  err = innobase_start_or_create_for_mysql();
2270
2315
 
2271
 
  if (err != DB_SUCCESS)
2272
 
  {
2273
 
    goto mem_free_and_error;
2274
 
  }
2275
 
 
2276
 
  err = dict_create_sys_replication_log();
2277
 
 
2278
2316
  if (err != DB_SUCCESS) {
2279
2317
    goto mem_free_and_error;
2280
2318
  }
2281
2319
 
2282
 
 
2283
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2284
 
                                                     TRUE);
2285
 
 
2286
2320
  innobase_open_tables = hash_create(200);
 
2321
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2322
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2323
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2324
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2325
  pthread_cond_init(&commit_cond, NULL);
2287
2326
  innodb_inited= 1;
2288
2327
 
2289
2328
  actuall_engine_ptr->dropTemporarySchema();
2290
2329
 
2291
 
  context.add(new InnodbStatusTool);
 
2330
  status_table_function_ptr= new InnodbStatusTool;
2292
2331
 
2293
2332
  context.add(innodb_engine_ptr);
2294
2333
 
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());
 
2334
  context.add(status_table_function_ptr);
 
2335
 
 
2336
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2337
  context.add(cmp_tool);
 
2338
 
 
2339
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2340
  context.add(cmp_reset_tool);
 
2341
 
 
2342
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2343
  context.add(cmp_mem_tool);
 
2344
 
 
2345
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2346
  context.add(cmp_mem_reset_tool);
 
2347
 
 
2348
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2349
  context.add(innodb_trx_tool);
 
2350
 
 
2351
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2352
  context.add(innodb_locks_tool);
 
2353
 
 
2354
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2355
  context.add(innodb_lock_waits_tool);
2322
2356
 
2323
2357
  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));
 
2358
 
2414
2359
  /* 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);
 
2360
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2417
2361
 
2418
2362
  return(FALSE);
2419
 
 
2420
2363
error:
2421
2364
  return(TRUE);
2422
2365
}
2513
2456
    trx_search_latch_release_if_reserved(trx);
2514
2457
  }
2515
2458
 
2516
 
  if (all)
2517
 
  {
 
2459
  if (all
 
2460
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2461
 
2518
2462
    /* We were instructed to commit the whole transaction, or
2519
2463
    this is an SQL statement end and autocommit is on */
2520
2464
 
2521
2465
    /* We need current binlog position for ibbackup to work.
2522
2466
    Note, the position is current because of
2523
2467
    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
 
 
 
2468
retry:
 
2469
    if (innobase_commit_concurrency > 0) {
 
2470
      pthread_mutex_lock(&commit_cond_m);
 
2471
      commit_threads++;
 
2472
 
 
2473
      if (commit_threads > innobase_commit_concurrency) {
2535
2474
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2475
        pthread_cond_wait(&commit_cond,
 
2476
          &commit_cond_m);
 
2477
        pthread_mutex_unlock(&commit_cond_m);
 
2478
        goto retry;
 
2479
      }
 
2480
      else {
 
2481
        pthread_mutex_unlock(&commit_cond_m);
 
2482
      }
2538
2483
    }
2539
2484
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2485
                /* Store transaction point for binlog
 
2486
    Later logic tests that this is set to _something_. We need
 
2487
    that logic to fire, even though we do not have a real name. */
 
2488
    trx->mysql_log_file_name = "UNUSED";
2541
2489
    trx->mysql_log_offset = 0;
2542
2490
 
2543
2491
    /* Don't do write + flush right now. For group commit
2547
2495
    innobase_commit_low(trx);
2548
2496
    trx->flush_log_later = FALSE;
2549
2497
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2498
    if (innobase_commit_concurrency > 0) {
 
2499
      pthread_mutex_lock(&commit_cond_m);
2553
2500
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2501
      pthread_cond_signal(&commit_cond);
 
2502
      pthread_mutex_unlock(&commit_cond_m);
2555
2503
    }
2556
2504
 
2557
2505
    /* Now do a write + flush of logs. */
2636
2584
 
2637
2585
  row_unlock_table_autoinc_for_mysql(trx);
2638
2586
 
2639
 
  if (all)
2640
 
  {
 
2587
  if (all
 
2588
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2589
 
2641
2590
    error = trx_rollback_for_mysql(trx);
2642
2591
  } else {
2643
2592
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2793
2742
  /* Warn if rolling back some things... */
2794
2743
  if (session->getKilled() != Session::NOT_KILLED &&
2795
2744
      trx->conc_state != TRX_NOT_STARTED &&
2796
 
      trx->undo_no > 0 &&
 
2745
      trx->undo_no.low > 0 &&
2797
2746
      global_system_variables.log_warnings)
2798
2747
  {
2799
 
      errmsg_printf(error::WARN,
 
2748
      errmsg_printf(ERRMSG_LVL_WARN, 
2800
2749
      "Drizzle is closing a connection during a KILL operation\n"
2801
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2750
      "that has an active InnoDB transaction.  %lu row modifications will "
2802
2751
      "roll back.\n",
2803
 
      (ullint) trx->undo_no);
 
2752
      (ulong) trx->undo_no.low);
2804
2753
  }
2805
2754
 
2806
2755
  innobase_rollback_trx(trx);
2876
2825
  return(true);
2877
2826
}
2878
2827
 
 
2828
/*****************************************************************//**
 
2829
Normalizes a table name string. A normalized name consists of the
 
2830
database name catenated to '/' and table name. An example:
 
2831
test/mytable. On Windows normalization puts both the database name and the
 
2832
table name always to lower case. */
 
2833
static
 
2834
void
 
2835
normalize_table_name(
 
2836
/*=================*/
 
2837
  char*   norm_name,  /*!< out: normalized name as a
 
2838
          null-terminated string */
 
2839
  const char* name)   /*!< in: table name string */
 
2840
{
 
2841
  const char* name_ptr;
 
2842
  const char* db_ptr;
 
2843
  const char* ptr;
 
2844
 
 
2845
  /* Scan name from the end */
 
2846
 
 
2847
  ptr = strchr(name, '\0')-1;
 
2848
 
 
2849
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2850
    ptr--;
 
2851
  }
 
2852
 
 
2853
  name_ptr = ptr + 1;
 
2854
 
 
2855
  assert(ptr > name);
 
2856
 
 
2857
  ptr--;
 
2858
 
 
2859
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2860
    ptr--;
 
2861
  }
 
2862
 
 
2863
  db_ptr = ptr + 1;
 
2864
 
 
2865
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2866
 
 
2867
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2868
 
 
2869
#ifdef __WIN__
 
2870
  innobase_casedn_str(norm_name);
 
2871
#endif
 
2872
}
 
2873
 
2879
2874
/********************************************************************//**
2880
2875
Get the upper limit of the MySQL integral and floating-point type.
2881
2876
@return maximum allowed value for the field */
3009
3004
        dict_index_t**  index_mapping;
3010
3005
        ibool           ret = TRUE;
3011
3006
 
3012
 
        mutex_enter(&dict_sys->mutex);
3013
 
 
3014
3007
        mysql_num_index = table->getShare()->keys;
3015
3008
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3016
3009
 
3040
3033
                                                         sizeof(*index_mapping));
3041
3034
 
3042
3035
                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
3036
                        ret = FALSE;
3050
3037
                        goto func_exit;
3051
3038
                }
3053
3040
                share->idx_trans_tbl.array_size = mysql_num_index;
3054
3041
        }
3055
3042
 
 
3043
 
3056
3044
        /* For each index in the mysql key_info array, fetch its
3057
3045
        corresponding InnoDB index pointer into index_mapping
3058
3046
        array. */
3064
3052
                        ib_table, table->key_info[count].name);
3065
3053
 
3066
3054
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
 
3055
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
 
3056
                                        "index dictionary.",
 
3057
                                        table->key_info[count].name);
3069
3058
                        ret = FALSE;
3070
3059
                        goto func_exit;
3071
3060
                }
3072
3061
 
3073
3062
                /* Double check fetched index has the same
3074
3063
                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;
 
3064
                if (!innobase_match_index_columns(&table->key_info[count],
 
3065
                                                  index_mapping[count])) {
 
3066
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
 
3067
                                        "does not match that of MySQL.",
 
3068
                                        table->key_info[count].name);
 
3069
                        ret = FALSE;
 
3070
                        goto func_exit;
3080
3071
                }
3081
3072
        }
3082
3073
 
3095
3086
 
3096
3087
        share->idx_trans_tbl.index_mapping = index_mapping;
3097
3088
 
3098
 
        mutex_exit(&dict_sys->mutex);
3099
 
 
3100
3089
        return(ret);
3101
3090
}
3102
3091
 
3146
3135
    auto_inc = 0;
3147
3136
 
3148
3137
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
 
3138
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
 
3139
            "column name\n");
3150
3140
  }
3151
3141
 
3152
3142
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3182
3172
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3183
3173
 
3184
3174
    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
 
 
 
3175
    case DB_SUCCESS:
3190
3176
      /* 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
 
 
 
3177
         or the offset, so use a default increment of 1. */
 
3178
      auto_inc = read_auto_inc + 1;
3195
3179
      break;
3196
 
    }
 
3180
 
3197
3181
    case DB_RECORD_NOT_FOUND:
3198
3182
      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);
 
3183
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
3184
              "dictionaries are out of sync.\n"
 
3185
              "InnoDB: Unable to find the AUTOINC column "
 
3186
              "%s in the InnoDB table %s.\n"
 
3187
              "InnoDB: We set the next AUTOINC column "
 
3188
              "value to 0,\n"
 
3189
              "InnoDB: in effect disabling the AUTOINC "
 
3190
              "next value generation.\n"
 
3191
              "InnoDB: You can either set the next "
 
3192
              "AUTOINC value explicitly using ALTER TABLE\n"
 
3193
              "InnoDB: or fix the data dictionary by "
 
3194
              "recreating the table.\n",
 
3195
              col_name, index->table->name);
3206
3196
 
3207
3197
      /* This will disable the AUTOINC generation. */
3208
3198
      auto_inc = 0;
3228
3218
@return 1 if error, 0 if success */
3229
3219
UNIV_INTERN
3230
3220
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
3221
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
3222
                    int   mode,   /*!< in: not used */
3233
3223
                    uint    test_if_locked) /*!< in: not used */
3234
3224
{
3235
3225
  dict_table_t* ib_table;
 
3226
  char    norm_name[FN_REFLEN];
3236
3227
  Session*    session;
3237
3228
 
3238
3229
  UT_NOT_USED(mode);
3247
3238
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3239
  }
3249
3240
 
 
3241
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3242
 
3250
3243
  user_session = NULL;
3251
3244
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3245
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3246
 
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
 
    }
 
3247
    return(1);
3270
3248
  }
3271
3249
 
3272
3250
  /* Create buffers for packing the fields of a record. Why
3275
3253
  stored the string length as the first byte. */
3276
3254
 
3277
3255
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
 
3256
        getTable()->getShare()->stored_rec_length
3279
3257
        + getTable()->getShare()->max_key_length
3280
3258
        + MAX_REF_PARTS * 3;
3281
3259
 
3293
3271
  }
3294
3272
 
3295
3273
  /* 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
 
  }
 
3274
  ib_table = dict_table_get(norm_name, TRUE);
3306
3275
  
3307
3276
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3277
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3278
        "the internal data dictionary of InnoDB "
3310
3279
        "though the .frm file for the\n"
3311
3280
        "table exists. Maybe you have deleted and "
3319
3288
        "doesn't support.\n"
3320
3289
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3290
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3291
        norm_name);
3323
3292
    free_share(share);
3324
3293
    upd_buff.resize(0);
3325
3294
    key_val_buff.resize(0);
3328
3297
    return(HA_ERR_NO_SUCH_TABLE);
3329
3298
  }
3330
3299
 
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 "
 
3300
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
3301
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3302
        "the .ibd file for\ntable %s does not exist.\n"
3334
3303
        "Have you deleted the .ibd file from the "
3335
3304
        "database directory under\nthe MySQL datadir, "
3336
3305
        "or have you used DISCARD TABLESPACE?\n"
3337
3306
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3307
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3308
        norm_name);
3340
3309
    free_share(share);
3341
3310
    upd_buff.resize(0);
3342
3311
    key_val_buff.resize(0);
3348
3317
 
3349
3318
  prebuilt = row_create_prebuilt(ib_table);
3350
3319
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
 
3320
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3352
3321
  prebuilt->default_rec = getTable()->getDefaultValues();
3353
3322
  ut_ad(prebuilt->default_rec);
3354
3323
 
3358
3327
  key_used_on_scan = primary_key;
3359
3328
 
3360
3329
  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());
 
3330
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
 
3331
                    " Table %s failed", identifier.getPath().c_str());
3363
3332
  }
3364
3333
 
3365
3334
  /* Allocate a buffer for a 'row reference'. A row reference is
3373
3342
    prebuilt->clust_index_was_generated = FALSE;
3374
3343
 
3375
3344
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
 
3345
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3377
3346
                    "InnoDB data dictionary, but not "
3378
3347
                    "in MySQL!", identifier.getTableName().c_str());
3379
3348
 
3428
3397
    }
3429
3398
  } else {
3430
3399
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
 
3400
      errmsg_printf(ERRMSG_LVL_ERROR,
3432
3401
                    "Table %s has no primary key in InnoDB data "
3433
3402
                    "dictionary, but has one in MySQL! If you "
3434
3403
                    "created the table with a MySQL version < "
3464
3433
    and it will never be updated anyway. */
3465
3434
 
3466
3435
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3436
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3437
        "Table %s key_used_on_scan is %lu even "
3469
3438
        "though there is no primary key inside "
3470
3439
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3481
3450
    /* We update the highest file format in the system table
3482
3451
    space, if this table has higher file format setting. */
3483
3452
 
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,
 
3453
    trx_sys_file_format_max_upgrade(
 
3454
      (const char**) &innobase_file_format_check,
3487
3455
      dict_table_get_format(prebuilt->table));
3488
 
    innobase_file_format_max= changed_file_format_max;
3489
3456
  }
3490
3457
 
 
3458
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3459
 
3491
3460
  /* Only if the table has an AUTOINC column. */
3492
3461
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
3493
3462
 
3505
3474
    dict_table_autoinc_unlock(prebuilt->table);
3506
3475
  }
3507
3476
 
3508
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3509
 
 
3510
3477
  return(0);
3511
3478
}
3512
3479
 
3616
3583
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3584
function, remember to update the prototype there!
3618
3585
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3586
extern "C" UNIV_INTERN
 
3587
int
3620
3588
innobase_mysql_cmp(
3621
3589
/*===============*/
3622
3590
  int   mysql_type, /*!< in: MySQL type */
3663
3631
      charset = get_charset(charset_number);
3664
3632
 
3665
3633
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3634
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3635
                      "a comparison, but MySQL cannot "
3668
3636
                      "find that charset.",
3669
3637
                      (ulong) charset_number);
3698
3666
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3667
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3668
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3669
extern "C" UNIV_INTERN
3702
3670
ulint
3703
3671
get_innobase_type_from_mysql_type(
3704
3672
/*==============================*/
3747
3715
      return(DATA_VARMYSQL);
3748
3716
    }
3749
3717
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3718
    return(DATA_FIXBINARY);
3752
3719
  case DRIZZLE_TYPE_LONG:
3753
3720
  case DRIZZLE_TYPE_LONGLONG:
3754
3721
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3722
  case DRIZZLE_TYPE_DATE:
3757
3723
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3724
    return(DATA_INT);
3760
3725
  case DRIZZLE_TYPE_DOUBLE:
3761
3726
    return(DATA_DOUBLE);
3762
3727
  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:
 
3728
                return(DATA_BLOB);
 
3729
  default:
3768
3730
    ut_error;
3769
3731
  }
3770
3732
 
4004
3966
      ulint     key_len;
4005
3967
      const unsigned char*    src_start;
4006
3968
      enum_field_types  real_type;
4007
 
      const CHARSET_INFO* cs= field->charset();
4008
3969
 
4009
3970
      key_len = key_part->length;
4010
3971
 
4026
3987
      memcpy(buff, src_start, true_len);
4027
3988
      buff += true_len;
4028
3989
 
4029
 
      /* Pad the unused space with spaces. */
 
3990
      /* Pad the unused space with spaces. Note that no
 
3991
      padding is ever needed for UCS-2 because in MySQL,
 
3992
      all UCS2 characters are 2 bytes, as MySQL does not
 
3993
      support surrogate pairs, which are needed to represent
 
3994
      characters in the range U+10000 to U+10FFFF. */
4030
3995
 
4031
3996
      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 */);
 
3997
        ulint pad_len = key_len - true_len;
 
3998
        memset(buff, ' ', pad_len);
4037
3999
        buff += pad_len;
4038
4000
      }
4039
4001
    }
4141
4103
 
4142
4104
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4143
4105
  'fields'. */
4144
 
  for (i = 0; i < n_fields; i++)
 
4106
  for (i = 0; i < n_fields; i++) 
4145
4107
  {
4146
 
    const dict_col_t *col= &index->table->cols[i];
4147
4108
    templ = prebuilt->mysql_template + n_requested_fields;
4148
4109
    field = table->getField(i);
4149
4110
 
4189
4150
    n_requested_fields++;
4190
4151
 
4191
4152
    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
4153
 
4195
4154
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4155
      templ->rec_field_no = dict_col_get_clust_pos(
 
4156
        &index->table->cols[i], index);
4197
4157
    } else {
4198
4158
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
4159
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
4160
    }
 
4161
 
 
4162
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4163
      prebuilt->need_to_access_clustered = TRUE;
4203
4164
    }
4204
4165
 
4205
4166
    if (field->null_ptr) {
4221
4182
      mysql_prefix_len = templ->mysql_col_offset
4222
4183
        + templ->mysql_col_len;
4223
4184
    }
4224
 
    templ->type = col->mtype;
 
4185
    templ->type = index->table->cols[i].mtype;
4225
4186
    templ->mysql_type = (ulint)field->type();
4226
4187
 
4227
4188
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4229
4190
        (((Field_varstring*)field)->pack_length_no_ptr());
4230
4191
    }
4231
4192
 
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;
 
4193
    templ->charset = dtype_get_charset_coll(
 
4194
      index->table->cols[i].prtype);
 
4195
    templ->mbminlen = index->table->cols[i].mbminlen;
 
4196
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
4197
    templ->is_unsigned = index->table->cols[i].prtype
 
4198
              & DATA_UNSIGNED;
4236
4199
    if (templ->type == DATA_BLOB) {
4237
4200
      prebuilt->templ_contains_blob = TRUE;
4238
4201
    }
4249
4212
    for (i = 0; i < n_requested_fields; i++) {
4250
4213
      templ = prebuilt->mysql_template + i;
4251
4214
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4215
      templ->rec_field_no = dict_col_get_clust_pos(
 
4216
        &index->table->cols[templ->col_no],
 
4217
        clust_index);
4253
4218
    }
4254
4219
  }
4255
4220
}
4323
4288
  trx_t*    trx = session_to_trx(user_session);
4324
4289
 
4325
4290
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4291
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4292
        "%p, but for the current thread it is at %p",
4328
4293
        (const void*) prebuilt->trx, (const void*) trx);
4329
4294
 
4337
4302
    ut_error;
4338
4303
  }
4339
4304
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4305
  sql_command = session_sql_command(user_session);
4341
4306
 
4342
4307
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4308
       || sql_command == SQLCOM_CREATE_INDEX
4448
4413
 
4449
4414
  error = row_insert_for_mysql((byte*) record, prebuilt);
4450
4415
 
4451
 
  user_session->setXaId(trx->id);
 
4416
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4452
4417
 
4453
4418
  /* Handle duplicate key errors */
4454
4419
  if (auto_inc_used) {
4771
4736
 
4772
4737
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4773
4738
 
4774
 
  user_session->setXaId(trx->id);
 
4739
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4775
4740
 
4776
4741
  /* We need to do some special AUTOINC handling for the following case:
4777
4742
 
4784
4749
  if (error == DB_SUCCESS
4785
4750
      && getTable()->next_number_field
4786
4751
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4752
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4753
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4754
    == TRX_DUP_IGNORE)  {
4790
4755
 
4863
4828
 
4864
4829
  error = row_update_for_mysql((byte*) record, prebuilt);
4865
4830
 
4866
 
  user_session->setXaId(trx->id);
 
4831
  user_session->setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
4867
4832
 
4868
4833
  innodb_srv_conc_exit_innodb(trx);
4869
4834
 
5123
5088
    return(HA_ERR_CRASHED);
5124
5089
  }
5125
5090
 
5126
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5127
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5128
 
  }
5129
5091
 
5130
5092
  /* Note that if the index for which the search template is built is not
5131
5093
  necessarily prebuilt->index, but can also be the clustered index */
5251
5213
         table. Only print message if the index translation
5252
5214
         table exists */
5253
5215
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
 
5216
        errmsg_printf(ERRMSG_LVL_ERROR,
5255
5217
                      "InnoDB could not find "
5256
5218
                      "index %s key no %u for "
5257
5219
                      "table %s through its "
5269
5231
  }
5270
5232
 
5271
5233
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
5234
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
5235
      "Innodb could not find key n:o %u with name %s "
5274
5236
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
5237
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
5238
      prebuilt->table->name);
5277
5239
  }
5278
5240
 
5298
5260
  prebuilt->index = innobase_get_index(keynr);
5299
5261
 
5300
5262
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
5263
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
5264
          keynr);
5303
5265
    prebuilt->index_usable = FALSE;
5304
5266
    return(1);
5664
5626
  table. */
5665
5627
 
5666
5628
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5629
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5630
        (ulong) len, (ulong) ref_length);
5669
5631
  }
5670
5632
}
5720
5682
 
5721
5683
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5722
5684
                  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
5685
    if (field->null_ptr) {
5739
5686
      nulls_allowed = 0;
5740
5687
    } else {
5757
5704
        /* in data0type.h we assume that the
5758
5705
        number fits in one byte in prtype */
5759
5706
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5707
          (Session*) trx->mysql_thd,
5761
5708
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5709
          ER_CANT_CREATE_TABLE,
5763
5710
          "In InnoDB, charset-collation codes"
5792
5739
    if (dict_col_name_is_reserved(field->field_name)){
5793
5740
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5794
5741
 
5795
 
  err_col:
5796
5742
      dict_mem_table_free(table);
5797
5743
      trx_commit_for_mysql(trx);
5798
5744
 
5923
5869
        || col_type == DATA_FLOAT
5924
5870
        || col_type == DATA_DOUBLE
5925
5871
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
5872
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
5873
          "MySQL is trying to create a column "
5928
5874
          "prefix index field, on an "
5929
5875
          "inappropriate data type. Table "
6023
5969
/*================*/
6024
5970
  Session         &session, /*!< in: Session */
6025
5971
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
5972
        const TableIdentifier &identifier,
6027
5973
        message::Table& create_proto)
6028
5974
{
6029
5975
  int   error;
6032
5978
  trx_t*    trx;
6033
5979
  int   primary_key_no;
6034
5980
  uint    i;
 
5981
  char    name2[FN_REFLEN];
 
5982
  char    norm_name[FN_REFLEN];
6035
5983
  ib_int64_t  auto_inc_value;
6036
5984
  ulint   iflags;
6037
5985
  /* Cache the value of innodb_file_format, in case it is
6041
5989
  const char* stmt;
6042
5990
  size_t stmt_len;
6043
5991
 
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
 
  }
 
5992
  const char *table_name= identifier.getPath().c_str();
6051
5993
 
6052
5994
  if (form.getShare()->sizeFields() > 1000) {
6053
5995
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
6012
 
6071
6013
  srv_lower_case_table_names = TRUE;
6072
6014
 
 
6015
  strcpy(name2, table_name);
 
6016
 
 
6017
  normalize_table_name(norm_name, name2);
 
6018
 
6073
6019
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
6020
    or lock waits can happen in it during a table create operation.
6075
6021
    Drop table etc. do this latching in row0mysql.c. */
6134
6080
# error "DICT_TF_ZSSIZE_MAX < 1"
6135
6081
#endif
6136
6082
 
6137
 
    if (strict_mode)
 
6083
    if (SessionVAR(&session, strict_mode))
6138
6084
    {
6139
6085
      if (! srv_file_per_table)
6140
6086
      {
6177
6123
  if (lex_identified_temp_table)
6178
6124
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
6125
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
6126
  error= create_table_def(trx, &form, norm_name,
 
6127
                          lex_identified_temp_table ? name2 : NULL,
6182
6128
                          iflags);
6183
6129
 
6184
 
  session.setXaId(trx->id);
 
6130
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6185
6131
 
6186
6132
  if (error) {
6187
6133
    goto cleanup;
6194
6140
      order the rows by their row id which is internally generated
6195
6141
      by InnoDB */
6196
6142
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
6143
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
6144
    if (error) {
6199
6145
      goto cleanup;
6200
6146
    }
6202
6148
 
6203
6149
  if (primary_key_no != -1) {
6204
6150
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6151
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
6152
                              (uint) primary_key_no))) {
6207
6153
      goto cleanup;
6208
6154
    }
6211
6157
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
6158
    if (i != (uint) primary_key_no) {
6213
6159
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6160
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
6161
                                i))) {
6216
6162
        goto cleanup;
6217
6163
      }
6218
6164
    }
6219
6165
  }
6220
6166
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
 
6167
  stmt = innobase_get_stmt(&session, &stmt_len);
6222
6168
 
6223
6169
  if (stmt) {
6224
6170
    string generated_create_table;
6225
6171
    const char *query= stmt;
6226
6172
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
6173
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
6174
    {
6229
6175
      message::transformTableDefinitionToSql(create_proto,
6230
6176
                                             generated_create_table,
6234
6180
 
6235
6181
    error = row_table_add_foreign_constraints(trx,
6236
6182
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
6183
                                              norm_name,
6238
6184
                                              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
6185
 
6262
6186
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
6187
 
6276
6200
 
6277
6201
  log_buffer_flush_to_disk();
6278
6202
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
6203
  innobase_table = dict_table_get(norm_name, FALSE);
6280
6204
 
6281
6205
  assert(innobase_table != 0);
6282
6206
 
6284
6208
    /* We update the highest file format in the system table
6285
6209
      space, if this table has higher file format setting. */
6286
6210
 
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;
 
6211
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
6212
                                    dict_table_get_format(innobase_table));
6292
6213
  }
6293
6214
 
6294
6215
  /* Note: We can't call update_session() as prebuilt will not be
6299
6220
    does a table copy too. */
6300
6221
 
6301
6222
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
6223
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
6224
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
6225
      && create_proto.options().auto_increment_value() != 0) {
6305
6226
 
6306
6227
    /* Query was one of :
6393
6314
 
6394
6315
  update_session(getTable()->in_use);
6395
6316
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
6317
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
6318
  fallback:
6398
6319
    /* We only handle TRUNCATE TABLE t as a special case.
6399
6320
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6348
InnobaseEngine::doDropTable(
6428
6349
/*======================*/
6429
6350
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6351
        const TableIdentifier &identifier)
6431
6352
{
6432
6353
  int error;
6433
6354
  trx_t*  parent_trx;
6434
6355
  trx_t*  trx;
 
6356
  char  norm_name[1000];
6435
6357
 
6436
6358
  ut_a(identifier.getPath().length() < 1000);
6437
6359
 
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
 
  }
 
6360
  /* Strangely, MySQL passes the table name without the '.frm'
 
6361
    extension, in contrast to ::create */
 
6362
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6363
 
6446
6364
  /* Get the transaction associated with the current session, or create one
6447
6365
    if not yet created */
6459
6377
 
6460
6378
  /* Drop the table in InnoDB */
6461
6379
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6380
  error = row_drop_table_for_mysql(norm_name, trx,
 
6381
                                   session_sql_command(&session)
6464
6382
                                   == SQLCOM_DROP_DB);
6465
6383
 
6466
 
  session.setXaId(trx->id);
 
6384
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6467
6385
 
6468
6386
  /* Flush the log to reduce probability that the .frm files and
6469
6387
    the InnoDB data dictionary get out-of-sync if the user runs
6488
6406
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6407
    {
6490
6408
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6409
      ulint sql_command = session_sql_command(&session);
6492
6410
 
6493
6411
      // If this was the final removal to an alter table then we will need
6494
6412
      // to remove the .dfe that was left behind.
6521
6439
bool
6522
6440
InnobaseEngine::doDropSchema(
6523
6441
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6442
                             const SchemaIdentifier &identifier)
6525
6443
    /*!< in: database path; inside InnoDB the name
6526
6444
      of the last directory in the path is used as
6527
6445
      the database name: for example, in 'mysql/data/test'
6571
6489
 
6572
6490
void InnobaseEngine::dropTemporarySchema()
6573
6491
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6492
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6493
  trx_t*  trx= NULL;
6576
6494
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6495
 
6608
6526
innobase_rename_table(
6609
6527
/*==================*/
6610
6528
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6529
  const char* from, /*!< in: old name of the table */
 
6530
  const char* to, /*!< in: new name of the table */
6613
6531
  ibool   lock_and_commit)
6614
6532
        /*!< in: TRUE=lock data dictionary and commit */
6615
6533
{
6616
6534
  int error;
 
6535
  char norm_to[FN_REFLEN];
 
6536
  char norm_from[FN_REFLEN];
6617
6537
 
6618
6538
  srv_lower_case_table_names = TRUE;
6619
6539
 
 
6540
  normalize_table_name(norm_to, to);
 
6541
  normalize_table_name(norm_from, from);
 
6542
 
6620
6543
  /* Serialize data dictionary operations with dictionary mutex:
6621
6544
  no deadlocks can occur then in these operations */
6622
6545
 
6624
6547
    row_mysql_lock_data_dictionary(trx);
6625
6548
  }
6626
6549
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6550
  error = row_rename_table_for_mysql(
 
6551
    norm_from, norm_to, trx, lock_and_commit);
6628
6552
 
6629
6553
  if (error != DB_SUCCESS) {
6630
6554
    FILE* ef = dict_foreign_err_file;
6631
6555
 
6632
6556
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6557
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6558
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6559
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6560
    fputs(" failed!\n", ef);
6637
6561
  }
6638
6562
 
6651
6575
/*********************************************************************//**
6652
6576
Renames an InnoDB table.
6653
6577
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6578
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6579
{
6656
6580
  // A temp table alter table/rename is a shallow rename and only the
6657
6581
  // definition needs to be updated.
6677
6601
 
6678
6602
  trx = innobase_trx_allocate(&session);
6679
6603
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
 
6604
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6681
6605
 
6682
 
  session.setXaId(trx->id);
 
6606
  session.setXaId((ib_uint64_t) ut_conv_dulint_to_longlong(trx->id));
6683
6607
 
6684
6608
  /* Tell the InnoDB server that there might be work for
6685
6609
    utility threads: */
6702
6626
     is the one we are trying to rename to) and return the generic
6703
6627
     error code. */
6704
6628
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6629
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6630
    error = DB_ERROR;
6707
6631
  }
6708
6632
 
6733
6657
  KeyInfo*    key;
6734
6658
  dict_index_t* index;
6735
6659
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
 
6660
              getTable()->getShare()->stored_rec_length
6737
6661
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
 
6662
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6739
6663
          + getTable()->getShare()->max_key_length + 100;
6740
6664
  dtuple_t* range_start;
6741
6665
  dtuple_t* range_end;
6767
6691
    goto func_exit;
6768
6692
  }
6769
6693
 
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
6694
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6776
6695
            + sizeof(dtuple_t)));
6777
6696
 
6845
6764
  dict_index_t* index;
6846
6765
  uint64_t  estimate;
6847
6766
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6767
 
6850
6768
  /* We do not know if MySQL can call this function before calling
6851
6769
  external_lock(). To be safe, update the session of the current table
6863
6781
 
6864
6782
  index = dict_table_get_first_index(prebuilt->table);
6865
6783
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6784
  ut_a(index->stat_n_leaf_pages > 0);
6869
6785
 
6870
6786
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6787
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6788
 
6873
6789
 
6874
6790
  /* Calculate a minimum length for a clustered index record and from
6971
6887
 
6972
6888
        /* If index does not belong to the table of share structure. Search
6973
6889
        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) {
 
6890
        if (index->table != ib_table
 
6891
            && strcmp(index->table->name, share->table_name)) {
6994
6892
                i = 0;
6995
6893
                ind = dict_table_get_first_index(index->table);
6996
6894
 
7018
6916
 
7019
6917
                /* Print an error message if we cannot find the index
7020
6918
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
 
6919
                errmsg_printf(ERRMSG_LVL_ERROR,
7022
6920
                              "Cannot find index %s in InnoDB index "
7023
6921
                                "translation table.", index->name);
7024
6922
        }
7035
6933
                }
7036
6934
        }
7037
6935
 
7038
 
                errmsg_printf(error::ERROR,
 
6936
                errmsg_printf(ERRMSG_LVL_ERROR,
7039
6937
                              "Cannot find matching index number for index %s "
7040
6938
                              "in InnoDB index list.", index->name);
7041
6939
 
7054
6952
  dict_index_t* index;
7055
6953
  ha_rows   rec_per_key;
7056
6954
  ib_int64_t  n_rows;
 
6955
  ulong   j;
 
6956
  ulong   i;
7057
6957
  os_file_stat_t  stat_info;
7058
6958
 
7059
6959
  /* If we are forcing recovery at a high level, we will suppress
7060
6960
  statistics calculation on tables, because that may crash the
7061
6961
  server if an index is badly corrupted. */
7062
6962
 
 
6963
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6964
 
 
6965
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6966
    because we want MySQL to process this query and not
 
6967
    stop, like it would do if it received the error code
 
6968
    HA_ERR_CRASHED. */
 
6969
 
 
6970
    return(0);
 
6971
  }
 
6972
 
7063
6973
  /* We do not know if MySQL can call this function before calling
7064
6974
  external_lock(). To be safe, update the session of the current table
7065
6975
  handle. */
7081
6991
 
7082
6992
    prebuilt->trx->op_info = "updating table statistics";
7083
6993
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
 
6994
    dict_update_statistics(ib_table);
7088
6995
 
7089
6996
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
6997
 
7101
7008
  }
7102
7009
 
7103
7010
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
7011
    n_rows = ib_table->stat_n_rows;
7108
7012
 
7109
7013
    /* Because we do not protect stat_n_rows by any mutex in a
7131
7035
    n_rows can not be 0 unless the table is empty, set to 1
7132
7036
    instead. The original problem of bug#29507 is actually
7133
7037
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
7038
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
7039
 
7136
7040
      n_rows = 1;
7137
7041
 
7153
7057
        ib_table->stat_sum_of_other_index_sizes)
7154
7058
          * UNIV_PAGE_SIZE;
7155
7059
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
7060
    /* Since fsp_get_available_space_in_free_extents() is
7159
7061
    acquiring latches inside InnoDB, we do not call it if we
7160
7062
    are asked by MySQL to avoid locking. Another reason to
7161
7063
    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) {
 
7064
    See Bug#38185.
 
7065
    We do not update delete_length if no locking is requested
 
7066
    so the "old" value can remain. delete_length is initialized
 
7067
    to 0 in the ha_statistics' constructor. */
 
7068
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
7069
 
 
7070
      /* lock the data dictionary to avoid races with
 
7071
      ibd_file_missing and tablespace_discarded */
 
7072
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
7073
 
 
7074
      /* ib_table->space must be an existent tablespace */
 
7075
      if (!ib_table->ibd_file_missing
 
7076
          && !ib_table->tablespace_discarded) {
 
7077
 
 
7078
        stats.delete_length =
 
7079
          fsp_get_available_space_in_free_extents(
 
7080
            ib_table->space) * 1024;
 
7081
      } else {
 
7082
 
7179
7083
        Session*  session;
7180
7084
 
7181
7085
        session= getTable()->in_use;
7193
7097
          ib_table->name);
7194
7098
 
7195
7099
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
7100
      }
 
7101
 
 
7102
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
7103
    }
7200
7104
 
7201
7105
    stats.check_time = 0;
7208
7112
  }
7209
7113
 
7210
7114
  if (flag & HA_STATUS_CONST) {
7211
 
    ulong i;
7212
7115
    /* Verify the number of index in InnoDB and MySQL
7213
7116
       matches up. If prebuilt->clust_index_was_generated
7214
7117
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7215
7118
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
7216
7119
 
7217
7120
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
 
7121
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7219
7122
                      "indexes inside InnoDB, which "
7220
7123
                      "is different from the number of "
7221
7124
                      "indexes %u defined in the MySQL ",
7223
7126
                      getTable()->getShare()->keys);
7224
7127
    }
7225
7128
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
7129
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
 
      ulong j;
7230
7130
      /* We could get index quickly through internal
7231
7131
         index mapping with the index translation table.
7232
7132
         The identity of index (match up index name with
7235
7135
      index = innobase_get_index(i);
7236
7136
 
7237
7137
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
7138
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
7139
            "indexes inside InnoDB than "
7240
7140
            "are defined in the MySQL "
7241
7141
            ".frm file. Have you mixed up "
7250
7150
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
7251
7151
 
7252
7152
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
7153
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
7154
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
7155
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
7156
"installations? "
7262
7162
          break;
7263
7163
        }
7264
7164
 
 
7165
        dict_index_stat_mutex_enter(index);
 
7166
 
7265
7167
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7266
7168
 
7267
7169
          rec_per_key = stats.records;
7270
7172
           index->stat_n_diff_key_vals[j + 1]);
7271
7173
        }
7272
7174
 
 
7175
        dict_index_stat_mutex_exit(index);
 
7176
 
7273
7177
        /* Since MySQL seems to favor table scans
7274
7178
        too much over index searches, we pretend
7275
7179
        index selectivity is 2 times better than
7286
7190
          (ulong) rec_per_key;
7287
7191
      }
7288
7192
    }
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
7193
  }
7296
7194
 
7297
7195
  if (flag & HA_STATUS_ERRKEY) {
7315
7213
    stats.auto_increment_value = innobase_peek_autoinc();
7316
7214
  }
7317
7215
 
7318
 
func_exit:
7319
7216
  prebuilt->trx->op_info = (char*)"";
7320
7217
 
7321
7218
  return(0);
7367
7264
  }
7368
7265
 
7369
7266
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
 
7267
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7371
7268
                    "InnoDB: MySQL is trying to use a table handle"
7372
7269
                    " but the .ibd file for\n"
7373
7270
                    "InnoDB: table %s does not exist.\n"
7617
7514
  flen = ftell(srv_dict_tmpfile);
7618
7515
  if (flen < 0) {
7619
7516
    flen = 0;
 
7517
  } else if (flen > 64000 - 1) {
 
7518
    flen = 64000 - 1;
7620
7519
  }
7621
7520
 
7622
7521
  /* allocate buffer for the string, and
7676
7575
      i++;
7677
7576
    }
7678
7577
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
7578
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
7579
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
7580
 
7682
7581
    /* Table name */
7683
7582
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7583
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
7584
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
7585
 
7687
7586
    /** Foreign Fields **/
7759
7658
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7659
 
7761
7660
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7661
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7662
    f_key_list->push_back(pf_key_info);
7764
7663
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7664
  }
8014
7913
{
8015
7914
  trx_t*      trx;
8016
7915
  static const char truncated_msg[] = "... truncated...\n";
8017
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7916
  const long    MAX_STATUS_SIZE = 64000;
8018
7917
  ulint     trx_list_start = ULINT_UNDEFINED;
8019
7918
  ulint     trx_list_end = ULINT_UNDEFINED;
8020
7919
 
8043
7942
 
8044
7943
  if (flen > MAX_STATUS_SIZE) {
8045
7944
    usable_len = MAX_STATUS_SIZE;
8046
 
    srv_truncated_status_writes++;
8047
7945
  } else {
8048
7946
    usable_len = flen;
8049
7947
  }
8079
7977
 
8080
7978
  mutex_exit(&srv_monitor_file_mutex);
8081
7979
 
8082
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8083
 
             STRING_WITH_LEN(""), str, flen);
 
7980
  bool result = FALSE;
8084
7981
 
 
7982
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7983
      STRING_WITH_LEN(""), str, flen)) {
 
7984
    result= TRUE;
 
7985
  }
8085
7986
  free(str);
8086
7987
 
8087
7988
  return(FALSE);
8289
8190
static INNOBASE_SHARE* get_share(const char* table_name)
8290
8191
{
8291
8192
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8193
  pthread_mutex_lock(&innobase_share_mutex);
8293
8194
 
8294
8195
  ulint fold = ut_fold_string(table_name);
8295
8196
 
8316
8217
  }
8317
8218
 
8318
8219
  share->use_count++;
 
8220
  pthread_mutex_unlock(&innobase_share_mutex);
8319
8221
 
8320
8222
  return(share);
8321
8223
}
8322
8224
 
8323
8225
static void free_share(INNOBASE_SHARE* share)
8324
8226
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8227
  pthread_mutex_lock(&innobase_share_mutex);
8326
8228
 
8327
8229
#ifdef UNIV_DEBUG
8328
8230
  INNOBASE_SHARE* share2;
8351
8253
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
8254
    shrinks too much */
8353
8255
  }
 
8256
 
 
8257
  pthread_mutex_unlock(&innobase_share_mutex);
8354
8258
}
8355
8259
 
8356
8260
/*****************************************************************//**
8385
8289
  trx = check_trx_exists(session);
8386
8290
 
8387
8291
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
8292
  const uint32_t sql_command = session_sql_command(session);
8389
8293
 
8390
8294
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
8295
 
8427
8331
        && (sql_command == SQLCOM_INSERT_SELECT
8428
8332
            || sql_command == SQLCOM_REPLACE_SELECT
8429
8333
            || sql_command == SQLCOM_UPDATE
8430
 
            || sql_command == SQLCOM_CREATE_TABLE
8431
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
8334
            || sql_command == SQLCOM_CREATE_TABLE)) {
8432
8335
 
8433
8336
      /* If we either have innobase_locks_unsafe_for_binlog
8434
8337
      option set or this session is using READ COMMITTED
8436
8339
      is not set to serializable and MySQL is doing
8437
8340
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8438
8341
      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. */
 
8342
      SELECT... without FOR UPDATE or IN SHARE
 
8343
      MODE in select, then we use consistent read
 
8344
      for select. */
8442
8345
 
8443
8346
      prebuilt->select_lock_type = LOCK_NONE;
8444
8347
      prebuilt->stored_select_lock_type = LOCK_NONE;
8471
8374
 
8472
8375
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
8376
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
8377
        && !session_tablespace_op(session)
8475
8378
        && sql_command != SQLCOM_TRUNCATE
8476
8379
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
8380
 
8526
8429
}
8527
8430
 
8528
8431
/*******************************************************************//**
8529
 
This function reads the global auto-inc counter. It doesn't use the
 
8432
This function reads the global auto-inc counter. It doesn't use the 
8530
8433
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8531
8434
@return the autoinc value */
8532
8435
UNIV_INTERN
8546
8449
 
8547
8450
  auto_inc = dict_table_autoinc_read(innodb_table);
8548
8451
 
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
 
  }
 
8452
  ut_a(auto_inc > 0);
8553
8453
 
8554
8454
  dict_table_autoinc_unlock(innodb_table);
8555
8455
 
8703
8603
/* See comment in Cursor.cc */
8704
8604
UNIV_INTERN
8705
8605
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
8606
InnobaseEngine::get_error_message(int, String *buf)
8707
8607
{
8708
8608
  trx_t*  trx = check_trx_exists(current_session);
8709
8609
 
8787
8687
finds charset information and returns length of prefix_len characters in the
8788
8688
index field in bytes.
8789
8689
@return number of bytes occupied by the first n characters */
 
8690
extern "C" UNIV_INTERN
 
8691
ulint
 
8692
innobase_get_at_most_n_mbchars(
 
8693
/*===========================*/
 
8694
  ulint charset_id, /*!< in: character set id */
 
8695
  ulint prefix_len, /*!< in: prefix length in bytes of the index
 
8696
        (this has to be divided by mbmaxlen to get the
 
8697
        number of CHARACTERS n in the prefix) */
 
8698
  ulint data_len,   /*!< in: length of the string in bytes */
 
8699
  const char* str); /*!< in: character string */
8790
8700
 
8791
8701
ulint
8792
8702
innobase_get_at_most_n_mbchars(
8870
8780
  trx->detailed_error[0]= '\0';
8871
8781
 
8872
8782
  /* Set the isolation level of the transaction. */
8873
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8783
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8874
8784
}
8875
8785
 
8876
8786
void
8913
8823
    return(0);
8914
8824
  }
8915
8825
 
8916
 
  session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->xid));
 
8826
  session->get_xid(reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
8917
8827
 
8918
8828
  /* Release a possible FIFO ticket and search latch. Since we will
8919
8829
  reserve the kernel mutex, we have to release the search system latch
8957
8867
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8958
8868
{
8959
8869
  trx_t *trx= session_to_trx(session);
8960
 
  return (trx->id);
 
8870
  return (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
8961
8871
}
8962
8872
 
8963
8873
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8975
8885
  trx->id= trx_sys_get_new_trx_id();
8976
8886
  mutex_exit(&kernel_mutex);
8977
8887
 
8978
 
  uint64_t transaction_id= trx->id;
 
8888
  uint64_t transaction_id= (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
8979
8889
 
8980
8890
  return transaction_id;
8981
8891
}
9091
9001
}
9092
9002
 
9093
9003
/************************************************************//**
 
9004
Validate the file format check value, is it one of "on" or "off",
 
9005
as a side effect it sets the srv_check_file_format_at_startup variable.
 
9006
@return true if config value one of "on" or  "off" */
 
9007
static
 
9008
bool
 
9009
innobase_file_format_check_on_off(
 
9010
/*==============================*/
 
9011
  const char* format_check) /*!< in: parameter value */
 
9012
{
 
9013
  bool    ret = true;
 
9014
 
 
9015
  if (!innobase_strcasecmp(format_check, "off")) {
 
9016
 
 
9017
    /* Set the value to disable checking. */
 
9018
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
9019
 
 
9020
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
9021
 
 
9022
    /* Set the value to the lowest supported format. */
 
9023
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
9024
  } else {
 
9025
    ret = FALSE;
 
9026
  }
 
9027
 
 
9028
  return(ret);
 
9029
}
 
9030
 
 
9031
/************************************************************//**
9094
9032
Validate the file format check config parameters, as a side effect it
9095
 
sets the srv_max_file_format_at_startup variable.
 
9033
sets the srv_check_file_format_at_startup variable.
9096
9034
@return the format_id if valid config value, otherwise, return -1 */
9097
9035
static
9098
9036
int
9099
9037
innobase_file_format_validate_and_set(
9100
9038
/*================================*/
9101
 
  const char* format_max) /*!< in: parameter value */
 
9039
  const char* format_check) /*!< in: parameter value */
9102
9040
{
9103
9041
  uint    format_id;
9104
9042
 
9105
 
  format_id = innobase_file_format_name_lookup(format_max);
 
9043
  format_id = innobase_file_format_name_lookup(format_check);
9106
9044
 
9107
9045
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9108
 
    srv_max_file_format_at_startup = format_id;
 
9046
    srv_check_file_format_at_startup = format_id;
9109
9047
    return((int) format_id);
9110
9048
  } else {
9111
9049
    return(-1);
9112
9050
  }
9113
9051
}
9114
9052
 
9115
 
 
 
9053
/*************************************************************//**
 
9054
Check if it is a valid file format. This function is registered as
 
9055
a callback with MySQL.
 
9056
@return 0 for valid file format */
 
9057
static
 
9058
int
 
9059
innodb_file_format_name_validate(
 
9060
/*=============================*/
 
9061
  Session*      , /*!< in: thread handle */
 
9062
  drizzle_sys_var*  , /*!< in: pointer to system
 
9063
            variable */
 
9064
  void*       save, /*!< out: immediate result
 
9065
            for update function */
 
9066
  drizzle_value*    value)  /*!< in: incoming string */
 
9067
{
 
9068
  const char* file_format_input;
 
9069
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9070
  int   len = sizeof(buff);
 
9071
 
 
9072
  ut_a(save != NULL);
 
9073
  ut_a(value != NULL);
 
9074
 
 
9075
  file_format_input = value->val_str(value, buff, &len);
 
9076
 
 
9077
  if (file_format_input != NULL) {
 
9078
    uint  format_id;
 
9079
 
 
9080
    format_id = innobase_file_format_name_lookup(
 
9081
      file_format_input);
 
9082
 
 
9083
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
9084
      /* Save a pointer to the name in the
 
9085
         'file_format_name_map' constant array. */
 
9086
      *static_cast<const char**>(save) =
 
9087
        trx_sys_file_format_id_to_name(format_id);
 
9088
 
 
9089
      return(0);
 
9090
    }
 
9091
  }
 
9092
 
 
9093
  *static_cast<const char**>(save) = NULL;
 
9094
  return(1);
 
9095
}
 
9096
 
 
9097
/****************************************************************//**
 
9098
Update the system variable innodb_file_format using the "saved"
 
9099
value. This function is registered as a callback with MySQL. */
 
9100
static
 
9101
void
 
9102
innodb_file_format_name_update(
 
9103
/*===========================*/
 
9104
  Session*      ,   /*!< in: thread handle */
 
9105
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9106
              system variable */
 
9107
  void*       var_ptr,  /*!< out: where the
 
9108
              formal string goes */
 
9109
  const void*     save)   /*!< in: immediate result
 
9110
              from check function */
 
9111
{
 
9112
  const char* format_name;
 
9113
 
 
9114
  ut_a(var_ptr != NULL);
 
9115
  ut_a(save != NULL);
 
9116
 
 
9117
  format_name = *static_cast<const char*const*>(save);
 
9118
 
 
9119
  if (format_name) {
 
9120
    uint  format_id;
 
9121
 
 
9122
    format_id = innobase_file_format_name_lookup(format_name);
 
9123
 
 
9124
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
9125
      srv_file_format = format_id;
 
9126
    }
 
9127
  }
 
9128
 
 
9129
  *static_cast<const char**>(var_ptr)
 
9130
    = trx_sys_file_format_id_to_name(srv_file_format);
 
9131
}
 
9132
 
 
9133
/*************************************************************//**
 
9134
Check if valid argument to innodb_file_format_check. This
 
9135
function is registered as a callback with MySQL.
 
9136
@return 0 for valid file format */
 
9137
static
 
9138
int
 
9139
innodb_file_format_check_validate(
 
9140
/*==============================*/
 
9141
  Session*      session, /*!< in: thread handle */
 
9142
  drizzle_sys_var*  , /*!< in: pointer to system
 
9143
            variable */
 
9144
  void*       save, /*!< out: immediate result
 
9145
            for update function */
 
9146
  drizzle_value*    value)  /*!< in: incoming string */
 
9147
{
 
9148
  const char* file_format_input;
 
9149
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9150
  int   len = sizeof(buff);
 
9151
  int   format_id;
 
9152
 
 
9153
  ut_a(save != NULL);
 
9154
  ut_a(value != NULL);
 
9155
 
 
9156
  file_format_input = value->val_str(value, buff, &len);
 
9157
 
 
9158
  if (file_format_input != NULL) {
 
9159
 
 
9160
    /* Check if user set on/off, we want to print a suitable
 
9161
    message if they did so. */
 
9162
 
 
9163
    if (innobase_file_format_check_on_off(file_format_input)) {
 
9164
      push_warning_printf(session,
 
9165
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9166
                          ER_WRONG_ARGUMENTS,
 
9167
        "InnoDB: invalid innodb_file_format_check "
 
9168
        "value; on/off can only be set at startup or "
 
9169
        "in the configuration file");
 
9170
    } else {
 
9171
      format_id = innobase_file_format_validate_and_set(file_format_input);
 
9172
      if (format_id >= 0) {
 
9173
        /* Save a pointer to the name in the
 
9174
           'file_format_name_map' constant array. */
 
9175
        *static_cast<const char**>(save) =
 
9176
          trx_sys_file_format_id_to_name(
 
9177
                                         (uint)format_id);
 
9178
 
 
9179
        return(0);
 
9180
 
 
9181
      } else {
 
9182
        push_warning_printf(session,
 
9183
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9184
                            ER_WRONG_ARGUMENTS,
 
9185
                            "InnoDB: invalid innodb_file_format_check "
 
9186
                            "value; can be any format up to %s "
 
9187
                            "or its equivalent numeric id",
 
9188
                            trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
9189
      }
 
9190
    }
 
9191
  }
 
9192
 
 
9193
  *static_cast<const char**>(save) = NULL;
 
9194
  return(1);
 
9195
}
 
9196
 
 
9197
/****************************************************************//**
 
9198
Update the system variable innodb_file_format_check using the "saved"
 
9199
value. This function is registered as a callback with MySQL. */
 
9200
static
 
9201
void
 
9202
innodb_file_format_check_update(
 
9203
/*============================*/
 
9204
  Session*      session,  /*!< in: thread handle */
 
9205
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9206
              system variable */
 
9207
  void*       var_ptr,  /*!< out: where the
 
9208
              formal string goes */
 
9209
  const void*     save)   /*!< in: immediate result
 
9210
              from check function */
 
9211
{
 
9212
  const char* format_name_in;
 
9213
  const char**  format_name_out;
 
9214
  uint    format_id;
 
9215
 
 
9216
  ut_a(save != NULL);
 
9217
  ut_a(var_ptr != NULL);
 
9218
 
 
9219
  format_name_in = *static_cast<const char*const*>(save);
 
9220
 
 
9221
  if (!format_name_in) {
 
9222
 
 
9223
    return;
 
9224
  }
 
9225
 
 
9226
  format_id = innobase_file_format_name_lookup(format_name_in);
 
9227
 
 
9228
  if (format_id > DICT_TF_FORMAT_MAX) {
 
9229
    /* DEFAULT is "on", which is invalid at runtime. */
 
9230
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
9231
            ER_WRONG_ARGUMENTS,
 
9232
            "Ignoring SET innodb_file_format=%s",
 
9233
            format_name_in);
 
9234
    return;
 
9235
  }
 
9236
 
 
9237
  format_name_out = static_cast<const char**>(var_ptr);
 
9238
 
 
9239
  /* Update the max format id in the system tablespace. */
 
9240
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
9241
    ut_print_timestamp(stderr);
 
9242
    fprintf(stderr,
 
9243
      " [Info] InnoDB: the file format in the system "
 
9244
      "tablespace is now set to %s.\n", *format_name_out);
 
9245
  }
 
9246
}
 
9247
 
 
9248
/****************************************************************//**
 
9249
Update the system variable innodb_adaptive_hash_index using the "saved"
 
9250
value. This function is registered as a callback with MySQL. */
 
9251
static
 
9252
void
 
9253
innodb_adaptive_hash_index_update(
 
9254
/*==============================*/
 
9255
  Session*      ,   /*!< in: thread handle */
 
9256
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9257
              system variable */
 
9258
  void*       , /*!< out: where the
 
9259
              formal string goes */
 
9260
  const void*     save)   /*!< in: immediate result
 
9261
              from check function */
 
9262
{
 
9263
  if (*(bool*) save) {
 
9264
    btr_search_enable();
 
9265
  } else {
 
9266
    btr_search_disable();
 
9267
  }
 
9268
}
 
9269
 
 
9270
/****************************************************************//**
 
9271
Update the system variable innodb_old_blocks_pct using the "saved"
 
9272
value. This function is registered as a callback with MySQL. */
 
9273
static
 
9274
void
 
9275
innodb_old_blocks_pct_update(
 
9276
/*=========================*/
 
9277
        Session*                        ,       /*!< in: thread handle */
 
9278
        drizzle_sys_var*        ,       /*!< in: pointer to
 
9279
                                                system variable */
 
9280
        void*                           ,/*!< out: where the
 
9281
                                                formal string goes */
 
9282
        const void*                     save)   /*!< in: immediate result
 
9283
                                                from check function */
 
9284
{
 
9285
        innobase_old_blocks_pct = buf_LRU_old_ratio_update(
 
9286
                *static_cast<const uint*>(save), TRUE);
 
9287
}
 
9288
 
 
9289
/*************************************************************//**
 
9290
Check if it is a valid value of innodb_change_buffering.  This function is
 
9291
registered as a callback with MySQL.
 
9292
@return 0 for valid innodb_change_buffering */
 
9293
static
 
9294
int
 
9295
innodb_change_buffering_validate(
 
9296
/*=============================*/
 
9297
  Session*      , /*!< in: thread handle */
 
9298
  drizzle_sys_var*  , /*!< in: pointer to system
 
9299
            variable */
 
9300
  void*       save, /*!< out: immediate result
 
9301
            for update function */
 
9302
  drizzle_value*    value)  /*!< in: incoming string */
 
9303
{
 
9304
  const char* change_buffering_input;
 
9305
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
9306
  int   len = sizeof(buff);
 
9307
 
 
9308
  ut_a(save != NULL);
 
9309
  ut_a(value != NULL);
 
9310
 
 
9311
  change_buffering_input = value->val_str(value, buff, &len);
 
9312
 
 
9313
  if (change_buffering_input != NULL) {
 
9314
    ulint use;
 
9315
 
 
9316
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
9317
         use++) {
 
9318
      if (!innobase_strcasecmp(
 
9319
            change_buffering_input,
 
9320
            innobase_change_buffering_values[use])) {
 
9321
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
9322
        return(0);
 
9323
      }
 
9324
    }
 
9325
  }
 
9326
 
 
9327
  return(1);
 
9328
}
 
9329
 
 
9330
/****************************************************************//**
 
9331
Update the system variable innodb_change_buffering using the "saved"
 
9332
value. This function is registered as a callback with MySQL. */
 
9333
static
 
9334
void
 
9335
innodb_change_buffering_update(
 
9336
/*===========================*/
 
9337
  Session*      ,   /*!< in: thread handle */
 
9338
  drizzle_sys_var*  ,   /*!< in: pointer to
 
9339
              system variable */
 
9340
  void*       var_ptr,  /*!< out: where the
 
9341
              formal string goes */
 
9342
  const void*     save)   /*!< in: immediate result
 
9343
              from check function */
 
9344
{
 
9345
  ut_a(var_ptr != NULL);
 
9346
  ut_a(save != NULL);
 
9347
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
9348
 
 
9349
  ibuf_use = *(const ibuf_use_t*) save;
 
9350
 
 
9351
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
9352
}
 
9353
 
 
9354
/* plugin options */
 
9355
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
9356
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9357
  "Enable InnoDB checksums validation (enabled by default). ",
 
9358
  NULL, NULL, TRUE);
 
9359
 
 
9360
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
9361
  PLUGIN_VAR_READONLY,
 
9362
  "The common part for InnoDB table spaces.",
 
9363
  NULL, NULL, NULL);
 
9364
 
 
9365
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
9366
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9367
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
9368
  NULL, NULL, TRUE);
 
9369
 
 
9370
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
9371
  PLUGIN_VAR_RQCMDARG,
 
9372
  "Number of IOPs the server can do. Tunes the background IO rate",
 
9373
  NULL, NULL, 200, 100, ~0L, 0);
 
9374
 
 
9375
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
9376
  PLUGIN_VAR_OPCMDARG,
 
9377
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
9378
  "values are 0, 1 (faster)"
 
9379
  " or 2 (fastest - crash-like)"
 
9380
  ".",
 
9381
  NULL, NULL, 1, 0, 2, 0);
 
9382
 
 
9383
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
9384
  PLUGIN_VAR_NOCMDARG,
 
9385
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
9386
  NULL, NULL, FALSE);
 
9387
 
 
9388
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
9389
  PLUGIN_VAR_RQCMDARG,
 
9390
  "File format to use for new tables in .ibd files.",
 
9391
  innodb_file_format_name_validate,
 
9392
  innodb_file_format_name_update, "Antelope");
 
9393
 
 
9394
/* If a new file format is introduced, the file format
 
9395
name needs to be updated accordingly. Please refer to
 
9396
file_format_name_map[] defined in trx0sys.c for the next
 
9397
file format name. */
 
9398
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
9399
  PLUGIN_VAR_OPCMDARG,
 
9400
  "The highest file format in the tablespace.",
 
9401
  innodb_file_format_check_validate,
 
9402
  innodb_file_format_check_update,
 
9403
  "Barracuda");
 
9404
 
 
9405
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
9406
  PLUGIN_VAR_OPCMDARG,
 
9407
  "Set to 0 (write and flush once per second),"
 
9408
  " 1 (write and flush at each commit)"
 
9409
  " or 2 (write at commit, flush once per second).",
 
9410
  NULL, NULL, 1, 0, 2, 0);
 
9411
 
 
9412
static DRIZZLE_SYSVAR_STR(flush_method, innobase_file_flush_method,
 
9413
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9414
  "With which method to flush data.", NULL, NULL, NULL);
 
9415
 
 
9416
#ifdef UNIV_LOG_ARCHIVE
 
9417
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
9418
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9419
  "Where full logs should be archived.", NULL, NULL, NULL);
 
9420
 
 
9421
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
9422
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
9423
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
9424
#endif /* UNIV_LOG_ARCHIVE */
 
9425
 
 
9426
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
9427
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9428
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
9429
 
 
9430
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
9431
  PLUGIN_VAR_RQCMDARG,
 
9432
  "Percentage of dirty pages allowed in bufferpool.",
 
9433
  NULL, NULL, 75, 0, 99, 0);
 
9434
 
 
9435
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
9436
  PLUGIN_VAR_NOCMDARG,
 
9437
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
9438
  NULL, NULL, TRUE);
 
9439
 
 
9440
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
9441
  PLUGIN_VAR_RQCMDARG,
 
9442
  "Desired maximum length of the purge queue (0 = no limit)",
 
9443
  NULL, NULL, 0, 0, ~0L, 0);
 
9444
 
 
9445
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
9446
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
9447
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
9448
  NULL, NULL, FALSE);
 
9449
 
 
9450
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
9451
  PLUGIN_VAR_RQCMDARG,
 
9452
  "The number of index pages to sample when calculating statistics (default 8)",
 
9453
  NULL, NULL, 8, 1, ~0ULL, 0);
 
9454
 
 
9455
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
9456
  PLUGIN_VAR_OPCMDARG,
 
9457
  "Enable InnoDB adaptive hash index (enabled by default).",
 
9458
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
9459
 
 
9460
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
9461
  PLUGIN_VAR_RQCMDARG,
 
9462
  "Replication thread delay (ms) on the slave server if "
 
9463
  "innodb_thread_concurrency is reached (0 by default)",
 
9464
  NULL, NULL, 0, 0, ~0UL, 0);
 
9465
 
 
9466
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
9467
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9468
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
9469
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
9470
 
 
9471
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
9472
  PLUGIN_VAR_RQCMDARG,
 
9473
  "Data file autoextend increment in megabytes",
 
9474
  NULL, NULL, 8L, 1L, 1000L, 0);
 
9475
 
 
9476
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
9477
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9478
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
9479
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
9480
 
 
9481
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
9482
  PLUGIN_VAR_RQCMDARG,
 
9483
  "Helps in performance tuning in heavily concurrent environments.",
 
9484
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
9485
 
 
9486
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
9487
  PLUGIN_VAR_RQCMDARG,
 
9488
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
9489
  NULL, NULL, 500L, 1L, ~0L, 0);
 
9490
 
 
9491
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
9492
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9493
  "Number of background read I/O threads in InnoDB.",
 
9494
  NULL, NULL, 4, 1, 64, 0);
 
9495
 
 
9496
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
9497
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9498
  "Number of background write I/O threads in InnoDB.",
 
9499
  NULL, NULL, 4, 1, 64, 0);
 
9500
 
 
9501
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
9502
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9503
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
9504
  NULL, NULL, 0, 0, 6, 0);
 
9505
 
 
9506
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
9507
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9508
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
9509
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
9510
 
 
9511
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
9512
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9513
  "Size of each log file in a log group.",
 
9514
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
9515
 
 
9516
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
9517
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9518
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
9519
  NULL, NULL, 2, 2, 100, 0);
 
9520
 
 
9521
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
9522
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9523
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
9524
  NULL, NULL, 1, 1, 10, 0);
 
9525
 
 
9526
static DRIZZLE_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
 
9527
  PLUGIN_VAR_RQCMDARG,
 
9528
  "Percentage of the buffer pool to reserve for 'old' blocks.",
 
9529
  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
 
9530
 
 
9531
static DRIZZLE_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
 
9532
  PLUGIN_VAR_RQCMDARG,
 
9533
  "Move blocks to the 'new' end of the buffer pool if the first access"
 
9534
  " was at least this many milliseconds ago."
 
9535
  " The timeout is disabled if 0 (the default).",
 
9536
  NULL, NULL, 0, 0, UINT32_MAX, 0);
 
9537
 
 
9538
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
9539
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9540
  "How many files at the maximum InnoDB keeps open at the same time.",
 
9541
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
9542
 
 
9543
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
9544
  PLUGIN_VAR_RQCMDARG,
 
9545
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
9546
  NULL, NULL, 30L, 0L, ~0L, 0);
 
9547
 
 
9548
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
9549
  PLUGIN_VAR_OPCMDARG,
 
9550
  "Maximum delay between polling for a spin lock (6 by default)",
 
9551
  NULL, NULL, 6L, 0L, ~0L, 0);
 
9552
 
 
9553
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
9554
  PLUGIN_VAR_RQCMDARG,
 
9555
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
9556
  NULL, NULL, 0, 0, 1000, 0);
 
9557
 
 
9558
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
9559
  PLUGIN_VAR_RQCMDARG,
 
9560
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
9561
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
9562
 
 
9563
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
9564
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
9565
  "Path to individual files and their sizes.",
 
9566
  NULL, NULL, NULL);
 
9567
 
 
9568
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
9569
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
9570
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
9571
 
 
9572
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
9573
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
9574
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
9575
  NULL, NULL, TRUE);
 
9576
 
 
9577
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
9578
  PLUGIN_VAR_RQCMDARG,
 
9579
  "Buffer changes to reduce random access: "
 
9580
  "OFF, ON, none, inserts.",
 
9581
  innodb_change_buffering_validate,
 
9582
  innodb_change_buffering_update, NULL);
 
9583
 
 
9584
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
9585
  PLUGIN_VAR_RQCMDARG,
 
9586
  "Number of pages that must be accessed sequentially for InnoDB to "
 
9587
  "trigger a readahead.",
 
9588
  NULL, NULL, 56, 0, 64, 0);
9116
9589
 
9117
9590
static void init_options(drizzled::module::option_context &context)
9118
9591
{
9124
9597
  context("disable-doublewrite",
9125
9598
          "Disable InnoDB doublewrite buffer.");
9126
9599
  context("io-capacity",
9127
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
9600
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9128
9601
          "Number of IOPs the server can do. Tunes the background IO rate");
9129
9602
  context("fast-shutdown",
9130
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
9603
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9131
9604
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9132
 
  context("purge-batch-size",
9133
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9134
 
          "Number of UNDO logs to purge in one batch from the history list. "
9135
 
          "Default is 20.");
9136
 
  context("purge-threads",
9137
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9138
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9139
9605
  context("file-per-table",
9140
9606
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9141
 
           "Stores each InnoDB table to an .ibd file in the database dir.");
9142
 
  context("file-format-max",
9143
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9144
 
          "The highest file format in the tablespace.");
9145
 
  context("file-format-check",
9146
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9147
 
          "Whether to perform system file format check.");
 
9607
          "Stores each InnoDB table to an .ibd file in the database dir.");
9148
9608
  context("file-format",
9149
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
9609
          po::value<string>()->default_value("Antelope"),
9150
9610
          "File format to use for new tables in .ibd files.");
 
9611
  context("file-format-check",
 
9612
          po::value<string>()->default_value("on"),
 
9613
          "The highest file format in the tablespace.");
9151
9614
  context("flush-log-at-trx-commit",
9152
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
9615
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9153
9616
          "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).");
9154
9617
  context("flush-method",
9155
9618
          po::value<string>(),
9156
9619
          "With which method to flush data.");
 
9620
#ifdef UNIV_LOG_ARCHIVE
 
9621
  context("log-arch-dir",
 
9622
          po::value<string>(),
 
9623
          "Where full logs should be archived.");
 
9624
  context("log-archive",
 
9625
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
9626
          "Set to 1 if you want to have logs archived.");
 
9627
#endif /* UNIV_LOG_ARCHIVE */
9157
9628
  context("log-group-home-dir",
9158
9629
          po::value<string>(),
9159
9630
          "Path to InnoDB log files.");
9160
9631
  context("max-dirty-pages-pct",
9161
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
9632
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9162
9633
          "Percentage of dirty pages allowed in bufferpool.");
9163
9634
  context("disable-adaptive-flushing",
9164
9635
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9165
9636
  context("max-purge-lag",
9166
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
9637
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9167
9638
          "Desired maximum length of the purge queue (0 = no limit)");
9168
9639
  context("status-file",
9169
9640
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9171
9642
  context("disable-stats-on-metadata",
9172
9643
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9173
9644
  context("stats-sample-pages",
9174
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
9645
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9175
9646
          "The number of index pages to sample when calculating statistics (default 8)");
9176
9647
  context("disable-adaptive-hash-index",
9177
9648
          "Enable InnoDB adaptive hash index (enabled by default)");
9178
9649
  context("replication-delay",
9179
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
9650
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9180
9651
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9181
9652
  context("additional-mem-pool-size",
9182
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
9653
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9183
9654
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9184
9655
  context("autoextend-increment",
9185
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
9656
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9186
9657
          "Data file autoextend increment in megabytes");
9187
9658
  context("buffer-pool-size",
9188
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
9659
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9189
9660
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9190
 
  context("buffer-pool-instances",
9191
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9192
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9193
 
 
9194
9661
  context("commit-concurrency",
9195
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
9662
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9196
9663
          "Helps in performance tuning in heavily concurrent environments.");
9197
9664
  context("concurrency-tickets",
9198
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
9665
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9199
9666
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9200
9667
  context("read-io-threads",
9201
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
9668
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9202
9669
          "Number of background read I/O threads in InnoDB.");
9203
9670
  context("write-io-threads",
9204
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
9671
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9205
9672
          "Number of background write I/O threads in InnoDB.");
9206
9673
  context("force-recovery",
9207
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
9674
          po::value<long>(&innobase_force_recovery)->default_value(0),
9208
9675
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9209
9676
  context("log-buffer-size",
9210
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
9677
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9211
9678
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9212
9679
  context("log-file-size",
9213
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
9680
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9214
9681
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9215
9682
  context("log-files-in-group",
9216
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
9683
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9217
9684
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9218
9685
  context("mirrored-log-groups",
9219
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
9686
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9220
9687
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9221
9688
  context("open-files",
9222
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
9689
          po::value<long>(&innobase_open_files)->default_value(300L),
9223
9690
          "How many files at the maximum InnoDB keeps open at the same time.");
9224
9691
  context("sync-spin-loops",
9225
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9692
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9226
9693
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9227
9694
  context("spin-wait-delay",
9228
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9695
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9229
9696
          "Maximum delay between polling for a spin lock (6 by default)");
9230
9697
  context("thread-concurrency",
9231
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9698
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9232
9699
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9233
9700
  context("thread-sleep-delay",
9234
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9701
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9235
9702
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9236
9703
  context("data-file-path",
9237
9704
          po::value<string>(),
9241
9708
          "InnoDB version");
9242
9709
  context("use-internal-malloc",
9243
9710
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9244
 
  context("disable-native-aio",
9245
 
          _("Do not use Native AIO library for IO, even if available"));
9246
9711
  context("change-buffering",
9247
 
          po::value<string>(&innobase_change_buffering),
 
9712
          po::value<string>(),
9248
9713
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9249
9714
  context("read-ahead-threshold",
9250
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9715
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9251
9716
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9252
9717
  context("disable-xa",
9253
9718
          "Disable InnoDB support for the XA two-phase commit");
9254
9719
  context("disable-table-locks",
9255
9720
          "Disable InnoDB locking in LOCK TABLES");
9256
9721
  context("strict-mode",
9257
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9722
          po::value<bool>()->default_value(false)->zero_tokens(),
9258
9723
          "Use strict mode when evaluating create options.");
9259
 
  context("replication-log",
9260
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9261
 
          _("Enable internal replication log."));
9262
9724
  context("lock-wait-timeout",
9263
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9264
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9265
 
  context("old-blocks-pct",
9266
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9267
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9268
 
  context("old-blocks-time",
9269
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9270
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9271
 
            " was at least this many milliseconds ago."
9272
 
            " The timeout is disabled if 0 (the default)."));
 
9725
          po::value<unsigned long>()->default_value(50),
 
9726
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9273
9727
}
9274
9728
 
9275
 
 
 
9729
static drizzle_sys_var* innobase_system_variables[]= {
 
9730
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9731
  DRIZZLE_SYSVAR(autoextend_increment),
 
9732
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9733
  DRIZZLE_SYSVAR(checksums),
 
9734
  DRIZZLE_SYSVAR(commit_concurrency),
 
9735
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9736
  DRIZZLE_SYSVAR(data_file_path),
 
9737
  DRIZZLE_SYSVAR(data_home_dir),
 
9738
  DRIZZLE_SYSVAR(doublewrite),
 
9739
  DRIZZLE_SYSVAR(fast_shutdown),
 
9740
  DRIZZLE_SYSVAR(read_io_threads),
 
9741
  DRIZZLE_SYSVAR(write_io_threads),
 
9742
  DRIZZLE_SYSVAR(file_per_table),
 
9743
  DRIZZLE_SYSVAR(file_format),
 
9744
  DRIZZLE_SYSVAR(file_format_check),
 
9745
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9746
  DRIZZLE_SYSVAR(flush_method),
 
9747
  DRIZZLE_SYSVAR(force_recovery),
 
9748
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9749
#ifdef UNIV_LOG_ARCHIVE
 
9750
  DRIZZLE_SYSVAR(log_arch_dir),
 
9751
  DRIZZLE_SYSVAR(log_archive),
 
9752
#endif /* UNIV_LOG_ARCHIVE */
 
9753
  DRIZZLE_SYSVAR(log_buffer_size),
 
9754
  DRIZZLE_SYSVAR(log_file_size),
 
9755
  DRIZZLE_SYSVAR(log_files_in_group),
 
9756
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9757
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9758
  DRIZZLE_SYSVAR(max_purge_lag),
 
9759
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9760
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9761
  DRIZZLE_SYSVAR(old_blocks_pct),
 
9762
  DRIZZLE_SYSVAR(old_blocks_time),
 
9763
  DRIZZLE_SYSVAR(open_files),
 
9764
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9765
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9766
  DRIZZLE_SYSVAR(replication_delay),
 
9767
  DRIZZLE_SYSVAR(status_file),
 
9768
  DRIZZLE_SYSVAR(strict_mode),
 
9769
  DRIZZLE_SYSVAR(support_xa),
 
9770
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9771
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9772
  DRIZZLE_SYSVAR(table_locks),
 
9773
  DRIZZLE_SYSVAR(thread_concurrency),
 
9774
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9775
  DRIZZLE_SYSVAR(version),
 
9776
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9777
  DRIZZLE_SYSVAR(change_buffering),
 
9778
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9779
  DRIZZLE_SYSVAR(io_capacity),
 
9780
  NULL
 
9781
};
9276
9782
 
9277
9783
DRIZZLE_DECLARE_PLUGIN
9278
9784
{
9283
9789
  "Supports transactions, row-level locking, and foreign keys",
9284
9790
  PLUGIN_LICENSE_GPL,
9285
9791
  innobase_init, /* Plugin Init */
9286
 
  NULL, /* depends */
 
9792
  innobase_system_variables, /* system variables */
9287
9793
  init_options /* reserved */
9288
9794
}
9289
9795
DRIZZLE_DECLARE_PLUGIN_END;
9311
9817
  return res;
9312
9818
}
9313
9819
 
 
9820
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9821
 
 
9822
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9823
from zero to nonzero. (Bug #42101)
 
9824
 
 
9825
The initial default value is 0, and without this extra initialization,
 
9826
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9827
to 0, even if it was initially set to nonzero at the command line
 
9828
or configuration file. */
 
9829
static
 
9830
void
 
9831
innobase_commit_concurrency_init_default(void)
 
9832
/*==========================================*/
 
9833
{
 
9834
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9835
    = innobase_commit_concurrency;
 
9836
}
 
9837
 
9314
9838
/***********************************************************************
9315
9839
This function checks each index name for a table against reserved
9316
9840
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9317
9841
this function pushes an warning message to the client, and returns true. */
9318
 
UNIV_INTERN
 
9842
extern "C" UNIV_INTERN
9319
9843
bool
9320
9844
innobase_index_name_is_reserved(
9321
9845
/*============================*/
9335
9859
    if (innobase_strcasecmp(key->name,
9336
9860
                            innobase_index_reserve_name) == 0) {
9337
9861
      /* Push warning to drizzle */
9338
 
      push_warning_printf(trx->mysql_thd,
 
9862
      push_warning_printf((Session*)trx->mysql_thd,
9339
9863
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9340
9864
                          ER_WRONG_NAME_FOR_INDEX,
9341
9865
                          "Cannot Create Index with name "
9361
9885
  ulint   buflen;
9362
9886
  const char* id;
9363
9887
  ulint   idlen;
9364
 
  drizzled::Session *session;
 
9888
  void*   session;
9365
9889
  ibool   file_id;
9366
9890
 
9367
9891
  const char* expected;