26 #include <drizzled/session.h>
27 #include <drizzled/error.h>
28 #include <drizzled/gettext.h>
29 #include <drizzled/plugin/xa_resource_manager.h>
30 #include <drizzled/xid.h>
31 #include <drizzled/errmsg_print.h>
32 #include <drizzled/sys_var.h>
42 typedef std::vector<XaResourceManager*> xa_resource_managers_t;
43 static xa_resource_managers_t xa_resource_managers;
47 std::vector<int> results;
49 results.push_back(commit ? it->xaCommitXid(xid) : it->xaRollbackXid(xid));
50 return std::find(results.begin(), results.end(), 0) == results.end();
69 class XaRecover : std::unary_function<XaResourceManager *, void>
72 int trans_len, found_foreign_xids, found_my_xids;
75 const XaResourceManager::commit_list_set &commit_list;
79 const XaResourceManager::commit_list_set& commit_list_arg,
81 : trans_len(trans_len_arg), found_foreign_xids(0), found_my_xids(0),
83 trans_list(trans_list_arg), commit_list(commit_list_arg),
89 return found_foreign_xids;
97 result_type operator() (argument_type resource_manager)
102 while ((got= resource_manager->xaRecover(trans_list, trans_len)) > 0 )
104 errmsg_printf(error::INFO,
105 _(
"Found %d prepared transaction(s) in resource manager."),
107 for (
int i=0; i < got; i ++)
109 my_xid x=trans_list[i].get_my_xid();
112 found_foreign_xids++;
121 if (commit_list.size() ?
122 commit_list.find(x) != commit_list.end() :
123 tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
125 resource_manager->xaCommitXid(trans_list+i);
129 resource_manager->xaRollbackXid(trans_list+i);
138 int XaResourceManager::recoverAllXids()
140 const XaResourceManager::commit_list_set empty_commit_set;
141 return recoverAllXids(empty_commit_set);
144 int XaResourceManager::recoverAllXids(
const XaResourceManager::commit_list_set &commit_list)
146 XID *trans_list= NULL;
149 bool dry_run= (commit_list.size() == 0 && tc_heuristic_recover==0);
152 assert(commit_list.size() == 0 || tc_heuristic_recover == 0);
154 if (xa_resource_managers.size() <= 1)
157 tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK;
159 for (trans_len= MAX_XID_LIST_SIZE ;
160 trans_list==0 && trans_len > MIN_XID_LIST_SIZE; trans_len/=2)
162 trans_list=(
XID *)malloc(trans_len*
sizeof(
XID));
166 errmsg_printf(error::ERROR, ER(ER_OUTOFMEMORY), trans_len*
sizeof(
XID));
170 if (commit_list.size())
171 errmsg_printf(error::INFO, _(
"Starting crash recovery..."));
173 XaRecover recover_func(trans_list, trans_len, commit_list, dry_run);
174 std::for_each(xa_resource_managers.begin(),
175 xa_resource_managers.end(),
179 if (recover_func.getForeignXIDs())
180 errmsg_printf(error::WARN,
181 _(
"Found %d prepared XA transactions"),
182 recover_func.getForeignXIDs());
184 if (dry_run && recover_func.getMyXIDs())
186 errmsg_printf(error::ERROR,
187 _(
"Found %d prepared transactions! It means that drizzled "
188 "was not shut down properly last time and critical "
189 "recovery information was "
190 "manually deleted after a crash. "
191 "This should never happen."),
192 recover_func.getMyXIDs());
196 if (commit_list.size())
197 errmsg_printf(error::INFO, _(
"Crash recovery finished."));
202 bool XaResourceManager::addPlugin(XaResourceManager *resource_manager)
204 xa_resource_managers.push_back(resource_manager);
208 void XaResourceManager::removePlugin(XaResourceManager *)
210 xa_resource_managers.clear();
static int commitOrRollbackXID(XID *xid, bool commit)
Defines the interface to the CachedDirectory class.