1 : /* Copyright (C) 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
2 :
3 : This program is free software; you can redistribute it and/or modify
4 : it under the terms of the GNU General Public License as published by
5 : the Free Software Foundation; version 2 of the License.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program; if not, write to the Free Software
14 : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15 :
16 : #include "maria_def.h"
17 : #include "trnman.h"
18 :
19 : /**
20 : writes a COMMIT record to log and commits transaction in memory
21 :
22 : @param trn transaction
23 :
24 : @return Operation status
25 : @retval 0 ok
26 : @retval 1 error (disk error or out of memory)
27 : */
28 :
29 : int ma_commit(TRN *trn)
30 687 : {
31 : int res;
32 : LSN commit_lsn;
33 : LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS];
34 687 : DBUG_ENTER("ma_commit");
35 :
36 687 : DBUG_ASSERT(trn->rec_lsn == LSN_IMPOSSIBLE);
37 687 : if (trn->undo_lsn == 0) /* no work done, rollback (cheaper than commit) */
38 104 : DBUG_RETURN(trnman_rollback_trn(trn));
39 : /*
40 : - if COMMIT record is written before trnman_commit_trn():
41 : if Checkpoint comes in the middle it will see trn is not committed,
42 : then if crash, Recovery might roll back trn (if min(rec_lsn) is after
43 : COMMIT record) and this is not an issue as
44 : * transaction's updates were not made visible to other transactions
45 : * "commit ok" was not sent to client
46 : Alternatively, Recovery might commit trn (if min(rec_lsn) is before COMMIT
47 : record), which is ok too. All in all it means that "trn committed" is not
48 : 100% equal to "COMMIT record written".
49 : - if COMMIT record is written after trnman_commit_trn():
50 : if crash happens between the two, trn will be rolled back which is an
51 : issue (transaction's updates were made visible to other transactions).
52 : So we need to go the first way.
53 :
54 : Note that we have to use | here to ensure that all calls are made.
55 : */
56 :
57 : /*
58 : We do not store "thd->transaction.xid_state.xid" for now, it will be
59 : needed only when we support XA.
60 : */
61 583 : res= (translog_write_record(&commit_lsn, LOGREC_COMMIT,
62 : trn, NULL, 0,
63 : sizeof(log_array)/sizeof(log_array[0]),
64 : log_array, NULL, NULL) |
65 : translog_flush(commit_lsn));
66 :
67 583 : DBUG_EXECUTE_IF("maria_sleep_in_commit",
68 : {
69 : DBUG_PRINT("info", ("maria_sleep_in_commit"));
70 : sleep(3);
71 : });
72 583 : res|= trnman_commit_trn(trn);
73 :
74 :
75 : /*
76 : Note: if trnman_commit_trn() fails above, we have already
77 : written the COMMIT record, so Checkpoint and Recovery will see the
78 : transaction as committed.
79 : */
80 583 : DBUG_RETURN(res);
81 : }
82 :
83 :
84 : /**
85 : Writes a COMMIT record for a transaciton associated with a file
86 :
87 : @param info Maria handler
88 :
89 : @return Operation status
90 : @retval 0 ok
91 : @retval # error (disk error or out of memory)
92 : */
93 :
94 : int maria_commit(MARIA_HA *info)
95 1190 : {
96 1190 : return info->s->now_transactional ? ma_commit(info->trn) : 0;
97 : }
98 :
99 :
100 : /**
101 : Starts a transaction on a file handle
102 :
103 : @param info Maria handler
104 :
105 : @return Operation status
106 : @retval 0 ok
107 : @retval # Error code.
108 :
109 : @note this can be used only in single-threaded programs (tests),
110 : because we create a transaction (trnman_new_trn) with WT_THD=0.
111 : XXX it needs to be fixed when we'll start using maria_begin from SQL.
112 : */
113 :
114 : int maria_begin(MARIA_HA *info)
115 1289 : {
116 1289 : DBUG_ENTER("maria_begin");
117 :
118 1289 : if (info->s->now_transactional)
119 : {
120 786 : TRN *trn= trnman_new_trn(0);
121 786 : if (unlikely(!trn))
122 0 : DBUG_RETURN(HA_ERR_OUT_OF_MEM);
123 :
124 786 : DBUG_PRINT("info", ("TRN set to 0x%lx", (ulong) trn));
125 786 : _ma_set_trn_for_table(info, trn);
126 : }
127 1289 : DBUG_RETURN(0);
128 : }
129 :
|