~drizzle-trunk/drizzle/development

1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 *  Copyright (C) 2010 Jay Pipes <jaypipes@gmail.com>
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; version 2 of the License.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
21
#include <config.h>
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
22
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
23
#include <drizzled/cached_directory.h>
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
24
25
#include <drizzled/definitions.h>
26
#include <drizzled/session.h>
27
#include <drizzled/error.h>
28
#include <drizzled/gettext.h>
29
#include <drizzled/plugin/xa_resource_manager.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
30
#include <drizzled/xid.h>
2239.1.6 by Olaf van der Spek
Refactor includes
31
#include <drizzled/errmsg_print.h>
2239.1.10 by Olaf van der Spek
Refactor includes
32
#include <drizzled/sys_var.h>
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
33
34
#include <string>
35
#include <vector>
36
#include <algorithm>
37
#include <functional>
38
2239.1.10 by Olaf van der Spek
Refactor includes
39
namespace drizzled {
40
namespace plugin {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
41
2318.8.9 by Olaf van der Spek
Use boost::to_upper
42
typedef std::vector<XaResourceManager*> xa_resource_managers_t;
43
static xa_resource_managers_t xa_resource_managers;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
44
45
int XaResourceManager::commitOrRollbackXID(XID *xid, bool commit)
46
{
1966.2.9 by Brian Aker
Remove the use of "using std" from the plugin interface .cc files.
47
  std::vector<int> results;
2318.8.9 by Olaf van der Spek
Use boost::to_upper
48
  BOOST_FOREACH(XaResourceManager* it, xa_resource_managers)
49
    results.push_back(commit ? it->xaCommitXid(xid) : it->xaRollbackXid(xid));
50
  return std::find(results.begin(), results.end(), 0) == results.end();
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
51
}
52
53
/**
54
  recover() step of xa.
55
56
  @note
57
    there are three modes of operation:
58
    - automatic recover after a crash
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
59
    in this case commit_list.size() != 0, tc_heuristic_recover==0
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
60
    all xids from commit_list are committed, others are rolled back
61
    - manual (heuristic) recover
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
62
    in this case commit_list.size()==0, tc_heuristic_recover != 0
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
63
    DBA has explicitly specified that all prepared transactions should
64
    be committed (or rolled back).
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
65
    - no recovery (Drizzle did not detect a crash)
66
    in this case commit_list.size()==0, tc_heuristic_recover == 0
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
67
    there should be no prepared transactions in this case.
68
*/
1966.2.9 by Brian Aker
Remove the use of "using std" from the plugin interface .cc files.
69
class XaRecover : std::unary_function<XaResourceManager *, void>
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
70
{
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
71
private:
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
72
  int trans_len, found_foreign_xids, found_my_xids;
73
  bool result;
74
  XID *trans_list;
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
75
  const XaResourceManager::commit_list_set &commit_list;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
76
  bool dry_run;
77
public:
78
  XaRecover(XID *trans_list_arg, int trans_len_arg,
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
79
            const XaResourceManager::commit_list_set& commit_list_arg,
2224.1.1 by Olaf van der Spek
Finish removing XID cache
80
            bool dry_run_arg)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
81
    : trans_len(trans_len_arg), found_foreign_xids(0), found_my_xids(0),
82
      result(false),
83
      trans_list(trans_list_arg), commit_list(commit_list_arg),
84
      dry_run(dry_run_arg)
85
  {}
2224.1.1 by Olaf van der Spek
Finish removing XID cache
86
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
87
  int getForeignXIDs()
88
  {
2224.1.1 by Olaf van der Spek
Finish removing XID cache
89
    return found_foreign_xids;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
90
  }
91
92
  int getMyXIDs()
93
  {
2224.1.1 by Olaf van der Spek
Finish removing XID cache
94
    return found_my_xids;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
95
  }
96
97
  result_type operator() (argument_type resource_manager)
98
  {
2224.1.1 by Olaf van der Spek
Finish removing XID cache
99
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
100
    int got;
2224.1.1 by Olaf van der Spek
Finish removing XID cache
101
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
102
    while ((got= resource_manager->xaRecover(trans_list, trans_len)) > 0 )
103
    {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
104
      errmsg_printf(error::INFO,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
105
                    _("Found %d prepared transaction(s) in resource manager."),
106
                    got);
107
      for (int i=0; i < got; i ++)
108
      {
109
        my_xid x=trans_list[i].get_my_xid();
110
        if (!x) // not "mine" - that is generated by external TM
111
        {
112
          found_foreign_xids++;
113
          continue;
114
        }
115
        if (dry_run)
116
        {
117
          found_my_xids++;
118
          continue;
119
        }
120
        // recovery mode
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
121
        if (commit_list.size() ?
122
            commit_list.find(x) != commit_list.end() :
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
123
            tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
124
        {
125
          resource_manager->xaCommitXid(trans_list+i);
126
        }
127
        else
128
        {
129
          resource_manager->xaRollbackXid(trans_list+i);
130
        }
131
      }
132
      if (got < trans_len)
133
        break;
134
    }
135
  }
136
};
137
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
138
int XaResourceManager::recoverAllXids()
139
{
140
  const XaResourceManager::commit_list_set empty_commit_set;
141
  return recoverAllXids(empty_commit_set);
142
}
143
144
int XaResourceManager::recoverAllXids(const XaResourceManager::commit_list_set &commit_list)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
145
{
146
  XID *trans_list= NULL;
147
  int trans_len= 0;
148
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
149
  bool dry_run= (commit_list.size() == 0 && tc_heuristic_recover==0);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
150
151
  /* commit_list and tc_heuristic_recover cannot be set both */
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
152
  assert(commit_list.size() == 0 || tc_heuristic_recover == 0);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
153
154
  if (xa_resource_managers.size() <= 1)
155
    return 0;
156
157
  tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
158
  dry_run=false;
159
  for (trans_len= MAX_XID_LIST_SIZE ;
160
       trans_list==0 && trans_len > MIN_XID_LIST_SIZE; trans_len/=2)
161
  {
162
    trans_list=(XID *)malloc(trans_len*sizeof(XID));
163
  }
164
  if (!trans_list)
165
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
166
    errmsg_printf(error::ERROR, ER(ER_OUTOFMEMORY), trans_len*sizeof(XID));
2318.6.77 by Olaf van der Spek
Refactor
167
    return 1;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
168
  }
169
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
170
  if (commit_list.size())
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
171
    errmsg_printf(error::INFO, _("Starting crash recovery..."));
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
172
173
  XaRecover recover_func(trans_list, trans_len, commit_list, dry_run);
1966.2.14 by Brian Aker
Merge in some additional std namespace finds.
174
  std::for_each(xa_resource_managers.begin(),
175
                xa_resource_managers.end(),
176
                recover_func);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
177
  free(trans_list);
2224.1.1 by Olaf van der Spek
Finish removing XID cache
178
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
179
  if (recover_func.getForeignXIDs())
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
180
    errmsg_printf(error::WARN,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
181
                  _("Found %d prepared XA transactions"),
182
                  recover_func.getForeignXIDs());
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
183
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
184
  if (dry_run && recover_func.getMyXIDs())
185
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
186
    errmsg_printf(error::ERROR,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
187
                  _("Found %d prepared transactions! It means that drizzled "
188
                    "was not shut down properly last time and critical "
189
                    "recovery information (last binlog or %s file) was "
190
                    "manually deleted after a crash. You have to start "
191
                    "drizzled with the --tc-heuristic-recover switch to "
192
                    "commit or rollback pending transactions."),
193
                    recover_func.getMyXIDs(), opt_tc_log_file);
2318.6.77 by Olaf van der Spek
Refactor
194
    return 1;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
195
  }
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
196
1720.5.3 by Monty Taylor
Removed a HASH in xa_resource_manager. It's not actually used, but I left it
197
  if (commit_list.size())
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
198
    errmsg_printf(error::INFO, _("Crash recovery finished."));
199
2318.6.58 by Olaf van der Spek
Refactor
200
  return 0;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
201
}
202
203
bool XaResourceManager::addPlugin(XaResourceManager *resource_manager)
204
{
205
  xa_resource_managers.push_back(resource_manager);
206
  return false;
207
}
208
209
void XaResourceManager::removePlugin(XaResourceManager *)
210
{
211
  xa_resource_managers.clear();
212
}
213
214
} /* namespace plugin */
215
} /* namespace drizzled */