~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-11-25 01:53:19 UTC
  • mto: (1953.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1955.
  • Revision ID: mordred@inaugust.com-20101125015319-ia85msn25uemopgc
Re-enabled -Wformat and then cleaned up the carnage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "srv0srv.h"
40
40
#include "trx0purge.h"
41
41
#include "log0log.h"
42
 
#include "log0recv.h"
43
42
#include "os0file.h"
44
43
#include "read0read.h"
45
44
 
127
126
static const ulint      FILE_FORMAT_NAME_N
128
127
        = sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
129
128
 
130
 
#ifdef UNIV_PFS_MUTEX
131
 
/* Key to register the mutex with performance schema */
132
 
UNIV_INTERN mysql_pfs_key_t     trx_doublewrite_mutex_key;
133
 
UNIV_INTERN mysql_pfs_key_t     file_format_max_mutex_key;
134
 
#endif /* UNIV_PFS_MUTEX */
135
 
 
136
129
#ifndef UNIV_HOTBACKUP
137
130
/** This is used to track the maximum file format id known to InnoDB. It's
138
 
updated via SET GLOBAL innodb_file_format_max = 'x' or when we open
 
131
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
139
132
or create a table. */
140
133
static  file_format_t   file_format_max;
141
134
 
186
179
        os_do_not_call_flush_at_each_write = TRUE;
187
180
#endif /* UNIV_DO_FLUSH */
188
181
 
189
 
        mutex_create(trx_doublewrite_mutex_key,
190
 
                     &trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
 
182
        mutex_create(&trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
191
183
 
192
184
        trx_doublewrite->first_free = 0;
193
185
 
249
241
{
250
242
        buf_block_t*    block;
251
243
        buf_block_t*    block2;
252
 
#ifdef UNIV_SYNC_DEBUG
253
244
        buf_block_t*    new_block;
254
 
#endif /* UNIV_SYNC_DEBUG */
255
245
        byte*   doublewrite;
256
246
        byte*   fseg_header;
257
247
        ulint   page_no;
354
344
                        the page position in the tablespace, then the page
355
345
                        has not been written to in doublewrite. */
356
346
 
357
 
#ifdef UNIV_SYNC_DEBUG
358
 
                        new_block =
359
 
#endif /* UNIV_SYNC_DEBUG */
360
 
                        buf_page_get(TRX_SYS_SPACE, 0, page_no,
361
 
                                     RW_X_LATCH, &mtr);
 
347
                        new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no,
 
348
                                                 RW_X_LATCH, &mtr);
362
349
                        buf_block_dbg_add_level(new_block,
363
350
                                                SYNC_NO_ORDER_CHECK);
364
351
 
669
656
 
670
657
        sys_header = trx_sysf_get(&mtr);
671
658
 
672
 
        mlog_write_ull(sys_header + TRX_SYS_TRX_ID_STORE,
673
 
                       trx_sys->max_trx_id, &mtr);
 
659
        mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE,
 
660
                          trx_sys->max_trx_id, &mtr);
674
661
        mtr_commit(&mtr);
675
662
}
676
663
 
883
870
        buf_block_t*    block;
884
871
        page_t*         page;
885
872
        ulint           page_no;
886
 
        byte*           ptr;
887
 
        ulint           len;
 
873
        ulint           i;
888
874
 
889
875
        ut_ad(mtr);
890
876
 
917
903
        sys_header = trx_sysf_get(mtr);
918
904
 
919
905
        /* Start counting transaction ids from number 1 up */
920
 
        mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1);
921
 
 
922
 
        /* Reset the rollback segment slots.  Old versions of InnoDB
923
 
        define TRX_SYS_N_RSEGS as 256 (TRX_SYS_OLD_N_RSEGS) and expect
924
 
        that the whole array is initialized. */
925
 
        ptr = TRX_SYS_RSEGS + sys_header;
926
 
        len = ut_max(TRX_SYS_OLD_N_RSEGS, TRX_SYS_N_RSEGS)
927
 
                * TRX_SYS_RSEG_SLOT_SIZE;
