Commit 810efe12 authored by marko's avatar marko

branches/innodb+: Merge revisions 2867:2986 from branches/zip:

  ------------------------------------------------------------------------
  r2867 | marko | 2008-10-24 10:24:17 +0300 (Fri, 24 Oct 2008) | 2 lines

  branches/zip: ChangeLog: Document r2763, r2794, r2683, r2799, r2809, r2866.
  ------------------------------------------------------------------------
  r2869 | vasil | 2008-10-24 11:14:16 +0300 (Fri, 24 Oct 2008) | 4 lines

  branches/zip:

  White space cleanup in ChangeLog
  ------------------------------------------------------------------------
  r2870 | vasil | 2008-10-24 13:36:14 +0300 (Fri, 24 Oct 2008) | 8 lines

  branches/zip:

  Remove a statement that causes the innodb-index test to fail.

  The change in behavior was introduced in MySQL BZR-r2738.

  Suggested by:	Marko
  ------------------------------------------------------------------------
  r2871 | vasil | 2008-10-24 13:48:38 +0300 (Fri, 24 Oct 2008) | 5 lines

  branches/zip:

  Adjust mysql-test/patches/innodb-index.diff after the change to
  mysql-test/innodb-index.(test|result) in r2870.
  ------------------------------------------------------------------------
  r2878 | calvin | 2008-10-27 11:05:42 +0200 (Mon, 27 Oct 2008) | 8 lines

  branches/zip: port the fix of Bug#19424 - InnoDB: Possibly a memory
  overrun of the buffer being freed with 64-bit Microsoft Visual C++.

  The changed file:

  CMakeLists.txt: Removing Win64 compiler optimizations for all 
  innodb/mem/* files.
  ------------------------------------------------------------------------
  r2884 | vasil | 2008-10-27 11:48:46 +0200 (Mon, 27 Oct 2008) | 7 lines

  branches/zip:

  ChangeLog:

  Add entry for the fix of Bug#19424 InnoDB: Possibly a memory overrun of
  the buffer being freed (64-bit Visual C)
  ------------------------------------------------------------------------
  r2886 | calvin | 2008-10-27 22:39:11 +0200 (Mon, 27 Oct 2008) | 8 lines

  branches/zip: This patch is to solve the issue that file handles can
  not cross DLL/EXE boundaries on Windows. In builtin InnoDB, it makes
  call to MySQL server for creating tmp files. innobase_mysql_tmpfile
  is now rewritten for the plugin. 

  rb://5

  Approved by:	Marko
  ------------------------------------------------------------------------
  r2887 | calvin | 2008-10-27 22:48:29 +0200 (Mon, 27 Oct 2008) | 44 lines

  branches/zip: implement the delayloading of externals for the plugin
  on Windows, which includes:

   * Load mysqld.map and insert all symbol/address pairs into hash for
     quick access
   * Resolves all external data variables. The delayloading mechanism
     in MSVC does not support automatic imports of data variables.
     A workaround is to explicitly handle the data import using the delay
     loader during the initialization of the plugin.
   * Resolves all external functions during run-time, by implementing
     the delayed loading helper function delayLoadHelper2, which is
     called by run-time as well as HrLoadAllImportsForDll. 

  The delay loader reuses the hash implementation in InnoDB. The normal
  hash_create (in hash0hash.c) creates hash tables in buffer pool. But
  the delay loader is invoked before the engine is initialized, and 
  buffer pools are not ready yet. Instead, the delay loader has its own
  implementation of hash_create() and hash_table_free(), called
  wdl_hash_create() and wdl_hash_table_free().

  This patch should be used with other two patches in order to build
  a dynamically linked plugin on Windows:
   * patch for tmpfile functions (r2886)
   * patch for "build" files (to be committed)

  The list of file changed:

  handler/handler0vars.h: new file, defines a list of external data
  variables (no external functions).

  handler/win_delay_loader.cc: new file, the implementation of the delay
  loader for Windows plugin.

  handler/ha_innodb.cc: add a header file, and changes for copying the
  system variables.

  handler/handler0alter.cc: add a header file

  handler/i_s.cc: add a header file

  rb://27

  Reviewed by:	Sunny, Marko
  Approved by:	Sunny
  ------------------------------------------------------------------------
  r2888 | calvin | 2008-10-28 01:51:49 +0200 (Tue, 28 Oct 2008) | 25 lines

  branches/zip: for building dynamic plugin on Windows, ha_innodb.dll,
  when INNODB_DYNAMIC_PLUGIN is specified.

  The changes are:

  CMakeLists.txt: add project ha_innodb for dynamic plugin on Windows.
  ha_innodb depends on project mysqld.

  ha_innodb.def: a new file with standard exports for a dynamic plugin.

  Two new files will be added:
   * sql/mysqld.def:	.def file for 32-bit compiler
   * sql/mysqld_x64.def:	.def file for x64 compiler

  It is also required to apply a patch to the MySQL source tree. The 
  patch is described in win-plugin/README:

  win-plugin/win-plugin.diff - a patch to be applied to MySQL source
  tree. When applied, the following files will be modified:
   * CMakeLists.txt:	add INNODB_DYNAMIC_PLUGIN and _USE_32BIT_TIME_T
   * sql/CMakeLists.txt:	add mysqld.def or mysqld_x64.def for mysqld
   * win/configure.js:	add INNODB_DYNAMIC_PLUGIN
   * win/build-vs71.bat:	provide an option to specify CMAKE_BUILD_TYPE
   * win/build-vs8.bat:	provide an option to specify CMAKE_BUILD_TYPE
   * win/build-vs8_x64.bat: provide an option to specify CMAKE_BUILD_TYPE
  ------------------------------------------------------------------------
  r2894 | marko | 2008-10-28 08:36:39 +0200 (Tue, 28 Oct 2008) | 4 lines

  branches/zip: dict_str_starts_with_keyword(): Removed this unused function.

  Spotted by Sunny.
  ------------------------------------------------------------------------
  r2895 | vasil | 2008-10-28 08:40:45 +0200 (Tue, 28 Oct 2008) | 6 lines

  branches/zip:

  ChangeLog:

  add entry for the Windows plugin.
  ------------------------------------------------------------------------
  r2917 | marko | 2008-10-28 23:53:23 +0200 (Tue, 28 Oct 2008) | 3 lines

  branches/zip: innodb_plugin_init(): Do not copy session variables,
  even when the variable is a global variable in the built-in InnoDB.
  ------------------------------------------------------------------------
  r2918 | calvin | 2008-10-29 00:08:11 +0200 (Wed, 29 Oct 2008) | 2 lines

  branches/zip: fix a problem introduced in r2917 - dyn is not
  initialized. Move the check into for().
  ------------------------------------------------------------------------
  r2922 | calvin | 2008-10-29 08:29:01 +0200 (Wed, 29 Oct 2008) | 16 lines

  branches/zip: fix issue #102 - Windows plugin: resolve dbug functions
  during run-time.

  Implement wrapper functions in the plugin. The plugin will get the
  function entries from mysqld.exe during the init, and invoke the
  corresponding functions (in mysqld.exe). The list of functions are:

  	_db_pargs_
  	_db_doprnt_
  	_db_enter_
  	_db_return_
  	_db_dump_

  rb://38

  Approved by:	Marko
  ------------------------------------------------------------------------
  r2923 | marko | 2008-10-29 09:52:30 +0200 (Wed, 29 Oct 2008) | 1 line

  branches/zip: ChangeLog: Mention Bug #27276.
  ------------------------------------------------------------------------
  r2925 | calvin | 2008-10-29 10:09:41 +0200 (Wed, 29 Oct 2008) | 16 lines

  branches/zip: change function names in sql/mysqld.def in order
  to work with 5.1.29-rc.

  In 5.1.29, the following function names are changed:
    _hash_init
    hash_free
    hash_search
    hash_delete

  changed to
    _my_hash_init
    my_hash_free
    my_hash_search
    my_hash_delete

  Approved by:	Marko (on IM)
  ------------------------------------------------------------------------
  r2927 | marko | 2008-10-29 11:43:23 +0200 (Wed, 29 Oct 2008) | 4 lines

  branches/zip: ha_innodb.cc: Make some functions static, so that they will
  not be compiled as weak global symbols.  These functions must not be
  redirected to the built-in InnoDB.
  ------------------------------------------------------------------------
  r2928 | michael | 2008-10-29 19:20:10 +0200 (Wed, 29 Oct 2008) | 4 lines

  Remove unnecessary assert

  Approved by: Heikki, over IM
  ------------------------------------------------------------------------
  r2930 | marko | 2008-10-29 21:39:24 +0200 (Wed, 29 Oct 2008) | 33 lines

  branches/zip: Merge revisions 2854:2929 from branches/5.1,
  except r2924, which was merged from branches/zip r2866 to branches/5.1
  and except r2879 which was merged separately by Calvin:

    ------------------------------------------------------------------------
    r2902 | vasil | 2008-10-28 12:10:25 +0200 (Tue, 28 Oct 2008) | 10 lines

    branches/5.1:

    Fix Bug#38189 innodb_stats_on_metadata missing

    Make the variable innodb_stats_on_metadata visible to the users and
    also settable at runtime. Previously it was only "visible" as a command
    line startup option to mysqld.

    Approved by:    Marko (https://svn.innodb.com/rb/r/36)
    ------------------------------------------------------------------------
    r2929 | marko | 2008-10-29 21:26:14 +0200 (Wed, 29 Oct 2008) | 13 lines

    branches/5.1: dtype_get_sql_null_size(): return the correct storage
    size of a SQL NULL column. (Bug #40369)

    When MySQL Bug #20877 was fixed in r834, this function was
    accidentally modified to return 0 or 1. Apparently, the only impact of
    this bug is that fixed-length columns cannot be updated in-place from
    or to SQL NULL, even in ROW_FORMAT=REDUNDANT.  After this fix,
    fixed-length columns in ROW_FORMAT=REDUNDANT will have a constant
    storage size as they should, no matter if NULL or non-NULL.  The bug
    caused fixed-length NULL columns to occupy 1 byte.

    rb://37 approved by Heikki over IM.
    ------------------------------------------------------------------------

  ------------------------------------------------------------------------
  r2931 | vasil | 2008-10-29 22:10:40 +0200 (Wed, 29 Oct 2008) | 4 lines

  branches/zip:

  Add 2 ChangeLog entries for the 2 bugfixes that were merged from branches/5.1.
  ------------------------------------------------------------------------
  r2935 | vasil | 2008-10-30 12:17:23 +0200 (Thu, 30 Oct 2008) | 17 lines

  branches/zip:

  Fix "Bug#40360 Binlog related errors with binlog off" in InnoDB code in order
  to have a Bug#40360-free InnoDB Plugin 1.0.2.

  The fix does check whether binary logging is enabled in MySQL by accessing the
  opt_bin_log global variable that is defined in sql/mysqld.cc.

  In case MySQL does develop another solution to this via Bug#40360 then we can
  revert this patch (except the mysql-tests).

  The windows-plugin part of this fix will be committed as a separate commit to
  ease eventual merge into branches/5.1 [note from the future: the separate
  commit went into r2936].

  Approved by:	Marko (https://svn.innodb.com/rb/r/39)
  ------------------------------------------------------------------------
  r2936 | vasil | 2008-10-30 12:24:09 +0200 (Thu, 30 Oct 2008) | 7 lines

  branches/zip:

  Followup to r2935: add the Windows Delay Loader stuff for the MySQL
  variable that we are accessing. If someday we have another solution for
  Bug#40360 Binlog related errors with binlog off
  then this should also be reverted.
  ------------------------------------------------------------------------
  r2937 | vasil | 2008-10-30 12:28:47 +0200 (Thu, 30 Oct 2008) | 4 lines

  branches/zip:

  Add ChangeLog entry for Bug#40360 Binlog related errors with binlog off
  ------------------------------------------------------------------------
  r2938 | vasil | 2008-10-30 12:33:28 +0200 (Thu, 30 Oct 2008) | 5 lines

  branches/zip:

  Non-functional change: convert handler/handler0vars.h and
  handler/win_delay_loader.cc from \r\n (dos) to \n (unix) line terminators.
  ------------------------------------------------------------------------
  r2939 | marko | 2008-10-30 12:38:18 +0200 (Thu, 30 Oct 2008) | 2 lines

  branches/zip: Set svn:eol-style native on some recently added text files.
  ------------------------------------------------------------------------
  r2940 | marko | 2008-10-30 12:46:21 +0200 (Thu, 30 Oct 2008) | 1 line

  branches/zip: ChangeLog, ha_innodb.def: Set svn:eol-style native
  ------------------------------------------------------------------------
  r2941 | vasil | 2008-10-30 19:34:27 +0200 (Thu, 30 Oct 2008) | 4 lines

  branches/zip:

  Increment the InnoDB Plugin version from 1.0.1 to 1.0.2.
  ------------------------------------------------------------------------
  r2943 | sunny | 2008-10-31 09:40:29 +0200 (Fri, 31 Oct 2008) | 15 lines

  branches/zip: 
    1. We add a vector of locks to trx_t. This array contains the autoinc
    locks granted to a transaction. There is one per table.

    2. We enforce releasing of these locks in the reverse order from the
    one in which they are acquired. The assumption is that since the
    AUTOINC locks are statement level locks. Nested statements introduced
    by triggers are stacked it should hold.

  There was some cleanup done to the vector code too by adding const and
  some new functions. Rename dict_table_t::auto_inc_lock to autoinc_lock.

  Fix Bug#26316 Triggers create duplicate entries on auto-increment columns
  rb://22
  ------------------------------------------------------------------------
  r2944 | vasil | 2008-10-31 09:44:16 +0200 (Fri, 31 Oct 2008) | 12 lines

  branches/zip:

  Revert our temporary fix for "Bug#40360 Binlog related errors with binlog off"
  (r2935, r2936) and deploy MySQL's one, but put the function
  mysql_bin_log_is_engaged() inside mysql_addons.cc instead of in mysql's log.cc
  and use a different name for it so there is no collision when MySQL adds this
  function in log.cc.

  [note from the future: the windows part of this patch went into r2947]

  Approved by:	Marko (https://svn.innodb.com/rb/r/41/)
  ------------------------------------------------------------------------
  r2945 | sunny | 2008-10-31 09:44:45 +0200 (Fri, 31 Oct 2008) | 2 lines

  branches/zip: Update ChangeLog with r2943 info.
  ------------------------------------------------------------------------
  r2946 | marko | 2008-10-31 10:18:47 +0200 (Fri, 31 Oct 2008) | 2 lines

  branches/zip: Revert the unintended change to univ.i that was made in r2943.
  ------------------------------------------------------------------------
  r2947 | calvin | 2008-10-31 10:38:26 +0200 (Fri, 31 Oct 2008) | 6 lines

  branches/zip: Windows plugin part of r2944

  r2944 has reference to mysql_bin_log.is_open(), which is new in InnoDB.
  Add two new entries and remove one duplicate in mysqld.def & 
  mysqld_x64.def.
  ------------------------------------------------------------------------
  r2948 | vasil | 2008-10-31 11:39:07 +0200 (Fri, 31 Oct 2008) | 9 lines

  branches/zip:

  Fix Mantis issue#106 plugin init error:InnoDB: stats_on_metadata in static
  InnoDB (flags=0x2401) differs from stats_on_metadata in dynamic InnoDB (fl

  Ignore the NOSYSVAR flag in addition to ignoring the READONLY flag.

  Approved by:	Marko (https://svn.innodb.com/rb/r/42/)
  ------------------------------------------------------------------------
  r2949 | vasil | 2008-10-31 11:47:56 +0200 (Fri, 31 Oct 2008) | 4 lines

  branches/zip:

  White-space cleanup in ChangeLog.
  ------------------------------------------------------------------------
  r2951 | marko | 2008-10-31 14:21:43 +0200 (Fri, 31 Oct 2008) | 4 lines

  branches/zip: scripts/install_innodb_plugins_win.sql: New script,
  for installing the InnoDB plugins in Windows.  Copied from
  scripts/install_innodb_plugins.sql.
  ------------------------------------------------------------------------
  r2954 | calvin | 2008-11-04 09:15:26 +0200 (Tue, 04 Nov 2008) | 8 lines

  branches/zip: ignore the failure when builtin_innobase_plugin is not
  available.

  External variable builtin_innobase_plugin is not available when mysqld
  does not have a builtin InnoDB. The init of the Windows plugin should
  not fail in this case. 

  Approved by:	Marko (on IM)
  ------------------------------------------------------------------------
  r2955 | calvin | 2008-11-04 12:43:14 +0200 (Tue, 04 Nov 2008) | 11 lines

  branches/zip: windows plugin - fix references to array variables.

  This problem surfaced when running new test innodb_bug40360.test. Both
  tx_isolation_names and binlog_format_names are name arrays, and
  should be defined as wdl_tx_isolation_names and wdl_binlog_format_names,
  not *wdl_tx_isolation_names and *wdl_binlog_format_names.

  Another array variable is all_charsets, which is already correctly
  defined.

  Approved by:	Marko (on IM)
  ------------------------------------------------------------------------
  r2986 | marko | 2008-11-11 09:28:37 +0200 (Tue, 11 Nov 2008) | 11 lines

  branches/zip: ha_innobase::create(): Remove the dependences on
  DICT_TF_ZSSIZE_MAX, so that the code can be compiled with a different
  uncompressed page size by redefining UNIV_PAGE_SIZE_SHIFT in univ.i.
  Currently, the allowed values are 12, 13, or 14 (4k, 8k, 16k).

  Make the default compressed page size half the uncompressed page size.
  The previous default was 8 kilobytes, which is the same when compiling
  with the default 16k uncompressed page size.

  rb://50 approved by Pekka Lampio and Sunny Bains.
  ------------------------------------------------------------------------
parent 72e3f38f
......@@ -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)
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
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
......@@ -27,25 +68,25 @@
2008-10-16 The InnoDB Team
* dict/dict0dict.c,
mysql-test/innodb-index.result, mysql-test/innodb-index.test:
* 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
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
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:
* 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
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.
......@@ -53,12 +94,12 @@
* 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,
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
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().
......@@ -69,10 +110,10 @@
* handler/handler0alter.cc, include/row0merge.h, row/row0merge.c,
row/row0mysql.c:
Fix some locking issues, mainly in fast index creation. The
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
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.
......@@ -92,13 +133,14 @@
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.
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
......@@ -137,8 +179,8 @@
* 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:
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
......@@ -151,15 +193,14 @@
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:
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
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
......@@ -168,12 +209,11 @@
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:
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
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
......@@ -429,7 +469,7 @@
2008-04-29 The InnoDB Team
* handler/i_s.cc, include/srv0start.h, srv/srv0start.c:
* handler/i_s.cc, include/srv0start.h, srv/srv0start.c:
Fix Bug#36310 InnoDB plugin crash
2008-04-23 The InnoDB Team
......
......@@ -3648,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
......
......@@ -58,7 +58,7 @@ 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);
......
EXPORTS
_mysql_plugin_interface_version_
_mysql_sizeof_struct_st_plugin_
_mysql_plugin_declarations_
......@@ -69,6 +69,8 @@ extern "C" {
#include "ha_innodb.h"
#include "i_s.h"
#include "handler0vars.h"
#include "mysql_addons.h"
#ifndef MYSQL_SERVER
/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
......@@ -107,7 +109,11 @@ undefined. Map it to NULL. */
#ifdef MYSQL_DYNAMIC_PLUGIN
/* These must be weak global variables in the dynamic plugin. */
struct handlerton* innodb_hton_ptr;
#ifdef __WIN__
struct st_mysql_plugin* builtin_innobase_plugin_ptr;
#else
int builtin_innobase_plugin;
#endif /* __WIN__ */
/********************************************************************
Copy InnoDB system variables from the static InnoDB to the dynamic
plugin. */
......@@ -163,7 +169,7 @@ static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
static my_bool innobase_stats_on_metadata = TRUE;
static my_bool innobase_adaptive_hash_index = TRUE;
static char* internal_innobase_data_file_path = NULL;
......@@ -520,7 +526,7 @@ thd_is_replication_slave_thread(
/**********************************************************************
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
inline
static inline
void
innodb_srv_conc_enter_innodb(
/*=========================*/
......@@ -537,7 +543,7 @@ innodb_srv_conc_enter_innodb(
/**********************************************************************
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
inline
static inline
void
innodb_srv_conc_exit_innodb(
/*========================*/
......@@ -556,7 +562,7 @@ Releases possible search latch and InnoDB thread FIFO ticket. These should
be released at each SQL statement end, and also when mysqld passes the
control to the client. It does no harm to release these also in the middle
of an SQL statement. */
inline
static inline
void
innobase_release_stat_resources(
/*============================*/
......@@ -630,7 +636,7 @@ thd_lock_wait_timeout(
/************************************************************************
Obtain the InnoDB transaction of a MySQL thread. */
inline
static inline
trx_t*&
thd_to_trx(
/*=======*/
......@@ -674,7 +680,7 @@ Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
time calls srv_active_wake_master_thread. This function should be used
when a single database operation may introduce a small need for
server utility activity, like checkpointing. */
inline
static inline
void
innobase_active_small(void)
/*=======================*/
......@@ -948,6 +954,99 @@ innobase_get_charset(
return(thd_charset((THD*) mysql_thd));
}
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
/***********************************************************************
Map an OS error to an errno value. The OS error number is stored in
_doserrno and the mapped value is stored in errno) */
extern "C"
void __cdecl
_dosmaperr(
unsigned long); /* in: OS error value */
/*************************************************************************
Creates a temporary file. */
extern "C" UNIV_INTERN
int
innobase_mysql_tmpfile(void)
/*========================*/
/* out: temporary file descriptor, or < 0 on error */
{
int fd; /* handle of opened file */
HANDLE osfh; /* OS handle of opened file */
char* tmpdir; /* point to the directory
where to create file */
TCHAR path_buf[MAX_PATH - 14]; /* buffer for tmp file path.
The length cannot be longer
than MAX_PATH - 14, or
GetTempFileName will fail. */
char filename[MAX_PATH]; /* name of the tmpfile */
DWORD fileaccess = GENERIC_READ /* OS file access */
| GENERIC_WRITE
| DELETE;
DWORD fileshare = FILE_SHARE_READ /* OS file sharing mode */
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE;
DWORD filecreate = CREATE_ALWAYS; /* OS method of open/create */
DWORD fileattrib = /* OS file attribute flags */
FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_DELETE_ON_CLOSE
| FILE_ATTRIBUTE_TEMPORARY
| FILE_FLAG_SEQUENTIAL_SCAN;
DBUG_ENTER("innobase_mysql_tmpfile");
tmpdir = my_tmpdir(&mysql_tmpdir_list);
/* The tmpdir parameter can not be NULL for GetTempFileName. */
if (!tmpdir) {
uint ret;
/* Use GetTempPath to determine path for temporary files. */
ret = GetTempPath(sizeof(path_buf), path_buf);
if (ret > sizeof(path_buf) || (ret == 0)) {
_dosmaperr(GetLastError()); /* map error */
DBUG_RETURN(-1);
}
tmpdir = path_buf;
}
/* Use GetTempFileName to generate a unique filename. */
if (!GetTempFileName(tmpdir, "ib", 0, filename)) {
_dosmaperr(GetLastError()); /* map error */
DBUG_RETURN(-1);
}
DBUG_PRINT("info", ("filename: %s", filename));
/* Open/Create the file. */
osfh = CreateFile(filename, fileaccess, fileshare, NULL,
filecreate, fileattrib, NULL);
if (osfh == INVALID_HANDLE_VALUE) {
/* open/create file failed! */
_dosmaperr(GetLastError()); /* map error */
DBUG_RETURN(-1);
}
do {
/* Associates a CRT file descriptor with the OS file handle. */
fd = _open_osfhandle((intptr_t) osfh, 0);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
/* Open failed, close the file handle. */
_dosmaperr(GetLastError()); /* map error */
CloseHandle(osfh); /* no need to check if
CloseHandle fails */
}
DBUG_RETURN(fd);
}
#else
/*************************************************************************
Creates a temporary file. */
extern "C" UNIV_INTERN
......@@ -979,6 +1078,7 @@ innobase_mysql_tmpfile(void)
}
return(fd2);
}
#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
/*************************************************************************
Wrapper around MySQL's copy_and_convert function, see it for
......@@ -1194,7 +1294,7 @@ ha_innobase::~ha_innobase()
Updates the user_thd field in a handle and also allocates a new InnoDB
transaction handle if needed, and updates the transaction fields in the
prebuilt struct. */
inline
UNIV_INTERN inline
void
ha_innobase::update_thd(
/*====================*/
......@@ -1231,7 +1331,7 @@ Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
roll back the statement if the statement results in an error. This MUST be
called for every SQL statement that may be rolled back by MySQL. Calling this
several times to register the same statement is allowed, too. */
inline
static inline
void
innobase_register_stmt(
/*===================*/
......@@ -1250,7 +1350,7 @@ MUST be called for every transaction for which the user may call commit or
rollback. Calling this several times to register the same transaction is
allowed, too.
This function also registers the current SQL statement. */
inline
static inline
void
innobase_register_trx_and_stmt(
/*===========================*/
......@@ -1984,8 +2084,6 @@ innobase_init(
srv_max_n_open_files = (ulint) innobase_open_files;
srv_innodb_status = (ibool) innobase_create_status_file;
srv_stats_on_metadata = (ibool) innobase_stats_on_metadata;
btr_search_disabled = (ibool) !innobase_adaptive_hash_index;
srv_print_verbose_log = mysqld_embedded ? 0 : 1;
......@@ -3038,7 +3136,7 @@ ha_innobase::close(void)
/******************************************************************
Gets field offset for a field in a table. */
inline
static inline
uint
get_field_offset(
/*=============*/
......@@ -3082,7 +3180,7 @@ field_in_record_is_null(
/******************************************************************
Sets a field in a record to SQL NULL. Uses the record format
information in table to track the null bit in record. */
inline
static inline
void
set_field_in_record_to_null(
/*========================*/
......@@ -3291,7 +3389,7 @@ get_innobase_type_from_mysql_type(
/***********************************************************************
Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
storage format. */
inline
static inline
void
innobase_write_to_2_little_endian(
/*==============================*/
......@@ -3307,7 +3405,7 @@ innobase_write_to_2_little_endian(
/***********************************************************************
Reads an unsigned integer value < 64k from 2 bytes, in the little-endian
storage format. */
inline
static inline
uint
innobase_read_from_2_little_endian(
/*===============================*/
......@@ -4637,7 +4735,7 @@ ha_innobase::index_end(void)
/*************************************************************************
Converts a search mode flag understood by MySQL to a flag understood
by InnoDB. */
inline
static inline
ulint
convert_search_mode_to_innobase(
/*============================*/
......@@ -5875,40 +5973,21 @@ ha_innobase::create(
if (create_info->key_block_size
|| (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
switch (create_info->key_block_size) {
case 1:
flags = 1 << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
case 2:
flags = 2 << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
case 4:
flags = 3 << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
case 8:
flags = 4 << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
case 16:
flags = 5 << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
#if DICT_TF_ZSSIZE_MAX != 5
# error "DICT_TF_ZSSIZE_MAX != 5"
#endif
/* Determine the page_zip.ssize corresponding to the
requested page size (key_block_size) in kilobytes. */
ulint ssize, ksize;
ulint key_block_size = create_info->key_block_size;
for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX;
ssize++, ksize <<= 1) {
if (key_block_size == ksize) {
flags = ssize << DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
break;
}
}
if (!srv_file_per_table) {
......@@ -5960,12 +6039,16 @@ ha_innobase::create(
/* No KEY_BLOCK_SIZE */
if (form->s->row_type == ROW_TYPE_COMPRESSED) {
/* ROW_FORMAT=COMPRESSED without
KEY_BLOCK_SIZE implies
KEY_BLOCK_SIZE=8. */
flags = 4 << DICT_TF_ZSSIZE_SHIFT
KEY_BLOCK_SIZE implies half the
maximum KEY_BLOCK_SIZE. */
flags = (DICT_TF_ZSSIZE_MAX - 1)
<< DICT_TF_ZSSIZE_SHIFT
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
<< DICT_TF_FORMAT_SHIFT;
#if DICT_TF_ZSSIZE_MAX < 1
# error "DICT_TF_ZSSIZE_MAX < 1"
#endif
}
}
......@@ -6777,7 +6860,7 @@ ha_innobase::info(
ib_table = prebuilt->table;
if (flag & HA_STATUS_TIME) {
if (srv_stats_on_metadata) {
if (innobase_stats_on_metadata) {
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
......@@ -7553,7 +7636,7 @@ ha_innobase::start_stmt(
/**********************************************************************
Maps a MySQL trx isolation level code to the InnoDB isolation level code */
inline
static inline
ulint
innobase_map_isolation_level(
/*=========================*/
......@@ -7596,12 +7679,12 @@ ha_innobase::external_lock(
READ UNCOMMITTED and READ COMMITTED since the necessary
locks cannot be taken. In this case, we print an
informative error message and return with an error. */
if (lock_type == F_WRLCK)
if (lock_type == F_WRLCK && ib_bin_log_is_engaged(thd))
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
if (tx_isolation <= ISO_READ_COMMITTED &&
binlog_format == BINLOG_FORMAT_STMT)
if (tx_isolation <= ISO_READ_COMMITTED
&& binlog_format == BINLOG_FORMAT_STMT)
{
char buf[256];
my_snprintf(buf, sizeof(buf),
......@@ -9343,7 +9426,7 @@ static MYSQL_SYSVAR_BOOL(status_file, innobase_create_status_file,
NULL, NULL, FALSE);
static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
PLUGIN_VAR_OPCMDARG,
"Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
NULL, NULL, TRUE);
......@@ -9568,6 +9651,20 @@ innodb_plugin_init(void)
#error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
#endif
/* Copy the system variables. */
struct st_mysql_plugin* builtin;
struct st_mysql_sys_var** sta; /* static parameters */
struct st_mysql_sys_var** dyn; /* dynamic parameters */
#ifdef __WIN__
if (!builtin_innobase_plugin_ptr) {
return(true);
}
builtin = builtin_innobase_plugin_ptr;
#else
switch (builtin_innobase_plugin) {
case 0:
return(true);
......@@ -9577,34 +9674,34 @@ innodb_plugin_init(void)
return(false);
}
/* Copy the system variables. */
struct st_mysql_plugin* builtin;
struct st_mysql_sys_var** sta; /* static parameters */
struct st_mysql_sys_var** dyn; /* dynamic parameters */
builtin = (struct st_mysql_plugin*) &builtin_innobase_plugin;
#endif
for (sta = builtin->system_vars; *sta != NULL; sta++) {
/* do not copy session variables */
if ((*sta)->flags & PLUGIN_VAR_THDLOCAL) {
continue;
}
for (dyn = innobase_system_variables; *dyn != NULL; dyn++) {
/* do not copy session variables */
if (((*sta)->flags | (*dyn)->flags)
& PLUGIN_VAR_THDLOCAL) {
continue;
}
if (innobase_match_parameter((*sta)->name,
(*dyn)->name)) {
/* found the corresponding parameter */
/* check if the flags are the same,
ignoring differences in the READONLY flag;
ignoring differences in the READONLY or
NOSYSVAR flags;
e.g. we are not copying string variable to
an integer one */
if (((*sta)->flags & ~PLUGIN_VAR_READONLY)
!= ((*dyn)->flags & ~PLUGIN_VAR_READONLY)) {
an integer one, but we do not care if it is
readonly in the static and not in the
dynamic */
if (((*sta)->flags ^ (*dyn)->flags)
& ~(PLUGIN_VAR_READONLY
| PLUGIN_VAR_NOSYSVAR)) {
fprintf(stderr,
"InnoDB: %s in static InnoDB "
......
......@@ -18,6 +18,7 @@ extern "C" {
}
#include "ha_innodb.h"
#include "handler0vars.h"
/*****************************************************************
Copies an InnoDB column to a MySQL field. This function is
......
/***********************************************************************
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);
}
/***********************************************************************
This file contains functions that implement the delay loader on Windows.
This is a customized version of delay loader with limited functionalities.
It does not support:
* (manual) unloading
* multiple delay loaded DLLs
* multiple loading of the same DLL
This delay loader is used only by the InnoDB plugin. Other components (DLLs)
can still use the default delay loader, provided by MSVC.
Several acronyms used by Microsoft:
* IAT: import address table
* INT: import name table
* RVA: Relative Virtual Address
See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
PE format.
(c) 2008 Innobase Oy
***********************************************************************/
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <delayimp.h>
# include <mysql_priv.h>
extern "C" {
# include "univ.i"
# include "hash0hash.h"
}
/***********************************************************************
This following contains 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. */
CHARSET_INFO* wdl_my_charset_bin;
CHARSET_INFO* wdl_my_charset_latin1;
CHARSET_INFO* wdl_my_charset_filename;
CHARSET_INFO** wdl_system_charset_info;
CHARSET_INFO** wdl_default_charset_info;
CHARSET_INFO** wdl_all_charsets;
system_variables* wdl_global_system_variables;
char* wdl_mysql_real_data_home;
char** wdl_mysql_data_home;
char** wdl_tx_isolation_names;
char** wdl_binlog_format_names;
char* wdl_reg_ext;
pthread_mutex_t* wdl_LOCK_thread_count;
key_map* wdl_key_map_full;
MY_TMPDIR* wdl_mysql_tmpdir_list;
bool* wdl_mysqld_embedded;
uint* wdl_lower_case_table_names;
ulong* wdl_specialflag;
int* wdl_my_umask;
/***********************************************************************
The following is defined in ha_innodb.cc. It is used for copying the
system variables from the builtin innodb plugin to the dynamic plugin.
*/
extern struct st_mysql_plugin* builtin_innobase_plugin_ptr;
/***********************************************************************
The preffered load-address defined in PE (portable executable format).*/
#if defined(_M_IA64)
#pragma section(".base", long, read)
extern "C"
__declspec(allocate(".base"))
const IMAGE_DOS_HEADER __ImageBase;
#else
extern "C"
const IMAGE_DOS_HEADER __ImageBase;
#endif
/***********************************************************************
A template function for converting a relative address (RVA) to an
absolute address (VA). This is due to the pointers in the delay
descriptor (ImgDelayDescr in delayimp.h) have been changed from
VAs to RVAs to work on both 32- and 64-bit platforms. */
template <class X>
X PFromRva(RVA rva) {
return X(PBYTE(&__ImageBase) + rva);
}
/***********************************************************************
Convert to the old format for convenience. The structure as well as its
element names follow the definition of ImgDelayDescr in delayimp.h. */
struct InternalImgDelayDescr {
DWORD grAttrs; /* attributes */
LPCSTR szName; /* pointer to dll name */
HMODULE* phmod; /* address of module handle */
PImgThunkData pIAT; /* address of the IAT */
PCImgThunkData pINT; /* address of the INT */
PCImgThunkData pBoundIAT; /* address of the optional bound IAT */
PCImgThunkData pUnloadIAT; /* address of optional copy of
original IAT */
DWORD dwTimeStamp; /* 0 if not bound,
otherwise date/time stamp of DLL
bound to (Old BIND) */
};
typedef struct map_hash_chain_struct map_hash_chain_t;
struct map_hash_chain_struct {
char* symbol; /* pointer to a symbol */
ulint value; /* address of the symbol */
map_hash_chain_t* next; /* pointer to the next cell
in the same folder. */
map_hash_chain_t* chain; /* a linear chain used for
cleanup. */
};
static HMODULE my_hmod = 0;
static struct hash_table_struct* m_htbl = NULL ;
static map_hash_chain_t* chain_header = NULL;
static ibool wdl_init = FALSE;
const ulint MAP_HASH_CELLS_NUM = 10000;
#ifndef DBUG_OFF
/***********************************************************************
In the dynamic plugin, it is required to call the following dbug functions
in the server:
_db_pargs_
_db_doprnt_
_db_enter_
_db_return_
_db_dump_
The plugin will get those function pointers during the initialization.
*/
typedef void (__cdecl* pfn_db_enter_)(
const char* _func_,
const char* _file_,
uint _line_,
const char** _sfunc_,
const char** _sfile_,
uint* _slevel_,
char***);
typedef void (__cdecl* pfn_db_return_)(
uint _line_,
const char** _sfunc_,
const char** _sfile_,
uint* _slevel_);
typedef void (__cdecl* pfn_db_pargs_)(
uint _line_,
const char* keyword);
typedef void (__cdecl* pfn_db_doprnt_)(
const char* format,
...);
typedef void (__cdecl* pfn_db_dump_)(
uint _line_,
const char* keyword,
const unsigned char* memory,
size_t length);
static pfn_db_enter_ wdl_db_enter_;
static pfn_db_return_ wdl_db_return_;
static pfn_db_pargs_ wdl_db_pargs_;
static pfn_db_doprnt_ wdl_db_doprnt_;
static pfn_db_dump_ wdl_db_dump_;
#endif /* !DBUG_OFF */
/*****************************************************************
Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n.
This is the same function as hash_create in hash0hash.c, except the
memory allocation. This function is invoked before the engine is
initialized, and buffer pools are not ready yet. */
static
hash_table_t*
wdl_hash_create(
/*============*/
/* out, own: created hash table */
ulint n) /* in: number of array cells */
{
hash_cell_t* array;
ulint prime;
hash_table_t* table;
prime = ut_find_prime(n);
table = (hash_table_t*) malloc(sizeof(hash_table_t));
if (table == NULL) {
return(NULL);
}
array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
if (array == NULL) {
free(table);
return(NULL);
}
table->array = array;
table->n_cells = prime;
table->n_mutexes = 0;
table->mutexes = NULL;
table->heaps = NULL;
table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N;
/* Initialize the cell array */
hash_table_clear(table);
return(table);
}
/*****************************************************************
Frees a hash table. */
static
void
wdl_hash_table_free(
/*================*/
hash_table_t* table) /* in, own: hash table */
{
ut_a(table != NULL);
ut_a(table->mutexes == NULL);
free(table->array);
free(table);
}
/***********************************************************************
Function for calculating the count of imports given the base of the IAT. */
static
ulint
wdl_import_count(
/*=============*/
/* out: number of imports */
PCImgThunkData pitd_base) /* in: base of the IAT */
{
ulint ret = 0;
PCImgThunkData pitd = pitd_base;
while (pitd->u1.Function) {
pitd++;
ret++;
}
return(ret);
}
/***********************************************************************
Read Mapfile to a hashtable for faster access */
static
ibool
wdl_load_mapfile(
/*=============*/
/* out: TRUE if the mapfile is
loaded successfully. */
const char* filename) /* in: name of the mapfile. */
{
FILE* fp;
const size_t nSize = 256;
char tmp_buf[nSize];
char* func_name;
char* func_addr;
ulint load_addr = 0;
ibool valid_load_addr = FALSE;
fp = fopen(filename, "r");
if (fp == NULL) {
return(FALSE);
}
/* Check whether to create the hashtable */
if (m_htbl == NULL) {
m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
if (m_htbl == NULL) {
fclose(fp);
return(FALSE);
}
}
/* Search start of symbol list and get the preferred load address */
while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
if (sscanf(tmp_buf, " Preferred load address is %16X",
&load_addr) == 1) {
valid_load_addr = TRUE;
}
if (strstr(tmp_buf, "Rva+Base") != NULL) {
break;
}
}
if (valid_load_addr == FALSE) {
/* No "Preferred load address", the map file is wrong. */
fclose(fp);
return(FALSE);
}
/* Read symbol list */
while (fgets(tmp_buf, sizeof(tmp_buf), fp))
{
map_hash_chain_t* map_cell;
ulint map_fold;
if (*tmp_buf == 0) {
continue;
}
func_name = strtok(tmp_buf, " ");
func_name = strtok(NULL, " ");
func_addr = strtok(NULL, " ");
if (func_name && func_addr) {
ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
if (*func_name == '_') {
func_name++;
}
map_cell = (map_hash_chain_t*)
malloc(sizeof(map_hash_chain_t));
if (map_cell == NULL) {
return(FALSE);
}
/* Chain all cells together */
map_cell->chain = chain_header;
chain_header = map_cell;
map_cell->symbol = strdup(func_name);
map_cell->value = strtoul(tmp_buf, NULL, 0)
- load_addr;
map_fold = ut_fold_string(map_cell->symbol);
HASH_INSERT(map_hash_chain_t,
next,
m_htbl,
map_fold,
map_cell);
}
}
fclose(fp);
return(TRUE);
}
/*****************************************************************
Cleanup.during DLL unload */
static
void
wdl_cleanup(void)
/*=============*/
{
while (chain_header != NULL) {
map_hash_chain_t* tmp;
tmp = chain_header->chain;
free(chain_header->symbol);
free(chain_header);
chain_header = tmp;
}
if (m_htbl != NULL) {
wdl_hash_table_free(m_htbl);
}
}
/***********************************************************************
Load the mapfile mysqld.map. */
static
HMODULE
wdl_get_mysqld_mapfile(void)
/*========================*/
/* out: the module handle */
{
char file_name[MAX_PATH];
char* ext;
ulint err;
if (my_hmod == 0) {
size_t nSize = MAX_PATH - strlen(".map") -1;
/* First find out the name of current executable */
my_hmod = GetModuleHandle(NULL);
if (my_hmod == 0) {
return(my_hmod);
}
err = GetModuleFileName(my_hmod, file_name, nSize);
if (err == 0) {
my_hmod = 0;
return(my_hmod);
}
ext = strrchr(file_name, '.');
if (ext != NULL) {
*ext = 0;
strcat(file_name, ".map");
err = wdl_load_mapfile(file_name);
if (err == 0) {
my_hmod = 0;
}
} else {
my_hmod = 0;
}
}
return(my_hmod);
}
/***********************************************************************
Retrieves the address of an exported function. It follows the convention
of GetProcAddress(). */
static
FARPROC
wdl_get_procaddr_from_map(
/*======================*/
/* out: address of exported
function. */
HANDLE m_handle, /* in: module handle */
const char* import_proc) /* in: procedure name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
map_fold = ut_fold_string(import_proc);
HASH_SEARCH(
next,
m_htbl,
map_fold,
map_hash_chain_t*,
hash_chain,
(ut_strcmp(hash_chain->symbol, import_proc) == 0));
if (hash_chain == NULL) {
#ifdef _WIN64
/* On Win64, the leading '_' may not be taken out. In this
case, search again without the leading '_'. */
if (*import_proc == '_') {
import_proc++;
}
map_fold = ut_fold_string(import_proc);
HASH_SEARCH(
next,
m_htbl,
map_fold,
map_hash_chain_t*,
hash_chain,
(ut_strcmp(hash_chain->symbol, import_proc) == 0));
if (hash_chain == NULL) {
#endif
if (wdl_init == TRUE) {
sql_print_error(
"InnoDB: the procedure pointer of %s"
" is not found.",
import_proc);
}
return(0);
#ifdef _WIN64
}
#endif
}
return((FARPROC) ((ulint) m_handle + hash_chain->value));
}
/***********************************************************************
Retrieves the address of an exported variable.
Note: It does not follow the Windows call convention FARPROC. */
static
void*
wdl_get_varaddr_from_map(
/*=====================*/
/* out: address of exported
variable. */
HANDLE m_handle, /* in: module handle */
const char* import_variable) /* in: variable name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
map_fold = ut_fold_string(import_variable);
HASH_SEARCH(
next,
m_htbl,
map_fold,
map_hash_chain_t*,
hash_chain,
(ut_strcmp(hash_chain->symbol, import_variable) == 0));
if (hash_chain == NULL) {
#ifdef _WIN64
/* On Win64, the leading '_' may not be taken out. In this
case, search again without the leading '_'. */
if (*import_variable == '_') {
import_variable++;
}
map_fold = ut_fold_string(import_variable);
HASH_SEARCH(
next,
m_htbl,
map_fold,
map_hash_chain_t*,
hash_chain,
(ut_strcmp(hash_chain->symbol, import_variable) == 0));
if (hash_chain == NULL) {
#endif
if (wdl_init == TRUE) {
sql_print_error(
"InnoDB: the variable address of %s"
" is not found.",
import_variable);
}
return(0);
#ifdef _WIN64
}
#endif
}
return((void*) ((ulint) m_handle + hash_chain->value));
}
/***********************************************************************
Bind all unresolved external variables from the MySQL executable. */
static
bool
wdl_get_external_variables(void)
/*============================*/
/* out: TRUE if successful */
{
HMODULE hmod = wdl_get_mysqld_mapfile();
if (hmod == 0) {
return(FALSE);
}
#define GET_SYM(sym, var, type) \
var = (type*) wdl_get_varaddr_from_map(hmod, sym); \
if (var == NULL) return(FALSE)
#ifdef _WIN64
#define GET_SYM2(sym1, sym2, var, type) \
var = (type*) wdl_get_varaddr_from_map(hmod, sym1); \
if (var == NULL) return(FALSE)
#else
#define GET_SYM2(sym1, sym2, var, type) \
var = (type*) wdl_get_varaddr_from_map(hmod, sym2); \
if (var == NULL) return(FALSE)
#endif // (_WIN64)
#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
#define GET_PROC_ADDR(sym) \
wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
GET_C_SYM(my_charset_bin, CHARSET_INFO);
GET_C_SYM(my_charset_latin1, CHARSET_INFO);
GET_C_SYM(my_charset_filename, CHARSET_INFO);
GET_C_SYM(default_charset_info, CHARSET_INFO*);
GET_C_SYM(all_charsets, CHARSET_INFO*);
GET_C_SYM(my_umask, int);
GET_SYM("?global_system_variables@@3Usystem_variables@@A",
wdl_global_system_variables, struct system_variables);
GET_SYM("?mysql_real_data_home@@3PADA",
wdl_mysql_real_data_home, char);
GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
wdl_LOCK_thread_count, pthread_mutex_t);
GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
wdl_key_map_full, key_map);
GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
wdl_mysql_tmpdir_list, MY_TMPDIR);
GET_SYM("?mysqld_embedded@@3_NA",
wdl_mysqld_embedded, bool);
GET_SYM("?lower_case_table_names@@3IA",
wdl_lower_case_table_names, uint);
GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
"?system_charset_info@@3PAUcharset_info_st@@A",
wdl_system_charset_info, CHARSET_INFO*);
GET_SYM2("?mysql_data_home@@3PEADEA",
"?mysql_data_home@@3PADA",
wdl_mysql_data_home, char*);
GET_SYM2("?tx_isolation_names@@3PAPEBDA",
"?tx_isolation_names@@3PAPBDA",
wdl_tx_isolation_names, char*);
GET_SYM2("?binlog_format_names@@3PAPEBDA",
"?binlog_format_names@@3PAPBDA",
wdl_binlog_format_names, char*);
/* It is fine if builtin_innobase_plugin is not available. */
builtin_innobase_plugin_ptr = (struct st_mysql_plugin*)
wdl_get_varaddr_from_map(
hmod,
"?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A");
#ifndef DBUG_OFF
GET_PROC_ADDR(_db_enter_);
GET_PROC_ADDR(_db_return_);
GET_PROC_ADDR(_db_pargs_);
GET_PROC_ADDR(_db_doprnt_);
GET_PROC_ADDR(_db_dump_);
/* If any of the dbug functions is not available, just make them
all invalid. This is the case when working with a non-debug
version of the server. */
if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
|| wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
|| wdl_db_dump_ == NULL) {
wdl_db_enter_ = NULL;
wdl_db_return_ = NULL;
wdl_db_pargs_ = NULL;
wdl_db_doprnt_ = NULL;
wdl_db_dump_ = NULL;
}
#endif /* !DBUG_OFF */
wdl_init = TRUE;
return(TRUE);
#undef GET_SYM
#undef GET_SYM2
#undef GET_C_SYM
#undef GET_PROC_ADDR
}
/***********************************************************************
The DLL Delayed Loading Helper Function for resolving externals.
The function may fail due to one of the three reasons:
* Invalid parameter, which happens if the attributes in pidd aren't
specified correctly.
* Failed to load the map file mysqld.map.
* Failed to find an external name in the map file mysqld.map.
Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
So, it has to follow Windows call convention. */
extern "C"
FARPROC WINAPI
__delayLoadHelper2(
/*===============*/
/* out: the address of the imported
function*/
PCImgDelayDescr pidd, /* in: a const pointer to a
ImgDelayDescr, see delayimp.h. */
FARPROC* iat_entry) /* in/out: A pointer to the slot in
the delay load import address table
to be updated with the address of the
imported function. */
{
ulint iIAT, iINT;
HMODULE hmod;
PCImgThunkData pitd;
FARPROC fun = NULL;
/* Set up data used for the hook procs */
InternalImgDelayDescr idd = {
pidd->grAttrs,
PFromRva<LPCSTR>(pidd->rvaDLLName),
PFromRva<HMODULE*>(pidd->rvaHmod),
PFromRva<PImgThunkData>(pidd->rvaIAT),
PFromRva<PCImgThunkData>(pidd->rvaINT),
PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
pidd->dwTimeStamp
};
DelayLoadInfo dli = {
sizeof(DelayLoadInfo),
pidd,
iat_entry,
idd.szName,
{0},
0,
0,
0
};
/* Check the Delay Load Attributes, log an error of invalid
parameter, which happens if the attributes in pidd are not
specified correctly. */
if ((idd.grAttrs & dlattrRva) == 0) {
sql_print_error("InnoDB: invalid parameter for delay loader.");
return(0);
}
hmod = *idd.phmod;
/* Calculate the index for the IAT entry in the import address table.
The INT entries are ordered the same as the IAT entries so the
calculation can be done on the IAT side. */
iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
iINT = iIAT;
pitd = &(idd.pINT[iINT]);
dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
if (dli.dlp.fImportByName) {
dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
} else {
dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
}
/* Now, load the mapfile, if it has not been done yet */
if (hmod == 0) {
hmod = wdl_get_mysqld_mapfile();
}
if (hmod == 0) {
/* LoadLibrary failed. */
PDelayLoadInfo rgpdli[1] = {&dli};
dli.dwLastError = ::GetLastError();
sql_print_error(
"InnoDB: failed to load mysqld.map with error %d.",
dli.dwLastError);
return(0);
}
/* Store the library handle. */
idd.phmod = &hmod;
/* Go for the procedure now. */
dli.hmodCur = hmod;
if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
/* Bound imports exist, check the timestamp from the target
image */
PIMAGE_NT_HEADERS pinh;
pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
+ ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
if (pinh->Signature == IMAGE_NT_SIGNATURE
&& pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
&& (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
/* We have a decent address in the bound IAT. */
fun = (FARPROC) (UINT_PTR)
idd.pBoundIAT[iIAT].u1.Function;
if (fun) {
*iat_entry = fun;
return(fun);
}
}
}
fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
if (fun == 0) {
return(0);
}
*iat_entry = fun;
return(fun);
}
/***********************************************************************
Unload a DLL that was delay loaded. This function is called by run-time. */
extern "C"
BOOL WINAPI
__FUnloadDelayLoadedDLL2(
/*=====================*/
/* out: TRUE is returned if the DLL is found
and the IAT matches the original one. */
LPCSTR module_name) /* in: DLL name */
{
return(TRUE);
}
/******************************************************************
Load all imports from a DLL that was specified with the /delayload linker
option.
Note: this function is called by run-time. So, it has to follow Windows call
convention. */
extern "C"
HRESULT WINAPI
__HrLoadAllImportsForDll(
/*=====================*/
/* out: S_OK if the DLL matches, otherwise
ERROR_MOD_NOT_FOUND is returned. */
LPCSTR module_name) /* in: DLL name */
{
PIMAGE_NT_HEADERS img;
PCImgDelayDescr pidd;
IMAGE_DATA_DIRECTORY* image_data;
LPCSTR current_module;
HRESULT ret = ERROR_MOD_NOT_FOUND;
HMODULE hmod = (HMODULE) &__ImageBase;
img = (PIMAGE_NT_HEADERS) ((byte*) hmod
+ ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
image_data =
&img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
/* Scan the delay load IAT/INT for the DLL */
if (image_data->Size) {
pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
/* Check all of the listed DLLs we want to load. */
while (pidd->rvaDLLName) {
current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
if (stricmp(module_name, current_module) == 0) {
/* Found it, break out with pidd and
current_module set appropriately */
break;
}
/* To the next delay import descriptor */
pidd++;
}
if (pidd->rvaDLLName) {
/* Found a matching DLL, now process it. */
FARPROC* iat_entry;
size_t count;
iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
count = wdl_import_count((PCImgThunkData) iat_entry);
/* now load all the imports from the DLL */
while (count > 0) {
/* No need to check the return value */
__delayLoadHelper2(pidd, iat_entry);
iat_entry++;
count--;
}
ret = S_OK;
}
}
return ret;
}
/******************************************************************
The main function of a DLL */
BOOL
WINAPI
DllMain(
/*====*/
/* out: TRUE if the call succeeds */
HINSTANCE hinstDLL, /* in: handle to the DLL module */
DWORD fdwReason, /* Reason code that indicates why the
DLL entry-point function is being
called.*/
LPVOID lpvReserved) /* in: additional parameter based on
fdwReason */
{
BOOL success = TRUE;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
success = wdl_get_external_variables();
break;
case DLL_PROCESS_DETACH:
wdl_cleanup();
break;
}
return(success);
}
#ifndef DBUG_OFF
/******************************************************************
Process entry point to user function. It makes the call to _db_enter_
in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
extern "C" UNIV_INTERN
void
_db_enter_(
const char* _func_, /* in: current function name */
const char* _file_, /* in: current file name */
uint _line_, /* in: current source line number */
const char** _sfunc_, /* out: previous _func_ */
const char** _sfile_, /* out: previous _file_ */
uint* _slevel_, /* out: previous nesting level */
char*** _sframep_) /* out: previous frame pointer */
{
if (wdl_db_enter_ != NULL) {
wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
_slevel_, _sframep_);
}
}
/******************************************************************
Process exit from user function. It makes the call to _db_return_()
in the server. */
extern "C" UNIV_INTERN
void
_db_return_(
uint _line_, /* in: current source line number */
const char** _sfunc_, /* out: previous _func_ */
const char** _sfile_, /* out: previous _file_ */
uint* _slevel_) /* out: previous level */
{
if (wdl_db_return_ != NULL) {
wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
}
}
/******************************************************************
Log arguments for subsequent use. It makes the call to _db_pargs_()
in the server. */
extern "C" UNIV_INTERN
void
_db_pargs_(
uint _line_, /* in: current source line number */
const char* keyword) /* in: keyword for current macro */
{
if (wdl_db_pargs_ != NULL) {
wdl_db_pargs_(_line_, keyword);
}
}
/******************************************************************
Handle print of debug lines. It saves the text into a buffer first,
then makes the call to _db_doprnt_() in the server. The text is
truncated to the size of buffer. */
extern "C" UNIV_INTERN
void
_db_doprnt_(
const char* format, /* in: the format string */
...) /* in: list of arguments */
{
va_list argp;
char buffer[512];
if (wdl_db_doprnt_ != NULL) {
va_start(argp, format);
/* it is ok to ignore the trunction. */
_vsnprintf(buffer, sizeof(buffer), format, argp);
wdl_db_doprnt_(buffer);
va_end(argp);
}
}
/******************************************************************
Dump a string in hex. It makes the call to _db_dump_() in the server. */
extern "C" UNIV_INTERN
void
_db_dump_(
uint _line_, /* in: current source line
number */
const char* keyword, /* in: keyword list */
const unsigned char* memory, /* in: memory to dump */
size_t length) /* in: bytes to dump */
{
if (wdl_db_dump_ != NULL) {
wdl_db_dump_(_line_, keyword, memory, length);
}
}
#endif /* !DBUG_OFF */
#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
......@@ -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));
}
......@@ -299,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
......
......@@ -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 */
......@@ -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,12 +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 */
ib_uint64_t autoinc;/* autoinc counter value to give to the
next inserted row */
/*----------------------*/
ulong n_waiting_or_granted_auto_inc_locks;
/* This counter is used to track the number
of granted and pending autoinc locks on this
......@@ -453,6 +468,9 @@ 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
......
......@@ -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
......@@ -653,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);
......@@ -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
......
......@@ -132,8 +132,6 @@ 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;
......
......@@ -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;
......@@ -601,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
......@@ -735,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. */
......
......@@ -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;
......
......@@ -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++;
}
......
......@@ -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);
}
......@@ -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");
}
/* Store pointer to lock to trx so that we know to
release it at the end of the SQL statement */
} else {
table->autoinc_trx = trx;
lock->trx->auto_inc_lock = lock;
ib_vector_push(trx->autoinc_locks, 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;
table->autoinc_trx = trx;
ut_a(trx->auto_inc_lock == NULL);
trx->auto_inc_lock = lock;
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;
/* 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 (lock == trx->auto_inc_lock) {
trx->auto_inc_lock = NULL;
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);
}
......@@ -5386,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. */
......
......@@ -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
......
......@@ -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
......
SET TX_ISOLATION='READ-COMMITTED';
CREATE TABLE bug40360 (a INT) engine=innodb;
INSERT INTO bug40360 VALUES (1);
DROP TABLE bug40360;
#
# 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;
......@@ -11,7 +11,7 @@ in the MySQL source repository.
Index: storage/innobase/mysql-test/innodb-index.result
===================================================================
--- storage/innobase/mysql-test/innodb-index.result (revision 2229)
--- 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,
......@@ -35,7 +35,7 @@ Index: storage/innobase/mysql-test/innodb-index.result
`b` int(11) DEFAULT NULL,
Index: storage/innobase/mysql-test/innodb-index.test
===================================================================
--- storage/innobase/mysql-test/innodb-index.test (revision 2229)
--- 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
......@@ -57,6 +57,6 @@ Index: storage/innobase/mysql-test/innodb-index.test
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
......@@ -852,19 +852,18 @@ row_update_statistics_if_needed(
}
/*************************************************************************
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 */
{
if (!trx->auto_inc_lock) {
mutex_enter(&kernel_mutex);
return;
}
lock_release_autoinc_locks(trx);
lock_table_unlock_auto_inc(trx);
mutex_exit(&kernel_mutex);
}
/*************************************************************************
......@@ -881,16 +880,20 @@ row_lock_table_autoinc_for_mysql(
row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL
table handle */
{
trx_t* trx = prebuilt->trx;
ins_node_t* node = prebuilt->ins_node;
que_thr_t* thr;
ulint err;
ibool was_lock_wait;
trx_t* trx = prebuilt->trx;
ins_node_t* node = prebuilt->ins_node;
const dict_table_t* table = prebuilt->table;
que_thr_t* thr;
ulint err;
ibool was_lock_wait;
ut_ad(trx);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
if (trx->auto_inc_lock) {
/* If we already hold an AUTOINC lock on the table then do nothing.
Note: We peek at the value of the current owner without acquiring
the kernel mutex. **/
if (trx == table->autoinc_trx) {
return(DB_SUCCESS);
}
......
-- execute these to install InnoDB if it is built as a dynamic plugin
INSTALL PLUGIN innodb SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_trx SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_locks SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_lock_waits SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.dll';
......@@ -299,8 +299,6 @@ UNIV_INTERN ulint srv_fast_shutdown = 0;
/* Generate a innodb_status.<pid> file */
UNIV_INTERN ibool srv_innodb_status = FALSE;
UNIV_INTERN ibool srv_stats_on_metadata = TRUE;
/* When estimating number of different key values in an index, sample
this many index pages */
UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
......
......@@ -169,8 +169,6 @@ trx_create(
trx->declared_to_be_inside_innodb = FALSE;
trx->n_tickets_to_enter_innodb = 0;
trx->auto_inc_lock = NULL;
trx->global_read_view_heap = mem_heap_create(256);
trx->global_read_view = NULL;
trx->read_view = NULL;
......@@ -181,6 +179,10 @@ trx_create(
trx->n_autoinc_rows = 0;
/* Remember to free the vector explicitly. */
trx->autoinc_locks = ib_vector_create(
mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 4), 4);
trx_reset_new_rec_lock_info(trx);
return(trx);
......@@ -305,7 +307,6 @@ trx_free(
ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
ut_a(!trx->has_search_latch);
ut_a(!trx->auto_inc_lock);
ut_a(trx->dict_operation_lock_mode == 0);
......@@ -323,6 +324,10 @@ trx_free(
ut_a(trx->read_view == NULL);
ut_a(ib_vector_is_empty(trx->autoinc_locks));
/* We allocated a dedicated heap for the vector. */
ib_vector_free(trx->autoinc_locks);
mem_free(trx);
}
......
This directory contains patches that need to be applied to the MySQL
source tree in order to build the dynamic plugin on Windows --
HA_INNODB.DLL. Please note the followings when adding the patches:
* The patch must be applied from the mysql top-level source directory.
patch -p0 < win-plugin.diff
* The patch filenames 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.
When applying the patch, the following files will be modified:
* CMakeLists.txt
* sql/CMakeLists.txt
* win/configure.js
* win/build-vs71.bat
* win/build-vs8.bat
* win/build-vs8_x64.bat
Also, two new files will be added:
* sql/mysqld.def
* sql/mysqld_x64.def
You can get "patch" utility for Windows from http://unxutils.sourceforge.net/
diff -Nur CMakeLists.txt.orig CMakeLists.txt
--- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
+++ CMakeLists.txt 2008-09-26 17:32:51 -05:00
@@ -97,6 +97,10 @@
IF(CYBOZU)
ADD_DEFINITIONS(-DCYBOZU)
ENDIF(CYBOZU)
+# Checks for 32-bit version. And always use 32-bit time_t for compatibility
+IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4)
+ ADD_DEFINITIONS(-D_USE_32BIT_TIME_T)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 4)
# in some places we use DBUG_OFF
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
@@ -246,9 +250,9 @@
IF(WITH_FEDERATED_STORAGE_ENGINE)
ADD_SUBDIRECTORY(storage/federated)
ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
-IF(WITH_INNOBASE_STORAGE_ENGINE)
+IF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
ADD_SUBDIRECTORY(storage/innobase)
-ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
+ENDIF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
ADD_SUBDIRECTORY(sql)
ADD_SUBDIRECTORY(server-tools/instance-manager)
ADD_SUBDIRECTORY(libmysql)
diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
--- sql/CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
+++ sql/CMakeLists.txt 2008-09-24 03:58:19 -05:00
@@ -100,6 +100,15 @@
LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
ENDIF(cmake_version EQUAL 20406)
+# Checks for 64-bit version
+IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
+SET_TARGET_PROPERTIES(mysqld PROPERTIES
+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld_x64.def\"")
+ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8)
+SET_TARGET_PROPERTIES(mysqld PROPERTIES
+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld.def\"")
+ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8)
+
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
ENDIF(EMBED_MANIFESTS)
diff -Nur sql/mysqld.def.orig sql/mysqld.def
--- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00
+++ sql/mysqld.def 2008-10-31 02:20:32 -05:00
@@ -0,0 +1,99 @@
+EXPORTS
+ ?use_hidden_primary_key@handler@@UAEXXZ
+ ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
+ ?read_first_row@handler@@UAEHPAEI@Z
+ ?read_range_next@handler@@UAEHXZ
+ ?read_range_first@handler@@UAEHPBUst_key_range@@0_N1@Z
+ ?read_multi_range_first@handler@@UAEHPAPAUst_key_multi_range@@PAU2@I_NPAUst_handler_buffer@@@Z
+ ?read_multi_range_next@handler@@UAEHPAPAUst_key_multi_range@@@Z
+ ?index_read_idx_map@handler@@UAEHPAEIPBEKW4ha_rkey_function@@@Z
+ ?print_error@handler@@UAEXHH@Z
+ ?clone@handler@@UAEPAV1@PAUst_mem_root@@@Z
+ ?get_auto_increment@handler@@UAEX_K00PA_K1@Z
+ ?index_next_same@handler@@UAEHPAEPBEI@Z
+ ?get_error_message@handler@@UAE_NHPAVString@@@Z
+ ?ha_thd@handler@@IBEPAVTHD@@XZ
+ ?update_auto_increment@handler@@QAEHXZ
+ ?ha_statistic_increment@handler@@IBEXPQsystem_status_var@@K@Z
+ ?trans_register_ha@@YAXPAVTHD@@_NPAUhandlerton@@@Z
+ ?cmp@Field_blob@@QAEHPBEI0I@Z
+ ?set_time@Field_timestamp@@QAEXXZ
+ ?sql_print_error@@YAXPBDZZ
+ ?sql_print_warning@@YAXPBDZZ
+ ?check_global_access@@YA_NPAVTHD@@K@Z
+ ?schema_table_store_record@@YA_NPAVTHD@@PAUst_table@@@Z
+ ?get_quote_char_for_identifier@@YAHPAVTHD@@PBDI@Z
+ ?copy@String@@QAE_NXZ
+ ?copy@String@@QAE_NABV1@@Z
+ ?copy@String@@QAE_NPBDIPAUcharset_info_st@@@Z
+ ?copy_and_convert@@YAIPADIPAUcharset_info_st@@PBDI1PAI@Z
+ ?filename_to_tablename@@YAIPBDPADI@Z
+ ?strconvert@@YAIPAUcharset_info_st@@PBD0PADIPAI@Z
+ ?calculate_key_len@@YAIPAUst_table@@IPBEK@Z
+ ?sql_alloc@@YAPAXI@Z
+ ?localtime_to_TIME@@YAXPAUst_mysql_time@@PAUtm@@@Z
+ ?push_warning@@YAPAVMYSQL_ERROR@@PAVTHD@@W4enum_warning_level@1@IPBD@Z
+ ?push_warning_printf@@YAXPAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPBDZZ
+ ?drop_table@handler@@EAEXPBD@Z
+ ?column_bitmaps_signal@handler@@UAEXXZ
+ ?delete_table@handler@@MAEHPBD@Z
+ ?rename_table@handler@@MAEHPBD0@Z
+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
+ ?THR_THD@@3PAVTHD@@A
+ ?end_of_list@@3Ulist_node@@A
+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
+ ?mysql_bin_log@@3VMYSQL_BIN_LOG@@A
+ ?is_open@MYSQL_LOG@@QAE_NXZ
+ mysql_query_cache_invalidate4
+ thd_query
+ thd_sql_command
+ thd_get_xid
+ thd_slave_thread
+ thd_non_transactional_update
+ thd_mark_transaction_to_rollback
+ thd_security_context
+ thd_charset
+ thd_test_options
+ thd_ha_data
+ thd_killed
+ thd_tx_isolation
+ thd_tablespace_op
+ thd_sql_command
+ thd_memdup
+ thd_make_lex_string
+ thd_in_lock_tables
+ thd_binlog_format
+ _my_hash_init
+ my_hash_free
+ my_tmpdir
+ check_if_legal_filename
+ my_filename
+ my_sync_dir_by_file
+ alloc_root
+ thr_lock_data_init
+ thr_lock_init
+ thr_lock_delete
+ my_multi_malloc
+ get_charset
+ unpack_filename
+ my_hash_insert
+ my_hash_search
+ my_hash_delete
+ mysql_bin_log_file_pos
+ mysql_bin_log_file_name
+ mysqld_embedded
+ my_thread_name
+ my_malloc
+ my_no_flags_free
+ _sanity
+ _mymalloc
+ _myfree
+ _my_strdup
+ _my_thread_var
+ my_error
+ pthread_cond_init
+ pthread_cond_signal
+ pthread_cond_wait
+ pthread_cond_destroy
+ localtime_r
+ my_strdup
diff -Nur ../old/sql/mysqld_x64.def.orig ./sql/mysqld_x64.def
--- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00
+++ sql/mysqld_x64.def 2008-10-31 02:22:04 -05:00
@@ -0,0 +1,99 @@
+EXPORTS
+ ?use_hidden_primary_key@handler@@UEAAXXZ
+ ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
+ ?read_first_row@handler@@UEAAHPEAEI@Z
+ ?read_range_next@handler@@UEAAHXZ
+ ?read_range_first@handler@@UEAAHPEBUst_key_range@@0_N1@Z
+ ?read_multi_range_first@handler@@UEAAHPEAPEAUst_key_multi_range@@PEAU2@I_NPEAUst_handler_buffer@@@Z
+ ?read_multi_range_next@handler@@UEAAHPEAPEAUst_key_multi_range@@@Z
+ ?index_read_idx_map@handler@@UEAAHPEAEIPEBEKW4ha_rkey_function@@@Z
+ ?print_error@handler@@UEAAXHH@Z
+ ?clone@handler@@UEAAPEAV1@PEAUst_mem_root@@@Z
+ ?get_auto_increment@handler@@UEAAX_K00PEA_K1@Z
+ ?index_next_same@handler@@UEAAHPEAEPEBEI@Z
+ ?get_error_message@handler@@UEAA_NHPEAVString@@@Z
+ ?ha_thd@handler@@IEBAPEAVTHD@@XZ
+ ?update_auto_increment@handler@@QEAAHXZ
+ ?ha_statistic_increment@handler@@IEBAXPEQsystem_status_var@@K@Z
+ ?trans_register_ha@@YAXPEAVTHD@@_NPEAUhandlerton@@@Z
+ ?cmp@Field_blob@@QEAAHPEBEI0I@Z
+ ?set_time@Field_timestamp@@QEAAXXZ
+ ?sql_print_error@@YAXPEBDZZ
+ ?sql_print_warning@@YAXPEBDZZ
+ ?check_global_access@@YA_NPEAVTHD@@K@Z
+ ?schema_table_store_record@@YA_NPEAVTHD@@PEAUst_table@@@Z
+ ?get_quote_char_for_identifier@@YAHPEAVTHD@@PEBDI@Z
+ ?copy@String@@QEAA_NXZ
+ ?copy@String@@QEAA_NAEBV1@@Z
+ ?copy@String@@QEAA_NPEBDIPEAUcharset_info_st@@@Z
+ ?copy_and_convert@@YAIPEADIPEAUcharset_info_st@@PEBDI1PEAI@Z
+ ?filename_to_tablename@@YAIPEBDPEADI@Z
+ ?strconvert@@YAIPEAUcharset_info_st@@PEBD0PEADIPEAI@Z
+ ?calculate_key_len@@YAIPEAUst_table@@IPEBEK@Z
+ ?sql_alloc@@YAPEAX_K@Z
+ ?localtime_to_TIME@@YAXPEAUst_mysql_time@@PEAUtm@@@Z
+ ?push_warning@@YAPEAVMYSQL_ERROR@@PEAVTHD@@W4enum_warning_level@1@IPEBD@Z
+ ?push_warning_printf@@YAXPEAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPEBDZZ
+ ?drop_table@handler@@EEAAXPEBD@Z
+ ?column_bitmaps_signal@handler@@UEAAXXZ
+ ?delete_table@handler@@MEAAHPEBD@Z
+ ?rename_table@handler@@MEAAHPEBD0@Z
+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
+ ?THR_THD@@3PEAVTHD@@EA
+ ?end_of_list@@3Ulist_node@@A
+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
+ ?mysql_bin_log@@3VMYSQL_BIN_LOG@@A
+ ?is_open@MYSQL_LOG@@QEAA_NXZ
+ mysql_query_cache_invalidate4
+ thd_query
+ thd_sql_command
+ thd_get_xid
+ thd_slave_thread
+ thd_non_transactional_update
+ thd_mark_transaction_to_rollback
+ thd_security_context
+ thd_charset
+ thd_test_options
+ thd_ha_data
+ thd_killed
+ thd_tx_isolation
+ thd_tablespace_op
+ thd_sql_command
+ thd_memdup
+ thd_make_lex_string
+ thd_in_lock_tables
+ thd_binlog_format
+ _my_hash_init
+ my_hash_free
+ my_tmpdir
+ check_if_legal_filename
+ my_filename
+ my_sync_dir_by_file
+ alloc_root
+ thr_lock_data_init
+ thr_lock_init
+ thr_lock_delete
+ my_multi_malloc
+ get_charset
+ unpack_filename
+ my_hash_insert
+ my_hash_search
+ my_hash_delete
+ mysql_bin_log_file_pos
+ mysql_bin_log_file_name
+ mysqld_embedded
+ my_thread_name
+ my_malloc
+ my_no_flags_free
+ _sanity
+ _mymalloc
+ _myfree
+ _my_strdup
+ _my_thread_var
+ my_error
+ pthread_cond_init
+ pthread_cond_signal
+ pthread_cond_wait
+ pthread_cond_destroy
+ localtime_r
+ my_strdup
diff -Nur win/configure.js.orig win/configure.js
--- win/configure.js.orig 2008-09-26 21:18:37 -05:00
+++ win/configure.js 2008-10-01 11:21:27 -05:00
@@ -49,6 +49,7 @@
case "CYBOZU":
case "EMBED_MANIFESTS":
case "WITH_EMBEDDED_SERVER":
+ case "INNODB_DYNAMIC_PLUGIN":
configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
break;
case "MYSQL_SERVER_SUFFIX":
diff -Nur win/build-vs71.bat.orig win/build-vs71.bat
--- win/build-vs71.bat.orig 2008-08-20 10:21:59 -05:00
+++ win/build-vs71.bat 2008-10-27 10:52:38 -05:00
@@ -15,8 +15,10 @@
REM along with this program; if not, write to the Free Software
REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
+
if exist cmakecache.txt del cmakecache.txt
copy win\vs71cache.txt cmakecache.txt
-cmake -G "Visual Studio 7 .NET 2003"
+cmake -G "Visual Studio 7 .NET 2003" -DCMAKE_BUILD_TYPE=%1
copy cmakecache.txt win\vs71cache.txt
diff -Nur win/build-vs8.bat.orig win/build-vs8.bat
--- win/build-vs8.bat.orig 2008-08-20 10:21:59 -05:00
+++ win/build-vs8.bat 2008-10-27 10:52:31 -05:00
@@ -15,7 +15,9 @@
REM along with this program; if not, write to the Free Software
REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
+
if exist cmakecache.txt del cmakecache.txt
copy win\vs8cache.txt cmakecache.txt
-cmake -G "Visual Studio 8 2005"
+cmake -G "Visual Studio 8 2005" -DCMAKE_BUILD_TYPE=%1
copy cmakecache.txt win\vs8cache.txt
diff -Nur win/build-vs8_x64.bat.orig win/build-vs8_x64.bat
--- win/build-vs8_x64.bat.orig 2008-08-20 10:21:59 -05:00
+++ win/build-vs8_x64.bat 2008-10-27 10:53:11 -05:00
@@ -15,7 +15,9 @@
REM along with this program; if not, write to the Free Software
REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
+
if exist cmakecache.txt del cmakecache.txt
copy win\vs8cache.txt cmakecache.txt
-cmake -G "Visual Studio 8 2005 Win64"
+cmake -G "Visual Studio 8 2005 Win64" -DCMAKE_BUILD_TYPE=%1
copy cmakecache.txt win\vs8cache.txt
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment