~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/fil/fil0fil.c

  • Committer: Lee Bieber
  • Date: 2010-12-15 16:23:36 UTC
  • mfrom: (1995.1.2 build)
  • Revision ID: kalebral@gmail.com-20101215162336-juntyt4gw4vgohg4
Merge Andrew - fix bug 628912: Crash / segfault in drizzled::Item_func::arguments (this=0x35) at ./drizzled/function/func.h
Merge Andrew - 663919: next query after KILL QUERY will error

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2010, 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
339
339
/*******************************************************************//**
340
340
Frees a space object from the tablespace memory cache. Closes the files in
341
341
the chain but does not delete them. There must not be any pending i/o's or
342
 
flushes on the files.
343
 
@return TRUE on success */
 
342
flushes on the files. */
344
343
static
345
344
ibool
346
345
fil_space_free(
347
346
/*===========*/
348
 
        ulint           id,             /* in: space id */
349
 
        ibool           x_latched);     /* in: TRUE if caller has space->latch
350
 
                                        in X mode */
 
347
                                /* out: TRUE if success */
 
348
        ulint           id,     /* in: space id */
 
349
        ibool           own_mutex);/* in: TRUE if own system->mutex */
351
350
/********************************************************************//**
352
351
Reads data from a space to a buffer. Remember that the possible incomplete
353
352
blocks at the end of file are ignored: they are not taken into account when
581
580
 
582
581
        mutex_enter(&fil_system->mutex);
583
582
 
584
 
        node = static_cast<fil_node_t *>(mem_alloc(sizeof(fil_node_t)));
 
583
        node = mem_alloc(sizeof(fil_node_t));
585
584
 
586
585
        node->name = mem_strdup(name);
587
586
        node->open = FALSE;
711
710
 
712
711
                /* Read the first page of the tablespace */
713
712
 
714
 
                buf2 = static_cast<unsigned char *>(ut_malloc(2 * UNIV_PAGE_SIZE));
 
713
                buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
715
714
                /* Align the memory for file i/o if we might have O_DIRECT
716
715
                set */
717
 
                page = static_cast<unsigned char *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
716
                page = ut_align(buf2, UNIV_PAGE_SIZE);
718
717
 
719
718
                success = os_file_read(node->handle, page, 0, 0,
720
719
                                       UNIV_PAGE_SIZE);
1141
1140
        space = fil_space_get_by_name(name);
1142
1141
 
1143
1142
        if (UNIV_LIKELY_NULL(space)) {
1144
 
                ibool   success;
1145
1143
                ulint   namesake_id;
1146
1144
 
1147
1145
                ut_print_timestamp(stderr);
1180
1178
 
1181
1179
                namesake_id = space->id;
1182
1180
 
1183
 
                success = fil_space_free(namesake_id, FALSE);
1184
 
                ut_a(success);
1185
 
 
1186
1181
                mutex_exit(&fil_system->mutex);
1187
1182
 
 
1183
                fil_space_free(namesake_id, FALSE);
 
1184
 
1188
1185
                goto try_again;
1189
1186
        }
1190
1187
 
1208
1205
                return(FALSE);
1209
1206
        }
1210
1207
 
1211
 
        space = static_cast<fil_space_t *>(mem_alloc(sizeof(fil_space_t)));
 
1208
        space = mem_alloc(sizeof(fil_space_t));
1212
1209
 
1213
1210
        space->name = mem_strdup(name);
1214
1211
        space->id = id;
1334
1331
/*===========*/
1335
1332
                                        /* out: TRUE if success */
1336
1333
        ulint           id,             /* in: space id */
1337
 
        ibool           x_latched)      /* in: TRUE if caller has space->latch
1338
 
                                        in X mode */
 
1334
        ibool           own_mutex)      /* in: TRUE if own system->mutex */
1339
1335
{
1340
1336
        fil_space_t*    space;
1341
 
        fil_space_t*    tablespace;
 
1337
        fil_space_t*    namespace;
1342
1338
        fil_node_t*     fil_node;
1343
1339
 
1344
 
        ut_ad(mutex_own(&fil_system->mutex));
 
1340
        if (!own_mutex) {
 
1341
                mutex_enter(&fil_system->mutex);
 
1342
        }
1345
1343
 
1346
1344
        space = fil_space_get_by_id(id);
1347
1345
 
1352
1350
                        " from the cache but\n"
1353
1351
                        "InnoDB: it is not there.\n", (ulong) id);
1354
1352
 
 
1353
                mutex_exit(&fil_system->mutex);
 
