~kentokushiba/spiderformysql/spider-1.0-src

« back to all changes in this revision

Viewing changes to spd_trx.cc

  • Committer: Kentoku SHIBA
  • Date: 2010-01-04 03:06:41 UTC
  • Revision ID: kentokushiba@gmail.com-20100104030641-y91fagyp7iswtsua
separate from doc files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2008-2009 Kentoku Shiba
 
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
#define MYSQL_SERVER 1
 
17
#include "mysql_priv.h"
 
18
#include <mysql/plugin.h>
 
19
#include "spd_err.h"
 
20
#include "spd_param.h"
 
21
#include "spd_db_include.h"
 
22
#include "spd_include.h"
 
23
#include "spd_sys_table.h"
 
24
#include "ha_spider.h"
 
25
#include "spd_trx.h"
 
26
#include "spd_db_conn.h"
 
27
#include "spd_table.h"
 
28
#include "spd_conn.h"
 
29
 
 
30
extern handlerton *spider_hton_ptr;
 
31
volatile ulonglong spider_thread_id = 1;
 
32
 
 
33
// for spider_alter_tables
 
34
uchar *spider_alter_tbl_get_key(
 
35
  SPIDER_ALTER_TABLE *alter_table,
 
36
  size_t *length,
 
37
  my_bool not_used __attribute__ ((unused))
 
38
) {
 
39
  DBUG_ENTER("spider_alter_tbl_get_key");
 
40
  *length = alter_table->table_name_length;
 
41
  DBUG_PRINT("info",("spider table_name_length=%d", *length));
 
42
  DBUG_PRINT("info",("spider table_name=%s", alter_table->table_name));
 
43
  DBUG_RETURN((uchar*) alter_table->table_name);
 
44
}
 
45
 
 
46
int spider_free_trx_conn(
 
47
  SPIDER_TRX *trx,
 
48
  bool trx_free
 
49
) {
 
50
  int roop_count = 0;
 
51
  SPIDER_CONN *conn;
 
52
  DBUG_ENTER("spider_free_trx_conn");
 
53
  if(
 
54
    trx_free ||
 
55
    THDVAR(trx->thd, conn_recycle_mode) != 2
 
56
  ) {
 
57
    while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_conn_hash,
 
58
      roop_count)))
 
59
    {
 
60
      if (conn->table_lock)
 
61
      {
 
62
        DBUG_ASSERT(!trx_free);
 
63
        roop_count++;
 
64
      } else
 
65
        spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &roop_count);
 
66
    }
 
67
    trx->trx_conn_adjustment++;
 
68
  }
 
69
  DBUG_RETURN(0);
 
70
}
 
71
 
 
72
int spider_free_trx_another_conn(
 
73
  SPIDER_TRX *trx,
 
74
  bool lock
 
75
) {
 
76
  int error_num, tmp_error_num;
 
77
  int roop_count = 0;
 
78
  SPIDER_CONN *conn;
 
79
  ha_spider tmp_spider;
 
80
  DBUG_ENTER("spider_free_trx_another_conn");
 
81
  error_num = 0;
 
82
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_another_conn_hash,
 
83
    roop_count)))
 
84
  {
 
85
    tmp_spider.conn = conn;
 
86
    tmp_spider.trx = trx;
 
87
    if (lock && (tmp_error_num = spider_db_unlock_tables(&tmp_spider)))
 
88
      error_num = tmp_error_num;
 
89
    spider_free_conn_from_trx(trx, conn, TRUE, TRUE, &roop_count);
 
90
  }
 
91
  DBUG_RETURN(error_num);
 
92
}
 
93
 
 
94
int spider_trx_another_lock_tables(
 
95
  SPIDER_TRX *trx
 
96
) {
 
97
  int error_num;
 
98
  int roop_count = 0;
 
99
  SPIDER_CONN *conn;
 
100
  ha_spider tmp_spider;
 
101
  SPIDER_SHARE tmp_share;
 
102
  DBUG_ENTER("spider_trx_another_lock_tables");
 
103
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
104
  memset(&tmp_share, 0, sizeof(SPIDER_SHARE));
 
105
  tmp_spider.share = &tmp_share;
 
106
  tmp_spider.trx = trx;
 
107
  tmp_share.access_charset = system_charset_info;
 
108
  if ((error_num = spider_db_append_set_names(&tmp_share)))
 
109
    DBUG_RETURN(error_num);
 
110
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_another_conn_hash,
 
111
    roop_count)))
 
112
  {
 
113
    tmp_spider.conn = conn;
 
114
    if ((error_num = spider_db_lock_tables(&tmp_spider)))
 
115
    {
 
116
      spider_db_free_set_names(&tmp_share);
 
117
      DBUG_RETURN(error_num);
 
118
    }
 
119
    roop_count++;
 
120
  }
 
121
  spider_db_free_set_names(&tmp_share);
 
122
  DBUG_RETURN(0);
 
123
}
 
124
 
 
125
int spider_trx_another_flush_tables(
 
126
  SPIDER_TRX *trx
 
127
) {
 
128
  int error_num;
 
129
  int roop_count = 0;
 
130
  SPIDER_CONN *conn;
 
131
  ha_spider tmp_spider;
 
132
  DBUG_ENTER("spider_trx_another_flush_tables");
 
133
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
134
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_another_conn_hash,
 
135
    roop_count)))
 
136
  {
 
137
    tmp_spider.conn = conn;
 
138
    if ((error_num = spider_db_flush_tables(&tmp_spider, FALSE)))
 
139
      DBUG_RETURN(error_num);
 
140
    roop_count++;
 
141
  }
 
142
  DBUG_RETURN(0);
 
143
}
 
144
 
 
145
int spider_trx_all_flush_tables(
 
146
  SPIDER_TRX *trx
 
147
) {
 
148
  int error_num;
 
149
  int roop_count = 0;
 
150
  SPIDER_CONN *conn;
 
151
  ha_spider tmp_spider;
 
152
  DBUG_ENTER("spider_trx_all_flush_tables");
 
153
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
154
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_conn_hash,
 
155
    roop_count)))
 
156
  {
 
157
    tmp_spider.conn = conn;
 
158
    if ((error_num = spider_db_flush_tables(&tmp_spider, TRUE)))
 
159
      DBUG_RETURN(error_num);
 
160
    roop_count++;
 
161
  }
 
162
  DBUG_RETURN(0);
 
163
}
 
164
 
 
165
int spider_trx_all_unlock_tables(
 
166
  SPIDER_TRX *trx
 
167
) {
 
168
  int error_num;
 
169
  int roop_count = 0;
 
170
  SPIDER_CONN *conn;
 
171
  ha_spider tmp_spider;
 
172
  DBUG_ENTER("spider_trx_all_unlock_tables");
 
173
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
174
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_conn_hash,
 
175
    roop_count)))
 
176
  {
 
177
    tmp_spider.conn = conn;
 
178
    tmp_spider.trx = trx;
 
179
    if ((error_num = spider_db_unlock_tables(&tmp_spider)))
 
180
      DBUG_RETURN(error_num);
 
181
    roop_count++;
 
182
  }
 
183
  DBUG_RETURN(0);
 
184
}
 
185
 
 
186
int spider_trx_all_start_trx(
 
187
  SPIDER_TRX *trx
 
188
) {
 
189
  int error_num;
 
190
  int roop_count = 0;
 
191
  SPIDER_CONN *conn;
 
192
  ha_spider tmp_spider;
 
193
  DBUG_ENTER("spider_trx_all_start_trx");
 
194
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
195
  tmp_spider.trx = trx;
 
196
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_conn_hash,
 
197
    roop_count)))
 
198
  {
 
199
    tmp_spider.conn = conn;
 
200
    if (
 
201
      (THDVAR(trx->thd, sync_trx_isolation) &&
 
202
        (error_num = spider_check_and_set_trx_isolation(conn))) ||
 
203
      (error_num = spider_internal_start_trx(&tmp_spider))
 
204
    )
 
205
      DBUG_RETURN(error_num);
 
206
    roop_count++;
 
207
  }
 
208
  DBUG_RETURN(0);
 
209
}
 
210
 
 
211
int spider_trx_all_flush_logs(
 
212
  SPIDER_TRX *trx
 
213
) {
 
214
  int error_num;
 
215
  int roop_count = 0;
 
216
  SPIDER_CONN *conn;
 
217
  ha_spider tmp_spider;
 
218
  DBUG_ENTER("spider_trx_all_flush_logs");
 
219
  memset(&tmp_spider, 0, sizeof(ha_spider));
 
220
  while ((conn = (SPIDER_CONN*) hash_element(&trx->trx_conn_hash,
 
221
    roop_count)))
 
222
  {
 
223
    tmp_spider.conn = conn;
 
224
    if ((error_num = spider_db_flush_logs(&tmp_spider)))
 
225
      DBUG_RETURN(error_num);
 
226
    roop_count++;
 
227
  }
 
228
  DBUG_RETURN(0);
 
229
}
 
230
 
 
231
void spider_free_trx_alter_table_alloc(
 
232
  SPIDER_TRX *trx,
 
233
  SPIDER_ALTER_TABLE *alter_table
 
234
) {
 
235
  DBUG_ENTER("spider_free_trx_alter_table_alloc");
 
236
  hash_delete(&trx->trx_alter_table_hash, (uchar*) alter_table);
 
237
  if (alter_table->tmp_char)
 
238
    my_free(alter_table->tmp_char, MYF(0));
 
239
  my_free(alter_table, MYF(0));
 
240
  DBUG_VOID_RETURN;
 
241
}
 
242
 
 
243
int spider_free_trx_alter_table(
 
244
  SPIDER_TRX *trx
 
245
) {
 
246
  SPIDER_ALTER_TABLE *alter_table;
 
247
  DBUG_ENTER("spider_free_trx_alter_table");
 
248
  while ((alter_table =
 
249
    (SPIDER_ALTER_TABLE*) hash_element(&trx->trx_alter_table_hash, 0)))
 
250
  {
 
251
    spider_free_trx_alter_table_alloc(trx, alter_table);
 
252
  }
 
253
  DBUG_RETURN(0);
 
254
}
 
255
 
 
256
int spider_create_trx_alter_table(
 
257
  SPIDER_TRX *trx,
 
258
  SPIDER_SHARE *share,
 
259
  bool now_create
 
260
) {
 
261
  int error_num;
 
262
  SPIDER_ALTER_TABLE *alter_table, *share_alter;
 
263
  char *tmp_name;
 
264
  char *tmp_server_name;
 
265
  char *tmp_tgt_table_name;
 
266
  char *tmp_tgt_db;
 
267
  char *tmp_tgt_host;
 
268
  char *tmp_tgt_username;
 
269
  char *tmp_tgt_password;
 
270
  char *tmp_tgt_socket;
 
271
  char *tmp_tgt_wrapper;
 
272
  DBUG_ENTER("spider_create_trx_alter_table");
 
273
  share_alter = &share->alter_table;
 
274
  if (!(alter_table = (SPIDER_ALTER_TABLE *)
 
275
    my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
 
276
      &alter_table, sizeof(*alter_table),
 
277
      &tmp_name, share->table_name_length + 1,
 
278
      &tmp_server_name,
 
279
        (share_alter->tmp_server_name ?
 
280
          share_alter->tmp_server_name_length + 1 : 0),
 
281
      &tmp_tgt_table_name,
 
282
        (share_alter->tmp_tgt_table_name ?
 
283
          share_alter->tmp_tgt_table_name_length + 1 : 0),
 
284
      &tmp_tgt_db,
 
285
        (share_alter->tmp_tgt_db ?
 
286
          share_alter->tmp_tgt_db_length + 1 : 0),
 
287
      &tmp_tgt_host,
 
288
        (share_alter->tmp_tgt_host ?
 
289
          share_alter->tmp_tgt_host_length + 1 : 0),
 
290
      &tmp_tgt_username,
 
291
        (share_alter->tmp_tgt_username ?
 
292
          share_alter->tmp_tgt_username_length + 1 : 0),
 
293
      &tmp_tgt_password,
 
294
        (share_alter->tmp_tgt_password ?
 
295
          share_alter->tmp_tgt_password_length + 1 : 0),
 
296
      &tmp_tgt_socket,
 
297
        (share_alter->tmp_tgt_socket ?
 
298
          share_alter->tmp_tgt_socket_length + 1 : 0),
 
299
      &tmp_tgt_wrapper,
 
300
        (share_alter->tmp_tgt_wrapper ?
 
301
          share_alter->tmp_tgt_wrapper_length + 1 : 0),
 
302
      NullS))
 
303
  ) {
 
304
    error_num = HA_ERR_OUT_OF_MEM;
 
305
    goto error_alloc_alter_table;
 
306
  }
 
307
  alter_table->now_create = now_create;
 
308
  alter_table->table_name = tmp_name;
 
309
  memcpy(alter_table->table_name, share->table_name, share->table_name_length);
 
310
  alter_table->table_name_length = share->table_name_length;
 
311
  alter_table->tmp_priority = share->priority;
 
312
  if (share_alter->tmp_server_name)
 
313
  {
 
314
    alter_table->tmp_server_name = tmp_server_name;
 
315
    memcpy(alter_table->tmp_server_name,
 
316
      share_alter->tmp_server_name, share_alter->tmp_server_name_length);
 
317
  }
 
318
  if (share_alter->tmp_tgt_table_name)
 
319
  {
 
320
    alter_table->tmp_tgt_table_name = tmp_tgt_table_name;
 
321
    memcpy(alter_table->tmp_tgt_table_name,
 
322
      share_alter->tmp_tgt_table_name, share_alter->tmp_tgt_table_name_length);
 
323
  }
 
324
  if (share_alter->tmp_tgt_db)
 
325
  {
 
326
    alter_table->tmp_tgt_db = tmp_tgt_db;
 
327
    memcpy(alter_table->tmp_tgt_db,
 
328
      share_alter->tmp_tgt_db, share_alter->tmp_tgt_db_length);
 
329
  }
 
330
  if (share_alter->tmp_tgt_host)
 
331
  {
 
332
    alter_table->tmp_tgt_host = tmp_tgt_host;
 
333
    memcpy(alter_table->tmp_tgt_host,
 
334
      share_alter->tmp_tgt_host, share_alter->tmp_tgt_host_length);
 
335
  }
 
336
  if (share_alter->tmp_tgt_username)
 
337
  {
 
338
    alter_table->tmp_tgt_username = tmp_tgt_username;
 
339
    memcpy(alter_table->tmp_tgt_username,
 
340
      share_alter->tmp_tgt_username, share_alter->tmp_tgt_username_length);
 
341
  }
 
342
  if (share_alter->tmp_tgt_password)
 
343
  {
 
344
    alter_table->tmp_tgt_password = tmp_tgt_password;
 
345
    memcpy(alter_table->tmp_tgt_password,
 
346
      share_alter->tmp_tgt_password, share_alter->tmp_tgt_password_length);
 
347
  }
 
348
  if (share_alter->tmp_tgt_socket)
 
349
  {
 
350
    alter_table->tmp_tgt_socket = tmp_tgt_socket;
 
351
    memcpy(alter_table->tmp_tgt_socket,
 
352
      share_alter->tmp_tgt_socket, share_alter->tmp_tgt_socket_length);
 
353
  }
 
354
  if (share_alter->tmp_tgt_wrapper)
 
355
  {
 
356
    alter_table->tmp_tgt_wrapper = tmp_tgt_wrapper;
 
357
    memcpy(alter_table->tmp_tgt_wrapper,
 
358
      share_alter->tmp_tgt_wrapper, share_alter->tmp_tgt_wrapper_length);
 
359
  }
 
360
  alter_table->tmp_tgt_port = share_alter->tmp_tgt_port;
 
361
  alter_table->tmp_server_name_length = share_alter->tmp_server_name_length;
 
362
  alter_table->tmp_tgt_table_name_length =
 
363
    share_alter->tmp_tgt_table_name_length;
 
364
  alter_table->tmp_tgt_db_length = share_alter->tmp_tgt_db_length;
 
365
  alter_table->tmp_tgt_host_length = share_alter->tmp_tgt_host_length;
 
366
  alter_table->tmp_tgt_username_length = share_alter->tmp_tgt_username_length;
 
367
  alter_table->tmp_tgt_password_length = share_alter->tmp_tgt_password_length;
 
368
  alter_table->tmp_tgt_socket_length = share_alter->tmp_tgt_socket_length;
 
369
  alter_table->tmp_tgt_wrapper_length = share_alter->tmp_tgt_wrapper_length;
 
370
  if (my_hash_insert(&trx->trx_alter_table_hash, (uchar*) alter_table))
 
371
  {
 
372
    error_num = HA_ERR_OUT_OF_MEM;
 
373
    goto error;
 
374
  }
 
375
  DBUG_RETURN(0);
 
376
 
 
377
error:
 
378
  my_free(alter_table, MYF(0));
 
379
error_alloc_alter_table:
 
380
  DBUG_RETURN(error_num);
 
381
}
 
382
 
 
383
bool spider_cmp_trx_alter_table(
 
384
  SPIDER_ALTER_TABLE *cmp1,
 
385
  SPIDER_ALTER_TABLE *cmp2
 
386
) {
 
387
  DBUG_ENTER("spider_cmp_trx_alter_table");
 
388
  if (
 
389
    cmp1->tmp_priority != cmp2->tmp_priority ||
 
390
    (
 
391
      cmp1->tmp_server_name != cmp2->tmp_server_name &&
 
392
      (
 
393
        !cmp1->tmp_server_name ||
 
394
        !cmp2->tmp_server_name ||
 
395
        strcmp(cmp1->tmp_server_name, cmp2->tmp_server_name)
 
396
      )
 
397
    ) ||
 
398
    (
 
399
      cmp1->tmp_tgt_table_name != cmp2->tmp_tgt_table_name &&
 
400
      (
 
401
        !cmp1->tmp_tgt_table_name ||
 
402
        !cmp2->tmp_tgt_table_name ||
 
403
        strcmp(cmp1->tmp_tgt_table_name, cmp2->tmp_tgt_table_name)
 
404
      )
 
405
    ) ||
 
406
    (
 
407
      cmp1->tmp_tgt_db != cmp2->tmp_tgt_db &&
 
408
      (
 
409
        !cmp1->tmp_tgt_db ||
 
410
        !cmp2->tmp_tgt_db ||
 
411
        strcmp(cmp1->tmp_tgt_db, cmp2->tmp_tgt_db)
 
412
      )
 
413
    ) ||
 
414
    (
 
415
      cmp1->tmp_tgt_host != cmp2->tmp_tgt_host &&
 
416
      (
 
417
        !cmp1->tmp_tgt_host ||
 
418
        !cmp2->tmp_tgt_host ||
 
419
        strcmp(cmp1->tmp_tgt_host, cmp2->tmp_tgt_host)
 
420
      )
 
421
    ) ||
 
422
    (
 
423
      cmp1->tmp_tgt_username != cmp2->tmp_tgt_username &&
 
424
      (
 
425
        !cmp1->tmp_tgt_username ||
 
426
        !cmp2->tmp_tgt_username ||
 
427
        strcmp(cmp1->tmp_tgt_username, cmp2->tmp_tgt_username)
 
428
      )
 
429
    ) ||
 
430
    (
 
431
      cmp1->tmp_tgt_password != cmp2->tmp_tgt_password &&
 
432
      (
 
433
        !cmp1->tmp_tgt_password ||
 
434
        !cmp2->tmp_tgt_password ||
 
435
        strcmp(cmp1->tmp_tgt_password, cmp2->tmp_tgt_password)
 
436
      )
 
437
    ) ||
 
438
    (
 
439
      cmp1->tmp_tgt_socket != cmp2->tmp_tgt_socket &&
 
440
      (
 
441
        !cmp1->tmp_tgt_socket ||
 
442
        !cmp2->tmp_tgt_socket ||
 
443
        strcmp(cmp1->tmp_tgt_socket, cmp2->tmp_tgt_socket)
 
444
      )
 
445
    ) ||
 
446
    (
 
447
      cmp1->tmp_tgt_wrapper != cmp2->tmp_tgt_wrapper &&
 
448
      (
 
449
        !cmp1->tmp_tgt_wrapper ||
 
450
        !cmp2->tmp_tgt_wrapper ||
 
451
        strcmp(cmp1->tmp_tgt_wrapper, cmp2->tmp_tgt_wrapper)
 
452
      )
 
453
    ) ||
 
454
    cmp1->tmp_tgt_port != cmp2->tmp_tgt_port
 
455
  )
 
456
    DBUG_RETURN(TRUE);
 
457
  DBUG_RETURN(FALSE);
 
458
}
 
459
 
 
460
int spider_free_trx_alloc(
 
461
  SPIDER_TRX *trx
 
462
) {
 
463
  DBUG_ENTER("spider_free_trx_alloc");
 
464
  spider_free_trx_conn(trx, TRUE);
 
465
  spider_free_trx_alter_table(trx);
 
466
  hash_free(&trx->trx_conn_hash);
 
467
  hash_free(&trx->trx_another_conn_hash);
 
468
  hash_free(&trx->trx_alter_table_hash);
 
469
  DBUG_RETURN(0);
 
470
}
 
471
 
 
472
SPIDER_TRX *spider_get_trx(
 
473
  const THD *thd,
 
474
  int *error_num
 
475
) {
 
476
  SPIDER_TRX *trx;
 
477
  DBUG_ENTER("spider_get_trx");
 
478
 
 
479
  if (
 
480
    !thd ||
 
481
    !(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr))
 
482
  ) {
 
483
    DBUG_PRINT("info",("spider create new trx"));
 
484
    if (!(trx = (SPIDER_TRX *)
 
485
          my_malloc(sizeof(*trx), MYF(MY_WME | MY_ZEROFILL)))
 
486
    )
 
487
      goto error_alloc_trx;
 
488
 
 
489
    if (
 
490
      hash_init(&trx->trx_conn_hash, system_charset_info, 32, 0, 0,
 
491
                   (hash_get_key) spider_conn_get_key, 0, 0)
 
492
    )
 
493
      goto error_init_hash;
 
494
 
 
495
    if (
 
496
      hash_init(&trx->trx_another_conn_hash, system_charset_info, 32, 0, 0,
 
497
                   (hash_get_key) spider_conn_get_key, 0, 0)
 
498
    )
 
499
      goto error_init_another_hash;
 
500
 
 
501
    if (
 
502
      hash_init(&trx->trx_alter_table_hash, system_charset_info, 32, 0, 0,
 
503
                   (hash_get_key) spider_alter_tbl_get_key, 0, 0)
 
504
    )
 
505
      goto error_init_alter_hash;
 
506
 
 
507
    trx->thd = (THD*) thd;
 
508
    trx->spider_thread_id = spider_thread_id++;
 
509
    trx->trx_conn_adjustment = 1;
 
510
 
 
511
    if (thd)
 
512
      thd_set_ha_data(thd, spider_hton_ptr, trx);
 
513
  }
 
514
 
 
515
  DBUG_PRINT("info",("spider trx=%x", trx));
 
516
  DBUG_RETURN(trx);
 
517
 
 
518
error_init_alter_hash:
 
519
  hash_free(&trx->trx_another_conn_hash);
 
520
error_init_another_hash:
 
521
  hash_free(&trx->trx_conn_hash);
 
522
error_init_hash:
 
523
  my_free(trx, MYF(0));
 
524
 
 
525
error_alloc_trx:
 
526
  *error_num = HA_ERR_OUT_OF_MEM;
 
527
  DBUG_RETURN(NULL);
 
528
}
 
529
 
 
530
int spider_free_trx(
 
531
  SPIDER_TRX *trx
 
532
) {
 
533
  DBUG_ENTER("spider_free_trx");
 
534
  if (trx->thd)
 
535
    thd_set_ha_data(trx->thd, spider_hton_ptr, NULL);
 
536
  spider_free_trx_alloc(trx);
 
537
  my_free(trx, MYF(0));
 
538
  DBUG_RETURN(0);
 
539
}
 
540
 
 
541
int spider_check_and_set_trx_isolation(
 
542
  SPIDER_CONN *conn
 
543
) {
 
544
  int error_num;
 
545
  int trx_isolation;
 
546
  DBUG_ENTER("spider_check_and_set_trx_isolation");
 
547
 
 
548
  trx_isolation = thd_tx_isolation(conn->thd);
 
549
  DBUG_PRINT("info",("spider local trx_isolation=%d", trx_isolation));
 
550
  DBUG_PRINT("info",("spider conn->trx_isolation=%d", conn->trx_isolation));
 
551
  if (conn->trx_isolation != trx_isolation)
 
552
  {
 
553
    if ((error_num = spider_db_set_trx_isolation(conn, trx_isolation)))
 
554
      DBUG_RETURN(error_num);
 
555
    conn->trx_isolation = trx_isolation;
 
556
  }
 
557
  DBUG_RETURN(0);
 
558
}
 
559
 
 
560
int spider_check_and_set_autocommit(
 
561
  THD *thd,
 
562
  SPIDER_CONN *conn
 
563
) {
 
564
  int error_num;
 
565
  bool autocommit;
 
566
  DBUG_ENTER("spider_check_and_set_autocommit");
 
567
 
 
568
  autocommit = !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT);
 
569
  if (autocommit && conn->autocommit != 1)
 
570
  {
 
571
    if ((error_num = spider_db_set_autocommit(conn, TRUE)))
 
572
      DBUG_RETURN(error_num);
 
573
    conn->autocommit = 1;
 
574
  } else if (!autocommit && conn->autocommit != 0)
 
575
  {
 
576
    if ((error_num = spider_db_set_autocommit(conn, FALSE)))
 
577
      DBUG_RETURN(error_num);
 
578
    conn->autocommit = 0;
 
579
  }
 
580
  DBUG_RETURN(0);
 
581
}
 
582
 
 
583
int spider_check_and_set_sql_log_off(
 
584
  THD *thd,
 
585
  SPIDER_CONN *conn
 
586
) {
 
587
  int error_num;
 
588
  bool internal_sql_log_off;
 
589
  DBUG_ENTER("spider_check_and_set_sql_log_off");
 
590
 
 
591
  internal_sql_log_off = THDVAR(thd, internal_sql_log_off);
 
592
  if (internal_sql_log_off && conn->sql_log_off != 1)
 
593
  {
 
594
    if ((error_num = spider_db_set_sql_log_off(conn, TRUE)))
 
595
      DBUG_RETURN(error_num);
 
596
    conn->sql_log_off = 1;
 
597
  } else if (!internal_sql_log_off && conn->sql_log_off != 0)
 
598
  {
 
599
    if ((error_num = spider_db_set_sql_log_off(conn, FALSE)))
 
600
      DBUG_RETURN(error_num);
 
601
    conn->sql_log_off = 0;
 
602
  }
 
603
  DBUG_RETURN(0);
 
604
}
 
605
 
 
606
int spider_xa_lock(
 
607
  XID_STATE *xid_state
 
608
) {
 
609
  int error_num;
 
610
  DBUG_ENTER("spider_xa_lock");
 
611
  pthread_mutex_lock(&LOCK_xid_cache);
 
612
  if (hash_search(&xid_cache,
 
613
    xid_state->xid.key(), xid_state->xid.key_length()))
 
614
  {
 
615
    error_num = ER_SPIDER_XA_LOCKED_NUM;
 
616
    goto error;
 
617
  }
 
618
  if (my_hash_insert(&xid_cache, (uchar*)xid_state))
 
619
  {
 
620
    error_num = HA_ERR_OUT_OF_MEM;
 
621
    goto error;
 
622
  }
 
623
  pthread_mutex_unlock(&LOCK_xid_cache);
 
624
  DBUG_RETURN(0);
 
625
 
 
626
error:
 
627
  pthread_mutex_unlock(&LOCK_xid_cache);
 
628
  DBUG_RETURN(error_num);
 
629
}
 
630
 
 
631
int spider_xa_unlock(
 
632
  XID_STATE *xid_state
 
633
) {
 
634
  DBUG_ENTER("spider_xa_unlock");
 
635
  pthread_mutex_lock(&LOCK_xid_cache);
 
636
  hash_delete(&xid_cache, (uchar *)xid_state);
 
637
  pthread_mutex_unlock(&LOCK_xid_cache);
 
638
  DBUG_RETURN(0);
 
639
}
 
640
 
 
641
int spider_start_internal_consistent_snapshot(
 
642
  SPIDER_TRX *trx,
 
643
  SPIDER_CONN *conn
 
644
) {
 
645
  int error_num;
 
646
  DBUG_ENTER("spider_start_internal_consistent_snapshot");
 
647
  if (trx->trx_consistent_snapshot)
 
648
    DBUG_RETURN(spider_db_consistent_snapshot(conn));
 
649
  DBUG_RETURN(0);
 
650
}
 
651
 
 
652
int spider_internal_start_trx(
 
653
  ha_spider *spider
 
654
) {
 
655
  int error_num;
 
656
  SPIDER_TRX *trx = spider->trx;
 
657
  SPIDER_CONN *conn = spider->conn;
 
658
  bool sync_autocommit = THDVAR(trx->thd, sync_autocommit);
 
659
  double ping_interval_at_trx_start =
 
660
    THDVAR(trx->thd, ping_interval_at_trx_start);
 
661
  bool xa_lock = FALSE;
 
662
  time_t tmp_time = (time_t) time((time_t*) 0);
 
663
  DBUG_ENTER("spider_internal_start_trx");
 
664
 
 
665
  if (
 
666
    (
 
667
      conn->server_lost ||
 
668
      difftime(tmp_time, conn->ping_time) >= ping_interval_at_trx_start
 
669
    ) &&
 
670
    (error_num = spider_db_ping(spider))
 
671
  )
 
672
    goto error;
 
673
  conn->disable_reconnect = TRUE;
 
674
  if (!trx->trx_start)
 
675
  {
 
676
    if (!trx->trx_consistent_snapshot)
 
677
    {
 
678
      trx->use_consistent_snapshot = THDVAR(trx->thd, use_consistent_snapshot);
 
679
      trx->internal_xa = THDVAR(trx->thd, internal_xa);
 
680
      trx->internal_xa_snapshot = THDVAR(trx->thd, internal_xa_snapshot);
 
681
    }
 
682
  }
 
683
  if (
 
684
    (error_num = spider_check_and_set_sql_log_off(trx->thd, conn)) ||
 
685
    (sync_autocommit &&
 
686
      (error_num = spider_check_and_set_autocommit(trx->thd, conn)))
 
687
  )
 
688
    goto error;
 
689
  if (trx->trx_consistent_snapshot)
 
690
  {
 
691
    if (trx->internal_xa && trx->internal_xa_snapshot < 2)
 
692
    {
 
693
      error_num = ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM;
 
694
      my_message(error_num, ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR,
 
695
        MYF(0));
 
696
      goto error;
 
697
    } else if (!trx->internal_xa || trx->internal_xa_snapshot == 2)
 
698
    {
 
699
      if ((error_num = spider_start_internal_consistent_snapshot(trx, conn)))
 
700
        goto error;
 
701
    }
 
702
  }
 
703
  if (!trx->trx_start)
 
704
  {
 
705
    if (
 
706
      trx->thd->transaction.xid_state.xa_state == XA_ACTIVE &&
 
707
      spider_support_xa
 
708
    ) {
 
709
      trx->trx_xa = TRUE;
 
710
      thd_get_xid(trx->thd, (MYSQL_XID*) &trx->xid);
 
711
    }
 
712
 
 
713
    if (!trx->trx_xa && trx->internal_xa)
 
714
    {
 
715
      if (!trx->trx_consistent_snapshot || trx->internal_xa_snapshot == 3)
 
716
      {
 
717
        trx->trx_xa = TRUE;
 
718
        trx->xid.formatID = 1;
 
719
        trx->xid.gtrid_length
 
720
          = my_sprintf(trx->xid.data,
 
721
          (trx->xid.data, "%lx", thd_get_thread_id(trx->thd)));
 
722
        trx->xid.bqual_length
 
723
          = my_sprintf(trx->xid.data + trx->xid.gtrid_length,
 
724
          (trx->xid.data + trx->xid.gtrid_length, "%x",
 
725
          trx->thd->server_id));
 
726
 
 
727
        trx->internal_xid_state.xa_state = XA_ACTIVE;
 
728
        trx->internal_xid_state.xid.set(&trx->xid);
 
729
        trx->internal_xid_state.in_thd = 1;
 
730
        while ((error_num = spider_xa_lock(&trx->internal_xid_state)))
 
731
        {
 
732
          if (error_num != ER_SPIDER_XA_LOCKED_NUM)
 
733
            goto error;
 
734
          else if (trx->xid.formatID == 0)
 
735
          {
 
736
            my_message(error_num, ER_SPIDER_XA_LOCKED_STR, MYF(0));
 
737
            goto error;
 
738
          }
 
739
          /* retry */
 
740
          trx->xid.formatID++;
 
741
          trx->internal_xid_state.xid.set(&trx->xid);
 
742
        }
 
743
        xa_lock = TRUE;
 
744
      }
 
745
    }
 
746
 
 
747
    if (!trx->trx_consistent_snapshot)
 
748
    {
 
749
      trans_register_ha(trx->thd, FALSE, spider_hton_ptr);
 
750
      if (thd_test_options(trx->thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
751
        trans_register_ha(trx->thd, TRUE, spider_hton_ptr);
 
752
    }
 
753
    trx->trx_start = TRUE;
 
754
  }
 
755
 
 
756
  DBUG_PRINT("info",("spider sync_autocommit = %d", sync_autocommit));
 
757
  DBUG_PRINT("info",("spider conn->semi_trx_chk = %d", conn->semi_trx_chk));
 
758
  DBUG_PRINT("info",("spider conn->table_lock = %d", conn->table_lock));
 
759
  DBUG_PRINT("info",("spider conn->autocommit = %d", conn->autocommit));
 
760
  DBUG_PRINT("info",("spider semi_trx = %d", THDVAR(trx->thd, semi_trx)));
 
761
  conn->semi_trx = FALSE;
 
762
  if (conn->table_lock == 3)
 
763
  {
 
764
    DBUG_PRINT("info",("spider conn->table_lock == 3"));
 
765
    conn->disable_xa = TRUE;
 
766
  } else if (trx->trx_xa)
 
767
  {
 
768
    DBUG_PRINT("info",("spider trx->trx_xa"));
 
769
    if (
 
770
      sync_autocommit &&
 
771
      conn->semi_trx_chk &&
 
772
      !conn->table_lock &&
 
773
      conn->autocommit == 1 &&
 
774
      THDVAR(trx->thd, semi_trx)
 
775
    ) {
 
776
      DBUG_PRINT("info",("spider semi_trx is set"));
 
777
      conn->semi_trx = TRUE;
 
778
    }
 
779
    if ((error_num = spider_db_xa_start(conn, &trx->xid)))
 
780
      goto error_start_trx;
 
781
    conn->disable_xa = FALSE;
 
782
  } else if (
 
783
    !trx->trx_consistent_snapshot &&
 
784
    !thd_test_options(trx->thd, OPTION_BEGIN) &&
 
785
    sync_autocommit &&
 
786
    conn->semi_trx_chk &&
 
787
    !conn->table_lock &&
 
788
    conn->autocommit == 1 &&
 
789
    THDVAR(trx->thd, semi_trx)
 
790
  ) {
 
791
    DBUG_PRINT("info",("spider semi_trx is set"));
 
792
    if ((error_num = spider_db_start_transaction(conn)))
 
793
      goto error_start_trx;
 
794
    conn->semi_trx = TRUE;
 
795
  } else if (
 
796
    !trx->trx_consistent_snapshot &&
 
797
    thd_test_options(trx->thd, OPTION_BEGIN)
 
798
  ) {
 
799
    DBUG_PRINT("info",("spider start transaction"));
 
800
    if ((error_num = spider_db_start_transaction(conn)))
 
801
      goto error_start_trx;
 
802
  }
 
803
 
 
804
  conn->join_trx = 1;
 
805
  if (trx->join_trx_top)
 
806
    spider_tree_insert(trx->join_trx_top, conn);
 
807
  else {
 
808
    conn->p_small = NULL;
 
809
    conn->p_big = NULL;
 
810
    conn->c_small = NULL;
 
811
    conn->c_big = NULL;
 
812
    trx->join_trx_top = conn;
 
813
  }
 
814
  DBUG_RETURN(0);
 
815
 
 
816
error_start_trx:
 
817
error:
 
818
  if (xa_lock)
 
819
    spider_xa_unlock(&trx->internal_xid_state);
 
820
  DBUG_RETURN(error_num);
 
821
}
 
822
 
 
823
int spider_internal_xa_commit(
 
824
  THD* thd,
 
825
  SPIDER_TRX *trx,
 
826
  XID* xid,
 
827
  TABLE *table_xa,
 
828
  TABLE *table_xa_member
 
829
) {
 
830
  int error_num;
 
831
  char xa_key[MAX_KEY_LENGTH];
 
832
  char xa_member_key[MAX_KEY_LENGTH];
 
833
  SPIDER_CONN *conn;
 
834
  uint force_commit = THDVAR(thd, force_commit);
 
835
  MEM_ROOT mem_root;
 
836
  Open_tables_state open_tables_backup;
 
837
  bool table_xa_opened = FALSE;
 
838
  bool table_xa_member_opened = FALSE;
 
839
  DBUG_ENTER("spider_internal_xa_commit");
 
840
 
 
841
  /*
 
842
    select
 
843
      status
 
844
    from
 
845
      mysql.spider_xa
 
846
    where
 
847
      format_id = xid->format_id and
 
848
      gtrid_length = xid->gtrid_length and
 
849
      data = xid->data
 
850
  */
 
851
  if (
 
852
    !(table_xa = spider_open_sys_table(
 
853
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
854
      TRUE, &open_tables_backup, TRUE, &error_num))
 
855
  )
 
856
    goto error_open_table;
 
857
  table_xa_opened = TRUE;
 
858
  spider_store_xa_pk(table_xa, &trx->xid);
 
859
  if (
 
860
    (error_num = spider_check_sys_table(table_xa, xa_key))
 
861
  ) {
 
862
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
863
    {
 
864
      table_xa->file->print_error(error_num, MYF(0));
 
865
      goto error;
 
866
    }
 
867
    my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
 
868
      MYF(0));
 
869
    error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
 
870
    goto error;
 
871
  }
 
872
  init_alloc_root(&mem_root, 4096, 0);
 
873
  if (
 
874
    force_commit != 2 &&
 
875
    (error_num = spider_check_sys_xa_status(
 
876
      table_xa,
 
877
      SPIDER_SYS_XA_PREPARED_STR,
 
878
      SPIDER_SYS_XA_COMMIT_STR,
 
879
      NULL,
 
880
      ER_SPIDER_XA_NOT_PREPARED_NUM,
 
881
      &mem_root))
 
882
  ) {
 
883
    free_root(&mem_root, MYF(0));
 
884
    if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
 
885
      my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
 
886
    goto error;
 
887
  }
 
888
  free_root(&mem_root, MYF(0));
 
889
 
 
890
  /*
 
891
    update
 
892
      mysql.spider_xa
 
893
    set
 
894
      status = 'COMMIT'
 
895
    where
 
896
      format_id = trx->xid.format_id and
 
897
      gtrid_length = trx->xid.gtrid_length and
 
898
      data = trx->xid.data
 
899
  */
 
900
  if (
 
901
    (error_num = spider_update_xa(
 
902
      table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR))
 
903
  )
 
904
    goto error;
 
905
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
906
  table_xa_opened = FALSE;
 
907
 
 
908
  if ((conn = spider_tree_first(trx->join_trx_top)))
 
909
  {
 
910
    do {
 
911
      if (conn->join_trx)
 
912
      {
 
913
        if ((error_num = spider_db_xa_commit(conn, &trx->xid)))
 
914
        {
 
915
          if (force_commit == 0 ||
 
916
            (force_commit == 1 && error_num != ER_XAER_NOTA))
 
917
            DBUG_RETURN(error_num);
 
918
        }
 
919
        if ((error_num = spider_end_trx(trx, conn)))
 
920
          DBUG_RETURN(error_num);
 
921
        conn->join_trx = 0;
 
922
      }
 
923
    } while ((conn = spider_tree_next(conn)));
 
924
    trx->join_trx_top = NULL;
 
925
  }
 
926
 
 
927
  /*
 
928
    delete from
 
929
      mysql.spider_xa_member
 
930
    where
 
931
      format_id = xid->format_id and
 
932
      gtrid_length = xid->gtrid_length and
 
933
      data = xid->data
 
934
  */
 
935
  if (
 
936
    !(table_xa_member = spider_open_sys_table(
 
937
      thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
 
938
      SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
 
939
      &error_num))
 
940
  )
 
941
    goto error_open_table;
 
942
  table_xa_member_opened = TRUE;
 
943
  if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
 
944
    goto error;
 
945
  spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
946
  table_xa_member_opened = FALSE;
 
947
 
 
948
  /*
 
949
    delete from
 
950
      mysql.spider_xa
 
951
    where
 
952
      format_id = xid->format_id and
 
953
      gtrid_length = xid->gtrid_length and
 
954
      data = xid->data
 
955
  */
 
956
  if (
 
957
    !(table_xa = spider_open_sys_table(
 
958
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
959
      TRUE, &open_tables_backup, TRUE, &error_num))
 
960
  )
 
961
    goto error_open_table;
 
962
  table_xa_opened = TRUE;
 
963
  if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
 
964
    goto error;
 
965
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
966
  table_xa_opened = FALSE;
 
967
  spider_xa_unlock(&trx->internal_xid_state);
 
968
  trx->internal_xid_state.xa_state = XA_NOTR;
 
969
  DBUG_RETURN(0);
 
970
 
 
971
error:
 
972
  if (table_xa_opened)
 
973
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
974
  if (table_xa_member_opened)
 
975
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
976
error_open_table:
 
977
  DBUG_RETURN(error_num);
 
978
}
 
979
 
 
980
int spider_internal_xa_rollback(
 
981
  THD* thd,
 
982
  SPIDER_TRX *trx
 
983
) {
 
984
  int error_num;
 
985
  TABLE *table_xa, *table_xa_member;
 
986
  char xa_key[MAX_KEY_LENGTH];
 
987
  char xa_member_key[MAX_KEY_LENGTH];
 
988
  SPIDER_CONN *conn;
 
989
  uint force_commit = THDVAR(thd, force_commit);
 
990
  MEM_ROOT mem_root;
 
991
  Open_tables_state open_tables_backup;
 
992
  bool server_lost = FALSE;
 
993
  bool prepared = (thd->transaction.xid_state.xa_state == XA_PREPARED);
 
994
  bool table_xa_opened = FALSE;
 
995
  bool table_xa_member_opened = FALSE;
 
996
  DBUG_ENTER("spider_internal_xa_rollback");
 
997
 
 
998
  if (prepared)
 
999
  {
 
1000
    /*
 
1001
      select
 
1002
        status
 
1003
      from
 
1004
        mysql.spider_xa
 
1005
      where
 
1006
        format_id = xid->format_id and
 
1007
        gtrid_length = xid->gtrid_length and
 
1008
        data = xid->data
 
1009
    */
 
1010
    if (
 
1011
      !(table_xa = spider_open_sys_table(
 
1012
        thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1013
        TRUE, &open_tables_backup, TRUE, &error_num))
 
1014
    )
 
1015
      goto error_open_table;
 
1016
    table_xa_opened = TRUE;
 
1017
    spider_store_xa_pk(table_xa, &trx->xid);
 
1018
    if (
 
1019
      (error_num = spider_check_sys_table(table_xa, xa_key))
 
1020
    ) {
 
1021
      if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
1022
      {
 
1023
        table_xa->file->print_error(error_num, MYF(0));
 
1024
        goto error;
 
1025
      }
 
1026
      my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
 
1027
        MYF(0));
 
1028
      error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
 
1029
      goto error;
 
1030
    }
 
1031
    init_alloc_root(&mem_root, 4096, 0);
 
1032
    if (
 
1033
      force_commit != 2 &&
 
1034
      (error_num = spider_check_sys_xa_status(
 
1035
        table_xa,
 
1036
        SPIDER_SYS_XA_PREPARED_STR,
 
1037
        SPIDER_SYS_XA_ROLLBACK_STR,
 
1038
        NULL,
 
1039
        ER_SPIDER_XA_NOT_PREPARED_NUM,
 
1040
        &mem_root))
 
1041
    ) {
 
1042
      free_root(&mem_root, MYF(0));
 
1043
      if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
 
1044
        my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
 
1045
      goto error;
 
1046
    }
 
1047
    free_root(&mem_root, MYF(0));
 
1048
 
 
1049
    /*
 
1050
      update
 
1051
        mysql.spider_xa
 
1052
      set
 
1053
        status = 'COMMIT'
 
1054
      where
 
1055
        format_id = trx->xid.format_id and
 
1056
        gtrid_length = trx->xid.gtrid_length and
 
1057
        data = trx->xid.data
 
1058
    */
 
1059
    if (
 
1060
      (error_num = spider_update_xa(
 
1061
        table_xa, &trx->xid, SPIDER_SYS_XA_ROLLBACK_STR))
 
1062
    )
 
1063
      goto error;
 
1064
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1065
    table_xa_opened = FALSE;
 
1066
  }
 
1067
 
 
1068
  if ((conn = spider_tree_first(trx->join_trx_top)))
 
1069
  {
 
1070
    do {
 
1071
      if (conn->join_trx)
 
1072
      {
 
1073
        if (conn->disable_xa)
 
1074
        {
 
1075
          if (conn->table_lock != 3 && !prepared)
 
1076
          {
 
1077
            if (
 
1078
              !conn->server_lost &&
 
1079
              (error_num = spider_db_rollback(conn))
 
1080
            )
 
1081
              DBUG_RETURN(error_num);
 
1082
          }
 
1083
        } else {
 
1084
          if (!conn->server_lost)
 
1085
          {
 
1086
            if (
 
1087
              !prepared &&
 
1088
              (error_num = spider_db_xa_end(conn, &trx->xid))
 
1089
            ) {
 
1090
              if (force_commit == 0 ||
 
1091
                (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1092
                DBUG_RETURN(error_num);
 
1093
            }
 
1094
            if ((error_num = spider_db_xa_rollback(conn, &trx->xid)))
 
1095
            {
 
1096
              if (force_commit == 0 ||
 
1097
                (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1098
                DBUG_RETURN(error_num);
 
1099
            }
 
1100
          }
 
1101
        }
 
1102
        if ((error_num = spider_end_trx(trx, conn)))
 
1103
          DBUG_RETURN(error_num);
 
1104
        conn->join_trx = 0;
 
1105
        if (conn->server_lost)
 
1106
          server_lost = TRUE;
 
1107
      }
 
1108
    } while ((conn = spider_tree_next(conn)));
 
1109
    trx->join_trx_top = NULL;
 
1110
  }
 
1111
 
 
1112
  if (
 
1113
    prepared &&
 
1114
    !server_lost
 
1115
  ) {
 
1116
    /*
 
1117
      delete from
 
1118
        mysql.spider_xa_member
 
1119
      where
 
1120
        format_id = xid->format_id and
 
1121
        gtrid_length = xid->gtrid_length and
 
1122
        data = xid->data
 
1123
    */
 
1124
    if (
 
1125
      !(table_xa_member = spider_open_sys_table(
 
1126
        thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
 
1127
        SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
 
1128
        &error_num))
 
1129
    )
 
1130
      goto error_open_table;
 
1131
    table_xa_member_opened = TRUE;
 
1132
    if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
 
1133
      goto error;
 
1134
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1135
    table_xa_member_opened = FALSE;
 
1136
 
 
1137
    /*
 
1138
      delete from
 
1139
        mysql.spider_xa
 
1140
      where
 
1141
        format_id = xid->format_id and
 
1142
        gtrid_length = xid->gtrid_length and
 
1143
        data = xid->data
 
1144
    */
 
1145
    if (
 
1146
      !(table_xa = spider_open_sys_table(
 
1147
        thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1148
        TRUE, &open_tables_backup, TRUE, &error_num))
 
1149
    )
 
1150
      goto error_open_table;
 
1151
    table_xa_opened = TRUE;
 
1152
    if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
 
1153
      goto error;
 
1154
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1155
    table_xa_opened = FALSE;
 
1156
  }
 
1157
  spider_xa_unlock(&trx->internal_xid_state);
 
1158
  trx->internal_xid_state.xa_state = XA_NOTR;
 
1159
  DBUG_RETURN(0);
 
1160
 
 
1161
error:
 
1162
  if (table_xa_opened)
 
1163
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1164
  if (table_xa_member_opened)
 
1165
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1166
error_open_table:
 
1167
  DBUG_RETURN(error_num);
 
1168
}
 
1169
 
 
1170
int spider_internal_xa_prepare(
 
1171
  THD* thd,
 
1172
  SPIDER_TRX *trx,
 
1173
  TABLE *table_xa,
 
1174
  TABLE *table_xa_member,
 
1175
  bool internal_xa
 
1176
) {
 
1177
  char table_xa_key[MAX_KEY_LENGTH];
 
1178
  int table_xa_key_length;
 
1179
  int error_num;
 
1180
  SPIDER_CONN *conn;
 
1181
  uint force_commit = THDVAR(thd, force_commit);
 
1182
  Open_tables_state open_tables_backup;
 
1183
  bool table_xa_opened = FALSE;
 
1184
  bool table_xa_member_opened = FALSE;
 
1185
  DBUG_ENTER("spider_internal_xa_prepare");
 
1186
  /*
 
1187
    insert into mysql.spider_xa
 
1188
      (format_id, gtrid_length, bqual_length, data, status) values
 
1189
      (trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length,
 
1190
      trx->xid.data, 'NOT YET')
 
1191
  */
 
1192
  if (
 
1193
    !(table_xa = spider_open_sys_table(
 
1194
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1195
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1196
  )
 
1197
    goto error_open_table;
 
1198
  table_xa_opened = TRUE;
 
1199
  if (
 
1200
    (error_num = spider_insert_xa(
 
1201
      table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR))
 
1202
  )
 
1203
    goto error;
 
1204
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1205
  table_xa_opened = FALSE;
 
1206
 
 
1207
  if (
 
1208
    !(table_xa_member = spider_open_sys_table(
 
1209
      thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
 
1210
      SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
 
1211
      &error_num))
 
1212
  )
 
1213
    goto error_open_table;
 
1214
  table_xa_member_opened = TRUE;
 
1215
  if ((conn = spider_tree_first(trx->join_trx_top)))
 
1216
  {
 
1217
    do {
 
1218
      if (conn->disable_xa)
 
1219
      {
 
1220
        if (conn->table_lock != 3)
 
1221
        {
 
1222
          if ((error_num = spider_db_rollback(conn)))
 
1223
            goto error;
 
1224
        }
 
1225
        if ((error_num = spider_end_trx(trx, conn)))
 
1226
          DBUG_RETURN(error_num);
 
1227
        conn->join_trx = 0;
 
1228
      } else {
 
1229
        /*
 
1230
          insert into mysql.spider_xa_member
 
1231
            (format_id, gtrid_length, bqual_length, data,
 
1232
            scheme, host, port, socket, username, password) values
 
1233
            (trx->xid.format_id, trx->xid.gtrid_length,
 
1234
            trx->xid.bqual_length, trx->xid.data,
 
1235
            conn->tgt_wrapper,
 
1236
            conn->tgt_host,
 
1237
            conn->tgt_port,
 
1238
            conn->tgt_socket,
 
1239
            conn->tgt_username,
 
1240
            conn->tgt_password)
 
1241
        */
 
1242
        if (
 
1243
          (error_num = spider_insert_xa_member(
 
1244
            table_xa_member, &trx->xid, conn))
 
1245
        )
 
1246
          goto error;
 
1247
 
 
1248
        if ((error_num = spider_db_xa_end(conn, &trx->xid)))
 
1249
        {
 
1250
          if (force_commit == 0 ||
 
1251
            (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1252
            goto error;
 
1253
        }
 
1254
        if ((error_num = spider_db_xa_prepare(conn, &trx->xid)))
 
1255
        {
 
1256
          if (force_commit == 0 ||
 
1257
            (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1258
            goto error;
 
1259
        }
 
1260
/*
 
1261
        if (!internal_xa)
 
1262
        {
 
1263
          if ((error_num = spider_end_trx(trx, conn)))
 
1264
            DBUG_RETURN(error_num);
 
1265
          conn->join_trx = 0;
 
1266
        }
 
1267
*/
 
1268
      }
 
1269
    } while ((conn = spider_tree_next(conn)));
 
1270
/*
 
1271
    if (!internal_xa)
 
1272
      trx->join_trx_top = NULL;
 
1273
*/
 
1274
  }
 
1275
  spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1276
  table_xa_member_opened = FALSE;
 
1277
 
 
1278
  /*
 
1279
    update
 
1280
      mysql.spider_xa
 
1281
    set
 
1282
      status = 'PREPARED'
 
1283
    where
 
1284
      format_id = trx->xid.format_id and
 
1285
      gtrid_length = trx->xid.gtrid_length and
 
1286
      data = trx->xid.data
 
1287
  */
 
1288
  if (
 
1289
    !(table_xa = spider_open_sys_table(
 
1290
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1291
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1292
  )
 
1293
    goto error_open_table;
 
1294
  table_xa_opened = TRUE;
 
1295
  if (
 
1296
    (error_num = spider_update_xa(
 
1297
      table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR))
 
1298
  )
 
1299
    goto error;
 
1300
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1301
  table_xa_opened = FALSE;
 
1302
  if (internal_xa)
 
1303
    trx->internal_xid_state.xa_state = XA_PREPARED;
 
1304
  DBUG_RETURN(0);
 
1305
 
 
1306
error:
 
1307
  if (table_xa_opened)
 
1308
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1309
  if (table_xa_member_opened)
 
1310
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1311
error_open_table:
 
1312
  DBUG_RETURN(error_num);
 
1313
}
 
1314
 
 
1315
int spider_internal_xa_recover(
 
1316
  THD* thd,
 
1317
  XID* xid_list,
 
1318
  uint len
 
1319
) {
 
1320
  TABLE *table_xa;
 
1321
  int cnt = 0;
 
1322
  char xa_key[MAX_KEY_LENGTH];
 
1323
  MEM_ROOT mem_root;
 
1324
  Open_tables_state open_tables_backup;
 
1325
  DBUG_ENTER("spider_internal_xa_recover");
 
1326
  /*
 
1327
    select
 
1328
      format_id,
 
1329
      gtrid_length,
 
1330
      bqual_length,
 
1331
      data
 
1332
    from
 
1333
      mysql.spider_xa
 
1334
    where
 
1335
      status = 'PREPARED'
 
1336
  */
 
1337
  if (
 
1338
    !(table_xa = spider_open_sys_table(
 
1339
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1340
      FALSE, &open_tables_backup, TRUE, &my_errno))
 
1341
  )
 
1342
    goto error_open_table;
 
1343
  spider_store_xa_status(table_xa, SPIDER_SYS_XA_PREPARED_STR);
 
1344
  if (
 
1345
    (my_errno = spider_get_sys_table_by_idx(table_xa, xa_key, 1,
 
1346
    SPIDER_SYS_XA_IDX1_COL_CNT))
 
1347
  ) {
 
1348
    spider_sys_index_end(table_xa);
 
1349
    if (my_errno != HA_ERR_KEY_NOT_FOUND && my_errno != HA_ERR_END_OF_FILE)
 
1350
    {
 
1351
      table_xa->file->print_error(my_errno, MYF(0));
 
1352
      goto error;
 
1353
    }
 
1354
    goto error;
 
1355
  }
 
1356
 
 
1357
  init_alloc_root(&mem_root, 4096, 0);
 
1358
  do {
 
1359
    spider_get_sys_xid(table_xa, &xid_list[cnt], &mem_root);
 
1360
    cnt++;
 
1361
    my_errno = spider_sys_index_next_same(table_xa, xa_key);
 
1362
  } while (my_errno == 0 && cnt < len);
 
1363
  free_root(&mem_root, MYF(0));
 
1364
  spider_sys_index_end(table_xa);
 
1365
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1366
  DBUG_RETURN(cnt);
 
1367
 
 
1368
error:
 
1369
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1370
error_open_table:
 
1371
  DBUG_RETURN(0);
 
1372
}
 
1373
 
 
1374
int spider_initinal_xa_recover(
 
1375
  XID* xid_list,
 
1376
  uint len
 
1377
) {
 
1378
  int error_num;
 
1379
  static THD *thd = NULL;
 
1380
  static TABLE *table_xa = NULL;
 
1381
  static READ_RECORD *read_record = NULL;
 
1382
  static Open_tables_state *open_tables_backup = NULL;
 
1383
  int cnt = 0;
 
1384
  MEM_ROOT mem_root;
 
1385
  DBUG_ENTER("spider_initinal_xa_recover");
 
1386
  if (!open_tables_backup)
 
1387
  {
 
1388
    if (!(open_tables_backup = new Open_tables_state))
 
1389
    {
 
1390
      error_num = HA_ERR_OUT_OF_MEM;
 
1391
      goto error_create_state;
 
1392
    }
 
1393
  }
 
1394
  if (!read_record)
 
1395
  {
 
1396
    if (!(read_record = new READ_RECORD))
 
1397
    {
 
1398
      error_num = HA_ERR_OUT_OF_MEM;
 
1399
      goto error_create_read_record;
 
1400
    }
 
1401
  }
 
1402
 
 
1403
  if (!thd)
 
1404
  {
 
1405
    if (!(thd = spider_create_tmp_thd()))
 
1406
    {
 
1407
      error_num = HA_ERR_OUT_OF_MEM;
 
1408
      goto error_create_thd;
 
1409
    }
 
1410
  }
 
1411
 
 
1412
  /*
 
1413
    select
 
1414
      format_id,
 
1415
      gtrid_length,
 
1416
      bqual_length,
 
1417
      data
 
1418
    from
 
1419
      mysql.spider_xa
 
1420
  */
 
1421
  if (!table_xa)
 
1422
  {
 
1423
    if (
 
1424
      !(table_xa = spider_open_sys_table(
 
1425
        thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1426
        FALSE, open_tables_backup, TRUE, &error_num))
 
1427
    )
 
1428
      goto error_open_table;
 
1429
    init_read_record(read_record, thd, table_xa, NULL, TRUE, FALSE, FALSE);
 
1430
  }
 
1431
  init_alloc_root(&mem_root, 4096, 0);
 
1432
  while ((!(read_record->read_record(read_record))) && cnt < len)
 
1433
  {
 
1434
    spider_get_sys_xid(table_xa, &xid_list[cnt], &mem_root);
 
1435
    cnt++;
 
1436
  }
 
1437
  free_root(&mem_root, MYF(0));
 
1438
 
 
1439
  if (cnt < len)
 
1440
  {
 
1441
    end_read_record(read_record);
 
1442
    spider_close_sys_table(thd, table_xa, open_tables_backup, TRUE);
 
1443
    table_xa = NULL;
 
1444
    spider_free_tmp_thd(thd);
 
1445
    thd = NULL;
 
1446
    delete read_record;
 
1447
    read_record = NULL;
 
1448
    delete open_tables_backup;
 
1449
    open_tables_backup = NULL;
 
1450
  }
 
1451
  DBUG_RETURN(cnt);
 
1452
 
 
1453
/*
 
1454
error:
 
1455
  end_read_record(&read_record_info);
 
1456
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1457
  table_xa = NULL;
 
1458
*/
 
1459
error_open_table:
 
1460
  spider_free_tmp_thd(thd);
 
1461
  thd = NULL;
 
1462
error_create_thd:
 
1463
  delete read_record;
 
1464
  read_record = NULL;
 
1465
error_create_read_record:
 
1466
  delete open_tables_backup;
 
1467
  open_tables_backup = NULL;
 
1468
error_create_state:
 
1469
  DBUG_RETURN(0);
 
1470
}
 
1471
 
 
1472
int spider_internal_xa_commit_by_xid(
 
1473
  THD* thd,
 
1474
  SPIDER_TRX *trx,
 
1475
  XID* xid
 
1476
) {
 
1477
  TABLE *table_xa, *table_xa_member;
 
1478
  int error_num;
 
1479
  char xa_key[MAX_KEY_LENGTH];
 
1480
  char xa_member_key[MAX_KEY_LENGTH];
 
1481
  SPIDER_SHARE tmp_share;
 
1482
  SPIDER_CONN *conn;
 
1483
  uint force_commit = THDVAR(thd, force_commit);
 
1484
  MEM_ROOT mem_root;
 
1485
  Open_tables_state open_tables_backup;
 
1486
  bool table_xa_opened = FALSE;
 
1487
  bool table_xa_member_opened = FALSE;
 
1488
  DBUG_ENTER("spider_internal_xa_commit_by_xid");
 
1489
  /*
 
1490
    select
 
1491
      status
 
1492
    from
 
1493
      mysql.spider_xa
 
1494
    where
 
1495
      format_id = xid->format_id and
 
1496
      gtrid_length = xid->gtrid_length and
 
1497
      data = xid->data
 
1498
  */
 
1499
  if (
 
1500
    !(table_xa = spider_open_sys_table(
 
1501
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1502
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1503
  )
 
1504
    goto error_open_table;
 
1505
  table_xa_opened = TRUE;
 
1506
  spider_store_xa_pk(table_xa, xid);
 
1507
  if (
 
1508
    (error_num = spider_check_sys_table(table_xa, xa_key))
 
1509
  ) {
 
1510
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
1511
    {
 
1512
      table_xa->file->print_error(error_num, MYF(0));
 
1513
      goto error;
 
1514
    }
 
1515
    my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
 
1516
      MYF(0));
 
1517
    error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
 
1518
    goto error;
 
1519
  }
 
1520
  init_alloc_root(&mem_root, 4096, 0);
 
1521
  if (
 
1522
    force_commit != 2 &&
 
1523
    (error_num = spider_check_sys_xa_status(
 
1524
      table_xa,
 
1525
      SPIDER_SYS_XA_PREPARED_STR,
 
1526
      SPIDER_SYS_XA_COMMIT_STR,
 
1527
      NULL,
 
1528
      ER_SPIDER_XA_NOT_PREPARED_NUM,
 
1529
      &mem_root))
 
1530
  ) {
 
1531
    free_root(&mem_root, MYF(0));
 
1532
    if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
 
1533
      my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
 
1534
    goto error;
 
1535
  }
 
1536
 
 
1537
  /*
 
1538
    update
 
1539
      mysql.spider_xa
 
1540
    set
 
1541
      status = 'COMMIT'
 
1542
    where
 
1543
      format_id = trx->xid.format_id and
 
1544
      gtrid_length = trx->xid.gtrid_length and
 
1545
      data = trx->xid.data
 
1546
  */
 
1547
  if (
 
1548
    (error_num = spider_update_xa(
 
1549
      table_xa, xid, SPIDER_SYS_XA_COMMIT_STR))
 
1550
  ) {
 
1551
    free_root(&mem_root, MYF(0));
 
1552
    goto error;
 
1553
  }
 
1554
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1555
  table_xa_opened = FALSE;
 
1556
 
 
1557
  /*
 
1558
    select
 
1559
      scheme tmp_share.tgt_wrapper,
 
1560
      host tmp_share.tgt_host,
 
1561
      port tmp_share.tgt_port,
 
1562
      socket tmp_share.tgt_socket,
 
1563
      username tmp_share.tgt_username,
 
1564
      password tmp_share.tgt_password
 
1565
    from
 
1566
      mysql.spider_xa_member
 
1567
    where
 
1568
      format_id = xid->format_id and
 
1569
      gtrid_length = xid->gtrid_length and
 
1570
      data = xid->data
 
1571
  */
 
1572
  if (
 
1573
    !(table_xa_member = spider_open_sys_table(
 
1574
      thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
 
1575
      SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
 
1576
      &error_num))
 
1577
  ) {
 
1578
    free_root(&mem_root, MYF(0));
 
1579
    goto error_open_table;
 
1580
  }
 
1581
  table_xa_member_opened = TRUE;
 
1582
  spider_store_xa_pk(table_xa_member, xid);
 
1583
  if (
 
1584
    (error_num = spider_get_sys_table_by_idx(table_xa_member, xa_member_key, 0,
 
1585
    SPIDER_SYS_XA_PK_COL_CNT))
 
1586
  ) {
 
1587
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
1588
    {
 
1589
      free_root(&mem_root, MYF(0));
 
1590
      table_xa_member->file->print_error(error_num, MYF(0));
 
1591
      goto error;
 
1592
    } else {
 
1593
      free_root(&mem_root, MYF(0));
 
1594
      spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1595
      table_xa_member_opened = FALSE;
 
1596
      goto xa_delete;
 
1597
    }
 
1598
  }
 
1599
 
 
1600
  memset(&tmp_share, 0, sizeof(SPIDER_SHARE));
 
1601
  do {
 
1602
    spider_get_sys_server_info(table_xa_member, &tmp_share, &mem_root);
 
1603
    if ((error_num = spider_create_conn_key(&tmp_share)))
 
1604
    {
 
1605
      spider_sys_index_end(table_xa_member);
 
1606
      free_root(&mem_root, MYF(0));
 
1607
      goto error;
 
1608
    }
 
1609
 
 
1610
    if (
 
1611
      (!(conn = spider_get_conn(
 
1612
      &tmp_share, trx, NULL, FALSE, FALSE, &error_num)) ||
 
1613
        (error_num = spider_db_xa_commit(conn, xid))) &&
 
1614
      (force_commit == 0 ||
 
1615
        (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1616
    ) {
 
1617
      spider_sys_index_end(table_xa_member);
 
1618
      spider_free_tmp_share_alloc(&tmp_share);
 
1619
      free_root(&mem_root, MYF(0));
 
1620
      goto error;
 
1621
    }
 
1622
    spider_free_tmp_share_alloc(&tmp_share);
 
1623
    error_num = spider_sys_index_next_same(table_xa_member, xa_member_key);
 
1624
  } while (error_num == 0);
 
1625
  if ((error_num = spider_sys_index_end(table_xa_member)))
 
1626
  {
 
1627
    free_root(&mem_root, MYF(0));
 
1628
    goto error;
 
1629
  }
 
1630
  free_root(&mem_root, MYF(0));
 
1631
  spider_free_trx_conn(trx, FALSE);
 
1632
 
 
1633
  /*
 
1634
    delete from
 
1635
      mysql.spider_xa_member
 
1636
    where
 
1637
      format_id = xid->format_id and
 
1638
      gtrid_length = xid->gtrid_length and
 
1639
      data = xid->data
 
1640
  */
 
1641
  if ((error_num = spider_delete_xa_member(table_xa_member, xid)))
 
1642
    goto error;
 
1643
  spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1644
  table_xa_member_opened = FALSE;
 
1645
 
 
1646
xa_delete:
 
1647
  /*
 
1648
    delete from
 
1649
      mysql.spider_xa
 
1650
    where
 
1651
      format_id = xid->format_id and
 
1652
      gtrid_length = xid->gtrid_length and
 
1653
      data = xid->data
 
1654
  */
 
1655
  if (
 
1656
    !(table_xa = spider_open_sys_table(
 
1657
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1658
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1659
  )
 
1660
    goto error_open_table;
 
1661
  table_xa_opened = TRUE;
 
1662
  if ((error_num = spider_delete_xa(table_xa, xid)))
 
1663
    goto error;
 
1664
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1665
  table_xa_opened = FALSE;
 
1666
  DBUG_RETURN(0);
 
1667
 
 
1668
error:
 
1669
  if (table_xa_opened)
 
1670
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1671
  if (table_xa_member_opened)
 
1672
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1673
error_open_table:
 
1674
  DBUG_RETURN(error_num);
 
1675
}
 
1676
 
 
1677
int spider_internal_xa_rollback_by_xid(
 
1678
  THD* thd,
 
1679
  SPIDER_TRX *trx,
 
1680
  XID* xid
 
1681
) {
 
1682
  TABLE *table_xa, *table_xa_member;
 
1683
  int error_num;
 
1684
  char xa_key[MAX_KEY_LENGTH];
 
1685
  char xa_member_key[MAX_KEY_LENGTH];
 
1686
  SPIDER_SHARE tmp_share;
 
1687
  SPIDER_CONN *conn;
 
1688
  uint force_commit = THDVAR(thd, force_commit);
 
1689
  MEM_ROOT mem_root;
 
1690
  Open_tables_state open_tables_backup;
 
1691
  bool table_xa_opened = FALSE;
 
1692
  bool table_xa_member_opened = FALSE;
 
1693
  DBUG_ENTER("spider_internal_xa_rollback_by_xid");
 
1694
  /*
 
1695
    select
 
1696
      status
 
1697
    from
 
1698
      mysql.spider_xa
 
1699
    where
 
1700
      format_id = xid->format_id and
 
1701
      gtrid_length = xid->gtrid_length and
 
1702
      data = xid->data
 
1703
  */
 
1704
  if (
 
1705
    !(table_xa = spider_open_sys_table(
 
1706
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1707
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1708
  )
 
1709
    goto error_open_table;
 
1710
  table_xa_opened = TRUE;
 
1711
  spider_store_xa_pk(table_xa, xid);
 
1712
  if (
 
1713
    (error_num = spider_check_sys_table(table_xa, xa_key))
 
1714
  ) {
 
1715
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
1716
    {
 
1717
      table_xa->file->print_error(error_num, MYF(0));
 
1718
      goto error;
 
1719
    }
 
1720
    error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
 
1721
    goto error;
 
1722
  }
 
1723
  init_alloc_root(&mem_root, 4096, 0);
 
1724
  if (
 
1725
    force_commit != 2 &&
 
1726
    (error_num = spider_check_sys_xa_status(
 
1727
      table_xa,
 
1728
      SPIDER_SYS_XA_NOT_YET_STR,
 
1729
      SPIDER_SYS_XA_PREPARED_STR,
 
1730
      SPIDER_SYS_XA_ROLLBACK_STR,
 
1731
      ER_SPIDER_XA_PREPARED_NUM,
 
1732
      &mem_root))
 
1733
  ) {
 
1734
    free_root(&mem_root, MYF(0));
 
1735
    if (error_num == ER_SPIDER_XA_PREPARED_NUM)
 
1736
      my_message(error_num, ER_SPIDER_XA_PREPARED_STR, MYF(0));
 
1737
    goto error;
 
1738
  }
 
1739
 
 
1740
  /*
 
1741
    update
 
1742
      mysql.spider_xa
 
1743
    set
 
1744
      status = 'ROLLBACK'
 
1745
    where
 
1746
      format_id = trx->xid.format_id and
 
1747
      gtrid_length = trx->xid.gtrid_length and
 
1748
      data = trx->xid.data
 
1749
  */
 
1750
  if (
 
1751
    (error_num = spider_update_xa(
 
1752
      table_xa, xid, SPIDER_SYS_XA_ROLLBACK_STR))
 
1753
  ) {
 
1754
    free_root(&mem_root, MYF(0));
 
1755
    goto error;
 
1756
  }
 
1757
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1758
  table_xa_opened = FALSE;
 
1759
 
 
1760
  /*
 
1761
    select
 
1762
      scheme tmp_share.tgt_wrapper,
 
1763
      host tmp_share.tgt_host,
 
1764
      port tmp_share.tgt_port,
 
1765
      socket tmp_share.tgt_socket,
 
1766
      username tmp_share.tgt_username,
 
1767
      password tmp_share.tgt_password
 
1768
    from
 
1769
      mysql.spider_xa_member
 
1770
    where
 
1771
      format_id = xid->format_id and
 
1772
      gtrid_length = xid->gtrid_length and
 
1773
      data = xid->data
 
1774
  */
 
1775
  if (
 
1776
    !(table_xa_member = spider_open_sys_table(
 
1777
      thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
 
1778
      SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
 
1779
      &error_num))
 
1780
  ) {
 
1781
    free_root(&mem_root, MYF(0));
 
1782
    goto error_open_table;
 
1783
  }
 
1784
  table_xa_member_opened = TRUE;
 
1785
  spider_store_xa_pk(table_xa_member, xid);
 
1786
  if (
 
1787
    (error_num = spider_get_sys_table_by_idx(table_xa_member, xa_member_key, 0,
 
1788
    SPIDER_SYS_XA_PK_COL_CNT))
 
1789
  ) {
 
1790
    if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
 
1791
    {
 
1792
      free_root(&mem_root, MYF(0));
 
1793
      table_xa_member->file->print_error(error_num, MYF(0));
 
1794
      goto error;
 
1795
    } else {
 
1796
      free_root(&mem_root, MYF(0));
 
1797
      spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1798
      table_xa_member_opened = FALSE;
 
1799
      goto xa_delete;
 
1800
    }
 
1801
  }
 
1802
 
 
1803
  memset(&tmp_share, 0, sizeof(SPIDER_SHARE));
 
1804
  do {
 
1805
    spider_get_sys_server_info(table_xa_member, &tmp_share, &mem_root);
 
1806
    if ((error_num = spider_create_conn_key(&tmp_share)))
 
1807
    {
 
1808
      spider_sys_index_end(table_xa_member);
 
1809
      free_root(&mem_root, MYF(0));
 
1810
      goto error;
 
1811
    }
 
1812
 
 
1813
    if (
 
1814
      (!(conn = spider_get_conn(
 
1815
      &tmp_share, trx, NULL, FALSE, FALSE, &error_num)) ||
 
1816
        (error_num = spider_db_xa_rollback(conn, xid))) &&
 
1817
      (force_commit == 0 ||
 
1818
        (force_commit == 1 && error_num != ER_XAER_NOTA))
 
1819
    ) {
 
1820
      spider_sys_index_end(table_xa_member);
 
1821
      spider_free_tmp_share_alloc(&tmp_share);
 
1822
      free_root(&mem_root, MYF(0));
 
1823
      goto error;
 
1824
    }
 
1825
    spider_free_tmp_share_alloc(&tmp_share);
 
1826
    error_num = spider_sys_index_next_same(table_xa_member, xa_member_key);
 
1827
  } while (error_num == 0);
 
1828
  if ((error_num = spider_sys_index_end(table_xa_member)))
 
1829
  {
 
1830
    free_root(&mem_root, MYF(0));
 
1831
    goto error;
 
1832
  }
 
1833
  free_root(&mem_root, MYF(0));
 
1834
  spider_free_trx_conn(trx, FALSE);
 
1835
 
 
1836
  /*
 
1837
    delete from
 
1838
      mysql.spider_xa_member
 
1839
    where
 
1840
      format_id = xid->format_id and
 
1841
      gtrid_length = xid->gtrid_length and
 
1842
      data = xid->data
 
1843
  */
 
1844
  if ((error_num = spider_delete_xa_member(table_xa_member, xid)))
 
1845
    goto error;
 
1846
  spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1847
  table_xa_member_opened = FALSE;
 
1848
 
 
1849
xa_delete:
 
1850
  /*
 
1851
    delete from
 
1852
      mysql.spider_xa
 
1853
    where
 
1854
      format_id = xid->format_id and
 
1855
      gtrid_length = xid->gtrid_length and
 
1856
      data = xid->data
 
1857
  */
 
1858
  if (
 
1859
    !(table_xa = spider_open_sys_table(
 
1860
      thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
 
1861
      TRUE, &open_tables_backup, TRUE, &error_num))
 
1862
  )
 
1863
    goto error_open_table;
 
1864
  table_xa_opened = TRUE;
 
1865
  if ((error_num = spider_delete_xa(table_xa, xid)))
 
1866
    goto error;
 
1867
  spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1868
  table_xa_opened = FALSE;
 
1869
  DBUG_RETURN(0);
 
1870
 
 
1871
error:
 
1872
  if (table_xa_opened)
 
1873
    spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
 
1874
  if (table_xa_member_opened)
 
1875
    spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
 
1876
error_open_table:
 
1877
  DBUG_RETURN(error_num);
 
1878
}
 
1879
 
 
1880
int spider_start_consistent_snapshot(
 
1881
  handlerton *hton,
 
1882
  THD* thd
 
1883
) {
 
1884
  int error_num;
 
1885
  SPIDER_TRX *trx;
 
1886
  DBUG_ENTER("spider_start_consistent_snapshot");
 
1887
 
 
1888
  if (!(trx = spider_get_trx(thd, &error_num)))
 
1889
    DBUG_RETURN(error_num);
 
1890
  if (THDVAR(trx->thd, use_consistent_snapshot))
 
1891
  {
 
1892
    if (THDVAR(trx->thd, internal_xa) &&
 
1893
      THDVAR(trx->thd, internal_xa_snapshot) == 1)
 
1894
    {
 
1895
      error_num = ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM;
 
1896
      my_message(error_num, ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR,
 
1897
        MYF(0));
 
1898
      goto error;
 
1899
    } else {
 
1900
      trx->trx_consistent_snapshot = TRUE;
 
1901
      trx->use_consistent_snapshot = TRUE;
 
1902
      trx->internal_xa_snapshot = THDVAR(trx->thd, internal_xa_snapshot);
 
1903
      trans_register_ha(trx->thd, FALSE, spider_hton_ptr);
 
1904
      trans_register_ha(trx->thd, TRUE, spider_hton_ptr);
 
1905
      if (THDVAR(trx->thd, use_all_conns_snapshot))
 
1906
      {
 
1907
        trx->internal_xa = FALSE;
 
1908
        if ((error_num = spider_open_all_tables(trx, TRUE)))
 
1909
          goto error_open_all_tables;
 
1910
        if (
 
1911
          THDVAR(trx->thd, use_snapshot_with_flush_tables) == 1 &&
 
1912
          (error_num = spider_trx_all_flush_tables(trx))
 
1913
        )
 
1914
          goto error_trx_all_flush_tables;
 
1915
        if (THDVAR(trx->thd, use_snapshot_with_flush_tables) == 2)
 
1916
        {
 
1917
          if ((error_num = spider_trx_another_lock_tables(trx)))
 
1918
            goto error_trx_another_lock_tables;
 
1919
          if ((error_num = spider_trx_another_flush_tables(trx)))
 
1920
            goto error_trx_another_flush_tables;
 
1921
        }
 
1922
        if ((error_num = spider_trx_all_start_trx(trx)))
 
1923
          goto error_trx_all_start_trx;
 
1924
        if (THDVAR(trx->thd, use_snapshot_with_flush_tables) == 1)
 
1925
        {
 
1926
          if (
 
1927
            THDVAR(trx->thd, use_flash_logs) &&
 
1928
            (error_num = spider_trx_all_flush_logs(trx))
 
1929
          )
 
1930
            goto error_trx_all_flush_logs;
 
1931
          if ((error_num = spider_trx_all_unlock_tables(trx)))
 
1932
            goto error_trx_all_unlock_tables;
 
1933
        }
 
1934
        if (THDVAR(trx->thd, use_snapshot_with_flush_tables) == 2)
 
1935
        {
 
1936
          if (
 
1937
            THDVAR(trx->thd, use_flash_logs) &&
 
1938
            (error_num = spider_trx_all_flush_logs(trx))
 
1939
          )
 
1940
            goto error_trx_all_flush_logs2;
 
1941
          if (error_num = spider_free_trx_another_conn(trx, TRUE))
 
1942
            goto error_free_trx_another_conn;
 
1943
        }
 
1944
      } else
 
1945
        trx->internal_xa = THDVAR(trx->thd, internal_xa);
 
1946
    }
 
1947
  }
 
1948
 
 
1949
  DBUG_RETURN(0);
 
1950
 
 
1951
error_trx_all_flush_logs:
 
1952
error_trx_all_start_trx:
 
1953
error_trx_another_flush_tables:
 
1954
error_trx_another_lock_tables:
 
1955
error_trx_all_flush_tables:
 
1956
  if (THDVAR(trx->thd, use_snapshot_with_flush_tables) == 1)
 
1957
    VOID(spider_trx_all_unlock_tables(trx));
 
1958
error_trx_all_flush_logs2:
 
1959
error_trx_all_unlock_tables:
 
1960
error_open_all_tables:
 
1961
  if (THDVAR(trx->thd, use_snapshot_with_flush_tables) == 2)
 
1962
    VOID(spider_free_trx_another_conn(trx, TRUE));
 
1963
error_free_trx_another_conn:
 
1964
error:
 
1965
  DBUG_RETURN(error_num);
 
1966
}
 
1967
 
 
1968
int spider_commit(
 
1969
  handlerton *hton,
 
1970
  THD *thd,
 
1971
  bool all
 
1972
) {
 
1973
  SPIDER_TRX *trx;
 
1974
  TABLE *table_xa;
 
1975
  TABLE *table_xa_member;
 
1976
  int error_num = 0;
 
1977
  SPIDER_CONN *conn;
 
1978
  DBUG_ENTER("spider_commit");
 
1979
 
 
1980
  if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
1981
  {
 
1982
    if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
 
1983
      DBUG_RETURN(0); /* transaction is not started */
 
1984
 
 
1985
    if (trx->trx_start)
 
1986
    {
 
1987
      if (trx->trx_xa)
 
1988
      {
 
1989
        if (
 
1990
          (trx->internal_xa &&
 
1991
            (error_num = spider_internal_xa_prepare(
 
1992
              thd, trx, table_xa, table_xa_member, TRUE))) ||
 
1993
          (error_num = spider_internal_xa_commit(
 
1994
            thd, trx, &trx->xid, table_xa, table_xa_member))
 
1995
        ) {
 
1996
          DBUG_RETURN(error_num);
 
1997
        }
 
1998
        trx->trx_xa = FALSE;
 
1999
      } else {
 
2000
        if ((conn = spider_tree_first(trx->join_trx_top)))
 
2001
        {
 
2002
          int tmp_error_num;
 
2003
          do {
 
2004
            if (
 
2005
              (conn->autocommit != 1 || conn->trx_start) &&
 
2006
              (tmp_error_num = spider_db_commit(conn))
 
2007
            )
 
2008
              error_num = tmp_error_num;
 
2009
            if ((tmp_error_num = spider_end_trx(trx, conn)))
 
2010
              error_num = tmp_error_num;
 
2011
            conn->join_trx = 0;
 
2012
          } while ((conn = spider_tree_next(conn)));
 
2013
          trx->join_trx_top = NULL;
 
2014
        }
 
2015
      }
 
2016
      trx->trx_start = FALSE;
 
2017
    }
 
2018
    spider_free_trx_conn(trx, FALSE);
 
2019
    trx->trx_consistent_snapshot = FALSE;
 
2020
  }
 
2021
  DBUG_RETURN(error_num);
 
2022
}
 
2023
 
 
2024
int spider_rollback(
 
2025
  handlerton *hton,
 
2026
  THD *thd,
 
2027
  bool all
 
2028
) {
 
2029
  SPIDER_TRX *trx;
 
2030
  int error_num = 0;
 
2031
  int roop_count;
 
2032
  SPIDER_CONN *conn;
 
2033
  DBUG_ENTER("spider_rollback");
 
2034
 
 
2035
  if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
2036
  {
 
2037
    if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
 
2038
      DBUG_RETURN(0); /* transaction is not started */
 
2039
 
 
2040
    if (trx->trx_start)
 
2041
    {
 
2042
      if (trx->trx_xa)
 
2043
      {
 
2044
        if (
 
2045
          (error_num = spider_internal_xa_rollback(thd, trx))
 
2046
        )
 
2047
          DBUG_RETURN(error_num);
 
2048
        trx->trx_xa = FALSE;
 
2049
      } else {
 
2050
        if ((conn = spider_tree_first(trx->join_trx_top)))
 
2051
        {
 
2052
          int tmp_error_num;
 
2053
          do {
 
2054
            if (
 
2055
              !conn->server_lost &&
 
2056
              (conn->autocommit != 1 || conn->trx_start) &&
 
2057
              (tmp_error_num = spider_db_rollback(conn))
 
2058
            )
 
2059
              error_num = tmp_error_num;
 
2060
            if ((tmp_error_num = spider_end_trx(trx, conn)))
 
2061
              error_num = tmp_error_num;
 
2062
            conn->join_trx = 0;
 
2063
          } while ((conn = spider_tree_next(conn)));
 
2064
          trx->join_trx_top = NULL;
 
2065
        }
 
2066
      }
 
2067
      trx->trx_start = FALSE;
 
2068
    }
 
2069
    spider_free_trx_conn(trx, FALSE);
 
2070
    trx->trx_consistent_snapshot = FALSE;
 
2071
  }
 
2072
 
 
2073
  DBUG_RETURN(error_num);
 
2074
}
 
2075
 
 
2076
int spider_xa_prepare(
 
2077
  handlerton *hton,
 
2078
  THD* thd,
 
2079
  bool all
 
2080
) {
 
2081
  int error_num;
 
2082
  SPIDER_TRX *trx;
 
2083
  TABLE *table_xa;
 
2084
  TABLE *table_xa_member;
 
2085
  DBUG_ENTER("spider_xa_prepare");
 
2086
 
 
2087
  if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
2088
  {
 
2089
    if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
 
2090
      DBUG_RETURN(0); /* transaction is not started */
 
2091
 
 
2092
    if (trx->trx_start)
 
2093
    {
 
2094
      if ((error_num = spider_internal_xa_prepare(
 
2095
        thd, trx, table_xa, table_xa_member, FALSE)))
 
2096
        goto error;
 
2097
    }
 
2098
  }
 
2099
 
 
2100
  DBUG_RETURN(0);
 
2101
 
 
2102
error:
 
2103
  DBUG_RETURN(error_num);
 
2104
}
 
2105
 
 
2106
int spider_xa_recover(
 
2107
  handlerton *hton,
 
2108
  XID* xid_list,
 
2109
  uint len
 
2110
) {
 
2111
  THD* thd = current_thd;
 
2112
  DBUG_ENTER("spider_xa_recover");
 
2113
        if (len == 0 || xid_list == NULL)
 
2114
    DBUG_RETURN(0);
 
2115
 
 
2116
  if (thd)
 
2117
    DBUG_RETURN(spider_internal_xa_recover(thd, xid_list, len));
 
2118
  else
 
2119
    DBUG_RETURN(spider_initinal_xa_recover(xid_list, len));
 
2120
}
 
2121
 
 
2122
int spider_xa_commit_by_xid(
 
2123
  handlerton *hton,
 
2124
  XID* xid
 
2125
) {
 
2126
  SPIDER_TRX *trx;
 
2127
  int error_num;
 
2128
  THD* thd = current_thd;
 
2129
  DBUG_ENTER("spider_xa_commit_by_xid");
 
2130
 
 
2131
  if (!(trx = spider_get_trx(thd, &error_num)))
 
2132
    goto error_get_trx;
 
2133
 
 
2134
  if ((error_num = spider_internal_xa_commit_by_xid(thd, trx, xid)))
 
2135
    goto error;
 
2136
 
 
2137
  DBUG_RETURN(0);
 
2138
 
 
2139
error:
 
2140
error_get_trx:
 
2141
  DBUG_RETURN(error_num);
 
2142
}
 
2143
 
 
2144
int spider_xa_rollback_by_xid(
 
2145
  handlerton *hton,
 
2146
  XID* xid
 
2147
) {
 
2148
  SPIDER_TRX *trx;
 
2149
  int error_num;
 
2150
  THD* thd = current_thd;
 
2151
  DBUG_ENTER("spider_xa_rollback_by_xid");
 
2152
 
 
2153
  if (!(trx = spider_get_trx(thd, &error_num)))
 
2154
    goto error_get_trx;
 
2155
 
 
2156
  if ((error_num = spider_internal_xa_rollback_by_xid(thd, trx, xid)))
 
2157
    goto error;
 
2158
 
 
2159
  DBUG_RETURN(0);
 
2160
 
 
2161
error:
 
2162
error_get_trx:
 
2163
  DBUG_RETURN(error_num);
 
2164
}
 
2165
 
 
2166
int spider_end_trx(
 
2167
  SPIDER_TRX *trx,
 
2168
  SPIDER_CONN *conn
 
2169
) {
 
2170
  int error_num = 0;
 
2171
  ha_spider tmp_spider;
 
2172
  DBUG_ENTER("spider_end_trx");
 
2173
  if (conn->table_lock == 3)
 
2174
  {
 
2175
    conn->table_lock = 0;
 
2176
    conn->disable_reconnect = FALSE;
 
2177
    tmp_spider.conn = conn;
 
2178
    tmp_spider.trx = trx;
 
2179
    if (
 
2180
      !conn->server_lost &&
 
2181
      (error_num = spider_db_unlock_tables(&tmp_spider))
 
2182
    ) {
 
2183
      if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
 
2184
        error_num = 0;
 
2185
    }
 
2186
  } else if (!conn->table_lock)
 
2187
    conn->disable_reconnect = FALSE;
 
2188
  if (
 
2189
    conn->semi_trx_isolation >= 0 &&
 
2190
    conn->trx_isolation != conn->semi_trx_isolation
 
2191
  ) {
 
2192
    if (
 
2193
      !conn->server_lost &&
 
2194
      (error_num = spider_db_set_trx_isolation(
 
2195
        conn, THDVAR(trx->thd, semi_trx_isolation)))
 
2196
    ) {
 
2197
      if (
 
2198
        !conn->disable_reconnect &&
 
2199
        error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM
 
2200
      )
 
2201
        error_num = 0;
 
2202
    }
 
2203
  }
 
2204
  conn->semi_trx_isolation = -2;
 
2205
  conn->semi_trx_isolation_chk = FALSE;
 
2206
  conn->semi_trx_chk = FALSE;
 
2207
  DBUG_RETURN(error_num);
 
2208
}
 
2209
 
 
2210
int spider_check_trx_and_get_conn(
 
2211
  THD *thd,
 
2212
  ha_spider *spider
 
2213
) {
 
2214
  int error_num;
 
2215
  SPIDER_TRX *trx;
 
2216
  SPIDER_CONN *conn = spider->conn;
 
2217
  DBUG_ENTER("spider_check_trx_and_get_conn");
 
2218
  if (!(trx = spider_get_trx(thd, &error_num)))
 
2219
  {
 
2220
    DBUG_PRINT("info",("spider get trx error"));
 
2221
    DBUG_RETURN(error_num);
 
2222
  }
 
2223
  if (trx->spider_thread_id != spider->spider_thread_id ||
 
2224
    trx->trx_conn_adjustment != spider->trx_conn_adjustment)
 
2225
  {
 
2226
    DBUG_PRINT("info",(trx != spider->trx ? "spider change thd" :
 
2227
      "spider next trx"));
 
2228
    spider->trx = trx;
 
2229
    spider->spider_thread_id = trx->spider_thread_id;
 
2230
    spider->trx_conn_adjustment = trx->trx_conn_adjustment;
 
2231
    if (
 
2232
      !(spider->conn = conn =
 
2233
        spider_get_conn(spider->share, trx, spider, FALSE, TRUE, &error_num))
 
2234
    ) {
 
2235
      DBUG_PRINT("info",("spider get conn error"));
 
2236
      DBUG_RETURN(error_num);
 
2237
    }
 
2238
  } else if (!conn)
 
2239
  {
 
2240
    DBUG_PRINT("info",("spider get conn"));
 
2241
    if (
 
2242
      !(spider->conn = conn =
 
2243
        spider_get_conn(spider->share, trx, spider, FALSE, TRUE, &error_num))
 
2244
    ) {
 
2245
      DBUG_PRINT("info",("spider get conn error"));
 
2246
      DBUG_RETURN(error_num);
 
2247
    }
 
2248
  }
 
2249
  DBUG_RETURN(0);
 
2250
}
 
2251
 
 
2252
THD *spider_create_tmp_thd()
 
2253
{
 
2254
  THD *thd;
 
2255
  DBUG_ENTER("spider_create_tmp_thd");
 
2256
  if (!(thd = new THD))
 
2257
    DBUG_RETURN(NULL);
 
2258
  thd->killed = THD::NOT_KILLED;
 
2259
  thd->locked_tables = FALSE;
 
2260
  thd->proc_info = "";
 
2261
  thd->thread_id = thd->variables.pseudo_thread_id = 0;
 
2262
  thd->thread_stack = (char*) &thd;
 
2263
  if (thd->store_globals())
 
2264
    DBUG_RETURN(NULL);
 
2265
  lex_start(thd);
 
2266
  DBUG_RETURN(thd);
 
2267
}
 
2268
 
 
2269
void spider_free_tmp_thd(
 
2270
  THD *thd
 
2271
) {
 
2272
  DBUG_ENTER("spider_free_tmp_thd");
 
2273
  thd->cleanup();
 
2274
  delete thd;
 
2275
  DBUG_VOID_RETURN;
 
2276
}