~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/trx/trx0i_s.c

Merge Stewart's dead code removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2007, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
13
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
28
28
Created July 17, 2007 Vasil Dimov
29
29
*******************************************************/
30
30
 
31
 
#include "config.h"
32
 
/* Found during the build of 5.5.3 on Linux 2.4 and early 2.6 kernels:
33
 
   The includes "univ.i" -> "my_global.h" cause a different path
34
 
   to be taken further down with pthread functions and types,
35
 
   so they must come first.
36
 
   From the symptoms, this is related to bug#46587 in the MySQL bug DB.
37
 
*/
38
 
#include "univ.i"
39
 
 
40
31
#if !defined(BUILD_DRIZZLE)
41
32
# include <mysql/plugin.h>
42
33
#endif
43
34
 
 
35
#include "mysql_addons.h"
 
36
 
 
37
#include "univ.i"
44
38
#include "buf0buf.h"
45
39
#include "dict0dict.h"
46
40
#include "ha0storage.h"
62
56
#include "ut0mem.h"
63
57
#include "ut0ut.h"
64
58
 
65
 
#include <drizzled/session.h>
66
 
 
67
59
/** Initial number of rows in the table cache */
68
60
#define TABLE_CACHE_INITIAL_ROWSNUM     1024
69
61
 
70
62
/** @brief The maximum number of chunks to allocate for a table cache.
71
63
 
72
64
The rows of a table cache are stored in a set of chunks. When a new
73
 
row is added a new chunk is allocated if necessary. Assuming that the
 
65
row is added a new chunk is allocated if necessary.  Assuming that the
74
66
first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
75
67
subsequent is N/2 where N is the number of rows we have allocated till
76
68
now, then 39th chunk would accommodate 1677416425 rows and all chunks
196
188
code in handler/i_s.cc. */
197
189
UNIV_INTERN trx_i_s_cache_t*    trx_i_s_cache = &trx_i_s_cache_static;
198
190
 
199
 
/* Key to register the lock/mutex with performance schema */
200
 
#ifdef UNIV_PFS_RWLOCK
201
 
UNIV_INTERN mysql_pfs_key_t     trx_i_s_cache_lock_key;
202
 
#endif /* UNIV_PFS_RWLOCK */
203
 
 
204
 
#ifdef UNIV_PFS_MUTEX
205
 
UNIV_INTERN mysql_pfs_key_t     cache_last_read_mutex_key;
206
 
#endif /* UNIV_PFS_MUTEX */
207
 
 
208
191
/*******************************************************************//**
209
192
For a record lock that is in waiting state retrieves the only bit that
210
193
is set, for a table lock returns ULINT_UNDEFINED.
257
240
}
258
241
 
259
242
/*******************************************************************//**
260
 
Frees a table cache. */
261
 
static
262
 
void
263
 
table_cache_free(
264
 
/*=============*/
265
 
        i_s_table_cache_t*      table_cache)    /*!< in/out: table cache */
266
 
{
267
 
        ulint   i;
268
 
 
269
 
        for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) {
270
 
 
271
 
                /* the memory is actually allocated in
272
 
                table_cache_create_empty_row() */
273
 
                if (table_cache->chunks[i].base) {
274
 
                        mem_free(table_cache->chunks[i].base);
275
 
                        table_cache->chunks[i].base = NULL;
276
 
                }
277
 
        }
278
 
}
279
 
 
280
 
/*******************************************************************//**
281
243
Returns an empty row from a table cache. The row is allocated if no more
282
244
empty rows are available. The number of used rows is incremented.
283
245
If the memory limit is hit then NULL is returned and nothing is
420
382
        return(row);
421
383
}
422
384
 
423
 
#ifdef UNIV_DEBUG
424
 
/*******************************************************************//**
425
 
Validates a row in the locks cache.
426
 
@return TRUE if valid */
427
 
static
428
 
ibool
429
 
i_s_locks_row_validate(
430
 
/*===================*/
431
 
        const i_s_locks_row_t*  row)    /*!< in: row to validate */
432
 