1354
 
1355
1355
                return(FALSE);
1356
1356
        }
1357
1357
 
1358
1358
        HASH_DELETE(fil_space_t, hash, fil_system->spaces, id, space);
1359
1359
 
1360
 
        tablespace = fil_space_get_by_name(space->name);
1361
 
        ut_a(tablespace);
1362
 
        ut_a(space == tablespace);
 
1360
        namespace = fil_space_get_by_name(space->name);
 
1361
        ut_a(namespace);
 
1362
        ut_a(space == namespace);
1363
1363
 
1364
1364
        HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
1365
1365
                    ut_fold_string(space->name), space);
1386
1386
 
1387
1387
        ut_a(0 == UT_LIST_GET_LEN(space->chain));
1388
1388
 
1389
 
        if (x_latched) {
1390
 
                rw_lock_x_unlock(&space->latch);
 
1389
        if (!own_mutex) {
 
1390
                mutex_exit(&fil_system->mutex);
1391
1391
        }
1392
1392
 
1393
1393
        rw_lock_free(&(space->latch));
1553
1553
        ut_a(hash_size > 0);
1554
1554
        ut_a(max_n_open > 0);
1555
1555
 
1556
 
        void *fil_system_ptr= mem_zalloc(sizeof(fil_system_t));
1557
 
        fil_system = static_cast<fil_system_t *>(fil_system_ptr);
 
1556
        fil_system = mem_zalloc(sizeof(fil_system_t));
1558
1557
 
1559
1558
        mutex_create(fil_system_mutex_key,
1560
1559
                     &fil_system->mutex, SYNC_ANY_LATCH);
1634
1633
/*=====================*/
1635
1634
{
1636
1635
        fil_space_t*    space;
 
1636
        fil_node_t*     node;
1637
1637
 
1638
1638
        mutex_enter(&fil_system->mutex);
1639
1639
 
1640
1640
        space = UT_LIST_GET_FIRST(fil_system->space_list);
1641
1641
 
1642
1642
        while (space != NULL) {
1643
 
                fil_node_t*     node;
1644
1643
                fil_space_t*    prev_space = space;
1645
1644
 
1646
 
                for (node = UT_LIST_GET_FIRST(space->chain);
1647
 
                     node != NULL;
1648
 
                     node = UT_LIST_GET_NEXT(chain, node)) {
 
1645
                node = UT_LIST_GET_FIRST(space->chain);
1649
1646
 
 
1647
                while (node != NULL) {
1650
1648
                        if (node->open) {
1651
1649
                                fil_node_close_file(node, fil_system);
1652
1650
                        }
 
1651
                        node = UT_LIST_GET_NEXT(chain, node);
1653
1652
                }
1654
 
 
1655
1653
                space = UT_LIST_GET_NEXT(space_list, space);
1656
 
 
1657
 
                fil_space_free(prev_space->id, FALSE);
 
1654
                fil_space_free(prev_space->id, TRUE);
1658
1655
        }
1659
1656
 
1660
1657
        mutex_exit(&fil_system->mutex);
1697
1694
        ulint           sum_of_sizes,   /*!< in: combined size of previous files
1698
1695
                                        in space, in database pages */
1699
1696
        ib_uint64_t     lsn,            /*!< in: lsn to write */
1700
 
        ulint           /*arch_log_no __attribute__((unused))*/)
 
1697
        ulint           arch_log_no __attribute__((unused)))
1701
1698
                                        /*!< in: archived log number to write */
1702
1699
{
1703
1700
        byte*   buf1;
1704
1701
        byte*   buf;
1705
1702
 
1706
 
        buf1 = static_cast<byte *>(mem_alloc(2 * UNIV_PAGE_SIZE));
1707
 
        buf = static_cast<byte *>(ut_align(buf1, UNIV_PAGE_SIZE));
 
1703
        buf1 = mem_alloc(2 * UNIV_PAGE_SIZE);
 
1704
        buf = ut_align(buf1, UNIV_PAGE_SIZE);
1708
1705
 
1709
1706
        fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1710
1707
 
1796
1793
        byte*           buf2;
1797
1794
        ib_uint64_t     flushed_lsn;
1798
1795
 
1799
 
        buf2 = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
 
1796
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
1800
1797
        /* Align the memory for a possible read from a raw device */
1801
 
        buf = static_cast<byte *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
1798
        buf = ut_align(buf2, UNIV_PAGE_SIZE);
1802
1799
 
1803
1800
        os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
1804
1801
 
1916
1913
        len = strlen(fil_path_to_mysql_datadir);
1917
1914
        namend = strchr(name, '/');
1918
1915
        ut_a(namend);
1919
 
        path = static_cast<char *>(mem_alloc(len + (namend - name) + 2));
 
1916
        path = mem_alloc(len + (namend - name) + 2);
1920
1917
 
1921
1918
        memcpy(path, fil_path_to_mysql_datadir, len);
1922
1919
        path[len] = '/';
2274
2271
        path = mem_strdup(space->name);
2275
2272
 
2276
2273
        mutex_exit(&fil_system->mutex);
2277
 
 
2278
 
        /* Important: We rely on the data dictionary mutex to ensure
2279
 
        that a race is not possible here. It should serialize the tablespace
2280
 
        drop/free. We acquire an X latch only to avoid a race condition
2281
 
        when accessing the tablespace instance via:
2282
 
 
2283
 
          fsp_get_available_space_in_free_extents().
2284
 
 
2285
 
        There our main motivation is to reduce the contention on the
2286
 
        dictionary mutex. */
2287
 
 
2288
 
        rw_lock_x_lock(&space->latch);
2289
 
 
2290
2274
#ifndef UNIV_HOTBACKUP
2291
2275
        /* Invalidate in the buffer pool all pages belonging to the
2292
2276
        tablespace. Since we have set space->is_being_deleted = TRUE, readahead
2299
2283
#endif
2300
2284
        /* printf("Deleting tablespace %s id %lu\n", space->name, id); */
2301
2285
 
2302
 
        mutex_enter(&fil_system->mutex);
2303
 
 
2304
 
        success = fil_space_free(id, TRUE);
2305
 
 
2306
 
        mutex_exit(&fil_system->mutex);
 
2286
        success = fil_space_free(id, FALSE);
2307
2287
 
2308
2288
        if (success) {
2309
2289
                success = os_file_delete(path);
2311
2291
                if (!success) {
2312
2292
                        success = os_file_delete_if_exists(path);
2313
2293
                }
2314
 
        } else {
2315
 
                rw_lock_x_unlock(&space->latch);
2316
2294
        }
2317
2295
 
2318
2296
        if (success) {
2340
2318
        return(FALSE);
2341
2319
}
2342
2320
 
2343
 
/*******************************************************************//**
2344
 
Returns TRUE if a single-table tablespace is being deleted.
2345
 
@return TRUE if being deleted */
2346
 
UNIV_INTERN
2347
 
ibool
2348
 
fil_tablespace_is_being_deleted(
2349
 
/*============================*/
2350
 
        ulint           id)     /*!< in: space id */
2351
 
{
2352
 
        fil_space_t*    space;
2353
 
        ibool           is_being_deleted;
2354
 
 
2355
 
        mutex_enter(&fil_system->mutex);
2356
 
 
2357
 
        space = fil_space_get_by_id(id);
2358
 
 
2359
 
        ut_a(space != NULL);
2360
 
 
2361
 
        is_being_deleted = space->is_being_deleted;
2362
 
 
2363
 
        mutex_exit(&fil_system->mutex);
2364
 
 
2365
 
        return(is_being_deleted);
2366
 
}
2367
 
 
2368
2321
#ifndef UNIV_HOTBACKUP
2369
2322
/*******************************************************************//**
2370
2323
Discards a single-table tablespace. The tablespace must be cached in the
2463
2416
{
2464
2417
        ulint   namelen         = strlen(name);
2465
2418
        ulint   dirlen          = strlen(fil_path_to_mysql_datadir);
2466
 
        char*   filename        = static_cast<char *>(mem_alloc(namelen + dirlen + sizeof "/.ibd"));
 
2419
        char*   filename        = mem_alloc(namelen + dirlen + sizeof "/.ibd");
2467
2420
 
2468
2421
        if (is_temp) {
2469
2422
                memcpy(filename, name, namelen);
2745
2698
        with zeros from the call of os_file_set_size(), until a buffer pool
2746
2699
        flush would write to it. */
2747
2700
 
2748
 
        buf2 = static_cast<byte *>(ut_malloc(3 * UNIV_PAGE_SIZE));
 
2701
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2749
2702
        /* Align the memory for file i/o if we might have O_DIRECT set */
2750
 
        page = static_cast<byte *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
2703
        page = ut_align(buf2, UNIV_PAGE_SIZE);
2751
2704
 
2752
2705
        memset(page, '\0', UNIV_PAGE_SIZE);
2753
2706
 
2885
2838
 
2886
2839
        /* Read the first page of the tablespace */
2887
2840
 
2888
 
        buf2 = static_cast<byte *>(ut_malloc(3 * UNIV_PAGE_SIZE));
 
2841
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2889
2842
        /* Align the memory for file i/o if we might have O_DIRECT set */
2890
 
        page = static_cast<byte *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
2843
        page = ut_align(buf2, UNIV_PAGE_SIZE);
2891
2844
 
2892
2845
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
2893
2846
        if (!success) {
3087
3040
 
3088
3041
        /* Read the first page of the tablespace */
3089
3042
 
3090
 
        buf2 = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
 
3043
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
3091
3044
        /* Align the memory for file i/o if we might have O_DIRECT set */
3092
 
        page = static_cast<byte *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
3045
        page = ut_align(buf2, UNIV_PAGE_SIZE);
3093
3046
 
3094
3047
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
3095
3048
 
3189
3142
#ifdef UNIV_HOTBACKUP
3190
3143
        fil_space_t*    space;
3191
3144
#endif
3192
 
        filepath = static_cast<char *>(mem_alloc(strlen(dbname) + strlen(filename)
3193
 
                             + strlen(fil_path_to_mysql_datadir) + 3));
 
3145
        filepath = mem_alloc(strlen(dbname) + strlen(filename)
 
3146
                             + strlen(fil_path_to_mysql_datadir) + 3);
3194
3147
 
3195
3148
        sprintf(filepath, "%s/%s/%s", fil_path_to_mysql_datadir, dbname,
3196
3149
                filename);
3324
3277
#endif
3325
3278
        /* Read the first page of the tablespace if the size big enough */
3326
3279
 
3327
 
        buf2 = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
 
3280
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
3328
3281
        /* Align the memory for file i/o if we might have O_DIRECT set */
3329
 
        page = static_cast<byte *>(ut_align(buf2, UNIV_PAGE_SIZE));
 
3282
        page = ut_align(buf2, UNIV_PAGE_SIZE);
3330
3283
 
3331
3284
        if (size >= FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
3332
3285
                success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
3513
3466
                return(DB_ERROR);
3514
3467
        }
3515
3468
 
3516
 
        dbpath = static_cast<char *>(mem_alloc(dbpath_len));
 
3469
        dbpath = mem_alloc(dbpath_len);
3517
3470
 
3518
3471
        /* Scan all directories under the datadir. They are the database
3519
3472
        directories of MySQL. */
3542
3495
                                mem_free(dbpath);
3543
3496
                        }
3544
3497
 
3545
 
                        dbpath = static_cast<char *>(mem_alloc(dbpath_len));
 
3498
                        dbpath = mem_alloc(dbpath_len);
3546
3499
                }
3547
3500
                sprintf(dbpath, "%s/%s", fil_path_to_mysql_datadir,
3548
3501
                        dbinfo.name);
3699
3652
                                        matching tablespace is not found from
3700
3653
                                        memory */
3701
3654
{
3702
 
        fil_space_t*    tablespace;
 
3655
        fil_space_t*    namespace;
3703
3656
        fil_space_t*    space;
3704
3657
        char*           path;
3705
3658
 
3716
3669
        /* Look if there is a space with the same name; the name is the
3717
3670
        directory path from the datadir to the file */
3718
3671
 
3719
 
        tablespace = fil_space_get_by_name(path);
3720
 
        if (space && space == tablespace) {
 
3672
        namespace = fil_space_get_by_name(path);
 
3673
        if (space && space == namespace) {
3721
3674
                /* Found */
3722
3675
 
3723
3676
                if (mark_space) {
3739
3692
        }
3740
3693
 
3741
3694
        if (space == NULL) {
3742
 
                if (tablespace == NULL) {
 
3695
                if (namespace == NULL) {
3743
3696
                        ut_print_timestamp(stderr);
3744
3697
                        fputs("  InnoDB: Error: table ", stderr);
3745
3698
                        ut_print_filename(stderr, name);
3768
3721
                                "InnoDB: a tablespace of name %s and id %lu,"
3769
3722
                                " though. Have\n"
3770
3723
                                "InnoDB: you deleted or moved .ibd files?\n",
3771
 
                                (ulong) id, tablespace->name,
3772
 
                                (ulong) tablespace->id);
 
3724
                                (ulong) id, namespace->name,
 
3725
                                (ulong) namespace->id);
3773
3726
                }
3774
3727
error_exit:
3775
3728
                fputs("InnoDB: Please refer to\n"
3794
3747
                        "InnoDB: Have you deleted or moved .ibd files?\n",
3795
3748
                        (ulong) id, space->name);
3796
3749
 
3797
 
                if (tablespace != NULL) {
 
3750
                if (namespace != NULL) {
3798
3751
                        fputs("InnoDB: There is a tablespace"
3799
3752
                              " with the right name\n"
3800
3753
                              "InnoDB: ", stderr);
3801
 
                        ut_print_filename(stderr, tablespace->name);
 
3754
                        ut_print_filename(stderr, namespace->name);
3802
3755
                        fprintf(stderr, ", but its id is %lu.\n",
3803
 
                                (ulong) tablespace->id);
 
3756
                                (ulong) namespace->id);
3804
3757
                }
3805
3758
 
3806
3759
                goto error_exit;
3823
3776
        const char*     name)   /*!< in: table name in the standard
3824
3777
                                'databasename/tablename' format */
3825
3778
{
3826
 
        fil_space_t*    tablespace;
 
3779
        fil_space_t*    namespace;
3827
3780
        ulint           id              = ULINT_UNDEFINED;
3828
3781
        char*           path;
3829
3782
 
3836
3789
        /* Look if there is a space with the same name; the name is the
3837
3790
        directory path to the file */
3838
3791
 
3839
 
        tablespace = fil_space_get_by_name(path);
 
3792
        namespace = fil_space_get_by_name(path);
3840
3793
 
3841
 
        if (tablespace) {
3842
 
                id = tablespace->id;
 
3794
        if (namespace) {
 
3795
                id = namespace->id;
3843
3796
        }
3844
3797
 
3845
3798
        mem_free(path);
3907
3860
 
3908
3861
        /* Extend at most 64 pages at a time */
3909
3862
        buf_size = ut_min(64, size_after_extend - start_page_no) * page_size;
3910
 
        buf2 = static_cast<byte *>(mem_alloc(buf_size + page_size));
3911
 
        buf = static_cast<byte *>(ut_align(buf2, page_size));
 
3863
        buf2 = mem_alloc(buf_size + page_size);
 
3864
        buf = ut_align(buf2, page_size);
3912
3865
 
3913
3866
        memset(buf, 0, buf_size);
3914
3867
 
4532
4485
 
4533
4486
        if (fil_node->space->purpose == FIL_TABLESPACE) {
4534
4487
                srv_set_io_thread_op_info(segment, "complete io for buf page");
4535
 
                buf_page_io_complete(static_cast<buf_page_t *>(message));
 
4488
                buf_page_io_complete(message);
4536
4489
        } else {
4537
4490
                srv_set_io_thread_op_info(segment, "complete io for log");
4538
 
                log_io_complete(static_cast<log_group_t *>(message));
 
4491
                log_io_complete(message);
4539
4492
        }
4540
4493
}
4541
4494
#endif /* UNIV_HOTBACKUP */
4682
4635
        traversed fil_system->unflushed_spaces and called UT_LIST_GET_NEXT()
4683
4636
        on a space that was just removed from the list by fil_flush().
4684
4637
        Thus, the space could be dropped and the memory overwritten. */
4685
 
        space_ids = static_cast<unsigned long *>(mem_alloc(n_space_ids * sizeof *space_ids));
 
4638
        space_ids = mem_alloc(n_space_ids * sizeof *space_ids);
4686
4639
 
4687
4640
        n_space_ids = 0;
4688
4641
 
4727
4680
 
4728
4681
        for (i = 0; i < hash_get_n_cells(fil_system->spaces); i++) {
4729
4682
 
4730
 
                space = static_cast<fil_space_t *>(HASH_GET_FIRST(fil_system->spaces, i));
 
4683
                space = HASH_GET_FIRST(fil_system->spaces, i);
4731
4684
 
4732
4685
                while (space != NULL) {
4733
4686
                        UT_LIST_VALIDATE(chain, fil_node_t, space->chain,
4746
4699
                                }
4747
4700
                                fil_node = UT_LIST_GET_NEXT(chain, fil_node);
4748
4701
                        }
4749
 
                        space = static_cast<fil_space_t *>(HASH_GET_NEXT(hash, space));
 
4702
                        space = HASH_GET_NEXT(hash, space);
4750
4703
                }
4751
4704
        }
4752
4705
 
4835
4788
        return(mach_read_from_2(page + FIL_PAGE_TYPE));
4836
4789
}
4837
4790
 
4838
 
/****************************************************************//**
 
4791
/********************************************************************
4839
4792
Initializes the tablespace memory cache. */
4840
4793
UNIV_INTERN
4841
4794
void