#include "trx0trx.h"#include "trx0undo.h"#include "trx0rseg.h"#include "log0log.h"#include "que0que.h"#include "lock0lock.h"#include "trx0roll.h"#include "usr0sess.h"#include "read0read.h"#include "srv0srv.h"#include "thr0loc.h"#include "btr0sea.h"#include "os0proc.h"#include "trx0xa.h"Include dependency graph for trx0trx.c:

Go to the source code of this file.
| commit_node_t* commit_node_create | ( | mem_heap_t * | heap | ) |
Definition at line 1508 of file trx0trx.c.
References COMMIT_NODE_SEND, commit_node_struct::common, mem_heap_alloc(), QUE_NODE_COMMIT, commit_node_struct::state, and que_common_struct::type.
Referenced by ind_create_graph_create(), pars_commit_statement(), and tab_create_graph_create().
01510 : commit node struct */ 01511 mem_heap_t* heap) /* in: mem heap where created */ 01512 { 01513 commit_node_t* node; 01514 01515 node = mem_heap_alloc(heap, sizeof(commit_node_t)); 01516 node->common.type = QUE_NODE_COMMIT; 01517 node->state = COMMIT_NODE_SEND; 01518 01519 return(node); 01520 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void innobase_mysql_print_thd | ( | FILE * | f, | |
| void * | thd, | |||
| ulint | max_query_len | |||
| ) |
| trx_t* trx_allocate_for_background | ( | void | ) |
Definition at line 239 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), sess_open(), trx_create(), and trx_dummy_sess.
Referenced by row_drop_table_for_mysql_in_background().
00241 : transaction object */ 00242 { 00243 trx_t* trx; 00244 00245 mutex_enter(&kernel_mutex); 00246 00247 /* Open a dummy session */ 00248 00249 if (!trx_dummy_sess) { 00250 trx_dummy_sess = sess_open(); 00251 } 00252 00253 trx = trx_create(trx_dummy_sess); 00254 00255 mutex_exit(&kernel_mutex); 00256 00257 return(trx); 00258 }
Here is the call graph for this function:

Here is the caller graph for this function:

| trx_t* trx_allocate_for_mysql | ( | void | ) |
Definition at line 206 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), trx_struct::mysql_process_no, trx_struct::mysql_thread_id, os_proc_get_number(), os_thread_get_curr_id(), sess_open(), trx_create(), trx_dummy_sess, trx_n_mysql_transactions, trx_sys, and UT_LIST_ADD_FIRST.
Referenced by dict_create_or_check_foreign_constraint_tables().
00208 : transaction object */ 00209 { 00210 trx_t* trx; 00211 00212 mutex_enter(&kernel_mutex); 00213 00214 /* Open a dummy session */ 00215 00216 if (!trx_dummy_sess) { 00217 trx_dummy_sess = sess_open(); 00218 } 00219 00220 trx = trx_create(trx_dummy_sess); 00221 00222 trx_n_mysql_transactions++; 00223 00224 UT_LIST_ADD_FIRST(mysql_trx_list, trx_sys->mysql_trx_list, trx); 00225 00226 mutex_exit(&kernel_mutex); 00227 00228 trx->mysql_thread_id = os_thread_get_curr_id(); 00229 00230 trx->mysql_process_no = os_proc_get_number(); 00231 00232 return(trx); 00233 }
Here is the call graph for this function:

Here is the caller graph for this function:

| read_view_t* trx_assign_read_view | ( | trx_t * | trx | ) |
Definition at line 985 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::global_read_view, trx_struct::global_read_view_heap, trx_struct::id, kernel_mutex, mutex_enter, mutex_exit(), trx_struct::read_view, read_view_open_now(), TRX_ACTIVE, and ut_ad.
Referenced by row_search_for_mysql(), and row_sel_step().
00987 : consistent read view */ 00988 trx_t* trx) /* in: active transaction */ 00989 { 00990 ut_ad(trx->conc_state == TRX_ACTIVE); 00991 00992 if (trx->read_view) { 00993 return(trx->read_view); 00994 } 00995 00996 mutex_enter(&kernel_mutex); 00997 00998 if (!trx->read_view) { 00999 trx->read_view = read_view_open_now(trx->id, 01000 trx->global_read_view_heap); 01001 trx->global_read_view = trx->read_view; 01002 } 01003 01004 mutex_exit(&kernel_mutex); 01005 01006 return(trx->read_view); 01007 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE ulint trx_assign_rseg | ( | void | ) |
Definition at line 616 of file trx0trx.c.
References trx_rseg_struct::id, kernel_mutex, trx_sys_struct::latest_rseg, NULL, trx_sys, TRX_SYS_SYSTEM_RSEG_ID, ut_ad, UT_LIST_GET_FIRST, UT_LIST_GET_LEN, and UT_LIST_GET_NEXT.
Referenced by trx_start_low().
00618 : assigned rollback segment id */ 00619 { 00620 trx_rseg_t* rseg = trx_sys->latest_rseg; 00621 00622 #ifdef UNIV_SYNC_DEBUG 00623 ut_ad(mutex_own(&kernel_mutex)); 00624 #endif /* UNIV_SYNC_DEBUG */ 00625 loop: 00626 /* Get next rseg in a round-robin fashion */ 00627 00628 rseg = UT_LIST_GET_NEXT(rseg_list, rseg); 00629 00630 if (rseg == NULL) { 00631 rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); 00632 } 00633 00634 /* If it is the SYSTEM rollback segment, and there exist others, skip 00635 it */ 00636 00637 if ((rseg->id == TRX_SYS_SYSTEM_RSEG_ID) 00638 && (UT_LIST_GET_LEN(trx_sys->rseg_list) > 1)) { 00639 goto loop; 00640 } 00641 00642 trx_sys->latest_rseg = rseg; 00643 00644 return(rseg->id); 00645 }
Here is the caller graph for this function:

| void trx_cleanup_at_db_startup | ( | trx_t * | trx | ) |
Definition at line 962 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::insert_undo, trx_struct::last_sql_stat_start, trx_savept_struct::least_undo_no, NULL, trx_struct::rseg, TRX_NOT_STARTED, trx_sys, trx_undo_insert_cleanup(), trx_struct::undo_no, ut_dulint_zero, and UT_LIST_REMOVE.
Referenced by trx_rollback_or_clean_all_without_sess().
00964 : transaction */ 00965 { 00966 if (trx->insert_undo != NULL) { 00967 00968 trx_undo_insert_cleanup(trx); 00969 } 00970 00971 trx->conc_state = TRX_NOT_STARTED; 00972 trx->rseg = NULL; 00973 trx->undo_no = ut_dulint_zero; 00974 trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; 00975 00976 UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); 00977 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1605 of file trx0trx.c.
References trx_struct::commit_lsn, FALSE, LOG_WAIT_ONE_GROUP, log_write_up_to(), trx_struct::must_flush_log_later, trx_struct::op_info, srv_flush_log_at_trx_commit, srv_unix_file_flush_method, SRV_UNIX_NOSYNC, TRUE, ut_a, and ut_error.
01607 : 0 or error number */ 01608 trx_t* trx) /* in: trx handle */ 01609 { 01610 dulint lsn = trx->commit_lsn; 01611 01612 ut_a(trx); 01613 01614 trx->op_info = "flushing log"; 01615 01616 if (!trx->must_flush_log_later) { 01617 /* Do nothing */ 01618 } else if (srv_flush_log_at_trx_commit == 0) { 01619 /* Do nothing */ 01620 } else if (srv_flush_log_at_trx_commit == 1) { 01621 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) { 01622 /* Write the log but do not flush it to disk */ 01623 01624 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); 01625 } else { 01626 /* Write the log to the log files AND flush them to 01627 disk */ 01628 01629 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); 01630 } 01631 } else if (srv_flush_log_at_trx_commit == 2) { 01632 01633 /* Write the log but do not flush it to disk */ 01634 01635 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); 01636 } else { 01637 ut_error; 01638 } 01639 01640 trx->must_flush_log_later = FALSE; 01641 01642 trx->op_info = ""; 01643 01644 return(0); 01645 }
Here is the call graph for this function:

Definition at line 1574 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), trx_struct::op_info, trx_commit_off_kernel(), trx_start_if_not_started(), and ut_a.
Referenced by row_create_table_for_mysql(), row_discard_tablespace_for_mysql(), row_drop_database_for_mysql(), row_drop_table_for_mysql(), row_drop_table_for_mysql_in_background(), row_import_tablespace_for_mysql(), row_mysql_recover_tmp_table(), row_rename_table_for_mysql(), and row_truncate_table_for_mysql().
01576 : 0 or error number */ 01577 trx_t* trx) /* in: trx handle */ 01578 { 01579 /* Because we do not do the commit by sending an Innobase 01580 sig to the transaction, we must here make sure that trx has been 01581 started. */ 01582 01583 ut_a(trx); 01584 01585 trx->op_info = "committing"; 01586 01587 trx_start_if_not_started(trx); 01588 01589 mutex_enter(&kernel_mutex); 01590 01591 trx_commit_off_kernel(trx); 01592 01593 mutex_exit(&kernel_mutex); 01594 01595 trx->op_info = ""; 01596 01597 return(0); 01598 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_commit_off_kernel | ( | trx_t * | trx | ) |
Definition at line 727 of file trx0trx.c.
References trx_struct::commit_lsn, trx_struct::conc_state, mtr_struct::end_lsn, FALSE, trx_struct::flush_log_later, trx_struct::global_read_view, trx_struct::global_read_view_heap, trx_struct::insert_undo, kernel_mutex, trx_struct::last_sql_stat_start, trx_savept_struct::least_undo_no, lock_release_off_kernel(), LOG_WAIT_ONE_GROUP, log_write_up_to(), mem_heap_empty(), mtr_commit(), mtr_start(), trx_struct::must_flush_log_later, trx_rseg_struct::mutex, mutex_enter, mutex_exit(), trx_struct::mysql_log_file_name, trx_struct::mysql_log_offset, trx_struct::mysql_master_log_file_name, trx_struct::mysql_master_log_pos, trx_struct::no, NULL, page_t, trx_struct::read_view, read_view_close(), trx_struct::rseg, srv_flush_log_at_trx_commit, srv_unix_file_flush_method, SRV_UNIX_NOSYNC, TRUE, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, trx_struct::trx_locks, TRX_NOT_STARTED, TRX_PREPARED, trx_roll_savepoints_free(), trx_sys, trx_sys_get_new_trx_no(), TRX_SYS_MYSQL_LOG_INFO, TRX_SYS_MYSQL_MASTER_LOG_INFO, trx_sys_update_mysql_binlog_offset(), trx_undo_insert_cleanup(), trx_undo_set_state_at_finish(), trx_undo_update_cleanup(), trx_struct::undo_no, trx_struct::update_undo, ut_ad, ut_dulint_zero, ut_error, UT_LIST_GET_LEN, UT_LIST_REMOVE, and trx_struct::wait_thrs.
Referenced by trx_commit_for_mysql(), trx_finish_rollback_off_kernel(), and trx_handle_commit_sig_off_kernel().
00729 : transaction */ 00730 { 00731 page_t* update_hdr_page; 00732 dulint lsn; 00733 trx_rseg_t* rseg; 00734 trx_undo_t* undo; 00735 ibool must_flush_log = FALSE; 00736 mtr_t mtr; 00737 00738 #ifdef UNIV_SYNC_DEBUG 00739 ut_ad(mutex_own(&kernel_mutex)); 00740 #endif /* UNIV_SYNC_DEBUG */ 00741 00742 trx->must_flush_log_later = FALSE; 00743 00744 rseg = trx->rseg; 00745 00746 if (trx->insert_undo != NULL || trx->update_undo != NULL) { 00747 00748 mutex_exit(&kernel_mutex); 00749 00750 mtr_start(&mtr); 00751 00752 must_flush_log = TRUE; 00753 00754 /* Change the undo log segment states from TRX_UNDO_ACTIVE 00755 to some other state: these modifications to the file data 00756 structure define the transaction as committed in the file 00757 based world, at the serialization point of the log sequence 00758 number lsn obtained below. */ 00759 00760 mutex_enter(&(rseg->mutex)); 00761 00762 if (trx->insert_undo != NULL) { 00763 trx_undo_set_state_at_finish(trx, trx->insert_undo, 00764 &mtr); 00765 } 00766 00767 undo = trx->update_undo; 00768 00769 if (undo) { 00770 mutex_enter(&kernel_mutex); 00771 trx->no = trx_sys_get_new_trx_no(); 00772 00773 mutex_exit(&kernel_mutex); 00774 00775 /* It is not necessary to obtain trx->undo_mutex here 00776 because only a single OS thread is allowed to do the 00777 transaction commit for this transaction. */ 00778 00779 update_hdr_page = trx_undo_set_state_at_finish(trx, 00780 undo, &mtr); 00781 00782 /* We have to do the cleanup for the update log while 00783 holding the rseg mutex because update log headers 00784 have to be put to the history list in the order of 00785 the trx number. */ 00786 00787 trx_undo_update_cleanup(trx, update_hdr_page, &mtr); 00788 } 00789 00790 mutex_exit(&(rseg->mutex)); 00791 00792 /* Update the latest MySQL binlog name and offset info 00793 in trx sys header if MySQL binlogging is on or the database 00794 server is a MySQL replication slave */ 00795 00796 if (trx->mysql_log_file_name 00797 && trx->mysql_log_file_name[0] != '\0') { 00798 trx_sys_update_mysql_binlog_offset( 00799 trx->mysql_log_file_name, 00800 trx->mysql_log_offset, 00801 TRX_SYS_MYSQL_LOG_INFO, &mtr); 00802 trx->mysql_log_file_name = NULL; 00803 } 00804 00805 if (trx->mysql_master_log_file_name[0] != '\0') { 00806 /* This database server is a MySQL replication slave */ 00807 trx_sys_update_mysql_binlog_offset( 00808 trx->mysql_master_log_file_name, 00809 trx->mysql_master_log_pos, 00810 TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr); 00811 } 00812 00813 /* The following call commits the mini-transaction, making the 00814 whole transaction committed in the file-based world, at this 00815 log sequence number. The transaction becomes 'durable' when 00816 we write the log to disk, but in the logical sense the commit 00817 in the file-based data structures (undo logs etc.) happens 00818 here. 00819 00820 NOTE that transaction numbers, which are assigned only to 00821 transactions with an update undo log, do not necessarily come 00822 in exactly the same order as commit lsn's, if the transactions 00823 have different rollback segments. To get exactly the same 00824 order we should hold the kernel mutex up to this point, 00825 adding to to the contention of the kernel mutex. However, if 00826 a transaction T2 is able to see modifications made by 00827 a transaction T1, T2 will always get a bigger transaction 00828 number and a bigger commit lsn than T1. */ 00829 00830 /*--------------*/ 00831 mtr_commit(&mtr); 00832 /*--------------*/ 00833 lsn = mtr.end_lsn; 00834 00835 mutex_enter(&kernel_mutex); 00836 } 00837 00838 ut_ad(trx->conc_state == TRX_ACTIVE 00839 || trx->conc_state == TRX_PREPARED); 00840 #ifdef UNIV_SYNC_DEBUG 00841 ut_ad(mutex_own(&kernel_mutex)); 00842 #endif /* UNIV_SYNC_DEBUG */ 00843 00844 /* The following assignment makes the transaction committed in memory 00845 and makes its changes to data visible to other transactions. 00846 NOTE that there is a small discrepancy from the strict formal 00847 visibility rules here: a human user of the database can see 00848 modifications made by another transaction T even before the necessary 00849 log segment has been flushed to the disk. If the database happens to 00850 crash before the flush, the user has seen modifications from T which 00851 will never be a committed transaction. However, any transaction T2 00852 which sees the modifications of the committing transaction T, and 00853 which also itself makes modifications to the database, will get an lsn 00854 larger than the committing transaction T. In the case where the log 00855 flush fails, and T never gets committed, also T2 will never get 00856 committed. */ 00857 00858 /*--------------------------------------*/ 00859 trx->conc_state = TRX_COMMITTED_IN_MEMORY; 00860 /*--------------------------------------*/ 00861 00862 lock_release_off_kernel(trx); 00863 00864 if (trx->global_read_view) { 00865 read_view_close(trx->global_read_view); 00866 mem_heap_empty(trx->global_read_view_heap); 00867 trx->global_read_view = NULL; 00868 } 00869 00870 trx->read_view = NULL; 00871 00872 if (must_flush_log) { 00873 00874 mutex_exit(&kernel_mutex); 00875 00876 if (trx->insert_undo != NULL) { 00877 00878 trx_undo_insert_cleanup(trx); 00879 } 00880 00881 /* NOTE that we could possibly make a group commit more 00882 efficient here: call os_thread_yield here to allow also other 00883 trxs to come to commit! */ 00884 00885 /*-------------------------------------*/ 00886 00887 /* Depending on the my.cnf options, we may now write the log 00888 buffer to the log files, making the transaction durable if 00889 the OS does not crash. We may also flush the log files to 00890 disk, making the transaction durable also at an OS crash or a 00891 power outage. 00892 00893 The idea in InnoDB's group commit is that a group of 00894 transactions gather behind a trx doing a physical disk write 00895 to log files, and when that physical write has been completed, 00896 one of those transactions does a write which commits the whole 00897 group. Note that this group commit will only bring benefit if 00898 there are > 2 users in the database. Then at least 2 users can 00899 gather behind one doing the physical log write to disk. 00900 00901 If we are calling trx_commit() under MySQL's binlog mutex, we 00902 will delay possible log write and flush to a separate function 00903 trx_commit_complete_for_mysql(), which is only called when the 00904 thread has released the binlog mutex. This is to make the 00905 group commit algorithm to work. Otherwise, the MySQL binlog 00906 mutex would serialize all commits and prevent a group of 00907 transactions from gathering. */ 00908 00909 if (trx->flush_log_later) { 00910 /* Do nothing yet */ 00911 trx->must_flush_log_later = TRUE; 00912 } else if (srv_flush_log_at_trx_commit == 0) { 00913 /* Do nothing */ 00914 } else if (srv_flush_log_at_trx_commit == 1) { 00915 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) { 00916 /* Write the log but do not flush it to disk */ 00917 00918 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, 00919 FALSE); 00920 } else { 00921 /* Write the log to the log files AND flush 00922 them to disk */ 00923 00924 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); 00925 } 00926 } else if (srv_flush_log_at_trx_commit == 2) { 00927 00928 /* Write the log but do not flush it to disk */ 00929 00930 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); 00931 } else { 00932 ut_error; 00933 } 00934 00935 trx->commit_lsn = lsn; 00936 00937 /*-------------------------------------*/ 00938 00939 mutex_enter(&kernel_mutex); 00940 } 00941 00942 /* Free savepoints */ 00943 trx_roll_savepoints_free(trx, NULL); 00944 00945 trx->conc_state = TRX_NOT_STARTED; 00946 trx->rseg = NULL; 00947 trx->undo_no = ut_dulint_zero; 00948 trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; 00949 00950 ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); 00951 ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0); 00952 00953 UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); 00954 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1526 of file trx0trx.c.
References COMMIT_NODE_SEND, COMMIT_NODE_WAIT, kernel_mutex, mutex_enter, mutex_exit(), NULL, que_thr_struct::prev_node, QUE_NODE_COMMIT, que_node_get_parent(), que_node_get_type(), QUE_THR_SIG_REPLY_WAIT, que_thr_struct::run_node, que_thr_struct::state, commit_node_struct::state, thr_get_trx(), TRX_SIG_COMMIT, TRX_SIG_SELF, trx_sig_send(), and ut_ad.
Referenced by que_thr_step().
01528 : query thread to run next, or NULL */ 01529 que_thr_t* thr) /* in: query thread */ 01530 { 01531 commit_node_t* node; 01532 que_thr_t* next_thr; 01533 01534 node = thr->run_node; 01535 01536 ut_ad(que_node_get_type(node) == QUE_NODE_COMMIT); 01537 01538 if (thr->prev_node == que_node_get_parent(node)) { 01539 node->state = COMMIT_NODE_SEND; 01540 } 01541 01542 if (node->state == COMMIT_NODE_SEND) { 01543 mutex_enter(&kernel_mutex); 01544 01545 node->state = COMMIT_NODE_WAIT; 01546 01547 next_thr = NULL; 01548 01549 thr->state = QUE_THR_SIG_REPLY_WAIT; 01550 01551 /* Send the commit signal to the transaction */ 01552 01553 trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, TRX_SIG_SELF, 01554 thr, NULL, &next_thr); 01555 01556 mutex_exit(&kernel_mutex); 01557 01558 return(next_thr); 01559 } 01560 01561 ut_ad(node->state == COMMIT_NODE_WAIT); 01562 01563 node->state = COMMIT_NODE_SEND; 01564 01565 thr->run_node = que_node_get_parent(node); 01566 01567 return(thr); 01568 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 97 of file trx0trx.c.
References trx_struct::auto_inc_lock, BTR_SEA_TIMEOUT, trx_struct::check_foreigns, trx_struct::check_unique_secondary, trx_struct::conc_state, DB_SUCCESS, trx_struct::declared_to_be_inside_innodb, trx_struct::detailed_error, trx_struct::dict_operation, trx_struct::dict_operation_lock_mode, trx_struct::error_state, FALSE, trx_struct::flush_log_later, xid_t::formatID, trx_struct::global_read_view, trx_struct::global_read_view_heap, trx_struct::graph, trx_struct::handling_signals, trx_struct::has_search_latch, trx_struct::id, trx_struct::insert_undo, trx_struct::isolation_level, kernel_mutex, trx_struct::last_sql_stat_start, trx_savept_struct::least_undo_no, trx_struct::lock_heap, trx_struct::magic_n, mem_alloc, mem_heap_create, mem_heap_create_in_buffer, memset, trx_struct::must_flush_log_later, mutex_create, trx_struct::mysql_log_file_name, trx_struct::mysql_log_offset, trx_struct::mysql_master_log_file_name, trx_struct::mysql_master_log_pos, trx_struct::mysql_n_tables_locked, trx_struct::mysql_query_str, trx_struct::mysql_thd, trx_struct::n_active_thrs, trx_struct::n_mysql_tables_in_use, trx_struct::n_tickets_to_enter_innodb, trx_struct::no, NULL, trx_struct::op_info, trx_struct::que_state, trx_struct::read_view, trx_struct::repl_wait_binlog_name, trx_struct::repl_wait_binlog_pos, trx_struct::reply_signals, trx_struct::rseg, trx_struct::search_latch_timeout, trx_struct::sess, trx_struct::signals, trx_struct::start_time, trx_struct::support_xa, SYNC_TRX_UNDO, TRUE, TRX_ISO_REPEATABLE_READ, trx_struct::trx_locks, TRX_MAGIC_N, TRX_NOT_STARTED, TRX_QUE_RUNNING, trx_reset_new_rec_lock_info(), trx_struct::trx_savepoints, TRX_USER, trx_struct::type, trx_struct::undo_mutex, trx_struct::undo_no, trx_struct::undo_no_arr, trx_struct::update_undo, ut_ad, ut_dulint_max, ut_dulint_zero, UT_LIST_INIT, trx_struct::wait_lock, trx_struct::wait_thrs, trx_struct::was_chosen_as_deadlock_victim, and trx_struct::xid.
Referenced by sess_open(), trx_allocate_for_background(), trx_allocate_for_mysql(), and trx_lists_init_at_db_start().
00099 : the transaction */ 00100 sess_t* sess) /* in: session or NULL */ 00101 { 00102 trx_t* trx; 00103 00104 #ifdef UNIV_SYNC_DEBUG 00105 ut_ad(mutex_own(&kernel_mutex)); 00106 #endif /* UNIV_SYNC_DEBUG */ 00107 00108 trx = mem_alloc(sizeof(trx_t)); 00109 00110 trx->magic_n = TRX_MAGIC_N; 00111 00112 trx->op_info = ""; 00113 00114 trx->type = TRX_USER; 00115 trx->conc_state = TRX_NOT_STARTED; 00116 trx->start_time = time(NULL); 00117 00118 trx->isolation_level = TRX_ISO_REPEATABLE_READ; 00119 00120 trx->id = ut_dulint_zero; 00121 trx->no = ut_dulint_max; 00122 00123 trx->support_xa = TRUE; 00124 00125 trx->check_foreigns = TRUE; 00126 trx->check_unique_secondary = TRUE; 00127 00128 trx->flush_log_later = FALSE; 00129 trx->must_flush_log_later = FALSE; 00130 00131 trx->dict_operation = FALSE; 00132 00133 trx->mysql_thd = NULL; 00134 trx->mysql_query_str = NULL; 00135 00136 trx->n_mysql_tables_in_use = 0; 00137 trx->mysql_n_tables_locked = 0; 00138 00139 trx->mysql_log_file_name = NULL; 00140 trx->mysql_log_offset = 0; 00141 trx->mysql_master_log_file_name = ""; 00142 trx->mysql_master_log_pos = 0; 00143 00144 trx->repl_wait_binlog_name = NULL; 00145 trx->repl_wait_binlog_pos = 0; 00146 00147 mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO); 00148 00149 trx->rseg = NULL; 00150 00151 trx->undo_no = ut_dulint_zero; 00152 trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; 00153 trx->insert_undo = NULL; 00154 trx->update_undo = NULL; 00155 trx->undo_no_arr = NULL; 00156 00157 trx->error_state = DB_SUCCESS; 00158 trx->detailed_error[0] = '\0'; 00159 00160 trx->sess = sess; 00161 trx->que_state = TRX_QUE_RUNNING; 00162 trx->n_active_thrs = 0; 00163 00164 trx->handling_signals = FALSE; 00165 00166 UT_LIST_INIT(trx->signals); 00167 UT_LIST_INIT(trx->reply_signals); 00168 00169 trx->graph = NULL; 00170 00171 trx->wait_lock = NULL; 00172 trx->was_chosen_as_deadlock_victim = FALSE; 00173 UT_LIST_INIT(trx->wait_thrs); 00174 00175 trx->lock_heap = mem_heap_create_in_buffer(256); 00176 UT_LIST_INIT(trx->trx_locks); 00177 00178 UT_LIST_INIT(trx->trx_savepoints); 00179 00180 trx->dict_operation_lock_mode = 0; 00181 trx->has_search_latch = FALSE; 00182 trx->search_latch_timeout = BTR_SEA_TIMEOUT; 00183 00184 trx->declared_to_be_inside_innodb = FALSE; 00185 trx->n_tickets_to_enter_innodb = 0; 00186 00187 trx->auto_inc_lock = NULL; 00188 00189 trx->global_read_view_heap = mem_heap_create(256); 00190 trx->global_read_view = NULL; 00191 trx->read_view = NULL; 00192 00193 /* Set X/Open XA transaction identification to NULL */ 00194 memset(&trx->xid, 0, sizeof(trx->xid)); 00195 trx->xid.formatID = -1; 00196 00197 trx_reset_new_rec_lock_info(trx); 00198 00199 return(trx); 00200 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_end_lock_wait | ( | trx_t * | trx | ) |
Definition at line 1061 of file trx0trx.c.
References kernel_mutex, NULL, trx_struct::que_state, que_thr_end_wait_no_next_thr(), TRX_QUE_LOCK_WAIT, TRX_QUE_RUNNING, ut_ad, UT_LIST_GET_FIRST, UT_LIST_REMOVE, and trx_struct::wait_thrs.
Referenced by lock_cancel_waiting_and_release(), lock_grant(), and lock_rec_cancel().
01063 : transaction */ 01064 { 01065 que_thr_t* thr; 01066 01067 #ifdef UNIV_SYNC_DEBUG 01068 ut_ad(mutex_own(&kernel_mutex)); 01069 #endif /* UNIV_SYNC_DEBUG */ 01070 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT); 01071 01072 thr = UT_LIST_GET_FIRST(trx->wait_thrs); 01073 01074 while (thr != NULL) { 01075 que_thr_end_wait_no_next_thr(thr); 01076 01077 UT_LIST_REMOVE(trx_thrs, trx->wait_thrs, thr); 01078 01079 thr = UT_LIST_GET_FIRST(trx->wait_thrs); 01080 } 01081 01082 trx->que_state = TRX_QUE_RUNNING; 01083 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_end_signal_handling | ( | trx_t * | trx | ) |
Definition at line 1317 of file trx0trx.c.
References FALSE, trx_struct::graph, trx_struct::graph_before_signal_handling, trx_struct::handling_signals, kernel_mutex, que_fork_error_handle(), trx_struct::sess, SESS_ERROR, sess_struct::state, TRUE, and ut_ad.
Referenced by que_thr_dec_refer_count(), and trx_sig_start_handle().
01319 : trx */ 01320 { 01321 #ifdef UNIV_SYNC_DEBUG 01322 ut_ad(mutex_own(&kernel_mutex)); 01323 #endif /* UNIV_SYNC_DEBUG */ 01324 ut_ad(trx->handling_signals == TRUE); 01325 01326 trx->handling_signals = FALSE; 01327 01328 trx->graph = trx->graph_before_signal_handling; 01329 01330 if (trx->graph && (trx->sess->state == SESS_ERROR)) { 01331 01332 que_fork_error_handle(trx, trx->graph); 01333 } 01334 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_free | ( | trx_t * | trx | ) |
Definition at line 279 of file trx0trx.c.
References trx_struct::auto_inc_lock, trx_struct::conc_state, trx_struct::declared_to_be_inside_innodb, trx_struct::dict_operation_lock_mode, trx_struct::global_read_view, trx_struct::global_read_view_heap, trx_struct::has_search_latch, trx_struct::insert_undo, kernel_mutex, trx_struct::lock_heap, trx_struct::magic_n, mem_free, mem_heap_free, mutex_free(), trx_struct::mysql_n_tables_locked, trx_struct::n_mysql_tables_in_use, NULL, trx_struct::read_view, trx_struct::repl_wait_binlog_name, trx_struct::reply_signals, trx_struct::signals, trx_struct::trx_locks, TRX_MAGIC_N, TRX_NOT_STARTED, trx_print(), trx_undo_arr_free(), trx_struct::undo_mutex, trx_struct::undo_no_arr, trx_struct::update_undo, ut_a, ut_ad, UT_LIST_GET_LEN, ut_print_buf(), ut_print_timestamp(), trx_struct::wait_lock, and trx_struct::wait_thrs.
Referenced by trx_free_for_background(), and trx_free_for_mysql().
00281 : trx object */ 00282 { 00283 #ifdef UNIV_SYNC_DEBUG 00284 ut_ad(mutex_own(&kernel_mutex)); 00285 #endif /* UNIV_SYNC_DEBUG */ 00286 00287 if (trx->declared_to_be_inside_innodb) { 00288 ut_print_timestamp(stderr); 00289 fputs( 00290 " InnoDB: Error: Freeing a trx which is declared to be processing\n" 00291 "InnoDB: inside InnoDB.\n", stderr); 00292 trx_print(stderr, trx, 600); 00293 putc('\n', stderr); 00294 } 00295 00296 if (trx->n_mysql_tables_in_use != 0 00297 || trx->mysql_n_tables_locked != 0) { 00298 00299 ut_print_timestamp(stderr); 00300 fprintf(stderr, 00301 " InnoDB: Error: MySQL is freeing a thd\n" 00302 "InnoDB: though trx->n_mysql_tables_in_use is %lu\n" 00303 "InnoDB: and trx->mysql_n_tables_locked is %lu.\n", 00304 (ulong)trx->n_mysql_tables_in_use, 00305 (ulong)trx->mysql_n_tables_locked); 00306 00307 trx_print(stderr, trx, 600); 00308 00309 ut_print_buf(stderr, trx, sizeof(trx_t)); 00310 } 00311 00312 ut_a(trx->magic_n == TRX_MAGIC_N); 00313 00314 trx->magic_n = 11112222; 00315 00316 ut_a(trx->conc_state == TRX_NOT_STARTED); 00317 00318 mutex_free(&(trx->undo_mutex)); 00319 00320 ut_a(trx->insert_undo == NULL); 00321 ut_a(trx->update_undo == NULL); 00322 00323 if (trx->undo_no_arr) { 00324 trx_undo_arr_free(trx->undo_no_arr); 00325 } 00326 00327 if (trx->repl_wait_binlog_name != NULL) { 00328 00329 mem_free(trx->repl_wait_binlog_name); 00330 } 00331 00332 ut_a(UT_LIST_GET_LEN(trx->signals) == 0); 00333 ut_a(UT_LIST_GET_LEN(trx->reply_signals) == 0); 00334 00335 ut_a(trx->wait_lock == NULL); 00336 ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0); 00337 00338 ut_a(!trx->has_search_latch); 00339 ut_a(!trx->auto_inc_lock); 00340 00341 ut_a(trx->dict_operation_lock_mode == 0); 00342 00343 if (trx->lock_heap) { 00344 mem_heap_free(trx->lock_heap); 00345 } 00346 00347 ut_a(UT_LIST_GET_LEN(trx->trx_locks) == 0); 00348 00349 if (trx->global_read_view_heap) { 00350 mem_heap_free(trx->global_read_view_heap); 00351 } 00352 00353 trx->global_read_view = NULL; 00354 00355 ut_a(trx->read_view == NULL); 00356 00357 mem_free(trx); 00358 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_free_for_background | ( | trx_t * | trx | ) |
Definition at line 385 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), and trx_free().
Referenced by row_drop_table_for_mysql_in_background().
00387 : trx object */ 00388 { 00389 mutex_enter(&kernel_mutex); 00390 00391 trx_free(trx); 00392 00393 mutex_exit(&kernel_mutex); 00394 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_free_for_mysql | ( | trx_t * | trx | ) |
Definition at line 364 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), trx_free(), trx_n_mysql_transactions, trx_sys, ut_a, and UT_LIST_REMOVE.
Referenced by dict_create_or_check_foreign_constraint_tables().
00366 : trx object */ 00367 { 00368 mutex_enter(&kernel_mutex); 00369 00370 UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx); 00371 00372 trx_free(trx); 00373 00374 ut_a(trx_n_mysql_transactions > 0); 00375 00376 trx_n_mysql_transactions--; 00377 00378 mutex_exit(&kernel_mutex); 00379 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void* trx_get_error_info | ( | trx_t * | trx | ) |
Definition at line 85 of file trx0trx.c.
References trx_struct::error_info.
00087 : the error info */ 00088 trx_t* trx) /* in: trx object */ 00089 { 00090 return(trx->error_info); 00091 }
Definition at line 1998 of file trx0trx.c.
References xid_t::bqual_length, trx_struct::conc_state, xid_t::data, xid_t::gtrid_length, kernel_mutex, memcmp(), mutex_enter, mutex_exit(), NULL, TRX_PREPARED, trx_sys, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, and trx_struct::xid.
02000 : trx or NULL */ 02001 XID* xid) /* in: X/Open XA transaction identification */ 02002 { 02003 trx_t* trx; 02004 02005 if (xid == NULL) { 02006 02007 return (NULL); 02008 } 02009 02010 mutex_enter(&kernel_mutex); 02011 02012 trx = UT_LIST_GET_FIRST(trx_sys->trx_list); 02013 02014 while (trx) { 02015 /* Compare two X/Open XA transaction id's: their 02016 length should be the same and binary comparison 02017 of gtrid_lenght+bqual_length bytes should be 02018 the same */ 02019 02020 if (xid->gtrid_length == trx->xid.gtrid_length && 02021 xid->bqual_length == trx->xid.bqual_length && 02022 memcmp(xid->data, trx->xid.data, 02023 xid->gtrid_length + 02024 xid->bqual_length) == 0) { 02025 break; 02026 } 02027 02028 trx = UT_LIST_GET_NEXT(trx_list, trx); 02029 } 02030 02031 mutex_exit(&kernel_mutex); 02032 02033 if (trx) { 02034 if (trx->conc_state != TRX_PREPARED) { 02035 02036 return(NULL); 02037 } 02038 02039 return(trx); 02040 } else { 02041 return(NULL); 02042 } 02043 }
Here is the call graph for this function:

Definition at line 1013 of file trx0trx.c.
References kernel_mutex, NULL, trx_struct::que_state, sig(), trx_struct::signals, trx_commit_off_kernel(), TRX_QUE_COMMITTING, TRX_QUE_RUNNING, TRX_SIG_COMMIT, trx_sig_remove(), trx_sig_reply(), ut_ad, UT_LIST_GET_FIRST, UT_LIST_GET_LEN, UT_LIST_GET_NEXT, and trx_struct::wait_thrs.
Referenced by trx_sig_start_handle().
01015 : transaction */ 01016 que_thr_t** next_thr) /* in/out: next query thread to run; 01017 if the value which is passed in is 01018 a pointer to a NULL pointer, then the 01019 calling function can start running 01020 a new query thread */ 01021 { 01022 trx_sig_t* sig; 01023 trx_sig_t* next_sig; 01024 01025 #ifdef UNIV_SYNC_DEBUG 01026 ut_ad(mutex_own(&kernel_mutex)); 01027 #endif /* UNIV_SYNC_DEBUG */ 01028 01029 trx->que_state = TRX_QUE_COMMITTING; 01030 01031 trx_commit_off_kernel(trx); 01032 01033 ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); 01034 01035 /* Remove all TRX_SIG_COMMIT signals from the signal queue and send 01036 reply messages to them */ 01037 01038 sig = UT_LIST_GET_FIRST(trx->signals); 01039 01040 while (sig != NULL) { 01041 next_sig = UT_LIST_GET_NEXT(signals, sig); 01042 01043 if (sig->type == TRX_SIG_COMMIT) { 01044 01045 trx_sig_reply(sig, next_thr); 01046 trx_sig_remove(trx, sig); 01047 } 01048 01049 sig = next_sig; 01050 } 01051 01052 trx->que_state = TRX_QUE_RUNNING; 01053 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void trx_list_insert_ordered | ( | trx_t * | trx | ) | [static] |
Definition at line 403 of file trx0trx.c.
References trx_struct::id, kernel_mutex, NULL, trx_sys, ut_ad, ut_dulint_cmp(), UT_LIST_ADD_FIRST, UT_LIST_ADD_LAST, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, UT_LIST_GET_PREV, and UT_LIST_INSERT_AFTER.
Referenced by trx_lists_init_at_db_start().
00405 : trx handle */ 00406 { 00407 trx_t* trx2; 00408 00409 #ifdef UNIV_SYNC_DEBUG 00410 ut_ad(mutex_own(&kernel_mutex)); 00411 #endif /* UNIV_SYNC_DEBUG */ 00412 00413 trx2 = UT_LIST_GET_FIRST(trx_sys->trx_list); 00414 00415 while (trx2 != NULL) { 00416 if (ut_dulint_cmp(trx->id, trx2->id) >= 0) { 00417 00418 ut_ad(ut_dulint_cmp(trx->id, trx2->id) == 1); 00419 break; 00420 } 00421 trx2 = UT_LIST_GET_NEXT(trx_list, trx2); 00422 } 00423 00424 if (trx2 != NULL) { 00425 trx2 = UT_LIST_GET_PREV(trx_list, trx2); 00426 00427 if (trx2 == NULL) { 00428 UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx); 00429 } else { 00430 UT_LIST_INSERT_AFTER(trx_list, trx_sys->trx_list, 00431 trx2, trx); 00432 } 00433 } else { 00434 UT_LIST_ADD_LAST(trx_list, trx_sys->trx_list, trx); 00435 } 00436 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_lists_init_at_db_start | ( | void | ) |
Definition at line 446 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::dict_operation, trx_undo_struct::dict_operation, trx_undo_struct::empty, trx_struct::id, trx_struct::insert_undo, trx_struct::no, NULL, trx_struct::rseg, srv_force_recovery, trx_undo_struct::state, trx_undo_struct::table_id, trx_struct::table_id, trx_undo_struct::top_undo_no, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, trx_create(), trx_get_on_id(), trx_undo_struct::trx_id, trx_list_insert_ordered(), TRX_PREPARED, trx_sys, TRX_UNDO_ACTIVE, TRX_UNDO_PREPARED, trx_struct::undo_no, trx_struct::update_undo, ut_dulint_add(), ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), ut_dulint_max, UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, UT_LIST_INIT, trx_undo_struct::xid, and trx_struct::xid.
Referenced by trx_sys_init_at_db_start().
00448 { 00449 trx_rseg_t* rseg; 00450 trx_undo_t* undo; 00451 trx_t* trx; 00452 00453 UT_LIST_INIT(trx_sys->trx_list); 00454 00455 /* Look from the rollback segments if there exist undo logs for 00456 transactions */ 00457 00458 rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); 00459 00460 while (rseg != NULL) { 00461 undo = UT_LIST_GET_FIRST(rseg->insert_undo_list); 00462 00463 while (undo != NULL) { 00464 00465 trx = trx_create(NULL); 00466 00467 trx->id = undo->trx_id; 00468 trx->xid = undo->xid; 00469 trx->insert_undo = undo; 00470 trx->rseg = rseg; 00471 00472 if (undo->state != TRX_UNDO_ACTIVE) { 00473 00474 /* Prepared transactions are left in 00475 the prepared state waiting for a 00476 commit or abort decision from MySQL */ 00477 00478 if (undo->state == TRX_UNDO_PREPARED) { 00479 00480 fprintf(stderr, 00481 "InnoDB: Transaction %lu %lu was in the XA prepared state.\n", 00482 ut_dulint_get_high(trx->id), 00483 ut_dulint_get_low(trx->id)); 00484 00485 if (srv_force_recovery == 0) { 00486 00487 trx->conc_state = TRX_PREPARED; 00488 } else { 00489 fprintf(stderr, 00490 "InnoDB: Since innodb_force_recovery > 0, we will rollback it anyway.\n"); 00491 00492 trx->conc_state = TRX_ACTIVE; 00493 } 00494 } else { 00495 trx->conc_state = 00496 TRX_COMMITTED_IN_MEMORY; 00497 } 00498 00499 /* We give a dummy value for the trx no; 00500 this should have no relevance since purge 00501 is not interested in committed transaction 00502 numbers, unless they are in the history 00503 list, in which case it looks the number 00504 from the disk based undo log structure */ 00505 00506 trx->no = trx->id; 00507 } else { 00508 trx->conc_state = TRX_ACTIVE; 00509 00510 /* A running transaction always has the number 00511 field inited to ut_dulint_max */ 00512 00513 trx->no = ut_dulint_max; 00514 } 00515 00516 if (undo->dict_operation) { 00517 trx->dict_operation = undo->dict_operation; 00518 trx->table_id = undo->table_id; 00519 } 00520 00521 if (!undo->empty) { 00522 trx->undo_no = ut_dulint_add(undo->top_undo_no, 00523 1); 00524 } 00525 00526 trx_list_insert_ordered(trx); 00527 00528 undo = UT_LIST_GET_NEXT(undo_list, undo); 00529 } 00530 00531 undo = UT_LIST_GET_FIRST(rseg->update_undo_list); 00532 00533 while (undo != NULL) { 00534 trx = trx_get_on_id(undo->trx_id); 00535 00536 if (NULL == trx) { 00537 trx = trx_create(NULL); 00538 00539 trx->id = undo->trx_id; 00540 trx->xid = undo->xid; 00541 00542 if (undo->state != TRX_UNDO_ACTIVE) { 00543 00544 /* Prepared transactions are left in 00545 the prepared state waiting for a 00546 commit or abort decision from MySQL */ 00547 00548 if (undo->state == TRX_UNDO_PREPARED) { 00549 fprintf(stderr, 00550 "InnoDB: Transaction %lu %lu was in the XA prepared state.\n", 00551 ut_dulint_get_high(trx->id), 00552 ut_dulint_get_low(trx->id)); 00553 00554 if (srv_force_recovery == 0) { 00555 00556 trx->conc_state = 00557 TRX_PREPARED; 00558 } else { 00559 fprintf(stderr, 00560 "InnoDB: Since innodb_force_recovery > 0, we will rollback it anyway.\n"); 00561 00562 trx->conc_state = 00563 TRX_ACTIVE; 00564 } 00565 } else { 00566 trx->conc_state = 00567 TRX_COMMITTED_IN_MEMORY; 00568 } 00569 00570 /* We give a dummy value for the trx 00571 number */ 00572 00573 trx->no = trx->id; 00574 } else { 00575 trx->conc_state = TRX_ACTIVE; 00576 00577 /* A running transaction always has 00578 the number field inited to 00579 ut_dulint_max */ 00580 00581 trx->no = ut_dulint_max; 00582 } 00583 00584 trx->rseg = rseg; 00585 trx_list_insert_ordered(trx); 00586 00587 if (undo->dict_operation) { 00588 trx->dict_operation = 00589 undo->dict_operation; 00590 trx->table_id = undo->table_id; 00591 } 00592 } 00593 00594 trx->update_undo = undo; 00595 00596 if ((!undo->empty) 00597 && (ut_dulint_cmp(undo->top_undo_no, 00598 trx->undo_no) >= 0)) { 00599 00600 trx->undo_no = ut_dulint_add(undo->top_undo_no, 00601 1); 00602 } 00603 00604 undo = UT_LIST_GET_NEXT(undo_list, undo); 00605 } 00606 00607 rseg = UT_LIST_GET_NEXT(rseg_list, rseg); 00608 } 00609 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void trx_lock_wait_to_suspended | ( | trx_t * | trx | ) | [static] |
Definition at line 1090 of file trx0trx.c.
References kernel_mutex, NULL, trx_struct::que_state, QUE_THR_SUSPENDED, que_thr_struct::state, TRX_QUE_LOCK_WAIT, TRX_QUE_RUNNING, ut_ad, UT_LIST_GET_FIRST, UT_LIST_REMOVE, and trx_struct::wait_thrs.
Referenced by trx_sig_start_handle().
01092 : transaction in the TRX_QUE_LOCK_WAIT state */ 01093 { 01094 que_thr_t* thr; 01095 01096 #ifdef UNIV_SYNC_DEBUG 01097 ut_ad(mutex_own(&kernel_mutex)); 01098 #endif /* UNIV_SYNC_DEBUG */ 01099 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT); 01100 01101 thr = UT_LIST_GET_FIRST(trx->wait_thrs); 01102 01103 while (thr != NULL) { 01104 thr->state = QUE_THR_SUSPENDED; 01105 01106 UT_LIST_REMOVE(trx_thrs, trx->wait_thrs, thr); 01107 01108 thr = UT_LIST_GET_FIRST(trx->wait_thrs); 01109 } 01110 01111 trx->que_state = TRX_QUE_RUNNING; 01112 }
Here is the caller graph for this function:

| void trx_mark_sql_stat_end | ( | trx_t * | trx | ) |
Definition at line 1651 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::last_sql_stat_start, trx_savept_struct::least_undo_no, TRX_NOT_STARTED, trx_struct::undo_no, ut_a, and ut_dulint_zero.
Referenced by trx_rollback_last_sql_stat_for_mysql(), and trx_rollback_to_savepoint_for_mysql().
01653 : trx handle */ 01654 { 01655 ut_a(trx); 01656 01657 if (trx->conc_state == TRX_NOT_STARTED) { 01658 trx->undo_no = ut_dulint_zero; 01659 } 01660 01661 trx->last_sql_stat_start.least_undo_no = trx->undo_no; 01662 }
Here is the caller graph for this function:

Definition at line 1899 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), trx_struct::op_info, trx_prepare_off_kernel(), trx_start_if_not_started(), and ut_a.
01901 : 0 or error number */ 01902 trx_t* trx) /* in: trx handle */ 01903 { 01904 /* Because we do not do the prepare by sending an Innobase 01905 sig to the transaction, we must here make sure that trx has been 01906 started. */ 01907 01908 ut_a(trx); 01909 01910 trx->op_info = "preparing"; 01911 01912 trx_start_if_not_started(trx); 01913 01914 mutex_enter(&kernel_mutex); 01915 01916 trx_prepare_off_kernel(trx); 01917 01918 mutex_exit(&kernel_mutex); 01919 01920 trx->op_info = ""; 01921 01922 return(0); 01923 }
Here is the call graph for this function:

