~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-10-27 21:19:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1886.
  • Revision ID: brian@tangent.org-20101027211918-1xnp5koya8stw35j
Additional documenation.

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.
 
3
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, 2009 Google Inc.
5
 
Copyright (c) 2009, Percona Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
13
 
Portions of this file contain modifications contributed and copyrighted
14
 
by Percona Inc.. Those modifications are
15
 
gratefully acknowledged and are described briefly in the InnoDB
16
 
documentation. The contributions by Percona Inc. are incorporated with
17
 
their permission, and subject to the conditions contained in the file
18
 
COPYING.Percona.
19
 
 
20
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
30
22
St, Fifth Floor, Boston, MA 02110-1301 USA
31
23
 
32
24
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
49
 
 
50
***********************************************************************/
33
51
 
34
52
/* TODO list for the InnoDB Cursor in 5.0:
35
53
  - fix savepoint functions to use savepoint storage area
102
120
#include "log0log.h"
103
121
#include "lock0lock.h"
104
122
#include "dict0crea.h"
105
 
#include "create_replication.h"
106
123
#include "btr0cur.h"
107
124
#include "btr0btr.h"
108
125
#include "fsp0fsp.h"
120
137
 
121
138
#include "ha_innodb.h"
122
139
#include "data_dictionary.h"
123
 
#include "replication_dictionary.h"
124
140
#include "internal_dictionary.h"
125
141
#include "handler0vars.h"
126
142
 
129
145
#include <string>
130
146
 
131
147
#include "plugin/innobase/handler/status_function.h"
132
 
#include "plugin/innobase/handler/replication_log.h"
133
 
 
134
 
#include <google/protobuf/io/zero_copy_stream.h>
135
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
136
 
#include <google/protobuf/io/coded_stream.h>
137
 
#include <google/protobuf/text_format.h>
138
148
 
139
149
using namespace std;
140
150
using namespace drizzled;
141
151
 
 
152
#ifndef DRIZZLE_SERVER
 
153
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
 
154
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
 
155
extern pthread_mutex_t LOCK_thread_count;
 
156
 
 
157
#endif /* DRIZZLE_SERVER */
 
158
 
142
159
/** to protect innobase_open_files */
143
160
static pthread_mutex_t innobase_share_mutex;
144
161
/** to force correct commit order in binlog */
147
164
static pthread_mutex_t commit_threads_m;
148
165
static pthread_cond_t commit_cond;
149
166
static pthread_mutex_t commit_cond_m;
 
167
static pthread_mutex_t analyze_mutex;
150
168
static bool innodb_inited = 0;
151
169
 
152
170
#define INSIDE_HA_INNOBASE_CC
170
188
static plugin::TableFunction* innodb_trx_tool= NULL;
171
189
static plugin::TableFunction* innodb_locks_tool= NULL;
172
190
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
173
 
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
174
 
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
175
 
 
176
 
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
177
 
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
178
 
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
179
 
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
180
 
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
181
 
 
182
 
static ReplicationLog *replication_logger= NULL;
183
 
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
184
 
static open_files_constraint innobase_open_files;
185
 
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
186
 
static mirrored_log_groups_constraint innobase_mirrored_log_groups;
187
 
typedef constrained_check<uint32_t, 100, 2> log_files_in_group_constraint;
188
 
static log_files_in_group_constraint innobase_log_files_in_group;
189
 
typedef constrained_check<uint32_t, 6, 0> force_recovery_constraint;
190
 
force_recovery_constraint innobase_force_recovery;
191
 
typedef constrained_check<size_t, SIZE_MAX, 256*1024, 1024> log_buffer_constraint;
192
 
static log_buffer_constraint innobase_log_buffer_size;
193
 
typedef constrained_check<size_t, SIZE_MAX, 512*1024, 1024> additional_mem_pool_constraint;
194
 
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
195
 
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
196
 
static autoextend_constraint innodb_auto_extend_increment;
197
 
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
198
 
static buffer_pool_constraint innobase_buffer_pool_size;
199
 
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
200
 
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
201
 
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
202
 
static io_capacity_constraint innodb_io_capacity;
203
 
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
204
 
static purge_batch_constraint innodb_purge_batch_size;
205
 
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
206
 
static purge_threads_constraint innodb_n_purge_threads;
207
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
208
 
static trinary_constraint innodb_flush_log_at_trx_commit;
209
 
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
210
 
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
211
 
static uint64_constraint innodb_max_purge_lag;
212
 
static uint64_nonzero_constraint innodb_stats_sample_pages;
213
 
typedef constrained_check<uint32_t, 64, 1> io_threads_constraint;
214
 
static io_threads_constraint innobase_read_io_threads;
215
 
static io_threads_constraint innobase_write_io_threads;
216
 
 
217
 
typedef constrained_check<uint32_t, 1000, 0> concurrency_constraint;
218
 
static concurrency_constraint innobase_commit_concurrency;
219
 
static concurrency_constraint innobase_thread_concurrency;
220
 
static uint32_nonzero_constraint innodb_concurrency_tickets;
221
 
 
222
 
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
223
 
static log_file_constraint innobase_log_file_size;
224
 
 
225
 
static uint64_constraint innodb_replication_delay;
 
191
 
 
192
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
193
  innobase_log_buffer_size,
 
194
  innobase_force_recovery, innobase_open_files;
 
195
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
196
static ulong innobase_commit_concurrency = 0;
 
197
static ulong innobase_read_io_threads;
 
198
static ulong innobase_write_io_threads;
 
199
 
 
200
/**
 
201
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
202
 */
 
203
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
204
static int64_t innobase_log_file_size;
226
205
 
227
206
/** Percentage of the buffer pool to reserve for 'old' blocks.
228
207
Connected to buf_LRU_old_ratio. */
229
 
typedef constrained_check<uint32_t, 95, 5> old_blocks_constraint;
230
 
static old_blocks_constraint innobase_old_blocks_pct;
231
 
 
232
 
static uint32_constraint innodb_sync_spin_loops;
233
 
static uint32_constraint innodb_spin_wait_delay;
234
 
static uint32_constraint innodb_thread_sleep_delay;
235
 
 
236
 
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
237
 
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
 
208
static uint innobase_old_blocks_pct;
238
209
 
239
210
/* The default values for the following char* start-up parameters
240
211
are determined in innobase_init below: */
241
212
 
242
 
std::string innobase_data_home_dir;
243
 
std::string innobase_data_file_path;
244
 
std::string innobase_log_group_home_dir;
245
 
static string innobase_file_format_name;
246
 
static string innobase_change_buffering;
247
 
 
248
 
/* The highest file format being used in the database. The value can be
249
 
set by user, however, it will be adjusted to the newer file format if
250
 
a table of such format is created/opened. */
251
 
static string innobase_file_format_max;
 
213
static char*  innobase_data_home_dir      = NULL;
 
214
static char*  innobase_data_file_path     = NULL;
 
215
static char*  innobase_log_group_home_dir   = NULL;
 
216
static char*  innobase_file_format_name   = NULL;
 
217
static char*  innobase_change_buffering   = NULL;
 
218
 
 
219
/* Note: This variable can be set to on/off and any of the supported
 
220
file formats in the configuration file, but can only be set to any
 
221
of the supported file formats during runtime. */
 
222
static char*  innobase_file_format_check    = NULL;
 
223
 
 
224
static char*  innobase_file_flush_method   = NULL;
252
225
 
253
226
/* Below we have boolean-valued start-up parameters, and their default
254
227
values */
255
228
 
256
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
257
 
static trinary_constraint innobase_fast_shutdown;
258
 
 
259
 
/* "innobase_file_format_check" decides whether we would continue
260
 
booting the server if the file format stamped on the system
261
 
table space exceeds the maximum file format supported
262
 
by the server. Can be set during server startup at command
263
 
line or configure file, and a read only variable after
264
 
server startup */
265
 
 
266
 
/* If a new file format is introduced, the file format
267
 
name needs to be updated accordingly. Please refer to
268
 
file_format_name_map[] defined in trx0sys.c for the next
269
 
file format name. */
270
 
 
271
 
static my_bool  innobase_file_format_check = TRUE;
 
229
static ulong  innobase_fast_shutdown      = 1;
 
230
#ifdef UNIV_LOG_ARCHIVE
 
231
static my_bool  innobase_log_archive      = FALSE;
 
232
static char*  innobase_log_arch_dir     = NULL;
 
233
#endif /* UNIV_LOG_ARCHIVE */
272
234
static my_bool  innobase_use_doublewrite    = TRUE;
273
235
static my_bool  innobase_use_checksums      = TRUE;
274
236
static my_bool  innobase_rollback_on_timeout    = FALSE;
275
237
static my_bool  innobase_create_status_file   = FALSE;
276
 
static bool innobase_use_replication_log;
277
 
static bool support_xa;
278
 
static bool strict_mode;
279
 
typedef constrained_check<uint32_t, 1024*1024*1024, 1> lock_wait_constraint;
280
 
static lock_wait_constraint lock_wait_timeout;
281
238
 
282
239
static char*  internal_innobase_data_file_path  = NULL;
283
240
 
 
241
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
242
 
284
243
/* The following counter is used to convey information to InnoDB
285
244
about server activity: in selects it is not sensible to call
286
245
srv_active_wake_master_thread after each fetch or search, we only do
298
257
/** Allowed values of innodb_change_buffering */
299
258
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
300
259
  "none",   /* IBUF_USE_NONE */
301
 
  "inserts",    /* IBUF_USE_INSERT */
302
 
  "deletes",    /* IBUF_USE_DELETE_MARK */
303
 
  "changes",    /* IBUF_USE_INSERT_DELETE_MARK */
304
 
  "purges",     /* IBUF_USE_DELETE */
305
 
  "all"         /* IBUF_USE_ALL */
 
260
  "inserts" /* IBUF_USE_INSERT */
306
261
};
307
262
 
308
263
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
356
311
      pthread_mutex_destroy(&prepare_commit_mutex);
357
312
      pthread_mutex_destroy(&commit_threads_m);
358
313
      pthread_mutex_destroy(&commit_cond_m);
 
314
      pthread_mutex_destroy(&analyze_mutex);
359
315
      pthread_cond_destroy(&commit_cond);
360
316
    }
361
317
    
362
318
    /* These get strdup'd from vm variables */
 
319
    free(innobase_data_home_dir);
 
320
    free(innobase_log_group_home_dir);
363
321
 
364
322
  }
365
323
 
390
348
  {
391
349
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
392
350
  }
393
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
394
 
  virtual uint64_t doGetNewTransactionId(Session *session);
395
351
  virtual int doCommit(Session* session, bool all);
396
352
  virtual int doRollback(Session* session, bool all);
397
353
 
514
470
 
515
471
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
472
                             const drizzled::SchemaIdentifier &schema_identifier,
517
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
473
                             drizzled::TableIdentifiers &set_of_identifiers);
518
474
  bool validateCreateTableOption(const std::string &key, const std::string &state);
519
475
  void dropTemporarySchema();
520
476
 
543
499
 
544
500
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
501
                                           const drizzled::SchemaIdentifier &schema_identifier,
546
 
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
 
502
                                           drizzled::TableIdentifiers &set_of_identifiers)
547
503
{
548
504
  CachedDirectory::Entries entries= directory.getEntries();
549
505
 
562
518
    { }
563
519
    else
564
520
    {
565
 
      std::string path;
566
 
      path+= directory.getPath();
567
 
      path+= FN_LIBCHAR;
568
 
      path+= entry->filename;
569
 
 
570
 
      message::Table definition;
571
 
      if (StorageEngine::readTableFile(path, definition))
572
 
      {
573
 
        /* 
574
 
           Using schema_identifier here to stop unused warning, could use
575
 
           definition.schema() instead
576
 
        */
577
 
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
578
 
        set_of_identifiers.push_back(identifier);
579
 
      }
 
521
      char uname[NAME_LEN + 1];
 
522
      uint32_t file_name_len;
 
523
 
 
524
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
525
      // TODO: Remove need for memory copy here
 
526
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
527
 
 
528
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
580
529
    }
581
530
  }
582
531
}
586
535
  string proto_path(identifier.getPath());
587
536
  proto_path.append(DEFAULT_FILE_EXTENSION);
588
537
 
589
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
 
538
  if (session.doesTableMessageExist(identifier))
590
539
    return true;
591
540
 
592
541
  if (access(proto_path.c_str(), F_OK))
605
554
  proto_path.append(DEFAULT_FILE_EXTENSION);
606
555
 
607
556
  // First we check the temporary tables.
608
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
557
  if (session.getTableMessage(identifier, table_proto))
609
558
    return EEXIST;
610
559
 
611
560
  if (access(proto_path.c_str(), F_OK))
619
568
  return ENOENT;
620
569
}
621
570
 
 
571
/** @brief Initialize the default value of innodb_commit_concurrency.
 
572
 
 
573
Once InnoDB is running, the innodb_commit_concurrency must not change
 
574
from zero to nonzero. (Bug #42101)
 
575
 
 
576
The initial default value is 0, and without this extra initialization,
 
577
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
578
to 0, even if it was initially set to nonzero at the command line
 
579
or configuration file. */
 
580
static
 
581
void
 
582
innobase_commit_concurrency_init_default(void);
 
583
/*==========================================*/
622
584
 
623
585
/************************************************************//**
624
586
Validate the file format name and return its corresponding id.
631
593
            name */
632
594
/************************************************************//**
633
595
Validate the file format check config parameters, as a side effect it
634
 
sets the srv_max_file_format_at_startup variable.
 
596
sets the srv_check_file_format_at_startup variable.
 
597
@return true if one of  "on" or "off" */
 
598
static
 
599
bool
 
600
innobase_file_format_check_on_off(
 
601
/*==============================*/
 
602
  const char* format_check);    /*!< in: parameter value */
 
603
/************************************************************//**
 
604
Validate the file format check config parameters, as a side effect it
 
605
sets the srv_check_file_format_at_startup variable.
635
606
@return the format_id if valid config value, otherwise, return -1 */
636
607
static
637
608
int
638
609
innobase_file_format_validate_and_set(
639
610
/*================================*/
640
 
  const char* format_max);    /*!< in: parameter value */
 
611
  const char* format_check);    /*!< in: parameter value */
641
612
 
642
613
static const char innobase_engine_name[]= "InnoDB";
643
614
 
 
615
/*************************************************************//**
 
616
Check for a valid value of innobase_commit_concurrency.
 
617
@return 0 for valid innodb_commit_concurrency */
 
618
static
 
619
int
 
620
innobase_commit_concurrency_validate(
 
621
/*=================================*/
 
622
  Session*      , /*!< in: thread handle */
 
623
  drizzle_sys_var*  , /*!< in: pointer to system
 
624
            variable */
 
625
  void*       save, /*!< out: immediate result
 
626
            for update function */
 
627
  drizzle_value*    value)  /*!< in: incoming string */
 
628
{
 
629
  int64_t   intbuf;
 
630
  ulong   commit_concurrency;
 
631
 
 
632
  if (value->val_int(value, &intbuf)) {
 
633
    /* The value is NULL. That is invalid. */
 
634
    return(1);
 
635
  }
 
636
 
 
637
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
638
    = static_cast<ulong>(intbuf);
 
639
 
 
640
  /* Allow the value to be updated, as long as it remains zero
 
641
  or nonzero. */
 
642
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
643
}
 
644
 
 
645
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
646
  "Enable InnoDB support for the XA two-phase commit",
 
647
  /* check_func */ NULL, /* update_func */ NULL,
 
648
  /* default */ TRUE);
 
649
 
 
650
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
651
  "Enable InnoDB locking in LOCK TABLES",
 
652
  /* check_func */ NULL, /* update_func */ NULL,
 
653
  /* default */ TRUE);
 
654
 
 
655
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
656
  "Use strict mode when evaluating create options.",
 
657
  NULL, NULL, FALSE);
 
658
 
 
659
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
660
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
661
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
662
 
644
663
 
645
664
/*****************************************************************//**
646
665
Commits a transaction in an InnoDB database. */
907
926
ibool
908
927
thd_supports_xa(
909
928
/*============*/
910
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
929
  void* session)  /*!< in: thread handle (Session*), or NULL to query
911
930
        the global innodb_supports_xa */
912
931
{
913
 
  /* TODO: Add support here for per-session value */
914
 
  return(support_xa);
 
932
  return(SessionVAR((Session*) session, support_xa));
915
933
}
916
934
 
917
935
/******************************************************************//**
921
939
ulong
922
940
thd_lock_wait_timeout(
923
941
/*==================*/
924
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
942
  void* session)  /*!< in: thread handle (Session*), or NULL to query
925
943
      the global innodb_lock_wait_timeout */
926
944
{
927
 
  /* TODO: Add support here for per-session value */
928
945
  /* According to <drizzle/plugin.h>, passing session == NULL
929
946
  returns the global value of the session variable. */
930
 
  return((ulong)lock_wait_timeout.get());
931
 
}
932
 
 
933
 
/******************************************************************//**
934
 
Set the time waited for the lock for the current query. */
935
 
extern "C" UNIV_INTERN
936
 
void
937
 
thd_set_lock_wait_time(
938
 
/*===================*/
939
 
        void*   thd,    /*!< in: thread handle (THD*) */
940
 
        ulint   value)  /*!< in: time waited for the lock */
941
 
{
942
 
        if (thd) {
943
 
          static_cast<Session*>(thd)->utime_after_lock+= value;
944
 
        }
 
947
  return(SessionVAR((Session*) session, lock_wait_timeout));
945
948
}
946
949
 
947
950
/********************************************************************//**
956
959
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
957
960
}
958
961
 
959
 
 
960
 
plugin::ReplicationReturnCode ReplicationLog::apply(Session &session,
961
 
                                                    const message::Transaction &message)
962
 
{
963
 
  char *data= new char[message.ByteSize()];
964
 
 
965
 
  message.SerializeToArray(data, message.ByteSize());
966
 
 
967
 
  trx_t *trx= session_to_trx(&session);
968
 
 
969
 
  uint64_t trx_id= message.transaction_context().transaction_id();
970
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
971
 
  (void)error;
972
 
 
973
 
  delete[] data;
974
 
 
975
 
  return plugin::SUCCESS;
976
 
}
977
 
 
978
962
/********************************************************************//**
979
963
Call this function when mysqld passes control to the client. That is to
980
964
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1039
1023
  case DB_INTERRUPTED:
1040
1024
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1041
1025
    /* fall through */
1042
 
 
1043
 
  case DB_FOREIGN_EXCEED_MAX_CASCADE:
1044
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1045
 
                        HA_ERR_ROW_IS_REFERENCED,
1046
 
                        "InnoDB: Cannot delete/update "
1047
 
                        "rows with cascading foreign key "
1048
 
                        "constraints that exceed max "
1049
 
                        "depth of %d. Please "
1050
 
                        "drop extra constraints and try "
1051
 
                        "again", DICT_FK_MAX_RECURSIVE_LOAD);
1052
 
    /* fall through */
1053
 
 
1054
1026
  case DB_ERROR:
1055
1027
  default:
1056
1028
    return(-1); /* unspecified error */
1165
1137
}
1166
1138
 
1167
1139
 
 
1140
 
 
1141
/*************************************************************//**
 
1142
If you want to print a session that is not associated with the current thread,
 
1143
you must call this function before reserving the InnoDB kernel_mutex, to
 
1144
protect Drizzle from setting session->query NULL. If you print a session of the
 
1145
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1146
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1147
after you release the kernel_mutex.
 
1148
 
 
1149
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1150
         in non-Cursor code.
 
1151
 */
 
1152
extern "C" UNIV_INTERN
 
1153
void
 
1154
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1155
/*============================================*/
 
1156
{
 
1157
  ut_ad(!mutex_own(&kernel_mutex));
 
1158
  LOCK_thread_count.lock();
 
1159
}
 
1160
 
 
1161
/*************************************************************//**
 
1162
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1163
In the InnoDB latching order, the mutex sits right above the
 
1164
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1165
released before this function is invoked. 
 
1166
 
 
1167
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1168
         in non-Cursor code.
 
1169
*/
 
1170
extern "C" UNIV_INTERN
 
1171
void
 
1172
innobase_mysql_end_print_arbitrary_thd(void)
 
1173
/*========================================*/
 
1174
{
 
1175
  ut_ad(!mutex_own(&kernel_mutex));
 
1176
  LOCK_thread_count.unlock();
 
1177
}
 
1178
 
1168
1179
/*************************************************************//**
1169
1180
Prints info of a Session object (== user session thread) to the given file. */
1170
1181
extern "C" UNIV_INTERN
1185
1196
          session->getSecurityContext().getIp().c_str(),
1186
1197
          session->getSecurityContext().getUser().c_str()
1187
1198
  );
1188
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1199
  fprintf(f,
 
1200
          "\n%s", session->getQueryString().c_str()
 
1201
  );
1189
1202
  putc('\n', f);
1190
1203
}
1191
1204
 
1208
1221
  if (cs) {
1209
1222
    *mbminlen = cs->mbminlen;
1210
1223
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1224
  } else {
1214
1225
    ut_a(cset == 0);
1215
1226
    *mbminlen = *mbmaxlen = 0;
1277
1288
/*=================*/
1278
1289
  void* mysql_session)  /*!< in: MySQL thread handle */
1279
1290
{
1280
 
  return static_cast<Session*>(mysql_session)->charset();
 
1291
  return session_charset(static_cast<Session*>(mysql_session));
1281
1292
}
1282
1293
 
1283
1294
extern "C" UNIV_INTERN
1297
1308
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1298
1309
}
1299
1310
 
1300
 
/**********************************************************************//**
1301
 
Determines the current SQL statement.
1302
 
@return        SQL statement string */
1303
 
extern "C" UNIV_INTERN
1304
 
const char*
1305
 
innobase_get_stmt(
1306
 
/*==============*/
1307
 
       void*   session,        /*!< in: MySQL thread handle */
1308
 
       size_t* length)         /*!< out: length of the SQL statement */
1309
 
{
1310
 
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
1311
 
}
1312
 
 
1313
1311
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1314
1312
/*******************************************************************//**
1315
1313
Map an OS error to an errno value. The OS error number is stored in
1575
1573
  trx = trx_allocate_for_mysql();
1576
1574
 
1577
1575
  trx->mysql_thd = session;
 
1576
  trx->mysql_query_str = session->query.c_str();
1578
1577
 
1579
1578
  innobase_trx_init(session, trx);
1580
1579
 
1804
1803
/*===============*/
1805
1804
  trx_t*  trx)  /*!< in: transaction */
1806
1805
{
1807
 
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1808
 
}
1809
 
 
1810
 
/**********************************************************************//**
1811
 
Determines if the currently running transaction is in strict mode.
1812
 
@return TRUE if strict */
1813
 
extern "C" UNIV_INTERN
1814
 
ibool
1815
 
trx_is_strict(
1816
 
/*==========*/
1817
 
        trx_t*  trx)    /*!< in: transaction */
1818
 
{
1819
 
        return(trx && trx->mysql_thd
1820
 
               && true);
 
1806
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1821
1807
}
1822
1808
 
1823
1809
/**************************************************************//**
1839
1825
  value= value - (value % align_val);
1840
1826
}
1841
1827
 
1842
 
static void auto_extend_update(Session *, sql_var_t)
1843
 
{
1844
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1845
 
}
1846
 
 
1847
 
static void io_capacity_update(Session *, sql_var_t)
1848
 
{
1849
 
  srv_io_capacity= innodb_io_capacity.get();
1850
 
}
1851
 
 
1852
 
static void purge_batch_update(Session *, sql_var_t)
1853
 
{
1854
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1855
 
}
1856
 
 
1857
 
static void purge_threads_update(Session *, sql_var_t)
1858
 
{
1859
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1860
 
}
1861
 
 
1862
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1863
 
{
1864
 
  if (btr_search_enabled)
1865
 
  {
1866
 
    btr_search_enable();
1867
 
  } else {
1868
 
    btr_search_disable();
1869
 
  }
1870
 
}
1871
 
 
1872
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1873
 
{
1874
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1875
 
}
1876
 
 
1877
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1878
 
{
1879
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1880
 
}
1881
 
 
1882
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1883
 
{
1884
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1885
 
}
1886
 
 
1887
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1888
 
{
1889
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1890
 
}
1891
 
 
1892
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1893
 
{
1894
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1895
 
}
1896
 
 
1897
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1898
 
{
1899
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1900
 
}
1901
 
 
1902
 
 
1903
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1904
 
{
1905
 
   uint32_t new_value= var->save_result.uint32_t_value;
1906
 
 
1907
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1908
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1909
 
   {
1910
 
     push_warning_printf(session,
1911
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1912
 
                         ER_WRONG_ARGUMENTS,
1913
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1914
 
                           "must not change between zero and nonzero."));
1915
 
     return 1;
1916
 
   }
1917
 
   return 0;
1918
 
}
1919
 
 
1920
 
/*************************************************************//**
1921
 
Check if it is a valid file format. This function is registered as
1922
 
a callback with MySQL.
1923
 
@return 0 for valid file format */
1924
 
static
1925
 
int
1926
 
innodb_file_format_name_validate(
1927
 
/*=============================*/
1928
 
  Session*      , /*!< in: thread handle */
1929
 
  set_var *var)
1930
 
{
1931
 
  const char *file_format_input = var->value->str_value.ptr();
1932
 
  if (file_format_input == NULL)
1933
 
    return 1;
1934
 
 
1935
 
  if (file_format_input != NULL) {
1936
 
    uint  format_id;
1937
 
 
1938
 
    format_id = innobase_file_format_name_lookup(
1939
 
      file_format_input);
1940
 
 
1941
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1942
 
      innobase_file_format_name =
1943
 
        trx_sys_file_format_id_to_name(format_id);
1944
 
 
1945
 
      return(0);
1946
 
    }
1947
 
  }
1948
 
 
1949
 
  return(1);
1950
 
}
1951
 
 
1952
 
/*************************************************************//**
1953
 
Check if it is a valid value of innodb_change_buffering. This function is
1954
 
registered as a callback with MySQL.
1955
 
@return 0 for valid innodb_change_buffering */
1956
 
static
1957
 
int
1958
 
innodb_change_buffering_validate(
1959
 
/*=============================*/
1960
 
  Session*      , /*!< in: thread handle */
1961
 
  set_var *var)
1962
 
{
1963
 
  const char *change_buffering_input = var->value->str_value.ptr();
1964
 
 
1965
 
  if (change_buffering_input == NULL)
1966
 
    return 1;
1967
 
 
1968
 
  ulint use;
1969
 
 
1970
 
  for (use = 0;
1971
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1972
 
       ++use) {
1973
 
    if (!innobase_strcasecmp(change_buffering_input,
1974
 
                             innobase_change_buffering_values[use]))
1975
 
    {
1976
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1977
 
      return 0;
1978
 
    }
1979
 
  }
1980
 
 
1981
 
  return 1;
1982
 
}
1983
 
 
1984
 
 
1985
 
/*************************************************************//**
1986
 
Check if valid argument to innodb_file_format_max. This function
1987
 
is registered as a callback with MySQL.
1988
 
@return 0 for valid file format */
1989
 
static
1990
 
int
1991
 
innodb_file_format_max_validate(
1992
 
/*==============================*/
1993
 
  Session*   session, /*!< in: thread handle */
1994
 
  set_var *var)
1995
 
{
1996
 
  const char *file_format_input = var->value->str_value.ptr();
1997
 
  if (file_format_input == NULL)
1998
 
    return 1;
1999
 
 
2000
 
  if (file_format_input != NULL) {
2001
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
2002
 
 
2003
 
    if (format_id > DICT_TF_FORMAT_MAX) {
2004
 
      /* DEFAULT is "on", which is invalid at runtime. */
2005
 
      return 1;
2006
 
    }
2007
 
 
2008
 
    if (format_id >= 0) {
2009
 
      innobase_file_format_max= 
2010
 
        trx_sys_file_format_id_to_name((uint)format_id);
2011
 
 
2012
 
      /* Update the max format id in the system tablespace. */
2013
 
      char name_buff[100];
2014
 
      strcpy(name_buff, innobase_file_format_max.c_str());
2015
 
      if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
2016
 
      {
2017
 
        errmsg_printf(ERRMSG_LVL_WARN,
2018
 
                      " [Info] InnoDB: the file format in the system "
2019
 
                      "tablespace is now set to %s.\n", name_buff);
2020
 
        innobase_file_format_max= name_buff;
2021
 
      }
2022
 
      return(0);
2023
 
 
2024
 
    } else {
2025
 
      push_warning_printf(session,
2026
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
2027
 
                          ER_WRONG_ARGUMENTS,
2028
 
                          "InnoDB: invalid innodb_file_format_max "
2029
 
                          "value; can be any format up to %s "
2030
 
                          "or equivalent id of %d",
2031
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
2032
 
                          DICT_TF_FORMAT_MAX);
2033
 
    }
2034
 
  }
2035
 
 
2036
 
  return(1);
2037
 
}
2038
 
 
2039
 
 
2040
1828
/*********************************************************************//**
2041
1829
Opens an InnoDB database.
2042
1830
@return 0 on success, error code on failure */
2052
1840
  InnobaseEngine *actuall_engine_ptr;
2053
1841
  const module::option_map &vm= context.getOptions();
2054
1842
 
2055
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2056
 
  srv_io_capacity= innodb_io_capacity.get();
2057
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2058
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2059
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2060
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2061
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2062
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2063
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2064
 
  srv_replication_delay= innodb_replication_delay.get();
2065
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2066
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2067
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2068
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2069
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2070
 
 
2071
1843
  /* Inverted Booleans */
2072
1844
 
2073
1845
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2074
1846
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2075
1847
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2076
1848
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2077
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2078
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2079
 
 
2080
 
 
2081
 
  /* Hafta do this here because we need to late-bind the default value */
 
1849
  (SessionVAR(NULL,support_xa))= (vm.count("disable-xa")) ? false : true;
 
1850
  (SessionVAR(NULL,table_locks))= (vm.count("disable-table-locks")) ? false : true;
 
1851
 
 
1852
  if (vm.count("io-capacity"))
 
1853
  {
 
1854
    if (srv_io_capacity < 100)
 
1855
    {
 
1856
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1857
      exit(-1);
 
1858
    }
 
1859
  }
 
1860
 
2082
1861
  if (vm.count("data-home-dir"))
2083
1862
  {
2084
 
    innobase_data_home_dir= vm["data-home-dir"].as<string>();
2085
 
  }
2086
 
  else
2087
 
  {
2088
 
    innobase_data_home_dir= getDataHome().file_string();
2089
 
  }
2090
 
 
 
1863
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1864
  }
 
1865
  else
 
1866
  {
 
1867
    innobase_data_home_dir= strdup(getDataHome().file_string().c_str());
 
1868
  }
 
1869
 
 
1870
  if (vm.count("fast-shutdown"))
 
1871
  {
 
1872
    if (innobase_fast_shutdown > 2)
 
1873
    {
 
1874
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1875
      exit(-1);
 
1876
    }
 
1877
  }
 
1878
 
 
1879
  if (vm.count("file-format-check"))
 
1880
  {
 
1881
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1882
  }
 
1883
 
 
1884
  if (vm.count("flush-log-at-trx-commit"))
 
1885
  {
 
1886
    if (srv_flush_log_at_trx_commit > 2)
 
1887
    {
 
1888
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1889
      exit(-1);
 
1890
    }
 
1891
  }
 
1892
 
 
1893
  if (vm.count("flush-method"))
 
1894
  {
 
1895
    innobase_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1896
  }
 
1897
  else
 
1898
  {
 
1899
    innobase_file_flush_method= NULL;
 
1900
  }
 
1901
 
 
1902
#ifdef UNIV_LOG_ARCHIVE
 
1903
  if (vm.count("log-arch-dir"))
 
1904
  {
 
1905
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1906
  }
 
1907
 
 
1908
  else
 
1909
  {
 
1910
    innobase_log_arch_dir= NULL;
 
1911
  }
 
1912
#endif /* UNIV_LOG_ARCHIVE */
 
1913
 
 
1914
  if (vm.count("max-dirty-pages-pct"))
 
1915
  {
 
1916
    if (srv_max_buf_pool_modified_pct > 99)
 
1917
    {
 
1918
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1919
      exit(-1);
 
1920
    }
 
1921
  }
 
1922
 
 
1923
  if (vm.count("stats-sample-pages"))
 
1924
  {
 
1925
    if (srv_stats_sample_pages < 8)
 
1926
    {
 
1927
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1928
      exit(-1);
 
1929
    }
 
1930
  }
 
1931
 
 
1932
  if (vm.count("additional-mem-pool-size"))
 
1933
  {
 
1934
    align_value(innobase_additional_mem_pool_size);
 
1935
 
 
1936
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1937
    {
 
1938
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1939
      exit(-1);
 
1940
    }
 
1941
 
 
1942
  }
 
1943
 
 
1944
  if (vm.count("autoextend-increment"))
 
1945
  {
 
1946
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1947
    {
 
1948
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1949
      exit(-1);
 
1950
    }
 
1951
  }
 
1952
 
 
1953
  if (vm.count("buffer-pool-size"))
 
1954
  {
 
1955
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1956
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1957
    {
 
1958
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1959
      exit(-1);
 
1960
    }
 
1961
    
 
1962
  }
 
1963
 
 
1964
  if (vm.count("commit-concurrency"))
 
1965
  {
 
1966
    if (srv_replication_delay > 1000)
 
1967
    {
 
1968
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1969
      exit(-1);
 
1970
    }
 
1971
  }
 
1972
 
 
1973
  if (vm.count("concurrency-tickets"))
 
1974
  {
 
1975
    if (srv_n_free_tickets_to_enter < 1)
 
1976
    {
 
1977
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1978
      exit(-1);
 
1979
    }
 
1980
  }
 
1981
 
 
1982
  if (vm.count("read-io-threads"))
 
1983
  {
 
1984
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1985
    {
 
1986
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1987
      exit(-1);
 
1988
    }
 
1989
  }
 
1990
 
 
1991
  if (vm.count("write-io-threads"))
 
1992
  {
 
1993
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
1994
    {
 
1995
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
1996
      exit(-1);
 
1997
    }
 
1998
  }
 
1999
 
 
2000
  if (vm.count("force-recovery"))
 
2001
  {
 
2002
    if (innobase_force_recovery > 6)
 
2003
    {
 
2004
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
2005
      exit(-1);
 
2006
    }
 
2007
  }
 
2008
 
 
2009
  if (vm.count("log-buffer-size"))
 
2010
  {
 
2011
    align_value(innobase_log_buffer_size);
 
2012
    if (innobase_log_buffer_size < 256*1024L)
 
2013
    {
 
2014
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2015
      exit(-1);
 
2016
    }
 
2017
  }
 
2018
 
 
2019
  if (vm.count("log-file-size"))
 
2020
  {
 
2021
    align_value(innobase_log_file_size, 1024*1024);
 
2022
    if (innobase_log_file_size < 1*1024*1024L)
 
2023
    {
 
2024
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2025
      exit(-1);
 
2026
    }
 
2027
  }
 
2028
 
 
2029
  if (vm.count("log-files-in-group"))
 
2030
  {
 
2031
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2032
    {
 
2033
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2034
      exit(-1);
 
2035
    }
 
2036
  }
 
2037
 
 
2038
  if (vm.count("mirrored-log-groups"))
 
2039
  {
 
2040
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2041
    {
 
2042
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2043
      exit(-1);
 
2044
    }
 
2045
  }
 
2046
 
 
2047
  if (vm.count("open-files"))
 
2048
  {
 
2049
    if (innobase_open_files < 10)
 
2050
    {
 
2051
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2052
      exit(-1);
 
2053
    }
 
2054
  }
 
2055
 
 
2056
  if (vm.count("thread-concurrency"))
 
2057
  {
 
2058
    if (srv_thread_concurrency > 1000)
 
2059
    {
 
2060
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2061
      exit(-1);
 
2062
    }
 
2063
  }
2091
2064
 
2092
2065
  if (vm.count("data-file-path"))
2093
2066
  {
2094
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2095
 
  }
2096
 
 
 
2067
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2068
  }
 
2069
  else
 
2070
  {
 
2071
    innobase_data_file_path= NULL;
 
2072
  }
 
2073
 
 
2074
  if (vm.count("version"))
 
2075
  {
 
2076
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2077
  }
 
2078
 
 
2079
  if (vm.count("read-ahead-threshold"))
 
2080
  {
 
2081
    if (srv_read_ahead_threshold > 64)
 
2082
    {
 
2083
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2084
      exit(-1);
 
2085
    }
 
2086
  }
 
2087
 
 
2088
  if (vm.count("strict-mode"))
 
2089
  {
 
2090
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2091
  }
 
2092
 
 
2093
  if (vm.count("lock-wait-timeout"))
 
2094
  {
 
2095
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2096
    {
 
2097
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2098
      exit(-1);
 
2099
    }
 
2100
 
 
2101
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2102
  }
2097
2103
 
2098
2104
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2099
2105
 
2117
2123
  }
2118
2124
#endif /* UNIV_DEBUG */
2119
2125
 
 
2126
  /* Check that values don't overflow on 32-bit systems. */
 
2127
  if (sizeof(ulint) == 4) {
 
2128
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2129
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2130
                    "innobase_buffer_pool_size can't be over 4GB"
 
2131
                    " on 32-bit systems");
 
2132
 
 
2133
      goto error;
 
2134
    }
 
2135
 
 
2136
    if (innobase_log_file_size > UINT32_MAX) {
 
2137
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2138
                    "innobase_log_file_size can't be over 4GB"
 
2139
                    " on 32-bit systems");
 
2140
 
 
2141
      goto error;
 
2142
    }
 
2143
  }
 
2144
 
2120
2145
  os_innodb_umask = (ulint)internal::my_umask;
2121
2146
 
2122
2147
 
2127
2152
 
2128
2153
  /* The default dir for data files is the datadir of MySQL */
2129
2154
 
2130
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2155
  srv_data_home = (char *)innobase_data_home_dir;
2131
2156
 
2132
2157
  /* Set default InnoDB data file size to 10 MB and let it be
2133
2158
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2134
2159
    to specify any startup options. */
2135
2160
 
2136
 
  if (innobase_data_file_path.empty()) 