928
 
        memset(ptr, 0xff, len);
929
 
        ptr += len;
930
 
        ut_a(ptr <= page + (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END));
931
 
 
932
 
        /* Initialize all of the page.  This part used to be uninitialized. */
933
 
        memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr);
934
 
 
935
 
        mlog_log_string(sys_header, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
936
 
                        + page - sys_header, mtr);
 
906
        mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE,
 
907
                          ut_dulint_create(0, 1), mtr);
 
908
 
 
909
        /* Reset the rollback segment slots */
 
910
        for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
 
911
 
 
912
                trx_sysf_rseg_set_space(sys_header, i, ULINT_UNDEFINED, mtr);
 
913
                trx_sysf_rseg_set_page_no(sys_header, i, FIL_NULL, mtr);
 
914
        }
 
915
 
 
916
        /* The remaining area (up to the page trailer) is uninitialized.
 
917
        Silence Valgrind warnings about it. */
 
918
        UNIV_MEM_VALID(sys_header + (TRX_SYS_RSEGS
 
919
                                     + TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
 
920
                                     + TRX_SYS_RSEG_SPACE),
 
921
                       (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
 
922
                        - (TRX_SYS_RSEGS
 
923
                           + TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
 
924
                           + TRX_SYS_RSEG_SPACE))
 
925
                       + page - sys_header);
937
926
 
938
927
        /* Create the first rollback segment in the SYSTEM tablespace */
939
 
        slot_no = trx_sysf_rseg_find_free(mtr);
940
 
        page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, slot_no,
 
928
        page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, &slot_no,
941
929
                                         mtr);
942
930
        ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
943
 
        ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
 
931
        ut_a(page_no != FIL_NULL);
944
932
 
945
933
        mutex_exit(&kernel_mutex);
946
934
}
954
942
/*==========================*/
955
943
{
956
944
        trx_sysf_t*     sys_header;
957
 
        ib_uint64_t     rows_to_undo    = 0;
 
945
        ib_int64_t      rows_to_undo    = 0;
958
946
        const char*     unit            = "";
959
947
        trx_t*          trx;
960
948
        mtr_t           mtr;
980
968
        to the disk-based header! Thus trx id values will not overlap when
981
969
        the database is repeatedly started! */
982
970
 
983
 
        trx_sys->max_trx_id = 2 * TRX_SYS_TRX_ID_WRITE_MARGIN
984
 
                + ut_uint64_align_up(mach_read_from_8(sys_header
985
 
                                                   + TRX_SYS_TRX_ID_STORE),
986
 
                                     TRX_SYS_TRX_ID_WRITE_MARGIN);
 
971
        trx_sys->max_trx_id = ut_dulint_add(
 
972
                ut_dulint_align_up(mtr_read_dulint(
 
973
                                           sys_header
 
974
                                           + TRX_SYS_TRX_ID_STORE, &mtr),
 
975
                                   TRX_SYS_TRX_ID_WRITE_MARGIN),
 
976
                2 * TRX_SYS_TRX_ID_WRITE_MARGIN);
987
977
 
988
978
        UT_LIST_INIT(trx_sys->mysql_trx_list);
989
979
        trx_dummy_sess = sess_open();
994
984
 
995
985
                for (;;) {
996
986
 
997
 
                        if (trx->conc_state != TRX_PREPARED) {
998
 
                                rows_to_undo += trx->undo_no;
 
987
                        if ( trx->conc_state != TRX_PREPARED) {
 
988
                                rows_to_undo += ut_conv_dulint_to_longlong(
 
989
                                        trx->undo_no);
999
990
                        }
1000
991
 
1001
992
                        trx = UT_LIST_GET_NEXT(trx_list, trx);
1018
1009
                        (ulong) rows_to_undo, unit);
1019
1010
 
1020
1011
                fprintf(stderr, "InnoDB: Trx id counter is " TRX_ID_FMT "\n",
1021
 
                        trx_sys->max_trx_id);
 
1012
                        TRX_ID_PREP_PRINTF(trx_sys->max_trx_id));
1022
1013
        }
1023
1014
 