| void trx_prepare_off_kernel | ( | trx_t * | trx | ) |
Definition at line 1782 of file trx0trx.c.
References trx_struct::conc_state, mtr_struct::end_lsn, FALSE, trx_struct::insert_undo, kernel_mutex, LOG_WAIT_ONE_GROUP, log_write_up_to(), mtr_commit(), mtr_start(), trx_rseg_struct::mutex, mutex_enter, mutex_exit(), NULL, page_t, trx_struct::rseg, srv_flush_log_at_trx_commit, srv_unix_file_flush_method, SRV_UNIX_NOSYNC, TRUE, TRX_PREPARED, trx_undo_set_state_at_prepare(), trx_struct::update_undo, ut_ad, and ut_error.
Referenced by trx_prepare_for_mysql().
01784 : transaction */ 01785 { 01786 page_t* update_hdr_page; 01787 trx_rseg_t* rseg; 01788 ibool must_flush_log = FALSE; 01789 dulint lsn; 01790 mtr_t mtr; 01791 01792 #ifdef UNIV_SYNC_DEBUG 01793 ut_ad(mutex_own(&kernel_mutex)); 01794 #endif /* UNIV_SYNC_DEBUG */ 01795 01796 rseg = trx->rseg; 01797 01798 if (trx->insert_undo != NULL || trx->update_undo != NULL) { 01799 01800 mutex_exit(&kernel_mutex); 01801 01802 mtr_start(&mtr); 01803 01804 must_flush_log = TRUE; 01805 01806 /* Change the undo log segment states from TRX_UNDO_ACTIVE 01807 to TRX_UNDO_PREPARED: these modifications to the file data 01808 structure define the transaction as prepared in the 01809 file-based world, at the serialization point of lsn. */ 01810 01811 mutex_enter(&(rseg->mutex)); 01812 01813 if (trx->insert_undo != NULL) { 01814 01815 /* It is not necessary to obtain trx->undo_mutex here 01816 because only a single OS thread is allowed to do the 01817 transaction prepare for this transaction. */ 01818 01819 trx_undo_set_state_at_prepare(trx, trx->insert_undo, 01820 &mtr); 01821 } 01822 01823 if (trx->update_undo) { 01824 update_hdr_page = trx_undo_set_state_at_prepare(trx, 01825 trx->update_undo, &mtr); 01826 } 01827 01828 mutex_exit(&(rseg->mutex)); 01829 01830 /*--------------*/ 01831 mtr_commit(&mtr); /* This mtr commit makes the 01832 transaction prepared in the file-based 01833 world */ 01834 /*--------------*/ 01835 lsn = mtr.end_lsn; 01836 01837 mutex_enter(&kernel_mutex); 01838 } 01839 01840 #ifdef UNIV_SYNC_DEBUG 01841 ut_ad(mutex_own(&kernel_mutex)); 01842 #endif /* UNIV_SYNC_DEBUG */ 01843 01844 /*--------------------------------------*/ 01845 trx->conc_state = TRX_PREPARED; 01846 /*--------------------------------------*/ 01847 01848 if (must_flush_log) { 01849 /* Depending on the my.cnf options, we may now write the log 01850 buffer to the log files, making the prepared state of the 01851 transaction durable if the OS does not crash. We may also 01852 flush the log files to disk, making the prepared state of the 01853 transaction durable also at an OS crash or a power outage. 01854 01855 The idea in InnoDB's group prepare is that a group of 01856 transactions gather behind a trx doing a physical disk write 01857 to log files, and when that physical write has been completed, 01858 one of those transactions does a write which prepares the whole 01859 group. Note that this group prepare will only bring benefit if 01860 there are > 2 users in the database. Then at least 2 users can 01861 gather behind one doing the physical log write to disk. 01862 01863 TODO: find out if MySQL holds some mutex when calling this. 01864 That would spoil our group prepare algorithm. */ 01865 01866 mutex_exit(&kernel_mutex); 01867 01868 if (srv_flush_log_at_trx_commit == 0) { 01869 /* Do nothing */ 01870 } else if (srv_flush_log_at_trx_commit == 1) { 01871 if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) { 01872 /* Write the log but do not flush it to disk */ 01873 01874 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, 01875 FALSE); 01876 } else { 01877 /* Write the log to the log files AND flush 01878 them to disk */ 01879 01880 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); 01881 } 01882 } else if (srv_flush_log_at_trx_commit == 2) { 01883 01884 /* Write the log but do not flush it to disk */ 01885 01886 log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); 01887 } else { 01888 ut_error; 01889 } 01890 01891 mutex_enter(&kernel_mutex); 01892 } 01893 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1671 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::declared_to_be_inside_innodb, FALSE, trx_struct::has_search_latch, trx_struct::id, innobase_mysql_print_thd(), trx_struct::lock_heap, lock_number_of_rows_locked(), mem_heap_get_size(), trx_struct::mysql_n_tables_locked, trx_struct::mysql_process_no, trx_struct::mysql_thd, trx_struct::mysql_thread_id, trx_struct::n_mysql_tables_in_use, trx_struct::n_tickets_to_enter_innodb, NULL, trx_struct::op_info, os_thread_pf(), trx_struct::que_state, trx_struct::start_time, TRUE, TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, trx_struct::trx_locks, TRX_NOT_STARTED, TRX_PREPARED, TRX_QUE_COMMITTING, TRX_QUE_LOCK_WAIT, TRX_QUE_ROLLING_BACK, TRX_QUE_RUNNING, TRX_USER, trx_struct::type, trx_struct::undo_no, ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), ut_dulint_zero, and UT_LIST_GET_LEN.
Referenced by btr_pcur_restore_position(), lock_deadlock_recursive(), lock_print_info_all_transactions(), row_ins_foreign_report_add_err(), row_ins_foreign_report_err(), row_search_for_mysql(), row_sel_get_clust_rec_for_mysql(), row_undo_mod_del_unmark_sec_and_undo_update(), row_upd_sec_index_entry(), srv_conc_enter_innodb(), and trx_free().
01673 : output stream */ 01674 trx_t* trx, /* in: transaction */ 01675 ulint max_query_len) /* in: max query length to print, or 0 to 01676 use the default max length */ 01677 { 01678 ibool newline; 01679 01680 fprintf(f, "TRANSACTION %lu %lu", 01681 (ulong) ut_dulint_get_high(trx->id), 01682 (ulong) ut_dulint_get_low(trx->id)); 01683 01684 switch (trx->conc_state) { 01685 case TRX_NOT_STARTED: 01686 fputs(", not started", f); 01687 break; 01688 case TRX_ACTIVE: 01689 fprintf(f, ", ACTIVE %lu sec", 01690 (ulong)difftime(time(NULL), trx->start_time)); 01691 break; 01692 case TRX_PREPARED: 01693 fprintf(f, ", ACTIVE (PREPARED) %lu sec", 01694 (ulong)difftime(time(NULL), trx->start_time)); 01695 break; 01696 case TRX_COMMITTED_IN_MEMORY: 01697 fputs(", COMMITTED IN MEMORY", f); 01698 break; 01699 default: 01700 fprintf(f, " state %lu", (ulong) trx->conc_state); 01701 } 01702 01703 #ifdef UNIV_LINUX 01704 fprintf(f, ", process no %lu", trx->mysql_process_no); 01705 #endif 01706 fprintf(f, ", OS thread id %lu", 01707 (ulong) os_thread_pf(trx->mysql_thread_id)); 01708 01709 if (*trx->op_info) { 01710 putc(' ', f); 01711 fputs(trx->op_info, f); 01712 } 01713 01714 if (trx->type != TRX_USER) { 01715 fputs(" purge trx", f); 01716 } 01717 01718 if (trx->declared_to_be_inside_innodb) { 01719 fprintf(f, ", thread declared inside InnoDB %lu", 01720 (ulong) trx->n_tickets_to_enter_innodb); 01721 } 01722 01723 putc('\n', f); 01724 01725 if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { 01726 fprintf(f, "mysql tables in use %lu, locked %lu\n", 01727 (ulong) trx->n_mysql_tables_in_use, 01728 (ulong) trx->mysql_n_tables_locked); 01729 } 01730 01731 newline = TRUE; 01732 01733 switch (trx->que_state) { 01734 case TRX_QUE_RUNNING: 01735 newline = FALSE; break; 01736 case TRX_QUE_LOCK_WAIT: 01737 fputs("LOCK WAIT ", f); break; 01738 case TRX_QUE_ROLLING_BACK: 01739 fputs("ROLLING BACK ", f); break; 01740 case TRX_QUE_COMMITTING: 01741 fputs("COMMITTING ", f); break; 01742 default: 01743 fprintf(f, "que state %lu ", (ulong) trx->que_state); 01744 } 01745 01746 if (0 < UT_LIST_GET_LEN(trx->trx_locks) || 01747 mem_heap_get_size(trx->lock_heap) > 400) { 01748 newline = TRUE; 01749 01750 fprintf(f, "%lu lock struct(s), heap size %lu", 01751 (ulong) UT_LIST_GET_LEN(trx->trx_locks), 01752 (ulong) mem_heap_get_size(trx->lock_heap)); 01753 01754 fprintf(f, "%lu row lock(s)", 01755 (ulong) lock_number_of_rows_locked(trx)); 01756 } 01757 01758 if (trx->has_search_latch) { 01759 newline = TRUE; 01760 fputs(", holds adaptive hash latch", f); 01761 } 01762 01763 if (ut_dulint_cmp(trx->undo_no, ut_dulint_zero) != 0) { 01764 newline = TRUE; 01765 fprintf(f, ", undo log entries %lu", 01766 (ulong) ut_dulint_get_low(trx->undo_no)); 01767 } 01768 01769 if (newline) { 01770 putc('\n', f); 01771 } 01772 01773 if (trx->mysql_thd != NULL) { 01774 innobase_mysql_print_thd(f, trx->mysql_thd, max_query_len); 01775 } 01776 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1930 of file trx0trx.c.
References trx_struct::conc_state, count, trx_struct::id, kernel_mutex, mutex_enter, mutex_exit(), TRX_PREPARED, trx_sys, trx_struct::undo_no, ut_ad, ut_conv_dulint_to_longlong(), ut_dulint_get_high(), ut_dulint_get_low(), UT_LIST_GET_FIRST, UT_LIST_GET_NEXT, ut_print_timestamp(), and trx_struct::xid.
01932 : number of prepared transactions 01933 stored in xid_list */ 01934 XID* xid_list, /* in/out: prepared transactions */ 01935 ulint len) /* in: number of slots in xid_list */ 01936 { 01937 trx_t* trx; 01938 ulint count = 0; 01939 01940 ut_ad(xid_list); 01941 ut_ad(len); 01942 01943 /* We should set those transactions which are in the prepared state 01944 to the xid_list */ 01945 01946 mutex_enter(&kernel_mutex); 01947 01948 trx = UT_LIST_GET_FIRST(trx_sys->trx_list); 01949 01950 while (trx) { 01951 if (trx->conc_state == TRX_PREPARED) { 01952 xid_list[count] = trx->xid; 01953 01954 if (count == 0) { 01955 ut_print_timestamp(stderr); 01956 fprintf(stderr, 01957 " InnoDB: Starting recovery for XA transactions...\n"); 01958 } 01959 01960 ut_print_timestamp(stderr); 01961 fprintf(stderr, 01962 " InnoDB: Transaction %lu %lu in prepared state after recovery\n", 01963 (ulong) ut_dulint_get_high(trx->id), 01964 (ulong) ut_dulint_get_low(trx->id)); 01965 01966 ut_print_timestamp(stderr); 01967 fprintf(stderr, 01968 " InnoDB: Transaction contains changes to %lu rows\n", 01969 (ulong)ut_conv_dulint_to_longlong(trx->undo_no)); 01970 01971 count++; 01972 01973 if (count == len) { 01974 break; 01975 } 01976 } 01977 01978 trx = UT_LIST_GET_NEXT(trx_list, trx); 01979 } 01980 01981 mutex_exit(&kernel_mutex); 01982 01983 if (count > 0){ 01984 ut_print_timestamp(stderr); 01985 fprintf(stderr, 01986 " InnoDB: %lu transactions in prepared state after recovery\n", 01987 (ulong) count); 01988 } 01989 01990 return (count); 01991 }
Here is the call graph for this function:

