149
149
bool not_used __attribute__((unused)));
150
150
static INNOBASE_SHARE *get_share(const char *table_name);
151
151
static void free_share(INNOBASE_SHARE *share);
152
static int innobase_close_connection(handlerton *hton, Session* thd);
153
static int innobase_commit(handlerton *hton, Session* thd, bool all);
154
static int innobase_rollback(handlerton *hton, Session* thd, bool all);
155
static int innobase_rollback_to_savepoint(handlerton *hton, Session* thd,
152
static int innobase_close_connection(handlerton *hton, Session* session);
153
static int innobase_commit(handlerton *hton, Session* session, bool all);
154
static int innobase_rollback(handlerton *hton, Session* session, bool all);
155
static int innobase_rollback_to_savepoint(handlerton *hton, Session* session,
156
156
void *savepoint);
157
static int innobase_savepoint(handlerton *hton, Session* thd, void *savepoint);
158
static int innobase_release_savepoint(handlerton *hton, Session* thd,
157
static int innobase_savepoint(handlerton *hton, Session* session, void *savepoint);
158
static int innobase_release_savepoint(handlerton *hton, Session* session,
159
159
void *savepoint);
160
160
static handler *innobase_create_handler(handlerton *hton,
161
161
TABLE_SHARE *table,
189
189
/*================*/
190
190
/* out: 0 or error number */
191
191
handlerton* hton,
192
Session* thd, /* in: handle to the MySQL thread of the user
192
Session* session, /* in: handle to the MySQL thread of the user
193
193
whose XA transaction should be prepared */
194
194
bool all); /* in: TRUE - commit transaction
195
195
FALSE - the current SQL statement ended */
235
235
/*========================*/
236
236
/* out: pointer to cursor view or NULL */
237
237
handlerton* hton, /* in: innobase hton */
238
Session* thd); /* in: user thread handle */
238
Session* session); /* in: user thread handle */
239
239
/***********************************************************************
240
240
Set the given consistent cursor view to a transaction which is created
241
241
if the corresponding MySQL thread still lacks one. If the given
246
246
innobase_set_cursor_view(
247
247
/*=====================*/
248
248
handlerton* hton,
249
Session* thd, /* in: user thread handle */
249
Session* session, /* in: user thread handle */
250
250
void* curview);/* in: Consistent cursor view to be set */
251
251
/***********************************************************************
252
252
Close the given consistent cursor view of a transaction and restore
257
257
innobase_close_cursor_view(
258
258
/*=======================*/
259
259
handlerton* hton,
260
Session* thd, /* in: user thread handle */
260
Session* session, /* in: user thread handle */
261
261
void* curview);/* in: Consistent read view to be closed */
262
262
/*********************************************************************
263
263
Removes all tables in the named database inside InnoDB. */
273
273
the database name is 'test' */
275
275
/*********************************************************************
276
Creates an InnoDB transaction struct for the thd if it does not yet have one.
276
Creates an InnoDB transaction struct for the session if it does not yet have one.
277
277
Starts a new InnoDB transaction if a transaction is not yet started. And
278
278
assigns a new snapshot for a consistent read if the transaction does not yet
283
283
/*====================================*/
285
285
handlerton* hton, /* in: Innodb handlerton */
286
Session* thd); /* in: MySQL thread handle of the user for whom
286
Session* session); /* in: MySQL thread handle of the user for whom
287
287
the transaction should be committed */
288
288
/********************************************************************
289
289
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
303
303
innodb_show_status(
304
304
/*===============*/
305
305
handlerton* hton, /* in: the innodb handlerton */
306
Session* thd, /* in: the MySQL query thread of the caller */
306
Session* session, /* in: the MySQL query thread of the caller */
307
307
stat_print_fn *stat_print);
309
bool innobase_show_status(handlerton *hton, Session* thd,
309
bool innobase_show_status(handlerton *hton, Session* session,
310
310
stat_print_fn* stat_print,
311
311
enum ha_stat_type stat_type);
418
418
srv_conc_force_exit_innodb(). */
421
thd_is_replication_slave_thread(
421
session_is_replication_slave_thread(
422
422
/*============================*/
423
/* out: true if thd is the replication thread */
424
void* thd) /* in: thread handle (Session*) */
423
/* out: true if session is the replication thread */
424
void* session) /* in: thread handle (Session*) */
426
return((ibool) thd_slave_thread((Session*) thd));
426
return((ibool) session_slave_thread((Session*) session));
429
429
/**********************************************************************
489
489
rolling back transactions that have edited non-transactional tables. */
492
thd_has_edited_nontrans_tables(
492
session_has_edited_nontrans_tables(
493
493
/*===========================*/
494
494
/* out: true if non-transactional tables have
496
void* thd) /* in: thread handle (Session*) */
496
void* session) /* in: thread handle (Session*) */
498
return((ibool) thd_non_transactional_update((Session*) thd));
498
return((ibool) session_non_transactional_update((Session*) session));
501
501
/************************************************************************
502
502
Obtain the InnoDB transaction of a MySQL thread. */
507
507
/* out: reference to transaction pointer */
508
Session* thd) /* in: MySQL thread */
508
Session* session) /* in: MySQL thread */
510
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
510
return(*(trx_t**) session_ha_data(session, innodb_hton_ptr));
513
513
/************************************************************************
514
514
Call this function when mysqld passes control to the client. That is to
515
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
515
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
516
516
documentation, see handler.cc. */
520
520
/*===============================*/
522
522
handlerton* hton __attribute__((unused)), /* in: handlerton */
523
Session* thd) /* in: MySQL thread */
523
Session* session) /* in: MySQL thread */
566
566
/*========================*/
567
567
/* out: MySQL error code */
568
568
int error, /* in: InnoDB error code */
569
Session* thd) /* in: user thread handle or NULL */
569
Session* session) /* in: user thread handle or NULL */
571
571
if (error == DB_SUCCESS) {
593
593
tell it also to MySQL so that MySQL knows to empty the
594
594
cached binlog for this transaction */
596
thd_mark_transaction_to_rollback(thd, TRUE);
596
session_mark_transaction_to_rollback(session, TRUE);
598
598
return(HA_ERR_LOCK_DEADLOCK);
599
599
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
602
602
latest SQL statement in a lock wait timeout. Previously, we
603
603
rolled back the whole transaction. */
605
thd_mark_transaction_to_rollback(thd,
605
session_mark_transaction_to_rollback(session,
606
606
(bool)row_rollback_on_timeout);
608
608
return(HA_ERR_LOCK_WAIT_TIMEOUT);
655
655
tell it also to MySQL so that MySQL knows to empty the
656
656
cached binlog for this transaction */
658
thd_mark_transaction_to_rollback(thd, TRUE);
658
session_mark_transaction_to_rollback(session, TRUE);
660
660
return(HA_ERR_LOCK_TABLE_FULL);
661
661
} else if (error == DB_TOO_MANY_CONCURRENT_TRXS) {
683
683
/*****************************************************************
684
If you want to print a thd that is not associated with the current thread,
684
If you want to print a session that is not associated with the current thread,
685
685
you must call this function before reserving the InnoDB kernel_mutex, to
686
protect MySQL from setting thd->query NULL. If you print a thd of the current
687
thread, we know that MySQL cannot modify thd->query, and it is not necessary
688
to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
686
protect MySQL from setting session->query NULL. If you print a session of the current
687
thread, we know that MySQL cannot modify session->query, and it is not necessary
688
to call this. Call innobase_mysql_end_print_arbitrary_session() after you release
689
689
the kernel_mutex.
690
690
NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
694
innobase_mysql_prepare_print_arbitrary_thd(void)
694
innobase_mysql_prepare_print_arbitrary_session(void)
695
695
/*============================================*/
697
697
pthread_mutex_lock(&LOCK_thread_count);
700
700
/*****************************************************************
701
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
701
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_session().
702
702
NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
706
innobase_mysql_end_print_arbitrary_thd(void)
706
innobase_mysql_end_print_arbitrary_session(void)
707
707
/*========================================*/
709
709
pthread_mutex_unlock(&LOCK_thread_count);
715
715
this function! */
718
innobase_mysql_print_thd(
718
innobase_mysql_print_session(
719
719
/*=====================*/
720
720
FILE* f, /* in: output stream */
721
void* input_thd __attribute__((unused)), /* in: pointer to a MySQL Session object */
721
void* input_session __attribute__((unused)), /* in: pointer to a MySQL Session object */
722
722
uint max_query_len __attribute__((unused))) /* in: max query length to print, or 0 to
723
723
use the default max length */
772
strconvert(thd_charset(current_thd), from,
772
strconvert(session_charset(current_session), from,
773
773
&my_charset_filename, to, (uint) len, &errors);
791
strconvert(thd_charset(current_thd), from,
791
strconvert(session_charset(current_session), from,
792
792
system_charset_info, to, (uint) len, &errors);
832
832
innobase_get_charset(
833
833
/*=================*/
834
834
/* out: connection character set */
835
void* mysql_thd) /* in: MySQL thread handle */
835
void* mysql_session) /* in: MySQL thread handle */
837
return(thd_charset((Session*) mysql_thd));
837
return(session_charset((Session*) mysql_session));
840
840
/*************************************************************************
897
897
check_trx_exists(
898
898
/*=============*/
899
899
/* out: InnoDB transaction handle */
900
Session* thd) /* in: user thread handle */
900
Session* session) /* in: user thread handle */
902
trx_t*& trx = thd_to_trx(thd);
902
trx_t*& trx = session_to_trx(session);
904
ut_ad(thd == current_thd);
904
ut_ad(session == current_session);
906
906
if (trx == NULL) {
907
assert(session != NULL);
908
908
trx = trx_allocate_for_mysql();
910
trx->mysql_thd = thd;
911
trx->mysql_query_str = thd_query(thd);
910
trx->mysql_session = session;
911
trx->mysql_query_str = session_query(session);
913
913
/* Update the info whether we should skip XA steps that eat
915
trx->support_xa = SessionVAR(thd, support_xa);
915
trx->support_xa = SessionVAR(session, support_xa);
917
917
if (trx->magic_n != TRX_MAGIC_N) {
918
918
mem_analyze_corruption(trx);
924
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
924
if (session_test_options(session, OPTION_NO_FOREIGN_KEY_CHECKS)) {
925
925
trx->check_foreigns = FALSE;
927
927
trx->check_foreigns = TRUE;
930
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
930
if (session_test_options(session, OPTION_RELAXED_UNIQUE_CHECKS)) {
931
931
trx->check_unique_secondary = FALSE;
933
933
trx->check_unique_secondary = TRUE;
965
965
/*************************************************************************
966
Updates the user_thd field in a handle and also allocates a new InnoDB
966
Updates the user_session field in a handle and also allocates a new InnoDB
967
967
transaction handle if needed, and updates the transaction fields in the
968
968
prebuilt struct. */
971
ha_innobase::update_thd(
971
ha_innobase::update_session(
972
972
/*====================*/
973
973
/* out: 0 or error code */
974
Session* thd) /* in: thd to use the handle */
974
Session* session) /* in: session to use the handle */
978
trx = check_trx_exists(thd);
978
trx = check_trx_exists(session);
980
980
if (prebuilt->trx != trx) {
982
982
row_update_prebuilt_trx(prebuilt, trx);
985
user_session = session;
997
997
innobase_register_stmt(
998
998
/*===================*/
999
999
handlerton* hton, /* in: Innobase hton */
1000
Session* thd) /* in: MySQL thd (connection) object */
1000
Session* session) /* in: MySQL session (connection) object */
1002
1002
/* Register the statement */
1003
trans_register_ha(thd, FALSE, hton);
1003
trans_register_ha(session, FALSE, hton);
1006
1006
/*************************************************************************
1015
1015
innobase_register_trx_and_stmt(
1016
1016
/*===========================*/
1017
1017
handlerton *hton, /* in: Innobase handlerton */
1018
Session* thd) /* in: MySQL thd (connection) object */
1018
Session* session) /* in: MySQL session (connection) object */
1020
1020
/* NOTE that actually innobase_register_stmt() registers also
1021
1021
the transaction in the AUTOCOMMIT=1 mode. */
1023
innobase_register_stmt(hton, thd);
1023
innobase_register_stmt(hton, session);
1025
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1025
if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1027
1027
/* No autocommit mode, register for a transaction */
1028
trans_register_ha(thd, TRUE, hton);
1028
trans_register_ha(session, TRUE, hton);
1063
1063
invalidation to the transaction commit.
1065
1065
2) To store or retrieve a value from the query cache of an InnoDB table TBL,
1066
any query must first ask InnoDB's permission. We must pass the thd as a
1066
any query must first ask InnoDB's permission. We must pass the session as a
1067
1067
parameter because InnoDB will look at the trx id, if any, associated with
1070
1070
3) Use of the query cache for InnoDB tables is now allowed also when
1071
1071
AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
1080
1080
The query cache is allowed to operate on certain query only if this function
1081
1081
returns TRUE for all tables in the query.
1083
If thd is not in the autocommit state, this function also starts a new
1084
transaction for thd if there is no active trx yet, and assigns a consistent
1083
If session is not in the autocommit state, this function also starts a new
1084
transaction for session if there is no active trx yet, and assigns a consistent
1085
1085
read view to it if there is no read view yet.
1087
1087
Why a deadlock of threads is not possible: the query cache calls this function
1098
1098
note that the value FALSE does not mean
1099
1099
we should invalidate the query cache:
1100
1100
invalidation is called explicitly */
1101
Session* thd, /* in: thd of the user who is trying to
1101
Session* session, /* in: session of the user who is trying to
1102
1102
store a result to the query cache or
1104
1104
char* full_name, /* in: concatenation of database name,
1115
1115
ut_a(full_name_len < 999);
1117
trx = check_trx_exists(thd);
1117
trx = check_trx_exists(session);
1119
1119
if (trx->isolation_level == TRX_ISO_SERIALIZABLE) {
1120
1120
/* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every
1219
1219
/* Argument TRUE below means we are using transactions */
1220
1220
#ifdef HAVE_QUERY_CACHE
1221
mysql_query_cache_invalidate4((Session*) trx->mysql_thd,
1221
mysql_query_cache_invalidate4((Session*) trx->mysql_session,
1222
1222
(const char*) full_name,
1223
1223
(uint32_t) full_name_len,
1268
if (!trx || !trx->mysql_thd) {
1268
if (!trx || !trx->mysql_session) {
1272
q = get_quote_char_for_identifier((Session*) trx->mysql_thd,
1272
q = get_quote_char_for_identifier((Session*) trx->mysql_session,
1273
1273
s, (int) namelen);
1300
1300
/* out: TRUE if interrupted */
1301
1301
trx_t* trx) /* in: transaction */
1303
return(trx && trx->mysql_thd && thd_killed((Session*) trx->mysql_thd));
1303
return(trx && trx->mysql_session && session_killed((Session*) trx->mysql_session));
1306
1306
/******************************************************************
1327
1327
ha_innobase::init_table_handle_for_HANDLER(void)
1328
1328
/*============================================*/
1330
/* If current thd does not yet have a trx struct, create one.
1330
/* If current session does not yet have a trx struct, create one.
1331
1331
If the current handle does not yet have a prebuilt struct, create
1332
1332
one. Update the trx pointers in the prebuilt struct. Normally
1333
1333
this operation is done in external_lock. */
1335
update_thd(ha_thd());
1335
update_session(ha_session());
1337
1337
/* Initialize the prebuilt struct much like it would be inited in
1338
1338
external_lock */
1352
1352
if (prebuilt->trx->active_trans == 0) {
1354
innobase_register_trx_and_stmt(ht, user_thd);
1354
innobase_register_trx_and_stmt(ht, user_session);
1356
1356
prebuilt->trx->active_trans = 1;
1706
1706
/*********************************************************************
1707
Creates an InnoDB transaction struct for the thd if it does not yet have one.
1707
Creates an InnoDB transaction struct for the session if it does not yet have one.
1708
1708
Starts a new InnoDB transaction if a transaction is not yet started. And
1709
1709
assigns a new snapshot for a consistent read if the transaction does not yet
1714
1714
/*====================================*/
1716
1716
handlerton *hton, /* in: Innodb handlerton */
1717
Session* thd) /* in: MySQL thread handle of the user for whom
1717
Session* session) /* in: MySQL thread handle of the user for whom
1718
1718
the transaction should be committed */
1722
/* Create a new trx struct for thd, if it does not yet have one */
1722
/* Create a new trx struct for session, if it does not yet have one */
1724
trx = check_trx_exists(thd);
1724
trx = check_trx_exists(session);
1726
1726
/* This is just to play safe: release a possible FIFO ticket and
1727
1727
search latch. Since we will reserve the kernel mutex, we have to
1740
1740
/* Set the MySQL flag to mark that there is an active transaction */
1742
1742
if (trx->active_trans == 0) {
1743
innobase_register_trx_and_stmt(hton, current_thd);
1743
innobase_register_trx_and_stmt(hton, current_session);
1744
1744
trx->active_trans = 1;
1756
1756
/*============*/
1758
1758
handlerton *hton __attribute__((unused)), /* in: Innodb handlerton */
1759
Session* thd, /* in: MySQL thread handle of the user for whom
1759
Session* session, /* in: MySQL thread handle of the user for whom
1760
1760
the transaction should be committed */
1761
1761
bool all) /* in: TRUE - commit transaction
1762
1762
FALSE - the current SQL statement ended */
1766
trx = check_trx_exists(thd);
1766
trx = check_trx_exists(session);
1768
1768
/* Update the info whether we should skip XA steps that eat CPU time */
1769
trx->support_xa = SessionVAR(thd, support_xa);
1769
trx->support_xa = SessionVAR(session, support_xa);
1771
1771
/* Since we will reserve the kernel mutex, we have to release
1772
1772
the search system latch first to obey the latching order. */
1797
1797
" trx->conc_state != TRX_NOT_STARTED");
1800
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
1800
|| (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
1802
1802
/* We were instructed to commit the whole transaction, or
1803
1803
this is an SQL statement end and autocommit is on */
1880
1880
/*==============*/
1881
1881
/* out: 0 or error number */
1882
1882
handlerton *hton __attribute__((unused)), /* in: Innodb handlerton */
1883
Session* thd, /* in: handle to the MySQL thread of the user
1883
Session* session, /* in: handle to the MySQL thread of the user
1884
1884
whose transaction should be rolled back */
1885
1885
bool all) /* in: TRUE - commit transaction
1886
1886
FALSE - the current SQL statement ended */
1891
trx = check_trx_exists(thd);
1891
trx = check_trx_exists(session);
1893
1893
/* Update the info whether we should skip XA steps that eat CPU time */
1894
trx->support_xa = SessionVAR(thd, support_xa);
1894
trx->support_xa = SessionVAR(session, support_xa);
1896
1896
/* Release a possible FIFO ticket and search latch. Since we will
1897
1897
reserve the kernel mutex, we have to release the search system latch
1906
1906
row_unlock_table_autoinc_for_mysql(trx);
1909
|| !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1909
|| !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1911
1911
error = trx_rollback_for_mysql(trx);
1912
1912
trx->active_trans = 0;
1954
1954
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
1955
1955
no savepoint with the given name */
1956
1956
handlerton *hton __attribute__((unused)), /* in: Innodb handlerton */
1957
Session* thd, /* in: handle to the MySQL thread of the user
1957
Session* session, /* in: handle to the MySQL thread of the user
1958
1958
whose transaction should be rolled back */
1959
1959
void* savepoint) /* in: savepoint data */
1966
trx = check_trx_exists(thd);
1966
trx = check_trx_exists(session);
1968
1968
/* Release a possible FIFO ticket and search latch. Since we will
1969
1969
reserve the kernel mutex, we have to release the search system latch
1989
1989
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
1990
1990
no savepoint with the given name */
1991
1991
handlerton* hton __attribute__((unused)), /* in: handlerton for Innodb */
1992
Session* thd, /* in: handle to the MySQL thread of the user
1992
Session* session, /* in: handle to the MySQL thread of the user
1993
1993
whose transaction should be rolled back */
1994
1994
void* savepoint) /* in: savepoint data */
2016
2016
/*===============*/
2017
2017
/* out: always 0, that is, always succeeds */
2018
2018
handlerton* hton __attribute__((unused)), /* in: handle to the Innodb handlerton */
2019
Session* thd, /* in: handle to the MySQL thread */
2019
Session* session, /* in: handle to the MySQL thread */
2020
2020
void* savepoint) /* in: savepoint data */
2027
2027
(unless we are in sub-statement), so SQL layer ensures that
2028
2028
this method is never called in such situation.
2030
#ifdef DRIZZLE_SERVER /* plugins cannot access thd->in_sub_stmt */
2031
assert(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2030
#ifdef DRIZZLE_SERVER /* plugins cannot access session->in_sub_stmt */
2031
assert(session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
2032
session->in_sub_stmt);
2033
2033
#endif /* DRIZZLE_SERVER */
2035
trx = check_trx_exists(thd);
2035
trx = check_trx_exists(session);
2037
2037
/* Release a possible FIFO ticket and search latch. Since we will
2038
2038
reserve the kernel mutex, we have to release the search system latch
2060
2060
/*======================*/
2061
2061
/* out: 0 or error number */
2062
2062
handlerton* hton __attribute__((unused)), /* in: innobase handlerton */
2063
Session* thd) /* in: handle to the MySQL thread of the user
2063
Session* session) /* in: handle to the MySQL thread of the user
2064
2064
whose resources should be free'd */
2068
2068
assert(hton == innodb_hton_ptr);
2069
trx = thd_to_trx(thd);
2069
trx = session_to_trx(session);
2128
2128
/* Need to use tx_isolation here since table flags is (also)
2129
2129
called before prebuilt is inited. */
2130
ulong const tx_isolation = thd_tx_isolation(current_thd);
2130
ulong const tx_isolation = session_tx_isolation(current_session);
2131
2131
if (tx_isolation <= ISO_READ_COMMITTED)
2132
2132
return int_table_flags;
2133
2133
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
2269
2269
return(HA_ERR_NO_SUCH_TABLE);
2272
if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) {
2272
if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
2273
2273
sql_print_error("MySQL is trying to open a table handle but "
2274
2274
"the .ibd file for\ntable %s does not exist.\n"
2275
2275
"Have you deleted the .ibd file from the "
2375
2375
/*====================*/
2380
thd = current_thd; // avoid calling current_thd twice, it may be slow
2382
innobase_release_temporary_latches(ht, thd);
2380
session = current_session; // avoid calling current_session twice, it may be slow
2381
if (session != NULL) {
2382
innobase_release_temporary_latches(ht, session);
2385
2385
row_prebuilt_free(prebuilt);
2886
2886
build_template(
2887
2887
/*===========*/
2888
2888
row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */
2889
Session* thd __attribute__((unused)), /* in: current user thread, used
2889
Session* session __attribute__((unused)), /* in: current user thread, used
2890
2890
only if templ_type is
2891
2891
ROW_DRIZZLE_REC_FIELDS */
2892
2892
Table* table, /* in: MySQL table */
3166
3166
old style only if another transaction has already acquired
3167
3167
the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
3168
3168
etc. type of statement. */
3169
if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
3169
if (session_sql_command(user_session) == SQLCOM_INSERT) {
3170
3170
dict_table_t* table = prebuilt->table;
3172
3172
/* Acquire the AUTOINC mutex. */
3263
3263
ibool auto_inc_used= FALSE;
3264
3264
ulint sql_command;
3265
trx_t* trx = thd_to_trx(user_thd);
3265
trx_t* trx = session_to_trx(user_session);
3267
3267
if (prebuilt->trx != trx) {
3268
3268
sql_print_error("The transaction object for the table handle is at "
3284
3284
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
3285
3285
table->timestamp_field->set_time();
3287
sql_command = thd_sql_command(user_thd);
3287
sql_command = session_sql_command(user_session);
3289
3289
if ((sql_command == SQLCOM_ALTER_TABLE
3290
3290
|| sql_command == SQLCOM_OPTIMIZE
3328
3328
no need to re-acquire locks on it. */
3330
3330
/* Altering to InnoDB format */
3331
innobase_commit(ht, user_thd, 1);
3331
innobase_commit(ht, user_session, 1);
3332
3332
/* Note that this transaction is still active. */
3333
3333
prebuilt->trx->active_trans = 1;
3334
3334
/* We will need an IX lock on the destination table. */
3345
3345
/* Commit the transaction. This will release the table
3346
3346
locks, so they have to be acquired again. */
3347
innobase_commit(ht, user_thd, 1);
3347
innobase_commit(ht, user_session, 1);
3348
3348
/* Note that this transaction is still active. */
3349
3349
prebuilt->trx->active_trans = 1;
3350
3350
/* Re-acquire the table lock on the source table. */
3473
3473
unsigned char* upd_buff, /* in: buffer to use */
3474
3474
ulint buff_len, /* in: buffer length */
3475
3475
row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
3476
Session* thd __attribute__((unused))) /* in: user thread */
3476
Session* session __attribute__((unused))) /* in: user thread */
3478
3478
unsigned char* original_upd_buff = upd_buff;
3647
3647
calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
3648
3648
upd_buff, (ulint)upd_and_key_val_buff_len,
3649
prebuilt, user_thd);
3649
prebuilt, user_session);
3651
3651
/* This is not a delete */
3652
3652
prebuilt->upd_node->is_delete = FALSE;
3668
3668
if (error == DB_SUCCESS
3669
3669
&& table->next_number_field
3670
3670
&& new_row == table->record[0]
3671
&& thd_sql_command(user_thd) == SQLCOM_INSERT
3671
&& session_sql_command(user_session) == SQLCOM_INSERT
3672
3672
&& (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
3673
3673
== TRX_DUP_IGNORE) {
3686
3686
innodb_srv_conc_exit_innodb(trx);
3688
error = convert_error_code_to_mysql(error, user_thd);
3688
error = convert_error_code_to_mysql(error, user_session);
3690
3690
/* Tell InnoDB server that there might be work for
3691
3691
utility threads: */
3748
3748
innodb_srv_conc_exit_innodb(trx);
3751
error = convert_error_code_to_mysql(error, user_thd);
3751
error = convert_error_code_to_mysql(error, user_session);
3753
3753
/* Tell the InnoDB server that there might be work for
3754
3754
utility threads: */
3805
3805
ha_innobase::try_semi_consistent_read(bool yes)
3806
3806
/*===========================================*/
3808
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
3808
ut_a(prebuilt->trx == session_to_trx(ha_session()));
3810
3810
/* Row read type is set to semi consistent read if this was
3811
3811
requested by the MySQL and either innodb_locks_unsafe_for_binlog
3997
3997
necessarily prebuilt->index, but can also be the clustered index */
3999
3999
if (prebuilt->sql_stat_start) {
4000
build_template(prebuilt, user_thd, table, this,
4000
build_template(prebuilt, user_session, table, this,
4001
4001
ROW_DRIZZLE_REC_FIELDS);
4057
4057
error = HA_ERR_KEY_NOT_FOUND;
4058
4058
table->status = STATUS_NOT_FOUND;
4060
error = convert_error_code_to_mysql((int) ret, user_thd);
4060
error = convert_error_code_to_mysql((int) ret, user_session);
4061
4061
table->status = STATUS_NOT_FOUND;
4099
4099
ha_statistic_increment(&SSV::ha_read_key_count);
4101
ut_ad(user_thd == ha_thd());
4102
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4101
ut_ad(user_session == ha_session());
4102
ut_a(prebuilt->trx == session_to_trx(user_session));
4104
4104
if (keynr != MAX_KEY && table->s->keys > 0) {
4105
4105
key = table->key_info + keynr;
4132
4132
index, even if it was internally generated by
4135
ut_ad(user_thd == ha_thd());
4136
ut_a(prebuilt->trx == thd_to_trx(user_thd));
4135
ut_ad(user_session == ha_session());
4136
ut_a(prebuilt->trx == session_to_trx(user_session));
4138
4138
active_index = keynr;
4156
4156
the flag ROW_DRIZZLE_WHOLE_ROW below, but that caused unnecessary
4157
4157
copying. Starting from MySQL-4.1 we use a more efficient flag here. */
4159
build_template(prebuilt, user_thd, table, this, ROW_DRIZZLE_REC_FIELDS);
4159
build_template(prebuilt, user_session, table, this, ROW_DRIZZLE_REC_FIELDS);
4225
4225
error = HA_ERR_END_OF_FILE;
4226
4226
table->status = STATUS_NOT_FOUND;
4228
error = convert_error_code_to_mysql((int) ret, user_thd);
4228
error = convert_error_code_to_mysql((int) ret, user_session);
4229
4229
table->status = STATUS_NOT_FOUND;
4420
4420
ha_statistic_increment(&SSV::ha_read_rnd_count);
4422
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
4422
ut_a(prebuilt->trx == session_to_trx(ha_session()));
4424
4424
/* Note that we assume the length of the row reference is fixed
4425
4425
for the table, and it is == ref_length */
4797
4797
char name2[FN_REFLEN];
4798
4798
char norm_name[FN_REFLEN];
4799
Session* thd = ha_thd();
4799
Session* session = ha_session();
4800
4800
ib_longlong auto_inc_value;
4803
assert(thd != NULL);
4803
assert(session != NULL);
4805
4805
if (form->s->stored_fields > 1000) {
4806
4806
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
4809
4809
return(HA_ERR_TO_BIG_ROW);
4812
/* Get the transaction associated with the current thd, or create one
4812
/* Get the transaction associated with the current session, or create one
4813
4813
if not yet created */
4815
parent_trx = check_trx_exists(thd);
4815
parent_trx = check_trx_exists(session);
4817
4817
/* In case MySQL calls this in the middle of a SELECT query, release
4818
4818
possible adaptive hash latch to avoid deadlocks of threads */
4822
4822
trx = trx_allocate_for_mysql();
4824
trx->mysql_thd = thd;
4825
trx->mysql_query_str = thd_query(thd);
4824
trx->mysql_session = session;
4825
trx->mysql_query_str = session_query(session);
4827
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
4827
if (session_test_options(session, OPTION_NO_FOREIGN_KEY_CHECKS)) {
4828
4828
trx->check_foreigns = FALSE;
4831
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
4831
if (session_test_options(session, OPTION_RELAXED_UNIQUE_CHECKS)) {
4832
4832
trx->check_unique_secondary = FALSE;
5015
/* Get the transaction associated with the current thd, or create one
5015
/* Get the transaction associated with the current session, or create one
5016
5016
if not yet created, and update prebuilt->trx */
5018
update_thd(ha_thd());
5018
update_session(ha_session());
5020
if (thd_sql_command(user_thd) != SQLCOM_TRUNCATE) {
5020
if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
5022
5022
/* We only handle TRUNCATE Table t as a special case.
5023
5023
DELETE FROM t will have to use ha_innobase::delete_row(). */
5055
5055
trx_t* parent_trx;
5057
Session *thd = ha_thd();
5057
Session *session = ha_session();
5058
5058
char norm_name[1000];
5060
/* Get the transaction associated with the current thd, or create one
5060
/* Get the transaction associated with the current session, or create one
5061
5061
if not yet created */
5063
parent_trx = check_trx_exists(thd);
5063
parent_trx = check_trx_exists(session);
5065
5065
/* In case MySQL calls this in the middle of a SELECT query, release
5066
5066
possible adaptive hash latch to avoid deadlocks of threads */
5076
5076
trx = trx_allocate_for_mysql();
5078
trx->mysql_thd = thd;
5079
trx->mysql_query_str = thd_query(thd);
5078
trx->mysql_session = session;
5079
trx->mysql_query_str = session_query(session);
5081
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5081
if (session_test_options(session, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5082
5082
trx->check_foreigns = FALSE;
5085
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
5085
if (session_test_options(session, OPTION_RELAXED_UNIQUE_CHECKS)) {
5086
5086
trx->check_unique_secondary = FALSE;
5098
5098
/* Drop the table in InnoDB */
5100
5100
error = row_drop_table_for_mysql(norm_name, trx,
5101
thd_sql_command(thd)
5101
session_sql_command(session)
5102
5102
== SQLCOM_DROP_DB);
5104
5104
/* Flush the log to reduce probability that the .frm files and
5143
Session* thd = current_thd;
5143
Session* session = current_session;
5145
/* Get the transaction associated with the current thd, or create one
5145
/* Get the transaction associated with the current session, or create one
5146
5146
if not yet created */
5148
parent_trx = check_trx_exists(thd);
5148
parent_trx = check_trx_exists(session);
5150
5150
/* In case MySQL calls this in the middle of a SELECT query, release
5151
5151
possible adaptive hash latch to avoid deadlocks of threads */
5169
5169
innobase_casedn_str(namebuf);
5171
5171
trx = trx_allocate_for_mysql();
5172
trx->mysql_thd = thd;
5173
trx->mysql_query_str = thd_query(thd);
5172
trx->mysql_session = session;
5173
trx->mysql_query_str = session_query(session);
5175
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5175
if (session_test_options(session, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5176
5176
trx->check_foreigns = FALSE;
5219
5219
char norm_from[1000];
5220
5220
char norm_to[1000];
5221
Session* thd = ha_thd();
5221
Session* session = ha_session();
5223
/* Get the transaction associated with the current thd, or create one
5223
/* Get the transaction associated with the current session, or create one
5224
5224
if not yet created */
5226
parent_trx = check_trx_exists(thd);
5226
parent_trx = check_trx_exists(session);
5228
5228
/* In case MySQL calls this in the middle of a SELECT query, release
5229
5229
possible adaptive hash latch to avoid deadlocks of threads */
5239
5239
trx = trx_allocate_for_mysql();
5240
trx->mysql_thd = thd;
5241
trx->mysql_query_str = thd_query(thd);
5240
trx->mysql_session = session;
5241
trx->mysql_query_str = session_query(session);
5243
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5243
if (session_test_options(session, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5244
5244
trx->check_foreigns = FALSE;
5393
5393
uint64_t local_data_file_length;
5395
5395
/* We do not know if MySQL can call this function before calling
5396
external_lock(). To be safe, update the thd of the current table
5396
external_lock(). To be safe, update the session of the current table
5399
update_thd(ha_thd());
5399
update_session(ha_session());
5401
5401
prebuilt->trx->op_info = (char*)
5402
5402
"calculating upper bound for table rows";
5515
5515
/* We do not know if MySQL can call this function before calling
5516
external_lock(). To be safe, update the thd of the current table
5516
external_lock(). To be safe, update the session of the current table
5519
update_thd(ha_thd());
5519
update_session(ha_session());
5521
5521
/* In case MySQL calls this in the middle of a SELECT query, release
5522
5522
possible adaptive hash latch to avoid deadlocks of threads */
5705
5705
ha_innobase::analyze(
5706
5706
/*=================*/
5707
5707
/* out: returns always 0 (success) */
5708
Session* thd __attribute__((unused)), /* in: connection thread handle */
5708
Session* session __attribute__((unused)), /* in: connection thread handle */
5709
5709
HA_CHECK_OPT* check_opt __attribute__((unused))) /* in: currently ignored */
5711
5711
/* Simply call ::info() with all the flags */
5722
5722
ha_innobase::optimize(
5723
5723
/*==================*/
5724
Session* thd __attribute__((unused)), /* in: connection thread handle */
5724
Session* session __attribute__((unused)), /* in: connection thread handle */
5725
5725
HA_CHECK_OPT* check_opt __attribute__((unused))) /* in: currently ignored */
5727
5727
return(HA_ADMIN_TRY_ALTER);
5737
5737
/*===============*/
5738
5738
/* out: HA_ADMIN_CORRUPT or
5740
Session* thd, /* in: user thread handle */
5740
Session* session, /* in: user thread handle */
5741
5741
HA_CHECK_OPT* check_opt __attribute__((unused))) /* in: check options, currently
5746
assert(thd == ha_thd());
5746
assert(session == ha_session());
5747
5747
ut_a(prebuilt->trx);
5748
5748
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
5749
ut_a(prebuilt->trx == thd_to_trx(thd));
5749
ut_a(prebuilt->trx == session_to_trx(session));
5751
5751
if (prebuilt->mysql_template == NULL) {
5752
5752
/* Build the template; we will use a dummy template
5783
5783
/* We do not know if MySQL can call this function before calling
5784
external_lock(). To be safe, update the thd of the current table
5784
external_lock(). To be safe, update the session of the current table
5787
5787
if (length > 64000 - 3) {
5788
5788
return((char*)comment); /* string too long */
5791
update_thd(ha_thd());
5791
update_session(ha_session());
5793
5793
prebuilt->trx->op_info = (char*)"returning table comment";
5856
5856
ut_a(prebuilt != NULL);
5858
5858
/* We do not know if MySQL can call this function before calling
5859
external_lock(). To be safe, update the thd of the current table
5859
external_lock(). To be safe, update the session of the current table
5862
update_thd(ha_thd());
5862
update_session(ha_session());
5864
5864
prebuilt->trx->op_info = (char*)"getting info on foreign keys";
5905
ha_innobase::get_foreign_key_list(Session *thd, List<FOREIGN_KEY_INFO> *f_key_list)
5905
ha_innobase::get_foreign_key_list(Session *session, List<FOREIGN_KEY_INFO> *f_key_list)
5907
5907
dict_foreign_t* foreign;
5909
5909
ut_a(prebuilt != NULL);
5910
update_thd(ha_thd());
5910
update_session(ha_session());
5911
5911
prebuilt->trx->op_info = (char*)"getting list of foreign keys";
5912
5912
trx_search_latch_release_if_reserved(prebuilt->trx);
5913
5913
mutex_enter_noninline(&(dict_sys->mutex));
5927
5927
while (tmp_buff[i] != '/')
5929
5929
tmp_buff+= i + 1;
5930
f_key_info.forein_id = thd_make_lex_string(thd, 0,
5930
f_key_info.forein_id = session_make_lex_string(session, 0,
5931
5931
tmp_buff, (uint) strlen(tmp_buff), 1);
5932
5932
tmp_buff= foreign->referenced_table_name;
5942
5942
ulen= filename_to_tablename(db_name, uname, sizeof(uname));
5943
f_key_info.referenced_db = thd_make_lex_string(thd, 0,
5943
f_key_info.referenced_db = session_make_lex_string(session, 0,
5944
5944
uname, ulen, 1);
5946
5946
/* Table name */
5947
5947
tmp_buff+= i + 1;
5948
5948
ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname));
5949
f_key_info.referenced_table = thd_make_lex_string(thd, 0,
5949
f_key_info.referenced_table = session_make_lex_string(session, 0,
5950
5950
uname, ulen, 1);
5953
5953
tmp_buff= foreign->foreign_col_names[i];
5954
name = thd_make_lex_string(thd, name,
5954
name = session_make_lex_string(session, name,
5955
5955
tmp_buff, (uint) strlen(tmp_buff), 1);
5956
5956
f_key_info.foreign_fields.push_back(name);
5957
5957
tmp_buff= foreign->referenced_col_names[i];
5958
name = thd_make_lex_string(thd, name,
5958
name = session_make_lex_string(session, name,
5959
5959
tmp_buff, (uint) strlen(tmp_buff), 1);
5960
5960
f_key_info.referenced_fields.push_back(name);
5961
5961
if (++i >= foreign->n_fields)
5984
5984
tmp_buff= "RESTRICT";
5986
f_key_info.delete_method = thd_make_lex_string(
5987
thd, f_key_info.delete_method, tmp_buff, length, 1);
5986
f_key_info.delete_method = session_make_lex_string(
5987
session, f_key_info.delete_method, tmp_buff, length, 1);
5990
5990
if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
6008
6008
tmp_buff= "RESTRICT";
6010
f_key_info.update_method = thd_make_lex_string(
6011
thd, f_key_info.update_method, tmp_buff, length, 1);
6010
f_key_info.update_method = session_make_lex_string(
6011
session, f_key_info.update_method, tmp_buff, length, 1);
6012
6012
if (foreign->referenced_index &&
6013
6013
foreign->referenced_index->name)
6015
f_key_info.referenced_key_name = thd_make_lex_string(
6016
thd, f_key_info.referenced_key_name,
6015
f_key_info.referenced_key_name = session_make_lex_string(
6016
session, f_key_info.referenced_key_name,
6017
6017
foreign->referenced_index->name,
6018
6018
strlen(foreign->referenced_index->name), 1);
6021
6021
f_key_info.referenced_key_name= 0;
6023
6023
FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
6024
thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO));
6024
session_memdup(session, &f_key_info, sizeof(FOREIGN_KEY_INFO));
6025
6025
f_key_list->push_back(pf_key_info);
6026
6026
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
6132
6132
/* IMPORTANT: prebuilt->trx can be obsolete in
6133
6133
this method, because it is not sure that MySQL
6134
6134
calls external_lock before this method with the
6135
parameters below. We must not invoke update_thd()
6135
parameters below. We must not invoke update_session()
6136
6136
either, because the calling threads may change.
6137
6137
CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
6138
6138
case HA_EXTRA_IGNORE_DUP_KEY:
6139
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE;
6139
session_to_trx(ha_session())->duplicates |= TRX_DUP_IGNORE;
6141
6141
case HA_EXTRA_WRITE_CAN_REPLACE:
6142
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE;
6142
session_to_trx(ha_session())->duplicates |= TRX_DUP_REPLACE;
6144
6144
case HA_EXTRA_WRITE_CANNOT_REPLACE:
6145
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
6145
session_to_trx(ha_session())->duplicates &= ~TRX_DUP_REPLACE;
6147
6147
case HA_EXTRA_NO_IGNORE_DUP_KEY:
6148
thd_to_trx(ha_thd())->duplicates &=
6148
session_to_trx(ha_session())->duplicates &=
6149
6149
~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
6151
6151
default:/* Do nothing */
6179
6179
MySQL-5.0 also calls this before each statement in an execution of a stored
6180
6180
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
6181
6181
locks all tables involved in a stored procedure with full explicit table
6182
locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the
6182
locks (session_in_lock_tables(session) holds in store_lock()) before executing the
6186
6186
ha_innobase::start_stmt(
6187
6187
/*====================*/
6188
6188
/* out: 0 or error code */
6189
Session* thd, /* in: handle to the user thread */
6189
Session* session, /* in: handle to the user thread */
6190
6190
thr_lock_type lock_type)
6194
update_session(session);
6196
6196
trx = prebuilt->trx;
6220
6220
prebuilt->select_lock_type = LOCK_X;
6222
6222
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
6223
&& thd_sql_command(thd) == SQLCOM_SELECT
6223
&& session_sql_command(session) == SQLCOM_SELECT
6224
6224
&& lock_type == TL_READ) {
6226
6226
/* For other than temporary tables, we obtain
6246
6246
/* Set the MySQL flag to mark that there is an active transaction */
6247
6247
if (trx->active_trans == 0) {
6249
innobase_register_trx_and_stmt(ht, thd);
6249
innobase_register_trx_and_stmt(ht, session);
6250
6250
trx->active_trans = 1;
6252
innobase_register_stmt(ht, thd);
6252
innobase_register_stmt(ht, session);
6286
6286
ha_innobase::external_lock(
6287
6287
/*=======================*/
6289
Session* thd, /* in: handle to the user thread */
6289
Session* session, /* in: handle to the user thread */
6290
6290
int lock_type) /* in: lock type */
6294
update_session(session);
6296
6296
/* Statement based binlogging does not work in isolation level
6297
6297
READ UNCOMMITTED and READ COMMITTED since the necessary
6299
6299
informative error message and return with an error. */
6300
6300
if (lock_type == F_WRLCK)
6302
ulong const binlog_format= thd_binlog_format(thd);
6303
ulong const tx_isolation = thd_tx_isolation(current_thd);
6302
ulong const binlog_format= session_binlog_format(session);
6303
ulong const tx_isolation = session_tx_isolation(current_session);
6304
6304
if (tx_isolation <= ISO_READ_COMMITTED &&
6305
6305
binlog_format == BINLOG_FORMAT_STMT)
6341
6341
if (trx->active_trans == 0) {
6343
innobase_register_trx_and_stmt(ht, thd);
6343
innobase_register_trx_and_stmt(ht, session);
6344
6344
trx->active_trans = 1;
6345
6345
} else if (trx->n_mysql_tables_in_use == 0) {
6346
innobase_register_stmt(ht, thd);
6346
innobase_register_stmt(ht, session);
6349
6349
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
6350
6350
&& prebuilt->select_lock_type == LOCK_NONE
6351
&& thd_test_options(thd,
6351
&& session_test_options(session,
6352
6352
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
6354
6354
/* To get serializable execution, we let InnoDB
6370
6370
VERY easily deadlocks.
6372
6372
We do not set InnoDB table locks if user has not explicitly
6373
requested a table lock. Note that thd_in_lock_tables(thd)
6373
requested a table lock. Note that session_in_lock_tables(session)
6374
6374
can hold in some cases, e.g., at the start of a stored
6375
6375
procedure call (SQLCOM_CALL). */
6377
6377
if (prebuilt->select_lock_type != LOCK_NONE) {
6379
if (thd_sql_command(thd) == SQLCOM_LOCK_TABLES
6380
&& SessionVAR(thd, table_locks)
6381
&& thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)
6382
&& thd_in_lock_tables(thd)) {
6379
if (session_sql_command(session) == SQLCOM_LOCK_TABLES
6380
&& SessionVAR(session, table_locks)
6381
&& session_test_options(session, OPTION_NOT_AUTOCOMMIT)
6382
&& session_in_lock_tables(session)) {
6384
6384
ulint error = row_lock_table_for_mysql(
6385
6385
prebuilt, NULL, 0);
6387
6387
if (error != DB_SUCCESS) {
6388
6388
error = convert_error_code_to_mysql(
6389
(int) error, session);
6390
6390
return((int) error);
6419
6419
trx->mysql_n_tables_locked = 0;
6420
6420
prebuilt->used_in_HANDLER = FALSE;
6422
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
6422
if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
6423
6423
if (trx->active_trans != 0) {
6424
innobase_commit(ht, thd, TRUE);
6424
innobase_commit(ht, session, TRUE);
6427
6427
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
6446
6446
ha_innobase::transactional_table_lock(
6447
6447
/*==================================*/
6448
6448
/* out: error code */
6449
Session* thd, /* in: handle to the user thread */
6449
Session* session, /* in: handle to the user thread */
6450
6450
int lock_type) /* in: lock type */
6454
6454
/* We do not know if MySQL can call this function before calling
6455
external_lock(). To be safe, update the thd of the current table
6455
external_lock(). To be safe, update the session of the current table
6458
update_session(session);
6460
if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
6460
if (prebuilt->table->ibd_file_missing && !session_tablespace_op(session)) {
6461
6461
ut_print_timestamp(stderr);
6462
6462
fprintf(stderr,
6463
6463
" InnoDB: MySQL is trying to use a table handle"
6500
6500
/* Set the MySQL flag to mark that there is an active transaction */
6501
6501
if (trx->active_trans == 0) {
6503
innobase_register_trx_and_stmt(ht, thd);
6503
innobase_register_trx_and_stmt(ht, session);
6504
6504
trx->active_trans = 1;
6507
if (SessionVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
6507
if (SessionVAR(session, table_locks) && session_in_lock_tables(session)) {
6508
6508
ulint error = DB_SUCCESS;
6510
6510
error = row_lock_table_for_mysql(prebuilt, NULL, 0);
6512
6512
if (error != DB_SUCCESS) {
6513
error = convert_error_code_to_mysql((int) error, thd);
6513
error = convert_error_code_to_mysql((int) error, session);
6514
6514
return((int) error);
6517
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
6517
if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
6519
6519
/* Store the current undo_no of the transaction
6520
6520
so that we know where to roll back if we have
6551
6551
innodb_show_status(
6552
6552
/*===============*/
6553
6553
handlerton* hton __attribute__((unused)), /* in: the innodb handlerton */
6554
Session* thd, /* in: the MySQL query thread of the caller */
6554
Session* session, /* in: the MySQL query thread of the caller */
6555
6555
stat_print_fn *stat_print)
6560
6560
ulint trx_list_start = ULINT_UNDEFINED;
6561
6561
ulint trx_list_end = ULINT_UNDEFINED;
6563
trx = check_trx_exists(thd);
6563
trx = check_trx_exists(session);
6565
6565
innobase_release_stat_resources(trx);
6621
6621
bool result = FALSE;
6623
if (stat_print(thd, innobase_hton_name, strlen(innobase_hton_name),
6623
if (stat_print(session, innobase_hton_name, strlen(innobase_hton_name),
6624
6624
STRING_WITH_LEN(""), str, flen)) {
6636
6636
innodb_mutex_show_status(
6637
6637
/*=====================*/
6638
6638
handlerton* hton __attribute__((unused)), /* in: the innodb handlerton */
6639
Session* thd, /* in: the MySQL query thread of the
6639
Session* session, /* in: the MySQL query thread of the
6641
6641
stat_print_fn* stat_print)
6675
6675
mutex->count_os_yield,
6676
6676
(ulong) (mutex->lspent_time/1000));
6678
if (stat_print(thd, innobase_hton_name,
6678
if (stat_print(session, innobase_hton_name,
6679
6679
hton_name_len, buf1, buf1len,
6680
6680
buf2, buf2len)) {
6681
6681
mutex_exit_noninline(
6698
6698
buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
6699
6699
mutex->count_os_wait);
6701
if (stat_print(thd, innobase_hton_name,
6701
if (stat_print(session, innobase_hton_name,
6702
6702
hton_name_len, buf1, buf1len,
6703
6703
buf2, buf2len)) {
6704
6704
mutex_exit_noninline(&mutex_list_mutex);
6720
6720
rw_lock_count_os_wait, rw_lock_count_os_yield,
6721
6721
(ulong) (rw_lock_wait_time/1000));
6723
if (stat_print(thd, innobase_hton_name, hton_name_len,
6723
if (stat_print(session, innobase_hton_name, hton_name_len,
6724
6724
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
6733
bool innobase_show_status(handlerton *hton, Session* thd,
6733
bool innobase_show_status(handlerton *hton, Session* session,
6734
6734
stat_print_fn* stat_print,
6735
6735
enum ha_stat_type stat_type)
6737
6737
switch (stat_type) {
6738
6738
case HA_ENGINE_STATUS:
6739
return innodb_show_status(hton, thd, stat_print);
6739
return innodb_show_status(hton, session, stat_print);
6740
6740
case HA_ENGINE_MUTEX:
6741
return innodb_mutex_show_status(hton, thd, stat_print);
6741
return innodb_mutex_show_status(hton, session, stat_print);
6821
6821
/*====================*/
6822
6822
/* out: pointer to the next
6823
6823
element in the 'to' array */
6824
Session* thd, /* in: user thread handle */
6824
Session* session, /* in: user thread handle */
6825
6825
THR_LOCK_DATA** to, /* in: pointer to an array
6826
6826
of pointers to lock structs;
6827
6827
pointer to the 'lock' field
6836
6836
/* Note that trx in this function is NOT necessarily prebuilt->trx
6837
because we call update_thd() later, in ::external_lock()! Failure to
6837
because we call update_session() later, in ::external_lock()! Failure to
6838
6838
understand this caused a serious memory corruption bug in 5.1.11. */
6840
trx = check_trx_exists(thd);
6840
trx = check_trx_exists(session);
6842
6842
/* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
6843
6843
Be careful to ignore TL_IGNORE if we are going to do something with
6849
6849
if (lock_type != TL_IGNORE
6850
6850
&& trx->n_mysql_tables_in_use == 0) {
6851
6851
trx->isolation_level = innobase_map_isolation_level(
6852
(enum_tx_isolation) thd_tx_isolation(thd));
6852
(enum_tx_isolation) session_tx_isolation(session));
6854
6854
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
6855
6855
&& trx->global_read_view) {
6864
assert(thd == current_thd);
6865
const bool in_lock_tables = thd_in_lock_tables(thd);
6866
const uint32_t sql_command = thd_sql_command(thd);
6864
assert(session == current_session);
6865
const bool in_lock_tables = session_in_lock_tables(session);
6866
const uint32_t sql_command = session_sql_command(session);
6868
6868
if (sql_command == SQLCOM_DROP_TABLE) {
6870
6870
/* MySQL calls this function in DROP Table though this table
6871
handle may belong to another thd that is running a query. Let
6871
handle may belong to another session that is running a query. Let
6872
6872
us in that case skip any changes to the prebuilt struct. */
6874
6874
} else if ((lock_type == TL_READ && in_lock_tables)
6978
6978
&& lock_type <= TL_WRITE)
6979
6979
&& !(in_lock_tables
6980
6980
&& sql_command == SQLCOM_LOCK_TABLES)
6981
&& !thd_tablespace_op(thd)
6981
&& !session_tablespace_op(session)
6982
6982
&& sql_command != SQLCOM_TRUNCATE
6983
6983
&& sql_command != SQLCOM_OPTIMIZE
6984
6984
&& sql_command != SQLCOM_CREATE_TABLE) {
6995
6995
We especially allow concurrent inserts if MySQL is at the
6996
6996
start of a stored procedure call (SQLCOM_CALL)
6997
(MySQL does have thd_in_lock_tables() TRUE there). */
6997
(MySQL does have session_in_lock_tables() TRUE there). */
6999
6999
if (lock_type == TL_READ_NO_INSERT
7000
7000
&& sql_command != SQLCOM_LOCK_TABLES) {
7037
7037
stmt_start = prebuilt->sql_stat_start;
7039
7039
/* Prepare prebuilt->trx in the table handle */
7040
update_thd(ha_thd());
7040
update_session(ha_session());
7042
7042
if (prebuilt->trx->conc_state == TRX_NOT_STARTED) {
7043
7043
trx_was_not_started = TRUE;
7279
update_thd(ha_thd());
7279
update_session(ha_session());
7281
7281
error = row_lock_table_autoinc_for_mysql(prebuilt);
7283
7283
if (error != DB_SUCCESS) {
7284
error = convert_error_code_to_mysql(error, user_thd);
7284
error = convert_error_code_to_mysql(error, user_session);
7296
7296
ha_innobase::get_error_message(int error __attribute__((unused)), String *buf)
7298
trx_t* trx = check_trx_exists(ha_thd());
7298
trx_t* trx = check_trx_exists(ha_session());
7300
7300
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
7301
7301
system_charset_info);
7380
7380
/*====================================*/
7381
7381
/* out: TRUE if query caching
7382
7382
of the table is permitted */
7383
Session* thd, /* in: user thread handle */
7383
Session* session, /* in: user thread handle */
7384
7384
char* table_key, /* in: concatenation of database name,
7385
7385
the null character '\0',
7386
7386
and the table name */
7395
7395
*call_back = innobase_query_caching_of_table_permitted;
7396
7396
*engine_data = 0;
7397
return(innobase_query_caching_of_table_permitted(thd, table_key,
7397
return(innobase_query_caching_of_table_permitted(session, table_key,
7496
7496
/*================*/
7497
7497
/* out: 0 or error number */
7498
7498
handlerton *hton __attribute__((unused)),
7499
Session* thd, /* in: handle to the MySQL thread of the user
7499
Session* session, /* in: handle to the MySQL thread of the user
7500
7500
whose XA transaction should be prepared */
7501
7501
bool all) /* in: TRUE - commit transaction
7502
7502
FALSE - the current SQL statement ended */
7505
trx_t* trx = check_trx_exists(thd);
7505
trx_t* trx = check_trx_exists(session);
7507
if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
7507
if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
7510
7510
/* For ibbackup to work the order of transactions in binlog
7530
7530
trx->active_trans = 2;
7533
if (!SessionVAR(thd, support_xa)) {
7533
if (!SessionVAR(session, support_xa)) {
7538
thd_get_xid(thd, (DRIZZLE_XID*) &trx->xid);
7538
session_get_xid(session, (DRIZZLE_XID*) &trx->xid);
7540
7540
/* Release a possible FIFO ticket and search latch. Since we will
7541
7541
reserve the kernel mutex, we have to release the search system latch
7553
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
7553
|| (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
7555
7555
/* We were instructed to prepare the whole transaction, or
7556
7556
this is an SQL statement end and autocommit is on */
7659
7659
/*========================*/
7660
7660
/* out: pointer to cursor view or NULL */
7661
7661
handlerton *hton __attribute__((unused)), /* in: innobase hton */
7662
Session* thd) /* in: user thread handle */
7662
Session* session) /* in: user thread handle */
7664
return(read_cursor_view_create_for_mysql(check_trx_exists(thd)));
7664
return(read_cursor_view_create_for_mysql(check_trx_exists(session)));
7667
7667
/***********************************************************************
7673
7673
innobase_close_cursor_view(
7674
7674
/*=======================*/
7675
7675
handlerton *hton __attribute__((unused)),
7676
Session* thd, /* in: user thread handle */
7676
Session* session, /* in: user thread handle */
7677
7677
void* curview)/* in: Consistent read view to be closed */
7679
read_cursor_view_close_for_mysql(check_trx_exists(thd),
7679
read_cursor_view_close_for_mysql(check_trx_exists(session),
7680
7680
(cursor_view_t*) curview);
7690
7690
innobase_set_cursor_view(
7691
7691
/*=====================*/
7692
7692
handlerton *hton __attribute__((unused)),
7693
Session* thd, /* in: user thread handle */
7693
Session* session, /* in: user thread handle */
7694
7694
void* curview)/* in: Consistent cursor view to be set */
7696
read_cursor_set_for_mysql(check_trx_exists(thd),
7696
read_cursor_set_for_mysql(check_trx_exists(session),
7697
7697
(cursor_view_t*) curview);
7727
7727
/* TODO: Fix the cast below!!! */
7729
static int show_innodb_vars(Session *thd __attribute__((unused)),
7729
static int show_innodb_vars(Session *session __attribute__((unused)),
7730
7730
SHOW_VAR *var, char *buff __attribute__((unused)))
7732
7732
innodb_export_status();