2137
 
  {
2138
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2161
  if (!innobase_data_file_path) {
 
2162
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2139
2163
  }
2140
2164
 
2141
2165
  /* Since InnoDB edits the argument in the next call, we make another
2142
2166
    copy of it: */
2143
2167
 
2144
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2168
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2145
2169
 
2146
2170
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2147
2171
                                                   internal_innobase_data_file_path);
2161
2185
 
2162
2186
  if (vm.count("log-group-home-dir"))
2163
2187
  {
2164
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2188
    innobase_log_group_home_dir= strdup(vm["log-group-home-dir"].as<string>().c_str());
2165
2189
  }
2166
2190
  else
2167
2191
  {
2168
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2192
    innobase_log_group_home_dir = strdup(getDataHome().file_string().c_str());
2169
2193
  }
2170
2194
 
 
2195
#ifdef UNIV_LOG_ARCHIVE
 
2196
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2197
    starting from 4.0.6 we always set it the same as
 
2198
innodb_log_group_home_dir: */
 
2199
 
 
2200
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2201
 
 
2202
  srv_arch_dir = innobase_log_arch_dir;
 
2203
#endif /* UNIG_LOG_ARCHIVE */
 
2204
 
2171
2205
  ret = (bool)
2172
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2206
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2173
2207
 
2174
 
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2175
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2176
 
                  _("syntax error in innodb_log_group_home_dir, or a "
2177
 
                  "wrong number of mirrored log groups"));
 
2208
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2209
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2210
                  "wrong number of mirrored log groups");
2178
2211
 
2179
2212
    goto mem_free_and_error;
2180
2213
  }
2199
2232
 
2200
2233
  srv_file_format = format_id;
2201
2234
 
2202
 
  innobase_file_format_name =
2203
 
    trx_sys_file_format_id_to_name(format_id);
2204
 
 
2205
 
  /* Check innobase_file_format_check variable */
2206
 
  if (!innobase_file_format_check)
2207
 
  {
2208
 
    /* Set the value to disable checking. */
2209
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
2210
 
  } else {
2211
 
    /* Set the value to the lowest supported format. */
2212
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN;
2213
 
  }
2214
 
 
2215
 
  /* Did the user specify a format name that we support?
2216
 
     As a side effect it will update the variable
2217
 
     srv_max_file_format_at_startup */
2218
 
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2219
 
  {
2220
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
2221
 
                    "innodb_file_format_max value: "
2222
 
                    "should be any value up to %s or its "
2223
 
                    "equivalent numeric id"),
2224
 
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2225
 
    goto mem_free_and_error;
 
2235
  /* Given the type of innobase_file_format_name we have little
 
2236
    choice but to cast away the constness from the returned name.
 
2237
    innobase_file_format_name is used in the MySQL set variable
 
2238
    interface and so can't be const. */
 
2239
 
 
2240
  innobase_file_format_name = 
 
2241
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2242
 
 
2243
  /* Process innobase_file_format_check variable */
 
2244
  ut_a(innobase_file_format_check != NULL);
 
2245
 
 
2246
  /* As a side effect it will set srv_check_file_format_at_startup
 
2247
    on valid input. First we check for "on"/"off". */
 
2248
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2249
 
 
2250
    /* Did the user specify a format name that we support ?
 
2251
      As a side effect it will update the variable
 
2252
      srv_check_file_format_at_startup */
 
2253
    if (innobase_file_format_validate_and_set(
 
2254
                                innobase_file_format_check) < 0) {
 
2255
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2256
                    "innodb_file_format_check value: "
 
2257
                    "should be either 'on' or 'off' or "
 
2258
                    "any value up to %s or its "
 
2259
                    "equivalent numeric id",
 
2260
                    trx_sys_file_format_id_to_name(
 
2261
                                                   DICT_TF_FORMAT_MAX));
 
2262
 
 
2263
      goto mem_free_and_error;
 
2264
    }
2226
2265
  }
2227
2266
 
2228
2267
  if (vm.count("change-buffering"))
2233
2272
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2234
2273
         use++) {
2235
2274
      if (!innobase_strcasecmp(
2236
 
                               innobase_change_buffering.c_str(),
 
2275
                               vm["change-buffering"].as<string>().c_str(),
2237
2276
                               innobase_change_buffering_values[use])) {
2238
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2277
        ibuf_use = (ibuf_use_t) use;
2239
2278
        goto innobase_change_buffering_inited_ok;
2240
2279
      }
2241
2280
    }
2242
2281
 
2243
2282
    errmsg_printf(ERRMSG_LVL_ERROR,
2244
2283
                  "InnoDB: invalid value "
2245
 
                  "innodb_change_buffering=%s",
 
2284
                  "innodb_file_format_check=%s",
2246
2285
                  vm["change-buffering"].as<string>().c_str());
2247
2286
    goto mem_free_and_error;
2248
2287
  }
2249
2288
 
2250
2289
innobase_change_buffering_inited_ok:
2251
2290
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2252
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2291
  innobase_change_buffering = (char*)
 
2292
    innobase_change_buffering_values[ibuf_use];
2253
2293
 
2254
2294
  /* --------------------------------------------------*/
2255
2295
 
2256
 
  if (vm.count("flush-method") != 0)
2257
 
  {
2258
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2259
 
  }
 
2296
  srv_file_flush_method_str = innobase_file_flush_method;
2260
2297
 
2261
2298
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2262
2299
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2263
2300
  srv_log_file_size = (ulint) innobase_log_file_size;
2264
2301
 
 
2302
#ifdef UNIV_LOG_ARCHIVE
 
2303
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2304
#endif /* UNIV_LOG_ARCHIVE */
2265
2305
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2266
2306
 
2267
2307
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2268
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2269
2308
 
2270
2309
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2271
2310
 
2296
2335
 
2297
2336
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2298
2337
 
 
2338
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct,
 
2339
                                                     FALSE);
 
2340
 
 
2341
  innobase_commit_concurrency_init_default();
 
2342
 
2299
2343
  /* Since we in this module access directly the fields of a trx
2300
2344
    struct, and due to different headers and flags it might happen that
2301
2345
    mutex_t has a different size in this module and in InnoDB
2304
2348
 
2305
2349
  err = innobase_start_or_create_for_mysql();
2306
2350
 
2307
 
  if (err != DB_SUCCESS)
2308
 
  {
2309
 
    goto mem_free_and_error;
2310
 
  }
2311
 
 
2312
 
  err = dict_create_sys_replication_log();
2313
 
 
2314
2351
  if (err != DB_SUCCESS) {
2315
2352
    goto mem_free_and_error;
2316
2353
  }
2317
2354
 
2318
 
 
2319
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2320
 
                                                     TRUE);
2321
 
 
2322
2355
  innobase_open_tables = hash_create(200);
2323
2356
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2324
2357
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2325
2358
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2326
2359
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2360
  pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
2327
2361
  pthread_cond_init(&commit_cond, NULL);
2328
2362
  innodb_inited= 1;
2329
2363
 
2356
2390
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2357
2391
  context.add(innodb_lock_waits_tool);
2358
2392
 
2359
 
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2360
 
  context.add(innodb_sys_tables_tool);
2361
 
 
2362
 
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2363
 
  context.add(innodb_sys_tablestats_tool);
2364
 
 
2365
 
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2366
 
  context.add(innodb_sys_indexes_tool);
2367
 
 
2368
 
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2369
 
  context.add(innodb_sys_columns_tool);
2370
 
 
2371
 
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2372
 
  context.add(innodb_sys_fields_tool);
2373
 
 
2374
 
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2375
 
  context.add(innodb_sys_foreign_tool);
2376
 
 
2377
 
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2378
 
  context.add(innodb_sys_foreign_cols_tool);
2379
 
 
2380
2393
  context.add(new(std::nothrow)InnodbInternalTables());
2381
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2382
 
 
2383
 
  if (innobase_use_replication_log)
2384
 
  {
2385
 
    replication_logger= new(std::nothrow)ReplicationLog();
2386
 
    context.add(replication_logger);
2387
 
    ReplicationLog::setup(replication_logger);
2388
 
  }
2389
 
 
2390
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2391
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2392
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2393
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2394
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2395
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2396
 
 
2397
 
 
2398
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2399
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2400
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2401
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2402
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2403
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2404
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2405
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2406
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2407
 
 
2408
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2409
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2410
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2411
 
 
2412
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2413
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2414
 
                                                                   innodb_auto_extend_increment,
2415
 
                                                                   auto_extend_update));
2416
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2417
 
                                                                   innodb_io_capacity,
2418
 
                                                                   io_capacity_update));
2419
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2420
 
                                                                   innodb_purge_batch_size,
2421
 
                                                                   purge_batch_update));
2422
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2423
 
                                                                   innodb_n_purge_threads,
2424
 
                                                                   purge_threads_update));
2425
 
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
2426
 
  context.registerVariable(new sys_var_std_string("file_format",
2427
 
                                                  innobase_file_format_name,
2428
 
                                                  innodb_file_format_name_validate));
2429
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2430
 
                                                  innobase_change_buffering,
2431
 
                                                  innodb_change_buffering_validate));
2432
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2433
 
                                                  innobase_file_format_max,
2434
 
                                                  innodb_file_format_max_validate));
2435
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2436
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2437
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2438
 
                                                  innodb_flush_log_at_trx_commit));
2439
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2440
 
                                                  innodb_max_dirty_pages_pct));
2441
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2442
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2443
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2444
 
 
2445
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2446
 
                                                                   innobase_commit_concurrency,
2447
 
                                                                   innodb_commit_concurrency_validate));
2448
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2449
 
                                                                   innodb_concurrency_tickets));
2450
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2451
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2452
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2453
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2454
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2455
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2456
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2457
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2458
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2459
 
                                                                   innobase_old_blocks_pct,
2460
 
                                                                   innodb_old_blocks_pct_update));
2461
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2462
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2463
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2464
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2465
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2466
 
                                                                   innobase_thread_concurrency,
2467
 
                                                                   innodb_thread_concurrency_update));
2468
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2469
 
                                                                   innodb_read_ahead_threshold,
2470
 
                                                                   innodb_read_ahead_threshold_update));
 
2394
 
2471
2395
  /* Get the current high water mark format. */
2472
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2473
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2396
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2474
2397
 
2475
2398
  return(FALSE);
2476
2399
error:
2579
2502
    Note, the position is current because of
2580
2503
    prepare_commit_mutex */
2581
2504
retry:
2582
 
    if (innobase_commit_concurrency.get() > 0) {
 
2505
    if (innobase_commit_concurrency > 0) {
2583
2506
      pthread_mutex_lock(&commit_cond_m);
2584
2507
      commit_threads++;
2585
2508
 
2586
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
2509
      if (commit_threads > innobase_commit_concurrency) {
2587
2510
        commit_threads--;
2588
2511
        pthread_cond_wait(&commit_cond,
2589
2512
          &commit_cond_m);
2608
2531
    innobase_commit_low(trx);
2609
2532
    trx->flush_log_later = FALSE;
2610
2533
 
2611
 
    if (innobase_commit_concurrency.get() > 0) {
 
2534
    if (innobase_commit_concurrency > 0) {
2612
2535
      pthread_mutex_lock(&commit_cond_m);
2613
2536
      commit_threads--;
2614
2537
      pthread_cond_signal(&commit_cond);
2632
2555
    SQL statement */
2633
2556
 
2634
2557
    trx_mark_sql_stat_end(trx);
2635
 
 
2636
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2637
 
    {
2638
 
      if (trx->conc_state != TRX_NOT_STARTED)
2639
 
      {
2640
 
        commit(session, TRUE);
2641
 
      }
2642
 
    }
2643
2558
  }
2644
2559
 
2645
2560
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2654
2569
  threads: */
2655
2570
  srv_active_wake_master_thread();
2656
2571
 
2657
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2658
 
      trx->global_read_view)
2659
 
  {
2660
 
    /* At low transaction isolation levels we let
2661
 
       each consistent read set its own snapshot */
2662
 
    read_view_close_for_mysql(trx);
2663
 
  }
2664
 
 
2665
2572
  return(0);
2666
2573
}
2667
2574
 
2705
2612
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2706
2613
  }
2707
2614
 
2708
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2709
 
      trx->global_read_view)
2710
 
  {
2711
 
    /* At low transaction isolation levels we let
2712
 
       each consistent read set its own snapshot */
2713
 
    read_view_close_for_mysql(trx);
2714
 
  }
2715
 
 
2716
2615
  return(convert_error_code_to_mysql(error, 0, NULL));
2717
2616
}
2718
2617
 
2849
2748
 
2850
2749
  ut_a(trx);
2851
2750
 
2852
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2751
  assert(session->killed != Session::NOT_KILLED ||
2853
2752
         trx->conc_state == TRX_NOT_STARTED);
2854
2753
 
2855
2754
  /* Warn if rolling back some things... */
2856
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2755
  if (session->killed != Session::NOT_KILLED &&
2857
2756
      trx->conc_state != TRX_NOT_STARTED &&
2858
 
      trx->undo_no > 0 &&
 
2757
      trx->undo_no.low > 0 &&
2859
2758
      global_system_variables.log_warnings)
2860
2759
  {
2861
 
      errmsg_printf(ERRMSG_LVL_WARN,
 
2760
      errmsg_printf(ERRMSG_LVL_WARN, 
2862
2761
      "Drizzle is closing a connection during a KILL operation\n"
2863
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2762
      "that has an active InnoDB transaction.  %lu row modifications will "
2864
2763
      "roll back.\n",
2865
 
      (ullint) trx->undo_no);
 
2764
      (ulong) trx->undo_no.low);
2866
2765
  }
2867
2766
 
2868
2767
  innobase_rollback_trx(trx);
2985
2884
}
2986
2885
 
2987
2886
/********************************************************************//**
2988
 
Get the upper limit of the MySQL integral and floating-point type.
2989
 
@return maximum allowed value for the field */
2990
 
static
2991
 
uint64_t
2992
 
innobase_get_int_col_max_value(
2993
 
/*===========================*/
2994
 
        const Field*    field)  /*!< in: MySQL field */
2995
 
{
2996
 
        uint64_t        max_value = 0;
2997
 
 
2998
 
        switch(field->key_type()) {
2999
 
        /* TINY */
3000
 
        case HA_KEYTYPE_BINARY:
3001
 
                max_value = 0xFFULL;
3002
 
                break;
3003
 
        /* LONG */
3004
 
        case HA_KEYTYPE_ULONG_INT:
3005
 
                max_value = 0xFFFFFFFFULL;
3006
 
                break;
3007
 
        case HA_KEYTYPE_LONG_INT:
3008
 
                max_value = 0x7FFFFFFFULL;
3009
 
                break;
3010
 
        /* BIG */
3011
 
        case HA_KEYTYPE_ULONGLONG:
3012
 
                max_value = 0xFFFFFFFFFFFFFFFFULL;
3013
 
                break;
3014
 
        case HA_KEYTYPE_LONGLONG:
3015
 
                max_value = 0x7FFFFFFFFFFFFFFFULL;
3016
 
                break;
3017
 
        case HA_KEYTYPE_DOUBLE:
3018
 
                /* We use the maximum as per IEEE754-2008 standard, 2^53 */
3019
 
                max_value = 0x20000000000000ULL;
3020
 
                break;
3021
 
        default:
3022
 
                ut_error;
3023
 
        }
3024
 
 
3025
 
        return(max_value);
3026
 
}
3027
 
 
3028
 
/*******************************************************************//**
3029
 
This function checks whether the index column information
3030
 
is consistent between KEY info from mysql and that from innodb index.
3031
 
@return TRUE if all column types match. */
3032
 
static
3033
 
ibool
3034
 
innobase_match_index_columns(
3035
 
/*=========================*/
3036
 
        const KeyInfo*          key_info,       /*!< in: Index info
3037
 
                                                from mysql */
3038
 
        const dict_index_t*     index_info)     /*!< in: Index info
3039
 
                                                from Innodb */
3040
 
{
3041
 
        const KeyPartInfo*      key_part;
3042
 
        const KeyPartInfo*      key_end;
3043
 
        const dict_field_t*     innodb_idx_fld;
3044
 
        const dict_field_t*     innodb_idx_fld_end;
3045
 
 
3046
 
        /* Check whether user defined index column count matches */
3047
 
        if (key_info->key_parts != index_info->n_user_defined_cols) {
3048
 
                return(FALSE);
3049
 
        }
3050
 
 
3051
 
        key_part = key_info->key_part;
3052
 
        key_end = key_part + key_info->key_parts;
3053
 
        innodb_idx_fld = index_info->fields;
3054
 
        innodb_idx_fld_end = index_info->fields + index_info->n_fields;
3055
 
 
3056
 
        /* Check each index column's datatype. We do not check
3057
 
        column name because there exists case that index
3058
 
        column name got modified in mysql but such change does not
3059
 
        propagate to InnoDB.
3060
 
        One hidden assumption here is that the index column sequences
3061
 
        are matched up between those in mysql and Innodb. */
3062
 
        for (; key_part != key_end; ++key_part) {
3063
 
                ulint   col_type;
3064
 
                ibool   is_unsigned;
3065
 
                ulint   mtype = innodb_idx_fld->col->mtype;
3066
 
 
3067
 
                /* Need to translate to InnoDB column type before
3068
 
                comparison. */
3069
 
                col_type = get_innobase_type_from_mysql_type(&is_unsigned,
3070
 
                                                             key_part->field);
3071
 
 
3072
 
                /* Ignore Innodb specific system columns. */
3073
 
                while (mtype == DATA_SYS) {
3074
 
                        innodb_idx_fld++;
3075
 
 
3076
 
                        if (innodb_idx_fld >= innodb_idx_fld_end) {
3077
 
                                return(FALSE);
3078
 
                        }
3079
 
                }
3080
 
 
3081
 
                if (col_type != mtype) {
3082
 
                        /* Column Type mismatches */
3083
 
                        return(FALSE);
3084
 
                }
3085
 
 
3086
 
                innodb_idx_fld++;
3087
 
        }
3088
 
 
3089
 
        return(TRUE);
3090
 
}
3091
 
 
3092
 
/*******************************************************************//**
3093
 
This function builds a translation table in INNOBASE_SHARE
3094
 
structure for fast index location with mysql array number from its
3095
 
table->key_info structure. This also provides the necessary translation
3096
 
between the key order in mysql key_info and Innodb ib_table->indexes if
3097
 
they are not fully matched with each other.
3098
 
Note we do not have any mutex protecting the translation table
3099
 
building based on the assumption that there is no concurrent
3100
 
index creation/drop and DMLs that requires index lookup. All table
3101
 
handle will be closed before the index creation/drop.
3102
 
@return TRUE if index translation table built successfully */
3103
 
static
3104
 
ibool
3105
 
innobase_build_index_translation(
3106
 
/*=============================*/
3107
 
        const Table*            table,    /*!< in: table in MySQL data
3108
 
                                          dictionary */
3109
 
        dict_table_t*           ib_table, /*!< in: table in Innodb data
3110
 
                                          dictionary */
3111
 
        INNOBASE_SHARE*         share)    /*!< in/out: share structure
3112
 
                                          where index translation table
3113
 
                                          will be constructed in. */
3114
 
