~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Updated an include guard thanks to a nice catch during code review from Jay. Thanks Jay!

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
***********************************************************************/
51
51
 
52
52
/* TODO list for the InnoDB Cursor in 5.0:
 
53
  - Remove the flag trx->active_trans and look at trx->conc_state
53
54
  - fix savepoint functions to use savepoint storage area
54
55
  - Find out what kind of problems the OS X case-insensitivity causes to
55
56
    table and database names; should we 'normalize' the names like we do
56
57
    in Windows?
57
58
*/
58
59
 
59
 
#include "config.h"
60
 
 
61
 
#include <limits.h>
62
 
#include <fcntl.h>
63
 
 
 
60
#include "drizzled/server_includes.h"
64
61
#include "drizzled/error.h"
65
62
#include "drizzled/errmsg_print.h"
66
 
#include "drizzled/charset_info.h"
67
 
#include "drizzled/internal/m_string.h"
68
 
#include "drizzled/internal/my_sys.h"
69
 
#include "drizzled/my_hash.h"
 
63
#include "mystrings/m_ctype.h"
 
64
#include "mysys/my_sys.h"
 
65
#include "mysys/hash.h"
 
66
#include "mysys/mysys_err.h"
70
67
#include "drizzled/plugin.h"
71
68
#include "drizzled/show.h"
72
69
#include "drizzled/data_home.h"
73
70
#include "drizzled/error.h"
74
71
#include "drizzled/field.h"
75
 
#include "drizzled/charset.h"
76
72
#include "drizzled/session.h"
77
73
#include "drizzled/current_session.h"
78
74
#include "drizzled/table.h"
79
75
#include "drizzled/field/blob.h"
80
76
#include "drizzled/field/varstring.h"
81
77
#include "drizzled/field/timestamp.h"
82
 
#include "drizzled/plugin/xa_storage_engine.h"
83
 
#include "drizzled/plugin/daemon.h"
 
78
#include "drizzled/plugin/storage_engine.h"
 
79
#include "drizzled/plugin/info_schema_table.h"
84
80
#include "drizzled/memory/multi_malloc.h"
85
 
#include "drizzled/pthread_globals.h"
86
 
#include "drizzled/named_savepoint.h"
87
 
 
88
 
#include <drizzled/transaction_services.h>
89
81
 
90
82
/** @file ha_innodb.cc */
91
83
 
123
115
}
124
116
 
125
117
#include "ha_innodb.h"
126
 
#include "data_dictionary.h"
 
118
#include "i_s.h"
127
119
#include "handler0vars.h"
128
120
 
129
 
#include <iostream>
130
 
#include <sstream>
131
121
#include <string>
132
122
 
133
 
#include "plugin/innobase/handler/status_function.h"
134
 
 
135
123
using namespace std;
136
 
using namespace drizzled;
 
124
 
137
125
 
138
126
#ifndef DRIZZLE_SERVER
139
127
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
164
152
# define EQ_CURRENT_SESSION(session) ((session) == current_session)
165
153
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
166
154
 
167
 
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
168
 
static plugin::TableFunction* status_table_function_ptr= NULL;
169
 
static plugin::TableFunction* cmp_tool= NULL;
170
 
static plugin::TableFunction* cmp_reset_tool= NULL;
171
 
static plugin::TableFunction* cmp_mem_tool= NULL;
172
 
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
173
 
static plugin::TableFunction* innodb_trx_tool= NULL;
174
 
static plugin::TableFunction* innodb_locks_tool= NULL;
175
 
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
155
static drizzled::plugin::StorageEngine* innodb_engine_ptr= NULL;
176
156
 
177
157
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
178
158
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
220
200
#endif /* UNIV_LOG_ARCHIVE */
221
201
static my_bool  innobase_use_doublewrite                = TRUE;
222
202
static my_bool  innobase_use_checksums                  = TRUE;
 
203
static my_bool  innobase_locks_unsafe_for_binlog        = TRUE;
223
204
static my_bool  innobase_rollback_on_timeout            = FALSE;
224
205
static my_bool  innobase_create_status_file             = FALSE;
225
206
static my_bool  innobase_stats_on_metadata              = TRUE;
255
236
  NULL
256
237
};
257
238
 
258
 
#define DEFAULT_FILE_EXTENSION ".dfe" // Deep Fried Elephant
259
 
 
260
239
static INNOBASE_SHARE *get_share(const char *table_name);
261
240
static void free_share(INNOBASE_SHARE *share);
262
241
 
263
 
class InnobaseEngine : public plugin::XaStorageEngine
 
242
class InnobaseEngine : public drizzled::plugin::StorageEngine
264
243
{
265
244
public:
266
 
  explicit InnobaseEngine(string name_arg) :
267
 
    plugin::XaStorageEngine(name_arg,
268
 
                            HTON_NULL_IN_KEY |
269
 
                            HTON_CAN_INDEX_BLOBS |
270
 
                            HTON_PRIMARY_KEY_REQUIRED_FOR_POSITION |
271
 
                            HTON_PRIMARY_KEY_IN_READ_INDEX |
272
 
                            HTON_PARTIAL_COLUMN_READ |
273
 
                            HTON_TABLE_SCAN_ON_INDEX |
274
 
                            HTON_HAS_FOREIGN_KEYS |
275
 
                            HTON_HAS_DOES_TRANSACTIONS)
 
245
  InnobaseEngine(string name_arg)
 
246
   : drizzled::plugin::StorageEngine(name_arg,
 
247
                                     HTON_NULL_IN_KEY |
 
248
                                     HTON_CAN_INDEX_BLOBS |
 
249
                                     HTON_PRIMARY_KEY_REQUIRED_FOR_POSITION |
 
250
                                     HTON_PRIMARY_KEY_IN_READ_INDEX |
 
251
                                     HTON_PARTIAL_COLUMN_READ |
 
252
                                     HTON_TABLE_SCAN_ON_INDEX |
 
253
                                     HTON_MRR_CANT_SORT |
 
254
                                     HTON_HAS_DOES_TRANSACTIONS, sizeof(trx_named_savept_t))
276
255
  {
277
 
    table_definition_ext= plugin::DEFAULT_DEFINITION_FILE_EXT;
 
256
    table_definition_ext= drizzled::plugin::DEFAULT_DEFINITION_FILE_EXT;
278
257
    addAlias("INNOBASE");
279
258
  }
280
259
 
281
 
  virtual ~InnobaseEngine()
282
 
  {
283
 
    int err= 0;
284
 
    if (innodb_inited) {
285
 
 
286
 
      srv_fast_shutdown = (ulint) innobase_fast_shutdown;
287
 
      innodb_inited = 0;
288
 
      hash_table_free(innobase_open_tables);
289
 
      innobase_open_tables = NULL;
290
 
      if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
291
 
        err = 1;
292
 
      }
293
 
      srv_free_paths_and_sizes();
294
 
      if (internal_innobase_data_file_path)
295
 
        free(internal_innobase_data_file_path);
296
 
      pthread_mutex_destroy(&innobase_share_mutex);
297
 
      pthread_mutex_destroy(&prepare_commit_mutex);
298
 
      pthread_mutex_destroy(&commit_threads_m);
299
 
      pthread_mutex_destroy(&commit_cond_m);
300
 
      pthread_cond_destroy(&commit_cond);
301
 
    }
302
 
  }
303
 
 
304
 
private:
305
 
  virtual int doStartTransaction(Session *session, start_transaction_option_t options);
306
 
  virtual void doStartStatement(Session *session);
307
 
  virtual void doEndStatement(Session *session);
308
 
public:
309
260
  virtual
310
261
  int
311
262
  close_connection(
314
265
        Session*        session);       /* in: handle to the MySQL thread of the user
315
266
                        whose resources should be free'd */
316
267
 
317
 
  virtual int doSetSavepoint(Session* session,
318
 
                                 drizzled::NamedSavepoint &savepoint);
319
 
  virtual int doRollbackToSavepoint(Session* session,
320
 
                                     drizzled::NamedSavepoint &savepoint);
321
 
  virtual int doReleaseSavepoint(Session* session,
322
 
                                     drizzled::NamedSavepoint &savepoint);
323
 
  virtual int doXaCommit(Session* session, bool all)
324
 
  {
325
 
    return doCommit(session, all); /* XA commit just does a SQL COMMIT */
326
 
  }
327
 
  virtual int doXaRollback(Session *session, bool all)
328
 
  {
329
 
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
330
 
  }
331
 
  virtual int doCommit(Session* session, bool all);
332
 
  virtual int doRollback(Session* session, bool all);
 
268
  virtual int savepoint_set_hook(Session* session,
 
269
                                 void *savepoint);
 
270
  virtual int savepoint_rollback_hook(Session* session,
 
271
                                      void *savepoint);
 
272
  virtual int savepoint_release_hook(Session* session,
 
273
                                     void *savepoint);
 
274
  virtual int commit(Session* session, bool all);
 
275
  virtual int rollback(Session* session, bool all);
333
276
 
334
277
  /***********************************************************************
335
278
  This function is used to prepare X/Open XA distributed transaction   */
336
279
  virtual
337
280
  int
338
 
  doXaPrepare(
 
281
  prepare(
339
282
  /*================*/
340
283
                        /* out: 0 or error number */
341
284
        Session*        session,        /* in: handle to the MySQL thread of the user
346
289
  This function is used to recover X/Open XA distributed transactions   */
347
290
  virtual
348
291
  int
349
 
  doXaRecover(
 
292
  recover(
350
293
  /*================*/
351
294
                                /* out: number of prepared transactions
352
295
                                stored in xid_list */
353
 
        ::drizzled::XID*        xid_list,       /* in/out: prepared transactions */
354
 
        size_t len);            /* in: number of slots in xid_list */
 
296
        XID*    xid_list,       /* in/out: prepared transactions */
 
297
        uint    len);           /* in: number of slots in xid_list */
355
298
  /***********************************************************************
356
299
  This function is used to commit one X/Open XA distributed transaction
357
300
  which is in the prepared state */
358
301
  virtual
359
302
  int
360
 
  doXaCommitXid(
 
303
  commit_by_xid(
361
304
  /*===================*/
362
305
                        /* out: 0 or error number */
363
 
        ::drizzled::XID*        xid);   /* in: X/Open XA transaction identification */
 
306
        XID*    xid);   /* in: X/Open XA transaction identification */
364
307
  /***********************************************************************
365
308
  This function is used to rollback one X/Open XA distributed transaction
366
309
  which is in the prepared state */
367
310
  virtual
368
311
  int
369
 
  doXaRollbackXid(
 
312
  rollback_by_xid(
370
313
  /*=====================*/
371
314
                        /* out: 0 or error number */
372
 
        ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
 
315
        XID     *xid);  /* in: X/Open XA transaction identification */
373
316
 
374
317
  virtual Cursor *create(TableShare &table,
375
 
                         memory::Root *mem_root)
 
318
                          MEM_ROOT *mem_root)
376
319
  {
377
320
    return new (mem_root) ha_innobase(*this, table);
378
321
  }
379
322
 
380
323
  /*********************************************************************
381
324
  Removes all tables in the named database inside InnoDB. */
382
 
  bool
383
 
  doDropSchema(
 
325
  virtual
 
326
  void
 
327
  drop_database(
384
328
  /*===================*/
385
329
                        /* out: error number */
386
 
        SchemaIdentifier        &identifier);   /* in: database path; inside InnoDB the name
 
330
        char*   path);  /* in: database path; inside InnoDB the name
387
331
                        of the last directory in the path is used as
388
332
                        the database name: for example, in 'mysql/data/test'
389
333
                        the database name is 'test' */
390
334
 
 
335
  /*********************************************************************
 
336
  Creates an InnoDB transaction struct for the session if it does not yet have one.
 
337
  Starts a new InnoDB transaction if a transaction is not yet started. And
 
338
  assigns a new snapshot for a consistent read if the transaction does not yet
 
339
  have one. */
 
340
  virtual
 
341
  int
 
342
  start_consistent_snapshot(
 
343
  /*====================================*/
 
344
                        /* out: 0 */
 
345
        Session*        session);       /* in: MySQL thread handle of the user for whom
 
346
                        the transaction should be committed */
391
347
  /********************************************************************
392
348
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
393
349
  the logs, and the name of this function should be innobase_checkpoint. */
410
366
 
411
367
  virtual
412
368
  int
413
 
  doReleaseTemporaryLatches(
 
369
  release_temporary_latches(
414
370
  /*===============================*/
415
371
                                /* out: 0 */
416
372
        Session*                session);       /* in: MySQL thread */
420
376
        return(ha_innobase_exts);
421
377
  }
422
378
 
423
 
  UNIV_INTERN int doCreateTable(Session &session,
424
 
                                Table &form,
425
 
                                drizzled::TableIdentifier &identifier,
426
 
                                message::Table&);
427
 
  UNIV_INTERN int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
428
 
  UNIV_INTERN int doDropTable(Session &session, TableIdentifier &identifier);
 
379
  UNIV_INTERN int doCreateTable(Session *session,
 
380
                                const char *table_name,
 
381
                                Table& form,
 
382
                                drizzled::message::Table&);
 
383
  UNIV_INTERN int doRenameTable(Session* session,
 
384
                                const char* from,
 
385
                                const char* to);
 
386
  UNIV_INTERN int doDropTable(Session& session, const string table_path);
429
387
 
430
388
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
431
389
 
442
400
            HA_READ_RANGE |
443
401
            HA_KEYREAD_ONLY);
444
402
  }
445
 
 
446
 
  int doGetTableDefinition(drizzled::Session& session,
447
 
                           drizzled::TableIdentifier &identifier,
448
 
                           drizzled::message::Table &table_proto);
449
 
 
450
 
  void doGetTableNames(drizzled::CachedDirectory &directory,
451
 
                       drizzled::SchemaIdentifier &schema_identifier,
452
 
                       std::set<std::string> &set_of_names);
453
 
 
454
 
  bool doDoesTableExist(drizzled::Session& session, drizzled::TableIdentifier &identifier);
455
 
 
456
 
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
457
 
                             drizzled::SchemaIdentifier &schema_identifier,
458
 
                             drizzled::TableIdentifiers &set_of_identifiers);
459
403
};
460
404
 
461
 
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
462
 
                                           drizzled::SchemaIdentifier &schema_identifier,
463
 
                                           drizzled::TableIdentifiers &set_of_identifiers)
464
 
{
465
 
  CachedDirectory::Entries entries= directory.getEntries();
466
 
 
467
 
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
468
 
       entry_iter != entries.end(); ++entry_iter)
469
 
  {
470
 
    CachedDirectory::Entry *entry= *entry_iter;
471
 
    const string *filename= &entry->filename;
472
 
 
473
 
    assert(filename->size());
474
 
 
475
 
    const char *ext= strchr(filename->c_str(), '.');
476
 
 
477
 
    if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_FILE_EXTENSION) ||
478
 
        (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
479
 
    { }
480
 
    else
481
 
    {
482
 
      char uname[NAME_LEN + 1];
483
 
      uint32_t file_name_len;
484
 
 
485
 
      file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
486
 
      // TODO: Remove need for memory copy here
487
 
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
488
 
 
489
 
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
490
 
    }
491
 
  }
492
 
}
493
 
 
494
 
bool InnobaseEngine::doDoesTableExist(Session&, TableIdentifier &identifier)
495
 
{
496
 
  string proto_path(identifier.getPath());
497
 
  proto_path.append(DEFAULT_FILE_EXTENSION);
498
 
 
499
 
  if (access(proto_path.c_str(), F_OK))
500
 
  {
501
 
    return false;
502
 
  }
503
 
 
504
 
  return true;
505
 
}
506
 
 
507
 
int InnobaseEngine::doGetTableDefinition(Session &,
508
 
                                         drizzled::TableIdentifier &identifier,
509
 
                                         message::Table &table_proto)
510
 
{
511
 
  string proto_path(identifier.getPath());
512
 
  proto_path.append(DEFAULT_FILE_EXTENSION);
513
 
 
514
 
  if (access(proto_path.c_str(), F_OK))
515
 
  {
516
 
    return errno;
517
 
  }
518
 
 
519
 
  if (StorageEngine::readTableFile(proto_path, table_proto))
520
 
    return EEXIST;
521
 
 
522
 
  return ENOENT;
523
 
}
524
 
 
525
 
void InnobaseEngine::doGetTableNames(CachedDirectory &directory, SchemaIdentifier&, set<string>& set_of_names)
526
 
{
527
 
  CachedDirectory::Entries entries= directory.getEntries();
528
 
 
529
 
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
530
 
       entry_iter != entries.end(); ++entry_iter)
531
 
  {
532
 
    CachedDirectory::Entry *entry= *entry_iter;
533
 
    const string *filename= &entry->filename;
534
 
 
535
 
    assert(filename->size());
536
 
 
537
 
    const char *ext= strchr(filename->c_str(), '.');
538
 
 
539
 
    if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_FILE_EXTENSION) ||
540
 
        (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
541
 
    { }
542
 
    else
543
 
    {
544
 
      char uname[NAME_LEN + 1];
545
 
      uint32_t file_name_len;
546
 
 
547
 
      file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
548
 
      // TODO: Remove need for memory copy here
549
 
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
550
 
      set_of_names.insert(uname);
551
 
    }
552
 
  }
553
 
}
554
 
 
555
405
/** @brief Initialize the default value of innodb_commit_concurrency.
556
406
 
557
407
Once InnoDB is running, the innodb_commit_concurrency must not change
645
495
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
646
496
 
647
497
 
 
498
/***********************************************************************
 
499
Closes an InnoDB database. */
 
500
static
 
501
int
 
502
innobase_deinit(drizzled::plugin::Registry &registry);
 
503
 
648
504
/*****************************************************************//**
649
505
Commits a transaction in an InnoDB database. */
650
506
static
653
509
/*================*/
654
510
        trx_t*  trx);   /*!< in: transaction handle */
655
511
 
656
 
static drizzle_show_var innodb_status_variables[]= {
 
512
static SHOW_VAR innodb_status_variables[]= {
657
513
  {"buffer_pool_pages_data",
658
514
  (char*) &export_vars.innodb_buffer_pool_pages_data,     SHOW_LONG},
659
515
  {"buffer_pool_pages_dirty",
747
603
  {NULL, NULL, SHOW_LONG}
748
604
};
749
605
 
750
 
InnodbStatusTool::Generator::Generator(drizzled::Field **fields) :
751
 
  plugin::TableFunction::Generator(fields)
752
 
753
 
  srv_export_innodb_status();
754
 
  status_var_ptr= innodb_status_variables;
755
 
}
756
 
 
757
 
bool InnodbStatusTool::Generator::populate()
758
 
{
759
 
  if (status_var_ptr->name)
760
 
  {
761
 
    std::ostringstream oss;
762
 
    string return_value;
763
 
    const char *value= status_var_ptr->value;
764
 
 
765
 
    /* VARIABLE_NAME */
766
 
    push(status_var_ptr->name);
767
 
 
768
 
    switch (status_var_ptr->type)
769
 
    {
770
 
    case SHOW_LONG:
771
 
      oss << *(int64_t*) value;
772
 
      return_value= oss.str();
773
 
      break;
774
 
    case SHOW_LONGLONG:
775
 
      oss << *(int64_t*) value;
776
 
      return_value= oss.str();
777
 
      break;
778
 
    case SHOW_BOOL:
779
 
      return_value= *(bool*) value ? "ON" : "OFF";
780
 
      break;
781
 
    default:
782
 
      assert(0);
783
 
    }
784
 
 
785
 
    /* VARIABLE_VALUE */
786
 
    if (return_value.length())
787
 
      push(return_value);
788
 
    else 
789
 
      push(" ");
790
 
 
791
 
    status_var_ptr++;
792
 
 
793
 
    return true;
794
 
  }
795
 
  return false;
796
 
}
797
 
 
798
606
/* General functions */
799
607
 
800
608
/******************************************************************//**
940
748
/*=======*/
941
749
        Session*        session)        /*!< in: Drizzle Session */
942
750
{
943
 
        return *(trx_t**) session->getEngineData(innodb_engine_ptr);
 
751
        return(*(trx_t**) session_ha_data(session, innodb_engine_ptr));
944
752
}
945
753
 
946
754
/********************************************************************//**
949
757
documentation, see Cursor.cc.
950
758
@return 0 */
951
759
int
952
 
InnobaseEngine::doReleaseTemporaryLatches(
 
760
InnobaseEngine::release_temporary_latches(
953
761
/*===============================*/
954
762
        Session*                session)        /*!< in: MySQL thread */
955
763
{
1161
969
          static_cast<uint64_t>(session_get_thread_id( session)),
1162
970
          static_cast<uint64_t>(session->getQueryId()),
1163
971
          glob_hostname,
1164
 
          session->getSecurityContext().getIp().c_str(),
1165
 
          session->getSecurityContext().getUser().c_str()
 
972
          session->security_ctx.ip.c_str(),
 
973
          session->security_ctx.user.c_str()
1166
974
  );
1167
975
  fprintf(f,
1168
 
          "\n%s", session->getQueryString().c_str()
 
976
          "\n%s", session->getQueryString()
1169
977
  );
1170
978
        putc('\n', f);
1171
979
}
1201
1009
void
1202
1010
innobase_convert_from_table_id(
1203
1011
/*===========================*/
1204
 
        const void*,                    /*!< in: the 'from' character set */
 
1012
        const struct charset_info_st*,  /*!< in: the 'from' character set */
1205
1013
        char*                   to,     /*!< out: converted identifier */
1206
1014
        const char*             from,   /*!< in: identifier to convert */
1207
1015
        ulint                   len)    /*!< in: length of 'to', in bytes */
1215
1023
void
1216
1024
innobase_convert_from_id(
1217
1025
/*=====================*/
1218
 
        const void*,                    /*!< in: the 'from' character set */
 
1026
        const struct charset_info_st*,  /*!< in: the 'from' character set */
1219
1027
        char*                   to,     /*!< out: converted identifier */
1220
1028
        const char*             from,   /*!< in: identifier to convert */
1221
1029
        ulint                   len)    /*!< in: length of 'to', in bytes */
1251
1059
Determines the connection character set.
1252
1060
@return connection character set */
1253
1061
extern "C" UNIV_INTERN
1254
 
const void*
 
1062
const charset_info_st*
1255
1063
innobase_get_charset(
1256
1064
/*=================*/
1257
1065
        void*   mysql_session)  /*!< in: MySQL thread handle */
1258
1066
{
1259
 
        return session_charset(static_cast<Session*>(mysql_session));
1260
 
}
1261
 
 
1262
 
extern "C" UNIV_INTERN
1263
 
bool
1264
 
innobase_isspace(
1265
 
        const void *cs,
1266
 
        char char_to_test)
1267
 
{
1268
 
        return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1269
 
}
1270
 
 
1271
 
UNIV_INTERN
1272
 
int
1273
 
innobase_fast_mutex_init(
1274
 
        os_fast_mutex_t*        fast_mutex)
1275
 
{
1276
 
        return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1067
        return(session_charset(static_cast<Session*>(mysql_session)));
1277
1068
}
1278
1069
 
