1. 17 Feb, 2012 4 commits
    • Vasil Dimov's avatar
      Print a deprecation warning when ignore-builtin-innodb is used · 98230b0f
      Vasil Dimov authored
      This is part of
      Bug#13586262 INNODB - HIBISCUS: ISSUE DEPRECATION WARNINGS FOR VARIABLES
      
      Reviewed by:	Mark Alff
      98230b0f
    • Marko Mäkelä's avatar
      Merge mysql-5.1 to mysql-5.5. · 8aaf9f6f
      Marko Mäkelä authored
      8aaf9f6f
    • Marko Mäkelä's avatar
      Bug#13721257 RACE CONDITION IN UPDATES OR INSERTS OF WIDE RECORDS · 11416318
      Marko Mäkelä authored
      This bug was originally filed and fixed as Bug#12612184. The original
      fix was buggy, and it was patched by Bug#12704861. Also that patch was
      buggy (potentially breaking crash recovery), and both fixes were
      reverted.
      
      This fix was not ported to the built-in InnoDB of MySQL 5.1, because
      the function signatures of many core functions are different from
      InnoDB Plugin and later versions. The block allocation routines and
      their callers would have to changed so that they handle block
      descriptors instead of page frames.
      
      When a record is updated so that its size grows, non-updated columns
      can be selected for external (off-page) storage. The bug is that the
      initially inserted updated record contains an all-zero BLOB pointer to
      the field that was not updated. Only after the BLOB pages have been
      allocated and written, the valid pointer can be written to the record.
      
      Between the release of the page latch in mtr_commit(mtr) after
      btr_cur_pessimistic_update() and the re-latching of the page in
      btr_pcur_restore_position(), other threads can see the invalid BLOB
      pointer consisting of 20 zero bytes. Moreover, if the system crashes
      at this point, the situation could persist after crash recovery, and
      the contents of the non-updated column would be permanently lost.
      
      The problem is amplified by the ROW_FORMAT=DYNAMIC and
      ROW_FORMAT=COMPRESSED that were introduced in
      innodb_file_format=barracuda in InnoDB Plugin, but the bug does exist
      in all InnoDB versions.
      
      The fix is as follows. After a pessimistic B-tree operation that needs
      to write out off-page columns, allocate the pages for these columns in
      the mini-transaction that performed the B-tree operation (btr_mtr),
      but write the pages in a separate mini-transaction (blob_mtr). Do
      mtr_commit(blob_mtr) before mtr_commit(btr_mtr). A quirk: Do not reuse
      pages that were previously freed in btr_mtr. Only write the off-page
      columns to 'fresh' pages.
      
      In this way, crash recovery will see redo log entries for blob_mtr
      before any redo log entry for btr_mtr. It will apply the BLOB page
      writes to pages that were marked free at that point. If crash recovery
      fails to see all of the btr_mtr redo log, there will be some
      unreachable BLOB data in free pages, but the B-tree will be in a
      consistent state.
      
      btr_page_alloc_low(): Renamed from btr_page_alloc(). Add the parameter
      init_mtr. Return an allocated block, or NULL. If init_mtr!=mtr but
      the page was already X-latched in mtr, do not initialize the page.
      
      btr_page_alloc(): Wrapper for btr_page_alloc_for_ibuf() and
      btr_page_alloc_low().
      
      btr_page_free(): Add a debug assertion that the page was a B-tree page.
      
      btr_lift_page_up(): Return the father block.
      
      btr_compress(), btr_cur_compress_if_useful(): Add the parameter ibool
      adjust, for adjusting the cursor position.
      
      btr_cur_pessimistic_update(): Preserve the cursor position when
      big_rec will be written and the new flag BTR_KEEP_POS_FLAG is defined.
      Remove a duplicate rec_get_offsets() call. Keep the X-latch on
      index->lock when big_rec is needed.
      
      btr_store_big_rec_extern_fields(): Replace update_inplace with
      an operation code, and local_mtr with btr_mtr. When not doing a
      fresh insert and btr_mtr has freed pages, put aside any pages that
      were previously X-latched in btr_mtr, and free the pages after
      writing out all data. The data must be written to 'fresh' pages,
      because btr_mtr will be committed and written to the redo log after
      the BLOB writes have been written to the redo log.
      
      btr_blob_op_is_update(): Check if an operation passed to
      btr_store_big_rec_extern_fields() is an update or insert-by-update.
      
      fseg_alloc_free_page_low(), fsp_alloc_free_page(),
      fseg_alloc_free_extent(), fseg_alloc_free_page_general(): Add the
      parameter init_mtr. Return an allocated block, or NULL. If
      init_mtr!=mtr but the page was already X-latched in mtr, do not
      initialize the page.
      
      xdes_get_descriptor_with_space_hdr(): Assert that the file space
      header is being X-latched.
      
      fsp_alloc_from_free_frag(): Refactored from fsp_alloc_free_page().
      
      fsp_page_create(): New function, for allocating, X-latching and
      potentially initializing a page. If init_mtr!=mtr but the page was
      already X-latched in mtr, do not initialize the page.
      
      fsp_free_page(): Add ut_ad(0) to the error outcomes.
      
      fsp_free_page(), fseg_free_page_low(): Increment mtr->n_freed_pages.
      
      fsp_alloc_seg_inode_page(), fseg_create_general(): Assert that the
      page was not previously X-latched in the mini-transaction. A file
      segment or inode page should never be allocated in the middle of an
      mini-transaction that frees pages, such as btr_cur_pessimistic_delete().
      
      fseg_alloc_free_page_low(): If the hinted page was allocated, skip the
      check if the tablespace should be extended. Return NULL instead of
      FIL_NULL on failure. Remove the flag frag_page_allocated. Instead,
      return directly, because the page would already have been initialized.
      
      fseg_find_free_frag_page_slot() would return ULINT_UNDEFINED on error,
      not FIL_NULL. Correct a bogus assertion.
      
      fseg_alloc_free_page(): Redefine as a wrapper macro around
      fseg_alloc_free_page_general().
      
      buf_block_buf_fix_inc(): Move the definition from the buf0buf.ic to
      buf0buf.h, so that it can be called from other modules.
      
      mtr_t: Add n_freed_pages (number of pages that have been freed).
      
      page_rec_get_nth_const(), page_rec_get_nth(): The inverse function of
      page_rec_get_n_recs_before(), get the nth record of the record
      list. This is faster than iterating the linked list. Refactored from
      page_get_middle_rec().
      
      trx_undo_rec_copy(): Add a debug assertion for the length.
      
      trx_undo_add_page(): Return a block descriptor or NULL instead of a
      page number or FIL_NULL.
      
      trx_undo_report_row_operation(): Add debug assertions.
      
      trx_sys_create_doublewrite_buf(): Assert that each page was not
      previously X-latched.
      
      page_cur_insert_rec_zip_reorg(): Make use of page_rec_get_nth().
      
      row_ins_clust_index_entry_by_modify(): Pass BTR_KEEP_POS_FLAG, so that
      the repositioning of the cursor can be avoided.
      
      row_ins_index_entry_low(): Add DEBUG_SYNC points before and after
      writing off-page columns. If inserting by updating a delete-marked
      record, do not reposition the cursor or commit the mini-transaction
      before writing the off-page columns.
      
      row_build(): Tighten a debug assertion about null BLOB pointers.
      
      row_upd_clust_rec(): Add DEBUG_SYNC points before and after writing
      off-page columns. Do not reposition the cursor or commit the
      mini-transaction before writing the off-page columns.
      
      rb:939 approved by Jimmy Yang
      11416318
    • Marko Mäkelä's avatar
      Put back a fix that was reverted when reverting the buggy Bug#12612184 fix in · 0bea9db0
      Marko Mäkelä authored
      revision-id inaam.rana@oracle.com-20110930110219-vnpaqghj9hm0grds
      (revno 3559).
      0bea9db0
  2. 16 Feb, 2012 14 commits
  3. 15 Feb, 2012 6 commits
  4. 13 Feb, 2012 2 commits
  5. 10 Feb, 2012 4 commits
  6. 09 Feb, 2012 2 commits
    • Rohit Kalhans's avatar
      Followup patch for bug#11758263. · 6203acb0
      Rohit Kalhans authored
      6203acb0
    • Rohit Kalhans's avatar
      BUG#11758263 50440: MARK UNORDERED UPDATE WITH AUTOINC UNSAFE · 52491489
      Rohit Kalhans authored
             
      Problem: Statements that write to tables with auto_increment columns
               based on the selection from another table, may lead to master
               and slave going out of sync, as the order in which the rows
               are retrieved from the table may differ on master and slave.
                  
      Solution: We mark writing to a table with auto_increment table
                based on the rows selected from another table as unsafe. This
                will cause the execution of such statements to throw a warning
                and forces the statement to be logged in ROW if the logging
                format is mixed. 
                  
      Changes:
             1. All the statements that writes to a table with auto_increment 
                column(s) based on the rows fetched from another table, will now
                be unsafe.
             2. CREATE TABLE with SELECT will now be unsafe.
      
      sql/share/errmsg-utf8.txt:
        Added new warning messages.
      sql/sql_base.cc:
        -Created function to check statements that write to 
         tables with auto_increment column and has select.
        -Marked all the statements that write to a table
         with auto_increment column based on rows fetched
         from other table(s) as unsafe.
      sql/sql_table.cc:
        mark CREATE TABLE[with auto_increment column] as unsafe.
      52491489
  7. 08 Feb, 2012 1 commit
  8. 07 Feb, 2012 1 commit
    • Rohit Kalhans's avatar
      BUG#11758263 50440: MARK UNORDERED UPDATE WITH AUTOINC UNSAFE · 7306edf0
      Rohit Kalhans authored
            
            Problem: Statements that write to tables with auto_increment columns
            based on the selection from another table, may lead to master
            and slave going out of sync, as the order in which the rows
            are retrived from the table may differ on master and slave.
            
            Solution: We mark writing to a table with auto_increment table
            as unsafe. This will cause the execution of such statements to
            throw a warning and forces the statement to be logged in ROW if
            the logging format is mixed. 
            
            Changes: 
            1. All the statements that writes to a table with auto_increment 
            column(s) based on the rows fetched from another table, will now
            be unsafe.
            2. CREATE TABLE with SELECT will now be unsafe.
      
      
      sql/share/errmsg-utf8.txt:
        Added new Warning messages
      sql/sql_base.cc:
        created a new function that checks for select + write on a autoinc table
        made all such statements to be unsafe.
      sql/sql_parse.cc:
        made create autoincremnet tabble + select unsafe
      7306edf0
  9. 06 Feb, 2012 2 commits
    • Vasil Dimov's avatar
      Merge mysql-5.1 -> mysql-5.5 · 99208a48
      Vasil Dimov authored
      The actual Bug#11754376 does not exist in MySQL 5.5 because at startup
      we drop entries for temporary tables from InnoDB dictionary cache (only
      if ROW_FORMAT is not REDUNDANT). But nevertheless the bug in
      normalize_table_name_low() is present so we fix it.
      99208a48
    • Vasil Dimov's avatar
      Fix Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON · 36ff9aeb
      Vasil Dimov authored
      GRACEFUL SHUTDOWN
      
      During startup mysql picks up .frm files from the tmpdir directory and
      tries to drop those tables in the storage engine.
      
      The problem is that when tmpdir ends in / then ha_innobase::delete_table()
      is passed a string like "/var/tmp//#sql123", then it wrongly normalizes it
      to "/#sql123" and calls row_drop_table_for_mysql() which of course fails
      to delete the table entry from the InnoDB dictionary cache.
      ha_innobase::delete_table() returns an error but nevertheless mysql wipes
      away the .frm file and the entry in the InnoDB dictionary cache remains
      orphaned with no easy way to remove it.
      
      The "no easy" way to remove it is to create a similar temporary table again,
      copy its .frm file to tmpdir under "#sql123.frm" and restart mysqld with
      tmpdir=/var/tmp (no trailing slash) - this way mysql will pick the .frm file
      after restart and will try to issue drop table for "/var/tmp/#sql123"
      (notice do double slash), ha_innobase::delete_table() will normalize it to
      "tmp/#sql123" and row_drop_table_for_mysql() will successfully remove the
      table entry from the dictionary cache.
      
      The solution is to fix normalize_table_name_low() to normalize things like
      "/var/tmp//table" correctly to "tmp/table".
      
      This patch also adds a test function which invokes
      normalize_table_name_low() with various inputs to make sure it works
      correctly and a mtr test that calls this test function.
      
      Reviewed by:	Marko (http://bur03.no.oracle.com/rb/r/929/)
      36ff9aeb
  10. 05 Feb, 2012 1 commit
  11. 03 Feb, 2012 3 commits