Many files:

  Push the patch of Jan Lindstrom: better comments
ha_innodb.cc:
  Partial fix for Bug #12263 : we let InnoDB always to perform a rollback on the trx object if MySQL closes a connection; but we do print a warning to the .err log if an InnoDB transaction was active; we may remove that print later, since the situation really is not a bug; MySQL just is not aware that some cursor operation started an InnoDB transaction
parent 05d4c0c7
...@@ -68,7 +68,6 @@ void ...@@ -68,7 +68,6 @@ void
read_view_print( read_view_print(
/*============*/ /*============*/
read_view_t* view); /* in: read view */ read_view_t* view); /* in: read view */
/************************************************************************* /*************************************************************************
Create a consistent cursor view for mysql to be used in cursors. In this Create a consistent cursor view for mysql to be used in cursors. In this
consistent read view modifications done by the creating transaction or future consistent read view modifications done by the creating transaction or future
...@@ -78,10 +77,9 @@ cursor_view_t* ...@@ -78,10 +77,9 @@ cursor_view_t*
read_cursor_view_create_for_mysql( read_cursor_view_create_for_mysql(
/*==============================*/ /*==============================*/
trx_t* cr_trx);/* in: trx where cursor view is created */ trx_t* cr_trx);/* in: trx where cursor view is created */
/************************************************************************* /*************************************************************************
Close a given consistent cursor view for and restore global read view Close a given consistent cursor view for mysql and restore global read view
back to a transaction. */ back to a transaction read view. */
void void
read_cursor_view_close_for_mysql( read_cursor_view_close_for_mysql(
...@@ -90,7 +88,7 @@ read_cursor_view_close_for_mysql( ...@@ -90,7 +88,7 @@ read_cursor_view_close_for_mysql(
cursor_view_t* curview); /* in: cursor view to be closed */ cursor_view_t* curview); /* in: cursor view to be closed */
/************************************************************************* /*************************************************************************
This function sets a given consistent cursor view to a transaction This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not null. Otherwice, function read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */ restores a global read view to a transaction read view. */
void void
......
...@@ -606,14 +606,13 @@ struct trx_struct{ ...@@ -606,14 +606,13 @@ struct trx_struct{
/* memory heap for the global read /* memory heap for the global read
view */ view */
read_view_t* global_read_view; read_view_t* global_read_view;
/* consistent read view used in the /* consistent read view associated
transaction is stored here if to a transaction or NULL */
transaction is using a consistent
read view associated to a cursor */
read_view_t* read_view; /* consistent read view used in the read_view_t* read_view; /* consistent read view used in the
transaction or NULL, this read view transaction or NULL, this read view
can be normal read view associated if defined can be normal read view
to a transaction or read view associated to a transaction (i.e.
same as global_read_view) or read view
associated to a cursor */ associated to a cursor */
/*------------------------------*/ /*------------------------------*/
UT_LIST_BASE_NODE_T(trx_named_savept_t) UT_LIST_BASE_NODE_T(trx_named_savept_t)
......
...@@ -347,8 +347,8 @@ read_cursor_view_create_for_mysql( ...@@ -347,8 +347,8 @@ read_cursor_view_create_for_mysql(
} }
/************************************************************************* /*************************************************************************
Close a given consistent cursor view for and restore global read view Close a given consistent cursor view for mysql and restore global read view
back to a transaction. */ back to a transaction read view. */
void void
read_cursor_view_close_for_mysql( read_cursor_view_close_for_mysql(
...@@ -372,7 +372,7 @@ read_cursor_view_close_for_mysql( ...@@ -372,7 +372,7 @@ read_cursor_view_close_for_mysql(
/************************************************************************* /*************************************************************************
This function sets a given consistent cursor view to a transaction This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not null. Otherwice, function read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */ restores a global read view to a transaction read view. */
void void
......
...@@ -3100,6 +3100,13 @@ row_search_for_mysql( ...@@ -3100,6 +3100,13 @@ row_search_for_mysql(
"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" "http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
"InnoDB: how you can resolve the problem.\n", "InnoDB: how you can resolve the problem.\n",
prebuilt->table->name); prebuilt->table->name);
/* Restore a global read view back to a transaction. This
forces MySQL always to set a cursor view before fetch from
a cursor. */
trx->read_view = trx->global_read_view;
return(DB_ERROR); return(DB_ERROR);
} }
...@@ -4091,8 +4098,9 @@ normal_return: ...@@ -4091,8 +4098,9 @@ normal_return:
} }
func_exit: func_exit:
/* Restore a global read view back to transaction. This forces /* Restore a global read view back to a transaction. This
MySQL always to set cursor view before fetch if it is used. */ forces MySQL always to set a cursor view before fetch from
a cursor. */
trx->read_view = trx->global_read_view; trx->read_view = trx->global_read_view;
......
...@@ -1711,6 +1711,10 @@ srv_printf_innodb_monitor( ...@@ -1711,6 +1711,10 @@ srv_printf_innodb_monitor(
fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n", fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n",
(long) srv_conc_n_threads, (long) srv_conc_n_threads,
(ulong) srv_conc_n_waiting_threads); (ulong) srv_conc_n_waiting_threads);
fprintf(file, "%lu read views open inside InnoDB\n",
UT_LIST_GET_LEN(trx_sys->view_list));
n_reserved = fil_space_get_n_reserved_extents(0); n_reserved = fil_space_get_n_reserved_extents(0);
if (n_reserved > 0) { if (n_reserved > 0) {
fprintf(file, fprintf(file,
......
...@@ -1833,6 +1833,16 @@ innobase_shutdown_for_mysql(void) ...@@ -1833,6 +1833,16 @@ innobase_shutdown_for_mysql(void)
srv_free(); srv_free();
os_sync_free(); os_sync_free();
/* Check that all read views are closed except read view owned
by a purge. */
if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
fprintf(stderr,
"InnoDB: Error: all read views were not closed before shutdown:\n"
"InnoDB: %lu read views open \n",
UT_LIST_GET_LEN(trx_sys->view_list) - 1);
}
/* 5. Free all allocated memory and the os_fast_mutex created in /* 5. Free all allocated memory and the os_fast_mutex created in
ut0mem.c */ ut0mem.c */
......
...@@ -833,26 +833,14 @@ trx_commit_off_kernel( ...@@ -833,26 +833,14 @@ trx_commit_off_kernel(
lock_release_off_kernel(trx); lock_release_off_kernel(trx);
if (trx->read_view) { if (trx->global_read_view) {
/* If transaction has a global read view this case read_view_close(trx->global_read_view);
means that transaction has been using a consistent
read view associated to a cursor. Only the global
read view associated to a transaction is closed
and read view is then removed from the transaction.
If read view associated to a cursor is still used
it must be re-registered to another transaction. */
if (UNIV_LIKELY_NULL(trx->global_read_view)) {
trx->read_view = trx->global_read_view;
}
read_view_close(trx->read_view);
mem_heap_empty(trx->global_read_view_heap); mem_heap_empty(trx->global_read_view_heap);
trx->read_view = NULL;
trx->global_read_view = NULL; trx->global_read_view = NULL;
} }
trx->read_view = NULL;
if (must_flush_log) { if (must_flush_log) {
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
......
...@@ -538,7 +538,7 @@ innobase_mysql_prepare_print_arbitrary_thd(void) ...@@ -538,7 +538,7 @@ innobase_mysql_prepare_print_arbitrary_thd(void)
} }
/***************************************************************** /*****************************************************************
Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd(). Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
function! */ function! */
extern "C" extern "C"
...@@ -1700,7 +1700,7 @@ innobase_store_binlog_offset_and_flush_log( ...@@ -1700,7 +1700,7 @@ innobase_store_binlog_offset_and_flush_log(
/* Commits the mini-transaction */ /* Commits the mini-transaction */
mtr_commit(&mtr); mtr_commit(&mtr);
/* Syncronous flush of the log buffer to disk */ /* Synchronous flush of the log buffer to disk */
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
} }
#endif #endif
...@@ -2132,15 +2132,34 @@ innobase_savepoint( ...@@ -2132,15 +2132,34 @@ innobase_savepoint(
/********************************************************************* /*********************************************************************
Frees a possible InnoDB trx object associated with the current THD. */ Frees a possible InnoDB trx object associated with the current THD. */
static
static int int
innobase_close_connection( innobase_close_connection(
/*======================*/ /*======================*/
/* out: 0 or error number */ /* out: 0 or error number */
THD* thd) /* in: handle to the MySQL thread of the user THD* thd) /* in: handle to the MySQL thread of the user
whose resources should be free'd */ whose resources should be free'd */
{ {
trx_free_for_mysql((trx_t*)thd->ha_data[innobase_hton.slot]); trx_t* trx;
trx = (trx_t*)thd->ha_data[innobase_hton.slot];
ut_a(trx);
if (trx->conc_state != TRX_NOT_STARTED) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Warning: MySQL is closing a connection"
"InnoDB: that has an active InnoDB transaction. We roll back that\n"
"InnoDB: transaction. %lu row modifications to roll back.\n",
(ulong)ut_dulint_get_low(trx->undo_no));
}
innobase_rollback_trx(trx);
trx_free_for_mysql(trx);
return(0); return(0);
} }
...@@ -2834,7 +2853,7 @@ ha_innobase::store_key_val_for_row( ...@@ -2834,7 +2853,7 @@ ha_innobase::store_key_val_for_row(
/* All indexes on BLOB and TEXT are column prefix /* All indexes on BLOB and TEXT are column prefix
indexes, and we may need to truncate the data to be indexes, and we may need to truncate the data to be
stored in the kay value: */ stored in the key value: */
if (blob_len > key_part->length) { if (blob_len > key_part->length) {
blob_len = key_part->length; blob_len = key_part->length;
...@@ -7117,7 +7136,7 @@ int ...@@ -7117,7 +7136,7 @@ int
innobase_rollback_by_xid( innobase_rollback_by_xid(
/*=====================*/ /*=====================*/
/* out: 0 or error number */ /* out: 0 or error number */
XID *xid) /* in: X/Open XA transaction idenfification */ XID *xid) /* in: X/Open XA transaction identification */
{ {
trx_t* trx; trx_t* trx;
...@@ -7131,9 +7150,10 @@ innobase_rollback_by_xid( ...@@ -7131,9 +7150,10 @@ innobase_rollback_by_xid(
} }
/*********************************************************************** /***********************************************************************
This function creates a consistent view for a cursor and start a transaction Create a consistent view for a cursor based on current transaction
if it has not been started. This consistent view is then used inside of MySQL which is created if the corresponding MySQL thread still lacks one.
when accesing records using a cursor. */ This consistent view is then used inside of MySQL when accessing records
using a cursor. */
void* void*
innobase_create_cursor_view(void) innobase_create_cursor_view(void)
...@@ -7145,9 +7165,9 @@ innobase_create_cursor_view(void) ...@@ -7145,9 +7165,9 @@ innobase_create_cursor_view(void)
} }
/*********************************************************************** /***********************************************************************
This function closes the given consistent cursor view. Note that Close the given consistent cursor view of a transaction and restore
global read view is restored to a transaction and a transaction is global read view to a transaction read view. Transaction is created if the
started if it has not been started. */ corresponding MySQL thread still lacks one. */
void void
innobase_close_cursor_view( innobase_close_cursor_view(
...@@ -7159,13 +7179,15 @@ innobase_close_cursor_view( ...@@ -7159,13 +7179,15 @@ innobase_close_cursor_view(
} }
/*********************************************************************** /***********************************************************************
This function sets the given consistent cursor view to a transaction. Set the given consistent cursor view to a transaction which is created
If a transaction does not exist, transaction is started. */ if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */
void void
innobase_set_cursor_view( innobase_set_cursor_view(
/*=====================*/ /*=====================*/
void* curview)/* in: Consistent cursor view to be closed */ void* curview)/* in: Consistent cursor view to be set */
{ {
read_cursor_set_for_mysql(check_trx_exists(current_thd), read_cursor_set_for_mysql(check_trx_exists(current_thd),
(cursor_view_t*) curview); (cursor_view_t*) curview);
......
...@@ -302,7 +302,7 @@ which is in the prepared state */ ...@@ -302,7 +302,7 @@ which is in the prepared state */
int innobase_rollback_by_xid( int innobase_rollback_by_xid(
/* out: 0 or error number */ /* out: 0 or error number */
XID *xid); /* in : X/Open XA Transaction Idenfification */ XID *xid); /* in : X/Open XA Transaction Identification */
int innobase_xa_end(THD *thd); int innobase_xa_end(THD *thd);
...@@ -312,9 +312,10 @@ int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name, ...@@ -312,9 +312,10 @@ int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
my_off_t end_offset); my_off_t end_offset);
/*********************************************************************** /***********************************************************************
This function creates a consistent view for a cursor and start a transaction Create a consistent view for a cursor based on current transaction
if it has not been started. This consistent view is then used inside of MySQL which is created if the corresponding MySQL thread still lacks one.
when accesing records using a cursor. */ This consistent view is then used inside of MySQL when accessing records
using a cursor. */
void* void*
innobase_create_cursor_view(void); innobase_create_cursor_view(void);
...@@ -322,9 +323,9 @@ innobase_create_cursor_view(void); ...@@ -322,9 +323,9 @@ innobase_create_cursor_view(void);
/* out: Pointer to cursor view or NULL */ /* out: Pointer to cursor view or NULL */
/*********************************************************************** /***********************************************************************
This function closes the given consistent cursor view. Note that Close the given consistent cursor view of a transaction and restore
global read view is restored to a transaction and a transaction is global read view to a transaction read view. Transaction is created if the
started if it has not been started. */ corresponding MySQL thread still lacks one. */
void void
innobase_close_cursor_view( innobase_close_cursor_view(
...@@ -332,8 +333,10 @@ innobase_close_cursor_view( ...@@ -332,8 +333,10 @@ innobase_close_cursor_view(
void* curview); /* in: Consistent read view to be closed */ void* curview); /* in: Consistent read view to be closed */
/*********************************************************************** /***********************************************************************
This function sets the given consistent cursor view to a transaction. Set the given consistent cursor view to a transaction which is created
If a transaction does not exist, transaction is started. */ if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
restored to a transaction read view. */
void void
innobase_set_cursor_view( innobase_set_cursor_view(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment