summaryrefslogtreecommitdiff
path: root/sql/ha_innodb.cc
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-11-30 11:45:02 +0200
committerunknown <jan@hundin.mysql.fi>2004-11-30 11:45:02 +0200
commitdf0e057a52db9f085c42ec593f3000da4afdbbd7 (patch)
treecb2f2ad9f5ccc63eec024ffada123df6cf2e74ba /sql/ha_innodb.cc
parentf4110834a374dc647f2cba4d7bceaa88dc9d66e9 (diff)
downloadmariadb-git-df0e057a52db9f085c42ec593f3000da4afdbbd7.tar.gz
Added support for X/Open XA prepare, recover, commit and rollback.
innobase/include/trx0roll.h: Changed prototype of the function trx_rollback_or_clean_all_without_sess because this function is executed in a background thread. innobase/include/trx0trx.h: Added support for X/Open XA prepare, recover and search by X/Open XA XID. innobase/include/trx0undo.h: Added support for X/Open XA prepare and recover. We need to store X/Open XA XID to the undo log header for recovery. innobase/log/log0recv.c: Create a thread to run trx_rollback_or_clean_all_without_sess function to rollback the uncommitted transactions which have no user session. innobase/row/row0ins.c: Remove unnecessary variables. innobase/trx/trx0roll.c: Changed so that trx_rollback_or_clean_all_without_sess is executed in a background thread. We should also leave all prepared transactions active to wait for commit or abort from MySQL. innobase/trx/trx0sys.c: Only those rows which belong to the active transaction in crash recovery are undone. innobase/trx/trx0trx.c: Added support for X/Open XA prepare and recover. We need to store X/Open XA XID to trx structure and left prepared transactions to wait for a commit or abort from MySQL. This requires also that we add TRX_PREPARED state to the transaction and TRX_UNDO_PREPARED state for undo logs. innobase/trx/trx0undo.c: Added support for X/Open XA prepare and recover. We need to store X/Open XA XID to undo log header for recovery of distributed transactions. sql/ha_innodb.h: Added prototypes for X/Open XA prepare, recover, commit and rollback. sql/handler.h: Added definition for X/Open XA XID structure.
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r--sql/ha_innodb.cc199
1 files changed, 198 insertions, 1 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 650cb86e253..e3fddd1a137 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -80,6 +80,7 @@ extern "C" {
#include "../innobase/include/fsp0fsp.h"
#include "../innobase/include/sync0sync.h"
#include "../innobase/include/fil0fil.h"
+#include "../innobase/include/xa.h"
}
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
@@ -149,6 +150,15 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
+/*********************************************************************
+Commits a transaction in an InnoDB database. */
+
+void
+innobase_commit_low(
+/*================*/
+ trx_t* trx); /* in: transaction handle */
+
+
/* General functions */
/**********************************************************************
@@ -1254,7 +1264,7 @@ innobase_commit(
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle
|| (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
- /* We were instructed to commit the whole transaction, or
+ /* We were instructed to commit the whole transaction, or
this is an SQL statement end and autocommit is on */
innobase_commit_low(trx);
@@ -1396,6 +1406,39 @@ innobase_rollback(
}
/*********************************************************************
+Rolls back a transaction */
+
+int
+innobase_rollback_trx(
+/*==================*/
+ /* out: 0 or error number */
+ trx_t* trx) /* in: transaction */
+{
+ int error = 0;
+
+ DBUG_ENTER("innobase_rollback_trx");
+ DBUG_PRINT("trans", ("aborting transaction"));
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ if (trx->auto_inc_lock) {
+ /* If we had reserved the auto-inc lock for some table (if
+ we come here to roll back the latest SQL statement) we
+ release it now before a possibly lengthy rollback */
+
+ row_unlock_table_autoinc_for_mysql(trx);
+ }
+
+ error = trx_rollback_for_mysql(trx);
+
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
+}
+
+/*********************************************************************
Rolls back a transaction to a savepoint. */
int
@@ -5666,4 +5709,158 @@ innobase_query_is_replace(void)
}
}
+/***********************************************************************
+This function is used to prepare X/Open XA distributed transaction */
+
+int innobase_xa_prepare(
+/*====================*/
+ /* out: 0 or error number */
+ THD* thd, /* in: handle to the MySQL thread of the user
+ whose XA transaction should be prepared */
+ bool all) /* in: TRUE - commit transaction
+ FALSE - the current SQL statement ended */
+{
+ int error = 0;
+ trx_t* trx;
+
+ trx = check_trx_exists(thd);
+
+ /* TODO: Get X/Open XA Transaction Identification from MySQL*/
+ memset(&trx->xid, 0, sizeof(trx->xid));
+ trx->xid.formatID = -1;
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
+
+ fprintf(stderr,
+"InnoDB: Error: thd->transaction.all.innodb_active_trans == 0\n"
+"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
+ }
+
+ if (all || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+
+ /* We were instructed to prepare the whole transaction, or
+ this is an SQL statement end and autocommit is on */
+
+ error = trx_prepare_for_mysql(trx);
+ } else {
+ /* We just mark the SQL statement ended and do not do a
+ transaction prepare */
+
+ if (trx->auto_inc_lock) {
+ /* If we had reserved the auto-inc lock for some
+ table in this SQL statement we release it now */
+
+ row_unlock_table_autoinc_for_mysql(trx);
+ }
+ /* 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);
+ }
+
+ /* Tell the InnoDB server that there might be work for utility
+ threads: */
+
+ srv_active_wake_master_thread();
+
+ return error;
+}
+
+/***********************************************************************
+This function is used to recover X/Open XA distributed transactions */
+
+int innobase_xa_recover(
+ /* out: number of prepared transactions
+ stored in xid_list */
+ XID* xid_list, /* in/out: prepared transactions */
+ uint len) /* in: number of slots in xid_list */
+/*====================*/
+{
+ if (len == 0 || xid_list == NULL) {
+ return 0;
+ }
+
+ return (trx_recover_for_mysql(xid_list, len));
+}
+
+/***********************************************************************
+This function is used to commit one X/Open XA distributed transaction
+which is in the prepared state */
+
+int innobase_commit_by_xid(
+/*=======================*/
+ /* out: 0 or error number */
+ XID* xid) /* in: X/Open XA Transaction Identification */
+{
+ trx_t* trx;
+
+ trx = trx_get_trx_by_xid(xid);
+
+ if (trx) {
+ innobase_commit_low(trx);
+
+ return(XA_OK);
+ } else {
+ return(XAER_NOTA);
+ }
+}
+
+/***********************************************************************
+This function is used to rollback one X/Open XA distributed transaction
+which is in the prepared state */
+
+int innobase_rollback_by_xid(
+ /* out: 0 or error number */
+ XID *xid) /* in : X/Open XA Transaction Idenfification */
+{
+ trx_t* trx;
+
+ trx = trx_get_trx_by_xid(xid);
+
+ if (trx) {
+ return(innobase_rollback_trx(trx));
+ } else {
+ return(XAER_NOTA);
+ }
+}
+
+/***********************************************************************
+This function is used to test commit/rollback of XA transactions */
+
+int innobase_xa_end(
+/*================*/
+ THD* thd) /* in: MySQL thread handle of the user for whom
+ transactions should be recovered */
+{
+ DBUG_ENTER("innobase_xa_end");
+
+ XID trx_list[100];
+ int trx_num, trx_num_max = 100;
+ int i;
+ XID xid;
+
+ while(trx_num = innobase_xa_recover(trx_list, trx_num_max)) {
+
+ for(i=0;i < trx_num; i++) {
+ xid = trx_list[i];
+
+ if ( i % 2) {
+ innobase_commit_by_xid(&xid);
+ } else {
+ innobase_rollback_by_xid(&xid);
+ }
+ }
+ }
+
+ free(trx_list);
+
+ DBUG_RETURN(0);
+}
#endif /* HAVE_INNOBASE_DB */