{
3115
 
        ulint           mysql_num_index;
3116
 
        ulint           ib_num_index;
3117
 
        dict_index_t**  index_mapping;
3118
 
        ibool           ret = TRUE;
3119
 
 
3120
 
        mutex_enter(&dict_sys->mutex);
3121
 
 
3122
 
        mysql_num_index = table->getShare()->keys;
3123
 
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3124
 
 
3125
 
        index_mapping = share->idx_trans_tbl.index_mapping;
3126
 
 
3127
 
        /* If there exists inconsistency between MySQL and InnoDB dictionary
3128
 
        (metadata) information, the number of index defined in MySQL
3129
 
        could exceed that in InnoDB, do not build index translation
3130
 
        table in such case */
3131
 
        if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3132
 
                ret = FALSE;
3133
 
                goto func_exit;
3134
 
        }
3135
 
 
3136
 
        /* If index entry count is non-zero, nothing has
3137
 
        changed since last update, directly return TRUE */
3138
 
        if (share->idx_trans_tbl.index_count) {
3139
 
                /* Index entry count should still match mysql_num_index */
3140
 
                ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
3141
 
                goto func_exit;
3142
 
        }
3143
 
 
3144
 
        /* The number of index increased, rebuild the mapping table */
3145
 
        if (mysql_num_index > share->idx_trans_tbl.array_size) {
3146
 
                index_mapping = (dict_index_t**) realloc(index_mapping,
3147
 
                                                        mysql_num_index *
3148
 
                                                         sizeof(*index_mapping));
3149
 
 
3150
 
                if (!index_mapping) {
3151
 
                        /* Report an error if index_mapping continues to be
3152
 
                        NULL and mysql_num_index is a non-zero value */
3153
 
                        errmsg_printf(ERRMSG_LVL_ERROR,
3154
 
                                      "InnoDB: fail to allocate memory for "
3155
 
                                        "index translation table. Number of "
3156
 
                                        "Index:%lu, array size:%lu",
3157
 
                                        mysql_num_index,
3158
 
                                        share->idx_trans_tbl.array_size);
3159
 
                        ret = FALSE;
3160
 
                        goto func_exit;
3161
 
                }
3162
 
 
3163
 
                share->idx_trans_tbl.array_size = mysql_num_index;
3164
 
        }
3165
 
 
3166
 
        /* For each index in the mysql key_info array, fetch its
3167
 
        corresponding InnoDB index pointer into index_mapping
3168
 
        array. */
3169
 
        for (ulint count = 0; count < mysql_num_index; count++) {
3170
 
 
3171
 
                /* Fetch index pointers into index_mapping according to mysql
3172
 
                index sequence */
3173
 
                index_mapping[count] = dict_table_get_index_on_name(
3174
 
                        ib_table, table->key_info[count].name);
3175
 
 
3176
 
                if (!index_mapping[count]) {
3177
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
3178
 
                                        "index dictionary.",
3179
 
                                        table->key_info[count].name);
3180
 
                        ret = FALSE;
3181
 
                        goto func_exit;
3182
 
                }
3183
 
 
3184
 
                /* Double check fetched index has the same
3185
 
                column info as those in mysql key_info. */
3186
 
                if (!innobase_match_index_columns(&table->key_info[count],
3187
 
                                                  index_mapping[count])) {
3188
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
3189
 
                                        "does not match that of MySQL.",
3190
 
                                        table->key_info[count].name);
3191
 
                        ret = FALSE;
3192
 
                        goto func_exit;
3193
 
                }
3194
 
        }
3195
 
 
3196
 
        /* Successfully built the translation table */
3197
 
        share->idx_trans_tbl.index_count = mysql_num_index;
3198
 
 
3199
 
func_exit:
3200
 
        if (!ret) {
3201
 
                /* Build translation table failed. */
3202
 
                free(index_mapping);
3203
 
 
3204
 
                share->idx_trans_tbl.array_size = 0;
3205
 
                share->idx_trans_tbl.index_count = 0;
3206
 
                index_mapping = NULL;
3207
 
        }
3208
 
 
3209
 
        share->idx_trans_tbl.index_mapping = index_mapping;
3210
 
 
3211
 
        mutex_exit(&dict_sys->mutex);
3212
 
 
3213
 
        return(ret);
3214
 
}
3215
 
 
3216
 
/*******************************************************************//**
3217
 
This function uses index translation table to quickly locate the
3218
 
requested index structure.
3219
 
Note we do not have mutex protection for the index translatoin table
3220
 
access, it is based on the assumption that there is no concurrent
3221
 
translation table rebuild (fter create/drop index) and DMLs that
3222
 
require index lookup.
3223
 
@return dict_index_t structure for requested index. NULL if
3224
 
fail to locate the index structure. */
3225
 
static
3226
 
dict_index_t*
3227
 
innobase_index_lookup(
3228
 
/*==================*/
3229
 
        INNOBASE_SHARE* share,  /*!< in: share structure for index
3230
 
                                translation table. */
3231
 
        uint            keynr)  /*!< in: index number for the requested
3232
 
                                index */
3233
 
{
3234
 
        if (!share->idx_trans_tbl.index_mapping
3235
 
            || keynr >= share->idx_trans_tbl.index_count) {
3236
 
                return(NULL);
3237
 
        }
3238
 
 
3239
 
        return(share->idx_trans_tbl.index_mapping[keynr]);
3240
 
}
3241
 
 
3242
 
/********************************************************************//**
3243
2887
Set the autoinc column max value. This should only be called once from
3244
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2888
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2889
@return DB_SUCCESS or error code */
3245
2890
UNIV_INTERN
3246
 
void
 
2891
ulint
3247
2892
ha_innobase::innobase_initialize_autoinc()
3248
2893
/*======================================*/
3249
2894
{
 
2895
  dict_index_t* index;
3250
2896
  uint64_t  auto_inc;
3251
 
  const Field*  field = getTable()->found_next_number_field;
3252
 
 
3253
 
  if (field != NULL) {
3254
 
    auto_inc = innobase_get_int_col_max_value(field);
3255
 
  } else {
3256
 
    /* We have no idea what's been passed in to us as the
3257
 
       autoinc column. We set it to the 0, effectively disabling
3258
 
       updates to the table. */
3259
 
    auto_inc = 0;
3260
 
 
 
2897
  const char* col_name;
 
2898
  ulint   error;
 
2899
 
 
2900
  col_name = getTable()->found_next_number_field->field_name;
 
2901
  index = innobase_get_index(getTable()->getShare()->next_number_index);
 
2902
 
 
2903
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2904
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2905
 
 
2906
  switch (error) {
 
2907
  case DB_SUCCESS:
 
2908
 
 
2909
    /* At the this stage we don't know the increment
 
2910
    or the offset, so use default inrement of 1. */
 
2911
    ++auto_inc;
 
2912
    break;
 
2913
 
 
2914
  case DB_RECORD_NOT_FOUND:
3261
2915
    ut_print_timestamp(stderr);
3262
 
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
3263
 
            "column name\n");
3264
 
  }
3265
 
 
3266
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3267
 
    /* If the recovery level is set so high that writes
3268
 
       are disabled we force the AUTOINC counter to 0
3269
 
       value effectively disabling writes to the table.
3270
 
       Secondly, we avoid reading the table in case the read
3271
 
       results in failure due to a corrupted table/index.
3272
 
 
3273
 
       We will not return an error to the client, so that the
3274
 
       tables can be dumped with minimal hassle.  If an error
3275
 
       were returned in this case, the first attempt to read
3276
 
       the table would fail and subsequent SELECTs would succeed. */
3277
 
    auto_inc = 0;
3278
 
  } else if (field == NULL) {
3279
 
    /* This is a far more serious error, best to avoid
3280
 
       opening the table and return failure. */
3281
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3282
 
  } else {
3283
 
    dict_index_t*       index;
3284
 
    const char* col_name;
3285
 
    uint64_t    read_auto_inc;
3286
 
    ulint               err;
3287
 
 
3288
 
    update_session(getTable()->in_use);
3289
 
    col_name = field->field_name;
3290
 
 
3291
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3292
 
 
3293
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3294
 
 
3295
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3296
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3297
 
 
3298
 
    switch (err) {
3299
 
    case DB_SUCCESS: {
3300
 
      uint64_t col_max_value;
3301
 
 
3302
 
      col_max_value = innobase_get_int_col_max_value(field);
3303
 
 
3304
 
      /* At the this stage we do not know the increment
3305
 
         nor the offset, so use a default increment of 1. */
3306
 
 
3307
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3308
 
 
3309
 
      break;
3310
 
    }
3311
 
    case DB_RECORD_NOT_FOUND:
3312
 
      ut_print_timestamp(stderr);
3313
 
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3314
 
              "dictionaries are out of sync.\n"
3315
 
              "InnoDB: Unable to find the AUTOINC column "
3316
 
              "%s in the InnoDB table %s.\n"
3317
 
              "InnoDB: We set the next AUTOINC column "
3318
 
              "value to 0,\n"
3319
 
              "InnoDB: in effect disabling the AUTOINC "
3320
 
              "next value generation.\n"
3321
 
              "InnoDB: You can either set the next "
3322
 
              "AUTOINC value explicitly using ALTER TABLE\n"
3323
 
              "InnoDB: or fix the data dictionary by "
3324
 
              "recreating the table.\n",
3325
 
              col_name, index->table->name);
3326
 
 
3327
 
      /* This will disable the AUTOINC generation. */
3328
 
      auto_inc = 0;
3329
 
 
3330
 
      /* We want the open to succeed, so that the user can
3331
 
         take corrective action. ie. reads should succeed but
3332
 
         updates should fail. */
3333
 
      err = DB_SUCCESS;
3334
 
      break;
3335
 
    default:
3336
 
      /* row_search_max_autoinc() should only return
3337
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3338
 
      ut_error;
3339
 
    }
 
2916
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2917
      "dictionaries are out of sync.\n"
 
2918
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2919
      "InnoDB table %s.\n"
 
2920
      "InnoDB: We set the next AUTOINC column value to the "
 
2921
      "maximum possible value,\n"
 
2922
      "InnoDB: in effect disabling the AUTOINC next value "
 
2923
      "generation.\n"
 
2924
      "InnoDB: You can either set the next AUTOINC value "
 
2925
      "explicitly using ALTER TABLE\n"
 
2926
      "InnoDB: or fix the data dictionary by recreating "
 
2927
      "the table.\n",
 
2928
      col_name, index->table->name);
 
2929
 
 
2930
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2931
    break;
 
2932
 
 
2933
  default:
 
2934
    return(error);
3340
2935
  }
3341
2936
 
3342
2937
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2938
 
 
2939
  return(DB_SUCCESS);
3343
2940
}
3344
2941
 
3345
2942
/*****************************************************************//**
3456
3053
  primary_key = getTable()->getShare()->getPrimaryKey();
3457
3054
  key_used_on_scan = primary_key;
3458
3055
 
3459
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3460
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
3461
 
                    " Table %s failed", identifier.getPath().c_str());
3462
 
  }
3463
 
 
3464
3056
  /* Allocate a buffer for a 'row reference'. A row reference is
3465
3057
  a string of bytes of length ref_length which uniquely specifies
3466
3058
  a row in our table. Note that MySQL may also compare two row
3468
3060
  of length ref_length! */
3469
3061
 
3470
3062
  if (!row_table_got_default_clust_index(ib_table)) {
 
3063
    if (primary_key >= MAX_KEY) {
 
3064
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3065
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3066
    }
3471
3067
 
3472
3068
    prebuilt->clust_index_was_generated = FALSE;
3473
3069
 
3474
 
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3475
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3476
 
                    "InnoDB data dictionary, but not "
3477
 
                    "in MySQL!", identifier.getTableName().c_str());
3478
 
 
3479
 
      /* This mismatch could cause further problems
3480
 
         if not attended, bring this to the user's attention
3481
 
         by printing a warning in addition to log a message
3482
 
         in the errorlog */
3483
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3484
 
                          ER_NO_SUCH_INDEX,
3485
 
                          "InnoDB: Table %s has a "
3486
 
                          "primary key in InnoDB data "
3487
 
                          "dictionary, but not in "
3488
 
                          "MySQL!", identifier.getTableName().c_str());
3489
 
 
3490
 
      /* If primary_key >= MAX_KEY, its (primary_key)
3491
 
         value could be out of bound if continue to index
3492
 
         into key_info[] array. Find InnoDB primary index,
3493
 
         and assign its key_length to ref_length.
3494
 
         In addition, since MySQL indexes are sorted starting
3495
 
         with primary index, unique index etc., initialize
3496
 
         ref_length to the first index key length in
3497
 
         case we fail to find InnoDB cluster index.
3498
 
 
3499
 
         Please note, this will not resolve the primary
3500
 
         index mismatch problem, other side effects are
3501
 
         possible if users continue to use the table.
3502
 
         However, we allow this table to be opened so
3503
 
         that user can adopt necessary measures for the
3504
 
         mismatch while still being accessible to the table
3505
 
         date. */
3506
 
      ref_length = getTable()->key_info[0].key_length;
3507
 
 
3508
 
      /* Find correspoinding cluster index
3509
 
         key length in MySQL's key_info[] array */
3510
 
      for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3511
 
        dict_index_t*   index;
3512
 
        index = innobase_get_index(i);
3513
 
        if (dict_index_is_clust(index)) {
3514
 
          ref_length =
3515
 
            getTable()->key_info[i].key_length;
3516
 
        }
3517
 
      }
3518
 
    } else {
3519
 
      /* MySQL allocates the buffer for ref.
3520
 
         key_info->key_length includes space for all key
3521
 
         columns + one byte for each column that may be
3522
 
         NULL. ref_length must be as exact as possible to
3523
 
         save space, because all row reference buffers are
3524
 
         allocated based on ref_length. */
3525
 
 
3526
 
      ref_length = getTable()->key_info[primary_key].key_length;
3527
 
    }
 
3070
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3071
    includes space for all key columns + one byte for each column
 
3072
    that may be NULL. ref_length must be as exact as possible to
 
3073
    save space, because all row reference buffers are allocated
 
3074
    based on ref_length. */
 
3075
 
 
3076
    ref_length = getTable()->key_info[primary_key].key_length;
3528
3077
  } else {
3529
3078
    if (primary_key != MAX_KEY) {
3530
 
      errmsg_printf(ERRMSG_LVL_ERROR,
3531
 
                    "Table %s has no primary key in InnoDB data "
3532
 
                    "dictionary, but has one in MySQL! If you "
3533
 
                    "created the table with a MySQL version < "
3534
 
                    "3.23.54 and did not define a primary key, "
3535
 
                    "but defined a unique key with all non-NULL "
3536
 
                    "columns, then MySQL internally treats that "
3537
 
                    "key as the primary key. You can fix this "
3538
 
                    "error by dump + DROP + CREATE + reimport "
3539
 
                    "of the table.", identifier.getTableName().c_str());
3540
 
 
3541
 
      /* This mismatch could cause further problems
3542
 
         if not attended, bring this to the user attention
3543
 
         by printing a warning in addition to log a message
3544
 
         in the errorlog */
3545
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3546
 
                          ER_NO_SUCH_INDEX,
3547
 
                          "InnoDB: Table %s has no "
3548
 
                          "primary key in InnoDB data "
3549
 
                          "dictionary, but has one in "
3550
 
                          "MySQL!", identifier.getTableName().c_str());
 
3079
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3080
          "dictionary, but has one in MySQL! If you "
 
3081
          "created the table with a MySQL version < "
 
3082
          "3.23.54 and did not define a primary key, "
 
3083
          "but defined a unique key with all non-NULL "
 
3084
          "columns, then MySQL internally treats that "
 
3085
          "key as the primary key. You can fix this "
 
3086
          "error by dump + DROP + CREATE + reimport "
 
3087
          "of the table.", identifier.getTableName().c_str());
3551
3088
    }
3552
3089
 
3553
3090
    prebuilt->clust_index_was_generated = TRUE;
3580
3117
    /* We update the highest file format in the system table
3581
3118
    space, if this table has higher file format setting. */
3582
3119
 
3583
 
    char changed_file_format_max[100];
3584
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3585
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
 
3120
    trx_sys_file_format_max_upgrade(
 
3121
      (const char**) &innobase_file_format_check,
3586
3122
      dict_table_get_format(prebuilt->table));
3587
 
    innobase_file_format_max= changed_file_format_max;
3588
3123
  }
3589
3124
 
 
3125
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3126
 
3590
3127
  /* Only if the table has an AUTOINC column. */
3591
3128
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3129
    ulint error;
3592
3130
 
3593
3131
    dict_table_autoinc_lock(prebuilt->table);
3594
3132
 
3598
3136
    autoinc value from a previous Drizzle open. */
3599
3137
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3600
3138
 
3601
 
      innobase_initialize_autoinc();
 
3139
      error = innobase_initialize_autoinc();
 
3140
      ut_a(error == DB_SUCCESS);
3602
3141
    }
3603
3142
 
3604
3143
    dict_table_autoinc_unlock(prebuilt->table);
3605
3144
  }
3606
3145
 
3607
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3608
 
 
3609
3146
  return(0);
3610
3147
}
3611
3148
 
3853
3390
  case DRIZZLE_TYPE_DATETIME:
3854
3391
  case DRIZZLE_TYPE_DATE:
3855
3392
  case DRIZZLE_TYPE_TIMESTAMP:
3856
 
  case DRIZZLE_TYPE_ENUM:
3857
3393
    return(DATA_INT);
3858
3394
  case DRIZZLE_TYPE_DOUBLE:
3859
3395
    return(DATA_DOUBLE);
3860
3396
  case DRIZZLE_TYPE_BLOB:
3861
 
    return(DATA_BLOB);
3862
 
  case DRIZZLE_TYPE_UUID:
3863
 
    return(DATA_FIXBINARY);
3864
 
  case DRIZZLE_TYPE_NULL:
 
3397
                return(DATA_BLOB);
 
3398
  default:
3865
3399
    ut_error;
3866
3400
  }
3867
3401
 
4101
3635
      ulint     key_len;
4102
3636
      const unsigned char*    src_start;
4103
3637
      enum_field_types  real_type;
4104
 
      const CHARSET_INFO* cs= field->charset();
4105
3638
 
4106
3639
      key_len = key_part->length;
4107
3640
 
4123
3656
      memcpy(buff, src_start, true_len);
4124
3657
      buff += true_len;
4125
3658
 
4126
 
      /* Pad the unused space with spaces. */
 
3659
      /* Pad the unused space with spaces. Note that no
 
3660
      padding is ever needed for UCS-2 because in MySQL,
 
3661
      all UCS2 characters are 2 bytes, as MySQL does not
 
3662
      support surrogate pairs, which are needed to represent
 
3663
      characters in the range U+10000 to U+10FFFF. */
4127
3664
 
4128
3665
      if (true_len < key_len) {
4129
 
        ulint   pad_len = key_len - true_len;
4130
 
        ut_a(!(pad_len % cs->mbminlen));
4131
 
 
4132
 
        cs->cset->fill(cs, buff, pad_len,
4133
 
                       0x20 /* space */);
 
3666
        ulint pad_len = key_len - true_len;
 
3667
        memset(buff, ' ', pad_len);
4134
3668
        buff += pad_len;
4135
3669
      }
4136
3670
    }
4238
3772
 
4239
3773
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4240
3774
  'fields'. */
4241
 
  for (i = 0; i < n_fields; i++)
 
3775
  for (i = 0; i < n_fields; i++) 
4242
3776
  {
4243
 
    const dict_col_t *col= &index->table->cols[i];
4244
3777
    templ = prebuilt->mysql_template + n_requested_fields;
4245
3778
    field = table->getField(i);
4246
3779
 
4288
3821
    templ->col_no = i;
4289
3822
 
4290
3823
    if (index == clust_index) {
4291
 
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
 
3824
      templ->rec_field_no = dict_col_get_clust_pos(
 
3825
        &index->table->cols[i], index);
4292
3826
    } else {
4293
3827
      templ->rec_field_no = dict_index_get_nth_col_pos(
4294
3828
                index, i);
4317
3851
      mysql_prefix_len = templ->mysql_col_offset
4318
3852
        + templ->mysql_col_len;
4319
3853
    }
4320
 
    templ->type = col->mtype;
 
3854
    templ->type = index->table->cols[i].mtype;
4321
3855
    templ->mysql_type = (ulint)field->type();
4322
3856
 
4323
3857
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4325
3859
        (((Field_varstring*)field)->pack_length_no_ptr());
4326
3860
    }
4327
3861
 
4328
 
    templ->charset = dtype_get_charset_coll(col->prtype);
4329
 
    templ->mbminlen = dict_col_get_mbminlen(col);
4330
 
    templ->mbmaxlen = dict_col_get_mbmaxlen(col);
4331
 
    templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 
3862
    templ->charset = dtype_get_charset_coll(
 
3863
      index->table->cols[i].prtype);
 
3864
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3865
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3866
    templ->is_unsigned = index->table->cols[i].prtype
 
3867
              & DATA_UNSIGNED;
4332
3868
    if (templ->type == DATA_BLOB) {
4333
3869
      prebuilt->templ_contains_blob = TRUE;
4334
3870
    }
4353
3889
}
4354
3890
 
4355
3891
/********************************************************************//**
 
3892
Get the upper limit of the MySQL integral and floating-point type. */
 
3893
UNIV_INTERN
 
3894
uint64_t
 
3895
ha_innobase::innobase_get_int_col_max_value(
 
3896
/*========================================*/
 
3897
  const Field*  field)
 
3898
{
 
3899
  uint64_t  max_value = 0;
 
3900
 
 
3901
  switch(field->key_type()) {
 
3902
  /* TINY */
 
3903
  case HA_KEYTYPE_BINARY:
 
3904
    max_value = 0xFFULL;
 
3905
    break;
 
3906
  /* LONG */
 
3907
  case HA_KEYTYPE_ULONG_INT:
 
3908
    max_value = 0xFFFFFFFFULL;
 
3909
    break;
 
3910
  case HA_KEYTYPE_LONG_INT:
 
3911
    max_value = 0x7FFFFFFFULL;
 
3912
    break;
 
3913
  /* BIG */
 
3914
  case HA_KEYTYPE_ULONGLONG:
 
3915
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3916
    break;
 
3917
  case HA_KEYTYPE_LONGLONG:
 
3918
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3919
    break;
 
3920
  case HA_KEYTYPE_DOUBLE:
 
3921
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3922
    max_value = 0x20000000000000ULL;
 
3923
    break;
 
3924
  default:
 
3925
    ut_error;
 
3926
  }
 
3927
 
 
3928
  return(max_value);
 
3929
}
 
3930
 
 
3931
/********************************************************************//**
4356
3932
This special handling is really to overcome the limitations of MySQL's
4357
3933
binlogging. We need to eliminate the non-determinism that will arise in
4358
3934
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4510
4086
    prebuilt->autoinc_error = DB_SUCCESS;
4511
4087
 
4512
4088
    if ((error = update_auto_increment())) {
 
4089
 
4513
4090
      /* We don't want to mask autoinc overflow errors. */
4514
 
 
4515
 
      /* Handle the case where the AUTOINC sub-system
4516
 
         failed during initialization. */
4517
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4518
 
        error_result = ER_AUTOINC_READ_FAILED;
4519
 
        /* Set the error message to report too. */
4520
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4521
 
        goto func_exit;
4522
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4091
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4523
4092
        error = (int) prebuilt->autoinc_error;
4524
4093
 
4525
4094
        goto report_error;
4546
4115
 
4547
4116
  error = row_insert_for_mysql((byte*) record, prebuilt);
4548
4117
 
4549
 
  user_session->setXaId(trx->id);
4550
 
 
4551
4118
  /* Handle duplicate key errors */
4552
4119
  if (auto_inc_used) {
4553
4120
    ulint   err;
4603
4170
      update the table upper limit. Note: last_value
4604
4171
      will be 0 if get_auto_increment() was not called.*/
4605
4172
 
4606
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4173
      if (auto_inc <= col_max_value
 
4174
          && auto_inc >= prebuilt->autoinc_last_value) {
4607
4175
set_max_autoinc:
4608
 
        /* This should filter out the negative
4609
 
           values set explicitly by the user. */
4610
 
        if (auto_inc <= col_max_value) {
4611
 
          ut_a(prebuilt->autoinc_increment > 0);
4612
 
 
4613
 
          uint64_t      need;
4614
 
          uint64_t      offset;
4615
 
 
4616
 
          offset = prebuilt->autoinc_offset;
4617
 
          need = prebuilt->autoinc_increment;
4618
 
 
4619
 
          auto_inc = innobase_next_autoinc(
4620
 
                                           auto_inc,
4621
 
                                           need, offset, col_max_value);
4622
 
 
4623
 
          err = innobase_set_max_autoinc(
4624
 
                                         auto_inc);
4625
 
 
4626
 
          if (err != DB_SUCCESS) {
4627
 
            error = err;
4628
 
          }
 
4176
        ut_a(prebuilt->autoinc_increment > 0);
 
4177
 
 
4178
        uint64_t  need;
 
4179
        uint64_t  offset;
 
4180
 
 
4181
        offset = prebuilt->autoinc_offset;
 
4182
        need = prebuilt->autoinc_increment;
 
4183
 
 
4184
        auto_inc = innobase_next_autoinc(
 
4185
          auto_inc, need, offset, col_max_value);
 
4186
 
 
4187
        err = innobase_set_max_autoinc(auto_inc);
 
4188
 
 
4189
        if (err != DB_SUCCESS) {
 
4190
          error = err;
4629
4191
        }
4630
4192
      }
4631
4193
      break;
4869
4431
 
4870
4432
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4871
4433
 
4872
 
  user_session->setXaId(trx->id);
4873
 
 
4874
4434
  /* We need to do some special AUTOINC handling for the following case:
4875
4435
 
4876
4436
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4961
4521
 
4962
4522
  error = row_update_for_mysql((byte*) record, prebuilt);
4963
4523
 
4964
 
  user_session->setXaId(trx->id);
4965
 
 
4966
4524
  innodb_srv_conc_exit_innodb(trx);
4967
4525
 
4968
4526
  error = convert_error_code_to_mysql(
4996
4554
  case ROW_READ_WITH_LOCKS:
4997
4555
    if (!srv_locks_unsafe_for_binlog
4998
4556
        && prebuilt->trx->isolation_level
4999
 
        > TRX_ISO_READ_COMMITTED) {
 
4557
        != TRX_ISO_READ_COMMITTED) {
5000
4558
      break;
5001
4559
    }
5002
4560
    /* fall through */
5035
4593
 
5036
4594
  if (yes
5037
4595
      && (srv_locks_unsafe_for_binlog
5038
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4596
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
5039
4597
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
5040
4598
  } else {
5041
4599
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5221
4779
    return(HA_ERR_CRASHED);
5222
4780
  }
5223
4781
 
5224
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5225
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5226
 
  }
5227
4782
 
5228
4783
  /* Note that if the index for which the search template is built is not
5229
4784
  necessarily prebuilt->index, but can also be the clustered index */
5337
4892
 
5338
4893
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5339
4894
 
 
4895
  ut_ad(user_session == table->in_use);
 
4896
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4897
 
5340
4898
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
5341
4899
  {
5342
 
    KeyInfo *key = getTable()->key_info + keynr;
5343
 
    index = innobase_index_lookup(share, keynr);
5344
 
 
5345
 
    if (index) {
5346
 
      ut_a(ut_strcmp(index->name, key->name) == 0);
5347
 
    } else {
5348
 
      /* Can't find index with keynr in the translation
5349
 
         table. Only print message if the index translation
5350
 
         table exists */
5351
 
      if (share->idx_trans_tbl.index_mapping) {
5352
 
        errmsg_printf(ERRMSG_LVL_ERROR,
5353
 
                      "InnoDB could not find "
5354
 
                      "index %s key no %u for "
5355
 
                      "table %s through its "
5356
 
                      "index translation table",
5357
 
                      key ? key->name : "NULL",
5358
 
                      keynr,
5359
 
                      prebuilt->table->name);
5360
 
      }
5361
 
 
5362
 
      index = dict_table_get_index_on_name(prebuilt->table,
5363
 
                                           key->name);
5364
 
    }
 
4900
    index = dict_table_get_index_on_name(prebuilt->table,
 
4901
                                         getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str());
5365
4902
  } else {
5366
4903
    index = dict_table_get_first_index(prebuilt->table);
5367
4904
  }
5818
5355
 
5819
5356
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5820
5357
                  field);
5821
 
 
5822
 
    if (!col_type) {
5823
 
      push_warning_printf(
5824
 
                          (Session*) trx->mysql_thd,
5825
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5826
 
                          ER_CANT_CREATE_TABLE,
5827
 
                          "Error creating table '%s' with "
5828
 
                          "column '%s'. Please check its "
5829
 
                          "column type and try to re-create "
5830
 
                          "the table with an appropriate "
5831
 
                          "column type.",
5832
 
                          table->name, (char*) field->field_name);
5833
 
      goto err_col;
5834
 
    }
5835
 
 
5836
5358
    if (field->null_ptr) {
5837
5359
      nulls_allowed = 0;
5838
5360
    } else {
5890
5412
    if (dict_col_name_is_reserved(field->field_name)){
5891
5413
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5892
5414
 
5893
 
  err_col:
5894
5415
      dict_mem_table_free(table);
5895
5416
      trx_commit_for_mysql(trx);
5896
5417
 
5913
5434
 
5914
5435
        if (error == DB_DUPLICATE_KEY) {
5915
5436
                char buf[100];
5916
 
                char* buf_end = innobase_convert_identifier(
5917
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5918
 
                        trx->mysql_thd, TRUE);
5919
 
 
5920
 
                *buf_end = '\0';
 
5437
                innobase_convert_identifier(buf, sizeof buf,
 
5438
                                            table_name, strlen(table_name),
 
5439
                                            trx->mysql_thd, TRUE);
5921
5440
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5922
5441
        }
5923
5442
 
6138
5657
    modified by another thread while the table is being created. */
6139
5658
  const ulint file_format = srv_file_format;
6140
5659
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6141
 
  const char* stmt;
6142
 
  size_t stmt_len;
6143
5660
 
6144
5661
  const char *table_name= identifier.getPath().c_str();
6145
5662
 
6232
5749
# error "DICT_TF_ZSSIZE_MAX < 1"
6233
5750
#endif
6234
5751
 
6235
 
    if (strict_mode)
 
5752
    if (SessionVAR(&session, strict_mode))
6236
5753
    {
6237
5754
      if (! srv_file_per_table)
6238
5755
      {
6259
5776
                   (int) form.getShare()->getPrimaryKey() :
6260
5777
                   -1);
6261
5778
 
6262
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5779
  /* Our function row_get_mysql_key_number_for_index assumes
6263
5780
    the primary key is always number 0, if it exists */
6264
5781
 
6265
5782
  assert(primary_key_no == -1 || primary_key_no == 0);
6279
5796
                          lex_identified_temp_table ? name2 : NULL,
6280
5797
                          iflags);
6281
5798
 
6282
 
  session.setXaId(trx->id);
6283
 
 
6284
5799
  if (error) {
6285
5800
    goto cleanup;
6286
5801
  }
6316
5831
    }
6317
5832
  }
6318
5833
 
6319
 
  stmt = innobase_get_stmt(&session, &stmt_len);
6320
 
 
6321
 
  if (stmt) {
 
5834
  if (trx->mysql_query_str) {
6322
5835
    string generated_create_table;
6323
 
    const char *query= stmt;
 
5836
    const char *query= trx->mysql_query_str;
6324
5837
 
6325
5838
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6326
5839
    {
6331
5844
    }
6332
5845
 
6333
5846
    error = row_table_add_foreign_constraints(trx,
6334
 
                                              query, strlen(query),
 
5847
                                              query,
6335
5848
                                              norm_name,
6336
5849
                                              lex_identified_temp_table);
6337
5850
 
6360
5873
    /* We update the highest file format in the system table
6361
5874
      space, if this table has higher file format setting. */
6362
5875
 
6363
 
    char changed_file_format_max[100];
6364
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6365
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
6366
 
      dict_table_get_format(innobase_table));
6367
 
    innobase_file_format_max= changed_file_format_max;
 
5876
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5877
                                    dict_table_get_format(innobase_table));
6368
5878
  }
6369
5879
 
6370
5880
  /* Note: We can't call update_session() as prebuilt will not be
6404
5914
 
6405
5915
  if (lex_identified_temp_table)
6406
5916
  {
6407
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5917
    session.storeTableMessage(identifier, create_proto);
6408
5918
  }
6409
5919
  else
6410
5920
  {
6536
6046
                                   session_sql_command(&session)
6537
6047
                                   == SQLCOM_DROP_DB);
6538
6048
 
6539
 
  session.setXaId(trx->id);
6540
 
 
6541
6049
  /* Flush the log to reduce probability that the .frm files and
6542
6050
    the InnoDB data dictionary get out-of-sync if the user runs
6543
6051
    with innodb_flush_log_at_trx_commit = 0 */
6560
6068
  {
6561
6069
    if (identifier.getType() == message::Table::TEMPORARY)
6562
6070
    {
6563
 
      session.getMessageCache().removeTableMessage(identifier);
 
6071
      session.removeTableMessage(identifier);
6564
6072
      ulint sql_command = session_sql_command(&session);
6565
6073
 
6566
6074
      // If this was the final removal to an alter table then we will need
6653
6161
  trx = trx_allocate_for_mysql();
6654
6162
 
6655
6163
  trx->mysql_thd = NULL;
 
6164
  trx->mysql_query_str = NULL;
6656
6165
 
6657
6166
  trx->check_foreigns = false;
6658
6167
  trx->check_unique_secondary = false;
6736
6245
  // definition needs to be updated.
6737
6246
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6738
6247
  {
6739
 
    session.getMessageCache().renameTableMessage(from, to);
 
6248
    session.renameTableMessage(from, to);
6740
6249
    return 0;
6741
6250
  }
6742
6251
 
6758
6267
 
6759
6268
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6760
6269
 
6761
 
  session.setXaId(trx->id);
6762
 
 
6763
6270
  /* Tell the InnoDB server that there might be work for
6764
6271
    utility threads: */
6765
6272
 
6836
6343
 
6837
6344
  key = &getTable()->key_info[active_index];
6838
6345
 
6839
 
  index = innobase_get_index(keynr);
6840
 
 
6841
 
  /* There exists possibility of not being able to find requested
6842
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6843
 
     Necessary message should have been printed in innobase_get_index() */
6844
 
  if (UNIV_UNLIKELY(!index)) {
6845
 
    n_rows = HA_POS_ERROR;
6846
 
    goto func_exit;
6847
 
  }
6848
 
 
6849
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6850
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6851
 
    goto func_exit;
6852
 
  }
 
6346
  index = dict_table_get_index_on_name(prebuilt->table, getTable()->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6347
 
 
6348
  /* MySQL knows about this index and so we must be able to find it.*/
 
6349
  ut_a(index);
6853
6350
 
6854
6351
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6855
6352
            + sizeof(dtuple_t)));
6894
6391
 
6895
6392
  mem_heap_free(heap);
6896
6393
 
6897
 
func_exit:
6898
6394
  free(key_val_buff2);
6899
6395
 
6900
6396
  prebuilt->trx->op_info = (char*)"";
7017
6513
}
7018
6514
 
7019
6515
/*********************************************************************//**
7020
 
Calculates the key number used inside MySQL for an Innobase index. We will
7021
 
first check the "index translation table" for a match of the index to get
7022
 
the index number. If there does not exist an "index translation table",
7023
 
or not able to find the index in the translation table, then we will fall back
7024
 
to the traditional way of looping through dict_index_t list to find a
7025
 
match. In this case, we have to take into account if we generated a
7026
 
default clustered index for the table
7027
 
@return the key number used inside MySQL */
7028
 
static
7029
 
unsigned int
7030
 
innobase_get_mysql_key_number_for_index(
7031
 
/*====================================*/
7032
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
7033
 
                                        translation table. */
7034
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
7035
 
                                        dictionary */
7036
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
7037
 
                                        dictionary */
7038
 
        const dict_index_t*     index)  /*!< in: index */
7039
 
{
7040
 
        const dict_index_t*     ind;
7041
 
        unsigned int            i;
7042
 
 
7043
 
        ut_ad(index);
7044
 
        ut_ad(ib_table);
7045
 
        ut_ad(table);
7046
 
        ut_ad(share);
7047
 
 
7048
 
        /* If index does not belong to the table of share structure. Search
7049
 
        index->table instead */
7050
 
        if (index->table != ib_table) {
7051
 
                i = 0;
7052
 
                ind = dict_table_get_first_index(index->table);
7053
 
 
7054
 
                while (index != ind) {
7055
 
                        ind = dict_table_get_next_index(ind);
7056
 
                        i++;
7057
 
                }
7058
 
 
7059
 
                if (row_table_got_default_clust_index(index->table)) {
7060
 
                        ut_a(i > 0);
7061
 
                        i--;
7062
 
                }
7063
 
 
7064
 
                return(i);
7065
 
        }
7066
 
 
7067
 
        /* If index does not belong to the table of share structure. Search
7068
 
        index->table instead */
7069
 
        if (index->table != ib_table) {
7070
 
                i = 0;
7071
 
                ind = dict_table_get_first_index(index->table);
7072
 
 
7073
 
                while (index != ind) {
7074
 
                        ind = dict_table_get_next_index(ind);
7075
 
                        i++;
7076
 
                }
7077
 
 
7078
 
                if (row_table_got_default_clust_index(index->table)) {
7079
 
                        ut_a(i > 0);
7080
 
                        i--;
7081
 
                }
7082
 
 
7083
 
                return(i);
7084
 
        }
7085
 
 
7086
 
        /* If index translation table exists, we will first check
7087
 
        the index through index translation table for a match. */
7088
 
        if (share->idx_trans_tbl.index_mapping) {
7089
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7090
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7091
 
                                return(i);
7092
 
                        }
7093
 
                }
7094
 
 
7095
 
                /* Print an error message if we cannot find the index
7096
 
                ** in the "index translation table". */
7097
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7098
 
                              "Cannot find index %s in InnoDB index "
7099
 
                                "translation table.", index->name);
7100
 
        }
7101
 
 
7102
 
        /* If we do not have an "index translation table", or not able
7103
 
        to find the index in the translation table, we'll directly find
7104
 
        matching index in the dict_index_t list */
7105
 
        for (i = 0; i < table->getShare()->keys; i++) {
7106
 
                ind = dict_table_get_index_on_name(
7107
 
                        ib_table, table->key_info[i].name);
7108
 
 
7109
 
                if (index == ind) {
7110
 
                        return(i);
7111
 
                }
7112
 
        }
