~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-03-25 22:03:13 UTC
  • mfrom: (960.2.47 mordred)
  • Revision ID: brian@tangent.org-20090325220313-fffae098oufxiaqg
Merge of Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
#include <drizzled/field/blob.h>
50
50
#include <drizzled/field/varstring.h>
51
51
#include <drizzled/field/timestamp.h>
 
52
#include <drizzled/plugin/storage_engine.h>
52
53
 
53
54
/* Include necessary InnoDB headers */
54
55
extern "C" {
87
88
#include "i_s.h"
88
89
#include "handler0vars.h"
89
90
 
 
91
#include <string>
 
92
 
 
93
using namespace std;
 
94
 
 
95
 
90
96
#ifndef DRIZZLE_SERVER
91
97
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
92
98
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
119
125
# define EQ_CURRENT_SESSION(session) ((session) == current_session)
120
126
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
121
127
 
 
128
 
 
129
StorageEngine* innodb_engine_ptr= NULL;
122
130
#ifdef DRIZZLE_DYNAMIC_PLUGIN
123
131
/* These must be weak global variables in the dynamic plugin. */
124
 
struct handlerton* innodb_hton_ptr;
125
132
#ifdef __WIN__
126
133
struct st_mysql_plugin* builtin_innobase_plugin_ptr;
127
134
#else
135
142
innodb_plugin_init(void);
136
143
/*====================*/
137
144
                /* out: TRUE if the dynamic InnoDB plugin should start */
138
 
#else /* DRIZZLE_DYNAMIC_PLUGIN */
139
 
/* This must be a global variable in the statically linked InnoDB. */
140
 
struct handlerton* innodb_hton_ptr = NULL;
141
145
#endif /* DRIZZLE_DYNAMIC_PLUGIN */
142
146
 
143
147
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
211
215
 
212
216
static INNOBASE_SHARE *get_share(const char *table_name);
213
217
static void free_share(INNOBASE_SHARE *share);
214
 
static int innobase_close_connection(handlerton *hton, Session* session);
215
 
static int innobase_commit(handlerton *hton, Session* session, bool all);
216
 
static int innobase_rollback(handlerton *hton, Session* session, bool all);
217
 
static int innobase_rollback_to_savepoint(handlerton *hton, Session* session, 
218
 
           void *savepoint);
219
 
static int innobase_savepoint(handlerton *hton, Session* session, void *savepoint);
220
 
static int innobase_release_savepoint(handlerton *hton, Session* session, 
221
 
           void *savepoint);
222
 
static handler *innobase_create_handler(handlerton *hton,
223
 
                                        TABLE_SHARE *table,
224
 
                                        MEM_ROOT *mem_root);
 
218
 
 
219
class InnobaseEngine : public StorageEngine
 
220
{
 
221
public:
 
222
  InnobaseEngine(string name_arg) : StorageEngine(name_arg) {}
 
223
 
 
224
  virtual
 
225
  int
 
226
  close_connection(
 
227
/*======================*/
 
228
                        /* out: 0 or error number */
 
229
        Session*        session);       /* in: handle to the MySQL thread of the user
 
230
                        whose resources should be free'd */
 
231
 
 
232
  virtual int savepoint_set(Session* session,
 
233
                        void *savepoint);
 
234
  virtual int savepoint_rollback(Session* session, 
 
235
                                    void *savepoint);
 
236
  virtual int savepoint_release(Session* session, 
 
237
                                void *savepoint);
 
238
  virtual int commit(Session* session, bool all);
 
239
  virtual int rollback(Session* session, bool all);
 
240
 
 
241
  /***********************************************************************
 
242
  This function is used to prepare X/Open XA distributed transaction   */
 
243
  virtual
 
244
  int
 
245
  prepare(
 
246
  /*================*/
 
247
                        /* out: 0 or error number */
 
248
        Session*        session,        /* in: handle to the MySQL thread of the user
 
249
                        whose XA transaction should be prepared */
 
250
        bool    all);   /* in: TRUE - commit transaction
 
251
                        FALSE - the current SQL statement ended */
 
252
  /***********************************************************************
 
253
  This function is used to recover X/Open XA distributed transactions   */
 
254
  virtual
 
255
  int
 
256
  recover(
 
257
  /*================*/
 
258
                                /* out: number of prepared transactions
 
259
                                stored in xid_list */
 
260
        XID*    xid_list,       /* in/out: prepared transactions */
 
261
        uint    len);           /* in: number of slots in xid_list */
 
262
  /***********************************************************************
 
263
  This function is used to commit one X/Open XA distributed transaction
 
264
  which is in the prepared state */
 
265
  virtual
 
266
  int
 
267
  commit_by_xid(
 
268
  /*===================*/
 
269
                        /* out: 0 or error number */
 
270
        XID*    xid);   /* in: X/Open XA transaction identification */
 
271
  /***********************************************************************
 
272
  This function is used to rollback one X/Open XA distributed transaction
 
273
  which is in the prepared state */
 
274
  virtual
 
275
  int
 
276
  rollback_by_xid(
 
277
  /*=====================*/
 
278
                        /* out: 0 or error number */
 
279
        XID     *xid);  /* in: X/Open XA transaction identification */
 
280
 
 
281
  virtual handler *create(TABLE_SHARE *table,
 
282
                          MEM_ROOT *mem_root)
 
283
  {
 
284
    return new (mem_root) ha_innobase(this, table);
 
285
  }
 
286
 
 
287
  /*********************************************************************
 
288
  Removes all tables in the named database inside InnoDB. */
 
289
  virtual
 
290
  void
 
291
  drop_database(
 
292
  /*===================*/
 
293
                        /* out: error number */
 
294
        char*   path);  /* in: database path; inside InnoDB the name
 
295
                        of the last directory in the path is used as
 
296
                        the database name: for example, in 'mysql/data/test'
 
297
                        the database name is 'test' */
 
298
 
 
299
  /*********************************************************************
 
300
  Creates an InnoDB transaction struct for the session if it does not yet have one.
 
301
  Starts a new InnoDB transaction if a transaction is not yet started. And
 
302
  assigns a new snapshot for a consistent read if the transaction does not yet
 
303
  have one. */
 
304
  virtual
 
305
  int
 
306
  start_consistent_snapshot(
 
307
  /*====================================*/
 
308
                        /* out: 0 */
 
309
        Session*        session);       /* in: MySQL thread handle of the user for whom
 
310
                        the transaction should be committed */
 
311
  /********************************************************************
 
312
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
 
313
  the logs, and the name of this function should be innobase_checkpoint. */
 
314
  virtual
 
315
  bool
 
316
  flush_logs();
 
317
  /*================*/
 
318
                                /* out: TRUE if error */
 
319
  
 
320
  /****************************************************************************
 
321
  Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
 
322
  Monitor to the client. */
 
323
  virtual
 
324
  bool
 
325
  show_status(
 
326
  /*===============*/
 
327
        Session*        session,        /* in: the MySQL query thread of the caller */
 
328
        stat_print_fn *stat_print,
 
329
        enum ha_stat_type stat_type);
 
330
 
 
331
  virtual
 
332
  int
 
333
  release_temporary_latches(
 
334
  /*===============================*/
 
335
                                /* out: 0 */
 
336
        Session*                session);       /* in: MySQL thread */
 
337
 
 
338
};
225
339
 
226
340
/****************************************************************
227
341
Validate the file format name and return its corresponding id. */
253
367
                                                config value */
254
368
        const char*     format_check);          /* in: parameter value */
255
369
 
256
 
static const char innobase_hton_name[]= "InnoDB";
 
370
static const char innobase_engine_name[]= "InnoDB";
 
371
 
257
372
 
258
373
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
259
374
  "Enable InnoDB support for the XA two-phase commit",
274
389
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
275
390
 
276
391
 
277
 
static handler *innobase_create_handler(handlerton *hton,
278
 
                                        TABLE_SHARE *table, 
279
 
                                        MEM_ROOT *mem_root)
280
 
{
281
 
  return new (mem_root) ha_innobase(hton, table);
282
 
}
283
 
 
284
 
/***********************************************************************
285
 
This function is used to prepare X/Open XA distributed transaction   */
286
 
static
287
 
int
288
 
innobase_xa_prepare(
289
 
/*================*/
290
 
                        /* out: 0 or error number */
291
 
        handlerton* hton,
292
 
        Session*        session,        /* in: handle to the MySQL thread of the user
293
 
                        whose XA transaction should be prepared */
294
 
        bool    all);   /* in: TRUE - commit transaction
295
 
                        FALSE - the current SQL statement ended */
296
 
/***********************************************************************
297
 
This function is used to recover X/Open XA distributed transactions   */
298
 
static
299
 
int
300
 
innobase_xa_recover(
301
 
/*================*/
302
 
                                /* out: number of prepared transactions
303
 
                                stored in xid_list */
304
 
        handlerton* hton,
305
 
        XID*    xid_list,       /* in/out: prepared transactions */
306
 
        uint    len);           /* in: number of slots in xid_list */
307
 
/***********************************************************************
308
 
This function is used to commit one X/Open XA distributed transaction
309
 
which is in the prepared state */
310
 
static
311
 
int
312
 
innobase_commit_by_xid(
313
 
/*===================*/
314
 
                        /* out: 0 or error number */
315
 
        handlerton* hton,
316
 
        XID*    xid);   /* in: X/Open XA transaction identification */
317
 
/***********************************************************************
318
 
This function is used to rollback one X/Open XA distributed transaction
319
 
which is in the prepared state */
320
 
static
321
 
int
322
 
innobase_rollback_by_xid(
323
 
/*=====================*/
324
 
                        /* out: 0 or error number */
325
 
        handlerton* hton,
326
 
        XID     *xid);  /* in: X/Open XA transaction identification */
327
 
/*********************************************************************
328
 
Removes all tables in the named database inside InnoDB. */
329
 
static
330
 
void
331
 
innobase_drop_database(
332
 
/*===================*/
333
 
                        /* out: error number */
334
 
        handlerton* hton, /* in: handlerton of Innodb */
335
 
        char*   path);  /* in: database path; inside InnoDB the name
336
 
                        of the last directory in the path is used as
337
 
                        the database name: for example, in 'mysql/data/test'
338
 
                        the database name is 'test' */
339
392
/***********************************************************************
340
393
Closes an InnoDB database. */
341
394
static
342
395
int
343
396
innobase_deinit(void *p);
344
397
 
345
 
/*********************************************************************
346
 
Creates an InnoDB transaction struct for the session if it does not yet have one.
347
 
Starts a new InnoDB transaction if a transaction is not yet started. And
348
 
assigns a new snapshot for a consistent read if the transaction does not yet
349
 
have one. */
350
 
static
351
 
int
352
 
innobase_start_trx_and_assign_read_view(
353
 
/*====================================*/
354
 
                        /* out: 0 */
355
 
        handlerton* hton, /* in: Innodb handlerton */ 
356
 
        Session*        session);       /* in: MySQL thread handle of the user for whom
357
 
                        the transaction should be committed */
358
 
/********************************************************************
359
 
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
360
 
the logs, and the name of this function should be innobase_checkpoint. */
361
 
static
362
 
bool
363
 
innobase_flush_logs(
364
 
/*================*/
365
 
                                /* out: TRUE if error */
366
 
        handlerton*     hton);  /* in: InnoDB handlerton */
367
 
 
368
 
/****************************************************************************
369
 
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
370
 
Monitor to the client. */
371
 
static
372
 
bool
373
 
innodb_show_status(
374
 
/*===============*/
375
 
        handlerton*     hton,   /* in: the innodb handlerton */
376
 
        Session*        session,        /* in: the MySQL query thread of the caller */
377
 
        stat_print_fn *stat_print);
378
 
static
379
 
bool innobase_show_status(handlerton *hton, Session* session, 
380
 
                          stat_print_fn* stat_print,
381
 
                          enum ha_stat_type stat_type);
382
398
 
383
399
/*********************************************************************
384
400
Commits a transaction in an InnoDB database. */
630
646
                        /* out: reference to transaction pointer */
631
647
        Session*        session)        /* in: MySQL thread */
632
648
{
633
 
        return(*(trx_t**) session_ha_data(session, innodb_hton_ptr));
 
649
        return(*(trx_t**) session_ha_data(session, innodb_engine_ptr));
634
650
}
635
651
 
636
652
/************************************************************************
637
653
Call this function when mysqld passes control to the client. That is to
638
654
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
639
655
documentation, see handler.cc. */
640
 
static
641
656
int
642
 
innobase_release_temporary_latches(
 
657
InnobaseEngine::release_temporary_latches(
643
658
/*===============================*/
644
659
                                /* out: 0 */
645
 
        handlerton *hton,       /* in: handlerton */
646
660
        Session*                session)        /* in: MySQL thread */
647
661
{
648
662
        trx_t*  trx;
649
663
 
650
 
        assert(hton == innodb_hton_ptr);
 
664
        assert(this == innodb_engine_ptr);
651
665
 
652
666
        if (!innodb_inited) {
653
667
 
1279
1293
/*************************************************************************
1280
1294
Construct ha_innobase handler. */
1281
1295
UNIV_INTERN
1282
 
ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
1283
 
  :handler(hton, table_arg),
 
1296
ha_innobase::ha_innobase(StorageEngine *engine_arg, TABLE_SHARE *table_arg)
 
1297
  :handler(engine_arg, table_arg),
1284
1298
  int_table_flags(HA_REC_NOT_IN_SEQ |
1285
1299
                  HA_NULL_IN_KEY |
1286
1300
                  HA_CAN_INDEX_BLOBS |
1350
1364
void
1351
1365
innobase_register_stmt(
1352
1366
/*===================*/
1353
 
        handlerton*     hton,   /* in: Innobase hton */
 
1367
        StorageEngine*  engine, /* in: Innobase engine */
1354
1368
        Session*        session)        /* in: MySQL session (connection) object */
1355
1369
{
1356
 
        assert(hton == innodb_hton_ptr);
 
1370
        assert(engine == innodb_engine_ptr);
1357
1371
        /* Register the statement */
1358
 
        trans_register_ha(session, FALSE, hton);
 
1372
        trans_register_ha(session, FALSE, engine);
1359
1373
}
1360
1374
 
1361
1375
/*************************************************************************
1369
1383
void
1370
1384
innobase_register_trx_and_stmt(
1371
1385
/*===========================*/
1372
 
        handlerton *hton, /* in: Innobase handlerton */
 
1386
        StorageEngine *engine, /* in: Innobase StorageEngine */
1373
1387
        Session*        session)        /* in: MySQL session (connection) object */
1374
1388
{
1375
1389
        /* NOTE that actually innobase_register_stmt() registers also
1376
1390
        the transaction in the AUTOCOMMIT=1 mode. */
1377
1391
 
1378
 
        innobase_register_stmt(hton, session);
 
1392
        innobase_register_stmt(engine, session);
1379
1393
 
1380
1394
        if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1381
1395
 
1382
1396
                /* No autocommit mode, register for a transaction */
1383
 
                trans_register_ha(session, TRUE, hton);
 
1397
                trans_register_ha(session, TRUE, engine);
1384
1398
        }
1385
1399
}
1386
1400
 
1536
1550
 
1537
1551
        if (trx->active_trans == 0) {
1538
1552
 
1539
 
                innobase_register_trx_and_stmt(innodb_hton_ptr, session);
 
1553
                innobase_register_trx_and_stmt(innodb_engine_ptr, session);
1540
1554
                trx->active_trans = 1;
1541
1555
        }
1542
1556
 
1783
1797
 
1784
1798
        if (prebuilt->trx->active_trans == 0) {
1785
1799
 
1786
 
                innobase_register_trx_and_stmt(ht, user_session);
 
1800
                innobase_register_trx_and_stmt(engine, user_session);
1787
1801
 
1788
1802
                prebuilt->trx->active_trans = 1;
1789
1803
        }
1817
1831
innobase_init(
1818
1832
/*==========*/
1819
1833
                        /* out: 0 on success, error code on failure */
1820
 
        void    *p)     /* in: InnoDB handlerton */
 
1834
        void    *p)     /* in: InnoDB StorageEngine */
1821
1835
{
1822
1836
        static char     current_dir[3];         /* Set if using current lib */
1823
1837
        int             err;
1825
1839
        char            *default_path;
1826
1840
        uint            format_id;
1827
1841
 
1828
 
        handlerton *innobase_hton= (handlerton *)p;
 
1842
        StorageEngine **engine= static_cast<StorageEngine **>(p);
 
1843
        InnobaseEngine *innobase_engine= new InnobaseEngine(string(innobase_engine_name));
1829
1844
 
1830
1845
#ifdef DRIZZLE_DYNAMIC_PLUGIN
1831
1846
        if (!innodb_plugin_init()) {
1832
1847
                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB plugin init failed.");
1833
1848
                return -1;
1834
1849
        }
1835
 
 
1836
 
        if (innodb_hton_ptr) {
1837
 
                /* Patch the statically linked handlerton and variables */
1838
 
                innobase_hton = innodb_hton_ptr;
1839
 
        }
1840
1850
#endif /* DRIZZLE_DYNAMIC_PLUGIN */
1841
1851
 
1842
 
        innodb_hton_ptr = innobase_hton;
 
1852
        innodb_engine_ptr = innobase_engine;
1843
1853
 
1844
 
        innobase_hton->state = SHOW_OPTION_YES;
1845
 
        innobase_hton->savepoint_offset=sizeof(trx_named_savept_t);
1846
 
        innobase_hton->close_connection=innobase_close_connection;
1847
 
        innobase_hton->savepoint_set=innobase_savepoint;
1848
 
        innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
1849
 
        innobase_hton->savepoint_release=innobase_release_savepoint;
1850
 
        innobase_hton->commit=innobase_commit;
1851
 
        innobase_hton->rollback=innobase_rollback;
1852
 
        innobase_hton->prepare=innobase_xa_prepare;
1853
 
        innobase_hton->recover=innobase_xa_recover;
1854
 
        innobase_hton->commit_by_xid=innobase_commit_by_xid;
1855
 
        innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
1856
 
        innobase_hton->create=innobase_create_handler;
1857
 
        innobase_hton->drop_database=innobase_drop_database;
1858
 
        innobase_hton->start_consistent_snapshot=innobase_start_trx_and_assign_read_view;
1859
 
        innobase_hton->flush_logs=innobase_flush_logs;
1860
 
        innobase_hton->show_status=innobase_show_status;
1861
 
        innobase_hton->flags=HTON_NO_FLAGS;
1862
 
        innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
 
1854
        innobase_engine->state = SHOW_OPTION_YES;
 
1855
        innobase_engine->savepoint_offset=sizeof(trx_named_savept_t);
 
1856
        innobase_engine->flags=HTON_NO_FLAGS;
1863
1857
 
1864
1858
        ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)DRIZZLE_TYPE_VARCHAR);
1865
1859
 
2101
2095
        pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2102
2096
        pthread_cond_init(&commit_cond, NULL);
2103
2097
        innodb_inited= 1;
2104
 
#ifdef DRIZZLE_DYNAMIC_PLUGIN
2105
 
        if (innobase_hton != p) {
2106
 
                innobase_hton = reinterpret_cast<handlerton*>(p);
2107
 
                *innobase_hton = *innodb_hton_ptr;
2108
 
        }
2109
 
#endif /* DRIZZLE_DYNAMIC_PLUGIN */
 
2098
 
 
2099
        *engine= innobase_engine;
2110
2100
 
2111
2101
        /* Get the current high water mark format. */
2112
2102
        innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2120
2110
Closes an InnoDB database. */
2121
2111
static
2122
2112
int
2123
 
innobase_deinit(void *)
 
2113
innobase_deinit(void *p)
2124
2114
/*==============*/
2125
2115
                                /* out: TRUE if error */
2126
2116
{
2127
2117
        int     err= 0;
 
2118
        InnobaseEngine *innobase_engine= static_cast<InnobaseEngine *>(p);
 
2119
        delete innobase_engine;
2128
2120
 
2129
2121
        if (innodb_inited) {
2130
2122
 
2151
2143
/********************************************************************
2152
2144
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
2153
2145
the logs, and the name of this function should be innobase_checkpoint. */
2154
 
static
2155
2146
bool
2156
 
innobase_flush_logs(handlerton *hton)
 
2147
InnobaseEngine::flush_logs()
2157
2148
/*=====================*/
2158
2149
                                /* out: TRUE if error */
2159
2150
{
2160
2151
        bool    result = 0;
2161
2152
 
2162
 
        assert(hton == innodb_hton_ptr);
 
2153
        assert(this == innodb_engine_ptr);
2163
2154
 
2164
2155
        log_buffer_flush_to_disk();
2165
2156
 
2187
2178
Starts a new InnoDB transaction if a transaction is not yet started. And
2188
2179
assigns a new snapshot for a consistent read if the transaction does not yet
2189
2180
have one. */
2190
 
static
2191
2181
int
2192
 
innobase_start_trx_and_assign_read_view(
 
2182
InnobaseEngine::start_consistent_snapshot(
2193
2183
/*====================================*/
2194
2184
                        /* out: 0 */
2195
 
        handlerton *hton, /* in: Innodb handlerton */ 
2196
2185
        Session*        session)        /* in: MySQL thread handle of the user for whom
2197
2186
                        the transaction should be committed */
2198
2187
{
2199
2188
        trx_t*  trx;
2200
2189
 
2201
 
        assert(hton == innodb_hton_ptr);
 
2190
        assert(this == innodb_engine_ptr);
2202
2191
 
2203
2192
        /* Create a new trx struct for session, if it does not yet have one */
2204
2193
 
2221
2210
        /* Set the MySQL flag to mark that there is an active transaction */
2222
2211
 
2223
2212
        if (trx->active_trans == 0) {
2224
 
                innobase_register_trx_and_stmt(hton, current_session);
 
2213
                innobase_register_trx_and_stmt(this, current_session);
2225
2214
                trx->active_trans = 1;
2226
2215
        }
2227
2216
 
2231
2220
/*********************************************************************
2232
2221
Commits a transaction in an InnoDB database or marks an SQL statement
2233
2222
ended. */
2234
 
static
2235
2223
int
2236
 
innobase_commit(
 
2224
InnobaseEngine::commit(
2237
2225
/*============*/
2238
2226
                        /* out: 0 */
2239
 
        handlerton *hton, /* in: Innodb handlerton */ 
2240
2227
        Session*        session,        /* in: MySQL thread handle of the user for whom
2241
2228
                        the transaction should be committed */
2242
2229
        bool    all)    /* in:  TRUE - commit transaction
2244
2231
{
2245
2232
        trx_t*          trx;
2246
2233
 
2247
 
        assert(hton == innodb_hton_ptr);
 
2234
        assert(this == innodb_engine_ptr);
2248
2235
 
2249
2236
        trx = check_trx_exists(session);
2250
2237
 
2260
2247
        1. ::external_lock(),
2261
2248
        2. ::start_stmt(),
2262
2249
        3. innobase_query_caching_of_table_permitted(),
2263
 
        4. innobase_savepoint(),
 
2250
        4. InnobaseEngine::savepoint_set(),
2264
2251
        5. ::init_table_handle_for_HANDLER(),
2265
 
        6. innobase_start_trx_and_assign_read_view(),
 
2252
        6. InnobaseEngine::start_consistent_snapshot(),
2266
2253
        7. ::transactional_table_lock()
2267
2254
 
2268
2255
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
2355
2342
 
2356
2343
/*********************************************************************
2357
2344
Rolls back a transaction or the latest SQL statement. */
2358
 
static
2359
2345
int
2360
 
innobase_rollback(
 
2346
InnobaseEngine::rollback(
2361
2347
/*==============*/
2362
2348
                        /* out: 0 or error number */
2363
 
        handlerton *hton, /* in: Innodb handlerton */ 
2364
2349
        Session*        session,        /* in: handle to the MySQL thread of the user
2365
2350
                        whose transaction should be rolled back */
2366
2351
        bool    all)    /* in:  TRUE - commit transaction
2369
2354
        int     error = 0;
2370
2355
        trx_t*  trx;
2371
2356
 
2372
 
        assert(hton == innodb_hton_ptr);
 
2357
        assert(this == innodb_engine_ptr);
2373
2358
 
2374
2359
        trx = check_trx_exists(session);
2375
2360
 
2427
2412
 
2428
2413
/*********************************************************************
2429
2414
Rolls back a transaction to a savepoint. */
2430
 
static
2431
2415
int
2432
 
innobase_rollback_to_savepoint(
 
2416
InnobaseEngine::savepoint_rollback(
2433
2417
/*===========================*/
2434
2418
                                /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
2435
2419
                                no savepoint with the given name */
2436
 
        handlerton *hton,       /* in: Innodb handlerton */ 
2437
2420
        Session*        session,                /* in: handle to the MySQL thread of the user
2438
2421
                                whose transaction should be rolled back */
2439
2422
        void*   savepoint)      /* in: savepoint data */
2441
2424
        ib_int64_t      mysql_binlog_cache_pos;
2442
2425
        int             error = 0;
2443
2426
        trx_t*          trx;
2444
 
        char            name[64];
 
2427
        char            sp_name[64];
2445
2428
 
2446
 
        assert(hton == innodb_hton_ptr);
 
2429
        assert(this == innodb_engine_ptr);
2447
2430
 
2448
2431
        trx = check_trx_exists(session);
2449
2432
 
2455
2438
 
2456
2439
        /* TODO: use provided savepoint data area to store savepoint data */
2457
2440
 
2458
 
        int64_t2str((ulint)savepoint, name, 36);
 
2441
        int64_t2str((ulint)savepoint, sp_name, 36);
2459
2442
 
2460
 
        error = (int) trx_rollback_to_savepoint_for_mysql(trx, name,
 
2443
        error = (int) trx_rollback_to_savepoint_for_mysql(trx, sp_name,
2461
2444
                                                &mysql_binlog_cache_pos);
2462
2445
        return(convert_error_code_to_mysql(error, 0, NULL));
2463
2446
}
2464
2447
 
2465
2448
/*********************************************************************
2466
2449
Release transaction savepoint name. */
2467
 
static
2468
2450
int
2469
 
innobase_release_savepoint(
 
2451
InnobaseEngine::savepoint_release(
2470
2452
/*=======================*/
2471
2453
                                /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
2472
2454
                                no savepoint with the given name */
2473
 
        handlerton*     hton,   /* in: handlerton for Innodb */
2474
2455
        Session*        session,                /* in: handle to the MySQL thread of the user
2475
2456
                                whose transaction should be rolled back */
2476
2457
        void*   savepoint)      /* in: savepoint data */
2477
2458
{
2478
2459
        int             error = 0;
2479
2460
        trx_t*          trx;
2480
 
        char            name[64];
 
2461
        char            sp_name[64];
2481
2462
 
2482
 
        assert(hton == innodb_hton_ptr);
 
2463
        assert(this == innodb_engine_ptr);
2483
2464
 
2484
2465
        trx = check_trx_exists(session);
2485
2466
 
2486
2467
        /* TODO: use provided savepoint data area to store savepoint data */
2487
2468
 
2488
 
        int64_t2str((ulint)savepoint, name, 36);
 
2469
        int64_t2str((ulint)savepoint, sp_name, 36);
2489
2470
 
2490
 
        error = (int) trx_release_savepoint_for_mysql(trx, name);
 
2471
        error = (int) trx_release_savepoint_for_mysql(trx, sp_name);
2491
2472
 
2492
2473
        return(convert_error_code_to_mysql(error, 0, NULL));
2493
2474
}
2494
2475
 
2495
2476
/*********************************************************************
2496
2477
Sets a transaction savepoint. */
2497
 
static
2498
2478
int
2499
 
innobase_savepoint(
 
2479
InnobaseEngine::savepoint_set(
2500
2480
/*===============*/
2501
2481
                                /* out: always 0, that is, always succeeds */
2502
 
        handlerton*     hton,   /* in: handle to the Innodb handlerton */
2503
2482
        Session*        session,                /* in: handle to the MySQL thread */
2504
2483
        void*   savepoint)      /* in: savepoint data */
2505
2484
{
2506
2485
        int     error = 0;
2507
2486
        trx_t*  trx;
2508
2487
 
2509
 
        assert(hton == innodb_hton_ptr);
 
2488
        assert(this == innodb_engine_ptr);
2510
2489
 
2511
2490
        /*
2512
2491
          In the autocommit mode there is no sense to set a savepoint
2526
2505
        assert(trx->active_trans);
2527
2506
 
2528
2507
        /* TODO: use provided savepoint data area to store savepoint data */
2529
 
        char name[64];
2530
 
        int64_t2str((ulint)savepoint,name,36);
 
2508
        char sp_name[64];
 
2509
        int64_t2str((ulint)savepoint,sp_name,36);
2531
2510
 
2532
 
        error = (int) trx_savepoint_for_mysql(trx, name, (ib_int64_t)0);
 
2511
        error = (int) trx_savepoint_for_mysql(trx, sp_name, (ib_int64_t)0);
2533
2512
 
2534
2513
        return(convert_error_code_to_mysql(error, 0, NULL));
2535
2514
}
2536
2515
 
2537
2516
/*********************************************************************
2538
2517
Frees a possible InnoDB trx object associated with the current Session. */
2539
 
static
2540
2518
int
2541
 
innobase_close_connection(
 
2519
InnobaseEngine::close_connection(
2542
2520
/*======================*/
2543
2521
                        /* out: 0 or error number */
2544
 
        handlerton*     hton,   /* in:  innobase handlerton */
2545
2522
        Session*        session)        /* in: handle to the MySQL thread of the user
2546
2523
                        whose resources should be free'd */
2547
2524
{
2548
2525
        trx_t*  trx;
2549
2526
 
2550
 
        assert(hton == innodb_hton_ptr);
 
2527
        assert(this == innodb_engine_ptr);
2551
2528
        trx = session_to_trx(session);
2552
2529
 
2553
2530
        ut_a(trx);
2650
2627
/*===========================*/
2651
2628
                                /* out: table type */
2652
2629
{
2653
 
        return(innobase_hton_name);
 
2630
        return(innobase_engine_name);
2654
2631
}
2655
2632
 
2656
2633
UNIV_INTERN
2835
2812
        holding btr_search_latch. This breaks the latching order as
2836
2813
        we acquire dict_sys->mutex below and leads to a deadlock. */
2837
2814
        if (session != NULL) {
2838
 
                innobase_release_temporary_latches(ht, session);
 
2815
                engine->release_temporary_latches(session);
2839
2816
        }
2840
2817
 
2841
2818
        normalize_table_name(norm_name, name);
3051
3028
 
3052
3029
        session = ha_session();
3053
3030
        if (session != NULL) {
3054
 
                innobase_release_temporary_latches(ht, session);
 
3031
                engine->release_temporary_latches(session);
3055
3032
        }
3056
3033
 
3057
3034
        row_prebuilt_free(prebuilt, FALSE);
4063
4040
                        no need to re-acquire locks on it. */
4064
4041
 
4065
4042
                        /* Altering to InnoDB format */
4066
 
                        innobase_commit(ht, user_session, 1);
 
4043
                        engine->commit(user_session, 1);
4067
4044
                        /* Note that this transaction is still active. */
4068
4045
                        prebuilt->trx->active_trans = 1;
4069
4046
                        /* We will need an IX lock on the destination table. */
4079
4056
 
4080
4057
                        /* Commit the transaction.  This will release the table
4081
4058
                        locks, so they have to be acquired again. */
4082
 
                        innobase_commit(ht, user_session, 1);
 
4059
                        engine->commit(user_session, 1);
4083
4060
                        /* Note that this transaction is still active. */
4084
4061
                        prebuilt->trx->active_trans = 1;
4085
4062
                        /* Re-acquire the table lock on the source table. */
6266
6243
 
6267
6244
/*********************************************************************
6268
6245
Removes all tables in the named database inside InnoDB. */
6269
 
static
6270
6246
void
6271
 
innobase_drop_database(
 
6247
InnobaseEngine::drop_database(
6272
6248
/*===================*/
6273
6249
                        /* out: error number */
6274
 
        handlerton *hton, /* in: handlerton of Innodb */
6275
6250
        char*   path)   /* in: database path; inside InnoDB the name
6276
6251
                        of the last directory in the path is used as
6277
6252
                        the database name: for example, in 'mysql/data/test'
6287
6262
        /* Get the transaction associated with the current session, or create one
6288
6263
        if not yet created */
6289
6264
 
6290
 
        assert(hton == innodb_hton_ptr);
 
6265
        assert(this == innodb_engine_ptr);
6291
6266
 
6292
6267
        /* In the Windows plugin, session = current_session is always NULL */
6293
6268
        if (session) {
7476
7451
        /* Set the MySQL flag to mark that there is an active transaction */
7477
7452
        if (trx->active_trans == 0) {
7478
7453
 
7479
 
                innobase_register_trx_and_stmt(ht, session);
 
7454
                innobase_register_trx_and_stmt(engine, session);
7480
7455
                trx->active_trans = 1;
7481
7456
        } else {
7482
 
                innobase_register_stmt(ht, session);
 
7457
                innobase_register_stmt(engine, session);
7483
7458
        }
7484
7459
 
7485
7460
        return(0);
7548
7523
                transaction */
7549
7524
                if (trx->active_trans == 0) {
7550
7525
 
7551
 
                        innobase_register_trx_and_stmt(ht, session);
 
7526
                        innobase_register_trx_and_stmt(engine, session);
7552
7527
                        trx->active_trans = 1;
7553
7528
                } else if (trx->n_mysql_tables_in_use == 0) {
7554
 
                        innobase_register_stmt(ht, session);
 
7529
                        innobase_register_stmt(engine, session);
7555
7530
                }
7556
7531
 
7557
7532
                if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7629
7604
 
7630
7605
                if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7631
7606
                        if (trx->active_trans != 0) {
7632
 
                                innobase_commit(ht, session, TRUE);
 
7607
                                engine->commit(session, TRUE);
7633
7608
                        }
7634
7609
                } else {
7635
7610
                        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7709
7684
        /* Set the MySQL flag to mark that there is an active transaction */
7710
7685
        if (trx->active_trans == 0) {
7711
7686
 
7712
 
                innobase_register_trx_and_stmt(ht, session);
 
7687
                innobase_register_trx_and_stmt(engine, session);
7713
7688
                trx->active_trans = 1;
7714
7689
        }
7715
7690
 
7758
7733
bool
7759
7734
innodb_show_status(
7760
7735
/*===============*/
7761
 
        handlerton*     hton,   /* in: the innodb handlerton */
 
7736
        StorageEngine*  engine, /* in: the innodb StorageEngine */
7762
7737
        Session*        session,        /* in: the MySQL query thread of the caller */
7763
7738
        stat_print_fn *stat_print)
7764
7739
{
7768
7743
        ulint                   trx_list_start = ULINT_UNDEFINED;
7769
7744
        ulint                   trx_list_end = ULINT_UNDEFINED;
7770
7745
 
7771
 
        assert(hton == innodb_hton_ptr);
 
7746
        assert(engine == innodb_engine_ptr);
7772
7747
 
7773
7748
        trx = check_trx_exists(session);
7774
7749
 
7830
7805
 
7831
7806
        bool result = FALSE;
7832
7807
 
7833
 
        if (stat_print(session, innobase_hton_name, strlen(innobase_hton_name),
 
7808
        if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
7834
7809
                        STRING_WITH_LEN(""), str, flen)) {
7835
7810
                result= TRUE;
7836
7811
        }
7845
7820
bool
7846
7821
innodb_mutex_show_status(
7847
7822
/*=====================*/
7848
 
        handlerton*     hton,   /* in: the innodb handlerton */
 
7823
        StorageEngine*  engine,
7849
7824
        Session*        session,                /* in: the MySQL query thread of the
7850
7825
                                        caller */
7851
7826
        stat_print_fn*  stat_print)
7861
7836
        ulint     rw_lock_count_os_yield= 0;
7862
7837
        uint64_t rw_lock_wait_time= 0;
7863
7838
#endif /* UNIV_DEBUG */
7864
 
        uint      hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
7865
 
        assert(hton == innodb_hton_ptr);
 
7839
        uint      engine_name_len= strlen(innobase_engine_name), buf1len, buf2len;
 
7840
        assert(engine == innodb_engine_ptr);
7866
7841
 
7867
7842
        mutex_enter(&mutex_list_mutex);
7868
7843
 
7887
7862
                                        mutex->count_os_yield,
7888
7863
                                        (ulong) (mutex->lspent_time/1000));
7889
7864
 
7890
 
                                if (stat_print(session, innobase_hton_name,
7891
 
                                                hton_name_len, buf1, buf1len,
 
7865
                                if (stat_print(session, innobase_engine_name,
 
7866
                                                engine_name_len, buf1, buf1len,
7892
7867
                                                buf2, buf2len)) {
7893
7868
                                        mutex_exit(&mutex_list_mutex);
7894
7869
                                        return(1);
7909
7884
                buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
7910
7885
                                  mutex->count_os_wait);
7911
7886
 
7912
 
                if (stat_print(session, innobase_hton_name,
7913
 
                               hton_name_len, buf1, buf1len,
 
7887
                if (stat_print(session, innobase_engine_name,
 
7888
                               engine_name_len, buf1, buf1len,
7914
7889
                               buf2, buf2len)) {
7915
7890
                        mutex_exit(&mutex_list_mutex);
7916
7891
                        return(1);
7933
7908
                        buf2len= snprintf(buf2, sizeof(buf2),
7934
7909
                                    "os_waits=%lu", lock->count_os_wait);
7935
7910
 
7936
 
                        if (stat_print(session, innobase_hton_name,
7937
 
                                       hton_name_len, buf1, buf1len,
 
7911
                        if (stat_print(session, innobase_engine_name,
 
7912
                                       engine_name_len, buf1, buf1len,
7938
7913
                                       buf2, buf2len)) {
7939
7914
                                mutex_exit(&rw_lock_list_mutex);
7940
7915
                                return(1);
7954
7929
                rw_lock_count_os_wait, rw_lock_count_os_yield,
7955
7930
                (ulong) (rw_lock_wait_time/1000));
7956
7931
 
7957
 
        if (stat_print(session, innobase_hton_name, hton_name_len,
 
7932
        if (stat_print(session, innobase_engine_name, engine_name_len,
7958
7933
                        STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
7959
7934
                return(1);
7960
7935
        }
7963
7938
        return(FALSE);
7964
7939
}
7965
7940
 
7966
 
static
7967
 
bool innobase_show_status(handlerton *hton, Session* session, 
7968
 
                          stat_print_fn* stat_print,
7969
 
                          enum ha_stat_type stat_type)
 
7941
bool InnobaseEngine::show_status(Session* session, 
 
7942
                                 stat_print_fn* stat_print,
 
7943
                                 enum ha_stat_type stat_type)
7970
7944
{
7971
 
        assert(hton == innodb_hton_ptr);
 
7945
        assert(this == innodb_engine_ptr);
7972
7946
 
7973
7947
        switch (stat_type) {
7974
7948
        case HA_ENGINE_STATUS:
7975
 
                return innodb_show_status(hton, session, stat_print);
 
7949
                return innodb_show_status(this, session, stat_print);
7976
7950
        case HA_ENGINE_MUTEX:
7977
 
                return innodb_mutex_show_status(hton, session, stat_print);
 
7951
                return innodb_mutex_show_status(this, session, stat_print);
7978
7952
        default:
7979
7953
                return(FALSE);
7980
7954
        }
8655
8629
 
8656
8630
/***********************************************************************
8657
8631
This function is used to prepare X/Open XA distributed transaction   */
8658
 
static
8659
8632
int
8660
 
innobase_xa_prepare(
 
8633
InnobaseEngine::prepare(
8661
8634
/*================*/
8662
8635
                        /* out: 0 or error number */
8663
 
        handlerton      *hton,
8664
8636
        Session*        session,        /* in: handle to the MySQL thread of the user
8665
8637
                        whose XA transaction should be prepared */
8666
8638
        bool    all)    /* in: TRUE - commit transaction
8669
8641
        int error = 0;
8670
8642
        trx_t* trx = check_trx_exists(session);
8671
8643
 
8672
 
        assert(hton == innodb_hton_ptr);
 
8644
        assert(this == innodb_engine_ptr);
8673
8645
 
8674
8646
        if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
8675
8647
        {
8755
8727
 
8756
8728
/***********************************************************************
8757
8729
This function is used to recover X/Open XA distributed transactions   */
8758
 
static
8759
8730
int
8760
 
innobase_xa_recover(
 
8731
InnobaseEngine::recover(
8761
8732
/*================*/
8762
8733
                                /* out: number of prepared transactions
8763
8734
                                stored in xid_list */
8764
 
        handlerton *hton,
8765
8735
        XID*    xid_list,       /* in/out: prepared transactions */
8766
8736
        uint    len)            /* in: number of slots in xid_list */
8767
8737
{
8768
 
        assert(hton == innodb_hton_ptr);
 
8738
        assert(this == innodb_engine_ptr);
8769
8739
 
8770
8740
        if (len == 0 || xid_list == NULL) {
8771
8741
 
8778
8748
/***********************************************************************
8779
8749
This function is used to commit one X/Open XA distributed transaction
8780
8750
which is in the prepared state */
8781
 
static
8782
8751
int
8783
 
innobase_commit_by_xid(
 
8752
InnobaseEngine::commit_by_xid(
8784
8753
/*===================*/
8785
8754
                        /* out: 0 or error number */
8786
 
        handlerton *hton,
8787
8755
        XID*    xid)    /* in: X/Open XA transaction identification */
8788
8756
{
8789
8757
        trx_t*  trx;
8790
8758
 
8791
 
        assert(hton == innodb_hton_ptr);
 
8759
        assert(this == innodb_engine_ptr);
8792
8760
 
8793
8761
        trx = trx_get_trx_by_xid(xid);
8794
8762
 
8804
8772
/***********************************************************************
8805
8773
This function is used to rollback one X/Open XA distributed transaction
8806
8774
which is in the prepared state */
8807
 
static
8808
8775
int
8809
 
innobase_rollback_by_xid(
 
8776
InnobaseEngine::rollback_by_xid(
8810
8777
/*=====================*/
8811
8778
                        /* out: 0 or error number */
8812
 
        handlerton *hton,
8813
8779
        XID     *xid)   /* in: X/Open XA transaction identification */
8814
8780
{
8815
8781
        trx_t*  trx;
8816
8782
 
8817
 
        assert(hton == innodb_hton_ptr);
 
8783
        assert(this == innodb_engine_ptr);
8818
8784
 
8819
8785
        trx = trx_get_trx_by_xid(xid);
8820
8786
 
9660
9626
drizzle_declare_plugin(innobase)
9661
9627
{
9662
9628
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
9663
 
  innobase_hton_name,
 
9629
  innobase_engine_name,
9664
9630
  "1.0.1",
9665
9631
  "Innobase Oy",
9666
9632
  "Supports transactions, row-level locking, and foreign keys",