1279
1070
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1374
1165
/*========================*/
1375
1166
{
1376
1167
        int     fd2 = -1;
1377
 
        int     fd = mysql_tmpfile("ib");
 
1168
        File    fd = mysql_tmpfile("ib");
1378
1169
        if (fd >= 0) {
1379
1170
                /* Copy the file descriptor, so that the additional resources
1380
1171
                allocated by create_temp_file() can be freed by invoking
1381
 
                internal::my_close().
 
1172
                my_close().
1382
1173
 
1383
1174
                Because the file descriptor returned by this function
1384
1175
                will be passed to fdopen(), it will be closed by invoking
1385
1176
                fclose(), which in turn will invoke close() instead of
1386
 
                internal::my_close(). */
 
1177
                my_close(). */
1387
1178
                fd2 = dup(fd);
1388
1179
                if (fd2 < 0) {
1389
 
                        errno=errno;
 
1180
                        my_errno=errno;
1390
1181
                        my_error(EE_OUT_OF_FILERESOURCES,
1391
1182
                                 MYF(ME_BELL+ME_WAITTANG),
1392
 
                                 "ib*", errno);
 
1183
                                 "ib*", my_errno);
1393
1184
                }
1394
 
                internal::my_close(fd, MYF(MY_WME));
 
1185
                my_close(fd, MYF(MY_WME));
1395
1186
        }
1396
1187
        return(fd2);
1397
1188
}
1542
1333
        trx = trx_allocate_for_mysql();
1543
1334
 
1544
1335
        trx->mysql_thd = session;
1545
 
        trx->mysql_query_str = session->query.c_str();
 
1336
        trx->mysql_query_str = session_query(session);
1546
1337
 
1547
1338
        innobase_trx_init(session, trx);
1548
1339
 
1580
1371
/*********************************************************************//**
1581
1372
Construct ha_innobase Cursor. */
1582
1373
UNIV_INTERN
1583
 
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
 
1374
ha_innobase::ha_innobase(drizzled::plugin::StorageEngine &engine_arg,
1584
1375
                         TableShare &table_arg)
1585
1376
  :Cursor(engine_arg, table_arg),
1586
1377
  primary_key(0), /* needs initialization because index_flags() may be called 
1634
1425
        update_session(session);
1635
1426
}
1636
1427
 
 
1428
/*********************************************************************//**
 
1429
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
 
1430
roll back the statement if the statement results in an error. This MUST be
 
1431
called for every SQL statement that may be rolled back by MySQL. Calling this
 
1432
several times to register the same statement is allowed, too. */
 
1433
static inline
 
1434
void
 
1435
innobase_register_stmt(
 
1436
/*===================*/
 
1437
        drizzled::plugin::StorageEngine*        engine, /*!< in: Innobase hton */
 
1438
        Session*        session)        /*!< in: MySQL thd (connection) object */
 
1439
{
 
1440
        assert(engine == innodb_engine_ptr);
 
1441
        /* Register the statement */
 
1442
        trans_register_ha(session, FALSE, engine);
 
1443
}
 
1444
 
 
1445
/*********************************************************************//**
 
1446
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
 
1447
to call the InnoDB prepare and commit, or rollback for the transaction. This
 
1448
MUST be called for every transaction for which the user may call commit or
 
1449
rollback. Calling this several times to register the same transaction is
 
1450
allowed, too.
 
1451
This function also registers the current SQL statement. */
 
1452
static inline
 
1453
void
 
1454
innobase_register_trx_and_stmt(
 
1455
/*===========================*/
 
1456
        drizzled::plugin::StorageEngine *engine, /*!< in: Innobase StorageEngine */
 
1457
        Session*        session)        /*!< in: MySQL thd (connection) object */
 
1458
{
 
1459
        /* NOTE that actually innobase_register_stmt() registers also
 
1460
        the transaction in the AUTOCOMMIT=1 mode. */
 
1461
 
 
1462
        innobase_register_stmt(engine, session);
 
1463
 
 
1464
        if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
1465
 
 
1466
                /* No autocommit mode, register for a transaction */
 
1467
                trans_register_ha(session, TRUE, engine);
 
1468
        }
 
1469
}
 
1470
 
1637
1471
/*****************************************************************//**
1638
1472
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
1639
1473
and quote it if needed.
1801
1635
        prebuilt->read_just_key = 0;
1802
1636
}
1803
1637
 
 
1638
/*****************************************************************//**
 
1639
Call this when you have opened a new table handle in HANDLER, before you
 
1640
call index_read_idx() etc. Actually, we can let the cursor stay open even
 
1641
over a transaction commit! Then you should call this before every operation,
 
1642
fetch next etc. This function inits the necessary things even after a
 
1643
transaction commit. */
 
1644
UNIV_INTERN
 
1645
void
 
1646
ha_innobase::init_table_handle_for_HANDLER(void)
 
1647
/*============================================*/
 
1648
{
 
1649
        /* If current session does not yet have a trx struct, create one.
 
1650
        If the current handle does not yet have a prebuilt struct, create
 
1651
        one. Update the trx pointers in the prebuilt struct. Normally
 
1652
        this operation is done in external_lock. */
 
1653
 
 
1654
        update_session(ha_session());
 
1655
 
 
1656
        /* Initialize the prebuilt struct much like it would be inited in
 
1657
        external_lock */
 
1658
 
 
1659
        innobase_release_stat_resources(prebuilt->trx);
 
1660
 
 
1661
        /* If the transaction is not started yet, start it */
 
1662
 
 
1663
        trx_start_if_not_started(prebuilt->trx);
 
1664
 
 
1665
        /* Assign a read view if the transaction does not have it yet */
 
1666
 
 
1667
        trx_assign_read_view(prebuilt->trx);
 
1668
 
 
1669
        /* Set the MySQL flag to mark that there is an active transaction */
 
1670
 
 
1671
        if (prebuilt->trx->active_trans == 0) {
 
1672
 
 
1673
                innobase_register_trx_and_stmt(engine, user_session);
 
1674
 
 
1675
                prebuilt->trx->active_trans = 1;
 
1676
        }
 
1677
 
 
1678
        /* We did the necessary inits in this function, no need to repeat them
 
1679
        in row_search_for_mysql */
 
1680
 
 
1681
        prebuilt->sql_stat_start = FALSE;
 
1682
 
 
1683
        /* We let HANDLER always to do the reads as consistent reads, even
 
1684
        if the trx isolation level would have been specified as SERIALIZABLE */
 
1685
 
 
1686
        prebuilt->select_lock_type = LOCK_NONE;
 
1687
        prebuilt->stored_select_lock_type = LOCK_NONE;
 
1688
 
 
1689
        /* Always fetch all columns in the index record */
 
1690
 
 
1691
        prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
 
1692
 
 
1693
        /* We want always to fetch all columns in the whole row? Or do
 
1694
        we???? */
 
1695
 
 
1696
        prebuilt->used_in_HANDLER = TRUE;
 
1697
        reset_template(prebuilt);
 
1698
}
 
1699
 
1804
1700
/*********************************************************************//**
1805
1701
Opens an InnoDB database.
1806
1702
@return 0 on success, error code on failure */
1808
1704
int
1809
1705
innobase_init(
1810
1706
/*==========*/
1811
 
        plugin::Context &context)       /*!< in: Drizzle Plugin Context */
 
1707
        drizzled::plugin::Registry      &registry)      /*!< in: Drizzle Plugin Registry */
1812
1708
{
1813
1709
        static char     current_dir[3];         /*!< Set if using current lib */
1814
1710
        int             err;
1818
1714
 
1819
1715
        innodb_engine_ptr= new InnobaseEngine(innobase_engine_name);
1820
1716
 
 
1717
 
1821
1718
        ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)DRIZZLE_TYPE_VARCHAR);
1822
1719
 
1823
1720
#ifdef UNIV_DEBUG
1857
1754
                }
1858
1755
        }
1859
1756
 
1860
 
        os_innodb_umask = (ulint)internal::my_umask;
 
1757
        os_innodb_umask = (ulint)my_umask;
1861
1758
 
1862
1759
        /* First calculate the default path for innodb_data_home_dir etc.,
1863
1760
        in case the user has not given any value.
2051
1948
 
2052
1949
        row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
2053
1950
 
2054
 
        srv_locks_unsafe_for_binlog = (ibool) TRUE;
 
1951
        srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
2055
1952
 
2056
1953
        srv_max_n_open_files = (ulint) innobase_open_files;
2057
1954
        srv_innodb_status = (ibool) innobase_create_status_file;
2086
1983
        pthread_cond_init(&commit_cond, NULL);
2087
1984
        innodb_inited= 1;
2088
1985
 
2089
 
        status_table_function_ptr= new InnodbStatusTool;
2090
 
 
2091
 
        context.add(innodb_engine_ptr);
2092
 
 
2093
 
        context.add(status_table_function_ptr);
2094
 
 
2095
 
        cmp_tool= new(std::nothrow)CmpTool(false);
2096
 
        context.add(cmp_tool);
2097
 
 
2098
 
        cmp_reset_tool= new(std::nothrow)CmpTool(true);
2099
 
        context.add(cmp_reset_tool);
2100
 
 
2101
 
        cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2102
 
        context.add(cmp_mem_tool);
2103
 
 
2104
 
        cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2105
 
        context.add(cmp_mem_reset_tool);
2106
 
 
2107
 
        innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2108
 
        context.add(innodb_trx_tool);
2109
 
 
2110
 
        innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2111
 
        context.add(innodb_locks_tool);
2112
 
 
2113
 
        innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2114
 
        context.add(innodb_lock_waits_tool);
 
1986
        if (innodb_locks_init() ||
 
1987
                innodb_trx_init() ||
 
1988
                innodb_lock_waits_init() ||
 
1989
                i_s_cmp_init() ||
 
1990
                i_s_cmp_reset_init() ||
 
1991
                i_s_cmpmem_init() ||
 
1992
                i_s_cmpmem_reset_init())
 
1993
                goto error;
 
1994
 
 
1995
        registry.add(innodb_engine_ptr);
 
1996
 
 
1997
        registry.add(innodb_trx_schema_table);
 
1998
        registry.add(innodb_locks_schema_table);
 
1999
        registry.add(innodb_lock_waits_schema_table);   
 
2000
        registry.add(innodb_cmp_schema_table);
 
2001
        registry.add(innodb_cmp_reset_schema_table);
 
2002
        registry.add(innodb_cmpmem_schema_table);
 
2003
        registry.add(innodb_cmpmem_reset_schema_table);
2115
2004
 
2116
2005
        /* Get the current high water mark format. */
2117
2006
        innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2121
2010
        return(TRUE);
2122
2011
}
2123
2012
 
 
2013
/*******************************************************************//**
 
2014
Closes an InnoDB database.
 
2015
@return TRUE if error */
 
2016
static
 
2017
int
 
2018
innobase_deinit(drizzled::plugin::Registry &registry)
 
2019
{
 
2020
        int     err= 0;
 
2021
        i_s_common_deinit(registry);
 
2022
        registry.remove(innodb_engine_ptr);
 
2023
        delete innodb_engine_ptr;
 
2024
 
 
2025
        if (innodb_inited) {
 
2026
 
 
2027
                srv_fast_shutdown = (ulint) innobase_fast_shutdown;
 
2028
                innodb_inited = 0;
 
2029
                hash_table_free(innobase_open_tables);
 
2030
                innobase_open_tables = NULL;
 
2031
                if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
 
2032
                        err = 1;
 
2033
                }
 
2034
                srv_free_paths_and_sizes();
 
2035
                if (internal_innobase_data_file_path)
 
2036
                  free(internal_innobase_data_file_path);
 
2037
                pthread_mutex_destroy(&innobase_share_mutex);
 
2038
                pthread_mutex_destroy(&prepare_commit_mutex);
 
2039
                pthread_mutex_destroy(&commit_threads_m);
 
2040
                pthread_mutex_destroy(&commit_cond_m);
 
2041
                pthread_cond_destroy(&commit_cond);
 
2042
        }
 
