~clint-fewbar/ubuntu/natty/mysql-5.1/merge-5.1.49-2

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/row/row0merge.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-08-04 13:18:27 UTC
  • mfrom: (1.2.2 upstream) (2.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100804131827-4tjg88vr9dd49s3k
Tags: 5.1.49-1ubuntu1
* Merge from debian unstable:
  + debian/control:
     * Update maintainer according to spec.
     * Move section from "misc" to "database".
     * Added libmysqlclient16-dev an empty transitional package. 
     * Added mysql-client-core-5.1 package.
     * Suggest mailx for mysql-server-5.1
     * Add mysql-testsuite package so you can run the testsuite seperately.
  + debian/additions/my.cnf:
    * Remove language options. Error message files are located in a different directory in Mysql
      5.0. Setting the language option to use /usr/share/mysql/english breaks Mysql 5.0. Both 5.0
      and 5.1 use a different value that works. (LP: #316974)
  + Add apparmor profile:
    + debian/apparmor-profile: apparmor-profile
    + debian/rules, debian/mysql-server-5.1.files: install apparmor profile
    + debian/mysql-server-5.1.dirs: add etc/apparmor.d/fore-complain
    + debian/mysql-server-5.1.postrm: remove symlink in force-complain/ on purge.
    + debian/mysql-server-5.1.README.Debian: add apparmor documentation.
    + debian/additions/my.cnf: Add warning about apparmor. (LP: #201799)
    + debian/mysql-server-5.1.postinst: reload apparmor profiles
  * Convert the package from sysvinit to upstart:
    + debian/mysql-server-5.1.mysql.upstart: Add upstart script.
    + debian/mysql-server-5.1.mysql.init: Dropped, unused now with upstart.
    + debian/additions/mysqld_safe_syslog.cnf: Dropped, unused now with upstart.
    + debian/additons/my.cnf: Remove pid declaration and setup error logging to /var/log/mysql since
      we're not piping anything around logger anymore.
    + debian/rules, debian/mysql-server-5.1.logcheck.ignore.{paranoid,worstation},
      debian/mysql-server-5.1.logcheck.ignore.server: : Remove references to mysqld_safe
    + debian/patches/38_scripts_mysqld_safe.sh_signals.dpatch: Dropped
  * Added -fno-strict-aliasing to CFLAGS to get around mysql testsuite build failures.
  * Add Apport hook (LP: #354188):
    + debian/mysql-server-5.1.py: apport package hook
    + debian/rules: Make it installable
  * debian/mysql-server-5.1.mysql-server.logrotate: Check to see if mysql is running before
    running logrotate. (LP: #513135)
  * Make the testsuite installable. (LP: #530752)
    + debian/mysql-server-5.1.files, debian/rules: install apport package hook
  * debian/mysql-server-5.1.preinst: Set mysql user's home directory
    to /nonexistent to protect against having the /var/lib/mysql
    user-writeable. If an attacker can trick mysqld into creating
    dot files in the home directory, he could do .rhost-like attacks
    on the system. (LP: #293258)
  * debian/control: mysql-client-5.1 should depend on mysql-core-client-5.1.
    (LP: #590952) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1578
1578
        const dict_index_t*     index,  /*!< in: index being created */
1579
1579
        merge_file_t*           file,   /*!< in/out: file containing
1580
1580
                                        index entries */
1581
 
        ulint*                  half,   /*!< in/out: half the file */
1582
1581
        row_merge_block_t*      block,  /*!< in/out: 3 buffers */
1583
1582
        int*                    tmpfd,  /*!< in/out: temporary file handle */
1584
 
        TABLE*                  table)  /*!< in/out: MySQL table, for
 
1583
        TABLE*                  table,  /*!< in/out: MySQL table, for
1585
1584
                                        reporting erroneous key value
1586
1585
                                        if applicable */
 
1586
        ulint*                  num_run,/*!< in/out: Number of runs remain
 
1587
                                        to be merged */
 
1588
        ulint*                  run_offset) /*!< in/out: Array contains the
 
1589
                                        first offset number for each merge
 
1590
                                        run */
1587
1591
{
1588
1592
        ulint           foffs0; /*!< first input offset */
1589
1593
        ulint           foffs1; /*!< second input offset */
1590
1594
        ulint           error;  /*!< error code */
1591
1595
        merge_file_t    of;     /*!< output file */
1592
 
        const ulint     ihalf   = *half;
 
1596
        const ulint     ihalf   = run_offset[*num_run / 2];
1593
1597
                                /*!< half the input file */
1594
 
        ulint           ohalf;  /*!< half the output file */
 
1598
        ulint           n_run   = 0;
 
1599
                                /*!< num of runs generated from this merge */
1595
1600
 
1596
1601
        UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
 
1602
 
1597
1603
        ut_ad(ihalf < file->offset);
1598
1604
 
1599
1605
        of.fd = *tmpfd;
1601
1607
        of.n_rec = 0;
1602
1608
 
1603
1609
        /* Merge blocks to the output file. */
1604
 
        ohalf = 0;
1605
1610
        foffs0 = 0;
1606
1611
        foffs1 = ihalf;
1607
1612
 
 
1613
        UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset);
 
1614
 
1608
1615
        for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
1609
 
                ulint   ahalf;  /*!< arithmetic half the input file */
1610
1616
 
1611
1617
                if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
1612
1618
                        return(DB_INTERRUPTED);
1613
1619
                }
1614
1620
 
 
1621
                /* Remember the offset number for this run */
 
1622
                run_offset[n_run++] = of.offset;
 
1623
 
1615
1624
                error = row_merge_blocks(index, file, block,
1616
1625
                                         &foffs0, &foffs1, &of, table);
1617
1626
 
1619
1628
                        return(error);
1620
1629
                }
1621
1630
 
1622
 
                /* Record the offset of the output file when
1623
 
                approximately half the output has been generated.  In
1624
 
                this way, the next invocation of row_merge() will
1625
 
                spend most of the time in this loop.  The initial
1626
 
                estimate is ohalf==0. */
1627
 
                ahalf = file->offset / 2;
1628
 
                ut_ad(ohalf <= of.offset);
1629
 
 
1630
 
                /* Improve the estimate until reaching half the input
1631
 
                file size, or we can not get any closer to it.  All
1632
 
                comparands should be non-negative when !(ohalf < ahalf)
1633
 
                because ohalf <= of.offset. */
1634
 
                if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) {
1635
 
                        ohalf = of.offset;
1636
 
                }
1637
1631
        }
1638
1632
 
1639
1633
        /* Copy the last blocks, if there are any. */
1643
1637
                        return(DB_INTERRUPTED);
1644
1638
                }
1645
1639
 
 
1640
                /* Remember the offset number for this run */
 
1641
                run_offset[n_run++] = of.offset;
 
1642
 
1646
1643
                if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
1647
1644
                        return(DB_CORRUPTION);
1648
1645
                }