1024
1015
        UT_LIST_INIT(trx_sys->view_list);
1062
1053
        mtr_t           mtr;
1063
1054
        byte*           ptr;
1064
1055
        buf_block_t*    block;
1065
 
        ib_uint64_t     tag_value;
 
1056
        ulint           tag_value_low;
1066
1057
 
1067
1058
        mtr_start(&mtr);
1068
1059
 
1073
1064
        file_format_max.name = trx_sys_file_format_id_to_name(format_id);
1074
1065
 
1075
1066
        ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
1076
 
        tag_value = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
 
1067
        tag_value_low = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1077
1068
 
1078
1069
        if (name) {
1079
1070
                *name = file_format_max.name;
1080
1071
        }
1081
1072
 
1082
 
        mlog_write_ull(ptr, tag_value, &mtr);
 
1073
        mlog_write_dulint(
 
1074
                ptr,
 
1075
                ut_dulint_create(TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH,
 
1076
                                 tag_value_low),
 
1077
                &mtr);
1083
1078
 
1084
1079
        mtr_commit(&mtr);
1085
1080
 
1097
1092
        mtr_t                   mtr;
1098
1093
        const byte*             ptr;
1099
1094
        const buf_block_t*      block;
1100
 
        ib_id_t                 file_format_id;
 
1095
        ulint                   format_id;
 
1096
        dulint                  file_format_id;
1101
1097
 
1102
1098
        /* Since this is called during the startup phase it's safe to
1103
1099
        read the value without a covering mutex. */
1111
1107
 
1112
1108
        mtr_commit(&mtr);
1113
1109
 
1114
 
        file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
 
1110
        format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1115
1111
 
1116
 
        if (file_format_id >= FILE_FORMAT_NAME_N) {
 
1112
        if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
 
1113
            || format_id >= FILE_FORMAT_NAME_N) {
1117
1114
 
1118
1115
                /* Either it has never been tagged, or garbage in it. */
1119
1116
                return(ULINT_UNDEFINED);
1120
1117
        }
1121
1118
 
1122
 
        return((ulint) file_format_id);
 
1119
        return(format_id);
1123
1120
}
1124
1121
 
1125
1122
/*****************************************************************//**
1155
1152
        if (format_id == ULINT_UNDEFINED) {
1156
1153
                /* Format ID was not set. Set it to minimum possible
1157
1154
                value. */
1158
 
                format_id = DICT_TF_FORMAT_MIN;
 
1155
                format_id = DICT_TF_FORMAT_51;
1159
1156
        }
1160
1157
 
1161
1158
        ut_print_timestamp(stderr);
1235
1232
 
1236
1233
        /* If format_id is not set then set it to the minimum. */
1237
1234
        if (format_id == ULINT_UNDEFINED) {
1238
 
                trx_sys_file_format_max_set(DICT_TF_FORMAT_MIN, NULL);
 
1235
                trx_sys_file_format_max_set(DICT_TF_FORMAT_51, NULL);
1239
1236
        }
1240
1237
}
1241
1238
 
1286
1283
trx_sys_file_format_init(void)
1287
1284
/*==========================*/
1288
1285
{
1289
 
        mutex_create(file_format_max_mutex_key,
1290
 
                     &file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
 
1286
        mutex_create(&file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
1291
1287
 
1292
1288
        /* We don't need a mutex here, as this function should only
1293
1289
        be called once at start up. */
1294
 
        file_format_max.id = DICT_TF_FORMAT_MIN;
 
1290
        file_format_max.id = DICT_TF_FORMAT_51;
1295
1291
 
1296
1292
        file_format_max.name = trx_sys_file_format_id_to_name(
1297
1293
                file_format_max.id);
1306
1302
{
1307
1303
        /* Does nothing at the moment */
1308
1304
}
1309
 
 
1310
 
/*********************************************************************
1311
 
Creates the rollback segments */
1312
 
UNIV_INTERN
1313
 
void
1314
 
trx_sys_create_rsegs(
1315
 
/*=================*/
1316
 
        ulint   n_rsegs)        /*!< number of rollback segments to create */
1317
 
{
1318
 
        ulint   new_rsegs = 0;
1319
 
 
1320
 
        /* Do not create additional rollback segments if
1321
 
        innodb_force_recovery has been set and the database
1322
 
        was not shutdown cleanly. */
1323
 
        if (!srv_force_recovery && !recv_needed_recovery) {
1324
 
                ulint   i;
1325
 
 
1326
 
                for (i = 0;  i < n_rsegs; ++i) {
1327
 
 
1328
 
                        if (trx_rseg_create() != NULL) {
1329
 
                                ++new_rsegs;
1330
 
                        } else {
1331
 
                                break;
1332
 
                        }
1333
 
                }
1334
 
        }
1335
 
 
1336
 
        if (new_rsegs > 0) {
1337
 
                fprintf(stderr,
1338
 
                        "InnoDB: %lu rollback segment(s) active.\n",
1339
 
                        new_rsegs);
1340
 
        }
1341
 
}
1342
 
 
1343
1305
#else /* !UNIV_HOTBACKUP */
1344
1306
/*****************************************************************//**
1345
1307
Prints to stderr the MySQL binlog info in the system header if the
1411
1373
        byte            buf[UNIV_PAGE_SIZE * 2];
1412
1374
        page_t*         page = ut_align(buf, UNIV_PAGE_SIZE);
1413
1375
        const byte*     ptr;
1414
 
        ib_id_t         file_format_id;
 
1376
        dulint          file_format_id;
1415
1377
 
1416
1378
        *format_id = ULINT_UNDEFINED;
1417
 
 
 
1379
        
1418
1380
        file = os_file_create_simple_no_error_handling(
1419
 
                innodb_file_data_key,
1420
1381
                pathname,
1421
1382
                OS_FILE_OPEN,
1422
1383
                OS_FILE_READ_ONLY,
1425
1386
        if (!success) {
1426
1387
                /* The following call prints an error message */
1427
1388
                os_file_get_last_error(TRUE);
1428
 
 
 
1389
        
1429
1390
                ut_print_timestamp(stderr);
1430
 
 
 
1391
        
1431
1392
                fprintf(stderr,
1432
1393
"  ibbackup: Error: trying to read system tablespace file format,\n"
1433
1394
"  ibbackup: but could not open the tablespace file %s!\n",
1444
1405
        if (!success) {
1445
1406
                /* The following call prints an error message */
1446
1407
                os_file_get_last_error(TRUE);
1447
 
 
 
1408
        
1448
1409
                ut_print_timestamp(stderr);
1449
 
 
 
1410
        
1450
1411
                fprintf(stderr,
1451
1412
"  ibbackup: Error: trying to read system table space file format,\n"
1452
1413
"  ibbackup: but failed to read the tablespace file %s!\n",
1460
1421
        /* get the file format from the page */
1461
1422
        ptr = page + TRX_SYS_FILE_FORMAT_TAG;
1462
1423
        file_format_id = mach_read_from_8(ptr);
1463
 
        file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1464
 
 
1465
 
        if (file_format_id >= FILE_FORMAT_NAME_N) {
 
1424
 
 
1425
        *format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
 
1426
 
 
1427
        if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
 
1428
            || *format_id >= FILE_FORMAT_NAME_N) {
1466
1429
 
1467
1430
                /* Either it has never been tagged, or garbage in it. */
 
1431
                *format_id = ULINT_UNDEFINED;
1468
1432
                return(TRUE);
1469
1433
        }
1470
 
 
1471
 
        *format_id = (ulint) file_format_id;
1472
 
 
 
1434
        
1473
1435
        return(TRUE);
1474
1436
}
1475
1437
 
1494
1456
        ib_uint32_t     flags;
1495
1457
 
1496
1458
        *format_id = ULINT_UNDEFINED;
1497
 
 
 
1459
        
1498
1460
        file = os_file_create_simple_no_error_handling(
1499
 
                innodb_file_data_key,
1500
1461
                pathname,
1501
1462
                OS_FILE_OPEN,
1502
1463
                OS_FILE_READ_ONLY,