{
433
 
        ut_ad(row->lock_trx_id != 0);
434
 
        ut_ad(row->lock_mode != NULL);
435
 
        ut_ad(row->lock_type != NULL);
436
 
        ut_ad(row->lock_table != NULL);
437
 
        ut_ad(row->lock_table_id != 0);
438
 
 
439
 
        if (row->lock_space == ULINT_UNDEFINED) {
440
 
                /* table lock */
441
 
                ut_ad(!strcmp("TABLE", row->lock_type));
442
 
                ut_ad(row->lock_index == NULL);
443
 
                ut_ad(row->lock_data == NULL);
444
 
                ut_ad(row->lock_page == ULINT_UNDEFINED);
445
 
                ut_ad(row->lock_rec == ULINT_UNDEFINED);
446
 
        } else {
447
 
                /* record lock */
448
 
                ut_ad(!strcmp("RECORD", row->lock_type));
449
 
                ut_ad(row->lock_index != NULL);
450
 
                ut_ad(row->lock_data != NULL);
451
 
                ut_ad(row->lock_page != ULINT_UNDEFINED);
452
 
                ut_ad(row->lock_rec != ULINT_UNDEFINED);
453
 
        }
454
 
 
455
 
        return(TRUE);
456
 
}
457
 
#endif /* UNIV_DEBUG */
458
 
 
459
385
/*******************************************************************//**
460
386
Fills i_s_trx_row_t object.
461
387
If memory can not be allocated then FALSE is returned.
477
403
                                                which to copy volatile
478
404
                                                strings */
479
405
{
480
 
        const char*     stmt;
481
 
        size_t          stmt_len;
482
 
        const char*     s;
483
 
 
484
 
        ut_ad(mutex_own(&kernel_mutex));
485
 
 
486
 
        row->trx_id = trx->id;
 
406
        row->trx_id = trx_get_id(trx);
487
407
        row->trx_started = (ib_time_t) trx->start_time;
488
408
        row->trx_state = trx_get_que_state_str(trx);
489
 
        row->requested_lock_row = requested_lock_row;
490
 
        ut_ad(requested_lock_row == NULL
491
 
              || i_s_locks_row_validate(requested_lock_row));
492
409
 
493
410
        if (trx->wait_lock != NULL) {
 
411
 
494
412
                ut_a(requested_lock_row != NULL);
 
413
 
 
414
                row->requested_lock_row = requested_lock_row;
495
415
                row->trx_wait_started = (ib_time_t) trx->wait_started;
496
416
        } else {
 
417
 
497
418
                ut_a(requested_lock_row == NULL);
 
419
 
 
420
                row->requested_lock_row = NULL;
498
421
                row->trx_wait_started = 0;
499
422
        }
500
423
 
501
 
        row->trx_weight = (ullint) TRX_WEIGHT(trx);
 
424
        row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx));
502
425
 
503
 
        if (trx->mysql_thd == NULL) {
 
426
        if (trx->mysql_thd != NULL) {
 
427
                row->trx_mysql_thread_id
 
428
#if defined(BUILD_DRIZZLE)
 
429
                        = session_get_thread_id(trx->mysql_thd);
 
430
#else
 
431
                        = thd_get_thread_id(trx->mysql_thd);
 
432
#endif
 
433
        } else {
504
434
                /* For internal transactions e.g., purge and transactions
505
435
                being recovered at startup there is no associated MySQL
506
436
                thread data structure. */
507
437
                row->trx_mysql_thread_id = 0;
508
 
                row->trx_query = NULL;
509
 
                goto thd_done;
510
438
        }
511
439
 
512
 
        row->trx_mysql_thread_id = trx->session()->getSessionId();
513
 
        stmt= trx->mysql_thd->getQueryStringCopy(stmt_len);
514
 
 
515
 
        if (stmt != NULL) {
516
 
 
517
 
                char    query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
518
 
 
519
 
                if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) {
520
 
                        stmt_len = TRX_I_S_TRX_QUERY_MAX_LEN;
 
440
        if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) {
 
441
 
 
442
                if (strlen(*trx->mysql_query_str)
 
443
                    > TRX_I_S_TRX_QUERY_MAX_LEN) {
 
444
 
 
445
                        char    query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
 
446
 
 
447
                        memcpy(query, *trx->mysql_query_str,
 
448
                               TRX_I_S_TRX_QUERY_MAX_LEN);
 
449
                        query[TRX_I_S_TRX_QUERY_MAX_LEN] = '\0';
 
450
 
 
451
                        row->trx_query = ha_storage_put_memlim(
 
452
                                cache->storage, query,
 
453
                                TRX_I_S_TRX_QUERY_MAX_LEN + 1,
 
454
                                MAX_ALLOWED_FOR_STORAGE(cache));
 
455
                } else {
 
456
 
 
457
                        row->trx_query = ha_storage_put_str_memlim(
 
458
                                cache->storage, *trx->mysql_query_str,
 
459
                                MAX_ALLOWED_FOR_STORAGE(cache));
521
460
                }
522
461
 
523
 
                memcpy(query, stmt, stmt_len);
524
 
                query[stmt_len] = '\0';
525
 
 
526
 
                row->trx_query = static_cast<const char *>(ha_storage_put_memlim(
527
 
                        cache->storage, stmt, stmt_len + 1,
528
 
                        MAX_ALLOWED_FOR_STORAGE(cache)));
529
 
 
530
462
                if (row->trx_query == NULL) {
531
463
 
532
464
                        return(FALSE);
536
468
                row->trx_query = NULL;
537
469
        }
538
470
 
539
 
thd_done:
540
 
        s = trx->op_info;
541
 
 
542
 
        if (s != NULL && s[0] != '\0') {
543
 
 
544
 
                TRX_I_S_STRING_COPY(s, row->trx_operation_state,
545
 
                                    TRX_I_S_TRX_OP_STATE_MAX_LEN, cache);
546
 
 
547
 
                if (row->trx_operation_state == NULL) {
548
 
 
549
 
                        return(FALSE);
550
 
                }
551
 
        } else {
552
 
 
553
 
                row->trx_operation_state = NULL;
554
 
        }
555
 
 
556
 
//      row->trx_tables_in_use = trx->n_mysql_tables_in_use;
557
 
 
558
 
        row->trx_tables_locked = trx->mysql_n_tables_locked;
559
 
 
560
 
        row->trx_lock_structs = UT_LIST_GET_LEN(trx->trx_locks);
561
 
 
562
 
        row->trx_lock_memory_bytes = mem_heap_get_size(trx->lock_heap);
563
 
 
564
 
        row->trx_rows_locked = lock_number_of_rows_locked(trx);
565
 
 
566
 
        row->trx_rows_modified = trx->undo_no;
567
 
 
568
 
        row->trx_concurrency_tickets = trx->n_tickets_to_enter_innodb;
569
 
 
570
 
        switch (trx->isolation_level) {
571
 
        case TRX_ISO_READ_UNCOMMITTED:
572
 
                row->trx_isolation_level = "READ UNCOMMITTED";
573
 
                break;
574
 
        case TRX_ISO_READ_COMMITTED:
575
 
                row->trx_isolation_level = "READ COMMITTED";
576
 
                break;
577
 
        case TRX_ISO_REPEATABLE_READ:
578
 
                row->trx_isolation_level = "REPEATABLE READ";
579
 
                break;
580
 
        case TRX_ISO_SERIALIZABLE:
581
 
                row->trx_isolation_level = "SERIALIZABLE";
582
 
                break;
583
 
        /* Should not happen as TRX_ISO_READ_COMMITTED is default */
584
 
        default:
585
 
                row->trx_isolation_level = "UNKNOWN";
586
 
        }
587
 
 
588
 
        row->trx_unique_checks = (ibool) trx->check_unique_secondary;
589
 
 
590
 
        row->trx_foreign_key_checks = (ibool) trx->check_foreigns;
591
 
 
592
 
        s = trx->detailed_error;
593
 
 
594
 
        if (s != NULL && s[0] != '\0') {
595
 
 
596
 
                TRX_I_S_STRING_COPY(s,
597
 
                                    row->trx_foreign_key_error,
598
 
                                    TRX_I_S_TRX_FK_ERROR_MAX_LEN, cache);
599
 
 
600
 
                if (row->trx_foreign_key_error == NULL) {
601
 
 
602
 
                        return(FALSE);
603
 
                }
604
 
        } else {
605
 
                row->trx_foreign_key_error = NULL;
606
 
        }
607
 
 
608
 
        row->trx_has_search_latch = (ibool) trx->has_search_latch;
609
 
 
610
 
        row->trx_search_latch_timeout = trx->search_latch_timeout;
611
 
 
612
471
        return(TRUE);
613
472
}
614
473
 
850
709
        row->lock_table_id = lock_get_table_id(lock);
851
710
 
852
711
        row->hash_chain.value = row;
853
 
        ut_ad(i_s_locks_row_validate(row));
854
712
 
855
713
        return(TRUE);
856
714
}
871
729
                                                relevant blocking lock
872
730
                                                row in innodb_locks */
873
731
{
874
 
        ut_ad(i_s_locks_row_validate(requested_lock_row));
875
 
        ut_ad(i_s_locks_row_validate(blocking_lock_row));
876
 
 
877
732
        row->requested_lock_row = requested_lock_row;
878
733
        row->blocking_lock_row = blocking_lock_row;
879
734
 
945
800
                                        or ULINT_UNDEFINED if the lock
946
801
                                        is a table lock */
947
802
{
948
 
        ut_ad(i_s_locks_row_validate(row));
949
803
#ifdef TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T
950
804
        return(0);
951
805
#else
1003
857
                /* auxiliary variable */
1004
858
                hash_chain,
1005
859
                /* assertion on every traversed item */
1006
 
                ut_ad(i_s_locks_row_validate(hash_chain->value)),
 
860
                ,
1007
861
                /* this determines if we have found the lock */
1008
862
                locks_row_eq_lock(hash_chain->value, lock, heap_no));
1009
863
 
1043
897
        dst_row = search_innodb_locks(cache, lock, heap_no);
1044
898
        if (dst_row != NULL) {
1045
899
 
1046
 
                ut_ad(i_s_locks_row_validate(dst_row));
1047
900
                return(dst_row);
1048
901
        }
1049
902
#endif
1081
934
        } /* for()-loop */
1082
935
#endif
1083
936
 
1084
 
        ut_ad(i_s_locks_row_validate(dst_row));
1085
937
        return(dst_row);
1086
938
}
1087
939
 
1338
1190
                return(1);
1339
1191
        }
1340
1192
 
 
1193
        /* We are going to access trx->query in all transactions */
 
1194
        innobase_mysql_prepare_print_arbitrary_thd();
 
1195
 
1341
1196
        /* We need to read trx_sys and record/table lock queues */
1342
1197
        mutex_enter(&kernel_mutex);
1343
1198
 
1345
1200
 
1346
1201
        mutex_exit(&kernel_mutex);
1347
1202
 
 
1203
        innobase_mysql_end_print_arbitrary_thd();
 
1204
 
1348
1205
        return(0);
1349
1206
}
1350
1207
 
1379
1236
        release trx_i_s_cache_t::last_read_mutex
1380
1237
        release trx_i_s_cache_t::rw_lock */
1381
1238
 
1382
 
        rw_lock_create(trx_i_s_cache_lock_key, &cache->rw_lock,
1383
 
                       SYNC_TRX_I_S_RWLOCK);
 
1239
        rw_lock_create(&cache->rw_lock, SYNC_TRX_I_S_RWLOCK);
1384
1240
 
1385
1241
        cache->last_read = 0;
1386
1242
 
1387
 
        mutex_create(cache_last_read_mutex_key,
1388
 
                     &cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ);
 
1243
        mutex_create(&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ);
1389
1244
 
1390
1245
        table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t));
1391
1246
        table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t));
1403
1258
}
1404
1259
 
1405
1260
/*******************************************************************//**
1406
 
Free the INFORMATION SCHEMA trx related cache. */
1407
 
UNIV_INTERN
1408
 
void
1409
 
trx_i_s_cache_free(
1410
 
/*===============*/
1411
 
        trx_i_s_cache_t*        cache)  /*!< in, own: cache to free */
1412
 
{
1413
 
        hash_table_free(cache->locks_hash);
1414
 
        ha_storage_free(cache->storage);
1415
 
        table_cache_free(&cache->innodb_trx);
1416
 
        table_cache_free(&cache->innodb_locks);
1417
 
        table_cache_free(&cache->innodb_lock_waits);
1418
 
        memset(cache, 0, sizeof *cache);
1419
 
}
1420
 
 
1421
 
/*******************************************************************//**
1422
1261
Issue a shared/read lock on the tables cache. */
1423
1262
UNIV_INTERN
1424
1263
void
1597
1436
        } else {
1598
1437
                /* table lock */
1599
1438
                res_len = ut_snprintf(lock_id, lock_id_size,
1600
 
                                      TRX_ID_FMT ":" TRX_ID_FMT,
 
1439
                                      TRX_ID_FMT ":%llu",
1601
1440
                                      row->lock_trx_id,
1602
1441
                                      row->lock_table_id);
1603
1442
        }