2043
 
 
2044
        return(err);
 
2045
}
2124
2046
 
2125
2047
/****************************************************************//**
2126
2048
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
2162
2084
have one.
2163
2085
@return 0 */
2164
2086
int
2165
 
InnobaseEngine::doStartTransaction(
 
2087
InnobaseEngine::start_consistent_snapshot(
2166
2088
/*====================================*/
2167
 
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
2168
 
                                                 the transaction should be committed */
2169
 
  start_transaction_option_t options)
 
2089
        Session*        session)        /*!< in: MySQL thread handle of the user for whom
 
2090
                        the transaction should be committed */
2170
2091
{
 
2092
        trx_t*  trx;
 
2093
 
2171
2094
        assert(this == innodb_engine_ptr);
2172
2095
 
2173
2096
        /* Create a new trx struct for session, if it does not yet have one */
2174
 
        trx_t *trx = check_trx_exists(session);
 
2097
 
 
2098
        trx = check_trx_exists(session);
2175
2099
 
2176
2100
        /* This is just to play safe: release a possible FIFO ticket and
2177
2101
        search latch. Since we will reserve the kernel mutex, we have to
2178
2102
        release the search system latch first to obey the latching order. */
 
2103
 
2179
2104
        innobase_release_stat_resources(trx);
2180
2105
 
2181
2106
        /* If the transaction is not started yet, start it */
 
2107
 
2182
2108
        trx_start_if_not_started(trx);
2183
2109
 
2184
2110
        /* Assign a read view if the transaction does not have it yet */
2185
 
  if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
2186
 
          trx_assign_read_view(trx);
2187
 
 
2188
 
        return 0;
 
2111
 
 
2112
        trx_assign_read_view(trx);
 
2113
 
 
2114
        /* Set the MySQL flag to mark that there is an active transaction */
 
2115
 
 
2116
        if (trx->active_trans == 0) {
 
2117
                innobase_register_trx_and_stmt(this, current_session);
 
2118
                trx->active_trans = 1;
 
2119
        }
 
2120
 
 
2121
        return(0);
2189
2122
}
2190
2123
 
2191
2124
/*****************************************************************//**
2193
2126
ended.
2194
2127
@return 0 */
2195
2128
int
2196
 
InnobaseEngine::doCommit(
 
2129
InnobaseEngine::commit(
2197
2130
/*============*/
2198
2131
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
2199
2132
                        the transaction should be committed */
2213
2146
                trx_search_latch_release_if_reserved(trx);
2214
2147
        }
2215
2148
 
 
2149
        /* The flag trx->active_trans is set to 1 in
 
2150
 
 
2151
        1. ::external_lock(),
 
2152
        2. ::start_stmt(),
 
2153
        3. innobase_query_caching_of_table_permitted(),
 
2154
        4. InnobaseEngine::savepoint_set(),
 
2155
        5. ::init_table_handle_for_HANDLER(),
 
2156
        6. InnobaseEngine::start_consistent_snapshot(),
 
2157
 
 
2158
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
 
2159
        there cannot be resources to be freed and we could return immediately.
 
2160
        For the time being, we play safe and do the cleanup though there should
 
2161
        be nothing to clean up. */
 
2162
 
 
2163
        if (trx->active_trans == 0
 
2164
                && trx->conc_state != TRX_NOT_STARTED) {
 
2165
 
 
2166
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
 
2167
                        " trx->conc_state != TRX_NOT_STARTED");
 
2168
        }
2216
2169
        if (all
2217
2170
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2218
2171
 
2259
2212
                        pthread_mutex_unlock(&commit_cond_m);
2260
2213
                }
2261
2214
 
2262
 
                if (trx->conc_state == TRX_PREPARED) {
 
2215
                if (trx->active_trans == 2) {
2263
2216
 
2264
2217
                        pthread_mutex_unlock(&prepare_commit_mutex);
2265
2218
                }
2266
2219
 
2267
2220
                /* Now do a write + flush of logs. */
2268
2221
                trx_commit_complete_for_mysql(trx);
 
2222
                trx->active_trans = 0;
2269
2223
 
2270
2224
        } else {
2271
2225
                /* We just mark the SQL statement ended and do not do a
2302
2256
Rolls back a transaction or the latest SQL statement.
2303
2257
@return 0 or error number */
2304
2258
int
2305
 
InnobaseEngine::doRollback(
 
2259
InnobaseEngine::rollback(
2306
2260
/*==============*/
2307
2261
        Session*        session,/*!< in: handle to the MySQL thread of the user
2308
2262
                        whose transaction should be rolled back */
2332
2286
                || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2333
2287
 
2334
2288
                error = trx_rollback_for_mysql(trx);
 
2289
                trx->active_trans = 0;
2335
2290
        } else {
2336
2291
                error = trx_rollback_last_sql_stat_for_mysql(trx);
2337
2292
        }
2372
2327
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2373
2328
given name */
2374
2329
int
2375
 
InnobaseEngine::doRollbackToSavepoint(
 
2330
InnobaseEngine::savepoint_rollback_hook(
2376
2331
/*===========================*/
2377
2332
        Session*        session,                /*!< in: handle to the MySQL thread of the user
2378
2333
                                whose transaction should be rolled back */
2379
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2334
        void*   savepoint)      /*!< in: savepoint data */
2380
2335
{
2381
2336
        ib_int64_t      mysql_binlog_cache_pos;
2382
2337
        int             error = 0;
2383
2338
        trx_t*          trx;
 
2339
        char            sp_name[64];
2384
2340
 
2385
2341
        assert(this == innodb_engine_ptr);
2386
2342
 
2392
2348
 
2393
2349
        innobase_release_stat_resources(trx);
2394
2350
 
2395
 
        error= (int)trx_rollback_to_savepoint_for_mysql(trx, named_savepoint.getName().c_str(),
2396
 
                                                        &mysql_binlog_cache_pos);
 
2351
        /* TODO: use provided savepoint data area to store savepoint data */
 
2352
 
 
2353
        int64_t2str((ulint)savepoint, sp_name, 36);
 
2354
 
 
2355
        error = (int) trx_rollback_to_savepoint_for_mysql(trx, sp_name,
 
2356
                                                &mysql_binlog_cache_pos);
2397
2357
        return(convert_error_code_to_mysql(error, 0, NULL));
2398
2358
}
2399
2359
 
2402
2362
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2403
2363
given name */
2404
2364
int
2405
 
InnobaseEngine::doReleaseSavepoint(
 
2365
InnobaseEngine::savepoint_release_hook(
2406
2366
/*=======================*/
2407
2367
        Session*        session,                /*!< in: handle to the MySQL thread of the user
2408
2368
                                whose transaction should be rolled back */
2409
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2369
        void*   savepoint)      /*!< in: savepoint data */
2410
2370
{
2411
2371
        int             error = 0;
2412
2372
        trx_t*          trx;
 
2373
        char            sp_name[64];
2413
2374
 
2414
2375
        assert(this == innodb_engine_ptr);
2415
2376
 
2416
2377
        trx = check_trx_exists(session);
2417
2378
 
2418
 
        error = (int) trx_release_savepoint_for_mysql(trx, named_savepoint.getName().c_str());
 
2379
        /* TODO: use provided savepoint data area to store savepoint data */
 
2380
 
 
2381
        int64_t2str((ulint)savepoint, sp_name, 36);
 
2382
 
 
2383
        error = (int) trx_release_savepoint_for_mysql(trx, sp_name);
2419
2384
 
2420
2385
        return(convert_error_code_to_mysql(error, 0, NULL));
2421
2386
}
2424
2389
Sets a transaction savepoint.
2425
2390
@return always 0, that is, always succeeds */
2426
2391
int
2427
 
InnobaseEngine::doSetSavepoint(
 
2392
InnobaseEngine::savepoint_set_hook(
2428
2393
/*===============*/
2429
2394
        Session*        session,/*!< in: handle to the MySQL thread */
2430
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2395
        void*   savepoint)      /*!< in: savepoint data */
2431
2396
{
2432
2397
        int     error = 0;
2433
2398
        trx_t*  trx;
2449
2414
        innobase_release_stat_resources(trx);
2450
2415
 
2451
2416
        /* cannot happen outside of transaction */
2452
 
        assert(trx->conc_state != TRX_NOT_STARTED);
2453
 
 
2454
 
        error = (int) trx_savepoint_for_mysql(trx, named_savepoint.getName().c_str(), (ib_int64_t)0);
 
2417
        assert(trx->active_trans);
 
2418
 
 
2419
        /* TODO: use provided savepoint data area to store savepoint data */
 
2420
        char sp_name[64];
 
2421
        int64_t2str((ulint)savepoint,sp_name,36);
 
2422
 
 
2423
        error = (int) trx_savepoint_for_mysql(trx, sp_name, (ib_int64_t)0);
2455
2424
 
2456
2425
        return(convert_error_code_to_mysql(error, 0, NULL));
2457
2426
}
2472
2441
 
2473
2442
        ut_a(trx);
2474
2443
 
2475
 
  assert(session->killed != Session::NOT_KILLED ||
2476
 
         trx->conc_state == TRX_NOT_STARTED);
2477
 
 
2478
 
  /* Warn if rolling back some things... */
2479
 
        if (session->killed != Session::NOT_KILLED &&
2480
 
      trx->conc_state != TRX_NOT_STARTED &&
2481
 
      trx->undo_no.low > 0 &&
2482
 
      global_system_variables.log_warnings)
2483
 
  {
2484
 
      errmsg_printf(ERRMSG_LVL_WARN, 
2485
 
      "Drizzle is closing a connection during a KILL operation\n"
2486
 
      "that has an active InnoDB transaction.  %lu row modifications will "
2487
 
      "roll back.\n",
2488
 
      (ulong) trx->undo_no.low);
2489
 
  }
 
2444
        if (trx->active_trans == 0
 
2445
                && trx->conc_state != TRX_NOT_STARTED) {
 
2446
 
 
2447
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
 
2448
                        " trx->conc_state != TRX_NOT_STARTED");
 
2449
        }
 
2450
 
 
2451
 
 
2452
        if (trx->conc_state != TRX_NOT_STARTED &&
 
2453
                global_system_variables.log_warnings) {
 
2454
                errmsg_printf(ERRMSG_LVL_WARN, 
 
2455
                        "MySQL is closing a connection that has an active "
 
2456
                        "InnoDB transaction.  %lu row modifications will "
 
2457
                        "roll back.",
 
2458
                        (ulong) trx->undo_no.low);
 
2459
        }
2490
2460
 
2491
2461
        innobase_rollback_trx(trx);
2492
2462
 
2727
2697
        holding btr_search_latch. This breaks the latching order as
2728
2698
        we acquire dict_sys->mutex below and leads to a deadlock. */
2729
2699
        if (session != NULL) {
2730
 
                getTransactionalEngine()->releaseTemporaryLatches(session);
 
2700
                engine->release_temporary_latches(session);
2731
2701
        }
2732
2702
 
2733
2703
        normalize_table_name(norm_name, name);
2748
2718
                                table->s->stored_rec_length
2749
2719
                                + table->s->max_key_length
2750
2720
                                + MAX_REF_PARTS * 3;
2751
 
        if (!(unsigned char*) memory::multi_malloc(false,
 
2721
        if (!(unsigned char*) drizzled::memory::multi_malloc(false,
2752
2722
                        &upd_buff, upd_and_key_val_buff_len,
2753
2723
                        &key_val_buff, upd_and_key_val_buff_len,
2754
2724
                        NULL)) {
2797
2767
                                norm_name);
2798
2768
                free_share(share);
2799
2769
                free(upd_buff);
2800
 
                errno = ENOENT;
 
2770
                my_errno = ENOENT;
2801
2771
 
2802
2772
                return(HA_ERR_NO_SUCH_TABLE);
2803
2773
        }
2813
2783
                                norm_name);
2814
2784
                free_share(share);
2815
2785
                free(upd_buff);
2816
 
                errno = ENOENT;
 
2786
                my_errno = ENOENT;
2817
2787
 
2818
2788
                dict_table_decrement_handle_count(ib_table, FALSE);
2819
2789
                return(HA_ERR_NO_SUCH_TABLE);
2942
2912
 
2943
2913
        session = ha_session();
2944
2914
        if (session != NULL) {
2945
 
                getTransactionalEngine()->releaseTemporaryLatches(session);
 
2915
                engine->release_temporary_latches(session);
2946
2916
        }
2947
2917
 
2948
2918
        row_prebuilt_free(prebuilt, FALSE);
3848
3818
                ut_error;
3849
3819
        }
3850
3820
 
3851
 
        ha_statistic_increment(&system_status_var::ha_write_count);
 
3821
        ha_statistic_increment(&SSV::ha_write_count);
3852
3822
 
3853
3823
        sql_command = session_sql_command(user_session);
3854
3824
 
3893
3863
                        no need to re-acquire locks on it. */
3894
3864
 
3895
3865
                        /* Altering to InnoDB format */
3896
 
                        getTransactionalEngine()->commit(user_session, 1);
 
3866
                        engine->commit(user_session, 1);
 
3867
                        /* Note that this transaction is still active. */
 
3868
                        prebuilt->trx->active_trans = 1;
3897
3869
                        /* We will need an IX lock on the destination table. */
3898
3870
                        prebuilt->sql_stat_start = TRUE;
3899
3871
                } else {
3907
3879
 
3908
3880
                        /* Commit the transaction.  This will release the table
3909
3881
                        locks, so they have to be acquired again. */
3910
 
                        getTransactionalEngine()->commit(user_session, 1);
 
3882
                        engine->commit(user_session, 1);
 
3883
                        /* Note that this transaction is still active. */
 
3884
                        prebuilt->trx->active_trans = 1;
3911
3885
                        /* Re-acquire the table lock on the source table. */
3912
3886
                        row_lock_table_for_mysql(prebuilt, src_table, mode);
3913
3887
                        /* We will need an IX lock on the destination table. */
4217
4191
 
4218
4192
        ut_a(prebuilt->trx == trx);
4219
4193
 
4220
 
        ha_statistic_increment(&system_status_var::ha_update_count);
 
4194
        ha_statistic_increment(&SSV::ha_update_count);
4221
4195
 
4222
4196
        if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
4223
4197
                table->timestamp_field->set_time();
4322
4296
 
4323
4297
        ut_a(prebuilt->trx == trx);
4324
4298
 
4325
 
        ha_statistic_increment(&system_status_var::ha_delete_count);
 
4299
        ha_statistic_increment(&SSV::ha_delete_count);
4326
4300
 
4327
4301
        if (!prebuilt->upd_node) {
4328
4302
                row_get_prebuilt_update_vector(prebuilt);
4510
4484
 
4511
4485
  A) if the user has not explicitly set any MySQL table level locks:
4512
4486
 
4513
 
  1) Drizzle calls StorageEngine::doStartStatement(), indicating to
4514
 
     InnoDB that a new SQL statement has begun.
4515
 
 
4516
 
  2a) For each InnoDB-managed table in the SELECT, Drizzle calls ::external_lock
4517
 
     to set an 'intention' table level lock on the table of the Cursor instance.
4518
 
     There we set prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should 
4519
 
     be set true if we are taking this table handle instance to use in a new SQL
4520
 
     statement issued by the user.
4521
 
 
4522
 
  2b) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
 
