1
/* Copyright (C) 2000-2005 MySQL AB & Innobase Oy
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* TODO list for the InnoDB handler in 5.0:
17
- Remove the flag trx->active_trans and look at trx->conc_state
18
- fix savepoint functions to use savepoint storage area
19
- Find out what kind of problems the OS X case-insensitivity causes to
20
table and database names; should we 'normalize' the names like we do
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation // gcc: Class implementation
28
#include <mysql_priv.h>
29
#include <mysqld_error.h>
33
#include <myisampack.h>
34
#include <mysys_err.h>
36
#include <mysql/plugin.h>
38
/* Include necessary InnoDB headers */
40
#include "../storage/innobase/include/univ.i"
41
#include "../storage/innobase/include/btr0sea.h"
42
#include "../storage/innobase/include/os0file.h"
43
#include "../storage/innobase/include/os0thread.h"
44
#include "../storage/innobase/include/srv0start.h"
45
#include "../storage/innobase/include/srv0srv.h"
46
#include "../storage/innobase/include/trx0roll.h"
47
#include "../storage/innobase/include/trx0trx.h"
48
#include "../storage/innobase/include/trx0sys.h"
49
#include "../storage/innobase/include/mtr0mtr.h"
50
#include "../storage/innobase/include/row0ins.h"
51
#include "../storage/innobase/include/row0mysql.h"
52
#include "../storage/innobase/include/row0sel.h"
53
#include "../storage/innobase/include/row0upd.h"
54
#include "../storage/innobase/include/log0log.h"
55
#include "../storage/innobase/include/lock0lock.h"
56
#include "../storage/innobase/include/dict0crea.h"
57
#include "../storage/innobase/include/btr0cur.h"
58
#include "../storage/innobase/include/btr0btr.h"
59
#include "../storage/innobase/include/fsp0fsp.h"
60
#include "../storage/innobase/include/sync0sync.h"
61
#include "../storage/innobase/include/fil0fil.h"
62
#include "../storage/innobase/include/trx0xa.h"
63
#include "../storage/innobase/include/row0merge.h"
64
#include "../storage/innobase/include/thr0loc.h"
65
#include "../storage/innobase/include/dict0boot.h"
66
#include "../storage/innobase/include/ha_prototypes.h"
67
#include "../storage/innobase/include/ut0mem.h"
70
#include "ha_innodb.h"
74
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
75
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
76
extern pthread_mutex_t LOCK_thread_count;
78
#if MYSQL_VERSION_ID < 50124
79
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
80
but we need it here */
81
bool check_global_access(THD *thd, ulong want_access);
82
#endif /* MYSQL_VERSION_ID < 50124 */
83
#endif /* MYSQL_SERVER */
85
/** to protect innobase_open_files */
86
static pthread_mutex_t innobase_share_mutex;
87
/** to force correct commit order in binlog */
88
static pthread_mutex_t prepare_commit_mutex;
89
static ulong commit_threads = 0;
90
static pthread_mutex_t commit_threads_m;
91
static pthread_cond_t commit_cond;
92
static pthread_mutex_t commit_cond_m;
93
static bool innodb_inited = 0;
95
#define INSIDE_HA_INNOBASE_CC
97
#ifdef MYSQL_DYNAMIC_PLUGIN
98
/* These must be weak global variables in the dynamic plugin. */
99
struct handlerton* innodb_hton_ptr;
100
int builtin_innobase_plugin;
101
/********************************************************************
102
Copy InnoDB system variables from the static InnoDB to the dynamic
106
innodb_plugin_init(void);
107
/*====================*/
108
/* out: TRUE if the dynamic InnoDB plugin should start */
109
#else /* MYSQL_DYNAMIC_PLUGIN */
110
/* This must be a global variable in the statically linked InnoDB. */
111
struct handlerton* innodb_hton_ptr = NULL;
112
#endif /* MYSQL_DYNAMIC_PLUGIN */
114
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
115
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
116
static const long AUTOINC_NO_LOCKING = 2;
118
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
119
innobase_log_buffer_size,
120
innobase_additional_mem_pool_size, innobase_file_io_threads,
121
innobase_lock_wait_timeout, innobase_force_recovery,
122
innobase_open_files, innobase_autoinc_lock_mode;
124
static long long innobase_buffer_pool_size, innobase_log_file_size;
126
/* The default values for the following char* start-up parameters
127
are determined in innobase_init below: */
129
static char* innobase_data_home_dir = NULL;
130
static char* innobase_data_file_path = NULL;
131
static char* innobase_log_group_home_dir = NULL;
132
static char* innobase_file_format_name = NULL;
134
/* Note: This variable can be set to on/off and any of the supported
135
file formats in the configuration file, but can only be set to any
136
of the supported file formats during runtime. */
137
static char* innobase_file_format_check = NULL;
139
/* The following has a misleading name: starting from 4.0.5, this also
141
static char* innobase_unix_file_flush_method = NULL;
143
/* Below we have boolean-valued start-up parameters, and their default
146
static ulong innobase_fast_shutdown = 1;
147
#ifdef UNIV_LOG_ARCHIVE
148
static my_bool innobase_log_archive = FALSE;
149
static char* innobase_log_arch_dir = NULL;
150
#endif /* UNIV_LOG_ARCHIVE */
151
static my_bool innobase_use_doublewrite = TRUE;
152
static my_bool innobase_use_checksums = TRUE;
153
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
154
static my_bool innobase_rollback_on_timeout = FALSE;
155
static my_bool innobase_create_status_file = FALSE;
156
static my_bool innobase_stats_on_metadata = TRUE;
157
static my_bool innobase_adaptive_hash_index = TRUE;
159
static char* internal_innobase_data_file_path = NULL;
161
static char* innodb_version_str = (char*) INNODB_VERSION_STR;
163
/* The following counter is used to convey information to InnoDB
164
about server activity: in selects it is not sensible to call
165
srv_active_wake_master_thread after each fetch or search, we only do
166
it every INNOBASE_WAKE_INTERVAL'th step. */
168
#define INNOBASE_WAKE_INTERVAL 32
169
static ulong innobase_active_counter = 0;
171
static HASH innobase_open_tables;
173
#ifdef __NETWARE__ /* some special cleanup for NetWare */
174
bool nw_panic = FALSE;
177
static uchar* innobase_get_key(INNOBASE_SHARE *share, size_t *length,
178
my_bool not_used __attribute__((unused)));
179
static INNOBASE_SHARE *get_share(const char *table_name);
180
static void free_share(INNOBASE_SHARE *share);
181
static int innobase_close_connection(handlerton *hton, THD* thd);
182
static int innobase_commit(handlerton *hton, THD* thd, bool all);
183
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
184
static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
186
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
187
static int innobase_release_savepoint(handlerton *hton, THD* thd,
189
static handler *innobase_create_handler(handlerton *hton,
193
/****************************************************************
194
Validate the file format name and return its corresponding id. */
197
innobase_file_format_name_lookup(
198
/*=============================*/
199
/* out: valid file format id */
200
const char* format_name); /* in: pointer to file format
202
/****************************************************************
203
Validate the file format check config parameters, as a side affect it
204
sets the srv_check_file_format_at_startup variable. */
207
innobase_file_format_check_on_off(
208
/*==============================*/
209
/* out: true if one of
211
const char* format_check); /* in: parameter value */
212
/****************************************************************
213
Validate the file format check config parameters, as a side affect it
214
sets the srv_check_file_format_at_startup variable. */
217
innobase_file_format_check_validate(
218
/*================================*/
219
/* out: true if valid
221
const char* format_check); /* in: parameter value */
222
/*****************************************************************
223
Check if it is a valid file format. This function is registered as
224
a callback with MySQL. */
227
innodb_file_format_name_validate(
228
/*=============================*/
229
/* out: 0 for valid file
231
THD* thd, /* in: thread handle */
232
struct st_mysql_sys_var* var, /* in: pointer to system
234
void* save, /* out: immediate result
235
for update function */
236
struct st_mysql_value* value); /* in: incoming string */
237
/********************************************************************
238
Update the system variable innodb_file_format using the "saved"
239
value. This function is registered as a callback with MySQL. */
242
innodb_file_format_name_update(
243
/*===========================*/
247
THD* thd, /* in: thread handle */
248
struct st_mysql_sys_var* var, /* in: pointer to
250
void* var_ptr,/* out: where the
251
formal string goes */
252
void* save); /* in: immediate result
253
from check function */
254
/*****************************************************************
255
Check if it is a valid file format. This function is registered as
256
a callback with MySQL. */
259
innodb_file_format_check_validate(
260
/*==============================*/
261
/* out: 0 for valid file
263
THD* thd, /* in: thread handle */
264
struct st_mysql_sys_var* var, /* in: pointer to system
266
void* save, /* out: immediate result
267
for update function */
268
struct st_mysql_value* value); /* in: incoming string */
269
/********************************************************************
270
Update the system variable innodb_file_format_check using the "saved"
271
value. This function is registered as a callback with MySQL. */
274
innodb_file_format_check_update(
275
/*============================*/
279
THD* thd, /* in: thread handle */
280
struct st_mysql_sys_var* var, /* in: pointer to
282
void* var_ptr,/* out: where the
283
formal string goes */
284
void* save); /* in: immediate result
285
from check function */
287
/********************************************************************
288
Return alter table flags supported in an InnoDB database. */
291
innobase_alter_table_flags(
292
/*=======================*/
295
static const char innobase_hton_name[]= "InnoDB";
297
static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
298
"Enable InnoDB support for the XA two-phase commit",
299
/* check_func */ NULL, /* update_func */ NULL,
302
static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
303
"Enable InnoDB locking in LOCK TABLES",
304
/* check_func */ NULL, /* update_func */ NULL,
307
static MYSQL_THDVAR_BOOL(strict_mode,
309
"Use strict mode when evaluating create options.",
313
static handler *innobase_create_handler(handlerton *hton,
317
return new (mem_root) ha_innobase(hton, table);
320
/***********************************************************************
321
This function is used to prepare X/Open XA distributed transaction */
326
/* out: 0 or error number */
328
THD* thd, /* in: handle to the MySQL thread of the user
329
whose XA transaction should be prepared */
330
bool all); /* in: TRUE - commit transaction
331
FALSE - the current SQL statement ended */
332
/***********************************************************************
333
This function is used to recover X/Open XA distributed transactions */
338
/* out: number of prepared transactions
339
stored in xid_list */
341
XID* xid_list, /* in/out: prepared transactions */
342
uint len); /* in: number of slots in xid_list */
343
/***********************************************************************
344
This function is used to commit one X/Open XA distributed transaction
345
which is in the prepared state */
348
innobase_commit_by_xid(
349
/*===================*/
350
/* out: 0 or error number */
352
XID* xid); /* in: X/Open XA transaction identification */
353
/***********************************************************************
354
This function is used to rollback one X/Open XA distributed transaction
355
which is in the prepared state */
358
innobase_rollback_by_xid(
359
/*=====================*/
360
/* out: 0 or error number */
362
XID *xid); /* in: X/Open XA transaction identification */
363
/***********************************************************************
364
Create a consistent view for a cursor based on current transaction
365
which is created if the corresponding MySQL thread still lacks one.
366
This consistent view is then used inside of MySQL when accessing records
370
innobase_create_cursor_view(
371
/*========================*/
372
/* out: pointer to cursor view or NULL */
373
handlerton* hton, /* in: innobase hton */
374
THD* thd); /* in: user thread handle */
375
/***********************************************************************
376
Set the given consistent cursor view to a transaction which is created
377
if the corresponding MySQL thread still lacks one. If the given
378
consistent cursor view is NULL global read view of a transaction is
379
restored to a transaction read view. */
382
innobase_set_cursor_view(
383
/*=====================*/
385
THD* thd, /* in: user thread handle */
386
void* curview);/* in: Consistent cursor view to be set */
387
/***********************************************************************
388
Close the given consistent cursor view of a transaction and restore
389
global read view to a transaction read view. Transaction is created if the
390
corresponding MySQL thread still lacks one. */
393
innobase_close_cursor_view(
394
/*=======================*/
396
THD* thd, /* in: user thread handle */
397
void* curview);/* in: Consistent read view to be closed */
398
/*********************************************************************
399
Removes all tables in the named database inside InnoDB. */
402
innobase_drop_database(
403
/*===================*/
404
/* out: error number */
405
handlerton* hton, /* in: handlerton of Innodb */
406
char* path); /* in: database path; inside InnoDB the name
407
of the last directory in the path is used as
408
the database name: for example, in 'mysql/data/test'
409
the database name is 'test' */
410
/***********************************************************************
411
Closes an InnoDB database. */
414
innobase_end(handlerton *hton, ha_panic_function type);
416
/*********************************************************************
417
Creates an InnoDB transaction struct for the thd if it does not yet have one.
418
Starts a new InnoDB transaction if a transaction is not yet started. And
419
assigns a new snapshot for a consistent read if the transaction does not yet
423
innobase_start_trx_and_assign_read_view(
424
/*====================================*/
426
handlerton* hton, /* in: Innodb handlerton */
427
THD* thd); /* in: MySQL thread handle of the user for whom
428
the transaction should be committed */
429
/********************************************************************
430
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
431
the logs, and the name of this function should be innobase_checkpoint. */
436
/* out: TRUE if error */
437
handlerton* hton); /* in: InnoDB handlerton */
439
/****************************************************************************
440
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
441
Monitor to the client. */
446
handlerton* hton, /* in: the innodb handlerton */
447
THD* thd, /* in: the MySQL query thread of the caller */
448
stat_print_fn *stat_print);
450
bool innobase_show_status(handlerton *hton, THD* thd,
451
stat_print_fn* stat_print,
452
enum ha_stat_type stat_type);
454
/*********************************************************************
455
Commits a transaction in an InnoDB database. */
460
trx_t* trx); /* in: transaction handle */
462
static SHOW_VAR innodb_status_variables[]= {
463
{"buffer_pool_pages_data",
464
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
465
{"buffer_pool_pages_dirty",
466
(char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
467
{"buffer_pool_pages_flushed",
468
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
469
{"buffer_pool_pages_free",
470
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
471
{"buffer_pool_pages_latched",
472
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
473
{"buffer_pool_pages_misc",
474
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
475
{"buffer_pool_pages_total",
476
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
477
{"buffer_pool_read_ahead_rnd",
478
(char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
479
{"buffer_pool_read_ahead_seq",
480
(char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
481
{"buffer_pool_read_requests",
482
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
483
{"buffer_pool_reads",
484
(char*) &export_vars.innodb_buffer_pool_reads, SHOW_LONG},
485
{"buffer_pool_wait_free",
486
(char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG},
487
{"buffer_pool_write_requests",
488
(char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG},
490
(char*) &export_vars.innodb_data_fsyncs, SHOW_LONG},
491
{"data_pending_fsyncs",
492
(char*) &export_vars.innodb_data_pending_fsyncs, SHOW_LONG},
493
{"data_pending_reads",
494
(char*) &export_vars.innodb_data_pending_reads, SHOW_LONG},
495
{"data_pending_writes",
496
(char*) &export_vars.innodb_data_pending_writes, SHOW_LONG},
498
(char*) &export_vars.innodb_data_read, SHOW_LONG},
500
(char*) &export_vars.innodb_data_reads, SHOW_LONG},
502
(char*) &export_vars.innodb_data_writes, SHOW_LONG},
504
(char*) &export_vars.innodb_data_written, SHOW_LONG},
505
{"dblwr_pages_written",
506
(char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
508
(char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
510
(char*) &export_vars.innodb_log_waits, SHOW_LONG},
511
{"log_write_requests",
512
(char*) &export_vars.innodb_log_write_requests, SHOW_LONG},
514
(char*) &export_vars.innodb_log_writes, SHOW_LONG},
516
(char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG},
517
{"os_log_pending_fsyncs",
518
(char*) &export_vars.innodb_os_log_pending_fsyncs, SHOW_LONG},
519
{"os_log_pending_writes",
520
(char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG},
522
(char*) &export_vars.innodb_os_log_written, SHOW_LONG},
524
(char*) &export_vars.innodb_page_size, SHOW_LONG},
526
(char*) &export_vars.innodb_pages_created, SHOW_LONG},
528
(char*) &export_vars.innodb_pages_read, SHOW_LONG},
530
(char*) &export_vars.innodb_pages_written, SHOW_LONG},
531
{"row_lock_current_waits",
532
(char*) &export_vars.innodb_row_lock_current_waits, SHOW_LONG},
534
(char*) &export_vars.innodb_row_lock_time, SHOW_LONGLONG},
535
{"row_lock_time_avg",
536
(char*) &export_vars.innodb_row_lock_time_avg, SHOW_LONG},
537
{"row_lock_time_max",
538
(char*) &export_vars.innodb_row_lock_time_max, SHOW_LONG},
540
(char*) &export_vars.innodb_row_lock_waits, SHOW_LONG},
542
(char*) &export_vars.innodb_rows_deleted, SHOW_LONG},
544
(char*) &export_vars.innodb_rows_inserted, SHOW_LONG},
546
(char*) &export_vars.innodb_rows_read, SHOW_LONG},
548
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
549
{NullS, NullS, SHOW_LONG}
552
/* General functions */
554
/**********************************************************************
555
Returns true if the thread is the replication thread on the slave
556
server. Used in srv_conc_enter_innodb() to determine if the thread
557
should be allowed to enter InnoDB - the replication thread is treated
558
differently than other threads. Also used in
559
srv_conc_force_exit_innodb(). */
560
extern "C" UNIV_INTERN
562
thd_is_replication_slave_thread(
563
/*============================*/
564
/* out: true if thd is the replication thread */
565
void* thd) /* in: thread handle (THD*) */
567
return((ibool) thd_slave_thread((THD*) thd));
570
/**********************************************************************
571
Save some CPU by testing the value of srv_thread_concurrency in inline
575
innodb_srv_conc_enter_innodb(
576
/*=========================*/
577
trx_t* trx) /* in: transaction handle */
579
if (UNIV_LIKELY(!srv_thread_concurrency)) {
584
srv_conc_enter_innodb(trx);
587
/**********************************************************************
588
Save some CPU by testing the value of srv_thread_concurrency in inline
592
innodb_srv_conc_exit_innodb(
593
/*========================*/
594
trx_t* trx) /* in: transaction handle */
596
if (UNIV_LIKELY(!srv_thread_concurrency)) {
601
srv_conc_exit_innodb(trx);
604
/**********************************************************************
605
Releases possible search latch and InnoDB thread FIFO ticket. These should
606
be released at each SQL statement end, and also when mysqld passes the
607
control to the client. It does no harm to release these also in the middle
608
of an SQL statement. */
611
innobase_release_stat_resources(
612
/*============================*/
613
trx_t* trx) /* in: transaction object */
615
if (trx->has_search_latch) {
616
trx_search_latch_release_if_reserved(trx);
619
if (trx->declared_to_be_inside_innodb) {
620
/* Release our possible ticket in the FIFO */
622
srv_conc_force_exit_innodb(trx);
626
/**********************************************************************
627
Returns true if the transaction this thread is processing has edited
628
non-transactional tables. Used by the deadlock detector when deciding
629
which transaction to rollback in case of a deadlock - we try to avoid
630
rolling back transactions that have edited non-transactional tables. */
631
extern "C" UNIV_INTERN
633
thd_has_edited_nontrans_tables(
634
/*===========================*/
635
/* out: true if non-transactional tables have
637
void* thd) /* in: thread handle (THD*) */
639
return((ibool) thd_non_transactional_update((THD*) thd));
642
/************************************************************************
643
Obtain the InnoDB transaction of a MySQL thread. */
648
/* out: reference to transaction pointer */
649
THD* thd) /* in: MySQL thread */
651
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
654
/************************************************************************
655
Call this function when mysqld passes control to the client. That is to
656
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
657
documentation, see handler.cc. */
660
innobase_release_temporary_latches(
661
/*===============================*/
663
handlerton* hton, /* in: handlerton */
664
THD* thd) /* in: MySQL thread */
668
DBUG_ASSERT(hton == innodb_hton_ptr);
670
if (!innodb_inited) {
675
trx = thd_to_trx(thd);
678
innobase_release_stat_resources(trx);
683
/************************************************************************
684
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
685
time calls srv_active_wake_master_thread. This function should be used
686
when a single database operation may introduce a small need for
687
server utility activity, like checkpointing. */
690
innobase_active_small(void)
691
/*=======================*/
693
innobase_active_counter++;
695
if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
696
srv_active_wake_master_thread();
700
/************************************************************************
701
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
702
about a possible transaction rollback inside InnoDB caused by a lock wait
703
timeout or a deadlock. */
704
extern "C" UNIV_INTERN
706
convert_error_code_to_mysql(
707
/*========================*/
708
/* out: MySQL error code */
709
int error, /* in: InnoDB error code */
710
ulint flags, /* in: InnoDB table flags, or 0 */
711
THD* thd) /* in: user thread handle or NULL */
719
return(-1); /* unspecified error */
721
case DB_DUPLICATE_KEY:
722
return(HA_ERR_FOUND_DUPP_KEY);
724
case DB_FOREIGN_DUPLICATE_KEY:
725
return(HA_ERR_FOREIGN_DUPLICATE_KEY);
727
case DB_RECORD_NOT_FOUND:
728
return(HA_ERR_NO_ACTIVE_RECORD);
731
/* Since we rolled back the whole transaction, we must
732
tell it also to MySQL so that MySQL knows to empty the
733
cached binlog for this transaction */
736
thd_mark_transaction_to_rollback(thd, TRUE);
739
return(HA_ERR_LOCK_DEADLOCK);
741
case DB_LOCK_WAIT_TIMEOUT:
742
/* Starting from 5.0.13, we let MySQL just roll back the
743
latest SQL statement in a lock wait timeout. Previously, we
744
rolled back the whole transaction. */
747
thd_mark_transaction_to_rollback(
748
thd, (bool)row_rollback_on_timeout);
751
return(HA_ERR_LOCK_WAIT_TIMEOUT);
753
case DB_NO_REFERENCED_ROW:
754
return(HA_ERR_NO_REFERENCED_ROW);
756
case DB_ROW_IS_REFERENCED:
757
return(HA_ERR_ROW_IS_REFERENCED);
759
case DB_CANNOT_ADD_CONSTRAINT:
760
return(HA_ERR_CANNOT_ADD_FOREIGN);
762
case DB_CANNOT_DROP_CONSTRAINT:
764
return(HA_ERR_ROW_IS_REFERENCED); /* TODO: This is a bit
765
misleading, a new MySQL error
766
code should be introduced */
768
case DB_COL_APPEARS_TWICE_IN_INDEX:
770
return(HA_ERR_CRASHED);
772
case DB_OUT_OF_FILE_SPACE:
773
return(HA_ERR_RECORD_FILE_FULL);
775
case DB_TABLE_IS_BEING_USED:
776
return(HA_ERR_WRONG_COMMAND);
778
case DB_TABLE_NOT_FOUND:
779
return(HA_ERR_NO_SUCH_TABLE);
781
case DB_TOO_BIG_RECORD:
782
my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
783
page_get_free_space_of_empty(flags
784
& DICT_TF_COMPACT) / 2);
785
return(HA_ERR_TO_BIG_ROW);
787
case DB_NO_SAVEPOINT:
788
return(HA_ERR_NO_SAVEPOINT);
790
case DB_LOCK_TABLE_FULL:
791
/* Since we rolled back the whole transaction, we must
792
tell it also to MySQL so that MySQL knows to empty the
793
cached binlog for this transaction */
796
thd_mark_transaction_to_rollback(thd, TRUE);
799
return(HA_ERR_LOCK_TABLE_FULL);
801
case DB_PRIMARY_KEY_IS_NULL:
802
return(ER_PRIMARY_CANT_HAVE_NULL);
804
case DB_TOO_MANY_CONCURRENT_TRXS:
805
/* Once MySQL add the appropriate code to errmsg.txt then
806
we can get rid of this #ifdef. NOTE: The code checked by
807
the #ifdef is the suggested name for the error condition
808
and the actual error code name could very well be different.
809
This will require some monitoring, ie. the status
810
of this request on our part.*/
811
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
812
return(ER_TOO_MANY_CONCURRENT_TRXS);
814
return(HA_ERR_RECORD_FILE_FULL);
817
return(HA_ERR_UNSUPPORTED);
821
/*****************************************************************
822
If you want to print a thd that is not associated with the current thread,
823
you must call this function before reserving the InnoDB kernel_mutex, to
824
protect MySQL from setting thd->query NULL. If you print a thd of the current
825
thread, we know that MySQL cannot modify thd->query, and it is not necessary
826
to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
828
extern "C" UNIV_INTERN
830
innobase_mysql_prepare_print_arbitrary_thd(void)
831
/*============================================*/
833
ut_ad(!mutex_own(&kernel_mutex));
834
VOID(pthread_mutex_lock(&LOCK_thread_count));
837
/*****************************************************************
838
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
839
In the InnoDB latching order, the mutex sits right above the
840
kernel_mutex. In debug builds, we assert that the kernel_mutex is
841
released before this function is invoked. */
842
extern "C" UNIV_INTERN
844
innobase_mysql_end_print_arbitrary_thd(void)
845
/*========================================*/
847
ut_ad(!mutex_own(&kernel_mutex));
848
VOID(pthread_mutex_unlock(&LOCK_thread_count));
851
/*****************************************************************
852
Prints info of a THD object (== user session thread) to the given file. */
853
extern "C" UNIV_INTERN
855
innobase_mysql_print_thd(
856
/*=====================*/
857
FILE* f, /* in: output stream */
858
void* thd, /* in: pointer to a MySQL THD object */
859
uint max_query_len) /* in: max query length to print, or 0 to
860
use the default max length */
864
fputs(thd_security_context((THD*) thd, buffer, sizeof buffer,
869
/**********************************************************************
870
Get the variable length bounds of the given character set. */
871
extern "C" UNIV_INTERN
873
innobase_get_cset_width(
874
/*====================*/
875
ulint cset, /* in: MySQL charset-collation code */
876
ulint* mbminlen, /* out: minimum length of a char (in bytes) */
877
ulint* mbmaxlen) /* out: maximum length of a char (in bytes) */
884
cs = all_charsets[cset];
886
*mbminlen = cs->mbminlen;
887
*mbmaxlen = cs->mbmaxlen;
890
*mbminlen = *mbmaxlen = 0;
894
/**********************************************************************
895
Converts an identifier to a table name.
897
NOTE that the exact prototype of this function has to be in
898
/innobase/dict/dict0dict.c! */
899
extern "C" UNIV_INTERN
901
innobase_convert_from_table_id(
902
/*===========================*/
903
char* to, /* out: converted identifier */
904
const char* from, /* in: identifier to convert */
905
ulint len) /* in: length of 'to', in bytes */
909
strconvert(thd_charset(current_thd), from,
910
&my_charset_filename, to, (uint) len, &errors);
913
/**********************************************************************
914
Converts an identifier to UTF-8.
916
NOTE that the exact prototype of this function has to be in
917
/innobase/dict/dict0dict.c! */
918
extern "C" UNIV_INTERN
920
innobase_convert_from_id(
921
/*=====================*/
922
char* to, /* out: converted identifier */
923
const char* from, /* in: identifier to convert */
924
ulint len) /* in: length of 'to', in bytes */
928
strconvert(thd_charset(current_thd), from,
929
system_charset_info, to, (uint) len, &errors);
932
/**********************************************************************
933
Compares NUL-terminated UTF-8 strings case insensitively. */
934
extern "C" UNIV_INTERN
938
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
939
const char* a, /* in: first string to compare */
940
const char* b) /* in: second string to compare */
942
return(my_strcasecmp(system_charset_info, a, b));
945
/**********************************************************************
946
Makes all characters in a NUL-terminated UTF-8 string lower case.
948
NOTE that the exact prototype of this function has to be in
949
/innobase/dict/dict0dict.c! */
950
extern "C" UNIV_INTERN
954
char* a) /* in/out: string to put in lower case */
956
my_casedn_str(system_charset_info, a);
959
/**************************************************************************
960
Determines the connection character set.
962
NOTE that the exact prototype of this function has to be in
963
/innobase/dict/dict0dict.c! */
964
extern "C" UNIV_INTERN
965
struct charset_info_st*
966
innobase_get_charset(
967
/*=================*/
968
/* out: connection character set */
969
void* mysql_thd) /* in: MySQL thread handle */
971
return(thd_charset((THD*) mysql_thd));
974
/*************************************************************************
975
Creates a temporary file. */
976
extern "C" UNIV_INTERN
978
innobase_mysql_tmpfile(void)
979
/*========================*/
980
/* out: temporary file descriptor, or < 0 on error */
983
File fd = mysql_tmpfile("ib");
985
/* Copy the file descriptor, so that the additional resources
986
allocated by create_temp_file() can be freed by invoking
989
Because the file descriptor returned by this function
990
will be passed to fdopen(), it will be closed by invoking
991
fclose(), which in turn will invoke close() instead of
995
DBUG_PRINT("error",("Got error %d on dup",fd2));
997
my_error(EE_OUT_OF_FILERESOURCES,
998
MYF(ME_BELL+ME_WAITTANG),
1001
my_close(fd, MYF(MY_WME));
1006
/*************************************************************************
1007
Wrapper around MySQL's copy_and_convert function, see it for
1009
extern "C" UNIV_INTERN
1011
innobase_convert_string(
1012
/*====================*/
1015
CHARSET_INFO* to_cs,
1018
CHARSET_INFO* from_cs,
1021
return(copy_and_convert((char*)to, (uint32) to_length, to_cs,
1022
(const char*)from, (uint32) from_length, from_cs,
1026
/***********************************************************************
1027
Formats the raw data in "data" (in InnoDB on-disk format) that is of
1028
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
1029
the result to "buf". The result is converted to "system_charset_info".
1030
Not more than "buf_size" bytes are written to "buf".
1031
The result is always '\0'-terminated (provided buf_size > 0) and the
1032
number of bytes that were written to "buf" is returned (including the
1033
terminating '\0'). */
1034
extern "C" UNIV_INTERN
1036
innobase_raw_format(
1037
/*================*/
1038
/* out: number of bytes
1039
that were written */
1040
const char* data, /* in: raw data */
1041
ulint data_len, /* in: raw data length
1043
ulint charset_coll, /* in: charset collation */
1044
char* buf, /* out: output buffer */
1045
ulint buf_size) /* in: output buffer size
1048
/* XXX we use a hard limit instead of allocating
1049
but_size bytes from the heap */
1050
CHARSET_INFO* data_cs;
1055
data_cs = all_charsets[charset_coll];
1057
buf_tmp_used = innobase_convert_string(buf_tmp, sizeof(buf_tmp),
1058
system_charset_info,
1059
data, data_len, data_cs,
1062
return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size));
1065
/*************************************************************************
1066
Gets the InnoDB transaction handle for a MySQL handler object, creates
1067
an InnoDB transaction struct if the corresponding MySQL thread struct still
1073
/* out: InnoDB transaction handle */
1074
THD* thd) /* in: user thread handle */
1076
trx_t*& trx = thd_to_trx(thd);
1078
ut_ad(thd == current_thd);
1081
DBUG_ASSERT(thd != NULL);
1082
trx = trx_allocate_for_mysql();
1084
trx->mysql_thd = thd;
1085
trx->mysql_query_str = thd_query(thd);
1087
/* Update the info whether we should skip XA steps that eat
1089
trx->support_xa = THDVAR(thd, support_xa);
1091
if (trx->magic_n != TRX_MAGIC_N) {
1092
mem_analyze_corruption(trx);
1098
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
1099
trx->check_foreigns = FALSE;
1101
trx->check_foreigns = TRUE;
1104
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
1105
trx->check_unique_secondary = FALSE;
1107
trx->check_unique_secondary = TRUE;
1114
/*************************************************************************
1115
Construct ha_innobase handler. */
1117
ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
1118
:handler(hton, table_arg),
1119
int_table_flags(HA_REC_NOT_IN_SEQ |
1121
HA_CAN_INDEX_BLOBS |
1122
HA_CAN_SQL_HANDLER |
1123
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
1124
HA_PRIMARY_KEY_IN_READ_INDEX |
1125
HA_BINLOG_ROW_CAPABLE |
1126
HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
1127
HA_TABLE_SCAN_ON_INDEX),
1132
/*************************************************************************
1133
Destruct ha_innobase handler. */
1135
ha_innobase::~ha_innobase()
1139
/*************************************************************************
1140
Updates the user_thd field in a handle and also allocates a new InnoDB
1141
transaction handle if needed, and updates the transaction fields in the
1145
ha_innobase::update_thd(
1146
/*====================*/
1147
THD* thd) /* in: thd to use the handle */
1151
trx = check_trx_exists(thd);
1153
if (prebuilt->trx != trx) {
1155
row_update_prebuilt_trx(prebuilt, trx);
1161
/*************************************************************************
1162
Updates the user_thd field in a handle and also allocates a new InnoDB
1163
transaction handle if needed, and updates the transaction fields in the
1167
ha_innobase::update_thd()
1168
/*=====================*/
1170
THD* thd = ha_thd();
1171
ut_ad(thd == current_thd);
1175
/*************************************************************************
1176
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
1177
roll back the statement if the statement results in an error. This MUST be
1178
called for every SQL statement that may be rolled back by MySQL. Calling this
1179
several times to register the same statement is allowed, too. */
1182
innobase_register_stmt(
1183
/*===================*/
1184
handlerton* hton, /* in: Innobase hton */
1185
THD* thd) /* in: MySQL thd (connection) object */
1187
DBUG_ASSERT(hton == innodb_hton_ptr);
1188
/* Register the statement */
1189
trans_register_ha(thd, FALSE, hton);
1192
/*************************************************************************
1193
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
1194
to call the InnoDB prepare and commit, or rollback for the transaction. This
1195
MUST be called for every transaction for which the user may call commit or
1196
rollback. Calling this several times to register the same transaction is
1198
This function also registers the current SQL statement. */
1201
innobase_register_trx_and_stmt(
1202
/*===========================*/
1203
handlerton *hton, /* in: Innobase handlerton */
1204
THD* thd) /* in: MySQL thd (connection) object */
1206
/* NOTE that actually innobase_register_stmt() registers also
1207
the transaction in the AUTOCOMMIT=1 mode. */
1209
innobase_register_stmt(hton, thd);
1211
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1213
/* No autocommit mode, register for a transaction */
1214
trans_register_ha(thd, TRUE, hton);
1218
/* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB
1219
------------------------------------------------------------
1221
1) The use of the query cache for TBL is disabled when there is an
1222
uncommitted change to TBL.
1224
2) When a change to TBL commits, InnoDB stores the current value of
1225
its global trx id counter, let us denote it by INV_TRX_ID, to the table object
1226
in the InnoDB data dictionary, and does only allow such transactions whose
1227
id <= INV_TRX_ID to use the query cache.
1229
3) When InnoDB does an INSERT/DELETE/UPDATE to a table TBL, or an implicit
1230
modification because an ON DELETE CASCADE, we invalidate the MySQL query cache
1233
How this is implemented inside InnoDB:
1235
1) Since every modification always sets an IX type table lock on the InnoDB
1236
table, it is easy to check if there can be uncommitted modifications for a
1237
table: just check if there are locks in the lock list of the table.
1239
2) When a transaction inside InnoDB commits, it reads the global trx id
1240
counter and stores the value INV_TRX_ID to the tables on which it had a lock.
1242
3) If there is an implicit table change from ON DELETE CASCADE or SET NULL,
1243
InnoDB calls an invalidate method for the MySQL query cache for that table.
1245
How this is implemented inside sql_cache.cc:
1247
1) The query cache for an InnoDB table TBL is invalidated immediately at an
1248
INSERT/UPDATE/DELETE, just like in the case of MyISAM. No need to delay
1249
invalidation to the transaction commit.
1251
2) To store or retrieve a value from the query cache of an InnoDB table TBL,
1252
any query must first ask InnoDB's permission. We must pass the thd as a
1253
parameter because InnoDB will look at the trx id, if any, associated with
1256
3) Use of the query cache for InnoDB tables is now allowed also when
1257
AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
1258
put restrictions on the use of the query cache.
1261
/**********************************************************************
1262
The MySQL query cache uses this to check from InnoDB if the query cache at
1263
the moment is allowed to operate on an InnoDB table. The SQL query must
1264
be a non-locking SELECT.
1266
The query cache is allowed to operate on certain query only if this function
1267
returns TRUE for all tables in the query.
1269
If thd is not in the autocommit state, this function also starts a new
1270
transaction for thd if there is no active trx yet, and assigns a consistent
1271
read view to it if there is no read view yet.
1273
Why a deadlock of threads is not possible: the query cache calls this function
1274
at the start of a SELECT processing. Then the calling thread cannot be
1275
holding any InnoDB semaphores. The calling thread is holding the
1276
query cache mutex, and this function will reserver the InnoDB kernel mutex.
1277
Thus, the 'rank' in sync0sync.h of the MySQL query cache mutex is above
1278
the InnoDB kernel mutex. */
1281
innobase_query_caching_of_table_permitted(
1282
/*======================================*/
1283
/* out: TRUE if permitted, FALSE if not;
1284
note that the value FALSE does not mean
1285
we should invalidate the query cache:
1286
invalidation is called explicitly */
1287
THD* thd, /* in: thd of the user who is trying to
1288
store a result to the query cache or
1290
char* full_name, /* in: concatenation of database name,
1291
the null character '\0', and the table
1293
uint full_name_len, /* in: length of the full name, i.e.
1294
len(dbname) + len(tablename) + 1 */
1295
ulonglong *unused) /* unused for this engine */
1297
ibool is_autocommit;
1299
char norm_name[1000];
1301
ut_a(full_name_len < 999);
1303
trx = check_trx_exists(thd);
1305
if (trx->isolation_level == TRX_ISO_SERIALIZABLE) {
1306
/* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every
1307
plain SELECT if AUTOCOMMIT is not on. */
1309
return((my_bool)FALSE);
1312
if (trx->has_search_latch) {
1313
sql_print_error("The calling thread is holding the adaptive "
1314
"search, latch though calling "
1315
"innobase_query_caching_of_table_permitted.");
1317
mutex_enter(&kernel_mutex);
1318
trx_print(stderr, trx, 1024);
1319
mutex_exit(&kernel_mutex);
1322
innobase_release_stat_resources(trx);
1324
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1326
is_autocommit = TRUE;
1328
is_autocommit = FALSE;
1332
if (is_autocommit && trx->n_mysql_tables_in_use == 0) {
1333
/* We are going to retrieve the query result from the query
1334
cache. This cannot be a store operation to the query cache
1335
because then MySQL would have locks on tables already.
1337
TODO: if the user has used LOCK TABLES to lock the table,
1338
then we open a transaction in the call of row_.. below.
1339
That trx can stay open until UNLOCK TABLES. The same problem
1340
exists even if we do not use the query cache. MySQL should be
1341
modified so that it ALWAYS calls some cleanup function when
1342
the processing of a query ends!
1344
We can imagine we instantaneously serialize this consistent
1345
read trx to the current trx id counter. If trx2 would have
1346
changed the tables of a query result stored in the cache, and
1347
trx2 would have already committed, making the result obsolete,
1348
then trx2 would have already invalidated the cache. Thus we
1349
can trust the result in the cache is ok for this query. */
1351
return((my_bool)TRUE);
1354
/* Normalize the table name to InnoDB format */
1356
memcpy(norm_name, full_name, full_name_len);
1358
norm_name[strlen(norm_name)] = '/'; /* InnoDB uses '/' as the
1359
separator between db and table */
1360
norm_name[full_name_len] = '\0';
1362
innobase_casedn_str(norm_name);
1364
/* The call of row_search_.. will start a new transaction if it is
1367
if (trx->active_trans == 0) {
1369
innobase_register_trx_and_stmt(innodb_hton_ptr, thd);
1370
trx->active_trans = 1;
1373
if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
1375
/* printf("Query cache for %s permitted\n", norm_name); */
1377
return((my_bool)TRUE);
1380
/* printf("Query cache for %s NOT permitted\n", norm_name); */
1382
return((my_bool)FALSE);
1385
/*********************************************************************
1386
Invalidates the MySQL query cache for the table.
1387
NOTE that the exact prototype of this function has to be in
1388
/innobase/row/row0ins.c! */
1389
extern "C" UNIV_INTERN
1391
innobase_invalidate_query_cache(
1392
/*============================*/
1393
trx_t* trx, /* in: transaction which modifies the table */
1394
char* full_name, /* in: concatenation of database name, null
1395
char '\0', table name, null char'\0';
1396
NOTE that in Windows this is always
1398
ulint full_name_len) /* in: full name length where also the null
1401
/* Note that the sync0sync.h rank of the query cache mutex is just
1402
above the InnoDB kernel mutex. The caller of this function must not
1403
have latches of a lower rank. */
1405
/* Argument TRUE below means we are using transactions */
1406
#ifdef HAVE_QUERY_CACHE
1407
mysql_query_cache_invalidate4((THD*) trx->mysql_thd,
1408
(const char*) full_name,
1409
(uint32) full_name_len,
1414
/*********************************************************************
1415
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
1416
and quote it if needed. */
1419
innobase_convert_identifier(
1420
/*========================*/
1421
/* out: pointer to the end of buf */
1422
char* buf, /* out: buffer for converted identifier */
1423
ulint buflen, /* in: length of buf, in bytes */
1424
const char* id, /* in: identifier to convert */
1425
ulint idlen, /* in: length of id, in bytes */
1426
void* thd, /* in: MySQL connection thread, or NULL */
1427
ibool file_id)/* in: TRUE=id is a table or database name;
1428
FALSE=id is an UTF-8 string */
1430
char nz[NAME_LEN + 1];
1431
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1437
/* Decode the table name. The filename_to_tablename()
1438
function expects a NUL-terminated string. The input and
1439
output strings buffers must not be shared. */
1441
if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
1442
idlen = (sizeof nz) - 1;
1445
memcpy(nz, id, idlen);
1449
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
1452
/* See if the identifier needs to be quoted. */
1453
if (UNIV_UNLIKELY(!thd)) {
1456
q = get_quote_char_for_identifier((THD*) thd, s, (int) idlen);
1460
if (UNIV_UNLIKELY(idlen > buflen)) {
1463
memcpy(buf, s, idlen);
1464
return(buf + idlen);
1467
/* Quote the identifier. */
1475
for (; idlen; idlen--) {
1477
if (UNIV_UNLIKELY(c == q)) {
1478
if (UNIV_UNLIKELY(buflen < 3)) {
1486
if (UNIV_UNLIKELY(buflen < 2)) {
1499
/*********************************************************************
1500
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1501
and quote it if needed. */
1502
extern "C" UNIV_INTERN
1504
innobase_convert_name(
1505
/*==================*/
1506
/* out: pointer to the end of buf */
1507
char* buf, /* out: buffer for converted identifier */
1508
ulint buflen, /* in: length of buf, in bytes */
1509
const char* id, /* in: identifier to convert */
1510
ulint idlen, /* in: length of id, in bytes */
1511
void* thd, /* in: MySQL connection thread, or NULL */
1512
ibool table_id)/* in: TRUE=id is a table or database name;
1513
FALSE=id is an index name */
1516
const char* bufend = buf + buflen;
1519
const char* slash = (const char*) memchr(id, '/', idlen);
1525
/* Print the database name and table name separately. */
1526
s = innobase_convert_identifier(s, bufend - s, id, slash - id,
1528
if (UNIV_LIKELY(s < bufend)) {
1530
s = innobase_convert_identifier(s, bufend - s,
1535
} else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) {
1536
/* Temporary index name (smart ALTER TABLE) */
1537
const char temp_index_suffix[]= "--temporary--";
1539
s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1,
1541
if (s - buf + (sizeof temp_index_suffix - 1) < buflen) {
1542
memcpy(s, temp_index_suffix,
1543
sizeof temp_index_suffix - 1);
1544
s += sizeof temp_index_suffix - 1;
1548
s = innobase_convert_identifier(buf, buflen, id, idlen,
1556
/**************************************************************************
1557
Determines if the currently running transaction has been interrupted. */
1558
extern "C" UNIV_INTERN
1562
/* out: TRUE if interrupted */
1563
trx_t* trx) /* in: transaction */
1565
return(trx && trx->mysql_thd && thd_killed((THD*) trx->mysql_thd));
1568
/******************************************************************
1569
Resets some fields of a prebuilt struct. The template is used in fast
1570
retrieval of just those column values MySQL needs in its processing. */
1575
row_prebuilt_t* prebuilt) /* in/out: prebuilt struct */
1577
prebuilt->keep_other_fields_on_keyread = 0;
1578
prebuilt->read_just_key = 0;
1581
/*********************************************************************
1582
Call this when you have opened a new table handle in HANDLER, before you
1583
call index_read_idx() etc. Actually, we can let the cursor stay open even
1584
over a transaction commit! Then you should call this before every operation,
1585
fetch next etc. This function inits the necessary things even after a
1586
transaction commit. */
1589
ha_innobase::init_table_handle_for_HANDLER(void)
1590
/*============================================*/
1592
/* If current thd does not yet have a trx struct, create one.
1593
If the current handle does not yet have a prebuilt struct, create
1594
one. Update the trx pointers in the prebuilt struct. Normally
1595
this operation is done in external_lock. */
1597
update_thd(ha_thd());
1599
/* Initialize the prebuilt struct much like it would be inited in
1602
innobase_release_stat_resources(prebuilt->trx);
1604
/* If the transaction is not started yet, start it */
1606
trx_start_if_not_started(prebuilt->trx);
1608
/* Assign a read view if the transaction does not have it yet */
1610
trx_assign_read_view(prebuilt->trx);
1612
/* Set the MySQL flag to mark that there is an active transaction */
1614
if (prebuilt->trx->active_trans == 0) {
1616
innobase_register_trx_and_stmt(ht, user_thd);
1618
prebuilt->trx->active_trans = 1;
1621
/* We did the necessary inits in this function, no need to repeat them
1622
in row_search_for_mysql */
1624
prebuilt->sql_stat_start = FALSE;
1626
/* We let HANDLER always to do the reads as consistent reads, even
1627
if the trx isolation level would have been specified as SERIALIZABLE */
1629
prebuilt->select_lock_type = LOCK_NONE;
1630
prebuilt->stored_select_lock_type = LOCK_NONE;
1632
/* Always fetch all columns in the index record */
1634
prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
1636
/* We want always to fetch all columns in the whole row? Or do
1639
prebuilt->used_in_HANDLER = TRUE;
1640
reset_template(prebuilt);
1643
/*************************************************************************
1644
Opens an InnoDB database. */
1649
/* out: 0 on success, error code on failure */
1650
void *p) /* in: InnoDB handlerton */
1652
static char current_dir[3]; /* Set if using current lib */
1658
DBUG_ENTER("innobase_init");
1659
handlerton *innobase_hton= (handlerton *)p;
1661
#ifdef MYSQL_DYNAMIC_PLUGIN
1662
if (!innodb_plugin_init()) {
1663
sql_print_error("InnoDB plugin init failed.");
1667
if (innodb_hton_ptr) {
1668
/* Patch the statically linked handlerton and variables */
1669
innobase_hton = innodb_hton_ptr;
1671
#endif /* MYSQL_DYNAMIC_PLUGIN */
1673
innodb_hton_ptr = innobase_hton;
1675
innobase_hton->state = SHOW_OPTION_YES;
1676
innobase_hton->db_type= DB_TYPE_INNODB;
1677
innobase_hton->savepoint_offset=sizeof(trx_named_savept_t);
1678
innobase_hton->close_connection=innobase_close_connection;
1679
innobase_hton->savepoint_set=innobase_savepoint;
1680
innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
1681
innobase_hton->savepoint_release=innobase_release_savepoint;
1682
innobase_hton->commit=innobase_commit;
1683
innobase_hton->rollback=innobase_rollback;
1684
innobase_hton->prepare=innobase_xa_prepare;
1685
innobase_hton->recover=innobase_xa_recover;
1686
innobase_hton->commit_by_xid=innobase_commit_by_xid;
1687
innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
1688
innobase_hton->create_cursor_read_view=innobase_create_cursor_view;
1689
innobase_hton->set_cursor_read_view=innobase_set_cursor_view;
1690
innobase_hton->close_cursor_read_view=innobase_close_cursor_view;
1691
innobase_hton->create=innobase_create_handler;
1692
innobase_hton->drop_database=innobase_drop_database;
1693
innobase_hton->panic=innobase_end;
1694
innobase_hton->start_consistent_snapshot=innobase_start_trx_and_assign_read_view;
1695
innobase_hton->flush_logs=innobase_flush_logs;
1696
innobase_hton->show_status=innobase_show_status;
1697
innobase_hton->flags=HTON_NO_FLAGS;
1698
innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
1699
innobase_hton->alter_table_flags = innobase_alter_table_flags;
1701
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
1704
static const char test_filename[] = "-@";
1705
char test_tablename[sizeof test_filename
1706
+ sizeof srv_mysql50_table_name_prefix];
1707
if ((sizeof test_tablename) - 1
1708
!= filename_to_tablename(test_filename, test_tablename,
1709
sizeof test_tablename)
1710
|| strncmp(test_tablename,
1711
srv_mysql50_table_name_prefix,
1712
sizeof srv_mysql50_table_name_prefix)
1713
|| strcmp(test_tablename
1714
+ sizeof srv_mysql50_table_name_prefix,
1716
sql_print_error("tablename encoding has been changed");
1719
#endif /* UNIV_DEBUG */
1721
/* Check that values don't overflow on 32-bit systems. */
1722
if (sizeof(ulint) == 4) {
1723
if (innobase_buffer_pool_size > UINT_MAX32) {
1725
"innobase_buffer_pool_size can't be over 4GB"
1726
" on 32-bit systems");
1731
if (innobase_log_file_size > UINT_MAX32) {
1733
"innobase_log_file_size can't be over 4GB"
1734
" on 32-bit systems");
1740
os_innodb_umask = (ulint)my_umask;
1742
/* First calculate the default path for innodb_data_home_dir etc.,
1743
in case the user has not given any value.
1745
Note that when using the embedded server, the datadirectory is not
1746
necessarily the current directory of this program. */
1748
if (mysqld_embedded) {
1749
default_path = mysql_real_data_home;
1750
fil_path_to_mysql_datadir = mysql_real_data_home;
1752
/* It's better to use current lib, to keep paths short */
1753
current_dir[0] = FN_CURLIB;
1754
current_dir[1] = FN_LIBCHAR;
1756
default_path = current_dir;
1761
if (specialflag & SPECIAL_NO_PRIOR) {
1762
srv_set_thread_priorities = FALSE;
1764
srv_set_thread_priorities = TRUE;
1765
srv_query_thread_priority = QUERY_PRIOR;
1768
/* Set InnoDB initialization parameters according to the values
1769
read from MySQL .cnf file */
1771
/*--------------- Data files -------------------------*/
1773
/* The default dir for data files is the datadir of MySQL */
1775
srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
1778
/* Set default InnoDB data file size to 10 MB and let it be
1779
auto-extending. Thus users can use InnoDB in >= 4.0 without having
1780
to specify any startup options. */
1782
if (!innobase_data_file_path) {
1783
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
1786
/* Since InnoDB edits the argument in the next call, we make another
1789
internal_innobase_data_file_path = my_strdup(innobase_data_file_path,
1792
ret = (bool) srv_parse_data_file_paths_and_sizes(
1793
internal_innobase_data_file_path,
1794
&srv_data_file_names,
1795
&srv_data_file_sizes,
1796
&srv_data_file_is_raw_partition,
1798
&srv_auto_extend_last_data_file,
1799
&srv_last_file_size_max);
1802
"InnoDB: syntax error in innodb_data_file_path");
1803
my_free(internal_innobase_data_file_path,
1804
MYF(MY_ALLOW_ZERO_PTR));
1808
/* -------------- Log files ---------------------------*/
1810
/* The default dir for log files is the datadir of MySQL */
1812
if (!innobase_log_group_home_dir) {
1813
innobase_log_group_home_dir = default_path;
1816
#ifdef UNIV_LOG_ARCHIVE
1817
/* Since innodb_log_arch_dir has no relevance under MySQL,
1818
starting from 4.0.6 we always set it the same as
1819
innodb_log_group_home_dir: */
1821
innobase_log_arch_dir = innobase_log_group_home_dir;
1823
srv_arch_dir = innobase_log_arch_dir;
1824
#endif /* UNIG_LOG_ARCHIVE */
1827
srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
1828
&srv_log_group_home_dirs);
1830
if (ret == FALSE || innobase_mirrored_log_groups != 1) {
1831
sql_print_error("syntax error in innodb_log_group_home_dir, or a "
1832
"wrong number of mirrored log groups");
1834
my_free(internal_innobase_data_file_path,
1835
MYF(MY_ALLOW_ZERO_PTR));
1839
/* Validate the file format by animal name */
1840
if (innobase_file_format_name != NULL) {
1842
format_id = innobase_file_format_name_lookup(
1843
innobase_file_format_name);
1845
if (format_id > DICT_TF_FORMAT_MAX) {
1847
sql_print_error("InnoDB: wrong innodb_file_format.");
1849
my_free(internal_innobase_data_file_path,
1850
MYF(MY_ALLOW_ZERO_PTR));
1854
/* Set it to the default file format id. Though this
1855
should never happen. */
1859
srv_file_format = format_id;
1861
/* Given the type of innobase_file_format_name we have little
1862
choice but to cast away the constness from the returned name.
1863
innobase_file_format_name is used in the MySQL set variable
1864
interface and so can't be const. */
1866
innobase_file_format_name =
1867
(char*) trx_sys_file_format_id_to_name(format_id);
1869
/* Process innobase_file_format_check variable */
1870
ut_a(innobase_file_format_check != NULL);
1872
/* As a side affect it will set srv_check_file_format_at_startup
1873
on valid input. First we check for "on"/"off". */
1874
if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
1876
/* Did the user specify a format name that we support ?
1877
As a side affect it will update the variable
1878
srv_check_file_format_at_startup*/
1879
if (!innobase_file_format_check_validate(
1880
innobase_file_format_check)) {
1882
sql_print_error("InnoDB: invalid "
1883
"innodb_file_format_check value: "
1884
"should be either 'on' or 'off' or "
1885
"any value up to %s or its "
1886
"equivalent numeric id",
1887
trx_sys_file_format_id_to_name(
1888
DICT_TF_FORMAT_MAX));
1890
my_free(internal_innobase_data_file_path,
1891
MYF(MY_ALLOW_ZERO_PTR));
1897
/* --------------------------------------------------*/
1899
srv_file_flush_method_str = innobase_unix_file_flush_method;
1901
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
1902
srv_n_log_files = (ulint) innobase_log_files_in_group;
1903
srv_log_file_size = (ulint) innobase_log_file_size;
1905
#ifdef UNIV_LOG_ARCHIVE
1906
srv_log_archive_on = (ulint) innobase_log_archive;
1907
#endif /* UNIV_LOG_ARCHIVE */
1908
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
1910
srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
1912
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
1914
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
1916
srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
1917
srv_force_recovery = (ulint) innobase_force_recovery;
1919
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
1920
srv_use_checksums = (ibool) innobase_use_checksums;
1922
#ifdef HAVE_LARGE_PAGES
1923
if ((os_use_large_pages = (ibool) my_use_large_pages))
1924
os_large_page_size = (ulint) opt_large_page_size;
1927
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
1929
srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
1931
srv_max_n_open_files = (ulint) innobase_open_files;
1932
srv_innodb_status = (ibool) innobase_create_status_file;
1934
srv_stats_on_metadata = (ibool) innobase_stats_on_metadata;
1936
btr_search_disabled = (ibool) !innobase_adaptive_hash_index;
1938
srv_print_verbose_log = mysqld_embedded ? 0 : 1;
1940
/* Store the default charset-collation number of this MySQL
1943
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
1945
ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
1946
my_charset_latin1.number);
1947
ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
1949
/* Store the latin1_swedish_ci character ordering table to InnoDB. For
1950
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
1951
and consequently we do not need to know the ordering internally in
1954
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
1955
srv_latin1_ordering = my_charset_latin1.sort_order;
1957
/* Since we in this module access directly the fields of a trx
1958
struct, and due to different headers and flags it might happen that
1959
mutex_t has a different size in this module and in InnoDB
1960
modules, we check at run time that the size is the same in
1961
these compilation modules. */
1963
err = innobase_start_or_create_for_mysql();
1965
if (err != DB_SUCCESS) {
1966
my_free(internal_innobase_data_file_path,
1967
MYF(MY_ALLOW_ZERO_PTR));
1971
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
1972
(hash_get_key) innobase_get_key, 0, 0);
1973
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
1974
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
1975
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
1976
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
1977
pthread_cond_init(&commit_cond, NULL);
1979
#ifdef MYSQL_DYNAMIC_PLUGIN
1980
if (innobase_hton != p) {
1981
innobase_hton = reinterpret_cast<handlerton*>(p);
1982
*innobase_hton = *innodb_hton_ptr;
1984
#endif /* MYSQL_DYNAMIC_PLUGIN */
1986
/* Get the current high water mark format. */
1987
innobase_file_format_check = (char*) trx_sys_file_format_max_get();
1994
/***********************************************************************
1995
Closes an InnoDB database. */
1998
innobase_end(handlerton *hton, ha_panic_function type)
2000
/* out: TRUE if error */
2004
DBUG_ENTER("innobase_end");
2005
DBUG_ASSERT(hton == innodb_hton_ptr);
2007
#ifdef __NETWARE__ /* some special cleanup for NetWare */
2009
set_panic_flag_for_netware();
2012
if (innodb_inited) {
2014
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
2016
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
2019
hash_free(&innobase_open_tables);
2020
my_free(internal_innobase_data_file_path,
2021
MYF(MY_ALLOW_ZERO_PTR));
2022
pthread_mutex_destroy(&innobase_share_mutex);
2023
pthread_mutex_destroy(&prepare_commit_mutex);
2024
pthread_mutex_destroy(&commit_threads_m);
2025
pthread_mutex_destroy(&commit_cond_m);
2026
pthread_cond_destroy(&commit_cond);
2032
/********************************************************************
2033
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
2034
the logs, and the name of this function should be innobase_checkpoint. */
2037
innobase_flush_logs(handlerton *hton)
2038
/*=====================*/
2039
/* out: TRUE if error */
2043
DBUG_ENTER("innobase_flush_logs");
2044
DBUG_ASSERT(hton == innodb_hton_ptr);
2046
log_buffer_flush_to_disk();
2048
DBUG_RETURN(result);
2051
/********************************************************************
2052
Return alter table flags supported in an InnoDB database. */
2055
innobase_alter_table_flags(
2056
/*=======================*/
2059
return(HA_ONLINE_ADD_INDEX_NO_WRITES
2060
| HA_ONLINE_DROP_INDEX_NO_WRITES
2061
| HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
2062
| HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
2063
| HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
2066
/*********************************************************************
2067
Commits a transaction in an InnoDB database. */
2070
innobase_commit_low(
2071
/*================*/
2072
trx_t* trx) /* in: transaction handle */
2074
if (trx->conc_state == TRX_NOT_STARTED) {
2079
trx_commit_for_mysql(trx);
2082
/*********************************************************************
2083
Creates an InnoDB transaction struct for the thd if it does not yet have one.
2084
Starts a new InnoDB transaction if a transaction is not yet started. And
2085
assigns a new snapshot for a consistent read if the transaction does not yet
2089
innobase_start_trx_and_assign_read_view(
2090
/*====================================*/
2092
handlerton *hton, /* in: Innodb handlerton */
2093
THD* thd) /* in: MySQL thread handle of the user for whom
2094
the transaction should be committed */
2098
DBUG_ENTER("innobase_start_trx_and_assign_read_view");
2099
DBUG_ASSERT(hton == innodb_hton_ptr);
2101
/* Create a new trx struct for thd, if it does not yet have one */
2103
trx = check_trx_exists(thd);
2105
/* This is just to play safe: release a possible FIFO ticket and
2106
search latch. Since we will reserve the kernel mutex, we have to
2107
release the search system latch first to obey the latching order. */
2109
innobase_release_stat_resources(trx);
2111
/* If the transaction is not started yet, start it */
2113
trx_start_if_not_started(trx);
2115
/* Assign a read view if the transaction does not have it yet */
2117
trx_assign_read_view(trx);
2119
/* Set the MySQL flag to mark that there is an active transaction */
2121
if (trx->active_trans == 0) {
2122
innobase_register_trx_and_stmt(hton, thd);
2123
trx->active_trans = 1;
2129
/*********************************************************************
2130
Commits a transaction in an InnoDB database or marks an SQL statement
2137
handlerton *hton, /* in: Innodb handlerton */
2138
THD* thd, /* in: MySQL thread handle of the user for whom
2139
the transaction should be committed */
2140
bool all) /* in: TRUE - commit transaction
2141
FALSE - the current SQL statement ended */
2145
DBUG_ENTER("innobase_commit");
2146
DBUG_ASSERT(hton == innodb_hton_ptr);
2147
DBUG_PRINT("trans", ("ending transaction"));
2149
trx = check_trx_exists(thd);
2151
/* Update the info whether we should skip XA steps that eat CPU time */
2152
trx->support_xa = THDVAR(thd, support_xa);
2154
/* Since we will reserve the kernel mutex, we have to release
2155
the search system latch first to obey the latching order. */
2157
if (trx->has_search_latch) {
2158
trx_search_latch_release_if_reserved(trx);
2161
/* The flag trx->active_trans is set to 1 in
2163
1. ::external_lock(),
2165
3. innobase_query_caching_of_table_permitted(),
2166
4. innobase_savepoint(),
2167
5. ::init_table_handle_for_HANDLER(),
2168
6. innobase_start_trx_and_assign_read_view(),
2169
7. ::transactional_table_lock()
2171
and it is only set to 0 in a commit or a rollback. If it is 0 we know
2172
there cannot be resources to be freed and we could return immediately.
2173
For the time being, we play safe and do the cleanup though there should
2174
be nothing to clean up. */
2176
if (trx->active_trans == 0
2177
&& trx->conc_state != TRX_NOT_STARTED) {
2179
sql_print_error("trx->active_trans == 0, but"
2180
" trx->conc_state != TRX_NOT_STARTED");
2183
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2185
/* We were instructed to commit the whole transaction, or
2186
this is an SQL statement end and autocommit is on */
2188
/* We need current binlog position for ibbackup to work.
2189
Note, the position is current because of
2190
prepare_commit_mutex */
2192
if (srv_commit_concurrency > 0) {
2193
pthread_mutex_lock(&commit_cond_m);
2196
if (commit_threads > srv_commit_concurrency) {
2198
pthread_cond_wait(&commit_cond,
2200
pthread_mutex_unlock(&commit_cond_m);
2204
pthread_mutex_unlock(&commit_cond_m);
2208
trx->mysql_log_file_name = mysql_bin_log_file_name();
2209
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
2211
innobase_commit_low(trx);
2213
if (srv_commit_concurrency > 0) {
2214
pthread_mutex_lock(&commit_cond_m);
2216
pthread_cond_signal(&commit_cond);
2217
pthread_mutex_unlock(&commit_cond_m);
2220
if (trx->active_trans == 2) {
2222
pthread_mutex_unlock(&prepare_commit_mutex);
2225
trx->active_trans = 0;
2228
/* We just mark the SQL statement ended and do not do a
2229
transaction commit */
2231
/* If we had reserved the auto-inc lock for some
2232
table in this SQL statement we release it now */
2234
row_unlock_table_autoinc_for_mysql(trx);
2236
/* Store the current undo_no of the transaction so that we
2237
know where to roll back if we have to roll back the next
2240
trx_mark_sql_stat_end(trx);
2243
trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2245
if (trx->declared_to_be_inside_innodb) {
2246
/* Release our possible ticket in the FIFO */
2248
srv_conc_force_exit_innodb(trx);
2251
/* Tell the InnoDB server that there might be work for utility
2253
srv_active_wake_master_thread();
2258
/*********************************************************************
2259
Rolls back a transaction or the latest SQL statement. */
2264
/* out: 0 or error number */
2265
handlerton *hton, /* in: Innodb handlerton */
2266
THD* thd, /* in: handle to the MySQL thread of the user
2267
whose transaction should be rolled back */
2268
bool all) /* in: TRUE - commit transaction
2269
FALSE - the current SQL statement ended */
2274
DBUG_ENTER("innobase_rollback");
2275
DBUG_ASSERT(hton == innodb_hton_ptr);
2276
DBUG_PRINT("trans", ("aborting transaction"));
2278
trx = check_trx_exists(thd);
2280
/* Update the info whether we should skip XA steps that eat CPU time */
2281
trx->support_xa = THDVAR(thd, support_xa);
2283
/* Release a possible FIFO ticket and search latch. Since we will
2284
reserve the kernel mutex, we have to release the search system latch
2285
first to obey the latching order. */
2287
innobase_release_stat_resources(trx);
2289
/* If we had reserved the auto-inc lock for some table (if
2290
we come here to roll back the latest SQL statement) we
2291
release it now before a possibly lengthy rollback */
2293
row_unlock_table_autoinc_for_mysql(trx);
2296
|| !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2298
error = trx_rollback_for_mysql(trx);
2299
trx->active_trans = 0;
2301
error = trx_rollback_last_sql_stat_for_mysql(trx);
2304
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
2307
/*********************************************************************
2308
Rolls back a transaction */
2311
innobase_rollback_trx(
2312
/*==================*/
2313
/* out: 0 or error number */
2314
trx_t* trx) /* in: transaction */
2318
DBUG_ENTER("innobase_rollback_trx");
2319
DBUG_PRINT("trans", ("aborting transaction"));
2321
/* Release a possible FIFO ticket and search latch. Since we will
2322
reserve the kernel mutex, we have to release the search system latch
2323
first to obey the latching order. */
2325
innobase_release_stat_resources(trx);
2327
/* If we had reserved the auto-inc lock for some table (if
2328
we come here to roll back the latest SQL statement) we
2329
release it now before a possibly lengthy rollback */
2331
row_unlock_table_autoinc_for_mysql(trx);
2333
error = trx_rollback_for_mysql(trx);
2335
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
2338
/*********************************************************************
2339
Rolls back a transaction to a savepoint. */
2342
innobase_rollback_to_savepoint(
2343
/*===========================*/
2344
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
2345
no savepoint with the given name */
2346
handlerton *hton, /* in: Innodb handlerton */
2347
THD* thd, /* in: handle to the MySQL thread of the user
2348
whose transaction should be rolled back */
2349
void* savepoint) /* in: savepoint data */
2351
ib_int64_t mysql_binlog_cache_pos;
2356
DBUG_ENTER("innobase_rollback_to_savepoint");
2357
DBUG_ASSERT(hton == innodb_hton_ptr);
2359
trx = check_trx_exists(thd);
2361
/* Release a possible FIFO ticket and search latch. Since we will
2362
reserve the kernel mutex, we have to release the search system latch
2363
first to obey the latching order. */
2365
innobase_release_stat_resources(trx);
2367
/* TODO: use provided savepoint data area to store savepoint data */
2369
longlong2str((ulint)savepoint, name, 36);
2371
error = (int) trx_rollback_to_savepoint_for_mysql(trx, name,
2372
&mysql_binlog_cache_pos);
2373
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
2376
/*********************************************************************
2377
Release transaction savepoint name. */
2380
innobase_release_savepoint(
2381
/*=======================*/
2382
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
2383
no savepoint with the given name */
2384
handlerton* hton, /* in: handlerton for Innodb */
2385
THD* thd, /* in: handle to the MySQL thread of the user
2386
whose transaction should be rolled back */
2387
void* savepoint) /* in: savepoint data */
2393
DBUG_ENTER("innobase_release_savepoint");
2394
DBUG_ASSERT(hton == innodb_hton_ptr);
2396
trx = check_trx_exists(thd);
2398
/* TODO: use provided savepoint data area to store savepoint data */
2400
longlong2str((ulint)savepoint, name, 36);
2402
error = (int) trx_release_savepoint_for_mysql(trx, name);
2404
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
2407
/*********************************************************************
2408
Sets a transaction savepoint. */
2413
/* out: always 0, that is, always succeeds */
2414
handlerton* hton, /* in: handle to the Innodb handlerton */
2415
THD* thd, /* in: handle to the MySQL thread */
2416
void* savepoint) /* in: savepoint data */
2421
DBUG_ENTER("innobase_savepoint");
2422
DBUG_ASSERT(hton == innodb_hton_ptr);
2425
In the autocommit mode there is no sense to set a savepoint
2426
(unless we are in sub-statement), so SQL layer ensures that
2427
this method is never called in such situation.
2429
#ifdef MYSQL_SERVER /* plugins cannot access thd->in_sub_stmt */
2430
DBUG_ASSERT(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2432
#endif /* MYSQL_SERVER */
2434
trx = check_trx_exists(thd);
2436
/* Release a possible FIFO ticket and search latch. Since we will
2437
reserve the kernel mutex, we have to release the search system latch
2438
first to obey the latching order. */
2440
innobase_release_stat_resources(trx);
2442
/* cannot happen outside of transaction */
2443
DBUG_ASSERT(trx->active_trans);
2445
/* TODO: use provided savepoint data area to store savepoint data */
2447
longlong2str((ulint)savepoint,name,36);
2449
error = (int) trx_savepoint_for_mysql(trx, name, (ib_int64_t)0);
2451
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
2454
/*********************************************************************
2455
Frees a possible InnoDB trx object associated with the current THD. */
2458
innobase_close_connection(
2459
/*======================*/
2460
/* out: 0 or error number */
2461
handlerton* hton, /* in: innobase handlerton */
2462
THD* thd) /* in: handle to the MySQL thread of the user
2463
whose resources should be free'd */
2467
DBUG_ENTER("innobase_close_connection");
2468
DBUG_ASSERT(hton == innodb_hton_ptr);
2469
trx = thd_to_trx(thd);
2473
if (trx->active_trans == 0
2474
&& trx->conc_state != TRX_NOT_STARTED) {
2476
sql_print_error("trx->active_trans == 0, but"
2477
" trx->conc_state != TRX_NOT_STARTED");
2481
if (trx->conc_state != TRX_NOT_STARTED &&
2482
global_system_variables.log_warnings) {
2484
"MySQL is closing a connection that has an active "
2485
"InnoDB transaction. %lu row modifications will "
2487
(ulong) trx->undo_no.low);
2490
innobase_rollback_trx(trx);
2492
thr_local_free(trx->mysql_thread_id);
2493
trx_free_for_mysql(trx);
2499
/*****************************************************************************
2500
** InnoDB database tables
2501
*****************************************************************************/
2503
/********************************************************************
2504
Get the record format from the data dictionary. */
2507
ha_innobase::get_row_type() const
2508
/*=============================*/
2512
ROW_TYPE_COMPRESSED,
2515
if (prebuilt && prebuilt->table) {
2516
const ulint flags = prebuilt->table->flags;
2518
if (UNIV_UNLIKELY(!flags)) {
2519
return(ROW_TYPE_REDUNDANT);
2522
ut_ad(flags & DICT_TF_COMPACT);
2524
switch (flags & DICT_TF_FORMAT_MASK) {
2525
case DICT_TF_FORMAT_51 << DICT_TF_FORMAT_SHIFT:
2526
return(ROW_TYPE_COMPACT);
2527
case DICT_TF_FORMAT_ZIP << DICT_TF_FORMAT_SHIFT:
2528
if (flags & DICT_TF_ZSSIZE_MASK) {
2529
return(ROW_TYPE_COMPRESSED);
2531
return(ROW_TYPE_DYNAMIC);
2533
#if DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX
2534
# error "DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX"
2539
return(ROW_TYPE_NOT_USED);
2544
/********************************************************************
2545
Get the table flags to use for the statement. */
2547
handler::Table_flags
2548
ha_innobase::table_flags() const
2550
/* Need to use tx_isolation here since table flags is (also)
2551
called before prebuilt is inited. */
2552
ulong const tx_isolation = thd_tx_isolation(current_thd);
2553
if (tx_isolation <= ISO_READ_COMMITTED)
2554
return int_table_flags;
2555
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
2558
/********************************************************************
2559
Gives the file extension of an InnoDB single-table tablespace. */
2560
static const char* ha_innobase_exts[] = {
2567
ha_innobase::table_type() const
2568
/*===========================*/
2569
/* out: table type */
2571
return(innobase_hton_name);
2576
ha_innobase::index_type(uint)
2577
/*=========================*/
2578
/* out: index type */
2585
ha_innobase::bas_ext() const
2586
/*========================*/
2587
/* out: file extension string */
2589
return(ha_innobase_exts);
2594
ha_innobase::index_flags(uint, uint, bool) const
2596
return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
2597
| HA_READ_RANGE | HA_KEYREAD_ONLY);
2602
ha_innobase::max_supported_keys() const
2609
ha_innobase::max_supported_key_length() const
2611
/* An InnoDB page must store >= 2 keys; a secondary key record
2612
must also contain the primary key value: max key length is
2613
therefore set to slightly less than 1 / 4 of page size which
2614
is 16 kB; but currently MySQL does not work with keys whose
2615
size is > MAX_KEY_LENGTH */
2621
ha_innobase::keys_to_use_for_scanning()
2623
return(&key_map_full);
2628
ha_innobase::table_cache_type()
2630
return(HA_CACHE_TBL_ASKTRANSACT);
2635
ha_innobase::primary_key_is_clustered()
2640
/*********************************************************************
2641
Normalizes a table name string. A normalized name consists of the
2642
database name catenated to '/' and table name. An example:
2643
test/mytable. On Windows normalization puts both the database name and the
2644
table name always to lower case. */
2647
normalize_table_name(
2648
/*=================*/
2649
char* norm_name, /* out: normalized name as a
2650
null-terminated string */
2651
const char* name) /* in: table name string */
2657
/* Scan name from the end */
2659
ptr = strend(name)-1;
2661
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2667
DBUG_ASSERT(ptr > name);
2671
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2677
memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2679
norm_name[name_ptr - db_ptr - 1] = '/';
2682
innobase_casedn_str(norm_name);
2686
/*********************************************************************
2687
Creates and opens a handle to a table which already exists in an InnoDB
2693
/* out: 1 if error, 0 if success */
2694
const char* name, /* in: table name */
2695
int mode, /* in: not used */
2696
uint test_if_locked) /* in: not used */
2698
dict_table_t* ib_table;
2699
char norm_name[1000];
2702
char* is_part = NULL;
2704
DBUG_ENTER("ha_innobase::open");
2707
UT_NOT_USED(test_if_locked);
2710
normalize_table_name(norm_name, name);
2714
if (!(share=get_share(name))) {
2719
/* Create buffers for packing the fields of a record. Why
2720
table->reclength did not work here? Obviously, because char
2721
fields when packed actually became 1 byte longer, when we also
2722
stored the string length as the first byte. */
2724
upd_and_key_val_buff_len =
2725
table->s->reclength + table->s->max_key_length
2726
+ MAX_REF_PARTS * 3;
2727
if (!(uchar*) my_multi_malloc(MYF(MY_WME),
2728
&upd_buff, upd_and_key_val_buff_len,
2729
&key_val_buff, upd_and_key_val_buff_len,
2736
/* We look for pattern #P# to see if the table is partitioned
2737
MySQL table. The retry logic for partitioned tables is a
2738
workaround for http://bugs.mysql.com/bug.php?id=33349. Look
2739
at support issue https://support.mysql.com/view.php?id=21080
2740
for more details. */
2741
is_part = strstr(norm_name, "#P#");
2743
/* Get pointer to a table object in InnoDB dictionary cache */
2744
ib_table = dict_table_get(norm_name, TRUE);
2746
if (NULL == ib_table) {
2747
if (is_part && retries < 10) {
2749
os_thread_sleep(100000);
2754
sql_print_error("Failed to open table %s after "
2755
"%lu attemtps.\n", norm_name,
2759
sql_print_error("Cannot find or open table %s from\n"
2760
"the internal data dictionary of InnoDB "
2761
"though the .frm file for the\n"
2762
"table exists. Maybe you have deleted and "
2763
"recreated InnoDB data\n"
2764
"files but have forgotten to delete the "
2765
"corresponding .frm files\n"
2766
"of InnoDB tables, or you have moved .frm "
2767
"files to another database?\n"
2768
"or, the table contains indexes that this "
2769
"version of the engine\n"
2770
"doesn't support.\n"
2771
"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
2772
"how you can resolve the problem.\n",
2775
my_free(upd_buff, MYF(0));
2778
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
2781
if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) {
2782
sql_print_error("MySQL is trying to open a table handle but "
2783
"the .ibd file for\ntable %s does not exist.\n"
2784
"Have you deleted the .ibd file from the "
2785
"database directory under\nthe MySQL datadir, "
2786
"or have you used DISCARD TABLESPACE?\n"
2787
"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
2788
"how you can resolve the problem.\n",
2791
my_free(upd_buff, MYF(0));
2794
dict_table_decrement_handle_count(ib_table, FALSE);
2795
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
2798
prebuilt = row_create_prebuilt(ib_table);
2800
prebuilt->mysql_row_len = table->s->reclength;
2802
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
2804
primary_key = table->s->primary_key;
2805
key_used_on_scan = primary_key;
2807
/* Allocate a buffer for a 'row reference'. A row reference is
2808
a string of bytes of length ref_length which uniquely specifies
2809
a row in our table. Note that MySQL may also compare two row
2810
references for equality by doing a simple memcmp on the strings
2811
of length ref_length! */
2813
if (!row_table_got_default_clust_index(ib_table)) {
2814
if (primary_key >= MAX_KEY) {
2815
sql_print_error("Table %s has a primary key in InnoDB data "
2816
"dictionary, but not in MySQL!", name);
2819
prebuilt->clust_index_was_generated = FALSE;
2821
/* MySQL allocates the buffer for ref. key_info->key_length
2822
includes space for all key columns + one byte for each column
2823
that may be NULL. ref_length must be as exact as possible to
2824
save space, because all row reference buffers are allocated
2825
based on ref_length. */
2827
ref_length = table->key_info[primary_key].key_length;
2829
if (primary_key != MAX_KEY) {
2830
sql_print_error("Table %s has no primary key in InnoDB data "
2831
"dictionary, but has one in MySQL! If you "
2832
"created the table with a MySQL version < "
2833
"3.23.54 and did not define a primary key, "
2834
"but defined a unique key with all non-NULL "
2835
"columns, then MySQL internally treats that "
2836
"key as the primary key. You can fix this "
2837
"error by dump + DROP + CREATE + reimport "
2838
"of the table.", name);
2841
prebuilt->clust_index_was_generated = TRUE;
2843
ref_length = DATA_ROW_ID_LEN;
2845
/* If we automatically created the clustered index, then
2846
MySQL does not know about it, and MySQL must NOT be aware
2847
of the index used on scan, to make it avoid checking if we
2848
update the column of the index. That is why we assert below
2849
that key_used_on_scan is the undefined value MAX_KEY.
2850
The column is the row id in the automatical generation case,
2851
and it will never be updated anyway. */
2853
if (key_used_on_scan != MAX_KEY) {
2855
"Table %s key_used_on_scan is %lu even "
2856
"though there is no primary key inside "
2857
"InnoDB.", name, (ulong) key_used_on_scan);
2861
/* Index block size in InnoDB: used by MySQL in query optimization */
2862
stats.block_size = 16 * 1024;
2864
/* Init table lock structure */
2865
thr_lock_data_init(&share->lock,&lock,(void*) 0);
2867
if (prebuilt->table) {
2868
/* We update the highest file format in the system table
2869
space, if this table has higher file format setting. */
2871
trx_sys_file_format_max_update(
2872
prebuilt->table->flags, &innobase_file_format_check);
2875
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
2882
ha_innobase::max_supported_key_part_length() const
2884
return(DICT_MAX_INDEX_COL_LEN - 1);
2887
/**********************************************************************
2888
Closes a handle to an InnoDB table. */
2891
ha_innobase::close(void)
2892
/*====================*/
2897
DBUG_ENTER("ha_innobase::close");
2899
thd = current_thd; // avoid calling current_thd twice, it may be slow
2901
innobase_release_temporary_latches(ht, thd);
2904
row_prebuilt_free(prebuilt, FALSE);
2906
my_free(upd_buff, MYF(0));
2909
/* Tell InnoDB server that there might be work for
2912
srv_active_wake_master_thread();
2917
/* The following accessor functions should really be inside MySQL code! */
2919
/******************************************************************
2920
Gets field offset for a field in a table. */
2926
TABLE* table, /* in: MySQL table object */
2927
Field* field) /* in: MySQL field object */
2929
return((uint) (field->ptr - table->record[0]));
2932
/******************************************************************
2933
Checks if a field in a record is SQL NULL. Uses the record format
2934
information in table to track the null bit in record. */
2937
field_in_record_is_null(
2938
/*====================*/
2939
/* out: 1 if NULL, 0 otherwise */
2940
TABLE* table, /* in: MySQL table object */
2941
Field* field, /* in: MySQL field object */
2942
char* record) /* in: a row in MySQL format */
2946
if (!field->null_ptr) {
2951
null_offset = (uint) ((char*) field->null_ptr
2952
- (char*) table->record[0]);
2954
if (record[null_offset] & field->null_bit) {
2962
/******************************************************************
2963
Sets a field in a record to SQL NULL. Uses the record format
2964
information in table to track the null bit in record. */
2967
set_field_in_record_to_null(
2968
/*========================*/
2969
TABLE* table, /* in: MySQL table object */
2970
Field* field, /* in: MySQL field object */
2971
char* record) /* in: a row in MySQL format */
2975
null_offset = (uint) ((char*) field->null_ptr
2976
- (char*) table->record[0]);
2978
record[null_offset] = record[null_offset] | field->null_bit;
2981
/*****************************************************************
2982
InnoDB uses this function to compare two data fields for which the data type
2983
is such that we must use MySQL code to compare them. NOTE that the prototype
2984
of this function is in rem0cmp.c in InnoDB source code! If you change this
2985
function, remember to update the prototype there! */
2986
extern "C" UNIV_INTERN
2990
/* out: 1, 0, -1, if a is greater,
2991
equal, less than b, respectively */
2992
int mysql_type, /* in: MySQL type */
2993
uint charset_number, /* in: number of the charset */
2994
const unsigned char* a, /* in: data field */
2995
unsigned int a_length, /* in: data field length,
2996
not UNIV_SQL_NULL */
2997
const unsigned char* b, /* in: data field */
2998
unsigned int b_length) /* in: data field length,
2999
not UNIV_SQL_NULL */
3001
CHARSET_INFO* charset;
3002
enum_field_types mysql_tp;
3005
DBUG_ASSERT(a_length != UNIV_SQL_NULL);
3006
DBUG_ASSERT(b_length != UNIV_SQL_NULL);
3008
mysql_tp = (enum_field_types) mysql_type;
3012
case MYSQL_TYPE_BIT:
3013
case MYSQL_TYPE_STRING:
3014
case MYSQL_TYPE_VAR_STRING:
3015
case MYSQL_TYPE_TINY_BLOB:
3016
case MYSQL_TYPE_MEDIUM_BLOB:
3017
case MYSQL_TYPE_BLOB:
3018
case MYSQL_TYPE_LONG_BLOB:
3019
case MYSQL_TYPE_VARCHAR:
3020
/* Use the charset number to pick the right charset struct for
3021
the comparison. Since the MySQL function get_charset may be
3022
slow before Bar removes the mutex operation there, we first
3023
look at 2 common charsets directly. */
3025
if (charset_number == default_charset_info->number) {
3026
charset = default_charset_info;
3027
} else if (charset_number == my_charset_latin1.number) {
3028
charset = &my_charset_latin1;
3030
charset = get_charset(charset_number, MYF(MY_WME));
3032
if (charset == NULL) {
3033
sql_print_error("InnoDB needs charset %lu for doing "
3034
"a comparison, but MySQL cannot "
3035
"find that charset.",
3036
(ulong) charset_number);
3041
/* Starting from 4.1.3, we use strnncollsp() in comparisons of
3042
non-latin1_swedish_ci strings. NOTE that the collation order
3043
changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users
3044
having indexes on such data need to rebuild their tables! */
3046
ret = charset->coll->strnncollsp(charset,
3051
} else if (ret > 0) {
3063
/******************************************************************
3064
Converts a MySQL type to an InnoDB type. Note that this function returns
3065
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3066
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'. */
3067
extern "C" UNIV_INTERN
3069
get_innobase_type_from_mysql_type(
3070
/*==============================*/
3071
/* out: DATA_BINARY,
3072
DATA_VARCHAR, ... */
3073
ulint* unsigned_flag, /* out: DATA_UNSIGNED if an
3075
at least ENUM and SET,
3076
and unsigned integer
3077
types are 'unsigned types' */
3078
const void* f) /* in: MySQL Field */
3080
const class Field* field = reinterpret_cast<const class Field*>(f);
3082
/* The following asserts try to check that the MySQL type code fits in
3083
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
3086
DBUG_ASSERT((ulint)MYSQL_TYPE_STRING < 256);
3087
DBUG_ASSERT((ulint)MYSQL_TYPE_VAR_STRING < 256);
3088
DBUG_ASSERT((ulint)MYSQL_TYPE_DOUBLE < 256);
3089
DBUG_ASSERT((ulint)MYSQL_TYPE_FLOAT < 256);
3090
DBUG_ASSERT((ulint)MYSQL_TYPE_DECIMAL < 256);
3092
if (field->flags & UNSIGNED_FLAG) {
3094
*unsigned_flag = DATA_UNSIGNED;
3099
if (field->real_type() == MYSQL_TYPE_ENUM
3100
|| field->real_type() == MYSQL_TYPE_SET) {
3102
/* MySQL has field->type() a string type for these, but the
3103
data is actually internally stored as an unsigned integer
3106
*unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
3107
flag set to zero, even though
3108
internally this is an unsigned
3113
switch (field->type()) {
3114
/* NOTE that we only allow string types in DATA_MYSQL and
3116
case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
3117
case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
3118
if (field->binary()) {
3119
return(DATA_BINARY);
3121
field->charset()->name,
3122
"latin1_swedish_ci") == 0) {
3123
return(DATA_VARCHAR);
3125
return(DATA_VARMYSQL);
3127
case MYSQL_TYPE_BIT:
3128
case MYSQL_TYPE_STRING: if (field->binary()) {
3130
return(DATA_FIXBINARY);
3132
field->charset()->name,
3133
"latin1_swedish_ci") == 0) {
3138
case MYSQL_TYPE_NEWDECIMAL:
3139
return(DATA_FIXBINARY);
3140
case MYSQL_TYPE_LONG:
3141
case MYSQL_TYPE_LONGLONG:
3142
case MYSQL_TYPE_TINY:
3143
case MYSQL_TYPE_SHORT:
3144
case MYSQL_TYPE_INT24:
3145
case MYSQL_TYPE_DATE:
3146
case MYSQL_TYPE_DATETIME:
3147
case MYSQL_TYPE_YEAR:
3148
case MYSQL_TYPE_NEWDATE:
3149
case MYSQL_TYPE_TIME:
3150
case MYSQL_TYPE_TIMESTAMP:
3152
case MYSQL_TYPE_FLOAT:
3154
case MYSQL_TYPE_DOUBLE:
3155
return(DATA_DOUBLE);
3156
case MYSQL_TYPE_DECIMAL:
3157
return(DATA_DECIMAL);
3158
case MYSQL_TYPE_GEOMETRY:
3159
case MYSQL_TYPE_TINY_BLOB:
3160
case MYSQL_TYPE_MEDIUM_BLOB:
3161
case MYSQL_TYPE_BLOB:
3162
case MYSQL_TYPE_LONG_BLOB:
3171
/***********************************************************************
3172
Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
3176
innobase_write_to_2_little_endian(
3177
/*==============================*/
3178
byte* buf, /* in: where to store */
3179
ulint val) /* in: value to write, must be < 64k */
3181
ut_a(val < 256 * 256);
3183
buf[0] = (byte)(val & 0xFF);
3184
buf[1] = (byte)(val / 256);
3187
/***********************************************************************
3188
Reads an unsigned integer value < 64k from 2 bytes, in the little-endian
3192
innobase_read_from_2_little_endian(
3193
/*===============================*/
3195
const uchar* buf) /* in: from where to read */
3197
return (uint) ((ulint)(buf[0]) + 256 * ((ulint)(buf[1])));
3200
/***********************************************************************
3201
Stores a key value for a row to a buffer. */
3204
ha_innobase::store_key_val_for_row(
3205
/*===============================*/
3206
/* out: key value length as stored in buff */
3207
uint keynr, /* in: key number */
3208
char* buff, /* in/out: buffer for the key value (in MySQL
3210
uint buff_len,/* in: buffer length */
3211
const uchar* record)/* in: row in MySQL format */
3213
KEY* key_info = table->key_info + keynr;
3214
KEY_PART_INFO* key_part = key_info->key_part;
3215
KEY_PART_INFO* end = key_part + key_info->key_parts;
3216
char* buff_start = buff;
3217
enum_field_types mysql_type;
3221
DBUG_ENTER("store_key_val_for_row");
3223
/* The format for storing a key field in MySQL is the following:
3225
1. If the column can be NULL, then in the first byte we put 1 if the
3226
field value is NULL, 0 otherwise.
3228
2. If the column is of a BLOB type (it must be a column prefix field
3229
in this case), then we put the length of the data in the field to the
3230
next 2 bytes, in the little-endian format. If the field is SQL NULL,
3231
then these 2 bytes are set to 0. Note that the length of data in the
3232
field is <= column prefix length.
3234
3. In a column prefix field, prefix_len next bytes are reserved for
3235
data. In a normal field the max field length next bytes are reserved
3236
for data. For a VARCHAR(n) the max field length is n. If the stored
3237
value is the SQL NULL then these data bytes are set to 0.
3239
4. We always use a 2 byte length for a true >= 5.0.3 VARCHAR. Note that
3240
in the MySQL row format, the length is stored in 1 or 2 bytes,
3241
depending on the maximum allowed length. But in the MySQL key value
3242
format, the length always takes 2 bytes.
3244
We have to zero-fill the buffer so that MySQL is able to use a
3245
simple memcmp to compare two key values to determine if they are
3246
equal. MySQL does this to compare contents of two 'ref' values. */
3248
bzero(buff, buff_len);
3250
for (; key_part != end; key_part++) {
3253
if (key_part->null_bit) {
3254
if (record[key_part->null_offset]
3255
& key_part->null_bit) {
3264
field = key_part->field;
3265
mysql_type = field->type();
3267
if (mysql_type == MYSQL_TYPE_VARCHAR) {
3268
/* >= 5.0.3 true VARCHAR */
3277
key_len = key_part->length;
3280
buff += key_len + 2;
3284
cs = field->charset();
3287
(((Field_varstring*)field)->length_bytes);
3289
data = row_mysql_read_true_varchar(&len,
3291
+ (ulint)get_field_offset(table, field)),
3296
/* For multi byte character sets we need to calculate
3297
the true length of the key */
3299
if (len > 0 && cs->mbmaxlen > 1) {
3300
true_len = (ulint) cs->cset->well_formed_len(cs,
3301
(const char *) data,
3302
(const char *) data + len,
3308
/* In a column prefix index, we may need to truncate
3309
the stored value: */
3311
if (true_len > key_len) {
3315
/* The length in a key value is always stored in 2
3318
row_mysql_store_true_var_len((byte*)buff, true_len, 2);
3321
memcpy(buff, data, true_len);
3323
/* Note that we always reserve the maximum possible
3324
length of the true VARCHAR in the key value, though
3325
only len first bytes after the 2 length bytes contain
3326
actual data. The rest of the space was reset to zero
3327
in the bzero() call above. */
3331
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
3332
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
3333
|| mysql_type == MYSQL_TYPE_BLOB
3334
|| mysql_type == MYSQL_TYPE_LONG_BLOB) {
3341
const byte* blob_data;
3343
ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
3345
key_len = key_part->length;
3348
buff += key_len + 2;
3353
cs = field->charset();
3355
blob_data = row_mysql_read_blob_ref(&blob_len,
3357
+ (ulint)get_field_offset(table, field)),
3358
(ulint) field->pack_length());
3360
true_len = blob_len;
3362
ut_a(get_field_offset(table, field)
3363
== key_part->offset);
3365
/* For multi byte character sets we need to calculate
3366
the true length of the key */
3368
if (blob_len > 0 && cs->mbmaxlen > 1) {
3369
true_len = (ulint) cs->cset->well_formed_len(cs,
3370
(const char *) blob_data,
3371
(const char *) blob_data
3378
/* All indexes on BLOB and TEXT are column prefix
3379
indexes, and we may need to truncate the data to be
3380
stored in the key value: */
3382
if (true_len > key_len) {
3386
/* MySQL reserves 2 bytes for the length and the
3387
storage of the number is little-endian */
3389
innobase_write_to_2_little_endian(
3390
(byte*)buff, true_len);
3393
memcpy(buff, blob_data, true_len);
3395
/* Note that we always reserve the maximum possible
3396
length of the BLOB prefix in the key value. */
3400
/* Here we handle all other data types except the
3401
true VARCHAR, BLOB and TEXT. Note that the column
3402
value we store may be also in a column prefix
3408
const uchar* src_start;
3410
enum_field_types real_type;
3412
key_len = key_part->length;
3420
src_start = record + key_part->offset;
3421
real_type = field->real_type();
3424
/* Character set for the field is defined only
3425
to fields whose type is string and real field
3426
type is not enum or set. For these fields check
3427
if character set is multi byte. */
3429
if (real_type != MYSQL_TYPE_ENUM
3430
&& real_type != MYSQL_TYPE_SET
3431
&& ( mysql_type == MYSQL_TYPE_VAR_STRING
3432
|| mysql_type == MYSQL_TYPE_STRING)) {
3434
cs = field->charset();
3436
/* For multi byte character sets we need to
3437
calculate the true length of the key */
3439
if (key_len > 0 && cs->mbmaxlen > 1) {
3442
cs->cset->well_formed_len(cs,
3443
(const char *)src_start,
3444
(const char *)src_start
3452
memcpy(buff, src_start, true_len);
3455
/* Pad the unused space with spaces. Note that no
3456
padding is ever needed for UCS-2 because in MySQL,
3457
all UCS2 characters are 2 bytes, as MySQL does not
3458
support surrogate pairs, which are needed to represent
3459
characters in the range U+10000 to U+10FFFF. */
3461
if (true_len < key_len) {
3462
ulint pad_len = key_len - true_len;
3463
memset(buff, ' ', pad_len);
3469
ut_a(buff <= buff_start + buff_len);
3471
DBUG_RETURN((uint)(buff - buff_start));
3474
/******************************************************************
3475
Builds a 'template' to the prebuilt struct. The template is used in fast
3476
retrieval of just those column values MySQL needs in its processing. */
3481
row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */
3482
THD* thd, /* in: current user thread, used
3483
only if templ_type is
3484
ROW_MYSQL_REC_FIELDS */
3485
TABLE* table, /* in: MySQL table */
3486
uint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
3487
ROW_MYSQL_REC_FIELDS */
3489
dict_index_t* index;
3490
dict_index_t* clust_index;
3491
mysql_row_templ_t* templ;
3494
ulint n_requested_fields = 0;
3495
ibool fetch_all_in_key = FALSE;
3496
ibool fetch_primary_key_cols = FALSE;
3498
/* byte offset of the end of last requested column */
3499
ulint mysql_prefix_len = 0;
3501
if (prebuilt->select_lock_type == LOCK_X) {
3502
/* We always retrieve the whole clustered index record if we
3503
use exclusive row level locks, for example, if the read is
3504
done in an UPDATE statement. */
3506
templ_type = ROW_MYSQL_WHOLE_ROW;
3509
if (templ_type == ROW_MYSQL_REC_FIELDS) {
3510
if (prebuilt->hint_need_to_fetch_extra_cols
3511
== ROW_RETRIEVE_ALL_COLS) {
3513
/* We know we must at least fetch all columns in the
3514
key, or all columns in the table */
3516
if (prebuilt->read_just_key) {
3517
/* MySQL has instructed us that it is enough
3518
to fetch the columns in the key; looks like
3519
MySQL can set this flag also when there is
3520
only a prefix of the column in the key: in
3521
that case we retrieve the whole column from
3522
the clustered index */
3524
fetch_all_in_key = TRUE;
3526
templ_type = ROW_MYSQL_WHOLE_ROW;
3528
} else if (prebuilt->hint_need_to_fetch_extra_cols
3529
== ROW_RETRIEVE_PRIMARY_KEY) {
3530
/* We must at least fetch all primary key cols. Note
3531
that if the clustered index was internally generated
3532
by InnoDB on the row id (no primary key was
3533
defined), then row_search_for_mysql() will always
3534
retrieve the row id to a special buffer in the
3537
fetch_primary_key_cols = TRUE;
3541
clust_index = dict_table_get_first_index(prebuilt->table);
3543
if (templ_type == ROW_MYSQL_REC_FIELDS) {
3544
index = prebuilt->index;
3546
index = clust_index;
3549
if (index == clust_index) {
3550
prebuilt->need_to_access_clustered = TRUE;
3552
prebuilt->need_to_access_clustered = FALSE;
3553
/* Below we check column by column if we need to access
3554
the clustered index */
3557
n_fields = (ulint)table->s->fields; /* number of columns */
3559
if (!prebuilt->mysql_template) {
3560
prebuilt->mysql_template = (mysql_row_templ_t*)
3561
mem_alloc(n_fields * sizeof(mysql_row_templ_t));
3564
prebuilt->template_type = templ_type;
3565
prebuilt->null_bitmap_len = table->s->null_bytes;
3567
prebuilt->templ_contains_blob = FALSE;
3569
/* Note that in InnoDB, i is the column number. MySQL calls columns
3571
for (i = 0; i < n_fields; i++) {
3572
templ = prebuilt->mysql_template + n_requested_fields;
3573
field = table->field[i];
3575
if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
3576
/* Decide which columns we should fetch
3577
and which we can skip. */
3578
register const ibool index_contains_field =
3579
dict_index_contains_col_or_prefix(index, i);
3581
if (!index_contains_field && prebuilt->read_just_key) {
3582
/* If this is a 'key read', we do not need
3583
columns that are not in the key */
3588
if (index_contains_field && fetch_all_in_key) {
3589
/* This field is needed in the query */
3594
if (bitmap_is_set(table->read_set, i) ||
3595
bitmap_is_set(table->write_set, i)) {
3596
/* This field is needed in the query */
3601
if (fetch_primary_key_cols
3602
&& dict_table_col_in_clustered_key(
3604
/* This field is needed in the query */
3609
/* This field is not needed in the query, skip it */
3614
n_requested_fields++;
3618
if (index == clust_index) {
3619
templ->rec_field_no = dict_col_get_clust_pos(
3620
&index->table->cols[i], index);
3622
templ->rec_field_no = dict_index_get_nth_col_pos(
3626
if (templ->rec_field_no == ULINT_UNDEFINED) {
3627
prebuilt->need_to_access_clustered = TRUE;
3630
if (field->null_ptr) {
3631
templ->mysql_null_byte_offset =
3632
(ulint) ((char*) field->null_ptr
3633
- (char*) table->record[0]);
3635
templ->mysql_null_bit_mask = (ulint) field->null_bit;
3637
templ->mysql_null_bit_mask = 0;
3640
templ->mysql_col_offset = (ulint)
3641
get_field_offset(table, field);
3643
templ->mysql_col_len = (ulint) field->pack_length();
3644
if (mysql_prefix_len < templ->mysql_col_offset
3645
+ templ->mysql_col_len) {
3646
mysql_prefix_len = templ->mysql_col_offset
3647
+ templ->mysql_col_len;
3649
templ->type = index->table->cols[i].mtype;
3650
templ->mysql_type = (ulint)field->type();
3652
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
3653
templ->mysql_length_bytes = (ulint)
3654
(((Field_varstring*)field)->length_bytes);
3657
templ->charset = dtype_get_charset_coll(
3658
index->table->cols[i].prtype);
3659
templ->mbminlen = index->table->cols[i].mbminlen;
3660
templ->mbmaxlen = index->table->cols[i].mbmaxlen;
3661
templ->is_unsigned = index->table->cols[i].prtype
3663
if (templ->type == DATA_BLOB) {
3664
prebuilt->templ_contains_blob = TRUE;
3670
prebuilt->n_template = n_requested_fields;
3671
prebuilt->mysql_prefix_len = mysql_prefix_len;
3673
if (index != clust_index && prebuilt->need_to_access_clustered) {
3674
/* Change rec_field_no's to correspond to the clustered index
3676
for (i = 0; i < n_requested_fields; i++) {
3677
templ = prebuilt->mysql_template + i;
3679
templ->rec_field_no = dict_col_get_clust_pos(
3680
&index->table->cols[templ->col_no],
3686
/************************************************************************
3687
This special handling is really to overcome the limitations of MySQL's
3688
binlogging. We need to eliminate the non-determinism that will arise in
3689
INSERT ... SELECT type of statements, since MySQL binlog only stores the
3690
min value of the autoinc interval. Once that is fixed we can get rid of
3691
the special lock handling.*/
3694
ha_innobase::innobase_autoinc_lock(void)
3695
/*====================================*/
3696
/* out: DB_SUCCESS if all OK else
3699
ulint error = DB_SUCCESS;
3701
switch (innobase_autoinc_lock_mode) {
3702
case AUTOINC_NO_LOCKING:
3703
/* Acquire only the AUTOINC mutex. */
3704
dict_table_autoinc_lock(prebuilt->table);
3707
case AUTOINC_NEW_STYLE_LOCKING:
3708
/* For simple (single/multi) row INSERTs, we fallback to the
3709
old style only if another transaction has already acquired
3710
the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
3711
etc. type of statement. */
3712
if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
3713
dict_table_t* table = prebuilt->table;
3715
/* Acquire the AUTOINC mutex. */
3716
dict_table_autoinc_lock(table);
3718
/* We need to check that another transaction isn't
3719
already holding the AUTOINC lock on the table. */
3720
if (table->n_waiting_or_granted_auto_inc_locks) {
3721
/* Release the mutex to avoid deadlocks. */
3722
dict_table_autoinc_unlock(table);
3727
/* Fall through to old style locking. */
3729
case AUTOINC_OLD_STYLE_LOCKING:
3730
error = row_lock_table_autoinc_for_mysql(prebuilt);
3732
if (error == DB_SUCCESS) {
3734
/* Acquire the AUTOINC mutex. */
3735
dict_table_autoinc_lock(prebuilt->table);
3743
return(ulong(error));
3746
/************************************************************************
3747
Reset the autoinc value in the table.*/
3750
ha_innobase::innobase_reset_autoinc(
3751
/*================================*/
3752
/* out: DB_SUCCESS if all went well
3754
ulonglong autoinc) /* in: value to store */
3758
error = innobase_autoinc_lock();
3760
if (error == DB_SUCCESS) {
3762
dict_table_autoinc_initialize(prebuilt->table, autoinc);
3764
dict_table_autoinc_unlock(prebuilt->table);
3767
return(ulong(error));
3770
/************************************************************************
3771
Store the autoinc value in the table. The autoinc value is only set if
3772
it's greater than the existing autoinc value in the table.*/
3775
ha_innobase::innobase_set_max_autoinc(
3776
/*==================================*/
3777
/* out: DB_SUCCES if all went well
3779
ulonglong auto_inc) /* in: value to store */
3783
error = innobase_autoinc_lock();
3785
if (error == DB_SUCCESS) {
3787
dict_table_autoinc_update(prebuilt->table, auto_inc);
3789
dict_table_autoinc_unlock(prebuilt->table);
3792
return(ulong(error));
3795
/************************************************************************
3796
Stores a row in an InnoDB database, to the table specified in this
3800
ha_innobase::write_row(
3801
/*===================*/
3802
/* out: error code */
3803
uchar* record) /* in: a row in MySQL format */
3806
ibool auto_inc_used= FALSE;
3808
trx_t* trx = thd_to_trx(user_thd);
3810
DBUG_ENTER("ha_innobase::write_row");
3812
if (prebuilt->trx != trx) {
3813
sql_print_error("The transaction object for the table handle is at "
3814
"%p, but for the current thread it is at %p",
3815
(const void*) prebuilt->trx, (const void*) trx);
3817
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
3818
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
3820
"InnoDB: Dump of 200 bytes around ha_data: ",
3822
ut_print_buf(stderr, ((const byte*) trx) - 100, 200);
3827
ha_statistic_increment(&SSV::ha_write_count);
3829
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
3830
table->timestamp_field->set_time();
3832
sql_command = thd_sql_command(user_thd);
3834
if ((sql_command == SQLCOM_ALTER_TABLE
3835
|| sql_command == SQLCOM_OPTIMIZE
3836
|| sql_command == SQLCOM_CREATE_INDEX
3837
|| sql_command == SQLCOM_DROP_INDEX)
3838
&& num_write_row >= 10000) {
3839
/* ALTER TABLE is COMMITted at every 10000 copied rows.
3840
The IX table lock for the original table has to be re-issued.
3841
As this method will be called on a temporary table where the
3842
contents of the original table is being copied to, it is
3843
a bit tricky to determine the source table. The cursor
3844
position in the source table need not be adjusted after the
3845
intermediate COMMIT, since writes by other transactions are
3846
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
3848
dict_table_t* src_table;
3849
enum lock_mode mode;
3853
/* Commit the transaction. This will release the table
3854
locks, so they have to be acquired again. */
3856
/* Altering an InnoDB table */
3857
/* Get the source table. */
3858
src_table = lock_get_src_table(
3859
prebuilt->trx, prebuilt->table, &mode);
3862
/* Unknown situation: do not commit */
3864
ut_print_timestamp(stderr);
3866
" InnoDB: ALTER TABLE is holding lock"
3867
" on %lu tables!\n",
3868
prebuilt->trx->mysql_n_tables_locked);
3871
} else if (src_table == prebuilt->table) {
3872
/* Source table is not in InnoDB format:
3873
no need to re-acquire locks on it. */
3875
/* Altering to InnoDB format */
3876
innobase_commit(ht, user_thd, 1);
3877
/* Note that this transaction is still active. */
3878
prebuilt->trx->active_trans = 1;
3879
/* We will need an IX lock on the destination table. */
3880
prebuilt->sql_stat_start = TRUE;
3882
/* Ensure that there are no other table locks than
3883
LOCK_IX and LOCK_AUTO_INC on the destination table. */
3885
if (!lock_is_table_exclusive(prebuilt->table,
3890
/* Commit the transaction. This will release the table
3891
locks, so they have to be acquired again. */
3892
innobase_commit(ht, user_thd, 1);
3893
/* Note that this transaction is still active. */
3894
prebuilt->trx->active_trans = 1;
3895
/* Re-acquire the table lock on the source table. */
3896
row_lock_table_for_mysql(prebuilt, src_table, mode);
3897
/* We will need an IX lock on the destination table. */
3898
prebuilt->sql_stat_start = TRUE;
3904
/* This is the case where the table has an auto-increment column */
3905
if (table->next_number_field && record == table->record[0]) {
3907
if ((error = update_auto_increment())) {
3912
auto_inc_used = TRUE;
3915
if (prebuilt->mysql_template == NULL
3916
|| prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
3918
/* Build the template used in converting quickly between
3919
the two database formats */
3921
build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
3924
innodb_srv_conc_enter_innodb(prebuilt->trx);
3926
error = row_insert_for_mysql((byte*) record, prebuilt);
3928
/* Handle duplicate key errors */
3929
if (auto_inc_used) {
3933
/* Note the number of rows processed for this statement, used
3934
by get_auto_increment() to determine the number of AUTO-INC
3935
values to reserve. This is only useful for a mult-value INSERT
3936
and is a statement level counter.*/
3937
if (trx->n_autoinc_rows > 0) {
3938
--trx->n_autoinc_rows;
3941
/* Get the value that MySQL attempted to store in the table.*/
3942
auto_inc = table->next_number_field->val_int();
3945
case DB_DUPLICATE_KEY:
3947
/* A REPLACE command and LOAD DATA INFILE REPLACE
3948
handle a duplicate key error themselves, but we
3949
must update the autoinc counter if we are performing
3950
those statements. */
3952
switch (sql_command) {
3954
if ((trx->duplicates
3955
& (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) {
3957
goto set_max_autoinc;
3961
case SQLCOM_REPLACE:
3962
case SQLCOM_INSERT_SELECT:
3963
case SQLCOM_REPLACE_SELECT:
3964
goto set_max_autoinc;
3973
/* If the actual value inserted is greater than
3974
the upper limit of the interval, then we try and
3975
update the table upper limit. Note: last_value
3976
will be 0 if get_auto_increment() was not called.*/
3978
if (auto_inc > prebuilt->last_value) {
3980
ut_a(prebuilt->table->autoinc_increment > 0);
3985
/* Check for overflow conditions. */
3986
need = prebuilt->table->autoinc_increment;
3987
have = ~0x0ULL - auto_inc;
3995
err = innobase_set_max_autoinc(auto_inc);
3997
if (err != DB_SUCCESS) {
4005
innodb_srv_conc_exit_innodb(prebuilt->trx);
4007
error = convert_error_code_to_mysql(error, prebuilt->table->flags,
4011
innobase_active_small();
4016
/**************************************************************************
4017
Checks which fields have changed in a row and stores information
4018
of them to an update vector. */
4021
calc_row_difference(
4022
/*================*/
4023
/* out: error number or 0 */
4024
upd_t* uvect, /* in/out: update vector */
4025
uchar* old_row, /* in: old row in MySQL format */
4026
uchar* new_row, /* in: new row in MySQL format */
4027
struct st_table* table, /* in: table in MySQL data
4029
uchar* upd_buff, /* in: buffer to use */
4030
ulint buff_len, /* in: buffer length */
4031
row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
4032
THD* thd) /* in: user thread */
4034
uchar* original_upd_buff = upd_buff;
4036
enum_field_types field_mysql_type;
4041
const byte* new_mysql_row_col;
4045
upd_field_t* ufield;
4047
ulint n_changed = 0;
4049
dict_index_t* clust_index;
4052
n_fields = table->s->fields;
4053
clust_index = dict_table_get_first_index(prebuilt->table);
4055
/* We use upd_buff to convert changed fields */
4056
buf = (byte*) upd_buff;
4058
for (i = 0; i < n_fields; i++) {
4059
field = table->field[i];
4061
o_ptr = (const byte*) old_row + get_field_offset(table, field);
4062
n_ptr = (const byte*) new_row + get_field_offset(table, field);
4064
/* Use new_mysql_row_col and col_pack_len save the values */
4066
new_mysql_row_col = n_ptr;
4067
col_pack_len = field->pack_length();
4069
o_len = col_pack_len;
4070
n_len = col_pack_len;
4072
/* We use o_ptr and n_ptr to dig up the actual data for
4075
field_mysql_type = field->type();
4077
col_type = prebuilt->table->cols[i].mtype;
4082
o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
4083
n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
4090
if (field_mysql_type == MYSQL_TYPE_VARCHAR) {
4091
/* This is a >= 5.0.3 type true VARCHAR where
4092
the real payload data length is stored in
4095
o_ptr = row_mysql_read_true_varchar(
4098
(((Field_varstring*)field)->length_bytes));
4100
n_ptr = row_mysql_read_true_varchar(
4103
(((Field_varstring*)field)->length_bytes));
4111
if (field->null_ptr) {
4112
if (field_in_record_is_null(table, field,
4114
o_len = UNIV_SQL_NULL;
4117
if (field_in_record_is_null(table, field,
4119
n_len = UNIV_SQL_NULL;
4123
if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
4124
0 != memcmp(o_ptr, n_ptr, o_len))) {
4125
/* The field has changed */
4127
ufield = uvect->fields + n_changed;
4129
/* Let us use a dummy dfield to make the conversion
4130
from the MySQL column format to the InnoDB format */
4132
dict_col_copy_type(prebuilt->table->cols + i,
4133
dfield_get_type(&dfield));
4135
if (n_len != UNIV_SQL_NULL) {
4136
buf = row_mysql_store_col_in_innobase_format(
4142
dict_table_is_comp(prebuilt->table));
4143
dfield_copy_data(&ufield->new_val, &dfield);
4145
dfield_set_null(&ufield->new_val);
4149
ufield->orig_len = 0;
4150
ufield->field_no = dict_col_get_clust_pos(
4151
&prebuilt->table->cols[i], clust_index);
4156
uvect->n_fields = n_changed;
4157
uvect->info_bits = 0;
4159
ut_a(buf <= (byte*)original_upd_buff + buff_len);
4164
/**************************************************************************
4165
Updates a row given as a parameter to a new value. Note that we are given
4166
whole rows, not just the fields which are updated: this incurs some
4167
overhead for CPU when we check which fields are actually updated.
4168
TODO: currently InnoDB does not prevent the 'Halloween problem':
4169
in a searched update a single row can get updated several times
4170
if its index columns are updated! */
4173
ha_innobase::update_row(
4174
/*====================*/
4175
/* out: error number or 0 */
4176
const uchar* old_row, /* in: old row in MySQL format */
4177
uchar* new_row) /* in: new row in MySQL format */
4181
trx_t* trx = thd_to_trx(user_thd);
4183
DBUG_ENTER("ha_innobase::update_row");
4185
ut_a(prebuilt->trx == trx);
4187
ha_statistic_increment(&SSV::ha_update_count);
4189
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
4190
table->timestamp_field->set_time();
4192
if (prebuilt->upd_node) {
4193
uvect = prebuilt->upd_node->update;
4195
uvect = row_get_prebuilt_update_vector(prebuilt);
4198
/* Build an update vector from the modified fields in the rows
4199
(uses upd_buff of the handle) */
4201
calc_row_difference(uvect, (uchar*) old_row, new_row, table,
4202
upd_buff, (ulint)upd_and_key_val_buff_len,
4203
prebuilt, user_thd);
4205
/* This is not a delete */
4206
prebuilt->upd_node->is_delete = FALSE;
4208
ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4210
innodb_srv_conc_enter_innodb(trx);
4212
error = row_update_for_mysql((byte*) old_row, prebuilt);
4214
/* We need to do some special AUTOINC handling for the following case:
4216
INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4218
We need to use the AUTOINC counter that was actually used by
4219
MySQL in the UPDATE statement, which can be different from the
4220
value used in the INSERT statement.*/
4222
if (error == DB_SUCCESS
4223
&& table->next_number_field
4224
&& new_row == table->record[0]
4225
&& thd_sql_command(user_thd) == SQLCOM_INSERT
4226
&& (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4227
== TRX_DUP_IGNORE) {
4231
auto_inc = table->next_number_field->val_int();
4233
if (auto_inc != 0) {
4234
auto_inc += prebuilt->table->autoinc_increment;
4236
error = innobase_set_max_autoinc(auto_inc);
4240
innodb_srv_conc_exit_innodb(trx);
4242
error = convert_error_code_to_mysql(error,
4243
prebuilt->table->flags, user_thd);
4245
if (error == 0 /* success */
4246
&& uvect->n_fields == 0 /* no columns were updated */) {
4248
/* This is the same as success, but instructs
4249
MySQL that the row is not really updated and it
4250
should not increase the count of updated rows.
4251
This is fix for http://bugs.mysql.com/29157 */
4252
error = HA_ERR_RECORD_IS_THE_SAME;
4255
/* Tell InnoDB server that there might be work for
4258
innobase_active_small();
4263
/**************************************************************************
4264
Deletes a row given as the parameter. */
4267
ha_innobase::delete_row(
4268
/*====================*/
4269
/* out: error number or 0 */
4270
const uchar* record) /* in: a row in MySQL format */
4273
trx_t* trx = thd_to_trx(user_thd);
4275
DBUG_ENTER("ha_innobase::delete_row");
4277
ut_a(prebuilt->trx == trx);
4279
ha_statistic_increment(&SSV::ha_delete_count);
4281
/* Only if the table has an AUTOINC column */
4282
if (table->found_next_number_field && record == table->record[0]) {
4283
ulonglong dummy = 0;
4285
/* First check whether the AUTOINC sub-system has been
4286
initialized using the AUTOINC mutex. If not then we
4287
do it the "proper" way, by acquiring the heavier locks. */
4288
dict_table_autoinc_lock(prebuilt->table);
4290
if (!prebuilt->table->autoinc_inited) {
4291
dict_table_autoinc_unlock(prebuilt->table);
4293
error = innobase_get_auto_increment(&dummy);
4295
if (error == DB_SUCCESS) {
4296
dict_table_autoinc_unlock(prebuilt->table);
4301
dict_table_autoinc_unlock(prebuilt->table);
4305
if (!prebuilt->upd_node) {
4306
row_get_prebuilt_update_vector(prebuilt);
4309
/* This is a delete */
4311
prebuilt->upd_node->is_delete = TRUE;
4313
innodb_srv_conc_enter_innodb(trx);
4315
error = row_update_for_mysql((byte*) record, prebuilt);
4317
innodb_srv_conc_exit_innodb(trx);
4320
error = convert_error_code_to_mysql(error,
4321
prebuilt->table->flags, user_thd);
4323
/* Tell the InnoDB server that there might be work for
4326
innobase_active_small();
4331
/**************************************************************************
4332
Removes a new lock set on a row, if it was not read optimistically. This can
4333
be called after a row has been read in the processing of an UPDATE or a DELETE
4334
query, if the option innodb_locks_unsafe_for_binlog is set. */
4337
ha_innobase::unlock_row(void)
4338
/*=========================*/
4340
DBUG_ENTER("ha_innobase::unlock_row");
4342
/* Consistent read does not take any locks, thus there is
4343
nothing to unlock. */
4345
if (prebuilt->select_lock_type == LOCK_NONE) {
4349
switch (prebuilt->row_read_type) {
4350
case ROW_READ_WITH_LOCKS:
4351
if (!srv_locks_unsafe_for_binlog
4352
|| prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED) {
4356
case ROW_READ_TRY_SEMI_CONSISTENT:
4357
row_unlock_for_mysql(prebuilt, FALSE);
4359
case ROW_READ_DID_SEMI_CONSISTENT:
4360
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4367
/* See handler.h and row0mysql.h for docs on this function. */
4370
ha_innobase::was_semi_consistent_read(void)
4371
/*=======================================*/
4373
return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT);
4376
/* See handler.h and row0mysql.h for docs on this function. */
4379
ha_innobase::try_semi_consistent_read(bool yes)
4380
/*===========================================*/
4382
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
4384
/* Row read type is set to semi consistent read if this was
4385
requested by the MySQL and either innodb_locks_unsafe_for_binlog
4386
option is used or this session is using READ COMMITTED isolation
4390
&& (srv_locks_unsafe_for_binlog
4391
|| prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
4392
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4394
prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
4398
#ifdef ROW_MERGE_IS_INDEX_USABLE
4399
/**********************************************************************
4400
Check if an index can be used by the optimizer. */
4403
ha_innobase::is_index_available(
4404
/*============================*/
4405
/* out: true if available else false*/
4406
uint keynr) /* in: index number to check */
4408
DBUG_ENTER("ha_innobase::is_index_available");
4410
if (table && keynr != MAX_KEY && table->s->keys > 0) {
4411
const dict_index_t* index;
4412
const KEY* key = table->key_info + keynr;
4414
ut_ad(user_thd == ha_thd());
4415
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4417
index = dict_table_get_index_on_name(
4418
prebuilt->table, key->name);
4420
if (!row_merge_is_index_usable(prebuilt->trx, index)) {
4428
#endif /* ROW_MERGE_IS_INDEX_USABLE */
4430
/**********************************************************************
4431
Initializes a handle to use an index. */
4434
ha_innobase::index_init(
4435
/*====================*/
4436
/* out: 0 or error number */
4437
uint keynr, /* in: key (index) number */
4438
bool sorted) /* in: 1 if result MUST be sorted according to index */
4440
DBUG_ENTER("index_init");
4442
DBUG_RETURN(change_active_index(keynr));
4445
/**********************************************************************
4446
Currently does nothing. */
4449
ha_innobase::index_end(void)
4450
/*========================*/
4453
DBUG_ENTER("index_end");
4454
active_index=MAX_KEY;
4458
/*************************************************************************
4459
Converts a search mode flag understood by MySQL to a flag understood
4463
convert_search_mode_to_innobase(
4464
/*============================*/
4465
enum ha_rkey_function find_flag)
4467
switch (find_flag) {
4468
case HA_READ_KEY_EXACT:
4469
/* this does not require the index to be UNIQUE */
4470
return(PAGE_CUR_GE);
4471
case HA_READ_KEY_OR_NEXT:
4472
return(PAGE_CUR_GE);
4473
case HA_READ_KEY_OR_PREV:
4474
return(PAGE_CUR_LE);
4475
case HA_READ_AFTER_KEY:
4477
case HA_READ_BEFORE_KEY:
4479
case HA_READ_PREFIX:
4480
return(PAGE_CUR_GE);
4481
case HA_READ_PREFIX_LAST:
4482
return(PAGE_CUR_LE);
4483
case HA_READ_PREFIX_LAST_OR_PREV:
4484
return(PAGE_CUR_LE);
4485
/* In MySQL-4.0 HA_READ_PREFIX and HA_READ_PREFIX_LAST always
4486
pass a complete-field prefix of a key value as the search
4487
tuple. I.e., it is not allowed that the last field would
4488
just contain n first bytes of the full field value.
4489
MySQL uses a 'padding' trick to convert LIKE 'abc%'
4490
type queries so that it can use as a search tuple
4491
a complete-field-prefix of a key value. Thus, the InnoDB
4492
search mode PAGE_CUR_LE_OR_EXTENDS is never used.
4493
TODO: when/if MySQL starts to use also partial-field
4494
prefixes, we have to deal with stripping of spaces
4495
and comparison of non-latin1 char type fields in
4496
innobase_mysql_cmp() to get PAGE_CUR_LE_OR_EXTENDS to
4498
case HA_READ_MBR_CONTAIN:
4499
case HA_READ_MBR_INTERSECT:
4500
case HA_READ_MBR_WITHIN:
4501
case HA_READ_MBR_DISJOINT:
4502
case HA_READ_MBR_EQUAL:
4503
my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0));
4504
return(PAGE_CUR_UNSUPP);
4505
/* do not use "default:" in order to produce a gcc warning:
4506
enumeration value '...' not handled in switch
4507
(if -Wswitch or -Wall is used) */
4510
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "this functionality");
4512
return(PAGE_CUR_UNSUPP);
4516
BACKGROUND INFO: HOW A SELECT SQL QUERY IS EXECUTED
4517
---------------------------------------------------
4518
The following does not cover all the details, but explains how we determine
4519
the start of a new SQL statement, and what is associated with it.
4521
For each table in the database the MySQL interpreter may have several
4522
table handle instances in use, also in a single SQL query. For each table
4523
handle instance there is an InnoDB 'prebuilt' struct which contains most
4524
of the InnoDB data associated with this table handle instance.
4526
A) if the user has not explicitly set any MySQL table level locks:
4528
1) MySQL calls ::external_lock to set an 'intention' table level lock on
4529
the table of the handle instance. There we set
4530
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
4531
true if we are taking this table handle instance to use in a new SQL
4532
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
4534
2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
4535
instructions to prebuilt->template of the table handle instance in
4536
::index_read. The template is used to save CPU time in large joins.
4538
3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
4539
allocate a new consistent read view for the trx if it does not yet have one,
4540
or in the case of a locking read, set an InnoDB 'intention' table level
4543
4) We do the SELECT. MySQL may repeatedly call ::index_read for the
4544
same table handle instance, if it is a join.
4546
5) When the SELECT ends, MySQL removes its intention table level locks
4547
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
4548
(a) we execute a COMMIT there if the autocommit is on,
4549
(b) we also release possible 'SQL statement level resources' InnoDB may
4550
have for this SQL statement. The MySQL interpreter does NOT execute
4551
autocommit for pure read transactions, though it should. That is why the
4552
table handler in that case has to execute the COMMIT in ::external_lock.
4554
B) If the user has explicitly set MySQL table level locks, then MySQL
4555
does NOT call ::external_lock at the start of the statement. To determine
4556
when we are at the start of a new SQL statement we at the start of
4557
::index_read also compare the query id to the latest query id where the
4558
table handle instance was used. If it has changed, we know we are at the
4559
start of a new SQL statement. Since the query id can theoretically
4560
overwrap, we use this test only as a secondary way of determining the
4561
start of a new SQL statement. */
4564
/**************************************************************************
4565
Positions an index cursor to the index specified in the handle. Fetches the
4569
ha_innobase::index_read(
4570
/*====================*/
4571
/* out: 0, HA_ERR_KEY_NOT_FOUND,
4573
uchar* buf, /* in/out: buffer for the returned
4575
const uchar* key_ptr, /* in: key value; if this is NULL
4576
we position the cursor at the
4577
start or end of index; this can
4578
also contain an InnoDB row id, in
4579
which case key_len is the InnoDB
4580
row id length; the key value can
4581
also be a prefix of a full key value,
4582
and the last column can be a prefix
4584
uint key_len,/* in: key value length */
4585
enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
4588
dict_index_t* index;
4589
ulint match_mode = 0;
4593
DBUG_ENTER("index_read");
4595
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4597
ha_statistic_increment(&SSV::ha_read_key_count);
4599
index = prebuilt->index;
4601
/* Note that if the index for which the search template is built is not
4602
necessarily prebuilt->index, but can also be the clustered index */
4604
if (prebuilt->sql_stat_start) {
4605
build_template(prebuilt, user_thd, table, ROW_MYSQL_REC_FIELDS);
4609
/* Convert the search key value to InnoDB format into
4610
prebuilt->search_tuple */
4612
row_sel_convert_mysql_key_to_innobase(
4613
prebuilt->search_tuple,
4614
(byte*) key_val_buff,
4615
(ulint)upd_and_key_val_buff_len,
4621
/* We position the cursor to the last or the first entry
4624
dtuple_set_n_fields(prebuilt->search_tuple, 0);
4627
mode = convert_search_mode_to_innobase(find_flag);
4631
if (find_flag == HA_READ_KEY_EXACT) {
4633
match_mode = ROW_SEL_EXACT;
4635
} else if (find_flag == HA_READ_PREFIX
4636
|| find_flag == HA_READ_PREFIX_LAST) {
4638
match_mode = ROW_SEL_EXACT_PREFIX;
4641
last_match_mode = (uint) match_mode;
4643
if (mode != PAGE_CUR_UNSUPP) {
4645
innodb_srv_conc_enter_innodb(prebuilt->trx);
4647
ret = row_search_for_mysql((byte*) buf, mode, prebuilt,
4650
innodb_srv_conc_exit_innodb(prebuilt->trx);
4653
ret = DB_UNSUPPORTED;
4661
case DB_RECORD_NOT_FOUND:
4662
error = HA_ERR_KEY_NOT_FOUND;
4663
table->status = STATUS_NOT_FOUND;
4665
case DB_END_OF_INDEX:
4666
error = HA_ERR_KEY_NOT_FOUND;
4667
table->status = STATUS_NOT_FOUND;
4670
error = convert_error_code_to_mysql((int) ret,
4671
prebuilt->table->flags,
4673
table->status = STATUS_NOT_FOUND;
4680
/***********************************************************************
4681
The following functions works like index_read, but it find the last
4682
row with the current key value or prefix. */
4685
ha_innobase::index_read_last(
4686
/*=========================*/
4687
/* out: 0, HA_ERR_KEY_NOT_FOUND, or an
4689
uchar* buf, /* out: fetched row */
4690
const uchar* key_ptr,/* in: key value, or a prefix of a full
4692
uint key_len)/* in: length of the key val or prefix
4695
return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
4698
/************************************************************************
4699
Get the index for a handle. Does not change active index.*/
4702
ha_innobase::innobase_get_index(
4703
/*============================*/
4704
/* out: NULL or index instance. */
4705
uint keynr) /* in: use this index; MAX_KEY means always
4706
clustered index, even if it was internally
4707
generated by InnoDB */
4710
dict_index_t* index = 0;
4712
DBUG_ENTER("innobase_get_index");
4713
ha_statistic_increment(&SSV::ha_read_key_count);
4715
ut_ad(user_thd == ha_thd());
4716
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4718
if (keynr != MAX_KEY && table->s->keys > 0) {
4719
key = table->key_info + keynr;
4721
index = dict_table_get_index_on_name(prebuilt->table,
4724
index = dict_table_get_first_index(prebuilt->table);
4729
"Innodb could not find key n:o %u with name %s "
4730
"from dict cache for table %s",
4731
keynr, key ? key->name : "NULL",
4732
prebuilt->table->name);
4738
/************************************************************************
4739
Changes the active index of a handle. */
4742
ha_innobase::change_active_index(
4743
/*=============================*/
4744
/* out: 0 or error code */
4745
uint keynr) /* in: use this index; MAX_KEY means always clustered
4746
index, even if it was internally generated by
4749
DBUG_ENTER("change_active_index");
4751
ut_ad(user_thd == ha_thd());
4752
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4754
active_index = keynr;
4756
prebuilt->index = innobase_get_index(keynr);
4758
if (UNIV_UNLIKELY(!prebuilt->index)) {
4759
sql_print_warning("InnoDB: change_active_index(%u) failed",
4764
ut_a(prebuilt->search_tuple != 0);
4766
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
4768
dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
4769
prebuilt->index->n_fields);
4771
/* MySQL changes the active index for a handle also during some
4772
queries, for example SELECT MAX(a), SUM(a) first retrieves the MAX()
4773
and then calculates the sum. Previously we played safe and used
4774
the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
4775
copying. Starting from MySQL-4.1 we use a more efficient flag here. */
4777
build_template(prebuilt, user_thd, table, ROW_MYSQL_REC_FIELDS);
4782
/**************************************************************************
4783
Positions an index cursor to the index specified in keynr. Fetches the
4785
/* ??? This is only used to read whole keys ??? */
4788
ha_innobase::index_read_idx(
4789
/*========================*/
4790
/* out: error number or 0 */
4791
uchar* buf, /* in/out: buffer for the returned
4793
uint keynr, /* in: use this index */
4794
const uchar* key, /* in: key value; if this is NULL
4795
we position the cursor at the
4796
start or end of index */
4797
uint key_len, /* in: key value length */
4798
enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
4800
if (change_active_index(keynr)) {
4805
return(index_read(buf, key, key_len, find_flag));
4808
/***************************************************************************
4809
Reads the next or previous row from a cursor, which must have previously been
4810
positioned using index_read. */
4813
ha_innobase::general_fetch(
4814
/*=======================*/
4815
/* out: 0, HA_ERR_END_OF_FILE, or error
4817
uchar* buf, /* in/out: buffer for next row in MySQL
4819
uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
4820
uint match_mode) /* in: 0, ROW_SEL_EXACT, or
4821
ROW_SEL_EXACT_PREFIX */
4826
DBUG_ENTER("general_fetch");
4828
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4830
innodb_srv_conc_enter_innodb(prebuilt->trx);
4832
ret = row_search_for_mysql(
4833
(byte*)buf, 0, prebuilt, match_mode, direction);
4835
innodb_srv_conc_exit_innodb(prebuilt->trx);
4842
case DB_RECORD_NOT_FOUND:
4843
error = HA_ERR_END_OF_FILE;
4844
table->status = STATUS_NOT_FOUND;
4846
case DB_END_OF_INDEX:
4847
error = HA_ERR_END_OF_FILE;
4848
table->status = STATUS_NOT_FOUND;
4851
error = convert_error_code_to_mysql(
4852
(int) ret, prebuilt->table->flags, user_thd);
4853
table->status = STATUS_NOT_FOUND;
4860
/***************************************************************************
4861
Reads the next row from a cursor, which must have previously been
4862
positioned using index_read. */
4865
ha_innobase::index_next(
4866
/*====================*/
4867
/* out: 0, HA_ERR_END_OF_FILE, or error
4869
uchar* buf) /* in/out: buffer for next row in MySQL
4872
ha_statistic_increment(&SSV::ha_read_next_count);
4874
return(general_fetch(buf, ROW_SEL_NEXT, 0));
4877
/***********************************************************************
4878
Reads the next row matching to the key value given as the parameter. */
4881
ha_innobase::index_next_same(
4882
/*=========================*/
4883
/* out: 0, HA_ERR_END_OF_FILE, or error
4885
uchar* buf, /* in/out: buffer for the row */
4886
const uchar* key, /* in: key value */
4887
uint keylen) /* in: key value length */
4889
ha_statistic_increment(&SSV::ha_read_next_count);
4891
return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
4894
/***************************************************************************
4895
Reads the previous row from a cursor, which must have previously been
4896
positioned using index_read. */
4899
ha_innobase::index_prev(
4900
/*====================*/
4901
/* out: 0, HA_ERR_END_OF_FILE, or error number */
4902
uchar* buf) /* in/out: buffer for previous row in MySQL format */
4904
ha_statistic_increment(&SSV::ha_read_prev_count);
4906
return(general_fetch(buf, ROW_SEL_PREV, 0));
4909
/************************************************************************
4910
Positions a cursor on the first record in an index and reads the
4911
corresponding row to buf. */
4914
ha_innobase::index_first(
4915
/*=====================*/
4916
/* out: 0, HA_ERR_END_OF_FILE, or error code */
4917
uchar* buf) /* in/out: buffer for the row */
4921
DBUG_ENTER("index_first");
4922
ha_statistic_increment(&SSV::ha_read_first_count);
4924
error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
4926
/* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
4928
if (error == HA_ERR_KEY_NOT_FOUND) {
4929
error = HA_ERR_END_OF_FILE;
4935
/************************************************************************
4936
Positions a cursor on the last record in an index and reads the
4937
corresponding row to buf. */
4940
ha_innobase::index_last(
4941
/*====================*/
4942
/* out: 0, HA_ERR_END_OF_FILE, or error code */
4943
uchar* buf) /* in/out: buffer for the row */
4947
DBUG_ENTER("index_last");
4948
ha_statistic_increment(&SSV::ha_read_last_count);
4950
error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
4952
/* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
4954
if (error == HA_ERR_KEY_NOT_FOUND) {
4955
error = HA_ERR_END_OF_FILE;
4961
/********************************************************************
4962
Initialize a table scan. */
4965
ha_innobase::rnd_init(
4966
/*==================*/
4967
/* out: 0 or error number */
4968
bool scan) /* in: TRUE if table/index scan FALSE otherwise */
4972
/* Store the active index value so that we can restore the original
4973
value after a scan */
4975
if (prebuilt->clust_index_was_generated) {
4976
err = change_active_index(MAX_KEY);
4978
err = change_active_index(primary_key);
4981
/* Don't use semi-consistent read in random row reads (by position).
4982
This means we must disable semi_consistent_read if scan is false */
4985
try_semi_consistent_read(0);
4993
/*********************************************************************
4994
Ends a table scan. */
4997
ha_innobase::rnd_end(void)
4998
/*======================*/
4999
/* out: 0 or error number */
5001
return(index_end());
5004
/*********************************************************************
5005
Reads the next row in a table scan (also used to read the FIRST row
5006
in a table scan). */
5009
ha_innobase::rnd_next(
5010
/*==================*/
5011
/* out: 0, HA_ERR_END_OF_FILE, or error number */
5012
uchar* buf) /* in/out: returns the row in this buffer,
5017
DBUG_ENTER("rnd_next");
5018
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
5020
if (start_of_scan) {
5021
error = index_first(buf);
5023
if (error == HA_ERR_KEY_NOT_FOUND) {
5024
error = HA_ERR_END_OF_FILE;
5029
error = general_fetch(buf, ROW_SEL_NEXT, 0);
5035
/**************************************************************************
5036
Fetches a row from the table based on a row reference. */
5039
ha_innobase::rnd_pos(
5040
/*=================*/
5041
/* out: 0, HA_ERR_KEY_NOT_FOUND, or error code */
5042
uchar* buf, /* in/out: buffer for the row */
5043
uchar* pos) /* in: primary key value of the row in the
5044
MySQL format, or the row id if the clustered
5045
index was internally generated by InnoDB; the
5046
length of data in pos has to be ref_length */
5049
uint keynr = active_index;
5050
DBUG_ENTER("rnd_pos");
5051
DBUG_DUMP("key", pos, ref_length);
5053
ha_statistic_increment(&SSV::ha_read_rnd_count);
5055
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
5057
if (prebuilt->clust_index_was_generated) {
5058
/* No primary key was defined for the table and we
5059
generated the clustered index from the row id: the
5060
row reference is the row id, not any key value
5061
that MySQL knows of */
5063
error = change_active_index(MAX_KEY);
5065
error = change_active_index(primary_key);
5069
DBUG_PRINT("error", ("Got error: %d", error));
5073
/* Note that we assume the length of the row reference is fixed
5074
for the table, and it is == ref_length */
5076
error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
5079
DBUG_PRINT("error", ("Got error: %d", error));
5082
change_active_index(keynr);
5087
/*************************************************************************
5088
Stores a reference to the current row to 'ref' field of the handle. Note
5089
that in the case where we have generated the clustered index for the
5090
table, the function parameter is illogical: we MUST ASSUME that 'record'
5091
is the current 'position' of the handle, because if row ref is actually
5092
the row id internally generated in InnoDB, then 'record' does not contain
5093
it. We just guess that the row id must be for the record where the handle
5094
was positioned the last time. */
5097
ha_innobase::position(
5098
/*==================*/
5099
const uchar* record) /* in: row in MySQL format */
5103
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
5105
if (prebuilt->clust_index_was_generated) {
5106
/* No primary key was defined for the table and we
5107
generated the clustered index from row id: the
5108
row reference will be the row id, not any key value
5109
that MySQL knows of */
5111
len = DATA_ROW_ID_LEN;
5113
memcpy(ref, prebuilt->row_id, len);
5115
len = store_key_val_for_row(primary_key, (char*)ref,
5116
ref_length, record);
5119
/* We assume that the 'ref' value len is always fixed for the same
5122
if (len != ref_length) {
5123
sql_print_error("Stored ref len is %lu, but table ref len is %lu",
5124
(ulong) len, (ulong) ref_length);
5128
/* limit innodb monitor access to users with PROCESS privilege.
5129
See http://bugs.mysql.com/32710 for expl. why we choose PROCESS. */
5130
#define IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name, thd) \
5131
(row_is_magic_monitor_table(table_name) \
5132
&& check_global_access(thd, PROCESS_ACL))
5134
/*********************************************************************
5135
Creates a table definition to an InnoDB database. */
5140
trx_t* trx, /* in: InnoDB transaction handle */
5141
TABLE* form, /* in: information on table
5142
columns and indexes */
5143
const char* table_name, /* in: table name */
5144
const char* path_of_temp_table,/* in: if this is a table explicitly
5145
created by the user with the
5146
TEMPORARY keyword, then this
5147
parameter is the dir path where the
5148
table should be placed if we create
5149
an .ibd file for it (no .ibd extension
5150
in the path, though); otherwise this
5152
ulint flags) /* in: table flags */
5155
dict_table_t* table;
5160
ulint nulls_allowed;
5161
ulint unsigned_type;
5163
ulint long_true_varchar;
5167
DBUG_ENTER("create_table_def");
5168
DBUG_PRINT("enter", ("table_name: %s", table_name));
5170
ut_a(trx->mysql_thd != NULL);
5171
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
5172
(THD*) trx->mysql_thd)) {
5173
DBUG_RETURN(HA_ERR_GENERIC);
5176
n_cols = form->s->fields;
5178
/* We pass 0 as the space id, and determine at a lower level the space
5179
id where to store the table */
5181
table = dict_mem_table_create(table_name, 0, n_cols, flags);
5183
if (path_of_temp_table) {
5184
table->dir_path_of_temp_table =
5185
mem_heap_strdup(table->heap, path_of_temp_table);
5188
for (i = 0; i < n_cols; i++) {
5189
field = form->field[i];
5191
col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5193
if (field->null_ptr) {
5196
nulls_allowed = DATA_NOT_NULL;
5199
if (field->binary()) {
5200
binary_type = DATA_BINARY_TYPE;
5207
if (dtype_is_string_type(col_type)) {
5209
charset_no = (ulint)field->charset()->number;
5211
ut_a(charset_no < 256); /* in data0type.h we assume
5212
that the number fits in one
5216
ut_a(field->type() < 256); /* we assume in dtype_form_prtype()
5217
that this fits in one byte */
5218
col_len = field->pack_length();
5220
/* The MySQL pack length contains 1 or 2 bytes length field
5221
for a true VARCHAR. Let us subtract that, so that the InnoDB
5222
column length in the InnoDB data dictionary is the real
5223
maximum byte length of the actual data. */
5225
long_true_varchar = 0;
5227
if (field->type() == MYSQL_TYPE_VARCHAR) {
5228
col_len -= ((Field_varstring*)field)->length_bytes;
5230
if (((Field_varstring*)field)->length_bytes == 2) {
5231
long_true_varchar = DATA_LONG_TRUE_VARCHAR;
5235
dict_mem_table_add_col(table, table->heap,
5236
(char*) field->field_name,
5239
(ulint)field->type()
5240
| nulls_allowed | unsigned_type
5241
| binary_type | long_true_varchar,
5246
error = row_create_table_for_mysql(table, trx);
5248
error = convert_error_code_to_mysql(error, flags, NULL);
5253
/*********************************************************************
5254
Creates an index in an InnoDB database. */
5259
trx_t* trx, /* in: InnoDB transaction handle */
5260
TABLE* form, /* in: information on table
5261
columns and indexes */
5262
ulint flags, /* in: InnoDB table flags */
5263
const char* table_name, /* in: table name */
5264
uint key_num) /* in: index number */
5267
dict_index_t* index;
5271
KEY_PART_INFO* key_part;
5278
ulint* field_lengths;
5280
DBUG_ENTER("create_index");
5282
key = form->key_info + key_num;
5284
n_fields = key->key_parts;
5288
if (key_num == form->s->primary_key) {
5289
ind_type = ind_type | DICT_CLUSTERED;
5292
if (key->flags & HA_NOSAME ) {
5293
ind_type = ind_type | DICT_UNIQUE;
5296
/* We pass 0 as the space id, and determine at a lower level the space
5297
id where to store the table */
5299
index = dict_mem_index_create(table_name, key->name, 0,
5300
ind_type, n_fields);
5302
field_lengths = (ulint*) my_malloc(sizeof(ulint) * n_fields,
5305
for (i = 0; i < n_fields; i++) {
5306
key_part = key->key_part + i;
5308
/* (The flag HA_PART_KEY_SEG denotes in MySQL a column prefix
5309
field in an index: we only store a specified number of first
5310
bytes of the column to the index field.) The flag does not
5311
seem to be properly set by MySQL. Let us fall back on testing
5312
the length of the key part versus the column. */
5315
for (j = 0; j < form->s->fields; j++) {
5317
field = form->field[j];
5319
if (0 == innobase_strcasecmp(
5321
key_part->field->field_name)) {
5322
/* Found the corresponding column */
5328
ut_a(j < form->s->fields);
5330
col_type = get_innobase_type_from_mysql_type(
5331
&is_unsigned, key_part->field);
5333
if (DATA_BLOB == col_type
5334
|| (key_part->length < field->pack_length()
5335
&& field->type() != MYSQL_TYPE_VARCHAR)
5336
|| (field->type() == MYSQL_TYPE_VARCHAR
5337
&& key_part->length < field->pack_length()
5338
- ((Field_varstring*)field)->length_bytes)) {
5340
prefix_len = key_part->length;
5342
if (col_type == DATA_INT
5343
|| col_type == DATA_FLOAT
5344
|| col_type == DATA_DOUBLE
5345
|| col_type == DATA_DECIMAL) {
5347
"MySQL is trying to create a column "
5348
"prefix index field, on an "
5349
"inappropriate data type. Table "
5350
"name %s, column name %s.",
5352
key_part->field->field_name);
5360
field_lengths[i] = key_part->length;
5362
dict_mem_index_add_field(index,
5363
(char*) key_part->field->field_name, prefix_len);
5366
/* Even though we've defined max_supported_key_part_length, we
5367
still do our own checking using field_lengths to be absolutely
5368
sure we don't create too long indexes. */
5369
error = row_create_index_for_mysql(index, trx, field_lengths);
5371
error = convert_error_code_to_mysql(error, flags, NULL);
5373
my_free(field_lengths, MYF(0));
5378
/*********************************************************************
5379
Creates an index to an InnoDB table when the user has defined no
5383
create_clustered_index_when_no_primary(
5384
/*===================================*/
5385
trx_t* trx, /* in: InnoDB transaction handle */
5386
ulint flags, /* in: InnoDB table flags */
5387
const char* table_name) /* in: table name */
5389
dict_index_t* index;
5392
/* We pass 0 as the space id, and determine at a lower level the space
5393
id where to store the table */
5395
index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
5396
0, DICT_CLUSTERED, 0);
5398
error = row_create_index_for_mysql(index, trx, NULL);
5400
error = convert_error_code_to_mysql(error, flags, NULL);
5405
/*********************************************************************
5406
Validates the create options. We may build on this function
5407
in future. For now, it checks two specifiers:
5408
KEY_BLOCK_SIZE and ROW_FORMAT
5409
If innodb_strict_mode is not set then this function is a no-op */
5412
create_options_are_valid(
5413
/*=====================*/
5414
/* out: TRUE if valid. */
5415
THD* thd, /* in: connection thread. */
5416
TABLE* form, /* in: information on table
5417
columns and indexes */
5418
HA_CREATE_INFO* create_info) /* in: create info. */
5420
ibool kbs_specified = FALSE;
5426
/* If innodb_strict_mode is not set don't do any validation. */
5427
if (!(THDVAR(thd, strict_mode))) {
5431
ut_ad(form != NULL);
5432
ut_ad(create_info != NULL);
5434
/* First check if KEY_BLOCK_SIZE was specified. */
5435
if (create_info->key_block_size
5436
|| (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
5438
kbs_specified = TRUE;
5439
switch (create_info->key_block_size) {
5448
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5449
ER_ILLEGAL_HA_CREATE_OPTION,
5451
" KEY_BLOCK_SIZE = %lu."
5453
" [1, 2, 4, 8, 16]",
5454
create_info->key_block_size);
5459
/* If KEY_BLOCK_SIZE was specified, check for its
5461
if (kbs_specified && !srv_file_per_table) {
5462
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5463
ER_ILLEGAL_HA_CREATE_OPTION,
5464
"InnoDB: KEY_BLOCK_SIZE"
5465
" requires innodb_file_per_table.");
5469
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
5470
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5471
ER_ILLEGAL_HA_CREATE_OPTION,
5472
"InnoDB: KEY_BLOCK_SIZE"
5473
" requires innodb_file_format >"
5478
/* Now check for ROW_FORMAT specifier. */
5479
if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
5480
switch (form->s->row_type) {
5481
const char* row_format_name;
5482
case ROW_TYPE_COMPRESSED:
5483
case ROW_TYPE_DYNAMIC:
5485
= form->s->row_type == ROW_TYPE_COMPRESSED
5489
/* These two ROW_FORMATs require
5490
srv_file_per_table and srv_file_format */
5491
if (!srv_file_per_table) {
5492
push_warning_printf(
5494
MYSQL_ERROR::WARN_LEVEL_ERROR,
5495
ER_ILLEGAL_HA_CREATE_OPTION,
5496
"InnoDB: ROW_FORMAT=%s"
5497
" requires innodb_file_per_table.",
5503
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
5504
push_warning_printf(
5506
MYSQL_ERROR::WARN_LEVEL_ERROR,
5507
ER_ILLEGAL_HA_CREATE_OPTION,
5508
"InnoDB: ROW_FORMAT=%s"
5509
" requires innodb_file_format >"
5515
/* Cannot specify KEY_BLOCK_SIZE with
5516
ROW_FORMAT = DYNAMIC.
5517
However, we do allow COMPRESSED to be
5518
specified with KEY_BLOCK_SIZE. */
5520
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
5521
push_warning_printf(
5523
MYSQL_ERROR::WARN_LEVEL_ERROR,
5524
ER_ILLEGAL_HA_CREATE_OPTION,
5525
"InnoDB: cannot specify"
5526
" ROW_FORMAT = DYNAMIC with"
5527
" KEY_BLOCK_SIZE.");
5533
case ROW_TYPE_REDUNDANT:
5534
case ROW_TYPE_COMPACT:
5535
case ROW_TYPE_DEFAULT:
5536
/* Default is COMPACT. */
5538
= form->s->row_type == ROW_TYPE_REDUNDANT
5542
/* Cannot specify KEY_BLOCK_SIZE with these
5543
format specifiers. */
5544
if (kbs_specified) {
5545
push_warning_printf(
5547
MYSQL_ERROR::WARN_LEVEL_ERROR,
5548
ER_ILLEGAL_HA_CREATE_OPTION,
5549
"InnoDB: cannot specify"
5550
" ROW_FORMAT = %s with"
5560
MYSQL_ERROR::WARN_LEVEL_ERROR,
5561
ER_ILLEGAL_HA_CREATE_OPTION,
5562
"InnoDB: invalid ROW_FORMAT specifier.");
5571
/*********************************************************************
5572
Update create_info. Used in SHOW CREATE TABLE et al. */
5575
ha_innobase::update_create_info(
5576
/*============================*/
5577
HA_CREATE_INFO* create_info) /* in/out: create info */
5579
if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
5580
ha_innobase::info(HA_STATUS_AUTO);
5581
create_info->auto_increment_value = stats.auto_increment_value;
5585
/*********************************************************************
5586
Creates a new table to an InnoDB database. */
5589
ha_innobase::create(
5590
/*================*/
5591
/* out: error number */
5592
const char* name, /* in: table name */
5593
TABLE* form, /* in: information on table
5594
columns and indexes */
5595
HA_CREATE_INFO* create_info) /* in: more information of the
5596
created table, contains also the
5597
create statement string */
5600
dict_table_t* innobase_table;
5605
char name2[FN_REFLEN];
5606
char norm_name[FN_REFLEN];
5607
THD* thd = ha_thd();
5608
ib_int64_t auto_inc_value;
5610
/* Cache the value of innodb_file_format, in case it is
5611
modified by another thread while the table is being created. */
5612
const ulint file_format = srv_file_format;
5614
DBUG_ENTER("ha_innobase::create");
5616
DBUG_ASSERT(thd != NULL);
5618
if (form->s->fields > 1000) {
5619
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
5620
but we play safe here */
5622
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
5625
/* Get the transaction associated with the current thd, or create one
5626
if not yet created */
5628
parent_trx = check_trx_exists(thd);
5630
/* In case MySQL calls this in the middle of a SELECT query, release
5631
possible adaptive hash latch to avoid deadlocks of threads */
5633
trx_search_latch_release_if_reserved(parent_trx);
5635
trx = trx_allocate_for_mysql();
5637
trx->mysql_thd = thd;
5638
trx->mysql_query_str = thd_query(thd);
5640
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5641
trx->check_foreigns = FALSE;
5644
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
5645
trx->check_unique_secondary = FALSE;
5648
if (lower_case_table_names) {
5649
srv_lower_case_table_names = TRUE;
5651
srv_lower_case_table_names = FALSE;
5654
strcpy(name2, name);
5656
normalize_table_name(norm_name, name2);
5658
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
5659
or lock waits can happen in it during a table create operation.
5660
Drop table etc. do this latching in row0mysql.c. */
5662
row_mysql_lock_data_dictionary(trx);
5664
/* Create the table definition in InnoDB */
5668
/* Validate create options if innodb_strict_mode is set. */
5669
if (!create_options_are_valid(thd, form, create_info)) {
5670
error = ER_ILLEGAL_HA_CREATE_OPTION;
5674
if (create_info->key_block_size
5675
|| (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
5676
switch (create_info->key_block_size) {
5678
flags = 1 << DICT_TF_ZSSIZE_SHIFT
5680
| DICT_TF_FORMAT_ZIP
5681
<< DICT_TF_FORMAT_SHIFT;
5684
flags = 2 << DICT_TF_ZSSIZE_SHIFT
5686
| DICT_TF_FORMAT_ZIP
5687
<< DICT_TF_FORMAT_SHIFT;
5690
flags = 3 << DICT_TF_ZSSIZE_SHIFT
5692
| DICT_TF_FORMAT_ZIP
5693
<< DICT_TF_FORMAT_SHIFT;
5696
flags = 4 << DICT_TF_ZSSIZE_SHIFT
5698
| DICT_TF_FORMAT_ZIP
5699
<< DICT_TF_FORMAT_SHIFT;
5702
flags = 5 << DICT_TF_ZSSIZE_SHIFT
5704
| DICT_TF_FORMAT_ZIP
5705
<< DICT_TF_FORMAT_SHIFT;
5707
#if DICT_TF_ZSSIZE_MAX != 5
5708
# error "DICT_TF_ZSSIZE_MAX != 5"
5712
if (!srv_file_per_table) {
5713
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
5714
ER_ILLEGAL_HA_CREATE_OPTION,
5715
"InnoDB: KEY_BLOCK_SIZE"
5716
" requires innodb_file_per_table.");
5720
if (file_format < DICT_TF_FORMAT_ZIP) {
5721
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
5722
ER_ILLEGAL_HA_CREATE_OPTION,
5723
"InnoDB: KEY_BLOCK_SIZE"
5724
" requires innodb_file_format >"
5730
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
5731
ER_ILLEGAL_HA_CREATE_OPTION,
5733
" KEY_BLOCK_SIZE=%lu.",
5734
create_info->key_block_size);
5738
if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
5740
/* KEY_BLOCK_SIZE was specified. */
5741
if (form->s->row_type != ROW_TYPE_COMPRESSED) {
5742
/* ROW_FORMAT other than COMPRESSED
5743
ignores KEY_BLOCK_SIZE. It does not
5744
make sense to reject conflicting
5745
KEY_BLOCK_SIZE and ROW_FORMAT, because
5746
such combinations can be obtained
5747
with ALTER TABLE anyway. */
5748
push_warning_printf(
5750
MYSQL_ERROR::WARN_LEVEL_WARN,
5751
ER_ILLEGAL_HA_CREATE_OPTION,
5752
"InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
5753
" unless ROW_FORMAT=COMPRESSED.",
5754
create_info->key_block_size);
5758
/* No KEY_BLOCK_SIZE */
5759
if (form->s->row_type == ROW_TYPE_COMPRESSED) {
5760
/* ROW_FORMAT=COMPRESSED without
5761
KEY_BLOCK_SIZE implies
5762
KEY_BLOCK_SIZE=8. */
5763
flags = 4 << DICT_TF_ZSSIZE_SHIFT
5765
| DICT_TF_FORMAT_ZIP
5766
<< DICT_TF_FORMAT_SHIFT;
5770
switch (form->s->row_type) {
5771
const char* row_format_name;
5772
case ROW_TYPE_REDUNDANT:
5774
case ROW_TYPE_COMPRESSED:
5775
case ROW_TYPE_DYNAMIC:
5777
= form->s->row_type == ROW_TYPE_COMPRESSED
5781
if (!srv_file_per_table) {
5782
push_warning_printf(
5784
MYSQL_ERROR::WARN_LEVEL_WARN,
5785
ER_ILLEGAL_HA_CREATE_OPTION,
5786
"InnoDB: ROW_FORMAT=%s"
5787
" requires innodb_file_per_table.",
5789
} else if (file_format < DICT_TF_FORMAT_ZIP) {
5790
push_warning_printf(
5792
MYSQL_ERROR::WARN_LEVEL_WARN,
5793
ER_ILLEGAL_HA_CREATE_OPTION,
5794
"InnoDB: ROW_FORMAT=%s"
5795
" requires innodb_file_format >"
5799
flags |= DICT_TF_COMPACT
5800
| (DICT_TF_FORMAT_ZIP
5801
<< DICT_TF_FORMAT_SHIFT);
5806
case ROW_TYPE_NOT_USED:
5807
case ROW_TYPE_FIXED:
5810
MYSQL_ERROR::WARN_LEVEL_WARN,
5811
ER_ILLEGAL_HA_CREATE_OPTION,
5812
"InnoDB: assuming ROW_FORMAT=COMPACT.");
5813
case ROW_TYPE_DEFAULT:
5814
case ROW_TYPE_COMPACT:
5815
flags = DICT_TF_COMPACT;
5818
} else if (!flags) {
5819
/* No KEY_BLOCK_SIZE or ROW_FORMAT specified:
5820
use ROW_FORMAT=COMPACT by default. */
5821
flags = DICT_TF_COMPACT;
5824
error = create_table_def(trx, form, norm_name,
5825
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
5832
/* Look for a primary key */
5834
primary_key_no= (form->s->primary_key != MAX_KEY ?
5835
(int) form->s->primary_key :
5838
/* Our function row_get_mysql_key_number_for_index assumes
5839
the primary key is always number 0, if it exists */
5841
DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
5843
/* Create the keys */
5845
if (form->s->keys == 0 || primary_key_no == -1) {
5846
/* Create an index which is used as the clustered index;
5847
order the rows by their row id which is internally generated
5850
error = create_clustered_index_when_no_primary(
5851
trx, flags, norm_name);
5857
if (primary_key_no != -1) {
5858
/* In InnoDB the clustered index must always be created
5860
if ((error = create_index(trx, form, flags, norm_name,
5861
(uint) primary_key_no))) {
5866
for (i = 0; i < form->s->keys; i++) {
5868
if (i != (uint) primary_key_no) {
5870
if ((error = create_index(trx, form, flags, norm_name,
5877
if (*trx->mysql_query_str) {
5878
error = row_table_add_foreign_constraints(trx,
5879
*trx->mysql_query_str, norm_name,
5880
create_info->options & HA_LEX_CREATE_TMP_TABLE);
5882
error = convert_error_code_to_mysql(error, flags, NULL);
5889
innobase_commit_low(trx);
5891
row_mysql_unlock_data_dictionary(trx);
5893
/* Flush the log to reduce probability that the .frm files and
5894
the InnoDB data dictionary get out-of-sync if the user runs
5895
with innodb_flush_log_at_trx_commit = 0 */
5897
log_buffer_flush_to_disk();
5899
innobase_table = dict_table_get(norm_name, FALSE);
5901
DBUG_ASSERT(innobase_table != 0);
5903
/* We update the highest file format in the system table
5904
space, if this table has a higher file format setting. */
5906
trx_sys_file_format_max_update(flags, &innobase_file_format_check);
5908
/* Note: We can't call update_thd() as prebuilt will not be
5909
setup at this stage and so we use thd. */
5911
/* We need to copy the AUTOINC value from the old table if
5912
this is an ALTER TABLE. */
5914
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
5915
|| thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
5916
&& create_info->auto_increment_value != 0) {
5918
/* Query was ALTER TABLE...AUTO_INCREMENT = x; or
5919
CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
5920
definition from the dictionary and get the current value
5921
of the auto increment field. Set a new value to the
5922
auto increment field if the value is greater than the
5923
maximum value in the column. */
5925
auto_inc_value = create_info->auto_increment_value;
5927
dict_table_autoinc_lock(innobase_table);
5928
dict_table_autoinc_initialize(innobase_table, auto_inc_value);
5929
dict_table_autoinc_unlock(innobase_table);
5932
/* Tell the InnoDB server that there might be work for
5935
srv_active_wake_master_thread();
5937
trx_free_for_mysql(trx);
5942
innobase_commit_low(trx);
5944
row_mysql_unlock_data_dictionary(trx);
5946
trx_free_for_mysql(trx);
5951
/*********************************************************************
5952
Discards or imports an InnoDB tablespace. */
5955
ha_innobase::discard_or_import_tablespace(
5956
/*======================================*/
5957
/* out: 0 == success, -1 == error */
5958
my_bool discard) /* in: TRUE if discard, else import */
5960
dict_table_t* dict_table;
5964
DBUG_ENTER("ha_innobase::discard_or_import_tablespace");
5966
ut_a(prebuilt->trx);
5967
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
5968
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
5970
dict_table = prebuilt->table;
5971
trx = prebuilt->trx;
5974
err = row_discard_tablespace_for_mysql(dict_table->name, trx);
5976
err = row_import_tablespace_for_mysql(dict_table->name, trx);
5979
err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
5984
/*********************************************************************
5985
Deletes all rows of an InnoDB table. */
5988
ha_innobase::delete_all_rows(void)
5989
/*==============================*/
5990
/* out: error number */
5994
DBUG_ENTER("ha_innobase::delete_all_rows");
5996
/* Get the transaction associated with the current thd, or create one
5997
if not yet created, and update prebuilt->trx */
5999
update_thd(ha_thd());
6001
if (thd_sql_command(user_thd) != SQLCOM_TRUNCATE) {
6003
/* We only handle TRUNCATE TABLE t as a special case.
6004
DELETE FROM t will have to use ha_innobase::delete_row(). */
6005
DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
6008
/* Truncate the table in InnoDB */
6010
error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
6011
if (error == DB_ERROR) {
6012
/* Cannot truncate; resort to ha_innobase::delete_row() */
6016
error = convert_error_code_to_mysql(error, prebuilt->table->flags,
6022
/*********************************************************************
6023
Drops a table from an InnoDB database. Before calling this function,
6024
MySQL calls innobase_commit to commit the transaction of the current user.
6025
Then the current user cannot have locks set on the table. Drop table
6026
operation inside InnoDB will remove all locks any user has on the table
6030
ha_innobase::delete_table(
6031
/*======================*/
6032
/* out: error number */
6033
const char* name) /* in: table name */
6039
THD *thd = ha_thd();
6040
char norm_name[1000];
6042
DBUG_ENTER("ha_innobase::delete_table");
6044
/* Strangely, MySQL passes the table name without the '.frm'
6045
extension, in contrast to ::create */
6046
normalize_table_name(norm_name, name);
6048
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
6049
DBUG_RETURN(HA_ERR_GENERIC);
6052
/* Get the transaction associated with the current thd, or create one
6053
if not yet created */
6055
parent_trx = check_trx_exists(thd);
6057
/* In case MySQL calls this in the middle of a SELECT query, release
6058
possible adaptive hash latch to avoid deadlocks of threads */
6060
trx_search_latch_release_if_reserved(parent_trx);
6062
if (lower_case_table_names) {
6063
srv_lower_case_table_names = TRUE;
6065
srv_lower_case_table_names = FALSE;
6068
trx = trx_allocate_for_mysql();
6070
trx->mysql_thd = thd;
6071
trx->mysql_query_str = thd_query(thd);
6073
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
6074
trx->check_foreigns = FALSE;
6077
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
6078
trx->check_unique_secondary = FALSE;
6081
name_len = strlen(name);
6083
ut_a(name_len < 1000);
6085
/* Drop the table in InnoDB */
6087
error = row_drop_table_for_mysql(norm_name, trx,
6088
thd_sql_command(thd)
6091
/* Flush the log to reduce probability that the .frm files and
6092
the InnoDB data dictionary get out-of-sync if the user runs
6093
with innodb_flush_log_at_trx_commit = 0 */
6095
log_buffer_flush_to_disk();
6097
/* Tell the InnoDB server that there might be work for
6100
srv_active_wake_master_thread();
6102
innobase_commit_low(trx);
6104
trx_free_for_mysql(trx);
6106
error = convert_error_code_to_mysql(error, 0, NULL);
6111
/*********************************************************************
6112
Removes all tables in the named database inside InnoDB. */
6115
innobase_drop_database(
6116
/*===================*/
6117
/* out: error number */
6118
handlerton *hton, /* in: handlerton of Innodb */
6119
char* path) /* in: database path; inside InnoDB the name
6120
of the last directory in the path is used as
6121
the database name: for example, in 'mysql/data/test'
6122
the database name is 'test' */
6130
THD* thd = current_thd;
6132
/* Get the transaction associated with the current thd, or create one
6133
if not yet created */
6135
DBUG_ASSERT(hton == innodb_hton_ptr);
6137
parent_trx = check_trx_exists(thd);
6139
/* In case MySQL calls this in the middle of a SELECT query, release
6140
possible adaptive hash latch to avoid deadlocks of threads */
6142
trx_search_latch_release_if_reserved(parent_trx);
6144
ptr = strend(path) - 2;
6146
while (ptr >= path && *ptr != '\\' && *ptr != '/') {
6152
namebuf = (char*) my_malloc((uint) len + 2, MYF(0));
6154
memcpy(namebuf, ptr, len);
6156
namebuf[len + 1] = '\0';
6158
innobase_casedn_str(namebuf);
6160
trx = trx_allocate_for_mysql();
6161
trx->mysql_thd = thd;
6162
trx->mysql_query_str = thd_query(thd);
6164
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
6165
trx->check_foreigns = FALSE;
6168
error = row_drop_database_for_mysql(namebuf, trx);
6169
my_free(namebuf, MYF(0));
6171
/* Flush the log to reduce probability that the .frm files and
6172
the InnoDB data dictionary get out-of-sync if the user runs
6173
with innodb_flush_log_at_trx_commit = 0 */
6175
log_buffer_flush_to_disk();
6177
/* Tell the InnoDB server that there might be work for
6180
srv_active_wake_master_thread();
6182
innobase_commit_low(trx);
6183
trx_free_for_mysql(trx);
6185
/*************************************************************************
6186
Renames an InnoDB table. */
6189
innobase_rename_table(
6190
/*==================*/
6191
/* out: 0 or error code */
6192
trx_t* trx, /* in: transaction */
6193
const char* from, /* in: old name of the table */
6194
const char* to, /* in: new name of the table */
6195
ibool lock_and_commit)
6196
/* in: TRUE=lock data dictionary and commit */
6202
if (lower_case_table_names) {
6203
srv_lower_case_table_names = TRUE;
6205
srv_lower_case_table_names = FALSE;
6208
// Magic number 64 arbitrary
6209
norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0));
6210
norm_from = (char*) my_malloc(strlen(from) + 64, MYF(0));
6212
normalize_table_name(norm_to, to);
6213
normalize_table_name(norm_from, from);
6215
/* Serialize data dictionary operations with dictionary mutex:
6216
no deadlocks can occur then in these operations */
6218
if (lock_and_commit) {
6219
row_mysql_lock_data_dictionary(trx);
6222
error = row_rename_table_for_mysql(
6223
norm_from, norm_to, trx, lock_and_commit);
6225
if (error != DB_SUCCESS) {
6226
FILE* ef = dict_foreign_err_file;
6228
fputs("InnoDB: Renaming table ", ef);
6229
ut_print_name(ef, trx, TRUE, norm_from);
6231
ut_print_name(ef, trx, TRUE, norm_to);
6232
fputs(" failed!\n", ef);
6235
if (lock_and_commit) {
6236
row_mysql_unlock_data_dictionary(trx);
6238
/* Flush the log to reduce probability that the .frm
6239
files and the InnoDB data dictionary get out-of-sync
6240
if the user runs with innodb_flush_log_at_trx_commit = 0 */
6242
log_buffer_flush_to_disk();
6245
my_free(norm_to, MYF(0));
6246
my_free(norm_from, MYF(0));
6250
/*************************************************************************
6251
Renames an InnoDB table. */
6254
ha_innobase::rename_table(
6255
/*======================*/
6256
/* out: 0 or error code */
6257
const char* from, /* in: old name of the table */
6258
const char* to) /* in: new name of the table */
6263
THD* thd = ha_thd();
6265
DBUG_ENTER("ha_innobase::rename_table");
6267
/* Get the transaction associated with the current thd, or create one
6268
if not yet created */
6270
parent_trx = check_trx_exists(thd);
6272
/* In case MySQL calls this in the middle of a SELECT query, release
6273
possible adaptive hash latch to avoid deadlocks of threads */
6275
trx_search_latch_release_if_reserved(parent_trx);
6277
trx = trx_allocate_for_mysql();
6278
trx->mysql_thd = thd;
6279
trx->mysql_query_str = thd_query(thd);
6281
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
6282
trx->check_foreigns = FALSE;
6285
error = innobase_rename_table(trx, from, to, TRUE);
6287
/* Tell the InnoDB server that there might be work for
6290
srv_active_wake_master_thread();
6292
innobase_commit_low(trx);
6293
trx_free_for_mysql(trx);
6295
error = convert_error_code_to_mysql(error, 0, NULL);
6300
/*************************************************************************
6301
Estimates the number of index records in a range. */
6304
ha_innobase::records_in_range(
6305
/*==========================*/
6306
/* out: estimated number of
6308
uint keynr, /* in: index number */
6309
key_range *min_key, /* in: start key value of the
6310
range, may also be 0 */
6311
key_range *max_key) /* in: range end key val, may
6315
dict_index_t* index;
6316
uchar* key_val_buff2 = (uchar*) my_malloc(
6318
+ table->s->max_key_length + 100,
6320
ulint buff2_len = table->s->reclength
6321
+ table->s->max_key_length + 100;
6322
dtuple_t* range_start;
6323
dtuple_t* range_end;
6329
DBUG_ENTER("records_in_range");
6331
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
6333
prebuilt->trx->op_info = (char*)"estimating records in index range";
6335
/* In case MySQL calls this in the middle of a SELECT query, release
6336
possible adaptive hash latch to avoid deadlocks of threads */
6338
trx_search_latch_release_if_reserved(prebuilt->trx);
6340
active_index = keynr;
6342
key = table->key_info + active_index;
6344
index = dict_table_get_index_on_name(prebuilt->table, key->name);
6346
/* MySQL knows about this index and so we must be able to find it.*/
6349
heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6350
+ sizeof(dtuple_t)));
6352
range_start = dtuple_create(heap, key->key_parts);
6353
dict_index_copy_types(range_start, index, key->key_parts);
6355
range_end = dtuple_create(heap, key->key_parts);
6356
dict_index_copy_types(range_end, index, key->key_parts);
6358
row_sel_convert_mysql_key_to_innobase(
6359
range_start, (byte*) key_val_buff,
6360
(ulint)upd_and_key_val_buff_len,
6362
(byte*) (min_key ? min_key->key :
6364
(ulint) (min_key ? min_key->length : 0),
6367
row_sel_convert_mysql_key_to_innobase(
6368
range_end, (byte*) key_val_buff2,
6370
(byte*) (max_key ? max_key->key :
6372
(ulint) (max_key ? max_key->length : 0),
6375
mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
6377
mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag :
6380
if (mode1 != PAGE_CUR_UNSUPP && mode2 != PAGE_CUR_UNSUPP) {
6382
n_rows = btr_estimate_n_rows_in_range(index, range_start,
6390
mem_heap_free(heap);
6392
my_free(key_val_buff2, MYF(0));
6394
prebuilt->trx->op_info = (char*)"";
6396
/* The MySQL optimizer seems to believe an estimate of 0 rows is
6397
always accurate and may return the result 'Empty set' based on that.
6398
The accuracy is not guaranteed, and even if it were, for a locking
6399
read we should anyway perform the search to set the next-key lock.
6400
Add 1 to the value to make sure MySQL does not make the assumption! */
6406
DBUG_RETURN((ha_rows) n_rows);
6409
/*************************************************************************
6410
Gives an UPPER BOUND to the number of rows in a table. This is used in
6414
ha_innobase::estimate_rows_upper_bound(void)
6415
/*======================================*/
6416
/* out: upper bound of rows */
6418
dict_index_t* index;
6420
ulonglong local_data_file_length;
6422
DBUG_ENTER("estimate_rows_upper_bound");
6424
/* We do not know if MySQL can call this function before calling
6425
external_lock(). To be safe, update the thd of the current table
6428
update_thd(ha_thd());
6430
prebuilt->trx->op_info = (char*)
6431
"calculating upper bound for table rows";
6433
/* In case MySQL calls this in the middle of a SELECT query, release
6434
possible adaptive hash latch to avoid deadlocks of threads */
6436
trx_search_latch_release_if_reserved(prebuilt->trx);
6438
index = dict_table_get_first_index(prebuilt->table);
6440
ut_a(index->stat_n_leaf_pages > 0);
6442
local_data_file_length =
6443
((ulonglong) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6446
/* Calculate a minimum length for a clustered index record and from
6447
that an upper bound for the number of rows. Since we only calculate
6448
new statistics in row0mysql.c when a table has grown by a threshold
6449
factor, we must add a safety factor 2 in front of the formula below. */
6451
estimate = 2 * local_data_file_length /
6452
dict_index_calc_min_rec_len(index);
6454
prebuilt->trx->op_info = (char*)"";
6456
DBUG_RETURN((ha_rows) estimate);
6459
/*************************************************************************
6460
How many seeks it will take to read through the table. This is to be
6461
comparable to the number returned by records_in_range so that we can
6462
decide if we should scan the table or use keys. */
6465
ha_innobase::scan_time()
6466
/*====================*/
6467
/* out: estimated time measured in disk seeks */
6469
/* Since MySQL seems to favor table scans too much over index
6470
searches, we pretend that a sequential read takes the same time
6471
as a random disk read, that is, we do not divide the following
6472
by 10, which would be physically realistic. */
6474
return((double) (prebuilt->table->stat_clustered_index_size));
6477
/**********************************************************************
6478
Calculate the time it takes to read a set of ranges through an index
6479
This enables us to optimise reads for clustered indexes. */
6482
ha_innobase::read_time(
6483
/*===================*/
6484
/* out: estimated time measured in disk seeks */
6485
uint index, /* in: key number */
6486
uint ranges, /* in: how many ranges */
6487
ha_rows rows) /* in: estimated number of rows in the ranges */
6490
double time_for_scan;
6492
if (index != table->s->primary_key) {
6494
return(handler::read_time(index, ranges, rows));
6499
return((double) rows);
6502
/* Assume that the read time is proportional to the scan time for all
6503
rows + at most one seek per range. */
6505
time_for_scan = scan_time();
6507
if ((total_rows = estimate_rows_upper_bound()) < rows) {
6509
return(time_for_scan);
6512
return(ranges + (double) rows / (double) total_rows * time_for_scan);
6515
/*************************************************************************
6516
Returns statistics information of the table to the MySQL interpreter,
6517
in various fields of the handle object. */
6522
uint flag) /* in: what information MySQL requests */
6524
dict_table_t* ib_table;
6525
dict_index_t* index;
6526
ha_rows rec_per_key;
6530
char path[FN_REFLEN];
6531
os_file_stat_t stat_info;
6535
/* If we are forcing recovery at a high level, we will suppress
6536
statistics calculation on tables, because that may crash the
6537
server if an index is badly corrupted. */
6539
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
6541
/* We return success (0) instead of HA_ERR_CRASHED,
6542
because we want MySQL to process this query and not
6543
stop, like it would do if it received the error code
6549
/* We do not know if MySQL can call this function before calling
6550
external_lock(). To be safe, update the thd of the current table
6553
update_thd(ha_thd());
6555
/* In case MySQL calls this in the middle of a SELECT query, release
6556
possible adaptive hash latch to avoid deadlocks of threads */
6558
prebuilt->trx->op_info = (char*)"returning various info to MySQL";
6560
trx_search_latch_release_if_reserved(prebuilt->trx);
6562
ib_table = prebuilt->table;
6564
if (flag & HA_STATUS_TIME) {
6565
if (srv_stats_on_metadata) {
6566
/* In sql_show we call with this flag: update
6567
then statistics so that they are up-to-date */
6569
prebuilt->trx->op_info = "updating table statistics";
6571
dict_update_statistics(ib_table);
6573
prebuilt->trx->op_info = "returning various info to MySQL";
6576
my_snprintf(path, sizeof(path), "%s/%s%s",
6577
mysql_data_home, ib_table->name, reg_ext);
6579
unpack_filename(path,path);
6581
/* Note that we do not know the access time of the table,
6582
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
6584
if (os_file_get_status(path,&stat_info)) {
6585
stats.create_time = stat_info.ctime;
6589
if (flag & HA_STATUS_VARIABLE) {
6590
n_rows = ib_table->stat_n_rows;
6592
/* Because we do not protect stat_n_rows by any mutex in a
6593
delete, it is theoretically possible that the value can be
6594
smaller than zero! TODO: fix this race.
6596
The MySQL optimizer seems to assume in a left join that n_rows
6597
is an accurate estimate if it is zero. Of course, it is not,
6598
since we do not have any locks on the rows yet at this phase.
6599
Since SHOW TABLE STATUS seems to call this function with the
6600
HA_STATUS_TIME flag set, while the left join optimizer does not
6601
set that flag, we add one to a zero value if the flag is not
6602
set. That way SHOW TABLE STATUS will show the best estimate,
6603
while the optimizer never sees the table empty. */
6609
if (n_rows == 0 && !(flag & HA_STATUS_TIME)) {
6613
/* Fix bug#29507: TRUNCATE shows too many rows affected.
6614
Do not show the estimates for TRUNCATE command. */
6615
if (thd_sql_command(user_thd) == SQLCOM_TRUNCATE) {
6620
stats.records = (ha_rows)n_rows;
6622
stats.data_file_length = ((ulonglong)
6623
ib_table->stat_clustered_index_size)
6625
stats.index_file_length = ((ulonglong)
6626
ib_table->stat_sum_of_other_index_sizes)
6628
stats.delete_length =
6629
fsp_get_available_space_in_free_extents(
6630
ib_table->space) * 1024;
6631
stats.check_time = 0;
6633
if (stats.records == 0) {
6634
stats.mean_rec_length = 0;
6636
stats.mean_rec_length = (ulong) (stats.data_file_length / stats.records);
6640
if (flag & HA_STATUS_CONST) {
6641
index = dict_table_get_first_index(ib_table);
6643
if (prebuilt->clust_index_was_generated) {
6644
index = dict_table_get_next_index(index);
6647
for (i = 0; i < table->s->keys; i++) {
6648
if (index == NULL) {
6649
sql_print_error("Table %s contains fewer "
6650
"indexes inside InnoDB than "
6651
"are defined in the MySQL "
6652
".frm file. Have you mixed up "
6653
".frm files from different "
6654
"installations? See "
6655
"http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
6661
for (j = 0; j < table->key_info[i].key_parts; j++) {
6663
if (j + 1 > index->n_uniq) {
6665
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
6666
"statistics for %lu columns. Have you mixed up .frm files from different "
6668
"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
6672
index->n_uniq, j + 1);
6676
if (index->stat_n_diff_key_vals[j + 1] == 0) {
6678
rec_per_key = stats.records;
6680
rec_per_key = (ha_rows)(stats.records /
6681
index->stat_n_diff_key_vals[j + 1]);
6684
/* Since MySQL seems to favor table scans
6685
too much over index searches, we pretend
6686
index selectivity is 2 times better than
6689
rec_per_key = rec_per_key / 2;
6691
if (rec_per_key == 0) {
6695
table->key_info[i].rec_per_key[j]=
6696
rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
6697
(ulong) rec_per_key;
6700
index = dict_table_get_next_index(index);
6704
if (flag & HA_STATUS_ERRKEY) {
6705
const dict_index_t* err_index;
6707
ut_a(prebuilt->trx);
6708
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6710
err_index = trx_get_error_info(prebuilt->trx);
6713
errkey = (unsigned int)
6714
row_get_mysql_key_number_for_index(err_index);
6716
errkey = (unsigned int) prebuilt->trx->error_key_num;
6720
if (flag & HA_STATUS_AUTO && table->found_next_number_field) {
6724
/* The following function call can the first time fail in
6725
a lock wait timeout error because it reserves the auto-inc
6726
lock on the table. If it fails, then someone is already initing
6727
the auto-inc counter, and the second call is guaranteed to
6730
ret = innobase_read_and_init_auto_inc(&auto_inc);
6733
ret = innobase_read_and_init_auto_inc(&auto_inc);
6736
sql_print_error("Cannot get table %s auto-inc"
6737
"counter value in ::info\n",
6743
stats.auto_increment_value = auto_inc;
6746
prebuilt->trx->op_info = (char*)"";
6751
/**************************************************************************
6752
Updates index cardinalities of the table, based on 8 random dives into
6753
each index tree. This does NOT calculate exact statistics on the table. */
6756
ha_innobase::analyze(
6757
/*=================*/
6758
/* out: returns always 0 (success) */
6759
THD* thd, /* in: connection thread handle */
6760
HA_CHECK_OPT* check_opt) /* in: currently ignored */
6762
/* Simply call ::info() with all the flags */
6763
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
6768
/**************************************************************************
6769
This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
6770
the table in MySQL. */
6773
ha_innobase::optimize(
6774
/*==================*/
6775
THD* thd, /* in: connection thread handle */
6776
HA_CHECK_OPT* check_opt) /* in: currently ignored */
6778
return(HA_ADMIN_TRY_ALTER);
6781
/***********************************************************************
6782
Tries to check that an InnoDB table is not corrupted. If corruption is
6783
noticed, prints to stderr information about it. In case of corruption
6784
may also assert a failure and crash the server. */
6789
/* out: HA_ADMIN_CORRUPT or
6791
THD* thd, /* in: user thread handle */
6792
HA_CHECK_OPT* check_opt) /* in: check options, currently
6797
DBUG_ASSERT(thd == ha_thd());
6798
ut_a(prebuilt->trx);
6799
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6800
ut_a(prebuilt->trx == thd_to_trx(thd));
6802
if (prebuilt->mysql_template == NULL) {
6803
/* Build the template; we will use a dummy template
6804
in index scans done in checking */
6806
build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
6809
ret = row_check_table_for_mysql(prebuilt);
6811
if (ret == DB_SUCCESS) {
6812
return(HA_ADMIN_OK);
6815
return(HA_ADMIN_CORRUPT);
6818
/*****************************************************************
6819
Adds information about free space in the InnoDB tablespace to a table comment
6820
which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
6824
ha_innobase::update_table_comment(
6825
/*==============================*/
6826
/* out: table comment + InnoDB free space +
6827
info on foreign keys */
6828
const char* comment)/* in: table comment defined by user */
6830
uint length = (uint) strlen(comment);
6834
/* We do not know if MySQL can call this function before calling
6835
external_lock(). To be safe, update the thd of the current table
6838
if (length > 64000 - 3) {
6839
return((char*)comment); /* string too long */
6842
update_thd(ha_thd());
6844
prebuilt->trx->op_info = (char*)"returning table comment";
6846
/* In case MySQL calls this in the middle of a SELECT query, release
6847
possible adaptive hash latch to avoid deadlocks of threads */
6849
trx_search_latch_release_if_reserved(prebuilt->trx);
6852
/* output the data to a temporary file */
6854
mutex_enter(&srv_dict_tmpfile_mutex);
6855
rewind(srv_dict_tmpfile);
6857
fprintf(srv_dict_tmpfile, "InnoDB free: %llu kB",
6858
fsp_get_available_space_in_free_extents(
6859
prebuilt->table->space));
6861
dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
6862
prebuilt->trx, prebuilt->table);
6863
flen = ftell(srv_dict_tmpfile);
6866
} else if (length + flen + 3 > 64000) {
6867
flen = 64000 - 3 - length;
6870
/* allocate buffer for the full string, and
6871
read the contents of the temporary file */
6873
str = (char*) my_malloc(length + flen + 3, MYF(0));
6876
char* pos = str + length;
6878
memcpy(str, comment, length);
6882
rewind(srv_dict_tmpfile);
6883
flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
6887
mutex_exit(&srv_dict_tmpfile_mutex);
6889
prebuilt->trx->op_info = (char*)"";
6891
return(str ? str : (char*) comment);
6894
/***********************************************************************
6895
Gets the foreign key create info for a table stored in InnoDB. */
6898
ha_innobase::get_foreign_key_create_info(void)
6899
/*==========================================*/
6900
/* out, own: character string in the form which
6901
can be inserted to the CREATE TABLE statement,
6902
MUST be freed with ::free_foreign_key_create_info */
6907
ut_a(prebuilt != NULL);
6909
/* We do not know if MySQL can call this function before calling
6910
external_lock(). To be safe, update the thd of the current table
6913
update_thd(ha_thd());
6915
prebuilt->trx->op_info = (char*)"getting info on foreign keys";
6917
/* In case MySQL calls this in the middle of a SELECT query,
6918
release possible adaptive hash latch to avoid
6919
deadlocks of threads */
6921
trx_search_latch_release_if_reserved(prebuilt->trx);
6923
mutex_enter(&srv_dict_tmpfile_mutex);
6924
rewind(srv_dict_tmpfile);
6926
/* output the data to a temporary file */
6927
dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
6928
prebuilt->trx, prebuilt->table);
6929
prebuilt->trx->op_info = (char*)"";
6931
flen = ftell(srv_dict_tmpfile);
6934
} else if (flen > 64000 - 1) {
6938
/* allocate buffer for the string, and
6939
read the contents of the temporary file */
6941
str = (char*) my_malloc(flen + 1, MYF(0));
6944
rewind(srv_dict_tmpfile);
6945
flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
6949
mutex_exit(&srv_dict_tmpfile_mutex);
6957
ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
6959
dict_foreign_t* foreign;
6961
DBUG_ENTER("get_foreign_key_list");
6962
ut_a(prebuilt != NULL);
6963
update_thd(ha_thd());
6964
prebuilt->trx->op_info = (char*)"getting list of foreign keys";
6965
trx_search_latch_release_if_reserved(prebuilt->trx);
6966
mutex_enter(&(dict_sys->mutex));
6967
foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
6969
while (foreign != NULL) {
6971
FOREIGN_KEY_INFO f_key_info;
6972
LEX_STRING *name= 0;
6974
char uname[NAME_LEN+1]; /* Unencoded name */
6975
char db_name[NAME_LEN+1];
6976
const char *tmp_buff;
6978
tmp_buff= foreign->id;
6980
while (tmp_buff[i] != '/')
6983
f_key_info.forein_id = thd_make_lex_string(thd, 0,
6984
tmp_buff, (uint) strlen(tmp_buff), 1);
6985
tmp_buff= foreign->referenced_table_name;
6989
while (tmp_buff[i] != '/')
6991
db_name[i]= tmp_buff[i];
6995
ulen= filename_to_tablename(db_name, uname, sizeof(uname));
6996
f_key_info.referenced_db = thd_make_lex_string(thd, 0,
7001
ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname));
7002
f_key_info.referenced_table = thd_make_lex_string(thd, 0,
7006
tmp_buff= foreign->foreign_col_names[i];
7007
name = thd_make_lex_string(thd, name,
7008
tmp_buff, (uint) strlen(tmp_buff), 1);
7009
f_key_info.foreign_fields.push_back(name);
7010
tmp_buff= foreign->referenced_col_names[i];
7011
name = thd_make_lex_string(thd, name,
7012
tmp_buff, (uint) strlen(tmp_buff), 1);
7013
f_key_info.referenced_fields.push_back(name);
7014
if (++i >= foreign->n_fields)
7019
if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)
7022
tmp_buff= "CASCADE";
7024
else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
7027
tmp_buff= "SET NULL";
7029
else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION)
7032
tmp_buff= "NO ACTION";
7037
tmp_buff= "RESTRICT";
7039
f_key_info.delete_method = thd_make_lex_string(
7040
thd, f_key_info.delete_method, tmp_buff, length, 1);
7043
if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
7046
tmp_buff= "CASCADE";
7048
else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
7051
tmp_buff= "SET NULL";
7053
else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION)
7056
tmp_buff= "NO ACTION";
7061
tmp_buff= "RESTRICT";
7063
f_key_info.update_method = thd_make_lex_string(
7064
thd, f_key_info.update_method, tmp_buff, length, 1);
7065
if (foreign->referenced_index &&
7066
foreign->referenced_index->name)
7068
f_key_info.referenced_key_name = thd_make_lex_string(
7069
thd, f_key_info.referenced_key_name,
7070
foreign->referenced_index->name,
7071
strlen(foreign->referenced_index->name), 1);
7074
f_key_info.referenced_key_name= 0;
7076
FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
7077
thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO));
7078
f_key_list->push_back(pf_key_info);
7079
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7081
mutex_exit(&(dict_sys->mutex));
7082
prebuilt->trx->op_info = (char*)"";
7087
/*********************************************************************
7088
Checks if ALTER TABLE may change the storage engine of the table.
7089
Changing storage engines is not allowed for tables for which there
7090
are foreign key constraints (parent or child tables). */
7093
ha_innobase::can_switch_engines(void)
7094
/*=================================*/
7098
DBUG_ENTER("ha_innobase::can_switch_engines");
7100
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
7102
prebuilt->trx->op_info =
7103
"determining if there are foreign key constraints";
7104
row_mysql_lock_data_dictionary(prebuilt->trx);
7106
can_switch = !UT_LIST_GET_FIRST(prebuilt->table->referenced_list)
7107
&& !UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
7109
row_mysql_unlock_data_dictionary(prebuilt->trx);
7110
prebuilt->trx->op_info = "";
7112
DBUG_RETURN(can_switch);
7115
/***********************************************************************
7116
Checks if a table is referenced by a foreign key. The MySQL manual states that
7117
a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a
7118
delete is then allowed internally to resolve a duplicate key conflict in
7119
REPLACE, not an update. */
7122
ha_innobase::referenced_by_foreign_key(void)
7123
/*========================================*/
7124
/* out: > 0 if referenced by a FOREIGN KEY */
7126
if (dict_table_is_referenced_by_foreign_key(prebuilt->table)) {
7134
/***********************************************************************
7135
Frees the foreign key create info for a table stored in InnoDB, if it is
7139
ha_innobase::free_foreign_key_create_info(
7140
/*======================================*/
7141
char* str) /* in, own: create info string to free */
7144
my_free(str, MYF(0));
7148
/***********************************************************************
7149
Tells something additional to the handler about how to do things. */
7154
/* out: 0 or error number */
7155
enum ha_extra_function operation)
7156
/* in: HA_EXTRA_FLUSH or some other flag */
7158
/* Warning: since it is not sure that MySQL calls external_lock
7159
before calling this function, the trx field in prebuilt can be
7162
switch (operation) {
7163
case HA_EXTRA_FLUSH:
7164
if (prebuilt->blob_heap) {
7165
row_mysql_prebuilt_free_blob_heap(prebuilt);
7168
case HA_EXTRA_RESET_STATE:
7169
reset_template(prebuilt);
7171
case HA_EXTRA_NO_KEYREAD:
7172
prebuilt->read_just_key = 0;
7174
case HA_EXTRA_KEYREAD:
7175
prebuilt->read_just_key = 1;
7177
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
7178
prebuilt->keep_other_fields_on_keyread = 1;
7181
/* IMPORTANT: prebuilt->trx can be obsolete in
7182
this method, because it is not sure that MySQL
7183
calls external_lock before this method with the
7184
parameters below. We must not invoke update_thd()
7185
either, because the calling threads may change.
7186
CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7187
case HA_EXTRA_IGNORE_DUP_KEY:
7188
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE;
7190
case HA_EXTRA_WRITE_CAN_REPLACE:
7191
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE;
7193
case HA_EXTRA_WRITE_CANNOT_REPLACE:
7194
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
7196
case HA_EXTRA_NO_IGNORE_DUP_KEY:
7197
thd_to_trx(ha_thd())->duplicates &=
7198
~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7200
default:/* Do nothing */
7209
ha_innobase::reset()
7211
if (prebuilt->blob_heap) {
7212
row_mysql_prebuilt_free_blob_heap(prebuilt);
7214
reset_template(prebuilt);
7219
/**********************************************************************
7220
MySQL calls this function at the start of each SQL statement inside LOCK
7221
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
7222
mark SQL statement borders. Note also a special case: if a temporary table
7223
is created inside LOCK TABLES, MySQL has not called external_lock() at all
7225
MySQL-5.0 also calls this before each statement in an execution of a stored
7226
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
7227
locks all tables involved in a stored procedure with full explicit table
7228
locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the
7232
ha_innobase::start_stmt(
7233
/*====================*/
7234
/* out: 0 or error code */
7235
THD* thd, /* in: handle to the user thread */
7236
thr_lock_type lock_type)
7242
trx = prebuilt->trx;
7244
/* Here we release the search latch and the InnoDB thread FIFO ticket
7245
if they were reserved. They should have been released already at the
7246
end of the previous statement, but because inside LOCK TABLES the
7247
lock count method does not work to mark the end of a SELECT statement,
7248
that may not be the case. We MUST release the search latch before an
7249
INSERT, for example. */
7251
innobase_release_stat_resources(trx);
7253
/* Reset the AUTOINC statement level counter for multi-row INSERTs. */
7254
trx->n_autoinc_rows = 0;
7256
prebuilt->sql_stat_start = TRUE;
7257
prebuilt->hint_need_to_fetch_extra_cols = 0;
7258
reset_template(prebuilt);
7260
if (!prebuilt->mysql_has_locked) {
7261
/* This handle is for a temporary table created inside
7262
this same LOCK TABLES; since MySQL does NOT call external_lock
7263
in this case, we must use x-row locks inside InnoDB to be
7264
prepared for an update of a row */
7266
prebuilt->select_lock_type = LOCK_X;
7268
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
7269
&& thd_sql_command(thd) == SQLCOM_SELECT
7270
&& lock_type == TL_READ) {
7272
/* For other than temporary tables, we obtain
7273
no lock for consistent read (plain SELECT). */
7275
prebuilt->select_lock_type = LOCK_NONE;
7277
/* Not a consistent read: restore the
7278
select_lock_type value. The value of
7279
stored_select_lock_type was decided in:
7281
2) ::external_lock(),
7282
3) ::init_table_handle_for_HANDLER(), and
7283
4) ::transactional_table_lock(). */
7285
prebuilt->select_lock_type =
7286
prebuilt->stored_select_lock_type;
7290
trx->detailed_error[0] = '\0';
7292
/* Set the MySQL flag to mark that there is an active transaction */
7293
if (trx->active_trans == 0) {
7295
innobase_register_trx_and_stmt(ht, thd);
7296
trx->active_trans = 1;
7298
innobase_register_stmt(ht, thd);
7304
/**********************************************************************
7305
Maps a MySQL trx isolation level code to the InnoDB isolation level code */
7308
innobase_map_isolation_level(
7309
/*=========================*/
7310
/* out: InnoDB isolation level */
7311
enum_tx_isolation iso) /* in: MySQL isolation level code */
7314
case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
7315
case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED);
7316
case ISO_SERIALIZABLE: return(TRX_ISO_SERIALIZABLE);
7317
case ISO_READ_UNCOMMITTED: return(TRX_ISO_READ_UNCOMMITTED);
7318
default: ut_a(0); return(0);
7322
/**********************************************************************
7323
As MySQL will execute an external lock for every new table it uses when it
7324
starts to process an SQL statement (an exception is when MySQL calls
7325
start_stmt for the handle) we can use this function to store the pointer to
7326
the THD in the handle. We will also use this function to communicate
7327
to InnoDB that a new SQL statement has started and that we must store a
7328
savepoint to our transaction handle, so that we are able to roll back
7329
the SQL statement in case of an error. */
7332
ha_innobase::external_lock(
7333
/*=======================*/
7335
THD* thd, /* in: handle to the user thread */
7336
int lock_type) /* in: lock type */
7340
DBUG_ENTER("ha_innobase::external_lock");
7341
DBUG_PRINT("enter",("lock_type: %d", lock_type));
7345
/* Statement based binlogging does not work in isolation level
7346
READ UNCOMMITTED and READ COMMITTED since the necessary
7347
locks cannot be taken. In this case, we print an
7348
informative error message and return with an error. */
7349
if (lock_type == F_WRLCK)
7351
ulong const binlog_format= thd_binlog_format(thd);
7352
ulong const tx_isolation = thd_tx_isolation(current_thd);
7353
if (tx_isolation <= ISO_READ_COMMITTED &&
7354
binlog_format == BINLOG_FORMAT_STMT)
7357
my_snprintf(buf, sizeof(buf),
7358
"Transaction level '%s' in"
7359
" InnoDB is not safe for binlog mode '%s'",
7360
tx_isolation_names[tx_isolation],
7361
binlog_format_names[binlog_format]);
7362
my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf);
7363
DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
7368
trx = prebuilt->trx;
7370
prebuilt->sql_stat_start = TRUE;
7371
prebuilt->hint_need_to_fetch_extra_cols = 0;
7373
reset_template(prebuilt);
7375
if (lock_type == F_WRLCK) {
7377
/* If this is a SELECT, then it is in UPDATE TABLE ...
7378
or SELECT ... FOR UPDATE */
7379
prebuilt->select_lock_type = LOCK_X;
7380
prebuilt->stored_select_lock_type = LOCK_X;
7383
if (lock_type != F_UNLCK) {
7384
/* MySQL is setting a new table lock */
7386
trx->detailed_error[0] = '\0';
7388
/* Set the MySQL flag to mark that there is an active
7390
if (trx->active_trans == 0) {
7392
innobase_register_trx_and_stmt(ht, thd);
7393
trx->active_trans = 1;
7394
} else if (trx->n_mysql_tables_in_use == 0) {
7395
innobase_register_stmt(ht, thd);
7398
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7399
&& prebuilt->select_lock_type == LOCK_NONE
7400
&& thd_test_options(thd,
7401
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7403
/* To get serializable execution, we let InnoDB
7404
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
7405
which otherwise would have been consistent reads. An
7406
exception is consistent reads in the AUTOCOMMIT=1 mode:
7407
we know that they are read-only transactions, and they
7408
can be serialized also if performed as consistent
7411
prebuilt->select_lock_type = LOCK_S;
7412
prebuilt->stored_select_lock_type = LOCK_S;
7415
/* Starting from 4.1.9, no InnoDB table lock is taken in LOCK
7416
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
7417
an InnoDB table lock if it is released immediately at the end
7418
of LOCK TABLES, and InnoDB's table locks in that case cause
7419
VERY easily deadlocks.
7421
We do not set InnoDB table locks if user has not explicitly
7422
requested a table lock. Note that thd_in_lock_tables(thd)
7423
can hold in some cases, e.g., at the start of a stored
7424
procedure call (SQLCOM_CALL). */
7426
if (prebuilt->select_lock_type != LOCK_NONE) {
7428
if (thd_sql_command(thd) == SQLCOM_LOCK_TABLES
7429
&& THDVAR(thd, table_locks)
7430
&& thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)
7431
&& thd_in_lock_tables(thd)) {
7433
ulint error = row_lock_table_for_mysql(
7436
if (error != DB_SUCCESS) {
7437
error = convert_error_code_to_mysql(
7438
(int) error, 0, thd);
7439
DBUG_RETURN((int) error);
7443
trx->mysql_n_tables_locked++;
7446
trx->n_mysql_tables_in_use++;
7447
prebuilt->mysql_has_locked = TRUE;
7452
/* MySQL is releasing a table lock */
7454
trx->n_mysql_tables_in_use--;
7455
prebuilt->mysql_has_locked = FALSE;
7457
/* Release a possible FIFO ticket and search latch. Since we
7458
may reserve the kernel mutex, we have to release the search
7459
system latch first to obey the latching order. */
7461
innobase_release_stat_resources(trx);
7463
/* If the MySQL lock count drops to zero we know that the current SQL
7464
statement has ended */
7466
if (trx->n_mysql_tables_in_use == 0) {
7468
trx->mysql_n_tables_locked = 0;
7469
prebuilt->used_in_HANDLER = FALSE;
7471
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7472
if (trx->active_trans != 0) {
7473
innobase_commit(ht, thd, TRUE);
7476
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7477
&& trx->global_read_view) {
7479
/* At low transaction isolation levels we let
7480
each consistent read set its own snapshot */
7482
read_view_close_for_mysql(trx);
7490
/**********************************************************************
7491
With this function MySQL request a transactional lock to a table when
7492
user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
7495
ha_innobase::transactional_table_lock(
7496
/*==================================*/
7497
/* out: error code */
7498
THD* thd, /* in: handle to the user thread */
7499
int lock_type) /* in: lock type */
7503
DBUG_ENTER("ha_innobase::transactional_table_lock");
7504
DBUG_PRINT("enter",("lock_type: %d", lock_type));
7506
/* We do not know if MySQL can call this function before calling
7507
external_lock(). To be safe, update the thd of the current table
7512
if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
7513
ut_print_timestamp(stderr);
7515
" InnoDB: MySQL is trying to use a table handle"
7516
" but the .ibd file for\n"
7517
"InnoDB: table %s does not exist.\n"
7518
"InnoDB: Have you deleted the .ibd file"
7519
" from the database directory under\n"
7520
"InnoDB: the MySQL datadir?"
7522
" http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
7523
"InnoDB: how you can resolve the problem.\n",
7524
prebuilt->table->name);
7525
DBUG_RETURN(HA_ERR_CRASHED);
7528
trx = prebuilt->trx;
7530
prebuilt->sql_stat_start = TRUE;
7531
prebuilt->hint_need_to_fetch_extra_cols = 0;
7533
reset_template(prebuilt);
7535
if (lock_type == F_WRLCK) {
7536
prebuilt->select_lock_type = LOCK_X;
7537
prebuilt->stored_select_lock_type = LOCK_X;
7538
} else if (lock_type == F_RDLCK) {
7539
prebuilt->select_lock_type = LOCK_S;
7540
prebuilt->stored_select_lock_type = LOCK_S;
7542
ut_print_timestamp(stderr);
7543
fprintf(stderr, " InnoDB error:\n"
7544
"MySQL is trying to set transactional table lock with corrupted lock type\n"
7545
"to table %s, lock type %d does not exist.\n",
7546
prebuilt->table->name, lock_type);
7547
DBUG_RETURN(HA_ERR_CRASHED);
7550
/* MySQL is setting a new transactional table lock */
7552
/* Set the MySQL flag to mark that there is an active transaction */
7553
if (trx->active_trans == 0) {
7555
innobase_register_trx_and_stmt(ht, thd);
7556
trx->active_trans = 1;
7559
if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
7560
ulint error = DB_SUCCESS;
7562
error = row_lock_table_for_mysql(prebuilt, NULL, 0);
7564
if (error != DB_SUCCESS) {
7565
error = convert_error_code_to_mysql(
7566
(int) error, prebuilt->table->flags, thd);
7567
DBUG_RETURN((int) error);
7570
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7572
/* Store the current undo_no of the transaction
7573
so that we know where to roll back if we have
7574
to roll back the next SQL statement */
7576
trx_mark_sql_stat_end(trx);
7583
/****************************************************************************
7584
Here we export InnoDB status variables to MySQL. */
7587
innodb_export_status()
7588
/*==================*/
7590
if (innodb_inited) {
7591
srv_export_innodb_status();
7597
/****************************************************************************
7598
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
7599
Monitor to the client. */
7604
handlerton* hton, /* in: the innodb handlerton */
7605
THD* thd, /* in: the MySQL query thread of the caller */
7606
stat_print_fn *stat_print)
7609
static const char truncated_msg[] = "... truncated...\n";
7610
const long MAX_STATUS_SIZE = 64000;
7611
ulint trx_list_start = ULINT_UNDEFINED;
7612
ulint trx_list_end = ULINT_UNDEFINED;
7614
DBUG_ENTER("innodb_show_status");
7615
DBUG_ASSERT(hton == innodb_hton_ptr);
7617
trx = check_trx_exists(thd);
7619
innobase_release_stat_resources(trx);
7621
/* We let the InnoDB Monitor to output at most MAX_STATUS_SIZE
7624
long flen, usable_len;
7627
mutex_enter(&srv_monitor_file_mutex);
7628
rewind(srv_monitor_file);
7629
srv_printf_innodb_monitor(srv_monitor_file,
7630
&trx_list_start, &trx_list_end);
7631
flen = ftell(srv_monitor_file);
7632
os_file_set_eof(srv_monitor_file);
7638
if (flen > MAX_STATUS_SIZE) {
7639
usable_len = MAX_STATUS_SIZE;
7644
/* allocate buffer for the string, and
7645
read the contents of the temporary file */
7647
if (!(str = (char*) my_malloc(usable_len + 1, MYF(0)))) {
7648
mutex_exit(&srv_monitor_file_mutex);
7652
rewind(srv_monitor_file);
7653
if (flen < MAX_STATUS_SIZE) {
7654
/* Display the entire output. */
7655
flen = (long) fread(str, 1, flen, srv_monitor_file);
7656
} else if (trx_list_end < (ulint) flen
7657
&& trx_list_start < trx_list_end
7658
&& trx_list_start + (flen - trx_list_end)
7659
< MAX_STATUS_SIZE - sizeof truncated_msg - 1) {
7660
/* Omit the beginning of the list of active transactions. */
7661
long len = (long) fread(str, 1, trx_list_start, srv_monitor_file);
7662
memcpy(str + len, truncated_msg, sizeof truncated_msg - 1);
7663
len += sizeof truncated_msg - 1;
7664
usable_len = (MAX_STATUS_SIZE - 1) - len;
7665
fseek(srv_monitor_file, flen - usable_len, SEEK_SET);
7666
len += (long) fread(str + len, 1, usable_len, srv_monitor_file);
7669
/* Omit the end of the output. */
7670
flen = (long) fread(str, 1, MAX_STATUS_SIZE - 1, srv_monitor_file);
7673
mutex_exit(&srv_monitor_file_mutex);
7675
bool result = FALSE;
7677
if (stat_print(thd, innobase_hton_name, strlen(innobase_hton_name),
7678
STRING_WITH_LEN(""), str, flen)) {
7681
my_free(str, MYF(0));
7686
/****************************************************************************
7687
Implements the SHOW MUTEX STATUS command. . */
7690
innodb_mutex_show_status(
7691
/*=====================*/
7692
handlerton* hton, /* in: the innodb handlerton */
7693
THD* thd, /* in: the MySQL query thread of the
7695
stat_print_fn* stat_print)
7697
char buf1[IO_SIZE], buf2[IO_SIZE];
7700
ulint rw_lock_count= 0;
7701
ulint rw_lock_count_spin_loop= 0;
7702
ulint rw_lock_count_spin_rounds= 0;
7703
ulint rw_lock_count_os_wait= 0;
7704
ulint rw_lock_count_os_yield= 0;
7705
ulonglong rw_lock_wait_time= 0;
7706
#endif /* UNIV_DEBUG */
7707
uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
7708
DBUG_ENTER("innodb_mutex_show_status");
7709
DBUG_ASSERT(hton == innodb_hton_ptr);
7711
mutex_enter(&mutex_list_mutex);
7713
mutex = UT_LIST_GET_FIRST(mutex_list);
7715
while (mutex != NULL) {
7717
if (mutex->mutex_type != 1) {
7718
if (mutex->count_using > 0) {
7719
buf1len= my_snprintf(buf1, sizeof(buf1),
7721
mutex->cmutex_name, mutex->cfile_name);
7722
buf2len= my_snprintf(buf2, sizeof(buf2),
7723
"count=%lu, spin_waits=%lu,"
7724
" spin_rounds=%lu, "
7725
"os_waits=%lu, os_yields=%lu,"
7726
" os_wait_times=%lu",
7728
mutex->count_spin_loop,
7729
mutex->count_spin_rounds,
7730
mutex->count_os_wait,
7731
mutex->count_os_yield,
7732
(ulong) (mutex->lspent_time/1000));
7734
if (stat_print(thd, innobase_hton_name,
7735
hton_name_len, buf1, buf1len,
7737
mutex_exit(&mutex_list_mutex);
7743
rw_lock_count += mutex->count_using;
7744
rw_lock_count_spin_loop += mutex->count_spin_loop;
7745
rw_lock_count_spin_rounds += mutex->count_spin_rounds;
7746
rw_lock_count_os_wait += mutex->count_os_wait;
7747
rw_lock_count_os_yield += mutex->count_os_yield;
7748
rw_lock_wait_time += mutex->lspent_time;
7750
#else /* UNIV_DEBUG */
7751
buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
7752
mutex->cfile_name, (ulong) mutex->cline);
7753
buf2len= my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
7754
mutex->count_os_wait);
7756
if (stat_print(thd, innobase_hton_name,
7757
hton_name_len, buf1, buf1len,
7759
mutex_exit(&mutex_list_mutex);
7762
#endif /* UNIV_DEBUG */
7764
mutex = UT_LIST_GET_NEXT(list, mutex);
7767
mutex_exit(&mutex_list_mutex);
7770
buf2len= my_snprintf(buf2, sizeof(buf2),
7771
"count=%lu, spin_waits=%lu, spin_rounds=%lu, "
7772
"os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
7773
rw_lock_count, rw_lock_count_spin_loop,
7774
rw_lock_count_spin_rounds,
7775
rw_lock_count_os_wait, rw_lock_count_os_yield,
7776
(ulong) (rw_lock_wait_time/1000));
7778
if (stat_print(thd, innobase_hton_name, hton_name_len,
7779
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
7782
#endif /* UNIV_DEBUG */
7788
bool innobase_show_status(handlerton *hton, THD* thd,
7789
stat_print_fn* stat_print,
7790
enum ha_stat_type stat_type)
7792
DBUG_ASSERT(hton == innodb_hton_ptr);
7794
switch (stat_type) {
7795
case HA_ENGINE_STATUS:
7796
return innodb_show_status(hton, thd, stat_print);
7797
case HA_ENGINE_MUTEX:
7798
return innodb_mutex_show_status(hton, thd, stat_print);
7805
/****************************************************************************
7806
Handling the shared INNOBASE_SHARE structure that is needed to provide table
7808
****************************************************************************/
7810
static uchar* innobase_get_key(INNOBASE_SHARE* share, size_t *length,
7811
my_bool not_used __attribute__((unused)))
7813
*length=share->table_name_length;
7815
return (uchar*) share->table_name;
7818
static INNOBASE_SHARE* get_share(const char* table_name)
7820
INNOBASE_SHARE *share;
7821
pthread_mutex_lock(&innobase_share_mutex);
7822
uint length=(uint) strlen(table_name);
7824
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
7825
(uchar*) table_name,
7828
share = (INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
7829
MYF(MY_FAE | MY_ZEROFILL));
7831
share->table_name_length=length;
7832
share->table_name=(char*) (share+1);
7833
strmov(share->table_name,table_name);
7835
if (my_hash_insert(&innobase_open_tables,
7837
pthread_mutex_unlock(&innobase_share_mutex);
7843
thr_lock_init(&share->lock);
7844
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
7848
pthread_mutex_unlock(&innobase_share_mutex);
7853
static void free_share(INNOBASE_SHARE* share)
7855
pthread_mutex_lock(&innobase_share_mutex);
7857
if (!--share->use_count) {
7858
hash_delete(&innobase_open_tables, (uchar*) share);
7859
thr_lock_delete(&share->lock);
7860
pthread_mutex_destroy(&share->mutex);
7861
my_free(share, MYF(0));
7864
pthread_mutex_unlock(&innobase_share_mutex);
7867
/*********************************************************************
7868
Converts a MySQL table lock stored in the 'lock' field of the handle to
7869
a proper type before storing pointer to the lock into an array of pointers.
7870
MySQL also calls this if it wants to reset some table locks to a not-locked
7871
state during the processing of an SQL query. An example is that during a
7872
SELECT the read lock is released early on the 'const' tables where we only
7873
fetch one row. MySQL does not call this when it releases all locks at the
7874
end of an SQL statement. */
7877
ha_innobase::store_lock(
7878
/*====================*/
7879
/* out: pointer to the next
7880
element in the 'to' array */
7881
THD* thd, /* in: user thread handle */
7882
THR_LOCK_DATA** to, /* in: pointer to an array
7883
of pointers to lock structs;
7884
pointer to the 'lock' field
7885
of current handle is stored
7886
next to this array */
7887
enum thr_lock_type lock_type) /* in: lock type to store in
7888
'lock'; this may also be
7893
/* Note that trx in this function is NOT necessarily prebuilt->trx
7894
because we call update_thd() later, in ::external_lock()! Failure to
7895
understand this caused a serious memory corruption bug in 5.1.11. */
7897
trx = check_trx_exists(thd);
7899
/* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
7900
Be careful to ignore TL_IGNORE if we are going to do something with
7901
only 'real' locks! */
7903
/* If no MySQL table is in use, we need to set the isolation level
7904
of the transaction. */
7906
if (lock_type != TL_IGNORE
7907
&& trx->n_mysql_tables_in_use == 0) {
7908
trx->isolation_level = innobase_map_isolation_level(
7909
(enum_tx_isolation) thd_tx_isolation(thd));
7911
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7912
&& trx->global_read_view) {
7914
/* At low transaction isolation levels we let
7915
each consistent read set its own snapshot */
7917
read_view_close_for_mysql(trx);
7921
DBUG_ASSERT(thd == current_thd);
7922
const bool in_lock_tables = thd_in_lock_tables(thd);
7923
const uint sql_command = thd_sql_command(thd);
7925
if (sql_command == SQLCOM_DROP_TABLE) {
7927
/* MySQL calls this function in DROP TABLE though this table
7928
handle may belong to another thd that is running a query. Let
7929
us in that case skip any changes to the prebuilt struct. */
7931
} else if ((lock_type == TL_READ && in_lock_tables)
7932
|| (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables)
7933
|| lock_type == TL_READ_WITH_SHARED_LOCKS
7934
|| lock_type == TL_READ_NO_INSERT
7935
|| (lock_type != TL_IGNORE
7936
&& sql_command != SQLCOM_SELECT)) {
7938
/* The OR cases above are in this order:
7939
1) MySQL is doing LOCK TABLES ... READ LOCAL, or we
7940
are processing a stored procedure or function, or
7941
2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
7942
3) this is a SELECT ... IN SHARE MODE, or
7943
4) we are doing a complex SQL statement like
7944
INSERT INTO ... SELECT ... and the logical logging (MySQL
7945
binlog) requires the use of a locking read, or
7946
MySQL is doing LOCK TABLES ... READ.
7947
5) we let InnoDB do locking reads for all SQL statements that
7948
are not simple SELECTs; note that select_lock_type in this
7949
case may get strengthened in ::external_lock() to LOCK_X.
7950
Note that we MUST use a locking read in all data modifying
7951
SQL statements, because otherwise the execution would not be
7952
serializable, and also the results from the update could be
7953
unexpected if an obsolete consistent read view would be
7956
ulint isolation_level;
7958
isolation_level = trx->isolation_level;
7960
if ((srv_locks_unsafe_for_binlog
7961
|| isolation_level == TRX_ISO_READ_COMMITTED)
7962
&& isolation_level != TRX_ISO_SERIALIZABLE
7963
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
7964
&& (sql_command == SQLCOM_INSERT_SELECT
7965
|| sql_command == SQLCOM_UPDATE
7966
|| sql_command == SQLCOM_CREATE_TABLE)) {
7968
/* If we either have innobase_locks_unsafe_for_binlog
7969
option set or this session is using READ COMMITTED
7970
isolation level and isolation level of the transaction
7971
is not set to serializable and MySQL is doing
7972
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
7973
CREATE ... SELECT... without FOR UPDATE or
7974
IN SHARE MODE in select, then we use consistent
7977
prebuilt->select_lock_type = LOCK_NONE;
7978
prebuilt->stored_select_lock_type = LOCK_NONE;
7979
} else if (sql_command == SQLCOM_CHECKSUM) {
7980
/* Use consistent read for checksum table */
7982
prebuilt->select_lock_type = LOCK_NONE;
7983
prebuilt->stored_select_lock_type = LOCK_NONE;
7985
prebuilt->select_lock_type = LOCK_S;
7986
prebuilt->stored_select_lock_type = LOCK_S;
7989
} else if (lock_type != TL_IGNORE) {
7991
/* We set possible LOCK_X value in external_lock, not yet
7992
here even if this would be SELECT ... FOR UPDATE */
7994
prebuilt->select_lock_type = LOCK_NONE;
7995
prebuilt->stored_select_lock_type = LOCK_NONE;
7998
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
8000
/* Starting from 5.0.7, we weaken also the table locks
8001
set at the start of a MySQL stored procedure call, just like
8002
we weaken the locks set at the start of an SQL statement.
8003
MySQL does set in_lock_tables TRUE there, but in reality
8004
we do not need table locks to make the execution of a
8005
single transaction stored procedure call deterministic
8006
(if it does not use a consistent read). */
8008
if (lock_type == TL_READ
8009
&& sql_command == SQLCOM_LOCK_TABLES) {
8010
/* We come here if MySQL is processing LOCK TABLES
8011
... READ LOCAL. MyISAM under that table lock type
8012
reads the table as it was at the time the lock was
8013
granted (new inserts are allowed, but not seen by the
8014
reader). To get a similar effect on an InnoDB table,
8015
we must use LOCK TABLES ... READ. We convert the lock
8016
type here, so that for InnoDB, READ LOCAL is
8017
equivalent to READ. This will change the InnoDB
8018
behavior in mysqldump, so that dumps of InnoDB tables
8019
are consistent with dumps of MyISAM tables. */
8021
lock_type = TL_READ_NO_INSERT;
8024
/* If we are not doing a LOCK TABLE, DISCARD/IMPORT
8025
TABLESPACE or TRUNCATE TABLE then allow multiple
8026
writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
8027
< TL_WRITE_CONCURRENT_INSERT.
8029
We especially allow multiple writers if MySQL is at the
8030
start of a stored procedure call (SQLCOM_CALL) or a
8031
stored function call (MySQL does have in_lock_tables
8034
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8035
&& lock_type <= TL_WRITE)
8037
&& sql_command == SQLCOM_LOCK_TABLES)
8038
&& !thd_tablespace_op(thd)
8039
&& sql_command != SQLCOM_TRUNCATE
8040
&& sql_command != SQLCOM_OPTIMIZE
8041
&& sql_command != SQLCOM_CREATE_TABLE) {
8043
lock_type = TL_WRITE_ALLOW_WRITE;
8046
/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
8047
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
8048
would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
8049
to t2. Convert the lock to a normal read lock to allow
8050
concurrent inserts to t2.
8052
We especially allow concurrent inserts if MySQL is at the
8053
start of a stored procedure call (SQLCOM_CALL)
8054
(MySQL does have thd_in_lock_tables() TRUE there). */
8056
if (lock_type == TL_READ_NO_INSERT
8057
&& sql_command != SQLCOM_LOCK_TABLES) {
8059
lock_type = TL_READ;
8062
lock.type = lock_type;
8070
/***********************************************************************
8071
This function initializes the auto-inc counter if it has not been
8072
initialized yet. This function does not change the value of the auto-inc
8073
counter if it already has been initialized. In parameter ret returns
8074
the value of the auto-inc counter. */
8077
ha_innobase::innobase_read_and_init_auto_inc(
8078
/*=========================================*/
8079
/* out: 0 or generic MySQL
8081
ulonglong* value) /* out: the autoinc value */
8085
int mysql_error = 0;
8086
dict_table_t* innodb_table = prebuilt->table;
8087
ibool trx_was_not_started = FALSE;
8090
ut_a(prebuilt->table);
8092
/* Remember if we are in the beginning of an SQL statement.
8093
This function must not change that flag. */
8094
stmt_start = prebuilt->sql_stat_start;
8096
/* Prepare prebuilt->trx in the table handle */
8097
update_thd(ha_thd());
8099
if (prebuilt->trx->conc_state == TRX_NOT_STARTED) {
8100
trx_was_not_started = TRUE;
8103
/* In case MySQL calls this in the middle of a SELECT query, release
8104
possible adaptive hash latch to avoid deadlocks of threads */
8106
trx_search_latch_release_if_reserved(prebuilt->trx);
8108
dict_table_autoinc_lock(prebuilt->table);
8110
auto_inc = dict_table_autoinc_read(prebuilt->table);
8112
/* Was the AUTOINC counter reset during normal processing, if
8113
so then we simply start count from 1. No need to go to the index.*/
8114
if (auto_inc == 0 && innodb_table->autoinc_inited) {
8116
dict_table_autoinc_initialize(innodb_table, auto_inc);
8119
if (auto_inc == 0) {
8120
dict_index_t* index;
8122
const char* autoinc_col_name;
8124
ut_a(!innodb_table->autoinc_inited);
8126
index = innobase_get_index(table->s->next_number_index);
8128
autoinc_col_name = table->found_next_number_field->field_name;
8130
error = row_search_max_autoinc(
8131
index, autoinc_col_name, &auto_inc);
8133
if (error == DB_SUCCESS) {
8134
if (auto_inc < ~0x0ULL) {
8137
dict_table_autoinc_initialize(innodb_table, auto_inc);
8139
ut_print_timestamp(stderr);
8140
fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
8141
"the max AUTOINC value from the index (%s).\n",
8142
error, index->name);
8150
dict_table_autoinc_unlock(prebuilt->table);
8152
/* Since MySQL does not seem to call autocommit after SHOW TABLE
8153
STATUS (even if we would register the trx here), we commit our
8154
transaction here if it was started here. This is to eliminate a
8155
dangling transaction. If the user had AUTOCOMMIT=0, then SHOW
8156
TABLE STATUS does leave a dangling transaction if the user does not
8157
himself call COMMIT. */
8159
if (trx_was_not_started) {
8161
innobase_commit_low(prebuilt->trx);
8164
prebuilt->sql_stat_start = stmt_start;
8166
return(mysql_error);
8169
/*******************************************************************************
8170
Read the next autoinc value, initialize the table if it's not initialized.
8171
On return if there is no error then the tables AUTOINC lock is locked.*/
8174
ha_innobase::innobase_get_auto_increment(
8175
/*=====================================*/
8176
ulonglong* value) /* out: autoinc value */
8182
/* Note: If the table is not initialized when we attempt the
8183
read below. We initialize the table's auto-inc counter and
8184
always do a reread of the AUTOINC value. */
8186
error = innobase_autoinc_lock();
8188
if (error == DB_SUCCESS) {
8191
/* Determine the first value of the interval */
8192
autoinc = dict_table_autoinc_read(prebuilt->table);
8194
/* We need to initialize the AUTO-INC value, for
8195
that we release all locks.*/
8199
trx = prebuilt->trx;
8200
dict_table_autoinc_unlock(prebuilt->table);
8202
/* If we had reserved the AUTO-INC
8203
lock in this SQL statement we release
8204
it before retrying.*/
8205
row_unlock_table_autoinc_for_mysql(trx);
8207
/* Just to make sure */
8208
ut_a(!trx->auto_inc_lock);
8212
mysql_error = innobase_read_and_init_auto_inc(
8221
/* A deadlock error during normal processing is OK
8222
and can be ignored. */
8223
} else if (error != DB_DEADLOCK) {
8225
sql_print_error("InnoDB: Error: %lu in "
8226
"::innobase_get_auto_increment()",
8230
} while (*value == 0 && error == DB_SUCCESS);
8235
/*******************************************************************************
8236
This function initializes the auto-inc counter if it has not been
8237
initialized yet. This function does not change the value of the auto-inc
8238
counter if it already has been initialized. Returns the value of the
8239
auto-inc counter in *first_value, and ULONGLONG_MAX in *nb_reserved_values (as
8240
we have a table-level lock). offset, increment, nb_desired_values are ignored.
8241
*first_value is set to -1 if error (deadlock or lock wait timeout) */
8244
ha_innobase::get_auto_increment(
8245
/*============================*/
8246
ulonglong offset, /* in: */
8247
ulonglong increment, /* in: table autoinc increment */
8248
ulonglong nb_desired_values, /* in: number of values reqd */
8249
ulonglong *first_value, /* out: the autoinc value */
8250
ulonglong *nb_reserved_values) /* out: count of reserved values */
8254
ulonglong autoinc = 0;
8256
/* Prepare prebuilt->trx in the table handle */
8257
update_thd(ha_thd());
8259
error = innobase_get_auto_increment(&autoinc);
8261
if (error != DB_SUCCESS) {
8262
*first_value = (~(ulonglong) 0);
8266
/* This is a hack, since nb_desired_values seems to be accurate only
8267
for the first call to get_auto_increment() for multi-row INSERT and
8268
meaningless for other statements e.g, LOAD etc. Subsequent calls to
8269
this method for the same statement results in different values which
8270
don't make sense. Therefore we store the value the first time we are
8271
called and count down from that as rows are written (see write_row()).
8274
trx = prebuilt->trx;
8276
/* Note: We can't rely on *first_value since some MySQL engines,
8277
in particular the partition engine, don't initialize it to 0 when
8278
invoking this method. So we are not sure if it's guaranteed to
8281
/* Called for the first time ? */
8282
if (trx->n_autoinc_rows == 0) {
8284
trx->n_autoinc_rows = (ulint) nb_desired_values;
8286
/* It's possible for nb_desired_values to be 0:
8287
e.g., INSERT INTO T1(C) SELECT C FROM T2; */
8288
if (nb_desired_values == 0) {
8290
trx->n_autoinc_rows = 1;
8293
set_if_bigger(*first_value, autoinc);
8294
/* Not in the middle of a mult-row INSERT. */
8295
} else if (prebuilt->last_value == 0) {
8296
set_if_bigger(*first_value, autoinc);
8299
*nb_reserved_values = trx->n_autoinc_rows;
8301
/* With old style AUTOINC locking we only update the table's
8302
AUTOINC counter after attempting to insert the row. */
8303
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
8307
/* Check for overflow conditions. */
8308
need = *nb_reserved_values * increment;
8309
have = ~0x0ULL - *first_value;
8315
/* Compute the last value in the interval */
8316
prebuilt->last_value = *first_value + need;
8318
ut_a(prebuilt->last_value >= *first_value);
8320
/* Update the table autoinc variable */
8321
dict_table_autoinc_update(
8322
prebuilt->table, prebuilt->last_value);
8324
/* This will force write_row() into attempting an update
8325
of the table's AUTOINC counter. */
8326
prebuilt->last_value = 0;
8329
/* The increment to be used to increase the AUTOINC value, we use
8330
this in write_row() and update_row() to increase the autoinc counter
8331
for columns that are filled by the user.*/
8332
prebuilt->table->autoinc_increment = increment;
8334
dict_table_autoinc_unlock(prebuilt->table);
8337
/* See comment in handler.h */
8340
ha_innobase::reset_auto_increment(
8341
/*==============================*/
8342
ulonglong value) /* in: new value for table autoinc */
8344
DBUG_ENTER("ha_innobase::reset_auto_increment");
8348
update_thd(ha_thd());
8350
error = row_lock_table_autoinc_for_mysql(prebuilt);
8352
if (error != DB_SUCCESS) {
8353
error = convert_error_code_to_mysql(error,
8354
prebuilt->table->flags,
8360
innobase_reset_autoinc(value);
8365
/* See comment in handler.cc */
8368
ha_innobase::get_error_message(int error, String *buf)
8370
trx_t* trx = check_trx_exists(ha_thd());
8372
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
8373
system_charset_info);
8378
/***********************************************************************
8379
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
8380
If there is no explicitly declared non-null unique key or a primary key, then
8381
InnoDB internally uses the row id as the primary key. */
8384
ha_innobase::cmp_ref(
8385
/*=================*/
8386
/* out: < 0 if ref1 < ref2, 0 if equal, else
8388
const uchar* ref1, /* in: an (internal) primary key value in the
8389
MySQL key value format */
8390
const uchar* ref2) /* in: an (internal) primary key value in the
8391
MySQL key value format */
8393
enum_field_types mysql_type;
8395
KEY_PART_INFO* key_part;
8396
KEY_PART_INFO* key_part_end;
8401
if (prebuilt->clust_index_was_generated) {
8402
/* The 'ref' is an InnoDB row id */
8404
return(memcmp(ref1, ref2, DATA_ROW_ID_LEN));
8407
/* Do a type-aware comparison of primary key fields. PK fields
8408
are always NOT NULL, so no checks for NULL are performed. */
8410
key_part = table->key_info[table->s->primary_key].key_part;
8412
key_part_end = key_part
8413
+ table->key_info[table->s->primary_key].key_parts;
8415
for (; key_part != key_part_end; ++key_part) {
8416
field = key_part->field;
8417
mysql_type = field->type();
8419
if (mysql_type == MYSQL_TYPE_TINY_BLOB
8420
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
8421
|| mysql_type == MYSQL_TYPE_BLOB
8422
|| mysql_type == MYSQL_TYPE_LONG_BLOB) {
8424
/* In the MySQL key value format, a column prefix of
8425
a BLOB is preceded by a 2-byte length field */
8427
len1 = innobase_read_from_2_little_endian(ref1);
8428
len2 = innobase_read_from_2_little_endian(ref2);
8432
result = ((Field_blob*)field)->cmp( ref1, len1,
8435
result = field->key_cmp(ref1, ref2);
8443
ref1 += key_part->store_length;
8444
ref2 += key_part->store_length;
8450
/***********************************************************************
8451
Ask InnoDB if a query to a table can be cached. */
8454
ha_innobase::register_query_cache_table(
8455
/*====================================*/
8456
/* out: TRUE if query caching
8457
of the table is permitted */
8458
THD* thd, /* in: user thread handle */
8459
char* table_key, /* in: concatenation of database name,
8460
the null character '\0',
8461
and the table name */
8462
uint key_length, /* in: length of the full name, i.e.
8463
len(dbname) + len(tablename) + 1 */
8465
call_back, /* out: pointer to function for
8466
checking if query caching
8468
ulonglong *engine_data) /* in/out: data to call_back */
8470
*call_back = innobase_query_caching_of_table_permitted;
8472
return(innobase_query_caching_of_table_permitted(thd, table_key,
8479
ha_innobase::get_mysql_bin_log_name()
8481
return(trx_sys_mysql_bin_log_name);
8486
ha_innobase::get_mysql_bin_log_pos()
8488
/* trx... is ib_int64_t, which is a typedef for a 64-bit integer
8489
(__int64 or longlong) so it's ok to cast it to ulonglong. */
8491
return(trx_sys_mysql_bin_log_pos);
8494
/**********************************************************************
8495
This function is used to find the storage length in bytes of the first n
8496
characters for prefix indexes using a multibyte character set. The function
8497
finds charset information and returns length of prefix_len characters in the
8498
index field in bytes.
8500
NOTE: the prototype of this function is copied to data0type.c! If you change
8501
this function, you MUST change also data0type.c! */
8502
extern "C" UNIV_INTERN
8504
innobase_get_at_most_n_mbchars(
8505
/*===========================*/
8506
/* out: number of bytes occupied by the first
8508
ulint charset_id, /* in: character set id */
8509
ulint prefix_len, /* in: prefix length in bytes of the index
8510
(this has to be divided by mbmaxlen to get the
8511
number of CHARACTERS n in the prefix) */
8512
ulint data_len, /* in: length of the string in bytes */
8513
const char* str) /* in: character string */
8515
ulint char_length; /* character length in bytes */
8516
ulint n_chars; /* number of characters in prefix */
8517
CHARSET_INFO* charset; /* charset used in the field */
8519
charset = get_charset((uint) charset_id, MYF(MY_WME));
8522
ut_ad(charset->mbmaxlen);
8524
/* Calculate how many characters at most the prefix index contains */
8526
n_chars = prefix_len / charset->mbmaxlen;
8528
/* If the charset is multi-byte, then we must find the length of the
8529
first at most n chars in the string. If the string contains less
8530
characters than n, then we return the length to the end of the last
8533
if (charset->mbmaxlen > 1) {
8534
/* my_charpos() returns the byte length of the first n_chars
8535
characters, or a value bigger than the length of str, if
8536
there were not enough full characters in str.
8538
Why does the code below work:
8539
Suppose that we are looking for n UTF-8 characters.
8541
1) If the string is long enough, then the prefix contains at
8542
least n complete UTF-8 characters + maybe some extra
8543
characters + an incomplete UTF-8 character. No problem in
8544
this case. The function returns the pointer to the
8545
end of the nth character.
8547
2) If the string is not long enough, then the string contains
8548
the complete value of a column, that is, only complete UTF-8
8549
characters, and we can store in the column prefix index the
8552
char_length = my_charpos(charset, str,
8553
str + data_len, (int) n_chars);
8554
if (char_length > data_len) {
8555
char_length = data_len;
8558
if (data_len < prefix_len) {
8559
char_length = data_len;
8561
char_length = prefix_len;
8565
return(char_length);
8568
/***********************************************************************
8569
This function is used to prepare X/Open XA distributed transaction */
8572
innobase_xa_prepare(
8573
/*================*/
8574
/* out: 0 or error number */
8576
THD* thd, /* in: handle to the MySQL thread of the user
8577
whose XA transaction should be prepared */
8578
bool all) /* in: TRUE - commit transaction
8579
FALSE - the current SQL statement ended */
8582
trx_t* trx = check_trx_exists(thd);
8584
DBUG_ASSERT(hton == innodb_hton_ptr);
8586
if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
8587
(all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
8590
/* For ibbackup to work the order of transactions in binlog
8591
and InnoDB must be the same. Consider the situation
8593
thread1> prepare; write to binlog; ...
8595
thread2> prepare; write to binlog; commit
8598
To ensure this will not happen we're taking the mutex on
8599
prepare, and releasing it on commit.
8601
Note: only do it for normal commits, done via ha_commit_trans.
8602
If 2pc protocol is executed by external transaction
8603
coordinator, it will be just a regular MySQL client
8604
executing XA PREPARE and XA COMMIT commands.
8605
In this case we cannot know how many minutes or hours
8606
will be between XA PREPARE and XA COMMIT, and we don't want
8607
to block for undefined period of time.
8609
pthread_mutex_lock(&prepare_commit_mutex);
8610
trx->active_trans = 2;
8613
if (!THDVAR(thd, support_xa)) {
8618
thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
8620
/* Release a possible FIFO ticket and search latch. Since we will
8621
reserve the kernel mutex, we have to release the search system latch
8622
first to obey the latching order. */
8624
innobase_release_stat_resources(trx);
8626
if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
8628
sql_print_error("trx->active_trans == 0, but trx->conc_state != "
8633
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
8635
/* We were instructed to prepare the whole transaction, or
8636
this is an SQL statement end and autocommit is on */
8638
ut_ad(trx->active_trans);
8640
error = (int) trx_prepare_for_mysql(trx);
8642
/* We just mark the SQL statement ended and do not do a
8643
transaction prepare */
8645
/* If we had reserved the auto-inc lock for some
8646
table in this SQL statement we release it now */
8648
row_unlock_table_autoinc_for_mysql(trx);
8650
/* Store the current undo_no of the transaction so that we
8651
know where to roll back if we have to roll back the next
8654
trx_mark_sql_stat_end(trx);
8657
/* Tell the InnoDB server that there might be work for utility
8660
srv_active_wake_master_thread();
8665
/***********************************************************************
8666
This function is used to recover X/Open XA distributed transactions */
8669
innobase_xa_recover(
8670
/*================*/
8671
/* out: number of prepared transactions
8672
stored in xid_list */
8674
XID* xid_list, /* in/out: prepared transactions */
8675
uint len) /* in: number of slots in xid_list */
8677
DBUG_ASSERT(hton == innodb_hton_ptr);
8679
if (len == 0 || xid_list == NULL) {
8684
return(trx_recover_for_mysql(xid_list, len));
8687
/***********************************************************************
8688
This function is used to commit one X/Open XA distributed transaction
8689
which is in the prepared state */
8692
innobase_commit_by_xid(
8693
/*===================*/
8694
/* out: 0 or error number */
8696
XID* xid) /* in: X/Open XA transaction identification */
8700
DBUG_ASSERT(hton == innodb_hton_ptr);
8702
trx = trx_get_trx_by_xid(xid);
8705
innobase_commit_low(trx);
8713
/***********************************************************************
8714
This function is used to rollback one X/Open XA distributed transaction
8715
which is in the prepared state */
8718
innobase_rollback_by_xid(
8719
/*=====================*/
8720
/* out: 0 or error number */
8722
XID *xid) /* in: X/Open XA transaction identification */
8726
DBUG_ASSERT(hton == innodb_hton_ptr);
8728
trx = trx_get_trx_by_xid(xid);
8731
return(innobase_rollback_trx(trx));
8737
/***********************************************************************
8738
Create a consistent view for a cursor based on current transaction
8739
which is created if the corresponding MySQL thread still lacks one.
8740
This consistent view is then used inside of MySQL when accessing records
8744
innobase_create_cursor_view(
8745
/*========================*/
8746
/* out: pointer to cursor view or NULL */
8747
handlerton *hton, /* in: innobase hton */
8748
THD* thd) /* in: user thread handle */
8750
DBUG_ASSERT(hton == innodb_hton_ptr);
8752
return(read_cursor_view_create_for_mysql(check_trx_exists(thd)));
8755
/***********************************************************************
8756
Close the given consistent cursor view of a transaction and restore
8757
global read view to a transaction read view. Transaction is created if the
8758
corresponding MySQL thread still lacks one. */
8761
innobase_close_cursor_view(
8762
/*=======================*/
8764
THD* thd, /* in: user thread handle */
8765
void* curview)/* in: Consistent read view to be closed */
8767
DBUG_ASSERT(hton == innodb_hton_ptr);
8769
read_cursor_view_close_for_mysql(check_trx_exists(thd),
8770
(cursor_view_t*) curview);
8773
/***********************************************************************
8774
Set the given consistent cursor view to a transaction which is created
8775
if the corresponding MySQL thread still lacks one. If the given
8776
consistent cursor view is NULL global read view of a transaction is
8777
restored to a transaction read view. */
8780
innobase_set_cursor_view(
8781
/*=====================*/
8783
THD* thd, /* in: user thread handle */
8784
void* curview)/* in: Consistent cursor view to be set */
8786
DBUG_ASSERT(hton == innodb_hton_ptr);
8788
read_cursor_set_for_mysql(check_trx_exists(thd),
8789
(cursor_view_t*) curview);
8795
ha_innobase::check_if_incompatible_data(
8796
HA_CREATE_INFO* info,
8799
if (table_changes != IS_EQUAL_YES) {
8801
return(COMPATIBLE_DATA_NO);
8804
/* Check that auto_increment value was not changed */
8805
if ((info->used_fields & HA_CREATE_USED_AUTO) &&
8806
info->auto_increment_value != 0) {
8808
return(COMPATIBLE_DATA_NO);
8811
/* Check that row format didn't change */
8812
if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) &&
8813
get_row_type() != info->row_type) {
8815
return(COMPATIBLE_DATA_NO);
8818
/* Specifying KEY_BLOCK_SIZE requests a rebuild of the table. */
8819
if (info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE) {
8820
return(COMPATIBLE_DATA_NO);
8823
return(COMPATIBLE_DATA_YES);
8826
/****************************************************************
8827
Validate the file format name and return its corresponding id. */
8830
innobase_file_format_name_lookup(
8831
/*=============================*/
8832
/* out: valid file format id*/
8833
const char* format_name) /* in: pointer to file format name */
8838
ut_a(format_name != NULL);
8840
/* The format name can contain the format id itself instead of
8841
the name and we check for that. */
8842
format_id = (uint) strtoul(format_name, &endp, 10);
8844
/* Check for valid parse. */
8845
if (*endp == '\0' && *format_name != '\0') {
8847
if (format_id <= DICT_TF_FORMAT_MAX) {
8853
for (format_id = 0; format_id <= DICT_TF_FORMAT_MAX;
8857
name = trx_sys_file_format_id_to_name(format_id);
8859
if (!innobase_strcasecmp(format_name, name)) {
8866
return(DICT_TF_FORMAT_MAX + 1);
8869
/****************************************************************
8870
Validate the file format check value, is it one of "on" or "off",
8871
as a side affect it sets the srv_check_file_format_at_startup variable. */
8874
innobase_file_format_check_on_off(
8875
/*==============================*/
8876
/* out: true if config value one
8878
const char* format_check) /* in: parameter value */
8882
if (!innobase_strcasecmp(format_check, "off")) {
8884
/* Set the value to disable checking. */
8885
srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
8887
} else if (!innobase_strcasecmp(format_check, "on")) {
8889
/* Set the value to the lowest supported format. */
8890
srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
8898
/****************************************************************
8899
Validate the file format check config parameters, as a side affect it
8900
sets the srv_check_file_format_at_startup variable. */
8903
innobase_file_format_check_validate(
8904
/*================================*/
8905
/* out: true if valid config value */
8906
const char* format_check) /* in: parameter value */
8911
format_id = innobase_file_format_name_lookup(format_check);
8913
if (format_id < DICT_TF_FORMAT_MAX + 1) {
8914
srv_check_file_format_at_startup = format_id;
8922
/*****************************************************************
8923
Check if it is a valid file format. This function is registered as
8924
a callback with MySQL. */
8927
innodb_file_format_name_validate(
8928
/*=============================*/
8929
/* out: 0 for valid file
8931
THD* thd, /* in: thread handle */
8932
struct st_mysql_sys_var* var, /* in: pointer to system
8934
void* save, /* out: immediate result
8935
for update function */
8936
struct st_mysql_value* value) /* in: incoming string */
8938
const char* file_format_input;
8939
char buff[STRING_BUFFER_USUAL_SIZE];
8940
int len = sizeof(buff);
8943
ut_a(value != NULL);
8945
file_format_input = value->val_str(value, buff, &len);
8947
if (file_format_input != NULL) {
8950
format_id = innobase_file_format_name_lookup(
8953
if (format_id <= DICT_TF_FORMAT_MAX) {
8955
*(uint*) save = format_id;
8963
/********************************************************************
8964
Update the system variable innodb_file_format using the "saved"
8965
value. This function is registered as a callback with MySQL. */
8968
innodb_file_format_name_update(
8969
/*===========================*/
8970
/* out: should never
8972
already validated */
8973
THD* thd, /* in: thread handle */
8974
struct st_mysql_sys_var* var, /* in: pointer to
8976
void* var_ptr, /* out: where the
8977
formal string goes */
8978
void* save) /* in: immediate result
8979
from check function */
8981
ut_a(var_ptr != NULL);
8983
ut_a((*(uint*) save) <= DICT_TF_FORMAT_MAX);
8985
srv_file_format = *(uint*) save;
8987
/* Given the type of var_ptr we have little choice but to cast
8988
away the constness from the returned name. */
8989
(*(char**) var_ptr) =
8990
(char*) trx_sys_file_format_id_to_name(srv_file_format);
8995
/*****************************************************************
8996
Check if valid argument to innodb_file_format_check. This
8997
function is registered as a callback with MySQL. */
9000
innodb_file_format_check_validate(
9001
/*==============================*/
9002
/* out: 0 for valid file
9004
THD* thd, /* in: thread handle */
9005
struct st_mysql_sys_var* var, /* in: pointer to system
9007
void* save, /* out: immediate result
9008
for update function */
9009
struct st_mysql_value* value) /* in: incoming string */
9011
const char* file_format_input;
9012
char buff[STRING_BUFFER_USUAL_SIZE];
9013
int len = sizeof(buff);
9016
ut_a(value != NULL);
9018
file_format_input = value->val_str(value, buff, &len);
9020
if (file_format_input != NULL) {
9022
/* Check if user set on/off, we want to print a suitable
9023
message if they did so. */
9025
if (innobase_file_format_check_on_off(file_format_input)) {
9027
"InnoDB: invalid innodb_file_format_check"
9028
"value; on/off can only be set at startup or "
9029
"in the configuration file");
9030
} else if (innobase_file_format_check_validate(
9031
file_format_input)) {
9035
format_id = innobase_file_format_name_lookup(
9038
ut_a(format_id <= DICT_TF_FORMAT_MAX);
9040
*(uint*) save = format_id;
9046
"InnoDB: invalid innodb_file_format_check "
9047
"value; can be any format up to %s "
9048
"or its equivalent numeric id",
9049
trx_sys_file_format_id_to_name(
9050
DICT_TF_FORMAT_MAX));
9057
/********************************************************************
9058
Update the system variable innodb_file_format_check using the "saved"
9059
value. This function is registered as a callback with MySQL. */
9062
innodb_file_format_check_update(
9063
/*============================*/
9064
/* out: should never
9066
already validated */
9067
THD* thd, /* in: thread handle */
9068
struct st_mysql_sys_var* var, /* in: pointer to
9070
void* var_ptr, /* out: where the
9071
formal string goes */
9072
void* save) /* in: immediate result
9073
from check function */
9078
ut_a(var_ptr != NULL);
9080
format_id = *(uint*) save;
9082
/* Update the max format id in the system tablespace. */
9083
if (trx_sys_file_format_max_set(format_id, (char**) var_ptr)) {
9084
ut_print_timestamp(stderr);
9086
" [Info] InnoDB: the file format in the system "
9087
"tablespace is now set to %s.\n", *(char**) var_ptr);
9093
static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
9095
innodb_export_status();
9096
var->type= SHOW_ARRAY;
9097
var->value= (char *) &innodb_status_variables;
9101
static SHOW_VAR innodb_status_variables_export[]= {
9102
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
9103
{NullS, NullS, SHOW_LONG}
9106
static struct st_mysql_storage_engine innobase_storage_engine=
9107
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
9109
/* plugin options */
9110
static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums,
9111
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
9112
"Enable InnoDB checksums validation (enabled by default). "
9113
"Disable with --skip-innodb-checksums.",
9116
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
9117
PLUGIN_VAR_READONLY,
9118
"The common part for InnoDB table spaces.",
9121
static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
9122
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
9123
"Enable InnoDB doublewrite buffer (enabled by default). "
9124
"Disable with --skip-innodb-doublewrite.",
9127
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
9128
PLUGIN_VAR_OPCMDARG,
9129
"Speeds up the shutdown process of the InnoDB storage engine. Possible "
9130
"values are 0, 1 (faster)"
9132
NetWare can't close unclosed files, can't automatically kill remaining
9133
threads, etc, so on this OS we disable the crash-like InnoDB shutdown.
9135
IF_NETWARE("", " or 2 (fastest - crash-like)")
9137
NULL, NULL, 1, 0, IF_NETWARE(1,2), 0);
9139
static MYSQL_SYSVAR_BOOL(file_per_table, srv_file_per_table,
9140
PLUGIN_VAR_NOCMDARG,
9141
"Stores each InnoDB table to an .ibd file in the database dir.",
9144
static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name,
9145
PLUGIN_VAR_RQCMDARG,
9146
"File format to use for new tables in .ibd files.",
9147
(mysql_var_check_func) &innodb_file_format_name_validate,
9148
(mysql_var_update_func) &innodb_file_format_name_update, "Antelope");
9150
static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check,
9151
PLUGIN_VAR_OPCMDARG,
9152
"The highest file format in the tablespace.",
9153
(mysql_var_check_func) &innodb_file_format_check_validate,
9154
(mysql_var_update_func) &innodb_file_format_check_update,
9157
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
9158
PLUGIN_VAR_OPCMDARG,
9159
"Set to 0 (write and flush once per second),"
9160
" 1 (write and flush at each commit)"
9161
" or 2 (write at commit, flush once per second).",
9162
NULL, NULL, 1, 0, 2, 0);
9164
static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
9165
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9166
"With which method to flush data.", NULL, NULL, NULL);
9168
static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
9169
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
9170
"Force InnoDB to not use next-key locking, to use only row-level locking.",
9173
#ifdef UNIV_LOG_ARCHIVE
9174
static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
9175
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9176
"Where full logs should be archived.", NULL, NULL, NULL);
9178
static MYSQL_SYSVAR_BOOL(log_archive, innobase_log_archive,
9179
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
9180
"Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
9181
#endif /* UNIV_LOG_ARCHIVE */
9183
static MYSQL_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
9184
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9185
"Path to InnoDB log files.", NULL, NULL, NULL);
9187
static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
9188
PLUGIN_VAR_RQCMDARG,
9189
"Percentage of dirty pages allowed in bufferpool.",
9190
NULL, NULL, 90, 0, 100, 0);
9192
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
9193
PLUGIN_VAR_RQCMDARG,
9194
"Desired maximum length of the purge queue (0 = no limit)",
9195
NULL, NULL, 0, 0, ~0L, 0);
9197
static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
9198
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
9199
"Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
9202
static MYSQL_SYSVAR_BOOL(status_file, innobase_create_status_file,
9203
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
9204
"Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
9207
static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
9208
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
9209
"Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
9212
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index,
9213
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
9214
"Enable InnoDB adaptive hash index (enabled by default). "
9215
"Disable with --skip-innodb-adaptive-hash-index.",
9218
static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
9219
PLUGIN_VAR_RQCMDARG,
9220
"Replication thread delay (ms) on the slave server if "
9221
"innodb_thread_concurrency is reached (0 by default)",
9222
NULL, NULL, 0, 0, ~0UL, 0);
9224
static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
9225
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9226
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
9227
NULL, NULL, 1*1024*1024L, 512*1024L, ~0L, 1024);
9229
static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
9230
PLUGIN_VAR_RQCMDARG,
9231
"Data file autoextend increment in megabytes",
9232
NULL, NULL, 8L, 1L, 1000L, 0);
9234
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
9235
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9236
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
9237
NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
9239
static MYSQL_SYSVAR_ULONG(commit_concurrency, srv_commit_concurrency,
9240
PLUGIN_VAR_RQCMDARG,
9241
"Helps in performance tuning in heavily concurrent environments.",
9242
NULL, NULL, 0, 0, 1000, 0);
9244
static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
9245
PLUGIN_VAR_RQCMDARG,
9246
"Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
9247
NULL, NULL, 500L, 1L, ~0L, 0);
9249
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
9250
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9251
"Number of file I/O threads in InnoDB.",
9252
NULL, NULL, 4, 4, 64, 0);
9254
static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
9255
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9256
"Helps to save your data in case the disk image of the database becomes corrupt.",
9257
NULL, NULL, 0, 0, 6, 0);
9259
static MYSQL_SYSVAR_LONG(lock_wait_timeout, innobase_lock_wait_timeout,
9260
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9261
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.",
9262
NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
9264
static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
9265
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9266
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
9267
NULL, NULL, 1024*1024L, 256*1024L, ~0L, 1024);
9269
static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
9270
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9271
"Size of each log file in a log group.",
9272
NULL, NULL, 5*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 1024*1024L);
9274
static MYSQL_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
9275
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9276
"Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
9277
NULL, NULL, 2, 2, 100, 0);
9279
static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
9280
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9281
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
9282
NULL, NULL, 1, 1, 10, 0);
9284
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
9285
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9286
"How many files at the maximum InnoDB keeps open at the same time.",
9287
NULL, NULL, 300L, 10L, ~0L, 0);
9289
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
9290
PLUGIN_VAR_RQCMDARG,
9291
"Count of spin-loop rounds in InnoDB mutexes",
9292
NULL, NULL, 20L, 0L, ~0L, 0);
9294
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
9295
PLUGIN_VAR_RQCMDARG,
9296
"Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
9297
NULL, NULL, 8, 0, 1000, 0);
9299
static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
9300
PLUGIN_VAR_RQCMDARG,
9301
"Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
9302
NULL, NULL, 10000L, 0L, ~0L, 0);
9304
static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
9305
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9306
"Path to individual files and their sizes.",
9309
static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
9310
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
9311
"The AUTOINC lock modes supported by InnoDB: "
9312
"0 => Old style AUTOINC locking (for backward"
9314
"1 => New style AUTOINC locking "
9315
"2 => No AUTOINC locking (unsafe for SBR)",
9317
AUTOINC_NEW_STYLE_LOCKING, /* Default setting */
9318
AUTOINC_OLD_STYLE_LOCKING, /* Minimum value */
9319
AUTOINC_NO_LOCKING, 0); /* Maximum value */
9321
static MYSQL_SYSVAR_STR(version, innodb_version_str,
9322
PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
9323
"InnoDB version", NULL, NULL, INNODB_VERSION_STR);
9325
static struct st_mysql_sys_var* innobase_system_variables[]= {
9326
MYSQL_SYSVAR(additional_mem_pool_size),
9327
MYSQL_SYSVAR(autoextend_increment),
9328
MYSQL_SYSVAR(buffer_pool_size),
9329
MYSQL_SYSVAR(checksums),
9330
MYSQL_SYSVAR(commit_concurrency),
9331
MYSQL_SYSVAR(concurrency_tickets),
9332
MYSQL_SYSVAR(data_file_path),
9333
MYSQL_SYSVAR(data_home_dir),
9334
MYSQL_SYSVAR(doublewrite),
9335
MYSQL_SYSVAR(fast_shutdown),
9336
MYSQL_SYSVAR(file_io_threads),
9337
MYSQL_SYSVAR(file_per_table),
9338
MYSQL_SYSVAR(file_format),
9339
MYSQL_SYSVAR(file_format_check),
9340
MYSQL_SYSVAR(flush_log_at_trx_commit),
9341
MYSQL_SYSVAR(flush_method),
9342
MYSQL_SYSVAR(force_recovery),
9343
MYSQL_SYSVAR(locks_unsafe_for_binlog),
9344
MYSQL_SYSVAR(lock_wait_timeout),
9345
#ifdef UNIV_LOG_ARCHIVE
9346
MYSQL_SYSVAR(log_arch_dir),
9347
MYSQL_SYSVAR(log_archive),
9348
#endif /* UNIV_LOG_ARCHIVE */
9349
MYSQL_SYSVAR(log_buffer_size),
9350
MYSQL_SYSVAR(log_file_size),
9351
MYSQL_SYSVAR(log_files_in_group),
9352
MYSQL_SYSVAR(log_group_home_dir),
9353
MYSQL_SYSVAR(max_dirty_pages_pct),
9354
MYSQL_SYSVAR(max_purge_lag),
9355
MYSQL_SYSVAR(mirrored_log_groups),
9356
MYSQL_SYSVAR(open_files),
9357
MYSQL_SYSVAR(rollback_on_timeout),
9358
MYSQL_SYSVAR(stats_on_metadata),
9359
MYSQL_SYSVAR(adaptive_hash_index),
9360
MYSQL_SYSVAR(replication_delay),
9361
MYSQL_SYSVAR(status_file),
9362
MYSQL_SYSVAR(strict_mode),
9363
MYSQL_SYSVAR(support_xa),
9364
MYSQL_SYSVAR(sync_spin_loops),
9365
MYSQL_SYSVAR(table_locks),
9366
MYSQL_SYSVAR(thread_concurrency),
9367
MYSQL_SYSVAR(thread_sleep_delay),
9368
MYSQL_SYSVAR(autoinc_lock_mode),
9369
MYSQL_SYSVAR(version),
9373
#ifdef MYSQL_DYNAMIC_PLUGIN
9374
struct st_mysql_sys_var
9376
MYSQL_PLUGIN_VAR_HEADER;
9380
struct param_mapping
9382
const char* server; /* Parameter name in the server. */
9383
const char* plugin; /* Paramater name in the plugin. */
9386
/********************************************************************
9387
Match the parameters from the static and dynamic versions. */
9390
innobase_match_parameter(
9391
/*=====================*/
9392
/* out: true if names match */
9393
const char* from_server, /* in: variable name from server */
9394
const char* from_plugin) /* in: variable name from plugin */
9396
static const param_mapping param_map[] = {
9397
{"use_adaptive_hash_indexes", "adaptive_hash_index"}
9400
if (strcmp(from_server, from_plugin) == 0) {
9404
const param_mapping* param = param_map;
9405
int n_elems = sizeof(param_map) / sizeof(param_map[0]);
9407
for (int i = 0; i < n_elems; ++i, ++param) {
9409
if (strcmp(param->server, from_server) == 0
9410
&& strcmp(param->plugin, from_plugin) == 0) {
9419
/********************************************************************
9420
Copy InnoDB system variables from the static InnoDB to the dynamic
9424
innodb_plugin_init(void)
9425
/*====================*/
9426
/* out: TRUE if the dynamic InnoDB plugin should start */
9428
# if !MYSQL_STORAGE_ENGINE_PLUGIN
9429
# error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
9431
switch (builtin_innobase_plugin) {
9434
case MYSQL_STORAGE_ENGINE_PLUGIN:
9440
/* Copy the system variables. */
9441
struct st_mysql_plugin* builtin
9442
= (struct st_mysql_plugin*) &builtin_innobase_plugin;
9443
struct st_mysql_sys_var** v = builtin->system_vars;
9444
struct st_mysql_sys_var** w = innobase_system_variables;
9446
for (; *v; v++, w++) {
9448
fprintf(stderr, "InnoDB: unknown parameter %s,0x%x\n",
9449
(*v)->name, (*v)->flags);
9451
} else if (!innobase_match_parameter((*v)->name, (*w)->name)) {
9452
/* Skip the destination parameter, since it doesn't
9453
exist in the source. */
9456
/* Ignore changes that affect the READONLY flag. */
9457
} else if (((*v)->flags ^ (*w)->flags) & ~PLUGIN_VAR_READONLY) {
9459
"InnoDB: parameter mismatch:"
9460
" %s,%s,0x%x,0x%x\n",
9461
(*v)->name, (*w)->name,
9462
(*v)->flags, (*w)->flags);
9464
} else if ((*v)->flags & PLUGIN_VAR_THDLOCAL) {
9465
/* Do not copy session variables. */
9470
& ~(PLUGIN_VAR_MASK | PLUGIN_VAR_UNSIGNED)) {
9471
# define COPY_VAR(label, type) \
9473
*(type*)(*w)->value = *(type*)(*v)->value; \
9476
COPY_VAR(PLUGIN_VAR_BOOL, char);
9477
COPY_VAR(PLUGIN_VAR_INT, int);
9478
COPY_VAR(PLUGIN_VAR_LONG, long);
9479
COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
9480
COPY_VAR(PLUGIN_VAR_STR, char*);
9483
fprintf(stderr, "InnoDB: unknown flags 0x%x for %s\n",
9484
(*v)->flags, (*v)->name);
9487
/* Make the static InnoDB variable point to the dynamic one */
9488
(*v)->value = (*w)->value;
9493
#endif /* MYSQL_DYNAMIC_PLUGIN */
9495
mysql_declare_plugin(innobase)
9497
MYSQL_STORAGE_ENGINE_PLUGIN,
9498
&innobase_storage_engine,
9501
"Supports transactions, row-level locking, and foreign keys",
9503
innobase_init, /* Plugin Init */
9504
NULL, /* Plugin Deinit */
9505
INNODB_VERSION_SHORT,
9506
innodb_status_variables_export,/* status variables */
9507
innobase_system_variables, /* system variables */
9512
i_s_innodb_lock_waits,
9514
i_s_innodb_cmp_reset,
9516
i_s_innodb_cmpmem_reset
9517
mysql_declare_plugin_end;
9519
#ifdef UNIV_COMPILE_TEST_FUNCS
9521
typedef struct innobase_convert_name_test_struct {
9529
const char* expected;
9530
} innobase_convert_name_test_t;
9533
test_innobase_convert_name()
9538
innobase_convert_name_test_t test_input[] = {
9539
{buf, sizeof(buf), "abcd", 4, NULL, TRUE, "\"abcd\""},
9540
{buf, 7, "abcd", 4, NULL, TRUE, "\"abcd\""},
9541
{buf, 6, "abcd", 4, NULL, TRUE, "\"abcd\""},
9542
{buf, 5, "abcd", 4, NULL, TRUE, "\"abc\""},
9543
{buf, 4, "abcd", 4, NULL, TRUE, "\"ab\""},
9545
{buf, sizeof(buf), "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9546
{buf, 9, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9547
{buf, 8, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9548
{buf, 7, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9549
{buf, 6, "ab@0060cd", 9, NULL, TRUE, "\"ab`c\""},
9550
{buf, 5, "ab@0060cd", 9, NULL, TRUE, "\"ab`\""},
9551
{buf, 4, "ab@0060cd", 9, NULL, TRUE, "\"ab\""},
9553
{buf, sizeof(buf), "ab\"cd", 5, NULL, TRUE,
9554
"\"#mysql50#ab\"\"cd\""},
9555
{buf, 17, "ab\"cd", 5, NULL, TRUE,
9556
"\"#mysql50#ab\"\"cd\""},
9557
{buf, 16, "ab\"cd", 5, NULL, TRUE,
9558
"\"#mysql50#ab\"\"c\""},
9559
{buf, 15, "ab\"cd", 5, NULL, TRUE,
9560
"\"#mysql50#ab\"\"\""},
9561
{buf, 14, "ab\"cd", 5, NULL, TRUE,
9563
{buf, 13, "ab\"cd", 5, NULL, TRUE,
9565
{buf, 12, "ab\"cd", 5, NULL, TRUE,
9567
{buf, 11, "ab\"cd", 5, NULL, TRUE,
9569
{buf, 10, "ab\"cd", 5, NULL, TRUE,
9572
{buf, sizeof(buf), "ab/cd", 5, NULL, TRUE, "\"ab\".\"cd\""},
9573
{buf, 9, "ab/cd", 5, NULL, TRUE, "\"ab\".\"cd\""},
9574
{buf, 8, "ab/cd", 5, NULL, TRUE, "\"ab\".\"c\""},
9575
{buf, 7, "ab/cd", 5, NULL, TRUE, "\"ab\".\"\""},
9576
{buf, 6, "ab/cd", 5, NULL, TRUE, "\"ab\"."},
9577
{buf, 5, "ab/cd", 5, NULL, TRUE, "\"ab\"."},
9578
{buf, 4, "ab/cd", 5, NULL, TRUE, "\"ab\""},
9579
{buf, 3, "ab/cd", 5, NULL, TRUE, "\"a\""},
9580
{buf, 2, "ab/cd", 5, NULL, TRUE, "\"\""},
9581
/* XXX probably "" is a better result in this case
9582
{buf, 1, "ab/cd", 5, NULL, TRUE, "."},
9584
{buf, 0, "ab/cd", 5, NULL, TRUE, ""},
9587
for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
9593
fprintf(stderr, "TESTING %lu, %s, %lu, %s\n",
9594
test_input[i].buflen,
9596
test_input[i].idlen,
9597
test_input[i].expected);
9599
end = innobase_convert_name(
9601
test_input[i].buflen,
9603
test_input[i].idlen,
9605
test_input[i].file_id);
9607
res_len = (size_t) (end - test_input[i].buf);
9609
if (res_len != strlen(test_input[i].expected)) {
9611
fprintf(stderr, "unexpected len of the result: %u, "
9612
"expected: %u\n", (unsigned) res_len,
9613
(unsigned) strlen(test_input[i].expected));
9617
if (memcmp(test_input[i].buf,
9618
test_input[i].expected,
9619
strlen(test_input[i].expected)) != 0
9622
fprintf(stderr, "unexpected result: %.*s, "
9623
"expected: %s\n", (int) res_len,
9625
test_input[i].expected);
9630
fprintf(stderr, "OK: res: %.*s\n\n", (int) res_len,
9633
fprintf(stderr, "FAILED\n\n");
9639
#endif /* UNIV_COMPILE_TEST_FUNCS */