7113
 
 
7114
 
                errmsg_printf(ERRMSG_LVL_ERROR,
7115
 
                              "Cannot find matching index number for index %s "
7116
 
                              "in InnoDB index list.", index->name);
7117
 
 
7118
 
        return(0);
7119
 
}
7120
 
/*********************************************************************//**
7121
6516
Returns statistics information of the table to the MySQL interpreter,
7122
6517
in various fields of the handle object. */
7123
6518
UNIV_INTERN
7130
6525
  dict_index_t* index;
7131
6526
  ha_rows   rec_per_key;
7132
6527
  ib_int64_t  n_rows;
 
6528
  ulong   j;
 
6529
  ulong   i;
7133
6530
  os_file_stat_t  stat_info;
7134
6531
 
7135
6532
  /* If we are forcing recovery at a high level, we will suppress
7136
6533
  statistics calculation on tables, because that may crash the
7137
6534
  server if an index is badly corrupted. */
7138
6535
 
 
6536
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6537
 
 
6538
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6539
    because we want MySQL to process this query and not
 
6540
    stop, like it would do if it received the error code
 
6541
    HA_ERR_CRASHED. */
 
6542
 
 
6543
    return(0);
 
6544
  }
 
6545
 
7139
6546
  /* We do not know if MySQL can call this function before calling
7140
6547
  external_lock(). To be safe, update the session of the current table
7141
6548
  handle. */
7227
6634
    acquiring latches inside InnoDB, we do not call it if we
7228
6635
    are asked by MySQL to avoid locking. Another reason to
7229
6636
    avoid the call is that it uses quite a lot of CPU.
7230
 
    See Bug#38185. */
7231
 
    if (flag & HA_STATUS_NO_LOCK) {
7232
 
      /* We do not update delete_length if no
7233
 
         locking is requested so the "old" value can
7234
 
         remain. delete_length is initialized to 0 in
7235
 
         the ha_statistics' constructor. */
7236
 
    } else if (UNIV_UNLIKELY
7237
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7238
 
      /* Avoid accessing the tablespace if
7239
 
         innodb_crash_recovery is set to a high value. */
7240
 
      stats.delete_length = 0;
7241
 
    } else {
 
6637
    See Bug#38185.
 
6638
    We do not update delete_length if no locking is requested
 
6639
    so the "old" value can remain. delete_length is initialized
 
6640
    to 0 in the ha_statistics' constructor. */
 
6641
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6642
 
7242
6643
      /* lock the data dictionary to avoid races with
7243
6644
      ibd_file_missing and tablespace_discarded */
7244
6645
      row_mysql_lock_data_dictionary(prebuilt->trx);
7284
6685
  }
7285
6686
 
7286
6687
  if (flag & HA_STATUS_CONST) {
7287
 
    ulong i;
7288
 
    /* Verify the number of index in InnoDB and MySQL
7289
 
       matches up. If prebuilt->clust_index_was_generated
7290
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7291
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6688
    index = dict_table_get_first_index(ib_table);
7292
6689
 
7293
 
    if (getTable()->getShare()->keys != num_innodb_index) {
7294
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7295
 
                      "indexes inside InnoDB, which "
7296
 
                      "is different from the number of "
7297
 
                      "indexes %u defined in the MySQL ",
7298
 
                      ib_table->name, num_innodb_index,
7299
 
                      getTable()->getShare()->keys);
 
6690
    if (prebuilt->clust_index_was_generated) {
 
6691
      index = dict_table_get_next_index(index);
7300
6692
    }
7301
6693
 
7302
6694
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7303
 
      ulong j;
7304
 
      /* We could get index quickly through internal
7305
 
         index mapping with the index translation table.
7306
 
         The identity of index (match up index name with
7307
 
         that of table->key_info[i]) is already verified in
7308
 
         innobase_get_index().  */
7309
 
      index = innobase_get_index(i);
7310
 
 
7311
6695
      if (index == NULL) {
7312
6696
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7313
6697
            "indexes inside InnoDB than "
7336
6720
          break;
7337
6721
        }
7338
6722
 
7339
 
        dict_index_stat_mutex_enter(index);
7340
 
 
7341
6723
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7342
6724
 
7343
6725
          rec_per_key = stats.records;
7346
6728
           index->stat_n_diff_key_vals[j + 1]);
7347
6729
        }
7348
6730
 
7349
 
        dict_index_stat_mutex_exit(index);
7350
 
 
7351
6731
        /* Since MySQL seems to favor table scans
7352
6732
        too much over index searches, we pretend
7353
6733
        index selectivity is 2 times better than
7363
6743
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7364
6744
          (ulong) rec_per_key;
7365
6745
      }
 
6746
 
 
6747
      index = dict_table_get_next_index(index);
7366
6748
    }
7367
6749
  }
7368
6750
 
7369
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7370
 
    goto func_exit;
7371
 
  }
7372
 
 
7373
6751
  if (flag & HA_STATUS_ERRKEY) {
7374
6752
    const dict_index_t* err_index;
7375
6753
 
7380
6758
 
7381
6759
    if (err_index) {
7382
6760
      errkey = (unsigned int)
7383
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7384
 
                                                err_index);
 
6761
        row_get_mysql_key_number_for_index(err_index);
7385
6762
    } else {
7386
6763
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7387
6764
    }
7391
6768
    stats.auto_increment_value = innobase_peek_autoinc();
7392
6769
  }
7393
6770
 
7394
 
func_exit:
7395
6771
  prebuilt->trx->op_info = (char*)"";
7396
6772
 
7397
6773
  return(0);
7407
6783
/*=================*/
7408
6784
  Session*)   /*!< in: connection thread handle */
7409
6785
{
 
6786
  /* Serialize ANALYZE TABLE inside InnoDB, see
 
6787
     Bug#38996 Race condition in ANALYZE TABLE */
 
6788
  pthread_mutex_lock(&analyze_mutex);
 
6789
 
7410
6790
  /* Simply call ::info() with all the flags */
7411
6791
  info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
7412
6792
 
 
6793
  pthread_mutex_unlock(&analyze_mutex);
 
6794
 
7413
6795
  return(0);
7414
6796
}
7415
6797
 
7424
6806
/*===============*/
7425
6807
  Session*  session)  /*!< in: user thread handle */
7426
6808
{
7427
 
  dict_index_t* index;
7428
 
  ulint         n_rows;
7429
 
  ulint         n_rows_in_table = ULINT_UNDEFINED;
7430
 
  ibool         is_ok           = TRUE;
7431
 
  ulint         old_isolation_level;
 
6809
  ulint   ret;
7432
6810
 
7433
6811
  assert(session == getTable()->in_use);
7434
6812
  ut_a(prebuilt->trx);
7442
6820
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
7443
6821
  }
7444
6822
 
7445
 
  if (prebuilt->table->ibd_file_missing) {
7446
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7447
 
                    "InnoDB: MySQL is trying to use a table handle"
7448
 
                    " but the .ibd file for\n"
7449
 
                    "InnoDB: table %s does not exist.\n"
7450
 
                    "InnoDB: Have you deleted the .ibd file"
7451
 
                    " from the database directory under\n"
7452
 
                    "InnoDB: the MySQL datadir, or have you"
7453
 
                    " used DISCARD TABLESPACE?\n"
7454
 
                    "InnoDB: Please refer to\n"
7455
 
                    "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
7456
 
                    "InnoDB: how you can resolve the problem.\n",
7457
 
                    prebuilt->table->name);
 
6823
  ret = row_check_table_for_mysql(prebuilt);
 
6824
 
 
6825
  switch (ret) {
 
6826
  case DB_SUCCESS:
 
6827
    return(HA_ADMIN_OK);
 
6828
  case DB_INTERRUPTED:
 
6829
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
 
6830
    return(-1);
 
6831
  default:
7458
6832
    return(HA_ADMIN_CORRUPT);
7459
6833
  }
7460
 
 
7461
 
  prebuilt->trx->op_info = "checking table";
7462
 
 
7463
 
  old_isolation_level = prebuilt->trx->isolation_level;
7464
 
 
7465
 
  /* We must run the index record counts at an isolation level
7466
 
     >= READ COMMITTED, because a dirty read can see a wrong number
7467
 
     of records in some index; to play safe, we use always
7468
 
     REPEATABLE READ here */
7469
 
 
7470
 
  prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7471
 
 
7472
 
  /* Enlarge the fatal lock wait timeout during CHECK TABLE. */
7473
 
  mutex_enter(&kernel_mutex);
7474
 
  srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
7475
 
  mutex_exit(&kernel_mutex);
7476
 
 
7477
 
  for (index = dict_table_get_first_index(prebuilt->table);
7478
 
       index != NULL;
7479
 
       index = dict_table_get_next_index(index)) {
7480
 
#if 0
7481
 
    fputs("Validating index ", stderr);
7482
 
    ut_print_name(stderr, trx, FALSE, index->name);
7483
 
    putc('\n', stderr);
7484
 
#endif
7485
 
 
7486
 
    if (!btr_validate_index(index, prebuilt->trx)) {
7487
 
      is_ok = FALSE;
7488
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7489
 
                          ER_NOT_KEYFILE,
7490
 
                          "InnoDB: The B-tree of"
7491
 
                          " index '%-.200s' is corrupted.",
7492
 
                          index->name);
7493
 
      continue;
7494
 
    }
7495
 
 
7496
 
    /* Instead of invoking change_active_index(), set up
7497
 
       a dummy template for non-locking reads, disabling
7498
 
       access to the clustered index. */
7499
 
    prebuilt->index = index;
7500
 
 
7501
 
    prebuilt->index_usable = row_merge_is_index_usable(
7502
 
                        prebuilt->trx, prebuilt->index);
7503
 
 
7504
 
    if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
7505
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7506
 
                          HA_ERR_TABLE_DEF_CHANGED,
7507
 
                          "InnoDB: Insufficient history for"
7508
 
                          " index '%-.200s'",
7509
 
                          index->name);
7510
 
      continue;
7511
 
    }
7512
 
 
7513
 
    prebuilt->sql_stat_start = TRUE;
7514
 
    prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
7515
 
    prebuilt->n_template = 0;
7516
 
    prebuilt->need_to_access_clustered = FALSE;
7517
 
 
7518
 
    dtuple_set_n_fields(prebuilt->search_tuple, 0);
7519
 
 
7520
 
    prebuilt->select_lock_type = LOCK_NONE;
7521
 
 
7522
 
    if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
7523
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7524
 
                          ER_NOT_KEYFILE,
7525
 
                          "InnoDB: The B-tree of"
7526
 
                          " index '%-.200s' is corrupted.",
7527
 
                          index->name);
7528
 
      is_ok = FALSE;
7529
 
    }
7530
 
 
7531
 
    if (user_session->getKilled()) {
7532
 
      break;
7533
 
    }
7534
 
 
7535
 
#if 0
7536
 
    fprintf(stderr, "%lu entries in index %s\n", n_rows,
7537
 
            index->name);
7538
 
#endif
7539
 
 
7540
 
    if (index == dict_table_get_first_index(prebuilt->table)) {
7541
 
      n_rows_in_table = n_rows;
7542
 
    } else if (n_rows != n_rows_in_table) {
7543
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7544
 
                          ER_NOT_KEYFILE,
7545
 
                          "InnoDB: Index '%-.200s'"
7546
 
                          " contains %lu entries,"
7547
 
                          " should be %lu.",
7548
 
                          index->name,
7549
 
                          (ulong) n_rows,
7550
 
                          (ulong) n_rows_in_table);
7551
 
      is_ok = FALSE;
7552
 
    }
7553
 
  }
7554
 
 
7555
 
  /* Restore the original isolation level */
7556
 
  prebuilt->trx->isolation_level = old_isolation_level;
7557
 
 
7558
 
  /* We validate also the whole adaptive hash index for all tables
7559
 
     at every CHECK TABLE */
7560
 
 
7561
 
  if (!btr_search_validate()) {
7562
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7563
 
                 ER_NOT_KEYFILE,
7564
 
                 "InnoDB: The adaptive hash index is corrupted.");
7565
 
    is_ok = FALSE;
7566
 
  }
7567
 
 
7568
 
  /* Restore the fatal lock wait timeout after CHECK TABLE. */
7569
 
  mutex_enter(&kernel_mutex);
7570
 
  srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
7571
 
  mutex_exit(&kernel_mutex);
7572
 
 
7573
 
  prebuilt->trx->op_info = "";
7574
 
  if (user_session->getKilled()) {
7575
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
7576
 
  }
7577
 
 
7578
 
  return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
7579
6834
}
7580
6835
 
7581
6836
/*************************************************************//**
8092
7347
{
8093
7348
  trx_t*      trx;
8094
7349
  static const char truncated_msg[] = "... truncated...\n";
8095
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7350
  const long    MAX_STATUS_SIZE = 64000;
8096
7351
  ulint     trx_list_start = ULINT_UNDEFINED;
8097
7352
  ulint     trx_list_end = ULINT_UNDEFINED;
8098
7353
 
8110
7365
 
8111
7366
  mutex_enter(&srv_monitor_file_mutex);
8112
7367
  rewind(srv_monitor_file);
8113
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7368
  srv_printf_innodb_monitor(srv_monitor_file,
8114
7369
        &trx_list_start, &trx_list_end);
8115
7370
  flen = ftell(srv_monitor_file);
8116
7371
  os_file_set_eof(srv_monitor_file);
8121
7376
 
8122
7377
  if (flen > MAX_STATUS_SIZE) {
8123
7378
    usable_len = MAX_STATUS_SIZE;
8124
 
    srv_truncated_status_writes++;
8125
7379
  } else {
8126
7380
    usable_len = flen;
8127
7381
  }
8157
7411
 
8158
7412
  mutex_exit(&srv_monitor_file_mutex);
8159
7413
 
8160
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8161
 
             STRING_WITH_LEN(""), str, flen);
 
7414
  bool result = FALSE;
8162
7415
 
 
7416
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7417
      STRING_WITH_LEN(""), str, flen)) {
 
7418
    result= TRUE;
 
7419
  }
8163
7420
  free(str);
8164
7421
 
8165
7422
  return(FALSE);
8166
7423
}
8167
7424
 
8168
7425
/************************************************************************//**
8169
 
Implements the SHOW MUTEX STATUS command.
8170
 
@return true on failure false on success*/
 
7426
Implements the SHOW MUTEX STATUS command. . */
8171
7427
static
8172
7428
bool
8173
7429
innodb_mutex_show_status(
8175
7431
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8176
7432
  Session*  session,  /*!< in: the MySQL query thread of the
8177
7433
          caller */
8178
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8179
 
                                        statistics */
 
7434
  stat_print_fn*  stat_print)
8180
7435
{
8181
7436
  char buf1[IO_SIZE], buf2[IO_SIZE];
8182
7437
  mutex_t*  mutex;
8183
7438
  rw_lock_t*  lock;
8184
 
  ulint         block_mutex_oswait_count = 0;
8185
 
  ulint         block_lock_oswait_count = 0;
8186
 
  mutex_t*      block_mutex = NULL;
8187
 
  rw_lock_t*    block_lock = NULL;
8188
7439
#ifdef UNIV_DEBUG
8189
7440
  ulint   rw_lock_count= 0;
8190
7441
  ulint   rw_lock_count_spin_loop= 0;
8198
7449
 
8199
7450
  mutex_enter(&mutex_list_mutex);
8200
7451
 
8201
 
  for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
8202
 
       mutex = UT_LIST_GET_NEXT(list, mutex)) {
8203
 
    if (mutex->count_os_wait == 0) {
8204
 
      continue;
8205
 
    }
8206
 
 
8207
 
 
8208
 
    if (buf_pool_is_block_mutex(mutex)) {
8209
 
      block_mutex = mutex;
8210
 
      block_mutex_oswait_count += mutex->count_os_wait;
8211
 
      continue;
 
7452
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7453
 
 
7454
  while (mutex != NULL) {
 
7455
    if (mutex->count_os_wait == 0
 
7456
        || buf_pool_is_block_mutex(mutex)) {
 
7457
      goto next_mutex;
8212
7458
    }
8213
7459
#ifdef UNIV_DEBUG
8214
7460
    if (mutex->mutex_type != 1) {
8235
7481
          return(1);
8236
7482
        }
8237
7483
      }
8238
 
    } else {
 
7484
    }
 
7485
    else {
8239
7486
      rw_lock_count += mutex->count_using;
8240
7487
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8241
7488
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8247
7494
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8248
7495
          mutex->cfile_name, (ulong) mutex->cline);
8249
7496
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8250
 
                      (ulong) mutex->count_os_wait);
 
7497
          mutex->count_os_wait);
8251
7498
 
8252
7499
    if (stat_print(session, innobase_engine_name,
8253
7500
             engine_name_len, buf1, buf1len,
8256
7503
      return(1);
8257
7504
    }
8258
7505
#endif /* UNIV_DEBUG */
8259
 
  }
8260
 
 
8261
 
  if (block_mutex) {
8262
 
    buf1len = snprintf(buf1, sizeof buf1,
8263
 
                       "combined %s:%lu",
8264
 
                       block_mutex->cfile_name,
8265
 
                       (ulong) block_mutex->cline);
8266
 
    buf2len = snprintf(buf2, sizeof buf2,
8267
 
                       "os_waits=%lu",
8268
 
                       (ulong) block_mutex_oswait_count);
8269
 
 
8270
 
    if (stat_print(session, innobase_engine_name,
8271
 
                   strlen(innobase_engine_name), buf1, buf1len,
8272
 
                   buf2, buf2len)) {
8273
 
      mutex_exit(&mutex_list_mutex);
8274
 
      return(1);
8275
 
    }
 
7506
 
 
7507
next_mutex:
 
7508
    mutex = UT_LIST_GET_NEXT(list, mutex);
8276
7509
  }
8277
7510
 
8278
7511
  mutex_exit(&mutex_list_mutex);
8279
7512
 
8280
7513
  mutex_enter(&rw_lock_list_mutex);
8281
7514
 
8282
 
  for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
8283
 
       lock = UT_LIST_GET_NEXT(list, lock)) {
8284
 
    if (lock->count_os_wait == 0) {
8285
 
      continue;
8286
 
    }
8287
 
 
8288
 
    if (buf_pool_is_block_lock(lock)) {
8289
 
      block_lock = lock;
8290
 
      block_lock_oswait_count += lock->count_os_wait;
8291
 
      continue;
8292
 
    }
8293
 
 
8294
 
    buf1len = snprintf(buf1, sizeof buf1, "%s:%lu",
8295
 
                       lock->cfile_name, (ulong) lock->cline);
8296
 
    buf2len = snprintf(buf2, sizeof buf2, "os_waits=%lu",
8297
 
                       (ulong) lock->count_os_wait);
8298
 
 
8299
 
    if (stat_print(session, innobase_engine_name,
8300
 
                   strlen(innobase_engine_name), buf1, buf1len,
8301
 
                   buf2, buf2len)) {
8302
 
      mutex_exit(&rw_lock_list_mutex);
8303
 
      return(1);
8304
 
    }
8305
 
  }
8306
 
 
8307
 
  if (block_lock) {
8308
 
    buf1len = snprintf(buf1, sizeof buf1,
8309
 
                       "combined %s:%lu",
8310
 
                       block_lock->cfile_name,
8311
 
                       (ulong) block_lock->cline);
8312
 
    buf2len = snprintf(buf2, sizeof buf2,
8313
 
                       "os_waits=%lu",
8314
 
                       (ulong) block_lock_oswait_count);
8315
 
 
8316
 
    if (stat_print(session, innobase_engine_name,
8317
 
                   strlen(innobase_engine_name), buf1, buf1len,
8318
 
                   buf2, buf2len)) {
8319
 
      mutex_exit(&rw_lock_list_mutex);
8320
 
      return(1);
8321
 
    }
 
7515
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7516
 
 
7517
  while (lock != NULL) {
 
7518
    if (lock->count_os_wait
 
7519
                    && !buf_pool_is_block_lock(lock)) {
 
7520
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7521
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7522
      buf2len= snprintf(buf2, sizeof(buf2),
 
7523
                                    "os_waits=%lu", lock->count_os_wait);
 
7524
 
 
7525
      if (stat_print(session, innobase_engine_name,
 
7526
               engine_name_len, buf1, buf1len,
 
7527
               buf2, buf2len)) {
 
7528
        mutex_exit(&rw_lock_list_mutex);
 
7529
        return(1);
 
7530
      }
 
7531
    }
 
7532
    lock = UT_LIST_GET_NEXT(list, lock);
8322
7533
  }
8323
7534
 
8324
7535
  mutex_exit(&rw_lock_list_mutex);
8325
7536
 
8326
7537
#ifdef UNIV_DEBUG
8327
 
  buf2len = snprintf(buf2, sizeof buf2,
8328
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8329
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8330
 
                     (ulong) rw_lock_count,
8331
 
                     (ulong) rw_lock_count_spin_loop,
8332
 
                     (ulong) rw_lock_count_spin_rounds,
8333
 
                     (ulong) rw_lock_count_os_wait,
8334
 
                     (ulong) rw_lock_count_os_yield,
8335
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7538
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7539
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7540
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7541
    rw_lock_count, rw_lock_count_spin_loop,
 
7542
    rw_lock_count_spin_rounds,
 
7543
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7544
    (ulong) (rw_lock_wait_time/1000));
8336
7545
 
8337
7546
  if (stat_print(session, innobase_engine_name, engine_name_len,
8338
7547
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8386
7595
          innobase_open_tables, fold, share);
8387
7596
 
8388
7597
    thr_lock_init(&share->lock);
8389
 
 
8390
 
    /* Index translation table initialization */
8391
 
    share->idx_trans_tbl.index_mapping = NULL;
8392
 
    share->idx_trans_tbl.index_count = 0;
8393
 
    share->idx_trans_tbl.array_size = 0;
8394
7598
  }
8395
7599
 
8396
7600
  share->use_count++;
8421
7625
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8422
7626
          innobase_open_tables, fold, share);
8423
7627
    share->lock.deinit();
8424
 
 
8425
 
    /* Free any memory from index translation table */
8426
 
    free(share->idx_trans_tbl.index_mapping);
8427
 
 
8428
7628
    delete share;
8429
7629
 
8430
7630
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8502
7702
    isolation_level = trx->isolation_level;
8503
7703
 
8504
7704
    if ((srv_locks_unsafe_for_binlog
8505
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7705
         || isolation_level == TRX_ISO_READ_COMMITTED)
8506
7706
        && isolation_level != TRX_ISO_SERIALIZABLE
8507
7707
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8508
7708
        && (sql_command == SQLCOM_INSERT_SELECT
8509
7709
            || sql_command == SQLCOM_REPLACE_SELECT
8510
7710
            || sql_command == SQLCOM_UPDATE
8511
 
            || sql_command == SQLCOM_CREATE_TABLE
8512
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7711
            || sql_command == SQLCOM_CREATE_TABLE)) {
8513
7712
 
8514
7713
      /* If we either have innobase_locks_unsafe_for_binlog
8515
7714
      option set or this session is using READ COMMITTED
8517
7716
      is not set to serializable and MySQL is doing
8518
7717
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8519
7718
      or UPDATE ... = (SELECT ...) or CREATE  ...
8520
 
      SELECT... or SET ... = (SELECT ...) without
8521
 
      FOR UPDATE or IN SHARE MODE in select,
8522
 
      then we use consistent read for select. */
 
7719
      SELECT... without FOR UPDATE or IN SHARE
 
7720
      MODE in select, then we use consistent read
 
7721
      for select. */
8523
7722
 
8524
7723
      prebuilt->select_lock_type = LOCK_NONE;
8525
7724
      prebuilt->stored_select_lock_type = LOCK_NONE;
8598
7797
  *value = dict_table_autoinc_read(prebuilt->table);
8599
7798
 
8600
7799
  /* It should have been initialized during open. */
8601
 
  if (*value == 0) {
8602
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8603
 
    dict_table_autoinc_unlock(prebuilt->table);
8604
 
  }
 
7800
  ut_a(*value != 0);
8605
7801
 
8606
7802
  return(DB_SUCCESS);
8607
7803
}
8608
7804
 
8609
7805
/*******************************************************************//**
8610
 
This function reads the global auto-inc counter. It doesn't use the
 
7806
This function reads the global auto-inc counter. It doesn't use the 
8611
7807
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8612
7808
@return the autoinc value */
8613
7809
UNIV_INTERN
8627
7823
 
8628
7824
  auto_inc = dict_table_autoinc_read(innodb_table);
8629
7825
 
8630
 
  if (auto_inc == 0) {
8631
 
    ut_print_timestamp(stderr);
8632
 
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
8633
 
            "is disabled for '%s'\n", innodb_table->name);
8634
 
  }
 
7826
  ut_a(auto_inc > 0);
8635
7827
 
8636
7828
  dict_table_autoinc_unlock(innodb_table);
8637
7829
 
8684
7876
  invoking this method. So we are not sure if it's guaranteed to
8685
7877
  be 0 or not. */
8686
7878
 
8687
 
  /* We need the upper limit of the col type to check for
8688
 
     whether we update the table autoinc counter or not. */
8689
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8690
 
 
8691
7879
  /* Called for the first time ? */
8692
7880
  if (trx->n_autoinc_rows == 0) {
8693
7881
 
8704
7892
  /* Not in the middle of a mult-row INSERT. */
8705
7893
  } else if (prebuilt->autoinc_last_value == 0) {
8706
7894
    set_if_bigger(*first_value, autoinc);
8707
 
    /* Check for -ve values. */
8708
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8709
 
    /* Set to next logical value. */
8710
 
    ut_a(autoinc > trx->n_autoinc_rows);
8711
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8712
7895
  }
8713
7896
 
8714
7897
  *nb_reserved_values = trx->n_autoinc_rows;
8718
7901
    uint64_t  need;
8719
7902
    uint64_t  current;
8720
7903
    uint64_t  next_value;
 
7904
    uint64_t  col_max_value;
 
7905
 
 
7906
    /* We need the upper limit of the col type to check for
 
7907
    whether we update the table autoinc counter or not. */
 
7908
    col_max_value = innobase_get_int_col_max_value(
 
7909
      getTable()->next_number_field);
8721
7910
 
8722
7911
    current = *first_value > col_max_value ? autoinc : *first_value;
8723
7912
    need = *nb_reserved_values * increment;
8977
8166
 
8978
8167
  innobase_release_stat_resources(trx);
8979
8168
 
 
8169
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8170
  {
 
8171
    if (trx->conc_state != TRX_NOT_STARTED)
 
8172
    {
 
8173
      commit(session, TRUE);
 
8174
    }
 
8175
  }
 
8176
  else
 
8177
  {
 
8178
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8179
        trx->global_read_view)
 
8180
    {
 
8181
      /* At low transaction isolation levels we let
 
8182
      each consistent read set its own snapshot */
 
8183
      read_view_close_for_mysql(trx);
 
8184
    }
 
8185
  }
8980
8186
}
8981
8187
 
8982
8188
/*******************************************************************//**
9046
8252
  return(error);
9047
8253
}
9048
8254
 
9049
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
9050
 
{
9051
 
  trx_t *trx= session_to_trx(session);
9052
 
  return (trx->id);
9053
 
}
9054
 
 
9055
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
9056
 
{
9057
 
  trx_t*& trx = session_to_trx(session);
9058
 
 
9059
 
  if (trx == NULL)
9060
 
  {
9061
 
    trx = innobase_trx_allocate(session);
9062
 
 
9063
 
    innobase_trx_init(session, trx);
9064
 
  }
9065
 
 
9066
 
  mutex_enter(&kernel_mutex);
9067
 
  trx->id= trx_sys_get_new_trx_id();
9068
 
  mutex_exit(&kernel_mutex);
9069
 
 
9070
 
  uint64_t transaction_id= trx->id;
9071
 
 
9072
 
  return transaction_id;
9073
 
}
9074
 
 
9075
8255
/*******************************************************************//**
9076
8256
This function is used to recover X/Open XA distributed transactions.
9077
8257
@return number of prepared transactions stored in xid_list */
9183
8363
}
9184
8364
 
9185
8365
/************************************************************//**
 
8366
Validate the file format check value, is it one of "on" or "off",
 
8367
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8368
@return true if config value one of "on" or  "off" */
 
8369
static
 
8370
bool
 
8371
innobase_file_format_check_on_off(
 
8372
/*==============================*/
 
8373
  const char* format_check) /*!< in: parameter value */
 
8374
{
 
8375
  bool    ret = true;
 
8376
 
 
8377
  if (!innobase_strcasecmp(format_check, "off")) {
 
8378
 
 
8379
    /* Set the value to disable checking. */
 
8380
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8381
 
 
8382
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8383
 
 
8384
    /* Set the value to the lowest supported format. */
 
8385
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8386
  } else {
 
8387
    ret = FALSE;
 
8388
  }
 
8389
 
 
8390
  return(ret);
 
8391
}
 
8392
 
 
8393
/************************************************************//**
9186
8394
Validate the file format check config parameters, as a side effect it
9187
 
sets the srv_max_file_format_at_startup variable.
 
8395
sets the srv_check_file_format_at_startup variable.
9188
8396
@return the format_id if valid config value, otherwise, return -1 */
9189
8397
static
9190
8398
int
9191
8399
innobase_file_format_validate_and_set(
9192
8400
/*================================*/
9193
 
  const char* format_max) /*!< in: parameter value */
 
8401
  const char* format_check) /*!< in: parameter value */
9194
8402
{
9195
8403
  uint    format_id;
9196
8404
 
9197
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8405
  format_id = innobase_file_format_name_lookup(format_check);
9198
8406
 
9199
8407
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9200
 
    srv_max_file_format_at_startup = format_id;
 
8408
    srv_check_file_format_at_startup = format_id;
9201
8409
    return((int) format_id);
9202
8410
  } else {
9203
8411
    return(-1);
9204
8412
  }
9205
8413
}
9206
8414
 
9207
 
 
 
8415
/*************************************************************//**
 
8416
Check if it is a valid file format. This function is registered as
 
8417
a callback with MySQL.
 
8418
@return 0 for valid file format */
 
8419
static
 
8420
int
 
8421
innodb_file_format_name_validate(
 
8422
/*=============================*/
 
8423
  Session*      , /*!< in: thread handle */
 
8424
  drizzle_sys_var*  , /*!< in: pointer to system
 
8425
            variable */
 
8426
  void*       save, /*!< out: immediate result
 
8427
            for update function */
 
8428
  drizzle_value*    value)  /*!< in: incoming string */
 
8429
{
 
8430
  const char* file_format_input;
 
8431
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8432
  int   len = sizeof(buff);
 
8433
 
 
8434
  ut_a(save != NULL);
 
8435
  ut_a(value != NULL);
 
8436
 
 
8437
  file_format_input = value->val_str(value, buff, &len);
 
8438
 
 
8439
  if (file_format_input != NULL) {
 
8440
    uint  format_id;
 
8441
 
 
8442
    format_id = innobase_file_format_name_lookup(
 
8443
      file_format_input);
 
8444
 
 
8445
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8446
      /* Save a pointer to the name in the
 
8447
         'file_format_name_map' constant array. */
 
8448
      *static_cast<const char**>(save) =
 
8449
        trx_sys_file_format_id_to_name(format_id);
 
8450
 
 
8451
      return(0);
 
8452
    }
 
8453
  }
 
8454
 
 
8455
  *static_cast<const char**>(save) = NULL;
 
8456
  return(1);
 
8457
}
 
8458
 
 
8459
/****************************************************************//**
 
8460
Update the system variable innodb_file_format using the "saved"
 
8461
value. This function is registered as a callback with MySQL. */
 
8462
static
 
8463
void
 
8464
innodb_file_format_name_update(
 
8465
/*===========================*/
 
8466
  Session*      ,   /*!< in: thread handle */
 
8467
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8468
              system variable */
 
8469
  void*       var_ptr,  /*!< out: where the
 
8470
              formal string goes */
 
8471
  const void*     save)   /*!< in: immediate result
 
8472
              from check function */
 
8473
{
 
8474
  const char* format_name;
 
8475
 
 
8476
  ut_a(var_ptr != NULL);
 
8477
  ut_a(save != NULL);
 
8478
 
 
8479
  format_name = *static_cast<const char*const*>(save);
 
8480
 
 
8481
  if (format_name) {
 
8482
    uint  format_id;
 
8483
 
 
8484
    format_id = innobase_file_format_name_lookup(format_name);
 
8485
 
 
8486
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8487
      srv_file_format = format_id;
 
8488
    }
 
8489
  }
 
8490
 
 
8491
  *static_cast<const char**>(var_ptr)
 
8492
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8493
}
 
8494
 
 
8495
/*************************************************************//**
 
8496
Check if valid argument to innodb_file_format_check. This
 
8497
function is registered as a callback with MySQL.
 
8498
@return 0 for valid file format */
 
8499
static
 
8500
int
 
8501
innodb_file_format_check_validate(
 
8502
/*==============================*/
 
8503
  Session*      session, /*!< in: thread handle */
 
8504
  drizzle_sys_var*  , /*!< in: pointer to system
 
8505
            variable */
 
8506
  void*       save, /*!< out: immediate result
 
8507
            for update function */
 
8508
  drizzle_value*    value)  /*!< in: incoming string */
 
8509
{
 
8510
  const char* file_format_input;
 
8511
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8512
  int   len = sizeof(buff);
 
8513
  int   format_id;
 
8514
 
 
8515
  ut_a(save != NULL);
 
8516
  ut_a(value != NULL);
 
8517
 
 
8518
  file_format_input = value->val_str(value, buff, &len);
 
8519
 
 
8520
  if (file_format_input != NULL) {
 
8521
 
 
8522
    /* Check if user set on/off, we want to print a suitable
 
8523
    message if they did so. */
 
8524
 
 
8525
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8526
      push_warning_printf(session,
 
8527
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8528
                          ER_WRONG_ARGUMENTS,
 
8529
        "InnoDB: invalid innodb_file_format_check "
 
8530
        "value; on/off can only be set at startup or "
 
8531
        "in the configuration file");
 
8532
    } else {
 
8533
      format_id = innobase_file_format_validate_and_set(file_format_input);
 
8534
      if (format_id >= 0) {
 
8535
        /* Save a pointer to the name in the
 
8536
           'file_format_name_map' constant array. */
 
8537
        *static_cast<const char**>(save) =
 
8538
          trx_sys_file_format_id_to_name(
 
8539
                                         (uint)format_id);
 
8540
 
 
8541
        return(0);
 
8542
 
 
8543
      } else {
 
8544
        push_warning_printf(session,
 
8545
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8546
                            ER_WRONG_ARGUMENTS,
 
8547
                            "InnoDB: invalid innodb_file_format_check "
 
8548
                            "value; can be any format up to %s "
 
8549
                            "or its equivalent numeric id",
 
8550
                            trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
8551
      }
 
8552
    }
 
8553
  }
 
8554
 
 
8555
  *static_cast<const char**>(save) = NULL;
 
8556
  return(1);
 
8557
}
 
8558
 
 
8559
/****************************************************************//**
 
8560
Update the system variable innodb_file_format_check using the "saved"
 
8561
value. This function is registered as a callback with MySQL. */
 
8562
static
 
8563
void
 
8564
innodb_file_format_check_update(
 
8565
/*============================*/
 
8566
  Session*      session,  /*!< in: thread handle */
 
8567
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8568
              system variable */
 
8569
  void*       var_ptr,  /*!< out: where the
 
8570
              formal string goes */
 
8571
  const void*     save)   /*!< in: immediate result
 
8572
              from check function */
 
8573
{
 
8574
  const char* format_name_in;
 
8575
  const char**  format_name_out;
 
8576
  uint    format_id;
 
8577
 
 
8578
  ut_a(save != NULL);
 
8579
  ut_a(var_ptr != NULL);
 
8580
 
 
8581
  format_name_in = *static_cast<const char*const*>(save);
 
8582
 
 
8583
  if (!format_name_in) {
 
8584
 
 
8585
    return;
 
8586
  }
 
8587
 
 
8588
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8589
 
 
8590
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8591
    /* DEFAULT is "on", which is invalid at runtime. */
 
8592
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8593
            ER_WRONG_ARGUMENTS,
 
8594
            "Ignoring SET innodb_file_format=%s",
 
8595
            format_name_in);
 
8596
    return;
 
8597
  }
 
8598
 
 
8599
  format_name_out = static_cast<const char**>(var_ptr);
 
8600
 
 
8601
  /* Update the max format id in the system tablespace. */
 
8602
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8603
    ut_print_timestamp(stderr);
 
8604
    fprintf(stderr,
 
8605
      " [Info] InnoDB: the file format in the system "
 
8606
      "tablespace is now set to %s.\n", *format_name_out);
 
8607
  }
 
8608
}
 
8609
 
 
8610
/****************************************************************//**
 
8611
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8612
value. This function is registered as a callback with MySQL. */
 
8613
static
 
8614
void
 
8615
innodb_adaptive_hash_index_update(
 
8616
/*==============================*/
 
8617
  Session*      ,   /*!< in: thread handle */
 
8618
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8619
              system variable */
 
8620
  void*       , /*!< out: where the
 
8621
              formal string goes */
 
8622
  const void*     save)   /*!< in: immediate result
 
8623
              from check function */
 
8624
{
 
8625
  if (*(bool*) save) {
 
8626
    btr_search_enable();
 
8627
  } else {
 
8628
    btr_search_disable();
 
8629
  }
 
8630
}
 
8631
 
 
8632
/****************************************************************//**
 
8633
Update the system variable innodb_old_blocks_pct using the "saved"
 
8634
value. This function is registered as a callback with MySQL. */
 
8635
static
 
8636
void
 
8637
innodb_old_blocks_pct_update(
 
8638
/*=========================*/
 
8639
        Session*                        ,       /*!< in: thread handle */
 
8640
        drizzle_sys_var*        ,       /*!< in: pointer to
 
8641
                                                system variable */
 
8642
        void*                           ,/*!< out: where the
 
8643
                                                formal string goes */
 
8644
        const void*                     save)   /*!< in: immediate result
 
8645
                                                from check function */
 
8646
{
 
8647
        innobase_old_blocks_pct = buf_LRU_old_ratio_update(
 
8648
                *static_cast<const uint*>(save), TRUE);
 
8649
}
 
8650
 
 
8651
/*************************************************************//**
 
8652
Check if it is a valid value of innodb_change_buffering.  This function is
 
8653
registered as a callback with MySQL.
 
8654
@return 0 for valid innodb_change_buffering */
 
8655
static
 
8656
int
 
8657
innodb_change_buffering_validate(
 
8658
/*=============================*/
 
8659
  Session*      , /*!< in: thread handle */
 
8660
  drizzle_sys_var*  , /*!< in: pointer to system
 
8661
            variable */
 
8662
  void*       save, /*!< out: immediate result
 
8663
            for update function */
 
8664
  drizzle_value*    value)  /*!< in: incoming string */
 
8665
{
 
8666
  const char* change_buffering_input;
 
8667
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8668
  int   len = sizeof(buff);
 
8669
 
 
8670
  ut_a(save != NULL);
 
8671
  ut_a(value != NULL);
 
8672
 
 
8673
  change_buffering_input = value->val_str(value, buff, &len);
 
8674
 
 
8675
  if (change_buffering_input != NULL) {
 
8676
    ulint use;
 
8677
 
 
8678
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8679
         use++) {
 
8680
      if (!innobase_strcasecmp(
 
8681
            change_buffering_input,
 
8682
            innobase_change_buffering_values[use])) {
 
8683
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8684
        return(0);
 
8685
      }
 
8686
    }
 
8687
  }
 
8688
 
 
8689
  return(1);
 
8690
}
 
8691
 
 
8692
/****************************************************************//**
 
8693
Update the system variable innodb_change_buffering using the "saved"
 
8694
value. This function is registered as a callback with MySQL. */
 
8695
static
 
8696
void
 
8697
innodb_change_buffering_update(
 
8698
/*===========================*/
 
8699
  Session*      ,   /*!< in: thread handle */
 
8700
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8701
              system variable */
 
8702
  void*       var_ptr,  /*!< out: where the
 
8703
              formal string goes */
 
8704
  const void*     save)   /*!< in: immediate result
 
8705
              from check function */
 
8706
{
 
8707
  ut_a(var_ptr != NULL);
 
8708
  ut_a(save != NULL);
 
8709
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8710
 
 
8711
  ibuf_use = *(const ibuf_use_t*) save;
 
8712
 
 
8713
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8714
}
 
8715
 
 
8716
/* plugin options */
 
8717
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8718
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8719
  "Enable InnoDB checksums validation (enabled by default). ",
 
8720
  NULL, NULL, TRUE);
 
8721
 
 
8722
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8723
  PLUGIN_VAR_READONLY,
 
8724
  "The common part for InnoDB table spaces.",
 
8725
  NULL, NULL, NULL);
 
8726
 
 
8727
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8728
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8729
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8730
  NULL, NULL, TRUE);
 
8731
 
 
8732
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8733
  PLUGIN_VAR_RQCMDARG,
 
8734
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8735
  NULL, NULL, 200, 100, ~0L, 0);
 
8736
 
 
8737
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8738
  PLUGIN_VAR_OPCMDARG,
 
8739
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8740
  "values are 0, 1 (faster)"
 
8741
  " or 2 (fastest - crash-like)"
 
8742
  ".",
 
8743
  NULL, NULL, 1, 0, 2, 0);
 
8744
 
 
8745
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8746
  PLUGIN_VAR_NOCMDARG,
 
8747
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8748
  NULL, NULL, FALSE);
 
8749
 
 
8750
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8751
  PLUGIN_VAR_RQCMDARG,
 
8752
  "File format to use for new tables in .ibd files.",
 
8753
  innodb_file_format_name_validate,
 
8754
  innodb_file_format_name_update, "Antelope");
 
8755
 
 
8756
/* If a new file format is introduced, the file format
 
8757
name needs to be updated accordingly. Please refer to
 
8758
file_format_name_map[] defined in trx0sys.c for the next
 
8759
file format name. */
 
8760
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8761
  PLUGIN_VAR_OPCMDARG,
 
8762
  "The highest file format in the tablespace.",
 
8763
  innodb_file_format_check_validate,
 
8764
  innodb_file_format_check_update,
 
8765
  "Barracuda");
 
8766
 
 
8767
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8768
  PLUGIN_VAR_OPCMDARG,
 
8769
  "Set to 0 (write and flush once per second),"
 
8770
  " 1 (write and flush at each commit)"
 
8771
  " or 2 (write at commit, flush once per second).",
 
8772
  NULL, NULL, 1, 0, 2, 0);
 
8773
 
 
8774
static DRIZZLE_SYSVAR_STR(flush_method, innobase_file_flush_method,
 
8775
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8776
  "With which method to flush data.", NULL, NULL, NULL);
 
8777
 
 
8778
#ifdef UNIV_LOG_ARCHIVE
 
8779
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8780
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8781
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8782
 
 
8783
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8784
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8785
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8786
#endif /* UNIV_LOG_ARCHIVE */
 
8787
 
 
8788
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8789
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8790
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8791
 
 
8792
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8793
  PLUGIN_VAR_RQCMDARG,
 
8794
  "Percentage of dirty pages allowed in bufferpool.",
 
8795
  NULL, NULL, 75, 0, 99, 0);
 
8796
 
 
8797
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8798
  PLUGIN_VAR_NOCMDARG,
 
8799
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8800
  NULL, NULL, TRUE);
 
8801
 
 
8802
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8803
  PLUGIN_VAR_RQCMDARG,
 
8804
  "Desired maximum length of the purge queue (0 = no limit)",
 
8805
  NULL, NULL, 0, 0, ~0L, 0);
 
8806
 
 
8807
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8808
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8809
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8810
  NULL, NULL, FALSE);
 
8811
 
 
8812
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8813
  PLUGIN_VAR_RQCMDARG,
 
8814
  "The number of index pages to sample when calculating statistics (default 8)",
 
8815
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8816
 
 
8817
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8818
  PLUGIN_VAR_OPCMDARG,
 
8819
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8820
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8821
 
 
8822
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8823
  PLUGIN_VAR_RQCMDARG,
 
8824
  "Replication thread delay (ms) on the slave server if "
 
8825
  "innodb_thread_concurrency is reached (0 by default)",
 
8826
  NULL, NULL, 0, 0, ~0UL, 0);
 
8827
 
 
8828
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8829
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8830
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8831
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8832
 
 
8833
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8834
  PLUGIN_VAR_RQCMDARG,
 
8835
  "Data file autoextend increment in megabytes",
 
8836
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8837
 
 
8838
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8839
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8840
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8841
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8842
 
 
8843
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8844
  PLUGIN_VAR_RQCMDARG,
 
8845
  "Helps in performance tuning in heavily concurrent environments.",
 
8846
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8847
 
 
8848
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8849
  PLUGIN_VAR_RQCMDARG,
 
8850
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8851
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8852
 
 
8853
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8854
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8855
  "Number of background read I/O threads in InnoDB.",
 
8856
  NULL, NULL, 4, 1, 64, 0);
 
8857
 
 
8858
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8859
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8860
  "Number of background write I/O threads in InnoDB.",
 
8861
  NULL, NULL, 4, 1, 64, 0);
 
8862
 
 
8863
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8864
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8865
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8866
  NULL, NULL, 0, 0, 6, 0);
 
8867
 
 
8868
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8869
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8870
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8871
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8872
 
 
8873
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8874
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8875
  "Size of each log file in a log group.",
 
8876
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8877
 
 
8878
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8879
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8880
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8881
  NULL, NULL, 2, 2, 100, 0);
 
8882
 
 
8883
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8884
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8885
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8886
  NULL, NULL, 1, 1, 10, 0);
 
8887
 
 
8888
static DRIZZLE_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
 
8889
  PLUGIN_VAR_RQCMDARG,
 
8890
  "Percentage of the buffer pool to reserve for 'old' blocks.",
 
8891
  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
 
8892
 
 
8893
static DRIZZLE_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
 
8894
  PLUGIN_VAR_RQCMDARG,
 
8895
  "Move blocks to the 'new' end of the buffer pool if the first access"
 
8896
  " was at least this many milliseconds ago."
 
8897
  " The timeout is disabled if 0 (the default).",
 
8898
  NULL, NULL, 0, 0, UINT32_MAX, 0);
 
8899
 
 
8900
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8901
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8902
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8903
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8904
 
 
8905
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8906
  PLUGIN_VAR_RQCMDARG,
 
8907
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8908
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8909
 
 
8910
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8911
  PLUGIN_VAR_OPCMDARG,
 
8912
  "Maximum delay between polling for a spin lock (6 by default)",
 
8913
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8914
 
 
8915
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8916
  PLUGIN_VAR_RQCMDARG,
 
8917
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8918
  NULL, NULL, 0, 0, 1000, 0);
 
8919
 
 
8920
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8921
  PLUGIN_VAR_RQCMDARG,
 
8922
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8923
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8924
 
 
8925
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8926
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8927
  "Path to individual files and their sizes.",
 
8928
  NULL, NULL, NULL);
 
8929
 
 
8930
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8931
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8932
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8933
 
 
8934
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8935
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8936
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8937
  NULL, NULL, TRUE);
 
8938
 
 
8939
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8940
  PLUGIN_VAR_RQCMDARG,
 
8941
  "Buffer changes to reduce random access: "
 
8942
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8943
  innodb_change_buffering_validate,
 
8944
  innodb_change_buffering_update, NULL);
 
8945
 
 
8946
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8947
  PLUGIN_VAR_RQCMDARG,
 
8948
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8949
  "trigger a readahead.",
 
8950
  NULL, NULL, 56, 0, 64, 0);
9208
8951
 
9209
8952
static void init_options(drizzled::module::option_context &context)
9210
8953
{
9216
8959
  context("disable-doublewrite",
9217
8960
          "Disable InnoDB doublewrite buffer.");
9218
8961
  context("io-capacity",
9219
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8962
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9220
8963
          "Number of IOPs the server can do. Tunes the background IO rate");
9221
8964
  context("fast-shutdown",
9222
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8965
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9223
8966
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9224
 
  context("purge-batch-size",
9225
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9226
 
          "Number of UNDO logs to purge in one batch from the history list. "
9227
 
          "Default is 20.");
9228
 
  context("purge-threads",
9229
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9230
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9231
8967
  context("file-per-table",
9232
8968
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9233
8969
          "Stores each InnoDB table to an .ibd file in the database dir.");
9234
8970
  context("file-format",
9235
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8971
          po::value<string>()->default_value("Antelope"),
9236
8972
          "File format to use for new tables in .ibd files.");
9237
 
  context("file-format-max",
9238
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
 
8973
  context("file-format-check",
 
8974
          po::value<string>()->default_value("on"),
9239
8975
          "The highest file format in the tablespace.");
9240
 
  context("file-format-check",
9241
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9242
 
          "Whether to perform system file format check.");
9243
8976
  context("flush-log-at-trx-commit",
9244
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8977
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9245
8978
          "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).");
9246
8979
  context("flush-method",
9247
8980
          po::value<string>(),
9248
8981
          "With which method to flush data.");
 
8982
#ifdef UNIV_LOG_ARCHIVE
 
8983
  context("log-arch-dir",
 
8984
          po::value<string>(),
 
8985
          "Where full logs should be archived.");
 
8986
  context("log-archive",
 
8987
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8988
          "Set to 1 if you want to have logs archived.");
 
8989
#endif /* UNIV_LOG_ARCHIVE */
9249
8990
  context("log-group-home-dir",
9250
8991
          po::value<string>(),
9251
8992
          "Path to InnoDB log files.");
9252
8993
  context("max-dirty-pages-pct",
9253
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8994
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9254
8995
          "Percentage of dirty pages allowed in bufferpool.");
9255
8996
  context("disable-adaptive-flushing",
9256
8997
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9257
8998
  context("max-purge-lag",
9258
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8999
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9259
9000
          "Desired maximum length of the purge queue (0 = no limit)");
9260
9001
  context("status-file",
9261
9002
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9263
9004
  context("disable-stats-on-metadata",
9264
9005
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9265
9006
  context("stats-sample-pages",
9266
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
9007
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9267
9008
          "The number of index pages to sample when calculating statistics (default 8)");
9268
9009
  context("disable-adaptive-hash-index",
9269
9010
          "Enable InnoDB adaptive hash index (enabled by default)");
9270
9011
  context("replication-delay",
9271
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
9012
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9272
9013
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9273
9014
  context("additional-mem-pool-size",
9274
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
9015
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9275
9016
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9276
9017
  context("autoextend-increment",
9277
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
 
9018
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9278
9019
          "Data file autoextend increment in megabytes");
9279
9020
  context("buffer-pool-size",
9280
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
9021
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9281
9022
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9282
 
  context("buffer-pool-instances",
9283
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9284
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9285
 
 
9286
9023
  context("commit-concurrency",
9287
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
9024
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9288
9025
          "Helps in performance tuning in heavily concurrent environments.");
9289
9026
  context("concurrency-tickets",
9290
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
9027
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9291
9028
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9292
9029
  context("read-io-threads",
9293
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
9030
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9294
9031
          "Number of background read I/O threads in InnoDB.");
9295
9032
  context("write-io-threads",
9296
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
9033
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9297
9034
          "Number of background write I/O threads in InnoDB.");
9298
9035
  context("force-recovery",
9299
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
9036
          po::value<long>(&innobase_force_recovery)->default_value(0),
9300
9037
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9301
9038
  context("log-buffer-size",
9302
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
9039
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9303
9040
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9304
9041
  context("log-file-size",
9305
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
9042
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9306
9043
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9307
9044
  context("log-files-in-group",
9308
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
9045
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9309
9046
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9310
9047
  context("mirrored-log-groups",
9311
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
9048
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9312
9049
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9313
9050
  context("open-files",
9314
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
9051
          po::value<long>(&innobase_open_files)->default_value(300L),
9315
9052
          "How many files at the maximum InnoDB keeps open at the same time.");
9316
9053
  context("sync-spin-loops",
9317
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9054
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9318
9055
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9319
9056
  context("spin-wait-delay",
9320
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9057
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9321
9058
          "Maximum delay between polling for a spin lock (6 by default)");
9322
9059
  context("thread-concurrency",
9323
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9060
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9324
9061
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9325
9062
  context("thread-sleep-delay",
9326
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9063
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9327
9064
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9328
9065
  context("data-file-path",
9329
9066
          po::value<string>(),
9334
9071
  context("use-internal-malloc",
9335
9072
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9336
9073
  context("change-buffering",
9337
 
          po::value<string>(&innobase_change_buffering),
 
9074
          po::value<string>(),
9338
9075
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9339
9076
  context("read-ahead-threshold",
9340
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9077
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9341
9078
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9342
9079
  context("disable-xa",
9343
9080
          "Disable InnoDB support for the XA two-phase commit");
9344
9081
  context("disable-table-locks",
9345
9082
          "Disable InnoDB locking in LOCK TABLES");
9346
9083
  context("strict-mode",
9347
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9084
          po::value<bool>()->default_value(false)->zero_tokens(),
9348
9085
          "Use strict mode when evaluating create options.");
9349
 
  context("replication-log",
9350
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9351
 
          _("Enable internal replication log."));
9352
9086
  context("lock-wait-timeout",
9353
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9354
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9355
 
  context("old-blocks-pct",
9356
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9357
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9358
 
  context("old-blocks-time",
9359
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9360
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9361
 
            " was at least this many milliseconds ago."
9362
 
            " The timeout is disabled if 0 (the default)."));
 
9087
          po::value<unsigned long>()->default_value(50),
 
9088
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9363
9089
}
9364
9090
 
9365
 
 
 
9091
static drizzle_sys_var* innobase_system_variables[]= {
 
9092
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9093
  DRIZZLE_SYSVAR(autoextend_increment),
 
9094
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9095
  DRIZZLE_SYSVAR(checksums),
 
9096
  DRIZZLE_SYSVAR(commit_concurrency),
 
9097
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9098
  DRIZZLE_SYSVAR(data_file_path),
 
9099
  DRIZZLE_SYSVAR(data_home_dir),
 
9100
  DRIZZLE_SYSVAR(doublewrite),
 
9101
  DRIZZLE_SYSVAR(fast_shutdown),
 
9102
  DRIZZLE_SYSVAR(read_io_threads),
 
9103
  DRIZZLE_SYSVAR(write_io_threads),
 
9104
  DRIZZLE_SYSVAR(file_per_table),
 
9105
  DRIZZLE_SYSVAR(file_format),
 
9106
  DRIZZLE_SYSVAR(file_format_check),
 
9107
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9108
  DRIZZLE_SYSVAR(flush_method),
 
9109
  DRIZZLE_SYSVAR(force_recovery),
 
9110
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9111
#ifdef UNIV_LOG_ARCHIVE
 
9112
  DRIZZLE_SYSVAR(log_arch_dir),
 
9113
  DRIZZLE_SYSVAR(log_archive),
 
9114
#endif /* UNIV_LOG_ARCHIVE */
 
9115
  DRIZZLE_SYSVAR(log_buffer_size),
 
9116
  DRIZZLE_SYSVAR(log_file_size),
 
9117
  DRIZZLE_SYSVAR(log_files_in_group),
 
9118
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9119
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9120
  DRIZZLE_SYSVAR(max_purge_lag),
 
9121
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9122
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9123
  DRIZZLE_SYSVAR(old_blocks_pct),
 
9124
  DRIZZLE_SYSVAR(old_blocks_time),
 
9125
  DRIZZLE_SYSVAR(open_files),
 
9126
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9127
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9128
  DRIZZLE_SYSVAR(replication_delay),
 
9129
  DRIZZLE_SYSVAR(status_file),
 
9130
  DRIZZLE_SYSVAR(strict_mode),
 
9131
  DRIZZLE_SYSVAR(support_xa),
 
9132
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9133
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9134
  DRIZZLE_SYSVAR(table_locks),
 
9135
  DRIZZLE_SYSVAR(thread_concurrency),
 
9136
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9137
  DRIZZLE_SYSVAR(version),
 
9138
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9139
  DRIZZLE_SYSVAR(change_buffering),
 
9140
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9141
  DRIZZLE_SYSVAR(io_capacity),
 
9142
  NULL
 
9143
};
9366
9144
 
9367
9145
DRIZZLE_DECLARE_PLUGIN
9368
9146
{
9373
9151
  "Supports transactions, row-level locking, and foreign keys",
9374
9152
  PLUGIN_LICENSE_GPL,
9375
9153
  innobase_init, /* Plugin Init */
9376
 
  NULL, /* system variables */
 
9154
  innobase_system_variables, /* system variables */
9377
9155
  init_options /* reserved */
9378
9156
}
9379
9157
DRIZZLE_DECLARE_PLUGIN_END;
9401
9179
  return res;
9402
9180
}
9403
9181
 
 
9182
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9183
 
 
9184
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9185
from zero to nonzero. (Bug #42101)
 
9186
 
 
9187
The initial default value is 0, and without this extra initialization,
 
9188
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9189
to 0, even if it was initially set to nonzero at the command line
 
9190
or configuration file. */
 
9191
static
 
9192
void
 
9193
innobase_commit_concurrency_init_default(void)
 
9194
/*==========================================*/
 
9195
{
 
9196
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9197
    = innobase_commit_concurrency;
 
9198
}
 
9199
 
9404
9200
/***********************************************************************
9405
9201
This function checks each index name for a table against reserved
9406
9202
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,