1655
1652
                        return(DB_INTERRUPTED);
1656
1653
                }
1657
1654
 
 
1655
                /* Remember the offset number for this run */
 
1656
                run_offset[n_run++] = of.offset;
 
1657
 
1658
1658
                if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
1659
1659
                        return(DB_CORRUPTION);
1660
1660
                }
1666
1666
                return(DB_CORRUPTION);
1667
1667
        }
1668
1668
 
 
1669
        ut_ad(n_run <= *num_run);
 
1670
 
 
1671
        *num_run = n_run;
 
1672
 
 
1673
        /* Each run can contain one or more offsets. As merge goes on,
 
1674
        the number of runs (to merge) will reduce until we have one
 
1675
        single run. So the number of runs will always be smaller than
 
1676
        the number of offsets in file */
 
1677
        ut_ad((*num_run) <= file->offset);
 
1678
 
 
1679
        /* The number of offsets in output file is always equal or
 
1680
        smaller than input file */
 
1681
        ut_ad(of.offset <= file->offset);
 
1682
 
1669
1683
        /* Swap file descriptors for the next pass. */
1670
1684
        *tmpfd = file->fd;
1671
1685
        *file = of;
1672
 
        *half = ohalf;
1673
1686
 
1674
1687
        UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
1675
1688
 
1694
1707
                                        if applicable */
1695
1708
{
1696
1709
        ulint   half = file->offset / 2;
 
1710
        ulint   num_runs;
 
1711
        ulint*  run_offset;
 
1712
        ulint   error = DB_SUCCESS;
 
1713
 
 
1714
        /* Record the number of merge runs we need to perform */
 
1715
        num_runs = file->offset;
 
1716
 
 
1717
        /* If num_runs are less than 1, nothing to merge */
 
1718
        if (num_runs <= 1) {
 
1719
                return(error);
 
1720
        }
 
1721
 
 
1722
        /* "run_offset" records each run's first offset number */
 
1723
        run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint));
 
1724
 
 
1725
        /* This tells row_merge() where to start for the first round
 
1726
        of merge. */
 
1727
        run_offset[half] = half;
1697
1728
 
1698
1729
        /* The file should always contain at least one byte (the end
1699
1730
        of file marker).  Thus, it must be at least one block. */
1700
1731
        ut_ad(file->offset > 0);
1701
1732
 
 
1733
        /* Merge the runs until we have one big run */
1702
1734
        do {
1703
 
                ulint   error;
 
1735
                error = row_merge(trx, index, file, block, tmpfd,
 
1736
                                  table, &num_runs, run_offset);
1704
1737
 
1705
 
                error = row_merge(trx, index, file, &half,
1706
 
                                  block, tmpfd, table);
 
1738
                UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
1707
1739
 
1708
1740
                if (error != DB_SUCCESS) {
1709
 
                        return(error);
 
1741
                        break;
1710
1742
                }
1711
 
 
1712
 
                /* half > 0 should hold except when the file consists
1713
 
                of one block.  No need to merge further then. */
1714
 
                ut_ad(half > 0 || file->offset == 1);
1715
 
        } while (half < file->offset && half > 0);
1716
 
 
1717
 
        return(DB_SUCCESS);
 
1743
        } while (num_runs > 1);
 
1744
 
 
1745
        mem_free(run_offset);
 
1746
 
 
1747
        return(error);
1718
1748
}
1719
1749
 
1720
1750
/*************************************************************//**
2306
2336
{
2307
2337
        ulint           err     = DB_ERROR;
2308
2338
        pars_info_t*    info;
2309
 
        const char*     old_name= old_table->name;
 
2339
        char            old_name[MAX_TABLE_NAME_LEN + 1];
2310
2340
 
2311
2341
        ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
2312
2342
        ut_ad(old_table != new_table);
2314
2344
 
2315
2345
        ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
2316
2346
 
 
2347
        /* store the old/current name to an automatic variable */
 
2348
        if (strlen(old_table->name) + 1 <= sizeof(old_name)) {
 
2349
                memcpy(old_name, old_table->name, strlen(old_table->name) + 1);
 
2350
        } else {
 
2351
                ut_print_timestamp(stderr);
 
2352
                fprintf(stderr, "InnoDB: too long table name: '%s', "
 
2353
                        "max length is %d\n", old_table->name,
 
2354
                        MAX_TABLE_NAME_LEN);
 
2355
                ut_error;
 
2356
        }
 
2357
 
2317
2358
        trx->op_info = "renaming tables";
2318
2359
 
2319
2360
        /* We use the private SQL parser of Innobase to generate the query