4487
  1) MySQL calls ::external_lock to set an 'intention' table level lock on
 
4488
the table of the handle instance. There we set
 
4489
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
 
4490
true if we are taking this table handle instance to use in a new SQL
 
4491
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
 
4492
 
 
4493
  2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
4523
4494
instructions to prebuilt->template of the table handle instance in
4524
4495
::index_read. The template is used to save CPU time in large joins.
4525
4496
 
4531
4502
  4) We do the SELECT. MySQL may repeatedly call ::index_read for the
4532
4503
same table handle instance, if it is a join.
4533
4504
 
4534
 
5) When the SELECT ends, the Drizzle kernel calls doEndStatement()
4535
 
 
4536
 
 (a) we execute a COMMIT there if the autocommit is on. The Drizzle interpreter 
4537
 
     does NOT execute autocommit for pure read transactions, though it should.
4538
 
     That is why we must execute the COMMIT in ::doEndStatement().
 
4505
  5) When the SELECT ends, MySQL removes its intention table level locks
 
4506
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
 
4507
 (a) we execute a COMMIT there if the autocommit is on,
4539
4508
 (b) we also release possible 'SQL statement level resources' InnoDB may
4540
 
     have for this SQL statement.
4541
 
 
4542
 
  @todo
4543
 
 
4544
 
  Remove need for InnoDB to call autocommit for read-only trx
4545
 
 
4546
 
  @todo Check the below is still valid (I don't think it is...)
 
4509
have for this SQL statement. The MySQL interpreter does NOT execute
 
4510
autocommit for pure read transactions, though it should. That is why the
 
4511
table Cursor in that case has to execute the COMMIT in ::external_lock.
4547
4512
 
4548
4513
  B) If the user has explicitly set MySQL table level locks, then MySQL
4549
4514
does NOT call ::external_lock at the start of the statement. To determine
4585
4550
 
4586
4551
        ut_a(prebuilt->trx == session_to_trx(user_session));
4587
4552
 
4588
 
        ha_statistic_increment(&system_status_var::ha_read_key_count);
 
4553
        ha_statistic_increment(&SSV::ha_read_key_count);
4589
4554
 
4590
4555
        index = prebuilt->index;
4591
4556
 
4700
4665
        KEY*            key = 0;
4701
4666
        dict_index_t*   index = 0;
4702
4667
 
4703
 
        ha_statistic_increment(&system_status_var::ha_read_key_count);
 
4668
        ha_statistic_increment(&SSV::ha_read_key_count);
4704
4669
 
4705
4670
        ut_ad(user_session == ha_session());
4706
4671
        ut_a(prebuilt->trx == session_to_trx(user_session));
4865
4830
        unsigned char*  buf)    /*!< in/out: buffer for next row in MySQL
4866
4831
                                format */
4867
4832
{
4868
 
        ha_statistic_increment(&system_status_var::ha_read_next_count);
 
4833
        ha_statistic_increment(&SSV::ha_read_next_count);
4869
4834
 
4870
4835
        return(general_fetch(buf, ROW_SEL_NEXT, 0));
4871
4836
}
4881
4846
        const unsigned char*    ,       /*!< in: key value */
4882
4847
        uint            )       /*!< in: key value length */
4883
4848
{
4884
 
        ha_statistic_increment(&system_status_var::ha_read_next_count);
 
4849
        ha_statistic_increment(&SSV::ha_read_next_count);
4885
4850
 
4886
4851
        return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
4887
4852
}
4896
4861
/*====================*/
4897
4862
        unsigned char*  buf)    /*!< in/out: buffer for previous row in MySQL format */
