mirror of
https://github.com/MariaDB/server.git
synced 2026-05-10 17:14:30 +02:00
1.0.2 version imported
This commit is contained in:
parent
84f733afa7
commit
2ed4d6349d
132 changed files with 7847 additions and 2648 deletions
|
|
@ -17,6 +17,14 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
|||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
|
||||
ADD_DEFINITIONS(-DMYSQL_SERVER -D_WIN32 -D_LIB)
|
||||
|
||||
# Bug 19424 - InnoDB: Possibly a memory overrun of the buffer being freed (64-bit Visual C)
|
||||
# Removing Win64 compiler optimizations for all innodb/mem/* files.
|
||||
IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/storage/innobase/mem/mem0mem.c
|
||||
${CMAKE_SOURCE_DIR}/storage/innobase/mem/mem0pool.c
|
||||
PROPERTIES COMPILE_FLAGS -Od)
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
|
||||
${CMAKE_SOURCE_DIR}/storage/innobase/include
|
||||
${CMAKE_SOURCE_DIR}/storage/innobase/handler
|
||||
|
|
@ -61,4 +69,28 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
|||
IF(NOT SOURCE_SUBLIBS)
|
||||
ADD_LIBRARY(innobase ${INNOBASE_SOURCES})
|
||||
ADD_DEPENDENCIES(innobase GenError)
|
||||
|
||||
IF(INNODB_DYNAMIC_PLUGIN)
|
||||
# The dynamic plugin requires CMake 2.6.0 or later. Otherwise, the /DELAYLOAD property
|
||||
# will not be set
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
|
||||
ADD_LIBRARY(ha_innodb SHARED ${INNOBASE_SOURCES} ha_innodb.def handler/win_delay_loader.cc)
|
||||
ADD_DEPENDENCIES(ha_innodb GenError mysqld)
|
||||
# If build type is not specified as Release, default to Debug
|
||||
# This is a workaround to a problem in CMake 2.6, which does not
|
||||
# set the path of mysqld.lib correctly
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
ELSE(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
SET(CMAKE_BUILD_TYPE "Debug")
|
||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
TARGET_LINK_LIBRARIES(ha_innodb strings zlib)
|
||||
TARGET_LINK_LIBRARIES(ha_innodb ${CMAKE_SOURCE_DIR}/sql/${CMAKE_BUILD_TYPE}/mysqld.lib)
|
||||
SET_TARGET_PROPERTIES(ha_innodb PROPERTIES OUTPUT_NAME ha_innodb)
|
||||
SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/MAP /MAPINFO:EXPORTS")
|
||||
SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/ENTRY:\"_DllMainCRTStartup@12\"")
|
||||
SET_TARGET_PROPERTIES(ha_innodb PROPERTIES COMPILE_FLAGS "-DMYSQL_DYNAMIC_PLUGIN")
|
||||
SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/DELAYLOAD:mysqld.exe")
|
||||
ENDIF(INNODB_DYNAMIC_PLUGIN)
|
||||
|
||||
ENDIF(NOT SOURCE_SUBLIBS)
|
||||
|
|
|
|||
418
ChangeLog
418
ChangeLog
|
|
@ -1,3 +1,421 @@
|
|||
2008-10-31 The InnoDB Team
|
||||
|
||||
* dict/dict0mem.c, include/dict0mem.h, include/lock0lock.h,
|
||||
include/row0mysql.h, include/trx0trx.h, include/univ.i,
|
||||
include/ut0vec.h, include/ut0vec.ic, lock/lock0lock.c,
|
||||
row/row0mysql.c, trx/trx0trx.c:
|
||||
Fix Bug#26316 Triggers create duplicate entries on auto-increment
|
||||
columns
|
||||
|
||||
2008-10-30 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/handler0vars.h,
|
||||
handler/win_delay_loader.cc, mysql-test/innodb_bug40360.result,
|
||||
mysql-test/innodb_bug40360.test:
|
||||
Fix Bug#40360 Binlog related errors with binlog off
|
||||
|
||||
2008-10-29 The InnoDB Team
|
||||
|
||||
* include/data0type.ic:
|
||||
Fix Bug#40369 dtype_get_sql_null_size() returns 0 or 1, not the size
|
||||
|
||||
2008-10-29 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/srv0srv.h, srv/srv0srv.c:
|
||||
Fix Bug#38189 innodb_stats_on_metadata missing
|
||||
|
||||
2008-10-28 The InnoDB Team
|
||||
|
||||
* CMakeLists.txt, ha_innodb.def, handler/ha_innodb.cc,
|
||||
handler/handler0alter.cc, handler/handler0vars.h, handler/i_s.cc,
|
||||
handler/win_delay_loader.cc, win-plugin/*:
|
||||
Implemented the delayloading of externals for the plugin on Windows.
|
||||
This makes it possible to build a dynamic plugin (ha_innodb.dll) on
|
||||
Windows.
|
||||
|
||||
2008-10-27 The InnoDB Team
|
||||
|
||||
* CMakeLists.txt:
|
||||
Fix Bug#19424 InnoDB: Possibly a memory overrun of the buffer being
|
||||
freed (64-bit Visual C)
|
||||
|
||||
2008-10-23 The InnoDB Team
|
||||
|
||||
* ibuf/ibuf0ibuf.c:
|
||||
ibuf_delete_rec(): When the cursor to the insert buffer record
|
||||
cannot be restored, do not complain if the tablespace does not
|
||||
exist, because the insert buffer record may have been discarded by
|
||||
some other thread. This bug has existed in MySQL/InnoDB since
|
||||
version 4.1, when innodb_file_per_table was implemented.
|
||||
This may fix Bug#27276 InnoDB Error: ibuf cursor restoration fails.
|
||||
|
||||
2008-10-22 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, dict/dict0mem.c, handler/ha_innodb.cc,
|
||||
handler/ha_innodb.h, include/dict0dict.h, include/dict0mem.h,
|
||||
row/row0mysql.c:
|
||||
Fix Bug#39830 Table autoinc value not updated on first insert
|
||||
Fix Bug#35498 Cannot get table test/table1 auto-inccounter value in
|
||||
::info
|
||||
Fix Bug#36411 "Failed to read auto-increment value from storage
|
||||
engine" in 5.1.24 auto-inc
|
||||
|
||||
2008-10-22 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
|
||||
Fix Bug#40224 New AUTOINC changes mask reporting of deadlock/timeout
|
||||
errors
|
||||
|
||||
2008-10-16 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, mysql-test/innodb-index.result,
|
||||
mysql-test/innodb-index.test:
|
||||
Skip the undo log size check when creating REDUNDANT and COMPACT
|
||||
tables. In ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED, column
|
||||
prefix indexes require that prefixes of externally stored columns
|
||||
be written to the undo log. This may make the undo log record
|
||||
bigger than the record on the B-tree page. The maximum size of an
|
||||
undo log record is the page size. That must be checked for, in
|
||||
dict_index_add_to_cache(). However, this restriction must not
|
||||
be enforced on REDUNDANT or COMPACT tables.
|
||||
|
||||
2008-10-15 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, include/btr0cur.h, row/row0ext.c, row/row0sel.c,
|
||||
row/row0upd.c:
|
||||
When the server crashes while freeing an externally stored column
|
||||
of a compressed table, the BTR_EXTERN_LEN field in the BLOB
|
||||
pointer will be written as 0. Tolerate this in the functions that
|
||||
deal with externally stored columns. This fixes problems after
|
||||
crash recovery, in the rollback of incomplete transactions, and in
|
||||
the purge of delete-marked records.
|
||||
|
||||
2008-10-15 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, include/page0zip.h, page/page0zip.c, include/univ.i:
|
||||
When a B-tree node of a compressed table is split or merged, the
|
||||
compression may fail. In this case, the entire compressed page
|
||||
will be copied and the excess records will be deleted. However,
|
||||
page_zip_copy(), now renamed to page_zip_copy_recs(), copied too
|
||||
many fields in the page header, overwriting PAGE_BTR_SEG_LEAF and
|
||||
PAGE_BTR_SEG_TOP when splitting the B-tree root. This caused
|
||||
corruption of compressed tables. Furthermore, the lock table and
|
||||
the adaptive hash index would be corrupted, because we forgot to
|
||||
update them when invoking page_zip_copy_recs().
|
||||
|
||||
Introduce the symbol UNIV_ZIP_DEBUG for triggering the copying of
|
||||
compressed pages more often, for debugging purposes.
|
||||
|
||||
2008-10-10 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc, include/row0merge.h, row/row0merge.c,
|
||||
row/row0mysql.c:
|
||||
Fix some locking issues, mainly in fast index creation. The
|
||||
InnoDB data dictionary cache should be latched whenever a
|
||||
transaction is holding locks on any data dictionary tables.
|
||||
Otherwise, lock waits or deadlocks could occur. Furthermore, the
|
||||
data dictionary transaction must be committed (and the locks
|
||||
released) before the data dictionary latch is released.
|
||||
|
||||
ha_innobase::add_index(): Lock the data dictionary before renaming
|
||||
or dropping the created indexes, because neither operation will
|
||||
commit the data dictionary transaction.
|
||||
|
||||
ha_innobase::final_drop_index(): Commit the transactions before
|
||||
unlocking the data dictionary.
|
||||
|
||||
2008-10-09 The InnoDB Team
|
||||
|
||||
* buf/buf0lru.c:
|
||||
Fix Bug#39939 DROP TABLE/DISCARD TABLESPACE takes long time in
|
||||
buf_LRU_invalidate_tablespace()
|
||||
|
||||
2008-10-08 The InnoDB Team
|
||||
|
||||
* dict/dict0crea.c, trx/trx0roll.c, include/row0mysql.h,
|
||||
row/row0merge.c, row/row0mysql.c:
|
||||
When dropping a table, hold the data dictionary latch until the
|
||||
transaction has been committed. The data dictionary latch is
|
||||
supposed to prevent lock waits and deadlocks in the data
|
||||
dictionary tables. Due to this bug, DROP TABLE could cause a
|
||||
deadlock or hang. Note that because of Bug#33650 and Bug#39833,
|
||||
MySQL may also drop a (temporary) table when executing CREATE INDEX
|
||||
or ALTER TABLE ... ADD INDEX.
|
||||
|
||||
2008-10-04 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb_bug39438-master.opt,
|
||||
mysql-test/innodb_bug39438.result, mysql-test/innodb_bug39438.test:
|
||||
Fix Bug#39438 Testcase for Bug#39436 crashes on 5.1 in
|
||||
fil_space_get_latch
|
||||
|
||||
2008-10-04 The InnoDB Team
|
||||
|
||||
* include/lock0lock.h, lock/lock0lock.c,
|
||||
mysql-test/innodb_bug38231.result, mysql-test/innodb_bug38231.test,
|
||||
row/row0mysql.c:
|
||||
Fix Bug#38231 Innodb crash in lock_reset_all_on_table() on TRUNCATE +
|
||||
LOCK / UNLOCK
|
||||
|
||||
2008-10-04 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#35498 Cannot get table test/table1 auto-inccounter value in
|
||||
::info
|
||||
|
||||
2008-10-04 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/ha_innodb.h:
|
||||
Fix Bug#37788 InnoDB Plugin: AUTO_INCREMENT wrong for compressed
|
||||
tables
|
||||
|
||||
2008-10-04 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, handler/ha_innodb.cc, handler/ha_innodb.h,
|
||||
include/dict0dict.h, include/dict0mem.h, row/row0mysql.c:
|
||||
Fix Bug#39830 Table autoinc value not updated on first insert
|
||||
|
||||
2008-10-03 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-index.test, mysql-test/innodb-index.result,
|
||||
mysql-test/innodb-timeout.test, mysql-test/innodb-timeout.result,
|
||||
srv/srv0srv.c, include/srv0srv.h, handler/ha_innodb.cc,
|
||||
include/ha_prototypes.h:
|
||||
Fix Bug#36285 innodb_lock_wait_timeout is not dynamic, not per session
|
||||
|
||||
2008-09-19 The InnoDB Team
|
||||
|
||||
* os/os0proc.c:
|
||||
Fix a memory leak on Windows. The memory leak was due to wrong
|
||||
parameters passed into VirtualFree() call. As the result, the
|
||||
call fails with Windows error 87.
|
||||
|
||||
2008-09-17 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result, mysql-test/innodb-zip.result,
|
||||
mysql-test/innodb-zip.test, mysql-test/innodb.test, ibuf/ibuf0ibuf.c,
|
||||
dict/dict0crea.c, dict/dict0load.c, dict/dict0boot.c,
|
||||
include/dict0dict.h, include/trx0trx.h, dict/dict0dict.c,
|
||||
trx/trx0trx.c, include/ha_prototypes.h, handler/ha_innodb.cc:
|
||||
When creating an index in innodb_strict_mode, check that the
|
||||
maximum record size will never exceed the B-tree page size limit.
|
||||
For uncompressed tables, there should always be enough space for
|
||||
two records in an empty B-tree page. For compressed tables, there
|
||||
should be enough space for storing two node pointer records or one
|
||||
data record in an empty page in uncompressed format.
|
||||
The purpose of this check is to guarantee that INSERT or UPDATE
|
||||
will never fail due to too big record size.
|
||||
|
||||
2008-09-17 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, data/data0data.c, include/page0zip.h,
|
||||
include/page0zip.ic, page/page0zip.c, mysql-test/innodb_bug36172.test:
|
||||
Prevent infinite B-tree page splits in compressed tables by
|
||||
ensuring that there will always be enough space for two node
|
||||
pointer records in an empty B-tree page. Also, require that at
|
||||
least one data record will fit in an empty compressed page. This
|
||||
will reduce the maximum size of records in compressed tables.
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result:
|
||||
Fix the failing innodb test by merging changes that MySQL made to
|
||||
that file (r2646.12.1 in MySQL BZR repository)
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc.test:
|
||||
Fix Bug#38839 auto increment does not work properly with InnoDB after
|
||||
update
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, handler/handler0alter.cc, include/dict0dict.h,
|
||||
mysql-test/innodb-index.result, mysql-test/innodb-index.test:
|
||||
Fix Bug#38786 InnoDB plugin crashes on drop table/create table with FK
|
||||
|
||||
2008-08-21 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/ha_prototypes.h, row/row0sel.c:
|
||||
Fix Bug#37885 row_search_for_mysql may gap lock unnecessarily with SQL
|
||||
comments in query
|
||||
|
||||
2008-08-21 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#38185 ha_innobase::info can hold locks even when called with
|
||||
HA_STATUS_NO_LOCK
|
||||
|
||||
2008-08-18 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.ic, include/univ.i:
|
||||
Introduce UNIV_LRU_DEBUG for debugging the LRU buffer pool cache
|
||||
|
||||
2008-08-08 The InnoDB Team
|
||||
|
||||
* buf/buf0lru.c, include/buf0buf.h:
|
||||
Fix two recovery bugs that could lead to a crash in debug builds with
|
||||
small buffer size
|
||||
|
||||
2008-08-07 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, handler/ha_innodb.cc, include/srv0srv.h,
|
||||
srv/srv0srv.c:
|
||||
Add a parameter innodb_stats_sample_pages to allow users to control
|
||||
the number of index dives when InnoDB estimates the cardinality of
|
||||
an index (ANALYZE TABLE, SHOW TABLE STATUS etc)
|
||||
|
||||
2008-08-07 The InnoDB Team
|
||||
|
||||
* trx/trx0i_s.c:
|
||||
Fix a bug that would lead to a crash if a SELECT was issued from the
|
||||
INFORMATION_SCHEMA tables and there are rolling back transactions at
|
||||
the same time
|
||||
|
||||
2008-08-06 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, btr/btr0cur.c, ibuf/ibuf0ibuf.c, include/btr0cur.h,
|
||||
include/trx0roll.h, include/trx0types.h, row/row0purge.c,
|
||||
row/row0uins.c, row/row0umod.c, trx/trx0roll.c:
|
||||
In the rollback of incomplete transactions after crash recovery,
|
||||
tolerate clustered index records whose externally stored columns
|
||||
have not been written.
|
||||
|
||||
2008-07-30 The InnoDB Team
|
||||
|
||||
* trx/trx0trx.c:
|
||||
Fixes a race in recovery where the recovery thread recovering a
|
||||
PREPARED trx and the background rollback thread can both try
|
||||
to free the trx after its status is set to COMMITTED_IN_MEMORY.
|
||||
|
||||
2008-07-29 The InnoDB Team
|
||||
|
||||
* include/trx0rec.h, row/row0purge.c, row/row0vers.c, trx/trx0rec.c:
|
||||
Fix a BLOB corruption bug
|
||||
|
||||
2008-07-15 The InnoDB Team
|
||||
|
||||
* btr/btr0sea.c, dict/dict0dict.c, include/btr0sea.h:
|
||||
Fixed a timing hole where a thread dropping an index can free the
|
||||
in-memory index struct while another thread is still using that
|
||||
structure to remove entries from adaptive hash index belonging
|
||||
to one of the pages that belongs to the index being dropped.
|
||||
|
||||
2008-07-04 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-index.result:
|
||||
Fix the failing innodb-index test by adjusting the result to a new
|
||||
MySQL behavior (the change occured in BZR-r2667)
|
||||
|
||||
2008-07-03 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
|
||||
Remove the negative test cases that produce warnings
|
||||
|
||||
2008-07-02 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-replace.result, mysql-test/innodb-index.test:
|
||||
Disable part of innodb-index test because MySQL changed its behavior
|
||||
and is not calling ::add_index() anymore when adding primary index on
|
||||
non-NULL column
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-replace.result, mysql-test/innodb-replace.test:
|
||||
Fix the failing innodb-replace test by merging changes that MySQL
|
||||
made to that file (r2659 in MySQL BZR repository)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* lock/lock0lock.c:
|
||||
Fix Bug#36942 Performance problem in lock_get_n_rec_locks (SHOW INNODB
|
||||
STATUS)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* ha/ha0ha.c:
|
||||
Fix Bug#36941 Performance problem in ha_print_info (SHOW INNODB
|
||||
STATUS)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc.test:
|
||||
Fix Bug#37531 After truncate, auto_increment behaves incorrectly for
|
||||
InnoDB
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Rewrite the function innodb_plugin_init() to support parameters in
|
||||
different order (in static and dynamic InnoDB) and to support more
|
||||
parameters in the static InnoDB
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc:
|
||||
Fix a bug in ::add_index() which set the transaction state to "active"
|
||||
but never restored it to the original value. This bug caused warnings
|
||||
to be printed by the rpl.rpl_ddl mysql-test.
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* mysql-test/patches:
|
||||
Add a directory which contains patches, which need to be applied to
|
||||
MySQL source in order to get some mysql-tests to succeed. The patches
|
||||
cannot be committed in MySQL repository because they are specific to
|
||||
the InnoDB plugin.
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test,
|
||||
row/row0row.c:
|
||||
Fix an anomaly when updating a record with BLOB prefix
|
||||
|
||||
2008-06-18 The InnoDB Team
|
||||
|
||||
* include/trx0sys.h, srv/srv0start.c, trx/trx0sys.c:
|
||||
Fix a bug in recovery which was a side effect of the file_format_check
|
||||
changes
|
||||
|
||||
2008-06-09 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result:
|
||||
Fix the failing innodb test by merging changes that MySQL made to that
|
||||
file
|
||||
|
||||
2008-06-06 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h,
|
||||
include/srv0srv.h, srv/srv0srv.c:
|
||||
Fix Bug#36600 SHOW STATUS takes a lot of CPU in
|
||||
buf_get_latched_pages_number
|
||||
|
||||
* handler/ha_innodb.cc, os/os0file.c:
|
||||
Fix Bug#11894 innodb_file_per_table crashes w/ Windows .sym symbolic
|
||||
link hack
|
||||
|
||||
* include/ut0ut.h, srv/srv0srv.c, ut/ut0ut.c:
|
||||
Fix Bug#36819 ut_usectime does not handle errors from gettimeofday
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#35602 Failed to read auto-increment value from storage engine
|
||||
|
||||
* srv/srv0start.c:
|
||||
Fix Bug#36149 Read buffer overflow in srv0start.c found during "make
|
||||
test"
|
||||
|
||||
2008-05-08 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, mysql-test/innodb_bug36172.result,
|
||||
mysql-test/innodb_bug36172.test:
|
||||
Fix Bug#36172 insert into compressed innodb table crashes
|
||||
|
||||
2008-05-08 The InnoDB Team
|
||||
|
||||
InnoDB Plugin 1.0.1 released
|
||||
|
||||
2008-05-06 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/srv0srv.h, include/sync0sync.h,
|
||||
|
|
|
|||
1469
Makefile.in
1469
Makefile.in
File diff suppressed because it is too large
Load diff
5
README
5
README
|
|
@ -1,4 +1,4 @@
|
|||
This is the source of the InnoDB Plugin 1.0.1 for MySQL 5.1
|
||||
This is the source of the InnoDB Plugin 1.0.2 for MySQL 5.1
|
||||
===========================================================
|
||||
|
||||
Instructions for compiling the plugin:
|
||||
|
|
@ -23,4 +23,7 @@ http://www.innodb.com/doc/innodb_plugin-1.0/innodb-plugin-installation.html
|
|||
For more information about InnoDB visit
|
||||
http://www.innodb.com
|
||||
|
||||
Please report any problems or issues with the plugin in the InnoDB Forums
|
||||
http://forums.innodb.com/ or in the MySQL Bugs database http://bugs.mysql.com
|
||||
|
||||
Thank you for using the InnoDB plugin!
|
||||
|
|
|
|||
202
btr/btr0btr.c
202
btr/btr0btr.c
|
|
@ -78,6 +78,26 @@ make them consecutive on disk if possible. From the other file segment
|
|||
we allocate pages for the non-leaf levels of the tree.
|
||||
*/
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
/******************************************************************
|
||||
Checks a file segment header within a B-tree root page. */
|
||||
static
|
||||
ibool
|
||||
btr_root_fseg_validate(
|
||||
/*===================*/
|
||||
/* out: TRUE if valid */
|
||||
const fseg_header_t* seg_header, /* in: segment header */
|
||||
ulint space) /* in: tablespace identifier */
|
||||
{
|
||||
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
|
||||
|
||||
ut_a(mach_read_from_4(seg_header + FSEG_HDR_SPACE) == space);
|
||||
ut_a(offset >= FIL_PAGE_DATA);
|
||||
ut_a(offset <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
|
||||
return(TRUE);
|
||||
}
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
/******************************************************************
|
||||
Gets the root node of a tree and x-latches it. */
|
||||
static
|
||||
|
|
@ -100,6 +120,16 @@ btr_root_block_get(
|
|||
block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
|
||||
ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
|
||||
== dict_table_is_comp(index->table));
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
if (!dict_index_is_ibuf(index)) {
|
||||
const page_t* root = buf_block_get_frame(block);
|
||||
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
}
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
|
@ -287,9 +317,7 @@ btr_page_alloc_for_ibuf(
|
|||
dict_table_zip_size(index->table),
|
||||
node_addr.page, RW_X_LATCH, mtr);
|
||||
new_page = buf_block_get_frame(new_block);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
||||
new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
|
||||
|
|
@ -349,9 +377,7 @@ btr_page_alloc(
|
|||
new_block = buf_page_get(dict_index_get_space(index),
|
||||
dict_table_zip_size(index->table),
|
||||
new_page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(new_block);
|
||||
}
|
||||
|
|
@ -709,9 +735,8 @@ btr_create(
|
|||
space, 0,
|
||||
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(ibuf_hdr_block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
ut_ad(buf_block_get_page_no(ibuf_hdr_block)
|
||||
== IBUF_HEADER_PAGE_NO);
|
||||
/* Allocate then the next page to the segment: it will be the
|
||||
|
|
@ -740,9 +765,7 @@ btr_create(
|
|||
page_no = buf_block_get_page_no(block);
|
||||
frame = buf_block_get_frame(block);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
if (type & DICT_IBUF) {
|
||||
/* It is an insert buffer tree: initialize the free list */
|
||||
|
|
@ -757,9 +780,7 @@ btr_create(
|
|||
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr);
|
||||
/* The fseg create acquires a second latch on the page,
|
||||
therefore we must declare it: */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
/* Create a new index page on the the allocated segment page */
|
||||
|
|
@ -820,6 +841,12 @@ leaf_loop:
|
|||
mtr_start(&mtr);
|
||||
|
||||
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
/* NOTE: page hash indexes are dropped when a page is freed inside
|
||||
fsp0fsp. */
|
||||
|
|
@ -836,6 +863,10 @@ top_loop:
|
|||
mtr_start(&mtr);
|
||||
|
||||
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
finished = fseg_free_step_not_header(
|
||||
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
|
||||
|
|
@ -868,6 +899,9 @@ btr_free_root(
|
|||
btr_search_drop_page_hash_index(block);
|
||||
|
||||
header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(header, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
while (!fseg_free_step(header, mtr));
|
||||
}
|
||||
|
|
@ -1104,8 +1138,18 @@ btr_root_raise_and_insert(
|
|||
ut_a(!root_page_zip || page_zip_validate(root_page_zip, root));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
index = btr_cur_get_index(cursor);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
if (!dict_index_is_ibuf(index)) {
|
||||
ulint space = dict_index_get_space(index);
|
||||
|
||||
ut_ad(dict_index_get_page(index) == page_get_page_no(root));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
}
|
||||
|
||||
ut_a(dict_index_get_page(index) == page_get_page_no(root));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
MTR_MEMO_X_LOCK));
|
||||
ut_ad(mtr_memo_contains(mtr, root_block, MTR_MEMO_PAGE_X_FIX));
|
||||
|
|
@ -1133,15 +1177,27 @@ btr_root_raise_and_insert(
|
|||
|
||||
/* Copy the records from root to the new page one by one. */
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
if (0
|
||||
#ifdef UNIV_ZIP_COPY
|
||||
|| new_page_zip
|
||||
#endif /* UNIV_ZIP_COPY */
|
||||
|| UNIV_UNLIKELY
|
||||
(!page_copy_rec_list_end(new_block, root_block,
|
||||
page_get_infimum_rec(root),
|
||||
index, mtr))) {
|
||||
ut_a(new_page_zip);
|
||||
|
||||
/* Copy the page byte for byte. */
|
||||
page_zip_copy(new_page_zip, new_page,
|
||||
root_page_zip, root, index, mtr);
|
||||
page_zip_copy_recs(new_page_zip, new_page,
|
||||
root_page_zip, root, index, mtr);
|
||||
|
||||
/* Update the lock table and possible hash index. */
|
||||
|
||||
lock_move_rec_list_end(new_block, root_block,
|
||||
page_get_infimum_rec(root));
|
||||
|
||||
btr_search_move_or_delete_hash_entries(new_block, root_block,
|
||||
index);
|
||||
}
|
||||
|
||||
/* If this is a pessimistic insert which is actually done to
|
||||
|
|
@ -1794,7 +1850,35 @@ func_start:
|
|||
} else {
|
||||
direction = FSP_UP;
|
||||
hint_page_no = page_no + 1;
|
||||
split_rec = page_get_middle_rec(page);
|
||||
|
||||
if (page_get_n_recs(page) == 1) {
|
||||
page_cur_t pcur;
|
||||
|
||||
/* There is only one record in the index page
|
||||
therefore we can't split the node in the middle
|
||||
by default. We need to determine whether the
|
||||
new record will be inserted to the left or right. */
|
||||
|
||||
/* Read the first (and only) record in the page. */
|
||||
page_cur_set_before_first(block, &pcur);
|
||||
page_cur_move_to_next(&pcur);
|
||||
first_rec = page_cur_get_rec(&pcur);
|
||||
|
||||
offsets = rec_get_offsets(
|
||||
first_rec, cursor->index, offsets,
|
||||
n_uniq, &heap);
|
||||
|
||||
/* If the new record is less than the existing record
|
||||
the the split in the middle will copy the existing
|
||||
record to the new node. */
|
||||
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
|
||||
split_rec = page_get_middle_rec(page);
|
||||
} else {
|
||||
split_rec = NULL;
|
||||
}
|
||||
} else {
|
||||
split_rec = page_get_middle_rec(page);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. Allocate a new page to the index */
|
||||
|
|
@ -1867,7 +1951,11 @@ insert_right:
|
|||
if (direction == FSP_DOWN) {
|
||||
/* fputs("Split left\n", stderr); */
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
if (0
|
||||
#ifdef UNIV_ZIP_COPY
|
||||
|| page_zip
|
||||
#endif /* UNIV_ZIP_COPY */
|
||||
|| UNIV_UNLIKELY
|
||||
(!page_move_rec_list_start(new_block, block, move_limit,
|
||||
cursor->index, mtr))) {
|
||||
/* For some reason, compressing new_page failed,
|
||||
|
|
@ -1877,12 +1965,24 @@ insert_right:
|
|||
as appropriate. Deleting will always succeed. */
|
||||
ut_a(new_page_zip);
|
||||
|
||||
page_zip_copy(new_page_zip, new_page,
|
||||
page_zip, page, cursor->index, mtr);
|
||||
page_zip_copy_recs(new_page_zip, new_page,
|
||||
page_zip, page, cursor->index, mtr);
|
||||
page_delete_rec_list_end(move_limit - page + new_page,
|
||||
new_block, cursor->index,
|
||||
ULINT_UNDEFINED,
|
||||
ULINT_UNDEFINED, mtr);
|
||||
|
||||
/* Update the lock table and possible hash index. */
|
||||
|
||||
lock_move_rec_list_start(
|
||||
new_block, block, move_limit,
|
||||
new_page + PAGE_NEW_INFIMUM);
|
||||
|
||||
btr_search_move_or_delete_hash_entries(
|
||||
new_block, block, cursor->index);
|
||||
|
||||
/* Delete the records from the source page. */
|
||||
|
||||
page_delete_rec_list_start(move_limit, block,
|
||||
cursor->index, mtr);
|
||||
}
|
||||
|
|
@ -1894,7 +1994,11 @@ insert_right:
|
|||
} else {
|
||||
/* fputs("Split right\n", stderr); */
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
if (0
|
||||
#ifdef UNIV_ZIP_COPY
|
||||
|| page_zip
|
||||
#endif /* UNIV_ZIP_COPY */
|
||||
|| UNIV_UNLIKELY
|
||||
(!page_move_rec_list_end(new_block, block, move_limit,
|
||||
cursor->index, mtr))) {
|
||||
/* For some reason, compressing new_page failed,
|
||||
|
|
@ -1904,11 +2008,21 @@ insert_right:
|
|||
as appropriate. Deleting will always succeed. */
|
||||
ut_a(new_page_zip);
|
||||
|
||||
page_zip_copy(new_page_zip, new_page,
|
||||
page_zip, page, cursor->index, mtr);
|
||||
page_zip_copy_recs(new_page_zip, new_page,
|
||||
page_zip, page, cursor->index, mtr);
|
||||
page_delete_rec_list_start(move_limit - page
|
||||
+ new_page, new_block,
|
||||
cursor->index, mtr);
|
||||
|
||||
/* Update the lock table and possible hash index. */
|
||||
|
||||
lock_move_rec_list_end(new_block, block, move_limit);
|
||||
|
||||
btr_search_move_or_delete_hash_entries(
|
||||
new_block, block, cursor->index);
|
||||
|
||||
/* Delete the records from the source page. */
|
||||
|
||||
page_delete_rec_list_end(move_limit, block,
|
||||
cursor->index,
|
||||
ULINT_UNDEFINED,
|
||||
|
|
@ -2174,7 +2288,7 @@ btr_node_ptr_delete(
|
|||
/* Delete node pointer on father page */
|
||||
btr_page_get_father(index, block, mtr, &cursor);
|
||||
|
||||
compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, FALSE,
|
||||
compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, RB_NONE,
|
||||
mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
|
|
@ -2257,7 +2371,11 @@ btr_lift_page_up(
|
|||
btr_page_set_level(father_page, father_page_zip, page_level, mtr);
|
||||
|
||||
/* Copy the records to the father page one by one. */
|
||||
if (UNIV_UNLIKELY
|
||||
if (0
|
||||
#ifdef UNIV_ZIP_COPY
|
||||
|| father_page_zip
|
||||
#endif /* UNIV_ZIP_COPY */
|
||||
|| UNIV_UNLIKELY
|
||||
(!page_copy_rec_list_end(father_block, block,
|
||||
page_get_infimum_rec(page),
|
||||
index, mtr))) {
|
||||
|
|
@ -2267,20 +2385,31 @@ btr_lift_page_up(
|
|||
ut_a(page_zip);
|
||||
|
||||
/* Copy the page byte for byte. */
|
||||
page_zip_copy(father_page_zip, father_page,
|
||||
page_zip, page, index, mtr);
|
||||
page_zip_copy_recs(father_page_zip, father_page,
|
||||
page_zip, page, index, mtr);
|
||||
|
||||
/* Update the lock table and possible hash index. */
|
||||
|
||||
lock_move_rec_list_end(father_block, block,
|
||||
page_get_infimum_rec(page));
|
||||
|
||||
btr_search_move_or_delete_hash_entries(father_block, block,
|
||||
index);
|
||||
}
|
||||
|
||||
lock_update_copy_and_discard(father_block, block);
|
||||
|
||||
/* Go upward to root page, decrementing levels by one. */
|
||||
for (i = 0; i < n_blocks; i++, page_level++) {
|
||||
page_t* page = buf_block_get_frame(blocks[i]);
|
||||
page_t* page = buf_block_get_frame(blocks[i]);
|
||||
page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]);
|
||||
|
||||
ut_ad(btr_page_get_level(page, mtr) == page_level + 1);
|
||||
|
||||
btr_page_set_level(page, buf_block_get_page_zip(blocks[i]),
|
||||
page_level, mtr);
|
||||
btr_page_set_level(page, page_zip, page_level, mtr);
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(!page_zip || page_zip_validate(page_zip, page));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
/* Free the file page */
|
||||
|
|
@ -2575,6 +2704,9 @@ err_exit:
|
|||
}
|
||||
|
||||
ut_ad(page_validate(merge_page, index));
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
/* Free the file page */
|
||||
btr_page_free(index, block, mtr);
|
||||
|
|
@ -2623,6 +2755,20 @@ btr_discard_only_page_on_level(
|
|||
== dict_index_get_page(index))) {
|
||||
/* The father is the root page */
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
if (!dict_index_is_ibuf(index)) {
|
||||
const page_t* root
|
||||
= buf_block_get_frame(father_block);
|
||||
const ulint space
|
||||
= dict_index_get_space(index);
|
||||
ut_a(btr_root_fseg_validate(
|
||||
FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(
|
||||
FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
}
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
btr_page_empty(father_block, father_page_zip, mtr, index);
|
||||
|
||||
/* We play safe and reset the free bits for the father */
|
||||
|
|
|
|||
246
btr/btr0cur.c
246
btr/btr0cur.c
|
|
@ -32,6 +32,7 @@ Created 10/16/1994 Heikki Tuuri
|
|||
#include "btr0sea.h"
|
||||
#include "row0upd.h"
|
||||
#include "trx0rec.h"
|
||||
#include "trx0roll.h" /* trx_is_recv() */
|
||||
#include "que0que.h"
|
||||
#include "row0row.h"
|
||||
#include "srv0srv.h"
|
||||
|
|
@ -55,10 +56,6 @@ can be released by page reorganize, then it is reorganized */
|
|||
|
||||
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
|
||||
|
||||
/* When estimating number of different key values in an index, sample
|
||||
this many index pages */
|
||||
#define BTR_KEY_VAL_ESTIMATE_N_PAGES 8
|
||||
|
||||
/* The structure of a BLOB part header */
|
||||
/*--------------------------------------*/
|
||||
#define BTR_BLOB_HDR_PART_LEN 0 /* BLOB part len on this
|
||||
|
|
@ -112,6 +109,7 @@ btr_rec_free_updated_extern_fields(
|
|||
part will be updated, or NULL */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
const upd_t* update, /* in: update vector */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the tree */
|
||||
/***************************************************************
|
||||
|
|
@ -126,9 +124,7 @@ btr_rec_free_externally_stored_fields(
|
|||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
|
||||
part will be updated, or NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the index
|
||||
tree */
|
||||
|
|
@ -394,8 +390,8 @@ btr_cur_search_to_nth_level(
|
|||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
#endif /* BTR_CUR_ADAPT */
|
||||
btr_cur_n_non_sea++;
|
||||
|
||||
/* If the hash search did not succeed, do binary search down the
|
||||
|
|
@ -468,8 +464,7 @@ retry_page_get:
|
|||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
rw_latch, guess, buf_mode,
|
||||
__FILE__, __LINE__,
|
||||
mtr);
|
||||
__FILE__, __LINE__, mtr);
|
||||
if (block == NULL) {
|
||||
/* This must be a search to perform an insert;
|
||||
try insert to the insert buffer */
|
||||
|
|
@ -508,11 +503,10 @@ retry_page_get:
|
|||
|
||||
block->check_index_page_at_flush = TRUE;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
if (rw_latch != RW_NO_LATCH) {
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
}
|
||||
#endif
|
||||
|
||||
ut_ad(0 == ut_dulint_cmp(index->id,
|
||||
btr_page_get_index_id(page)));
|
||||
|
||||
|
|
@ -690,8 +684,7 @@ btr_cur_open_at_index_side(
|
|||
page_t* page;
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
__FILE__, __LINE__,
|
||||
mtr);
|
||||
__FILE__, __LINE__, mtr);
|
||||
page = buf_block_get_frame(block);
|
||||
ut_ad(0 == ut_dulint_cmp(index->id,
|
||||
btr_page_get_index_id(page)));
|
||||
|
|
@ -810,8 +803,7 @@ btr_cur_open_at_rnd_pos(
|
|||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
__FILE__, __LINE__,
|
||||
mtr);
|
||||
__FILE__, __LINE__, mtr);
|
||||
page = buf_block_get_frame(block);
|
||||
ut_ad(0 == ut_dulint_cmp(index->id,
|
||||
btr_page_get_index_id(page)));
|
||||
|
|
@ -854,7 +846,7 @@ btr_cur_open_at_rnd_pos(
|
|||
|
||||
/*****************************************************************
|
||||
Inserts a record if there is enough space, or if enough space can
|
||||
be freed by reorganizing. Differs from _optimistic_insert because
|
||||
be freed by reorganizing. Differs from btr_cur_optimistic_insert because
|
||||
no heuristics is applied to whether it pays to use CPU time for
|
||||
reorganizing the page or not. */
|
||||
static
|
||||
|
|
@ -1058,7 +1050,8 @@ btr_cur_optimistic_insert(
|
|||
/* Calculate the record size when entry is converted to a record */
|
||||
rec_size = rec_get_converted_size(index, entry, n_ext);
|
||||
|
||||
if (page_zip_rec_needs_ext(rec_size, page_is_comp(page), zip_size)) {
|
||||
if (page_zip_rec_needs_ext(rec_size, page_is_comp(page),
|
||||
dtuple_get_n_fields(entry), zip_size)) {
|
||||
|
||||
/* The record is so big that we have to store some fields
|
||||
externally on separate database pages */
|
||||
|
|
@ -1072,6 +1065,45 @@ btr_cur_optimistic_insert(
|
|||
rec_size = rec_get_converted_size(index, entry, n_ext);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
/* Estimate the free space of an empty compressed page.
|
||||
Subtract one byte for the encoded heap_no in the
|
||||
modification log. */
|
||||
ulint free_space_zip = page_zip_empty_size(
|
||||
cursor->index->n_fields, zip_size) - 1;
|
||||
ulint n_uniq = dict_index_get_n_unique_in_tree(index);
|
||||
|
||||
ut_ad(dict_table_is_comp(index->table));
|
||||
|
||||
/* There should be enough room for two node pointer
|
||||
records on an empty non-leaf page. This prevents
|
||||
infinite page splits. */
|
||||
|
||||
if (UNIV_LIKELY(entry->n_fields >= n_uniq)
|
||||
&& UNIV_UNLIKELY(REC_NODE_PTR_SIZE
|
||||
+ rec_get_converted_size_comp_prefix(
|
||||
index, entry->fields, n_uniq,
|
||||
NULL)
|
||||
/* On a compressed page, there is
|
||||
a two-byte entry in the dense
|
||||
page directory for every record.
|
||||
But there is no record header. */
|
||||
- (REC_N_NEW_EXTRA_BYTES - 2)
|
||||
> free_space_zip / 2)) {
|
||||
|
||||
if (big_rec_vec) {
|
||||
dtuple_convert_back_big_rec(
|
||||
index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there have been many consecutive inserts, and we are on the leaf
|
||||
level, check if we have to split the page to reserve enough free space
|
||||
for future updates of records. */
|
||||
|
|
@ -1303,6 +1335,7 @@ btr_cur_pessimistic_insert(
|
|||
|
||||
if (page_zip_rec_needs_ext(rec_get_converted_size(index, entry, n_ext),
|
||||
dict_table_is_comp(index->table),
|
||||
dict_index_get_n_fields(index),
|
||||
zip_size)) {
|
||||
/* The record is so big that we have to store some fields
|
||||
externally on separate database pages */
|
||||
|
|
@ -1326,45 +1359,6 @@ btr_cur_pessimistic_insert(
|
|||
}
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
/* Estimate the free space of an empty compressed page. */
|
||||
ulint free_space_zip = page_zip_empty_size(
|
||||
cursor->index->n_fields, zip_size);
|
||||
|
||||
if (UNIV_UNLIKELY(rec_get_converted_size(index, entry, n_ext)
|
||||
> free_space_zip)) {
|
||||
/* Try to insert the record by itself on a new page.
|
||||
If it fails, no amount of splitting will help. */
|
||||
buf_block_t* temp_block
|
||||
= buf_block_alloc(zip_size);
|
||||
page_t* temp_page
|
||||
= page_create_zip(temp_block, index, 0, NULL);
|
||||
page_cur_t temp_cursor;
|
||||
rec_t* temp_rec;
|
||||
|
||||
page_cur_position(temp_page + PAGE_NEW_INFIMUM,
|
||||
temp_block, &temp_cursor);
|
||||
|
||||
temp_rec = page_cur_tuple_insert(&temp_cursor,
|
||||
entry, index,
|
||||
n_ext, NULL);
|
||||
buf_block_free(temp_block);
|
||||
|
||||
if (UNIV_UNLIKELY(!temp_rec)) {
|
||||
if (big_rec_vec) {
|
||||
dtuple_convert_back_big_rec(
|
||||
index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dict_index_get_page(index)
|
||||
== buf_block_get_page_no(btr_cur_get_block(cursor))) {
|
||||
|
||||
|
|
@ -2162,8 +2156,9 @@ btr_cur_pessimistic_update(
|
|||
|
||||
ut_ad(big_rec_vec == NULL);
|
||||
|
||||
btr_rec_free_updated_extern_fields(index, rec, page_zip,
|
||||
offsets, update, mtr);
|
||||
btr_rec_free_updated_extern_fields(
|
||||
index, rec, page_zip, offsets, update,
|
||||
trx_is_recv(trx) ? RB_RECOVERY : RB_NORMAL, mtr);
|
||||
}
|
||||
|
||||
/* We have to set appropriate extern storage bits in the new
|
||||
|
|
@ -2173,10 +2168,20 @@ btr_cur_pessimistic_update(
|
|||
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
|
||||
n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
|
||||
|
||||
if (page_zip_rec_needs_ext(rec_get_converted_size(index, new_entry,
|
||||
n_ext),
|
||||
page_is_comp(page), page_zip
|
||||
? page_zip_get_size(page_zip) : 0)) {
|
||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||
ut_ad(page_is_comp(page));
|
||||
if (page_zip_rec_needs_ext(
|
||||
rec_get_converted_size(index, new_entry, n_ext),
|
||||
TRUE,
|
||||
dict_index_get_n_fields(index),
|
||||
page_zip_get_size(page_zip))) {
|
||||
|
||||
goto make_external;
|
||||
}
|
||||
} else if (page_zip_rec_needs_ext(
|
||||
rec_get_converted_size(index, new_entry, n_ext),
|
||||
page_is_comp(page), 0, 0)) {
|
||||
make_external:
|
||||
big_rec_vec = dtuple_convert_big_rec(index, new_entry, &n_ext);
|
||||
if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
|
||||
|
||||
|
|
@ -2655,7 +2660,7 @@ btr_cur_del_mark_set_sec_rec(
|
|||
}
|
||||
|
||||
/***************************************************************
|
||||
Sets a secondary index record delete mark to FALSE. This function is only
|
||||
Clear a secondary index record's delete mark. This function is only
|
||||
used by the insert buffer insert merge mechanism. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
|
@ -2811,7 +2816,7 @@ btr_cur_pessimistic_delete(
|
|||
if compression does not occur, the cursor
|
||||
stays valid: it points to successor of
|
||||
deleted record on function exit */
|
||||
ibool in_rollback,/* in: TRUE if called in rollback */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
buf_block_t* block;
|
||||
|
|
@ -2865,14 +2870,14 @@ btr_cur_pessimistic_delete(
|
|||
if (rec_offs_any_extern(offsets)) {
|
||||
btr_rec_free_externally_stored_fields(index,
|
||||
rec, offsets, page_zip,
|
||||
in_rollback, mtr);
|
||||
rb_ctx, mtr);
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(!page_zip || page_zip_validate(page_zip, page));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
|
||||
&& UNIV_UNLIKELY(dict_index_get_page(btr_cur_get_index(cursor))
|
||||
&& UNIV_UNLIKELY(dict_index_get_page(index)
|
||||
!= buf_block_get_page_no(block))) {
|
||||
|
||||
/* If there is only one record, drop the whole page in
|
||||
|
|
@ -3154,11 +3159,12 @@ btr_estimate_number_of_different_key_vals(
|
|||
ulint matched_fields;
|
||||
ulint matched_bytes;
|
||||
ib_int64_t* n_diff;
|
||||
ullint n_sample_pages; /* number of pages to sample */
|
||||
ulint not_empty_flag = 0;
|
||||
ulint total_external_size = 0;
|
||||
ulint i;
|
||||
ulint j;
|
||||
ulint add_on;
|
||||
ullint add_on;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_rec_[REC_OFFS_NORMAL_SIZE];
|
||||
|
|
@ -3172,9 +3178,21 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
|
||||
|
||||
/* It makes no sense to test more pages than are contained
|
||||
in the index, thus we lower the number if it is too high */
|
||||
if (srv_stats_sample_pages > index->stat_index_size) {
|
||||
if (index->stat_index_size > 0) {
|
||||
n_sample_pages = index->stat_index_size;
|
||||
} else {
|
||||
n_sample_pages = 1;
|
||||
}
|
||||
} else {
|
||||
n_sample_pages = srv_stats_sample_pages;
|
||||
}
|
||||
|
||||
/* We sample some pages in the index to get an estimate */
|
||||
|
||||
for (i = 0; i < BTR_KEY_VAL_ESTIMATE_N_PAGES; i++) {
|
||||
for (i = 0; i < n_sample_pages; i++) {
|
||||
rec_t* supremum;
|
||||
mtr_start(&mtr);
|
||||
|
||||
|
|
@ -3182,7 +3200,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
/* Count the number of different key values for each prefix of
|
||||
the key on this index page. If the prefix does not determine
|
||||
the index record uniquely in te B-tree, then we subtract one
|
||||
the index record uniquely in the B-tree, then we subtract one
|
||||
because otherwise our algorithm would give a wrong estimate
|
||||
for an index where there is just one key value. */
|
||||
|
||||
|
|
@ -3263,7 +3281,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
|
||||
/* If we saw k borders between different key values on
|
||||
BTR_KEY_VAL_ESTIMATE_N_PAGES leaf pages, we can estimate how many
|
||||
n_sample_pages leaf pages, we can estimate how many
|
||||
there will be in index->stat_n_leaf_pages */
|
||||
|
||||
/* We must take into account that our sample actually represents
|
||||
|
|
@ -3274,26 +3292,26 @@ btr_estimate_number_of_different_key_vals(
|
|||
index->stat_n_diff_key_vals[j]
|
||||
= ((n_diff[j]
|
||||
* (ib_int64_t)index->stat_n_leaf_pages
|
||||
+ BTR_KEY_VAL_ESTIMATE_N_PAGES - 1
|
||||
+ n_sample_pages - 1
|
||||
+ total_external_size
|
||||
+ not_empty_flag)
|
||||
/ (BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||
/ (n_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
/* If the tree is small, smaller than
|
||||
10 * BTR_KEY_VAL_ESTIMATE_N_PAGES + total_external_size, then
|
||||
10 * n_sample_pages + total_external_size, then
|
||||
the above estimate is ok. For bigger trees it is common that we
|
||||
do not see any borders between key values in the few pages
|
||||
we pick. But still there may be BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||
we pick. But still there may be n_sample_pages
|
||||
different key values, or even more. Let us try to approximate
|
||||
that: */
|
||||
|
||||
add_on = index->stat_n_leaf_pages
|
||||
/ (10 * (BTR_KEY_VAL_ESTIMATE_N_PAGES
|
||||
/ (10 * (n_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
if (add_on > BTR_KEY_VAL_ESTIMATE_N_PAGES) {
|
||||
add_on = BTR_KEY_VAL_ESTIMATE_N_PAGES;
|
||||
if (add_on > n_sample_pages) {
|
||||
add_on = n_sample_pages;
|
||||
}
|
||||
|
||||
index->stat_n_diff_key_vals[j] += add_on;
|
||||
|
|
@ -3832,10 +3850,8 @@ btr_store_big_rec_extern_fields(
|
|||
prev_block = buf_page_get(space_id, zip_size,
|
||||
prev_page_no,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(prev_block,
|
||||
SYNC_EXTERN_STORAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
prev_page = buf_block_get_frame(prev_block);
|
||||
|
||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||
|
|
@ -3930,10 +3946,9 @@ btr_store_big_rec_extern_fields(
|
|||
rec_block = buf_page_get(space_id, zip_size,
|
||||
rec_page_no,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(rec_block,
|
||||
SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
if (err == Z_STREAM_END) {
|
||||
mach_write_to_4(field_ref
|
||||
+ BTR_EXTERN_LEN, 0);
|
||||
|
|
@ -4009,10 +4024,8 @@ next_zip_page:
|
|||
rec_block = buf_page_get(space_id, zip_size,
|
||||
rec_page_no,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(rec_block,
|
||||
SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
mlog_write_ulint(field_ref + BTR_EXTERN_LEN, 0,
|
||||
MLOG_4BYTES, &mtr);
|
||||
|
|
@ -4084,9 +4097,7 @@ btr_free_externally_stored_field(
|
|||
to rec, or NULL if rec == NULL */
|
||||
ulint i, /* in: field number of field_ref;
|
||||
ignored if rec == NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* local_mtr __attribute__((unused))) /* in: mtr
|
||||
containing the latch to data an an
|
||||
X-latch to the index tree */
|
||||
|
|
@ -4116,6 +4127,15 @@ btr_free_externally_stored_field(
|
|||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
|
||||
BTR_EXTERN_FIELD_REF_SIZE))) {
|
||||
/* In the rollback of uncommitted transactions, we may
|
||||
encounter a clustered index record whose BLOBs have
|
||||
not been written. There is nothing to free then. */
|
||||
ut_a(rb_ctx == RB_RECOVERY);
|
||||
return;
|
||||
}
|
||||
|
||||
space_id = mach_read_from_4(field_ref + BTR_EXTERN_SPACE_ID);
|
||||
|
||||
if (UNIV_UNLIKELY(space_id != dict_index_get_space(index))) {
|
||||
|
|
@ -4149,9 +4169,7 @@ btr_free_externally_stored_field(
|
|||
page_get_page_no(
|
||||
page_align(field_ref)),
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(rec_block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
page_no = mach_read_from_4(field_ref + BTR_EXTERN_PAGE_NO);
|
||||
|
||||
if (/* There is no external storage data */
|
||||
|
|
@ -4160,7 +4178,7 @@ btr_free_externally_stored_field(
|
|||
|| (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_OWNER_FLAG)
|
||||
/* Rollback and inherited field */
|
||||
|| (do_not_free_inherited
|
||||
|| (rb_ctx != RB_NONE
|
||||
&& (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_INHERITED_FLAG))) {
|
||||
|
||||
|
|
@ -4172,9 +4190,7 @@ btr_free_externally_stored_field(
|
|||
|
||||
ext_block = buf_page_get(space_id, ext_zip_size, page_no,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(ext_block, SYNC_EXTERN_STORAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
page = buf_block_get_frame(ext_block);
|
||||
|
||||
if (ext_zip_size) {
|
||||
|
|
@ -4208,14 +4224,8 @@ btr_free_externally_stored_field(
|
|||
MLOG_4BYTES, &mtr);
|
||||
}
|
||||
} else {
|
||||
ulint extern_len = mach_read_from_4(
|
||||
field_ref + BTR_EXTERN_LEN + 4);
|
||||
ulint part_len = btr_blob_get_part_len(
|
||||
page + FIL_PAGE_DATA);
|
||||
|
||||
ut_a(fil_page_get_type(page) == FIL_PAGE_TYPE_BLOB);
|
||||
ut_a(!page_zip);
|
||||
ut_a(extern_len >= part_len);
|
||||
|
||||
next_page_no = mach_read_from_4(
|
||||
page + FIL_PAGE_DATA
|
||||
|
|
@ -4233,16 +4243,14 @@ btr_free_externally_stored_field(
|
|||
mlog_write_ulint(field_ref + BTR_EXTERN_PAGE_NO,
|
||||
next_page_no,
|
||||
MLOG_4BYTES, &mtr);
|
||||
/* Zero out the BLOB length. If the server
|
||||
crashes during the execution of this function,
|
||||
trx_rollback_or_clean_all_recovered() could
|
||||
dereference the half-deleted BLOB, fetching a
|
||||
wrong prefix for the BLOB. */
|
||||
mlog_write_ulint(field_ref + BTR_EXTERN_LEN + 4,
|
||||
extern_len - part_len,
|
||||
0,
|
||||
MLOG_4BYTES, &mtr);
|
||||
if (next_page_no == FIL_NULL) {
|
||||
ut_a(extern_len - part_len == 0);
|
||||
}
|
||||
|
||||
if (extern_len - part_len == 0) {
|
||||
ut_a(next_page_no == FIL_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit mtr and release the BLOB block to save memory. */
|
||||
|
|
@ -4262,9 +4270,7 @@ btr_rec_free_externally_stored_fields(
|
|||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
|
||||
part will be updated, or NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the index
|
||||
tree */
|
||||
|
|
@ -4288,8 +4294,7 @@ btr_rec_free_externally_stored_fields(
|
|||
|
||||
btr_free_externally_stored_field(
|
||||
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||
rec, offsets, page_zip, i,
|
||||
do_not_free_inherited, mtr);
|
||||
rec, offsets, page_zip, i, rb_ctx, mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4308,6 +4313,7 @@ btr_rec_free_updated_extern_fields(
|
|||
part will be updated, or NULL */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
const upd_t* update, /* in: update vector */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the tree */
|
||||
{
|
||||
|
|
@ -4333,7 +4339,7 @@ btr_rec_free_updated_extern_fields(
|
|||
btr_free_externally_stored_field(
|
||||
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||
rec, offsets, page_zip,
|
||||
ufield->field_no, TRUE, mtr);
|
||||
ufield->field_no, rb_ctx, mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4366,9 +4372,7 @@ btr_copy_blob_prefix(
|
|||
mtr_start(&mtr);
|
||||
|
||||
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
/* Unfortunately, FIL_PAGE_TYPE was uninitialized for
|
||||
|
|
@ -4584,7 +4588,9 @@ UNIV_INTERN
|
|||
ulint
|
||||
btr_copy_externally_stored_field_prefix(
|
||||
/*====================================*/
|
||||
/* out: the length of the copied field */
|
||||
/* out: the length of the copied field,
|
||||
or 0 if the column was being or has been
|
||||
deleted */
|
||||
byte* buf, /* out: the field, or a prefix of it */
|
||||
ulint len, /* in: length of buf, in bytes */
|
||||
ulint zip_size,/* in: nonzero=compressed BLOB page size,
|
||||
|
|
@ -4613,6 +4619,14 @@ btr_copy_externally_stored_field_prefix(
|
|||
|
||||
ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
|
||||
|
||||
if (!mach_read_from_4(data + BTR_EXTERN_LEN + 4)) {
|
||||
/* The externally stored part of the column has been
|
||||
(partially) deleted. Signal the half-deleted BLOB
|
||||
to the caller. */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
space_id = mach_read_from_4(data + BTR_EXTERN_SPACE_ID);
|
||||
|
||||
page_no = mach_read_from_4(data + BTR_EXTERN_PAGE_NO);
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ btr_pcur_restore_position(
|
|||
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
|
||||
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
|
||||
ut_print_buf(stderr, cursor, sizeof(btr_pcur_t));
|
||||
putc('\n', stderr);
|
||||
if (cursor->trx_if_known) {
|
||||
trx_print(stderr, cursor->trx_if_known, 0);
|
||||
}
|
||||
|
|
@ -243,10 +244,10 @@ btr_pcur_restore_position(
|
|||
cursor->block_when_stored,
|
||||
cursor->modify_clock, mtr))) {
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
|
||||
SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
if (cursor->rel_pos == BTR_PCUR_ON) {
|
||||
#ifdef UNIV_DEBUG
|
||||
const rec_t* rec;
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ btr_search_info_create(
|
|||
info->magic_n = BTR_SEARCH_MAGIC_N;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
info->ref_count = 0;
|
||||
info->root_guess = NULL;
|
||||
|
||||
info->hash_analysis = 0;
|
||||
|
|
@ -211,6 +212,32 @@ btr_search_info_create(
|
|||
return(info);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Returns the value of ref_count. The value is protected by
|
||||
btr_search_latch. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
/*==========================*/
|
||||
/* out: ref_count value. */
|
||||
btr_search_t* info) /* in: search info. */
|
||||
{
|
||||
ulint ret;
|
||||
|
||||
ut_ad(info);
|
||||
|
||||
#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_EX));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
ret = info->ref_count;
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Updates the search info of an index about hash successes. NOTE that info
|
||||
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
||||
|
|
@ -818,9 +845,7 @@ btr_search_guess_on_hash(
|
|||
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(buf_block_get_state(block)
|
||||
|
|
@ -944,21 +969,21 @@ btr_search_drop_page_hash_index(
|
|||
for which we know that
|
||||
block->buf_fix_count == 0 */
|
||||
{
|
||||
hash_table_t* table;
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
page_t* page;
|
||||
rec_t* rec;
|
||||
ulint fold;
|
||||
ulint prev_fold;
|
||||
dulint index_id;
|
||||
ulint n_cached;
|
||||
ulint n_recs;
|
||||
ulint* folds;
|
||||
ulint i;
|
||||
mem_heap_t* heap;
|
||||
dict_index_t* index;
|
||||
ulint* offsets;
|
||||
hash_table_t* table;
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
const page_t* page;
|
||||
const rec_t* rec;
|
||||
ulint fold;
|
||||
ulint prev_fold;
|
||||
dulint index_id;
|
||||
ulint n_cached;
|
||||
ulint n_recs;
|
||||
ulint* folds;
|
||||
ulint i;
|
||||
mem_heap_t* heap;
|
||||
const dict_index_t* index;
|
||||
ulint* offsets;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
|
||||
|
|
@ -1007,7 +1032,7 @@ retry:
|
|||
n_cached = 0;
|
||||
|
||||
rec = page_get_infimum_rec(page);
|
||||
rec = page_rec_get_next(rec);
|
||||
rec = page_rec_get_next_low(rec, page_is_comp(page));
|
||||
|
||||
index_id = btr_page_get_index_id(page);
|
||||
|
||||
|
|
@ -1035,7 +1060,7 @@ retry:
|
|||
folds[n_cached] = fold;
|
||||
n_cached++;
|
||||
next_rec:
|
||||
rec = page_rec_get_next(rec);
|
||||
rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
|
||||
prev_fold = fold;
|
||||
}
|
||||
|
||||
|
|
@ -1070,8 +1095,12 @@ next_rec:
|
|||
ha_remove_all_nodes_to_page(table, folds[i], page);
|
||||
}
|
||||
|
||||
ut_a(index->search_info->ref_count > 0);
|
||||
index->search_info->ref_count--;
|
||||
|
||||
block->is_hashed = FALSE;
|
||||
block->index = NULL;
|
||||
|
||||
cleanup:
|
||||
#ifdef UNIV_DEBUG
|
||||
if (UNIV_UNLIKELY(block->n_pointers)) {
|
||||
|
|
@ -1127,9 +1156,7 @@ btr_search_drop_page_hash_when_freed(
|
|||
BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
|
||||
&mtr);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
btr_search_drop_page_hash_index(block);
|
||||
|
||||
|
|
@ -1295,6 +1322,15 @@ btr_search_build_page_hash_index(
|
|||
goto exit_func;
|
||||
}
|
||||
|
||||
/* This counter is decremented every time we drop page
|
||||
hash index entries and is incremented here. Since we can
|
||||
rebuild hash index for a page that is already hashed, we
|
||||
have to take care not to increment the counter in that
|
||||
case. */
|
||||
if (!block->is_hashed) {
|
||||
index->search_info->ref_count++;
|
||||
}
|
||||
|
||||
block->is_hashed = TRUE;
|
||||
block->n_hash_helps = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ buf_page_is_corrupted(
|
|||
}
|
||||
|
||||
/* 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_OR_CHKSUM */
|
||||
|
||||
if (checksum_field != 0
|
||||
&& checksum_field != BUF_NO_CHECKSUM_MAGIC
|
||||
|
|
@ -443,7 +443,7 @@ buf_page_print(
|
|||
fprintf(stderr, " InnoDB: Page dump in ascii and hex (%lu bytes):\n",
|
||||
(ulong) size);
|
||||
ut_print_buf(stderr, read_buf, size);
|
||||
fputs("InnoDB: End of page dump\n", stderr);
|
||||
fputs("\nInnoDB: End of page dump\n", stderr);
|
||||
|
||||
if (zip_size) {
|
||||
/* Print compressed page. */
|
||||
|
|
@ -1053,6 +1053,14 @@ buf_relocate(
|
|||
|
||||
if (UNIV_UNLIKELY(buf_pool->LRU_old == bpage)) {
|
||||
buf_pool->LRU_old = dpage;
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU));
|
||||
|
|
@ -2193,9 +2201,8 @@ buf_page_optimistic_get_func(
|
|||
}
|
||||
|
||||
if (UNIV_UNLIKELY(modify_clock != block->modify_clock)) {
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
if (rw_latch == RW_S_LATCH) {
|
||||
rw_lock_s_unlock(&(block->lock));
|
||||
} else {
|
||||
|
|
@ -2395,9 +2402,8 @@ buf_page_try_get_func(
|
|||
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
||||
ut_a(block->page.file_page_was_freed == FALSE);
|
||||
#endif /* UNIV_DEBUG_FILE_ACCESSES */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
buf_pool->n_page_gets++;
|
||||
|
||||
return(block);
|
||||
|
|
@ -3070,9 +3076,6 @@ corrupt:
|
|||
ut_error;
|
||||
}
|
||||
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (buf_debug_prints) {
|
||||
fprintf(stderr, "Has %s page space %lu page no %lu\n",
|
||||
|
|
@ -3081,6 +3084,9 @@ corrupt:
|
|||
(ulong) buf_page_get_page_no(bpage));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
buf_pool_mutex_exit();
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
@ -3446,6 +3452,7 @@ buf_print(void)
|
|||
}
|
||||
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/*************************************************************************
|
||||
Returns the number of latched pages in the buffer pool. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -3532,6 +3539,7 @@ buf_get_latched_pages_number(void)
|
|||
|
||||
return(fixed_pages_number);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/*************************************************************************
|
||||
Returns the number of pending buf pool ios. */
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ buf_flush_ready_for_replace(
|
|||
" in the LRU list!\n",
|
||||
(ulong) buf_page_get_state(bpage));
|
||||
ut_print_buf(stderr, bpage, sizeof(buf_page_t));
|
||||
putc('\n', stderr);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
|
@ -634,6 +635,13 @@ buf_flush_init_for_writing(
|
|||
return;
|
||||
}
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: ERROR: The compressed page to be written"
|
||||
" seems corrupt:", stderr);
|
||||
ut_print_buf(stderr, page, zip_size);
|
||||
fputs("\nInnoDB: Possibly older version of the page:", stderr);
|
||||
ut_print_buf(stderr, page_zip->data, zip_size);
|
||||
putc('\n', stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
|
|
|||
210
buf/buf0lru.c
210
buf/buf0lru.c
|
|
@ -44,6 +44,11 @@ initial segment in buf_LRU_get_recent_limit */
|
|||
|
||||
#define BUF_LRU_INITIAL_RATIO 8
|
||||
|
||||
/* When dropping the search hash index entries before deleting an ibd
|
||||
file, we build a local array of pages belonging to that tablespace
|
||||
in the buffer pool. Following is the size of that array. */
|
||||
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
|
||||
|
||||
/* If we switch on the InnoDB monitor because there are too few available
|
||||
frames in the buffer pool, we set this to TRUE */
|
||||
UNIV_INTERN ibool buf_lru_switched_on_innodb_mon = FALSE;
|
||||
|
|
@ -157,6 +162,133 @@ buf_LRU_evict_from_unzip_LRU(void)
|
|||
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Attempts to drop page hash index on a batch of pages belonging to a
|
||||
particular space id. */
|
||||
static
|
||||
void
|
||||
buf_LRU_drop_page_hash_batch(
|
||||
/*=========================*/
|
||||
ulint space_id, /* in: space id */
|
||||
ulint zip_size, /* in: compressed page size in bytes
|
||||
or 0 for uncompressed pages */
|
||||
const ulint* arr, /* in: array of page_no */
|
||||
ulint count) /* in: number of entries in array */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
ut_ad(arr != NULL);
|
||||
ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
btr_search_drop_page_hash_when_freed(space_id, zip_size,
|
||||
arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
|
||||
hash index entries belonging to that table. This function tries to
|
||||
do that in batch. Note that this is a 'best effort' attempt and does
|
||||
not guarantee that ALL hash entries will be removed. */
|
||||
static
|
||||
void
|
||||
buf_LRU_drop_page_hash_for_tablespace(
|
||||
/*==================================*/
|
||||
ulint id) /* in: space id */
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
ulint* page_arr;
|
||||
ulint num_entries;
|
||||
ulint zip_size;
|
||||
|
||||
zip_size = fil_space_get_zip_size(id);
|
||||
|
||||
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
|
||||
/* Somehow, the tablespace does not exist. Nothing to drop. */
|
||||
ut_ad(0);
|
||||
return;
|
||||
}
|
||||
|
||||
page_arr = ut_malloc(sizeof(ulint)
|
||||
* BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
||||
buf_pool_mutex_enter();
|
||||
|
||||
scan_again:
|
||||
num_entries = 0;
|
||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
while (bpage != NULL) {
|
||||
mutex_t* block_mutex = buf_page_get_mutex(bpage);
|
||||
buf_page_t* prev_bpage;
|
||||
|
||||
mutex_enter(block_mutex);
|
||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|
||||
|| bpage->space != id
|
||||
|| bpage->buf_fix_count > 0
|
||||
|| bpage->io_fix != BUF_IO_NONE) {
|
||||
/* We leave the fixed pages as is in this scan.
|
||||
To be dealt with later in the final scan. */
|
||||
mutex_exit(block_mutex);
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
if (((buf_block_t*) bpage)->is_hashed) {
|
||||
|
||||
/* Store the offset(i.e.: page_no) in the array
|
||||
so that we can drop hash index in a batch
|
||||
later. */
|
||||
page_arr[num_entries] = bpage->offset;
|
||||
mutex_exit(block_mutex);
|
||||
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
||||
++num_entries;
|
||||
|
||||
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
|
||||
goto next_page;
|
||||
}
|
||||
/* Array full. We release the buf_pool->mutex to
|
||||
obey the latching order. */
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
|
||||
num_entries);
|
||||
num_entries = 0;
|
||||
buf_pool_mutex_enter();
|
||||
} else {
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
|
||||
next_page:
|
||||
/* Note that we may have released the buf_pool mutex
|
||||
above after reading the prev_bpage during processing
|
||||
of a page_hash_batch (i.e.: when the array was full).
|
||||
This means that prev_bpage can change in LRU list.
|
||||
This is OK because this function is a 'best effort'
|
||||
to drop as many search hash entries as possible and
|
||||
it does not guarantee that ALL such entries will be
|
||||
dropped. */
|
||||
bpage = prev_bpage;
|
||||
|
||||
/* If, however, bpage has been removed from LRU list
|
||||
to the free list then we should restart the scan.
|
||||
bpage->state is protected by buf_pool mutex. */
|
||||
if (bpage && !buf_page_in_file(bpage)) {
|
||||
ut_a(num_entries == 0);
|
||||
goto scan_again;
|
||||
}
|
||||
}
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
/* Drop any remaining batch of search hashed pages. */
|
||||
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
|
||||
ut_free(page_arr);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Invalidates all pages belonging to a given tablespace when we are deleting
|
||||
the data file(s) of that tablespace. */
|
||||
|
|
@ -170,6 +302,14 @@ buf_LRU_invalidate_tablespace(
|
|||
ulint page_no;
|
||||
ibool all_freed;
|
||||
|
||||
/* Before we attempt to drop pages one by one we first
|
||||
attempt to drop page hash index entries in batches to make
|
||||
it more efficient. The batching attempt is a best effort
|
||||
attempt and does not guarantee that all pages hash entries
|
||||
will be dropped. We get rid of remaining page hash entries
|
||||
one by one below. */
|
||||
buf_LRU_drop_page_hash_for_tablespace(id);
|
||||
|
||||
scan_again:
|
||||
buf_pool_mutex_enter();
|
||||
|
||||
|
|
@ -632,7 +772,7 @@ loop:
|
|||
|
||||
if (!buf_lru_switched_on_innodb_mon) {
|
||||
|
||||
/* Over 67 % of the buffer pool is occupied by lock
|
||||
/* Over 67 % of the buffer pool is occupied by lock
|
||||
heaps or the adaptive hash index. This may be a memory
|
||||
leak! */
|
||||
|
||||
|
|
@ -712,7 +852,7 @@ loop:
|
|||
if (n_iterations > 30) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Warning: difficult to find free blocks from\n"
|
||||
" InnoDB: Warning: difficult to find free blocks in\n"
|
||||
"InnoDB: the buffer pool (%lu search iterations)!"
|
||||
" Consider\n"
|
||||
"InnoDB: increasing the buffer pool size.\n"
|
||||
|
|
@ -790,12 +930,25 @@ buf_LRU_old_adjust_len(void)
|
|||
#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
|
||||
# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
|
||||
#endif
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
for (;;) {
|
||||
old_len = buf_pool->LRU_old_len;
|
||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
||||
|
||||
ut_ad(buf_pool->LRU_old->in_LRU_list);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
/* Update the LRU_old pointer if necessary */
|
||||
|
||||
|
|
@ -803,6 +956,9 @@ buf_LRU_old_adjust_len(void)
|
|||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(
|
||||
LRU, buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
buf_pool->LRU_old_len++;
|
||||
|
||||
|
|
@ -813,8 +969,6 @@ buf_LRU_old_adjust_len(void)
|
|||
LRU, buf_pool->LRU_old);
|
||||
buf_pool->LRU_old_len--;
|
||||
} else {
|
||||
ut_a(buf_pool->LRU_old); /* Check that we did not
|
||||
fall out of the LRU list */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -901,6 +1055,9 @@ buf_LRU_remove_block(
|
|||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
|
|
@ -974,8 +1131,6 @@ buf_LRU_add_block_to_end_low(
|
|||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
|
||||
last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
if (last_bpage) {
|
||||
|
|
@ -988,6 +1143,8 @@ buf_LRU_add_block_to_end_low(
|
|||
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
|
||||
ut_d(bpage->in_LRU_list = TRUE);
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
|
|
@ -1035,8 +1192,6 @@ buf_LRU_add_block_low(
|
|||
ut_a(buf_page_in_file(bpage));
|
||||
ut_ad(!bpage->in_LRU_list);
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
|
||||
if (!old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) {
|
||||
|
||||
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
|
||||
|
|
@ -1044,6 +1199,15 @@ buf_LRU_add_block_low(
|
|||
bpage->LRU_position = buf_pool_clock_tic();
|
||||
bpage->freed_page_clock = buf_pool->freed_page_clock;
|
||||
} else {
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
|
||||
bpage);
|
||||
buf_pool->LRU_old_len++;
|
||||
|
|
@ -1056,6 +1220,8 @@ buf_LRU_add_block_low(
|
|||
|
||||
ut_d(bpage->in_LRU_list = TRUE);
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
ut_ad(buf_pool->LRU_old);
|
||||
|
|
@ -1246,6 +1412,21 @@ alloc:
|
|||
|
||||
if (buf_page_is_old(b)) {
|
||||
buf_pool->LRU_old_len++;
|
||||
if (UNIV_UNLIKELY
|
||||
(buf_pool->LRU_old
|
||||
== UT_LIST_GET_NEXT(LRU, b))) {
|
||||
|
||||
buf_pool->LRU_old = b;
|
||||
}
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
} else {
|
||||
ut_a(!prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
|
@ -1455,6 +1636,8 @@ buf_LRU_block_remove_hashed_page(
|
|||
buf_block_modify_clock_inc((buf_block_t*) bpage);
|
||||
if (bpage->zip.data) {
|
||||
const page_t* page = ((buf_block_t*) bpage)->frame;
|
||||
const ulint zip_size
|
||||
= page_zip_get_size(&bpage->zip);
|
||||
|
||||
ut_a(!zip || bpage->oldest_modification == 0);
|
||||
|
||||
|
|
@ -1472,7 +1655,7 @@ buf_LRU_block_remove_hashed_page(
|
|||
to the compressed page, which will
|
||||
be preserved. */
|
||||
memcpy(bpage->zip.data, page,
|
||||
page_zip_get_size(&bpage->zip));
|
||||
zip_size);
|
||||
}
|
||||
break;
|
||||
case FIL_PAGE_TYPE_ZBLOB:
|
||||
|
|
@ -1484,6 +1667,15 @@ buf_LRU_block_remove_hashed_page(
|
|||
#endif /* UNIV_ZIP_DEBUG */
|
||||
break;
|
||||
default:
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: ERROR: The compressed page"
|
||||
" to be evicted seems corrupt:", stderr);
|
||||
ut_print_buf(stderr, page, zip_size);
|
||||
fputs("\nInnoDB: Possibly older version"
|
||||
" of the page:", stderr);
|
||||
ut_print_buf(stderr, bpage->zip.data,
|
||||
zip_size);
|
||||
putc('\n', stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -607,6 +607,7 @@ dtuple_convert_big_rec(
|
|||
while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry,
|
||||
*n_ext),
|
||||
dict_table_is_comp(index->table),
|
||||
dict_index_get_n_fields(index),
|
||||
dict_table_zip_size(index->table))) {
|
||||
ulint i;
|
||||
ulint longest = 0;
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ dict_hdr_get(
|
|||
block = buf_page_get(DICT_HDR_SPACE, 0, DICT_HDR_PAGE_NO,
|
||||
RW_X_LATCH, mtr);
|
||||
header = DICT_HDR + buf_block_get_frame(block);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_DICT_HEADER);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(header);
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +279,8 @@ dict_boot(void)
|
|||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_TABLES,
|
||||
MLOG_4BYTES, &mtr));
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
/*-------------------------*/
|
||||
|
|
@ -291,7 +292,8 @@ dict_boot(void)
|
|||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_TABLE_IDS,
|
||||
MLOG_4BYTES, &mtr));
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
/*-------------------------*/
|
||||
|
|
@ -322,7 +324,8 @@ dict_boot(void)
|
|||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_COLUMNS,
|
||||
MLOG_4BYTES, &mtr));
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
/*-------------------------*/
|
||||
|
|
@ -363,7 +366,8 @@ dict_boot(void)
|
|||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_INDEXES,
|
||||
MLOG_4BYTES, &mtr));
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
/*-------------------------*/
|
||||
|
|
@ -389,7 +393,8 @@ dict_boot(void)
|
|||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_FIELDS,
|
||||
MLOG_4BYTES, &mtr));
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ dict_build_table_def_step(
|
|||
const char* path_or_name;
|
||||
ibool is_path;
|
||||
mtr_t mtr;
|
||||
ulint i;
|
||||
ulint row_len;
|
||||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
|
|
@ -227,14 +225,6 @@ dict_build_table_def_step(
|
|||
|
||||
thr_get_trx(thr)->table_id = table->id;
|
||||
|
||||
row_len = 0;
|
||||
for (i = 0; i < table->n_def; i++) {
|
||||
row_len += dict_col_get_min_size(&table->cols[i]);
|
||||
}
|
||||
if (row_len > BTR_PAGE_MAX_REC_SIZE) {
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
|
||||
if (srv_file_per_table) {
|
||||
/* We create a new single-table tablespace for the table.
|
||||
We initially let it be 4 pages:
|
||||
|
|
@ -543,11 +533,7 @@ dict_build_index_def_step(
|
|||
ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
|
||||
|| dict_index_is_clust(index));
|
||||
|
||||
/* For fast index creation we have already allocated an index id
|
||||
for this index so that we could write an UNDO log record for it.*/
|
||||
if (ut_dulint_is_zero(index->id)) {
|
||||
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
|
||||
}
|
||||
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
|
||||
|
||||
/* Inherit the space id from the table; we store all indexes of a
|
||||
table in the same tablespace */
|
||||
|
|
@ -1093,7 +1079,7 @@ dict_create_index_step(
|
|||
dulint index_id = node->index->id;
|
||||
|
||||
err = dict_index_add_to_cache(node->table, node->index,
|
||||
FIL_NULL);
|
||||
FIL_NULL, trx_is_strict(trx));
|
||||
|
||||
node->index = dict_index_get_if_in_cache_low(index_id);
|
||||
ut_a(!node->index == (err != DB_SUCCESS));
|
||||
|
|
@ -1239,7 +1225,6 @@ dict_create_or_check_foreign_constraint_tables(void)
|
|||
" FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
|
||||
"CREATE UNIQUE CLUSTERED INDEX ID_IND"
|
||||
" ON SYS_FOREIGN_COLS (ID, POS);\n"
|
||||
"COMMIT WORK;\n"
|
||||
"END;\n"
|
||||
, FALSE, trx);
|
||||
|
||||
|
|
@ -1262,7 +1247,7 @@ dict_create_or_check_foreign_constraint_tables(void)
|
|||
error = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
}
|
||||
|
||||
trx->op_info = "";
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
|
|
|
|||
472
dict/dict0dict.c
472
dict/dict0dict.c
|
|
@ -22,6 +22,8 @@ Created 1/8/1996 Heikki Tuuri
|
|||
#include "btr0btr.h"
|
||||
#include "btr0cur.h"
|
||||
#include "btr0sea.h"
|
||||
#include "page0zip.h"
|
||||
#include "page0page.h"
|
||||
#include "pars0pars.h"
|
||||
#include "pars0sym.h"
|
||||
#include "que0que.h"
|
||||
|
|
@ -55,56 +57,6 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
|
|||
/* Identifies generated InnoDB foreign key names */
|
||||
static char dict_ibfk[] = "_ibfk_";
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 5 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 3 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_casedn_str(
|
||||
/*================*/
|
||||
char* a); /* in/out: string to put in lower case */
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd); /* in: MySQL thread handle */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/***********************************************************************
|
||||
Tries to find column names for the index and sets the col field of the
|
||||
index. */
|
||||
|
|
@ -335,8 +287,7 @@ dict_table_autoinc_lock(
|
|||
}
|
||||
|
||||
/************************************************************************
|
||||
Initializes the autoinc counter. It is not an error to initialize an already
|
||||
initialized counter. */
|
||||
Unconditionally set the autoinc counter. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_table_autoinc_initialize(
|
||||
|
|
@ -346,7 +297,6 @@ dict_table_autoinc_initialize(
|
|||
{
|
||||
ut_ad(mutex_own(&table->autoinc_mutex));
|
||||
|
||||
table->autoinc_inited = TRUE;
|
||||
table->autoinc = value;
|
||||
}
|
||||
|
||||
|
|
@ -360,32 +310,25 @@ dict_table_autoinc_read(
|
|||
/* out: value for a new row, or 0 */
|
||||
const dict_table_t* table) /* in: table */
|
||||
{
|
||||
ib_int64_t value;
|
||||
|
||||
ut_ad(mutex_own(&table->autoinc_mutex));
|
||||
|
||||
if (!table->autoinc_inited) {
|
||||
|
||||
value = 0;
|
||||
} else {
|
||||
value = table->autoinc;
|
||||
}
|
||||
|
||||
return(value);
|
||||
return(table->autoinc);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Updates the autoinc counter if the value supplied is greater than the
|
||||
current value. If not inited, does nothing. */
|
||||
current value. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_table_autoinc_update(
|
||||
/*======================*/
|
||||
dict_table_autoinc_update_if_greater(
|
||||
/*=================================*/
|
||||
|
||||
dict_table_t* table, /* in/out: table */
|
||||
ib_uint64_t value) /* in: value which was assigned to a row */
|
||||
{
|
||||
if (table->autoinc_inited && value > table->autoinc) {
|
||||
ut_ad(mutex_own(&table->autoinc_mutex));
|
||||
|
||||
if (value > table->autoinc) {
|
||||
|
||||
table->autoinc = value;
|
||||
}
|
||||
|
|
@ -1312,6 +1255,156 @@ is_ord_part:
|
|||
return(undo_page_len >= UNIV_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
If a record of this index might not fit on a single B-tree page,
|
||||
return TRUE. */
|
||||
static
|
||||
ibool
|
||||
dict_index_too_big_for_tree(
|
||||
/*========================*/
|
||||
/* out: TRUE if the index
|
||||
record could become too big */
|
||||
const dict_table_t* table, /* in: table */
|
||||
const dict_index_t* new_index) /* in: index */
|
||||
{
|
||||
ulint zip_size;
|
||||
ulint comp;
|
||||
ulint i;
|
||||
/* maximum possible storage size of a record */
|
||||
ulint rec_max_size;
|
||||
/* maximum allowed size of a record on a leaf page */
|
||||
ulint page_rec_max;
|
||||
/* maximum allowed size of a node pointer record */
|
||||
ulint page_ptr_max;
|
||||
|
||||
comp = dict_table_is_comp(table);
|
||||
zip_size = dict_table_zip_size(table);
|
||||
|
||||
if (zip_size && zip_size < UNIV_PAGE_SIZE) {
|
||||
/* On a compressed page, two records must fit in the
|
||||
uncompressed page modification log. On compressed
|
||||
pages with zip_size == UNIV_PAGE_SIZE, this limit will
|
||||
never be reached. */
|
||||
ut_ad(comp);
|
||||
/* The maximum allowed record size is the size of
|
||||
an empty page, minus a byte for recoding the heap
|
||||
number in the page modification log. The maximum
|
||||
allowed node pointer size is half that. */
|
||||
page_rec_max = page_zip_empty_size(new_index->n_fields,
|
||||
zip_size) - 1;
|
||||
page_ptr_max = page_rec_max / 2;
|
||||
/* On a compressed page, there is a two-byte entry in
|
||||
the dense page directory for every record. But there
|
||||
is no record header. */
|
||||
rec_max_size = 2;
|
||||
} else {
|
||||
/* The maximum allowed record size is half a B-tree
|
||||
page. No additional sparse page directory entry will
|
||||
be generated for the first few user records. */
|
||||
page_rec_max = page_get_free_space_of_empty(comp) / 2;
|
||||
page_ptr_max = page_rec_max;
|
||||
/* Each record has a header. */
|
||||
rec_max_size = comp
|
||||
? REC_N_NEW_EXTRA_BYTES
|
||||
: REC_N_OLD_EXTRA_BYTES;
|
||||
}
|
||||
|
||||
if (comp) {
|
||||
/* Include the "null" flags in the
|
||||
maximum possible record size. */
|
||||
rec_max_size += UT_BITS_IN_BYTES(new_index->n_nullable);
|
||||
} else {
|
||||
/* For each column, include a 2-byte offset and a
|
||||
"null" flag. The 1-byte format is only used in short
|
||||
records that do not contain externally stored columns.
|
||||
Such records could never exceed the page limit, even
|
||||
when using the 2-byte format. */
|
||||
rec_max_size += 2 * new_index->n_fields;
|
||||
}
|
||||
|
||||
/* Compute the maximum possible record size. */
|
||||
for (i = 0; i < new_index->n_fields; i++) {
|
||||
const dict_field_t* field
|
||||
= dict_index_get_nth_field(new_index, i);
|
||||
const dict_col_t* col
|
||||
= dict_field_get_col(field);
|
||||
ulint field_max_size;
|
||||
ulint field_ext_max_size;
|
||||
|
||||
/* In dtuple_convert_big_rec(), variable-length columns
|
||||
that are longer than BTR_EXTERN_FIELD_REF_SIZE * 2
|
||||
may be chosen for external storage.
|
||||
|
||||
Fixed-length columns, and all columns of secondary
|
||||
index records are always stored inline. */
|
||||
|
||||
/* Determine the maximum length of the index field.
|
||||
The field_ext_max_size should be computed as the worst
|
||||
case in rec_get_converted_size_comp() for
|
||||
REC_STATUS_ORDINARY records. */
|
||||
|
||||
field_max_size = dict_col_get_fixed_size(col);
|
||||
if (field_max_size) {
|
||||
/* dict_index_add_col() should guarantee this */
|
||||
ut_ad(!field->prefix_len
|
||||
|| field->fixed_len == field->prefix_len);
|
||||
/* Fixed lengths are not encoded
|
||||
in ROW_FORMAT=COMPACT. */
|
||||
field_ext_max_size = 0;
|
||||
goto add_field_size;
|
||||
}
|
||||
|
||||
field_max_size = dict_col_get_max_size(col);
|
||||
field_ext_max_size = field_max_size < 256 ? 1 : 2;
|
||||
|
||||
if (field->prefix_len) {
|
||||
if (field->prefix_len < field_max_size) {
|
||||
field_max_size = field->prefix_len;
|
||||
}
|
||||
} else if (field_max_size > BTR_EXTERN_FIELD_REF_SIZE * 2
|
||||
&& dict_index_is_clust(new_index)) {
|
||||
|
||||
/* In the worst case, we have a locally stored
|
||||
column of BTR_EXTERN_FIELD_REF_SIZE * 2 bytes.
|
||||
The length can be stored in one byte. If the
|
||||
column were stored externally, the lengths in
|
||||
the clustered index page would be
|
||||
BTR_EXTERN_FIELD_REF_SIZE and 2. */
|
||||
field_max_size = BTR_EXTERN_FIELD_REF_SIZE * 2;
|
||||
field_ext_max_size = 1;
|
||||
}
|
||||
|
||||
if (comp) {
|
||||
/* Add the extra size for ROW_FORMAT=COMPACT.
|
||||
For ROW_FORMAT=REDUNDANT, these bytes were
|
||||
added to rec_max_size before this loop. */
|
||||
rec_max_size += field_ext_max_size;
|
||||
}
|
||||
add_field_size:
|
||||
rec_max_size += field_max_size;
|
||||
|
||||
/* Check the size limit on leaf pages. */
|
||||
if (UNIV_UNLIKELY(rec_max_size >= page_rec_max)) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* Check the size limit on non-leaf pages. Records
|
||||
stored in non-leaf B-tree pages consist of the unique
|
||||
columns of the record (the key columns of the B-tree)
|
||||
and a node pointer field. When we have processed the
|
||||
unique columns, rec_max_size equals the size of the
|
||||
node pointer record minus the node pointer column. */
|
||||
if (i + 1 == dict_index_get_n_unique_in_tree(new_index)
|
||||
&& rec_max_size + REC_NODE_PTR_SIZE >= page_ptr_max) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Adds an index to the dictionary cache. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -1322,7 +1415,10 @@ dict_index_add_to_cache(
|
|||
dict_table_t* table, /* in: table on which the index is */
|
||||
dict_index_t* index, /* in, own: index; NOTE! The index memory
|
||||
object is freed in this function! */
|
||||
ulint page_no)/* in: root page number of the index */
|
||||
ulint page_no,/* in: root page number of the index */
|
||||
ibool strict) /* in: TRUE=refuse to create the index
|
||||
if records could be too big to fit in
|
||||
an B-tree page */
|
||||
{
|
||||
dict_index_t* new_index;
|
||||
ulint n_ord;
|
||||
|
|
@ -1353,12 +1449,42 @@ dict_index_add_to_cache(
|
|||
|
||||
new_index->n_fields = new_index->n_def;
|
||||
|
||||
if (strict && dict_index_too_big_for_tree(table, new_index)) {
|
||||
too_big:
|
||||
dict_mem_index_free(new_index);
|
||||
dict_mem_index_free(index);
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
|
||||
n_ord = new_index->n_fields;
|
||||
} else {
|
||||
n_ord = new_index->n_uniq;
|
||||
}
|
||||
|
||||
switch (dict_table_get_format(table)) {
|
||||
case DICT_TF_FORMAT_51:
|
||||
/* ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT store
|
||||
prefixes of externally stored columns locally within
|
||||
the record. There are no special considerations for
|
||||
the undo log record size. */
|
||||
goto undo_size_ok;
|
||||
|
||||
case DICT_TF_FORMAT_ZIP:
|
||||
/* In ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED,
|
||||
column prefix indexes require that prefixes of
|
||||
externally stored columns are written to the undo log.
|
||||
This may make the undo log record bigger than the
|
||||
record on the B-tree page. The maximum size of an
|
||||
undo log record is the page size. That must be
|
||||
checked for below. */
|
||||
break;
|
||||
|
||||
#if DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX
|
||||
# error "DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX"
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < n_ord; i++) {
|
||||
const dict_field_t* field
|
||||
= dict_index_get_nth_field(new_index, i);
|
||||
|
|
@ -1384,15 +1510,15 @@ dict_index_add_to_cache(
|
|||
if (dict_index_too_big_for_undo(table, new_index)) {
|
||||
/* An undo log record might not fit in
|
||||
a single page. Refuse to create this index. */
|
||||
dict_mem_index_free(new_index);
|
||||
dict_mem_index_free(index);
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
|
||||
goto too_big;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
undo_size_ok:
|
||||
/* Flag the ordering columns */
|
||||
|
||||
for (i = 0; i < n_ord; i++) {
|
||||
|
|
@ -1446,12 +1572,59 @@ dict_index_remove_from_cache(
|
|||
dict_index_t* index) /* in, own: index */
|
||||
{
|
||||
ulint size;
|
||||
ulint retries = 0;
|
||||
btr_search_t* info;
|
||||
|
||||
ut_ad(table && index);
|
||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
/* We always create search info whether or not adaptive
|
||||
hash index is enabled or not. */
|
||||
info = index->search_info;
|
||||
ut_ad(info);
|
||||
|
||||
/* We are not allowed to free the in-memory index struct
|
||||
dict_index_t until all entries in the adaptive hash index
|
||||
that point to any of the page belonging to his b-tree index
|
||||
are dropped. This is so because dropping of these entries
|
||||
require access to dict_index_t struct. To avoid such scenario
|
||||
We keep a count of number of such pages in the search_info and
|
||||
only free the dict_index_t struct when this count drops to
|
||||
zero. */
|
||||
|
||||
for (;;) {
|
||||
ulint ref_count = btr_search_info_get_ref_count(info);
|
||||
if (ref_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sleep for 10ms before trying again. */
|
||||
os_thread_sleep(10000);
|
||||
++retries;
|
||||
|
||||
if (retries % 500 == 0) {
|
||||
/* No luck after 5 seconds of wait. */
|
||||
fprintf(stderr, "InnoDB: Error: Waited for"
|
||||
" %lu secs for hash index"
|
||||
" ref_count (%lu) to drop"
|
||||
" to 0.\n"
|
||||
"index: \"%s\""
|
||||
" table: \"%s\"\n",
|
||||
retries/100,
|
||||
ref_count,
|
||||
index->name,
|
||||
table->name);
|
||||
}
|
||||
|
||||
/* To avoid a hang here we commit suicide if the
|
||||
ref_count doesn't drop to zero in 600 seconds. */
|
||||
if (retries >= 60000) {
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
|
||||
rw_lock_free(&index->lock);
|
||||
|
||||
/* Remove the index from the list of indexes of the table */
|
||||
|
|
@ -1901,27 +2074,19 @@ dict_table_get_referenced_constraint(
|
|||
dict_table_t* table, /* in: InnoDB table */
|
||||
dict_index_t* index) /* in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign = NULL;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index && table);
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
/* If the referenced list is empty, nothing to do */
|
||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
||||
|
||||
if (UT_LIST_GET_LEN(table->referenced_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->referenced_index == index
|
||||
|| foreign->referenced_index == index) {
|
||||
if (foreign->referenced_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -1940,29 +2105,20 @@ dict_table_get_foreign_constraint(
|
|||
dict_table_t* table, /* in: InnoDB table */
|
||||
dict_index_t* index) /* in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign = NULL;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index && table);
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
/* If list empty then nothgin to do */
|
||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
||||
|
||||
if (UT_LIST_GET_LEN(table->foreign_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Check whether this index is defined for a foreign key */
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->foreign_index == index
|
||||
|| foreign->referenced_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -2132,6 +2288,30 @@ next_rec:
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Find an index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_foreign_find_equiv_index(
|
||||
/*==========================*/
|
||||
/* out: index equivalent to
|
||||
foreign->foreign_index, or NULL */
|
||||
dict_foreign_t* foreign)/* in: foreign key */
|
||||
{
|
||||
ut_a(foreign != NULL);
|
||||
|
||||
/* Try to find an index which contains the columns as the
|
||||
first fields and in the right order, and the types are the
|
||||
same as in foreign->foreign_index */
|
||||
|
||||
return(dict_foreign_find_index(
|
||||
foreign->foreign_table,
|
||||
foreign->foreign_col_names, foreign->n_fields,
|
||||
foreign->foreign_index, TRUE, /* check types */
|
||||
FALSE/* allow columns to be NULL */));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns an index object by matching on the name and column names and
|
||||
if more than one index matches return the index with the max id */
|
||||
|
|
@ -2362,7 +2542,7 @@ dict_foreign_add_to_cache(
|
|||
Scans from pointer onwards. Stops if is at the start of a copy of
|
||||
'string' where characters are compared without case sensitivity, and
|
||||
only outside `` or "" quotes. Stops also at '\0'. */
|
||||
UNIV_INTERN
|
||||
static
|
||||
const char*
|
||||
dict_scan_to(
|
||||
/*=========*/
|
||||
|
|
@ -2537,7 +2717,7 @@ convert_id:
|
|||
len = 3 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
innobase_convert_from_id(dst, str, len);
|
||||
innobase_convert_from_id(cs, dst, str, len);
|
||||
} else if (!strncmp(str, srv_mysql50_table_name_prefix,
|
||||
sizeof srv_mysql50_table_name_prefix)) {
|
||||
/* This is a pre-5.1 table name
|
||||
|
|
@ -2551,7 +2731,7 @@ convert_id:
|
|||
len = 5 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
innobase_convert_from_table_id(dst, str, len);
|
||||
innobase_convert_from_table_id(cs, dst, str, len);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
|
@ -3468,25 +3648,6 @@ try_find_index:
|
|||
goto loop;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines whether a string starts with the specified keyword. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
/* out: TRUE if str starts
|
||||
with keyword */
|
||||
void* mysql_thd, /* in: MySQL thread handle */
|
||||
const char* str, /* in: string to scan for keyword */
|
||||
const char* keyword) /* in: keyword to look for */
|
||||
{
|
||||
struct charset_info_st* cs = innobase_get_charset(mysql_thd);
|
||||
ibool success;
|
||||
|
||||
dict_accept(cs, str, keyword, &success);
|
||||
return(success);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Scans a table create SQL string and adds to the data dictionary the foreign
|
||||
key constraints declared in the string. This function should be called after
|
||||
|
|
@ -4455,41 +4616,6 @@ dict_table_get_index_on_name(
|
|||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Find and index that is equivalent to the one passed in. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_table_find_equivalent_index(
|
||||
/*=============================*/
|
||||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index) /* in: index to match */
|
||||
{
|
||||
ulint i;
|
||||
const char** column_names;
|
||||
dict_index_t* equiv_index;
|
||||
|
||||
if (UT_LIST_GET_LEN(table->foreign_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
column_names = mem_alloc(index->n_fields * sizeof *column_names);
|
||||
|
||||
/* Convert the column names to the format & type accepted by the find
|
||||
index function */
|
||||
for (i = 0; i < index->n_fields; i++) {
|
||||
column_names[i] = index->fields[i].name;
|
||||
}
|
||||
|
||||
equiv_index = dict_foreign_find_index(
|
||||
table, column_names, index->n_fields,
|
||||
index, TRUE, FALSE);
|
||||
|
||||
mem_free((void*) column_names);
|
||||
|
||||
return(equiv_index);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Replace the index passed in with another equivalent index in the tables
|
||||
foreign key list. */
|
||||
|
|
@ -4500,30 +4626,18 @@ dict_table_replace_index_in_foreign_list(
|
|||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index) /* in: index to be replaced */
|
||||
{
|
||||
dict_index_t* new_index;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
new_index = dict_table_find_equivalent_index(table, index);
|
||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
||||
|
||||
/* If match found */
|
||||
if (new_index) {
|
||||
dict_foreign_t* foreign;
|
||||
if (foreign->foreign_index == index) {
|
||||
dict_index_t* new_index
|
||||
= dict_foreign_find_equiv_index(foreign);
|
||||
ut_a(new_index);
|
||||
|
||||
ut_a(new_index != index);
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
|
||||
/* If the list is not empty then this should hold */
|
||||
ut_a(foreign);
|
||||
|
||||
/* Iterate over the foreign index list and replace the index
|
||||
passed in with the new index */
|
||||
while (foreign) {
|
||||
|
||||
if (foreign->foreign_index == index) {
|
||||
foreign->foreign_index = new_index;
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
||||
foreign->foreign_index = new_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -765,7 +765,8 @@ dict_load_indexes(
|
|||
index->id = id;
|
||||
|
||||
dict_load_fields(index, heap);
|
||||
error = dict_index_add_to_cache(table, index, page_no);
|
||||
error = dict_index_add_to_cache(table, index, page_no,
|
||||
FALSE);
|
||||
/* The data dictionary tables should never contain
|
||||
invalid index definitions. If we ignored this error
|
||||
and simply did not load this index definition, the
|
||||
|
|
|
|||
|
|
@ -58,13 +58,15 @@ dict_mem_table_create(
|
|||
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
|
||||
* sizeof(dict_col_t));
|
||||
|
||||
table->auto_inc_lock = mem_heap_alloc(heap, lock_get_size());
|
||||
table->autoinc_lock = mem_heap_alloc(heap, lock_get_size());
|
||||
|
||||
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
|
||||
|
||||
/* The actual increment value will be set by MySQL, we simply
|
||||
default to 1 here.*/
|
||||
table->autoinc_increment = 1;
|
||||
table->autoinc = 0;
|
||||
|
||||
/* The number of transactions that are either waiting on the
|
||||
AUTOINC lock or have been granted the lock. */
|
||||
table->n_waiting_or_granted_auto_inc_locks = 0;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
table->magic_n = DICT_TABLE_MAGIC_N;
|
||||
|
|
|
|||
|
|
@ -4312,18 +4312,16 @@ fil_io(
|
|||
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|
||||
|| !ibuf_bitmap_page(zip_size, block_offset)
|
||||
|| sync || is_log);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|
||||
|| ibuf_page(space_id, zip_size, block_offset));
|
||||
#endif
|
||||
#endif
|
||||
if (sync) {
|
||||
mode = OS_AIO_SYNC;
|
||||
} else if (type == OS_FILE_READ && !is_log
|
||||
&& ibuf_page(space_id, zip_size, block_offset)) {
|
||||
mode = OS_AIO_IBUF;
|
||||
} else if (is_log) {
|
||||
mode = OS_AIO_LOG;
|
||||
} else if (type == OS_FILE_READ
|
||||
&& ibuf_page(space_id, zip_size, block_offset)) {
|
||||
mode = OS_AIO_IBUF;
|
||||
} else {
|
||||
mode = OS_AIO_NORMAL;
|
||||
}
|
||||
|
|
@ -4492,8 +4490,6 @@ fil_aio_wait(
|
|||
#ifdef WIN_ASYNC_IO
|
||||
ret = os_aio_windows_handle(segment, 0, &fil_node,
|
||||
&message, &type);
|
||||
#elif defined(POSIX_ASYNC_IO)
|
||||
ret = os_aio_posix_handle(segment, &fil_node, &message);
|
||||
#else
|
||||
ret = 0; /* Eliminate compiler warning */
|
||||
ut_error;
|
||||
|
|
|
|||
|
|
@ -345,9 +345,8 @@ fsp_get_space_header(
|
|||
|
||||
block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
|
||||
header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
ut_ad(id == mach_read_from_4(FSP_SPACE_ID + header));
|
||||
ut_ad(zip_size == dict_table_flags_to_zip_size(
|
||||
mach_read_from_4(FSP_SPACE_FLAGS + header)));
|
||||
|
|
@ -700,6 +699,7 @@ xdes_get_descriptor_with_space_hdr(
|
|||
MTR_MEMO_X_LOCK));
|
||||
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
|
||||
|| mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
|
||||
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
|
||||
/* Read free limit and space size */
|
||||
limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
|
||||
size = mach_read_from_4(sp_header + FSP_SIZE);
|
||||
|
|
@ -730,9 +730,8 @@ xdes_get_descriptor_with_space_hdr(
|
|||
|
||||
block = buf_page_get(space, zip_size, descr_page_no,
|
||||
RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
descr_page = buf_block_get_frame(block);
|
||||
}
|
||||
|
||||
|
|
@ -765,9 +764,8 @@ xdes_get_descriptor(
|
|||
fsp_header_t* sp_header;
|
||||
|
||||
block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
|
||||
return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset,
|
||||
mtr));
|
||||
|
|
@ -948,9 +946,7 @@ fsp_header_init(
|
|||
zip_size = dict_table_flags_to_zip_size(flags);
|
||||
block = buf_page_create(space, 0, zip_size, mtr);
|
||||
buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
/* The prior contents of the file page should be ignored */
|
||||
|
||||
|
|
@ -1316,6 +1312,7 @@ fsp_fill_free_list(
|
|||
mtr_t ibuf_mtr;
|
||||
|
||||
ut_ad(header && mtr);
|
||||
ut_ad(page_offset(header) == FSP_HEADER_OFFSET);
|
||||
|
||||
/* Check if we can fill free list from above the free list limit */
|
||||
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
|
||||
|
|
@ -1380,10 +1377,9 @@ fsp_fill_free_list(
|
|||
space, i, zip_size, mtr);
|
||||
buf_page_get(space, zip_size, i,
|
||||
RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block,
|
||||
SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
fsp_init_file_page(block, mtr);
|
||||
mlog_write_ulint(buf_block_get_frame(block)
|
||||
+ FIL_PAGE_TYPE,
|
||||
|
|
@ -1404,9 +1400,8 @@ fsp_fill_free_list(
|
|||
buf_page_get(space, zip_size,
|
||||
i + FSP_IBUF_BITMAP_OFFSET,
|
||||
RW_X_LATCH, &ibuf_mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
fsp_init_file_page(block, &ibuf_mtr);
|
||||
|
||||
ibuf_bitmap_page_init(block, &ibuf_mtr);
|
||||
|
|
@ -1577,6 +1572,7 @@ fsp_alloc_free_page(
|
|||
if (free == ULINT_UNDEFINED) {
|
||||
|
||||
ut_print_buf(stderr, ((byte*)descr) - 500, 1000);
|
||||
putc('\n', stderr);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
|
@ -1636,9 +1632,7 @@ fsp_alloc_free_page(
|
|||
buf_page_create(space, page_no, zip_size, mtr);
|
||||
|
||||
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
/* Prior contents of the page should be ignored */
|
||||
fsp_init_file_page(block, mtr);
|
||||
|
|
@ -1760,6 +1754,7 @@ fsp_free_extent(
|
|||
if (xdes_get_state(descr, mtr) == XDES_FREE) {
|
||||
|
||||
ut_print_buf(stderr, (byte*)descr - 500, 1000);
|
||||
putc('\n', stderr);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
|
@ -1867,6 +1862,8 @@ fsp_alloc_seg_inode_page(
|
|||
ulint zip_size;
|
||||
ulint i;
|
||||
|
||||
ut_ad(page_offset(space_header) == FSP_HEADER_OFFSET);
|
||||
|
||||
space = page_get_space_id(page_align(space_header));
|
||||
zip_size = dict_table_flags_to_zip_size(
|
||||
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
|
||||
|
|
@ -1879,9 +1876,7 @@ fsp_alloc_seg_inode_page(
|
|||
}
|
||||
|
||||
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
block->check_index_page_at_flush = FALSE;
|
||||
|
||||
|
|
@ -1922,6 +1917,8 @@ fsp_alloc_seg_inode(
|
|||
ulint zip_size;
|
||||
ulint n;
|
||||
|
||||
ut_ad(page_offset(space_header) == FSP_HEADER_OFFSET);
|
||||
|
||||
if (flst_get_len(space_header + FSP_SEG_INODES_FREE, mtr) == 0) {
|
||||
/* Allocate a new segment inode page */
|
||||
|
||||
|
|
@ -1939,9 +1936,8 @@ fsp_alloc_seg_inode(
|
|||
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
|
||||
block = buf_page_get(page_get_space_id(page_align(space_header)),
|
||||
zip_size, page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
|
||||
|
|
@ -2402,6 +2398,7 @@ fseg_fill_free_list(
|
|||
ulint used;
|
||||
|
||||
ut_ad(inode && mtr);
|
||||
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
|
||||
reserved = fseg_n_reserved_pages_low(inode, &used, mtr);
|
||||
|
||||
|
|
@ -2462,6 +2459,8 @@ fseg_alloc_free_extent(
|
|||
dulint seg_id;
|
||||
fil_addr_t first;
|
||||
|
||||
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
|
||||
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
|
||||
/* Segment free list is not empty, allocate from it */
|
||||
|
||||
|
|
@ -2531,6 +2530,7 @@ fseg_alloc_free_page_low(
|
|||
ut_ad((direction >= FSP_UP) && (direction <= FSP_NO_DIR));
|
||||
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr);
|
||||
|
||||
ut_ad(!ut_dulint_is_zero(seg_id));
|
||||
|
|
@ -2712,9 +2712,8 @@ fseg_alloc_free_page_low(
|
|||
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
|
||||
|
||||
block = buf_page_create(space, ret_page, zip_size, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size,
|
||||
ret_page, RW_X_LATCH,
|
||||
mtr))) {
|
||||
|
|
@ -3121,6 +3120,7 @@ fseg_mark_page_used(
|
|||
ulint not_full_n_used;
|
||||
|
||||
ut_ad(seg_inode && mtr);
|
||||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
|
||||
descr = xdes_get_descriptor(space, zip_size, page, mtr);
|
||||
|
||||
|
|
@ -3183,6 +3183,7 @@ fseg_free_page_low(
|
|||
ut_ad(seg_inode && mtr);
|
||||
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
|
||||
== FSEG_MAGIC_N_VALUE);
|
||||
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
|
||||
|
||||
/* Drop search system page hash index if the page is found in
|
||||
the pool and is hashed */
|
||||
|
|
|
|||
21
ha/ha0ha.c
21
ha/ha0ha.c
|
|
@ -373,11 +373,20 @@ ha_print_info(
|
|||
FILE* file, /* in: file where to print */
|
||||
hash_table_t* table) /* in: hash table */
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Some of the code here is disabled for performance reasons in production
|
||||
builds, see http://bugs.mysql.com/36941 */
|
||||
#define PRINT_USED_CELLS
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
hash_cell_t* cell;
|
||||
ulint cells = 0;
|
||||
ulint n_bufs;
|
||||
ulint i;
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
ulint n_bufs;
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
for (i = 0; i < hash_get_n_cells(table); i++) {
|
||||
|
||||
cell = hash_get_nth_cell(table, i);
|
||||
|
|
@ -387,10 +396,14 @@ ha_print_info(
|
|||
cells++;
|
||||
}
|
||||
}
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
|
||||
fprintf(file,
|
||||
"Hash table size %lu, used cells %lu",
|
||||
(ulong) hash_get_n_cells(table), (ulong) cells);
|
||||
fprintf(file, "Hash table size %lu",
|
||||
(ulong) hash_get_n_cells(table));
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
fprintf(file, ", used cells %lu", (ulong) cells);
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
|
||||
if (table->heaps == NULL && table->heap != NULL) {
|
||||
|
||||
|
|
|
|||
4
ha_innodb.def
Normal file
4
ha_innodb.def
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
EXPORTS
|
||||
_mysql_plugin_interface_version_
|
||||
_mysql_sizeof_struct_st_plugin_
|
||||
_mysql_plugin_declarations_
|
||||
1219
handler/ha_innodb.cc
1219
handler/ha_innodb.cc
File diff suppressed because it is too large
Load diff
|
|
@ -73,12 +73,15 @@ class ha_innobase: public handler
|
|||
void update_thd();
|
||||
int change_active_index(uint keynr);
|
||||
int general_fetch(uchar* buf, uint direction, uint match_mode);
|
||||
int innobase_read_and_init_auto_inc(ulonglong* ret);
|
||||
ulong innobase_autoinc_lock();
|
||||
ulong innobase_set_max_autoinc(ulonglong auto_inc);
|
||||
ulong innobase_reset_autoinc(ulonglong auto_inc);
|
||||
ulong innobase_get_auto_increment(ulonglong* value);
|
||||
ulint innobase_lock_autoinc();
|
||||
ulonglong innobase_peek_autoinc();
|
||||
ulint innobase_set_max_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_reset_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_get_autoinc(ulonglong* value);
|
||||
ulint innobase_update_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_initialize_autoinc();
|
||||
dict_index_t* innobase_get_index(uint keynr);
|
||||
ulonglong innobase_get_int_col_max_value(const Field* field);
|
||||
|
||||
/* Init values for the class: */
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "ha_innodb.h"
|
||||
#include "handler0vars.h"
|
||||
|
||||
/*****************************************************************
|
||||
Copies an InnoDB column to a MySQL field. This function is
|
||||
|
|
@ -635,9 +636,6 @@ ha_innobase::add_index(
|
|||
trx = trx_allocate_for_mysql();
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trans_register_ha(user_thd, FALSE, ht);
|
||||
prebuilt->trx->active_trans = 1;
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
|
|
@ -801,7 +799,9 @@ error_handling:
|
|||
const char* old_name;
|
||||
char* tmp_name;
|
||||
case DB_SUCCESS:
|
||||
ut_ad(!dict_locked);
|
||||
ut_a(!dict_locked);
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
dict_locked = TRUE;
|
||||
|
||||
if (!new_primary) {
|
||||
error = row_merge_rename_indexes(trx, indexed_table);
|
||||
|
|
@ -822,9 +822,6 @@ error_handling:
|
|||
tmp_name = innobase_create_temporary_tablename(heap, '2',
|
||||
old_name);
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
dict_locked = TRUE;
|
||||
|
||||
error = row_merge_rename_tables(innodb_table, indexed_table,
|
||||
tmp_name, trx);
|
||||
|
||||
|
|
@ -868,6 +865,11 @@ error:
|
|||
if (new_primary) {
|
||||
row_merge_drop_table(trx, indexed_table);
|
||||
} else {
|
||||
if (!dict_locked) {
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
dict_locked = TRUE;
|
||||
}
|
||||
|
||||
row_merge_drop_indexes(trx, indexed_table,
|
||||
index, num_created);
|
||||
}
|
||||
|
|
@ -986,15 +988,16 @@ ha_innobase::prepare_drop_index(
|
|||
|
||||
if (trx->check_foreigns
|
||||
&& thd_sql_command(user_thd) != SQLCOM_CREATE_INDEX) {
|
||||
dict_index_t* index
|
||||
= dict_table_get_first_index(prebuilt->table);
|
||||
dict_index_t* index;
|
||||
|
||||
do {
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
index;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
if (!index->to_be_dropped) {
|
||||
|
||||
goto next_index;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the index is referenced. */
|
||||
|
|
@ -1022,20 +1025,61 @@ index_needed:
|
|||
ut_a(foreign->foreign_index == index);
|
||||
|
||||
/* Search for an equivalent index that
|
||||
the foreign key contraint could use
|
||||
the foreign key constraint could use
|
||||
if this index were to be deleted. */
|
||||
if (!dict_table_find_equivalent_index(
|
||||
prebuilt->table,
|
||||
foreign->foreign_index)) {
|
||||
if (!dict_foreign_find_equiv_index(
|
||||
foreign)) {
|
||||
|
||||
goto index_needed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (thd_sql_command(user_thd) == SQLCOM_CREATE_INDEX) {
|
||||
/* This is a drop of a foreign key constraint index that
|
||||
was created by MySQL when the constraint was added. MySQL
|
||||
does this when the user creates an index explicitly which
|
||||
can be used in place of the automatically generated index. */
|
||||
|
||||
next_index:
|
||||
index = dict_table_get_next_index(index);
|
||||
} while (index);
|
||||
dict_index_t* index;
|
||||
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
index;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
if (!index->to_be_dropped) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if this index references some other table */
|
||||
foreign = dict_table_get_foreign_constraint(
|
||||
prebuilt->table, index);
|
||||
|
||||
if (foreign == NULL) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ut_a(foreign->foreign_index == index);
|
||||
|
||||
/* Search for an equivalent index that the
|
||||
foreign key constraint could use if this index
|
||||
were to be deleted. */
|
||||
|
||||
if (!dict_foreign_find_equiv_index(foreign)) {
|
||||
trx_set_detailed_error(
|
||||
trx,
|
||||
"Index needed in foreign key "
|
||||
"constraint");
|
||||
|
||||
trx->error_info = foreign->foreign_index;
|
||||
|
||||
err = HA_ERR_DROP_INDEX_FK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func_exit:
|
||||
|
|
@ -1084,9 +1128,6 @@ ha_innobase::final_drop_index(
|
|||
trx = trx_allocate_for_mysql();
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trans_register_ha(user_thd, FALSE, ht);
|
||||
prebuilt->trx->active_trans = 1;
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
|
|
@ -1100,25 +1141,22 @@ ha_innobase::final_drop_index(
|
|||
row_merge_lock_table(prebuilt->trx, prebuilt->table, LOCK_X),
|
||||
prebuilt->table->flags, user_thd);
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
if (UNIV_UNLIKELY(err)) {
|
||||
|
||||
/* Unmark the indexes to be dropped. */
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
index; index = dict_table_get_next_index(index)) {
|
||||
|
||||
index->to_be_dropped = FALSE;
|
||||
}
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
/* Drop indexes marked to be dropped */
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
index = dict_table_get_first_index(prebuilt->table);
|
||||
|
||||
while (index) {
|
||||
|
|
@ -1143,11 +1181,11 @@ ha_innobase::final_drop_index(
|
|||
#ifdef UNIV_DEBUG
|
||||
dict_table_check_for_dup_indexes(prebuilt->table);
|
||||
#endif
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
func_exit:
|
||||
trx_commit_for_mysql(trx);
|
||||
trx_commit_for_mysql(prebuilt->trx);
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
/* Flush the log to reduce probability that the .frm files and
|
||||
the InnoDB data dictionary get out-of-sync if the user runs
|
||||
|
|
|
|||
51
handler/handler0vars.h
Normal file
51
handler/handler0vars.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/***********************************************************************
|
||||
This file contains accessor functions for dynamic plugin on Windows.
|
||||
|
||||
(c) 2008 Innobase Oy
|
||||
***********************************************************************/
|
||||
#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
|
||||
/***********************************************************************
|
||||
This is a list of externals that can not be resolved by delay loading.
|
||||
They have to be resolved indirectly via their addresses in the .map file.
|
||||
All of them are external variables. */
|
||||
extern CHARSET_INFO* wdl_my_charset_bin;
|
||||
extern CHARSET_INFO* wdl_my_charset_latin1;
|
||||
extern CHARSET_INFO* wdl_my_charset_filename;
|
||||
extern CHARSET_INFO** wdl_system_charset_info;
|
||||
extern CHARSET_INFO** wdl_default_charset_info;
|
||||
extern CHARSET_INFO** wdl_all_charsets;
|
||||
extern system_variables* wdl_global_system_variables;
|
||||
extern char* wdl_mysql_real_data_home;
|
||||
extern char** wdl_mysql_data_home;
|
||||
extern char** wdl_tx_isolation_names;
|
||||
extern char** wdl_binlog_format_names;
|
||||
extern char* wdl_reg_ext;
|
||||
extern pthread_mutex_t* wdl_LOCK_thread_count;
|
||||
extern key_map* wdl_key_map_full;
|
||||
extern MY_TMPDIR* wdl_mysql_tmpdir_list;
|
||||
extern bool* wdl_mysqld_embedded;
|
||||
extern uint* wdl_lower_case_table_names;
|
||||
extern ulong* wdl_specialflag;
|
||||
extern int* wdl_my_umask;
|
||||
|
||||
#define my_charset_bin (*wdl_my_charset_bin)
|
||||
#define my_charset_latin1 (*wdl_my_charset_latin1)
|
||||
#define my_charset_filename (*wdl_my_charset_filename)
|
||||
#define system_charset_info (*wdl_system_charset_info)
|
||||
#define default_charset_info (*wdl_default_charset_info)
|
||||
#define all_charsets (wdl_all_charsets)
|
||||
#define global_system_variables (*wdl_global_system_variables)
|
||||
#define mysql_real_data_home (wdl_mysql_real_data_home)
|
||||
#define mysql_data_home (*wdl_mysql_data_home)
|
||||
#define tx_isolation_names (wdl_tx_isolation_names)
|
||||
#define binlog_format_names (wdl_binlog_format_names)
|
||||
#define reg_ext (wdl_reg_ext)
|
||||
#define LOCK_thread_count (*wdl_LOCK_thread_count)
|
||||
#define key_map_full (*wdl_key_map_full)
|
||||
#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
|
||||
#define mysqld_embedded (*wdl_mysqld_embedded)
|
||||
#define lower_case_table_names (*wdl_lower_case_table_names)
|
||||
#define specialflag (*wdl_specialflag)
|
||||
#define my_umask (*wdl_my_umask)
|
||||
|
||||
#endif
|
||||
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
#include "ha_prototypes.h" /* for innobase_convert_name() */
|
||||
#include "srv0start.h" /* for srv_was_started */
|
||||
}
|
||||
#include "handler0vars.h"
|
||||
|
||||
static const char plugin_author[] = "Innobase Oy";
|
||||
|
||||
|
|
|
|||
|
|
@ -36,3 +36,16 @@ ib_thd_get_thread_id(
|
|||
{
|
||||
return((unsigned long) ((THD*) thd)->thread_id);
|
||||
}
|
||||
|
||||
/* http://bugs.mysql.com/40360 */
|
||||
/* http://lists.mysql.com/commits/57450 */
|
||||
/**
|
||||
See if the binary log is engaged for a thread, i.e., open and
|
||||
LOG_BIN is set.
|
||||
|
||||
@return @c true if the binlog is active, @c false otherwise.
|
||||
*/
|
||||
my_bool ib_bin_log_is_engaged(const MYSQL_THD thd)
|
||||
{
|
||||
return mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
|
||||
}
|
||||
|
|
|
|||
1016
handler/win_delay_loader.cc
Normal file
1016
handler/win_delay_loader.cc
Normal file
File diff suppressed because it is too large
Load diff
112
ibuf/ibuf0ibuf.c
112
ibuf/ibuf0ibuf.c
|
|
@ -304,10 +304,7 @@ ibuf_header_page_get(
|
|||
|
||||
block = buf_page_get(space, 0, FSP_IBUF_HEADER_PAGE_NO,
|
||||
RW_X_LATCH, mtr);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
|
@ -332,9 +329,7 @@ ibuf_tree_root_get(
|
|||
|
||||
block = buf_page_get(space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
|
||||
mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
|
@ -497,9 +492,8 @@ ibuf_data_init_for_space(
|
|||
buf_block_t* block = buf_page_get(
|
||||
space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
root = buf_block_get_frame(block);
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +543,7 @@ ibuf_data_init_for_space(
|
|||
index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
|
||||
|
||||
error = dict_index_add_to_cache(table, index,
|
||||
FSP_IBUF_TREE_ROOT_PAGE_NO);
|
||||
FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
data->index = dict_table_get_first_index(table);
|
||||
|
|
@ -777,9 +771,7 @@ ibuf_bitmap_get_map_page(
|
|||
block = buf_page_get(space, zip_size,
|
||||
ibuf_bitmap_page_no_calc(zip_size, page_no),
|
||||
RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
|
@ -899,9 +891,13 @@ ibuf_set_free_bits_func(
|
|||
|
||||
/****************************************************************************
|
||||
Resets the free bits of the page in the ibuf bitmap. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict further
|
||||
work to only ibuf bitmap operations, which would result if the latch to the
|
||||
bitmap page were kept. */
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to decrement or reset the bits in the bitmap in a mini-transaction
|
||||
that is committed before the mini-transaction that affects the free
|
||||
space. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_reset_free_bits(
|
||||
|
|
@ -914,9 +910,13 @@ ibuf_reset_free_bits(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for an uncompressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for an uncompressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_low(
|
||||
|
|
@ -948,9 +948,13 @@ ibuf_update_free_bits_low(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for a compressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for a compressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_zip(
|
||||
|
|
@ -989,9 +993,12 @@ ibuf_update_free_bits_zip(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for the two pages to reflect the present state. Does
|
||||
this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations until mtr is committed. */
|
||||
Updates the free bits for the two pages to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules
|
||||
virtually prevent any further operations until mtr is committed.
|
||||
NOTE: The free bits in the insert buffer bitmap must never exceed the
|
||||
free space on a page. It is safe to set the free bits in the same
|
||||
mini-transaction that updated the pages. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_for_two_pages_low(
|
||||
|
|
@ -1758,9 +1765,8 @@ ibuf_add_free_page(
|
|||
{
|
||||
buf_block_t* block = buf_page_get(
|
||||
space, 0, page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
}
|
||||
|
||||
|
|
@ -1888,9 +1894,8 @@ ibuf_remove_free_page(
|
|||
{
|
||||
buf_block_t* block = buf_page_get(
|
||||
space, 0, page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
}
|
||||
|
||||
|
|
@ -2375,7 +2380,7 @@ ibuf_contract_after_insert(
|
|||
/*************************************************************************
|
||||
Gets an upper limit for the combined size of entries buffered in the insert
|
||||
buffer for a given page. */
|
||||
UNIV_INTERN
|
||||
static
|
||||
ulint
|
||||
ibuf_get_volume_buffered(
|
||||
/*=====================*/
|
||||
|
|
@ -2447,9 +2452,8 @@ ibuf_get_volume_buffered(
|
|||
{
|
||||
buf_block_t* block = buf_page_get(
|
||||
0, 0, prev_page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
prev_page = buf_block_get_frame(block);
|
||||
}
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
|
|
@ -2517,9 +2521,8 @@ count_later:
|
|||
{
|
||||
buf_block_t* block = buf_page_get(
|
||||
0, 0, next_page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
next_page = buf_block_get_frame(block);
|
||||
}
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
|
|
@ -2840,17 +2843,17 @@ function_exit:
|
|||
|
||||
mem_heap_free(heap);
|
||||
|
||||
mutex_enter(&ibuf_mutex);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
mutex_enter(&ibuf_mutex);
|
||||
|
||||
ibuf_data->empty = FALSE;
|
||||
ibuf_data->n_inserts++;
|
||||
}
|
||||
|
||||
mutex_exit(&ibuf_mutex);
|
||||
mutex_exit(&ibuf_mutex);
|
||||
|
||||
if ((mode == BTR_MODIFY_TREE) && (err == DB_SUCCESS)) {
|
||||
ibuf_contract_after_insert(entry_size);
|
||||
if (mode == BTR_MODIFY_TREE) {
|
||||
ibuf_contract_after_insert(entry_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_merge) {
|
||||
|
|
@ -2978,11 +2981,9 @@ dump:
|
|||
PAGE_CUR_LE, &page_cur);
|
||||
|
||||
if (low_match == dtuple_get_n_fields(entry)) {
|
||||
buf_block_t* block;
|
||||
page_zip_des_t* page_zip;
|
||||
|
||||
rec = page_cur_get_rec(&page_cur);
|
||||
block = page_cur_get_block(&page_cur);
|
||||
page_zip = buf_block_get_page_zip(block);
|
||||
|
||||
btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr);
|
||||
|
|
@ -3072,6 +3073,9 @@ ibuf_delete_rec(
|
|||
ulint err;
|
||||
|
||||
ut_ad(ibuf_inside());
|
||||
ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
|
||||
ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
|
||||
ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
|
||||
|
||||
success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
|
||||
|
||||
|
|
@ -3087,6 +3091,10 @@ ibuf_delete_rec(
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
|
||||
ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
|
||||
ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
|
||||
|
||||
/* We have to resort to a pessimistic delete from ibuf */
|
||||
btr_pcur_store_position(pcur, mtr);
|
||||
|
||||
|
|
@ -3104,6 +3112,13 @@ ibuf_delete_rec(
|
|||
success = btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr);
|
||||
|
||||
if (!success) {
|
||||
if (fil_space_get_flags(space) == ULINT_UNDEFINED) {
|
||||
/* The tablespace has been dropped. It is possible
|
||||
that another thread has deleted the insert buffer
|
||||
entry. Do not complain. */
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: ERROR: Submit the output to"
|
||||
" http://bugs.mysql.com\n"
|
||||
|
|
@ -3130,23 +3145,17 @@ ibuf_delete_rec(
|
|||
fprintf(stderr, "InnoDB: ibuf tree ok\n");
|
||||
fflush(stderr);
|
||||
|
||||
btr_pcur_close(pcur);
|
||||
|
||||
mutex_exit(&ibuf_mutex);
|
||||
|
||||
return(TRUE);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
root = ibuf_tree_root_get(ibuf_data, 0, mtr);
|
||||
|
||||
btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur),
|
||||
FALSE, mtr);
|
||||
RB_NONE, mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
|
||||
#else
|
||||
UT_NOT_USED(space);
|
||||
#endif
|
||||
ibuf_data_sizes_update(ibuf_data, root, mtr);
|
||||
|
||||
|
|
@ -3154,6 +3163,7 @@ ibuf_delete_rec(
|
|||
|
||||
btr_pcur_commit_specify_mtr(pcur, mtr);
|
||||
|
||||
func_exit:
|
||||
btr_pcur_close(pcur);
|
||||
|
||||
mutex_exit(&ibuf_mutex);
|
||||
|
|
@ -3296,7 +3306,8 @@ ibuf_merge_or_delete_for_page(
|
|||
page_zip = buf_block_get_page_zip(block);
|
||||
|
||||
if (UNIV_UNLIKELY(fil_page_get_type(block->frame)
|
||||
!= FIL_PAGE_INDEX)) {
|
||||
!= FIL_PAGE_INDEX)
|
||||
|| UNIV_UNLIKELY(!page_is_leaf(block->frame))) {
|
||||
|
||||
corruption_noticed = TRUE;
|
||||
|
||||
|
|
@ -3323,7 +3334,7 @@ ibuf_merge_or_delete_for_page(
|
|||
"InnoDB: buffer records to page n:o %lu"
|
||||
" though the page\n"
|
||||
"InnoDB: type is %lu, which is"
|
||||
" not an index page!\n"
|
||||
" not an index leaf page!\n"
|
||||
"InnoDB: We try to resolve the problem"
|
||||
" by skipping the insert buffer\n"
|
||||
"InnoDB: merge for this page."
|
||||
|
|
@ -3351,9 +3362,8 @@ loop:
|
|||
__FILE__, __LINE__,
|
||||
&mtr);
|
||||
ut_a(success);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
/* Position pcur in the insert buffer at the first entry for this
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ btr_block_get(
|
|||
buf_block_t* block;
|
||||
|
||||
block = buf_page_get(space, zip_size, page_no, mode, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
||||
if (mode != RW_NO_LATCH) {
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,8 +312,8 @@ btr_cur_del_mark_set_sec_rec(
|
|||
que_thr_t* thr, /* in: query thread */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/***************************************************************
|
||||
Sets a secondary index record delete mark to FALSE. This function is
|
||||
only used by the insert buffer insert merge mechanism. */
|
||||
Clear a secondary index record's delete mark. This function is only
|
||||
used by the insert buffer insert merge mechanism. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_cur_del_unmark_for_ibuf(
|
||||
|
|
@ -379,7 +379,7 @@ btr_cur_pessimistic_delete(
|
|||
if compression does not occur, the cursor
|
||||
stays valid: it points to successor of
|
||||
deleted record on function exit */
|
||||
ibool in_rollback,/* in: TRUE if called in rollback */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/***************************************************************
|
||||
Parses a redo log record of updating a record in-place. */
|
||||
|
|
@ -521,9 +521,7 @@ btr_free_externally_stored_field(
|
|||
to rec, or NULL if rec == NULL */
|
||||
ulint i, /* in: field number of field_ref;
|
||||
ignored if rec == NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* local_mtr); /* in: mtr containing the latch to
|
||||
data an an X-latch to the index
|
||||
tree */
|
||||
|
|
@ -534,7 +532,9 @@ UNIV_INTERN
|
|||
ulint
|
||||
btr_copy_externally_stored_field_prefix(
|
||||
/*====================================*/
|
||||
/* out: the length of the copied field */
|
||||
/* out: the length of the copied field,
|
||||
or 0 if the column is being or has been
|
||||
deleted */
|
||||
byte* buf, /* out: the field, or a prefix of it */
|
||||
ulint len, /* in: length of buf, in bytes */
|
||||
ulint zip_size,/* in: nonzero=compressed BLOB page size,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,15 @@ btr_search_info_create(
|
|||
/*===================*/
|
||||
/* out, own: search info struct */
|
||||
mem_heap_t* heap); /* in: heap where created */
|
||||
/*********************************************************************
|
||||
Returns the value of ref_count. The value is protected by
|
||||
btr_search_latch. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
/*==========================*/
|
||||
/* out: ref_count value. */
|
||||
btr_search_t* info); /* in: search info. */
|
||||
/*************************************************************************
|
||||
Updates the search info. */
|
||||
UNIV_INLINE
|
||||
|
|
@ -162,6 +171,13 @@ extern ibool btr_search_disabled;
|
|||
/* The search info struct in an index */
|
||||
|
||||
struct btr_search_struct{
|
||||
ulint ref_count; /* Number of blocks in this index tree
|
||||
that have search index built
|
||||
i.e. block->index points to this index.
|
||||
Protected by btr_search_latch except
|
||||
when during initialization in
|
||||
btr_search_info_create(). */
|
||||
|
||||
/* The following fields are not protected by any latch.
|
||||
Unfortunately, this means that they must be aligned to
|
||||
the machine word, i.e., they cannot be turned into bit-fields. */
|
||||
|
|
|
|||
|
|
@ -530,12 +530,14 @@ buf_page_print(
|
|||
const byte* read_buf, /* in: a database page */
|
||||
ulint zip_size); /* in: compressed page size, or
|
||||
0 for uncompressed pages */
|
||||
#ifdef UNIV_DEBUG
|
||||
/*************************************************************************
|
||||
Returns the number of latched pages in the buffer pool. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_get_latched_pages_number(void);
|
||||
/*==============================*/
|
||||
#endif /* UNIV_DEBUG */
|
||||
/*************************************************************************
|
||||
Returns the number of pending buf pool ios. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -601,6 +603,8 @@ buf_block_dbg_add_level(
|
|||
buf_block_t* block, /* in: buffer page
|
||||
where we have acquired latch */
|
||||
ulint level); /* in: latching order level */
|
||||
#else /* UNIV_SYNC_DEBUG */
|
||||
# define buf_block_dbg_add_level(block, level) /* nothing */
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
/*************************************************************************
|
||||
Gets the state of a block. */
|
||||
|
|
@ -1275,13 +1279,17 @@ struct buf_pool_struct{
|
|||
/* base node of the LRU list */
|
||||
buf_page_t* LRU_old; /* pointer to the about 3/8 oldest
|
||||
blocks in the LRU list; NULL if LRU
|
||||
length less than BUF_LRU_OLD_MIN_LEN */
|
||||
length less than BUF_LRU_OLD_MIN_LEN;
|
||||
NOTE: when LRU_old != NULL, its length
|
||||
should always equal LRU_old_len */
|
||||
ulint LRU_old_len; /* length of the LRU list from
|
||||
the block to which LRU_old points
|
||||
onward, including that block;
|
||||
see buf0lru.c for the restrictions
|
||||
on this value; not defined if
|
||||
LRU_old == NULL */
|
||||
LRU_old == NULL;
|
||||
NOTE: LRU_old_len must be adjusted
|
||||
whenever LRU_old shrinks or grows! */
|
||||
|
||||
UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
|
||||
/* base node of the unzip_LRU list */
|
||||
|
|
|
|||
|
|
@ -444,6 +444,15 @@ buf_page_set_old(
|
|||
{
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
|
||||
&& UT_LIST_GET_PREV(LRU, bpage)->old
|
||||
== UT_LIST_GET_NEXT(LRU, bpage)->old) {
|
||||
ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
|
||||
}
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
bpage->old = old;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,5 +567,5 @@ dtype_get_sql_null_size(
|
|||
const dtype_t* type) /* in: type */
|
||||
{
|
||||
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
|
||||
type->mbminlen, type->mbmaxlen) > 0);
|
||||
type->mbminlen, type->mbmaxlen));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,8 +172,7 @@ dict_table_autoinc_lock(
|
|||
/*====================*/
|
||||
dict_table_t* table); /* in/out: table */
|
||||
/************************************************************************
|
||||
Initializes the autoinc counter. It is not an error to initialize an already
|
||||
initialized counter. */
|
||||
Unconditionally set the autoinc counter. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_table_autoinc_initialize(
|
||||
|
|
@ -190,12 +189,12 @@ dict_table_autoinc_read(
|
|||
/* out: value for a new row, or 0 */
|
||||
const dict_table_t* table); /* in: table */
|
||||
/************************************************************************
|
||||
Updates the autoinc counter if the value supplied is equal or bigger than the
|
||||
current value. If not inited, does nothing. */
|
||||
Updates the autoinc counter if the value supplied is greater than the
|
||||
current value. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_table_autoinc_update(
|
||||
/*======================*/
|
||||
dict_table_autoinc_update_if_greater(
|
||||
/*=================================*/
|
||||
|
||||
dict_table_t* table, /* in/out: table */
|
||||
ib_uint64_t value); /* in: value which was assigned to a row */
|
||||
|
|
@ -300,17 +299,6 @@ dict_table_replace_index_in_foreign_list(
|
|||
/*=====================================*/
|
||||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index); /* in: index to be replaced */
|
||||
/**************************************************************************
|
||||
Determines whether a string starts with the specified keyword. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
/* out: TRUE if str starts
|
||||
with keyword */
|
||||
void* mysql_thd, /* in: MySQL thread handle */
|
||||
const char* str, /* in: string to scan for keyword */
|
||||
const char* keyword); /* in: keyword to look for */
|
||||
/*************************************************************************
|
||||
Checks if a index is defined for a foreign key constraint. Index is a part
|
||||
of a foreign key constraint if the index is referenced by foreign key
|
||||
|
|
@ -420,6 +408,16 @@ dict_table_get_on_id_low(
|
|||
/* out: table, NULL if does not exist */
|
||||
dulint table_id); /* in: table id */
|
||||
/**************************************************************************
|
||||
Find an index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_foreign_find_equiv_index(
|
||||
/*==========================*/
|
||||
/* out: index equivalent to
|
||||
foreign->foreign_index, or NULL */
|
||||
dict_foreign_t* foreign);/* in: foreign key */
|
||||
/**************************************************************************
|
||||
Returns an index object by matching on the name and column names and if
|
||||
more than index is found return the index with the higher id.*/
|
||||
UNIV_INTERN
|
||||
|
|
@ -706,7 +704,10 @@ dict_index_add_to_cache(
|
|||
dict_table_t* table, /* in: table on which the index is */
|
||||
dict_index_t* index, /* in, own: index; NOTE! The index memory
|
||||
object is freed in this function! */
|
||||
ulint page_no);/* in: root page number of the index */
|
||||
ulint page_no,/* in: root page number of the index */
|
||||
ibool strict);/* in: TRUE=refuse to create the index
|
||||
if records could be too big to fit in
|
||||
an B-tree page */
|
||||
/**************************************************************************
|
||||
Removes an index from the dictionary cache. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -1068,17 +1069,6 @@ dict_tables_have_same_db(
|
|||
const char* name2); /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
/*************************************************************************
|
||||
Scans from pointer onwards. Stops if is at the start of a copy of
|
||||
'string' where characters are compared without case sensitivity. Stops
|
||||
also at '\0'. */
|
||||
|
||||
const char*
|
||||
dict_scan_to(
|
||||
/*=========*/
|
||||
/* out: scanned up to this */
|
||||
const char* ptr, /* in: scan from */
|
||||
const char* string);/* in: look for this */
|
||||
/*************************************************************************
|
||||
Removes an index from the cache */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
|
@ -1096,15 +1086,6 @@ dict_table_get_index_on_name(
|
|||
dict_table_t* table, /* in: table */
|
||||
const char* name); /* in: name of the index to find */
|
||||
/**************************************************************************
|
||||
Find and index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_table_find_equivalent_index(
|
||||
/*=============================*/
|
||||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index); /* in: index to match */
|
||||
/**************************************************************************
|
||||
In case there is more than one index with the same name return the index
|
||||
with the min(id). */
|
||||
UNIV_INTERN
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ Created 1/8/1996 Heikki Tuuri
|
|||
#include "lock0types.h"
|
||||
#include "hash0hash.h"
|
||||
#include "que0types.h"
|
||||
#include "trx0types.h"
|
||||
|
||||
/* Type flags of an index: OR'ing of the flags is allowed to define a
|
||||
combination of types */
|
||||
|
|
@ -221,7 +222,7 @@ struct dict_index_struct{
|
|||
unsigned page:32;/* index tree root page number */
|
||||
unsigned type:4; /* index type (DICT_CLUSTERED, DICT_UNIQUE,
|
||||
DICT_UNIVERSAL, DICT_IBUF) */
|
||||
unsigned trx_id_offset:10;/* position of the the trx id column
|
||||
unsigned trx_id_offset:10;/* position of the trx id column
|
||||
in a clustered index record, if the fields
|
||||
before it are known to be of a fixed size,
|
||||
0 otherwise */
|
||||
|
|
@ -381,13 +382,6 @@ struct dict_table_struct{
|
|||
on the table: we cannot drop the table while
|
||||
there are foreign key checks running on
|
||||
it! */
|
||||
lock_t* auto_inc_lock;/* a buffer for an auto-inc lock
|
||||
for this table: we allocate the memory here
|
||||
so that individual transactions can get it
|
||||
and release it without a need to allocate
|
||||
space from the lock heap of the trx:
|
||||
otherwise the lock heap would grow rapidly
|
||||
if we do a large insert from a select */
|
||||
dulint query_cache_inv_trx_id;
|
||||
/* transactions whose trx id < than this
|
||||
number are not allowed to store to the MySQL
|
||||
|
|
@ -438,20 +432,33 @@ struct dict_table_struct{
|
|||
any latch, because this is only used for
|
||||
heuristics */
|
||||
/*----------------------*/
|
||||
/* The following fields are used by the
|
||||
AUTOINC code. The actual collection of
|
||||
tables locked during AUTOINC read/write is
|
||||
kept in trx_t. In order to quickly determine
|
||||
whether a transaction has locked the AUTOINC
|
||||
lock we keep a pointer to the transaction
|
||||
here in the autoinc_trx variable. This is to
|
||||
avoid acquiring the kernel mutex and scanning
|
||||
the vector in trx_t.
|
||||
|
||||
When an AUTOINC lock has to wait, the
|
||||
corresponding lock instance is created on
|
||||
the trx lock heap rather than use the
|
||||
pre-allocated instance in autoinc_lock below.*/
|
||||
lock_t* autoinc_lock;
|
||||
/* a buffer for an AUTOINC lock
|
||||
for this table: we allocate the memory here
|
||||
so that individual transactions can get it
|
||||
and release it without a need to allocate
|
||||
space from the lock heap of the trx:
|
||||
otherwise the lock heap would grow rapidly
|
||||
if we do a large insert from a select */
|
||||
mutex_t autoinc_mutex;
|
||||
/* mutex protecting the autoincrement
|
||||
counter */
|
||||
ibool autoinc_inited;
|
||||
/* TRUE if the autoinc counter has been
|
||||
inited; MySQL gets the init value by executing
|
||||
SELECT MAX(auto inc column) */
|
||||
ib_uint64_t autoinc;/* autoinc counter value to give to the
|
||||
next inserted row */
|
||||
ib_int64_t autoinc_increment;
|
||||
/* The increment step of the auto increment
|
||||
column. Value must be greater than or equal
|
||||
to 1 */
|
||||
/*----------------------*/
|
||||
ulong n_waiting_or_granted_auto_inc_locks;
|
||||
/* This counter is used to track the number
|
||||
of granted and pending autoinc locks on this
|
||||
|
|
@ -461,6 +468,10 @@ struct dict_table_struct{
|
|||
acquired the AUTOINC lock or not. Of course
|
||||
only one transaction can be granted the
|
||||
lock but there can be multiple waiters. */
|
||||
const trx_t* autoinc_trx;
|
||||
/* The transaction that currently holds the
|
||||
the AUTOINC lock on this table. */
|
||||
/*----------------------*/
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint magic_n;/* magic number */
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ fut_get_ptr(
|
|||
block = buf_page_get(space, zip_size, addr.page, rw_latch, mtr);
|
||||
ptr = buf_block_get_frame(block) + addr.boffset;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ flst_write_addr(
|
|||
{
|
||||
ut_ad(faddr && mtr);
|
||||
ut_ad(mtr_memo_contains_page(mtr, faddr, MTR_MEMO_PAGE_X_FIX));
|
||||
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
||||
ut_a(ut_align_offset(faddr, UNIV_PAGE_SIZE) >= FIL_PAGE_DATA);
|
||||
|
||||
mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset,
|
||||
|
|
@ -61,6 +63,8 @@ flst_read_addr(
|
|||
addr.page = mtr_read_ulint(faddr + FIL_ADDR_PAGE, MLOG_4BYTES, mtr);
|
||||
addr.boffset = mtr_read_ulint(faddr + FIL_ADDR_BYTE, MLOG_2BYTES,
|
||||
mtr);
|
||||
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
||||
ut_a(ut_align_offset(faddr, UNIV_PAGE_SIZE) >= FIL_PAGE_DATA);
|
||||
return(addr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,5 +158,72 @@ innobase_strcasecmp(
|
|||
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
|
||||
const char* a, /* in: first string to compare */
|
||||
const char* b); /* in: second string to compare */
|
||||
|
||||
/**********************************************************************
|
||||
Returns true if the thread is executing a SELECT statement. */
|
||||
|
||||
ibool
|
||||
thd_is_select(
|
||||
/*==========*/
|
||||
/* out: true if thd is executing SELECT */
|
||||
const void* thd); /* in: thread handle (THD*) */
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes; should
|
||||
be at least 5 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes; should
|
||||
be at least 3 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_casedn_str(
|
||||
/*================*/
|
||||
char* a); /* in/out: string to put in lower case */
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set. */
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd); /* in: MySQL thread handle */
|
||||
|
||||
/**********************************************************************
|
||||
Returns true if the thread is executing in innodb_strict_mode. */
|
||||
|
||||
ibool
|
||||
thd_is_strict(
|
||||
/*==========*/
|
||||
/* out: true if thd is in strict mode */
|
||||
void* thd); /* in: thread handle (THD*) */
|
||||
|
||||
/**********************************************************************
|
||||
Returns the lock wait timeout for the current connection. */
|
||||
|
||||
ulong
|
||||
thd_lock_wait_timeout(
|
||||
/*==================*/
|
||||
/* out: the lock wait timeout, in seconds */
|
||||
void* thd); /* in: thread handle (THD*), or NULL to query
|
||||
the global innodb_lock_wait_timeout */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ do {\
|
|||
if (cell3333->node == NULL) {\
|
||||
cell3333->node = DATA;\
|
||||
} else {\
|
||||
struct3333 = cell3333->node;\
|
||||
struct3333 = (TYPE*) cell3333->node;\
|
||||
\
|
||||
while (struct3333->NAME != NULL) {\
|
||||
\
|
||||
|
|
|
|||
|
|
@ -20,6 +20,26 @@ Created 7/19/1997 Heikki Tuuri
|
|||
|
||||
extern ibuf_t* ibuf;
|
||||
|
||||
/* The purpose of the insert buffer is to reduce random disk access.
|
||||
When we wish to insert a record into a non-unique secondary index and
|
||||
the B-tree leaf page where the record belongs to is not in the buffer
|
||||
pool, we insert the record into the insert buffer B-tree, indexed by
|
||||
(space_id, page_no). When the page is eventually read into the buffer
|
||||
pool, we look up the insert buffer B-tree for any modifications to the
|
||||
page, and apply these upon the completion of the read operation. This
|
||||
is called the insert buffer merge. */
|
||||
|
||||
/* The insert buffer merge must always succeed. To guarantee this,
|
||||
the insert buffer subsystem keeps track of the free space in pages for
|
||||
which it can buffer operations. Two bits per page in the insert
|
||||
buffer bitmap indicate the available space in coarse increments. The
|
||||
free bits in the insert buffer bitmap must never exceed the free space
|
||||
on a page. It is safe to decrement or reset the bits in the bitmap in
|
||||
a mini-transaction that is committed before the mini-transaction that
|
||||
affects the free space. It is unsafe to increment the bits in a
|
||||
separately committed mini-transaction, because in crash recovery, the
|
||||
free bits could momentarily be set too high. */
|
||||
|
||||
/**********************************************************************
|
||||
Creates the insert buffer data struct for a single tablespace. Reads the
|
||||
root page of the insert buffer tree in the tablespace. This function can
|
||||
|
|
@ -56,9 +76,13 @@ ibuf_bitmap_page_init(
|
|||
mtr_t* mtr); /* in: mtr */
|
||||
/****************************************************************************
|
||||
Resets the free bits of the page in the ibuf bitmap. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict further
|
||||
work to only ibuf bitmap operations, which would result if the latch to the
|
||||
bitmap page were kept. */
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to decrement or reset the bits in the bitmap in a mini-transaction
|
||||
that is committed before the mini-transaction that affects the free
|
||||
space. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_reset_free_bits(
|
||||
|
|
@ -68,10 +92,17 @@ ibuf_reset_free_bits(
|
|||
non-unique, and page level is 0 */
|
||||
/****************************************************************************
|
||||
Updates the free bits of an uncompressed page in the ibuf bitmap if
|
||||
there is not enough free on the page any more. This is done in a
|
||||
there is not enough free on the page any more. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. */
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is
|
||||
unsafe to increment the bits in a separately committed
|
||||
mini-transaction, because in crash recovery, the free bits could
|
||||
momentarily be set too high. It is only safe to use this function for
|
||||
decrementing the free bits. Should more free space become available,
|
||||
we must not update the free bits here, because that would break crash
|
||||
recovery. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ibuf_update_free_bits_if_full(
|
||||
|
|
@ -88,9 +119,13 @@ ibuf_update_free_bits_if_full(
|
|||
used in the latest operation, if known, or
|
||||
ULINT_UNDEFINED */
|
||||
/**************************************************************************
|
||||
Updates the free bits for an uncompressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for an uncompressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_low(
|
||||
|
|
@ -103,9 +138,13 @@ ibuf_update_free_bits_low(
|
|||
performed to the page */
|
||||
mtr_t* mtr); /* in/out: mtr */
|
||||
/**************************************************************************
|
||||
Updates the free bits for a compressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for a compressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_zip(
|
||||
|
|
@ -113,9 +152,12 @@ ibuf_update_free_bits_zip(
|
|||
buf_block_t* block, /* in/out: index page */
|
||||
mtr_t* mtr); /* in/out: mtr */
|
||||
/**************************************************************************
|
||||
Updates the free bits for the two pages to reflect the present state. Does
|
||||
this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations until mtr is committed. */
|
||||
Updates the free bits for the two pages to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules
|
||||
virtually prevent any further operations until mtr is committed.
|
||||
NOTE: The free bits in the insert buffer bitmap must never exceed the
|
||||
free space on a page. It is safe to set the free bits in the same
|
||||
mini-transaction that updated the pages. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_for_two_pages_low(
|
||||
|
|
|
|||
|
|
@ -253,10 +253,17 @@ ibuf_index_page_calc_free(
|
|||
|
||||
/****************************************************************************
|
||||
Updates the free bits of an uncompressed page in the ibuf bitmap if
|
||||
there is not enough free on the page any more. This is done in a
|
||||
there is not enough free on the page any more. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. */
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is
|
||||
unsafe to increment the bits in a separately committed
|
||||
mini-transaction, because in crash recovery, the free bits could
|
||||
momentarily be set too high. It is only safe to use this function for
|
||||
decrementing the free bits. Should more free space become available,
|
||||
we must not update the free bits here, because that would break crash
|
||||
recovery. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ibuf_update_free_bits_if_full(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ Created 5/7/1996 Heikki Tuuri
|
|||
#include "lock0types.h"
|
||||
#include "read0types.h"
|
||||
#include "hash0hash.h"
|
||||
#include "ut0vec.h"
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
extern ibool lock_print_waits;
|
||||
|
|
@ -490,14 +491,6 @@ lock_table_unlock(
|
|||
/*==============*/
|
||||
lock_t* lock); /* in: lock */
|
||||
/*************************************************************************
|
||||
Releases an auto-inc lock a transaction possibly has on a table.
|
||||
Releases possible other transactions waiting for this lock. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_table_unlock_auto_inc(
|
||||
/*=======================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/*************************************************************************
|
||||
Releases transaction locks, and releases possible other transactions waiting
|
||||
because of these locks. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -513,14 +506,21 @@ void
|
|||
lock_cancel_waiting_and_release(
|
||||
/*============================*/
|
||||
lock_t* lock); /* in: waiting lock request */
|
||||
|
||||
/*************************************************************************
|
||||
Resets all locks, both table and record locks, on a table to be dropped.
|
||||
No lock is allowed to be a wait lock. */
|
||||
Removes locks on a table to be dropped or truncated.
|
||||
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
|
||||
also removed in addition to other table-level and record-level locks.
|
||||
No lock, that is going to be removed, is allowed to be a wait lock. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_reset_all_on_table(
|
||||
/*====================*/
|
||||
dict_table_t* table); /* in: table to be dropped */
|
||||
lock_remove_all_on_table(
|
||||
/*=====================*/
|
||||
dict_table_t* table, /* in: table to be dropped
|
||||
or truncated */
|
||||
ibool remove_also_table_sx_locks);/* in: also removes
|
||||
table S and X locks */
|
||||
|
||||
/*************************************************************************
|
||||
Calculates the fold value of a page file address: used in inserting or
|
||||
searching for a lock in the hash table. */
|
||||
|
|
@ -646,6 +646,13 @@ ulint
|
|||
lock_number_of_rows_locked(
|
||||
/*=======================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/***********************************************************************
|
||||
Release all the transaction's autoinc locks. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_release_autoinc_locks(
|
||||
/*=======================*/
|
||||
trx_t* trx); /* in/out: transaction */
|
||||
|
||||
/***********************************************************************
|
||||
Gets the type of a lock. Non-inline version for using outside of the
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ here. In a perfect world this file exists but is empty.
|
|||
Created November 07, 2007 Vasil Dimov
|
||||
*******************************************************/
|
||||
|
||||
#include <my_global.h> /* for my_bool */
|
||||
#include <mysql/plugin.h> /* for MYSQL_THD */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
|
@ -32,3 +35,13 @@ ib_thd_get_thread_id(
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* http://bugs.mysql.com/40360 */
|
||||
/* http://lists.mysql.com/commits/57450 */
|
||||
/**
|
||||
See if the binary log is engaged for a thread, i.e., open and
|
||||
LOG_BIN is set.
|
||||
|
||||
@return @c true if the binlog is active, @c false otherwise.
|
||||
*/
|
||||
my_bool ib_bin_log_is_engaged(const MYSQL_THD thd);
|
||||
|
|
|
|||
|
|
@ -663,24 +663,6 @@ os_aio_windows_handle(
|
|||
ulint* type); /* out: OS_FILE_WRITE or ..._READ */
|
||||
#endif
|
||||
|
||||
/* Currently we do not use Posix async i/o */
|
||||
#ifdef POSIX_ASYNC_IO
|
||||
/**************************************************************************
|
||||
This function is only used in Posix asynchronous i/o. Waits for an aio
|
||||
operation to complete. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_aio_posix_handle(
|
||||
/*================*/
|
||||
/* out: TRUE if the aio operation succeeded */
|
||||
ulint array_no, /* in: array number 0 - 3 */
|
||||
fil_node_t**message1, /* out: the messages passed with the aio
|
||||
request; note that also in the case where
|
||||
the aio operation failed, these output
|
||||
parameters are valid and can be used to
|
||||
restart the operation, for example */
|
||||
void** message2);
|
||||
#endif
|
||||
/**************************************************************************
|
||||
Does simulated aio. This function should be called by an i/o-handler
|
||||
thread. */
|
||||
|
|
|
|||
|
|
@ -244,21 +244,25 @@ page_header_reset_last_insert(
|
|||
uncompressed part will be updated, or NULL */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/****************************************************************
|
||||
Gets the first record on the page. */
|
||||
Gets the offset of the first record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_infimum_rec(
|
||||
/*=================*/
|
||||
/* out: the first record in record list */
|
||||
page_t* page); /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_infimum_offset(
|
||||
/*====================*/
|
||||
/* out: offset of the first record
|
||||
in record list, relative from page */
|
||||
const page_t* page); /* in: page which must have record(s) */
|
||||
/****************************************************************
|
||||
Gets the last record on the page. */
|
||||
Gets the offset of the last record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_supremum_rec(
|
||||
/*==================*/
|
||||
/* out: the last record in record list */
|
||||
page_t* page); /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_supremum_offset(
|
||||
/*=====================*/
|
||||
/* out: offset of the last record in
|
||||
record list, relative from page */
|
||||
const page_t* page); /* in: page which must have record(s) */
|
||||
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
|
||||
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
|
||||
/****************************************************************
|
||||
Returns the middle record of record list. If there are an even number
|
||||
of records in the list, returns the first record of upper half-list. */
|
||||
|
|
@ -691,8 +695,7 @@ void
|
|||
page_mem_free(
|
||||
/*==========*/
|
||||
page_t* page, /* in/out: index page */
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page with at least
|
||||
6 bytes available, or NULL */
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
|
||||
rec_t* rec, /* in: pointer to the (origin of) record */
|
||||
dict_index_t* index, /* in: index of rec */
|
||||
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
||||
|
|
|
|||
|
|
@ -246,38 +246,42 @@ page_is_leaf(
|
|||
}
|
||||
|
||||
/****************************************************************
|
||||
Gets the first record on the page. */
|
||||
Gets the offset of the first record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_infimum_rec(
|
||||
/*=================*/
|
||||
/* out: the first record in record list */
|
||||
page_t* page) /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_infimum_offset(
|
||||
/*====================*/
|
||||
/* out: offset of the first record
|
||||
in record list, relative from page */
|
||||
const page_t* page) /* in: page which must have record(s) */
|
||||
{
|
||||
ut_ad(page);
|
||||
ut_ad(!page_offset(page));
|
||||
|
||||
if (page_is_comp(page)) {
|
||||
return(page + PAGE_NEW_INFIMUM);
|
||||
return(PAGE_NEW_INFIMUM);
|
||||
} else {
|
||||
return(page + PAGE_OLD_INFIMUM);
|
||||
return(PAGE_OLD_INFIMUM);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Gets the last record on the page. */
|
||||
Gets the offset of the last record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_supremum_rec(
|
||||
/*==================*/
|
||||
/* out: the last record in record list */
|
||||
page_t* page) /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_supremum_offset(
|
||||
/*=====================*/
|
||||
/* out: offset of the last record in
|
||||
record list, relative from page */
|
||||
const page_t* page) /* in: page which must have record(s) */
|
||||
{
|
||||
ut_ad(page);
|
||||
ut_ad(!page_offset(page));
|
||||
|
||||
if (page_is_comp(page)) {
|
||||
return(page + PAGE_NEW_SUPREMUM);
|
||||
return(PAGE_NEW_SUPREMUM);
|
||||
} else {
|
||||
return(page + PAGE_OLD_SUPREMUM);
|
||||
return(PAGE_OLD_SUPREMUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1007,8 +1011,7 @@ void
|
|||
page_mem_free(
|
||||
/*==========*/
|
||||
page_t* page, /* in/out: index page */
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page with at least
|
||||
6 bytes available, or NULL */
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
|
||||
rec_t* rec, /* in: pointer to the (origin of) record */
|
||||
dict_index_t* index, /* in: index of rec */
|
||||
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
||||
|
|
|
|||
|
|
@ -76,21 +76,6 @@ typedef struct page_zip_stat_struct page_zip_stat_t;
|
|||
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
|
||||
extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
|
||||
|
||||
/**************************************************************************
|
||||
Write data to the compressed page. The data must already be written to
|
||||
the uncompressed page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
page_zip_write(
|
||||
/*===========*/
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page */
|
||||
const byte* rec, /* in: record whose data is being written */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
lint offset, /* in: start address of the block,
|
||||
relative to rec */
|
||||
ulint length) /* in: length of the data */
|
||||
__attribute__((nonnull));
|
||||
|
||||
/**************************************************************************
|
||||
Write the "deleted" flag of a record on a compressed page. The flag must
|
||||
already have been written on the uncompressed page. */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ page_zip_rec_needs_ext(
|
|||
can be stored locally on the page */
|
||||
ulint rec_size, /* in: length of the record in bytes */
|
||||
ulint comp, /* in: nonzero=compact format */
|
||||
ulint n_fields, /* in: number of fields in the record;
|
||||
ignored if zip_size == 0 */
|
||||
ulint zip_size) /* in: compressed page size in bytes, or 0 */
|
||||
__attribute__((const));
|
||||
|
||||
|
|
@ -126,6 +128,18 @@ page_zip_simple_validate(
|
|||
Check that the compressed and decompressed pages match. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
page_zip_validate_low(
|
||||
/*==================*/
|
||||
/* out: TRUE if valid, FALSE if not */
|
||||
const page_zip_des_t* page_zip,/* in: compressed page */
|
||||
const page_t* page, /* in: uncompressed page */
|
||||
ibool sloppy) /* in: FALSE=strict,
|
||||
TRUE=ignore the MIN_REC_FLAG */
|
||||
__attribute__((nonnull));
|
||||
/**************************************************************************
|
||||
Check that the compressed and decompressed pages match. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
page_zip_validate(
|
||||
/*==============*/
|
||||
const page_zip_des_t* page_zip,/* in: compressed page */
|
||||
|
|
@ -371,11 +385,14 @@ page_zip_reorganize(
|
|||
mtr_t* mtr) /* in: mini-transaction */
|
||||
__attribute__((nonnull));
|
||||
/**************************************************************************
|
||||
Copy a page byte for byte, except for the file page header and trailer. */
|
||||
Copy the records of a page byte for byte. Do not copy the page header
|
||||
or trailer, except those B-tree header fields that are directly
|
||||
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
|
||||
NOTE: The caller must update the lock table and the adaptive hash index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
page_zip_copy(
|
||||
/*==========*/
|
||||
page_zip_copy_recs(
|
||||
/*===============*/
|
||||
page_zip_des_t* page_zip, /* out: copy of src_zip
|
||||
(n_blobs, m_start, m_end,
|
||||
m_nonempty, data[0..size-1]) */
|
||||
|
|
|
|||
|
|
@ -148,10 +148,13 @@ page_zip_rec_needs_ext(
|
|||
can be stored locally on the page */
|
||||
ulint rec_size, /* in: length of the record in bytes */
|
||||
ulint comp, /* in: nonzero=compact format */
|
||||
ulint n_fields, /* in: number of fields in the record;
|
||||
ignored if zip_size == 0 */
|
||||
ulint zip_size) /* in: compressed page size in bytes, or 0 */
|
||||
{
|
||||
ut_ad(rec_size > comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES);
|
||||
ut_ad(ut_is_2pow(zip_size));
|
||||
ut_ad(comp || !zip_size);
|
||||
|
||||
#if UNIV_PAGE_SIZE > REC_MAX_DATA_SIZE
|
||||
if (UNIV_UNLIKELY(rec_size >= REC_MAX_DATA_SIZE)) {
|
||||
|
|
@ -159,21 +162,20 @@ page_zip_rec_needs_ext(
|
|||
}
|
||||
#endif
|
||||
|
||||
if (UNIV_UNLIKELY(!comp)) {
|
||||
ut_ad(!zip_size);
|
||||
return(rec_size >= page_get_free_space_of_empty(FALSE) / 2);
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
ut_ad(comp);
|
||||
/* On a compressed page, there is a two-byte entry in
|
||||
the dense page directory for every record. But there
|
||||
is no record header. There should be enough room for
|
||||
one record on an empty leaf page. Subtract 1 byte for
|
||||
the encoded heap number. Check also the available space
|
||||
on the uncompressed page. */
|
||||
return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2)
|
||||
>= (page_zip_empty_size(n_fields, zip_size) - 1)
|
||||
|| rec_size >= page_get_free_space_of_empty(TRUE) / 2);
|
||||
}
|
||||
|
||||
/* If zip_size != 0, the record should fit on the compressed page.
|
||||
If not, the right-hand-side of the comparison will overwrap
|
||||
and the condition will not hold. Thus, we do not need to test
|
||||
for zip_size != 0. We subtract the size of the page header and
|
||||
assume that compressing the index information takes 50 bytes. */
|
||||
if (rec_size >= zip_size - (PAGE_DATA + 50)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(rec_size >= page_get_free_space_of_empty(TRUE) / 2);
|
||||
return(rec_size >= page_get_free_space_of_empty(comp) / 2);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
|
|
|||
|
|
@ -693,6 +693,20 @@ rec_get_converted_extra_size(
|
|||
ulint n_ext) /* in: number of externally stored columns */
|
||||
__attribute__((const));
|
||||
/**************************************************************
|
||||
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
rec_get_converted_size_comp_prefix(
|
||||
/*===============================*/
|
||||
/* out: total size */
|
||||
const dict_index_t* index, /* in: record descriptor;
|
||||
dict_table_is_comp() is
|
||||
assumed to hold, even if
|
||||
it does not */
|
||||
const dfield_t* fields, /* in: array of data fields */
|
||||
ulint n_fields,/* in: number of data fields */
|
||||
ulint* extra); /* out: extra size */
|
||||
/**************************************************************
|
||||
Determines the size of a data tuple in ROW_FORMAT=COMPACT. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
|
|
|
|||
|
|
@ -54,7 +54,9 @@ row_merge_lock_table(
|
|||
dict_table_t* table, /* in: table to lock */
|
||||
enum lock_mode mode); /* in: LOCK_X or LOCK_S */
|
||||
/*************************************************************************
|
||||
Drop an index from the InnoDB system tables. */
|
||||
Drop an index from the InnoDB system tables. The data dictionary must
|
||||
have been locked exclusively by the caller, because the transaction
|
||||
will not be committed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_merge_drop_index(
|
||||
|
|
@ -63,8 +65,10 @@ row_merge_drop_index(
|
|||
dict_table_t* table, /* in: table */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/*************************************************************************
|
||||
Drop those indexes which were created before an error occurred
|
||||
when building an index. */
|
||||
Drop those indexes which were created before an error occurred when
|
||||
building an index. The data dictionary must have been locked
|
||||
exclusively by the caller, because the transaction will not be
|
||||
committed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_merge_drop_indexes(
|
||||
|
|
@ -80,7 +84,9 @@ void
|
|||
row_merge_drop_temp_indexes(void);
|
||||
/*=============================*/
|
||||
/*************************************************************************
|
||||
Rename the tables in the data dictionary. */
|
||||
Rename the tables in the data dictionary. The data dictionary must
|
||||
have been locked exclusively by the caller, because the transaction
|
||||
will not be committed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
row_merge_rename_tables(
|
||||
|
|
@ -109,7 +115,9 @@ row_merge_create_temporary_table(
|
|||
trx_t* trx); /* in/out: transaction
|
||||
(sets error_state) */
|
||||
/*************************************************************************
|
||||
Rename the temporary indexes in the dictionary to permanent ones. */
|
||||
Rename the temporary indexes in the dictionary to permanent ones. The
|
||||
data dictionary must have been locked exclusively by the caller,
|
||||
because the transaction will not be committed. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
row_merge_rename_indexes(
|
||||
|
|
|
|||
|
|
@ -163,12 +163,12 @@ row_update_prebuilt_trx(
|
|||
handle */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/*************************************************************************
|
||||
Unlocks an AUTO_INC type lock possibly reserved by trx. */
|
||||
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_unlock_table_autoinc_for_mysql(
|
||||
/*===============================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
trx_t* trx); /* in/out: transaction */
|
||||
/*************************************************************************
|
||||
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
|
||||
AUTO_INC lock gives exclusive access to the auto-inc counter of the
|
||||
|
|
@ -339,7 +339,8 @@ int
|
|||
row_create_table_for_mysql(
|
||||
/*=======================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
dict_table_t* table, /* in: table definition */
|
||||
dict_table_t* table, /* in, own: table definition
|
||||
(will be freed) */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/*************************************************************************
|
||||
Does an index creation operation for MySQL. TODO: currently failure
|
||||
|
|
@ -350,7 +351,8 @@ int
|
|||
row_create_index_for_mysql(
|
||||
/*=======================*/
|
||||
/* out: error number or DB_SUCCESS */
|
||||
dict_index_t* index, /* in: index definition */
|
||||
dict_index_t* index, /* in, own: index definition
|
||||
(will be freed) */
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
const ulint* field_lengths); /* in: if not NULL, must contain
|
||||
dict_index_get_n_fields(index)
|
||||
|
|
@ -411,10 +413,12 @@ row_truncate_table_for_mysql(
|
|||
dict_table_t* table, /* in: table handle */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/*************************************************************************
|
||||
Drops a table for MySQL. If the name of the dropped table ends in
|
||||
Drops a table for MySQL. If the name of the dropped table ends in
|
||||
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
|
||||
"innodb_table_monitor", then this will also stop the printing of monitor
|
||||
output by the master thread. */
|
||||
output by the master thread. If the data dictionary was not already locked
|
||||
by the transaction, the transaction will be committed. Otherwise, the
|
||||
data dictionary will remain locked. */
|
||||
UNIV_INTERN
|
||||
int
|
||||
row_drop_table_for_mysql(
|
||||
|
|
@ -425,20 +429,6 @@ row_drop_table_for_mysql(
|
|||
ibool drop_db);/* in: TRUE=dropping whole database */
|
||||
|
||||
/*************************************************************************
|
||||
Drops a table for MySQL but does not commit the transaction. If the
|
||||
name of the dropped table ends in one of "innodb_monitor",
|
||||
"innodb_lock_monitor", "innodb_tablespace_monitor",
|
||||
"innodb_table_monitor", then this will also stop the printing of
|
||||
monitor output by the master thread. */
|
||||
UNIV_INTERN
|
||||
int
|
||||
row_drop_table_for_mysql_no_commit(
|
||||
/*===============================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
const char* name, /* in: table name */
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
ibool drop_db);/* in: TRUE=dropping whole database */
|
||||
/*************************************************************************
|
||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
||||
means that this function deletes the .ibd file and assigns a new table id for
|
||||
the table. Also the flag table->ibd_file_missing is set TRUE. */
|
||||
|
|
@ -708,7 +698,21 @@ struct row_prebuilt_struct {
|
|||
to this heap */
|
||||
mem_heap_t* old_vers_heap; /* memory heap where a previous
|
||||
version is built in consistent read */
|
||||
ulonglong last_value; /* last value of AUTO-INC interval */
|
||||
/*----------------------*/
|
||||
ulonglong autoinc_last_value;/* last value of AUTO-INC interval */
|
||||
ulonglong autoinc_increment;/* The increment step of the auto
|
||||
increment column. Value must be
|
||||
greater than or equal to 1. Required to
|
||||
calculate the next value */
|
||||
ulonglong autoinc_offset; /* The offset passed to
|
||||
get_auto_increment() by MySQL. Required
|
||||
to calculate the next value */
|
||||
ulint autoinc_error; /* The actual error code encountered
|
||||
while trying to init or read the
|
||||
autoinc value from the table. We
|
||||
store it here so that we can return
|
||||
it to MySQL */
|
||||
/*----------------------*/
|
||||
UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
|
||||
/* list node of table->prebuilts */
|
||||
ulint magic_n2; /* this should be the same as
|
||||
|
|
|
|||
|
|
@ -107,8 +107,6 @@ extern ibool srv_archive_recovery;
|
|||
extern dulint srv_archive_recovery_limit_lsn;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
extern ulint srv_lock_wait_timeout;
|
||||
|
||||
extern char* srv_file_flush_method_str;
|
||||
extern ulint srv_unix_file_flush_method;
|
||||
extern ulint srv_win_file_flush_method;
|
||||
|
|
@ -134,7 +132,7 @@ extern ulint srv_fast_shutdown; /* If this is 1, do not do a
|
|||
transactions). */
|
||||
extern ibool srv_innodb_status;
|
||||
|
||||
extern ibool srv_stats_on_metadata;
|
||||
extern unsigned long long srv_stats_sample_pages;
|
||||
|
||||
extern ibool srv_use_doublewrite_buf;
|
||||
extern ibool srv_use_checksums;
|
||||
|
|
@ -145,7 +143,7 @@ extern int srv_query_thread_priority;
|
|||
extern ulong srv_max_buf_pool_modified_pct;
|
||||
extern ulong srv_max_purge_lag;
|
||||
|
||||
extern ulint srv_replication_delay;
|
||||
extern ulong srv_replication_delay;
|
||||
/*-------------------------------------------*/
|
||||
|
||||
extern ulint srv_n_rows_inserted;
|
||||
|
|
@ -517,7 +515,9 @@ struct export_var_struct{
|
|||
ulint innodb_buffer_pool_pages_dirty;
|
||||
ulint innodb_buffer_pool_pages_misc;
|
||||
ulint innodb_buffer_pool_pages_free;
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint innodb_buffer_pool_pages_latched;
|
||||
#endif /* UNIV_DEBUG */
|
||||
ulint innodb_buffer_pool_read_requests;
|
||||
ulint innodb_buffer_pool_reads;
|
||||
ulint innodb_buffer_pool_wait_free;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ trx_undo_rec_get_partial_row(
|
|||
record! */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
dtuple_t** row, /* out, own: partial row */
|
||||
ibool ignore_prefix, /* in: flag to indicate if we
|
||||
expect blob prefixes in undo. Used
|
||||
only in the assertion. */
|
||||
mem_heap_t* heap); /* in: memory heap from which the memory
|
||||
needed is allocated */
|
||||
/***************************************************************************
|
||||
|
|
|
|||
|
|
@ -15,6 +15,17 @@ Created 3/26/1996 Heikki Tuuri
|
|||
#include "mtr0mtr.h"
|
||||
#include "trx0sys.h"
|
||||
|
||||
/***********************************************************************
|
||||
Determines if this transaction is rolling back an incomplete transaction
|
||||
in crash recovery. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_is_recv(
|
||||
/*========*/
|
||||
/* out: TRUE if trx is an incomplete
|
||||
transaction that is being rolled back
|
||||
in crash recovery */
|
||||
const trx_t* trx); /* in: transaction */
|
||||
/***********************************************************************
|
||||
Returns a transaction savepoint taken at this point in time. */
|
||||
UNIV_INTERN
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@ trx_rsegf_get(
|
|||
trx_rsegf_t* header;
|
||||
|
||||
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
header = TRX_RSEG + buf_block_get_frame(block);
|
||||
|
||||
return(header);
|
||||
|
|
@ -52,9 +51,8 @@ trx_rsegf_get_new(
|
|||
trx_rsegf_t* header;
|
||||
|
||||
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
header = TRX_RSEG + buf_block_get_frame(block);
|
||||
|
||||
return(header);
|
||||
|
|
|
|||
|
|
@ -310,6 +310,15 @@ UNIV_INTERN
|
|||
void
|
||||
trx_sys_file_format_close(void);
|
||||
/*===========================*/
|
||||
/************************************************************************
|
||||
Tags the system table space with minimum format id if it has not been
|
||||
tagged yet.
|
||||
WARNING: This function is only called during the startup and AFTER the
|
||||
redo log application during recovery has finished. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_file_format_tag_init(void);
|
||||
/*==============================*/
|
||||
/*********************************************************************
|
||||
Get the name representation of the file format from its id. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -317,16 +326,18 @@ const char*
|
|||
trx_sys_file_format_id_to_name(
|
||||
/*===========================*/
|
||||
/* out: pointer to the name */
|
||||
const uint id); /* in: id of the file format */
|
||||
const ulint id); /* in: id of the file format */
|
||||
/*********************************************************************
|
||||
Set the file format tag unconditonally. */
|
||||
Set the file format id unconditionally except if it's already the
|
||||
same value. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_sys_file_format_max_set(
|
||||
/*===========================*/
|
||||
/*========================*/
|
||||
/* out: TRUE if value updated */
|
||||
ulint file_format, /* in: file format id */
|
||||
char** name); /* out: max format name */
|
||||
ulint format_id, /* in: file format id */
|
||||
const char** name); /* out: max file format name or
|
||||
NULL if not needed. */
|
||||
/*********************************************************************
|
||||
Get the name representation of the file format from its id. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -343,14 +354,16 @@ trx_sys_file_format_max_check(
|
|||
/* out: DB_SUCCESS or error code */
|
||||
ulint max_format_id); /* in: the max format id to check */
|
||||
/************************************************************************
|
||||
Update the file format tag in the tablespace to the max value. */
|
||||
Update the file format tag in the system tablespace only if the given
|
||||
format id is greater than the known max id. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_sys_file_format_max_update(
|
||||
/*===========================*/
|
||||
/* out: TRUE if value updated */
|
||||
uint flags, /* in: flags of the table */
|
||||
char** name); /* out: max format name */
|
||||
trx_sys_file_format_max_upgrade(
|
||||
/*============================*/
|
||||
/* out: TRUE if format_id was
|
||||
bigger than the known max id */
|
||||
const char** name, /* out: max file format name */
|
||||
ulint format_id); /* in: file format identifier */
|
||||
/* The automatically created system rollback segment has this id */
|
||||
#define TRX_SYS_SYSTEM_RSEG_ID 0
|
||||
|
||||
|
|
|
|||
|
|
@ -100,9 +100,8 @@ trx_sysf_get(
|
|||
|
||||
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
|
||||
RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
header = TRX_SYS + buf_block_get_frame(block);
|
||||
|
||||
return(header);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ Created 3/26/1996 Heikki Tuuri
|
|||
#include "read0types.h"
|
||||
#include "dict0types.h"
|
||||
#include "trx0xa.h"
|
||||
#include "ut0vec.h"
|
||||
|
||||
/* Dummy session used currently in MySQL interface */
|
||||
extern sess_t* trx_dummy_sess;
|
||||
|
|
@ -406,6 +407,15 @@ trx_is_interrupted(
|
|||
#define trx_is_interrupted(trx) FALSE
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/**************************************************************************
|
||||
Determines if the currently running transaction is in innodb_strict_mode. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_is_strict(
|
||||
/*==========*/
|
||||
/* out: TRUE if strict */
|
||||
trx_t* trx); /* in: transaction */
|
||||
|
||||
/***********************************************************************
|
||||
Calculates the "weight" of a transaction. The weight of one transaction
|
||||
is estimated as the number of altered rows + the number of locked rows.
|
||||
|
|
@ -592,9 +602,6 @@ struct trx_struct{
|
|||
to srv_conc_innodb_enter, if the value
|
||||
here is > 0, we decrement this by 1 */
|
||||
/*------------------------------*/
|
||||
lock_t* auto_inc_lock; /* possible auto-inc lock reserved by
|
||||
the transaction; note that it is also
|
||||
in the lock list trx_locks */
|
||||
dict_index_t* new_rec_locks[2];/* these are normally NULL; if
|
||||
srv_locks_unsafe_for_binlog is TRUE
|
||||
or session is using READ COMMITTED
|
||||
|
|
@ -726,9 +733,15 @@ struct trx_struct{
|
|||
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
|
||||
records which are currently processed
|
||||
by a rollback operation */
|
||||
/*------------------------------*/
|
||||
ulint n_autoinc_rows; /* no. of AUTO-INC rows required for
|
||||
an SQL statement. This is useful for
|
||||
multi-row INSERTs */
|
||||
ib_vector_t* autoinc_locks; /* AUTOINC locks held by this
|
||||
transaction. Note that these are
|
||||
also in the lock list trx_locks. This
|
||||
vector needs to be freed explicitly
|
||||
when the trx_t instance is desrtoyed */
|
||||
/*------------------------------*/
|
||||
char detailed_error[256]; /* detailed error message for last
|
||||
error, or empty. */
|
||||
|
|
|
|||
|
|
@ -36,6 +36,14 @@ typedef struct roll_node_struct roll_node_t;
|
|||
typedef struct commit_node_struct commit_node_t;
|
||||
typedef struct trx_named_savept_struct trx_named_savept_t;
|
||||
|
||||
/* Rollback contexts */
|
||||
enum trx_rb_ctx {
|
||||
RB_NONE = 0, /* no rollback */
|
||||
RB_NORMAL, /* normal rollback */
|
||||
RB_RECOVERY, /* rolling back an incomplete transaction,
|
||||
in crash recovery */
|
||||
};
|
||||
|
||||
/* Transaction savepoint */
|
||||
typedef struct trx_savept_struct trx_savept_t;
|
||||
struct trx_savept_struct{
|
||||
|
|
|
|||
|
|
@ -232,10 +232,9 @@ ulint
|
|||
trx_undo_assign_undo(
|
||||
/*=================*/
|
||||
/* out: DB_SUCCESS if undo log assign
|
||||
* successful, possible error codes are:
|
||||
* ER_TOO_MANY_CONCURRENT_TRXS
|
||||
* DB_OUT_OF_FILE_SPAC
|
||||
* DB_OUT_OF_MEMORY */
|
||||
successful, possible error codes are:
|
||||
DB_TOO_MANY_CONCURRENT_TRXS
|
||||
DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
|
||||
trx_t* trx, /* in: transaction */
|
||||
ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
|
||||
/**********************************************************************
|
||||
|
|
|
|||
|
|
@ -135,9 +135,7 @@ trx_undo_page_get(
|
|||
{
|
||||
buf_block_t* block = buf_page_get(space, zip_size, page_no,
|
||||
RW_X_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
|
@ -157,9 +155,7 @@ trx_undo_page_get_s_latched(
|
|||
{
|
||||
buf_block_t* block = buf_page_get(space, zip_size, page_no,
|
||||
RW_S_LATCH, mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Created 1/20/1994 Heikki Tuuri
|
|||
|
||||
#define INNODB_VERSION_MAJOR 1
|
||||
#define INNODB_VERSION_MINOR 0
|
||||
#define INNODB_VERSION_BUGFIX 1
|
||||
#define INNODB_VERSION_BUGFIX 2
|
||||
|
||||
/* The following is the InnoDB version as shown in
|
||||
SELECT plugin_version FROM information_schema.plugins;
|
||||
|
|
@ -137,6 +137,7 @@ command. Not tested on Windows. */
|
|||
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
|
||||
(field file_page_was_freed
|
||||
in buf_page_t) */
|
||||
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
|
||||
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
|
||||
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
||||
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
|
||||
|
|
@ -157,6 +158,8 @@ operations (very slow); also UNIV_DEBUG must be defined */
|
|||
printing B-trees */
|
||||
#define UNIV_ZIP_DEBUG /* extensive consistency checks
|
||||
for compressed pages */
|
||||
#define UNIV_ZIP_COPY /* call page_zip_copy_recs()
|
||||
more often */
|
||||
#endif
|
||||
|
||||
#define UNIV_BTR_DEBUG /* check B-tree links */
|
||||
|
|
|
|||
|
|
@ -175,20 +175,11 @@ ut_fold_string(
|
|||
/* out: folded value */
|
||||
const char* str) /* in: null-terminated string */
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint i = 0;
|
||||
#endif
|
||||
ulint fold = 0;
|
||||
|
||||
ut_ad(str);
|
||||
|
||||
while (*str != '\0') {
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
i++;
|
||||
ut_a(i < 100);
|
||||
#endif
|
||||
|
||||
fold = ut_fold_ulint_pair(fold, (ulint)(*str));
|
||||
str++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,11 +150,15 @@ ib_time_t
|
|||
ut_time(void);
|
||||
/*=========*/
|
||||
/**************************************************************
|
||||
Returns system time. */
|
||||
Returns system time.
|
||||
Upon successful completion, the value 0 is returned; otherwise the
|
||||
value -1 is returned and the global variable errno is set to indicate the
|
||||
error. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
int
|
||||
ut_usectime(
|
||||
/*========*/
|
||||
/* out: 0 on success, -1 otherwise */
|
||||
ulint* sec, /* out: seconds since the Epoch */
|
||||
ulint* ms); /* out: microseconds since the Epoch+*sec */
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,16 @@ ulint
|
|||
ib_vector_size(
|
||||
/*===========*/
|
||||
/* out: number of elements in vector */
|
||||
ib_vector_t* vec); /* in: vector */
|
||||
const ib_vector_t* vec); /* in: vector */
|
||||
|
||||
/********************************************************************
|
||||
Test whether a vector is empty or not. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
ib_vector_is_empty(
|
||||
/*===============*/
|
||||
/* out: TRUE if empty */
|
||||
const ib_vector_t* vec); /* in: vector */
|
||||
|
||||
/********************************************************************
|
||||
Get the n'th element. */
|
||||
|
|
@ -58,6 +67,23 @@ ib_vector_get(
|
|||
ib_vector_t* vec, /* in: vector */
|
||||
ulint n); /* in: element index to get */
|
||||
|
||||
/********************************************************************
|
||||
Remove the last element from the vector. */
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ib_vector_pop(
|
||||
/*==========*/
|
||||
ib_vector_t* vec); /* in: vector */
|
||||
|
||||
/********************************************************************
|
||||
Free the underlying heap of the vector. Note that vec is invalid
|
||||
after this call. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ib_vector_free(
|
||||
/*===========*/
|
||||
ib_vector_t* vec); /* in,own: vector */
|
||||
|
||||
/* See comment at beginning of file. */
|
||||
struct ib_vector_struct {
|
||||
mem_heap_t* heap; /* heap */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ ulint
|
|||
ib_vector_size(
|
||||
/*===========*/
|
||||
/* out: number of elements in vector */
|
||||
ib_vector_t* vec) /* in: vector */
|
||||
const ib_vector_t* vec) /* in: vector */
|
||||
{
|
||||
return(vec->used);
|
||||
}
|
||||
|
|
@ -24,3 +24,47 @@ ib_vector_get(
|
|||
|
||||
return(vec->data[n]);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Remove the last element from the vector. */
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ib_vector_pop(
|
||||
/*==========*/
|
||||
/* out: last vector element */
|
||||
ib_vector_t* vec) /* in/out: vector */
|
||||
{
|
||||
void* elem;
|
||||
|
||||
ut_a(vec->used > 0);
|
||||
--vec->used;
|
||||
elem = vec->data[vec->used];
|
||||
|
||||
ut_d(vec->data[vec->used] = NULL);
|
||||
UNIV_MEM_INVALID(&vec->data[vec->used], sizeof(*vec->data));
|
||||
|
||||
return(elem);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Free the underlying heap of the vector. Note that vec is invalid
|
||||
after this call. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ib_vector_free(
|
||||
/*===========*/
|
||||
ib_vector_t* vec) /* in, own: vector */
|
||||
{
|
||||
mem_heap_free(vec->heap);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Test whether a vector is empty or not. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
ib_vector_is_empty(
|
||||
/*===============*/ /* out: TRUE if empty else FALSE */
|
||||
const ib_vector_t* vec) /* in vector to test */
|
||||
{
|
||||
return(ib_vector_size(vec) == 0);
|
||||
}
|
||||
|
|
|
|||
238
lock/lock0lock.c
238
lock/lock0lock.c
|
|
@ -2166,24 +2166,25 @@ static
|
|||
void
|
||||
lock_grant(
|
||||
/*=======*/
|
||||
lock_t* lock) /* in: waiting lock request */
|
||||
lock_t* lock) /* in/out: waiting lock request */
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
lock_reset_lock_and_trx_wait(lock);
|
||||
|
||||
if (lock_get_mode(lock) == LOCK_AUTO_INC) {
|
||||
trx_t* trx = lock->trx;
|
||||
dict_table_t* table = lock->un_member.tab_lock.table;
|
||||
|
||||
if (lock->trx->auto_inc_lock != NULL) {
|
||||
if (table->autoinc_trx == trx) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trx already had"
|
||||
" an AUTO-INC lock!\n");
|
||||
} else {
|
||||
table->autoinc_trx = trx;
|
||||
|
||||
ib_vector_push(trx->autoinc_locks, lock);
|
||||
}
|
||||
|
||||
/* Store pointer to lock to trx so that we know to
|
||||
release it at the end of the SQL statement */
|
||||
|
||||
lock->trx->auto_inc_lock = lock;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
|
@ -3531,15 +3532,16 @@ lock_table_create(
|
|||
++table->n_waiting_or_granted_auto_inc_locks;
|
||||
}
|
||||
|
||||
/* For AUTOINC locking we reuse the lock instance only if
|
||||
there is no wait involved else we allocate the waiting lock
|
||||
from the transaction lock heap. */
|
||||
if (type_mode == LOCK_AUTO_INC) {
|
||||
/* Only one trx can have the lock on the table
|
||||
at a time: we may use the memory preallocated
|
||||
to the table object */
|
||||
|
||||
lock = table->auto_inc_lock;
|
||||
lock = table->autoinc_lock;
|
||||
|
||||
ut_a(trx->auto_inc_lock == NULL);
|
||||
trx->auto_inc_lock = lock;
|
||||
table->autoinc_trx = trx;
|
||||
|
||||
ib_vector_push(trx->autoinc_locks, lock);
|
||||
} else {
|
||||
lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t));
|
||||
}
|
||||
|
|
@ -3571,16 +3573,39 @@ lock_table_remove_low(
|
|||
/*==================*/
|
||||
lock_t* lock) /* in: table lock */
|
||||
{
|
||||
dict_table_t* table;
|
||||
trx_t* trx;
|
||||
dict_table_t* table;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
table = lock->un_member.tab_lock.table;
|
||||
trx = lock->trx;
|
||||
table = lock->un_member.tab_lock.table;
|
||||
|
||||
if (lock == trx->auto_inc_lock) {
|
||||
trx->auto_inc_lock = NULL;
|
||||
/* Remove the table from the transaction's AUTOINC vector, if
|
||||
the lock that is being release is an AUTOINC lock. */
|
||||
if (lock_get_mode(lock) == LOCK_AUTO_INC) {
|
||||
|
||||
/* The table's AUTOINC lock can get transferred to
|
||||
another transaction before we get here. */
|
||||
if (table->autoinc_trx == trx) {
|
||||
table->autoinc_trx = NULL;
|
||||
}
|
||||
|
||||
/* The locks must be freed in the reverse order from
|
||||
the one in which they were acquired. This is to avoid
|
||||
traversing the AUTOINC lock vector unnecessarily.
|
||||
|
||||
We only store locks that were granted in the
|
||||
trx->autoinc_locks vector (see lock_table_create()
|
||||
and lock_grant()). Therefore it can be empty and we
|
||||
need to check for that. */
|
||||
|
||||
if (!ib_vector_is_empty(trx->autoinc_locks)) {
|
||||
lock_t* autoinc_lock;
|
||||
|
||||
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
|
||||
ut_a(autoinc_lock == lock);
|
||||
}
|
||||
|
||||
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
|
||||
--table->n_waiting_or_granted_auto_inc_locks;
|
||||
|
|
@ -3955,24 +3980,6 @@ lock_table_unlock(
|
|||
mutex_exit(&kernel_mutex);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Releases an auto-inc lock a transaction possibly has on a table.
|
||||
Releases possible other transactions waiting for this lock. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_table_unlock_auto_inc(
|
||||
/*=======================*/
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
if (trx->auto_inc_lock) {
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
lock_table_dequeue(trx->auto_inc_lock);
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Releases transaction locks, and releases possible other transactions waiting
|
||||
because of these locks. */
|
||||
|
|
@ -4032,9 +4039,9 @@ lock_release_off_kernel(
|
|||
lock = UT_LIST_GET_LAST(trx->trx_locks);
|
||||
}
|
||||
|
||||
mem_heap_empty(trx->lock_heap);
|
||||
ut_a(ib_vector_size(trx->autoinc_locks) == 0);
|
||||
|
||||
ut_a(trx->auto_inc_lock == NULL);
|
||||
mem_heap_empty(trx->lock_heap);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
@ -4054,6 +4061,11 @@ lock_cancel_waiting_and_release(
|
|||
} else {
|
||||
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
|
||||
|
||||
if (lock->trx->autoinc_locks != NULL) {
|
||||
/* Release the transaction's AUTOINC locks/ */
|
||||
lock_release_autoinc_locks(lock->trx);
|
||||
}
|
||||
|
||||
lock_table_dequeue(lock);
|
||||
}
|
||||
|
||||
|
|
@ -4066,15 +4078,25 @@ lock_cancel_waiting_and_release(
|
|||
trx_end_lock_wait(lock->trx);
|
||||
}
|
||||
|
||||
/* True if a lock mode is S or X */
|
||||
#define IS_LOCK_S_OR_X(lock) \
|
||||
(lock_get_mode(lock) == LOCK_S \
|
||||
|| lock_get_mode(lock) == LOCK_X)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Resets all record and table locks of a transaction on a table to be dropped.
|
||||
No lock is allowed to be a wait lock. */
|
||||
Removes locks of a transaction on a table to be dropped.
|
||||
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
|
||||
also removed in addition to other table-level and record-level locks.
|
||||
No lock, that is going to be removed, is allowed to be a wait lock. */
|
||||
static
|
||||
void
|
||||
lock_reset_all_on_table_for_trx(
|
||||
/*============================*/
|
||||
dict_table_t* table, /* in: table to be dropped */
|
||||
trx_t* trx) /* in: a transaction */
|
||||
lock_remove_all_on_table_for_trx(
|
||||
/*=============================*/
|
||||
dict_table_t* table, /* in: table to be dropped */
|
||||
trx_t* trx, /* in: a transaction */
|
||||
ibool remove_also_table_sx_locks)/* in: also removes
|
||||
table S and X locks */
|
||||
{
|
||||
lock_t* lock;
|
||||
lock_t* prev_lock;
|
||||
|
|
@ -4092,7 +4114,9 @@ lock_reset_all_on_table_for_trx(
|
|||
|
||||
lock_rec_discard(lock);
|
||||
} else if (lock_get_type_low(lock) & LOCK_TABLE
|
||||
&& lock->un_member.tab_lock.table == table) {
|
||||
&& lock->un_member.tab_lock.table == table
|
||||
&& (remove_also_table_sx_locks
|
||||
|| !IS_LOCK_S_OR_X(lock))) {
|
||||
|
||||
ut_a(!lock_get_wait(lock));
|
||||
|
||||
|
|
@ -4104,26 +4128,65 @@ lock_reset_all_on_table_for_trx(
|
|||
}
|
||||
|
||||
/*************************************************************************
|
||||
Resets all locks, both table and record locks, on a table to be dropped.
|
||||
No lock is allowed to be a wait lock. */
|
||||
Removes locks on a table to be dropped or truncated.
|
||||
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
|
||||
also removed in addition to other table-level and record-level locks.
|
||||
No lock, that is going to be removed, is allowed to be a wait lock. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_reset_all_on_table(
|
||||
/*====================*/
|
||||
dict_table_t* table) /* in: table to be dropped */
|
||||
lock_remove_all_on_table(
|
||||
/*=====================*/
|
||||
dict_table_t* table, /* in: table to be dropped
|
||||
or truncated */
|
||||
ibool remove_also_table_sx_locks)/* in: also removes
|
||||
table S and X locks */
|
||||
{
|
||||
lock_t* lock;
|
||||
lock_t* prev_lock;
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
|
||||
lock = UT_LIST_GET_FIRST(table->locks);
|
||||
|
||||
while (lock) {
|
||||
ut_a(!lock_get_wait(lock));
|
||||
while (lock != NULL) {
|
||||
|
||||
lock_reset_all_on_table_for_trx(table, lock->trx);
|
||||
prev_lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
|
||||
lock);
|
||||
|
||||
lock = UT_LIST_GET_FIRST(table->locks);
|
||||
/* If we should remove all locks (remove_also_table_sx_locks
|
||||
is TRUE), or if the lock is not table-level S or X lock,
|
||||
then check we are not going to remove a wait lock. */
|
||||
if (remove_also_table_sx_locks
|
||||
|| !(lock_get_type(lock) == LOCK_TABLE
|
||||
&& IS_LOCK_S_OR_X(lock))) {
|
||||
|
||||
ut_a(!lock_get_wait(lock));
|
||||
}
|
||||
|
||||
lock_remove_all_on_table_for_trx(table, lock->trx,
|
||||
remove_also_table_sx_locks);
|
||||
|
||||
if (prev_lock == NULL) {
|
||||
if (lock == UT_LIST_GET_FIRST(table->locks)) {
|
||||
/* lock was not removed, pick its successor */
|
||||
lock = UT_LIST_GET_NEXT(
|
||||
un_member.tab_lock.locks, lock);
|
||||
} else {
|
||||
/* lock was removed, pick the first one */
|
||||
lock = UT_LIST_GET_FIRST(table->locks);
|
||||
}
|
||||
} else if (UT_LIST_GET_NEXT(un_member.tab_lock.locks,
|
||||
prev_lock) != lock) {
|
||||
/* If lock was removed by
|
||||
lock_remove_all_on_table_for_trx() then pick the
|
||||
successor of prev_lock ... */
|
||||
lock = UT_LIST_GET_NEXT(
|
||||
un_member.tab_lock.locks, prev_lock);
|
||||
} else {
|
||||
/* ... otherwise pick the successor of lock. */
|
||||
lock = UT_LIST_GET_NEXT(
|
||||
un_member.tab_lock.locks, lock);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
|
@ -4264,6 +4327,15 @@ lock_rec_print(
|
|||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Print the number of lock structs from lock_print_info_summary() only
|
||||
in non-production builds for performance reasons, see
|
||||
http://bugs.mysql.com/36942 */
|
||||
#define PRINT_NUM_OF_LOCK_STRUCTS
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
|
||||
/*************************************************************************
|
||||
Calculates the number of record lock structs in the record lock hash table. */
|
||||
static
|
||||
|
|
@ -4290,6 +4362,7 @@ lock_get_n_rec_locks(void)
|
|||
|
||||
return(n_locks);
|
||||
}
|
||||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
|
||||
/*************************************************************************
|
||||
Prints info of locks for all transactions. */
|
||||
|
|
@ -4331,9 +4404,11 @@ lock_print_info_summary(
|
|||
"History list length %lu\n",
|
||||
(ulong) trx_sys->rseg_history_len);
|
||||
|
||||
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
|
||||
fprintf(file,
|
||||
"Total number of lock structs in row lock hash table %lu\n",
|
||||
(ulong) lock_get_n_rec_locks());
|
||||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
@ -4687,9 +4762,8 @@ lock_rec_validate_page(
|
|||
|
||||
block = buf_page_get(space, fil_space_get_zip_size(space),
|
||||
page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
page = block->frame;
|
||||
|
||||
lock_mutex_enter_kernel();
|
||||
|
|
@ -5324,6 +5398,60 @@ lock_clust_rec_read_check_and_lock_alt(
|
|||
return(ret);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Release the last lock from the transaction's autoinc locks. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_release_autoinc_last_lock(
|
||||
/*===========================*/
|
||||
ib_vector_t* autoinc_locks) /* in/out: vector of AUTOINC locks */
|
||||
{
|
||||
ulint last;
|
||||
lock_t* lock;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
ut_a(!ib_vector_is_empty(autoinc_locks));
|
||||
|
||||
/* The lock to be release must be the last lock acquired. */
|
||||
last = ib_vector_size(autoinc_locks) - 1;
|
||||
lock = ib_vector_get(autoinc_locks, last);
|
||||
|
||||
/* Should have only AUTOINC locks in the vector. */
|
||||
ut_a(lock_get_mode(lock) == LOCK_AUTO_INC);
|
||||
ut_a(lock_get_type(lock) == LOCK_TABLE);
|
||||
|
||||
ut_a(lock->un_member.tab_lock.table != NULL);
|
||||
|
||||
/* This will remove the lock from the trx autoinc_locks too. */
|
||||
lock_table_dequeue(lock);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Release all the transaction's autoinc locks. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
lock_release_autoinc_locks(
|
||||
/*=======================*/
|
||||
trx_t* trx) /* in/out: transaction */
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
ut_a(trx->autoinc_locks != NULL);
|
||||
|
||||
/* We release the locks in the reverse order. This is to
|
||||
avoid searching the vector for the element to delete at
|
||||
the lower level. See (lock_table_remove_low()) for details. */
|
||||
while (!ib_vector_is_empty(trx->autoinc_locks)) {
|
||||
|
||||
/* lock_table_remove_low() will also remove the lock from
|
||||
the transaction's autoinc_locks vector. */
|
||||
lock_release_autoinc_last_lock(trx->autoinc_locks);
|
||||
}
|
||||
|
||||
/* Should release all locks. */
|
||||
ut_a(ib_vector_is_empty(trx->autoinc_locks));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Gets the type of a lock. Non-inline version for using outside of the
|
||||
lock module. */
|
||||
|
|
|
|||
|
|
@ -1253,9 +1253,7 @@ recv_recover_page(
|
|||
&mtr);
|
||||
ut_a(success);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
}
|
||||
|
||||
/* Read the newest modification lsn from the page */
|
||||
|
|
@ -1343,6 +1341,16 @@ recv_recover_page(
|
|||
recv = UT_LIST_GET_NEXT(rec_list, recv);
|
||||
}
|
||||
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
|
||||
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||
|
||||
if (page_zip) {
|
||||
ut_a(page_zip_validate_low(page_zip, page, FALSE));
|
||||
}
|
||||
}
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
||||
mutex_enter(&(recv_sys->mutex));
|
||||
|
||||
if (recv_max_page_lsn < page_lsn) {
|
||||
|
|
@ -1491,10 +1499,9 @@ loop:
|
|||
block = buf_page_get(
|
||||
space, zip_size, page_no,
|
||||
RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_block_dbg_add_level(
|
||||
block, SYNC_NO_ORDER_CHECK);
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
recv_recover_page(FALSE, FALSE, block);
|
||||
mtr_commit(&mtr);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -491,6 +491,7 @@ mem_heap_validate_or_print(
|
|||
|
||||
if (print) {
|
||||
ut_print_buf(stderr, user_field, len);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
total_len += len;
|
||||
|
|
|
|||
|
|
@ -330,40 +330,33 @@ mem_heap_create_block(
|
|||
}
|
||||
|
||||
/* In dynamic allocation, calculate the size: block header + data. */
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
|
||||
if (type == MEM_HEAP_DYNAMIC) {
|
||||
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
|
||||
|
||||
ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
|
||||
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
block = mem_area_alloc(&len, mem_comm_pool);
|
||||
} else {
|
||||
ut_ad(n <= MEM_MAX_ALLOC_IN_BUF);
|
||||
len = UNIV_PAGE_SIZE;
|
||||
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
if ((type & MEM_HEAP_BTR_SEARCH) && heap) {
|
||||
/* We cannot allocate the block from the
|
||||
buffer pool, but must get the free block from
|
||||
the heap header free block field */
|
||||
|
||||
if (len < UNIV_PAGE_SIZE / 2) {
|
||||
buf_block = heap->free_block;
|
||||
heap->free_block = NULL;
|
||||
|
||||
block = mem_area_alloc(&len, mem_comm_pool);
|
||||
} else {
|
||||
len = UNIV_PAGE_SIZE;
|
||||
if (UNIV_UNLIKELY(!buf_block)) {
|
||||
|
||||
if ((type & MEM_HEAP_BTR_SEARCH) && heap) {
|
||||
/* We cannot allocate the block from the
|
||||
buffer pool, but must get the free block from
|
||||
the heap header free block field */
|
||||
|
||||
buf_block = heap->free_block;
|
||||
heap->free_block = NULL;
|
||||
|
||||
if (UNIV_UNLIKELY(!buf_block)) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
buf_block = buf_block_alloc(0);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
block = (mem_block_t*) buf_block->frame;
|
||||
} else {
|
||||
buf_block = buf_block_alloc(0);
|
||||
}
|
||||
|
||||
block = (mem_block_t*) buf_block->frame;
|
||||
}
|
||||
|
||||
ut_ad(block);
|
||||
|
|
@ -492,19 +485,14 @@ mem_heap_block_free(
|
|||
UNIV_MEM_ASSERT_AND_FREE(block, len);
|
||||
#endif /* UNIV_MEM_DEBUG */
|
||||
|
||||
if (type == MEM_HEAP_DYNAMIC) {
|
||||
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
|
||||
|
||||
ut_ad(!buf_block);
|
||||
mem_area_free(block, mem_comm_pool);
|
||||
} else {
|
||||
ut_ad(type & MEM_HEAP_BUFFER);
|
||||
|
||||
if (len >= UNIV_PAGE_SIZE / 2) {
|
||||
buf_block_free(buf_block);
|
||||
} else {
|
||||
ut_ad(!buf_block);
|
||||
mem_area_free(block, mem_comm_pool);
|
||||
}
|
||||
buf_block_free(buf_block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
2
mysql-test/innodb-analyze.result
Normal file
2
mysql-test/innodb-analyze.result
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Variable_name Value
|
||||
innodb_stats_sample_pages 1
|
||||
63
mysql-test/innodb-analyze.test
Normal file
63
mysql-test/innodb-analyze.test
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# Test that mysqld does not crash when running ANALYZE TABLE with
|
||||
# different values of the parameter innodb_stats_sample_pages.
|
||||
#
|
||||
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
# we care only that the following SQL commands do not produce errors
|
||||
# and do not crash the server
|
||||
-- disable_query_log
|
||||
-- disable_result_log
|
||||
-- enable_warnings
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=0;
|
||||
|
||||
# check that the value has been adjusted to 1
|
||||
-- enable_result_log
|
||||
SHOW VARIABLES LIKE 'innodb_stats_sample_pages';
|
||||
-- disable_result_log
|
||||
|
||||
CREATE TABLE innodb_analyze (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY(a),
|
||||
KEY(b,a)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
# test with empty table
|
||||
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=2;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=4;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=8;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=16;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
INSERT INTO innodb_analyze VALUES
|
||||
(1,1), (1,1), (1,2), (1,3), (1,4), (1,5),
|
||||
(8,1), (8,8), (8,2), (7,1), (1,4), (3,5);
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=1;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=2;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=4;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=8;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=16;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
DROP TABLE innodb_analyze;
|
||||
|
|
@ -87,3 +87,497 @@ SELECT * FROM t1;
|
|||
c1 c2
|
||||
18446744073709551615 NULL
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
TRUNCATE TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DELETE FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
7
|
||||
8
|
||||
9
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1);
|
||||
INSERT INTO t1 VALUES (NULL,8);
|
||||
SELECT * FROM t1;
|
||||
c1 c2
|
||||
2 1
|
||||
3 8
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1), (NULL, 8);
|
||||
INSERT INTO t1 VALUES (NULL,9);
|
||||
SELECT * FROM t1;
|
||||
c1 c2
|
||||
2 1
|
||||
3 8
|
||||
5 9
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 100
|
||||
auto_increment_offset 10
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL),(5),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
5
|
||||
10
|
||||
110
|
||||
250
|
||||
310
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
5
|
||||
10
|
||||
110
|
||||
250
|
||||
310
|
||||
400
|
||||
410
|
||||
1000
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(0);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
INSERT INTO t1 VALUES (-1), (NULL),(2),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
250
|
||||
410
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
Got one of the listed errors
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
250
|
||||
410
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 100
|
||||
auto_increment_offset 10
|
||||
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
1
|
||||
2
|
||||
10
|
||||
250
|
||||
310
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
1
|
||||
2
|
||||
10
|
||||
250
|
||||
310
|
||||
400
|
||||
410
|
||||
1000
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 100
|
||||
auto_increment_offset 10
|
||||
INSERT INTO t1 VALUES (-2);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (2);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (250);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
210
|
||||
250
|
||||
310
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
210
|
||||
250
|
||||
310
|
||||
400
|
||||
1000
|
||||
1010
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 100
|
||||
auto_increment_offset 10
|
||||
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
210
|
||||
250
|
||||
410
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
Got one of the listed errors
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
10
|
||||
110
|
||||
210
|
||||
250
|
||||
410
|
||||
1000
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (9223372036854775794);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
9223372036854775794
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 2
|
||||
auto_increment_offset 10
|
||||
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
9223372036854775794
|
||||
9223372036854775796
|
||||
9223372036854775798
|
||||
9223372036854775800
|
||||
9223372036854775802
|
||||
9223372036854775804
|
||||
9223372036854775806
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551603);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
18446744073709551603
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 2
|
||||
auto_increment_offset 10
|
||||
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
0
|
||||
1
|
||||
18446744073709551603
|
||||
18446744073709551604
|
||||
18446744073709551606
|
||||
18446744073709551608
|
||||
18446744073709551610
|
||||
18446744073709551612
|
||||
18446744073709551614
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551603);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
18446744073709551603
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 5
|
||||
auto_increment_offset 7
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
Got one of the listed errors
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
18446744073709551603
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES(-9223372036854775806);
|
||||
INSERT INTO t1 VALUES(-9223372036854775807);
|
||||
INSERT INTO t1 VALUES(-9223372036854775808);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-9223372036854775808
|
||||
-9223372036854775807
|
||||
-9223372036854775806
|
||||
1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 3
|
||||
auto_increment_offset 3
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
-9223372036854775808
|
||||
-9223372036854775807
|
||||
-9223372036854775806
|
||||
1
|
||||
3
|
||||
6
|
||||
9
|
||||
DROP TABLE t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 1
|
||||
auto_increment_offset 1
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551610);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
18446744073709551610
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect auto_increment_increment value: '1152921504606846976'
|
||||
Warning 1292 Truncated incorrect auto_increment_offset value: '1152921504606846976'
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
Variable_name Value
|
||||
auto_increment_increment 65535
|
||||
auto_increment_offset 65535
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
65534
|
||||
65535
|
||||
18446744073709551610
|
||||
18446744073709551615
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -105,3 +105,269 @@ INSERT INTO t1 VALUES (18446744073709551615, null);
|
|||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 37531
|
||||
# After truncate, auto_increment behaves incorrectly for InnoDB
|
||||
#
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
TRUNCATE TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Deleting all records should not reset the AUTOINC counter.
|
||||
#
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DELETE FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 38839
|
||||
# Reset the last value generated at end of statement
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1);
|
||||
INSERT INTO t1 VALUES (NULL,8);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
# Bug 38839 -- same as above but for multi value insert
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1), (NULL, 8);
|
||||
INSERT INTO t1 VALUES (NULL,9);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test changes to AUTOINC next value calculation
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL),(5),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test with SIGNED INT column, by inserting a 0 for the first column value
|
||||
# 0 is treated in the same was NULL.
|
||||
# Reset the AUTOINC session variables
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(0);
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
INSERT INTO t1 VALUES (-1), (NULL),(2),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
SET @@INSERT_ID=400;
|
||||
# Duplicate error expected here for autoinc_lock_mode != TRADITIONAL
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test with SIGNED INT column
|
||||
# Reset the AUTOINC session variables
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test with UNSIGNED INT column, single insert
|
||||
# The sign in the value is ignored and a new column value is generated
|
||||
# Reset the AUTOINC session variables
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
INSERT INTO t1 VALUES (-2);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (2);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
INSERT INTO t1 VALUES (250);
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Test with UNSIGNED INT column, multi-value inserts
|
||||
# The sign in the value is ignored and a new column value is generated
|
||||
# Reset the AUTOINC session variables
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(-1);
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
|
||||
INSERT INTO t1 VALUES (250),(NULL);
|
||||
SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (1000);
|
||||
SET @@INSERT_ID=400;
|
||||
# Duplicate error expected here for autoinc_lock_mode != TRADITIONAL
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Check for overflow handling when increment is > 1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
# TODO: Fix the autoinc init code
|
||||
# We have to do this because of a bug in the AUTOINC init code.
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (9223372036854775794); -- 2^63 - 14
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
# This should just fit
|
||||
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Check for overflow handling when increment and offser are > 1
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
# TODO: Fix the autoinc init code
|
||||
# We have to do this because of a bug in the AUTOINC init code.
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551603); -- 2^64 - 13
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
# This should fail because of overflow but it doesn't, it seems to be
|
||||
# a MySQL server bug. It wraps around to 0 for the last value.
|
||||
# See MySQL Bug# 39828
|
||||
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Check for overflow handling when increment and offset are odd numbers
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
# TODO: Fix the autoinc init code
|
||||
# We have to do this because of a bug in the AUTOINC init code.
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551603); -- 2^64 - 13
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
# This should fail because of overflow but it doesn't. It fails with
|
||||
# a duplicate entry message because of a MySQL server bug, it wraps
|
||||
# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace
|
||||
# the ER_DUP_ENTRY, 1062 below with the appropriate error message
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Check for overflow handling when increment and offset are odd numbers
|
||||
# and check for large -ve numbers
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
# TODO: Fix the autoinc init code
|
||||
# We have to do this because of a bug in the AUTOINC init code.
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES(-9223372036854775806); -- -2^63 + 2
|
||||
INSERT INTO t1 VALUES(-9223372036854775807); -- -2^63 + 1
|
||||
INSERT INTO t1 VALUES(-9223372036854775808); -- -2^63
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Check for overflow handling when increment and offset are very
|
||||
# large numbers 2^60
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
|
||||
SET @@INSERT_ID=1;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
# TODO: Fix the autoinc init code
|
||||
# We have to do this because of a bug in the AUTOINC init code.
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES (18446744073709551610); -- 2^64 - 2
|
||||
SELECT * FROM t1;
|
||||
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
|
||||
SHOW VARIABLES LIKE "%auto_inc%";
|
||||
# This should fail because of overflow but it doesn't. It wraps around
|
||||
# and the autoinc values look bogus too.
|
||||
# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
|
||||
# code expected test.
|
||||
# -- error ER_AUTOINC_READ_FAILED,1467
|
||||
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@ t1 CREATE TABLE `t1` (
|
|||
explain select * from t1 force index(c) order by c;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL c 10 NULL 4
|
||||
drop index c on t1;
|
||||
ERROR 42000: This table type requires a primary key
|
||||
alter table t1 add primary key (a), drop index c;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
|
|
@ -765,7 +763,6 @@ insert into t2 values ('jejdkrun87'),('adfd72nh9k'),
|
|||
('adfdpplkeock'),('adfdijnmnb78k'),('adfdijn0loKNHJik');
|
||||
create table t1(a int, b blob, c text, d text not null)
|
||||
engine=innodb default charset = utf8;
|
||||
insert into t1 values (null,null,null,'null');
|
||||
insert into t1
|
||||
select a,left(repeat(d,100*a),65535),repeat(d,20*a),d from t2,t3;
|
||||
drop table t2, t3;
|
||||
|
|
@ -775,7 +772,6 @@ count(*)
|
|||
select a,
|
||||
length(b),b=left(repeat(d,100*a),65535),length(c),c=repeat(d,20*a),d from t1;
|
||||
a length(b) b=left(repeat(d,100*a),65535) length(c) c=repeat(d,20*a) d
|
||||
NULL NULL NULL NULL NULL null
|
||||
22 22000 1 4400 1 adfd72nh9k
|
||||
22 35200 1 7040 1 adfdijn0loKNHJik
|
||||
22 28600 1 5720 1 adfdijnmnb78k
|
||||
|
|
@ -802,9 +798,6 @@ NULL NULL NULL NULL NULL null
|
|||
66 65535 1 15840 1 adfdpplkeock
|
||||
66 65535 1 13200 1 jejdkrun87
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
ERROR 42000: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead
|
||||
delete from t1 where d='null';
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
ERROR 23000: Duplicate entry '22' for key 'PRIMARY'
|
||||
delete from t1 where a%2;
|
||||
check table t1;
|
||||
|
|
@ -847,15 +840,17 @@ Table Op Msg_type Msg_text
|
|||
test.t1 check status OK
|
||||
explain select * from t1 where b like 'adfd%';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range b b 769 NULL 11 Using where
|
||||
1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where
|
||||
create table t2(a int, b varchar(255), primary key(a,b)) engine=innodb;
|
||||
insert into t2 select a,left(b,255) from t1;
|
||||
drop table t1;
|
||||
rename table t2 to t1;
|
||||
set innodb_lock_wait_timeout=1;
|
||||
begin;
|
||||
select a from t1 limit 1 for update;
|
||||
a
|
||||
22
|
||||
set innodb_lock_wait_timeout=1;
|
||||
create index t1ba on t1 (b,a);
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
commit;
|
||||
|
|
@ -889,10 +884,12 @@ a
|
|||
44
|
||||
commit;
|
||||
drop table t1;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format='Barracuda';
|
||||
create table t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob,
|
||||
i blob,j blob,k blob,l blob,m blob,n blob,o blob,p blob,
|
||||
q blob,r blob,s blob,t blob,u blob)
|
||||
engine=innodb;
|
||||
engine=innodb row_format=dynamic;
|
||||
create index t1a on t1 (a(1));
|
||||
create index t1b on t1 (b(1));
|
||||
create index t1c on t1 (c(1));
|
||||
|
|
@ -963,5 +960,175 @@ t1 CREATE TABLE `t1` (
|
|||
KEY `t1s` (`s`(1)),
|
||||
KEY `t1t` (`t`(1)),
|
||||
KEY `t1st` (`s`(1),`t`(1))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
create index t1u on t1 (u(1));
|
||||
ERROR HY000: Too big row
|
||||
alter table t1 row_format=compact;
|
||||
create index t1u on t1 (u(1));
|
||||
drop table t1;
|
||||
set global innodb_file_per_table=0;
|
||||
set global innodb_file_format=Antelope;
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
INSERT INTO t1 VALUES(0);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1,c2,c3)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`,`c2`,`c3`),
|
||||
KEY `fk_t2_ca` (`c3`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`,`c2`,`c3`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
INSERT INTO t2 VALUES(0,0,1);
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
DELETE FROM t1;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
DELETE FROM t2;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
c2 INT(4) NOT NULL,
|
||||
PRIMARY KEY (c2,c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(12) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c2`,`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c2_c1 ON t2(c2, c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c1_c2 ON t2(c3, c1, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
KEY `i_t2_c3_c1_c2` (`c3`,`c1`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
KEY `i_t2_c3_c1_c2` (`c3`,`c1`,`c2`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ drop table `t1#2`;
|
|||
alter table t1 add unique index (c), add index (d);
|
||||
show create table t1;
|
||||
explain select * from t1 force index(c) order by c;
|
||||
--error ER_REQUIRES_PRIMARY_KEY
|
||||
drop index c on t1;
|
||||
alter table t1 add primary key (a), drop index c;
|
||||
show create table t1;
|
||||
--error ER_MULTIPLE_PRI_KEY
|
||||
|
|
@ -239,16 +237,47 @@ insert into t2 values ('jejdkrun87'),('adfd72nh9k'),
|
|||
create table t1(a int, b blob, c text, d text not null)
|
||||
engine=innodb default charset = utf8;
|
||||
|
||||
insert into t1 values (null,null,null,'null');
|
||||
# r2667 The following test is disabled because MySQL behavior changed.
|
||||
# r2667 The test was added with this comment:
|
||||
# r2667
|
||||
# r2667 ------------------------------------------------------------------------
|
||||
# r2667 r1699 | marko | 2007-08-10 19:53:19 +0300 (Fri, 10 Aug 2007) | 5 lines
|
||||
# r2667
|
||||
# r2667 branches/zip: Add changes that accidentally omitted from r1698:
|
||||
# r2667
|
||||
# r2667 innodb-index.test, innodb-index.result: Add a test for creating
|
||||
# r2667 a PRIMARY KEY on a column that contains a NULL value.
|
||||
# r2667 ------------------------------------------------------------------------
|
||||
# r2667
|
||||
# r2667 but in BZR-r2667:
|
||||
# r2667 http://bazaar.launchpad.net/~mysql/mysql-server/mysql-5.1/revision/davi%40mysql.com-20080617141221-8yre8ys9j4uw3xx5?start_revid=joerg%40mysql.com-20080630105418-7qoe5ehomgrcdb89
|
||||
# r2667 MySQL changed the behavior to do full table copy when creating PRIMARY INDEX
|
||||
# r2667 on a non-NULL column instead of calling ::add_index() which would fail (and
|
||||
# r2667 this is what we were testing here). Before r2667 the code execution path was
|
||||
# r2667 like this (when adding PRIMARY INDEX on a non-NULL column with ALTER TABLE):
|
||||
# r2667
|
||||
# r2667 mysql_alter_table()
|
||||
# r2667 compare_tables() // would return ALTER_TABLE_INDEX_CHANGED
|
||||
# r2667 ::add_index() // would fail with "primary index cannot contain NULL"
|
||||
# r2667
|
||||
# r2667 after r2667 the code execution path is the following:
|
||||
# r2667
|
||||
# r2667 mysql_alter_table()
|
||||
# r2667 compare_tables() // returns ALTER_TABLE_DATA_CHANGED
|
||||
# r2667 full copy is done, without calling ::add_index()
|
||||
# r2667
|
||||
# r2667 To enable, remove "# r2667: " below.
|
||||
# r2667
|
||||
# r2667: insert into t1 values (null,null,null,'null');
|
||||
insert into t1
|
||||
select a,left(repeat(d,100*a),65535),repeat(d,20*a),d from t2,t3;
|
||||
drop table t2, t3;
|
||||
select count(*) from t1 where a=44;
|
||||
select a,
|
||||
length(b),b=left(repeat(d,100*a),65535),length(c),c=repeat(d,20*a),d from t1;
|
||||
--error ER_PRIMARY_CANT_HAVE_NULL
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
delete from t1 where d='null';
|
||||
# r2667: --error ER_PRIMARY_CANT_HAVE_NULL
|
||||
# r2667: alter table t1 add primary key (a), add key (b(20));
|
||||
# r2667: delete from t1 where d='null';
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
delete from t1 where a%2;
|
||||
|
|
@ -273,10 +302,12 @@ rename table t2 to t1;
|
|||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
set innodb_lock_wait_timeout=1;
|
||||
begin;
|
||||
# Obtain an IX lock on the table
|
||||
select a from t1 limit 1 for update;
|
||||
connection b;
|
||||
set innodb_lock_wait_timeout=1;
|
||||
# This would require an S lock on the table, conflicting with the IX lock.
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
create index t1ba on t1 (b,a);
|
||||
|
|
@ -321,6 +352,10 @@ disconnect b;
|
|||
|
||||
drop table t1;
|
||||
|
||||
let $per_table=`select @@innodb_file_per_table`;
|
||||
let $format=`select @@innodb_file_format`;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format='Barracuda';
|
||||
# Test creating a table that could lead to undo log overflow.
|
||||
# In the undo log, we write a 768-byte prefix (REC_MAX_INDEX_COL_LEN)
|
||||
# of each externally stored column that appears as a column prefix in an index.
|
||||
|
|
@ -328,7 +363,7 @@ drop table t1;
|
|||
create table t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob,
|
||||
i blob,j blob,k blob,l blob,m blob,n blob,o blob,p blob,
|
||||
q blob,r blob,s blob,t blob,u blob)
|
||||
engine=innodb;
|
||||
engine=innodb row_format=dynamic;
|
||||
create index t1a on t1 (a(1));
|
||||
create index t1b on t1 (b(1));
|
||||
create index t1c on t1 (c(1));
|
||||
|
|
@ -355,4 +390,122 @@ create index t1u on t1 (u(1));
|
|||
create index t1ut on t1 (u(1), t(1));
|
||||
create index t1st on t1 (s(1), t(1));
|
||||
show create table t1;
|
||||
--error 139
|
||||
create index t1u on t1 (u(1));
|
||||
alter table t1 row_format=compact;
|
||||
create index t1u on t1 (u(1));
|
||||
|
||||
drop table t1;
|
||||
eval set global innodb_file_per_table=$per_table;
|
||||
eval set global innodb_file_format=$format;
|
||||
|
||||
#
|
||||
# Test to check whether CREATE INDEX handles implicit foreign key
|
||||
# constraint modifications (Issue #70, Bug #38786)
|
||||
#
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
INSERT INTO t1 VALUES(0);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1,c2,c3)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO t2 VALUES(0,0,1);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
--error ER_ROW_IS_REFERENCED_2
|
||||
DELETE FROM t1;
|
||||
DELETE FROM t2;
|
||||
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
c2 INT(4) NOT NULL,
|
||||
PRIMARY KEY (c2,c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1);
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL;
|
||||
--replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c2_c1 ON t2(c2, c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c3_c1_c2 ON t2(c3, c1, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=inn
|
|||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
ERROR HY000: DELAYED option not supported for table 't1'
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
ERROR HY000: DELAYED option not supported for table 't1'
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
drop table t1;
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ drop table if exists t1;
|
|||
#
|
||||
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
|
||||
select * from t1;
|
||||
--error 1031
|
||||
--error ER_DELAYED_NOT_SUPPORTED
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
select * from t1;
|
||||
--error 1031
|
||||
--error ER_DELAYED_NOT_SUPPORTED
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
drop table if exists t1;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
|
|
@ -6,6 +7,7 @@ set autocommit=0;
|
|||
select * from t1 where a=3 lock in share mode;
|
||||
a
|
||||
3
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
update t1 set a=10 where a=5;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ drop table if exists t1;
|
|||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
|
|
@ -17,6 +18,7 @@ set autocommit=0;
|
|||
# this should lock the entire table
|
||||
select * from t1 where a=3 lock in share mode;
|
||||
connection b;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set autocommit=0;
|
||||
-- error ER_LOCK_WAIT_TIMEOUT
|
||||
|
|
|
|||
38
mysql-test/innodb-timeout.result
Normal file
38
mysql-test/innodb-timeout.result
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
set global innodb_lock_wait_timeout=42;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
42
|
||||
set innodb_lock_wait_timeout=1;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
1
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
42
|
||||
set global innodb_lock_wait_timeout=347;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
42
|
||||
set innodb_lock_wait_timeout=1;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
1
|
||||
select @@innodb_lock_wait_timeout;
|
||||
@@innodb_lock_wait_timeout
|
||||
347
|
||||
create table t1(a int primary key)engine=innodb;
|
||||
begin;
|
||||
insert into t1 values(1),(2),(3);
|
||||
select * from t1 for update;
|
||||
commit;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
begin;
|
||||
insert into t1 values(4);
|
||||
select * from t1 for update;
|
||||
commit;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
drop table t1;
|
||||
set global innodb_lock_wait_timeout=50;
|
||||
64
mysql-test/innodb-timeout.test
Normal file
64
mysql-test/innodb-timeout.test
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
-- source include/have_innodb.inc
|
||||
|
||||
let $timeout=`select @@innodb_lock_wait_timeout`;
|
||||
set global innodb_lock_wait_timeout=42;
|
||||
|
||||
connect (a,localhost,root,,);
|
||||
connect (b,localhost,root,,);
|
||||
|
||||
connection a;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
set innodb_lock_wait_timeout=1;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
|
||||
connection b;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
set global innodb_lock_wait_timeout=347;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
set innodb_lock_wait_timeout=1;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
|
||||
connect (c,localhost,root,,);
|
||||
connection c;
|
||||
select @@innodb_lock_wait_timeout;
|
||||
connection default;
|
||||
disconnect c;
|
||||
|
||||
connection a;
|
||||
create table t1(a int primary key)engine=innodb;
|
||||
begin;
|
||||
insert into t1 values(1),(2),(3);
|
||||
|
||||
connection b;
|
||||
--send
|
||||
select * from t1 for update;
|
||||
|
||||
connection a;
|
||||
commit;
|
||||
|
||||
connection b;
|
||||
reap;
|
||||
|
||||
connection a;
|
||||
begin;
|
||||
insert into t1 values(4);
|
||||
|
||||
connection b;
|
||||
--send
|
||||
select * from t1 for update;
|
||||
|
||||
connection a;
|
||||
sleep 2;
|
||||
commit;
|
||||
|
||||
connection b;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
reap;
|
||||
drop table t1;
|
||||
|
||||
connection default;
|
||||
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
|
||||
eval set global innodb_lock_wait_timeout=$timeout;
|
||||
|
|
@ -122,14 +122,47 @@ table_schema table_name row_format
|
|||
test t1 Compressed
|
||||
test t2 Compact
|
||||
drop table t1,t2;
|
||||
SET SESSION innodb_strict_mode = on;
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
INSERT INTO t1 VALUES(
|
||||
'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~)+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}(+.147:=@CFILORUX[^adgjmpsvy|(+.147:=@CFILORUX[^adgjmpsvy|(+.147:=@CFILORUX[^adgjmpsvy|(,048<@DHLPTX\`dhlptx|)-159=AEIMQUY]aeimquy}*.26:>BFJNRVZ^bfjnrvz~+/37;?CGKOSW[_cgkosw{(-27<AFKPUZ_dinsx}+05:?DINSX]bglqv{).38=BGLQV[`ejoty~,16;@EJOTY^chmrw|*/49>CHMRW\afkpuz(.4:@FLRX^djpv|+17=CIOU[agmsy(.4:@FLRX^djpv|+17=CIOU[agmsy(.4:@FLRX^djpv|+17=CIOU[agmsy(/6=DKRY`gnu|,3:AHOV]dkry)07>ELSZahov}-4;BIPW^elsz*18?FMT[bipw~.5<CJQX_fmt{+29@GNU\cjqx(08@HPX`hpx)19AIQYaiqy*2:BJRZbjrz+3;CKS[cks{,4<DLT\dlt|-5=EMU]emu}.6>FNV^fnv~/7?GOW_gow(1:CLU^gpy+4=FOXajs|.7@IR[dmv(1:CLU^gpy+4=FOXajs|.7@IR[dmv(1:CLU^gpy+4=',
|
||||
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII;
|
||||
drop table t1;
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
|
||||
DROP TABLE t1;
|
||||
create table t1( c1 int not null, c2 blob, c3 blob, c4 blob,
|
||||
primary key(c1, c2(22), c3(22)))
|
||||
engine = innodb row_format = dynamic;
|
||||
begin;
|
||||
insert into t1 values(1, repeat('A', 20000), repeat('B', 20000),
|
||||
repeat('C', 20000));
|
||||
update t1 set c3 = repeat('D', 20000) where c1 = 1;
|
||||
commit;
|
||||
select count(*) from t1 where c2 = repeat('A', 20000);
|
||||
count(*)
|
||||
1
|
||||
select count(*) from t1 where c3 = repeat('D', 20000);
|
||||
count(*)
|
||||
1
|
||||
select count(*) from t1 where c4 = repeat('C', 20000);
|
||||
count(*)
|
||||
1
|
||||
update t1 set c3 = repeat('E', 20000) where c1 = 1;
|
||||
drop table t1;
|
||||
set global innodb_file_format=`0`;
|
||||
select @@innodb_file_format;
|
||||
|
|
@ -155,6 +188,11 @@ set global innodb_file_format=``;
|
|||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_per_table = on;
|
||||
set global innodb_file_format = `1`;
|
||||
set innodb_strict_mode = off;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
Warnings:
|
||||
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0.
|
||||
drop table t1;
|
||||
set innodb_strict_mode = on;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
|
|
@ -357,7 +395,6 @@ test t9 Redundant
|
|||
drop table t8, t9;
|
||||
set global innodb_file_per_table=0;
|
||||
set global innodb_file_format=Antelope;
|
||||
set innodb_strict_mode=0;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format=`Barracuda`;
|
||||
set global innodb_file_format_check=`Antelope`;
|
||||
|
|
@ -381,13 +418,4 @@ show table status;
|
|||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format_check=`Cheetah`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check=`on`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check=`off`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
drop table normal_table, zip_table;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
let $per_table=`select @@innodb_file_per_table`;
|
||||
let $format=`select @@innodb_file_format`;
|
||||
let $mode=`select @@innodb_strict_mode`;
|
||||
set global innodb_file_per_table=off;
|
||||
set global innodb_file_format=`0`;
|
||||
|
||||
|
|
@ -85,21 +84,55 @@ SELECT table_schema, table_name, row_format
|
|||
FROM information_schema.tables WHERE engine='innodb';
|
||||
drop table t1,t2;
|
||||
|
||||
# data generated with
|
||||
SET SESSION innodb_strict_mode = on;
|
||||
--error ER_TOO_BIG_ROWSIZE
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
|
||||
# random data generated with
|
||||
# perl -e 'my $i,$j,$k;for($j=1;$j<19;$j++){for($i=$k=0;$k<87;$k++,$i+=$j,$i%=87){printf "%c",$i+40}}'
|
||||
# truncated to 2*767 bytes and split to two 767-byte columns
|
||||
--error ER_TOO_BIG_ROWSIZE
|
||||
INSERT INTO t1 VALUES(
|
||||
'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~)+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}(+.147:=@CFILORUX[^adgjmpsvy|(+.147:=@CFILORUX[^adgjmpsvy|(+.147:=@CFILORUX[^adgjmpsvy|(,048<@DHLPTX\`dhlptx|)-159=AEIMQUY]aeimquy}*.26:>BFJNRVZ^bfjnrvz~+/37;?CGKOSW[_cgkosw{(-27<AFKPUZ_dinsx}+05:?DINSX]bglqv{).38=BGLQV[`ejoty~,16;@EJOTY^chmrw|*/49>CHMRW\afkpuz(.4:@FLRX^djpv|+17=CIOU[agmsy(.4:@FLRX^djpv|+17=CIOU[agmsy(.4:@FLRX^djpv|+17=CIOU[agmsy(/6=DKRY`gnu|,3:AHOV]dkry)07>ELSZahov}-4;BIPW^elsz*18?FMT[bipw~.5<CJQX_fmt{+29@GNU\cjqx(08@HPX`hpx)19AIQYaiqy*2:BJRZbjrz+3;CKS[cks{,4<DLT\dlt|-5=EMU]emu}.6>FNV^fnv~/7?GOW_gow(1:CLU^gpy+4=FOXajs|.7@IR[dmv(1:CLU^gpy+4=FOXajs|.7@IR[dmv(1:CLU^gpy+4=',
|
||||
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII;
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII;
|
||||
drop table t1;
|
||||
--error ER_TOO_BIG_ROWSIZE
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test blob column inheritance (mantis issue#36)
|
||||
#
|
||||
|
||||
create table t1( c1 int not null, c2 blob, c3 blob, c4 blob,
|
||||
primary key(c1, c2(22), c3(22)))
|
||||
engine = innodb row_format = dynamic;
|
||||
begin;
|
||||
insert into t1 values(1, repeat('A', 20000), repeat('B', 20000),
|
||||
repeat('C', 20000));
|
||||
|
||||
update t1 set c3 = repeat('D', 20000) where c1 = 1;
|
||||
commit;
|
||||
|
||||
# one blob column which is unchanged in update and part of PK
|
||||
# one blob column which is changed and part of of PK
|
||||
# one blob column which is not part of PK and is unchanged
|
||||
select count(*) from t1 where c2 = repeat('A', 20000);
|
||||
select count(*) from t1 where c3 = repeat('D', 20000);
|
||||
select count(*) from t1 where c4 = repeat('C', 20000);
|
||||
|
||||
update t1 set c3 = repeat('E', 20000) where c1 = 1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
#
|
||||
# Test innodb_file_format
|
||||
#
|
||||
|
|
@ -127,6 +160,10 @@ set global innodb_file_format=``;
|
|||
set global innodb_file_per_table = on;
|
||||
set global innodb_file_format = `1`;
|
||||
|
||||
set innodb_strict_mode = off;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
drop table t1;
|
||||
|
||||
#set strict_mode
|
||||
set innodb_strict_mode = on;
|
||||
|
||||
|
|
@ -269,7 +306,6 @@ drop table t8, t9;
|
|||
|
||||
eval set global innodb_file_per_table=$per_table;
|
||||
eval set global innodb_file_format=$format;
|
||||
eval set innodb_strict_mode=$mode;
|
||||
#
|
||||
# Testing of tablespace tagging
|
||||
#
|
||||
|
|
@ -291,12 +327,5 @@ select @@innodb_file_format_check;
|
|||
show table status;
|
||||
-- enable_result_log
|
||||
select @@innodb_file_format_check;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`Cheetah`;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`on`;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`off`;
|
||||
select @@innodb_file_format_check;
|
||||
drop table normal_table, zip_table;
|
||||
-- disable_result_log
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ level id parent_id
|
|||
1 1007 101
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
show keys from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
|
|
@ -190,6 +191,7 @@ create table t1 (a int) engine=innodb;
|
|||
insert into t1 values (1), (2);
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
delete from t1 where a = 1;
|
||||
select * from t1;
|
||||
|
|
@ -738,6 +740,7 @@ world 2
|
|||
hello 1
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
show keys from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
|
|
@ -925,7 +928,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t1 index NULL b 4 NULL # Using index
|
||||
explain select a,b from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL #
|
||||
1 SIMPLE t1 index NULL b 4 NULL # Using index
|
||||
explain select a,b,c from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL #
|
||||
|
|
@ -1021,6 +1024,7 @@ id code name
|
|||
4 2 Erik
|
||||
5 3 Sasha
|
||||
COMMIT;
|
||||
SET binlog_format='MIXED';
|
||||
BEGIN;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||
insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
|
||||
|
|
@ -1166,14 +1170,14 @@ UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
|
|||
SELECT * from t1;
|
||||
a b
|
||||
1 1
|
||||
102 2
|
||||
103 3
|
||||
4 4
|
||||
5 5
|
||||
6 6
|
||||
7 7
|
||||
8 8
|
||||
9 9
|
||||
102 2
|
||||
103 3
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) engine=innodb;
|
||||
CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) engine=innodb;
|
||||
|
|
@ -1197,6 +1201,7 @@ a b
|
|||
update t1,t2 set t1.a=t1.a+100 where t1.a=101;
|
||||
select * from t1;
|
||||
a b
|
||||
201 1
|
||||
102 2
|
||||
103 3
|
||||
104 4
|
||||
|
|
@ -1208,11 +1213,10 @@ a b
|
|||
110 10
|
||||
111 11
|
||||
112 12
|
||||
201 1
|
||||
update t1,t2 set t1.b=t1.b+10 where t1.b=2;
|
||||
select * from t1;
|
||||
a b
|
||||
102 12
|
||||
201 1
|
||||
103 3
|
||||
104 4
|
||||
105 5
|
||||
|
|
@ -1222,34 +1226,34 @@ a b
|
|||
109 9
|
||||
110 10
|
||||
111 11
|
||||
102 12
|
||||
112 12
|
||||
201 1
|
||||
update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
|
||||
select * from t1;
|
||||
a b
|
||||
102 12
|
||||
201 1
|
||||
103 5
|
||||
104 6
|
||||
105 7
|
||||
106 6
|
||||
105 7
|
||||
107 7
|
||||
108 8
|
||||
109 9
|
||||
110 10
|
||||
111 11
|
||||
102 12
|
||||
112 12
|
||||
201 1
|
||||
select * from t2;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
3 13
|
||||
4 14
|
||||
5 15
|
||||
6 6
|
||||
7 7
|
||||
8 8
|
||||
9 9
|
||||
3 13
|
||||
4 14
|
||||
5 15
|
||||
drop table t1,t2;
|
||||
CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) ENGINE=MyISAM;
|
||||
CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
|
@ -1300,11 +1304,11 @@ insert into t1 (id) values (null),(null),(null),(null),(null);
|
|||
update t1 set fk=69 where fk is null order by id limit 1;
|
||||
SELECT * from t1;
|
||||
id fk
|
||||
1 69
|
||||
2 NULL
|
||||
3 NULL
|
||||
4 NULL
|
||||
5 NULL
|
||||
1 69
|
||||
drop table t1;
|
||||
create table t1 (a int not null, b int not null, key (a));
|
||||
insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
|
||||
|
|
@ -1836,7 +1840,6 @@ set @a=repeat(' ',20);
|
|||
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'v' at row 1
|
||||
Note 1265 Data truncated for column 'c' at row 1
|
||||
select concat('*',v,'*',c,'*',t,'*') from t1;
|
||||
concat('*',v,'*',c,'*',t,'*')
|
||||
*+ *+*+ *
|
||||
|
|
@ -2440,8 +2443,8 @@ insert into t1 (b) values (1);
|
|||
replace into t1 (b) values (2), (1), (3);
|
||||
select * from t1;
|
||||
a b
|
||||
2 2
|
||||
3 1
|
||||
2 2
|
||||
4 3
|
||||
truncate table t1;
|
||||
insert into t1 (b) values (1);
|
||||
|
|
@ -2450,8 +2453,8 @@ replace into t1 (b) values (1);
|
|||
replace into t1 (b) values (3);
|
||||
select * from t1;
|
||||
a b
|
||||
2 2
|
||||
3 1
|
||||
2 2
|
||||
4 3
|
||||
drop table t1;
|
||||
create table t1 (rowid int not null auto_increment, val int not null,primary
|
||||
|
|
@ -2961,9 +2964,11 @@ 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),(7,3);
|
||||
commit;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
update t1 set b = 5 where b = 1;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
select * from t1 where a = 7 and b = 3 for update;
|
||||
|
|
@ -3002,6 +3007,7 @@ d e
|
|||
3 1
|
||||
8 6
|
||||
12 1
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
insert into t1 select * from t2;
|
||||
|
|
@ -3032,30 +3038,39 @@ a b
|
|||
3 1
|
||||
8 6
|
||||
12 1
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
insert into t1 select * from t2;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
update t3 set b = (select b from t2 where a = d);
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
insert into t5 (select * from t2 lock in share mode);
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
update t6 set e = (select b from t2 where a = d lock in share mode);
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
insert into t8 (select * from t2 for update);
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
update t9 set e = (select b from t2 where a = d for update);
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
|
||||
|
|
@ -3112,6 +3127,7 @@ BEGIN;
|
|||
INSERT INTO t1 VALUES (1);
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
|
||||
|
|
@ -3174,6 +3190,7 @@ t1 CREATE TABLE `t1` (
|
|||
CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1,t2;
|
||||
set innodb_strict_mode=on;
|
||||
CREATE TABLE t1 (
|
||||
c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
|
||||
c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
|
||||
|
|
@ -3201,6 +3218,7 @@ id
|
|||
-10
|
||||
1
|
||||
DROP TABLE t1;
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
|
|
@ -3211,6 +3229,7 @@ CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
|
|||
CREATE TABLE t2 LIKE t1;
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
|
@ -3218,10 +3237,12 @@ COMMIT;
|
|||
SELECT * FROM t1 WHERE a=1;
|
||||
a
|
||||
1
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
INSERT INTO t1 VALUES (2);
|
||||
|
|
|
|||
|
|
@ -701,6 +701,7 @@ insert into t1 (code, name) values (2, 'Erik'), (3, 'Sasha');
|
|||
select id, code, name from t1 order by id;
|
||||
COMMIT;
|
||||
|
||||
SET binlog_format='MIXED';
|
||||
BEGIN;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||
insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
|
||||
|
|
@ -2001,10 +2002,12 @@ 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),(7,3);
|
||||
commit;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
update t1 set b = 5 where b = 1;
|
||||
connection b;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
#
|
||||
|
|
@ -2072,6 +2075,7 @@ commit;
|
|||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
insert into t1 select * from t2;
|
||||
|
|
@ -2128,46 +2132,55 @@ commit;
|
|||
set autocommit = 0;
|
||||
select * from t2 for update;
|
||||
connection b;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--send
|
||||
insert into t1 select * from t2;
|
||||
connection c;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--send
|
||||
update t3 set b = (select b from t2 where a = d);
|
||||
connection d;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
||||
--send
|
||||
create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
|
||||
connection e;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
insert into t5 (select * from t2 lock in share mode);
|
||||
connection f;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
update t6 set e = (select b from t2 where a = d lock in share mode);
|
||||
connection g;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
|
||||
connection h;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
insert into t8 (select * from t2 for update);
|
||||
connection i;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
update t9 set e = (select b from t2 where a = d for update);
|
||||
connection j;
|
||||
SET binlog_format='MIXED';
|
||||
set autocommit = 0;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
--send
|
||||
|
|
@ -2343,6 +2356,7 @@ DROP TABLE t1,t2;
|
|||
#
|
||||
# Bug #21101 (Prints wrong error message if max row size is too large)
|
||||
#
|
||||
set innodb_strict_mode=on;
|
||||
--error 1118
|
||||
CREATE TABLE t1 (
|
||||
c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
|
||||
|
|
@ -2381,6 +2395,7 @@ DROP TABLE t1;
|
|||
CONNECT (c1,localhost,root,,);
|
||||
CONNECT (c2,localhost,root,,);
|
||||
CONNECTION c1;
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
|
|
@ -2388,6 +2403,7 @@ CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
|
|||
CREATE TABLE t2 LIKE t1;
|
||||
SELECT * FROM t2;
|
||||
CONNECTION c2;
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
|
@ -2399,10 +2415,12 @@ DISCONNECT c2;
|
|||
CONNECT (c1,localhost,root,,);
|
||||
CONNECT (c2,localhost,root,,);
|
||||
CONNECTION c1;
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
SELECT * FROM t2;
|
||||
CONNECTION c2;
|
||||
SET binlog_format='MIXED';
|
||||
SET TX_ISOLATION='read-committed';
|
||||
SET AUTOCOMMIT=0;
|
||||
INSERT INTO t1 VALUES (2);
|
||||
|
|
|
|||
1
mysql-test/innodb_bug36172.result
Normal file
1
mysql-test/innodb_bug36172.result
Normal file
|
|
@ -0,0 +1 @@
|
|||
SET storage_engine=InnoDB;
|
||||
26
mysql-test/innodb_bug36172.test
Normal file
26
mysql-test/innodb_bug36172.test
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# Test case for bug 36172
|
||||
#
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
SET storage_engine=InnoDB;
|
||||
|
||||
# we do not really care about what gets printed, we are only
|
||||
# interested in getting success or failure according to our
|
||||
# expectations
|
||||
|
||||
-- disable_query_log
|
||||
-- disable_result_log
|
||||
|
||||
SET GLOBAL innodb_file_format='Barracuda';
|
||||
SET GLOBAL innodb_file_per_table=on;
|
||||
|
||||
DROP TABLE IF EXISTS `table0`;
|
||||
CREATE TABLE `table0` ( `col0` tinyint(1) DEFAULT NULL, `col1` tinyint(1) DEFAULT NULL, `col2` tinyint(4) DEFAULT NULL, `col3` date DEFAULT NULL, `col4` time DEFAULT NULL, `col5` set('test1','test2','test3') DEFAULT NULL, `col6` time DEFAULT NULL, `col7` text, `col8` decimal(10,0) DEFAULT NULL, `col9` set('test1','test2','test3') DEFAULT NULL, `col10` float DEFAULT NULL, `col11` double DEFAULT NULL, `col12` enum('test1','test2','test3') DEFAULT NULL, `col13` tinyblob, `col14` year(4) DEFAULT NULL, `col15` set('test1','test2','test3') DEFAULT NULL, `col16` decimal(10,0) DEFAULT NULL, `col17` decimal(10,0) DEFAULT NULL, `col18` blob, `col19` datetime DEFAULT NULL, `col20` double DEFAULT NULL, `col21` decimal(10,0) DEFAULT NULL, `col22` datetime DEFAULT NULL, `col23` decimal(10,0) DEFAULT NULL, `col24` decimal(10,0) DEFAULT NULL, `col25` longtext, `col26` tinyblob, `col27` time DEFAULT NULL, `col28` tinyblob, `col29` enum('test1','test2','test3') DEFAULT NULL, `col30` smallint(6) DEFAULT NULL, `col31` double DEFAULT NULL, `col32` float DEFAULT NULL, `col33` char(175) DEFAULT NULL, `col34` tinytext, `col35` tinytext, `col36` tinyblob, `col37` tinyblob, `col38` tinytext, `col39` mediumblob, `col40` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `col41` double DEFAULT NULL, `col42` smallint(6) DEFAULT NULL, `col43` longblob, `col44` varchar(80) DEFAULT NULL, `col45` mediumtext, `col46` decimal(10,0) DEFAULT NULL, `col47` bigint(20) DEFAULT NULL, `col48` date DEFAULT NULL, `col49` tinyblob, `col50` date DEFAULT NULL, `col51` tinyint(1) DEFAULT NULL, `col52` mediumint(9) DEFAULT NULL, `col53` float DEFAULT NULL, `col54` tinyblob, `col55` longtext, `col56` smallint(6) DEFAULT NULL, `col57` enum('test1','test2','test3') DEFAULT NULL, `col58` datetime DEFAULT NULL, `col59` mediumtext, `col60` varchar(232) DEFAULT NULL, `col61` decimal(10,0) DEFAULT NULL, `col62` year(4) DEFAULT NULL, `col63` smallint(6) DEFAULT NULL, `col64` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col65` blob, `col66` longblob, `col67` int(11) DEFAULT NULL, `col68` longtext, `col69` enum('test1','test2','test3') DEFAULT NULL, `col70` int(11) DEFAULT NULL, `col71` time DEFAULT NULL, `col72` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col73` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col74` varchar(170) DEFAULT NULL, `col75` set('test1','test2','test3') DEFAULT NULL, `col76` tinyblob, `col77` bigint(20) DEFAULT NULL, `col78` decimal(10,0) DEFAULT NULL, `col79` datetime DEFAULT NULL, `col80` year(4) DEFAULT NULL, `col81` decimal(10,0) DEFAULT NULL, `col82` longblob, `col83` text, `col84` char(83) DEFAULT NULL, `col85` decimal(10,0) DEFAULT NULL, `col86` float DEFAULT NULL, `col87` int(11) DEFAULT NULL, `col88` varchar(145) DEFAULT NULL, `col89` date DEFAULT NULL, `col90` decimal(10,0) DEFAULT NULL, `col91` decimal(10,0) DEFAULT NULL, `col92` mediumblob, `col93` time DEFAULT NULL, KEY `idx0` (`col69`,`col90`,`col8`), KEY `idx1` (`col60`), KEY `idx2` (`col60`,`col70`,`col74`), KEY `idx3` (`col22`,`col32`,`col72`,`col30`), KEY `idx4` (`col29`), KEY `idx5` (`col19`,`col45`(143)), KEY `idx6` (`col46`,`col48`,`col5`,`col39`(118)), KEY `idx7` (`col48`,`col61`), KEY `idx8` (`col93`), KEY `idx9` (`col31`), KEY `idx10` (`col30`,`col21`), KEY `idx11` (`col67`), KEY `idx12` (`col44`,`col6`,`col8`,`col38`(226)), KEY `idx13` (`col71`,`col41`,`col15`,`col49`(88)), KEY `idx14` (`col78`), KEY `idx15` (`col63`,`col67`,`col64`), KEY `idx16` (`col17`,`col86`), KEY `idx17` (`col77`,`col56`,`col10`,`col55`(24)), KEY `idx18` (`col62`), KEY `idx19` (`col31`,`col57`,`col56`,`col53`), KEY `idx20` (`col46`), KEY `idx21` (`col83`(54)), KEY `idx22` (`col51`,`col7`(120)), KEY `idx23` (`col7`(163),`col31`,`col71`,`col14`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2;
|
||||
insert ignore into `table0` set `col23` = 7887371.5084383683, `col24` = 4293854615.6906948000, `col25` = 'vitalist', `col26` = 'widespread', `col27` = '3570490', `col28` = 'habitual', `col30` = -5471, `col31` = 4286985783.6771750000, `col32` = 6354540.9826654866, `col33` = 'defoliation', `col34` = 'logarithms', `col35` = 'tegument\'s', `col36` = 'scouting\'s', `col37` = 'intermittency', `col38` = 'elongates', `col39` = 'prophecies', `col40` = '20560103035939', `col41` = 4292809130.0544143000, `col42` = 22057, `col43` = 'Hess\'s', `col44` = 'bandstand', `col45` = 'phenylketonuria', `col46` = 6338767.4018677324, `col47` = 5310247, `col48` = '12592418', `col49` = 'churchman\'s', `col50` = '32226125', `col51` = -58, `col52` = -6207968, `col53` = 1244839.3255104220, `col54` = 'robotized', `col55` = 'monotonous', `col56` = -26909, `col58` = '20720107023550', `col59` = 'suggestiveness\'s', `col60` = 'gemology', `col61` = 4287800670.2229986000, `col62` = '1944', `col63` = -16827, `col64` = '20700107212324', `col65` = 'Nicolais', `col66` = 'apteryx', `col67` = 6935317, `col68` = 'stroganoff', `col70` = 3316430, `col71` = '3277608', `col72` = '19300511045918', `col73` = '20421201003327', `col74` = 'attenuant', `col75` = '15173', `col76` = 'upstroke\'s', `col77` = 8118987, `col78` = 6791516.2735374002, `col79` = '20780701144624', `col80` = '2134', `col81` = 4290682351.3127537000, `col82` = 'unexplainably', `col83` = 'Storm', `col84` = 'Greyso\'s', `col85` = 4289119212.4306774000, `col86` = 7617575.8796655172, `col87` = -6325335, `col88` = 'fondue\'s', `col89` = '40608940', `col90` = 1659421.8093508712, `col91` = 8346904.6584368423, `col92` = 'reloads', `col93` = '5188366';
|
||||
CHECK TABLE table0 EXTENDED;
|
||||
INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
|
||||
CHECK TABLE table0 EXTENDED;
|
||||
DROP TABLE table0;
|
||||
4
mysql-test/innodb_bug40360.result
Normal file
4
mysql-test/innodb_bug40360.result
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
SET TX_ISOLATION='READ-COMMITTED';
|
||||
CREATE TABLE bug40360 (a INT) engine=innodb;
|
||||
INSERT INTO bug40360 VALUES (1);
|
||||
DROP TABLE bug40360;
|
||||
16
mysql-test/innodb_bug40360.test
Normal file
16
mysql-test/innodb_bug40360.test
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Make sure http://bugs.mysql.com/40360 remains fixed.
|
||||
#
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
SET TX_ISOLATION='READ-COMMITTED';
|
||||
|
||||
# This is the default since MySQL 5.1.29 SET BINLOG_FORMAT='STATEMENT';
|
||||
|
||||
CREATE TABLE bug40360 (a INT) engine=innodb;
|
||||
|
||||
INSERT INTO bug40360 VALUES (1);
|
||||
|
||||
DROP TABLE bug40360;
|
||||
30
mysql-test/patches/README
Normal file
30
mysql-test/patches/README
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
This directory contains patches that need to be applied to the MySQL
|
||||
source tree in order to get the mysql-test suite to succeed (when
|
||||
storage/innobase is replaced with this InnoDB branch). Things to keep
|
||||
in mind when adding new patches here:
|
||||
|
||||
* The patch must be appliable from the mysql top-level source directory.
|
||||
|
||||
* The patch filename must end in ".diff".
|
||||
|
||||
* All patches here are expected to apply cleanly to the latest MySQL 5.1
|
||||
tree when storage/innobase is replaced with this InnoDB branch. If
|
||||
changes to either of those cause the patch to fail, then please check
|
||||
whether the patch is still needed and, if yes, adjust it so it applies
|
||||
cleanly.
|
||||
|
||||
* If applicable, always submit the patch at http://bugs.mysql.com and
|
||||
name the file here like bug%d.diff. Once the patch is committed to
|
||||
MySQL remove the file from here.
|
||||
|
||||
* If the patch cannot be proposed for inclusion in the MySQL source tree
|
||||
(via http://bugs.mysql.com) then add a comment at the beginning of the
|
||||
patch, explaining the problem it is solving, how it does solve it and
|
||||
why it is not applicable for inclusion in the MySQL source tree.
|
||||
Obviously this is a very bad situation and should be avoided at all
|
||||
costs, especially for files that are in the MySQL source repository
|
||||
(not in storage/innobase).
|
||||
|
||||
* If you ever need to add a patch here that is not related to mysql-test
|
||||
suite, then please move this directory from ./mysql-test/patches to
|
||||
./patches and remove this text.
|
||||
10
mysql-test/patches/bug32625.diff
Normal file
10
mysql-test/patches/bug32625.diff
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
--- mysql-test/t/type_bit_innodb.test.orig 2008-10-07 11:32:32.000000000 +0300
|
||||
+++ mysql-test/t/type_bit_innodb.test 2008-10-07 11:56:40.000000000 +0300
|
||||
@@ -40,6 +40,7 @@
|
||||
create table t1 (a bit) engine=innodb;
|
||||
insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001');
|
||||
select hex(a) from t1;
|
||||
+--replace_regex /entry '(.*)' for/entry '' for/
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add unique (a);
|
||||
drop table t1;
|
||||
85
mysql-test/patches/bug35261.diff
Normal file
85
mysql-test/patches/bug35261.diff
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
--- mysql-test/t/date_formats.test.orig 2007-06-15 02:53:07.000000000 +0300
|
||||
+++ mysql-test/t/date_formats.test 2008-03-19 17:25:10.000000000 +0200
|
||||
@@ -7,9 +7,15 @@
|
||||
--enable_warnings
|
||||
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW GLOBAL VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.global_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
|
||||
#
|
||||
# Test setting a lot of different formats to see which formats are accepted and
|
||||
@@ -37,7 +43,10 @@
|
||||
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
|
||||
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
|
||||
--error 1231
|
||||
SET time_format='%h:%i:%s';
|
||||
--- mysql-test/r/date_formats.result.orig 2008-02-12 21:09:14.000000000 +0200
|
||||
+++ mysql-test/r/date_formats.result 2008-03-19 17:26:33.000000000 +0200
|
||||
@@ -1,14 +1,20 @@
|
||||
drop table if exists t1;
|
||||
-SHOW GLOBAL VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %d.%m.%Y
|
||||
-datetime_format %Y-%m-%d %H:%i:%s
|
||||
-time_format %H.%i.%s
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %d.%m.%Y
|
||||
-datetime_format %Y-%m-%d %H:%i:%s
|
||||
-time_format %H.%i.%s
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.global_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %Y-%m-%d %H:%i:%s
|
||||
+DATE_FORMAT %d.%m.%Y
|
||||
+TIME_FORMAT %H.%i.%s
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %Y-%m-%d %H:%i:%s
|
||||
+DATE_FORMAT %d.%m.%Y
|
||||
+TIME_FORMAT %H.%i.%s
|
||||
SET time_format='%H%i%s';
|
||||
SET time_format='%H:%i:%s.%f';
|
||||
SET time_format='%h-%i-%s.%f%p';
|
||||
@@ -26,11 +32,14 @@
|
||||
set datetime_format= '%H:%i:%s.%f %m-%d-%Y';
|
||||
set datetime_format= '%h:%i:%s %p %Y-%m-%d';
|
||||
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %m-%d-%Y
|
||||
-datetime_format %h:%i:%s.%f %p %Y-%m-%d
|
||||
-time_format %h:%i:%s%p
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %h:%i:%s.%f %p %Y-%m-%d
|
||||
+DATE_FORMAT %m-%d-%Y
|
||||
+TIME_FORMAT %h:%i:%s%p
|
||||
SET time_format='%h:%i:%s';
|
||||
ERROR 42000: Variable 'time_format' can't be set to the value of '%h:%i:%s'
|
||||
SET time_format='%H %i:%s';
|
||||
31
mysql-test/patches/index_merge_innodb-explain.diff
Normal file
31
mysql-test/patches/index_merge_innodb-explain.diff
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
InnoDB's estimate for the index cardinality depends on a pseudo random
|
||||
number generator (it picks up random pages to sample). After an
|
||||
optimization that was made in r2625 the following EXPLAINs started
|
||||
returning a different number of rows (3 instead of 4).
|
||||
|
||||
This patch adjusts the result file.
|
||||
|
||||
This patch cannot be proposed to MySQL because the failures occur only
|
||||
in this tree and do not occur in the standard InnoDB 5.1. Furthermore,
|
||||
the file index_merge2.inc is used by other engines too.
|
||||
|
||||
--- mysql-test/r/index_merge_innodb.result.orig 2008-09-30 18:32:13.000000000 +0300
|
||||
+++ mysql-test/r/index_merge_innodb.result 2008-09-30 18:33:01.000000000 +0300
|
||||
@@ -111,7 +111,7 @@
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
-1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 4 Using intersect(i1,i2); Using where; Using index
|
||||
+1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
|
||||
count(*)
|
||||
@@ -119,7 +119,7 @@
|
||||
explain select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
-1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 4 Using intersect(i1,i3); Using where; Using index
|
||||
+1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index
|
||||
select count(*) from t1 where
|
||||
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
|
||||
count(*)
|
||||
125
mysql-test/patches/information_schema.diff
Normal file
125
mysql-test/patches/information_schema.diff
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
diff mysql-test/r/information_schema.result.orig mysql-test/r/information_schema.result
|
||||
--- mysql-test/r/information_schema.result.orig 2008-08-04 09:27:49.000000000 +0300
|
||||
+++ mysql-test/r/information_schema.result 2008-10-07 11:21:51.000000000 +0300
|
||||
@@ -64,6 +64,13 @@
|
||||
TRIGGERS
|
||||
USER_PRIVILEGES
|
||||
VIEWS
|
||||
+INNODB_CMP_RESET
|
||||
+INNODB_TRX
|
||||
+INNODB_CMPMEM_RESET
|
||||
+INNODB_LOCK_WAITS
|
||||
+INNODB_CMPMEM
|
||||
+INNODB_CMP
|
||||
+INNODB_LOCKS
|
||||
columns_priv
|
||||
db
|
||||
event
|
||||
@@ -795,6 +802,8 @@
|
||||
TABLES UPDATE_TIME datetime
|
||||
TABLES CHECK_TIME datetime
|
||||
TRIGGERS CREATED datetime
|
||||
+INNODB_TRX trx_started datetime
|
||||
+INNODB_TRX trx_wait_started datetime
|
||||
event execute_at datetime
|
||||
event last_executed datetime
|
||||
event starts datetime
|
||||
@@ -848,7 +857,7 @@
|
||||
flush privileges;
|
||||
SELECT table_schema, count(*) FROM information_schema.TABLES where table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
|
||||
table_schema count(*)
|
||||
-information_schema 28
|
||||
+information_schema 35
|
||||
mysql 22
|
||||
create table t1 (i int, j int);
|
||||
create trigger trg1 before insert on t1 for each row
|
||||
@@ -1263,6 +1272,13 @@
|
||||
TRIGGERS TRIGGER_SCHEMA
|
||||
USER_PRIVILEGES GRANTEE
|
||||
VIEWS TABLE_SCHEMA
|
||||
+INNODB_CMP_RESET page_size
|
||||
+INNODB_TRX trx_id
|
||||
+INNODB_CMPMEM_RESET page_size
|
||||
+INNODB_LOCK_WAITS requesting_trx_id
|
||||
+INNODB_CMPMEM page_size
|
||||
+INNODB_CMP page_size
|
||||
+INNODB_LOCKS lock_id
|
||||
SELECT t.table_name, c1.column_name
|
||||
FROM information_schema.tables t
|
||||
INNER JOIN
|
||||
@@ -1306,6 +1322,13 @@
|
||||
TRIGGERS TRIGGER_SCHEMA
|
||||
USER_PRIVILEGES GRANTEE
|
||||
VIEWS TABLE_SCHEMA
|
||||
+INNODB_CMP_RESET page_size
|
||||
+INNODB_TRX trx_id
|
||||
+INNODB_CMPMEM_RESET page_size
|
||||
+INNODB_LOCK_WAITS requesting_trx_id
|
||||
+INNODB_CMPMEM page_size
|
||||
+INNODB_CMP page_size
|
||||
+INNODB_LOCKS lock_id
|
||||
SELECT MAX(table_name) FROM information_schema.tables;
|
||||
MAX(table_name)
|
||||
VIEWS
|
||||
@@ -1382,6 +1405,13 @@
|
||||
FILES information_schema.FILES 1
|
||||
GLOBAL_STATUS information_schema.GLOBAL_STATUS 1
|
||||
GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1
|
||||
+INNODB_CMP information_schema.INNODB_CMP 1
|
||||
+INNODB_CMPMEM information_schema.INNODB_CMPMEM 1
|
||||
+INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1
|
||||
+INNODB_CMP_RESET information_schema.INNODB_CMP_RESET 1
|
||||
+INNODB_LOCKS information_schema.INNODB_LOCKS 1
|
||||
+INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1
|
||||
+INNODB_TRX information_schema.INNODB_TRX 1
|
||||
KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
|
||||
PARTITIONS information_schema.PARTITIONS 1
|
||||
PLUGINS information_schema.PLUGINS 1
|
||||
diff mysql-test/r/information_schema_db.result.orig mysql-test/r/information_schema_db.result
|
||||
--- mysql-test/r/information_schema_db.result.orig 2008-08-04 09:27:49.000000000 +0300
|
||||
+++ mysql-test/r/information_schema_db.result 2008-10-07 12:26:31.000000000 +0300
|
||||
@@ -33,6 +33,13 @@
|
||||
TRIGGERS
|
||||
USER_PRIVILEGES
|
||||
VIEWS
|
||||
+INNODB_CMP_RESET
|
||||
+INNODB_TRX
|
||||
+INNODB_CMPMEM_RESET
|
||||
+INNODB_LOCK_WAITS
|
||||
+INNODB_CMPMEM
|
||||
+INNODB_CMP
|
||||
+INNODB_LOCKS
|
||||
show tables from INFORMATION_SCHEMA like 'T%';
|
||||
Tables_in_information_schema (T%)
|
||||
TABLES
|
||||
diff mysql-test/r/mysqlshow.result.orig mysql-test/r/mysqlshow.result
|
||||
--- mysql-test/r/mysqlshow.result.orig 2008-08-04 09:27:51.000000000 +0300
|
||||
+++ mysql-test/r/mysqlshow.result 2008-10-07 12:35:39.000000000 +0300
|
||||
@@ -107,6 +107,13 @@
|
||||
| TRIGGERS |
|
||||
| USER_PRIVILEGES |
|
||||
| VIEWS |
|
||||
+| INNODB_CMP_RESET |
|
||||
+| INNODB_TRX |
|
||||
+| INNODB_CMPMEM_RESET |
|
||||
+| INNODB_LOCK_WAITS |
|
||||
+| INNODB_CMPMEM |
|
||||
+| INNODB_CMP |
|
||||
+| INNODB_LOCKS |
|
||||
+---------------------------------------+
|
||||
Database: INFORMATION_SCHEMA
|
||||
+---------------------------------------+
|
||||
@@ -140,6 +147,13 @@
|
||||
| TRIGGERS |
|
||||
| USER_PRIVILEGES |
|
||||
| VIEWS |
|
||||
+| INNODB_CMP_RESET |
|
||||
+| INNODB_TRX |
|
||||
+| INNODB_CMPMEM_RESET |
|
||||
+| INNODB_LOCK_WAITS |
|
||||
+| INNODB_CMPMEM |
|
||||
+| INNODB_CMP |
|
||||
+| INNODB_LOCKS |
|
||||
+---------------------------------------+
|
||||
Wildcard: inf_rmation_schema
|
||||
+--------------------+
|
||||
62
mysql-test/patches/innodb-index.diff
Normal file
62
mysql-test/patches/innodb-index.diff
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
This part of the innodb-index test causes mysqld to print some warnings
|
||||
and subsequently the whole mysql-test suite to fail.
|
||||
|
||||
A permanent solution is probably to remove the printouts from the source
|
||||
code or to somehow tell the mysql-test suite that warnings are expected.
|
||||
Currently we simply do not execute the problematic tests. Please
|
||||
coordinate a permanent solution with Marko, who added those tests.
|
||||
|
||||
This cannot be proposed to MySQL because it touches files that are not
|
||||
in the MySQL source repository.
|
||||
|
||||
Index: storage/innobase/mysql-test/innodb-index.result
|
||||
===================================================================
|
||||
--- storage/innobase/mysql-test/innodb-index.result (revision 2870)
|
||||
+++ storage/innobase/mysql-test/innodb-index.result (working copy)
|
||||
@@ -43,19 +43,12 @@ t1 CREATE TABLE `t1` (
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` char(10) NOT NULL,
|
||||
`d` varchar(20) DEFAULT NULL,
|
||||
KEY `d2` (`d`),
|
||||
KEY `b` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-ERROR HY000: Table 'test.t1#1' already exists
|
||||
-rename table `t1#1` to `t1#2`;
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-ERROR HY000: Table 'test.t1#2' already exists
|
||||
-drop table `t1#2`;
|
||||
alter table t1 add unique index (c), add index (d);
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
Index: storage/innobase/mysql-test/innodb-index.test
|
||||
===================================================================
|
||||
--- storage/innobase/mysql-test/innodb-index.test (revision 2870)
|
||||
+++ storage/innobase/mysql-test/innodb-index.test (working copy)
|
||||
@@ -14,22 +14,12 @@ select * from t1 force index (d2) order
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add unique index (b);
|
||||
show create table t1;
|
||||
alter table t1 add index (b);
|
||||
show create table t1;
|
||||
|
||||
-# Check how existing tables interfere with temporary tables.
|
||||
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
-
|
||||
---error 156
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-rename table `t1#1` to `t1#2`;
|
||||
---error 156
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-drop table `t1#2`;
|
||||
-
|
||||
alter table t1 add unique index (c), add index (d);
|
||||
show create table t1;
|
||||
explain select * from t1 force index(c) order by c;
|
||||
alter table t1 add primary key (a), drop index c;
|
||||
show create table t1;
|
||||
--error ER_MULTIPLE_PRI_KEY
|
||||
47
mysql-test/patches/innodb_file_per_table.diff
Normal file
47
mysql-test/patches/innodb_file_per_table.diff
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
diff mysql-test/t/innodb_file_per_table_basic.test.orig mysql-test/t/innodb_file_per_table_basic.test
|
||||
--- mysql-test/t/innodb_file_per_table_basic.test.orig 2008-10-07 11:32:30.000000000 +0300
|
||||
+++ mysql-test/t/innodb_file_per_table_basic.test 2008-10-07 11:52:14.000000000 +0300
|
||||
@@ -37,10 +37,6 @@
|
||||
# Check if Value can set #
|
||||
####################################################################
|
||||
|
||||
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
-SET @@GLOBAL.innodb_file_per_table=1;
|
||||
---echo Expected error 'Read only variable'
|
||||
-
|
||||
SELECT COUNT(@@GLOBAL.innodb_file_per_table);
|
||||
--echo 1 Expected
|
||||
|
||||
@@ -52,7 +48,7 @@
|
||||
# Check if the value in GLOBAL Table matches value in variable #
|
||||
#################################################################
|
||||
|
||||
-SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE
|
||||
+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_file_per_table';
|
||||
--echo 1 Expected
|
||||
diff mysql-test/t/innodb_file_per_table_basic.result.orig mysql-test/t/innodb_file_per_table_basic.result
|
||||
--- mysql-test/r/innodb_file_per_table_basic.result.orig 2008-10-07 11:32:02.000000000 +0300
|
||||
+++ mysql-test/r/innodb_file_per_table_basic.result 2008-10-07 11:52:47.000000000 +0300
|
||||
@@ -4,18 +4,15 @@
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_028_02----------------------#'
|
||||
-SET @@GLOBAL.innodb_file_per_table=1;
|
||||
-ERROR HY000: Variable 'innodb_file_per_table' is a read only variable
|
||||
-Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_file_per_table);
|
||||
COUNT(@@GLOBAL.innodb_file_per_table)
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_028_03----------------------#'
|
||||
-SELECT @@GLOBAL.innodb_file_per_table = VARIABLE_VALUE
|
||||
+SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_file_per_table';
|
||||
-@@GLOBAL.innodb_file_per_table = VARIABLE_VALUE
|
||||
+IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.innodb_file_per_table);
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue