~percona-core/percona-server/5.5

« back to all changes in this revision

Viewing changes to Percona-Server/storage/innobase/trx/trx0trx.c

  • Committer: jenkins at percona
  • Date: 2013-03-26 01:40:02 UTC
  • mfrom: (450.9.2 bug1131189)
  • Revision ID: jenkins@jenkins.percona.com-20130326014002-1m2hg8pt1b27chq2
MergeĀ lp:~akopytov/percona-server/bug1131189

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
                            sizeof(trx->detailed_error));
86
86
}
87
87
 
 
88
/*************************************************************//**
 
89
Callback function for trx_find_descriptor() to compare trx IDs. */
 
90
UNIV_INTERN
 
91
int
 
92
trx_descr_cmp(
 
93
/*==========*/
 
94
        const void *a,  /*!< in: pointer to first comparison argument */
 
95
        const void *b)  /*!< in: pointer to second comparison argument */
 
96
{
 
97
        const trx_id_t* da = (const trx_id_t*) a;
 
98
        const trx_id_t* db = (const trx_id_t*) b;
 
99
 
 
100
        if (*da < *db) {
 
101
                return -1;
 
102
        } else if (*da > *db) {
 
103
                return 1;
 
104
        }
 
105
 
 
106
        return 0;
 
107
}
 
108
 
 
109
/*************************************************************//**
 
110
Reserve a slot for a given trx in the global descriptors array. */
 
111
UNIV_INLINE
 
112
void
 
113
trx_reserve_descriptor(
 
114
/*===================*/
 
115
        const trx_t* trx)       /*!< in: trx pointer */
 
116
{
 
117
        ulint           n_used;
 
118
        ulint           n_max;
 
119
        trx_id_t*       descr;
 
120
 
 
121
        ut_ad(mutex_own(&kernel_mutex));
 
122
        ut_ad(!trx_find_descriptor(trx_sys->descriptors,
 
123
                                   trx_sys->descr_n_used,
 
124
                                   trx->id));
 
125
 
 
126
        n_used = trx_sys->descr_n_used + 1;
 
127
        n_max = trx_sys->descr_n_max;
 
128
 
 
129
        if (UNIV_UNLIKELY(n_used > n_max)) {
 
130
 
 
131
                n_max = n_max * 2;
 
132
 
 
133
                trx_sys->descriptors =
 
134
                        ut_realloc(trx_sys->descriptors,
 
135
                                   n_max * sizeof(trx_id_t));
 
136
 
 
137
                trx_sys->descr_n_max = n_max;
 
138
        }
 
139
 
 
140
        descr = trx_sys->descriptors + n_used - 1;
 
141
 
 
142
        if (UNIV_UNLIKELY(n_used > 1 && trx->id < descr[-1])) {
 
143
 
 
144
                /* Find the slot where it should be inserted. We could use a
 
145
                binary search, but in reality linear search should be faster,
 
146
                because the slot we are looking for is near the array end. */
 
147
 
 
148
                trx_id_t*       tdescr;
 
149
 
 
150
                for (tdescr = descr - 1;
 
151
                     tdescr >= trx_sys->descriptors && *tdescr > trx->id;
 
152
                     tdescr--) {
 
153
                }
 
154
 
 
155
                tdescr++;
 
156
 
 
157
                ut_memmove(tdescr + 1, tdescr, (descr - tdescr) *
 
158
                           sizeof(trx_id_t));
 
159
 
 
160
                descr = tdescr;
 
161
        }
 
162
 
 
163
        *descr = trx->id;
 
164
 
 
165
        trx_sys->descr_n_used = n_used;
 
166
}
 
167
 
 
168
/*************************************************************//**
 
169
Release a slot for a given trx in the global descriptors array. */
 
170
UNIV_INTERN
 
171
void
 
172
trx_release_descriptor(
 
173
/*===================*/
 
174
        trx_t* trx)     /*!< in: trx pointer */
 
175
{
 
176
        ulint           size;
 
177
        trx_id_t*       descr;
 
178
 
 
179
        ut_ad(mutex_own(&kernel_mutex));
 
180
 
 
181
        if (UNIV_LIKELY(trx->is_in_trx_serial_list)) {
 
182
 
 
183
                UT_LIST_REMOVE(trx_serial_list, trx_sys->trx_serial_list,
 
184
                               trx);
 
185
                trx->is_in_trx_serial_list = 0;
 
186
        }
 
187
 
 
188
        descr = trx_find_descriptor(trx_sys->descriptors,
 
189
                                    trx_sys->descr_n_used,
 
190
                                    trx->id);
 
191
 
 
192
        if (UNIV_UNLIKELY(descr == NULL)) {
 
193
 
 
194
                return;
 
195
        }
 
196
 
 
197
        size = (trx_sys->descriptors + trx_sys->descr_n_used - 1 - descr) *
 
198
                sizeof(trx_id_t);
 
199
 
 
200
        if (UNIV_LIKELY(size > 0)) {
 
201
 
 
202
                ut_memmove(descr, descr + 1, size);
 
203
        }
 
204
 
 
205
        trx_sys->descr_n_used--;
 
206
}
 
207
 
88
208
/****************************************************************//**
89
209
Creates and initializes a transaction object.
90
210
@return own: the transaction */
107
227
 
108
228
        trx->is_purge = 0;
109
229
        trx->is_recovered = 0;
110
 
        trx->conc_state = TRX_NOT_STARTED;
 
230
        trx->state = TRX_NOT_STARTED;
111
231
 
112
232
        trx->is_registered = 0;
113
233
        trx->owns_prepare_mutex = 0;
119
239
 
120
240
        trx->id = 0;
121
241
        trx->no = IB_ULONGLONG_MAX;
 
242
        trx->is_in_trx_serial_list = 0;
122
243
 
123
244
        trx->support_xa = TRUE;
124
245
 
328
449
 
329
450
        trx->magic_n = 11112222;
330
451
 
331
 
        ut_a(trx->conc_state == TRX_NOT_STARTED);
 
452
        ut_a(trx->state == TRX_NOT_STARTED);
332
453
 
333
454
        mutex_free(&(trx->undo_mutex));
334
455
 
359
480
                read_view_free(trx->prebuilt_view);
360
481
        }
361
482
 
362
 
        trx->global_read_view = NULL;
363
 
        trx->prebuilt_view = NULL;
364
 
 
365
483
        ut_a(trx->read_view == NULL);
366
484
 
367
485
        ut_a(ib_vector_is_empty(trx->autoinc_locks));
368
486
        /* We allocated a dedicated heap for the vector. */
369
487
        ib_vector_free(trx->autoinc_locks);
370
488
 
 
489
        trx_release_descriptor(trx);
 
490
 
371
491
        mem_free(trx);
372
492
}
373
493
 
380
500
        trx_t*  trx)    /*!< in, own: trx object */
381
501
{
382
502
        ut_ad(mutex_own(&kernel_mutex));
383
 
        ut_a(trx->conc_state == TRX_PREPARED);
 
503
        ut_a(trx->state == TRX_PREPARED);
384
504
        ut_a(trx->magic_n == TRX_MAGIC_N);
385
505
 
386
506
        /* Prepared transactions are sort of active; they allow
416
536
        ut_a(ib_vector_is_empty(trx->autoinc_locks));
417
537
        ib_vector_free(trx->autoinc_locks);
418
538
 
 
539
        trx_release_descriptor(trx);
 
540
 
 
541
        if (trx->prebuilt_view != NULL) {
 
542
                read_view_free(trx->prebuilt_view);
 
543
        }
 
544
 
419
545
        UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
420
546
 
 
547
        ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
 
548
 
421
549
        mem_free(trx);
422
550
}
423
551
 
526
654
 
527
655
        ut_ad(mutex_own(&kernel_mutex));
528
656
        UT_LIST_INIT(trx_sys->trx_list);
 
657
        UT_LIST_INIT(trx_sys->trx_serial_list);
529
658
 
530
659
        /* Look from the rollback segments if there exist undo logs for
531
660
        transactions */
562
691
 
563
692
                                        if (srv_force_recovery == 0) {
564
693
 
565
 
                                                trx->conc_state = TRX_PREPARED;
 
694
                                                trx->state = TRX_PREPARED;
566
695
                                                trx_n_prepared++;
567
696
                                        } else {
568
697
                                                fprintf(stderr,
572
701
                                                        " rollback it"
573
702
                                                        " anyway.\n");
574
703
 
575
 
                                                trx->conc_state = TRX_ACTIVE;
 
704
                                                trx->state = TRX_ACTIVE;
576
705
                                        }
 
706
 
 
707
                                        trx_reserve_descriptor(trx);
577
708
                                } else {
578
 
                                        trx->conc_state
579
 
                                                = TRX_COMMITTED_IN_MEMORY;
 
709
                                        trx->state = TRX_COMMITTED_IN_MEMORY;
580
710
                                }
581
711
 
582
712
                                /* We give a dummy value for the trx no;
588
718
 
589
719
                                trx->no = trx->id;
590
720
                        } else {
591
 
                                trx->conc_state = TRX_ACTIVE;
 
721
                                trx->state = TRX_ACTIVE;
592
722
 
593
723
                                /* A running transaction always has the number
594
724
                                field inited to IB_ULONGLONG_MAX */
595
725
 
596
726
                                trx->no = IB_ULONGLONG_MAX;
 
727
 
 
728
                                trx_reserve_descriptor(trx);
 
729
 
597
730
                        }
598
731
 
599
732
                        if (undo->dict_operation) {
638
771
 
639
772
                                                if (srv_force_recovery == 0) {
640
773
 
641
 
                                                        trx->conc_state
 
774
                                                        trx->state
642
775
                                                                = TRX_PREPARED;
643
776
                                                        trx_n_prepared++;
644
777
                                                } else {
649
782
                                                                " rollback it"
650
783
                                                                " anyway.\n");
651
784
 
652
 
                                                        trx->conc_state
653
 
                                                                = TRX_ACTIVE;
 
785
                                                        trx->state = TRX_ACTIVE;
 
786
                                                        trx_reserve_descriptor(
 
787
                                                                trx);
654
788
                                                }
655
789
                                        } else {
656
 
                                                trx->conc_state
 
790
                                                trx->state
657
791
                                                        = TRX_COMMITTED_IN_MEMORY;
658
792
                                        }
659
793
 
662
796
 
663
797
                                        trx->no = trx->id;
664
798
                                } else {
665
 
                                        trx->conc_state = TRX_ACTIVE;
666
 
 
 
799
                                        trx->state = TRX_ACTIVE;
667
800
                                        /* A running transaction always has
668
801
                                        the number field inited to
669
802
                                        IB_ULONGLONG_MAX */
670
803
 
671
804
                                        trx->no = IB_ULONGLONG_MAX;
 
805
 
 
806
                                        trx_reserve_descriptor(trx);
672
807
                                }
673
808
 
674
809
                                trx->rseg = rseg;
739
874
 
740
875
        if (trx->is_purge) {
741
876
                trx->id = 0;
742
 
                trx->conc_state = TRX_ACTIVE;
 
877
                /* Don't reserve a descriptor, since this trx is not added to
 
878
                trx_list. */
 
879
                trx->state = TRX_ACTIVE;
743
880
                trx->start_time = time(NULL);
744
881
 
745
882
                return(TRUE);
746
883
        }
747
884
 
748
 
        ut_ad(trx->conc_state != TRX_ACTIVE);
 
885
        ut_ad(trx->state != TRX_ACTIVE);
749
886
 
750
887
        ut_a(rseg_id == ULINT_UNDEFINED);
751
888
 
760
897
 
761
898
        trx->rseg = rseg;
762
899
 
763
 
        trx->conc_state = TRX_ACTIVE;
 
900
        trx->state = TRX_ACTIVE;
 
901
 
 
902
        trx_reserve_descriptor(trx);
 
903
 
764
904
        trx->start_time = time(NULL);
765
905
 
766
906
        UT_LIST_ADD_FIRST(trx_list, trx_sys->trx_list, trx);
817
957
 
818
958
        trx->no = trx_sys_get_new_trx_id();
819
959
 
 
960
        if (UNIV_LIKELY(trx->is_in_trx_serial_list == 0)) {
 
961
 
 
962
                UT_LIST_ADD_LAST(trx_serial_list, trx_sys->trx_serial_list,
 
963
                                 trx);
 
964
 
 
965
                trx->is_in_trx_serial_list = 1;
 
966
        }
 
967
 
820
968
        /* If the rollack segment is not empty then the
821
969
        new trx_t::no can't be less than any trx_t::no
822
970
        already in the rollback segment. User threads only
998
1146
                lsn = 0;
999
1147
        }
1000
1148
 
1001
 
        ut_ad(trx->conc_state == TRX_ACTIVE || trx->conc_state == TRX_PREPARED);
 
1149
        ut_ad(trx->state == TRX_ACTIVE || trx->state == TRX_PREPARED);
1002
1150
        ut_ad(mutex_own(&kernel_mutex));
1003
1151
 
1004
 
        if (UNIV_UNLIKELY(trx->conc_state == TRX_PREPARED)) {
 
1152
        if (UNIV_UNLIKELY(trx->state == TRX_PREPARED)) {
1005
1153
                ut_a(trx_n_prepared > 0);
1006
1154
                trx_n_prepared--;
1007
1155
        }
1021
1169
        committed. */
1022
1170
 
1023
1171
        /*--------------------------------------*/
1024
 
        trx->conc_state = TRX_COMMITTED_IN_MEMORY;
 
1172
        trx->state = TRX_COMMITTED_IN_MEMORY;
 
1173
        /* The following also removes trx from trx_serial_list */
 
1174
        trx_release_descriptor(trx);
1025
1175
        /*--------------------------------------*/
1026
1176
 
1027
1177
        /* If we release kernel_mutex below and we are still doing
1127
1277
        /* Free all savepoints */
1128
1278
        trx_roll_free_all_savepoints(trx);
1129
1279
 
1130
 
        trx->conc_state = TRX_NOT_STARTED;
 
1280
        trx->state = TRX_NOT_STARTED;
1131
1281
        trx->rseg = NULL;
1132
1282
        trx->undo_no = 0;
1133
1283
        trx->last_sql_stat_start.least_undo_no = 0;
1137
1287
 
1138
1288
        UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
1139
1289
 
 
1290
        ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
 
1291
 
1140
1292
        trx->error_state = DB_SUCCESS;
1141
1293
}
1142
1294
 
1155
1307
                trx_undo_insert_cleanup(trx);
1156
1308
        }
1157
1309
 
1158
 
        trx->conc_state = TRX_NOT_STARTED;
 
1310
        trx->state = TRX_NOT_STARTED;
 
1311
        trx_release_descriptor(trx);
1159
1312
        trx->rseg = NULL;
1160
1313
        trx->undo_no = 0;
1161
1314
        trx->last_sql_stat_start.least_undo_no = 0;
1162
1315
 
1163
1316
        UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
 
1317
 
 
1318
        ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->trx_list));
1164
1319
}
1165
1320
 
1166
1321
/********************************************************************//**
1174
1329
/*=================*/
1175
1330
        trx_t*  trx)    /*!< in: active transaction */
1176
1331
{
1177
 
        ut_ad(trx->conc_state == TRX_ACTIVE);
 
1332
        ut_ad(trx->state == TRX_ACTIVE);
1178
1333
 
1179
1334
        if (trx->read_view) {
1180
1335
                return(trx->read_view);
1182
1337
 
1183
1338
        mutex_enter(&kernel_mutex);
1184
1339
 
1185
 
        if (!trx->read_view) {
1186
 
                trx->read_view = read_view_open_now(trx->id,
1187
 
                                                    trx->prebuilt_view);
1188
 
                trx->prebuilt_view = trx->read_view;
1189
 
                trx->global_read_view = trx->read_view;
1190
 
        }
 
1340
        trx->read_view = read_view_open_now(trx->id, trx->prebuilt_view, TRUE);
 
1341
        trx->prebuilt_view = trx->read_view;
 
1342
        trx->global_read_view = trx->read_view;
1191
1343
 
1192
1344
        mutex_exit(&kernel_mutex);
1193
1345
 
1552
1704
                return;
1553
1705
        }
1554
1706
 
1555
 
        if (trx->conc_state == TRX_NOT_STARTED) {
 
1707
        if (trx->state == TRX_NOT_STARTED) {
1556
1708
 
1557
1709
                trx_start_low(trx, ULINT_UNDEFINED);
1558
1710
        }
1844
1996
{
1845
1997
        ut_a(trx);
1846
1998
 
1847
 
        if (trx->conc_state == TRX_NOT_STARTED) {
 
1999
        if (trx->state == TRX_NOT_STARTED) {
1848
2000
                trx->undo_no = 0;
1849
2001
        }
1850
2002
 
1867
2019
 
1868
2020
        fprintf(f, "TRANSACTION " TRX_ID_FMT, (ullint) trx->id);
1869
2021
 
1870
 
        switch (trx->conc_state) {
 
2022
        switch (trx->state) {
1871
2023
        case TRX_NOT_STARTED:
1872
2024
                fputs(", not started", f);
1873
2025
                break;
1883
2035
                fputs(", COMMITTED IN MEMORY", f);
1884
2036
                break;
1885
2037
        default:
1886
 
                fprintf(f, " state %lu", (ulong) trx->conc_state);
 
2038
                fprintf(f, " state %lu", (ulong) trx->state);
1887
2039
        }
1888
2040
 
1889
2041
        if (*trx->op_info) {
2078
2230
        ut_ad(mutex_own(&kernel_mutex));
2079
2231
 
2080
2232
        /*--------------------------------------*/
2081
 
        trx->conc_state = TRX_PREPARED;
 
2233
        if (UNIV_UNLIKELY(trx->state != TRX_ACTIVE)) {
 
2234
 
 
2235
                trx_reserve_descriptor(trx);
 
2236
        }
 
2237
        trx->state = TRX_PREPARED;
2082
2238
        trx_n_prepared++;
2083
2239
        /*--------------------------------------*/
2084
2240
 
2192
2348
        trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
2193
2349
 
2194
2350
        while (trx) {
2195
 
                if (trx->conc_state == TRX_PREPARED) {
 
2351
                if (trx->state == TRX_PREPARED) {
2196
2352
                        xid_list[count] = trx->xid;
2197
2353
 
2198
2354
                        if (count == 0) {
2265
2421
                the same */
2266
2422
 
2267
2423
                if (trx->is_recovered
2268
 
                    && trx->conc_state == TRX_PREPARED
 
2424
                    && trx->state == TRX_PREPARED
2269
2425
                    && xid->gtrid_length == trx->xid.gtrid_length
2270
2426
                    && xid->bqual_length == trx->xid.bqual_length
2271
2427
                    && memcmp(xid->data, trx->xid.data,