4898
4863
{
4899
 
        ha_statistic_increment(&system_status_var::ha_read_prev_count);
 
4864
        ha_statistic_increment(&SSV::ha_read_prev_count);
4900
4865
 
4901
4866
        return(general_fetch(buf, ROW_SEL_PREV, 0));
4902
4867
}
4913
4878
{
4914
4879
        int     error;
4915
4880
 
4916
 
        ha_statistic_increment(&system_status_var::ha_read_first_count);
 
4881
        ha_statistic_increment(&SSV::ha_read_first_count);
4917
4882
 
4918
4883
        error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
4919
4884
 
4938
4903
{
4939
4904
        int     error;
4940
4905
 
4941
 
        ha_statistic_increment(&system_status_var::ha_read_last_count);
 
4906
        ha_statistic_increment(&SSV::ha_read_last_count);
4942
4907
 
4943
4908
        error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
4944
4909
 
5007
4972
{
5008
4973
        int     error;
5009
4974
 
5010
 
        ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
 
4975
        ha_statistic_increment(&SSV::ha_read_rnd_next_count);
5011
4976
 
5012
4977
        if (start_of_scan) {
5013
4978
                error = index_first(buf);
5040
5005
        int             error;
5041
5006
        uint            keynr   = active_index;
5042
5007
 
5043
 
        ha_statistic_increment(&system_status_var::ha_read_rnd_count);
 
5008
        ha_statistic_increment(&SSV::ha_read_rnd_count);
5044
5009
 
5045
5010
        ut_a(prebuilt->trx == session_to_trx(ha_session()));
5046
5011
 
5396
5361
        Session*        session,        /*!< in: connection thread. */
5397
5362
        Table&          form,           /*!< in: information on table
5398
5363
                                        columns and indexes */
5399
 
        message::Table& create_proto)
 
5364
        drizzled::message::Table& create_proto)
5400
5365
{
5401
5366
        ibool   kbs_specified   = FALSE;
5402
5367
        ibool   ret             = TRUE;
5551
5516
int
5552
5517
InnobaseEngine::doCreateTable(
5553
5518
/*================*/
5554
 
        Session         &session,       /*!< in: Session */
5555
 
        Table&          form,           /*!< in: information on table columns and indexes */
5556
 
        drizzled::TableIdentifier &identifier,
5557
 
        message::Table& create_proto)
 
5519
        Session*        session,        /*!< in: Session */
 
5520
        const char*     table_name,     /*!< in: table name */
 
5521
        Table&          form,           /*!< in: information on table
 
5522
                                        columns and indexes */
 
5523
        drizzled::message::Table& create_proto)
5558
5524
{
5559
5525
        int             error;
5560
5526
        dict_table_t*   innobase_table;
5569
5535
        /* Cache the value of innodb_file_format, in case it is
5570
5536
        modified by another thread while the table is being created. */
5571
5537
        const ulint     file_format = srv_file_format;
5572
 
        bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
 
5538
        bool lex_identified_temp_table= (create_proto.type() == drizzled::message::Table::TEMPORARY);
5573
5539
 
5574
 
        const char *table_name= identifier.getPath().c_str();
 
5540
        assert(session != NULL);
5575
5541
 
5576
5542
#ifdef __WIN__
5577
5543
        /* Names passed in from server are in two formats:
5605
5571
        /* Get the transaction associated with the current session, or create one
5606
5572
        if not yet created */
5607
5573
 
5608
 
        parent_trx = check_trx_exists(&session);
 
5574
        parent_trx = check_trx_exists(session);
5609
5575
 
5610
5576
        /* In case MySQL calls this in the middle of a SELECT query, release
5611
5577
        possible adaptive hash latch to avoid deadlocks of threads */
5612
5578
 
5613
5579
        trx_search_latch_release_if_reserved(parent_trx);
5614
5580
 
5615
 
        trx = innobase_trx_allocate(&session);
 
5581
        trx = innobase_trx_allocate(session);
5616
5582
 
5617
5583
        srv_lower_case_table_names = TRUE;
5618
5584
 
5631
5597
        iflags = 0;
5632
5598
 
5633
5599
        /* Validate create options if innodb_strict_mode is set. */
5634
 
        if (! create_options_are_valid(&session, form, create_proto)) {
 
5600
        if (! create_options_are_valid(session, form, create_proto)) {
5635
5601
                error = ER_ILLEGAL_HA_CREATE_OPTION;
5636
5602
                goto cleanup;
5637
5603
        }
5655
5621
                }
5656
5622
 
5657
5623
                if (!srv_file_per_table) {
5658
 
                        push_warning(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5624
                        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5659
5625
                                     ER_ILLEGAL_HA_CREATE_OPTION,
5660
5626
                                     "InnoDB: KEY_BLOCK_SIZE"
5661
5627
                                     " requires innodb_file_per_table.");
5663
5629
                }
5664
5630
 
5665
5631
                if (file_format < DICT_TF_FORMAT_ZIP) {
5666
 
                        push_warning(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5632
                        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5667
5633
                                     ER_ILLEGAL_HA_CREATE_OPTION,
5668
5634
                                     "InnoDB: KEY_BLOCK_SIZE"
5669
5635
                                     " requires innodb_file_format >"
5672
5638
                }
5673
5639
 
5674
5640
                if (!iflags) {
5675
 
                        push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5641
                        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5676
5642
                                            ER_ILLEGAL_HA_CREATE_OPTION,
5677
5643
                                            "InnoDB: ignoring"
5678
5644
                                            " KEY_BLOCK_SIZE=%lu.",
5691
5657
                                such combinations can be obtained
5692
5658
                                with ALTER TABLE anyway. */
5693
5659
                                push_warning_printf(
5694
 
                                        &session,
 
5660
                                        session,
5695
5661
                                        DRIZZLE_ERROR::WARN_LEVEL_WARN,
5696
5662
                                        ER_ILLEGAL_HA_CREATE_OPTION,
5697
5663
                                        "InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
5729
5695
 
5730
5696
                        if (!srv_file_per_table) {
5731
5697
                                push_warning_printf(
5732
 
                                        &session,
 
5698
                                        session,
5733
5699
                                        DRIZZLE_ERROR::WARN_LEVEL_WARN,
5734
5700
                                        ER_ILLEGAL_HA_CREATE_OPTION,
5735
5701
                                        "InnoDB: ROW_FORMAT=%s"
5737
5703
                                        row_format_name);
5738
5704
                        } else if (file_format < DICT_TF_FORMAT_ZIP) {
5739
5705
                                push_warning_printf(
5740
 
                                        &session,
 
5706
                                        session,
5741
5707
                                        DRIZZLE_ERROR::WARN_LEVEL_WARN,
5742
5708
                                        ER_ILLEGAL_HA_CREATE_OPTION,
5743
5709
                                        "InnoDB: ROW_FORMAT=%s"
5821
5787
                }
5822
5788
        }
5823
5789
 
5824
 
        if (trx->mysql_query_str) {
 
5790
        if (*trx->mysql_query_str) {
5825
5791
                error = row_table_add_foreign_constraints(trx,
5826
 
                        trx->mysql_query_str, norm_name,
 
5792
                        *trx->mysql_query_str, norm_name,
5827
5793
                        lex_identified_temp_table);
5828
5794
 
5829
5795
                error = convert_error_code_to_mysql(error, iflags, NULL);
5863
5829
        this is an ALTER TABLE. */
5864
5830
 
5865
5831
        if ((create_proto.options().has_auto_increment_value()
5866
 
            || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
 
5832
            || session_sql_command(session) == SQLCOM_ALTER_TABLE)
5867
5833
            && create_proto.options().auto_increment_value() != 0) {
5868
5834
 
5869
5835
                /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
5887
5853
 
5888
5854
        trx_free_for_mysql(trx);
5889
5855
 
5890
 
        StorageEngine::writeDefinitionFromPath(identifier, create_proto);
5891
 
 
5892
5856
        return(0);
5893
5857
 
5894
5858
cleanup:
5952
5916
                /* We only handle TRUNCATE TABLE t as a special case.
5953
5917
                DELETE FROM t will have to use ha_innobase::delete_row(),
5954
5918
                because DELETE is transactional while TRUNCATE is not. */
5955
 
                return(errno=HA_ERR_WRONG_COMMAND);
 
5919
                return(my_errno=HA_ERR_WRONG_COMMAND);
5956
5920
        }
5957
5921
 
5958
5922
        /* Truncate the table in InnoDB */
5980
5944
int
5981
5945
InnobaseEngine::doDropTable(
5982
5946
/*======================*/
5983
 
        Session &session,
5984
 
        TableIdentifier &identifier)
 
5947
        Session& session,
 
5948
        const string table_path)        /* in: table name */
5985
5949
{
5986
5950
        int     error;
5987
5951
        trx_t*  parent_trx;
5988
5952
        trx_t*  trx;
5989
5953
        char    norm_name[1000];
5990
5954
 
5991
 
        ut_a(identifier.getPath().length() < 1000);
 
5955
        ut_a(table_path.length() < 1000);
5992
5956
 
5993
5957
        /* Strangely, MySQL passes the table name without the '.frm'
5994
5958
        extension, in contrast to ::create */
5995
 
        normalize_table_name(norm_name, identifier.getPath().c_str());
 
5959
        normalize_table_name(norm_name, table_path.c_str());
5996
5960
 
5997
5961
        /* Get the transaction associated with the current session, or create one
5998
5962
        if not yet created */
6032
5996
        if(error!=ENOENT)
6033
5997
          error = convert_error_code_to_mysql(error, 0, NULL);
6034
5998
 
6035
 
        if (error == 0 || error == ENOENT)
6036
 
        {
6037
 
          string path(identifier.getPath());
6038
 
 
6039
 
          path.append(DEFAULT_FILE_EXTENSION);
6040
 
 
6041
 
          (void)internal::my_delete(path.c_str(), MYF(0));
6042
 
        }
6043
 
 
6044
5999
        return(error);
6045
6000
}
6046
6001
 
6047
6002
/*****************************************************************//**
6048
6003
Removes all tables in the named database inside InnoDB. */
6049
 
bool
6050
 
InnobaseEngine::doDropSchema(
 
6004
void
 
6005
InnobaseEngine::drop_database(
6051
6006
/*===================*/
6052
 
                             SchemaIdentifier &identifier)
6053
 
                /*!< in: database path; inside InnoDB the name
 
6007
        char*   path)   /*!< in: database path; inside InnoDB the name
6054
6008
                        of the last directory in the path is used as
6055
6009
                        the database name: for example, in 'mysql/data/test'
6056
6010
                        the database name is 'test' */
6057
6011
{
 
6012
        ulint   len             = 0;
6058
6013
        trx_t*  trx;
 
6014
        char*   ptr;
6059
6015
        int     error;
6060
 
        string schema_path(identifier.getPath());
 
6016
        char*   namebuf;
6061
6017
        Session*        session         = current_session;
6062
6018
 
6063
6019
        /* Get the transaction associated with the current session, or create one
6076
6032
                trx_search_latch_release_if_reserved(parent_trx);
6077
6033
        }
6078
6034
 
6079
 
        schema_path.append("/");
 
6035
        ptr = strchr(path, '\0') - 2;
 
6036
 
 
6037
        while (ptr >= path && *ptr != '\\' && *ptr != '/') {
 
6038
                ptr--;
 
6039
                len++;
 
6040
        }
 
6041
 
 
6042
        ptr++;
 
6043
        namebuf = (char*) malloc((uint) len + 2);
 
6044
 
 
6045
        memcpy(namebuf, ptr, len);
 
6046
        namebuf[len] = '/';
 
6047
        namebuf[len + 1] = '\0';
 
6048
#ifdef  __WIN__
 
6049
        innobase_casedn_str(namebuf);
 
6050
#endif
 
6051
#if defined __WIN__ && !defined MYSQL_SERVER
 
6052
        /* In the Windows plugin, thd = current_thd is always NULL */
 
6053
        trx = trx_allocate_for_mysql();
 
6054
        trx->mysql_thd = NULL;
 
6055
        trx->mysql_query_str = NULL;
 
6056
#else
6080
6057
        trx = innobase_trx_allocate(session);
6081
 
        error = row_drop_database_for_mysql(schema_path.c_str(), trx);
 
6058
#endif
 
6059
        error = row_drop_database_for_mysql(namebuf, trx);
 
6060
        free(namebuf);
6082
6061
 
6083
6062
        /* Flush the log to reduce probability that the .frm files and
6084
6063
        the InnoDB data dictionary get out-of-sync if the user runs
6093
6072
 
6094
6073
        innobase_commit_low(trx);
6095
6074
        trx_free_for_mysql(trx);
6096
 
 
6097
 
        return false; // We are just a listener since we lack control over DDL, so we give no positive acknowledgement. 
6098
6075
}
6099
6076
/*********************************************************************//**
6100
6077
Renames an InnoDB table.
6160
6137
/*********************************************************************//**
6161
6138
Renames an InnoDB table.
6162
6139
@return 0 or error code */
6163
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
 
6140
UNIV_INTERN
 
6141
int
 
6142
InnobaseEngine::doRenameTable(
 
6143
/*======================*/
 
6144
        Session*        session,
 
6145
        const char*     from,   /*!< in: old name of the table */
 
6146
        const char*     to)     /*!< in: new name of the table */
6164
6147
{
6165
 
        // A temp table alter table/rename is a shallow rename and only the
6166
 
        // definition needs to be updated.
6167
 
        if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6168
 
        {
6169
 
          return plugin::StorageEngine::renameDefinitionFromPath(to, from);
6170
 
        }
6171
 
 
6172
6148
        trx_t*  trx;
6173
6149
        int     error;
6174
6150
        trx_t*  parent_trx;
6176
6152
        /* Get the transaction associated with the current session, or create one
6177
6153
        if not yet created */
6178
6154
 
6179
 
        parent_trx = check_trx_exists(&session);
 
6155
        parent_trx = check_trx_exists(session);
6180
6156
 
6181
6157
        /* In case MySQL calls this in the middle of a SELECT query, release
6182
6158
        possible adaptive hash latch to avoid deadlocks of threads */
6183
6159
 
6184
6160
        trx_search_latch_release_if_reserved(parent_trx);
6185
6161
 
6186
 
        trx = innobase_trx_allocate(&session);
 
6162
        trx = innobase_trx_allocate(session);
6187
6163
 
6188
 
        error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
 
6164
        error = innobase_rename_table(trx, from, to, TRUE);
6189
6165
 
6190
6166
        /* Tell the InnoDB server that there might be work for
6191
6167
        utility threads: */
6197
6173
 
6198
6174
        error = convert_error_code_to_mysql(error, 0, NULL);
6199
6175
 
6200
 
        if (not error)
6201
 
        {
6202
 
          // If this fails, we are in trouble
6203
 
          plugin::StorageEngine::renameDefinitionFromPath(to, from);
6204
 
        }
6205
 
 
6206
6176
        return(error);
6207
6177
}
6208
6178
 
6477
6447
                snprintf(path, sizeof(path), "%s/%s%s",
6478
6448
                               drizzle_data_home, ib_table->name, ".dfe");
6479
6449
 
6480
 
                internal::unpack_filename(path,path);
 
6450
                unpack_filename(path,path);
6481
6451
 
6482
6452
                /* Note that we do not know the access time of the table,
6483
6453
                nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
6892
6862
          while (tmp_buff[i] != '/')
6893
6863
                  i++;
6894
6864
          tmp_buff+= i + 1;
6895
 
          f_key_info.forein_id = session->make_lex_string(NULL, tmp_buff, strlen(tmp_buff), true);
 
6865
          f_key_info.forein_id = session_make_lex_string(session, 0,
 
6866
                  tmp_buff, (uint) strlen(tmp_buff), 1);
6896
6867
          tmp_buff= foreign->referenced_table_name;
6897
6868
 
6898
6869
          /* Database name */
6904
6875
          }
6905
6876
          db_name[i]= 0;
6906
6877
          ulen= filename_to_tablename(db_name, uname, sizeof(uname));
6907
 
          f_key_info.referenced_db = session->make_lex_string(NULL, uname, ulen, true);
 
6878
          f_key_info.referenced_db = session_make_lex_string(session, 0,
 
6879
                  uname, ulen, 1);
6908
6880
 
6909
6881
          /* Table name */
6910
6882
          tmp_buff+= i + 1;
6911
6883
          ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname));
6912
 
          f_key_info.referenced_table = session->make_lex_string(NULL, uname, ulen, true);
 
6884
          f_key_info.referenced_table = session_make_lex_string(session, 0,
 
6885
                  uname, ulen, 1);
6913
6886
 
6914
6887
          for (i= 0;;) {
6915
6888
                  tmp_buff= foreign->foreign_col_names[i];
6916
 
                  name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
 
6889
                  name = session_make_lex_string(session, name,
 
6890
                          tmp_buff, (uint) strlen(tmp_buff), 1);
6917
6891
                  f_key_info.foreign_fields.push_back(name);
6918
6892
                  tmp_buff= foreign->referenced_col_names[i];
6919
 
                  name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
 
6893
                  name = session_make_lex_string(session, name,
 
6894
                        tmp_buff, (uint) strlen(tmp_buff), 1);
6920
6895
                  f_key_info.referenced_fields.push_back(name);
6921
6896
                  if (++i >= foreign->n_fields)
6922
6897
                          break;
6943
6918
            length=8;
6944
6919
            tmp_buff= "RESTRICT";
6945
6920
          }
6946
 
          f_key_info.delete_method = session->make_lex_string(
6947
 
                  f_key_info.delete_method, tmp_buff, length, true);
 
6921
          f_key_info.delete_method = session_make_lex_string(
 
6922
                  session, f_key_info.delete_method, tmp_buff, length, 1);
6948
6923
 
6949
6924
 
6950
6925
          if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
6967
6942
            length=8;
6968
6943
            tmp_buff= "RESTRICT";
6969
6944
          }
6970
 
          f_key_info.update_method = session->make_lex_string(
6971
 
                  f_key_info.update_method, tmp_buff, length, true);
 
6945
          f_key_info.update_method = session_make_lex_string(
 
6946
                  session, f_key_info.update_method, tmp_buff, length, 1);
6972
6947
          if (foreign->referenced_index &&
6973
6948
              foreign->referenced_index->name)
6974
6949
          {
6975
 
            f_key_info.referenced_key_name = session->make_lex_string(
6976
 
                    f_key_info.referenced_key_name,
 
6950
            f_key_info.referenced_key_name = session_make_lex_string(
 
6951
                    session, f_key_info.referenced_key_name,
6977
6952
                    foreign->referenced_index->name,
6978
 
                    strlen(foreign->referenced_index->name), true);
 
6953
                    (uint) strlen(foreign->referenced_index->name), 1);
6979
6954
          }
6980
6955
          else
6981
6956
            f_key_info.referenced_key_name= 0;
7130
7105
}
7131
7106
 
7132
7107
/******************************************************************//**
 
7108
MySQL calls this function at the start of each SQL statement inside LOCK
 
7109
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
 
7110
mark SQL statement borders. Note also a special case: if a temporary table
 
7111
is created inside LOCK TABLES, MySQL has not called external_lock() at all
 
7112
on that table.
 
7113
MySQL-5.0 also calls this before each statement in an execution of a stored
 
7114
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
 
7115
locks all tables involved in a stored procedure with full explicit table
 
7116
locks (session_in_lock_tables(session) holds in store_lock()) before executing
 
7117
the procedure.
 
7118
@return 0 or error code */
 
7119
UNIV_INTERN
 
7120
int
 
7121
ha_innobase::start_stmt(
 
7122
/*====================*/
 
7123
        Session*        session,        /*!< in: handle to the user thread */
 
7124
        thr_lock_type   lock_type)
 
7125
{
 
7126
        trx_t*          trx;
 
7127
 
 
7128
        update_session(session);
 
7129
 
 
7130
        trx = prebuilt->trx;
 
7131
 
 
7132
        /* Here we release the search latch and the InnoDB thread FIFO ticket
 
7133
        if they were reserved. They should have been released already at the
 
7134
        end of the previous statement, but because inside LOCK TABLES the
 
7135
        lock count method does not work to mark the end of a SELECT statement,
 
7136
        that may not be the case. We MUST release the search latch before an
 
7137
        INSERT, for example. */
 
7138
 
 
7139
        innobase_release_stat_resources(trx);
 
7140
 
 
7141
        /* Reset the AUTOINC statement level counter for multi-row INSERTs. */
 
7142
        trx->n_autoinc_rows = 0;
 
7143
 
 
7144
        prebuilt->sql_stat_start = TRUE;
 
7145
        prebuilt->hint_need_to_fetch_extra_cols = 0;
 
7146
        reset_template(prebuilt);
 
7147
 
 
7148
        if (!prebuilt->mysql_has_locked) {
 
7149
                /* This handle is for a temporary table created inside
 
7150
                this same LOCK TABLES; since MySQL does NOT call external_lock
 
7151
                in this case, we must use x-row locks inside InnoDB to be
 
7152
                prepared for an update of a row */
 
7153
 
 
7154
                prebuilt->select_lock_type = LOCK_X;
 
7155
        } else {
 
7156
                if (trx->isolation_level != TRX_ISO_SERIALIZABLE
 
7157
                        && session_sql_command(session) == SQLCOM_SELECT
 
7158
                        && lock_type == TL_READ) {
 
7159
 
 
7160
                        /* For other than temporary tables, we obtain
 
7161
                        no lock for consistent read (plain SELECT). */
 
7162
 
 
7163
                        prebuilt->select_lock_type = LOCK_NONE;
 
7164
                } else {
 
7165
                        /* Not a consistent read: restore the
 
7166
                        select_lock_type value. The value of
 
7167
                        stored_select_lock_type was decided in:
 
7168
                        1) ::store_lock(),
 
7169
                        2) ::external_lock(),
 
7170
                        3) ::init_table_handle_for_HANDLER(), and
 
7171
                      */
 
7172
 
 
7173
                        prebuilt->select_lock_type =
 
7174
                                prebuilt->stored_select_lock_type;
 
7175
                }
 
7176
        }
 
7177
 
 
7178
        trx->detailed_error[0] = '\0';
 
7179
 
 
7180
        /* Set the MySQL flag to mark that there is an active transaction */
 
7181
        if (trx->active_trans == 0) {
 
7182
 
 
7183
                innobase_register_trx_and_stmt(engine, session);
 
7184
                trx->active_trans = 1;
 
7185
        } else {
 
7186
                innobase_register_stmt(engine, session);
 
7187
        }
 
7188
 
 
7189
        return(0);
 
7190
}
 
7191
 
 
7192
/******************************************************************//**
7133
7193
Maps a MySQL trx isolation level code to the InnoDB isolation level code
7134
7194
@return InnoDB isolation level */
7135
7195
static inline
7149
7209
 
7150
7210
/******************************************************************//**
7151
7211
As MySQL will execute an external lock for every new table it uses when it
7152
 
starts to process an SQL statement.  We can use this function to store the pointer to
7153
 
the Session in the handle.
 
7212
starts to process an SQL statement (an exception is when MySQL calls
 
7213
start_stmt for the handle) we can use this function to store the pointer to
 
7214
the Session in the handle. We will also use this function to communicate
 
7215
to InnoDB that a new SQL statement has started and that we must store a
 
7216
savepoint to our transaction handle, so that we are able to roll back
 
7217
the SQL statement in case of an error.
7154
7218
@return 0 */
7155
7219
UNIV_INTERN
7156
7220
int
7159
7223
        Session*        session,        /*!< in: handle to the user thread */
7160
7224
        int     lock_type)      /*!< in: lock type */
7161
7225
{
 
7226
        trx_t*          trx;
 
7227
 
 
7228
 
7162
7229
        update_session(session);
7163
7230
 
7164
 
  trx_t *trx= prebuilt->trx;
 
7231
        trx = prebuilt->trx;
7165
7232
 
7166
7233
        prebuilt->sql_stat_start = TRUE;
7167
7234
        prebuilt->hint_need_to_fetch_extra_cols = 0;
7179
7246
        if (lock_type != F_UNLCK) {
7180
7247
                /* MySQL is setting a new table lock */
7181
7248
 
 
7249
                trx->detailed_error[0] = '\0';
 
7250
 
 
7251
                /* Set the MySQL flag to mark that there is an active
 
7252
                transaction */
 
7253
                if (trx->active_trans == 0) {
 
7254
 
 
7255
                        innobase_register_trx_and_stmt(engine, session);
 
7256
                        trx->active_trans = 1;
 
7257
                } else if (trx->n_mysql_tables_in_use == 0) {
 
7258
                        innobase_register_stmt(engine, session);
 
7259
                }
 
7260
 
7182
7261
                if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7183
7262
                        && prebuilt->select_lock_type == LOCK_NONE
7184
7263
                        && session_test_options(session,
7211
7290
                        trx->mysql_n_tables_locked++;
7212
7291
                }
7213
7292
 
 
7293
                trx->n_mysql_tables_in_use++;
7214
7294
                prebuilt->mysql_has_locked = TRUE;
7215
7295
 
7216
7296
                return(0);
7217
7297
        }
7218
7298
 
7219
7299
        /* MySQL is releasing a table lock */
 
7300
 
 
7301
        trx->n_mysql_tables_in_use--;
7220
7302
        prebuilt->mysql_has_locked = FALSE;
7221
 
        trx->mysql_n_tables_locked= 0;
 
7303
 
 
7304
        /* Release a possible FIFO ticket and search latch. Since we
 
7305
        may reserve the kernel mutex, we have to release the search
 
7306
        system latch first to obey the latching order. */
 
7307
 
 
7308
        innobase_release_stat_resources(trx);
 
7309
 
 
7310
        /* If the MySQL lock count drops to zero we know that the current SQL
 
7311
        statement has ended */
 
7312
 
 
7313
        if (trx->n_mysql_tables_in_use == 0) {
 
7314
 
 
7315
                trx->mysql_n_tables_locked = 0;
 
7316
                prebuilt->used_in_HANDLER = FALSE;
 
7317
 
 
7318
                if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
7319
                        if (trx->active_trans != 0) {
 
7320
                                engine->commit(session, TRUE);
 
7321
                        }
 
7322
                } else {
 
7323
                        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
7324
                                                && trx->global_read_view) {
 
7325
 
 
7326
                                /* At low transaction isolation levels we let
 
7327
                                each consistent read set its own snapshot */
 
7328
 
 
7329
                                read_view_close_for_mysql(trx);
 
7330
                        }
 
7331
                }
 
7332
        }
7222
7333
 
7223
7334
        return(0);
7224
7335
}
7225
7336
 
7226
7337
/************************************************************************//**
 
7338
Here we export InnoDB status variables to MySQL. */
 
7339
static
 
7340
void
 
7341
innodb_export_status(void)
 
7342
/*======================*/
 
7343
{
 
7344
        if (innodb_inited) {
 
7345
                srv_export_innodb_status();
 
7346
        }
 
7347
}
 
7348
 
 
7349
/************************************************************************//**
7227
7350
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
7228
7351
Monitor to the client. */
7229
7352
static
7230
7353
bool
7231
7354
innodb_show_status(
7232
7355
/*===============*/
7233
 
        plugin::StorageEngine*  engine, /*!< in: the innodb StorageEngine */
 
7356
        drizzled::plugin::StorageEngine*        engine, /*!< in: the innodb StorageEngine */
7234
7357
        Session*        session,/*!< in: the MySQL query thread of the caller */
7235
7358
        stat_print_fn *stat_print)
7236
7359
{
7317
7440
bool
7318
7441
innodb_mutex_show_status(
7319
7442
/*=====================*/
7320
 
        plugin::StorageEngine*  engine,         /*!< in: the innodb StorageEngine */
 
7443
        drizzled::plugin::StorageEngine*        engine,         /*!< in: the innodb StorageEngine */
7321
7444
        Session*        session,        /*!< in: the MySQL query thread of the
7322
7445
                                        caller */
7323
7446
        stat_print_fn*  stat_print)
7561
7684
 
7562
7685
        trx = check_trx_exists(session);
7563
7686
 
 
7687
        /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
 
7688
        Be careful to ignore TL_IGNORE if we are going to do something with
 
7689
        only 'real' locks! */
 
7690
 
 
7691
        /* If no MySQL table is in use, we need to set the isolation level
 
7692
        of the transaction. */
 
7693
 
 
7694
        if (lock_type != TL_IGNORE
 
7695
            && trx->n_mysql_tables_in_use == 0) {
 
7696
                trx->isolation_level = innobase_map_isolation_level(
 
7697
                        (enum_tx_isolation) session_tx_isolation(session));
 
7698
 
 
7699
                if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
7700
                    && trx->global_read_view) {
 
7701
 
 
7702
                        /* At low transaction isolation levels we let
 
7703
                        each consistent read set its own snapshot */
 
7704
 
 
7705
                        read_view_close_for_mysql(trx);
 
7706
                }
 
7707
        }
 
7708
 
7564
7709
        assert(EQ_CURRENT_SESSION(session));
7565
7710
        const uint32_t sql_command = session_sql_command(session);
7566
7711
 
7641
7786
                TABLESPACE or TRUNCATE TABLE then allow multiple
7642
7787
                writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
7643
7788
                < TL_WRITE_CONCURRENT_INSERT.
7644
 
                */
 
7789
 
 
7790
                We especially allow multiple writers if MySQL is at the
 
7791
                start of a stored procedure call (SQLCOM_CALL) or a
 
7792
                stored function call (MySQL does have in_lock_tables
 
7793
                TRUE there). */
7645
7794
 
7646
7795
                if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
7647
7796
                     && lock_type <= TL_WRITE)
7657
7806
                would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
7658
7807
                to t2. Convert the lock to a normal read lock to allow
7659
7808
                concurrent inserts to t2.
7660
 
    */
 
7809
 
 
7810
                We especially allow concurrent inserts if MySQL is at the
 
7811
                start of a stored procedure call (SQLCOM_CALL)
 
7812
                (MySQL does have session_in_lock_tables() TRUE there). */
7661
7813
 
7662
7814
                if (lock_type == TL_READ_NO_INSERT) {
7663
7815
 
8032
8184
 
8033
8185
        return(char_length);
8034
8186
}
8035
 
/**
8036
 
 * We will also use this function to communicate
8037
 
 * to InnoDB that a new SQL statement has started and that we must store a
8038
 
 * savepoint to our transaction handle, so that we are able to roll back
8039
 
 * the SQL statement in case of an error.
8040
 
 */
8041
 
void
8042
 
InnobaseEngine::doStartStatement(
8043
 
        Session *session) /*!< in: handle to the Drizzle session */
8044
 
{
8045
 
  /* 
8046
 
   * Create the InnoDB transaction structure
8047
 
   * for the session
8048
 
   */
8049
 
        trx_t *trx= check_trx_exists(session);
8050
 
 
8051
 
  /* "reset" the error message for the transaction */
8052
 
  trx->detailed_error[0]= '\0';
8053
 
 
8054
 
        /* Set the isolation level of the transaction. */
8055
 
  trx->isolation_level= innobase_map_isolation_level((enum_tx_isolation) session_tx_isolation(session));
8056
 
}
8057
 
 
8058
 
