summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2005-03-13 12:49:39 +0200
committerunknown <heikki@hundin.mysql.fi>2005-03-13 12:49:39 +0200
commita569b08375672b561bd1d15a66fc1dafa69c72a5 (patch)
tree051259ff15bee8fda0011d7798a20f4f3471287a /innobase
parentdad8e1f59a30e6bdc45bf57d6b3404313d8b2b25 (diff)
downloadmariadb-git-a569b08375672b561bd1d15a66fc1dafa69c72a5.tar.gz
set_var.cc, mysqld.cc, ha_innodb.cc, sql_class.h:
Add a settable session variable innodb_support_xa; setting it to 0 can save up to 10 % of CPU time and 150 bytes of space in each undo log trx0trx.h, trx0undo.c, trx0trx.c, trx0roll.c: Enable XA if innodb_support_xa is not set to 0; make prepare to do log fsync's according to innodb_flush_log_at_trx_commit innobase/trx/trx0roll.c: Enable XA if innodb_support_xa is not set to 0; make prepare to do log fsync's according to innodb_flush_log_at_trx_commit innobase/trx/trx0trx.c: Enable XA if innodb_support_xa is not set to 0; make prepare to do log fsync's according to innodb_flush_log_at_trx_commit innobase/trx/trx0undo.c: Enable XA if innodb_support_xa is not set to 0; make prepare to do log fsync's according to innodb_flush_log_at_trx_commit innobase/include/trx0trx.h: Enable XA if innodb_support_xa is not set to 0; make prepare to do log fsync's according to innodb_flush_log_at_trx_commit sql/sql_class.h: Add a settable session variable innodb_support_xa; setting it to 0 can save up to 10 % of CPU time and 150 bytes of space in each undo log sql/ha_innodb.cc: Add a settable session variable innodb_support_xa; setting it to 0 can save up to 10 % of CPU time and 150 bytes of space in each undo log sql/mysqld.cc: Add a settable session variable innodb_support_xa; setting it to 0 can save up to 10 % of CPU time and 150 bytes of space in each undo log sql/set_var.cc: Add a settable session variable innodb_support_xa; setting it to 0 can save up to 10 % of CPU time and 150 bytes of space in each undo log
Diffstat (limited to 'innobase')
-rw-r--r--innobase/include/trx0trx.h5
-rw-r--r--innobase/trx/trx0roll.c14
-rw-r--r--innobase/trx/trx0trx.c104
-rw-r--r--innobase/trx/trx0undo.c31
4 files changed, 101 insertions, 53 deletions
diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h
index 61d372a824a..9db69261468 100644
--- a/innobase/include/trx0trx.h
+++ b/innobase/include/trx0trx.h
@@ -369,6 +369,11 @@ struct trx_struct{
XID xid; /* X/Open XA transaction
identification to identify a
transaction branch */
+ ibool support_xa; /* normally we do the XA two-phase
+ commit steps, but by setting this to
+ FALSE, one can save CPU time and about
+ 150 bytes in the undo log size as then
+ we skip XA steps */
dulint no; /* transaction serialization number ==
max trx id when the transaction is
moved to COMMITTED_IN_MEMORY state */
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 4c68e0a0dd3..69f7a99187f 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -441,16 +441,8 @@ loop:
trx = UT_LIST_GET_NEXT(trx_list, trx);
} else if (trx->conc_state == TRX_PREPARED) {
- /* Roll back all prepared transactions if
- innobase_force_recovery > 0 in my.cnf */
-
- if (srv_force_recovery > 0) {
- trx->conc_state = TRX_ACTIVE;
- break;
- } else {
- trx->sess = trx_dummy_sess;
- trx = UT_LIST_GET_NEXT(trx_list, trx);
- }
+ trx->sess = trx_dummy_sess;
+ trx = UT_LIST_GET_NEXT(trx_list, trx);
} else {
break;
}
@@ -461,7 +453,7 @@ loop:
if (trx == NULL) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Rollback of uncommitted transactions completed\n");
+ " InnoDB: Rollback of non-prepared transactions completed\n");
mem_heap_free(heap);
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index ad82560e26c..614058e6860 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -93,6 +93,8 @@ trx_create(
trx->id = ut_dulint_zero;
trx->no = ut_dulint_max;
+ trx->support_xa = TRUE;
+
trx->check_foreigns = TRUE;
trx->check_unique_secondary = TRUE;
@@ -453,9 +455,15 @@ trx_lists_init_at_db_start(void)
ut_dulint_get_high(trx->id),
ut_dulint_get_low(trx->id));
- trx->conc_state = TRX_ACTIVE;
+ if (srv_force_recovery == 0) {
- /* trx->conc_state = TRX_PREPARED;*/
+ trx->conc_state = TRX_PREPARED;
+ } else {
+ fprintf(stderr,
+"InnoDB: Since innodb_force_recovery > 0, we will rollback it anyway.\n");
+
+ trx->conc_state = TRX_ACTIVE;
+ }
} else {
trx->conc_state =
TRX_COMMITTED_IN_MEMORY;
@@ -511,15 +519,20 @@ trx_lists_init_at_db_start(void)
commit or abort decision from MySQL */
if (undo->state == TRX_UNDO_PREPARED) {
- fprintf(stderr,
+ fprintf(stderr,
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
- ut_dulint_get_high(trx->id),
- ut_dulint_get_low(trx->id));
+ ut_dulint_get_high(trx->id),
+ ut_dulint_get_low(trx->id));
- trx->conc_state = TRX_ACTIVE;
+ if (srv_force_recovery == 0) {
+
+ trx->conc_state = TRX_PREPARED;
+ } else {
+ fprintf(stderr,
+"InnoDB: Since innodb_force_recovery > 0, we will rollback it anyway.\n");
- /* trx->conc_state =
- TRX_PREPARED; */
+ trx->conc_state = TRX_ACTIVE;
+ }
} else {
trx->conc_state =
TRX_COMMITTED_IN_MEMORY;
@@ -823,9 +836,6 @@ trx_commit_off_kernel(
trx->read_view = NULL;
}
-/* fprintf(stderr, "Trx %lu commit finished\n",
- ut_dulint_get_low(trx->id)); */
-
if (must_flush_log) {
mutex_exit(&kernel_mutex);
@@ -869,14 +879,15 @@ trx_commit_off_kernel(
/* 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 */
+ /* Write the log but do not flush it to disk */
- log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
+ FALSE);
} else {
- /* Write the log to the log files AND flush
- them to disk */
+ /* Write the log to the log files AND flush
+ them to disk */
- log_write_up_to(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) {
@@ -1747,12 +1758,11 @@ Prepares a transaction. */
void
trx_prepare_off_kernel(
-/*==================*/
+/*===================*/
trx_t* trx) /* in: transaction */
{
page_t* update_hdr_page;
trx_rseg_t* rseg;
- trx_undo_t* undo;
ibool must_flush_log = FALSE;
dulint lsn;
mtr_t mtr;
@@ -1779,19 +1789,18 @@ trx_prepare_off_kernel(
mutex_enter(&(rseg->mutex));
if (trx->insert_undo != NULL) {
- trx_undo_set_state_at_prepare(trx, trx->insert_undo,
- &mtr);
- }
-
- undo = trx->update_undo;
- if (undo) {
/* It is not necessary to obtain trx->undo_mutex here
because only a single OS thread is allowed to do the
transaction prepare for this transaction. */
-
+
+ trx_undo_set_state_at_prepare(trx, trx->insert_undo,
+ &mtr);
+ }
+
+ if (trx->update_undo) {
update_hdr_page = trx_undo_set_state_at_prepare(trx,
- undo, &mtr);
+ trx->update_undo, &mtr);
}
mutex_exit(&(rseg->mutex));
@@ -1815,17 +1824,48 @@ trx_prepare_off_kernel(
/*--------------------------------------*/
if (must_flush_log) {
+ /* Depending on the my.cnf options, we may now write the log
+ buffer to the log files, making the prepared state of the
+ transaction durable if the OS does not crash. We may also
+ flush the log files to disk, making the prepared state of the
+ transaction durable also at an OS crash or a power outage.
+
+ The idea in InnoDB's group prepare 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 prepares the whole
+ group. Note that this group prepare 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.
+
+ TODO: find out if MySQL holds some mutex when calling this.
+ That would spoil our group prepare algorithm. */
mutex_exit(&kernel_mutex);
-
- /* Write the log to the log files AND flush them to disk */
- /*-------------------------------------*/
+ 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, TRUE);
+ 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_error;
+ }
- /*-------------------------------------*/
-
mutex_enter(&kernel_mutex);
}
}
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index 88185973dfc..bb314dd35e9 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -596,7 +596,7 @@ trx_undo_read_xid(
}
/*******************************************************************
-Adds the XA XID after an undo log old-style header. */
+Adds space for the XA XID after an undo log old-style header. */
static
void
trx_undo_header_add_space_for_xid(
@@ -1488,6 +1488,7 @@ trx_undo_create(
/*============*/
/* out: undo log object, NULL if did not
succeed: out of space */
+ trx_t* trx, /* in: transaction */
trx_rseg_t* rseg, /* in: rollback segment memory copy */
ulint type, /* in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
@@ -1530,7 +1531,10 @@ trx_undo_create(
offset = trx_undo_header_create(undo_page, trx_id, mtr);
- trx_undo_header_add_space_for_xid(undo_page, undo_page + offset, mtr);
+ if (trx->support_xa) {
+ trx_undo_header_add_space_for_xid(undo_page,
+ undo_page + offset, mtr);
+ }
undo = trx_undo_mem_create(rseg, id, type, trx_id, xid,
page_no, offset);
@@ -1547,6 +1551,7 @@ trx_undo_reuse_cached(
/*==================*/
/* out: the undo log memory object, NULL if
none cached */
+ trx_t* trx, /* in: transaction */
trx_rseg_t* rseg, /* in: rollback segment memory object */
ulint type, /* in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
@@ -1597,16 +1602,22 @@ trx_undo_reuse_cached(
if (type == TRX_UNDO_INSERT) {
offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
- trx_undo_header_add_space_for_xid(undo_page, undo_page + offset,
- mtr);
+
+ if (trx->support_xa) {
+ trx_undo_header_add_space_for_xid(undo_page,
+ undo_page + offset, mtr);
+ }
} else {
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_TYPE)
== TRX_UNDO_UPDATE);
offset = trx_undo_header_create(undo_page, trx_id, mtr);
- trx_undo_header_add_space_for_xid(undo_page, undo_page + offset,
- mtr);
+
+ if (trx->support_xa) {
+ trx_undo_header_add_space_for_xid(undo_page,
+ undo_page + offset, mtr);
+ }
}
trx_undo_mem_init_for_reuse(undo, trx_id, xid, offset);
@@ -1674,11 +1685,11 @@ trx_undo_assign_undo(
#endif /* UNIV_SYNC_DEBUG */
mutex_enter(&(rseg->mutex));
- undo = trx_undo_reuse_cached(rseg, type, trx->id, &trx->xid, &mtr);
-
+ undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, &trx->xid,
+ &mtr);
if (undo == NULL) {
- undo = trx_undo_create(rseg, type, trx->id, &trx->xid, &mtr);
-
+ undo = trx_undo_create(trx, rseg, type, trx->id, &trx->xid,
+ &mtr);
if (undo == NULL) {
/* Did not succeed */