| void trx_search_latch_release_if_reserved | ( | trx_t * | trx | ) |
Definition at line 264 of file trx0trx.c.
References btr_search_latch, FALSE, trx_struct::has_search_latch, and rw_lock_s_unlock.
00266 : transaction */ 00267 { 00268 if (trx->has_search_latch) { 00269 rw_lock_s_unlock(&btr_search_latch); 00270 00271 trx->has_search_latch = FALSE; 00272 } 00273 }
| void trx_set_detailed_error | ( | trx_t * | trx, | |
| const char * | msg | |||
| ) |
Definition at line 59 of file trx0trx.c.
References trx_struct::detailed_error, and ut_strlcpy().
Referenced by row_ins_set_detailed().
00061 : transaction struct */ 00062 const char* msg) /* in: detailed error message */ 00063 { 00064 ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error)); 00065 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_set_detailed_error_from_file | ( | trx_t * | trx, | |
| FILE * | file | |||
| ) |
Definition at line 72 of file trx0trx.c.
References trx_struct::detailed_error, and os_file_read_string().
Referenced by row_ins_set_detailed().
00074 : transaction struct */ 00075 FILE* file) /* in: file to read message from */ 00076 { 00077 os_file_read_string(file, trx->detailed_error, 00078 sizeof(trx->detailed_error)); 00079 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1152 of file trx0trx.c.
References FALSE, kernel_mutex, NULL, sig(), trx_struct::signals, TRUE, TRX_SIG_BREAK_EXECUTION, TRX_SIG_COMMIT, TRX_SIG_ERROR_OCCURRED, TRX_SIG_OTHER_SESS, TRX_SIG_SELF, TRX_SIG_TOTAL_ROLLBACK, ut_ad, ut_error, UT_LIST_GET_FIRST, UT_LIST_GET_LEN, and UT_LIST_GET_NEXT.
Referenced by trx_sig_send().
01154 : TRUE if the signal can be queued */ 01155 trx_t* trx, /* in: trx handle */ 01156 ulint type, /* in: signal type */ 01157 ulint sender) /* in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */ 01158 { 01159 trx_sig_t* sig; 01160 01161 #ifdef UNIV_SYNC_DEBUG 01162 ut_ad(mutex_own(&kernel_mutex)); 01163 #endif /* UNIV_SYNC_DEBUG */ 01164 01165 if (UT_LIST_GET_LEN(trx->signals) == 0) { 01166 01167 return(TRUE); 01168 } 01169 01170 if (sender == TRX_SIG_SELF) { 01171 if (type == TRX_SIG_ERROR_OCCURRED) { 01172 01173 return(TRUE); 01174 01175 } else if (type == TRX_SIG_BREAK_EXECUTION) { 01176 01177 return(TRUE); 01178 } else { 01179 return(FALSE); 01180 } 01181 } 01182 01183 ut_ad(sender == TRX_SIG_OTHER_SESS); 01184 01185 sig = UT_LIST_GET_FIRST(trx->signals); 01186 01187 if (type == TRX_SIG_COMMIT) { 01188 while (sig != NULL) { 01189 01190 if (sig->type == TRX_SIG_TOTAL_ROLLBACK) { 01191 01192 return(FALSE); 01193 } 01194 01195 sig = UT_LIST_GET_NEXT(signals, sig); 01196 } 01197 01198 return(TRUE); 01199 01200 } else if (type == TRX_SIG_TOTAL_ROLLBACK) { 01201 while (sig != NULL) { 01202 01203 if (sig->type == TRX_SIG_COMMIT) { 01204 01205 return(FALSE); 01206 } 01207 01208 sig = UT_LIST_GET_NEXT(signals, sig); 01209 } 01210 01211 return(TRUE); 01212 01213 } else if (type == TRX_SIG_BREAK_EXECUTION) { 01214 01215 return(TRUE); 01216 } else { 01217 ut_error; 01218 01219 return(FALSE); 01220 } 01221 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1484 of file trx0trx.c.
References kernel_mutex, mem_free, NULL, trx_struct::sig, sig(), trx_struct::signals, ut_ad, and UT_LIST_REMOVE.
Referenced by trx_finish_error_processing(), trx_finish_partial_rollback_off_kernel(), trx_finish_rollback_off_kernel(), trx_handle_commit_sig_off_kernel(), and trx_sig_start_handle().
01486 : trx handle */ 01487 trx_sig_t* sig) /* in, own: signal */ 01488 { 01489 ut_ad(trx && sig); 01490 #ifdef UNIV_SYNC_DEBUG 01491 ut_ad(mutex_own(&kernel_mutex)); 01492 #endif /* UNIV_SYNC_DEBUG */ 01493 01494 ut_ad(sig->receiver == NULL); 01495 01496 UT_LIST_REMOVE(signals, trx->signals, sig); 01497 sig->type = 0; /* reset the field to catch possible bugs */ 01498 01499 if (sig != &(trx->sig)) { 01500 mem_free(sig); 01501 } 01502 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1448 of file trx0trx.c.
References kernel_mutex, NULL, que_thr_end_wait(), QUE_THR_SIG_REPLY_WAIT, trx_struct::reply_signals, trx_struct::sess, SESS_ERROR, sig(), sess_struct::state, thr_get_trx(), ut_ad, and UT_LIST_REMOVE.
Referenced by trx_finish_partial_rollback_off_kernel(), trx_finish_rollback_off_kernel(), trx_handle_commit_sig_off_kernel(), and trx_sig_start_handle().
01450 : signal */ 01451 que_thr_t** next_thr) /* in/out: next query thread to run; 01452 if the value which is passed in is 01453 a pointer to a NULL pointer, then the 01454 calling function can start running 01455 a new query thread */ 01456 { 01457 trx_t* receiver_trx; 01458 01459 ut_ad(sig); 01460 #ifdef UNIV_SYNC_DEBUG 01461 ut_ad(mutex_own(&kernel_mutex)); 01462 #endif /* UNIV_SYNC_DEBUG */ 01463 01464 if (sig->receiver != NULL) { 01465 ut_ad((sig->receiver)->state == QUE_THR_SIG_REPLY_WAIT); 01466 01467 receiver_trx = thr_get_trx(sig->receiver); 01468 01469 UT_LIST_REMOVE(reply_signals, receiver_trx->reply_signals, 01470 sig); 01471 ut_ad(receiver_trx->sess->state != SESS_ERROR); 01472 01473 que_thr_end_wait(sig->receiver, next_thr); 01474 01475 sig->receiver = NULL; 01476 01477 } 01478 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void trx_sig_reply_wait_to_suspended | ( | trx_t * | trx | ) | [static] |
Definition at line 1119 of file trx0trx.c.
References kernel_mutex, NULL, QUE_THR_SIG_REPLY_WAIT, QUE_THR_SUSPENDED, trx_struct::reply_signals, sig(), que_thr_struct::state, ut_ad, UT_LIST_GET_FIRST, and UT_LIST_REMOVE.
Referenced by trx_sig_send(), and trx_sig_start_handle().
01121 : transaction */ 01122 { 01123 trx_sig_t* sig; 01124 que_thr_t* thr; 01125 01126 #ifdef UNIV_SYNC_DEBUG 01127 ut_ad(mutex_own(&kernel_mutex)); 01128 #endif /* UNIV_SYNC_DEBUG */ 01129 01130 sig = UT_LIST_GET_FIRST(trx->reply_signals); 01131 01132 while (sig != NULL) { 01133 thr = sig->receiver; 01134 01135 ut_ad(thr->state == QUE_THR_SIG_REPLY_WAIT); 01136 01137 thr->state = QUE_THR_SUSPENDED; 01138 01139 sig->receiver = NULL; 01140 01141 UT_LIST_REMOVE(reply_signals, trx->reply_signals, sig); 01142 01143 sig = UT_LIST_GET_FIRST(trx->reply_signals); 01144 } 01145 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void trx_sig_send | ( | trx_t * | trx, | |
| ulint | type, | |||
| ulint | sender, | |||
| que_thr_t * | receiver_thr, | |||
| trx_savept_t * | savept, | |||
| que_thr_t ** | next_thr | |||
| ) |
Definition at line 1227 of file trx0trx.c.
References kernel_mutex, mem_alloc, trx_struct::reply_signals, trx_struct::sess, SESS_ERROR, trx_struct::sig, sig(), trx_struct::signals, sess_struct::state, thr_get_trx(), TRX_SIG_BREAK_EXECUTION, trx_sig_is_compatible(), trx_sig_reply_wait_to_suspended(), TRX_SIG_SELF, trx_sig_start_handle(), TRX_SIG_WAITING, ut_ad, ut_error, UT_LIST_ADD_LAST, UT_LIST_GET_FIRST, and UT_LIST_GET_LEN.
Referenced by trx_commit_step(), and trx_rollback_step().
01229 : trx handle */ 01230 ulint type, /* in: signal type */ 01231 ulint sender, /* in: TRX_SIG_SELF or 01232 TRX_SIG_OTHER_SESS */ 01233 que_thr_t* receiver_thr, /* in: query thread which wants the 01234 reply, or NULL; if type is 01235 TRX_SIG_END_WAIT, this must be NULL */ 01236 trx_savept_t* savept, /* in: possible rollback savepoint, or 01237 NULL */ 01238 que_thr_t** next_thr) /* in/out: next query thread to run; 01239 if the value which is passed in is 01240 a pointer to a NULL pointer, then the 01241 calling function can start running 01242 a new query thread; if the parameter 01243 is NULL, it is ignored */ 01244 { 01245 trx_sig_t* sig; 01246 trx_t* receiver_trx; 01247 01248 ut_ad(trx); 01249 #ifdef UNIV_SYNC_DEBUG 01250 ut_ad(mutex_own(&kernel_mutex)); 01251 #endif /* UNIV_SYNC_DEBUG */ 01252 01253 if (!trx_sig_is_compatible(trx, type, sender)) { 01254 /* The signal is not compatible with the other signals in 01255 the queue: die */ 01256 01257 ut_error; 01258 } 01259 01260 /* Queue the signal object */ 01261 01262 if (UT_LIST_GET_LEN(trx->signals) == 0) { 01263 01264 /* The signal list is empty: the 'sig' slot must be unused 01265 (we improve performance a bit by avoiding mem_alloc) */ 01266 sig = &(trx->sig); 01267 } else { 01268 /* It might be that the 'sig' slot is unused also in this 01269 case, but we choose the easy way of using mem_alloc */ 01270 01271 sig = mem_alloc(sizeof(trx_sig_t)); 01272 } 01273 01274 UT_LIST_ADD_LAST(signals, trx->signals, sig); 01275 01276 sig->type = type; 01277 sig->state = TRX_SIG_WAITING; 01278 sig->sender = sender; 01279 sig->receiver = receiver_thr; 01280 01281 if (savept) { 01282 sig->savept = *savept; 01283 } 01284 01285 if (receiver_thr) { 01286 receiver_trx = thr_get_trx(receiver_thr); 01287 01288 UT_LIST_ADD_LAST(reply_signals, receiver_trx->reply_signals, 01289 sig); 01290 } 01291 01292 if (trx->sess->state == SESS_ERROR) { 01293 01294 trx_sig_reply_wait_to_suspended(trx); 01295 } 01296 01297 if ((sender != TRX_SIG_SELF) || (type == TRX_SIG_BREAK_EXECUTION)) { 01298 ut_error; 01299 } 01300 01301 /* If there were no other signals ahead in the queue, try to start 01302 handling of the signal */ 01303 01304 if (UT_LIST_GET_FIRST(trx->signals) == sig) { 01305 01306 trx_sig_start_handle(trx, next_thr); 01307 } 01308 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1340 of file trx0trx.c.
References trx_struct::conc_state, FALSE, trx_struct::graph, trx_struct::graph_before_signal_handling, trx_struct::handling_signals, kernel_mutex, trx_struct::n_active_thrs, trx_struct::que_state, trx_struct::sess, SESS_ERROR, sig(), trx_struct::signals, sess_struct::state, TRUE, trx_end_signal_handling(), trx_handle_commit_sig_off_kernel(), trx_lock_wait_to_suspended(), TRX_NOT_STARTED, TRX_QUE_LOCK_WAIT, trx_rollback(), TRX_SIG_BREAK_EXECUTION, TRX_SIG_COMMIT, TRX_SIG_ERROR_OCCURRED, trx_sig_remove(), trx_sig_reply(), trx_sig_reply_wait_to_suspended(), TRX_SIG_ROLLBACK_TO_SAVEPT, TRX_SIG_TOTAL_ROLLBACK, trx_start_low(), ut_ad, ut_error, UT_LIST_GET_FIRST, and UT_LIST_GET_LEN.
Referenced by que_thr_dec_refer_count(), and trx_sig_send().
01342 : trx handle */ 01343 que_thr_t** next_thr) /* in/out: next query thread to run; 01344 if the value which is passed in is 01345 a pointer to a NULL pointer, then the 01346 calling function can start running 01347 a new query thread; if the parameter 01348 is NULL, it is ignored */ 01349 { 01350 trx_sig_t* sig; 01351 ulint type; 01352 loop: 01353 /* We loop in this function body as long as there are queued signals 01354 we can process immediately */ 01355 01356 ut_ad(trx); 01357 #ifdef UNIV_SYNC_DEBUG 01358 ut_ad(mutex_own(&kernel_mutex)); 01359 #endif /* UNIV_SYNC_DEBUG */ 01360 01361 if (trx->handling_signals && (UT_LIST_GET_LEN(trx->signals) == 0)) { 01362 01363 trx_end_signal_handling(trx); 01364 01365 return; 01366 } 01367 01368 if (trx->conc_state == TRX_NOT_STARTED) { 01369 01370 trx_start_low(trx, ULINT_UNDEFINED); 01371 } 01372 01373 /* If the trx is in a lock wait state, moves the waiting query threads 01374 to the suspended state */ 01375 01376 if (trx->que_state == TRX_QUE_LOCK_WAIT) { 01377 01378 trx_lock_wait_to_suspended(trx); 01379 } 01380 01381 /* If the session is in the error state and this trx has threads 01382 waiting for reply from signals, moves these threads to the suspended 01383 state, canceling wait reservations; note that if the transaction has 01384 sent a commit or rollback signal to itself, and its session is not in 01385 the error state, then nothing is done here. */ 01386 01387 if (trx->sess->state == SESS_ERROR) { 01388 trx_sig_reply_wait_to_suspended(trx); 01389 } 01390 01391 /* If there are no running query threads, we can start processing of a 01392 signal, otherwise we have to wait until all query threads of this 01393 transaction are aware of the arrival of the signal. */ 01394 01395 if (trx->n_active_thrs > 0) { 01396 01397 return; 01398 } 01399 01400 if (trx->handling_signals == FALSE) { 01401 trx->graph_before_signal_handling = trx->graph; 01402 01403 trx->handling_signals = TRUE; 01404 } 01405 01406 sig = UT_LIST_GET_FIRST(trx->signals); 01407 type = sig->type; 01408 01409 if (type == TRX_SIG_COMMIT) { 01410 01411 trx_handle_commit_sig_off_kernel(trx, next_thr); 01412 01413 } else if ((type == TRX_SIG_TOTAL_ROLLBACK) 01414 || (type == TRX_SIG_ROLLBACK_TO_SAVEPT)) { 01415 01416 trx_rollback(trx, sig, next_thr); 01417 01418 /* No further signals can be handled until the rollback 01419 completes, therefore we return */ 01420 01421 return; 01422 01423 } else if (type == TRX_SIG_ERROR_OCCURRED) { 01424 01425 trx_rollback(trx, sig, next_thr); 01426 01427 /* No further signals can be handled until the rollback 01428 completes, therefore we return */ 01429 01430 return; 01431 01432 } else if (type == TRX_SIG_BREAK_EXECUTION) { 01433 01434 trx_sig_reply(sig, next_thr); 01435 trx_sig_remove(trx, sig); 01436 } else { 01437 ut_error; 01438 } 01439 01440 goto loop; 01441 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 704 of file trx0trx.c.
References kernel_mutex, mutex_enter, mutex_exit(), and trx_start_low().
00706 : TRUE */ 00707 trx_t* trx, /* in: transaction */ 00708 ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED 00709 is passed, the system chooses the rollback segment 00710 automatically in a round-robin fashion */ 00711 { 00712 ibool ret; 00713 00714 mutex_enter(&kernel_mutex); 00715 00716 ret = trx_start_low(trx, rseg_id); 00717 00718 mutex_exit(&kernel_mutex); 00719 00720 return(ret); 00721 }
Here is the call graph for this function:

| void trx_start_if_not_started_noninline | ( | trx_t * | trx | ) |
Definition at line 48 of file trx0trx.c.
References trx_start_if_not_started().
00050 : transaction */ 00051 { 00052 trx_start_if_not_started(trx); 00053 }
Here is the call graph for this function:

Definition at line 651 of file trx0trx.c.
References trx_struct::conc_state, trx_struct::id, kernel_mutex, trx_struct::no, NULL, trx_struct::rseg, trx_struct::start_time, TRUE, TRX_ACTIVE, trx_assign_rseg(), TRX_PURGE, trx_sys, trx_sys_get_new_trx_id(), trx_sys_get_nth_rseg(), trx_struct::type, ut_ad, ut_dulint_max, ut_dulint_zero, and UT_LIST_ADD_FIRST.
Referenced by trx_purge_sys_create(), trx_sig_start_handle(), and trx_start().
00653 : TRUE */ 00654 trx_t* trx, /* in: transaction */ 00655 ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED 00656 is passed, the system chooses the rollback segment 00657 automatically in a round-robin fashion */ 00658 { 00659 trx_rseg_t* rseg; 00660 00661 #ifdef UNIV_SYNC_DEBUG 00662 ut_ad(mutex_own(&kernel_mutex)); 00663 #endif /* UNIV_SYNC_DEBUG */ 00664 ut_ad(trx->rseg == NULL); 00665 00666 if (trx->type == TRX_PURGE) { 00667 trx->id = ut_dulint_zero; 00668 trx->conc_state = TRX_ACTIVE; 00669 trx->start_time = time(NULL); 00670 00671 return(TRUE); 00672 } 00673 00674 ut_ad(trx->conc_state != TRX_ACTIVE); 00675 00676 if (rseg_id == ULINT_UNDEFINED) { 00677 00678 rseg_id = trx_assign_rseg(); 00679 } 00680 00681 rseg = trx_sys_get_nth_rseg(trx_sys, rseg_id); 00682 00683 trx->id = trx_sys_get_new_trx_id(); 00684 00685 /* The initial value for trx->no: ut_dulint_max is used in 00686 read_view_open_now: */ 00687 00688 trx->no = ut_dulint_max; 00689 00690 trx->rseg = rseg; 00691 00692 trx->conc_state = TRX_ACTIVE; 00693 trx->start_time = time(NULL); 00694 00695 UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx); 00696 00697 return(TRUE); 00698 }
Here is the call graph for this function:

Here is the caller graph for this function:

| sess_t* trx_dummy_sess = NULL |
Definition at line 38 of file trx0trx.c.
Referenced by trx_allocate_for_background(), trx_allocate_for_mysql(), and trx_rollback_or_clean_all_without_sess().
Definition at line 42 of file trx0trx.c.
Referenced by logs_empty_and_mark_files_at_shutdown(), trx_allocate_for_mysql(), and trx_free_for_mysql().
1.4.7

