~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/xa_resource_manager.cc

  • Committer: Brian Aker
  • Date: 2010-05-26 21:49:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1568.
  • Revision ID: brian@gaz-20100526214918-8kdibq48e9lnyr6t
This fixes bug 586009, increases the size of the log files so that the UNION
test doesn't hit Innodb's default limit. Increases the size of the initial
Innodb data file, and fixes one case where an empty string on error was
causing a crash on OSX.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "config.h"
22
22
 
 
23
#include "drizzled/my_hash.h"
23
24
#include "drizzled/cached_directory.h"
24
25
 
25
26
#include <drizzled/definitions.h>
35
36
#include <algorithm>
36
37
#include <functional>
37
38
 
 
39
using namespace std;
 
40
 
38
41
namespace drizzled
39
42
{
40
43
 
41
44
namespace plugin
42
45
{
43
46
 
44
 
static std::vector<XaResourceManager *> xa_resource_managers;
 
47
static vector<XaResourceManager *> xa_resource_managers;
45
48
 
46
49
int XaResourceManager::commitOrRollbackXID(XID *xid, bool commit)
47
50
{
48
 
  std::vector<int> results;
 
51
  vector<int> results;
49
52
  
50
53
  if (commit)
51
54
    transform(xa_resource_managers.begin(), xa_resource_managers.end(), results.begin(),
52
 
              std::bind2nd(std::mem_fun(&XaResourceManager::xaCommitXid), xid));
 
55
              bind2nd(mem_fun(&XaResourceManager::xaCommitXid), xid));
53
56
  else
54
57
    transform(xa_resource_managers.begin(), xa_resource_managers.end(), results.begin(),
55
 
              std::bind2nd(std::mem_fun(&XaResourceManager::xaRollbackXid), xid));
 
58
              bind2nd(mem_fun(&XaResourceManager::xaRollbackXid), xid));
56
59
 
57
 
  if (std::find_if(results.begin(), results.end(), std::bind2nd(std::equal_to<int>(),0)) == results.end())
 
60
  if (find_if(results.begin(), results.end(), bind2nd(equal_to<int>(),0))
 
61
         == results.end())
58
62
    return 1;
59
 
 
60
63
  return 0;
61
64
}
62
65
 
66
69
  @note
67
70
    there are three modes of operation:
68
71
    - automatic recover after a crash
69
 
    in this case commit_list.size() != 0, tc_heuristic_recover==0
 
72
    in this case commit_list != 0, tc_heuristic_recover==0
70
73
    all xids from commit_list are committed, others are rolled back
71
74
    - manual (heuristic) recover
72
 
    in this case commit_list.size()==0, tc_heuristic_recover != 0
 
75
    in this case commit_list==0, tc_heuristic_recover != 0
73
76
    DBA has explicitly specified that all prepared transactions should
74
77
    be committed (or rolled back).
75
 
    - no recovery (Drizzle did not detect a crash)
76
 
    in this case commit_list.size()==0, tc_heuristic_recover == 0
 
78
    - no recovery (MySQL did not detect a crash)
 
79
    in this case commit_list==0, tc_heuristic_recover == 0
77
80
    there should be no prepared transactions in this case.
78
81
*/
79
 
class XaRecover : std::unary_function<XaResourceManager *, void>
 
82
class XaRecover : unary_function<XaResourceManager *, void>
80
83
{
81
 
private:
82
84
  int trans_len, found_foreign_xids, found_my_xids;
83
85
  bool result;
84
86
  XID *trans_list;
85
 
  const XaResourceManager::commit_list_set &commit_list;
 
87
  HASH *commit_list;
86
88
  bool dry_run;
87
89
public:
88
90
  XaRecover(XID *trans_list_arg, int trans_len_arg,
89
 
            const XaResourceManager::commit_list_set& commit_list_arg,
90
 
            bool dry_run_arg) 
 
91
            HASH *commit_list_arg, bool dry_run_arg) 
91
92
    : trans_len(trans_len_arg), found_foreign_xids(0), found_my_xids(0),
92
93
      result(false),
93
94
      trans_list(trans_list_arg), commit_list(commit_list_arg),
129
130
          continue;
130
131
        }
131
132
        // recovery mode
132
 
        if (commit_list.size() ?
133
 
            commit_list.find(x) != commit_list.end() :
 
133
        if (commit_list ?
 
134
            hash_search(commit_list, (unsigned char *)&x, sizeof(x)) != 0 :
134
135
            tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
135
136
        {
136
137
          resource_manager->xaCommitXid(trans_list+i);
146
147
  }
147
148
};
148
149
 
149
 
int XaResourceManager::recoverAllXids()
150
 
{
151
 
  const XaResourceManager::commit_list_set empty_commit_set;
152
 
  return recoverAllXids(empty_commit_set);
153
 
}
154
 
 
155
 
int XaResourceManager::recoverAllXids(const XaResourceManager::commit_list_set &commit_list)
 
150
int XaResourceManager::recoverAllXids(HASH *commit_list)
156
151
{
157
152
  XID *trans_list= NULL;
158
153
  int trans_len= 0;
159
154
 
160
 
  bool dry_run= (commit_list.size() == 0 && tc_heuristic_recover==0);
 
155
  bool dry_run= (commit_list==0 && tc_heuristic_recover==0);
161
156
 
162
157
  /* commit_list and tc_heuristic_recover cannot be set both */
163
 
  assert(commit_list.size() == 0 || tc_heuristic_recover == 0);
 
158
  assert(commit_list==0 || tc_heuristic_recover==0);
164
159
 
165
160
  if (xa_resource_managers.size() <= 1)
166
161
    return 0;
178
173
    return(1);
179
174
  }
180
175
 
181
 
  if (commit_list.size())
 
176
  if (commit_list)
182
177
    errmsg_printf(ERRMSG_LVL_INFO, _("Starting crash recovery..."));
183
178
 
184
179
  XaRecover recover_func(trans_list, trans_len, commit_list, dry_run);
185
 
  std::for_each(xa_resource_managers.begin(),
186
 
                xa_resource_managers.end(),
187
 
                recover_func);
 
180
  for_each(xa_resource_managers.begin(),
 
181
           xa_resource_managers.end(),
 
182
           recover_func);
188
183
  free(trans_list);
189
184
 
190
185
  if (recover_func.getForeignXIDs())
203
198
                    recover_func.getMyXIDs(), opt_tc_log_file);
204
199
    return(1);
205
200
  }
206
 
  if (commit_list.size())
 
201
  if (commit_list)
207
202
    errmsg_printf(ERRMSG_LVL_INFO, _("Crash recovery finished."));
208
203
  return(0);
209
204
}