summaryrefslogtreecommitdiff
path: root/innobase/trx
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-08-11 22:44:43 +0300
committerunknown <monty@mashka.mysql.fi>2003-08-11 22:44:43 +0300
commit034b44cb9ff914ceb6d32706a3a284eda00891b3 (patch)
tree3c0ddcb446b8be099c3ab2616c459a573ee3cf92 /innobase/trx
parentf4646c0d063fb541f48dd2824ecccea464a9958d (diff)
parent6db21de014d603477952c7a16449bcae40a70e5c (diff)
downloadmariadb-git-034b44cb9ff914ceb6d32706a3a284eda00891b3.tar.gz
Merge with 4.0.14
BitKeeper/etc/logging_ok: auto-union scripts/make_win_src_distribution.old: Merge rename: scripts/make_win_src_distribution.sh -> scripts/make_win_src_distribution.old BUILD/compile-pentium-debug-max: Auto merged BitKeeper/deleted/.del-sel000001.result~383913ae4505ec86: Auto merged BitKeeper/deleted/.del-sel000001.test~9567c1646058cc: Auto merged Build-tools/Bootstrap: Auto merged Build-tools/Do-compile: Auto merged Docs/Makefile.am: Auto merged client/get_password.c: Auto merged client/mysql.cc: Auto merged client/mysqltest.c: Auto merged extra/perror.c: Auto merged include/config-win.h: Auto merged include/my_sys.h: Auto merged innobase/btr/btr0cur.c: Auto merged innobase/btr/btr0pcur.c: Auto merged innobase/buf/buf0buf.c: Auto merged innobase/buf/buf0flu.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/dict/dict0load.c: Auto merged innobase/include/buf0buf.h: Auto merged innobase/include/log0recv.h: Auto merged innobase/include/row0sel.h: Auto merged innobase/include/srv0srv.h: Auto merged innobase/include/ut0mem.h: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/log/log0log.c: Auto merged innobase/mem/mem0pool.c: Auto merged innobase/os/os0file.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/trx/trx0sys.c: Auto merged innobase/trx/trx0trx.c: Auto merged innobase/ut/ut0mem.c: Auto merged innobase/ut/ut0ut.c: Auto merged myisam/ft_boolean_search.c: Auto merged myisam/mi_check.c: Auto merged myisam/mi_extra.c: Auto merged myisam/mi_key.c: Auto merged myisam/myisamdef.h: Auto merged myisammrg/myrg_queue.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/ctype_latin1_de.result: Auto merged mysql-test/r/flush.result: Auto merged mysql-test/r/func_time.result: Auto merged mysql-test/r/grant_cache.result: Auto merged mysql-test/r/join.result: Auto merged mysql-test/r/join_outer.result: Auto merged mysql-test/r/range.result: Auto merged mysql-test/r/rpl000018.result: Auto merged mysql-test/r/rpl_insert_id.result: Auto merged mysql-test/r/rpl_master_pos_wait.result: Auto merged mysql-test/r/rpl_relayspace.result: Auto merged mysql-test/r/select_safe.result: Auto merged mysql-test/r/symlink.result: Auto merged mysql-test/r/type_date.result: Auto merged mysql-test/r/type_datetime.result: Auto merged mysql-test/t/alias.test: Auto merged mysql-test/t/ctype_latin1_de.test: Auto merged mysql-test/t/fulltext_left_join.test: Auto merged mysql-test/t/func_time.test: Auto merged mysql-test/t/handler.test: Auto merged mysql-test/t/heap.test: Auto merged mysql-test/t/join.test: Auto merged mysql-test/t/join_outer.test: Auto merged mysql-test/t/order_by.test: Auto merged mysql-test/t/range.test: Auto merged mysql-test/t/rpl000001.test: Auto merged mysql-test/t/rpl000018.test: Auto merged mysql-test/t/rpl_insert_id.test: Auto merged mysql-test/t/sel000100.test: Auto merged mysql-test/t/select_safe.test: Auto merged mysql-test/t/type_date.test: Auto merged mysql-test/t/type_datetime.test: Auto merged mysql-test/t/user_var.test: Auto merged mysys/default.c: Auto merged mysys/mf_format.c: Auto merged mysys/my_getopt.c: Auto merged mysys/thr_lock.c: Auto merged mysys/tree.c: Auto merged scripts/Makefile.am: Auto merged scripts/mysql_install_db.sh: Auto merged scripts/mysqld_safe.sh: Auto merged sql/Makefile.am: Auto merged sql/field_conv.cc: Auto merged sql/ha_innodb.h: Auto merged sql/ha_myisam.cc: Auto merged sql/ha_myisammrg.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item.h: Auto merged sql/item_func.cc: Auto merged sql/item_timefunc.cc: Auto merged sql/net_serv.cc: Auto merged sql/nt_servc.cc: Auto merged sql/opt_range.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.h: Auto merged sql/sql_db.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_list.h: Auto merged sql/sql_load.cc: Auto merged sql/sql_rename.cc: Auto merged sql/sql_repl.h: Auto merged sql/sql_update.cc: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged sql/uniques.cc: Auto merged support-files/mysql.spec.sh: Auto merged vio/viosocket.c: Auto merged BitKeeper/deleted/.del-ctype-latin1_de.c~c5d8f9208bceb98e: merge BitKeeper/deleted/.del-mini_client.cc~8677895ec8169183: merge acinclude.m4: Merge with 4.0 (openssl patch) client/mysqlbinlog.cc: Merge with 4.0 in which we had added code from 4.1 (We are basicly only using the 4.1 code here) configure.in: Keep 4.1 file heap/hp_open.c: merge with 4.0 include/my_base.h: merge with 4.0 include/my_global.h: merge with 4.0 include/mysqld_error.h: merge with 4.0 innobase/ha/ha0ha.c: merge with 4.0 (Code should be same but we use indentaion from 4.0) innobase/log/log0recv.c: merge with 4.0 libmysql/libmysql.c: Remove with 4.0 code that was ported from 4.1 libmysqld/lib_sql.cc: merge with 4.0 myisam/mi_open.c: Remove 4.0 specific code myisam/myisamchk.c: merge with 4.0 myisammrg/myrg_rkey.c: merge with 4.0 mysql-test/r/alter_table.result: May need to be fixed after merge mysql-test/r/create.result: May need to be fixed after merge mysql-test/r/distinct.result: May need to be fixed after merge mysql-test/r/drop.result: May need to be fixed after merge mysql-test/r/fulltext.result: May need to be fixed after merge mysql-test/r/func_set.result: May need to be fixed after merge mysql-test/r/func_str.result: May need to be fixed after merge mysql-test/r/func_test.result: May need to be fixed after merge mysql-test/r/grant.result: May need to be fixed after merge mysql-test/r/group_by.result: May need to be fixed after merge mysql-test/r/handler.result: May need to be fixed after merge mysql-test/r/heap.result: May need to be fixed after merge mysql-test/r/innodb.result: May need to be fixed after merge mysql-test/r/insert.result: May need to be fixed after merge mysql-test/r/insert_select.result: May need to be fixed after merge mysql-test/r/key_diff.result: May need to be fixed after merge mysql-test/r/merge.result: May need to be fixed after merge mysql-test/r/myisam.result: May need to be fixed after merge mysql-test/r/order_by.result: May need to be fixed after merge mysql-test/r/query_cache.result: May need to be fixed after merge mysql-test/r/rpl_flush_log_loop.result: May need to be fixed after merge mysql-test/r/rpl_loaddata.result: May need to be fixed after merge mysql-test/r/rpl_log.result: May need to be fixed after merge mysql-test/r/rpl_log_pos.result: May need to be fixed after merge mysql-test/r/rpl_rotate_logs.result: May need to be fixed after merge mysql-test/r/select.result: May need to be fixed after merge mysql-test/r/union.result: May need to be fixed after merge mysql-test/r/user_var.result: May need to be fixed after merge mysql-test/t/alter_table.test: merge with 4.0 mysql-test/t/create.test: merge with 4.0 mysql-test/t/distinct.test: merge with 4.0 mysql-test/t/drop.test: merge with 4.0 mysql-test/t/flush.test: merge with 4.0 mysql-test/t/fulltext.test: merge with 4.0 mysql-test/t/func_set.test: merge with 4.0 mysql-test/t/func_str.test: merge with 4.0 mysql-test/t/func_test.test: merge with 4.0 mysql-test/t/grant.test: merge with 4.0 mysql-test/t/grant_cache.test: merge with 4.0 mysql-test/t/innodb.test: Add back EXPLAIN and SHOW KEYS statements, but make them independent of number of rows returned by InnoDB mysql-test/t/insert.test: merge with 4.0 mysql-test/t/insert_select.test: merge with 4.0 mysql-test/t/merge.test: merge with 4.0 mysql-test/t/query_cache.test: merge with 4.0 mysql-test/t/rpl_flush_log_loop.test: merge with 4.0 mysql-test/t/rpl_loaddata.test: merge with 4.0 mysql-test/t/rpl_rotate_logs.test: merge with 4.0 mysql-test/t/select.test: merge with 4.0 mysql-test/t/symlink.test: merge with 4.0 mysql-test/t/union.test: merge with 4.0 mysys/charset.c: merge with 4.0 scripts/mysql_fix_privilege_tables.sh: merge with 4.0 (Add quoting for some variables) sql/field.h: merge with 4.0 sql/ha_innodb.cc: merge with 4.0 sql/item_cmpfunc.cc: merge with 4.0 sql/item_cmpfunc.h: merge with 4.0 sql/item_func.h: merge with 4.0 sql/item_strfunc.cc: merge with 4.0 Fixed null handling with ELT() sql/item_timefunc.h: merge with 4.0 sql/lex.h: merge with 4.0 sql/log.cc: merge with 4.0 sql/log_event.cc: Merge with 4.0 Cleanups: - Indentation - #endif comments - Replace strmov() with *pos++= for two byte strings - Moved variable declarations to start of functions - Merged identical code (LOAD_EVENT) - Added casts when subtracting pointers Did a full diff between this and 4.0 to ensure that the file is correct after merge. sql/log_event.h: merge with 4.0 sql/mysql_priv.h: merge with 4.0 sql/mysqld.cc: merge with 4.0 sql/repl_failsafe.cc: merge with 4.0 sql/set_var.cc: merge with 4.0 sql/set_var.h: merge with 4.0 sql/share/czech/errmsg.txt: merge with 4.0 sql/share/danish/errmsg.txt: merge with 4.0 sql/share/dutch/errmsg.txt: merge with 4.0 sql/share/english/errmsg.txt: merge with 4.0 sql/share/estonian/errmsg.txt: merge with 4.0 sql/share/french/errmsg.txt: merge with 4.0 sql/share/german/errmsg.txt: merge with 4.0 sql/share/greek/errmsg.txt: merge with 4.0 sql/share/hungarian/errmsg.txt: merge with 4.0 sql/share/italian/errmsg.txt: merge with 4.0 sql/share/japanese/errmsg.txt: merge with 4.0 sql/share/korean/errmsg.txt: merge with 4.0 sql/share/norwegian-ny/errmsg.txt: merge with 4.0 sql/share/norwegian/errmsg.txt: merge with 4.0 sql/share/polish/errmsg.txt: merge with 4.0 sql/share/portuguese/errmsg.txt: merge with 4.0 sql/share/romanian/errmsg.txt: merge with 4.0 sql/share/russian/errmsg.txt: merge with 4.0 sql/share/slovak/errmsg.txt: merge with 4.0 sql/share/spanish/errmsg.txt: merge with 4.0 sql/share/swedish/errmsg.txt: merge with 4.0 sql/share/ukrainian/errmsg.txt: merge with 4.0 sql/slave.cc: Merge + some indentation fixes sql/slave.h: merge with 4.0 sql/sql_acl.cc: merge with 4.0 Some end space removal to make it easier to do future merges sql/sql_acl.h: merge with 4.0 sql/sql_cache.cc: merge with 4.0 sql/sql_class.h: merge with 4.0 sql/sql_handler.cc: merge with 4.0 sql/sql_lex.cc: merge with 4.0 sql/sql_lex.h: merge with 4.0 sql/sql_parse.cc: merge with 4.0 sql/sql_repl.cc: merge with 4.0 sql/sql_select.cc: merge with 4.0 sql/sql_table.cc: merge with 4.0 sql/sql_union.cc: Merge with 4.0 Note that I couldn't find out how to merge OPTION_FOUND_ROWS handling so this has to be fixed later sql/sql_yacc.yy: merge with 4.0 Removed end space to make merge easier vio/Makefile.am: merge with 4.0
Diffstat (limited to 'innobase/trx')
-rw-r--r--innobase/trx/trx0purge.c13
-rw-r--r--innobase/trx/trx0rec.c24
-rw-r--r--innobase/trx/trx0roll.c222
-rw-r--r--innobase/trx/trx0sys.c2
-rw-r--r--innobase/trx/trx0trx.c118
5 files changed, 290 insertions, 89 deletions
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c
index d58240d3c11..fa9c287b0ad 100644
--- a/innobase/trx/trx0purge.c
+++ b/innobase/trx/trx0purge.c
@@ -593,7 +593,7 @@ trx_purge_rseg_get_next_history_log(
mutex_enter(&(rseg->mutex));
- ut_ad(rseg->last_page_no != FIL_NULL);
+ ut_a(rseg->last_page_no != FIL_NULL);
purge_sys->purge_trx_no = ut_dulint_add(rseg->last_trx_no, 1);
purge_sys->purge_undo_no = ut_dulint_zero;
@@ -606,16 +606,9 @@ trx_purge_rseg_get_next_history_log(
log_hdr = undo_page + rseg->last_offset;
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
- if ((mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG) == 0)
- && (mach_read_from_2(seg_hdr + TRX_UNDO_STATE)
- == TRX_UNDO_TO_PURGE)) {
-
- /* This is the last log header on this page and the log
- segment cannot be reused: we may increment the number of
- pages handled */
+ /* Increase the purge page count by one for every handled log */
- purge_sys->n_pages_handled++;
- }
+ purge_sys->n_pages_handled++;
prev_log_addr = trx_purge_get_log_from_hist(
flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE,
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index 05e179e06a5..9453189d598 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -272,8 +272,8 @@ trx_undo_page_report_insert(
mach_write_to_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
ptr - undo_page);
- /* Write the log entry to the REDO log of this change in the UNDO log */
-
+ /* Write the log entry to the REDO log of this change in the UNDO
+ log */
trx_undof_page_add_undo_rec_log(undo_page, first_free,
ptr - undo_page, mtr);
return(first_free);
@@ -492,7 +492,8 @@ trx_undo_page_report_modify(
/* Reserve 2 bytes for the pointer to the next undo log record */
ptr += 2;
- /* Store first some general parameters to the undo log */
+ /* Store first some general parameters to the undo log */
+
if (update) {
if (rec_get_deleted_flag(rec)) {
type_cmpl = TRX_UNDO_UPD_DEL_REC;
@@ -526,8 +527,7 @@ trx_undo_page_report_modify(
/* Store the values of the system columns */
trx_id = dict_index_rec_get_sys_col(index, DATA_TRX_ID, rec);
- roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec);
-
+ roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec);
len = mach_dulint_write_compressed(ptr, trx_id);
ptr += len;
@@ -632,7 +632,11 @@ trx_undo_page_report_modify(
columns which occur as ordering fields in any index. This info is used
in the purge of old versions where we use it to build and search the
delete marked index records, to look if we can remove them from the
- index tree. */
+ index tree. Note that starting from 4.0.14 also externally stored
+ fields can be ordering in some index. But we always store at least
+ 384 first bytes locally to the clustered index record, which means
+ we can construct the column prefix fields in the index from the
+ stored data. */
if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
@@ -1408,11 +1412,11 @@ trx_undo_prev_version_build(
return(DB_ERROR);
}
- if (row_upd_changes_field_size(rec, index, update)) {
-
- entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
+ if (row_upd_changes_field_size_or_external(rec, index, update)) {
- row_upd_clust_index_replace_new_col_vals(entry, update);
+ entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec,
+ heap);
+ row_upd_index_replace_new_col_vals(entry, index, update, heap);
buf = mem_heap_alloc(heap, rec_get_converted_size(entry));
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index a9f8c5ad22c..7d1b341221c 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -52,6 +52,11 @@ trx_general_rollback_for_mysql(
que_thr_t* thr;
roll_node_t* roll_node;
+ /* Tell Innobase server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
trx_start_if_not_started(trx);
heap = mem_heap_create(512);
@@ -89,6 +94,11 @@ trx_general_rollback_for_mysql(
ut_a(trx->error_state == DB_SUCCESS);
+ /* Tell Innobase server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
return((int) trx->error_state);
}
@@ -110,20 +120,8 @@ trx_rollback_for_mysql(
trx->op_info = (char *) "rollback";
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
- trx_mark_sql_stat_end(trx);
-
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
trx->op_info = (char *) "";
return(err);
@@ -147,26 +145,192 @@ trx_rollback_last_sql_stat_for_mysql(
trx->op_info = (char *) "rollback of SQL statement";
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
err = trx_general_rollback_for_mysql(trx, TRUE,
&(trx->last_sql_stat_start));
+ /* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
- /* Tell Innobase server that there might be work for
- utility threads: */
+ trx->op_info = (char *) "";
+
+ return(err);
+}
- srv_active_wake_master_thread();
+/***********************************************************************
+Frees savepoint structs. */
- trx->op_info = (char *) "";
+void
+trx_roll_savepoints_free(
+/*=====================*/
+ trx_t* trx, /* in: transaction handle */
+ trx_named_savept_t* savep) /* in: free all savepoints > this one;
+ if this is NULL, free all savepoints
+ of trx */
+{
+ trx_named_savept_t* next_savep;
+
+ if (savep == NULL) {
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+ } else {
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+ while (savep != NULL) {
+ next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+
+ UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
+ mem_free(savep->name);
+ mem_free(savep);
+
+ savep = next_savep;
+ }
+}
+
+/***********************************************************************
+Rolls back a transaction back to a named savepoint. Modifications after the
+savepoint are undone but InnoDB does NOT release the corresponding locks
+which are stored in memory. If a lock is 'implicit', that is, a new inserted
+row holds a lock where the lock information is carried by the trx id stored in
+the row, these locks are naturally released in the rollback. Savepoints which
+were set after this savepoint are deleted. */
+
+ulint
+trx_rollback_to_savepoint_for_mysql(
+/*================================*/
+ /* out: if no savepoint
+ of the name found then
+ DB_NO_SAVEPOINT,
+ otherwise DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong* mysql_binlog_cache_pos) /* out: the MySQL binlog cache
+ position corresponding to this
+ savepoint; MySQL needs this
+ information to remove the
+ binlog entries of the queries
+ executed after the savepoint */
+{
+ trx_named_savept_t* savep;
+ ulint err;
+
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+
+ while (savep != NULL) {
+ if (0 == ut_strcmp(savep->name, savepoint_name)) {
+ /* Found */
+ break;
+ }
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+
+ if (savep == NULL) {
+
+ return(DB_NO_SAVEPOINT);
+ }
+
+ if (trx->conc_state == TRX_NOT_STARTED) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: transaction has a savepoint %s though it is not started\n",
+ savep->name);
+ return(DB_ERROR);
+ }
+
+ /* We can now free all savepoints strictly later than this one */
+
+ trx_roll_savepoints_free(trx, savep);
+
+ *mysql_binlog_cache_pos = savep->mysql_binlog_cache_pos;
+
+ trx->op_info = (char *) "rollback to a savepoint";
+
+ err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+
+ /* Store the current undo_no of the transaction so that we know where
+ to roll back if we have to roll back the next SQL statement: */
+
+ trx_mark_sql_stat_end(trx);
+
+ trx->op_info = (char *) "";
+
return(err);
}
/***********************************************************************
+Creates a named savepoint. If the transaction is not yet started, starts it.
+If there is already a savepoint of the same name, this call erases that old
+savepoint and replaces it with a new. Savepoints are deleted in a transaction
+commit or rollback. */
+
+ulint
+trx_savepoint_for_mysql(
+/*====================*/
+ /* out: always DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong binlog_cache_pos) /* in: MySQL binlog cache
+ position corresponding to this
+ connection at the time of the
+ savepoint */
+{
+ trx_named_savept_t* savep;
+
+ ut_a(trx);
+ ut_a(savepoint_name);
+
+ trx_start_if_not_started(trx);
+
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+
+ while (savep != NULL) {
+ if (0 == ut_strcmp(savep->name, savepoint_name)) {
+ /* Found */
+ break;
+ }
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+
+ if (savep) {
+ /* There is a savepoint with the same name: free that */
+
+ UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
+
+ mem_free(savep->name);
+ mem_free(savep);
+ }
+
+ /* Create a new savepoint and add it as the last in the list */
+
+ savep = mem_alloc(sizeof(trx_named_savept_t));
+
+ savep->name = mem_alloc(1 + ut_strlen(savepoint_name));
+ ut_memcpy(savep->name, savepoint_name, 1 + ut_strlen(savepoint_name));
+
+ savep->savept = trx_savept_take(trx);
+
+ savep->mysql_binlog_cache_pos = binlog_cache_pos;
+
+ UT_LIST_ADD_LAST(trx_savepoints, trx->trx_savepoints, savep);
+
+ return(DB_SUCCESS);
+}
+
+/***********************************************************************
+Returns a transaction savepoint taken at this point in time. */
+
+trx_savept_t
+trx_savept_take(
+/*============*/
+ /* out: savepoint */
+ trx_t* trx) /* in: transaction */
+{
+ trx_savept_t savept;
+
+ savept.least_undo_no = trx->undo_no;
+
+ return(savept);
+}
+
+/***********************************************************************
Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. */
@@ -325,22 +489,6 @@ loop:
goto loop;
}
-
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
-
-trx_savept_t
-trx_savept_take(
-/*============*/
- /* out: savepoint */
- trx_t* trx) /* in: transaction */
-{
- trx_savept_t savept;
-
- savept.least_undo_no = trx->undo_no;
-
- return(savept);
-}
/***********************************************************************
Creates an undo number array. */
diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c
index b9e4a9fea4b..0c0dbab708c 100644
--- a/innobase/trx/trx0sys.c
+++ b/innobase/trx/trx0sys.c
@@ -321,8 +321,8 @@ trx_sys_doublewrite_restore_corrupt_pages(void)
for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) {
- space_id = mach_read_from_4(page + FIL_PAGE_SPACE);
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
+ space_id = 0;
if (!fil_check_adress_in_tablespace(space_id, page_no)) {
fprintf(stderr,
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 5753b5b338e..1ece349ec6c 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -86,6 +86,10 @@ trx_create(
trx->start_time = time(NULL);
trx->isolation_level = TRX_ISO_REPEATABLE_READ;
+
+ trx->id = ut_dulint_zero;
+ trx->no = ut_dulint_max;
+
trx->check_foreigns = TRUE;
trx->check_unique_secondary = TRUE;
@@ -135,6 +139,8 @@ trx_create(
trx->lock_heap = mem_heap_create_in_buffer(256);
UT_LIST_INIT(trx->trx_locks);
+ UT_LIST_INIT(trx->trx_savepoints);
+
trx->dict_operation_lock_mode = 0;
trx->has_search_latch = FALSE;
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
@@ -776,29 +782,53 @@ trx_commit_off_kernel(
efficient here: call os_thread_yield here to allow also other
trxs to come to commit! */
- /* We now flush the log, as the transaction made changes to
- the database, making the transaction committed on disk. It is
- enough that any one of the log groups gets written to disk. */
-
/*-------------------------------------*/
- /* Most MySQL users run with srv_flush_.. set to 0: */
-
- if (srv_flush_log_at_trx_commit != 0) {
- if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC
- && srv_flush_log_at_trx_commit != 2
- && !trx->flush_log_later) {
-
- /* Write the log to the log files AND flush
- them to disk */
-
- log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
- } else {
- /* Write the log but do not flush it to disk */
-
- log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
- }
- }
+ /* Depending on the my.cnf options, we may now write the log
+ buffer to the log files, making the transaction durable if
+ the OS does not crash. We may also flush the log files to
+ disk, making the transaction durable also at an OS crash or a
+ power outage.
+
+ The idea in InnoDB's group commit is that a group of
+ transactions gather behind a trx doing a physical disk write
+ to log files, and when that physical write has been completed,
+ one of those transactions does a write which commits the whole
+ group. Note that this group commit will only bring benefit if
+ there are > 2 users in the database. Then at least 2 users can
+ gather behind one doing the physical log write to disk.
+
+ If we are calling trx_commit() under MySQL's binlog mutex, we
+ will delay possible log write and flush to a separate function
+ trx_commit_complete_for_mysql(), which is only called when the
+ thread has released the binlog mutex. This is to make the
+ group commit algorithm to work. Otherwise, the MySQL binlog
+ mutex would serialize all commits and prevent a group of
+ transactions from gathering. */
+
+ if (trx->flush_log_later) {
+ /* Do nothing yet */
+ } else if (srv_flush_log_at_trx_commit == 0) {
+ /* Do nothing */
+ } else if (srv_flush_log_at_trx_commit == 1) {
+ if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ /* Write the log to the log files AND flush
+ them to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
+ }
+ } else if (srv_flush_log_at_trx_commit == 2) {
+
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ ut_a(0);
+ }
trx->commit_lsn = lsn;
@@ -807,6 +837,9 @@ trx_commit_off_kernel(
mutex_enter(&kernel_mutex);
}
+ /* Free savepoints */
+ trx_roll_savepoints_free(trx, NULL);
+
trx->conc_state = TRX_NOT_STARTED;
trx->rseg = NULL;
trx->undo_no = ut_dulint_zero;
@@ -1492,21 +1525,37 @@ trx_commit_complete_for_mysql(
/* out: 0 or error number */
trx_t* trx) /* in: trx handle */
{
- ut_a(trx);
+ dulint lsn = trx->commit_lsn;
+
+ ut_a(trx);
+
+ trx->op_info = (char*)"flushing log";
- if (srv_flush_log_at_trx_commit == 1
- && srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
-
- trx->op_info = (char *) "flushing log";
+ if (srv_flush_log_at_trx_commit == 0) {
+ /* Do nothing */
+ } else if (srv_flush_log_at_trx_commit == 1) {
+ if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
+ /* Write the log but do not flush it to disk */
- /* Flush the log files to disk */
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ /* Write the log to the log files AND flush them to
+ disk */
- log_write_up_to(trx->commit_lsn, LOG_WAIT_ONE_GROUP, TRUE);
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
+ }
+ } else if (srv_flush_log_at_trx_commit == 2) {
- trx->op_info = (char *) "";
- }
+ /* Write the log but do not flush it to disk */
- return(0);
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ ut_a(0);
+ }
+
+ trx->op_info = (char*)"";
+
+ return(0);
}
/**************************************************************************
@@ -1575,6 +1624,13 @@ trx_print(
}
buf += sprintf(buf, "\n");
+
+ if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) {
+
+ buf += sprintf(buf, "mysql tables in use %lu, locked %lu\n",
+ trx->n_mysql_tables_in_use,
+ trx->mysql_n_tables_locked);
+ }
start_of_line = buf;