void
8059
 
InnobaseEngine::doEndStatement(
8060
 
  Session *session)
8061
 
{
8062
 
  trx_t *trx= check_trx_exists(session);
8063
 
 
8064
 
  /* Release a possible FIFO ticket and search latch. Since we
8065
 
  may reserve the kernel mutex, we have to release the search
8066
 
  system latch first to obey the latching order. */
8067
 
 
8068
 
  innobase_release_stat_resources(trx);
8069
 
 
8070
 
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
8071
 
  {
8072
 
    if (trx->conc_state != TRX_NOT_STARTED)
8073
 
    {
8074
 
      commit(session, TRUE);
8075
 
    }
8076
 
  }
8077
 
  else
8078
 
  {
8079
 
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
8080
 
        trx->global_read_view)
8081
 
    {
8082
 
      /* At low transaction isolation levels we let
8083
 
      each consistent read set its own snapshot */
8084
 
      read_view_close_for_mysql(trx);
8085
 
    }
8086
 
  }
8087
 
}
8088
8187
 
8089
8188
/*******************************************************************//**
8090
8189
This function is used to prepare an X/Open XA distributed transaction.
8091
8190
@return 0 or error number */
8092
8191
int
8093
 
InnobaseEngine::doXaPrepare(
 
8192
InnobaseEngine::prepare(
8094
8193
/*================*/
8095
8194
        Session*        session,/*!< in: handle to the MySQL thread of
8096
8195
                                the user whose XA transaction should
8120
8219
 
8121
8220
        innobase_release_stat_resources(trx);
8122
8221
 
 
8222
        if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
 
8223
 
 
8224
          errmsg_printf(ERRMSG_LVL_ERROR,
 
8225
                        "trx->active_trans == 0, but trx->conc_state != "
 
8226
                        "TRX_NOT_STARTED");
 
8227
        }
 
8228
 
8123
8229
        if (all
8124
8230
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
8125
8231
 
8126
8232
                /* We were instructed to prepare the whole transaction, or
8127
8233
                this is an SQL statement end and autocommit is on */
8128
8234
 
8129
 
                ut_ad(trx->conc_state != TRX_NOT_STARTED);
 
8235
                ut_ad(trx->active_trans);
8130
8236
 
8131
8237
                error = (int) trx_prepare_for_mysql(trx);
8132
8238
        } else {
8173
8279
                to block for undefined period of time.
8174
8280
                */
8175
8281
                pthread_mutex_lock(&prepare_commit_mutex);
8176
 
                trx->conc_state = TRX_PREPARED;
 
8282
                trx->active_trans = 2;
8177
8283
        }
8178
8284
        return(error);
8179
8285
}
8182
8288
This function is used to recover X/Open XA distributed transactions.
8183
8289
@return number of prepared transactions stored in xid_list */
8184
8290
int
8185
 
InnobaseEngine::doXaRecover(
 
8291
InnobaseEngine::recover(
8186
8292
/*================*/
8187
 
        ::drizzled::XID*        xid_list,/*!< in/out: prepared transactions */
8188
 
        size_t len)     /*!< in: number of slots in xid_list */
 
8293
        XID*            xid_list,/*!< in/out: prepared transactions */
 
8294
        uint            len)    /*!< in: number of slots in xid_list */
8189
8295
{
8190
8296
        assert(this == innodb_engine_ptr);
8191
8297
 
8194
8300
                return(0);
8195
8301
        }
8196
8302
 
8197
 
        return(trx_recover_for_mysql((::XID *)xid_list, len));
 
8303
        return(trx_recover_for_mysql(xid_list, len));
8198
8304
}
8199
8305
 
8200
8306
/*******************************************************************//**
8202
8308
which is in the prepared state
8203
8309
@return 0 or error number */
8204
8310
int
8205
 
InnobaseEngine::doXaCommitXid(
 
8311
InnobaseEngine::commit_by_xid(
8206
8312
/*===================*/
8207
 
        ::drizzled::XID*        xid)    /*!< in: X/Open XA transaction identification */
 
8313
        XID*    xid)    /*!< in: X/Open XA transaction identification */
8208
8314
{
8209
8315
        trx_t*  trx;
8210
8316
 
8211
8317
        assert(this == innodb_engine_ptr);
8212
8318
 
8213
 
        trx = trx_get_trx_by_xid((::XID *)xid);
 
8319
        trx = trx_get_trx_by_xid(xid);
8214
8320
 
8215
8321
        if (trx) {
8216
8322
                innobase_commit_low(trx);
8226
8332
which is in the prepared state
8227
8333
@return 0 or error number */
8228
8334
int
8229
 
InnobaseEngine::doXaRollbackXid(
 
8335
InnobaseEngine::rollback_by_xid(
8230
8336
/*=====================*/
8231
 
        ::drizzled::XID*                xid)    /*!< in: X/Open XA transaction
 
8337
        XID*            xid)    /*!< in: X/Open XA transaction
8232
8338
                                identification */
8233
8339
{
8234
8340
        trx_t*  trx;
8235
8341
 
8236
8342
        assert(this == innodb_engine_ptr);
8237
8343
 
8238
 
        trx = trx_get_trx_by_xid((::XID *)xid);
 
8344
        trx = trx_get_trx_by_xid(xid);
8239
8345
 
8240
8346
        if (trx) {
8241
8347
                return(innobase_rollback_trx(trx));
8610
8716
        *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
8611
8717
}
8612
8718
 
 
8719
static int show_innodb_vars(SHOW_VAR *var, char *)
 
8720
{
 
8721
  innodb_export_status();
 
8722
  var->type= SHOW_ARRAY;
 
8723
  var->value= (char *) &innodb_status_variables;
 
8724
  return 0;
 
8725
}
 
8726
 
 
8727
static st_show_var_func_container
 
8728
show_innodb_vars_cont = { &show_innodb_vars };
 
8729
 
 
8730
static SHOW_VAR innodb_status_variables_export[]= {
 
8731
  {"Innodb",                   (char*) &show_innodb_vars_cont, SHOW_FUNC},
 
8732
  {NULL, NULL, SHOW_LONG}
 
8733
};
 
8734
 
 
8735
 
8613
8736
/* plugin options */
8614
8737
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
8615
8738
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8670
8793
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8671
8794
  "With which method to flush data.", NULL, NULL, NULL);
8672
8795
 
 
8796
static DRIZZLE_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
 
8797
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8798
  "Force InnoDB to not use next-key locking, to use only row-level locking.",
 
8799
  NULL, NULL, TRUE);
 
8800
 
8673
8801
#ifdef UNIV_LOG_ARCHIVE
8674
8802
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
8675
8803
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8880
9008
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
8881
9009
  DRIZZLE_SYSVAR(flush_method),
8882
9010
  DRIZZLE_SYSVAR(force_recovery),
 
9011
  DRIZZLE_SYSVAR(locks_unsafe_for_binlog),
8883
9012
  DRIZZLE_SYSVAR(lock_wait_timeout),
8884
9013
#ifdef UNIV_LOG_ARCHIVE
8885
9014
  DRIZZLE_SYSVAR(log_arch_dir),
8918
9047
 
8919
9048
DRIZZLE_DECLARE_PLUGIN
8920
9049
{
8921
 
  DRIZZLE_VERSION_ID,
8922
9050
  innobase_engine_name,
8923
9051
  INNODB_VERSION_STR,
8924
9052
  "Innobase Oy",
8925
9053
  "Supports transactions, row-level locking, and foreign keys",
8926
9054
  PLUGIN_LICENSE_GPL,
8927
9055
  innobase_init, /* Plugin Init */
 
9056
  innobase_deinit, /* Plugin Deinit */
 
9057
  innodb_status_variables_export,/* status variables             */
8928
9058
  innobase_system_variables, /* system variables */
8929
9059
  NULL /* reserved */
8930
9060
}