~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/maria/ma_commit.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2007 MySQL AB
 
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
   @brief 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
{
 
31
  int res;
 
32
  LSN commit_lsn;
 
33
  LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS];
 
34
  DBUG_ENTER("ma_commit");
 
35
 
 
36
  if (trn->undo_lsn == 0) /* no work done, rollback (cheaper than commit) */
 
37
    DBUG_RETURN(trnman_rollback_trn(trn));
 
38
  /*
 
39
    - if COMMIT record is written before trnman_commit_trn():
 
40
    if Checkpoint comes in the middle it will see trn is not committed,
 
41
    then if crash, Recovery might roll back trn (if min(rec_lsn) is after
 
42
    COMMIT record) and this is not an issue as
 
43
    * transaction's updates were not made visible to other transactions
 
44
    * "commit ok" was not sent to client
 
45
    Alternatively, Recovery might commit trn (if min(rec_lsn) is before COMMIT
 
46
    record), which is ok too. All in all it means that "trn committed" is not
 
47
    100% equal to "COMMIT record written".
 
48
    - if COMMIT record is written after trnman_commit_trn():
 
49
    if crash happens between the two, trn will be rolled back which is an
 
50
    issue (transaction's updates were made visible to other transactions).
 
51
    So we need to go the first way.
 
52
 
 
53
    Note that we have to use | here to ensure that all calls are made.
 
54
  */
 
55
 
 
56
  /*
 
57
    We do not store "thd->transaction.xid_state.xid" for now, it will be
 
58
    needed only when we support XA.
 
59
  */
 
60
  res= (translog_write_record(&commit_lsn, LOGREC_COMMIT,
 
61
                             trn, NULL, 0,
 
62
                             sizeof(log_array)/sizeof(log_array[0]),
 
63
                             log_array, NULL, NULL) |
 
64
        translog_flush(commit_lsn) |
 
65
        trnman_commit_trn(trn));
 
66
 
 
67
 
 
68
  /*
 
69
    Note: if trnman_commit_trn() fails above, we have already
 
70
    written the COMMIT record, so Checkpoint and Recovery will see the
 
71
    transaction as committed.
 
72
  */
 
73
  DBUG_RETURN(res);
 
74
}
 
75
 
 
76
 
 
77
/**
 
78
   @brief Writes a COMMIT record for a transaciton associated with a file
 
79
 
 
80
   @param  info              Maria handler
 
81
 
 
82
   @return Operation status
 
83
     @retval 0      ok
 
84
     @retval #      error (disk error or out of memory)
 
85
*/
 
86
 
 
87
int maria_commit(MARIA_HA *info)
 
88
{
 
89
  return info->s->now_transactional ? ma_commit(info->trn) : 0;
 
90
}
 
91
 
 
92
 
 
93
/**
 
94
   @brief Starts a transaction on a file handle
 
95
 
 
96
   @param  info              Maria handler
 
97
 
 
98
   @return Operation status
 
99
     @retval 0      ok
 
100
     @retval #      Error code.
 
101
*/
 
102
 
 
103
int maria_begin(MARIA_HA *info)
 
104
{
 
105
  DBUG_ENTER("maria_begin");
 
106
 
 
107
  if (info->s->now_transactional)
 
108
  {
 
109
    TRN *trn;
 
110
    struct st_my_thread_var *mysys_var= my_thread_var;
 
111
    trn= trnman_new_trn(&mysys_var->mutex,
 
112
                        &mysys_var->suspend,
 
113
                        (char*) &mysys_var + STACK_DIRECTION *1024*128);
 
114
    if (unlikely(!trn))
 
115
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
116
 
 
117
    DBUG_PRINT("info", ("TRN set to 0x%lx", (ulong) trn));
 
118
    info->trn= trn;
 
119
  }
 
120
  DBUG_RETURN(0);
 
121
}
 
122