Commit 050f14ac authored by unknown's avatar unknown

Applied innodb-5.1-ss269 snapshot.

  Fixed BUGS:
  #3300: "UPDATE statement with no index column in where condition locks
    all rows"
    Implement semi-consistent read to reduce lock conflicts at the cost
    of breaking serializability.
    ha_innobase::unlock_row(): reset the "did semi consistent read" flag
    ha_innobase::was_semi_consistent_read(),
    ha_innobase::try_semi_consistent_read(): new methods
    row_prebuilt_t, row_create_prebuilt(): add field row_read_type for
    keeping track of semi-consistent reads
    row_vers_build_for_semi_consistent_read(),
    row_sel_build_committed_vers_for_mysql(): new functions
    row_search_for_mysql(): implement semi-consistent reads

  #9802: "Foreign key checks disallow alter table".
    Added test cases.

  #12456: "Cursor shows incorrect data - DML does not affect,
    probably caching"
    This patch implements a high-granularity read view to be used with
    cursors. In this high-granularity consistent read view modifications 
    done by the creating transaction after the cursor is created or 
   future transactions are not visible. But those modifications that 
   transaction did before the cursor was created are visible.

  #12701: "Support >4GB buffer pool and log files on 64-bit Windows"
    Do not call os_file_create_tmpfile() at runtime. Instead, create all
    tempfiles at startup and guard access to them with mutexes.

  #13778: "If FOREIGN_KEY_CHECKS=0, one can create inconsistent FOREIGN KEYs".
    When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between
    foreign key references are compatible.

  #14189: "VARBINARY and BINARY variables: trailing space ignored with InnoDB"
    innobase_init(): Assert that
    DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
    dtype_get_pad_char(): Do not pad VARBINARY or BINARY columns.
    row_ins_cascade_calc_update_vec(): Refuse ON UPDATE CASCADE when trying
    to change the length of a VARBINARY column that refers to or is referenced
    by a BINARY column. BINARY columns are no longer padded on comparison,
    and thus they cannot be padded on storage either.

  #14747: "Race condition can cause btr_search_drop_page_hash_index() to crash"
    Note that buf_block_t::index should be protected by btr_search_latch
    or an s-latch or x-latch on the index page.
    btr_search_drop_page_hash_index(): Read block->index while holding
    btr_search_latch and use the cached value in the loop.  Remove some
    redundant assertions.

  #15108: "mysqld crashes when innodb_log_file_size is set > 4G"

  #15308: "Problem of Order with Enum Column in Primary Key"

  #15550: "mysqld crashes in printing a FOREIGN KEY error in InnoDB"
    row_ins_foreign_report_add_err(): When printing the parent record,
    use the index in the parent table rather than the index in the child table.

  #15653: "Slow inserts to InnoDB if many thousands of .ibd files"
    Keep track on unflushed modifications to file spaces.  When there are tens
    of thousands of file spaces, flushing all files in fil_flush_file_spaces()
    would be very slow.
    fil_flush_file_spaces(): Only flush unflushed file spaces.
    fil_space_t, fil_system_t: Add a list of unflushed spaces.

  #15991: "innodb-file-per-table + symlink database + rename = cr"
   os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and EISDIR
   to the new code OS_FILE_PATH_ERROR. Treat this code as OS_FILE_PATH_ERROR.
   This fixes the crash on RENAME TABLE when the .ibd file is a symbolic link
   to a different file system.

  #16157: "InnoDB crashes when main location settings are empty"
    This patch is from Heikki.

  #16298: "InnoDB segfaults in INSERTs in upgrade of 4.0 -> 5.0 tables
    with VARCHAR BINARY"
    dict_load_columns(): Set the charset-collation code
    DATA_MYSQL_BINARY_CHARSET_COLL for those binary string columns
    that lack a charset-collation code, i.e., the tables were created
    with an older version of MySQL/InnoDB than 4.1.2.

  #16229: "MySQL/InnoDB uses full explicit table locks in trigger processing"
    Take a InnoDB table lock only if user has explicitly requested a table
    lock. Added some additional comments to store_lock() and external_lock().

  #16387: "InnoDB crash when dropping a foreign key <table>_ibfk_0"
    Do not mistake TABLENAME_ibfk_0 for auto-generated id.
    dict_table_get_highest_foreign_id(): Ignore foreign constraint
    identifiers starting with the pattern TABLENAME_ibfk_0.

  #16582: "InnoDB: Error in an adaptive hash index pointer to page"
    Account for a race condition when dropping the adaptive hash index
    for a B-tree page.
    btr_search_drop_page_hash_index(): Retry the operation if a hash index
    with different parameters was built meanwhile.  Add diagnostics for the
    case that hash node pointers to the page remain.
    btr_search_info_update_hash(), btr_search_info_update_slow():
    Document the parameter "info" as in/out.

  #16814: "SHOW INNODB STATUS format error in LATEST FOREIGN KEY ERROR
    section"
    Add a missing newline to the LAST FOREIGN KEY ERROR section in SHOW
    INNODB STATUS output.
    dict_foreign_error_report(): Always print a newline after invoking
    dict_print_info_on_foreign_key_in_create_format().

  #16827: "Better InnoDB error message if ibdata files omitted from my.cnf"

  #17126: "CHECK TABLE on InnoDB causes a short hang during check of adaptive
    hash"
    CHECK TABLE blocking other queries, by releasing the btr_search_latch
    periodically during the adaptive hash table validation.

  #17405: "Valgrind: conditional jump or move depends on unititialised values"
    buf_block_init(): Reset magic_n, buf_fix_count and io_fix to avoid
    testing uninitialized variables.



mysql-test/r/innodb.result:
  Applied innodb-5.1-ss269 snapshot.
mysql-test/t/innodb.test:
  Applied innodb-5.1-ss269 snapshot.
sql/ha_innodb.cc:
  Applied innodb-5.1-ss269 snapshot.
sql/ha_innodb.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0btr.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0cur.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0pcur.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0sea.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0buf.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0flu.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0lru.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0rea.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/data/data0data.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/data/data0type.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0boot.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0crea.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0dict.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0load.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0mem.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/dyn/dyn0dyn.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/eval/eval0eval.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/eval/eval0proc.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/fil/fil0fil.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/fsp/fsp0fsp.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/fut/fut0lst.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ha/ha0ha.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ha/hash0hash.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ibuf/ibuf0ibuf.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0btr.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0btr.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0cur.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0cur.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0pcur.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0pcur.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0sea.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0sea.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0buf.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0buf.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0flu.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0flu.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0lru.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0data.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0data.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0type.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0type.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/db0err.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0boot.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0boot.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0crea.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0dict.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0dict.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0load.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0mem.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dyn0dyn.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dyn0dyn.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0eval.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0eval.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0proc.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0proc.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fil0fil.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fsp0fsp.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fut0lst.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ha0ha.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/hash0hash.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/hash0hash.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ibuf0ibuf.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ibuf0ibuf.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/lock0lock.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/lock0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0log.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0log.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0recv.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mach0data.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mach0data.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0dbg.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0dbg.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0mem.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0mem.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0pool.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0log.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0mtr.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0mtr.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0file.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0proc.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0sync.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0sync.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0thread.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0cur.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0cur.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0page.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0page.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0grm.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0opt.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0pars.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0sym.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0que.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0que.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/read0read.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/read0read.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0cmp.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0cmp.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0rec.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0rec.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0ins.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0mysql.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0purge.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0row.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0row.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0sel.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0sel.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0uins.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0umod.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0undo.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0upd.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0upd.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0vers.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/srv0srv.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/srv0start.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0arr.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0rw.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0rw.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0sync.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0sync.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0purge.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0purge.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rec.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0roll.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rseg.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rseg.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0sys.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0sys.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0trx.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0trx.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0undo.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0undo.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0xa.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/univ.i:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/usr0sess.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/usr0types.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0byte.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0byte.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0dbg.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0lst.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0mem.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0mem.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0rnd.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0rnd.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0sort.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0ut.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0ut.ic:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/lock/lock0lock.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/log/log0log.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/log/log0recv.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mach/mach0data.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0dbg.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0mem.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0pool.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mtr/mtr0log.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/mtr/mtr0mtr.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0file.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0proc.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0sync.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0thread.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/page/page0cur.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/page/page0page.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/lexyy.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.h:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.y:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0lex.l:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0opt.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0pars.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0sym.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/que/que0que.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/read/read0read.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/rem/rem0cmp.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/rem/rem0rec.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0ins.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0mysql.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0purge.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0row.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0sel.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0uins.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0umod.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0undo.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0upd.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0vers.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0que.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0srv.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0start.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0arr.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0rw.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0sync.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/thr/thr0loc.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0purge.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0rec.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0roll.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0rseg.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0sys.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0trx.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0undo.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/usr/usr0sess.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0byte.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0dbg.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0mem.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0rnd.c:
  Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0ut.c:
  Applied innodb-5.1-ss269 snapshot.
mysql-test/r/innodb_unsafe_binlog.result:
  New BitKeeper file ``mysql-test/r/innodb_unsafe_binlog.result''
mysql-test/t/innodb_unsafe_binlog-master.opt:
  New BitKeeper file ``mysql-test/t/innodb_unsafe_binlog-master.opt''
mysql-test/t/innodb_unsafe_binlog.test:
  New BitKeeper file ``mysql-test/t/innodb_unsafe_binlog.test''
storage/innobase/pars/make_bison.sh:
  New BitKeeper file ``storage/innobase/pars/make_bison.sh''
parent 1cef1679
This diff is collapsed.
drop table if exists t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
id f_id f
drop table t1,t2;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
a b
1 1
2 2
3 1
4 2
5 1
6 2
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 2 and b = 2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
commit;
drop table t1;
This diff is collapsed.
--innodb_locks_unsafe_for_binlog=true
-- source include/have_innodb.inc
#
# Note that these tests uses a innodb_locks_unsafe_for_binlog option.
#
#
# Test cases for a bug #15650
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
drop table t1,t2;
#
# Test case for unlock row bug where unlock releases all locks granted for
# a row. Only the latest lock should be released.
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
#
--error 1205
select * from t1 where a = 2 and b = 2 for update;
connection a;
commit;
connection b;
commit;
drop table t1;
disconnect a;
disconnect b;
This diff is collapsed.
...@@ -52,7 +52,6 @@ class ha_innobase: public handler ...@@ -52,7 +52,6 @@ class ha_innobase: public handler
THR_LOCK_DATA lock; THR_LOCK_DATA lock;
INNOBASE_SHARE *share; INNOBASE_SHARE *share;
gptr alloc_ptr;
byte* upd_buff; /* buffer used in updates */ byte* upd_buff; /* buffer used in updates */
byte* key_val_buff; /* buffer used in converting byte* key_val_buff; /* buffer used in converting
search key values from MySQL format search key values from MySQL format
...@@ -62,7 +61,6 @@ class ha_innobase: public handler ...@@ -62,7 +61,6 @@ class ha_innobase: public handler
two buffers */ two buffers */
ulong int_table_flags; ulong int_table_flags;
uint primary_key; uint primary_key;
uint last_dup_key;
ulong start_of_scan; /* this is set to 1 when we are ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not starting a table scan but have not
yet fetched any row, else 0 */ yet fetched any row, else 0 */
...@@ -70,7 +68,6 @@ class ha_innobase: public handler ...@@ -70,7 +68,6 @@ class ha_innobase: public handler
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */ or undefined */
uint num_write_row; /* number of write_row() calls */ uint num_write_row; /* number of write_row() calls */
ulong max_supported_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len, uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const byte* record); const byte* record);
...@@ -213,12 +210,9 @@ class ha_innobase: public handler ...@@ -213,12 +210,9 @@ class ha_innobase: public handler
}; };
extern SHOW_VAR innodb_status_variables[]; extern SHOW_VAR innodb_status_variables[];
extern uint innobase_init_flags, innobase_lock_type;
extern uint innobase_flush_log_at_trx_commit; extern uint innobase_flush_log_at_trx_commit;
extern ulong innobase_cache_size, innobase_fast_shutdown; extern ulong innobase_fast_shutdown;
extern ulong innobase_large_page_size; extern ulong innobase_large_page_size;
extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
extern long innobase_lock_scan_time;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group; extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_buffer_pool_size, innobase_log_file_size; extern longlong innobase_buffer_pool_size, innobase_log_file_size;
extern long innobase_log_buffer_size; extern long innobase_log_buffer_size;
...@@ -239,10 +233,11 @@ extern my_bool innobase_log_archive, ...@@ -239,10 +233,11 @@ extern my_bool innobase_log_archive,
innobase_file_per_table, innobase_locks_unsafe_for_binlog, innobase_file_per_table, innobase_locks_unsafe_for_binlog,
innobase_create_status_file; innobase_create_status_file;
extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before extern my_bool innobase_very_fast_shutdown; /* set this to 1 just before
calling innobase_end() if you want calling innobase_end() if
InnoDB to shut down without you want InnoDB to shut down
flushing the buffer pool: this without flushing the buffer
is equivalent to a 'crash' */ pool: this is equivalent to
a 'crash' */
extern "C" { extern "C" {
extern ulong srv_max_buf_pool_modified_pct; extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag; extern ulong srv_max_purge_lag;
...@@ -254,8 +249,6 @@ extern ulong srv_thread_concurrency; ...@@ -254,8 +249,6 @@ extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency; extern ulong srv_commit_concurrency;
} }
extern TYPELIB innobase_lock_typelib;
bool innobase_init(void); bool innobase_init(void);
int innobase_end(ha_panic_function type); int innobase_end(ha_panic_function type);
bool innobase_flush_logs(void); bool innobase_flush_logs(void);
...@@ -323,9 +316,6 @@ int innobase_rollback_by_xid( ...@@ -323,9 +316,6 @@ int innobase_rollback_by_xid(
XID *xid); /* in : X/Open XA Transaction Identification */ XID *xid); /* in : X/Open XA Transaction Identification */
int innobase_xa_end(THD *thd);
int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name, int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
my_off_t end_offset); my_off_t end_offset);
......
...@@ -144,7 +144,7 @@ btr_root_get( ...@@ -144,7 +144,7 @@ btr_root_get(
root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr); root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
ut_a((ibool)!!page_is_comp(root) == ut_a((ibool)!!page_is_comp(root) ==
UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp); dict_table_is_comp(UT_LIST_GET_FIRST(tree->tree_indexes)->table));
return(root); return(root);
} }
...@@ -259,7 +259,7 @@ btr_page_create( ...@@ -259,7 +259,7 @@ btr_page_create(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
page_create(page, mtr, page_create(page, mtr,
UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp); dict_table_is_comp(UT_LIST_GET_FIRST(tree->tree_indexes)->table));
buf_block_align(page)->check_index_page_at_flush = TRUE; buf_block_align(page)->check_index_page_at_flush = TRUE;
btr_page_set_index_id(page, tree->id, mtr); btr_page_set_index_id(page, tree->id, mtr);
...@@ -846,7 +846,7 @@ btr_page_reorganize_low( ...@@ -846,7 +846,7 @@ btr_page_reorganize_low(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_ad(!!page_is_comp(page) == index->table->comp); ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
data_size1 = page_get_data_size(page); data_size1 = page_get_data_size(page);
max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1); max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
...@@ -1416,15 +1416,12 @@ btr_insert_on_non_leaf_level( ...@@ -1416,15 +1416,12 @@ btr_insert_on_non_leaf_level(
first parameter for btr_cur_search_to_nth_level. */ first parameter for btr_cur_search_to_nth_level. */
btr_cur_search_to_nth_level(UT_LIST_GET_FIRST(tree->tree_indexes), btr_cur_search_to_nth_level(UT_LIST_GET_FIRST(tree->tree_indexes),
level, tuple, PAGE_CUR_LE, level, tuple, PAGE_CUR_LE, BTR_CONT_MODIFY_TREE,
BTR_CONT_MODIFY_TREE,
&cursor, 0, mtr); &cursor, 0, mtr);
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG | BTR_KEEP_SYS_FLAG | BTR_NO_UNDO_LOG_FLAG,
| BTR_NO_UNDO_LOG_FLAG, &cursor, tuple, &rec, &dummy_big_rec, NULL, mtr);
&cursor, tuple,
&rec, &dummy_big_rec, NULL, mtr);
ut_a(err == DB_SUCCESS); ut_a(err == DB_SUCCESS);
} }
...@@ -2014,7 +2011,7 @@ btr_compress( ...@@ -2014,7 +2011,7 @@ btr_compress(
page = btr_cur_get_page(cursor); page = btr_cur_get_page(cursor);
tree = btr_cur_get_tree(cursor); tree = btr_cur_get_tree(cursor);
comp = page_is_comp(page); comp = page_is_comp(page);
ut_a((ibool)!!comp == cursor->index->table->comp); ut_a((ibool)!!comp == dict_table_is_comp(cursor->index->table));
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
...@@ -2413,6 +2410,7 @@ btr_print_tree( ...@@ -2413,6 +2410,7 @@ btr_print_tree(
} }
#endif /* UNIV_BTR_PRINT */ #endif /* UNIV_BTR_PRINT */
#ifdef UNIV_DEBUG
/**************************************************************** /****************************************************************
Checks that the node pointer to a page is appropriate. */ Checks that the node pointer to a page is appropriate. */
...@@ -2458,6 +2456,7 @@ btr_check_node_ptr( ...@@ -2458,6 +2456,7 @@ btr_check_node_ptr(
return(TRUE); return(TRUE);
} }
#endif /* UNIV_DEBUG */
/**************************************************************** /****************************************************************
Display identification information for a record. */ Display identification information for a record. */
...@@ -2481,7 +2480,7 @@ the index. */ ...@@ -2481,7 +2480,7 @@ the index. */
ibool ibool
btr_index_rec_validate( btr_index_rec_validate(
/*====================*/ /*===================*/
/* out: TRUE if ok */ /* out: TRUE if ok */
rec_t* rec, /* in: index record */ rec_t* rec, /* in: index record */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
...@@ -2508,11 +2507,13 @@ btr_index_rec_validate( ...@@ -2508,11 +2507,13 @@ btr_index_rec_validate(
return(TRUE); return(TRUE);
} }
if (UNIV_UNLIKELY((ibool)!!page_is_comp(page) != index->table->comp)) { if (UNIV_UNLIKELY((ibool)!!page_is_comp(page)
!= dict_table_is_comp(index->table))) {
btr_index_rec_validate_report(page, rec, index); btr_index_rec_validate_report(page, rec, index);
fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n", fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n",
(ulong) !!page_is_comp(page), (ulong) !!page_is_comp(page),
(ulong) index->table->comp); (ulong) dict_table_is_comp(index->table));
return(FALSE); return(FALSE);
} }
......
...@@ -513,7 +513,7 @@ retry_page_get: ...@@ -513,7 +513,7 @@ retry_page_get:
page = btr_page_get(space, page = btr_page_get(space,
page_no, RW_X_LATCH, mtr); page_no, RW_X_LATCH, mtr);
ut_a((ibool)!!page_is_comp(page) ut_a((ibool)!!page_is_comp(page)
== index->table->comp); == dict_table_is_comp(index->table));
} }
break; break;
...@@ -1304,7 +1304,7 @@ btr_cur_update_in_place_log( ...@@ -1304,7 +1304,7 @@ btr_cur_update_in_place_log(
byte* log_ptr; byte* log_ptr;
page_t* page = ut_align_down(rec, UNIV_PAGE_SIZE); page_t* page = ut_align_down(rec, UNIV_PAGE_SIZE);
ut_ad(flags < 256); ut_ad(flags < 256);
ut_ad(!!page_is_comp(page) == index->table->comp); ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
log_ptr = mlog_open_and_write_index(mtr, rec, index, page_is_comp(page) log_ptr = mlog_open_and_write_index(mtr, rec, index, page_is_comp(page)
? MLOG_COMP_REC_UPDATE_IN_PLACE ? MLOG_COMP_REC_UPDATE_IN_PLACE
...@@ -1390,7 +1390,7 @@ btr_cur_parse_update_in_place( ...@@ -1390,7 +1390,7 @@ btr_cur_parse_update_in_place(
goto func_exit; goto func_exit;
} }
ut_a((ibool)!!page_is_comp(page) == index->table->comp); ut_a((ibool)!!page_is_comp(page) == dict_table_is_comp(index->table));
rec = page + rec_offset; rec = page + rec_offset;
/* We do not need to reserve btr_search_latch, as the page is only /* We do not need to reserve btr_search_latch, as the page is only
...@@ -1443,7 +1443,7 @@ btr_cur_update_in_place( ...@@ -1443,7 +1443,7 @@ btr_cur_update_in_place(
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
index = cursor->index; index = cursor->index;
ut_ad(!!page_rec_is_comp(rec) == index->table->comp); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -1466,7 +1466,7 @@ btr_cur_update_in_place( ...@@ -1466,7 +1466,7 @@ btr_cur_update_in_place(
block = buf_block_align(rec); block = buf_block_align(rec);
ut_ad(!!page_is_comp(buf_block_get_frame(block)) ut_ad(!!page_is_comp(buf_block_get_frame(block))
== index->table->comp); == dict_table_is_comp(index->table));
if (block->is_hashed) { if (block->is_hashed) {
/* The function row_upd_changes_ord_field_binary works only /* The function row_upd_changes_ord_field_binary works only
...@@ -1558,7 +1558,7 @@ btr_cur_optimistic_update( ...@@ -1558,7 +1558,7 @@ btr_cur_optimistic_update(
page = btr_cur_get_page(cursor); page = btr_cur_get_page(cursor);
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
index = cursor->index; index = cursor->index;
ut_ad(!!page_rec_is_comp(rec) == index->table->comp); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
...@@ -2009,7 +2009,7 @@ btr_cur_del_mark_set_clust_rec_log( ...@@ -2009,7 +2009,7 @@ btr_cur_del_mark_set_clust_rec_log(
ut_ad(flags < 256); ut_ad(flags < 256);
ut_ad(val <= 1); ut_ad(val <= 1);
ut_ad(!!page_rec_is_comp(rec) == index->table->comp); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
log_ptr = mlog_open_and_write_index(mtr, rec, index, log_ptr = mlog_open_and_write_index(mtr, rec, index,
page_rec_is_comp(rec) page_rec_is_comp(rec)
...@@ -2056,7 +2056,8 @@ btr_cur_parse_del_mark_set_clust_rec( ...@@ -2056,7 +2056,8 @@ btr_cur_parse_del_mark_set_clust_rec(
ulint offset; ulint offset;
rec_t* rec; rec_t* rec;
ut_ad(!page || !!page_is_comp(page) == index->table->comp); ut_ad(!page
|| !!page_is_comp(page) == dict_table_is_comp(index->table));
if (end_ptr < ptr + 2) { if (end_ptr < ptr + 2) {
...@@ -2142,7 +2143,7 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2142,7 +2143,7 @@ btr_cur_del_mark_set_clust_rec(
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
index = cursor->index; index = cursor->index;
ut_ad(!!page_rec_is_comp(rec) == index->table->comp); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -2315,7 +2316,7 @@ btr_cur_del_mark_set_sec_rec( ...@@ -2315,7 +2316,7 @@ btr_cur_del_mark_set_sec_rec(
block = buf_block_align(rec); block = buf_block_align(rec);
ut_ad(!!page_is_comp(buf_block_get_frame(block)) ut_ad(!!page_is_comp(buf_block_get_frame(block))
== cursor->index->table->comp); == dict_table_is_comp(cursor->index->table));
if (block->is_hashed) { if (block->is_hashed) {
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
...@@ -3392,6 +3393,9 @@ btr_store_big_rec_extern_fields( ...@@ -3392,6 +3393,9 @@ btr_store_big_rec_extern_fields(
return(DB_OUT_OF_FILE_SPACE); return(DB_OUT_OF_FILE_SPACE);
} }
mlog_write_ulint(page + FIL_PAGE_TYPE,
FIL_PAGE_TYPE_BLOB, MLOG_2BYTES, &mtr);
page_no = buf_frame_get_page_no(page); page_no = buf_frame_get_page_no(page);
if (prev_page_no != FIL_NULL) { if (prev_page_no != FIL_NULL) {
...@@ -3637,7 +3641,7 @@ btr_rec_free_externally_stored_fields( ...@@ -3637,7 +3641,7 @@ btr_rec_free_externally_stored_fields(
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
/* Free possible externally stored fields in the record */ /* Free possible externally stored fields in the record */
ut_ad(index->table->comp == !!rec_offs_comp(offsets)); ut_ad(dict_table_is_comp(index->table) == !!rec_offs_comp(offsets));
n_fields = rec_offs_n_fields(offsets); n_fields = rec_offs_n_fields(offsets);
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
......
...@@ -158,7 +158,7 @@ btr_pcur_copy_stored_position( ...@@ -158,7 +158,7 @@ btr_pcur_copy_stored_position(
mem_free(pcur_receive->old_rec_buf); mem_free(pcur_receive->old_rec_buf);
} }
ut_memcpy((byte*)pcur_receive, (byte*)pcur_donate, sizeof(btr_pcur_t)); ut_memcpy(pcur_receive, pcur_donate, sizeof(btr_pcur_t));
if (pcur_donate->old_rec_buf) { if (pcur_donate->old_rec_buf) {
...@@ -208,7 +208,7 @@ btr_pcur_restore_position( ...@@ -208,7 +208,7 @@ btr_pcur_restore_position(
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED) if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED || UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) { && cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t)); ut_print_buf(stderr, cursor, sizeof(btr_pcur_t));
if (cursor->trx_if_known) { if (cursor->trx_if_known) {
trx_print(stderr, cursor->trx_if_known, 0); trx_print(stderr, cursor->trx_if_known, 0);
} }
......
...@@ -191,7 +191,7 @@ static ...@@ -191,7 +191,7 @@ static
void void
btr_search_info_update_hash( btr_search_info_update_hash(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */ btr_cur_t* cursor) /* in: cursor which was just positioned */
{ {
dict_index_t* index; dict_index_t* index;
...@@ -452,7 +452,7 @@ Updates the search info. */ ...@@ -452,7 +452,7 @@ Updates the search info. */
void void
btr_search_info_update_slow( btr_search_info_update_slow(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */ btr_cur_t* cursor) /* in: cursor which was just positioned */
{ {
buf_block_t* block; buf_block_t* block;
...@@ -798,8 +798,8 @@ btr_search_guess_on_hash( ...@@ -798,8 +798,8 @@ btr_search_guess_on_hash(
record to determine if our guess for the cursor position is record to determine if our guess for the cursor position is
right. */ right. */
if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0) if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
|| !btr_search_check_guess(cursor, can_only_compare_to_cursor_rec, || !btr_search_check_guess(cursor,
tuple, mode, mtr)) { can_only_compare_to_cursor_rec, tuple, mode, mtr)) {
if (UNIV_LIKELY(!has_search_latch)) { if (UNIV_LIKELY(!has_search_latch)) {
btr_leaf_page_release(page, latch_mode, mtr); btr_leaf_page_release(page, latch_mode, mtr);
} }
...@@ -889,7 +889,8 @@ Drops a page hash index. */ ...@@ -889,7 +889,8 @@ Drops a page hash index. */
void void
btr_search_drop_page_hash_index( btr_search_drop_page_hash_index(
/*============================*/ /*============================*/
page_t* page) /* in: index page, s- or x-latched */ page_t* page) /* in: index page, s- or x-latched, or an index page
for which we know that block->buf_fix_count == 0 */
{ {
hash_table_t* table; hash_table_t* table;
buf_block_t* block; buf_block_t* block;
...@@ -904,18 +905,19 @@ btr_search_drop_page_hash_index( ...@@ -904,18 +905,19 @@ btr_search_drop_page_hash_index(
ulint* folds; ulint* folds;
ulint i; ulint i;
mem_heap_t* heap; mem_heap_t* heap;
dict_index_t* index;
ulint* offsets; ulint* offsets;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
retry:
rw_lock_s_lock(&btr_search_latch); rw_lock_s_lock(&btr_search_latch);
block = buf_block_align(page); block = buf_block_align(page);
if (!block->is_hashed) { if (UNIV_LIKELY(!block->is_hashed)) {
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
...@@ -932,11 +934,16 @@ btr_search_drop_page_hash_index( ...@@ -932,11 +934,16 @@ btr_search_drop_page_hash_index(
n_fields = block->curr_n_fields; n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes; n_bytes = block->curr_n_bytes;
index = block->index;
ut_a(n_fields + n_bytes > 0); /* NOTE: The fields of block must not be accessed after
releasing btr_search_latch, as the index page might only
be s-latched! */
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
ut_a(n_fields + n_bytes > 0);
n_recs = page_get_n_recs(page); n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion /* Calculate and cache fold values into an array for fast deletion
...@@ -949,33 +956,21 @@ btr_search_drop_page_hash_index( ...@@ -949,33 +956,21 @@ btr_search_drop_page_hash_index(
rec = page_get_infimum_rec(page); rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec); rec = page_rec_get_next(rec);
if (!page_rec_is_supremum(rec)) {
ut_a(n_fields <= rec_get_n_fields(rec, block->index));
if (n_bytes > 0) {
ut_a(n_fields < rec_get_n_fields(rec, block->index));
}
}
tree_id = btr_page_get_index_id(page); tree_id = btr_page_get_index_id(page);
ut_a(0 == ut_dulint_cmp(tree_id, index->id));
prev_fold = 0; prev_fold = 0;
heap = NULL; heap = NULL;
offsets = NULL; offsets = NULL;
if (block->index == NULL) {
mem_analyze_corruption((byte*)block);
ut_a(block->index != NULL);
}
while (!page_rec_is_supremum(rec)) { while (!page_rec_is_supremum(rec)) {
/* FIXME: in a mixed tree, not all records may have enough /* FIXME: in a mixed tree, not all records may have enough
ordering fields: */ ordering fields: */
offsets = rec_get_offsets(rec, block->index, offsets = rec_get_offsets(rec, index, offsets,
offsets, n_fields + (n_bytes > 0), &heap); n_fields + (n_bytes > 0), &heap);
ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) { if (fold == prev_fold && prev_fold != 0) {
...@@ -999,6 +994,26 @@ next_rec: ...@@ -999,6 +994,26 @@ next_rec:
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
if (UNIV_UNLIKELY(!block->is_hashed)) {
/* Someone else has meanwhile dropped the hash index */
goto cleanup;
}
ut_a(block->index == index);
if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
|| UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
/* Someone else has meanwhile built a new hash index on the
page, with different parameters */
rw_lock_x_unlock(&btr_search_latch);
mem_free(folds);
goto retry;
}
for (i = 0; i < n_cached; i++) { for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page); ha_remove_all_nodes_to_page(table, folds[i], page);
...@@ -1006,8 +1021,20 @@ next_rec: ...@@ -1006,8 +1021,20 @@ next_rec:
block->is_hashed = FALSE; block->is_hashed = FALSE;
block->index = NULL; block->index = NULL;
cleanup:
if (UNIV_UNLIKELY(block->n_pointers)) {
/* Corruption */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Corruption of adaptive hash index. After dropping\n"
"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
index->name, (ulong) block->n_pointers);
rw_lock_x_unlock(&btr_search_latch);
btr_search_validate();
} else {
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
}
mem_free(folds); mem_free(folds);
} }
...@@ -1573,14 +1600,29 @@ btr_search_validate(void) ...@@ -1573,14 +1600,29 @@ btr_search_validate(void)
ulint n_page_dumps = 0; ulint n_page_dumps = 0;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
ulint cell_count;
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_; ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_;
/* How many cells to check before temporarily releasing
btr_search_latch. */
ulint chunk_size = 10000;
rw_lock_x_lock(&btr_search_latch);
cell_count = hash_get_n_cells(btr_search_sys->hash_index);
for (i = 0; i < cell_count; i++) {
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
}
for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) {
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
while (node != NULL) { while (node != NULL) {
...@@ -1634,10 +1676,21 @@ btr_search_validate(void) ...@@ -1634,10 +1676,21 @@ btr_search_validate(void)
} }
} }
if (!ha_validate(btr_search_sys->hash_index)) { for (i = 0; i < cell_count; i += chunk_size) {
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if (i != 0) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
ok = FALSE; ok = FALSE;
} }
}
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
......
...@@ -335,10 +335,10 @@ buf_page_is_corrupted( ...@@ -335,10 +335,10 @@ buf_page_is_corrupted(
} }
#endif #endif
/* If we use checksums validation, make additional check before returning /* If we use checksums validation, make additional check before
TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which returning TRUE to ensure that the checksum is not equal to
might be stored by InnoDB with checksums disabled. BUF_NO_CHECKSUM_MAGIC which might be stored by InnoDB with checksums
Otherwise, skip checksum calculation and return FALSE */ disabled. Otherwise, skip checksum calculation and return FALSE */
if (srv_use_checksums) { if (srv_use_checksums) {
old_checksum = buf_calc_page_old_checksum(read_buf); old_checksum = buf_calc_page_old_checksum(read_buf);
...@@ -347,11 +347,15 @@ buf_page_is_corrupted( ...@@ -347,11 +347,15 @@ buf_page_is_corrupted(
- FIL_PAGE_END_LSN_OLD_CHKSUM); - FIL_PAGE_END_LSN_OLD_CHKSUM);
/* There are 2 valid formulas for old_checksum_field: /* There are 2 valid formulas for old_checksum_field:
1. Very old versions of InnoDB only stored 8 byte lsn to the start
and the end of the page.
2. Newer InnoDB versions store the old formula checksum there. */
if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN) 1. Very old versions of InnoDB only stored 8 byte lsn to the
start and the end of the page.
2. Newer InnoDB versions store the old formula checksum
there. */
if (old_checksum_field != mach_read_from_4(read_buf
+ FIL_PAGE_LSN)
&& old_checksum_field != old_checksum && old_checksum_field != old_checksum
&& old_checksum_field != BUF_NO_CHECKSUM_MAGIC) { && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) {
...@@ -359,7 +363,8 @@ buf_page_is_corrupted( ...@@ -359,7 +363,8 @@ buf_page_is_corrupted(
} }
checksum = buf_calc_page_new_checksum(read_buf); checksum = buf_calc_page_new_checksum(read_buf);
checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM); checksum_field = mach_read_from_4(read_buf +
FIL_PAGE_SPACE_OR_CHKSUM);
/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
(always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */ (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
...@@ -427,7 +432,8 @@ buf_page_print( ...@@ -427,7 +432,8 @@ buf_page_print(
"InnoDB: Page may be an update undo log page\n"); "InnoDB: Page may be an update undo log page\n");
} }
if (fil_page_get_type(read_buf) == FIL_PAGE_INDEX) { switch (fil_page_get_type(read_buf)) {
case FIL_PAGE_INDEX:
fprintf(stderr, fprintf(stderr,
"InnoDB: Page may be an index page where index id is %lu %lu\n", "InnoDB: Page may be an index page where index id is %lu %lu\n",
(ulong) ut_dulint_get_high(btr_page_get_index_id(read_buf)), (ulong) ut_dulint_get_high(btr_page_get_index_id(read_buf)),
...@@ -446,11 +452,42 @@ buf_page_print( ...@@ -446,11 +452,42 @@ buf_page_print(
fputs(")\n", stderr); fputs(")\n", stderr);
} }
} }
} else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) { break;
case FIL_PAGE_INODE:
fputs("InnoDB: Page may be an 'inode' page\n", stderr); fputs("InnoDB: Page may be an 'inode' page\n", stderr);
} else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) { break;
case FIL_PAGE_IBUF_FREE_LIST:
fputs("InnoDB: Page may be an insert buffer free list page\n", fputs("InnoDB: Page may be an insert buffer free list page\n",
stderr); stderr);
break;
case FIL_PAGE_TYPE_ALLOCATED:
fputs("InnoDB: Page may be a freshly allocated page\n",
stderr);
break;
case FIL_PAGE_IBUF_BITMAP:
fputs("InnoDB: Page may be an insert buffer bitmap page\n",
stderr);
break;
case FIL_PAGE_TYPE_SYS:
fputs("InnoDB: Page may be a system page\n",
stderr);
break;
case FIL_PAGE_TYPE_TRX_SYS:
fputs("InnoDB: Page may be a transaction system page\n",
stderr);
break;
case FIL_PAGE_TYPE_FSP_HDR:
fputs("InnoDB: Page may be a file space header page\n",
stderr);
break;
case FIL_PAGE_TYPE_XDES:
fputs("InnoDB: Page may be an extent descriptor page\n",
stderr);
break;
case FIL_PAGE_TYPE_BLOB:
fputs("InnoDB: Page may be a BLOB page\n",
stderr);
break;
} }
} }
...@@ -464,12 +501,17 @@ buf_block_init( ...@@ -464,12 +501,17 @@ buf_block_init(
byte* frame) /* in: pointer to buffer frame, or NULL if in byte* frame) /* in: pointer to buffer frame, or NULL if in
the case of AWE there is no frame */ the case of AWE there is no frame */
{ {
block->magic_n = 0;
block->state = BUF_BLOCK_NOT_USED; block->state = BUF_BLOCK_NOT_USED;
block->frame = frame; block->frame = frame;
block->awe_info = NULL; block->awe_info = NULL;
block->buf_fix_count = 0;
block->io_fix = 0;
block->modify_clock = ut_dulint_zero; block->modify_clock = ut_dulint_zero;
block->file_page_was_freed = FALSE; block->file_page_was_freed = FALSE;
...@@ -839,7 +881,7 @@ the buffer pool. */ ...@@ -839,7 +881,7 @@ the buffer pool. */
void void
buf_page_make_young( buf_page_make_young(
/*=================*/ /*================*/
buf_frame_t* frame) /* in: buffer frame of a file page */ buf_frame_t* frame) /* in: buffer frame of a file page */
{ {
buf_block_t* block; buf_block_t* block;
...@@ -1779,6 +1821,10 @@ buf_page_create( ...@@ -1779,6 +1821,10 @@ buf_page_create(
frame = block->frame; frame = block->frame;
memset(frame + FIL_PAGE_PREV, 0xff, 4);
memset(frame + FIL_PAGE_NEXT, 0xff, 4);
mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED);
/* Reset to zero the file flush lsn field in the page; if the first /* Reset to zero the file flush lsn field in the page; if the first
page of an ibdata file is 'created' in this function into the buffer page of an ibdata file is 'created' in this function into the buffer
pool then we lose the original contents of the file flush lsn stamp. pool then we lose the original contents of the file flush lsn stamp.
...@@ -2297,9 +2343,8 @@ buf_print_io( ...@@ -2297,9 +2343,8 @@ buf_print_io(
if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) { if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
fprintf(file, "Buffer pool hit rate %lu / 1000\n", fprintf(file, "Buffer pool hit rate %lu / 1000\n",
(ulong) (1000 (ulong) (1000 -
- ((1000 * ((1000 * (buf_pool->n_pages_read - buf_pool->n_pages_read_old))
(buf_pool->n_pages_read - buf_pool->n_pages_read_old))
/ (buf_pool->n_page_gets - buf_pool->n_page_gets_old)))); / (buf_pool->n_page_gets - buf_pool->n_page_gets_old))));
} else { } else {
fputs("No buffer pool page gets since the last printout\n", fputs("No buffer pool page gets since the last printout\n",
......
...@@ -120,7 +120,7 @@ buf_flush_ready_for_replace( ...@@ -120,7 +120,7 @@ buf_flush_ready_for_replace(
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: buffer block state %lu in the LRU list!\n", " InnoDB: Error: buffer block state %lu in the LRU list!\n",
(ulong)block->state); (ulong)block->state);
ut_print_buf(stderr, (byte*)block, sizeof(buf_block_t)); ut_print_buf(stderr, block, sizeof(buf_block_t));
return(FALSE); return(FALSE);
} }
...@@ -357,7 +357,8 @@ buf_flush_buffered_writes(void) ...@@ -357,7 +357,8 @@ buf_flush_buffered_writes(void)
"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n" "InnoDB: The lsn fields do not match! Noticed in the buffer pool\n"
"InnoDB: after posting and flushing the doublewrite buffer.\n" "InnoDB: after posting and flushing the doublewrite buffer.\n"
"InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n", "InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n",
(ulong)block->buf_fix_count, (ulong)block->io_fix, (ulong)block->buf_fix_count,
(ulong)block->io_fix,
(ulong)block->state); (ulong)block->state);
} }
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
......
...@@ -458,7 +458,8 @@ buf_read_ahead_linear( ...@@ -458,7 +458,8 @@ buf_read_ahead_linear(
/* Not accessed */ /* Not accessed */
fail_count++; fail_count++;
} else if (pred_block && (ut_ulint_cmp(block->LRU_position, } else if (pred_block
&& (ut_ulint_cmp(block->LRU_position,
pred_block->LRU_position) pred_block->LRU_position)
!= asc_or_desc)) { != asc_or_desc)) {
/* Accesses not in the right order */ /* Accesses not in the right order */
......
...@@ -18,10 +18,10 @@ Created 5/30/1994 Heikki Tuuri ...@@ -18,10 +18,10 @@ Created 5/30/1994 Heikki Tuuri
#include "dict0dict.h" #include "dict0dict.h"
#include "btr0cur.h" #include "btr0cur.h"
#ifdef UNIV_DEBUG
byte data_error; /* data pointers of tuple fields are initialized byte data_error; /* data pointers of tuple fields are initialized
to point here for error checking */ to point here for error checking */
#ifdef UNIV_DEBUG
ulint data_dummy; /* this is used to fool the compiler in ulint data_dummy; /* this is used to fool the compiler in
dtuple_validate */ dtuple_validate */
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
...@@ -431,6 +431,22 @@ dfield_print_also_hex( ...@@ -431,6 +431,22 @@ dfield_print_also_hex(
} }
} }
/*****************************************************************
Print a dfield value using ut_print_buf. */
void
dfield_print_raw(
/*=============*/
FILE* f, /* in: output stream */
dfield_t* dfield) /* in: dfield */
{
if (dfield->len != UNIV_SQL_NULL) {
ut_print_buf(f, dfield->data, dfield->len);
} else {
fputs(" SQL NULL", f);
}
}
/************************************************************** /**************************************************************
The following function prints the contents of a tuple. */ The following function prints the contents of a tuple. */
...@@ -440,7 +456,6 @@ dtuple_print( ...@@ -440,7 +456,6 @@ dtuple_print(
FILE* f, /* in: output stream */ FILE* f, /* in: output stream */
dtuple_t* tuple) /* in: tuple */ dtuple_t* tuple) /* in: tuple */
{ {
dfield_t* field;
ulint n_fields; ulint n_fields;
ulint i; ulint i;
...@@ -451,13 +466,7 @@ dtuple_print( ...@@ -451,13 +466,7 @@ dtuple_print(
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
fprintf(f, " %lu:", (ulong) i); fprintf(f, " %lu:", (ulong) i);
field = dtuple_get_nth_field(tuple, i); dfield_print_raw(f, dtuple_get_nth_field(tuple, i));
if (field->len != UNIV_SQL_NULL) {
ut_print_buf(f, field->data, field->len);
} else {
fputs(" SQL NULL", f);
}
putc(';', f); putc(';', f);
} }
...@@ -526,7 +535,7 @@ dtuple_convert_big_rec( ...@@ -526,7 +535,7 @@ dtuple_convert_big_rec(
while (rec_get_converted_size(index, entry) while (rec_get_converted_size(index, entry)
>= ut_min(page_get_free_space_of_empty( >= ut_min(page_get_free_space_of_empty(
index->table->comp) / 2, dict_table_is_comp(index->table)) / 2,
REC_MAX_DATA_SIZE)) { REC_MAX_DATA_SIZE)) {
longest = 0; longest = 0;
...@@ -563,7 +572,9 @@ dtuple_convert_big_rec( ...@@ -563,7 +572,9 @@ dtuple_convert_big_rec(
/* We do not store externally fields which are smaller than /* We do not store externally fields which are smaller than
DICT_MAX_INDEX_COL_LEN */ DICT_MAX_INDEX_COL_LEN */
ut_a(DICT_MAX_INDEX_COL_LEN > REC_1BYTE_OFFS_LIMIT); #if DICT_MAX_INDEX_COL_LEN <= REC_1BYTE_OFFS_LIMIT
# error "DICT_MAX_INDEX_COL_LEN <= REC_1BYTE_OFFS_LIMIT"
#endif
if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10 if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
+ DICT_MAX_INDEX_COL_LEN) { + DICT_MAX_INDEX_COL_LEN) {
......
...@@ -252,7 +252,7 @@ dtype_print( ...@@ -252,7 +252,7 @@ dtype_print(
} else if (prtype == DATA_ENGLISH) { } else if (prtype == DATA_ENGLISH) {
fputs("DATA_ENGLISH", stderr); fputs("DATA_ENGLISH", stderr);
} else { } else {
fprintf(stderr, "prtype %lu", (ulong) mtype); fprintf(stderr, "prtype %lu", (ulong) prtype);
} }
} }
......
...@@ -238,15 +238,14 @@ dict_boot(void) ...@@ -238,15 +238,14 @@ dict_boot(void)
dict_sys->row_id = ut_dulint_add( dict_sys->row_id = ut_dulint_add(
ut_dulint_align_up( ut_dulint_align_up(
mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID, mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID, &mtr),
&mtr),
DICT_HDR_ROW_ID_WRITE_MARGIN), DICT_HDR_ROW_ID_WRITE_MARGIN),
DICT_HDR_ROW_ID_WRITE_MARGIN); DICT_HDR_ROW_ID_WRITE_MARGIN);
/* Insert into the dictionary cache the descriptions of the basic /* Insert into the dictionary cache the descriptions of the basic
system tables */ system tables */
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, FALSE); table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
...@@ -265,7 +264,7 @@ dict_boot(void) ...@@ -265,7 +264,7 @@ dict_boot(void)
index = dict_mem_index_create("SYS_TABLES", "CLUST_IND", index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1);
dict_mem_index_add_field(index, "NAME", 0, 0); dict_mem_index_add_field(index, "NAME", 0);
index->id = DICT_TABLES_ID; index->id = DICT_TABLES_ID;
...@@ -275,14 +274,14 @@ dict_boot(void) ...@@ -275,14 +274,14 @@ dict_boot(void)
/*-------------------------*/ /*-------------------------*/
index = dict_mem_index_create("SYS_TABLES", "ID_IND", index = dict_mem_index_create("SYS_TABLES", "ID_IND",
DICT_HDR_SPACE, DICT_UNIQUE, 1); DICT_HDR_SPACE, DICT_UNIQUE, 1);
dict_mem_index_add_field(index, "ID", 0, 0); dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_TABLE_IDS_ID; index->id = DICT_TABLE_IDS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE); table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0); dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
...@@ -300,15 +299,15 @@ dict_boot(void) ...@@ -300,15 +299,15 @@ dict_boot(void)
index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND", index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "TABLE_ID", 0);
dict_mem_index_add_field(index, "POS", 0, 0); dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_COLUMNS_ID; index->id = DICT_COLUMNS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE); table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0); dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
...@@ -336,15 +335,15 @@ dict_boot(void) ...@@ -336,15 +335,15 @@ dict_boot(void)
index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND", index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "TABLE_ID", 0);
dict_mem_index_add_field(index, "ID", 0, 0); dict_mem_index_add_field(index, "ID", 0);
index->id = DICT_INDEXES_ID; index->id = DICT_INDEXES_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr)); dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr));
ut_a(success); ut_a(success);
/*-------------------------*/ /*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE); table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0); dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0); dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
...@@ -357,8 +356,8 @@ dict_boot(void) ...@@ -357,8 +356,8 @@ dict_boot(void)
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND", index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
dict_mem_index_add_field(index, "INDEX_ID", 0, 0); dict_mem_index_add_field(index, "INDEX_ID", 0);
dict_mem_index_add_field(index, "POS", 0, 0); dict_mem_index_add_field(index, "POS", 0);
index->id = DICT_FIELDS_ID; index->id = DICT_FIELDS_ID;
success = dict_index_add_to_cache(table, index, mtr_read_ulint( success = dict_index_add_to_cache(table, index, mtr_read_ulint(
......
...@@ -62,9 +62,13 @@ dict_create_sys_tables_tuple( ...@@ -62,9 +62,13 @@ dict_create_sys_tables_tuple(
/* 4: N_COLS ---------------------------*/ /* 4: N_COLS ---------------------------*/
dfield = dtuple_get_nth_field(entry, 2); dfield = dtuple_get_nth_field(entry, 2);
#if DICT_TF_COMPACT != 1
#error
#endif
ptr = mem_heap_alloc(heap, 4); ptr = mem_heap_alloc(heap, 4);
mach_write_to_4(ptr, table->n_def mach_write_to_4(ptr, table->n_def
| ((ulint) table->comp << 31)); | ((table->flags & DICT_TF_COMPACT) << 31));
dfield_set_data(dfield, ptr, 4); dfield_set_data(dfield, ptr, 4);
/* 5: TYPE -----------------------------*/ /* 5: TYPE -----------------------------*/
dfield = dtuple_get_nth_field(entry, 3); dfield = dtuple_get_nth_field(entry, 3);
...@@ -634,7 +638,7 @@ dict_create_index_tree_step( ...@@ -634,7 +638,7 @@ dict_create_index_tree_step(
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
node->page_no = btr_create(index->type, index->space, index->id, node->page_no = btr_create(index->type, index->space, index->id,
table->comp, &mtr); dict_table_is_comp(table), &mtr);
/* printf("Created a new index tree in space %lu root page %lu\n", /* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */ index->space, index->page_no); */
...@@ -671,7 +675,7 @@ dict_drop_index_tree( ...@@ -671,7 +675,7 @@ dict_drop_index_tree(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(!dict_sys->sys_indexes->comp); ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_ad(len == 4); ut_ad(len == 4);
...@@ -743,7 +747,7 @@ dict_truncate_index_tree( ...@@ -743,7 +747,7 @@ dict_truncate_index_tree(
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(!dict_sys->sys_indexes->comp); ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
ut_ad(len == 4); ut_ad(len == 4);
...@@ -1324,7 +1328,7 @@ dict_create_add_foreigns_to_dictionary( ...@@ -1324,7 +1328,7 @@ dict_create_add_foreigns_to_dictionary(
if (NULL == dict_table_get_low("SYS_FOREIGN")) { if (NULL == dict_table_get_low("SYS_FOREIGN")) {
fprintf(stderr, fprintf(stderr,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n"); "InnoDB: table SYS_FOREIGN not found from internal data dictionary\n");
return(DB_ERROR); return(DB_ERROR);
} }
......
This diff is collapsed.
...@@ -58,7 +58,7 @@ dict_get_first_table_name_in_db( ...@@ -58,7 +58,7 @@ dict_get_first_table_name_in_db(
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -94,7 +94,7 @@ loop: ...@@ -94,7 +94,7 @@ loop:
return(NULL); return(NULL);
} }
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
...@@ -169,7 +169,7 @@ loop: ...@@ -169,7 +169,7 @@ loop:
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
...@@ -235,7 +235,7 @@ dict_check_tablespaces_and_store_max_id( ...@@ -235,7 +235,7 @@ dict_check_tablespaces_and_store_max_id(
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
TRUE, &mtr); TRUE, &mtr);
...@@ -264,7 +264,7 @@ loop: ...@@ -264,7 +264,7 @@ loop:
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
if (!rec_get_deleted_flag(rec, sys_tables->comp)) { if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */ /* We found one */
...@@ -343,7 +343,7 @@ dict_load_columns( ...@@ -343,7 +343,7 @@ dict_load_columns(
sys_columns = dict_table_get_low("SYS_COLUMNS"); sys_columns = dict_table_get_low("SYS_COLUMNS");
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
ut_a(!sys_columns->comp); ut_a(!dict_table_is_comp(sys_columns));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -362,7 +362,7 @@ dict_load_columns( ...@@ -362,7 +362,7 @@ dict_load_columns(
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
ut_a(!rec_get_deleted_flag(rec, sys_columns->comp)); ut_a(!rec_get_deleted_flag(rec, 0));
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_ad(len == 8); ut_ad(len == 8);
...@@ -385,14 +385,24 @@ dict_load_columns( ...@@ -385,14 +385,24 @@ dict_load_columns(
field = rec_get_nth_field_old(rec, 6, &len); field = rec_get_nth_field_old(rec, 6, &len);
prtype = mach_read_from_4(field); prtype = mach_read_from_4(field);
if (dtype_is_non_binary_string_type(mtype, prtype) if (dtype_get_charset_coll(prtype) == 0
&& dtype_get_charset_coll(prtype) == 0) { && dtype_is_string_type(mtype)) {
/* This is a non-binary string type, and the table /* The table was created with < 4.1.2. */
was created with < 4.1.2. Use the default charset. */
if (dtype_is_binary_string_type(mtype, prtype)) {
/* Use the binary collation for
string columns of binary type. */
prtype = dtype_form_prtype(prtype,
DATA_MYSQL_BINARY_CHARSET_COLL);
} else {
/* Use the default charset for
other than binary columns. */
prtype = dtype_form_prtype(prtype, prtype = dtype_form_prtype(prtype,
data_mysql_default_charset_coll); data_mysql_default_charset_coll);
} }
}
field = rec_get_nth_field_old(rec, 7, &len); field = rec_get_nth_field_old(rec, 7, &len);
col_len = mach_read_from_4(field); col_len = mach_read_from_4(field);
...@@ -466,7 +476,7 @@ dict_load_fields( ...@@ -466,7 +476,7 @@ dict_load_fields(
sys_fields = dict_table_get_low("SYS_FIELDS"); sys_fields = dict_table_get_low("SYS_FIELDS");
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
ut_a(!sys_fields->comp); ut_a(!dict_table_is_comp(sys_fields));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -484,7 +494,7 @@ dict_load_fields( ...@@ -484,7 +494,7 @@ dict_load_fields(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
if (rec_get_deleted_flag(rec, sys_fields->comp)) { if (rec_get_deleted_flag(rec, 0)) {
dict_load_report_deleted_index(table->name, i); dict_load_report_deleted_index(table->name, i);
} }
...@@ -523,7 +533,7 @@ dict_load_fields( ...@@ -523,7 +533,7 @@ dict_load_fields(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
dict_mem_index_add_field(index, dict_mem_index_add_field(index,
mem_heap_strdupl(heap, (char*) field, len), 0, prefix_len); mem_heap_strdupl(heap, (char*) field, len), prefix_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
...@@ -579,7 +589,7 @@ dict_load_indexes( ...@@ -579,7 +589,7 @@ dict_load_indexes(
sys_indexes = dict_table_get_low("SYS_INDEXES"); sys_indexes = dict_table_get_low("SYS_INDEXES");
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
ut_a(!sys_indexes->comp); ut_a(!dict_table_is_comp(sys_indexes));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -607,7 +617,7 @@ dict_load_indexes( ...@@ -607,7 +617,7 @@ dict_load_indexes(
break; break;
} }
if (rec_get_deleted_flag(rec, table->comp)) { if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) {
dict_load_report_deleted_index(table->name, dict_load_report_deleted_index(table->name,
ULINT_UNDEFINED); ULINT_UNDEFINED);
...@@ -729,6 +739,7 @@ dict_load_table( ...@@ -729,6 +739,7 @@ dict_load_table(
ulint len; ulint len;
ulint space; ulint space;
ulint n_cols; ulint n_cols;
ulint flags;
ulint err; ulint err;
mtr_t mtr; mtr_t mtr;
...@@ -742,7 +753,7 @@ dict_load_table( ...@@ -742,7 +753,7 @@ dict_load_table(
sys_tables = dict_table_get_low("SYS_TABLES"); sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -755,7 +766,7 @@ dict_load_table( ...@@ -755,7 +766,7 @@ dict_load_table(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
...@@ -817,10 +828,15 @@ dict_load_table( ...@@ -817,10 +828,15 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
n_cols = mach_read_from_4(field); n_cols = mach_read_from_4(field);
flags = 0;
/* The high-order bit of N_COLS is the "compact format" flag. */ /* The high-order bit of N_COLS is the "compact format" flag. */
table = dict_mem_table_create(name, space, if (n_cols & 0x80000000UL) {
n_cols & ~0x80000000UL, flags |= DICT_TF_COMPACT;
!!(n_cols & 0x80000000UL)); }
table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL,
flags);
table->ibd_file_missing = ibd_file_missing; table->ibd_file_missing = ibd_file_missing;
...@@ -928,7 +944,7 @@ dict_load_table_on_id( ...@@ -928,7 +944,7 @@ dict_load_table_on_id(
sys_tables = dict_sys->sys_tables; sys_tables = dict_sys->sys_tables;
sys_table_ids = dict_table_get_next_index( sys_table_ids = dict_table_get_next_index(
dict_table_get_first_index(sys_tables)); dict_table_get_first_index(sys_tables));
ut_a(!sys_tables->comp); ut_a(!dict_table_is_comp(sys_tables));
heap = mem_heap_create(256); heap = mem_heap_create(256);
tuple = dtuple_create(heap, 1); tuple = dtuple_create(heap, 1);
...@@ -945,7 +961,7 @@ dict_load_table_on_id( ...@@ -945,7 +961,7 @@ dict_load_table_on_id(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
...@@ -1042,7 +1058,7 @@ dict_load_foreign_cols( ...@@ -1042,7 +1058,7 @@ dict_load_foreign_cols(
sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS"); sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes); sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
ut_a(!sys_foreign_cols->comp); ut_a(!dict_table_is_comp(sys_foreign_cols));
tuple = dtuple_create(foreign->heap, 1); tuple = dtuple_create(foreign->heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -1057,7 +1073,7 @@ dict_load_foreign_cols( ...@@ -1057,7 +1073,7 @@ dict_load_foreign_cols(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
ut_a(!rec_get_deleted_flag(rec, sys_foreign_cols->comp)); ut_a(!rec_get_deleted_flag(rec, 0));
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
ut_a(len == ut_strlen(id)); ut_a(len == ut_strlen(id));
...@@ -1091,7 +1107,7 @@ dict_load_foreign( ...@@ -1091,7 +1107,7 @@ dict_load_foreign(
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* id, /* in: foreign constraint id as a const char* id, /* in: foreign constraint id as a
null-terminated string */ null-terminated string */
ibool check_types)/* in: TRUE=check type compatibility */ ibool check_charsets)/* in: TRUE=check charset compatibility */
{ {
dict_foreign_t* foreign; dict_foreign_t* foreign;
dict_table_t* sys_foreign; dict_table_t* sys_foreign;
...@@ -1115,7 +1131,7 @@ dict_load_foreign( ...@@ -1115,7 +1131,7 @@ dict_load_foreign(
sys_foreign = dict_table_get_low("SYS_FOREIGN"); sys_foreign = dict_table_get_low("SYS_FOREIGN");
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes); sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
ut_a(!sys_foreign->comp); ut_a(!dict_table_is_comp(sys_foreign));
tuple = dtuple_create(heap2, 1); tuple = dtuple_create(heap2, 1);
dfield = dtuple_get_nth_field(tuple, 0); dfield = dtuple_get_nth_field(tuple, 0);
...@@ -1128,7 +1144,7 @@ dict_load_foreign( ...@@ -1128,7 +1144,7 @@ dict_load_foreign(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr) if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_foreign->comp)) { || rec_get_deleted_flag(rec, 0)) {
/* Not found */ /* Not found */
fprintf(stderr, fprintf(stderr,
...@@ -1204,7 +1220,7 @@ dict_load_foreign( ...@@ -1204,7 +1220,7 @@ dict_load_foreign(
a new foreign key constraint but loading one from the data a new foreign key constraint but loading one from the data
dictionary. */ dictionary. */
return(dict_foreign_add_to_cache(foreign, check_types)); return(dict_foreign_add_to_cache(foreign, check_charsets));
} }
/*************************************************************************** /***************************************************************************
...@@ -1219,7 +1235,8 @@ dict_load_foreigns( ...@@ -1219,7 +1235,8 @@ dict_load_foreigns(
/*===============*/ /*===============*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */ const char* table_name, /* in: table name */
ibool check_types) /* in: TRUE=check type compatibility */ ibool check_charsets) /* in: TRUE=check charset
compatibility */
{ {
btr_pcur_t pcur; btr_pcur_t pcur;
mem_heap_t* heap; mem_heap_t* heap;
...@@ -1249,7 +1266,7 @@ dict_load_foreigns( ...@@ -1249,7 +1266,7 @@ dict_load_foreigns(
return(DB_ERROR); return(DB_ERROR);
} }
ut_a(!sys_foreign->comp); ut_a(!dict_table_is_comp(sys_foreign));
mtr_start(&mtr); mtr_start(&mtr);
/* Get the secondary index based on FOR_NAME from table /* Get the secondary index based on FOR_NAME from table
...@@ -1304,7 +1321,7 @@ loop: ...@@ -1304,7 +1321,7 @@ loop:
goto next_rec; goto next_rec;
} }
if (rec_get_deleted_flag(rec, sys_foreign->comp)) { if (rec_get_deleted_flag(rec, 0)) {
goto next_rec; goto next_rec;
} }
...@@ -1319,7 +1336,7 @@ loop: ...@@ -1319,7 +1336,7 @@ loop:
/* Load the foreign constraint definition to the dictionary cache */ /* Load the foreign constraint definition to the dictionary cache */
err = dict_load_foreign(id, check_types); err = dict_load_foreign(id, check_charsets);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
......
...@@ -36,13 +36,13 @@ dict_mem_table_create( ...@@ -36,13 +36,13 @@ dict_mem_table_create(
ignored if the table is made a member of ignored if the table is made a member of
a cluster */ a cluster */
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
ibool comp) /* in: TRUE=compact page format */ ulint flags) /* in: table flags */
{ {
dict_table_t* table; dict_table_t* table;
mem_heap_t* heap; mem_heap_t* heap;
ut_ad(name); ut_ad(name);
ut_ad(comp == FALSE || comp == TRUE); ut_ad(!(flags & ~DICT_TF_COMPACT));
heap = mem_heap_create(DICT_HEAP_SIZE); heap = mem_heap_create(DICT_HEAP_SIZE);
...@@ -51,12 +51,12 @@ dict_mem_table_create( ...@@ -51,12 +51,12 @@ dict_mem_table_create(
table->heap = heap; table->heap = heap;
table->type = DICT_TABLE_ORDINARY; table->type = DICT_TABLE_ORDINARY;
table->flags = flags;
table->name = mem_heap_strdup(heap, name); table->name = mem_heap_strdup(heap, name);
table->dir_path_of_temp_table = NULL; table->dir_path_of_temp_table = NULL;
table->space = space; table->space = space;
table->ibd_file_missing = FALSE; table->ibd_file_missing = FALSE;
table->tablespace_discarded = FALSE; table->tablespace_discarded = FALSE;
table->comp = comp;
table->n_def = 0; table->n_def = 0;
table->n_cols = n_cols + DATA_N_SYS_COLS; table->n_cols = n_cols + DATA_N_SYS_COLS;
table->mem_fix = 0; table->mem_fix = 0;
...@@ -114,7 +114,7 @@ dict_mem_cluster_create( ...@@ -114,7 +114,7 @@ dict_mem_cluster_create(
dict_table_t* cluster; dict_table_t* cluster;
/* Clustered tables cannot work with the compact record format. */ /* Clustered tables cannot work with the compact record format. */
cluster = dict_mem_table_create(name, space, n_cols, FALSE); cluster = dict_mem_table_create(name, space, n_cols, 0);
cluster->type = DICT_TABLE_CLUSTER; cluster->type = DICT_TABLE_CLUSTER;
cluster->mix_len = mix_len; cluster->mix_len = mix_len;
...@@ -261,8 +261,6 @@ dict_mem_index_add_field( ...@@ -261,8 +261,6 @@ dict_mem_index_add_field(
/*=====================*/ /*=====================*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
const char* name, /* in: column name */ const char* name, /* in: column name */
ulint order, /* in: order criterion; 0 means an
ascending order */
ulint prefix_len) /* in: 0 or the column prefix length ulint prefix_len) /* in: 0 or the column prefix length
in a MySQL index like in a MySQL index like
INDEX (textcol(25)) */ INDEX (textcol(25)) */
...@@ -277,8 +275,6 @@ dict_mem_index_add_field( ...@@ -277,8 +275,6 @@ dict_mem_index_add_field(
field = dict_index_get_nth_field(index, index->n_def - 1); field = dict_index_get_nth_field(index, index->n_def - 1);
field->name = name; field->name = name;
field->order = order;
field->prefix_len = prefix_len; field->prefix_len = prefix_len;
} }
......
...@@ -181,6 +181,11 @@ struct fil_space_struct { ...@@ -181,6 +181,11 @@ struct fil_space_struct {
hash_node_t name_hash;/* hash chain the name_hash table */ hash_node_t name_hash;/* hash chain the name_hash table */
rw_lock_t latch; /* latch protecting the file space storage rw_lock_t latch; /* latch protecting the file space storage
allocation */ allocation */
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
/* list of spaces with at least one unflushed
file we have written to */
ibool is_in_unflushed_spaces; /* TRUE if this space is
currently in the list above */
UT_LIST_NODE_T(fil_space_t) space_list; UT_LIST_NODE_T(fil_space_t) space_list;
/* list of all spaces */ /* list of all spaces */
ibuf_data_t* ibuf_data; ibuf_data_t* ibuf_data;
...@@ -213,6 +218,12 @@ struct fil_system_struct { ...@@ -213,6 +218,12 @@ struct fil_system_struct {
not put to this list: they are opened not put to this list: they are opened
after the startup, and kept open until after the startup, and kept open until
shutdown */ shutdown */
UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
/* base node for the list of those
tablespaces whose files contain
unflushed writes; those spaces have
at least one file node where
modification_counter > flush_counter */
ulint n_open; /* number of files currently open */ ulint n_open; /* number of files currently open */
ulint max_n_open; /* n_open is not allowed to exceed ulint max_n_open; /* n_open is not allowed to exceed
this */ this */
...@@ -389,6 +400,36 @@ fil_space_get_ibuf_data( ...@@ -389,6 +400,36 @@ fil_space_get_ibuf_data(
return(space->ibuf_data); return(space->ibuf_data);
} }
/**************************************************************************
Checks if all the file nodes in a space are flushed. The caller must hold
the fil_system mutex. */
static
ibool
fil_space_is_flushed(
/*=================*/
/* out: TRUE if all are flushed */
fil_space_t* space) /* in: space */
{
fil_node_t* node;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(fil_system->mutex)));
#endif /* UNIV_SYNC_DEBUG */
node = UT_LIST_GET_FIRST(space->chain);
while (node) {
if (node->modification_counter > node->flush_counter) {
return(FALSE);
}
node = UT_LIST_GET_NEXT(chain, node);
}
return(TRUE);
}
/*********************************************************************** /***********************************************************************
Appends a new file to the chain of files of a space. File must be closed. */ Appends a new file to the chain of files of a space. File must be closed. */
...@@ -469,10 +510,12 @@ fil_node_open_file( ...@@ -469,10 +510,12 @@ fil_node_open_file(
ulint size_low; ulint size_low;
ulint size_high; ulint size_high;
ibool ret; ibool ret;
ibool success;
#ifndef UNIV_HOTBACKUP
byte* buf2; byte* buf2;
byte* page; byte* page;
ibool success;
ulint space_id; ulint space_id;
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(system->mutex))); ut_ad(mutex_own(&(system->mutex)));
...@@ -505,9 +548,6 @@ fil_node_open_file( ...@@ -505,9 +548,6 @@ fil_node_open_file(
ut_a(0); ut_a(0);
} }
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
os_file_get_size(node->handle, &size_low, &size_high); os_file_get_size(node->handle, &size_low, &size_high);
size_bytes = (((ib_longlong)size_high) << 32) size_bytes = (((ib_longlong)size_high) << 32)
...@@ -516,6 +556,9 @@ fil_node_open_file( ...@@ -516,6 +556,9 @@ fil_node_open_file(
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE); node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
#else #else
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) { if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace file %s\n" "InnoDB: Error: the size of single-table tablespace file %s\n"
...@@ -841,6 +884,16 @@ fil_node_free( ...@@ -841,6 +884,16 @@ fil_node_free(
node->modification_counter = node->flush_counter; node->modification_counter = node->flush_counter;
if (space->is_in_unflushed_spaces
&& fil_space_is_flushed(space)) {
space->is_in_unflushed_spaces = FALSE;
UT_LIST_REMOVE(unflushed_spaces,
system->unflushed_spaces,
space);
}
fil_node_close_file(node, system); fil_node_close_file(node, system);
} }
...@@ -1004,6 +1057,8 @@ try_again: ...@@ -1004,6 +1057,8 @@ try_again:
HASH_INSERT(fil_space_t, name_hash, system->name_hash, HASH_INSERT(fil_space_t, name_hash, system->name_hash,
ut_fold_string(name), space); ut_fold_string(name), space);
space->is_in_unflushed_spaces = FALSE;
UT_LIST_ADD_LAST(space_list, system->space_list, space); UT_LIST_ADD_LAST(space_list, system->space_list, space);
mutex_exit(&(system->mutex)); mutex_exit(&(system->mutex));
...@@ -1099,6 +1154,13 @@ fil_space_free( ...@@ -1099,6 +1154,13 @@ fil_space_free(
HASH_DELETE(fil_space_t, name_hash, system->name_hash, HASH_DELETE(fil_space_t, name_hash, system->name_hash,
ut_fold_string(space->name), space); ut_fold_string(space->name), space);
if (space->is_in_unflushed_spaces) {
space->is_in_unflushed_spaces = FALSE;
UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
space);
}
UT_LIST_REMOVE(space_list, system->space_list, space); UT_LIST_REMOVE(space_list, system->space_list, space);
ut_a(space->magic_n == FIL_SPACE_MAGIC_N); ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
...@@ -1250,6 +1312,7 @@ fil_system_create( ...@@ -1250,6 +1312,7 @@ fil_system_create(
system->tablespace_version = 0; system->tablespace_version = 0;
UT_LIST_INIT(system->unflushed_spaces);
UT_LIST_INIT(system->space_list); UT_LIST_INIT(system->space_list);
return(system); return(system);
...@@ -1581,7 +1644,7 @@ Decrements the count of pending insert buffer page merges. */ ...@@ -1581,7 +1644,7 @@ Decrements the count of pending insert buffer page merges. */
void void
fil_decr_pending_ibuf_merges( fil_decr_pending_ibuf_merges(
/*========================*/ /*=========================*/
ulint id) /* in: space id */ ulint id) /* in: space id */
{ {
fil_system_t* system = fil_system; fil_system_t* system = fil_system;
...@@ -2744,6 +2807,7 @@ fil_load_single_table_tablespace( ...@@ -2744,6 +2807,7 @@ fil_load_single_table_tablespace(
filename); filename);
srv_normalize_path_for_win(filepath); srv_normalize_path_for_win(filepath);
#ifdef __WIN__ #ifdef __WIN__
# ifndef UNIV_HOTBACKUP
/* If lower_case_table_names is 0 or 2, then MySQL allows database /* If lower_case_table_names is 0 or 2, then MySQL allows database
directory names with upper case letters. On Windows, all table and directory names with upper case letters. On Windows, all table and
database names in InnoDB are internally always in lower case. Put the database names in InnoDB are internally always in lower case. Put the
...@@ -2751,6 +2815,7 @@ fil_load_single_table_tablespace( ...@@ -2751,6 +2815,7 @@ fil_load_single_table_tablespace(
internal data dictionary. */ internal data dictionary. */
dict_casedn_str(filepath); dict_casedn_str(filepath);
# endif /* !UNIV_HOTBACKUP */
#endif #endif
file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN, file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN,
OS_FILE_READ_ONLY, &success); OS_FILE_READ_ONLY, &success);
...@@ -3059,7 +3124,7 @@ fil_load_single_table_tablespaces(void) ...@@ -3059,7 +3124,7 @@ fil_load_single_table_tablespaces(void)
&fileinfo); &fileinfo);
while (ret == 0) { while (ret == 0) {
/* printf( /* printf(
" Looking at file %s\n", fileinfo.name); */ " Looking at file %s\n", fileinfo.name); */
if (fileinfo.type == OS_FILE_TYPE_DIR) { if (fileinfo.type == OS_FILE_TYPE_DIR) {
...@@ -3496,6 +3561,7 @@ fil_extend_space_to_desired_size( ...@@ -3496,6 +3561,7 @@ fil_extend_space_to_desired_size(
*actual_size = space->size; *actual_size = space->size;
#ifndef UNIV_HOTBACKUP
if (space_id == 0) { if (space_id == 0) {
ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE; ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE;
...@@ -3505,6 +3571,7 @@ fil_extend_space_to_desired_size( ...@@ -3505,6 +3571,7 @@ fil_extend_space_to_desired_size(
srv_data_file_sizes[srv_n_data_files - 1] = srv_data_file_sizes[srv_n_data_files - 1] =
(node->size / pages_per_mb) * pages_per_mb; (node->size / pages_per_mb) * pages_per_mb;
} }
#endif /* !UNIV_HOTBACKUP */
/* /*
printf("Extended %s to %lu, actual size %lu pages\n", space->name, printf("Extended %s to %lu, actual size %lu pages\n", space->name,
...@@ -3545,8 +3612,8 @@ fil_extend_tablespaces_to_stored_len(void) ...@@ -3545,8 +3612,8 @@ fil_extend_tablespaces_to_stored_len(void)
ut_a(space->purpose == FIL_TABLESPACE); ut_a(space->purpose == FIL_TABLESPACE);
mutex_exit(&(system->mutex)); /* no need to protect with a mutex_exit(&(system->mutex)); /* no need to protect with a
mutex, because this is a single- mutex, because this is a
threaded operation */ single-threaded operation */
error = fil_read(TRUE, space->id, 0, 0, UNIV_PAGE_SIZE, buf, error = fil_read(TRUE, space->id, 0, 0, UNIV_PAGE_SIZE, buf,
NULL); NULL);
ut_a(error == DB_SUCCESS); ut_a(error == DB_SUCCESS);
...@@ -3742,6 +3809,14 @@ fil_node_complete_io( ...@@ -3742,6 +3809,14 @@ fil_node_complete_io(
if (type == OS_FILE_WRITE) { if (type == OS_FILE_WRITE) {
system->modification_counter++; system->modification_counter++;
node->modification_counter = system->modification_counter; node->modification_counter = system->modification_counter;
if (!node->space->is_in_unflushed_spaces) {
node->space->is_in_unflushed_spaces = TRUE;
UT_LIST_ADD_FIRST(unflushed_spaces,
system->unflushed_spaces,
node->space);
}
} }
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
...@@ -3751,6 +3826,31 @@ fil_node_complete_io( ...@@ -3751,6 +3826,31 @@ fil_node_complete_io(
} }
} }
/************************************************************************
Report information about an invalid page access. */
static
void
fil_report_invalid_page_access(
/*===========================*/
ulint block_offset, /* in: block offset */
ulint space_id, /* in: space id */
const char* space_name, /* in: space name */
ulint byte_offset, /* in: byte offset */
ulint len, /* in: I/O length */
ulint type) /* in: I/O type */
{
fprintf(stderr,
"InnoDB: Error: trying to access page number %lu in space %lu,\n"
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n"
"InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
"InnoDB: If you get this error at mysqld startup, please check that\n"
"InnoDB: your my.cnf matches the ibdata files that you have in the\n"
"InnoDB: MySQL server.\n",
(ulong) block_offset, (ulong) space_id, space_name,
(ulong) byte_offset, (ulong) len, (ulong) type);
}
/************************************************************************ /************************************************************************
Reads or writes data. This operation is asynchronous (aio). */ Reads or writes data. This operation is asynchronous (aio). */
...@@ -3857,14 +3957,8 @@ fil_io( ...@@ -3857,14 +3957,8 @@ fil_io(
for (;;) { for (;;) {
if (node == NULL) { if (node == NULL) {
fprintf(stderr, fil_report_invalid_page_access(block_offset, space_id,
"InnoDB: Error: trying to access page number %lu in space %lu,\n" space->name, byte_offset, len, type);
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n"
"InnoDB: Byte offset %lu, len %lu, i/o type %lu\n",
(ulong) block_offset, (ulong) space_id,
space->name, (ulong) byte_offset, (ulong) len,
(ulong) type);
ut_error; ut_error;
} }
...@@ -3893,15 +3987,10 @@ fil_io( ...@@ -3893,15 +3987,10 @@ fil_io(
if (space->purpose == FIL_TABLESPACE && space->id != 0 if (space->purpose == FIL_TABLESPACE && space->id != 0
&& node->size <= block_offset) { && node->size <= block_offset) {
fprintf(stderr, fil_report_invalid_page_access(block_offset, space_id,
"InnoDB: Error: trying to access page number %lu in space %lu,\n" space->name, byte_offset, len, type);
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n" ut_error;
"InnoDB: Byte offset %lu, len %lu, i/o type %lu\n",
(ulong) block_offset, (ulong) space_id,
space->name, (ulong) byte_offset, (ulong) len,
(ulong) type);
ut_a(0);
} }
/* Now we have made the changes in the data structures of system */ /* Now we have made the changes in the data structures of system */
...@@ -4162,6 +4251,16 @@ retry: ...@@ -4162,6 +4251,16 @@ retry:
skip_flush: skip_flush:
if (node->flush_counter < old_mod_counter) { if (node->flush_counter < old_mod_counter) {
node->flush_counter = old_mod_counter; node->flush_counter = old_mod_counter;
if (space->is_in_unflushed_spaces
&& fil_space_is_flushed(space)) {
space->is_in_unflushed_spaces = FALSE;
UT_LIST_REMOVE(unflushed_spaces,
system->unflushed_spaces,
space);
}
} }
if (space->purpose == FIL_TABLESPACE) { if (space->purpose == FIL_TABLESPACE) {
...@@ -4193,13 +4292,13 @@ fil_flush_file_spaces( ...@@ -4193,13 +4292,13 @@ fil_flush_file_spaces(
mutex_enter(&(system->mutex)); mutex_enter(&(system->mutex));
space = UT_LIST_GET_FIRST(system->space_list); space = UT_LIST_GET_FIRST(system->unflushed_spaces);
while (space) { while (space) {
if (space->purpose == purpose && !space->is_being_deleted) { if (space->purpose == purpose && !space->is_being_deleted) {
space->n_pending_flushes++; /* prevent dropping of the space->n_pending_flushes++; /* prevent dropping of
space while we are the space while we are
flushing */ flushing */
mutex_exit(&(system->mutex)); mutex_exit(&(system->mutex));
...@@ -4209,7 +4308,7 @@ fil_flush_file_spaces( ...@@ -4209,7 +4308,7 @@ fil_flush_file_spaces(
space->n_pending_flushes--; space->n_pending_flushes--;
} }
space = UT_LIST_GET_NEXT(space_list, space); space = UT_LIST_GET_NEXT(unflushed_spaces, space);
} }
mutex_exit(&(system->mutex)); mutex_exit(&(system->mutex));
......
...@@ -610,8 +610,10 @@ xdes_calc_descriptor_page( ...@@ -610,8 +610,10 @@ xdes_calc_descriptor_page(
/* out: descriptor page offset */ /* out: descriptor page offset */
ulint offset) /* in: page offset */ ulint offset) /* in: page offset */
{ {
ut_ad(UNIV_PAGE_SIZE > XDES_ARR_OFFSET #if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+ (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE); + (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE
# error
#endif
return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE)); return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE));
} }
...@@ -789,7 +791,7 @@ Inits a file page whose prior contents should be ignored. */ ...@@ -789,7 +791,7 @@ Inits a file page whose prior contents should be ignored. */
static static
void void
fsp_init_file_page_low( fsp_init_file_page_low(
/*=====================*/ /*===================*/
byte* ptr) /* in: pointer to a page */ byte* ptr) /* in: pointer to a page */
{ {
page_t* page; page_t* page;
...@@ -807,7 +809,6 @@ fsp_init_file_page_low( ...@@ -807,7 +809,6 @@ fsp_init_file_page_low(
/*************************************************************** /***************************************************************
Inits a file page whose prior contents should be ignored. */ Inits a file page whose prior contents should be ignored. */
static static
void void
fsp_init_file_page( fsp_init_file_page(
...@@ -891,9 +892,13 @@ fsp_header_init( ...@@ -891,9 +892,13 @@ fsp_header_init(
fsp_init_file_page(page, mtr); fsp_init_file_page(page, mtr);
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR,
MLOG_2BYTES, mtr);
header = FSP_HEADER_OFFSET + page; header = FSP_HEADER_OFFSET + page;
mlog_write_ulint(header + FSP_SPACE_ID, space, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_SPACE_ID, space, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_NOT_USED, 0, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
...@@ -935,8 +940,8 @@ fsp_header_get_space_id( ...@@ -935,8 +940,8 @@ fsp_header_get_space_id(
if (id != fsp_id) { if (id != fsp_id) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: space id in fsp header %lu, but in the page header %lu\n", "InnoDB: Error: space id in fsp header %lu, but in the page header %lu\n",
(ulong) fsp_id, (ulong) fsp_id, (ulong) id);
(ulong) id);
return(ULINT_UNDEFINED); return(ULINT_UNDEFINED);
} }
...@@ -1252,6 +1257,8 @@ fsp_fill_free_list( ...@@ -1252,6 +1257,8 @@ fsp_fill_free_list(
SYNC_FSP_PAGE); SYNC_FSP_PAGE);
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
fsp_init_file_page(descr_page, mtr); fsp_init_file_page(descr_page, mtr);
mlog_write_ulint(descr_page + FIL_PAGE_TYPE,
FIL_PAGE_TYPE_XDES, MLOG_2BYTES, mtr);
} }
/* Initialize the ibuf bitmap page in a separate /* Initialize the ibuf bitmap page in a separate
...@@ -1279,7 +1286,9 @@ fsp_fill_free_list( ...@@ -1279,7 +1286,9 @@ fsp_fill_free_list(
mtr); mtr);
xdes_init(descr, mtr); xdes_init(descr, mtr);
ut_ad(XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE == 0); #if XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE
# error "XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE != 0"
#endif
if (0 == i % XDES_DESCRIBED_PER_PAGE) { if (0 == i % XDES_DESCRIBED_PER_PAGE) {
...@@ -1716,7 +1725,8 @@ fsp_alloc_seg_inode_page( ...@@ -1716,7 +1725,8 @@ fsp_alloc_seg_inode_page(
buf_block_align(page)->check_index_page_at_flush = FALSE; buf_block_align(page)->check_index_page_at_flush = FALSE;
fil_page_set_type(page, FIL_PAGE_INODE); mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_INODE,
MLOG_2BYTES, mtr);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_FSP_PAGE); buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
...@@ -2087,6 +2097,8 @@ fseg_create_general( ...@@ -2087,6 +2097,8 @@ fseg_create_general(
header = byte_offset header = byte_offset
+ buf_page_get(space, page, RW_X_LATCH, mtr); + buf_page_get(space, page, RW_X_LATCH, mtr);
mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE,
FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr);
} }
mlog_write_ulint(header + FSEG_HDR_OFFSET, mlog_write_ulint(header + FSEG_HDR_OFFSET,
...@@ -2844,8 +2856,9 @@ fsp_get_available_space_in_free_extents( ...@@ -2844,8 +2856,9 @@ fsp_get_available_space_in_free_extents(
if (size < FSP_EXTENT_SIZE) { if (size < FSP_EXTENT_SIZE) {
ut_a(space != 0); /* This must be a single-table ut_a(space != 0); /* This must be a single-table
tablespace */ tablespace */
return(0); /* TODO: count free frag pages and return
a value based on that */ return(0); /* TODO: count free frag pages and
return a value based on that */
} }
/* Below we play safe when counting free extents above the free limit: /* Below we play safe when counting free extents above the free limit:
...@@ -3721,18 +3734,22 @@ fsp_validate( ...@@ -3721,18 +3734,22 @@ fsp_validate(
mtr_start(&mtr); mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr); mtr_x_lock(fil_space_get_latch(space), &mtr);
seg_inode_page = fut_get_ptr(space, node_addr, RW_X_LATCH, seg_inode_page = fut_get_ptr(space, node_addr,
&mtr) - FSEG_INODE_PAGE_NODE; RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE;
seg_inode = fsp_seg_inode_page_get_nth_inode(seg_inode_page, seg_inode = fsp_seg_inode_page_get_nth_inode(
n, &mtr); seg_inode_page, n, &mtr);
ut_a(ut_dulint_cmp(mach_read_from_8(seg_inode + FSEG_ID), ut_a(ut_dulint_cmp(
mach_read_from_8(seg_inode + FSEG_ID),
ut_dulint_zero) != 0); ut_dulint_zero) != 0);
fseg_validate_low(seg_inode, &mtr); fseg_validate_low(seg_inode, &mtr);
descr_count += flst_get_len(seg_inode + FSEG_FREE, &mtr); descr_count += flst_get_len(seg_inode + FSEG_FREE,
descr_count += flst_get_len(seg_inode + FSEG_FULL, &mtr); &mtr);
descr_count += flst_get_len(seg_inode + FSEG_NOT_FULL, &mtr); descr_count += flst_get_len(seg_inode + FSEG_FULL,
&mtr);
descr_count += flst_get_len(seg_inode + FSEG_NOT_FULL,
&mtr);
n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr); n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr);
...@@ -3762,22 +3779,24 @@ fsp_validate( ...@@ -3762,22 +3779,24 @@ fsp_validate(
mtr_start(&mtr); mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr); mtr_x_lock(fil_space_get_latch(space), &mtr);
seg_inode_page = fut_get_ptr(space, node_addr, RW_X_LATCH, seg_inode_page = fut_get_ptr(space, node_addr,
&mtr) - FSEG_INODE_PAGE_NODE; RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE;
seg_inode = fsp_seg_inode_page_get_nth_inode(seg_inode_page, seg_inode = fsp_seg_inode_page_get_nth_inode(
n, &mtr); seg_inode_page, n, &mtr);
if (ut_dulint_cmp(mach_read_from_8(seg_inode + FSEG_ID), if (ut_dulint_cmp(mach_read_from_8(
seg_inode + FSEG_ID),
ut_dulint_zero) != 0) { ut_dulint_zero) != 0) {
fseg_validate_low(seg_inode, &mtr); fseg_validate_low(seg_inode, &mtr);
descr_count += flst_get_len(seg_inode + FSEG_FREE, descr_count += flst_get_len(
&mtr); seg_inode + FSEG_FREE, &mtr);
descr_count += flst_get_len(seg_inode + FSEG_FULL, descr_count += flst_get_len(
&mtr); seg_inode + FSEG_FULL, &mtr);
descr_count += flst_get_len(seg_inode + FSEG_NOT_FULL, descr_count += flst_get_len(
&mtr); seg_inode + FSEG_NOT_FULL, &mtr);
n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr); n_used2 += fseg_get_n_frag_pages(
seg_inode, &mtr);
} }
next_node_addr = flst_get_next_addr(seg_inode_page next_node_addr = flst_get_next_addr(seg_inode_page
...@@ -3796,6 +3815,7 @@ fsp_validate( ...@@ -3796,6 +3815,7 @@ fsp_validate(
ut_a(frag_n_used == n_used); ut_a(frag_n_used == n_used);
mtr_commit(&mtr2); mtr_commit(&mtr2);
return(TRUE); return(TRUE);
} }
...@@ -3884,12 +3904,13 @@ fsp_print( ...@@ -3884,12 +3904,13 @@ fsp_print(
mtr_start(&mtr); mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr); mtr_x_lock(fil_space_get_latch(space), &mtr);
seg_inode_page = fut_get_ptr(space, node_addr, RW_X_LATCH, seg_inode_page = fut_get_ptr(space, node_addr,
&mtr) - FSEG_INODE_PAGE_NODE; RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE;
seg_inode = fsp_seg_inode_page_get_nth_inode(seg_inode_page, seg_inode = fsp_seg_inode_page_get_nth_inode(
n, &mtr); seg_inode_page, n, &mtr);
ut_a(ut_dulint_cmp(mach_read_from_8(seg_inode + FSEG_ID), ut_a(ut_dulint_cmp(mach_read_from_8(
seg_inode + FSEG_ID),
ut_dulint_zero) != 0); ut_dulint_zero) != 0);
fseg_print_low(seg_inode, &mtr); fseg_print_low(seg_inode, &mtr);
...@@ -3919,12 +3940,13 @@ fsp_print( ...@@ -3919,12 +3940,13 @@ fsp_print(
mtr_start(&mtr); mtr_start(&mtr);
mtr_x_lock(fil_space_get_latch(space), &mtr); mtr_x_lock(fil_space_get_latch(space), &mtr);
seg_inode_page = fut_get_ptr(space, node_addr, RW_X_LATCH, seg_inode_page = fut_get_ptr(space, node_addr,
&mtr) - FSEG_INODE_PAGE_NODE; RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE;
seg_inode = fsp_seg_inode_page_get_nth_inode(seg_inode_page, seg_inode = fsp_seg_inode_page_get_nth_inode(
n, &mtr); seg_inode_page, n, &mtr);
if (ut_dulint_cmp(mach_read_from_8(seg_inode + FSEG_ID), if (ut_dulint_cmp(mach_read_from_8(
seg_inode + FSEG_ID),
ut_dulint_zero) != 0) { ut_dulint_zero) != 0) {
fseg_print_low(seg_inode, &mtr); fseg_print_low(seg_inode, &mtr);
......
...@@ -281,20 +281,26 @@ ha_remove_all_nodes_to_page( ...@@ -281,20 +281,26 @@ ha_remove_all_nodes_to_page(
} }
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table) /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index) /* in: end index */
{ {
hash_cell_t* cell; hash_cell_t* cell;
ha_node_t* node; ha_node_t* node;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
for (i = 0; i < hash_get_n_cells(table); i++) { ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table));
for (i = start_index; i <= end_index; i++) {
cell = hash_get_nth_cell(table, i); cell = hash_get_nth_cell(table, i);
......
...@@ -140,8 +140,7 @@ access order rules. */ ...@@ -140,8 +140,7 @@ access order rules. */
/* The insert buffer control structure */ /* The insert buffer control structure */
ibuf_t* ibuf = NULL; ibuf_t* ibuf = NULL;
static static ulint ibuf_rnd = 986058871;
ulint ibuf_rnd = 986058871;
ulint ibuf_flush_count = 0; ulint ibuf_flush_count = 0;
...@@ -533,7 +532,7 @@ ibuf_data_init_for_space( ...@@ -533,7 +532,7 @@ ibuf_data_init_for_space(
sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space); sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
/* use old-style record format for the insert buffer */ /* use old-style record format for the insert buffer */
table = dict_mem_table_create(buf, space, 2, FALSE); table = dict_mem_table_create(buf, space, 2, 0);
dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
...@@ -545,8 +544,8 @@ ibuf_data_init_for_space( ...@@ -545,8 +544,8 @@ ibuf_data_init_for_space(
index = dict_mem_index_create(buf, "CLUST_IND", space, index = dict_mem_index_create(buf, "CLUST_IND", space,
DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2); DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2);
dict_mem_index_add_field(index, "PAGE_NO", 0, 0); dict_mem_index_add_field(index, "PAGE_NO", 0);
dict_mem_index_add_field(index, "TYPES", 0, 0); dict_mem_index_add_field(index, "TYPES", 0);
index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
...@@ -574,18 +573,18 @@ ibuf_bitmap_page_init( ...@@ -574,18 +573,18 @@ ibuf_bitmap_page_init(
{ {
ulint bit_offset; ulint bit_offset;
ulint byte_offset; ulint byte_offset;
ulint i;
/* Write all zeros to the bitmap */ /* Write all zeros to the bitmap */
bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE; bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE;
byte_offset = bit_offset / 8 + 1; byte_offset = bit_offset / 8 + 1; /* better: (bit_offset + 7) / 8 */
for (i = IBUF_BITMAP; i < IBUF_BITMAP + byte_offset; i++) { fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP);
*(page + i) = (byte)0; memset(page + IBUF_BITMAP, 0, byte_offset);
}
/* The remaining area (up to the page trailer) is uninitialized. */
mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr); mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr);
} }
...@@ -621,8 +620,9 @@ ibuf_bitmap_page_get_bits( ...@@ -621,8 +620,9 @@ ibuf_bitmap_page_get_bits(
page_t* page, /* in: bitmap page */ page_t* page, /* in: bitmap page */
ulint page_no,/* in: page whose bits to get */ ulint page_no,/* in: page whose bits to get */
ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */ ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
mtr_t* mtr __attribute__((unused))) /* in: mtr containing an x-latch mtr_t* mtr __attribute__((unused))) /* in: mtr containing an
to the bitmap page */ x-latch to the bitmap
page */
{ {
ulint byte_offset; ulint byte_offset;
ulint bit_offset; ulint bit_offset;
...@@ -630,7 +630,9 @@ ibuf_bitmap_page_get_bits( ...@@ -630,7 +630,9 @@ ibuf_bitmap_page_get_bits(
ulint value; ulint value;
ut_ad(bit < IBUF_BITS_PER_PAGE); ut_ad(bit < IBUF_BITS_PER_PAGE);
ut_ad(IBUF_BITS_PER_PAGE % 2 == 0); #if IBUF_BITS_PER_PAGE % 2
# error "IBUF_BITS_PER_PAGE % 2 != 0"
#endif
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
...@@ -672,12 +674,15 @@ ibuf_bitmap_page_set_bits( ...@@ -672,12 +674,15 @@ ibuf_bitmap_page_set_bits(
ulint map_byte; ulint map_byte;
ut_ad(bit < IBUF_BITS_PER_PAGE); ut_ad(bit < IBUF_BITS_PER_PAGE);
ut_ad(IBUF_BITS_PER_PAGE % 2 == 0); #if IBUF_BITS_PER_PAGE % 2
# error "IBUF_BITS_PER_PAGE % 2 != 0"
#endif
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE) ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE)
|| (0 == ibuf_count_get(buf_frame_get_space_id(page), page_no))); || (0 == ibuf_count_get(buf_frame_get_space_id(page),
page_no)));
#endif #endif
bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE
+ bit; + bit;
...@@ -1122,13 +1127,18 @@ ibuf_dummy_index_create( ...@@ -1122,13 +1127,18 @@ ibuf_dummy_index_create(
{ {
dict_table_t* table; dict_table_t* table;
dict_index_t* index; dict_index_t* index;
table = dict_mem_table_create("IBUF_DUMMY", table = dict_mem_table_create("IBUF_DUMMY",
DICT_HDR_SPACE, n, comp); DICT_HDR_SPACE, n, comp ? DICT_TF_COMPACT : 0);
index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY", index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY",
DICT_HDR_SPACE, 0, n); DICT_HDR_SPACE, 0, n);
index->table = table; index->table = table;
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */ /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
index->cached = TRUE; index->cached = TRUE;
return(index); return(index);
} }
/************************************************************************ /************************************************************************
...@@ -1136,7 +1146,7 @@ Add a column to the dummy index */ ...@@ -1136,7 +1146,7 @@ Add a column to the dummy index */
static static
void void
ibuf_dummy_index_add_col( ibuf_dummy_index_add_col(
/*====================*/ /*=====================*/
dict_index_t* index, /* in: dummy index */ dict_index_t* index, /* in: dummy index */
dtype_t* type, /* in: the data type of the column */ dtype_t* type, /* in: the data type of the column */
ulint len) /* in: length of the column */ ulint len) /* in: length of the column */
...@@ -1148,7 +1158,7 @@ ibuf_dummy_index_add_col( ...@@ -1148,7 +1158,7 @@ ibuf_dummy_index_add_col(
dtype_get_len(type), dtype_get_len(type),
dtype_get_prec(type)); dtype_get_prec(type));
dict_index_add_col(index, dict_index_add_col(index,
dict_table_get_nth_col(index->table, i), 0, len); dict_table_get_nth_col(index->table, i), len);
} }
/************************************************************************ /************************************************************************
Deallocates a dummy index for inserting a record to a non-clustered index. Deallocates a dummy index for inserting a record to a non-clustered index.
...@@ -1156,7 +1166,7 @@ Deallocates a dummy index for inserting a record to a non-clustered index. ...@@ -1156,7 +1166,7 @@ Deallocates a dummy index for inserting a record to a non-clustered index.
static static
void void
ibuf_dummy_index_free( ibuf_dummy_index_free(
/*====================*/ /*==================*/
dict_index_t* index) /* in: dummy index */ dict_index_t* index) /* in: dummy index */
{ {
dict_table_t* table = index->table; dict_table_t* table = index->table;
...@@ -1676,7 +1686,8 @@ ibuf_add_free_page( ...@@ -1676,7 +1686,8 @@ ibuf_add_free_page(
flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr); page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
fil_page_set_type(page, FIL_PAGE_IBUF_FREE_LIST); mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_IBUF_FREE_LIST,
MLOG_2BYTES, &mtr);
ibuf_data->seg_size++; ibuf_data->seg_size++;
ibuf_data->free_list_len++; ibuf_data->free_list_len++;
...@@ -2448,7 +2459,7 @@ ibuf_update_max_tablespace_id(void) ...@@ -2448,7 +2459,7 @@ ibuf_update_max_tablespace_id(void)
ibuf_data = fil_space_get_ibuf_data(0); ibuf_data = fil_space_get_ibuf_data(0);
ibuf_index = ibuf_data->index; ibuf_index = ibuf_data->index;
ut_a(!ibuf_index->table->comp); ut_a(!dict_table_is_comp(ibuf_index->table));
ibuf_enter(); ibuf_enter();
...@@ -2592,7 +2603,7 @@ ibuf_insert_low( ...@@ -2592,7 +2603,7 @@ ibuf_insert_low(
the first fields and the type information for other fields, and which the first fields and the type information for other fields, and which
will be inserted to the insert buffer. */ will be inserted to the insert buffer. */
ibuf_entry = ibuf_entry_build(entry, index->table->comp, ibuf_entry = ibuf_entry_build(entry, dict_table_is_comp(index->table),
space, page_no, heap); space, page_no, heap);
/* Open a cursor to the insert buffer tree to calculate if we can add /* Open a cursor to the insert buffer tree to calculate if we can add
...@@ -2763,7 +2774,8 @@ ibuf_insert( ...@@ -2763,7 +2774,8 @@ ibuf_insert(
ut_a(!(index->type & DICT_CLUSTERED)); ut_a(!(index->type & DICT_CLUSTERED));
if (rec_get_converted_size(index, entry) if (rec_get_converted_size(index, entry)
>= page_get_free_space_of_empty(index->table->comp) / 2) { >= page_get_free_space_of_empty(
dict_table_is_comp(index->table)) / 2) {
return(FALSE); return(FALSE);
} }
...@@ -2810,7 +2822,8 @@ ibuf_insert_to_index_page( ...@@ -2810,7 +2822,8 @@ ibuf_insert_to_index_page(
ut_ad(ibuf_inside()); ut_ad(ibuf_inside());
ut_ad(dtuple_check_typed(entry)); ut_ad(dtuple_check_typed(entry));
if (UNIV_UNLIKELY(index->table->comp != (ibool)!!page_is_comp(page))) { if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
!= (ibool)!!page_is_comp(page))) {
fputs( fputs(
"InnoDB: Trying to insert a record from the insert buffer to an index page\n" "InnoDB: Trying to insert a record from the insert buffer to an index page\n"
"InnoDB: but the 'compact' flag does not match!\n", stderr); "InnoDB: but the 'compact' flag does not match!\n", stderr);
......
...@@ -277,6 +277,7 @@ btr_node_ptr_delete( ...@@ -277,6 +277,7 @@ btr_node_ptr_delete(
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: page whose node pointer is deleted */ page_t* page, /* in: page whose node pointer is deleted */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
#ifdef UNIV_DEBUG
/**************************************************************** /****************************************************************
Checks that the node pointer to a page is appropriate. */ Checks that the node pointer to a page is appropriate. */
...@@ -287,6 +288,7 @@ btr_check_node_ptr( ...@@ -287,6 +288,7 @@ btr_check_node_ptr(
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
page_t* page, /* in: index page */ page_t* page, /* in: index page */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr */
#endif /* UNIV_DEBUG */
/***************************************************************** /*****************************************************************
Tries to merge the page first to the left immediate brother if such a Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the brother exists, and the node pointers to the current page and to the
...@@ -412,7 +414,7 @@ the index. */ ...@@ -412,7 +414,7 @@ the index. */
ibool ibool
btr_index_rec_validate( btr_index_rec_validate(
/*====================*/ /*===================*/
/* out: TRUE if ok */ /* out: TRUE if ok */
rec_t* rec, /* in: index record */ rec_t* rec, /* in: index record */
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
......
...@@ -53,7 +53,8 @@ btr_cur_get_page( ...@@ -53,7 +53,8 @@ btr_cur_get_page(
btr_cur_t* cursor) /* in: tree cursor */ btr_cur_t* cursor) /* in: tree cursor */
{ {
page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur))); page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur)));
ut_ad(!!page_is_comp(page) == cursor->index->table->comp); ut_ad(!!page_is_comp(page)
== dict_table_is_comp(cursor->index->table));
return(page); return(page);
} }
......
...@@ -16,7 +16,7 @@ Updates the search info. */ ...@@ -16,7 +16,7 @@ Updates the search info. */
void void
btr_search_info_update_slow( btr_search_info_update_slow(
/*========================*/ /*========================*/
btr_search_t* info, /* in: search info */ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor);/* in: cursor which was just positioned */ btr_cur_t* cursor);/* in: cursor which was just positioned */
/************************************************************************ /************************************************************************
......
...@@ -266,7 +266,7 @@ the buffer pool. */ ...@@ -266,7 +266,7 @@ the buffer pool. */
void void
buf_page_make_young( buf_page_make_young(
/*=================*/ /*================*/
buf_frame_t* frame); /* in: buffer frame of a file page */ buf_frame_t* frame); /* in: buffer frame of a file page */
/************************************************************************ /************************************************************************
Returns TRUE if the page can be found in the buffer pool hash table. NOTE Returns TRUE if the page can be found in the buffer pool hash table. NOTE
...@@ -745,8 +745,6 @@ struct buf_block_struct{ ...@@ -745,8 +745,6 @@ struct buf_block_struct{
buffer pool which are index pages, buffer pool which are index pages,
but this flag is not set because but this flag is not set because
we do not keep track of all pages */ we do not keep track of all pages */
dict_index_t* index; /* index for which the adaptive
hash index has been created */
/* 2. Page flushing fields */ /* 2. Page flushing fields */
UT_LIST_NODE_T(buf_block_t) flush_list; UT_LIST_NODE_T(buf_block_t) flush_list;
...@@ -833,7 +831,13 @@ struct buf_block_struct{ ...@@ -833,7 +831,13 @@ struct buf_block_struct{
records with the same prefix should be records with the same prefix should be
indexed in the hash index */ indexed in the hash index */
/* The following 4 fields are protected by btr_search_latch: */ /* These 6 fields may only be modified when we have
an x-latch on btr_search_latch AND
a) we are holding an s-latch or x-latch on block->lock or
b) we know that block->buf_fix_count == 0.
An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */
ibool is_hashed; /* TRUE if hash index has already been ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does built on this page; note that it does
...@@ -850,6 +854,8 @@ struct buf_block_struct{ ...@@ -850,6 +854,8 @@ struct buf_block_struct{
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
BTR_SEARCH_RIGHT_SIDE in hash BTR_SEARCH_RIGHT_SIDE in hash
indexing */ indexing */
dict_index_t* index; /* Index for which the adaptive
hash index has been created. */
/* 6. Debug fields */ /* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread rw_lock_t debug_latch; /* in the debug version, each thread
......
...@@ -82,7 +82,8 @@ buf_pool_is_block( ...@@ -82,7 +82,8 @@ buf_pool_is_block(
void* ptr) /* in: pointer to memory */ void* ptr) /* in: pointer to memory */
{ {
if ((buf_pool->blocks <= (buf_block_t*)ptr) if ((buf_pool->blocks <= (buf_block_t*)ptr)
&& ((buf_block_t*)ptr < buf_pool->blocks + buf_pool->max_size)) { && ((buf_block_t*)ptr < buf_pool->blocks
+ buf_pool->max_size)) {
return(TRUE); return(TRUE);
} }
......
...@@ -320,6 +320,14 @@ void ...@@ -320,6 +320,14 @@ void
dfield_print_also_hex( dfield_print_also_hex(
/*==================*/ /*==================*/
dfield_t* dfield); /* in: dfield */ dfield_t* dfield); /* in: dfield */
/*****************************************************************
Print a dfield value using ut_print_buf. */
void
dfield_print_raw(
/*=============*/
FILE* f, /* in: output stream */
dfield_t* dfield); /* in: dfield */
/************************************************************** /**************************************************************
The following function prints the contents of a tuple. */ The following function prints the contents of a tuple. */
......
...@@ -9,7 +9,9 @@ Created 5/30/1994 Heikki Tuuri ...@@ -9,7 +9,9 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h" #include "mem0mem.h"
#include "ut0rnd.h" #include "ut0rnd.h"
#ifdef UNIV_DEBUG
extern byte data_error; extern byte data_error;
#endif /* UNIV_DEBUG */
/************************************************************************* /*************************************************************************
Gets pointer to the type struct of SQL data field. */ Gets pointer to the type struct of SQL data field. */
...@@ -145,7 +147,8 @@ dfield_datas_are_binary_equal( ...@@ -145,7 +147,8 @@ dfield_datas_are_binary_equal(
if ((len != field2->len) if ((len != field2->len)
|| ((len != UNIV_SQL_NULL) || ((len != UNIV_SQL_NULL)
&& (0 != ut_memcmp(field1->data, field2->data, len)))) { && (0 != ut_memcmp(field1->data, field2->data,
len)))) {
return(FALSE); return(FALSE);
} }
......
...@@ -13,6 +13,7 @@ Created 1/16/1996 Heikki Tuuri ...@@ -13,6 +13,7 @@ Created 1/16/1996 Heikki Tuuri
extern ulint data_mysql_default_charset_coll; extern ulint data_mysql_default_charset_coll;
#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8 #define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
#define DATA_MYSQL_BINARY_CHARSET_COLL 63
/* SQL data type struct */ /* SQL data type struct */
typedef struct dtype_struct dtype_t; typedef struct dtype_struct dtype_t;
...@@ -311,7 +312,7 @@ dtype_get_pad_char( ...@@ -311,7 +312,7 @@ dtype_get_pad_char(
/*===============*/ /*===============*/
/* out: padding character code, or /* out: padding character code, or
ULINT_UNDEFINED if no padding specified */ ULINT_UNDEFINED if no padding specified */
dtype_t* type); /* in: type */ const dtype_t* type); /* in: type */
/*************************************************************************** /***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */ Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE UNIV_INLINE
......
...@@ -8,6 +8,7 @@ Created 1/16/1996 Heikki Tuuri ...@@ -8,6 +8,7 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h" #include "mach0data.h"
#ifndef UNIV_HOTBACKUP
/********************************************************************** /**********************************************************************
Get the variable length bounds of the given character set. Get the variable length bounds of the given character set.
...@@ -20,6 +21,7 @@ innobase_get_cset_width( ...@@ -20,6 +21,7 @@ innobase_get_cset_width(
ulint cset, /* in: MySQL charset-collation code */ ulint cset, /* in: MySQL charset-collation code */
ulint* mbminlen, /* out: minimum length of a char (in bytes) */ ulint* mbminlen, /* out: minimum length of a char (in bytes) */
ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */ ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************* /*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */ Gets the MySQL charset-collation code for MySQL string types. */
...@@ -55,9 +57,21 @@ dtype_set_mblen( ...@@ -55,9 +57,21 @@ dtype_set_mblen(
{ {
ut_ad(type); ut_ad(type);
if (dtype_is_string_type(type->mtype)) { if (dtype_is_string_type(type->mtype)) {
#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(type->prtype), innobase_get_cset_width(dtype_get_charset_coll(type->prtype),
&type->mbminlen, &type->mbmaxlen); &type->mbminlen, &type->mbmaxlen);
ut_ad(type->mbminlen <= type->mbmaxlen); ut_ad(type->mbminlen <= type->mbmaxlen);
#else /* !UNIV_HOTBACKUP */
#ifdef notdefined
printf("ibbackup: DEBUG: type->mtype=%lu, type->prtype=%lu\n",
type->mtype, type->prtype);
#endif
ut_a(type->mtype <= DATA_BINARY);
#ifdef notdefined
ut_a(type->prtype == (DATA_BINARY | DATA_NOT_NULL));
#endif
type->mbminlen = type->mbmaxlen = 1;
#endif /* !UNIV_HOTBACKUP */
} else { } else {
type->mbminlen = type->mbmaxlen = 0; type->mbminlen = type->mbmaxlen = 0;
} }
...@@ -188,26 +202,35 @@ dtype_get_pad_char( ...@@ -188,26 +202,35 @@ dtype_get_pad_char(
/*===============*/ /*===============*/
/* out: padding character code, or /* out: padding character code, or
ULINT_UNDEFINED if no padding specified */ ULINT_UNDEFINED if no padding specified */
dtype_t* type) /* in: type */ const dtype_t* type) /* in: type */
{ {
if (type->mtype == DATA_CHAR switch (type->mtype) {
|| type->mtype == DATA_VARCHAR case DATA_FIXBINARY:
|| type->mtype == DATA_BINARY case DATA_BINARY:
|| type->mtype == DATA_FIXBINARY if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
|| type->mtype == DATA_MYSQL == DATA_MYSQL_BINARY_CHARSET_COLL)) {
|| type->mtype == DATA_VARMYSQL /* Starting from 5.0.18, do not pad
|| (type->mtype == DATA_BLOB VARBINARY or BINARY columns. */
&& (type->prtype & DATA_BINARY_TYPE) == 0)) { return(ULINT_UNDEFINED);
}
/* Fall through */
case DATA_CHAR:
case DATA_VARCHAR:
case DATA_MYSQL:
case DATA_VARMYSQL:
/* Space is the padding character for all char and binary /* Space is the padding character for all char and binary
strings, and starting from 5.0.3, also for TEXT strings. */ strings, and starting from 5.0.3, also for TEXT strings. */
return((ulint)' '); return(0x20);
case DATA_BLOB:
if ((type->prtype & DATA_BINARY_TYPE) == 0) {
return(0x20);
} }
/* Fall through */
default:
/* No padding specified */ /* No padding specified */
return(ULINT_UNDEFINED); return(ULINT_UNDEFINED);
}
} }
/************************************************************************** /**************************************************************************
...@@ -329,7 +352,6 @@ dtype_new_read_for_order_and_null_size( ...@@ -329,7 +352,6 @@ dtype_new_read_for_order_and_null_size(
dtype_set_mblen(type); dtype_set_mblen(type);
} }
#ifndef UNIV_HOTBACKUP
/*************************************************************************** /***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */ Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE UNIV_INLINE
...@@ -374,6 +396,11 @@ dtype_get_fixed_size( ...@@ -374,6 +396,11 @@ dtype_get_fixed_size(
if (type->prtype & DATA_BINARY_TYPE) { if (type->prtype & DATA_BINARY_TYPE) {
return(dtype_get_len(type)); return(dtype_get_len(type));
} else { } else {
#ifdef UNIV_HOTBACKUP
if (type->mbminlen == type->mbmaxlen) {
return(dtype_get_len(type));
}
#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for /* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although mbminlen and mbmaxlen. Although
type->mbminlen and type->mbmaxlen are type->mbminlen and type->mbmaxlen are
...@@ -405,6 +432,7 @@ dtype_get_fixed_size( ...@@ -405,6 +432,7 @@ dtype_get_fixed_size(
if (mbminlen == mbmaxlen) { if (mbminlen == mbmaxlen) {
return(dtype_get_len(type)); return(dtype_get_len(type));
} }
#endif /* !UNIV_HOTBACKUP */
} }
/* fall through for variable-length charsets */ /* fall through for variable-length charsets */
case DATA_VARCHAR: case DATA_VARCHAR:
...@@ -476,7 +504,6 @@ dtype_get_min_size( ...@@ -476,7 +504,6 @@ dtype_get_min_size(
return(0); return(0);
} }
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************** /***************************************************************************
Returns a stored SQL NULL size for a type. For fixed length types it is Returns a stored SQL NULL size for a type. For fixed length types it is
......
...@@ -42,7 +42,7 @@ Created 5/24/1996 Heikki Tuuri ...@@ -42,7 +42,7 @@ Created 5/24/1996 Heikki Tuuri
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint #define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */ to a table failed */
#define DB_CORRUPTION 39 /* data structure corruption noticed */ #define DB_CORRUPTION 39 /* data structure corruption noticed */
#define DB_COL_APPEARS_TWICE_IN_INDEX 40 /* InnoDB cannot handle an index #define DB_COL_APPEARS_TWICE_IN_INDEX 40/* InnoDB cannot handle an index
where same column appears twice */ where same column appears twice */
#define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint #define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint
from a table failed */ from a table failed */
......
...@@ -50,7 +50,9 @@ dict_sys_read_row_id( ...@@ -50,7 +50,9 @@ dict_sys_read_row_id(
/* out: row id */ /* out: row id */
byte* field) /* in: record field */ byte* field) /* in: record field */
{ {
ut_ad(DATA_ROW_ID_LEN == 6); #if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
#endif
return(mach_read_from_6(field)); return(mach_read_from_6(field));
} }
...@@ -64,7 +66,9 @@ dict_sys_write_row_id( ...@@ -64,7 +66,9 @@ dict_sys_write_row_id(
byte* field, /* in: record field */ byte* field, /* in: record field */
dulint row_id) /* in: row id */ dulint row_id) /* in: row id */
{ {
ut_ad(DATA_ROW_ID_LEN == 6); #if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
#endif
mach_write_to_6(field, row_id); mach_write_to_6(field, row_id);
} }
......
...@@ -26,6 +26,7 @@ Created 1/8/1996 Heikki Tuuri ...@@ -26,6 +26,7 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include "trx0types.h" #include "trx0types.h"
#ifndef UNIV_HOTBACKUP
/********************************************************************** /**********************************************************************
Makes all characters in a NUL-terminated UTF-8 string lower case. */ Makes all characters in a NUL-terminated UTF-8 string lower case. */
...@@ -33,6 +34,7 @@ void ...@@ -33,6 +34,7 @@ void
dict_casedn_str( dict_casedn_str(
/*============*/ /*============*/
char* a); /* in/out: string to put in lower case */ char* a); /* in/out: string to put in lower case */
#endif /* !UNIV_HOTBACKUP */
/************************************************************************ /************************************************************************
Get the database name length in a table name. */ Get the database name length in a table name. */
...@@ -197,7 +199,8 @@ dict_foreign_add_to_cache( ...@@ -197,7 +199,8 @@ dict_foreign_add_to_cache(
/*======================*/ /*======================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
dict_foreign_t* foreign, /* in, own: foreign key constraint */ dict_foreign_t* foreign, /* in, own: foreign key constraint */
ibool check_types); /* in: TRUE=check type compatibility */ ibool check_charsets);/* in: TRUE=check charset
compatibility */
/************************************************************************* /*************************************************************************
Checks if a table is referenced by foreign keys. */ Checks if a table is referenced by foreign keys. */
...@@ -305,7 +308,7 @@ Checks if a table is in the dictionary cache. */ ...@@ -305,7 +308,7 @@ Checks if a table is in the dictionary cache. */
UNIV_INLINE UNIV_INLINE
dict_table_t* dict_table_t*
dict_table_check_if_in_cache_low( dict_table_check_if_in_cache_low(
/*==============================*/ /*=============================*/
/* out: table, NULL if not found */ /* out: table, NULL if not found */
const char* table_name); /* in: table name */ const char* table_name); /* in: table name */
/************************************************************************** /**************************************************************************
...@@ -484,6 +487,15 @@ dict_table_get_sys_col_no( ...@@ -484,6 +487,15 @@ dict_table_get_sys_col_no(
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
ulint sys); /* in: DATA_ROW_ID, ... */ ulint sys); /* in: DATA_ROW_ID, ... */
/************************************************************************ /************************************************************************
Check whether the table uses the compact page format. */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
/* out: TRUE if table uses the
compact page format */
const dict_table_t* table); /* in: table */
/************************************************************************
Checks if a column is in the ordering columns of the clustered index of a Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns. */ table. Column prefixes are treated like whole columns. */
...@@ -659,7 +671,6 @@ dict_index_add_col( ...@@ -659,7 +671,6 @@ dict_index_add_col(
/*===============*/ /*===============*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
dict_col_t* col, /* in: column */ dict_col_t* col, /* in: column */
ulint order, /* in: order criterion */
ulint prefix_len); /* in: column prefix length */ ulint prefix_len); /* in: column prefix length */
/*********************************************************************** /***********************************************************************
Copies types of fields contained in index to tuple. */ Copies types of fields contained in index to tuple. */
...@@ -679,13 +690,6 @@ dict_index_get_tree( ...@@ -679,13 +690,6 @@ dict_index_get_tree(
/* out: index tree */ /* out: index tree */
dict_index_t* index); /* in: index */ dict_index_t* index); /* in: index */
/************************************************************************* /*************************************************************************
Gets the field order criterion. */
UNIV_INLINE
ulint
dict_field_get_order(
/*=================*/
dict_field_t* field);
/*************************************************************************
Gets the field column. */ Gets the field column. */
UNIV_INLINE UNIV_INLINE
dict_col_t* dict_col_t*
......
...@@ -189,6 +189,25 @@ dict_table_get_sys_col_no( ...@@ -189,6 +189,25 @@ dict_table_get_sys_col_no(
return(table->n_cols - DATA_N_SYS_COLS + sys); return(table->n_cols - DATA_N_SYS_COLS + sys);
} }
/************************************************************************
Check whether the table uses the compact page format. */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
/* out: TRUE if table uses the
compact page format */
const dict_table_t* table) /* in: table */
{
ut_ad(table);
#if DICT_TF_COMPACT != TRUE
#error
#endif
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
}
/************************************************************************ /************************************************************************
Gets the number of fields in the internal representation of an index, Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system. */ including fields added by the dictionary system. */
...@@ -326,19 +345,6 @@ dict_index_get_tree( ...@@ -326,19 +345,6 @@ dict_index_get_tree(
return(index->tree); return(index->tree);
} }
/*************************************************************************
Gets the field order criterion. */
UNIV_INLINE
ulint
dict_field_get_order(
/*=================*/
dict_field_t* field)
{
ut_ad(field);
return(field->order);
}
/************************************************************************* /*************************************************************************
Gets the field column. */ Gets the field column. */
UNIV_INLINE UNIV_INLINE
...@@ -494,7 +500,7 @@ Checks if a table is in the dictionary cache. */ ...@@ -494,7 +500,7 @@ Checks if a table is in the dictionary cache. */
UNIV_INLINE UNIV_INLINE
dict_table_t* dict_table_t*
dict_table_check_if_in_cache_low( dict_table_check_if_in_cache_low(
/*==============================*/ /*=============================*/
/* out: table, NULL if not found */ /* out: table, NULL if not found */
const char* table_name) /* in: table name */ const char* table_name) /* in: table name */
{ {
......
...@@ -82,7 +82,8 @@ dict_load_foreigns( ...@@ -82,7 +82,8 @@ dict_load_foreigns(
/*===============*/ /*===============*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
const char* table_name, /* in: table name */ const char* table_name, /* in: table name */
ibool check_types); /* in: TRUE=check type compatibility */ ibool check_charsets);/* in: TRUE=check charsets
compatibility */
/************************************************************************ /************************************************************************
Prints to the standard output information on all tables found in the data Prints to the standard output information on all tables found in the data
dictionary system table. */ dictionary system table. */
......
...@@ -33,15 +33,15 @@ combination of types */ ...@@ -33,15 +33,15 @@ combination of types */
other index */ other index */
#define DICT_IBUF 8 /* insert buffer tree */ #define DICT_IBUF 8 /* insert buffer tree */
/* Flags for ordering an index field: OR'ing of the flags allowed */
#define DICT_DESCEND 1 /* in descending order (default ascending) */
/* Types for a table object */ /* Types for a table object */
#define DICT_TABLE_ORDINARY 1 #define DICT_TABLE_ORDINARY 1
#define DICT_TABLE_CLUSTER_MEMBER 2 #define DICT_TABLE_CLUSTER_MEMBER 2
#define DICT_TABLE_CLUSTER 3 /* this means that the table is #define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */ really a cluster definition */
/* Table flags */
#define DICT_TF_COMPACT 1 /* compact page format */
/************************************************************************** /**************************************************************************
Creates a table memory object. */ Creates a table memory object. */
...@@ -55,7 +55,7 @@ dict_mem_table_create( ...@@ -55,7 +55,7 @@ dict_mem_table_create(
is ignored if the table is made is ignored if the table is made
a member of a cluster */ a member of a cluster */
ulint n_cols, /* in: number of columns */ ulint n_cols, /* in: number of columns */
ibool comp); /* in: TRUE=compact page format */ ulint flags); /* in: table flags */
/************************************************************************** /**************************************************************************
Creates a cluster memory object. */ Creates a cluster memory object. */
...@@ -116,8 +116,6 @@ dict_mem_index_add_field( ...@@ -116,8 +116,6 @@ dict_mem_index_add_field(
/*=====================*/ /*=====================*/
dict_index_t* index, /* in: index */ dict_index_t* index, /* in: index */
const char* name, /* in: column name */ const char* name, /* in: column name */
ulint order, /* in: order criterion; 0 means an
ascending order */
ulint prefix_len); /* in: 0 or the column prefix length ulint prefix_len); /* in: 0 or the column prefix length
in a MySQL index like in a MySQL index like
INDEX (textcol(25)) */ INDEX (textcol(25)) */
...@@ -163,8 +161,6 @@ UTF-8 charset. In that charset, a character may take at most 3 bytes. */ ...@@ -163,8 +161,6 @@ UTF-8 charset. In that charset, a character may take at most 3 bytes. */
struct dict_field_struct{ struct dict_field_struct{
dict_col_t* col; /* pointer to the table column */ dict_col_t* col; /* pointer to the table column */
const char* name; /* name of the column */ const char* name; /* name of the column */
ulint order; /* flags for ordering this field:
DICT_DESCEND, ... */
ulint prefix_len; /* 0 or the length of the column ulint prefix_len; /* 0 or the length of the column
prefix in bytes in a MySQL index of prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25)); type, e.g., INDEX (textcol(25));
...@@ -175,10 +171,6 @@ struct dict_field_struct{ ...@@ -175,10 +171,6 @@ struct dict_field_struct{
ulint fixed_len; /* 0 or the fixed length of the ulint fixed_len; /* 0 or the fixed length of the
column if smaller than column if smaller than
DICT_MAX_INDEX_COL_LEN */ DICT_MAX_INDEX_COL_LEN */
ulint fixed_offs; /* offset to the field, or
ULINT_UNDEFINED if it is not fixed
within the record (due to preceding
variable-length fields) */
}; };
/* Data structure for an index tree */ /* Data structure for an index tree */
...@@ -311,6 +303,7 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ ...@@ -311,6 +303,7 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */
struct dict_table_struct{ struct dict_table_struct{
dulint id; /* id of the table or cluster */ dulint id; /* id of the table or cluster */
ulint type; /* DICT_TABLE_ORDINARY, ... */ ulint type; /* DICT_TABLE_ORDINARY, ... */
ulint flags; /* DICT_TF_COMPACT, ... */
mem_heap_t* heap; /* memory heap */ mem_heap_t* heap; /* memory heap */
const char* name; /* table name */ const char* name; /* table name */
const char* dir_path_of_temp_table;/* NULL or the directory path const char* dir_path_of_temp_table;/* NULL or the directory path
...@@ -328,7 +321,6 @@ struct dict_table_struct{ ...@@ -328,7 +321,6 @@ struct dict_table_struct{
ibool tablespace_discarded;/* this flag is set TRUE when the ibool tablespace_discarded;/* this flag is set TRUE when the
user calls DISCARD TABLESPACE on this table, user calls DISCARD TABLESPACE on this table,
and reset to FALSE in IMPORT TABLESPACE */ and reset to FALSE in IMPORT TABLESPACE */
ibool comp; /* flag: TRUE=compact page format */
hash_node_t name_hash; /* hash chain node */ hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */ hash_node_t id_hash; /* hash chain node */
ulint n_def; /* number of columns defined so far */ ulint n_def; /* number of columns defined so far */
......
...@@ -106,7 +106,9 @@ dyn_array_create( ...@@ -106,7 +106,9 @@ dyn_array_create(
size sizeof(dyn_array_t) */ size sizeof(dyn_array_t) */
{ {
ut_ad(arr); ut_ad(arr);
ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG); #if DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG
# error "DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG"
#endif
arr->heap = NULL; arr->heap = NULL;
arr->used = 0; arr->used = 0;
......
...@@ -77,7 +77,7 @@ Gets a iboolean value from a query node. */ ...@@ -77,7 +77,7 @@ Gets a iboolean value from a query node. */
UNIV_INLINE UNIV_INLINE
ibool ibool
eval_node_get_ibool_val( eval_node_get_ibool_val(
/*===================*/ /*====================*/
/* out: iboolean value */ /* out: iboolean value */
que_node_t* node); /* in: query graph node */ que_node_t* node); /* in: query graph node */
/********************************************************************* /*********************************************************************
......
...@@ -149,7 +149,7 @@ Gets a iboolean value from a query node. */ ...@@ -149,7 +149,7 @@ Gets a iboolean value from a query node. */
UNIV_INLINE UNIV_INLINE
ibool ibool
eval_node_get_ibool_val( eval_node_get_ibool_val(
/*===================*/ /*====================*/
/* out: iboolean value */ /* out: iboolean value */
que_node_t* node) /* in: query graph node */ que_node_t* node) /* in: query graph node */
{ {
...@@ -170,7 +170,7 @@ Sets a iboolean value as the value of a function node. */ ...@@ -170,7 +170,7 @@ Sets a iboolean value as the value of a function node. */
UNIV_INLINE UNIV_INLINE
void void
eval_node_set_ibool_val( eval_node_set_ibool_val(
/*===================*/ /*====================*/
func_node_t* func_node, /* in: function node */ func_node_t* func_node, /* in: function node */
ibool val) /* in: value to set */ ibool val) /* in: value to set */
{ {
......
...@@ -63,7 +63,20 @@ extern fil_addr_t fil_addr_null; ...@@ -63,7 +63,20 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_LSN 16 /* lsn of the end of the newest #define FIL_PAGE_LSN 16 /* lsn of the end of the newest
modification log record to the page */ modification log record to the page */
#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,..., #define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,...,
2 bytes */ 2 bytes.
The contents of this field can only
be trusted in the following case:
if the page is an uncompressed
B-tree index page, then it is
guaranteed that the value is
FIL_PAGE_INDEX.
The opposite does not hold.
In tablespaces created by
MySQL/InnoDB 5.1.7 or later, the
contents of this field is valid
for all uncompressed pages. */
#define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the #define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the
first page in a data file: the file first page in a data file: the file
has been flushed to disk at least up has been flushed to disk at least up
...@@ -79,11 +92,19 @@ extern fil_addr_t fil_addr_null; ...@@ -79,11 +92,19 @@ extern fil_addr_t fil_addr_null;
to the last 4 bytes of FIL_PAGE_LSN */ to the last 4 bytes of FIL_PAGE_LSN */
#define FIL_PAGE_DATA_END 8 #define FIL_PAGE_DATA_END 8
/* File page types */ /* File page types (values of FIL_PAGE_TYPE) */
#define FIL_PAGE_INDEX 17855 #define FIL_PAGE_INDEX 17855 /* B-tree node */
#define FIL_PAGE_UNDO_LOG 2 #define FIL_PAGE_UNDO_LOG 2 /* Undo log page */
#define FIL_PAGE_INODE 3 #define FIL_PAGE_INODE 3 /* Index node */
#define FIL_PAGE_IBUF_FREE_LIST 4 #define FIL_PAGE_IBUF_FREE_LIST 4 /* Insert buffer free list */
/* File page types introduced in MySQL/InnoDB 5.1.7 */
#define FIL_PAGE_TYPE_ALLOCATED 0 /* Freshly allocated page */
#define FIL_PAGE_IBUF_BITMAP 5 /* Insert buffer bitmap */
#define FIL_PAGE_TYPE_SYS 6 /* System page */
#define FIL_PAGE_TYPE_TRX_SYS 7 /* Transaction system data */
#define FIL_PAGE_TYPE_FSP_HDR 8 /* File space header */
#define FIL_PAGE_TYPE_XDES 9 /* Extent descriptor page */
#define FIL_PAGE_TYPE_BLOB 10 /* Uncompressed BLOB page */
/* Space types */ /* Space types */
#define FIL_TABLESPACE 501 #define FIL_TABLESPACE 501
...@@ -271,7 +292,7 @@ Decrements the count of pending insert buffer page merges. */ ...@@ -271,7 +292,7 @@ Decrements the count of pending insert buffer page merges. */
void void
fil_decr_pending_ibuf_merges( fil_decr_pending_ibuf_merges(
/*========================*/ /*=========================*/
ulint id); /* in: space id */ ulint id); /* in: space id */
/*********************************************************************** /***********************************************************************
Parses the body of a log record written about an .ibd file operation. That is, Parses the body of a log record written about an .ibd file operation. That is,
......
...@@ -99,13 +99,15 @@ ha_remove_all_nodes_to_page( ...@@ -99,13 +99,15 @@ ha_remove_all_nodes_to_page(
ulint fold, /* in: fold value */ ulint fold, /* in: fold value */
page_t* page); /* in: buffer page */ page_t* page); /* in: buffer page */
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table); /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index); /* in: end index */
/***************************************************************** /*****************************************************************
Prints info of a hash table. */ Prints info of a hash table. */
......
...@@ -109,8 +109,8 @@ do {\ ...@@ -109,8 +109,8 @@ do {\
\ \
while (struct3333->NAME != DATA) {\ while (struct3333->NAME != DATA) {\
\ \
ut_a(struct3333);\
struct3333 = struct3333->NAME;\ struct3333 = struct3333->NAME;\
ut_a(struct3333);\
}\ }\
\ \
struct3333->NAME = DATA->NAME;\ struct3333->NAME = DATA->NAME;\
......
...@@ -206,8 +206,9 @@ ibuf_update_free_bits_if_full( ...@@ -206,8 +206,9 @@ ibuf_update_free_bits_if_full(
before = ibuf_index_page_calc_free_bits(max_ins_size); before = ibuf_index_page_calc_free_bits(max_ins_size);
if (max_ins_size >= increase) { if (max_ins_size >= increase) {
ut_ad(ULINT_UNDEFINED > UNIV_PAGE_SIZE); #if ULINT32_UNDEFINED <= UNIV_PAGE_SIZE
# error "ULINT32_UNDEFINED <= UNIV_PAGE_SIZE"
#endif
after = ibuf_index_page_calc_free_bits(max_ins_size after = ibuf_index_page_calc_free_bits(max_ins_size
- increase); - increase);
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
......
...@@ -477,7 +477,7 @@ searching for a lock in the hash table. */ ...@@ -477,7 +477,7 @@ searching for a lock in the hash table. */
UNIV_INLINE UNIV_INLINE
ulint ulint
lock_rec_fold( lock_rec_fold(
/*===========*/ /*==========*/
/* out: folded value */ /* out: folded value */
ulint space, /* in: space */ ulint space, /* in: space */
ulint page_no);/* in: page number */ ulint page_no);/* in: page number */
......
...@@ -281,7 +281,7 @@ Reads a float. It is stored in a little-endian format. */ ...@@ -281,7 +281,7 @@ Reads a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
float float
mach_float_read( mach_float_read(
/*=============*/ /*============*/
/* out: float read */ /* out: float read */
byte* b); /* in: pointer to memory from where to read */ byte* b); /* in: pointer to memory from where to read */
/************************************************************* /*************************************************************
...@@ -289,7 +289,7 @@ Writes a float. It is stored in a little-endian format. */ ...@@ -289,7 +289,7 @@ Writes a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
void void
mach_float_write( mach_float_write(
/*==============*/ /*=============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
float d); /* in: float */ float d); /* in: float */
/************************************************************* /*************************************************************
......
...@@ -578,7 +578,7 @@ Reads a float. It is stored in a little-endian format. */ ...@@ -578,7 +578,7 @@ Reads a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
float float
mach_float_read( mach_float_read(
/*=============*/ /*============*/
/* out: float read */ /* out: float read */
byte* b) /* in: pointer to memory from where to read */ byte* b) /* in: pointer to memory from where to read */
{ {
...@@ -604,7 +604,7 @@ Writes a float. It is stored in a little-endian format. */ ...@@ -604,7 +604,7 @@ Writes a float. It is stored in a little-endian format. */
UNIV_INLINE UNIV_INLINE
void void
mach_float_write( mach_float_write(
/*==============*/ /*=============*/
byte* b, /* in: pointer to memory where to write */ byte* b, /* in: pointer to memory where to write */
float d) /* in: float */ float d) /* in: float */
{ {
......
...@@ -25,8 +25,7 @@ UNIV_MEM_ALIGNMENT. In the debug version there are also ...@@ -25,8 +25,7 @@ UNIV_MEM_ALIGNMENT. In the debug version there are also
check fields at the both ends of the field. */ check fields at the both ends of the field. */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
#define MEM_SPACE_NEEDED(N) ut_calc_align((N) + MEM_FIELD_HEADER_SIZE\ #define MEM_SPACE_NEEDED(N) ut_calc_align((N) + MEM_FIELD_HEADER_SIZE\
+ MEM_FIELD_TRAILER_SIZE,\ + MEM_FIELD_TRAILER_SIZE, UNIV_MEM_ALIGNMENT)
UNIV_MEM_ALIGNMENT)
#else #else
#define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT)
#endif #endif
...@@ -115,7 +114,7 @@ the neighborhood of a given pointer. */ ...@@ -115,7 +114,7 @@ the neighborhood of a given pointer. */
void void
mem_analyze_corruption( mem_analyze_corruption(
/*===================*/ /*===================*/
byte* ptr); /* in: pointer to place of possible corruption */ void* ptr); /* in: pointer to place of possible corruption */
/********************************************************************* /*********************************************************************
Prints information of dynamic memory usage and currently allocated memory Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */ heaps or buffers. Can only be used in the debug version. */
......
...@@ -68,22 +68,19 @@ Use this macro instead of the corresponding function! Macro for memory ...@@ -68,22 +68,19 @@ Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create(N) mem_heap_create_func(\ #define mem_heap_create(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_DYNAMIC,\ (N), NULL, MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\ #define mem_heap_create_in_buffer(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BUFFER,\ (N), NULL, MEM_HEAP_BUFFER, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
heap creation. */ heap creation. */
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(\ #define mem_heap_create_in_btr_search(N) mem_heap_create_func(\
(N), NULL, MEM_HEAP_BTR_SEARCH |\ (N), NULL, MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
MEM_HEAP_BUFFER,\
__FILE__, __LINE__) __FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for fast Use this macro instead of the corresponding function! Macro for fast
...@@ -92,8 +89,7 @@ caller, N is its size, and this memory block is not freed by ...@@ -92,8 +89,7 @@ caller, N is its size, and this memory block is not freed by
mem_heap_free. See the parameter comment in mem_heap_create_func below. */ mem_heap_free. See the parameter comment in mem_heap_create_func below. */
#define mem_heap_fast_create(N, B) mem_heap_create_func(\ #define mem_heap_fast_create(N, B) mem_heap_create_func(\
(N), (B), MEM_HEAP_DYNAMIC,\ (N), (B), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
__FILE__, __LINE__)
/****************************************************************** /******************************************************************
Use this macro instead of the corresponding function! Macro for memory Use this macro instead of the corresponding function! Macro for memory
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -80,7 +80,7 @@ os_thread_create( ...@@ -80,7 +80,7 @@ os_thread_create(
thread */ thread */
int int
os_thread_join( os_thread_join(
/*=============*/ /*===========*/
os_thread_id_t thread_id); /* in: id of the thread to join */ os_thread_id_t thread_id); /* in: id of the thread to join */
/********************************************************************* /*********************************************************************
Exits the current thread. */ Exits the current thread. */
......
This diff is collapsed.
...@@ -284,7 +284,7 @@ TRUE if the record is the infimum record on a page. */ ...@@ -284,7 +284,7 @@ TRUE if the record is the infimum record on a page. */
UNIV_INLINE UNIV_INLINE
ibool ibool
page_rec_is_infimum_low( page_rec_is_infimum_low(
/*=====================*/ /*====================*/
/* out: TRUE if the infimum record */ /* out: TRUE if the infimum record */
ulint offset) /* in: record offset on page */ ulint offset) /* in: record offset on page */
{ {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment