From 890c52d889231c7854c52d7b649d2be24e509e69 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 10 Feb 2010 20:23:24 +0100 Subject: [PATCH 001/207] Add components to INSTALL, some eraly Wix support --- CMakeLists.txt | 20 ++-- client/CMakeLists.txt | 2 +- cmake/install_macros.cmake | 96 +++++++++++++++-- cmake/libutils.cmake | 7 +- cmake/mysql_add_executable.cmake | 13 ++- cmake/package_name.cmake | 5 +- cmake/plugin.cmake | 2 +- extra/CMakeLists.txt | 2 + include/CMakeLists.txt | 4 +- libmysql/CMakeLists.txt | 8 +- libmysqld/CMakeLists.txt | 5 +- mysql-test/CMakeLists.txt | 1 + mysql-test/lib/My/SafeProcess/CMakeLists.txt | 19 ++-- packaging/WiX/AdminBackground.jpg | Bin 0 -> 20557 bytes packaging/WiX/AdminHeader.jpg | Bin 0 -> 3469 bytes packaging/WiX/CMakeLists.txt | 28 +++++ packaging/WiX/create_fragments.cmake | 86 ++++++++++++++++ packaging/WiX/create_msi.cmake.in | 103 +++++++++++++++++++ packaging/WiX/mysql_server.wxs.in | 40 +++++++ scripts/CMakeLists.txt | 46 +++------ scripts/make_win_bin_dist | 2 +- sql/CMakeLists.txt | 2 +- sql/share/CMakeLists.txt | 6 +- support-files/CMakeLists.txt | 2 +- 24 files changed, 422 insertions(+), 77 deletions(-) create mode 100644 packaging/WiX/AdminBackground.jpg create mode 100644 packaging/WiX/AdminHeader.jpg create mode 100644 packaging/WiX/CMakeLists.txt create mode 100644 packaging/WiX/create_fragments.cmake create mode 100644 packaging/WiX/create_msi.cmake.in create mode 100644 packaging/WiX/mysql_server.wxs.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 369e03bf988..f1185e65028 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,14 +261,10 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc.in ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc) -# Packaging -IF(WIN32) - SET(CPACK_GENERATOR "ZIP") -ELSE() - SET(CPACK_GENERATOR "TGZ") -ENDIF() -INCLUDE(CPack) -INSTALL(FILES COPYING EXCEPTIONS-CLIENT README DESTINATION ${INSTALL_DOCREADMEDIR}) +INSTALL(FILES EXCEPTIONS-CLIENT DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT + Development) + +INSTALL(FILES COPYING README DESTINATION ${INSTALL_DOCREADMEDIR}) IF(UNIX) INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) ENDIF() @@ -276,3 +272,11 @@ ENDIF() SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR}) +# Packaging +IF(WIN32) + SET(CPACK_GENERATOR "ZIP") +ELSE() + SET(CPACK_GENERATOR "TGZ") +ENDIF() +ADD_SUBDIRECTORY(packaging/WiX) +INCLUDE(CPack) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index f4e223c9c72..d0bb8d43edd 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -33,7 +33,7 @@ IF(UNIX) TARGET_LINK_LIBRARIES(mysql ${READLINE_LIBRARY}) ENDIF(UNIX) -MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc) +MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqltest mysqlclient regex) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 8a201cbb026..5b20c1966be 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -40,10 +40,74 @@ MACRO (INSTALL_DEBUG_SYMBOLS targets) ENDIF() ENDMACRO() +# Installs manpage for given file (either script or executable) +# +FUNCTION(INSTALL_MANPAGE file) + IF(NOT UNIX) + RETURN() + ENDIF() + GET_FILENAME_COMPONENT(file_name "${file}" NAME) + SET(GLOB_EXPR + ${CMAKE_SOURCE_DIR}/man/*${file}man.1* + ${CMAKE_SOURCE_DIR}/man/*${file}man.8* + ${CMAKE_BINARY_DIR}/man/*${file}man.1* + ${CMAKE_BINARY_DIR}/man/*${file}man.8* + ) + IF(MYSQL_DOC_DIR) + SET(GLOB_EXPR + ${MYSQL_DOC_DIR}/man/*${file}man.1* + ${MYSQL_DOC_DIR}/man/*${file}man.8* + ${MYSQL_DOC_DIR}/man/*${file}.1* + ${MYSQL_DOC_DIR}/man/*${file}.8* + ${GLOB_EXPR} + ) + ENDIF() + + FILE(GLOB_RECURSE MANPAGES ${GLOB_EXPR}) + IF(MANPAGES) + LIST(GET MANPAGES 0 MANPAGE) + STRING(REPLACE "${file}man.1" "${file}.1" MANPAGE "${MANPAGE}") + STRING(REPLACE "${file}man.8" "${file}.8" MANPAGE "${MANPAGE}") + IF(MANPAGE MATCHES "${file}.1") + SET(SECTION man1) + ELSE() + SET(SECTION man8) + ENDIF() + INSTALL(FILES "${MANPAGE}" DESTINATION "${INSTALL_MANDIR}/${SECTION}") + ENDIF() +ENDFUNCTION() + +FUNCTION(INSTALL_SCRIPT) + CMAKE_PARSE_ARGUMENTS(ARG + "DESTINATION;COMPONENT" + "" + ${ARGN} + ) + + SET(script ${ARG_DEFAULT_ARGS}) + IF(NOT ARG_DESTINATION) + SET(ARG_DESTINATION ${INSTALL_BINDIR}) + ENDIF() + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ELSE() + SET(COMP) + ENDIF() + + INSTALL(FILES + ${script} + DESTINATION ${ARG_DESTINATION} + PERMISSIONS OWNER_READ OWNER_WRITE + OWNER_EXECUTE GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE ${COMP} + ) + INSTALL_MANPAGE(${script}) +ENDFUNCTION() + # Install symbolic link to CMake target. # the link is created in the same directory as target # and extension will be the same as for target file. -MACRO(INSTALL_SYMLINK linkbasename target destination) +MACRO(INSTALL_SYMLINK linkbasename target destination component) IF(UNIX) GET_TARGET_PROPERTY(location ${target} LOCATION) GET_FILENAME_COMPONENT(path ${location} PATH) @@ -69,7 +133,12 @@ IF(UNIX) STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" output ${output}) ENDIF() - INSTALL(FILES ${output} DESTINATION ${destination}) + IF(component) + SET(COMP COMPONENT ${component}) + ELSE() + SET(COMP) + ENDIF() + INSTALL(FILES ${output} DESTINATION ${destination} ${COMP}) ENDIF() ENDMACRO() @@ -129,13 +198,11 @@ ENDMACRO() # Installs targets, also installs pdbs on Windows. # -# More stuff can be added later, e.g signing -# or pre-link custom targets (one example is creating -# version resource for windows executables) +# FUNCTION(MYSQL_INSTALL_TARGETS) CMAKE_PARSE_ARGUMENTS(ARG - "DESTINATION" + "DESTINATION;COMPONENT" "" ${ARGN} ) @@ -147,15 +214,24 @@ FUNCTION(MYSQL_INSTALL_TARGETS) MESSAGE(FATAL_ERROR "Need DESTINATION parameter for MYSQL_INSTALL_TARGETS") ENDIF() - # If signing is required, sign executables before installing + FOREACH(target ${TARGETS}) - IF(SIGNCODE AND SIGNCODE_ENABLED) + # If signing is required, sign executables before installing + IF(SIGNCODE AND SIGNCODE_ENABLED) SIGN_TARGET(${target}) ENDIF() + # For Windows, add version info to executables ADD_VERSION_INFO(${target}) + # Install man pages on Unix + IF(UNIX) + GET_TARGET_PROPERTY(target_location ${target} LOCATION) + INSTALL_MANPAGE(${target_location}) + ENDIF() ENDFOREACH() - - INSTALL(TARGETS ${TARGETS} DESTINATION ${ARG_DESTINATION}) + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ENDIF() + INSTALL(TARGETS ${TARGETS} DESTINATION ${ARG_DESTINATION} ${COMP}) SET(INSTALL_LOCATION ${ARG_DESTINATION} ) INSTALL_DEBUG_SYMBOLS("${TARGETS}") SET(INSTALL_LOCATION) diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index 2263b146ed6..ba63df71428 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -214,7 +214,7 @@ ENDMACRO() #) MACRO(MERGE_LIBRARIES) CMAKE_PARSE_ARGUMENTS(ARG - "EXPORTS;OUTPUT_NAME" + "EXPORTS;OUTPUT_NAME;COMPONENT" "STATIC;SHARED;MODULE;NOINSTALL" ${ARGN} ) @@ -259,7 +259,10 @@ MACRO(MERGE_LIBRARIES) MESSAGE(FATAL_ERROR "Unknown library type") ENDIF() IF(NOT ARG_NOINSTALL) - MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}") + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ENDIF() + MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP}) ENDIF() SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "") ENDMACRO() diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index 2157d03e6d1..86301c2eec8 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -29,7 +29,7 @@ INCLUDE(cmake_parse_arguments) FUNCTION (MYSQL_ADD_EXECUTABLE) # Pass-through arguments for ADD_EXECUTABLE CMAKE_PARSE_ARGUMENTS(ARG - "WIN32;MACOSX_BUNDLE;EXCLUDE_FROM_ALL;DESTINATION" + "WIN32;MACOSX_BUNDLE;EXCLUDE_FROM_ALL;DESTINATION;COMPONENT" "" ${ARGN} ) @@ -43,7 +43,14 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) IF(NOT ARG_EXCLUDE_FROM_ALL) IF(NOT ARG_DESTINATION) SET(ARG_DESTINATION ${INSTALL_BINDIR}) + ENDIF() + IF(ARG_COMPONENT) + SET(COMP COMPONENT ${ARG_COMPONENT}) + ELSEIF(MYSQL_INSTALL_COMPONENT) + SET(COMP COMPONENT ${MYSQL_INSTALL_COMPONENT}) + ELSE() + SET(COMP COMPONENT Client) ENDIF() - MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION}) + MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP}) ENDIF() -ENDFUNCTION() \ No newline at end of file +ENDFUNCTION() diff --git a/cmake/package_name.cmake b/cmake/package_name.cmake index d2998cfd795..6e6fe89e8b3 100644 --- a/cmake/package_name.cmake +++ b/cmake/package_name.cmake @@ -15,6 +15,8 @@ # Produce meaningful package name for the binary package # The logic is rather involved with special cases for different OSes +INCLUDE(CheckTypeSize) +CHECK_TYPE_SIZE("void *" SIZEOF_VOIDP) MACRO(GET_PACKAGE_FILE_NAME Var) IF(NOT VERSION) MESSAGE(FATAL_ERROR @@ -24,7 +26,8 @@ IF(NOT VERSION) SET(NEED_DASH_BETWEEN_PLATFORM_AND_MACHINE 1) SET(DEFAULT_PLATFORM ${CMAKE_SYSTEM_NAME}) SET(DEFAULT_MACHINE ${CMAKE_SYSTEM_PROCESSOR}) - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + MESSAGE("SIZEOF_VOIDP=${SIZEOF_VOIDP}") + IF(SIZEOF_VOIDP EQUAL 8) SET(64BIT 1) ENDIF() diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index d6411641192..585883a7ca3 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -168,7 +168,7 @@ MACRO(MYSQL_ADD_PLUGIN) SET_TARGET_PROPERTIES(${target} PROPERTIES OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}") # Install dynamic library - MYSQL_INSTALL_TARGETS(${target} DESTINATION ${INSTALL_PLUGINDIR}) + MYSQL_INSTALL_TARGETS(${target} DESTINATION ${INSTALL_PLUGINDIR} COMPONENT Server) ENDIF() ENDMACRO() diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 479fb8cbd71..ee575685655 100755 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -24,6 +24,8 @@ ${CMAKE_SOURCE_DIR}/storage/ndb/include/ndbapi ${CMAKE_SOURCE_DIR}/storage/ndb/include/portlib ${CMAKE_SOURCE_DIR}/storage/ndb/include/mgmapi) +# Default install component for the files is Server here +SET(MYSQL_INSTALL_COMPONENT Server) IF(NOT CMAKE_CROSSCOMPILING) ADD_EXECUTABLE(comp_err comp_err.c) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index e2ef01b3b4c..c3922231047 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -57,7 +57,7 @@ SET(HEADERS ${HEADERS_GEN_CONFIGURE} ) -INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR}) -INSTALL(DIRECTORY mysql/ DESTINATION ${INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") +INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT Development) +INSTALL(DIRECTORY mysql/ DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT Development FILES_MATCHING PATTERN "*.h" ) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index acdff87f4a0..2206f74c528 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -152,13 +152,13 @@ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES}) # Merge several convenience libraries into one big mysqlclient # and link them together into shared library. -MERGE_LIBRARIES(mysqlclient STATIC ${LIBS}) +MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development) IF(UNIX) - INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r mysqlclient ${INSTALL_LIBDIR}) + INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r mysqlclient ${INSTALL_LIBDIR} COMPONENT SharedLibraries) ENDIF() IF(NOT DISABLE_SHARED) - MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}) + MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS} COMPONENT SharedLibraries) IF(UNIX) # Name of shared library is mysqlclient on Unix SET_TARGET_PROPERTIES(libmysql PROPERTIES @@ -177,6 +177,6 @@ IF(NOT DISABLE_SHARED) #(mysqlclient in this case) SET_TARGET_PROPERTIES(mysqlclient PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1) - INSTALL_SYMLINK(${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r libmysql ${INSTALL_LIBDIR}) + INSTALL_SYMLINK(${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r libmysql ${INSTALL_LIBDIR} SharedLibraries) ENDIF() ENDIF() diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 5c83db5f87c..b02510bda46 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -123,8 +123,9 @@ FOREACH(LIB ${LIBS}) ENDFOREACH() MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS} - OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME}) + OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded) IF(MSVC AND NOT DISABLE_SHARED) - MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}) + MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS} + COMPONENT Embedded) ENDIF() diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt index 75e7502751c..c00d5153d3e 100644 --- a/mysql-test/CMakeLists.txt +++ b/mysql-test/CMakeLists.txt @@ -16,6 +16,7 @@ INSTALL( DIRECTORY . DESTINATION ${INSTALL_MYSQLTESTDIR} + COMPONENT Test PATTERN "var/" EXCLUDE PATTERN "lib/My/SafeProcess" EXCLUDE PATTERN "CPack" EXCLUDE diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt index ec2a13b910c..f133528a44b 100644 --- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt +++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt @@ -13,15 +13,18 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +SET(INSTALL_ARGS + DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" + COMPONENT Test +) + IF (WIN32) - ADD_EXECUTABLE(my_safe_process safe_process_win.cc) - ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc) + MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS}) + MYSQL_ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc ${INSTALL_ARGS}) ELSE() - ADD_EXECUTABLE(my_safe_process safe_process.cc) + MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS}) ENDIF() -INSTALL(TARGETS my_safe_process DESTINATION "mysql-test/lib/My/SafeProcess") -IF(WIN32) - INSTALL(TARGETS my_safe_kill DESTINATION "mysql-test/lib/My/SafeProcess") -ENDIF() -INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess") + +INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" +COMPONENT Test) diff --git a/packaging/WiX/AdminBackground.jpg b/packaging/WiX/AdminBackground.jpg new file mode 100644 index 0000000000000000000000000000000000000000..847dc6cdbede91dbbd4049492de464d095585e08 GIT binary patch literal 20557 zcmbrl2Ut_vwl<90UeJRyrFjGd4Fp7*^sQ2)O9>GIMyXOlhe+QWHwZyMK)S#-^w6Xv zfgoWkgkFTuk`N-D5JD$(_~SkI|GsnYf4=*9??3ZAN!FTc&h@T2-ZAD_bB=L5cKn^= zZw9*hx*R8d;oxv&e>jepIJmR}9NdFAPH>#!;NW<|KDEqo`GKRCy%UGyU+gm{jwu{} zaQyPW%1QRWlc(6QKe2K01Q*9ITqjO)oj7jg z7+}NxrbNiZF-oW!oAFIDaI`IwoCOi10 z5XJegtxn26vaodYe?Mg9{92&^6p%{bI>GMs1p66Joa$AQU*=8?(BK^}#*ny-&6_|DpkiSwo?@>?F0IWDoA{=#*Vi$jZ} z6c;3Hy*m}1`|HQzceh<TxQ*S`cectvd3;@fp7cefxPp4EUHia+=wn-Y1r#=A^ec;UaUF874k z!K1K#np6GvN2Y)O{~QE>w;d(jcbgX|TE`quiRy-16+2Qk4b5rN~>iLr`t-_6FL5FkAL261WBAQm@;qd0jEKOji)H0B%m3PGTQZT6U!*5HSOA?5;13Vo z9pUP#3q0mX^-9y?6JgM+e)mf1ASWnbz9h(40~s1u(I6iJU)tlm-`c|tb>DNZ_xe2pTAT4-`wSvCTK#_Y%VZ!C0 zux4{ItF3cC=sm9L!gNl(Y_K8FFq8q^y1`27V&2x?*rqA;nlHHE}R;>PS}pK>#MVGS_DR*2D3a zlWuqvzj94cX8j~05deYa2cc2+^{EQ7RZm3IWfE^ zrp9bTPI{_EV)-WE7lm1tYiJ9zYJ-ddpIV_CfB@h9@&)`cM-Qpui$_m?`tbP-Z)(^v zhZG;BICLxAq+ug)Q!o0Jmh;*zamAz-;SG3K>n^qPNh??vm7((ft*w9NEFz@u;8x2i zV+gpc*-U}z1)dsjfCCBnh?VB5)kRwbuo?*Zm|9+`H$3!}R4V57LgccxuVPn|kL3pa zcMFv}0k_APUzDwFn6F@NhS{D2mX>C{r+7L=HT4C_IbFlf=M%1NLB&R_v2PsOvM4)@ zyW{ZFHHLL}LqESoAkS7_4!@0Pm$Y1nn~QnT4!>X(8gWm_D`*V3Qb#l(O>_cW!tZHh zpaP3^kpQGj#M4eV4}P+CwvEa>>2ojy&q~8&JtJodyzd&3xe7ox3DiF?OZ=3C_;6b_ zK}I8~Y2A~vRDP+pkero9_biEm1Yk`@ItAn=fFU>Hp5@YZ?re*AxjT0*1oao?UU3t3 zC=wc;gBsT`=`J)OI~WyjKYtL*zOkBEr6>aZhsX zr8+UG@A@v;GoG~t55F;n>e)3Uh@;yx&VIik_l)(?G1n_UWVlkc`rXBxA zzm_s$h1a)PU|q`|hw^nwDn_L@-f^>YB!H zQzlmB-UyMuWf|KGTBtPTvD)1aPsa2b`G4JzK`d-LmpZrW0a3#`URfUjjz#upqUiHD z1nPV2l9BhrTN?!bu6Ev9r)tl=d$?l6JdeG5yo^$G`gi+4r!&;w8Ba>ShG zOEYi3Y5Q$}Jh>j}zj1FeBd+ZBUI}i=kMH9SW@5T5KNq7GGL4Xsq6n3dq+@b#cZ^Pe zTB>a2)+J5cMO{H4oCg*nucsL_9hd1+4!^ZjlAQdwaHJVB_iv zH##+;g+`A|J&rkmV?*kCKV~@3)bEM(n$Yl)fWMDIN`8U~XXm6$#fs~NZ-98EOIa;mO+H>~} z(a;B3p%WnNsQ8i=`y#2Th0X-2_tpwdRNyICV<A!(9;tUAoNPoG0x>p}l+{p+a+S%abfCO`pl?;^uDBVG z`sLl7G9n}TqqA00N#m6{YUA*ZqC~aOknbx1ms_`-URv&h_5a|mC1f5gpJ5Gcm`5Ne zS~-D=H@Lze;Wr=!J5qb0dHg8hhl+D^KOy!LyV=AJI@;S!Q);OaN#2gl9JJZJ!yG`p z%6IZBO0w9y8(3)~KN+8*`AB?q8W+q8KGcu+1GNC7c=qj1?xGy4LPrgB8?Mm>l98I4 zOZ;d%K{GkajlVObvn#W_idylIEQ&Oy(Y`Ts8O!9{$0+BZ-911{@NO|dJI`>=l0v^E zPfWaAax-LU7z}H&VLe>4Pos@Q<5mz7TN(IwePV zyOE}Pja=6H?UAB(LPA>Z8CCrv`0Hy!gg(%-3{eTm`u3}YK-ZYc1rW8f1Cj^_X{riF z8P|F#g6f7=Q7u3Nhe$*D?AJ-Ws_57^rg6NhpNR|Q?YuZCps985y?I=k5drU3tuSEA zTSEI#!dznxhu`SZ&%mhOydbel&r=h9H%_idR*Q1HSNlEp&WvOH(N?c7;M$yY&e|mm zHJMuN-=1b(*+Wy#baSYlSWI)vZwBJk6xUg`WLTpHAzo@CD2aPuVvhe_gLUAiar$_CMX^I_l_}3aQdN9-v5Ikj`iQ7) zceb5Tnw{YEP`uQO1hx3kC)k>^k5hTdS&yC!Wr-hioLF$^6jJU9EOLs;oQfy%ZZxR| ziMX}==UL0Yc-s$)sm5-IZRWgwjLEb8h|oYZqS)wI7zODVEJ|0d6!QHlHeNnG=ZkBFv zMr?oyLj~HZ$`Uhc-D|y{Z7t+&24fp%*Z&Uk`HBb%E;6t~8+*of4dX}k^i{FQ1-Zmr z?e;OIg4;|1_4H?JDGe?VSOxF#mlo-~fIH#`*7na>va7`w%vZ?djTWU|hfqn>Ehm`pEl1c_ z)q01_*!S^zlI!o&J+hR_G|KFQY2fae(6Z4BDH|iLv|$Lo(VGl}yH_9$-2C%%qo7af z7CQ!#+d4%33hbq_$Lr-!gFs3mU{s5zreKk%`{3a2(Q8n+YiEK?wyPjcJ$uOA=YVQ7 zs9EFcl9^F$<)YH>d2zK0ZuuoNK1KLWt)E^$L7r*VRBk)5<#eIyEeq!aJ>vI2e_(d= zibbt#GJpMaoM}RchTsj|Bt#XD0^93hJ3nk6=v}Fv-Z2L}B*eWTN2?W<*VmX;9HUv$ zG=bG#b@|r07M!D?$eQ{I4xQM=4|dQMy~*nCuHnwzrbOQ2sxm#v>KnZGidVlExl57~ zcDFPar7Q2R@8#OUIzsYex25;rxZ#qd++3lLK%5?`tDPrj5bD~@fr-i8 zPF3zc2{eCu%c`jwM`?{i>jx_qtpkz+vdR42ce zcGc!u%Wx|9h!s<@0#%x(Uz}#MI4-mcvYlmmFugz^=r11b^42_Y7(L$``(EiZ`G7Ho zJOw_L|9OSL#Q0%GNNQJmx}GY7vZAGU@ru5!opu%$LS2=<4QA!cq2Q`WKvarZF0M{N4>;zV}!!Sb-ch}|j?~@*Y>u;lG5y7$7hV*(C3ap>& z_*FkknlU$37=rlsnDn8-3P1HnZGx@&dTXD?ugP08>4^=dVGq1D2Pem1+&0^V#)J4> z`N25YFj2P_ldG_A@McJtrHmG;aFa-e12$J}fk6>>n=RzIVRwkTT2i3-4=H?+qAnOCNT-BNn?e4Eo!+YD+5nwi8N?n?uyt#MGL1p#NQ+vUAhlU|do>AXdKC(@x zs?8JSpCCQQmA>et0o0U2m{mq{{#H|y1wT^9`f7;4#6rQ5@~3SliiB#ZX4RK0#{Fuz zCafCk0T({zK$q_$gBCDbWQMU$0IJB(A^HA%lGw6dQ>89arE|RA-$?(uFU|8}W$i@F zSP7B7HZyGPY(uE^*CwJVcKM%J_?Ft17v#W~(jy&Vvj`qgXw?@k$1FVnUJoS+)&Low zRYD$&`al)a?FSdCT|MIDAbjnV2*}Ib(6@^ElMc%xs)oZD91$u~cq>#U+R-FI+t=R@ z+}ZoA1aCOB<*Z+`fKzS}u~nMEz#9F_jCHc6(Upd-jkTvi(BaWjMxtf$>OzE7J!GiS znhpzl8nP6`?1ec*7%5)bGu#|qr8XjiDe(==FU4`0a^220F_|Y*yW(}xpgzzSE-rPD zk>%s^o6OA4T9QguiW}`t)?r?UWsNz+2^G($Y+IT||1-qgBquRmJf8nbSf8`-1*)@t zTz+(5yZL_VR7DCwq-WFA05apIb}RM$Xs}~(-9Q6_*S>+y^LT4JqjbDvWK(BVra|&< zqb#2~*2=-d=x`Aq)HQvBb4Qw1W3S1K$vgZLCZM$o`|`LxVnD^|P~d(8en0q|!k&iq zk>hS)u+E%uw(%;c*Rpi7SU_^Vp}>$X^+DCP8vkyyIZxWBh-c_>${5{QH-g({W%h30 z{nYrh-irL^mSaKOenj6(o0dy>rj1*+Mv)_-qoXYCj)X62dPP)+JgjZR)o=P0utmzh zM5x6`T=jVow>+J*R-;}zF&l=ghLkOXl2xC=h6abaO$~-iOF~}QH$iyh;2JBIMgk*6 zfF|xzXuH#Xp#*(0Hgmy83%)`*=8#?yoH%OEr;p4_q-G7y+rL-f0u*Z83$h=nl(pQ+ zt%PURz4X?V_V?}cE6=eC!iDDa$RsJD5dW9~5~9La=2+tmNm@%3myPAQs(yT7(*)+2 zOYm8%)M^OsM`>HvAsIn96}4ya?`1U z0!`?Jl}>gV0fu?v{;RDs*0UwPD3s1vQy0Wqq4TE|G;>@n7a5PiP@Q)xuuIY?>SFM185 zz9bM6K9ERU741Va)D09dK* zn|3P4eMaD?$n-z4Xznpww@umR=1p3^S6<*)!eR64ao3Lkh=!t1RJwug*sX@4hZ&)S zuP9{r67_1+P3Y>mQ9s-5@Bp>k{L|InCSJ1Qku9d;d~qP*+$4}=8sM=*aXk2PrLUX- zqFxe_RM{J-&nj|$wqq}FdiveYT-PqLlE(LR@eX;uUys+(Vo0uB2MlQ8&Xd$OB}lLN z+66*hFuo57v zH=>$F(@^Av`tA>E0IW}D9dl^Tp+i0sd6$6=pxvqaUfUt87Rxo>EW`PP&WujtW0J;U zQ%Rno=z4`gbOPH?5{fdA-Tu>=MOBH_sB8S8CDr}mg-yL1U$yik2_kRw3?#;XLPbvO zZVz@W$jIvvy#IvRNq=gn&nK6J;-s!vnO++Hv^G4bHp^+%htm@5O^sVe%-A~T8ws?- zWf9e2ba>UvTJaum5%rMDy_hHJnSaR%i%<;%&L=9TuDsq}g5*Z0x>p29+i0}BBnWOO zc=@WBB|M8yO3?P>rwjzEm1XODiWD6qNarlc;nfLgiQeAwhvKZgym3*(xxi)gw> z%f0W@YHdeZ&Xb+-PvBF1icDHlJ^Q$=;al_NIY1F$G!RvE=X?E~k{+D8j)NcRQn4CNM%c%sL;=1<8&gjRH$oI%I z5_j8%3v$LJzqf7qfe-Gb9f87gmBRKl{Jd5)+*L#%EQ-I~w&62`7d9&ab^bP^G>2rN zr^cru2Cwe*75#X%mRp|$bWzG(vM@v@@B7zie)=}p!2{KLz+^W1{SxA;)K8Z^gYMVZ z56SNT1D|G!(723v53BnLy*v4Pu*5M3Sok9{vQR)~20dQl=86@e<+#f7wJ#Elh6w!R zQORuE9NtUHYY=s-730C#7?vmXPL-o);}xKdQ*p?3PioqTm=_;d_H*218J~u2dys5; zWN!7`0R!&e4xU*|Z+aFjlW^FdEOpDdZ#>PN0jnO*bgU=ZUZt6hzw2Kg#8}2JPBc|A zzeFU3o*#95%eHib)dnTNmcVqyhWqXmg0lPOt>}T=HMYMCAKeJS?H`5| z(TvqI8yZA=>q!lZll36jF5Mxr>0QlrN2f<3v%`<~pP~?bh!JImR6|>$NY?%w1pf}2m<-k2n!L|;TsxT_dvR2z@o5CsKC0P_E z5;e5ANbR+Fh?Y}{&%ORqYMdnMTkK9QnOPjR_~b_o{cpf#dxCtH>x>@(i9pRnsrdDjB$9F*)S%Rc2J_iSFuj5jPMSJTb= za>!Kt4e@r^US^(KU7UTb0*yo@-dzsOYssqg3L9~q(#W!McIC38;$P})9pqizzJ==* zBd$7?CS89s*e2F|e?FMDo6tcjBpR`3{(8$4!r|Oj!7&FyCI=U=_Bx?MSW#E6)Z z;#_$LNcZ(T_dU+*i`X=pV$I*6HU)Q|Pj9jtZ&RbXhYD>zTM0mnKHG6=6{2L5RCBZ` z&cG3hqeUFX6X%IbYIGzxH*x8g%pbf?U2mK|a}IZqgke->5o<(6$I4l)gKBVV&SA_Q z29Wz+mbiYtTZ3(r?UweM?+z-vU3$1rD9LW{PdxeS8!rJpbK5j!Wpv2!UDXv}C;v3+ z^cp(x*Wzb&}xlK=V%Gjabx zei9zk@$%&i!0h{;V-l)enFq?lD|$OtSz-W3u6*K|Q)mrD?f#0|3oZ!;?3UT)UUu6> z7G2QAQOX+=dQ(^vHAFZ256a9x@~gvi#$-w_lV@>Ou(ENOhw(UI{I(l3LAcLWlK>`! zG>!MCIb-Ow7P#epEmcF9IB(FMA2)?zCN{4Z3sgjT;fOVpPNmV9TLkF?#AYQ*E#-UT}a8sUY2ZX2Eu#h@d75!>9zH4Ik z3kdJh!}>l%oYQ%^QP>Rrn7ONLjHWdXNT2T0=nle-d%U^nl+Ea%#o0mml z(ur;=0}TTzh&jNPTbXSsA_(xY*dEVtPLk(RsPZH;*O>tqmoUs)K?k^Vm&dw?u5FpV zP&LURse`bR(+gU)<%&I+S7PtIJIpx{A(YU=k)rh*{LfdZ+tA$ZO6)B$QlWin4$)xu zTk6-ihY4WaA-`cY2ki~tP3`+foYJ&pU<^fG4>Fr8J3BrqL@ny&H_~yYj_QTgV!IpB z;TUy{UGsCS^`x&h`I@!C=;T1>FRt4W#%9kN8cc`wOw0mPPG^+Ir?u*37k5qXRah>{ z+odtLjrwz{X>g!$(Xe7Dplf&79AKcNB9{hsh?K47;<8;z^4574ZRl-B;F8mo0#0Q; zOr-`%B}jfAr@_aR4_7HhHOjtr<)0ev+@3MAdYm1lt-)SE5r|Sl z*<(LobDVl@ZDI=7h@-n97(?DMS1y0g^cq1oq^MMQva`{enutA*UaE8tMg2=aaa5K+ zB`x7%x0q>^c+%j5dxtW~XEh@5cO+K!Q&>w|iXvgfalSr!CL>yUVnCZ&ey@R(A+n*k zT(WTO9^^}vUsd=7-7}YOFX)H%-g!*^?Ps*tH9x5d)cHeupA2+Z<`ae%Hmw@!kvo6h zPQ>a7+h9+bi@#^;3+3Lw`C8&ylkAzICEqu90_Si0q#B|E&n#4-e;t)-2BY`tD%;zy ziR;N%Wg#6hMKnEc7uMFY117Qpfxuz=?v=I)e4bi3Hu%%r#f#>g!!^K=)NA$bUu(=X z%+yCuW%5S+wtLVM9;ijiOf=<|TpwH6_S_&uoawz$5zONjy3Gr2mwmPw{c3`CIYTO` zY%2K3{R(JpF7L}+P*^Z5loyXK^t)T@qrKi!IsjOtaQiUkI%X{9H!|`Au%>BZ!{WZn zjY##pvBZ?TAg>6o2^C~kuNNilJRFn>cu^d`-cw!SuhDB=U}?mw@%Eui87P2d1aZ{1 zz__gLr_`x>JYCl%WmZv`U~j4UV-E8&qlh`jgJH#e=9)}m6utOkB$k<>81Jd00Q!Op#+x4*Izw=j6< z5sB9Yst>9v_~)2ag$RvATuc?*%GiAa#CxwnM3zQEFtx55I_a=Qa3y1f-v%zx*60zp zMeVfkN%8W$Xe@}LSN?6(P&`T1^=Y$@5kI7)C;&bFp5aVVN+n z_IC_ukXi?`x`=cgHt*FKoIKn5{+Q!#qNDe=#2xDBjnXlP-}x<2yFvGv%Qg<}U!tXR zjyaNJyI`Ld)|M=7?`c@~x;IV#-lt{O(eCGz9C=Hx^8r@WrqJs<&W4P32WyVx2wt&|z?Y2QcWd7w_5crXtuuJ<;bo1D#8jSL$9YVwx(egl%+XG&Qbpdl*t1 zWD?TOJX85(Fbm3efp$J>??R_3^0yoA^9zlM+M37bXx+Nf3>XaH?>C&QqOcgSeFuDQ zX1O1nx75t+?rM2Vd^tu;Xj@{vdv1v}S}6=LtXqz>F<2m4y>#4ls}Ean)^@AXF+Kf7 zoo56%v0!oT;%L|+9 zO7d8ov!vsQXp&Y17c?%G6y$8%pfJ)0ai$>e$jKQ~rK3QWsj@8%AYPN#&i64_=ggy$ zw}Z>`BO`IsKx65r;;(vYAvi&Dx5jn5!nJC`Xdw*p{-kj#GP76UbNTfNC3Oaq9gl6p$pnS##k1&7%5~ zx!jol^5cx*a1j}>Z04tz)!sJWb}_~Cj+ro=3OA}4IT?J<%lZ54`=cs~R^jLO>eCZg z93&#zVXTuTg5J23eg7vc>RJ9eUuA;^*pKB80hJ5y6?}Pb|GRblX9f!J9XNeWNRD3f z_&rq-V^AW)^G!d|VWudl23^UtwB?0FelG|!{v2o|u^_t}WWQYcbeVr1mf8Jecz`?? zI5NSv;}||Qy*Dq~F{FzE>IkNv%95Gg$;v3!W^dLyltUd!0k^(=S_JmOUcADFy|y2B zrB`Op4Lej8R7=ekRN-5U#TDWt&TUt3-L8lS3B;f>xO|_tr+o+{3{juP7JnF8_~cSB zTSF;rM2NalEl)HY+U&WEnW@rl+$2{f6GdwTHHTxjy@J%AjzXrB&j5n9o0`8GwkO!% z@$h(+y=ITlZq>8@;OkW`6}XgH>yyU~Ww=d&9#@Vwe8;qv&a>`@PUjA@RGv0Ja6vX} z<{qi3R}aVyYr(Q7&&o7k^2gZ4_6U0U5{c|3Rc?&VuFVh%W1AamQf0~bXjw9%QNL-j zJQ}W#cMYOu0t+dUm?X`xBrX4AjzL1AMVtiPnj!QFcfT-Nx0`#f=J9AlrBP}ZD!5} zH!5Zv(#Jxwt>N2nq}nm5rf+33}wu1F$CH+FBo9TnMbu zWpgw+F?$8uMNwB?o>@t>*?P~+_zBLPOvsX$1@oFJkmD{ z)ReC1OK?V1*Q(t?gVbt#FvcSo_3RbgL8_B(aSD+rbzLnJR>-6 zmRmwQxw&p(jTCn4F)gB# zP|rnw13>=v6QIrl{e6|P8n*sL_y26<{u|Yw!ZQR(jVc;iDE5lgiVjr%2dGcJvOhqz z1G3Nk45)i`#<>+2{z3Vlkj{Tn5_StSwLMoC=arcu7Kt@FA*;GaNs z;$fYy>>_dDUv&T9pvphB*3SQ{VrgRhT`on0yx+SNRkaOU-%Iz2w=y3k}-7sXoZltld z!lc>5^3&C38B;9Q`sJg3FIZL6M2}6C@5Jsg#|7Qji?me=y+Pxh)t^6uYX9*kR2Dl@ z>Aw;Kdpyi6Wc)v;H11lw!!WUFQuXVH7>XXGMrq?^DGG+h#J+F|u$WG5BBF-!r;~j4 z6~ElIHM^KCd0Cpz?*7zH7J+CT8;5ID@?^LN0f**?9c#vk2@F>yf+#H8wb}ES!>wAw zh;Rky8~x2=B=^ZAV`~`~scpa98*jMRMFpP`23+NT+?fw;^Spq6C8?V$Gw{5d`J$7H zdmy|sp|8kLC9UjiZAptidvW0Y6vm-4dlKLw0~!;0PsYHcHl$?umebX4Y5SUw5&<$7 z%Z$~mMMY(Gd_}P$8Sl1K)p5Z-ZJkuLsnAc=0~^AcmCZ7XJznud5q)yfW(?Z&KhQyQ zLdnbP=E~492c^+{1>VwDOsCK^qjiX~y(#fBek03CHWr*kQ|W|95rxyJuL< zkQog1%={Cv0S@OeNylBc--c?SE8XmF7eMdN7OsFy+uT8SrGo+=XU}s^F!$A)vo-ZC zHa=K*-XF3SnUHl;gB|RL6p;&5F|;b82dt%b`xF<9UT9Fpy!5T+aV1|D&dJ{tVM0hs zu0Bj~aUVb-mN(&zf4IMrp2qBlRVH-CZc0$wlYMB2g-M#+o>fl}1D9)qex^TZjP1B* zF+rcrcJ*RdU45#&RlMX*pK*IW(ly6o5N67QckJV>rkn>ED_@rS(T*z^c(}ga=z4iD z3M$g~m>TMp*rs-?(#J~@x~R+xzq;N8)W}a+`W8yyglRSE)ZgajF<6u~yBo*}N>*2W zj*7`pDeo*BwC2ki_Z8yo|~HTT)XPSk)k>jd&( zb48PJ=T7-`{i3=z3KZUTm zfvWIs{avFHhma63vXM>xG<7WKT8%dp)6KFIX%@}SdFk07H|Ib~zk&AH_DYlrovPT- z>l_b3V|%%;UxmKRzU3sv-|%--ycHnB3|x6BHNnkcD(CTDuR49hE+JTQdBJFwTtDKv z)O#aG#Fd_?`j99FQu_DU|AA@AYB<9^5@57@5Lw5G)D#INHow~vZxjWzBB1-Dp*;Yu7nH#et#M`fW} zPHrJKa_6RB36WaTpD5g<1Tk5(av2;|$m&+eG9pzibcTiOlyWUZrBV1Po=gfxW578R z01SzYzOZ-R%%@FdEYVH2+Cqp|J^dpnU3jc2TZYE1!^%@^SfeCUN41TDtf}(C)-Oxc z9rKn#a^Tp@Lsi`{8J(etP^ZL3p@7Q-8B4BR`(d}Ha?_}{?S$EhDt7vlq35gZau(Yx zUP4!#J-XZ|krvjIOJy&Y<#<)*n31t$r&|!V7sI@`KpD zvTS145`&?l(myk-Vu$LnypR4>?vBDbo7(JE-+z(Xa|bFF96{TU^8t^sa&#)jAsrCZ zC=T9q%P}#bh-R%vCXZTFbM>aCzKu_?+9`7Jt0GkDbnnckx&SBSqL1_xTGTH|2ZtQq6D|r`-OXnISA5l zLe+Hc#E^IgiKtCK+c}5vR-LHQPJwJO$@y0EWwK}Eu#^U$V4by0%aI*X-tj0tus1gh z!?IH4F3M#`rt;{i$G0|0rNTB91iy~nGGuaBfRgEk>UHS%7AR5a_Zwg58c_8Tx9ic~ z>`4EIR_TxwV|gW$!!^7l{%--}*vptPth80Oy}hfPM#?$78eDp{F+WW(el)v&L^HK6 zH7D7#+sO5pL+w(z?yb(4JZ_;_**7lm-(};@R3YVPq-DDU&8Sf8vf2G2KYM!B5Ei3l zqNcH2u#NQ^v7D9b}I$q;$IsabZxO$SJ0Ks32gIH-w#e~rT-fzMl`gx_z#qVy$r=czx{-& zoyjgv$||XQC`9UqaQ|L`K`^J%FW|BdQuJKvAU7S++@Ux*=Lm8q56oTh8Ul3?HuHri z@6TCMK)R8&arPWYee}cgSqw$RT|RIjeqVV@PDpssFtK5F)J>yWIIL*bDZX}OZ24_` zifT^ZlKzyx`Qy=Qp_0)69XFJHju}{@Idyhm(5s+zv*pH}d0e>D)Apx02`YUWW=l{*P}JnLj>Dd$$;<@UWC-0+lOxuFee`4XI! zF1OY!{cYw07^-Y1C;>za2A9=H&5n`$HLs2?uC*D$;$S)B76$EhO5L`{9Ix=~^x(2* zTB~ajMN$!mVrc=6hZ#rWD=dlT%6|1@j*G!0^;E3#CiYr+(ug+0)~C~Qv7RIl*iotd z#b)~mF!gNRl*d)&Gwqt_!gqEOL`?h^Gq+GrY4s>SO{X>umU|}yVGIwtSwY>UB`_7u z&F^7~mUcc=B-@+|5Y;htm{=gM6xM%)l&`UE6_KW-GYU1ywy&PgjLExYQHQ@Ycbz$v zZBIUWKNvb-6ZAB1J8t@zV-HO`=D5PYXD@loQQ+HGo>zOLHRY&vbc-~fH~DzqB?xx; z*TNE~T#V`=k9!%ASZyt(ibQt{vcnOO&*!ExcBecJ@>*3jUAa}=8FF}KI}!Z_CZYv8 z_aVjN&y2S$b4mY|*!9E0M6yseX1ihn-|d2ENDUl=Dn3HlJ6x-9jE@fi)u@1ce1o`D zv=IIuh#EV03FB6+JtLxGj;#UxHemVH<>K^7tc*1_nqFY;u2wdD{)VZT0}7Gg?vY4=~en5a_!xYZzWDCu{ozwh}|MhZn>QOB*F>DC?8BKs!kBEX&TrWSO=UM{ggoi*+Ffmeh|R zM)hkMV!PeuWUf3ZdFRC%bWeMe-P|k)>RP$z>(nTIK+2WLTJcnsekwPWn8d|rGFHTF z0*;!BYM7UdVp>9i;M(TRXd3@8i z)0HvUH}a8(yCWN3tC*$cGKOE3NXVEL`KvIkS>Ph$XIzGy)qSK)*zG+d2PhB*4Ep%iTeyv7G(L?V6}bYtu;rl z%={vkA?r81B+oqOv8tq2U>?TvGtqR>G;iBc;FGln7Ldi)JP|JgKcn)AAb<*h-BP-p z3u{wU9^Zuxns6%S$cwx@a2c5)+i8q{RkRt;;p=H91g?;_-6}qlgh`lVVqgHAIpQWr@wUd@c&YrXa5#AZe_wiiuL=qyjU#?`qJ$;8&ghE zHq9DKP2H^MhxbKL8jChUtDihA`ege887XkKi`7B8IRsV%fqZo6-^%6=a8zCv#iM6L z3LP@J>=Pm19=1*4TkTbX1Eph0f)lZbYE*sLIm<^cQURM4i?4n5e#0+!8*h71Jj|Gj z7lLs?FU2#LlLou0%j{6I3mN`@HO(Cq_3~nXA&Vyf*k&K^Q+A3Gq$!Zm(>U4wC?q$gE#XlID%hbAdA#S z2H@q#5>%nhH9AV%!FGWnYEq>OKu%K08Iwy2H+H&B5xYasfNEvEQ`$XN>_B%lI%jt~ zY2Er73`38}1+<#%c@LJkF<=+TbDD^=iXA0$S5y^c8>=^Bt8;4JJLwu3Q)#U;2zKxl z+^^7&vfSO_0}UNnv3FNv7_a0JYkg)k#`1=@ZiK|NA9ILAuriM>HaEM|;+yvlw0I%{ z!HjY1!N)ZQ$cr@9+ zM_<8>64dlLyGhGgX_V#_ZIov~L#*hO>_n6{e`kAqTo>r{)J377})^zu`WMVjPAJERqeAzmt)= zTAX`1O7X4uDAIbCDhCcPqh3`Ms>~X8Cx$h|zGp(7A6Q2PYc^_0w-+Xc*EM1&VKmKt5)*2GzvFTx_~rz}! zwx~+=EK0`U8>T(?zz%X_X>3o=#rP-0C2?lrEojl|;ZjR^`hYVK`)QHF`sF>sdyjKCI-|rln zMpE|f@iEdizF&rM6_%@>ZX0jbEV@fYbmDH0d!+Tu z2iE#pOPS+%+|$RC%rZ6)oDcMuplZh)+gtUDd17X;l*B_L_*%Q;(*AU4fT^+8zLKA7 zxaal8#7$XjWQcM|5lrQev%#TA_r@2+%G^N$)%pO%#Kj!0uF~jRl2Pjv z)S8IL7>1;E&z&S+6IurSn?sJ47$HugJ3sOcg$vu$;!T(ut!OhkK3ej{f{PM_)+0UcuZk}%g;wo4eJ$@czseuN`);-&-Wjlm7M45>R zgppd*!nbh894`gW9&^~jjyaAwTnvxiF>dT1*&TCiP91a1VAuSr4wV`YFXdIkzq4f4 zDX9t|w3T6Rv$wHsQhw=6z+`5~e6Y?14F|t{u6|!h-(u4nVnZ7_z@6pB%ZB%i>qxKx zHP0-FjnSY)@H2hIP9CG|U@J+D;$pT^Doo#_RR<9gCnDY)$FQV5gkjApJ*08mW;xk7 zr^{N~v7(zLoLsYIJ2UrT3l1+CT95{Pud@pZDkeHXQj% zcGG4zAdYgwuk9R28~|NPug9z`$3i@CP}hlZPv)>oQ|K^?tt%NTS6RmR2spuie2k zXZ=KCk(*+?&-E=2g7PhTA#rYR)psDt8>JftINzPBJg&&!R+pkk2h9R1LS@6@%&?CM zeLcmE@2>K-Upj)cqf6{AXLX1M&F+Jvx%x8%4lJt+p{&+GFMc0ET}O z+~aJ;$ZA*lfGO+hjk;vNCV73@(-Q?FjoQ1;oSrHiGqV?AblC^s}QI;Nax{vPX$EVRr} zb}HtnHHpO0$_5Mj)7ug5X%Xs24wu}ajocdWKl+Lg?`i0?MR>`04OvoKn6MP+h*4`I zJ&)Saq~hyz+;YJRka-&lsZ9b&|?OZ(@;6EafF_X{njjZWRYkK}^ z6#AArlCI`~_KxMx(Q0`dhnn6rN^Y#2V$ZYkpB-$O=OQoin1lm1}1fel%FsXWM#_}zo`r9oM1*O8%B zUh9a1bHPhZ!LnTci6*750F1-}goa8gpHmA_@`%l;uw_ctf{&cm@3vA0Lx+wRqr*tj zm}IjHq^j0&NFsa(;yL@9_Q}5nhuaGE>rjJ@N=S8KGqiZZU0{+p$_JYwKMP!l6|1k( z^42t9YZ~+OYZ~estd)Cw-n*6MHI2I$SLNe{vQ!|R)cK7eN%NscdJkeSfQN`J$#S!u#n@_g3heDw< zP<@c~qE}Fa*K){yHEB(w{<``}YFEb_4&AfosKTJLKxkI`p~GC?gm0{+(^>K9#fyAR zF?KGS{84((X-eKXyYOSSDNRG(xh499hvSC-7n;&G6d`rB14q27)<5TUy%4d_54oGR Tra}LqcTbp?{S4JJ*M$E8j%h+9 literal 0 HcmV?d00001 diff --git a/packaging/WiX/AdminHeader.jpg b/packaging/WiX/AdminHeader.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e2e33d404f0d954ba6a852422d4f4721740e989 GIT binary patch literal 3469 zcmcguXH?T!7XOEif*KJ}imntHh9)EkLCQ!8C;VfXjWx$l;DU%ThNcXvPR4grTQz|X@0 z5FY^e?loX{1^}Cf_+Y{T5Fh{mz@G>ExA>2I zsI&-pZygZdm-7n$J|l<^%r9_K`>^0SFRaAnysGwvHOb0%uqNTxI`Bk+N@|fQRoo!anb0!t#IyvKnLs}{=SS3C-lD<#O z!b}qV+7dVrIiC^ni^Dw(IovvMI za&?Hllv5F}?D{@XgV(Nxl@C&@=mbdjV;lmJ#)4O8f8_a$a{^YjpFOCQwH1lgzh&Pf z)|ZBLD}g;q#|0#C^GDb2lF&T$5w;}MVJBB;vD4flhS4s8qJ6Zf_0fMYCSG!5cCf2u zR^BN$ly_T^JG(7rsx*0dden1yxUph+#fKcDEo zuR8LujxDyf5N)-x!j`lz8OBND$KBm*PEk*DY5028I|Hknaf6}?ziCD%@8Q|E6{>S& zSGJ|j+p5x@ymqi$_of0-p}0Owp7PAojB!8QaQ@b;LpPptN(;Q*zPaVY9uFOD8l*eZ zkcy5qLF;85wdjP13Iwi`sCGz8zc^58OFFi31tLlIvBMXA3Q@bpbk#;LWNcmxw@$jT zS$bdN{}3v6h4E0|hAnKYA|T<#>2?1XM~)KH2_>Ih&Qy}2{tlkm4)E_M>r{pU!({Y| z2g!wgSi%TvadIi7f66V=c&rX12bpe*u`JE@C=#!}OG+&HiJ*p(>@>T=O=3T-vGGq2QkQBZygSe?(i0PEI`D@N=`B}i>+E$`?G<-SxoHm1+3bUj-^k&xg0 z%Y!;h6QOYxmCxxaY;JD0o`@Pu>FDPuwBOk2VGw#z(42@Ttm&0PSC zt_p~w^?OuU*Ts?l*8Jn`yq{VpR@Dq+omR3>H&Nuel0PF16N7^+B??lNahD~*5Ah)@ zM#tBP%NeB2+qlus21YV&Z)%GP&oeU^pPR>~dD>;~+cGv~J95+=I?X#fZ7gG_qYR(} zzP-0B;Ynp!TDL=*l~w^Q@?#>mM|Z3LVadN5iZK#$xo2%ny*s5QBw8@JjiyWl$$Q$x zD;P_UBT`v5X=I74=Z;_zBr^W{O*y$Hdr9>WjHL++qTu5f^YhQ}d|1r&k{lZ?1WNTm zLVfxYG*V%3vq-bCASg#wot~b3-O){%{d5dBWO-gO`Qbynw2kqD*t%KcWjmuckF+e` z@)%pI1IV3Q86yl6xpjjlN;B2-ESYJ!Cl@ADP40OR2}5C>c>1M5xUL4bJIca2kXSvY z^}g}j5%_BTZ$Ffq-_IlDlH*5o_N z`Jo#HX!7G=ih0EM$KArLii_&hw4L$T$ml+jK^AmP!=)>OB^G5^f4eK3An&6?@l2_N ze!v%&c2%J%rnLbn?F}=5n5;4Lp(KR-WY%PsJd~1F=z~{%Hk%c};f@6+L|4uxd`K;` zm3%?Dab>0(g^8S`w@A?9s;Wpfl`Xx*p!Xy8VHi5hEayNU0>*+Zd4)@;CHMB7#ZLSZ z!bQFPky}J@teI83@!kBm)hd}8v|J@OiiR1aLM^)dF(||ZPN%lSsa?RXS4NtuaEhHU z>;c(eM7UE^``x(P5h+1>?wm{IaNUQ>udNTC^URZUCzg&^u#lSN9dpL9b?+ba`Y%dA zlEBl3G_Cd}Q8J~khf`y2j>QLkT1$5+f4SOKey%vT|5`k6-xRXAO5AUF8=2`7Ws$-9 z--cZ(;7orJ)TP1~k;{fUvqzKV%r z1Zq^fCeAdd4Dgup40U@8rFH}9kYMzBa2T;5#beMOobi=t@H|}tG_qaz9 zT4f%FfL8{@)m!Kz<=jZL2x>6Npgxe$2R@n*v7rOm39g;->&f=FyQ4GDO%L^+ed%>< zAEP6e=_E<=E{tavWOtPgNSja4)BU$O@vMWQxM%ZEjucKchs31V+zP+CSr<7zfAU9k z?||$Qw!$s+zQrPJIchAk&1xh`f7muPUNLtv`E_%^gLzv7Vw`2!(~(s6$@2sw{@uL4 z{~VQM#X#PVK5?Q|3x<1f|KsDZ{Sa2!89jgR&FsI^nZ!rQZJt?OObe&NM>ZmHJW{)^ zBO7_<$$YOyf)gxiV)13gphvd93HnK9ZV@4oOSU`lOgNYPsd094 zFw3}0m!SS`%k`-h$(BtFt@K>)sG82)Y%{h=@Asc>^K&;bX0?ug_HUbi*MtkXl1bO= zi*dkCx7g`-!nJiryUeu^HG>gk708K{2+Qv<6r+xah~SZ8+3=AhDJ3lVD7`olebda# zx#?UP1d@qxS+RRhueM*2@BANsUimumE!^h1y+=WZ?TwO*`MpNpwr-M|\n") + ELSE() + FILE(APPEND ${file} "\n") + ENDIF() + + FOREACH(f ${all_files}) + IF(NOT IS_DIRECTORY ${f}) + FILE(RELATIVE_PATH rel ${topdir} ${f}) + MAKE_WIX_IDENTIFIER("${rel}" id) + FILE(TO_NATIVE_PATH ${f} f_native) + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file_comp} " \n") + ENDIF() + ENDFOREACH() + FILE(APPEND ${file} "\n") + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${dir_root}) + ENDIF() + ENDFOREACH() +ENDFUNCTION() + +FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) + FILE(RELATIVE_PATH rel ${topdir} ${dir}) + IF(rel) + MAKE_WIX_IDENTIFIER("${rel}" id) + GET_FILENAME_COMPONENT(name ${dir} NAME) + FILE(APPEND ${file} "${prefix}\n") + ENDIF() + FILE(GLOB all_files ${dir}/*) + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ") + ENDIF() + ENDFOREACH() + IF(rel) + FILE(APPEND ${file} "\n") + ENDIF() +ENDFUNCTION() + + +GET_FILENAME_COMPONENT(abs . ABSOLUTE) +FOREACH(d ${DIRS}) + GET_FILENAME_COMPONENT(d ${d} ABSOLUTE) + GET_FILENAME_COMPONENT(d_name ${d} NAME) + FILE(WRITE + ${abs}/${d_name}.wxs "\n\n") + FILE(WRITE + ${abs}/${d_name}_component_group.wxs "\n\n\n") + TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs "${abs}/dirs") + FILE(APPEND ${abs}/${d_name}.wxs " \n") + FILE(APPEND ${abs}/${d_name}_component_group.wxs "\n\n") +ENDFOREACH() +FILE(WRITE directories.wxs "\n\n\n") +TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") +FILE(APPEND directories.wxs "\n\n\n") + diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in new file mode 100644 index 00000000000..13836d6d35f --- /dev/null +++ b/packaging/WiX/create_msi.cmake.in @@ -0,0 +1,103 @@ +SET(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@") +SET(CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") +SET(CANDLE_EXECUTABLE "@CANDLE_EXECUTABLE@") +SET(LIGHT_EXECUTABLE "@LIGHT_EXECUTABLE@") +SET(CMAKE_COMMAND "@CMAKE_COMMAND@") +SET(CMAKE_CFG_INTDIR "@CMAKE_CFG_INTDIR@") +SET(ENV{VS_UNICODE_OUTPUT}) +INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig.cmake) + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) + +IF(CMAKE_INSTALL_CONFIG_NAME) + SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_INSTALL_CONFIG_NAME}") +ENDIF() + +FOREACH(comp ${CPACK_COMPONENTS_ALL}) + SET(ENV{DESTDIR} testinstall/${comp}) + SET(DIRS ${DIRS} testinstall/${comp}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -DCMAKE_INSTALL_COMPONENT=${comp} + -DCMAKE_INSTALL_PREFIX= -P ${CMAKE_BINARY_DIR}/cmake_install.cmake + ) +ENDFOREACH() + +MACRO(MAKE_WIX_IDENTIFIER str varname) + STRING(REPLACE "/" "." ${varname} "${str}") + STRING(REPLACE "-" "_" ${varname} "${${varname}}") +ENDMACRO() + +FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) + FILE(GLOB all_files ${dir}/*) + IF(NOT all_files) + RETURN() + ENDIF() + FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) + IF(dir_rel) + MAKE_DIRECTORY(${dir_root}/${dir_rel}) + MAKE_WIX_IDENTIFIER("${dir_rel}" id) + FILE(APPEND ${file} "\n") + ELSE() + FILE(APPEND ${file} "\n") + ENDIF() + + FOREACH(f ${all_files}) + IF(NOT IS_DIRECTORY ${f}) + FILE(RELATIVE_PATH rel ${topdir} ${f}) + MAKE_WIX_IDENTIFIER("${rel}" id) + FILE(TO_NATIVE_PATH ${f} f_native) + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file_comp} " \n") + ENDIF() + ENDFOREACH() + FILE(APPEND ${file} "\n") + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${dir_root}) + ENDIF() + ENDFOREACH() +ENDFUNCTION() + +FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) + FILE(RELATIVE_PATH rel ${topdir} ${dir}) + IF(rel AND IS_DIRECTORY "${f}") + MAKE_WIX_IDENTIFIER("${rel}" id) + GET_FILENAME_COMPONENT(name ${dir} NAME) + FILE(APPEND ${file} "${prefix}\n") + ENDIF() + FILE(GLOB all_files ${dir}/*) + FOREACH(f ${all_files}) + IF(IS_DIRECTORY ${f}) + TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ") + ENDIF() + ENDFOREACH() + IF(rel AND IS_DIRECTORY "${f}") + FILE(APPEND ${file} "\n") + ENDIF() +ENDFUNCTION() + + +GET_FILENAME_COMPONENT(abs . ABSOLUTE) +FOREACH(d ${DIRS}) + GET_FILENAME_COMPONENT(d ${d} ABSOLUTE) + GET_FILENAME_COMPONENT(d_name ${d} NAME) + FILE(WRITE + ${abs}/${d_name}.wxs "\n\n") + FILE(WRITE + ${abs}/${d_name}_component_group.wxs "\n\n\n") + TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs "${abs}/dirs") + FILE(APPEND ${abs}/${d_name}.wxs " \n") + FILE(APPEND ${abs}/${d_name}_component_group.wxs "\n\n") +ENDFOREACH() +FILE(WRITE directories.wxs "\n\n\n") +TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") +FILE(APPEND directories.wxs "\n\n\n") + +EXECUTE_PROCESS( + COMMAND ${CANDLE_EXECUTABLE} *.wxs + COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension *.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi +) + diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in new file mode 100644 index 00000000000..21f2a6256f3 --- /dev/null +++ b/packaging/WiX/mysql_server.wxs.in @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index dd9c5785dcb..28b14661265 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -66,7 +66,7 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mysql_system_tables_data.sql ${CMAKE_CURRENT_SOURCE_DIR}/fill_help_tables.sql ${CMAKE_CURRENT_SOURCE_DIR}/mysql_test_data_timezone.sql - DESTINATION ${INSTALL_MYSQLSHAREDIR} + DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server ) # TCMalloc hacks @@ -166,12 +166,10 @@ ELSE() SET(EXT ".pl") ENDIF() -INSTALL(FILES +INSTALL_SCRIPT( "${CMAKE_CURRENT_BINARY_DIR}/mysql_install_db${EXT}" - DESTINATION ${DEST} - PERMISSIONS OWNER_READ OWNER_WRITE - OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE + DESTINATION ${INSTALL_BINDIR} + COMPONENT Server ) @@ -260,29 +258,17 @@ IF(WIN32) FOREACH(file ${PLIN_FILES}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.pl.in ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl ESCAPE_QUOTES @ONLY) - - INSTALL(FILES - ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl - DESTINATION scripts - PERMISSIONS OWNER_READ OWNER_WRITE - OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - ) + INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl) ENDFOREACH() FOREACH(file ${SH_FILES}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl ESCAPE_QUOTES @ONLY) - INSTALL(FILES - ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl - DESTINATION scripts - PERMISSIONS OWNER_READ OWNER_WRITE - OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - ) + INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl) ENDFOREACH() ELSE() # On Unix, most of the files end up in the bin directory + SET(mysql_config_COMPONENT COMPONENT Development) SET(BIN_SCRIPTS msql2mysql mysql_config @@ -312,13 +298,14 @@ ELSE() MESSAGE(FATAL_ERROR "Can not find ${file}.sh or ${file} in " "${CMAKE_CURRENT_SOURCE_DIR}" ) ENDIF() - INSTALL(FILES - ${CMAKE_CURRENT_BINARY_DIR}/${file} - DESTINATION ${INSTALL_BINDIR} - PERMISSIONS OWNER_READ OWNER_WRITE - OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - ) + IF(NOT ${file}_COMPONENT) + SET(${file}_COMPONENT Server) + ENDIF() + INSTALL_SCRIPT( + ${CMAKE_CURRENT_BINARY_DIR}/${file} + DESTINATION ${INSTALL_BINDIR} + COMPONENT ${${file}_COMPONENT} + ) ENDFOREACH() ENDIF() @@ -333,7 +320,8 @@ IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_FLAGS MATCHES "-static") ERROR_QUIET ) IF(${RESULT} EQUAL 0 AND EXISTS ${LIBGCC_LOCATION}) - INSTALL(FILES "${LIBGCC_LOCATION}" DESTINATION ${INSTALL_LIBDIR}) + INSTALL(FILES "${LIBGCC_LOCATION}" DESTINATION ${INSTALL_LIBDIR} + COMPONENT Development) ENDIF() ENDIF() diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 51271a3dad0..0cbbd5db283 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -158,7 +158,7 @@ cp tests/$TARGET/*.exe $DESTDIR/bin/ cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/ cp sql/$TARGET/mysqld.exe $DESTDIR/bin/mysqld$EXE_SUFFIX.exe -cp sql/$TARGET/mysqld.map $DESTDIR/bin/mysqld$EXE_SUFFIX.map +cp sql/$TARGET/mysqld.map $DESTDIR/bin/mysqld$EXE_SUFFIX.map || /bin/true if [ x"$TARGET" != x"release" ] ; then cp sql/$TARGET/mysqld.pdb $DESTDIR/bin/mysqld$EXE_SUFFIX.pdb fi diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 85970ff5c0a..0c727626138 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -100,7 +100,7 @@ ELSE() SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL}) ENDIF() -MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR}) +MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) IF(NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE) diff --git a/sql/share/CMakeLists.txt b/sql/share/CMakeLists.txt index 944120cfc24..0d241928208 100644 --- a/sql/share/CMakeLists.txt +++ b/sql/share/CMakeLists.txt @@ -45,8 +45,8 @@ SET(files FOREACH (dir ${dirs}) INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} - DESTINATION ${INSTALL_MYSQLSHAREDIR}) + DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) ENDFOREACH() -INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/charsets DESTINATION ${INSTALL_MYSQLSHAREDIR}) +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/charsets DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) -INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR}) +INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index ff98a7dd885..906f516eac2 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -62,7 +62,7 @@ IF(UNIX) INSTALL(FILES magic DESTINATION ${inst_location}) ENDIF() - INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal) + INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development) CONFIGURE_FILE(MySQL-shared-compat.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/MySQL-shared-compat.spec @ONLY) CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.spec @ONLY) CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/mysql.${VERSION}.spec @ONLY) From ab6f78734175005dfcc32c2f1855d076fe465cec Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 11 Feb 2010 03:28:12 +0100 Subject: [PATCH 002/207] Fix XML error in compiling MSI --- packaging/WiX/create_msi.cmake.in | 38 ++++++++++++++++++++++++------- packaging/WiX/mysql_server.wxs.in | 11 +-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index 13836d6d35f..34aa53fdc91 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -4,6 +4,10 @@ SET(CANDLE_EXECUTABLE "@CANDLE_EXECUTABLE@") SET(LIGHT_EXECUTABLE "@LIGHT_EXECUTABLE@") SET(CMAKE_COMMAND "@CMAKE_COMMAND@") SET(CMAKE_CFG_INTDIR "@CMAKE_CFG_INTDIR@") +SET(MAJOR_VERSION "@MAJOR_VERSION@") +SET(MINOR_VERSION "@MINOR_VERSION@") +SET(PATCH "@PATCH@") + SET(ENV{VS_UNICODE_OUTPUT}) INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig.cmake) @@ -25,7 +29,16 @@ ENDFOREACH() MACRO(MAKE_WIX_IDENTIFIER str varname) STRING(REPLACE "/" "." ${varname} "${str}") - STRING(REPLACE "-" "_" ${varname} "${${varname}}") + STRING(REGEX REPLACE "[^a-zA-Z_0-9.]" "_" ${varname} "${${varname}}") + STRING(LENGTH "${${varname}}" len) + # Identifier should be smaller than 72 character + # We have to cut down the length to 70 chars, since we add 2 char prefix + # pretty often + IF(len GREATER 70) + STRING(RANDOM r) + STRING(SUBSTRING "${${varname}}" 0 65 shortstr) + SET(${varname} "${shortstr}${r}") + ENDIF() ENDMACRO() FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) @@ -37,7 +50,7 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) IF(dir_rel) MAKE_DIRECTORY(${dir_root}/${dir_rel}) MAKE_WIX_IDENTIFIER("${dir_rel}" id) - FILE(APPEND ${file} "\n") + FILE(APPEND ${file} "\n") ELSE() FILE(APPEND ${file} "\n") ENDIF() @@ -47,10 +60,10 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FILE(RELATIVE_PATH rel ${topdir} ${f}) MAKE_WIX_IDENTIFIER("${rel}" id) FILE(TO_NATIVE_PATH ${f} f_native) - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") FILE(APPEND ${file} " \n") - FILE(APPEND ${file_comp} " \n") + FILE(APPEND ${file_comp} " \n") ENDIF() ENDFOREACH() FILE(APPEND ${file} "\n") @@ -66,7 +79,7 @@ FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) IF(rel AND IS_DIRECTORY "${f}") MAKE_WIX_IDENTIFIER("${rel}" id) GET_FILENAME_COMPONENT(name ${dir} NAME) - FILE(APPEND ${file} "${prefix}\n") + FILE(APPEND ${file} "${prefix}\n") ENDIF() FILE(GLOB all_files ${dir}/*) FOREACH(f ${all_files}) @@ -96,8 +109,17 @@ FILE(WRITE directories.wxs " - + Date: Thu, 11 Feb 2010 19:23:11 +0100 Subject: [PATCH 003/207] Fix CMake 2.6 errors --- packaging/WiX/CMakeLists.txt | 16 ++++++++++++---- packaging/WiX/create_msi.cmake.in | 8 +++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packaging/WiX/CMakeLists.txt b/packaging/WiX/CMakeLists.txt index 1d1a82f7b1c..81852697fb8 100644 --- a/packaging/WiX/CMakeLists.txt +++ b/packaging/WiX/CMakeLists.txt @@ -1,18 +1,26 @@ + +IF(NOT WIN32) + RETURN() +ENDIF() + FIND_PATH(WIX_DIR heat.exe $ENV{WIX_DIR}/bin $ENV{ProgramFiles}/wix/bin - "$ENV{ProgramFiles}/Windows Installer XML v3.0/bin" + "$ENV{ProgramFiles}/Windows Installer XML v3/bin" "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" ) IF(NOT WIX_DIR) - MESSAGE(FATAL_ERROR "Cannot find wix") + IF(NOT _WIX_DIR_CHECKED) + SET(_WIX_DIR_CHECKED 1 CACHE INTERNAL "") + MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") + ENDIF() + RETURN() ENDIF() FIND_PROGRAM(HEAT_EXECUTABLE heat ${WIX_DIR}) FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake @@ -21,7 +29,7 @@ IF(CMAKE_GENERATOR MATCHES "Visual Studio") SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") ENDIF() ADD_CUSTOM_TARGET( - WIX_Installer + MSI COMMAND set VS_UNICODE_OUTPUT= COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake ) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index 34aa53fdc91..15cdc3e4315 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -24,9 +24,11 @@ FOREACH(comp ${CPACK_COMPONENTS_ALL}) EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -DCMAKE_INSTALL_COMPONENT=${comp} -DCMAKE_INSTALL_PREFIX= -P ${CMAKE_BINARY_DIR}/cmake_install.cmake + OUTPUT_QUIET ) ENDFOREACH() +SET(INC_VAR 0) MACRO(MAKE_WIX_IDENTIFIER str varname) STRING(REPLACE "/" "." ${varname} "${str}") STRING(REGEX REPLACE "[^a-zA-Z_0-9.]" "_" ${varname} "${${varname}}") @@ -35,9 +37,9 @@ MACRO(MAKE_WIX_IDENTIFIER str varname) # We have to cut down the length to 70 chars, since we add 2 char prefix # pretty often IF(len GREATER 70) - STRING(RANDOM r) - STRING(SUBSTRING "${${varname}}" 0 65 shortstr) - SET(${varname} "${shortstr}${r}") + STRING(SUBSTRING "${${varname}}" 0 67 shortstr) + MATH(EXPR INC_VAR ${INC_VAR}+1) + SET(${varname} "${shortstr}${INC_VAR}") ENDIF() ENDMACRO() From 7e01172ce3737d5ab621c3f4ffd06af00b416df8 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 16 Feb 2010 16:06:57 +0100 Subject: [PATCH 004/207] Fix a couple fo things replated to MSI --- CMakeLists.txt | 8 +- cmake/install_macros.cmake | 7 +- packaging/WiX/CMakeLists.txt | 16 ++- packaging/WiX/create_fragments.cmake | 45 +++++-- packaging/WiX/create_msi.cmake.in | 181 +++++++++++++++++++++++++-- packaging/WiX/mysql_server.wxs.in | 21 ++-- scripts/CMakeLists.txt | 8 +- sql/CMakeLists.txt | 4 +- support-files/CMakeLists.txt | 3 +- tests/CMakeLists.txt | 2 +- 10 files changed, 245 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1185e65028..814d2ebaf7c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,14 +264,16 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc.in INSTALL(FILES EXCEPTIONS-CLIENT DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Development) -INSTALL(FILES COPYING README DESTINATION ${INSTALL_DOCREADMEDIR}) + +INSTALL(FILES COPYING DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme OPTIONAL) +INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme) IF(UNIX) - INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) + INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Documentation) ENDIF() # MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) -INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR}) +INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} COMPONENT Documentation) # Packaging IF(WIN32) SET(CPACK_GENERATOR "ZIP") diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 5b20c1966be..26e0d9581ac 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -35,7 +35,12 @@ MACRO (INSTALL_DEBUG_SYMBOLS targets) IF(CMAKE_GENERATOR MATCHES "Visual Studio") STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" pdb_location ${pdb_location}) ENDIF() - INSTALL(FILES ${pdb_location} DESTINATION ${INSTALL_LOCATION}) + IF(target STREQUAL "mysqld") + SET(comp Server) + ELSE() + SET(comp Debuginfo) + ENDIF() + INSTALL(FILES ${pdb_location} DESTINATION ${INSTALL_LOCATION} COMPONENT ${comp}) ENDFOREACH() ENDIF() ENDMACRO() diff --git a/packaging/WiX/CMakeLists.txt b/packaging/WiX/CMakeLists.txt index 81852697fb8..f083c79e1df 100644 --- a/packaging/WiX/CMakeLists.txt +++ b/packaging/WiX/CMakeLists.txt @@ -4,10 +4,10 @@ IF(NOT WIN32) ENDIF() FIND_PATH(WIX_DIR heat.exe - $ENV{WIX_DIR}/bin - $ENV{ProgramFiles}/wix/bin - "$ENV{ProgramFiles}/Windows Installer XML v3/bin" - "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" + $ENV{WIX_DIR}/bin + $ENV{ProgramFiles}/wix/bin + "$ENV{ProgramFiles}/Windows Installer XML v3/bin" + "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" ) IF(NOT WIX_DIR) @@ -31,6 +31,12 @@ ENDIF() ADD_CUSTOM_TARGET( MSI COMMAND set VS_UNICODE_OUTPUT= - COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake + COMMAND ${CMAKE_COMMAND} -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake +) + +ADD_CUSTOM_TARGET( + MSI_ESSENTIALS + COMMAND set VS_UNICODE_OUTPUT= + COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake ) diff --git a/packaging/WiX/create_fragments.cmake b/packaging/WiX/create_fragments.cmake index 01e8a11c0cf..9b7eecdc47d 100644 --- a/packaging/WiX/create_fragments.cmake +++ b/packaging/WiX/create_fragments.cmake @@ -11,9 +11,21 @@ FOREACH(comp ${COMPS}) ) ENDFOREACH() +SET(INC 0) MACRO(MAKE_WIX_IDENTIFIER str varname) - STRING(REPLACE "/" "." ${varname} "${str}") - STRING(REPLACE "-" "_" ${varname} "${${varname}}") + STRING(REPLACE "/" "." ret "${str}") + STRING(REPLACE "-" "_" ret "${ret}}") + STRING(LENGTH l "${ret}") + IF(l GREATER 65) + STRING(SUBSTRING "${ret}" 0 64 ret) + MATH(EXPR INC ${INC}+1) + SET(ret "${ret}${INC}) + ENDIF() + SET(${varname} ${ret}) +ENDMACRO() + +MACRO(GENERATE_GUID VarName) + EXECUTE_PROCESS(COMMAND uuidgen -c OUTPUT_VARIABLE ${VarName} OUTPUT_STRIP_TRAILING_WHITESPACE) ENDMACRO() FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) @@ -24,23 +36,34 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) IF(dir_rel) MAKE_DIRECTORY(${dir_root}/${dir_rel}) - MAKE_WIX_IDENTIFIER("${dir_rel}" id) - FILE(APPEND ${file} "\n") + MAKE_WIX_IDENTIFIER("${dir_rel}" dir_id) ELSE() FILE(APPEND ${file} "\n") ENDIF() + FILE(APPEND ${file} "\n") + SET(NONEXEFILES) FOREACH(f ${all_files}) IF(NOT IS_DIRECTORY ${f}) - FILE(RELATIVE_PATH rel ${topdir} ${f}) + GET_FILENAME_COMPONENT(ext "${f}" EXT) + FILE(TO_NATIVE_PATH ${f} f_native) + FILE(RELATIVE_PATH rel ${topdir} ${f}) MAKE_WIX_IDENTIFIER("${rel}" id) - FILE(TO_NATIVE_PATH ${f} f_native) - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file_comp} " \n") + IF(ext MATCHES ".dll" OR ext MATCHES ".exe") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file_comp} " \n") + ELSE() + # Collect nonexe files into a single component to reduce number of components + SET(NONEXEFILES "${NONEXEFILES} \n") + ENDIF() ENDIF() ENDFOREACH() + IF(NONEXEFILES) + GENERATE_GUID(guid) + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} "${prefix}\n") ENDIF() FILE(GLOB all_files ${dir}/*) FOREACH(f ${all_files}) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index 15cdc3e4315..d932e064237 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -7,12 +7,143 @@ SET(CMAKE_CFG_INTDIR "@CMAKE_CFG_INTDIR@") SET(MAJOR_VERSION "@MAJOR_VERSION@") SET(MINOR_VERSION "@MINOR_VERSION@") SET(PATCH "@PATCH@") +SET(CMAKE_SIZEOF_VOID_P @CMAKE_SIZEOF_VOID_P@) + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(Win64 " Win64='yes'") + SET(Platform x64) + SET(PlatformProgramFilesFolder ProgramFiles64Folder) +ELSE() + SET(Platform x86) + SET(PlatformProgramFilesFolder ProgramFilesFolder) + SET(Win64) +ENDIF() SET(ENV{VS_UNICODE_OUTPUT}) + INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig.cmake) +IF(CPACK_WIX_CONFIG) + INCLUDE(${CPACK_WIX_CONFIG}) +ENDIF() + +IF(NOT CPACK_WIX_UI) + SET(CPACK_WIX_UI "WixUI_Mondo") +ENDIF() + +SET(WIX_FEATURES) +FOREACH(comp ${CPACK_COMPONENTS_ALL}) + STRING(TOUPPER "${comp}" comp_upper) + IF(NOT CPACK_COMPONENT_${comp_upper}_GROUP) + SET(WIX_FEATURE_${comp_upper}_COMPONENTS "${comp}") + SET(CPACK_COMPONENT_${comp_upper}_HIDDEN 1) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_DISPLAY_NAME ${CPACK_COMPONENT_${comp_upper}_DISPLAY_NAME}) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_DESCRIPTION ${CPACK_COMPONENT_${comp_upper}_DESCRIPTION}) + SET(CPACK_COMPONENT_GROUP_${comp_upper}_WIX_LEVEL ${CPACK_COMPONENT_${comp_upper}_WIX_LEVEL}) + SET(WIX_FEATURES ${WIX_FEATURES} WIX_FEATURE_${comp_upper}) + ELSE() + SET(FEATURE_NAME WIX_FEATURE_${CPACK_COMPONENT_${comp_upper}_GROUP}) + SET(WIX_FEATURES ${WIX_FEATURES} ${FEATURE_NAME}) + LIST(APPEND ${FEATURE_NAME}_COMPONENTS ${comp}) + ENDIF() +ENDFOREACH() + +LIST(REMOVE_DUPLICATES WIX_FEATURES) + +SET(CPACK_WIX_FEATURES) + +FOREACH(f ${WIX_FEATURES}) + STRING(TOUPPER "${f}" f_upper) + STRING(REPLACE "WIX_FEATURE_" "" f_upper ${f_upper}) + IF (CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + ENDIF() + + IF (CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + ENDIF() + IF(CPACK_COMPONENT_${f_upper}_WIX_LEVEL) + SET(Level ${CPACK_COMPONENT_${f_upper}_WIX_LEVEL}) + ELSE() + SET(Level 1) + ENDIF() + IF(CPACK_COMPONENT_GROUP_${f_upper}_HIDDEN) + SET(DISPLAY "Display='hidden'") + SET(TITLE ${f_upper}) + SET(DESCRIPTION ${f_upper}) + ELSE() + SET(DISPLAY) + IF(CPACK_COMPONENT_GROUP_${f_upper}_EXPANDED) + SET(DISPLAY "Display='expand'") + ENDIF() + IF (CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_GROUP_${f_upper}_DISPLAY_NAME) + ENDIF() + IF (CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_GROUP_${f_upper}_DESCRIPTION) + ENDIF() + ENDIF() + + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + " + ) + FOREACH(c ${${f}_COMPONENTS}) + STRING(TOUPPER "${c}" c_upper) + IF (CPACK_COMPONENT_${c_upper}_DISPLAY_NAME) + SET(TITLE ${CPACK_COMPONENT_${c_upper}_DISPLAY_NAME}) + ELSE() + SET(TITLE CPACK_COMPONENT_${c_upper}_DISPLAY_NAME) + ENDIF() + + IF (CPACK_COMPONENT_${c_upper}_DESCRIPTION) + SET(DESCRIPTION ${CPACK_COMPONENT_${c_upper}_DESCRIPTION}) + ELSE() + SET(DESCRIPTION CPACK_COMPONENT_${c_upper}_DESCRIPTION) + ENDIF() + IF(CPACK_COMPONENT_${c_upper}_WIX_LEVEL) + SET(Level ${CPACK_COMPONENT_${c_upper}_WIX_LEVEL}) + ELSE() + SET(Level 1) + ENDIF() + IF(CPACK_COMPONENT_${c_upper}_HIDDEN) + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + ") + ELSE() + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + + + ") + ENDIF() + + ENDFOREACH() + SET(CPACK_WIX_FEATURES + "${CPACK_WIX_FEATURES} + + ") +ENDFOREACH() + + + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) + IF(CMAKE_INSTALL_CONFIG_NAME) SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_INSTALL_CONFIG_NAME}") @@ -28,6 +159,12 @@ FOREACH(comp ${CPACK_COMPONENTS_ALL}) ) ENDFOREACH() +MACRO(GENERATE_GUID VarName) + EXECUTE_PROCESS(COMMAND uuidgen -c + OUTPUT_VARIABLE ${VarName} + OUTPUT_STRIP_TRAILING_WHITESPACE) +ENDMACRO() + SET(INC_VAR 0) MACRO(MAKE_WIX_IDENTIFIER str varname) STRING(REPLACE "/" "." ${varname} "${str}") @@ -43,7 +180,8 @@ MACRO(MAKE_WIX_IDENTIFIER str varname) ENDIF() ENDMACRO() -FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) + +FUNCTION(TRAVERSE_FILES dir topdir file file_comp file_default_component dir_root) FILE(GLOB all_files ${dir}/*) IF(NOT all_files) RETURN() @@ -52,26 +190,42 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) IF(dir_rel) MAKE_DIRECTORY(${dir_root}/${dir_rel}) MAKE_WIX_IDENTIFIER("${dir_rel}" id) - FILE(APPEND ${file} "\n") + SET(DirectoryRefId "D.${id}") ELSE() - FILE(APPEND ${file} "\n") + SET(DirectoryRefId "INSTALLDIR") ENDIF() - + FILE(APPEND ${file} "\n") + + SET(NONEXEFILES) FOREACH(f ${all_files}) IF(NOT IS_DIRECTORY ${f}) FILE(RELATIVE_PATH rel ${topdir} ${f}) MAKE_WIX_IDENTIFIER("${rel}" id) FILE(TO_NATIVE_PATH ${f} f_native) - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file_comp} " \n") + GET_FILENAME_COMPONENT(f_ext "${f}" EXT) + # According to MSDN each DLL or EXE should be in the own component + IF(f_ext MATCHES ".exe" OR f_ext MATCHES ".dll") + + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file} " \n") + FILE(APPEND ${file_comp} " \n") + ELSE() + SET(NONEXEFILES "${NONEXEFILES}\n" ) + ENDIF() ENDIF() ENDFOREACH() FILE(APPEND ${file} "\n") + IF(NONEXEFILES) + GENERATE_GUID(guid) + SET(ComponentId "C._files_${COMP_NAME}.${DirectoryRefId}") + FILE(APPEND ${file_default_component} + "\n${NONEXEFILES}\n\n") + FILE(APPEND ${file_comp} " \n") + ENDIF() FOREACH(f ${all_files}) IF(IS_DIRECTORY ${f}) - TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${dir_root}) + TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${file_default_component} ${dir_root}) ENDIF() ENDFOREACH() ENDFUNCTION() @@ -101,9 +255,14 @@ FOREACH(d ${DIRS}) GET_FILENAME_COMPONENT(d_name ${d} NAME) FILE(WRITE ${abs}/${d_name}.wxs "\n\n") + FILE(WRITE + ${abs}/${d_name}_default_component.wxs "") FILE(WRITE - ${abs}/${d_name}_component_group.wxs "\n\n\n") - TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs "${abs}/dirs") + ${abs}/${d_name}_component_group.wxs " + \n") + SET(COMP_NAME ${d_name}) + TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs ${abs}/${d_name}_default_component.wxs "${abs}/dirs") + FILE(APPEND ${abs}/${d_name}_default_component.wxs "\n\n") FILE(APPEND ${abs}/${d_name}.wxs " \n") FILE(APPEND ${abs}/${d_name}_component_group.wxs "\n\n") ENDFOREACH() diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index a4289195d47..2e1443e0153 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -3,27 +3,22 @@ Name="MySQL Server @MAJOR_VERSION@.@MINOR_VERSION@" Version="@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH@" Language="1033" Manufacturer="MySQL AB"> + InstallerVersion='200' Languages='1033' Compressed='yes' SummaryCodepage='1252' + Platform='@Platform@'/> - + - - - - - - - - - - + + @CPACK_WIX_FEATURES@ + + + diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 28b14661265..58412a9140e 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -244,6 +244,7 @@ IF(MSVC) ENDIF() SET(NON_THREADED_LIBS ${CLIENT_LIBS}) +SET(mysql_config_COMPONENT COMPONENT Development) IF(WIN32) # On Windows, some .sh and some .pl.in files are configured @@ -256,15 +257,18 @@ IF(WIN32) SET(SH_FILES mysql_convert_table_format mysqld_multi) FOREACH(file ${PLIN_FILES}) + IF(NOT ${file}_COMPONENT) + SET(${file}_COMPONENT Server_Scripts) + ENDIF() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.pl.in ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl ESCAPE_QUOTES @ONLY) - INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl) + INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl COMPONENT ${${file}_COMPONENT}) ENDFOREACH() FOREACH(file ${SH_FILES}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.pl ESCAPE_QUOTES @ONLY) - INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl) + INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/${file}.pl COMPONENT ${${file}_COMPONENT}) ENDFOREACH() ELSE() # On Unix, most of the files end up in the bin directory diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 0c727626138..7373d82c827 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -241,7 +241,7 @@ IF(INSTALL_LAYOUT STREQUAL "STANDALONE") # Avoid completely empty directories and install dummy file instead. SET(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/.empty ) FILE(WRITE ${DUMMY_FILE} "") -INSTALL(FILES ${DUMMY_FILE} DESTINATION data/test) +INSTALL(FILES ${DUMMY_FILE} DESTINATION data/test COMPONENT DataFiles) # Install initial database on windows IF(NOT CMAKE_CROSSCOMPILING) @@ -269,7 +269,7 @@ IF(WIN32 AND MYSQLD_EXECUTABLE) ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/data/mysql/user.frm ) - INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data/mysql DESTINATION data) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data/mysql DESTINATION data COMPONENT DataFiles) ELSE() # Not windows or cross compiling, just install an empty directory INSTALL(FILES ${DUMMY_FILE} DESTINATION data/mysql) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 906f516eac2..194ddaf3ca4 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -34,7 +34,8 @@ ENDIF() FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${inifile}.cnf.sh ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} @ONLY) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} DESTINATION ${INSTALL_DOCREADMEDIR}) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} DESTINATION + ${INSTALL_DOCREADMEDIR} COMPONENT IniFiles) ENDFOREACH() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ea2f41abb73..b0e3342b1bc 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,4 +27,4 @@ IF(WITH_UNIT_TESTS) SET_TARGET_PROPERTIES(bug25714 PROPERTIES LINKER_LANGUAGE CXX) ENDIF() -INSTALL(TARGETS mysql_client_test DESTINATION bin) +INSTALL(TARGETS mysql_client_test DESTINATION ${INSTALL_BINDIR} COMPONENT Test) From df312a95a06919faa4523f142661c05f3a30a5c3 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 16 Feb 2010 16:17:10 +0100 Subject: [PATCH 005/207] adding CPackWixConfig --- packaging/WiX/CPackWixConfig.cmake | 95 +++++++++++++++++++++++ packaging/WiX/create_fragments.cmake | 109 --------------------------- 2 files changed, 95 insertions(+), 109 deletions(-) create mode 100644 packaging/WiX/CPackWixConfig.cmake delete mode 100644 packaging/WiX/create_fragments.cmake diff --git a/packaging/WiX/CPackWixConfig.cmake b/packaging/WiX/CPackWixConfig.cmake new file mode 100644 index 00000000000..9577574bbaf --- /dev/null +++ b/packaging/WiX/CPackWixConfig.cmake @@ -0,0 +1,95 @@ + +IF(ESSENTIALS) + MESSAGE("Essentials!") + SET(CPACK_COMPONENTS_USED "Server;Client;DataFiles") + SET(CPACK_WIX_UI "WixUI_InstallDir") + MATH(EXPR bits ${CMAKE_SIZEOF_VOID_P}*8) + SET(CPACK_PACKAGE_FILE_NAME "mysql-essentials-${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH}-win${bits}") +ELSE() + SET(CPACK_COMPONENTS_USED + "Server;Client;DataFiles;Development;SharedLibraries;Embedded;Debuginfo;Documentation;IniFiles;Readme;Server_Scripts") +ENDIF() + + +# Some components like Embedded are optional +# We will build MSI without embedded if it was not selected for build +#(need to modify CPACK_COMPONENTS_ALL for that) +SET(CPACK_ALL) +FOREACH(comp1 ${CPACK_COMPONENTS_USED}) + SET(found) + FOREACH(comp2 ${CPACK_COMPONENTS_ALL}) + IF(comp1 STREQUAL comp2) + SET(found 1) + BREAK() + ENDIF() + ENDFOREACH() + IF(found) + SET(CPACK_ALL ${CPACK_ALL} ${comp1}) + ENDIF() +ENDFOREACH() +SET(CPACK_COMPONENTS_ALL ${CPACK_ALL}) + +# Always install (hidden), includes Readme files +SET(CPACK_COMPONENT_GROUP_ALWAYSINSTALL_HIDDEN 1) +SET(CPACK_COMPONENT_README_GROUP "AlwaysInstall") + +# Feature MySQL Server +SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_DISPLAY_NAME "MySQL Server") +SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_EXPANDED "1") +SET(CPACK_COMPONENT_GROUP_MYSQLSERVER_DESCRIPTION "Install MySQL Server") + # Subfeature "Server" (hidden) + SET(CPACK_COMPONENT_SERVER_GROUP "MySQLServer") + SET(CPACK_COMPONENT_SERVER_HIDDEN 1) + # Subfeature "Client" + SET(CPACK_COMPONENT_CLIENT_GROUP "MySQLServer") + SET(CPACK_COMPONENT_CLIENT_DISPLAY_NAME "Client Programs") + SET(CPACK_COMPONENT_CLIENT_DESCRIPTION + "Various helpful (commandline) tools including the mysql command line client" ) + + #Subfeature "Data Files" + SET(CPACK_COMPONENT_DATAFILES_GROUP "MySQLServer") + SET(CPACK_COMPONENT_DATAFILES_DISPLAY_NAME "Server data files") + SET(CPACK_COMPONENT_DATAFILES_DESCRIPTION "Server data files" ) + + +#Feature "Devel" +SET(CPACK_COMPONENT_GROUP_DEVEL_DISPLAY_NAME "Development Components") +SET(CPACK_COMPONENT_GROUP_DEVEL_DESCRIPTION "Installs C/C++ header files and libraries") + #Subfeature "Development" + SET(CPACK_COMPONENT_DEVELOPMENT_GROUP "Devel") + SET(CPACK_COMPONENT_DEVELOPMENT_HIDDEN 1) + + #Subfeature "Shared libraries" + SET(CPACK_COMPONENT_SHAREDLIBRARIES_GROUP "Devel") + SET(CPACK_COMPONENT_SHAREDLIBRARIES_DISPLAY_NAME "Client C API library (shared)") + SET(CPACK_COMPONENT_SHAREDLIBRARIES_DESCRIPTION "Installs shared client library") + + #Subfeature "Embedded" + SET(CPACK_COMPONENT_EMBEDDED_GROUP "Devel") + SET(CPACK_COMPONENT_EMBEDDED_DISPLAY_NAME "Embedded server library") + SET(CPACK_COMPONENT_EMBEDDED_DESCRIPTION "Installs embedded server library") + SET(CPACK_COMPONENT_EMBEDDED_WIX_LEVEL 2) + +#Feature Debug Symbols +SET(CPACK_COMPONENT_GROUP_DEBUGSYMBOLS_DISPLAY_NAME "Debug Symbols") +SET(CPACK_COMPONENT_GROUP_DEBUGSYMBOLS_DESCRIPTION "Installs Debug Symbols") +SET(CPACK_COMPONENT_GROUP_DEBUGSYMBOLS_WIX_LEVEL 2) + SET(CPACK_COMPONENT_DEBUGINFO_GROUP "DebugSymbols") + SET(CPACK_COMPONENT_DEBUGINFO_HIDDEN 1) + +#Feature Documentation +SET(CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "Documentation") +SET(CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION "Installs documentation") +SET(CPACK_COMPONENT_DOCUMENTATION_WIX_LEVEL 2) + +#Feature tests +SET(CPACK_COMPONENT_TEST_DISPLAY_NAME "Tests") +SET(CPACK_COMPONENT_TEST_DESCRIPTION "Installs unittests (requires Perl to run)") +SET(CPACK_COMPONENT_TEST_WIX_LEVEL 2) + + +#Feature Misc (hidden, installs only if everything is installed) +SET(CPACK_COMPONENT_GROUP_MISC_HIDDEN 1) +SET(CPACK_COMPONENT_GROUP_MISC_WIX_LEVEL 100) + SET(CPACK_COMPONENT_INIFILES_GROUP "Misc") + SET(CPACK_COMPONENT_SERVER_SCRIPTS_GROUP "Misc") diff --git a/packaging/WiX/create_fragments.cmake b/packaging/WiX/create_fragments.cmake deleted file mode 100644 index 9b7eecdc47d..00000000000 --- a/packaging/WiX/create_fragments.cmake +++ /dev/null @@ -1,109 +0,0 @@ -INCLUDE(${CMAKE_BINARY_DIR}/CPackConfig) - -FOREACH(comp ${COMPS}) - SET(CMDS ${CMDS} - COMMAND set DESTDIR=testinstall/${comp} - COMMAND ${CMAKE_COMMAND} - -DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR} - -DCMAKE_INSTALL_COMPONENT=${comp} - -DCMAKE_INSTALL_PREFIX= - -P ${CMAKE_BINARY_DIR}/cmake_install.cmake - ) -ENDFOREACH() - -SET(INC 0) -MACRO(MAKE_WIX_IDENTIFIER str varname) - STRING(REPLACE "/" "." ret "${str}") - STRING(REPLACE "-" "_" ret "${ret}}") - STRING(LENGTH l "${ret}") - IF(l GREATER 65) - STRING(SUBSTRING "${ret}" 0 64 ret) - MATH(EXPR INC ${INC}+1) - SET(ret "${ret}${INC}) - ENDIF() - SET(${varname} ${ret}) -ENDMACRO() - -MACRO(GENERATE_GUID VarName) - EXECUTE_PROCESS(COMMAND uuidgen -c OUTPUT_VARIABLE ${VarName} OUTPUT_STRIP_TRAILING_WHITESPACE) -ENDMACRO() - -FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) - FILE(GLOB all_files ${dir}/*) - IF(NOT all_files) - RETURN() - ENDIF() - FILE(RELATIVE_PATH dir_rel ${topdir} ${dir}) - IF(dir_rel) - MAKE_DIRECTORY(${dir_root}/${dir_rel}) - MAKE_WIX_IDENTIFIER("${dir_rel}" dir_id) - ELSE() - FILE(APPEND ${file} "\n") - ENDIF() - FILE(APPEND ${file} "\n") - - SET(NONEXEFILES) - FOREACH(f ${all_files}) - IF(NOT IS_DIRECTORY ${f}) - GET_FILENAME_COMPONENT(ext "${f}" EXT) - FILE(TO_NATIVE_PATH ${f} f_native) - FILE(RELATIVE_PATH rel ${topdir} ${f}) - MAKE_WIX_IDENTIFIER("${rel}" id) - IF(ext MATCHES ".dll" OR ext MATCHES ".exe") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file} " \n") - FILE(APPEND ${file_comp} " \n") - ELSE() - # Collect nonexe files into a single component to reduce number of components - SET(NONEXEFILES "${NONEXEFILES} \n") - ENDIF() - ENDIF() - ENDFOREACH() - IF(NONEXEFILES) - GENERATE_GUID(guid) - FILE(APPEND ${file} " \n") - ENDIF() - FILE(GLOB all_files ${dir}/*) - FOREACH(f ${all_files}) - IF(IS_DIRECTORY ${f}) - TRAVERSE_DIRECTORIES(${f} ${topdir} ${file} "${prefix} ") - ENDIF() - ENDFOREACH() - IF(rel) - FILE(APPEND ${file} "\n") - ENDIF() -ENDFUNCTION() - - -GET_FILENAME_COMPONENT(abs . ABSOLUTE) -FOREACH(d ${DIRS}) - GET_FILENAME_COMPONENT(d ${d} ABSOLUTE) - GET_FILENAME_COMPONENT(d_name ${d} NAME) - FILE(WRITE - ${abs}/${d_name}.wxs "\n\n") - FILE(WRITE - ${abs}/${d_name}_component_group.wxs "\n\n\n") - TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs "${abs}/dirs") - FILE(APPEND ${abs}/${d_name}.wxs " \n") - FILE(APPEND ${abs}/${d_name}_component_group.wxs "\n\n") -ENDFOREACH() -FILE(WRITE directories.wxs "\n\n\n") -TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") -FILE(APPEND directories.wxs "\n\n\n") - From 7fcf60b80e66b6a7c037d89e3b266b7a9d68bc48 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 18 Feb 2010 23:52:35 +0100 Subject: [PATCH 006/207] Refactor some stuff --- packaging/WiX/CMakeLists.txt | 18 ++++++- packaging/WiX/create_msi.cmake.in | 48 ++++++++++-------- packaging/WiX/extra.wxs.in | 32 ++++++++++++ packaging/WiX/mysql_server.wxs.in | 82 ++++++++++++++++++++++++++----- 4 files changed, 145 insertions(+), 35 deletions(-) create mode 100644 packaging/WiX/extra.wxs.in diff --git a/packaging/WiX/CMakeLists.txt b/packaging/WiX/CMakeLists.txt index f083c79e1df..9cd043e001b 100644 --- a/packaging/WiX/CMakeLists.txt +++ b/packaging/WiX/CMakeLists.txt @@ -25,18 +25,32 @@ FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/extra.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + @ONLY@ + ) + IF(CMAKE_GENERATOR MATCHES "Visual Studio") SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") ENDIF() + ADD_CUSTOM_TARGET( MSI COMMAND set VS_UNICODE_OUTPUT= - COMMAND ${CMAKE_COMMAND} -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake + COMMAND ${CMAKE_COMMAND} + -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake + -DCPACK_WIX_EXTRA_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake ) ADD_CUSTOM_TARGET( MSI_ESSENTIALS COMMAND set VS_UNICODE_OUTPUT= - COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake + COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 + -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake + -DCPACK_WIX_EXTRA_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake ) diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index d932e064237..92bba7d34e9 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -181,7 +181,7 @@ MACRO(MAKE_WIX_IDENTIFIER str varname) ENDMACRO() -FUNCTION(TRAVERSE_FILES dir topdir file file_comp file_default_component dir_root) +FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FILE(GLOB all_files ${dir}/*) IF(NOT all_files) RETURN() @@ -219,13 +219,13 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp file_default_component dir_roo IF(NONEXEFILES) GENERATE_GUID(guid) SET(ComponentId "C._files_${COMP_NAME}.${DirectoryRefId}") - FILE(APPEND ${file_default_component} + FILE(APPEND ${file} "\n${NONEXEFILES}\n\n") FILE(APPEND ${file_comp} " \n") ENDIF() FOREACH(f ${all_files}) IF(IS_DIRECTORY ${f}) - TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${file_default_component} ${dir_root}) + TRAVERSE_FILES(${f} ${topdir} ${file} ${file_comp} ${dir_root}) ENDIF() ENDFOREACH() ENDFUNCTION() @@ -244,33 +244,41 @@ FUNCTION(TRAVERSE_DIRECTORIES dir topdir file prefix) ENDIF() ENDFOREACH() IF(rel AND IS_DIRECTORY "${f}") - FILE(APPEND ${file} "\n") + FILE(APPEND ${file} "${prefix}\n") ENDIF() ENDFUNCTION() - +SET(CPACK_WIX_COMPONENTS) +SET(CPACK_WIX_COMPONENT_GROUPS) GET_FILENAME_COMPONENT(abs . ABSOLUTE) FOREACH(d ${DIRS}) GET_FILENAME_COMPONENT(d ${d} ABSOLUTE) GET_FILENAME_COMPONENT(d_name ${d} NAME) - FILE(WRITE - ${abs}/${d_name}.wxs "\n\n") - FILE(WRITE - ${abs}/${d_name}_default_component.wxs "") - FILE(WRITE - ${abs}/${d_name}_component_group.wxs " - \n") + FILE(WRITE ${abs}/${d_name}_component_group.wxs "") SET(COMP_NAME ${d_name}) - TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs ${abs}/${d_name}_default_component.wxs "${abs}/dirs") - FILE(APPEND ${abs}/${d_name}_default_component.wxs "\n\n") - FILE(APPEND ${abs}/${d_name}.wxs " \n") - FILE(APPEND ${abs}/${d_name}_component_group.wxs "\n\n") + TRAVERSE_FILES(${d} ${d} ${abs}/${d_name}.wxs ${abs}/${d_name}_component_group.wxs "${abs}/dirs") + FILE(APPEND ${abs}/${d_name}_component_group.wxs "") + FILE(READ ${d_name}.wxs WIX_TMP) + SET(CPACK_WIX_COMPONENTS "${CPACK_WIX_COMPONENTS}\n${WIX_TMP}") + FILE(REMOVE ${d_name}.wxs) + FILE(READ ${d_name}_component_group.wxs WIX_TMP) + + SET(CPACK_WIX_COMPONENT_GROUPS "${CPACK_WIX_COMPONENT_GROUPS}\n${WIX_TMP}") + FILE(REMOVE ${d_name}_component_group.wxs) ENDFOREACH() -FILE(WRITE directories.wxs "\n\n\n") -TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") -FILE(APPEND directories.wxs "\n\n\n") -FILE(GLOB WXS_FILES *.wxs) +FILE(WRITE directories.wxs "\n") +TRAVERSE_DIRECTORIES(${abs}/dirs ${abs}/dirs directories.wxs "") +FILE(APPEND directories.wxs "\n") + +FILE(READ directories.wxs CPACK_WIX_DIRECTORIES) +FILE(REMOVE directories.wxs) + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) + + +SET(WXS_FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs ${CPACK_WIX_EXTRA_SOURCE}) SET(WIXOBJ_NATIVE_FILES) SET(WXS_NATIVE_FILES) FOREACH(f "${WXS_FILES}") diff --git a/packaging/WiX/extra.wxs.in b/packaging/WiX/extra.wxs.in new file mode 100644 index 00000000000..b1286bfba61 --- /dev/null +++ b/packaging/WiX/extra.wxs.in @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index 2e1443e0153..30baefbf64b 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -1,11 +1,62 @@ - - + + + InstallerVersion='200' + Languages='1033' + Compressed='yes' + SummaryCodepage='1252' + Platform='@Platform@'/> + + + + + + + + + NOT NEWERVERSIONDETECTED OR Installed + + + + + + + + + + + + + + + + @@ -14,13 +65,18 @@ - - @CPACK_WIX_FEATURES@ - - - - - - + + + @CPACK_WIX_FEATURES@ + + + @CPACK_WIX_DIRECTORIES@ + + + @CPACK_WIX_COMPONENTS@ + + + @CPACK_WIX_COMPONENT_GROUPS@ + From 7e852519d7eaabdac442b5ab5679de280f1c24ae Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 18 Mar 2010 21:06:12 +0100 Subject: [PATCH 007/207] Fixes from wlad --- .bzr-mysql/default.conf | 4 ++-- cmake/build_configurations/mysql_release.cmake | 8 ++++++-- mysys/my_init.c | 8 ++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index fcb3cab2de6..ac654d5cf71 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" +#post_commit_to = "commits@lists.mysql.com" +#post_push_to = "commits@lists.mysql.com" tree_name = "mysql-trunk" diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index b329a09d56e..9b3db827ab3 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -122,8 +122,12 @@ IF(UNIX) IF(CMAKE_SYSTEM_NAME MATCHES "HP-UX") IF(CMAKE_C_COMPILER_ID MATCHES "HP") IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ia64") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-g +O2 +DD64 +DSitanium2 -mt -AC99") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g +O2 +DD64 +DSitanium2 -mt -Aa") + SET(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} +DD64 +DSitanium2 -mt -AC99") + SET(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} +DD64 +DSitanium2 -mt -Aa") + SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} +O2") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} +O2") ENDIF() ENDIF() SET(WITH_SSL) diff --git a/mysys/my_init.c b/mysys/my_init.c index a3e53fdaae1..e68a8b7a194 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -93,10 +93,6 @@ my_bool my_basic_init(void) my_umask_dir= (int) (atoi_octal(str) | 0700); #endif - /* $HOME is needed early to parse configuration files located in ~/ */ - if ((home_dir= getenv("HOME")) != 0) - home_dir= intern_filename(home_dir_buff, home_dir); - init_glob_errs(); instrumented_stdin.m_file= stdin; @@ -122,6 +118,10 @@ my_bool my_basic_init(void) return 1; #endif + /* $HOME is needed early to parse configuration files located in ~/ */ + if ((home_dir= getenv("HOME")) != 0) + home_dir= intern_filename(home_dir_buff, home_dir); + return 0; } From 9a8986637ac7840a99196c49596e389300ef4e98 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 19 Mar 2010 15:34:42 +0100 Subject: [PATCH 008/207] First cut at SVR4 layout. --- cmake/install_layout.cmake | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 92eebebd4e2..cd886a00c3a 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -53,13 +53,17 @@ CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip IF(NOT INSTALL_LAYOUT MATCHES "STANDALONE") IF(NOT INSTALL_LAYOUT MATCHES "UNIX") - SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") + # XXX not keen on this, how many more will we need? prefer to just bail... + IF(NOT INSTALL_LAYOUT MATCHES "SVR4") + SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") ENDIF() ENDIF() IF(UNIX) IF(INSTALL_LAYOUT MATCHES "UNIX") SET(default_prefix "/usr") + ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") + SET(default_prefix "/opt/mysql/mysql") ELSE() SET(default_prefix "/usr/local/mysql") ENDIF() @@ -91,6 +95,23 @@ ENDIF() SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") SET(INSTALL_MYSQLDATADIR_STANDALONE "data") + # SVR4 layout + SET(INSTALL_BINDIR_SVR4 "bin") + SET(INSTALL_SBINDIR_SVR4 "bin") + SET(INSTALL_LIBDIR_SVR4 "lib") + SET(INSTALL_INCLUDEDIR_SVR4 "include") + SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") + SET(INSTALL_DOCDIR_SVR4 "docs") + SET(INSTALL_MANDIR_SVR4 "man") + SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") + SET(INSTALL_SHAREDIR_SVR4 "share") + SET(INSTALL_SCRIPTDIR_SVR4 "scripts") + SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") + SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") + SET(INSTALL_DOCREADMEDIR_SVR4 ".") + SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") + SET(MYSQL_DATADIR "/var/lib/mysql") + # UNIX layout SET(INSTALL_BINDIR_UNIX "bin") SET(INSTALL_SBINDIR_UNIX "sbin") From 486c06e29a4a9cbfb56c3f3b38a992ba547367ef Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 19 Mar 2010 16:26:33 +0100 Subject: [PATCH 009/207] Fix syntax. --- cmake/install_layout.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index cd886a00c3a..6b873762ece 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -56,6 +56,7 @@ IF(NOT INSTALL_LAYOUT MATCHES "STANDALONE") # XXX not keen on this, how many more will we need? prefer to just bail... IF(NOT INSTALL_LAYOUT MATCHES "SVR4") SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") + ENDIF() ENDIF() ENDIF() From 6ca0c6f52898dcb26a1cb55dd99742b365c48071 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 22 Mar 2010 15:16:52 +0100 Subject: [PATCH 010/207] Try to fix SVR4 packages. --- support-files/CMakeLists.txt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 85be470e21b..9cd373c6e9c 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -31,14 +31,12 @@ ELSE() SET(ini_file_extension "cnf") ENDIF() -IF(UNIX) - IF(INSTALL_LAYOUT MATCHES "STANDALONE") - SET(inst_location ${INSTALL_SUPPORTFILESDIR}) - ELSE() - SET(inst_location ${INSTALL_DOCREADMEDIR}) - ENDIF() -ELSE() +# XXX: shouldn't we just have variables for all this stuff and centralise +# XXX: their configuration in install_layout.cmake? +IF(WIN32) SET(inst_location ${INSTALL_DOCREADMEDIR}) +ELSE() + SET(inst_location ${INSTALL_SUPPORTFILESDIR}) ENDIF() FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small) @@ -48,14 +46,13 @@ FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small) ENDFOREACH() IF(UNIX) + # XXX: again, used elsewhere (scripts/), should be standardised in + # XXX: install_layout.cmake IF(INSTALL_LAYOUT MATCHES "STANDALONE") SET(prefix ".") - SET(inst_location ${INSTALL_SUPPORTFILESDIR}) ELSE() SET(prefix ${CMAKE_INSTALL_PREFIX}) - SET(inst_location ${INSTALL_MYSQLSHAREDIR}) ENDIF() - FOREACH(script mysqld_multi.server mysql-log-rotate binary-configure config.medium.ini config.small.ini config.huge.ini ndb-config-2-node.ini) From 31cc7f2eb041358d8ceeecaefb3de82bbedd46c8 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 22 Mar 2010 16:00:37 +0100 Subject: [PATCH 011/207] Tidy. --- cmake/install_layout.cmake | 199 +++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 98 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 6b873762ece..3a0a3fa6bca 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -14,54 +14,60 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # The purpose of this file is to set the default installation layout. -# Currently, there are 2 different installation layouts , -# one is used in tar.gz packages (Windows zip is about the same), another one -# in RPMs. - -# There are currently 2 layouts defines, named STANDALONE (tar.gz layout) -# and UNIX (rpm layout). To force a directory layout when invoking cmake use -# -DINSTALL_LAYOUT=[STANDALONE|UNIX]. -# This wil use a predefined layout. There is a possibility to further fine-tune -# installation directories. Several variables are can be overwritten # -# - INSTALL_BINDIR (directory with client executables and Unix shell scripts) -# - INSTALL_SBINDIR (directory with mysqld) -# - INSTALL_LIBDIR (directory with client end embedded libraries) -# - INSTALL_PLUGINDIR (directory for plugins) -# - INSTALL_INCLUDEDIR (directory for MySQL headers) -# - INSTALL_DOCDIR (documentation) -# - INSTALL_MANDIR (man pages) -# - INSTALL_SCRIPTDIR (several scripts, rarely used) -# - INSTALL_MYSQLSHAREDIR (MySQL character sets and localized error messages) -# - INSTALL_SHAREDIR (location of aclocal/mysql.m4) -# - INSTALL_SQLBENCHDIR (sql-bench) -# - INSTALL_MYSQLTESTDIR (mysql-test) -# - INSTALL_DOCREADMEDIR (readme and similar) +# The current choices of installation layout are: +# +# STANDALONE +# Build with prefix=/usr/local/mysql, create tarball with install prefix="." +# and relative links. Windows zip uses the same tarball layout but without +# the build prefix. +# +# RPM +# Build as per default RPM layout, with prefix=/usr +# +# SVR4 +# Solaris package layout suitable for pkg* tools, prefix=/opt/mysql/mysql +# +# To force a directory layout, use -DINSTALL_LAYOUT=. +# +# The default is STANDALONE. +# +# There is the possibility to further fine-tune installation directories. +# Several variables can be overwritten: +# +# - INSTALL_BINDIR (directory with client executables and scripts) +# - INSTALL_SBINDIR (directory with mysqld) +# - INSTALL_LIBDIR (directory with client end embedded libraries) +# - INSTALL_PLUGINDIR (directory for plugins) +# - INSTALL_INCLUDEDIR (directory for MySQL headers) +# - INSTALL_DOCDIR (documentation) +# - INSTALL_MANDIR (man pages) +# - INSTALL_SCRIPTDIR (several scripts, rarely used) +# - INSTALL_MYSQLSHAREDIR (MySQL character sets and localized error messages) +# - INSTALL_SHAREDIR (location of aclocal/mysql.m4) +# - INSTALL_SQLBENCHDIR (sql-bench) +# - INSTALL_MYSQLTESTDIR (mysql-test) +# - INSTALL_DOCREADMEDIR (readme and similar) # - INSTALL_SUPPORTFILESDIR (used only in standalone installer) -# Default installation layout on Unix is UNIX (kent wants it so) IF(NOT INSTALL_LAYOUT) - IF(WIN32) - SET(DEFAULT_INSTALL_LAYOUT "STANDALONE") - ELSE() - SET(DEFAULT_INSTALL_LAYOUT "UNIX") - ENDIF() + SET(DEFAULT_INSTALL_LAYOUT "STANDALONE") ENDIF() -SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}" -CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer) or UNIX") +SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}" +CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer) or UNIX") -IF(NOT INSTALL_LAYOUT MATCHES "STANDALONE") - IF(NOT INSTALL_LAYOUT MATCHES "UNIX") - # XXX not keen on this, how many more will we need? prefer to just bail... - IF(NOT INSTALL_LAYOUT MATCHES "SVR4") - SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") - ENDIF() - ENDIF() -ENDIF() +#IF(NOT INSTALL_LAYOUT MATCHES "STANDALONE") +# IF(NOT INSTALL_LAYOUT MATCHES "UNIX") +# # XXX not keen on this, how many more will we need? prefer to just bail... +# IF(NOT INSTALL_LAYOUT MATCHES "SVR4") +# SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") +# ENDIF() +# ENDIF() +#ENDIF() IF(UNIX) - IF(INSTALL_LAYOUT MATCHES "UNIX") + IF(INSTALL_LAYOUT MATCHES "UNIX") SET(default_prefix "/usr") ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") SET(default_prefix "/opt/mysql/mysql") @@ -69,67 +75,64 @@ IF(UNIX) SET(default_prefix "/usr/local/mysql") ENDIF() IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - SET(CMAKE_INSTALL_PREFIX ${default_prefix} + SET(CMAKE_INSTALL_PREFIX ${default_prefix} CACHE PATH "install prefix" FORCE) ENDIF() - SET(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc" + SET(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc" CACHE PATH "config directory (for my.cnf)") MARK_AS_ADVANCED(SYSCONFDIR) ENDIF() - - - # STANDALONE layout - SET(INSTALL_BINDIR_STANDALONE "bin") - SET(INSTALL_SBINDIR_STANDALONE "bin") - SET(INSTALL_LIBDIR_STANDALONE "lib") - SET(INSTALL_INCLUDEDIR_STANDALONE "include") - SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") - SET(INSTALL_DOCDIR_STANDALONE "docs") - SET(INSTALL_MANDIR_STANDALONE "man") - SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") - SET(INSTALL_SHAREDIR_STANDALONE "share") - SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") - SET(INSTALL_MYSQLTESTDIR_STANDALONE "mysql-test") - SET(INSTALL_SQLBENCHROOTDIR_STANDALONE ".") - SET(INSTALL_DOCREADMEDIR_STANDALONE ".") - SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") - SET(INSTALL_MYSQLDATADIR_STANDALONE "data") - - # SVR4 layout - SET(INSTALL_BINDIR_SVR4 "bin") - SET(INSTALL_SBINDIR_SVR4 "bin") - SET(INSTALL_LIBDIR_SVR4 "lib") - SET(INSTALL_INCLUDEDIR_SVR4 "include") - SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") - SET(INSTALL_DOCDIR_SVR4 "docs") - SET(INSTALL_MANDIR_SVR4 "man") - SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") - SET(INSTALL_SHAREDIR_SVR4 "share") - SET(INSTALL_SCRIPTDIR_SVR4 "scripts") - SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") - SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") - SET(INSTALL_DOCREADMEDIR_SVR4 ".") - SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") - SET(MYSQL_DATADIR "/var/lib/mysql") - - # UNIX layout - SET(INSTALL_BINDIR_UNIX "bin") - SET(INSTALL_SBINDIR_UNIX "sbin") - SET(INSTALL_LIBDIR_UNIX "lib/mysql") - SET(INSTALL_PLUGINDIR_UNIX "lib/mysql/plugin") - SET(INSTALL_DOCDIR_UNIX "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") - SET(INSTALL_MANDIR_UNIX "share/mysql/man") - SET(INSTALL_INCLUDEDIR_UNIX "include/mysql") - SET(INSTALL_MYSQLSHAREDIR_UNIX "share/mysql") - SET(INSTALL_SHAREDIR_UNIX "share") - SET(INSTALL_SCRIPTDIR_UNIX "bin") - SET(INSTALL_MYSQLTESTDIR_UNIX "mysql-test") - SET(INSTALL_SQLBENCHROOTDIR_UNIX "") - SET(INSTALL_DOCREADMEDIR_UNIX "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") - SET(INSTALL_SUPPORTFILESDIR_UNIX "") - SET(INSTALL_MYSQLDATADIR_UNIX "var") +# STANDALONE layout +SET(INSTALL_BINDIR_STANDALONE "bin") +SET(INSTALL_SBINDIR_STANDALONE "bin") +SET(INSTALL_LIBDIR_STANDALONE "lib") +SET(INSTALL_INCLUDEDIR_STANDALONE "include") +SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") +SET(INSTALL_DOCDIR_STANDALONE "docs") +SET(INSTALL_MANDIR_STANDALONE "man") +SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") +SET(INSTALL_SHAREDIR_STANDALONE "share") +SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") +SET(INSTALL_MYSQLTESTDIR_STANDALONE "mysql-test") +SET(INSTALL_SQLBENCHROOTDIR_STANDALONE ".") +SET(INSTALL_DOCREADMEDIR_STANDALONE ".") +SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") +SET(INSTALL_MYSQLDATADIR_STANDALONE "data") +# RPM layout +SET(INSTALL_BINDIR_RPM "bin") +SET(INSTALL_SBINDIR_RPM "sbin") +SET(INSTALL_LIBDIR_RPM "lib/mysql") +SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin") +SET(INSTALL_DOCDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") +SET(INSTALL_MANDIR_RPM "share/mysql/man") +SET(INSTALL_INCLUDEDIR_RPM "include/mysql") +SET(INSTALL_MYSQLSHAREDIR_RPM "share/mysql") +SET(INSTALL_SHAREDIR_RPM "share") +SET(INSTALL_SCRIPTDIR_RPM "bin") +SET(INSTALL_MYSQLTESTDIR_RPM "mysql-test") +SET(INSTALL_SQLBENCHROOTDIR_RPM "") +SET(INSTALL_DOCREADMEDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") +SET(INSTALL_SUPPORTFILESDIR_RPM "") +SET(INSTALL_MYSQLDATADIR_RPM "var") + +# SVR4 layout +SET(INSTALL_BINDIR_SVR4 "bin") +SET(INSTALL_SBINDIR_SVR4 "bin") +SET(INSTALL_LIBDIR_SVR4 "lib") +SET(INSTALL_INCLUDEDIR_SVR4 "include") +SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") +SET(INSTALL_DOCDIR_SVR4 "docs") +SET(INSTALL_MANDIR_SVR4 "man") +SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") +SET(INSTALL_SHAREDIR_SVR4 "share") +SET(INSTALL_SCRIPTDIR_SVR4 "scripts") +SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") +SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") +SET(INSTALL_DOCREADMEDIR_SVR4 ".") +SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") +SET(MYSQL_DATADIR "/var/lib/mysql") # Clear cached variables if install layout was changed IF(OLD_INSTALL_LAYOUT) @@ -139,12 +142,12 @@ IF(OLD_INSTALL_LAYOUT) ENDIF() SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "") -# Set INSTALL_FOODIR variables for chosen layout -# (for example, INSTALL_BINDIR will be defined as -# ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE layout is chosen) -FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN +# Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR +# will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE +# layout is chosen) +FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN MYSQLTEST SQLBENCHROOT DOCREADME SUPPORTFILES MYSQLDATA) - SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} + SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} CACHE STRING "${var} installation directory" ${FORCE}) MARK_AS_ADVANCED(INSTALL_${var}DIR) ENDFOREACH() From c41240939b978b0995b612c9be0f0c29f191d8dd Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 22 Mar 2010 18:33:20 +0100 Subject: [PATCH 012/207] Attempt to fix RPM support-files directory. --- cmake/install_layout.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 3a0a3fa6bca..ad857058ca4 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -114,7 +114,7 @@ SET(INSTALL_SCRIPTDIR_RPM "bin") SET(INSTALL_MYSQLTESTDIR_RPM "mysql-test") SET(INSTALL_SQLBENCHROOTDIR_RPM "") SET(INSTALL_DOCREADMEDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") -SET(INSTALL_SUPPORTFILESDIR_RPM "") +SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") SET(INSTALL_MYSQLDATADIR_RPM "var") # SVR4 layout From bb0d53752484f8680b8ee71171f73946eb59cd65 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 22 Mar 2010 23:15:28 +0100 Subject: [PATCH 013/207] Set CPACK_PACKAGE_CONTACT, required for .deb --- cmake/mysql_version.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index 3a61bcf40ab..a935643380c 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -106,6 +106,7 @@ ENDIF() IF(NOT CPACK_SOURCE_PACKAGE_FILE_NAME) SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mysql-${VERSION}") ENDIF() +SET(CPACK_PACKAGE_CONTACT "MySQL Build Team ") SET(CPACK_PACKAGE_VENDOR "Sun Microsystems, Inc") SET(CPACK_SOURCE_GENERATOR "TGZ") INCLUDE(cpack_source_ignore_files) From 3fbdf9b838540d1d12c187c783e1a66005d75924 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 22 Mar 2010 23:23:18 +0100 Subject: [PATCH 014/207] Fix RPM prefix. --- cmake/install_layout.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index ad857058ca4..250bd3cff5b 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -67,7 +67,7 @@ CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip #ENDIF() IF(UNIX) - IF(INSTALL_LAYOUT MATCHES "UNIX") + IF(INSTALL_LAYOUT MATCHES "RPM") SET(default_prefix "/usr") ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") SET(default_prefix "/opt/mysql/mysql") From 2dcbad90ba2d29d121f8ec034e0809a9dd9543da Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 23 Mar 2010 12:28:13 +0100 Subject: [PATCH 015/207] Try some more RPM fixes. --- cmake/install_layout.cmake | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 250bd3cff5b..680fa5ff863 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -103,10 +103,14 @@ SET(INSTALL_MYSQLDATADIR_STANDALONE "data") # RPM layout SET(INSTALL_BINDIR_RPM "bin") SET(INSTALL_SBINDIR_RPM "sbin") -SET(INSTALL_LIBDIR_RPM "lib/mysql") -SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin") +IF(64BIT) + SET(INSTALL_LIBDIR_RPM "lib64/mysql") +ELSE() + SET(INSTALL_LIBDIR_RPM "lib/mysql") +ENDIF() +SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/plugin") SET(INSTALL_DOCDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") -SET(INSTALL_MANDIR_RPM "share/mysql/man") +SET(INSTALL_MANDIR_RPM "share/man") SET(INSTALL_INCLUDEDIR_RPM "include/mysql") SET(INSTALL_MYSQLSHAREDIR_RPM "share/mysql") SET(INSTALL_SHAREDIR_RPM "share") From 146a47ee1271466cc775da1ac86f4af12d022ca9 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 23 Mar 2010 13:56:28 +0100 Subject: [PATCH 016/207] Install libs directly into %{_libdir} --- cmake/install_layout.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 680fa5ff863..67d90309b12 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -104,11 +104,11 @@ SET(INSTALL_MYSQLDATADIR_STANDALONE "data") SET(INSTALL_BINDIR_RPM "bin") SET(INSTALL_SBINDIR_RPM "sbin") IF(64BIT) - SET(INSTALL_LIBDIR_RPM "lib64/mysql") + SET(INSTALL_LIBDIR_RPM "lib64") ELSE() - SET(INSTALL_LIBDIR_RPM "lib/mysql") + SET(INSTALL_LIBDIR_RPM "lib") ENDIF() -SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/plugin") +SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/mysql/plugin") SET(INSTALL_DOCDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") SET(INSTALL_MANDIR_RPM "share/man") SET(INSTALL_INCLUDEDIR_RPM "include/mysql") From b960456150e37cb6aae2c055c2b11a3f46cd9f7a Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 23 Mar 2010 15:33:35 +0100 Subject: [PATCH 017/207] First cut at -DINSTALL_LAYOUT=DEB support. --- cmake/install_layout.cmake | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 67d90309b12..26801627811 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -25,6 +25,9 @@ # RPM # Build as per default RPM layout, with prefix=/usr # +# DEB +# Build as per STANDALONE, prefix=/opt/mysql-$major.$minor +# # SVR4 # Solaris package layout suitable for pkg* tools, prefix=/opt/mysql/mysql # @@ -69,6 +72,10 @@ CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip IF(UNIX) IF(INSTALL_LAYOUT MATCHES "RPM") SET(default_prefix "/usr") + ELSEIF(INSTALL_LAYOUT MATCHES "DEB") + SET(default_prefix "/opt/${MYSQL_BASE_VERSION}") + # This is required to avoid "cpack -GDEB" default of prefix=/usr + SET(CPACK_SET_DESTDIR ON) ELSEIF(INSTALL_LAYOUT MATCHES "SVR4") SET(default_prefix "/opt/mysql/mysql") ELSE() @@ -121,6 +128,23 @@ SET(INSTALL_DOCREADMEDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSI SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") SET(INSTALL_MYSQLDATADIR_RPM "var") +# DEB layout +SET(INSTALL_BINDIR_DEB "bin") +SET(INSTALL_SBINDIR_DEB "bin") +SET(INSTALL_LIBDIR_DEB "lib") +SET(INSTALL_INCLUDEDIR_DEB "include") +SET(INSTALL_PLUGINDIR_DEB "lib/plugin") +SET(INSTALL_DOCDIR_DEB "docs") +SET(INSTALL_MANDIR_DEB "man") +SET(INSTALL_MYSQLSHAREDIR_DEB "share") +SET(INSTALL_SHAREDIR_DEB "share") +SET(INSTALL_SCRIPTDIR_DEB "scripts") +SET(INSTALL_MYSQLTESTDIR_DEB "mysql-test") +SET(INSTALL_SQLBENCHROOTDIR_DEB ".") +SET(INSTALL_DOCREADMEDIR_DEB ".") +SET(INSTALL_SUPPORTFILESDIR_DEB "support-files") +SET(INSTALL_MYSQLDATADIR_DEB "data") + # SVR4 layout SET(INSTALL_BINDIR_SVR4 "bin") SET(INSTALL_SBINDIR_SVR4 "bin") From aa917229b999ab1a340037999279ff3cd0fac754 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 23 Mar 2010 16:53:11 +0100 Subject: [PATCH 018/207] Fix mysql-test directory in RPMs. While here: - split INSTALL_*DIR variables into two sections, first set the major variables, then second set the minor ones, using the major where appropriate. - format the settings for easier parsing (at least with a wide terminal) --- cmake/install_layout.cmake | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 26801627811..74720dfe5ad 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -107,26 +107,29 @@ SET(INSTALL_DOCREADMEDIR_STANDALONE ".") SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") SET(INSTALL_MYSQLDATADIR_STANDALONE "data") +# # RPM layout -SET(INSTALL_BINDIR_RPM "bin") -SET(INSTALL_SBINDIR_RPM "sbin") +# +SET(INSTALL_BINDIR_RPM "bin") +SET(INSTALL_INCLUDEDIR_RPM "include/mysql") IF(64BIT) - SET(INSTALL_LIBDIR_RPM "lib64") + SET(INSTALL_LIBDIR_RPM "lib64") ELSE() - SET(INSTALL_LIBDIR_RPM "lib") + SET(INSTALL_LIBDIR_RPM "lib") ENDIF() -SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/mysql/plugin") -SET(INSTALL_DOCDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") -SET(INSTALL_MANDIR_RPM "share/man") -SET(INSTALL_INCLUDEDIR_RPM "include/mysql") -SET(INSTALL_MYSQLSHAREDIR_RPM "share/mysql") -SET(INSTALL_SHAREDIR_RPM "share") -SET(INSTALL_SCRIPTDIR_RPM "bin") -SET(INSTALL_MYSQLTESTDIR_RPM "mysql-test") -SET(INSTALL_SQLBENCHROOTDIR_RPM "") -SET(INSTALL_DOCREADMEDIR_RPM "share/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") -SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") -SET(INSTALL_MYSQLDATADIR_RPM "var") +SET(INSTALL_SBINDIR_RPM "sbin") +SET(INSTALL_SHAREDIR_RPM "share") +# +SET(INSTALL_DOCDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") +SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") +SET(INSTALL_MANDIR_RPM "${INSTALL_SHAREDIR_RPM}/man") +SET(INSTALL_MYSQLDATADIR_RPM "var") +SET(INSTALL_MYSQLSHAREDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") +SET(INSTALL_MYSQLTESTDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql-test") +SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/mysql/plugin") +SET(INSTALL_SCRIPTDIR_RPM "${INSTALL_BINDIR_RPM}") +SET(INSTALL_SQLBENCHROOTDIR_RPM "") +SET(INSTALL_SUPPORTFILESDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") # DEB layout SET(INSTALL_BINDIR_DEB "bin") From 03bb7032e2e1bfe80ae878769113ebda238ef027 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 24 Mar 2010 17:52:47 +0100 Subject: [PATCH 019/207] Try to add support for MYSQL_U_SCORE_VERSION and MYSQL_COPYRIGHT_YEAR. --- cmake/mysql_version.cmake | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index a935643380c..cc9d2b38b8e 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -55,6 +55,7 @@ MACRO(GET_MYSQL_VERSION) ENDIF() SET(VERSION ${VERSION_STRING}) + STRING(REPLACE "-" "_" MYSQL_U_SCORE_VERSION "${VERSION_STRING}") # Remove trailing (non-numeric) part of the version string STRING(REGEX REPLACE "[^\\.0-9].*" "" VERSION_STRING ${VERSION_STRING}) @@ -115,6 +116,16 @@ INCLUDE(cpack_source_ignore_files) SET(PRODUCTNAME "MySQL Server") SET(COMPANYNAME ${CPACK_PACKAGE_VENDOR}) +# Windows 'date' command has unpredictable output, so cannot rely on it to +# set MYSQL_COPYRIGHT_YEAR - if someone finds a portable way to do so then +# it might be useful +#IF (WIN32) +# EXECUTE_PROCESS(COMMAND "date" "/T" OUTPUT_VARIABLE TMP_DATE) +# STRING(REGEX REPLACE "(..)/(..)/..(..).*" "\\3\\2\\1" MYSQL_COPYRIGHT_YEAR ${TMP_DATE}) +IF(UNIX) + EXECUTE_PROCESS(COMMAND "date" "+%Y" OUTPUT_VARIABLE MYSQL_COPYRIGHT_YEAR) +ENDIF() + # Add version information to the exe and dll files # Refer to http://msdn.microsoft.com/en-us/library/aa381058(VS.85).aspx # for more info. From d5d30d435a9d951ec2ab5c02e5b1fcc4d57b2a03 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 24 Mar 2010 20:17:41 +0100 Subject: [PATCH 020/207] Avoid newline in date output. --- cmake/mysql_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index cc9d2b38b8e..6adca2ccc2f 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -123,7 +123,7 @@ SET(COMPANYNAME ${CPACK_PACKAGE_VENDOR}) # EXECUTE_PROCESS(COMMAND "date" "/T" OUTPUT_VARIABLE TMP_DATE) # STRING(REGEX REPLACE "(..)/(..)/..(..).*" "\\3\\2\\1" MYSQL_COPYRIGHT_YEAR ${TMP_DATE}) IF(UNIX) - EXECUTE_PROCESS(COMMAND "date" "+%Y" OUTPUT_VARIABLE MYSQL_COPYRIGHT_YEAR) + EXECUTE_PROCESS(COMMAND "date" "+%Y" OUTPUT_VARIABLE MYSQL_COPYRIGHT_YEAR OUTPUT_STRIP_TRAILING_WHITESPACE) ENDIF() # Add version information to the exe and dll files From e7711a372a37c788e10380ae115922b69f435899 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 24 Mar 2010 21:17:13 +0100 Subject: [PATCH 021/207] Initial attempt at CMake support. --- support-files/mysql.spec.sh | 285 +++++++++--------------------------- 1 file changed, 71 insertions(+), 214 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index f02773e73b9..68935eed9e4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. +# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -131,10 +131,10 @@ Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} -License: Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ %{mysql_vendor} All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field. +License: Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field. Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/%{src_dir}.tar.gz URL: http://www.mysql.com/ -Packager: %{mysql_vendor} Product Engineering Team +Packager: MySQL Build Team Vendor: %{mysql_vendor} Provides: msqlormysql MySQL-server mysql BuildRequires: ncurses-devel @@ -152,7 +152,7 @@ is intended for mission-critical, heavy-load production systems as well as for embedding into mass-deployed software. MySQL is a trademark of %{mysql_vendor} -Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ %{mysql_vendor} All rights reserved. +Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Use is subject to license terms. This software comes with ABSOLUTELY NO WARRANTY. This is free software, @@ -180,7 +180,7 @@ is intended for mission-critical, heavy-load production systems as well as for embedding into mass-deployed software. MySQL is a trademark of %{mysql_vendor} -Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ %{mysql_vendor} All rights reserved. +Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Use is subject to license terms. This software comes with ABSOLUTELY NO WARRANTY. This is free software, @@ -328,9 +328,6 @@ client/server version. %endif ############################################################################## -# -############################################################################## - %prep # We unpack the source two times, for 'debug' and 'release' build. %setup -T -a 0 -c -n mysql-%{mysql_version} @@ -339,197 +336,72 @@ mv mysql-%{mysql_version} mysql-debug-%{mysql_version} mv mysql-%{mysql_version} mysql-release-%{mysql_version} ############################################################################## -# The actual build -############################################################################## - %build -BuildMySQL() { -# Let "MYSQL_BUILD_*FLAGS" take precedence. -CFLAGS=${MYSQL_BUILD_CFLAGS:-$CFLAGS} -CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-$CXXFLAGS} -LDFLAGS=${MYSQL_BUILD_LDFLAGS:-$LDFLAGS} -# Fall back on RPM_OPT_FLAGS (part of RPM environment) if no flags are given. -CFLAGS=${CFLAGS:-$RPM_OPT_FLAGS} -CXXFLAGS=${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti } -# Evaluate current setting of $DEBUG -if [ $DEBUG -gt 0 ] ; then - OPT_COMMENT='--with-comment="%{debug_comment}"' - OPT_DEBUG='--with-debug' - CFLAGS=`echo " $CFLAGS " | \ - sed -e 's/ -O[0-9]* / /' -e 's/ -unroll2 / /' -e 's/ -ip / /' \ - -e 's/^ //' -e 's/ $//'` - CXXFLAGS=`echo " $CXXFLAGS " | \ - sed -e 's/ -O[0-9]* / /' -e 's/ -unroll2 / /' -e 's/ -ip / /' \ - -e 's/^ //' -e 's/ $//'` -else - OPT_COMMENT='--with-comment="%{ndbug_comment}"' - OPT_DEBUG='' -fi -# The --enable-assembler simply does nothing on systems that does not -# support assembler speedups. -sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ - CC=\"${MYSQL_BUILD_CC:-$CC}\" \ - CXX=\"${MYSQL_BUILD_CXX:-$CXX}\" \ - CFLAGS=\"$CFLAGS\" \ - CXXFLAGS=\"$CXXFLAGS\" \ - LDFLAGS=\"$LDFLAGS\" \ - ./configure \ - $* \ - --with-mysqld-ldflags='-static' \ - --with-client-ldflags='-static' \ - --enable-assembler \ - --enable-local-infile \ - --with-fast-mutexes \ - --with-mysqld-user=%{mysqld_user} \ - --with-unix-socket-path=/var/lib/mysql/mysql.sock \ - --with-pic \ - --prefix=/ \ -%if %{CLUSTER_BUILD} - --with-extra-charsets=all \ -%else - --with-extra-charsets=complex \ -%endif -%if %{YASSL_BUILD} - --with-ssl \ -%else - --without-ssl \ -%endif - --exec-prefix=%{_exec_prefix} \ - --libexecdir=%{_sbindir} \ - --libdir=%{_libdir} \ - --sysconfdir=%{_sysconfdir} \ - --datadir=%{_datadir} \ - --localstatedir=%{mysqldatadir} \ - --infodir=%{_infodir} \ - --includedir=%{_includedir} \ - --mandir=%{_mandir} \ - --enable-thread-safe-client \ - $OPT_COMMENT \ - $OPT_DEBUG \ - --with-readline \ -%if %{WITH_BUNDLED_ZLIB} - --with-zlib-dir=bundled \ -%endif -%if %{CLUSTER_BUILD} - --with-plugin-ndbcluster \ -%else - --without-plugin-ndbcluster \ -%endif -%if %{INNODB_BUILD} - --with-plugin-innobase \ -%else - --without-plugin-innobase \ -%endif -%if %{PARTITION_BUILD} - --with-plugin-partition \ -%else - --without-plugin-partition \ -%endif - --with-plugin-csv \ - --with-plugin-archive \ - --with-plugin-blackhole \ - --with-plugin-federated \ - --without-plugin-daemon_example \ - --without-plugin-ftexample \ -%if %{EMBEDDED_BUILD} - --with-embedded-server \ -%else - --without-embedded-server \ -%endif - --with-big-tables \ - --enable-shared \ - " - make -} -# end of function definition "BuildMySQL" +# Be strict about variables, bail at earliest opportunity, etc. +set -eu -# Use our own copy of glibc +# Use specific MYSQL_BUILD_* setup if requested +${MYSQL_BUILD_PATH:+PATH="${MYSQL_BUILD_PATH}"} +${MYSQL_BUILD_CC:+CC="${MYSQL_BUILD_CC}"} +${MYSQL_BUILD_CC:+CC="${MYSQL_BUILD_CC}"} +${MYSQL_BUILD_CXX:+CXX="${MYSQL_BUILD_CXX}"} +${MYSQL_BUILD_CFLAGS:+CFLAGS="${MYSQL_BUILD_CFLAGS}"} +${MYSQL_BUILD_CXXFLAGS:+CXXFLAGS="${MYSQL_BUILD_CXXFLAGS}"} +${MYSQL_BUILD_LDFLAGS:+LDFLAGS="${MYSQL_BUILD_LDFLAGS}"} +${MYSQL_BUILD_CMAKE:+CMAKE="${MYSQL_BUILD_CMAKE}"} -OTHER_LIBC_DIR=/usr/local/mysql-glibc -USE_OTHER_LIBC_DIR="" -if test -d "$OTHER_LIBC_DIR" -then - USE_OTHER_LIBC_DIR="--with-other-libc=$OTHER_LIBC_DIR" -fi +# Set defaults. $RPM_OPT_FLAGS should be part of RPM environment +: ${CC:="gcc"} +: ${CXX:="g++"} +: ${CFLAGS:="${RPM_OPT_FLAGS}"} +: ${CXXFLAGS:="${RPM_OPT_FLAGS} -felide-constructors -fno-exceptions -fno-rtti"} +: ${LDFLAGS:=""} +: ${CMAKE:="cmake"} + +# Build debug mysqld and libmysqld.a +mkdir debug +( + cd debug + # Attempt to remove any optimisation flags from the debug build + CFLAGS=`echo " ${CFLAGS} " | \ + sed -e 's/ -O[0-9]* / /' \ + -e 's/ -unroll2 / /' \ + -e 's/ -ip / /' \ + -e 's/^ //' \ + -e 's/ $//'` + CXXFLAGS=`echo " ${CXXFLAGS} " | \ + sed -e 's/ -O[0-9]* / /' \ + -e 's/ -unroll2 / /' \ + -e 's/ -ip / /' \ + -e 's/^ //' \ + -e 's/ $//'` + ${CMAKE} .. -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ + -DCMAKE_BUILD_TYPE=Debug + make VERBOSE=1 mysqld mysqlserver +) +# Build full release +mkdir release +( + cd release + ${CMAKE} .. -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM + make VERBOSE=1 +) # Use the build root for temporary storage of the shared libraries. - RBR=$RPM_BUILD_ROOT # Clean up the BuildRoot first -[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR; +[ "$RBR" != "/" ] && [ -d "$RBR" ] && rm -rf "$RBR"; mkdir -p $RBR%{_libdir}/mysql -# -# Use MYSQL_BUILD_PATH so that we can use a dedicated version of gcc -# -PATH=${MYSQL_BUILD_PATH:-/bin:/usr/bin} -export PATH - -# Build the Debug binary. - -# Use gcc for C and C++ code (to avoid a dependency on libstdc++ and -# including exceptions into the code -if [ -z "$CXX" -a -z "$CC" ] ; then - export CC="gcc" CXX="gcc" -fi - - -############################################################################## -# -# Build the debug version -# -############################################################################## - -( -# We are in a subshell, so we can modify variables just for one run. - -# Add -g and --with-debug. -DEBUG=1 -cd mysql-debug-%{mysql_version} && -CFLAGS="$CFLAGS" \ -CXXFLAGS="$CXXFLAGS" \ -BuildMySQL -) - -# We might want to save the config log file -if test -n "$MYSQL_DEBUGCONFLOG_DEST" -then - cp -fp mysql-debug-%{mysql_version}/config.log "$MYSQL_DEBUGCONFLOG_DEST" -fi - -(cd mysql-debug-%{mysql_version} ; make test-bt-debug) - -############################################################################## -# -# Build the release binary -# -############################################################################## - -DEBUG=0 -(cd mysql-release-%{mysql_version} && -CFLAGS="$CFLAGS" \ -CXXFLAGS="$CXXFLAGS" \ -BuildMySQL -) -# We might want to save the config log file -if test -n "$MYSQL_CONFLOG_DEST" -then - cp -fp mysql-release-%{mysql_version}/config.log "$MYSQL_CONFLOG_DEST" -fi - -(cd mysql-release-%{mysql_version} ; make test-bt) - -############################################################################## - # For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) # Some "icc" calls may have "gcc" in the argument string, so we should first # check for "icc". (If we don't check, the "--print-libgcc-file" call will fail.) if expr "$CC" : ".*icc.*" > /dev/null ; then - %define WITH_LIBGCC 0 - : + %define WITH_LIBGCC 0 + : elif expr "$CC" : ".*gcc.*" > /dev/null ; then libgcc=`$CC $CFLAGS --print-libgcc-file` @@ -542,15 +414,15 @@ then : fi else - %define WITH_LIBGCC 0 - : + %define WITH_LIBGCC 0 + : fi ############################################################################## - %install + RBR=$RPM_BUILD_ROOT -MBD=$RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-release-%{mysql_version} +MBD=$RPM_BUILD_DIR/%{src_dir} # Ensure that needed directories exists install -d $RBR%{_sysconfdir}/{logrotate.d,init.d} @@ -561,41 +433,26 @@ install -d $RBR%{_libdir} install -d $RBR%{_mandir} install -d $RBR%{_sbindir} -# Get the plugin files from the debug build -mkdir $RBR/tmp-debug-plugin $MBD/plugin/debug -( cd $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/plugin - make install DESTDIR=$RBR/tmp-debug-plugin - mv $RBR/tmp-debug-plugin/usr/local/mysql/lib/mysql/plugin/* $MBD/plugin/debug/ - # From here, the install hook in "plugin/Makefile.am" will do the rest. -) -rmdir -p $RBR/tmp-debug-plugin/usr/local/mysql/lib/mysql/plugin - # Install all binaries -(cd $MBD && make install DESTDIR=$RBR testroot=%{_datadir}) -# Old packages put shared libs in %{_libdir}/ (not %{_libdir}/mysql), so do -# the same here. -mv $RBR/%{_libdir}/mysql/*.so* $RBR/%{_libdir}/ +( + cd $MBD/release + make DESTDIR=$RBR install +) -# install "mysqld-debug" -$MBD/libtool --mode=execute install -m 755 \ - $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/mysqld \ - $RBR%{_sbindir}/mysqld-debug +# FIXME: kent attempted to have debug libmysqld.a installed automatically but +# FIXME: could not get it working, so do it manually for now +install -m 644 $MBD/debug/libmysqld/libmysqld.a \ + $RBR%{_libdir}/mysql/libmysqld-debug.a -# install saved perror binary with NDB support (BUG#13740) -install -m 755 $MBD/extra/perror $RBR%{_bindir}/perror +# FIXME: at some point we should stop doing this and just install everything +# FIXME: directly into %{_libdir}/mysql - perhaps at the same time as renaming +# FIXME: the shared libraries to use libmysql*-$major.$minor.so syntax +mv -v $RBR/%{_libdir}/*.a $RBR/%{_libdir}/mysql/ # Install logrotate and autostart install -m 644 $MBD/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql install -m 755 $MBD/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql -%if %{EMBEDDED_BUILD} -# Install embedded server library in the build root -install -m 644 $MBD/libmysqld/libmysqld.a $RBR%{_libdir}/mysql/ -%endif - -# in RPMs, it is unlikely that anybody should use "sql-bench" -rm -fr $RBR%{_datadir}/sql-bench - # Create a symlink "rcmysql", pointing to the init.script. SuSE users # will appreciate that, as all services usually offer this. ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql From 29fd67ff4e1a67ad401b2a84d965796400ebbd31 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 24 Mar 2010 22:30:39 +0100 Subject: [PATCH 022/207] Fix source layout. --- support-files/mysql.spec.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 68935eed9e4..e9bb79dbe9d 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -329,11 +329,7 @@ client/server version. ############################################################################## %prep -# We unpack the source two times, for 'debug' and 'release' build. -%setup -T -a 0 -c -n mysql-%{mysql_version} -mv mysql-%{mysql_version} mysql-debug-%{mysql_version} -%setup -D -T -a 0 -n mysql-%{mysql_version} -mv mysql-%{mysql_version} mysql-release-%{mysql_version} +%setup -T -a 0 -c -n %{src_dir} ############################################################################## %build @@ -376,7 +372,7 @@ mkdir debug -e 's/ -ip / /' \ -e 's/^ //' \ -e 's/ $//'` - ${CMAKE} .. -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ + ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ -DCMAKE_BUILD_TYPE=Debug make VERBOSE=1 mysqld mysqlserver ) @@ -384,7 +380,7 @@ mkdir debug mkdir release ( cd release - ${CMAKE} .. -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM + ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM make VERBOSE=1 ) From 5fd878c3f0df927f9f7dbb2ffffd1697061eb177 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 11:43:11 +0100 Subject: [PATCH 023/207] Add INSTALL_INFODIR and use it to install mysql.info into the correct location. --- CMakeLists.txt | 9 +++++---- cmake/install_layout.cmake | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d20939f33ac..0445e2a3d5b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,8 +277,8 @@ INCLUDE(CPack) INSTALL(FILES COPYING EXCEPTIONS-CLIENT LICENSE.mysql DESTINATION ${INSTALL_DOCREADMEDIR} OPTIONAL) INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR}) IF(UNIX) - INSTALL(FILES Docs/INSTALL-BINARY DESTINATION - ${INSTALL_DOCREADMEDIR}) + INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR}) + INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) ENDIF() # MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") @@ -286,8 +286,9 @@ MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} PATTERN "INSTALL-BINARY" EXCLUDE PATTERN "Makefile.*" EXCLUDE - PATTERN "myisam.txt" EXCLUDE PATTERN "glibc*" EXCLUDE - PATTERN "sp-imp-spec.txt" EXCLUDE PATTERN "linuxthreads.txt" EXCLUDE + PATTERN "myisam.txt" EXCLUDE + PATTERN "mysql.info" EXCLUDE + PATTERN "sp-imp-spec.txt" EXCLUDE ) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 74720dfe5ad..1919aacfe43 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -98,6 +98,7 @@ SET(INSTALL_INCLUDEDIR_STANDALONE "include") SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") SET(INSTALL_DOCDIR_STANDALONE "docs") SET(INSTALL_MANDIR_STANDALONE "man") +SET(INSTALL_INFODIR_STANDALONE "docs") SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") SET(INSTALL_SHAREDIR_STANDALONE "share") SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") @@ -122,6 +123,7 @@ SET(INSTALL_SHAREDIR_RPM "share") # SET(INSTALL_DOCDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") +SET(INSTALL_INFODIR_RPM "${INSTALL_SHAREDIR_RPM}/info") SET(INSTALL_MANDIR_RPM "${INSTALL_SHAREDIR_RPM}/man") SET(INSTALL_MYSQLDATADIR_RPM "var") SET(INSTALL_MYSQLSHAREDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") @@ -139,6 +141,7 @@ SET(INSTALL_INCLUDEDIR_DEB "include") SET(INSTALL_PLUGINDIR_DEB "lib/plugin") SET(INSTALL_DOCDIR_DEB "docs") SET(INSTALL_MANDIR_DEB "man") +SET(INSTALL_INFODIR_DEB "docs") SET(INSTALL_MYSQLSHAREDIR_DEB "share") SET(INSTALL_SHAREDIR_DEB "share") SET(INSTALL_SCRIPTDIR_DEB "scripts") @@ -156,6 +159,7 @@ SET(INSTALL_INCLUDEDIR_SVR4 "include") SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") SET(INSTALL_DOCDIR_SVR4 "docs") SET(INSTALL_MANDIR_SVR4 "man") +SET(INSTALL_INFODIR_SVR4 "docs") SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") SET(INSTALL_SHAREDIR_SVR4 "share") SET(INSTALL_SCRIPTDIR_SVR4 "scripts") From 127bdb6eda8ea594d31802409d635b37fe60ae96 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 13:16:13 +0100 Subject: [PATCH 024/207] Don't install documentation when INSTALL_LAYOUT=RPM, as the spec file prefers to take docs directly from the source tree. --- CMakeLists.txt | 37 ++++++++++++++++++++++--------------- cmake/install_layout.cmake | 4 ++-- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0445e2a3d5b..c23733d039f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,21 +274,28 @@ ELSE() SET(CPACK_GENERATOR "TGZ") ENDIF() INCLUDE(CPack) -INSTALL(FILES COPYING EXCEPTIONS-CLIENT LICENSE.mysql DESTINATION ${INSTALL_DOCREADMEDIR} OPTIONAL) -INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR}) IF(UNIX) INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR}) - INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) ENDIF() -# MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory -SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") -MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) -INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} - PATTERN "INSTALL-BINARY" EXCLUDE - PATTERN "Makefile.*" EXCLUDE - PATTERN "glibc*" EXCLUDE - PATTERN "linuxthreads.txt" EXCLUDE - PATTERN "myisam.txt" EXCLUDE - PATTERN "mysql.info" EXCLUDE - PATTERN "sp-imp-spec.txt" EXCLUDE -) +# +# RPM installs documentation directly from the source tree +# +IF(NOT INSTALL_LAYOUT MATCHES "RPM") + INSTALL(FILES COPYING EXCEPTIONS-CLIENT LICENSE.mysql DESTINATION ${INSTALL_DOCREADMEDIR} OPTIONAL) + INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR}) + IF(UNIX) + INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR}) + ENDIF() + # MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory + SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") + MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) + INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} + PATTERN "INSTALL-BINARY" EXCLUDE + PATTERN "Makefile.*" EXCLUDE + PATTERN "glibc*" EXCLUDE + PATTERN "linuxthreads.txt" EXCLUDE + PATTERN "myisam.txt" EXCLUDE + PATTERN "mysql.info" EXCLUDE + PATTERN "sp-imp-spec.txt" EXCLUDE + ) +ENDIF() diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 1919aacfe43..8640d8ec315 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -121,8 +121,8 @@ ENDIF() SET(INSTALL_SBINDIR_RPM "sbin") SET(INSTALL_SHAREDIR_RPM "share") # -SET(INSTALL_DOCDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql/doc/MySQL-server-${MYSQL_NO_DASH_VERSION}") -SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") +#SET(INSTALL_DOCDIR_RPM "XXXunset") +#SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") SET(INSTALL_INFODIR_RPM "${INSTALL_SHAREDIR_RPM}/info") SET(INSTALL_MANDIR_RPM "${INSTALL_SHAREDIR_RPM}/man") SET(INSTALL_MYSQLDATADIR_RPM "var") From ebaccc5fb0b6d1ab4cff23499fe5ca17c3d1ae17 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 13:29:02 +0100 Subject: [PATCH 025/207] Current iteration of spec file cleanup. --- support-files/mysql.spec.sh | 47 +++++++++---------------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index e9bb79dbe9d..0a9d1a655a4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -446,8 +446,8 @@ install -m 644 $MBD/debug/libmysqld/libmysqld.a \ mv -v $RBR/%{_libdir}/*.a $RBR/%{_libdir}/mysql/ # Install logrotate and autostart -install -m 644 $MBD/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql -install -m 755 $MBD/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql +install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql +install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql # Create a symlink "rcmysql", pointing to the init.script. SuSE users # will appreciate that, as all services usually offer this. @@ -652,10 +652,11 @@ fi %files server %defattr(-,root,root,0755) -%doc mysql-release-%{mysql_version}/COPYING mysql-release-%{mysql_version}/README -%doc mysql-release-%{mysql_version}/support-files/my-*.cnf +%doc COPYING +%doc README +%doc support-files/my-*.cnf %if %{CLUSTER_BUILD} -%doc mysql-release-%{mysql_version}/support-files/ndb-*.ini +%doc support-files/ndb-*.ini %endif %doc %attr(644, root, root) %{_infodir}/mysql.info* @@ -727,12 +728,12 @@ fi %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/rcmysql -%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so* +#%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/debug/ha_example.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so* +#%attr(755, root, root) %{_libdir}/mysql/plugin/debug/ha_example.so* +#%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so* +#%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so* %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} @@ -832,7 +833,7 @@ fi %files devel %defattr(-, root, root, 0755) -%doc mysql-release-%{mysql_version}/EXCEPTIONS-CLIENT +%doc EXCEPTIONS-CLIENT %doc %attr(644, root, man) %{_mandir}/man1/comp_err.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1* %attr(755, root, root) %{_bindir}/mysql_config @@ -840,39 +841,13 @@ fi %dir %attr(755, root, root) %{_libdir}/mysql %{_includedir}/mysql/* %{_datadir}/aclocal/mysql.m4 -%{_libdir}/mysql/libdbug.a -%{_libdir}/mysql/libheap.a %if %{WITH_LIBGCC} %{_libdir}/mysql/libmygcc.a %endif -%{_libdir}/mysql/libmyisam.a -%{_libdir}/mysql/libmyisammrg.a -%{_libdir}/mysql/libmysqlclient.a -%{_libdir}/mysql/libmysqlclient.la -%{_libdir}/mysql/libmysqlclient_r.a -%{_libdir}/mysql/libmysqlclient_r.la -%{_libdir}/mysql/libmysqlservices.a -%{_libdir}/mysql/libmystrings.a -%{_libdir}/mysql/libmysys.a %if %{CLUSTER_BUILD} %{_libdir}/mysql/libndbclient.a %{_libdir}/mysql/libndbclient.la %endif -%{_libdir}/mysql/libvio.a -%{_libdir}/mysql/libz.a -%{_libdir}/mysql/libz.la -%{_libdir}/mysql/plugin/ha_example.a -%{_libdir}/mysql/plugin/ha_example.la -%{_libdir}/mysql/plugin/semisync_master.a -%{_libdir}/mysql/plugin/semisync_master.la -%{_libdir}/mysql/plugin/semisync_slave.a -%{_libdir}/mysql/plugin/semisync_slave.la -%{_libdir}/mysql/plugin/debug/ha_example.a -%{_libdir}/mysql/plugin/debug/ha_example.la -%{_libdir}/mysql/plugin/debug/semisync_master.a -%{_libdir}/mysql/plugin/debug/semisync_master.la -%{_libdir}/mysql/plugin/debug/semisync_slave.a -%{_libdir}/mysql/plugin/debug/semisync_slave.la %files shared %defattr(-, root, root, 0755) From 48f61d94f74afe2dd8c06cc2b1bfcda48bc20960 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 15:04:39 +0100 Subject: [PATCH 026/207] Expand INSTALL_INFODIR correctly. Make mysql.info optional. --- CMakeLists.txt | 2 +- cmake/install_layout.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c23733d039f..dd4f4a80516 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,7 +275,7 @@ ELSE() ENDIF() INCLUDE(CPack) IF(UNIX) - INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR}) + INSTALL(FILES Docs/mysql.info DESTINATION ${INSTALL_INFODIR} OPTIONAL) ENDIF() # # RPM installs documentation directly from the source tree diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 8640d8ec315..5258da6f40f 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -181,7 +181,7 @@ SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "") # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE # layout is chosen) FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN - MYSQLTEST SQLBENCHROOT DOCREADME SUPPORTFILES MYSQLDATA) + INFO MYSQLTEST SQLBENCHROOT DOCREADME SUPPORTFILES MYSQLDATA) SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} CACHE STRING "${var} installation directory" ${FORCE}) MARK_AS_ADVANCED(INSTALL_${var}DIR) From 0612d16a56808240bef4933c400901a3fb5e2295 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 17:15:34 +0100 Subject: [PATCH 027/207] Fix some paths. --- support-files/mysql.spec.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 0a9d1a655a4..a162c6a03e9 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -652,11 +652,11 @@ fi %files server %defattr(-,root,root,0755) -%doc COPYING -%doc README -%doc support-files/my-*.cnf +%doc %{src_dir}/COPYING +%doc %{src_dir}/README +%doc release/support-files/my-*.cnf %if %{CLUSTER_BUILD} -%doc support-files/ndb-*.ini +%doc release/support-files/ndb-*.ini %endif %doc %attr(644, root, root) %{_infodir}/mysql.info* @@ -703,7 +703,6 @@ fi %attr(755, root, root) %{_bindir}/myisampack %attr(755, root, root) %{_bindir}/mysql_convert_table_format %attr(755, root, root) %{_bindir}/mysql_fix_extensions -%attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables %attr(755, root, root) %{_bindir}/mysql_install_db %attr(755, root, root) %{_bindir}/mysql_secure_installation %attr(755, root, root) %{_bindir}/mysql_setpermission @@ -833,7 +832,7 @@ fi %files devel %defattr(-, root, root, 0755) -%doc EXCEPTIONS-CLIENT +%doc %{src_dir}/EXCEPTIONS-CLIENT %doc %attr(644, root, man) %{_mandir}/man1/comp_err.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1* %attr(755, root, root) %{_bindir}/mysql_config From cda94abe8deda9a13f7d0e9d63fc499bbdf69974 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 25 Mar 2010 19:54:47 +0100 Subject: [PATCH 028/207] Put back libmysqlclient*.a Add ChangeLog. --- support-files/mysql.spec.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 79f7f867f60..823ca2dae08 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -464,6 +464,9 @@ touch $RBR%{_sysconfdir}/my.cnf install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}" %endif +# ChangeLog file is optional, create an empty one if it doesn't exist +[ -f $MBD/%{src_dir}/Docs/ChangeLog ] || >$MBD/%{src_dir}/Docs/ChangeLog + ############################################################################## # Post processing actions, i.e. when installed ############################################################################## @@ -654,6 +657,7 @@ fi %doc %{src_dir}/COPYING %doc %{src_dir}/README +%doc %{src_dir}/Docs/ChangeLog %doc release/support-files/my-*.cnf %if %{CLUSTER_BUILD} %doc release/support-files/ndb-*.ini @@ -838,6 +842,8 @@ fi %{_datadir}/aclocal/mysql.m4 %if %{WITH_LIBGCC} %{_libdir}/mysql/libmygcc.a +%{_libdir}/mysql/libmysqlclient.a +%{_libdir}/mysql/libmysqlclient_r.a %endif %if %{CLUSTER_BUILD} %{_libdir}/mysql/libndbclient.a From dec6ab7b3a9f655ed57b260d7f37aeda3f7f8cb1 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 26 Mar 2010 11:25:02 +0100 Subject: [PATCH 029/207] Move libmysqlclient*.a out of the WITH_LIBGCC section. --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 823ca2dae08..0aa2fb29f23 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -842,9 +842,9 @@ fi %{_datadir}/aclocal/mysql.m4 %if %{WITH_LIBGCC} %{_libdir}/mysql/libmygcc.a +%endif %{_libdir}/mysql/libmysqlclient.a %{_libdir}/mysql/libmysqlclient_r.a -%endif %if %{CLUSTER_BUILD} %{_libdir}/mysql/libndbclient.a %{_libdir}/mysql/libndbclient.la From ddf5d0517a7bc16225e58b6a0190b499a3aceec0 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 26 Mar 2010 16:11:56 +0100 Subject: [PATCH 030/207] Install mtr, mysql-test-run and my_safe_process into the correct locations. --- mysql-test/CMakeLists.txt | 3 ++- mysql-test/lib/My/SafeProcess/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt index 2cc65a9c82f..ce3b684295b 100644 --- a/mysql-test/CMakeLists.txt +++ b/mysql-test/CMakeLists.txt @@ -46,7 +46,8 @@ IF(UNIX) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtr - ${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run DESTINATION mysql-test) + ${CMAKE_CURRENT_BINARY_DIR}/mysql-test-run + DESTINATION ${INSTALL_MYSQLTESTDIR}) ENDIF() IF(CMAKE_GENERATOR MATCHES "Visual Studio") diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt index ec2a13b910c..893e6d896be 100644 --- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt +++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt @@ -20,8 +20,8 @@ ELSE() ADD_EXECUTABLE(my_safe_process safe_process.cc) ENDIF() -INSTALL(TARGETS my_safe_process DESTINATION "mysql-test/lib/My/SafeProcess") +INSTALL(TARGETS my_safe_process DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess") IF(WIN32) - INSTALL(TARGETS my_safe_kill DESTINATION "mysql-test/lib/My/SafeProcess") + INSTALL(TARGETS my_safe_kill DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess") ENDIF() INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess") From 71785753b67ca0ba4af001bc6406a0902d4e61fc Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 26 Mar 2010 17:28:06 +0100 Subject: [PATCH 031/207] Install debug plugins, from wlad. --- cmake/plugin.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 30a7932a0d7..896624996d3 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -174,6 +174,7 @@ MACRO(MYSQL_ADD_PLUGIN) OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}") # Install dynamic library MYSQL_INSTALL_TARGETS(${target} DESTINATION ${INSTALL_PLUGINDIR}) + INSTALL_DEBUG_TARGET(${target} DESTINATION ${INSTALL_PLUGINDIR}/debug) ENDIF() ENDMACRO() From af315a60fa002fee6543df09c514c3813f1e0adf Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 29 Mar 2010 17:01:15 +0200 Subject: [PATCH 032/207] Fix environment setup. Don't create empty ChangeLog. --- support-files/mysql.spec.sh | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 0aa2fb29f23..6ff92e17a17 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -337,23 +337,18 @@ client/server version. # Be strict about variables, bail at earliest opportunity, etc. set -eu -# Use specific MYSQL_BUILD_* setup if requested -${MYSQL_BUILD_PATH:+PATH="${MYSQL_BUILD_PATH}"} -${MYSQL_BUILD_CC:+CC="${MYSQL_BUILD_CC}"} -${MYSQL_BUILD_CC:+CC="${MYSQL_BUILD_CC}"} -${MYSQL_BUILD_CXX:+CXX="${MYSQL_BUILD_CXX}"} -${MYSQL_BUILD_CFLAGS:+CFLAGS="${MYSQL_BUILD_CFLAGS}"} -${MYSQL_BUILD_CXXFLAGS:+CXXFLAGS="${MYSQL_BUILD_CXXFLAGS}"} -${MYSQL_BUILD_LDFLAGS:+LDFLAGS="${MYSQL_BUILD_LDFLAGS}"} -${MYSQL_BUILD_CMAKE:+CMAKE="${MYSQL_BUILD_CMAKE}"} - -# Set defaults. $RPM_OPT_FLAGS should be part of RPM environment -: ${CC:="gcc"} -: ${CXX:="g++"} -: ${CFLAGS:="${RPM_OPT_FLAGS}"} -: ${CXXFLAGS:="${RPM_OPT_FLAGS} -felide-constructors -fno-exceptions -fno-rtti"} -: ${LDFLAGS:=""} -: ${CMAKE:="cmake"} +# +# Set environment in order of preference, MYSQL_BUILD_* first, then +# variable name, finally a default. RPM_OPT_FLAGS is assumed to be +# a part of the default rpm build environment. +# +PATH=${MYSQL_BUILD_PATH:-$PATH} +CC=${MYSQL_BUILD_CC:-${CC:-gcc}} +CXX=${MYSQL_BUILD_CXX:-${CXX:-g++}} +CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}} +CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti}} +LDFLAGS=${MYSQL_BUILD_LDFLAGS:-${LDFLAGS:-}} +CMAKE=${MYSQL_BUILD_CMAKE:-${CMAKE:-cmake}} # Build debug mysqld and libmysqld.a mkdir debug @@ -464,9 +459,6 @@ touch $RBR%{_sysconfdir}/my.cnf install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}" %endif -# ChangeLog file is optional, create an empty one if it doesn't exist -[ -f $MBD/%{src_dir}/Docs/ChangeLog ] || >$MBD/%{src_dir}/Docs/ChangeLog - ############################################################################## # Post processing actions, i.e. when installed ############################################################################## From 483a5b249adb9748de35abf16e6ba82d70e1f259 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 29 Mar 2010 17:54:08 +0200 Subject: [PATCH 033/207] Variables need to be exported so cmake can pick them up. --- support-files/mysql.spec.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 6ff92e17a17..b9adab7ed6d 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -342,13 +342,13 @@ set -eu # variable name, finally a default. RPM_OPT_FLAGS is assumed to be # a part of the default rpm build environment. # -PATH=${MYSQL_BUILD_PATH:-$PATH} -CC=${MYSQL_BUILD_CC:-${CC:-gcc}} -CXX=${MYSQL_BUILD_CXX:-${CXX:-g++}} -CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}} -CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti}} -LDFLAGS=${MYSQL_BUILD_LDFLAGS:-${LDFLAGS:-}} -CMAKE=${MYSQL_BUILD_CMAKE:-${CMAKE:-cmake}} +export PATH=${MYSQL_BUILD_PATH:-$PATH} +export CC=${MYSQL_BUILD_CC:-${CC:-gcc}} +export CXX=${MYSQL_BUILD_CXX:-${CXX:-g++}} +export CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}} +export CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti}} +export LDFLAGS=${MYSQL_BUILD_LDFLAGS:-${LDFLAGS:-}} +export CMAKE=${MYSQL_BUILD_CMAKE:-${CMAKE:-cmake}} # Build debug mysqld and libmysqld.a mkdir debug From 0145b00834024c8ceb9c10b39609cdd61b2816c6 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 11:54:25 +0200 Subject: [PATCH 034/207] Must specify -DDCMAKE_BUILD_TYPE=RelWithDebInfo now that compiler flags are being used correctly. --- support-files/mysql.spec.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b9adab7ed6d..501355497b9 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -368,14 +368,15 @@ mkdir debug -e 's/^ //' \ -e 's/ $//'` ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ - -DCMAKE_BUILD_TYPE=Debug + -DCMAKE_BUILD_TYPE=Debug make VERBOSE=1 mysqld mysqlserver ) # Build full release mkdir release ( cd release - ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM + ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo make VERBOSE=1 ) From d2b8d2487f4afff75e0541bfb8983fe770bfcd6f Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 12:01:30 +0200 Subject: [PATCH 035/207] Default to CXX=gcc --- support-files/mysql.spec.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 501355497b9..8c51cff0929 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -338,13 +338,18 @@ client/server version. set -eu # -# Set environment in order of preference, MYSQL_BUILD_* first, then -# variable name, finally a default. RPM_OPT_FLAGS is assumed to be -# a part of the default rpm build environment. +# Set environment in order of preference, MYSQL_BUILD_* first, then variable +# name, finally a default. RPM_OPT_FLAGS is assumed to be a part of the +# default RPM build environment. +# +# We set CXX=gcc by default to support so-called 'generic' binaries, where we +# do not have a dependancy on libgcc/libstdc++. This only works while we do +# not require C++ features such as exceptions, and may need to be removed at +# a later date. # export PATH=${MYSQL_BUILD_PATH:-$PATH} export CC=${MYSQL_BUILD_CC:-${CC:-gcc}} -export CXX=${MYSQL_BUILD_CXX:-${CXX:-g++}} +export CXX=${MYSQL_BUILD_CXX:-${CXX:-gcc}} export CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}} export CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti}} export LDFLAGS=${MYSQL_BUILD_LDFLAGS:-${LDFLAGS:-}} From 6740352b92a442415d56f85bd0354dad35e464e3 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 12:32:38 +0200 Subject: [PATCH 036/207] Try to fix the debug permissions stuff. --- cmake/install_macros.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 1dcf8b5ca21..a070c316bf2 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -174,7 +174,8 @@ FUNCTION(INSTALL_DEBUG_TARGET target) "" ${ARGN} ) - GET_TARGET_PROPERTY(target_type ${target} TYPE) + GET_TARGET_PROPERTY(target_type ${target} TYPE) + GET_TARGET_PROPERTY(target_permissions ${target} PERMISSIONS) IF(ARG_RENAME) SET(RENAME_PARAM RENAME ${ARG_RENAME}${CMAKE_${target_type}_SUFFIX}) ELSE() @@ -193,6 +194,7 @@ FUNCTION(INSTALL_DEBUG_TARGET target) INSTALL(FILES ${debug_target_location} DESTINATION ${ARG_DESTINATION} ${RENAME_PARAM} + PERMISSIONS ${target_permissions} CONFIGURATIONS Release RelWithDebInfo OPTIONAL) From 2e160175c4552c5cae04af717a7b7a15887fa44d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 13:37:17 +0200 Subject: [PATCH 037/207] Try again.. --- cmake/install_macros.cmake | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index a070c316bf2..da935b71a18 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -175,7 +175,6 @@ FUNCTION(INSTALL_DEBUG_TARGET target) ${ARGN} ) GET_TARGET_PROPERTY(target_type ${target} TYPE) - GET_TARGET_PROPERTY(target_permissions ${target} PERMISSIONS) IF(ARG_RENAME) SET(RENAME_PARAM RENAME ${ARG_RENAME}${CMAKE_${target_type}_SUFFIX}) ELSE() @@ -184,6 +183,11 @@ FUNCTION(INSTALL_DEBUG_TARGET target) IF(NOT ARG_DESTINATION) MESSAGE(FATAL_ERROR "Need DESTINATION parameter for INSTALL_DEBUG_TARGET") ENDIF() + IF(target_type MATCHES "EXECUTABLE") + SET(INSTALL_TYPE TARGETS) + ELSE() + SET(INSTALL_TYPE FILES) + ENDIF() GET_TARGET_PROPERTY(target_location ${target} LOCATION) IF(CMAKE_GENERATOR MATCHES "Makefiles") STRING(REPLACE "${CMAKE_BINARY_DIR}" "${DEBUGBUILDDIR}" debug_target_location "${target_location}") @@ -191,10 +195,9 @@ FUNCTION(INSTALL_DEBUG_TARGET target) STRING(REPLACE "${CMAKE_CFG_INTDIR}" "Debug" debug_target_location "${target_location}" ) ENDIF() - INSTALL(FILES ${debug_target_location} + INSTALL(${INSTALL_TYPE} ${debug_target_location} DESTINATION ${ARG_DESTINATION} ${RENAME_PARAM} - PERMISSIONS ${target_permissions} CONFIGURATIONS Release RelWithDebInfo OPTIONAL) From 98e33d14fac33c0052243930ded85df255304c18 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 17:13:07 +0200 Subject: [PATCH 038/207] Fix from wlad. --- cmake/install_macros.cmake | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index da935b71a18..3350373a2b6 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -195,9 +195,40 @@ FUNCTION(INSTALL_DEBUG_TARGET target) STRING(REPLACE "${CMAKE_CFG_INTDIR}" "Debug" debug_target_location "${target_location}" ) ENDIF() + # Define permissions + # For executable files + SET(PERMISSIONS_EXECUTABLE + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + + # Permissions for shared library (honors CMAKE_INSTALL_NO_EXE which is + # typically set on Debian) + IF(CMAKE_INSTALL_SO_NO_EXE) + SET(PERMISSIONS_SHARED_LIBRARY + PERMISSIONS + OWNER_READ OWNER_WRITE + GROUP_READ + WORLD_READ) + ELSE() + SET(PERMISSIONS_SHARED_LIBRARY ${PERMISSIONS_EXECUTABLE}) + ENDIF() + + # Shared modules get the same permissions as shared libraries + SET(PERMISSIONS_MODULE_LIBRARY ${PERMISSIONS_SHARED_LIBRARY}) + + # Define permissions for static library + SET(PERMISSIONS_STATIC_LIBRARY + PERMISSIONS + OWNER_READ OWNER_WRITE + GROUP_READ + WORLD_READ) + INSTALL(${INSTALL_TYPE} ${debug_target_location} DESTINATION ${ARG_DESTINATION} ${RENAME_PARAM} + ${PERMISSIONS_${target_type}} CONFIGURATIONS Release RelWithDebInfo OPTIONAL) From e28ea740ad5956e2d427e0e8a164a384f9c6c8bd Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 30 Mar 2010 17:24:44 +0200 Subject: [PATCH 039/207] Back out remains of previous attempt. --- cmake/install_macros.cmake | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 3350373a2b6..5be9149b92f 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -183,11 +183,6 @@ FUNCTION(INSTALL_DEBUG_TARGET target) IF(NOT ARG_DESTINATION) MESSAGE(FATAL_ERROR "Need DESTINATION parameter for INSTALL_DEBUG_TARGET") ENDIF() - IF(target_type MATCHES "EXECUTABLE") - SET(INSTALL_TYPE TARGETS) - ELSE() - SET(INSTALL_TYPE FILES) - ENDIF() GET_TARGET_PROPERTY(target_location ${target} LOCATION) IF(CMAKE_GENERATOR MATCHES "Makefiles") STRING(REPLACE "${CMAKE_BINARY_DIR}" "${DEBUGBUILDDIR}" debug_target_location "${target_location}") @@ -225,7 +220,7 @@ FUNCTION(INSTALL_DEBUG_TARGET target) GROUP_READ WORLD_READ) - INSTALL(${INSTALL_TYPE} ${debug_target_location} + INSTALL(FILES ${debug_target_location} DESTINATION ${ARG_DESTINATION} ${RENAME_PARAM} ${PERMISSIONS_${target_type}} From 80fd4bef18258c45abf98ee60c2ad1862d123670 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 31 Mar 2010 11:40:02 +0200 Subject: [PATCH 040/207] Apply wlad fixes from mysql-next-mr-bugfixing --- cmake/install_layout.cmake | 2 +- cmake/install_macros.cmake | 15 +++++++-------- libmysql/CMakeLists.txt | 29 +++++++++++++++++++++++++---- libmysqld/CMakeLists.txt | 5 +++++ libservices/CMakeLists.txt | 1 + 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 5258da6f40f..cb7314d5085 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -171,7 +171,7 @@ SET(MYSQL_DATADIR "/var/lib/mysql") # Clear cached variables if install layout was changed IF(OLD_INSTALL_LAYOUT) - IF(NOT OLD_INSTALL_LAYOUT STREQUAL INSTALL_LAYOUR) + IF(NOT OLD_INSTALL_LAYOUT STREQUAL INSTALL_LAYOUT) SET(FORCE FORCE) ENDIF() ENDIF() diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 5be9149b92f..f049776b8f4 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -43,27 +43,26 @@ ENDMACRO() # Install symbolic link to CMake target. # the link is created in the same directory as target # and extension will be the same as for target file. -MACRO(INSTALL_SYMLINK linkbasename target destination) +MACRO(INSTALL_SYMLINK linkname target destination) IF(UNIX) GET_TARGET_PROPERTY(location ${target} LOCATION) GET_FILENAME_COMPONENT(path ${location} PATH) - GET_FILENAME_COMPONENT(name_we ${location} NAME_WE) - GET_FILENAME_COMPONENT(ext ${location} EXT) - SET(output ${path}/${linkbasename}${ext}) + GET_FILENAME_COMPONENT(name ${location} NAME) + SET(output ${path}/${linkname}) ADD_CUSTOM_COMMAND( OUTPUT ${output} COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${output} COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink - ${name_we}${ext} - ${linkbasename}${ext} + ${name} + ${linkname} WORKING_DIRECTORY ${path} DEPENDS ${target} ) - ADD_CUSTOM_TARGET(symlink_${linkbasename}${ext} + ADD_CUSTOM_TARGET(symlink_${linkname} ALL DEPENDS ${output}) - SET_TARGET_PROPERTIES(symlink_${linkbasename}${ext} PROPERTIES CLEAN_DIRECT_OUTPUT 1) + SET_TARGET_PROPERTIES(symlink_${linkname} PROPERTIES CLEAN_DIRECT_OUTPUT 1) IF(CMAKE_GENERATOR MATCHES "Xcode") # For Xcode, replace project config with install config STRING(REPLACE "${CMAKE_CFG_INTDIR}" diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index f9fc5355641..26af9c80a2b 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -153,15 +153,26 @@ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES}) # Merge several convenience libraries into one big mysqlclient # and link them together into shared library. MERGE_LIBRARIES(mysqlclient STATIC ${LIBS}) -IF(UNIX) - INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r mysqlclient ${INSTALL_LIBDIR}) -ENDIF() # Visual Studio users need debug static library for debug projects IF(MSVC) INSTALL_DEBUG_TARGET(mysqlclient DESTINATION ${INSTALL_LIBDIR}/debug) ENDIF() +IF(UNIX) + MACRO(GET_VERSIONED_LIBNAME LIBNAME EXTENSION VERSION OUTNAME) + SET(DOT_VERSION ".${VERSION}") + IF(DOT_VERSION STREQUAL ".") + SET(DOT_VERSION "") + ENDIF() + IF(APPLE) + SET(${OUTNAME} ${LIBNAME}${DOT_VERSION}${EXTENSION}) + ELSE() + SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION}) + ENDIF() + ENDMACRO() +ENDIF() + IF(NOT DISABLE_SHARED) MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}) IF(UNIX) @@ -182,6 +193,16 @@ IF(NOT DISABLE_SHARED) #(mysqlclient in this case) SET_TARGET_PROPERTIES(mysqlclient PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1) - INSTALL_SYMLINK(${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r libmysql ${INSTALL_LIBDIR}) + + # Install 3 links to libmysqlclient.so (client_r) + FOREACH(ver "" "${SHARED_LIB_MAJOR_VERSION}" + "${SHARED_LIB_MAJOR_VERSION}.0.0") + GET_VERSIONED_LIBNAME( + "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" + "${CMAKE_SHARED_LIBRARY_SUFFIX}" + "${ver}" + linkname) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR}) + ENDFOREACH() ENDIF() ENDIF() diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index e5f2a8b56f9..26332cab61b 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -131,6 +131,11 @@ IF(MSVC) INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR}/debug) ENDIF() +IF(UNIX) + INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME + ${CMAKE_STATIC_LIBRARY_PREFIX}/mysqld-debug) +ENDIF() + IF(MSVC AND NOT DISABLE_SHARED) MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}) ENDIF() diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index ddfa2495ade..da84368b46c 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -18,3 +18,4 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c) ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES}) +INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR}) From 719d62a3dd3e77857d373366311cb5449e492573 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 31 Mar 2010 12:04:21 +0200 Subject: [PATCH 041/207] Fix socket path in RPMs. XXX should be put into cmake/* somewhere. --- support-files/mysql.spec.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8c51cff0929..b31c7551951 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -372,16 +372,20 @@ mkdir debug -e 's/ -ip / /' \ -e 's/^ //' \ -e 's/ $//'` + # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included before + # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ - -DCMAKE_BUILD_TYPE=Debug + -DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" -DCMAKE_BUILD_TYPE=Debug make VERBOSE=1 mysqld mysqlserver ) # Build full release mkdir release ( cd release + # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included before + # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" -DCMAKE_BUILD_TYPE=RelWithDebInfo make VERBOSE=1 ) From 2f71bf43efb719cbcf835a752b613c4c847601af Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 31 Mar 2010 19:04:22 +0200 Subject: [PATCH 042/207] Put back libmysqlclient_r.a, not sure it was supposed to be removed. Remove libmysqld-debug.a, it doesn't exist in current packages? --- libmysql/CMakeLists.txt | 1 + support-files/mysql.spec.sh | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 26af9c80a2b..d448f72b0c2 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -171,6 +171,7 @@ IF(UNIX) SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION}) ENDIF() ENDMACRO() + INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r mysqlclient ${INSTALL_LIBDIR}) ENDIF() IF(NOT DISABLE_SHARED) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b31c7551951..c44181c2597 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -440,11 +440,6 @@ install -d $RBR%{_sbindir} make DESTDIR=$RBR install ) -# FIXME: kent attempted to have debug libmysqld.a installed automatically but -# FIXME: could not get it working, so do it manually for now -install -m 644 $MBD/debug/libmysqld/libmysqld.a \ - $RBR%{_libdir}/mysql/libmysqld-debug.a - # FIXME: at some point we should stop doing this and just install everything # FIXME: directly into %{_libdir}/mysql - perhaps at the same time as renaming # FIXME: the shared libraries to use libmysql*-$major.$minor.so syntax From e3cda8a342671a8c7e97f7880eada204733db6e4 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 31 Mar 2010 20:33:28 +0200 Subject: [PATCH 043/207] Need to add .a extension now. --- libmysql/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index d448f72b0c2..1193b9d7e27 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -171,7 +171,7 @@ IF(UNIX) SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION}) ENDIF() ENDMACRO() - INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r mysqlclient ${INSTALL_LIBDIR}) + INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR}) ENDIF() IF(NOT DISABLE_SHARED) From f0856cc114a198a8cb269989db439c9f33a46532 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 31 Mar 2010 23:52:49 +0200 Subject: [PATCH 044/207] Try a bunch of fixes. --- libmysqld/CMakeLists.txt | 2 +- scripts/CMakeLists.txt | 3 +-- support-files/mysql.spec.sh | 14 ++++++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 26332cab61b..08f9dcbb92a 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -133,7 +133,7 @@ ENDIF() IF(UNIX) INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME - ${CMAKE_STATIC_LIBRARY_PREFIX}/mysqld-debug) + ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug) ENDIF() IF(MSVC AND NOT DISABLE_SHARED) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index e6ce5717d95..e85928a5c42 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -298,14 +298,13 @@ ELSE() mysql_secure_installation mysql_zap mysqlaccess + mysqlaccess.conf mysqlbug mysql_convert_table_format mysql_find_rows mysqlhotcopy mysqldumpslow mysqld_multi - mysqlaccess - mysqlaccess.conf mysqld_safe ) FOREACH(file ${BIN_SCRIPTS}) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index c44181c2597..1960a187931 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -401,21 +401,21 @@ mkdir -p $RBR%{_libdir}/mysql # check for "icc". (If we don't check, the "--print-libgcc-file" call will fail.) if expr "$CC" : ".*icc.*" > /dev/null ; then - %define WITH_LIBGCC 0 + %global WITH_LIBGCC 0 : elif expr "$CC" : ".*gcc.*" > /dev/null ; then libgcc=`$CC $CFLAGS --print-libgcc-file` if [ -f $libgcc ] then - %define WITH_LIBGCC 1 + %global WITH_LIBGCC 1 install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a else - %define WITH_LIBGCC 0 + %global WITH_LIBGCC 0 : fi else - %define WITH_LIBGCC 0 + %global WITH_LIBGCC 0 : fi @@ -728,6 +728,7 @@ fi %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/rcmysql +%attr(755, root, root) %{_libdir}/mysql/plugin/mypluglib.so %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* @@ -747,6 +748,8 @@ fi %attr(755, root, root) %{_bindir}/mysql_find_rows %attr(755, root, root) %{_bindir}/mysql_waitpid %attr(755, root, root) %{_bindir}/mysqlaccess +# XXX: Silly place to put this script +%attr(644, root, root) %{_bindir}/mysqlaccess.conf %attr(755, root, root) %{_bindir}/mysqladmin %attr(755, root, root) %{_bindir}/mysqlbinlog %attr(755, root, root) %{_bindir}/mysqlcheck @@ -842,6 +845,7 @@ fi %endif %{_libdir}/mysql/libmysqlclient.a %{_libdir}/mysql/libmysqlclient_r.a +%{_libdir}/mysql/libmysqlservices.a %if %{CLUSTER_BUILD} %{_libdir}/mysql/libndbclient.a %{_libdir}/mysql/libndbclient.la @@ -872,7 +876,9 @@ fi %if %{EMBEDDED_BUILD} %files embedded %defattr(-, root, root, 0755) +%attr(755, root, root) %{_bindir}/mysql_embedded %attr(644, root, root) %{_libdir}/mysql/libmysqld.a +%attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a %endif ############################################################################## From 515de61347a603219789d15b8ab1b8f55b5b5254 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 02:20:41 +0200 Subject: [PATCH 045/207] Try some more fixes. --- support-files/mysql.spec.sh | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1960a187931..f74fb894cf0 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -68,6 +68,9 @@ %undefine __perl_provides %undefine __perl_requires +# Set default +%global WITH_LIBGCC 0 + ############################################################################## # Command line handling ############################################################################## @@ -397,26 +400,14 @@ RBR=$RPM_BUILD_ROOT mkdir -p $RBR%{_libdir}/mysql # For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) -# Some "icc" calls may have "gcc" in the argument string, so we should first -# check for "icc". (If we don't check, the "--print-libgcc-file" call will fail.) -if expr "$CC" : ".*icc.*" > /dev/null ; -then - %global WITH_LIBGCC 0 - : -elif expr "$CC" : ".*gcc.*" > /dev/null ; +if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 then libgcc=`$CC $CFLAGS --print-libgcc-file` if [ -f $libgcc ] then - %global WITH_LIBGCC 1 + %define WITH_LIBGCC 1 install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a - else - %global WITH_LIBGCC 0 - : fi -else - %global WITH_LIBGCC 0 - : fi ############################################################################## @@ -464,6 +455,10 @@ touch $RBR%{_sysconfdir}/my.cnf install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}" %endif +# Remove man pages we explicitly do not want to package, avoids 'unpackaged +# files' warning. +rm -f $RBR%{_mandir}/man1/make_win_bin_dist.1* + ############################################################################## # Post processing actions, i.e. when installed ############################################################################## From 8c750455fce32cec5885823b3cb1e8df854c3321 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 10:32:29 +0200 Subject: [PATCH 046/207] Just put libs in %{_libdir}. Can't see how mysqld_safe can work with current setup, so make it look in $pkglibdir/mysql too. Other cleanups. --- scripts/mysqld_safe.sh | 2 +- support-files/mysql.spec.sh | 32 +++++++++++--------------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 5420ebd908e..019706467b0 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -306,7 +306,7 @@ set_malloc_lib() { malloc_lib= # This list is kept intentionally simple. Simply set --malloc-lib # to a full path if another location is desired. - for libdir in /usr/lib "$pkglibdir"; do + for libdir in /usr/lib "$pkglibdir" "$pkglibdir/mysql"; do for flavor in _minimal '' _and_profiler _debug; do tmp="$libdir/libtcmalloc$flavor.so" #log_notice "DEBUG: Checking for malloc lib '$tmp'" diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index f74fb894cf0..d1623d13e8b 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -68,7 +68,7 @@ %undefine __perl_provides %undefine __perl_requires -# Set default +# Variables which need to be global so they can be changed during phases. %global WITH_LIBGCC 0 ############################################################################## @@ -397,7 +397,6 @@ RBR=$RPM_BUILD_ROOT # Clean up the BuildRoot first [ "$RBR" != "/" ] && [ -d "$RBR" ] && rm -rf "$RBR"; -mkdir -p $RBR%{_libdir}/mysql # For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 @@ -406,7 +405,7 @@ then if [ -f $libgcc ] then %define WITH_LIBGCC 1 - install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a + install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a fi fi @@ -431,11 +430,6 @@ install -d $RBR%{_sbindir} make DESTDIR=$RBR install ) -# FIXME: at some point we should stop doing this and just install everything -# FIXME: directly into %{_libdir}/mysql - perhaps at the same time as renaming -# FIXME: the shared libraries to use libmysql*-$major.$minor.so syntax -mv -v $RBR/%{_libdir}/*.a $RBR/%{_libdir}/mysql/ - # Install logrotate and autostart install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql @@ -716,10 +710,6 @@ fi %attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/resolveip -%if %{WITH_TCMALLOC} -%attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} -%endif - %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/rcmysql @@ -743,7 +733,7 @@ fi %attr(755, root, root) %{_bindir}/mysql_find_rows %attr(755, root, root) %{_bindir}/mysql_waitpid %attr(755, root, root) %{_bindir}/mysqlaccess -# XXX: Silly place to put this script +# XXX: This should be moved to %{_sysconfdir} %attr(644, root, root) %{_bindir}/mysqlaccess.conf %attr(755, root, root) %{_bindir}/mysqladmin %attr(755, root, root) %{_bindir}/mysqlbinlog @@ -836,14 +826,14 @@ fi %{_includedir}/mysql/* %{_datadir}/aclocal/mysql.m4 %if %{WITH_LIBGCC} -%{_libdir}/mysql/libmygcc.a +%{_libdir}/libmygcc.a %endif -%{_libdir}/mysql/libmysqlclient.a -%{_libdir}/mysql/libmysqlclient_r.a -%{_libdir}/mysql/libmysqlservices.a +%{_libdir}/libmysqlclient.a +%{_libdir}/libmysqlclient_r.a +%{_libdir}/libmysqlservices.a %if %{CLUSTER_BUILD} -%{_libdir}/mysql/libndbclient.a -%{_libdir}/mysql/libndbclient.la +%{_libdir}/libndbclient.a +%{_libdir}/libndbclient.la %endif %files shared @@ -872,8 +862,8 @@ fi %files embedded %defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/mysql_embedded -%attr(644, root, root) %{_libdir}/mysql/libmysqld.a -%attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a +%attr(644, root, root) %{_libdir}/libmysqld.a +%attr(644, root, root) %{_libdir}/libmysqld-debug.a %endif ############################################################################## From 346c2b7afaa1e085c390fb1decddbc36b29cb929 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 12:18:51 +0200 Subject: [PATCH 047/207] We do need the mkdir. --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index d1623d13e8b..b92db0e7912 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -405,6 +405,7 @@ then if [ -f $libgcc ] then %define WITH_LIBGCC 1 + mkdir -p $RBR%{_libdir} install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a fi fi From 2785be2d708c17dc9138b9f58f288cbe4f660ee3 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 12:24:00 +0200 Subject: [PATCH 048/207] Actually, move the libgcc stuff to %install where it belongs. --- support-files/mysql.spec.sh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b92db0e7912..57ea4b344b7 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -398,18 +398,6 @@ RBR=$RPM_BUILD_ROOT # Clean up the BuildRoot first [ "$RBR" != "/" ] && [ -d "$RBR" ] && rm -rf "$RBR"; -# For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) -if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 -then - libgcc=`$CC $CFLAGS --print-libgcc-file` - if [ -f $libgcc ] - then - %define WITH_LIBGCC 1 - mkdir -p $RBR%{_libdir} - install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a - fi -fi - ############################################################################## %install @@ -431,6 +419,17 @@ install -d $RBR%{_sbindir} make DESTDIR=$RBR install ) +# For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) +if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 +then + libgcc=`$CC $CFLAGS --print-libgcc-file` + if [ -f $libgcc ] + then + %define WITH_LIBGCC 1 + install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a + fi +fi + # Install logrotate and autostart install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql From f037ad4fbf1ed87254d36e94f4368cfb348d8248 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 13:35:16 +0200 Subject: [PATCH 049/207] Try to fix datadir --- CMakeLists.txt | 7 +++++-- cmake/install_layout.cmake | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd4f4a80516..889dc463769 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,8 +189,11 @@ ELSE() ENDIF() SET(DEFAULT_BASEDIR "${DEFAULT_MYSQL_HOME}") -SET(MYSQL_DATADIR "${DEFAULT_MYSQL_HOME}/${INSTALL_MYSQLDATADIR}" CACHE PATH - "default MySQL data directory") +IF(INSTALL_MYSQLDATADIR MATCHES "^/.*") + SET(MYSQL_DATADIR ${INSTALL_MYSQLDATADIR} CACHE PATH "default MySQL data directory") +ELSE() + SET(MYSQL_DATADIR "${DEFAULT_MYSQL_HOME}/${INSTALL_MYSQLDATADIR}" CACHE PATH "default MySQL data directory") +ENDIF() SET(DEFAULT_CHARSET_HOME "${DEFAULT_MYSQL_HOME}") SET(PLUGINDIR "${DEFAULT_MYSQL_HOME}/${INSTALL_PLUGINDIR}") IF(SYSCONFDIR) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index cb7314d5085..619f40c5774 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -125,7 +125,7 @@ SET(INSTALL_SHAREDIR_RPM "share") #SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") SET(INSTALL_INFODIR_RPM "${INSTALL_SHAREDIR_RPM}/info") SET(INSTALL_MANDIR_RPM "${INSTALL_SHAREDIR_RPM}/man") -SET(INSTALL_MYSQLDATADIR_RPM "var") +SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") SET(INSTALL_MYSQLSHAREDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") SET(INSTALL_MYSQLTESTDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql-test") SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/mysql/plugin") @@ -167,7 +167,7 @@ SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") SET(INSTALL_DOCREADMEDIR_SVR4 ".") SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") -SET(MYSQL_DATADIR "/var/lib/mysql") +SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") # Clear cached variables if install layout was changed IF(OLD_INSTALL_LAYOUT) From 5f1e75d58459048aceaa869709e0da52122472f7 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 13:48:44 +0200 Subject: [PATCH 050/207] Put libmygcc back in %build, needs $CC etc of course... --- support-files/mysql.spec.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 57ea4b344b7..1b6ca25234f 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -398,6 +398,19 @@ RBR=$RPM_BUILD_ROOT # Clean up the BuildRoot first [ "$RBR" != "/" ] && [ -d "$RBR" ] && rm -rf "$RBR"; +# For gcc builds, include libgcc.a in the devel subpackage (BUG 4921). This +# needs to be in %build as $CC is not set in %install. +if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 +then + libgcc=`$CC $CFLAGS --print-libgcc-file` + if [ -f $libgcc ] + then + %define WITH_LIBGCC 1 + mkdir -p $RBR%{_libdir} + install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a + fi +fi + ############################################################################## %install @@ -419,17 +432,6 @@ install -d $RBR%{_sbindir} make DESTDIR=$RBR install ) -# For gcc builds, include libgcc.a in the devel subpackage (BUG 4921) -if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 -then - libgcc=`$CC $CFLAGS --print-libgcc-file` - if [ -f $libgcc ] - then - %define WITH_LIBGCC 1 - install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a - fi -fi - # Install logrotate and autostart install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql From 5593e29304b08652f5249bcee223655cb98e896b Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 14:56:25 +0200 Subject: [PATCH 051/207] Fix SVR4 datadir --- cmake/install_layout.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 619f40c5774..79eec502995 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -167,7 +167,7 @@ SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") SET(INSTALL_DOCREADMEDIR_SVR4 ".") SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") -SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") +SET(INSTALL_MYSQLDATADIR_SVR4 "/var/lib/mysql") # Clear cached variables if install layout was changed IF(OLD_INSTALL_LAYOUT) From 8148145929113d554ee06a3040cbc445361877eb Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 15:10:05 +0200 Subject: [PATCH 052/207] RPM doesn't like %install in comments, doh --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1b6ca25234f..a7bd6fe8234 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -399,7 +399,7 @@ RBR=$RPM_BUILD_ROOT [ "$RBR" != "/" ] && [ -d "$RBR" ] && rm -rf "$RBR"; # For gcc builds, include libgcc.a in the devel subpackage (BUG 4921). This -# needs to be in %build as $CC is not set in %install. +# needs to be during build phase as $CC is not set during install. if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 then libgcc=`$CC $CFLAGS --print-libgcc-file` From bbe86d08ba83425423c70b29d1ca757bf57a5e34 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 1 Apr 2010 20:47:19 +0200 Subject: [PATCH 053/207] Expand @HOSTNAME@. --- scripts/CMakeLists.txt | 5 ++--- support-files/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index e85928a5c42..bfe65a0acd8 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -134,11 +134,10 @@ ELSE() SET(CHECK_PID "kill -s SIGCONT $PID > /dev/null 2> /dev/null") ENDIF() +SET(HOSTNAME "hostname") + ENDIF(UNIX) - - - # Really ugly, one script, "mysql_install_db", needs prefix set to ".", # i.e. makes access relative the current directory. This matches # the documentation, so better not change this. diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 9cd373c6e9c..d748b4b195c 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -29,6 +29,7 @@ ELSE() SET(CXXFLAGS ${CMAKE_CXX_FLAGS}) SET(MYSQLD_USER "mysql") SET(ini_file_extension "cnf") + SET(HOSTNAME "hostname") ENDIF() # XXX: shouldn't we just have variables for all this stuff and centralise From 478c27599a74ab393bb769f9a8ec4b236c5cb8d9 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 8 Apr 2010 12:30:04 +0200 Subject: [PATCH 054/207] Revert library changes, let's just stick with keeping to existing setup for now, leave large changes to later. --- support-files/mysql.spec.sh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index a7bd6fe8234..8dba4fb4277 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -406,8 +406,8 @@ then if [ -f $libgcc ] then %define WITH_LIBGCC 1 - mkdir -p $RBR%{_libdir} - install -m 644 $libgcc $RBR%{_libdir}/libmygcc.a + mkdir -p $RBR%{_libdir}/mysql + install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a fi fi @@ -432,6 +432,11 @@ install -d $RBR%{_sbindir} make DESTDIR=$RBR install ) +# FIXME: at some point we should stop doing this and just install everything +# FIXME: directly into %{_libdir}/mysql - perhaps at the same time as renaming +# FIXME: the shared libraries to use libmysql*-$major.$minor.so syntax +mv -v $RBR/%{_libdir}/*.a $RBR/%{_libdir}/mysql/ + # Install logrotate and autostart install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql @@ -828,14 +833,14 @@ fi %{_includedir}/mysql/* %{_datadir}/aclocal/mysql.m4 %if %{WITH_LIBGCC} -%{_libdir}/libmygcc.a +%{_libdir}/mysql/libmygcc.a %endif -%{_libdir}/libmysqlclient.a -%{_libdir}/libmysqlclient_r.a -%{_libdir}/libmysqlservices.a +%{_libdir}/mysql/libmysqlclient.a +%{_libdir}/mysql/libmysqlclient_r.a +%{_libdir}/mysql/libmysqlservices.a %if %{CLUSTER_BUILD} -%{_libdir}/libndbclient.a -%{_libdir}/libndbclient.la +%{_libdir}/mysql/libndbclient.a +%{_libdir}/mysql/libndbclient.la %endif %files shared @@ -864,8 +869,8 @@ fi %files embedded %defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/mysql_embedded -%attr(644, root, root) %{_libdir}/libmysqld.a -%attr(644, root, root) %{_libdir}/libmysqld-debug.a +%attr(644, root, root) %{_libdir}/mysql/libmysqld.a +%attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a %endif ############################################################################## From fe1030303a05e0c743222a34ae773e6090e81ff5 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 8 Apr 2010 15:21:31 +0200 Subject: [PATCH 055/207] Fix gcc check, SuSE doesn't print (GCC) anywhere. Get rid of WITH_LIBGCC %define, it isn't subject to shell rules and is parsed anyway. Instead create a file with optional files to include. --- support-files/mysql.spec.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8dba4fb4277..f7fe9f598b4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -68,9 +68,6 @@ %undefine __perl_provides %undefine __perl_requires -# Variables which need to be global so they can be changed during phases. -%global WITH_LIBGCC 0 - ############################################################################## # Command line handling ############################################################################## @@ -340,6 +337,9 @@ client/server version. # Be strict about variables, bail at earliest opportunity, etc. set -eu +# Optional files to include +touch optional-server-files + # # Set environment in order of preference, MYSQL_BUILD_* first, then variable # name, finally a default. RPM_OPT_FLAGS is assumed to be a part of the @@ -400,14 +400,14 @@ RBR=$RPM_BUILD_ROOT # For gcc builds, include libgcc.a in the devel subpackage (BUG 4921). This # needs to be during build phase as $CC is not set during install. -if "$CC" --version | grep '(GCC)' >/dev/null 2>&1 +if "$CC" -v | grep '^gcc.version' >/dev/null 2>&1 then libgcc=`$CC $CFLAGS --print-libgcc-file` if [ -f $libgcc ] then - %define WITH_LIBGCC 1 mkdir -p $RBR%{_libdir}/mysql install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a + echo "%{_libdir}/mysql/libmygcc.a" >>optional-server-files fi fi @@ -645,7 +645,7 @@ fi # Files section ############################################################################## -%files server +%files server -f optional-server-files %defattr(-,root,root,0755) %doc %{src_dir}/COPYING @@ -832,9 +832,6 @@ fi %dir %attr(755, root, root) %{_libdir}/mysql %{_includedir}/mysql/* %{_datadir}/aclocal/mysql.m4 -%if %{WITH_LIBGCC} -%{_libdir}/mysql/libmygcc.a -%endif %{_libdir}/mysql/libmysqlclient.a %{_libdir}/mysql/libmysqlclient_r.a %{_libdir}/mysql/libmysqlservices.a From bdcac621104819fd1fd6e250fe9cb5f2e5e421cc Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 8 Apr 2010 15:32:15 +0200 Subject: [PATCH 056/207] Remove _unpackaged_files_terminate_build=0, we should not ignore errors. --- support-files/mysql.spec.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index f7fe9f598b4..663b9bf15e4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -49,12 +49,6 @@ # ------------------------------------------------------------------------------ %define __os_install_post /usr/lib/rpm/brp-compress -# ------------------------------------------------------------------------------ -# We don't package all files installed into the build root by intention - -# See BUG#998 for details. -# ------------------------------------------------------------------------------ -%define _unpackaged_files_terminate_build 0 - # ------------------------------------------------------------------------------ # RPM build tools now automatically detects Perl module dependencies. This # detection gives problems as it is broken in some versions, and it also From 7d9c661c05ee6e4a437e96316e9a0c092e454209 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 9 Apr 2010 17:22:31 +0200 Subject: [PATCH 057/207] Combined spec file. --- support-files/mysql.spec.sh | 466 ++++++++++++++++++++---------------- 1 file changed, 257 insertions(+), 209 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 663b9bf15e4..b6106783a71 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -10,7 +10,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the +# along with this program; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1301 USA. @@ -20,119 +20,177 @@ # NOTE: "vendor" is used in upgrade/downgrade check, so you can't # change these, has to be exactly as is. -%define mysql_old_vendor MySQL AB -%define mysql_vendor_2 Sun Microsystems, Inc. -%define mysql_vendor Oracle and/or its affiliates +%define mysql_old_vendor MySQL AB +%define mysql_vendor_2 Sun Microsystems, Inc. +%define mysql_vendor Oracle and/or its affiliates -%define mysql_version @VERSION@ +%define mysql_license GPL +%define mysql_version @VERSION@ -%define mysqld_user mysql -%define mysqld_group mysql -%define mysqldatadir /var/lib/mysql -%define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com +%define mysqld_user mysql +%define mysqld_group mysql +%define mysqldatadir /var/lib/mysql -# ------------------------------------------------------------------------------ -# On SuSE 9 no separate "debuginfo" package is built. To enable basic -# debugging on that platform, we don't strip binaries on SuSE 9. We -# disable the strip of binaries by redefining the RPM macro -# "__os_install_post" leaving out the script calls that normally does -# this. We do this in all cases, as on platforms where "debuginfo" is -# created, a script "find-debuginfo.sh" will be called that will do -# the strip anyway, part of separating the executable and debug -# information into separate files put into separate packages. -# -# Some references (shows more advanced conditional usage): -# http://www.redhat.com/archives/rpm-list/2001-November/msg00257.html -# http://www.redhat.com/archives/rpm-list/2003-February/msg00275.html -# http://www.redhat.com/archives/rhl-devel-list/2004-January/msg01546.html -# http://lists.opensuse.org/archive/opensuse-commit/2006-May/1171.html -# ------------------------------------------------------------------------------ -%define __os_install_post /usr/lib/rpm/brp-compress +%define release 1 -# ------------------------------------------------------------------------------ -# RPM build tools now automatically detects Perl module dependencies. This -# detection gives problems as it is broken in some versions, and it also -# give unwanted dependencies from mandatory scripts in our package. -# Might not be possible to disable in all RPM tool versions, but here we -# try. We keep the "AutoReqProv: no" for the "test" sub package, as disabling -# here might fail, and that package has the most problems. -# See http://fedoraproject.org/wiki/Packaging/Perl#Filtering_Requires:_and_Provides -# http://www.wideopen.com/archives/rpm-list/2002-October/msg00343.html -# ------------------------------------------------------------------------------ +# ---------------------------------------------------------------------------- +# RPM build tools now automatically detect Perl module dependencies. This +# detection causes problems as it is broken in some versions, and it also +# provides unwanted dependencies from mandatory scripts in our package. +# It might not be possible to disable this in all versions of RPM, but here we +# try anyway. We keep the "AutoReqProv: no" for the "test" sub package, as +# disabling here might fail, and that package has the most problems. +# See: +# http://fedoraproject.org/wiki/Packaging/Perl#Filtering_Requires:_and_Provides +# http://www.wideopen.com/archives/rpm-list/2002-October/msg00343.html +# ---------------------------------------------------------------------------- %undefine __perl_provides %undefine __perl_requires ############################################################################## # Command line handling ############################################################################## +# +# To enable the following options: +# +# $ rpmbuild --with \n") FILE(READ directories.wxs CPACK_WIX_DIRECTORIES) FILE(REMOVE directories.wxs) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in - ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) - - -SET(WXS_FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs ${CPACK_WIX_EXTRA_SOURCE}) -SET(WIXOBJ_NATIVE_FILES) -SET(WXS_NATIVE_FILES) -FOREACH(f "${WXS_FILES}") - FILE(TO_NATIVE_PATH "${f}" f) - EXECUTE_PROCESS(COMMAND ${CANDLE_EXECUTABLE} ${f}) - STRING(REPLACE ".wxs" ".wixobj" f "${f}") - LIST(APPEND WIXOBJ_NATIVE_FILES ${f}) + +FOREACH(src ${CPACK_WIX_INCLUDE}) +SET(CPACK_WIX_INCLUDES +"${CPACK_WIX_INCLUDES} + " +) ENDFOREACH() + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) + +FILE(REMOVE mysql_server.wixobj) EXECUTE_PROCESS( - COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension ${WIXOBJ_NATIVE_FILES} -out ${CPACK_PACKAGE_FILE_NAME}.msi + COMMAND ${CANDLE_EXECUTABLE} -ext WixUtilExtension mysql_server.wxs +) +EXECUTE_PROCESS( + COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension + mysql_server.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi ) diff --git a/packaging/WiX/extra.wxs.in b/packaging/WiX/extra.wxs.in index b1286bfba61..78e6f96dbcc 100644 --- a/packaging/WiX/extra.wxs.in +++ b/packaging/WiX/extra.wxs.in @@ -1,32 +1,85 @@ - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @DATADIR_MYSQL_FILES@ + + + + + @DATADIR_PERFORMANCE_SCHEMA_FILES@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index 30baefbf64b..8c2b839c6e7 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -1,4 +1,5 @@ - + @CPACK_WIX_COMPONENT_GROUPS@ + + @CPACK_WIX_INCLUDES@ - + + \ No newline at end of file From 23ab4ab1d011ae5a5652987631c354a796f09d34 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 26 Apr 2010 13:32:54 +0200 Subject: [PATCH 088/207] Try to fix libmysqlclient symlinks on per-OS basis. --- libmysql/CMakeLists.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 1193b9d7e27..0690211f981 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -177,10 +177,18 @@ ENDIF() IF(NOT DISABLE_SHARED) MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}) IF(UNIX) + # libtool compatability + IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE) + SET(OS_SHARED_LIB_VERSION "${SHARED_LIB_MAJOR_VERSION}") + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "HP-UX") + SET(OS_SHARED_LIB_VERSION "${SHARED_LIB_MAJOR_VERSION}.0") + ELSE() + SET(OS_SHARED_LIB_VERSION "${SHARED_LIB_MAJOR_VERSION}.0.0") + ENDIF() # Name of shared library is mysqlclient on Unix SET_TARGET_PROPERTIES(libmysql PROPERTIES OUTPUT_NAME mysqlclient - VERSION "${SHARED_LIB_MAJOR_VERSION}.0.0" + VERSION "${OS_SHARED_LIB_VERSION}" SOVERSION "${SHARED_LIB_MAJOR_VERSION}") IF(LINK_FLAG_NO_UNDEFINED) GET_TARGET_PROPERTY(libmysql_link_flags libmysql LINK_FLAGS) @@ -196,8 +204,7 @@ IF(NOT DISABLE_SHARED) SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1) # Install 3 links to libmysqlclient.so (client_r) - FOREACH(ver "" "${SHARED_LIB_MAJOR_VERSION}" - "${SHARED_LIB_MAJOR_VERSION}.0.0") + FOREACH(ver "" "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") GET_VERSIONED_LIBNAME( "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" "${CMAKE_SHARED_LIBRARY_SUFFIX}" From ce5cd7bc8ec237f04550a41f30cf98fd6832b3ff Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 26 Apr 2010 14:51:01 +0200 Subject: [PATCH 089/207] Remove duplicates. --- libmysql/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 0690211f981..7eb42b3367c 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -203,8 +203,10 @@ IF(NOT DISABLE_SHARED) SET_TARGET_PROPERTIES(mysqlclient PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1) - # Install 3 links to libmysqlclient.so (client_r) - FOREACH(ver "" "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") + # Install links to libmysqlclient.so (client_r) + SET(OS_SHARED_LIB_SYMLINKS "" "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") + LIST(REMOVE_DUPLICATES OS_SHARED_LIB_SYMLINKS) + FOREACH(ver ${OS_SHARED_LIB_SYMLINKS}) GET_VERSIONED_LIBNAME( "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" "${CMAKE_SHARED_LIBRARY_SUFFIX}" From 4542bc32406f09b9733233a06bd9c5c37165d0b3 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 26 Apr 2010 18:06:59 +0200 Subject: [PATCH 090/207] Try new RPM layout. Fix libmysqlclient_r symlinks. --- libmysql/CMakeLists.txt | 18 +++++++---- support-files/mysql.spec.sh | 61 +++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 7eb42b3367c..cd23f825b9e 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -204,14 +204,20 @@ IF(NOT DISABLE_SHARED) SET_TARGET_PROPERTIES(libmysql PROPERTIES CLEAN_DIRECT_OUTPUT 1) # Install links to libmysqlclient.so (client_r) - SET(OS_SHARED_LIB_SYMLINKS "" "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") + GET_VERSIONED_LIBNAME( + "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" + "${CMAKE_SHARED_LIBRARY_SUFFIX}" + "" + linkname) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR}) + SET(OS_SHARED_LIB_SYMLINKS "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") LIST(REMOVE_DUPLICATES OS_SHARED_LIB_SYMLINKS) FOREACH(ver ${OS_SHARED_LIB_SYMLINKS}) - GET_VERSIONED_LIBNAME( - "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" - "${CMAKE_SHARED_LIBRARY_SUFFIX}" - "${ver}" - linkname) + GET_VERSIONED_LIBNAME( + "${CMAKE_SHARED_LIBRARY_PREFIX}mysqlclient_r" + "${CMAKE_SHARED_LIBRARY_SUFFIX}" + "${ver}" + linkname) INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR}) ENDFOREACH() ENDIF() diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b1fbc90d829..8520057b71a 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -168,6 +168,14 @@ %define distro_requires coreutils grep procps /sbin/chkconfig /usr/sbin/useradd /usr/sbin/groupadd %endif +# Turn on debuginfo RPMs for SuSE >= 10 +%define debugrpm 0 +%if %{defined suse_version} + %if %suse_version >= 1000 + %define debugrpm 1 + %endif +%endif + # ---------------------------------------------------------------------------- # Support optional "tcmalloc" library (experimental) # ---------------------------------------------------------------------------- @@ -235,14 +243,14 @@ documentation and the manual for more information. # Sub package definition ############################################################################## -%package -n MySQL-server%{product_suffix} +%package -n %{name}-server Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases Requires: %{distro_requires} Provides: msqlormysql mysql-server mysql MySQL MySQL-server Obsoletes: MySQL mysql mysql-server MySQL-server -%description -n MySQL-server%{product_suffix} +%description -n %{name}-server The MySQL(TM) software delivers a very fast, multi-threaded, multi-user, and robust SQL (Structured Query Language) database server. MySQL Server is intended for mission-critical, heavy-load production systems as well @@ -264,64 +272,64 @@ This package includes the MySQL server binary as well as related utilities to run and administer a MySQL server. If you want to access and work with the database, you have to install -package "MySQL-client%{product_suffix}" as well! +package "%{name}-client" as well! # ---------------------------------------------------------------------------- -%package -n MySQL-client%{product_suffix} +%package -n %{name}-client Summary: MySQL - Client Group: Applications/Databases Obsoletes: mysql-client MySQL-client Provides: mysql-client MySQL-client -%description -n MySQL-client%{product_suffix} +%description -n %{name}-client This package contains the standard MySQL clients and administration tools. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n MySQL-test%{product_suffix} -Requires: MySQL-client%{product_suffix} perl +%package -n %{name}-test +Requires: %{name}-client perl Summary: MySQL - Test suite Group: Applications/Databases Provides: mysql-test Obsoletes: mysql-bench mysql-test AutoReqProv: no -%description -n MySQL-test%{product_suffix} +%description -n %{name}-test This package contains the MySQL regression test suite. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n MySQL-devel%{product_suffix} +%package -n %{name}-devel Summary: MySQL - Development header files and libraries Group: Applications/Databases Provides: mysql-devel Obsoletes: mysql-devel -%description -n MySQL-devel%{product_suffix} +%description -n %{name}-devel This package contains the development header files and libraries necessary to develop MySQL client applications. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n MySQL-shared%{product_suffix} +%package -n %{name}-shared Summary: MySQL - Shared libraries Group: Applications/Databases -%description -n MySQL-shared%{product_suffix} +%description -n %{name}-shared This package contains the shared libraries (*.so*) which certain languages and applications need to dynamically load and use MySQL. # ---------------------------------------------------------------------------- -%package -n MySQL-embedded%{product_suffix} +%package -n %{name}-embedded Summary: MySQL - embedded library Group: Applications/Databases -Requires: MySQL-devel%{product_suffix} +Requires: %{name}-devel Obsoletes: mysql-embedded -%description -n MySQL-embedded%{product_suffix} +%description -n %{name}-embedded This package contains the MySQL server as an embedded library. The embedded MySQL server library makes it possible to run a full-featured @@ -334,6 +342,7 @@ client/server version. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ ############################################################################## +%{?debugrpm:%debug_package} %prep %setup -T -a 0 -c -n %{src_dir} @@ -478,7 +487,7 @@ rm -f $RBR%{_mandir}/man1/make_win_bin_dist.1* # Post processing actions, i.e. when installed ############################################################################## -%pre -n MySQL-server%{product_suffix} +%pre -n %{name}-server # Check if we can safely upgrade. An upgrade is only safe if it's from one # of our RPMs in the same version family. @@ -554,7 +563,7 @@ if [ -x %{_sysconfdir}/init.d/mysql ] ; then sleep 5 fi -%post -n MySQL-server%{product_suffix} +%post -n %{name}-server mysql_datadir=%{mysqldatadir} # ---------------------------------------------------------------------- @@ -622,7 +631,7 @@ sleep 2 #scheduled service packs and more. Visit www.mysql.com/enterprise for more #information." -%preun -n MySQL-server%{product_suffix} +%preun -n %{name}-server if [ $1 = 0 ] ; then # Stop MySQL before uninstalling it if [ -x %{_sysconfdir}/init.d/mysql ] ; then @@ -651,7 +660,7 @@ fi # Files section ############################################################################## -%files -n MySQL-server%{product_suffix} +%files -n %{name}-server %defattr(-,root,root,0755) %if %{defined license_files_server} @@ -734,7 +743,7 @@ fi %attr(755, root, root) %{_datadir}/mysql/ # ---------------------------------------------------------------------------- -%files -n MySQL-client%{product_suffix} +%files -n %{name}-client %defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/msql2mysql @@ -766,7 +775,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysqlslap.1* # ---------------------------------------------------------------------------- -%files -n MySQL-devel%{product_suffix} -f optional-files-devel +%files -n %{name}-devel -f optional-files-devel %defattr(-, root, root, 0755) %if %{defined license_files_devel} %doc %{license_files_devel} @@ -783,19 +792,19 @@ fi %{_libdir}/mysql/libmysqlservices.a # ---------------------------------------------------------------------------- -%files -n MySQL-shared%{product_suffix} +%files -n %{name}-shared %defattr(-, root, root, 0755) # Shared libraries (omit for architectures that don't support them) %{_libdir}/libmysql*.so* -%post -n MySQL-shared%{product_suffix} +%post -n %{name}-shared /sbin/ldconfig -%postun -n MySQL-shared%{product_suffix} +%postun -n %{name}-shared /sbin/ldconfig # ---------------------------------------------------------------------------- -%files -n MySQL-test%{product_suffix} +%files -n %{name}-test %defattr(-, root, root, 0755) %attr(-, root, root) %{_datadir}/mysql-test %attr(755, root, root) %{_bindir}/mysql_client_test @@ -808,7 +817,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysqltest_embedded.1* # ---------------------------------------------------------------------------- -%files -n MySQL-embedded%{product_suffix} +%files -n %{name}-embedded %defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/mysql_embedded %attr(644, root, root) %{_libdir}/mysql/libmysqld.a From 036343c3eab737899d22b412d29841f7677dc584 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 26 Apr 2010 19:25:58 +0200 Subject: [PATCH 091/207] Try removing debuginfo altogether. --- support-files/mysql.spec.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8520057b71a..b96dc64332a 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -168,13 +168,8 @@ %define distro_requires coreutils grep procps /sbin/chkconfig /usr/sbin/useradd /usr/sbin/groupadd %endif -# Turn on debuginfo RPMs for SuSE >= 10 -%define debugrpm 0 -%if %{defined suse_version} - %if %suse_version >= 1000 - %define debugrpm 1 - %endif -%endif +# Avoid debuginfo RPMs, leaves binaries unstripped +%define debug_package %{nil} # ---------------------------------------------------------------------------- # Support optional "tcmalloc" library (experimental) @@ -342,7 +337,6 @@ client/server version. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ ############################################################################## -%{?debugrpm:%debug_package} %prep %setup -T -a 0 -c -n %{src_dir} From b2c44afba95f37e872bb7b247560ec70e4444598 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 27 Apr 2010 12:09:55 +0200 Subject: [PATCH 092/207] Avoid __os_install_post RHEL5 bug by redefining __strip. --- support-files/mysql.spec.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b96dc64332a..0a100fd919c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -171,6 +171,10 @@ # Avoid debuginfo RPMs, leaves binaries unstripped %define debug_package %{nil} +# Hack to work around bug in RHEL5 __os_install_post macro, wrong inverted +# test for __debug_package +%define __strip /bin/true + # ---------------------------------------------------------------------------- # Support optional "tcmalloc" library (experimental) # ---------------------------------------------------------------------------- From 58aec8118548f9c6f9ced93b090106d651d9ce60 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 27 Apr 2010 17:10:06 +0200 Subject: [PATCH 093/207] Try to exclude make_win_bin_dist.1 Build full debug release in RPMs so we can include bits we need. --- man/CMakeLists.txt | 4 +++- support-files/mysql.spec.sh | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 29de4432c0c..aeee5824047 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -17,7 +17,9 @@ FILE(GLOB MAN1_FILES *.1) FILE(GLOB MAN8_FILES *.8) IF(MAN1_FILES) - INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) + INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1 + PATTERN "make_win_bin_dist.1" EXCLUDE + ) ENDIF() IF(MAN8_FILES) INSTALL(FILES ${MAN8_FILES} DESTINATION ${INSTALL_MANDIR}/man8) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 0a100fd919c..1803ce9f8e8 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -396,7 +396,7 @@ mkdir debug -DFEATURE_SET="%{feature_set}" \ -DCOMPILATION_COMMENT="%{compilation_comment_debug}" \ -DMYSQL_SERVER_SUFFIX="%{server_suffix}" - make VERBOSE=1 mysqld mysqlserver + make VERBOSE=1 ) # Build full release mkdir release @@ -730,6 +730,9 @@ fi %attr(755, root, root) %{_libdir}/mysql/plugin/mypluglib.so %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/mypluglib.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so* %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} From 159852698b601686443903367f78644db3a0f60d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 27 Apr 2010 20:12:13 +0200 Subject: [PATCH 094/207] Try again --- man/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index aeee5824047..31603f64334 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -17,9 +17,8 @@ FILE(GLOB MAN1_FILES *.1) FILE(GLOB MAN8_FILES *.8) IF(MAN1_FILES) - INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1 - PATTERN "make_win_bin_dist.1" EXCLUDE - ) + LIST(REMOVE_ITEM MAN1_FILES "make_win_bin_dist.1" + INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) ENDIF() IF(MAN8_FILES) INSTALL(FILES ${MAN8_FILES} DESTINATION ${INSTALL_MANDIR}/man8) From 83de7f640a7c50a0bd05d1a19c5bdd887c5e8147 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 27 Apr 2010 20:12:43 +0200 Subject: [PATCH 095/207] syntax --- man/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 31603f64334..d437e9a0c76 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -17,7 +17,7 @@ FILE(GLOB MAN1_FILES *.1) FILE(GLOB MAN8_FILES *.8) IF(MAN1_FILES) - LIST(REMOVE_ITEM MAN1_FILES "make_win_bin_dist.1" + LIST(REMOVE_ITEM MAN1_FILES "make_win_bin_dist.1") INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) ENDIF() IF(MAN8_FILES) From b9303c87e3841cd75a8f95fc752497eca14a7c2c Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Tue, 27 Apr 2010 22:21:48 +0200 Subject: [PATCH 096/207] On Mac OS X, add the "-arch" option to the 'mysql_config' output --- scripts/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index bfe65a0acd8..7f7baecc6c1 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -93,6 +93,10 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") # No multiconfig build - use CMAKE_C_FLAGS SET(CFLAGS "@CMAKE_C_FLAGS@") SET(CXXFLAGS "@CMAKE_CXX_FLAGS@") + FOREACH(ARCH ${CMAKE_OSX_ARCHITECTURES}) + SET(CFLAGS "${CFLAGS} -arch ${ARCH}") + SET(CXXFLAGS "${CXXFLAGS} -arch ${ARCH}") + ENDFOREACH() ELSE() # Multiconfig build - use CMAKE_C_FLAGS_RELWITHDEBINFO SET(CFLAGS "@CMAKE_C_FLAGS_RELWITHDEBINFO@") From d110132ffce95352755604ef19abd9545fe78f89 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 28 Apr 2010 11:25:11 +0200 Subject: [PATCH 097/207] Exclude "mysql_embedded" from being installed or part of a binary package, is more of a linktest of the embedded library. --- libmysqld/examples/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index f8adae9c931..f98470a2047 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -23,7 +23,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_DEFINITIONS(-DEMBEDDED_LIBRARY -UMYSQL_CLIENT) -MYSQL_ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc +# We never use "mysql_embedded", is more of a linktest, so we don't +# use MYSQL_ADD_EXECUTABLE as that would install it and package it +ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ../../client/mysql.cc ../../client/readline.cc) TARGET_LINK_LIBRARIES(mysql_embedded mysqlserver) IF(UNIX) From 9eefdcfd1ae5a3f9ff477c57362e94ed64446d8a Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 28 Apr 2010 11:52:26 +0200 Subject: [PATCH 098/207] Try to fix the manual again, and a kent change --- man/CMakeLists.txt | 3 ++- support-files/mysql.spec.sh | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index d437e9a0c76..beae58bc2c2 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -15,9 +15,10 @@ # Copy man pages FILE(GLOB MAN1_FILES *.1) +FILE(GLOB MAN1_EXCLUDE make_win_bin_dist.1) FILE(GLOB MAN8_FILES *.8) IF(MAN1_FILES) - LIST(REMOVE_ITEM MAN1_FILES "make_win_bin_dist.1") + LIST(REMOVE_ITEM MAN1_FILES ${MAN1_EXCLUDE}) INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) ENDIF() IF(MAN8_FILES) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1803ce9f8e8..3f5f4282310 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -820,7 +820,6 @@ fi # ---------------------------------------------------------------------------- %files -n %{name}-embedded %defattr(-, root, root, 0755) -%attr(755, root, root) %{_bindir}/mysql_embedded %attr(644, root, root) %{_libdir}/mysql/libmysqld.a %attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a From 3b8334f9d32b4e0f23f125b9b6696e74d9f57f78 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 28 Apr 2010 12:48:44 +0200 Subject: [PATCH 099/207] fix man bootstrap --- man/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index beae58bc2c2..1113b73fd8d 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -18,7 +18,9 @@ FILE(GLOB MAN1_FILES *.1) FILE(GLOB MAN1_EXCLUDE make_win_bin_dist.1) FILE(GLOB MAN8_FILES *.8) IF(MAN1_FILES) - LIST(REMOVE_ITEM MAN1_FILES ${MAN1_EXCLUDE}) + IF(MAN1_EXCLUDE) + LIST(REMOVE_ITEM MAN1_FILES ${MAN1_EXCLUDE}) + ENDIF() INSTALL(FILES ${MAN1_FILES} DESTINATION ${INSTALL_MANDIR}/man1) ENDIF() IF(MAN8_FILES) From 5492202344c1d2ebaecbbb2873f1b50ce932ee26 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 28 Apr 2010 14:56:38 +0200 Subject: [PATCH 100/207] Do not install mysql-test/lib/t --- mysql-test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt index ce3b684295b..0755af5e7db 100644 --- a/mysql-test/CMakeLists.txt +++ b/mysql-test/CMakeLists.txt @@ -18,6 +18,7 @@ INSTALL( DESTINATION ${INSTALL_MYSQLTESTDIR} PATTERN "var/" EXCLUDE PATTERN "lib/My/SafeProcess" EXCLUDE + PATTERN "lib/t*" EXCLUDE PATTERN "CPack" EXCLUDE PATTERN "CMake*" EXCLUDE PATTERN "mtr.out*" EXCLUDE From 32a4de454f95d0752bd2939a95a45368968ff00d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 28 Apr 2010 17:55:45 +0200 Subject: [PATCH 101/207] Revert the RPM naming change, we know it works, and can apply it to a later release. --- support-files/mysql.spec.sh | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 3f5f4282310..52dce98c69f 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -242,14 +242,14 @@ documentation and the manual for more information. # Sub package definition ############################################################################## -%package -n %{name}-server +%package -n MySQL-server%{product_suffix} Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases Requires: %{distro_requires} Provides: msqlormysql mysql-server mysql MySQL MySQL-server Obsoletes: MySQL mysql mysql-server MySQL-server -%description -n %{name}-server +%description -n MySQL-server%{product_suffix} The MySQL(TM) software delivers a very fast, multi-threaded, multi-user, and robust SQL (Structured Query Language) database server. MySQL Server is intended for mission-critical, heavy-load production systems as well @@ -271,64 +271,64 @@ This package includes the MySQL server binary as well as related utilities to run and administer a MySQL server. If you want to access and work with the database, you have to install -package "%{name}-client" as well! +package "MySQL-client%{product_suffix}" as well! # ---------------------------------------------------------------------------- -%package -n %{name}-client +%package -n MySQL-client%{product_suffix} Summary: MySQL - Client Group: Applications/Databases Obsoletes: mysql-client MySQL-client Provides: mysql-client MySQL-client -%description -n %{name}-client +%description -n MySQL-client%{product_suffix} This package contains the standard MySQL clients and administration tools. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n %{name}-test -Requires: %{name}-client perl +%package -n MySQL-test%{product_suffix} +Requires: MySQL-client%{product_suffix} perl Summary: MySQL - Test suite Group: Applications/Databases Provides: mysql-test Obsoletes: mysql-bench mysql-test AutoReqProv: no -%description -n %{name}-test +%description -n MySQL-test%{product_suffix} This package contains the MySQL regression test suite. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n %{name}-devel +%package -n MySQL-devel%{product_suffix} Summary: MySQL - Development header files and libraries Group: Applications/Databases Provides: mysql-devel Obsoletes: mysql-devel -%description -n %{name}-devel +%description -n MySQL-devel%{product_suffix} This package contains the development header files and libraries necessary to develop MySQL client applications. For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ # ---------------------------------------------------------------------------- -%package -n %{name}-shared +%package -n MySQL-shared%{product_suffix} Summary: MySQL - Shared libraries Group: Applications/Databases -%description -n %{name}-shared +%description -n MySQL-shared%{product_suffix} This package contains the shared libraries (*.so*) which certain languages and applications need to dynamically load and use MySQL. # ---------------------------------------------------------------------------- -%package -n %{name}-embedded +%package -n MySQL-embedded%{product_suffix} Summary: MySQL - embedded library Group: Applications/Databases -Requires: %{name}-devel +Requires: MySQL-devel%{product_suffix} Obsoletes: mysql-embedded -%description -n %{name}-embedded +%description -n MySQL-embedded%{product_suffix} This package contains the MySQL server as an embedded library. The embedded MySQL server library makes it possible to run a full-featured @@ -485,7 +485,7 @@ rm -f $RBR%{_mandir}/man1/make_win_bin_dist.1* # Post processing actions, i.e. when installed ############################################################################## -%pre -n %{name}-server +%pre -n MySQL-server%{product_suffix} # Check if we can safely upgrade. An upgrade is only safe if it's from one # of our RPMs in the same version family. @@ -561,7 +561,7 @@ if [ -x %{_sysconfdir}/init.d/mysql ] ; then sleep 5 fi -%post -n %{name}-server +%post -n MySQL-server%{product_suffix} mysql_datadir=%{mysqldatadir} # ---------------------------------------------------------------------- @@ -629,7 +629,7 @@ sleep 2 #scheduled service packs and more. Visit www.mysql.com/enterprise for more #information." -%preun -n %{name}-server +%preun -n MySQL-server%{product_suffix} if [ $1 = 0 ] ; then # Stop MySQL before uninstalling it if [ -x %{_sysconfdir}/init.d/mysql ] ; then @@ -658,7 +658,7 @@ fi # Files section ############################################################################## -%files -n %{name}-server +%files -n MySQL-server%{product_suffix} %defattr(-,root,root,0755) %if %{defined license_files_server} @@ -744,7 +744,7 @@ fi %attr(755, root, root) %{_datadir}/mysql/ # ---------------------------------------------------------------------------- -%files -n %{name}-client +%files -n MySQL-client%{product_suffix} %defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/msql2mysql @@ -776,7 +776,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysqlslap.1* # ---------------------------------------------------------------------------- -%files -n %{name}-devel -f optional-files-devel +%files -n MySQL-devel%{product_suffix} -f optional-files-devel %defattr(-, root, root, 0755) %if %{defined license_files_devel} %doc %{license_files_devel} @@ -793,19 +793,19 @@ fi %{_libdir}/mysql/libmysqlservices.a # ---------------------------------------------------------------------------- -%files -n %{name}-shared +%files -n MySQL-shared%{product_suffix} %defattr(-, root, root, 0755) # Shared libraries (omit for architectures that don't support them) %{_libdir}/libmysql*.so* -%post -n %{name}-shared +%post -n MySQL-shared%{product_suffix} /sbin/ldconfig -%postun -n %{name}-shared +%postun -n MySQL-shared%{product_suffix} /sbin/ldconfig # ---------------------------------------------------------------------------- -%files -n %{name}-test +%files -n MySQL-test%{product_suffix} %defattr(-, root, root, 0755) %attr(-, root, root) %{_datadir}/mysql-test %attr(755, root, root) %{_bindir}/mysql_client_test @@ -818,7 +818,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysqltest_embedded.1* # ---------------------------------------------------------------------------- -%files -n %{name}-embedded +%files -n MySQL-embedded%{product_suffix} %defattr(-, root, root, 0755) %attr(644, root, root) %{_libdir}/mysql/libmysqld.a %attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a From ce57e2415c18370985e182c707e96e26a8ec752d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 28 Apr 2010 21:01:26 +0200 Subject: [PATCH 102/207] Sync icc flags with reality. --- cmake/build_configurations/mysql_release.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index de92544ada5..eeef9f04544 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -136,8 +136,8 @@ IF(UNIX) # Linux flags IF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(CMAKE_C_COMPILER_ID MATCHES "Intel") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-static-intel -g -O3 -unroll2 -ip -mp -restrict") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-static-intel -g -O3 -unroll2 -ip -mp -restrict") + SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-static-intel -static-libgcc -g -O3 -unroll2 -ip -mp -restrict -no-ftz -no-prefetch") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-static-intel -static-libgcc -g -O3 -unroll2 -ip -mp -restrict -no-ftz -no-prefetch") SET(WITH_SSL no) ENDIF() ENDIF() From 241b702d7a66ce700f846d51915befea98c588a2 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 29 Apr 2010 12:31:15 +0200 Subject: [PATCH 103/207] Do not include Comments, as3ap or example --- sql-bench/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql-bench/CMakeLists.txt b/sql-bench/CMakeLists.txt index 59dca2e84cc..4b7f9520cc1 100644 --- a/sql-bench/CMakeLists.txt +++ b/sql-bench/CMakeLists.txt @@ -18,7 +18,6 @@ FILE(GLOB all_files ${CMAKE_SOURCE_DIR}/sql-bench/* ${CMAKE_SOURCE_DIR}/sql-bench/Data/ATIS/* ${CMAKE_SOURCE_DIR}/sql-bench/Data/Wisconsin/* -${CMAKE_SOURCE_DIR}/sql-bench/Comments/* ${CMAKE_SOURCE_DIR}/sql-bench/limits/* ) @@ -34,7 +33,7 @@ ENDIF() GET_FILENAME_COMPONENT(basedir ${CMAKE_SOURCE_DIR} ABSOLUTE) FOREACH(file ${all_files}) - IF(NOT IS_DIRECTORY ${file} AND NOT ${file} MATCHES "Make" ) + IF(NOT IS_DIRECTORY ${file} AND NOT ${file} MATCHES "Make|as3ap|/example$" ) FILE(RELATIVE_PATH relpath ${basedir} ${file}) SET(target_relpath ${relpath}) GET_FILENAME_COMPONENT(ext ${file} EXT) From 17206900a07660ec35b7d86d8febabccac6a384f Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 29 Apr 2010 16:37:28 +0200 Subject: [PATCH 104/207] Rebrand Red Hat as 'Enterprise Linux' --- support-files/mysql.spec.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 52dce98c69f..764c67b85c7 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -122,20 +122,20 @@ %endif %if %{distro_specific} %if %(test -f /etc/redhat-release && echo 1 || echo 0) - %define redhatver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g') - %if "%redhatver" == "4" - %define distro_description Red Hat Enterprise Linux 4 - %define distro_releasetag rhel4 + %define elver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g') + %if "%elver" == "4" + %define distro_description Enterprise Linux 4 + %define distro_releasetag el4 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %if "%redhatver" == "5" - %define distro_description Red Hat Enterprise Linux 5 - %define distro_releasetag rhel5 + %if "%elver" == "5" + %define distro_description Enterprise Linux 5 + %define distro_releasetag el5 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %{error:Red Hat %{redhatver} is unsupported} + %{error:Enterprise Linux %{elver} is unsupported} %endif %endif %else @@ -577,7 +577,7 @@ if [ ! -d $mysql_datadir/test ] ; then mkdir $mysql_datadir/test; fi # use insserv for older SuSE Linux versions if [ -x /sbin/insserv ] ; then /sbin/insserv %{_sysconfdir}/init.d/mysql -# use chkconfig on Red Hat and newer SuSE releases +# use chkconfig on Enterprise Linux and newer SuSE releases elif [ -x /sbin/chkconfig ] ; then /sbin/chkconfig --add mysql fi @@ -638,7 +638,7 @@ if [ $1 = 0 ] ; then # For older SuSE Linux versions if [ -x /sbin/insserv ] ; then /sbin/insserv -r %{_sysconfdir}/init.d/mysql - # use chkconfig on Red Hat and newer SuSE releases + # use chkconfig on Enterprise Linux and newer SuSE releases elif [ -x /sbin/chkconfig ] ; then /sbin/chkconfig --del mysql fi From d60efe5820d98bba41f1b76c37927c8f648937c9 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Fri, 30 Apr 2010 13:30:32 +0200 Subject: [PATCH 105/207] Changes to MSI installer: - Introduce MANUFACTURER setting to set package manufacturer via CMake. - Introduce COMMUNITY_BUILD setting to be passed on to packaging (not used here, but required for our own packages to determine what added files should be included in the package). - Create an RTF version of the COPYING text file and use that as the default license (can be overridden by providing a COPYING.rtf file). - Allow passing extra arguments to candle and light via environment. (Need -sval in pushbuild, but want validation elsewhere.) - Introduce a custom action that stops and uninstalls the service if the user installed one that points into the MySQL directory that is being removed. (Our own packages historically used the instance configuration wizard for this, but it wouldn't be very nice if MSIs created by our users couldn't remove it too.) - Make install location configurable again ("Browse" button in custom installation was greyed out before). - Remove registry keys that use "MySQL AB"; they should only be set in packages provided by us. Users can set their own registry keys if they want to. --- CMakeLists.txt | 12 ++ packaging/WiX/CMakeLists.txt | 187 +++++++++++++++++------------ packaging/WiX/ca/CMakeLists.txt | 27 +++++ packaging/WiX/ca/CustomAction.cpp | 188 ++++++++++++++++++++++++++++++ packaging/WiX/ca/CustomAction.def | 8 ++ packaging/WiX/ca/CustomAction.rc | 18 +++ packaging/WiX/create_msi.cmake.in | 18 ++- packaging/WiX/extra.wxs.in | 33 +----- packaging/WiX/mysql_server.wxs.in | 32 ++++- 9 files changed, 412 insertions(+), 111 deletions(-) create mode 100644 packaging/WiX/ca/CMakeLists.txt create mode 100644 packaging/WiX/ca/CustomAction.cpp create mode 100644 packaging/WiX/ca/CustomAction.def create mode 100644 packaging/WiX/ca/CustomAction.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index 8edd1e5c158..43c1c2ea095 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,18 @@ SET(CUSTOM_C_FLAGS $ENV{CFLAGS}) OPTION(WITH_DEBUG "Use dbug/safemutex" OFF) OPTION(WITH_DEBUG_FULL "Use dbug and safemalloc/safemutex. Slow" OFF) +# Distinguish between community and non-community builds, with the +# default being a community build. This does not impact the feature +# set that will be compiled in; it's merely provided as a hint to +# custom packaging steps. +OPTION(COMMUNITY_BUILD "Set to true if this is a community build" ON) + +# Use a default manufacturer if no manufacturer was identified. +SET(MANUFACTURER_DOCSTRING + "Set the entity that appears as the manufacturer of packages that support a manufacturer field.") +IF(NOT DEFINED MANUFACTURER) + SET(MANUFACTURER "Built from Source" CACHE BOOL ${MANUFACTURER_DOCSTRING}) +ENDIF() # We choose to provide WITH_DEBUG as alias to standard CMAKE_BUILD_TYPE=Debug # which turns out to be not trivial, as this involves synchronization diff --git a/packaging/WiX/CMakeLists.txt b/packaging/WiX/CMakeLists.txt index f3fa3eb7a30..8a6a4ae4c41 100644 --- a/packaging/WiX/CMakeLists.txt +++ b/packaging/WiX/CMakeLists.txt @@ -1,75 +1,112 @@ - -IF(NOT WIN32) - RETURN() -ENDIF() - -FIND_PATH(WIX_DIR heat.exe - $ENV{WIX_DIR}/bin - $ENV{ProgramFiles}/wix/bin - "$ENV{ProgramFiles}/Windows Installer XML v3/bin" - "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" -) - -IF(NOT WIX_DIR) - IF(NOT _WIX_DIR_CHECKED) - SET(_WIX_DIR_CHECKED 1 CACHE INTERNAL "") - MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") - ENDIF() - RETURN() -ENDIF() - -# extra.wxs.in needs DATADIR_MYSQL_FILES and DATADIR_PERFORMANCE_SCHEMA_FILES, i.e -# Wix-compatible file lists for ${builddir}\sql\data\{mysql,performance_schema} - -FOREACH(dir mysql performance_schema) - FILE(GLOB files ${CMAKE_BINARY_DIR}/sql/data/${dir}/*) - SET(filelist) - FOREACH(f ${files}) - FILE(TO_NATIVE_PATH "${f}" file_native_path) - GET_FILENAME_COMPONENT(file_name "${f}" NAME) - SET(filelist -"${filelist} -") - ENDFOREACH() - STRING(TOUPPER ${dir} DIR_UPPER) - SET(DATADIR_${DIR_UPPER}_FILES "${filelist}") -ENDFOREACH() - - -FIND_PROGRAM(HEAT_EXECUTABLE heat ${WIX_DIR}) -FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) -FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake - @ONLY) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/extra.wxs.in - ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs - @ONLY - ) - -IF(CMAKE_GENERATOR MATCHES "Visual Studio") - SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") -ENDIF() - - -ADD_CUSTOM_TARGET( - MSI - COMMAND set VS_UNICODE_OUTPUT= - COMMAND ${CMAKE_COMMAND} - -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake - -DCPACK_WIX_INCLUDE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs - ${CONFIG_PARAM} - -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake -) - -ADD_CUSTOM_TARGET( - MSI_ESSENTIALS - COMMAND set VS_UNICODE_OUTPUT= - COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 - -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake - -DCPACK_WIX_INCLUDE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs - ${CONFIG_PARAM} - -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake -) - +# Copyright 2010, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +IF(NOT WIN32) + RETURN() +ENDIF() + +FIND_PATH(WIX_DIR heat.exe + $ENV{WIX_DIR}/bin + $ENV{ProgramFiles}/wix/bin + "$ENV{ProgramFiles}/Windows Installer XML v3/bin" + "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin" +) + +IF(NOT WIX_DIR) + IF(NOT _WIX_DIR_CHECKED) + SET(_WIX_DIR_CHECKED 1 CACHE INTERNAL "") + MESSAGE(STATUS "Cannot find wix 3, installer project will not be generated") + ENDIF() + RETURN() +ENDIF() + +ADD_SUBDIRECTORY(ca) + +# extra.wxs.in needs DATADIR_MYSQL_FILES and DATADIR_PERFORMANCE_SCHEMA_FILES, i.e +# Wix-compatible file lists for ${builddir}\sql\data\{mysql,performance_schema} + +FOREACH(dir mysql performance_schema) + FILE(GLOB files ${CMAKE_BINARY_DIR}/sql/data/${dir}/*) + SET(filelist) + FOREACH(f ${files}) + FILE(TO_NATIVE_PATH "${f}" file_native_path) + GET_FILENAME_COMPONENT(file_name "${f}" NAME) + SET(filelist +"${filelist} +") + ENDFOREACH() + STRING(TOUPPER ${dir} DIR_UPPER) + SET(DATADIR_${DIR_UPPER}_FILES "${filelist}") +ENDFOREACH() + + +FIND_PROGRAM(HEAT_EXECUTABLE heat ${WIX_DIR}) +FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) +FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake + @ONLY) + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(WixWin64 " Win64='yes'") +ELSE() + SET(WixWin64) +ENDIF() +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/extra.wxs.in + ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs) + +IF(CMAKE_GENERATOR MATCHES "Visual Studio") + SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") +ENDIF() + +# WiX wants the license text as rtf; if there is no rtf license, +# we create a fake one from the plain text COPYING file. +IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf") + MESSAGE("copying COPYING.rtf") + FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.rtf" CONTENTS) + FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "${CONTENTS}") +ELSE() + MESSAGE("creating COPYING.rtf") + FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING" CONTENTS) + STRING(REGEX REPLACE "\n" "\\\\par\n" CONTENTS "${CONTENTS}") + STRING(REGEX REPLACE "\t" "\\\\tab" CONTENTS "${CONTENTS}") + FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\\viewkind4\\uc1\\pard\\lang1031\\f0\\fs15") + FILE(APPEND "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "${CONTENTS}") + FILE(APPEND "${CMAKE_CURRENT_BINARY_DIR}/COPYING.rtf" "\n}\n") +ENDIF() + +ADD_CUSTOM_TARGET( + MSI + COMMAND set VS_UNICODE_OUTPUT= + COMMAND ${CMAKE_COMMAND} + -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake + -DCPACK_WIX_INCLUDE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake +) +ADD_DEPENDENCIES(MSI wixca) + +ADD_CUSTOM_TARGET( + MSI_ESSENTIALS + COMMAND set VS_UNICODE_OUTPUT= + COMMAND ${CMAKE_COMMAND} -DESSENTIALS=1 + -DCPACK_WIX_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake + -DCPACK_WIX_INCLUDE=${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${CONFIG_PARAM} + -P ${CMAKE_CURRENT_BINARY_DIR}/create_msi.cmake +) +ADD_DEPENDENCIES(MSI wixca) + diff --git a/packaging/WiX/ca/CMakeLists.txt b/packaging/WiX/ca/CMakeLists.txt new file mode 100644 index 00000000000..c74b51284c7 --- /dev/null +++ b/packaging/WiX/ca/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright 2010, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/inc) +LINK_DIRECTORIES(${WIX_DIR}/../SDK/lib) + +SET(WIXCA_SOURCES CustomAction.cpp CustomAction.rc CustomAction.def) + +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + LINK_LIBRARIES(wcautil_x64 dutil_x64 msi version) +ELSE() + LINK_LIBRARIES(wcautil dutil msi version) +ENDIF() + +ADD_LIBRARY(wixca SHARED ${WIXCA_SOURCES}) diff --git a/packaging/WiX/ca/CustomAction.cpp b/packaging/WiX/ca/CustomAction.cpp new file mode 100644 index 00000000000..806535bc79a --- /dev/null +++ b/packaging/WiX/ca/CustomAction.cpp @@ -0,0 +1,188 @@ +/* Copyright 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef UNICODE +#define UNICODE +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* + * Search the registry for a service whose ImagePath starts + * with our install directory. Stop and remove it if requested. + */ +static TCHAR last_service_name[128]; +int remove_service(TCHAR *installdir, int check_only) { + HKEY hKey; + int done = 0; + + if(wcslen(installdir) < 3) { + WcaLog(LOGMSG_STANDARD, "INSTALLDIR is suspiciously short, better not do anything."); + return 0; + } + + if(check_only == 0) { + WcaLog(LOGMSG_STANDARD, "Determining number of matching services..."); + int servicecount = remove_service(installdir, 1); + if(servicecount <= 0) { + WcaLog(LOGMSG_STANDARD, "No services found, not removing anything."); + return 0; + } else if(servicecount == 1) { + TCHAR buf[256]; + swprintf_s(buf, sizeof(buf), TEXT("There is a service called '%ls' set up to run from this installation. Do you wish me to stop and remove that service?"), last_service_name); + int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL); + if(rc == IDCANCEL) return -1; + if(rc != IDYES) return 0; + } else if(servicecount > 0) { + TCHAR buf[256]; + swprintf_s(buf, sizeof(buf), TEXT("There appear to be %d services set up to run from this installation. Do you wish me to stop and remove those services?"), servicecount); + int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL); + if(rc == IDCANCEL) return -1; + if(rc != IDYES) return 0; + } + } + + if(check_only == -1) check_only = 0; + + WcaLog(LOGMSG_STANDARD, "Looking for service..."); + WcaLog(LOGMSG_STANDARD, "INSTALLDIR = %ls", installdir); + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\services"), 0, KEY_READ, &hKey)==ERROR_SUCCESS) { + DWORD index = 0; + TCHAR keyname[1024]; + DWORD keylen = sizeof(keyname); + FILETIME t; + /* Go through all services in the registry */ + while(RegEnumKeyExW(hKey, index, keyname, &keylen, NULL, NULL, NULL, &t) == ERROR_SUCCESS) { + HKEY hServiceKey = 0; + TCHAR path[1024]; + DWORD pathlen = sizeof(path)-1; + if (RegOpenKeyExW(hKey, keyname, NULL, KEY_READ, &hServiceKey) == ERROR_SUCCESS) { + /* Look at the ImagePath value of each service */ + if (RegQueryValueExW(hServiceKey, TEXT("ImagePath"), NULL, NULL, (LPBYTE)path, &pathlen) == ERROR_SUCCESS) { + path[pathlen] = 0; + TCHAR *p = path; + if(p[0] == '"') p += 1; + /* See if it is similar to our install directory */ + if(wcsncmp(p, installdir, wcslen(installdir)) == 0) { + WcaLog(LOGMSG_STANDARD, "Found service '%ls' with ImagePath '%ls'.", keyname, path); + swprintf_s(last_service_name, sizeof(last_service_name), TEXT("%ls"), keyname); + /* If we are supposed to stop and remove the service... */ + if(!check_only) { + WcaLog(LOGMSG_STANDARD, "Trying to stop the service."); + SC_HANDLE hSCM = NULL; + hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + if(hSCM != NULL) { + SC_HANDLE hService = NULL; + hService = OpenService(hSCM, keyname, SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE); + if(hService != NULL) { + WcaLog(LOGMSG_STANDARD, "Waiting for the service to stop..."); + SERVICE_STATUS status; + /* Attempt to stop the service */ + if(ControlService(hService, SERVICE_CONTROL_STOP, &status)) { + /* Now wait until it's stopped */ + while("it's one big, mean and cruel world out there") { + if(!QueryServiceStatus(hService, &status)) break; + if(status.dwCurrentState == SERVICE_STOPPED) break; + Sleep(1000); + } + WcaLog(LOGMSG_STANDARD, "Stopped the service."); + } + /* Mark the service for deletion */ + DeleteService(hService); + CloseServiceHandle(hService); + } + CloseServiceHandle(hSCM); + } + } + done++; + } + } + RegCloseKey(hServiceKey); + } + index++; + keylen = sizeof(keyname)-1; + } + RegCloseKey(hKey); + } else { + WcaLog(LOGMSG_STANDARD, "Can't seem to go through the list of installed services in the registry."); + } + return done; +} + +UINT wrap(MSIHANDLE hInstall, char *name, int check_only) { + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, name); + ExitOnFailure(hr, "Failed to initialize"); + + WcaLog(LOGMSG_STANDARD, "Initialized."); + + TCHAR INSTALLDIR[1024]; + DWORD INSTALLDIR_size = sizeof(INSTALLDIR); + if(MsiGetPropertyW(hInstall, TEXT("CustomActionData"), INSTALLDIR, &INSTALLDIR_size) == ERROR_SUCCESS) { + int rc = remove_service(INSTALLDIR, check_only); + if(rc < 0) { + er = ERROR_CANCELLED; + } + } else { + er = ERROR_CANT_ACCESS_FILE; + } + +LExit: + return WcaFinalize(er); +} + +UINT __stdcall RemoveServiceNoninteractive(MSIHANDLE hInstall) +{ + return wrap(hInstall, "RemoveServiceNoninteractive", -1); +} + +UINT __stdcall RemoveService(MSIHANDLE hInstall) +{ + return wrap(hInstall, "RemoveService", 0); +} + +UINT __stdcall TestService(MSIHANDLE hInstall) +{ + return wrap(hInstall, "TestService", 1); +} + +/* DllMain - Initialize and cleanup WiX custom action utils */ +extern "C" BOOL WINAPI DllMain( + __in HINSTANCE hInst, + __in ULONG ulReason, + __in LPVOID + ) +{ + switch(ulReason) + { + case DLL_PROCESS_ATTACH: + WcaGlobalInitialize(hInst); + break; + + case DLL_PROCESS_DETACH: + WcaGlobalFinalize(); + break; + } + + return TRUE; +} diff --git a/packaging/WiX/ca/CustomAction.def b/packaging/WiX/ca/CustomAction.def new file mode 100644 index 00000000000..5f5e6630013 --- /dev/null +++ b/packaging/WiX/ca/CustomAction.def @@ -0,0 +1,8 @@ +LIBRARY "wixca" +VERSION 1.0 + +EXPORTS + +RemoveService +RemoveServiceNoninteractive +TestService diff --git a/packaging/WiX/ca/CustomAction.rc b/packaging/WiX/ca/CustomAction.rc new file mode 100644 index 00000000000..3f37126ee77 --- /dev/null +++ b/packaging/WiX/ca/CustomAction.rc @@ -0,0 +1,18 @@ +#include "afxres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN +END + diff --git a/packaging/WiX/create_msi.cmake.in b/packaging/WiX/create_msi.cmake.in index dc60123b58a..ff18009fd0c 100644 --- a/packaging/WiX/create_msi.cmake.in +++ b/packaging/WiX/create_msi.cmake.in @@ -8,6 +8,7 @@ SET(MAJOR_VERSION "@MAJOR_VERSION@") SET(MINOR_VERSION "@MINOR_VERSION@") SET(PATCH "@PATCH@") SET(CMAKE_SIZEOF_VOID_P @CMAKE_SIZEOF_VOID_P@) +SET(MANUFACTURER "@MANUFACTURER@") IF(CMAKE_SIZEOF_VOID_P EQUAL 8) SET(Win64 " Win64='yes'") @@ -97,6 +98,7 @@ FOREACH(f ${WIX_FEATURES}) " ) FOREACH(c ${${f}_COMPONENTS}) @@ -127,6 +129,7 @@ FOREACH(f ${WIX_FEATURES}) ") @@ -286,12 +289,23 @@ ENDFOREACH() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_server.wxs.in ${CMAKE_CURRENT_BINARY_DIR}/mysql_server.wxs) +SET(EXTRA_CANDLE_ARGS) +IF("$ENV{EXTRA_CANDLE_ARGS}") + SET(EXTRA_CANDLE_ARGS "$ENV{EXTRA_CANDLE_ARGS}") +ENDIF() + +SET(EXTRA_LIGHT_ARGS) +IF("$ENV{EXTRA_LIGHT_ARGS}") + SET(EXTRA_LIGHT_ARGS "$ENV{EXTRA_LIGHT_ARGS}") +ENDIF() + FILE(REMOVE mysql_server.wixobj) EXECUTE_PROCESS( - COMMAND ${CANDLE_EXECUTABLE} -ext WixUtilExtension mysql_server.wxs + COMMAND ${CANDLE_EXECUTABLE} -ext WixUtilExtension mysql_server.wxs ${EXTRA_CANDLE_ARGS} ) EXECUTE_PROCESS( - COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension + COMMAND ${LIGHT_EXECUTABLE} -ext WixUIExtension -ext WixUtilExtension mysql_server.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi + ${EXTRA_LIGHT_ARGS} ) diff --git a/packaging/WiX/extra.wxs.in b/packaging/WiX/extra.wxs.in index 78e6f96dbcc..4957071526b 100644 --- a/packaging/WiX/extra.wxs.in +++ b/packaging/WiX/extra.wxs.in @@ -1,34 +1,5 @@ - - - - - - - - - - - - - @@ -43,7 +14,6 @@ - - - + diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index 8c2b839c6e7..8b20644e58d 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -6,12 +6,12 @@ Name="MySQL Server @MAJOR_VERSION@.@MINOR_VERSION@" Version="@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH@" Language="1033" - Manufacturer="MySQL AB"> + Manufacturer="@MANUFACTURER@"> + + + + + + + + + + + Installed And Not UPGRADINGPRODUCTCODE + Installed And Not UPGRADINGPRODUCTCODE + Installed And Not UPGRADINGPRODUCTCODE And UILevel>2 + Installed And Not UPGRADINGPRODUCTCODE And UILevel<=2 + + From 5c4ccba3240052728f08257d91017c5bf9d5ec66 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Fri, 30 Apr 2010 14:12:56 +0200 Subject: [PATCH 106/207] post-merge fix --- libmysql/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index cf0f8f8ebde..2ae09c1707a 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -209,7 +209,7 @@ IF(NOT DISABLE_SHARED) "${CMAKE_SHARED_LIBRARY_SUFFIX}" "" linkname) - INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR}) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} COMPONENT SharedLibraries) SET(OS_SHARED_LIB_SYMLINKS "${SHARED_LIB_MAJOR_VERSION}" "${OS_SHARED_LIB_VERSION}") LIST(REMOVE_DUPLICATES OS_SHARED_LIB_SYMLINKS) FOREACH(ver ${OS_SHARED_LIB_SYMLINKS}) @@ -218,7 +218,7 @@ IF(NOT DISABLE_SHARED) "${CMAKE_SHARED_LIBRARY_SUFFIX}" "${ver}" linkname) - INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR}) + INSTALL_SYMLINK(${linkname} libmysql ${INSTALL_LIBDIR} COMPONENT SharedLibraries) ENDFOREACH() ENDIF() ENDIF() From 9e7536638ac90d695b7a19b426d7af27fa0d4f1f Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Fri, 30 Apr 2010 15:28:08 +0200 Subject: [PATCH 107/207] apply wlad's patch to read the fill_help_tables.sql file whole, not line by line --- cmake/create_initial_db.cmake.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/create_initial_db.cmake.in b/cmake/create_initial_db.cmake.in index 649d96a6627..01b2da665a6 100644 --- a/cmake/create_initial_db.cmake.in +++ b/cmake/create_initial_db.cmake.in @@ -31,8 +31,7 @@ ENDIF() # Create bootstrapper SQL script FILE(WRITE bootstrap.sql "use mysql;\n" ) -FOREACH(FILENAME mysql_system_tables.sql mysql_system_tables_data.sql - fill_help_tables.sql) +FOREACH(FILENAME mysql_system_tables.sql mysql_system_tables_data.sql) FILE(STRINGS ${CMAKE_SOURCE_DIR}/scripts/${FILENAME} CONTENTS) FOREACH(STR ${CONTENTS}) IF(NOT STR MATCHES "@current_hostname") @@ -40,6 +39,8 @@ FOREACH(FILENAME mysql_system_tables.sql mysql_system_tables_data.sql ENDIF() ENDFOREACH() ENDFOREACH() +FILE(READ ${CMAKE_SOURCE_DIR}/scripts/fill_help_tables.sql CONTENTS) +FILE(APPEND bootstrap.sql ${CONTENTS}) FILE(REMOVE_RECURSE mysql) From 487b6e1c72e66cd87e9e9e0af6ce1c48e9c6f200 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Fri, 30 Apr 2010 17:12:01 +0200 Subject: [PATCH 108/207] WiX is worried that we aren't going to create these directories after all, so let's reaffirm our intention to do so. --- packaging/WiX/extra.wxs.in | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packaging/WiX/extra.wxs.in b/packaging/WiX/extra.wxs.in index 4957071526b..b6c42136129 100644 --- a/packaging/WiX/extra.wxs.in +++ b/packaging/WiX/extra.wxs.in @@ -10,15 +10,18 @@ Name="MySQL Server @MAJOR_VERSION@.@MINOR_VERSION@"> - - - + + + + + + @DATADIR_MYSQL_FILES@ @@ -27,6 +30,9 @@ + + + @DATADIR_PERFORMANCE_SCHEMA_FILES@ From e32c25628793455b7537022d679f8a80913edd4f Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 4 May 2010 12:34:00 +0200 Subject: [PATCH 109/207] Put back SELinux files --- support-files/mysql.spec.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 764c67b85c7..0016c456b60 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -442,6 +442,7 @@ MBD=$RPM_BUILD_DIR/%{src_dir} install -d $RBR%{_sysconfdir}/{logrotate.d,init.d} install -d $RBR%{mysqldatadir}/mysql install -d $RBR%{_datadir}/mysql-test +install -d $RBR%{_datadir}/mysql/SELinux/RHEL4 install -d $RBR%{_includedir} install -d $RBR%{_libdir} install -d $RBR%{_mandir} @@ -470,6 +471,10 @@ ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql # Just to make sure it's in the file list and marked as a config file touch $RBR%{_sysconfdir}/my.cnf +# Install SELinux files in datadir +install -m 600 $MBD/support-files/RHEL4-SElinux/mysql.{fc,te} \ + $RBR%{_datadir}/mysql/SELinux/RHEL4 + %if %{WITH_TCMALLOC} # Even though this is a shared library, put it under /usr/lib*/mysql, so it # doesn't conflict with possible shared lib by the same name in /usr/lib*. See From 0187562f0171f0eb411e384024b5dd73736a6a70 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 4 May 2010 14:03:10 +0200 Subject: [PATCH 110/207] fix --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 0016c456b60..c8d34528a8b 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -472,7 +472,7 @@ ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql touch $RBR%{_sysconfdir}/my.cnf # Install SELinux files in datadir -install -m 600 $MBD/support-files/RHEL4-SElinux/mysql.{fc,te} \ +install -m 600 $MBD/release/support-files/RHEL4-SElinux/mysql.{fc,te} \ $RBR%{_datadir}/mysql/SELinux/RHEL4 %if %{WITH_TCMALLOC} From 58b15f80581c2c7aef2ef568cffb88bba0c3dc93 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 4 May 2010 15:41:42 +0200 Subject: [PATCH 111/207] Ok, let's try, one more time --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index c8d34528a8b..6f033bc8546 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -472,7 +472,7 @@ ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql touch $RBR%{_sysconfdir}/my.cnf # Install SELinux files in datadir -install -m 600 $MBD/release/support-files/RHEL4-SElinux/mysql.{fc,te} \ +install -m 600 $MBD/%{src_dir}/support-files/RHEL4-SElinux/mysql.{fc,te} \ $RBR%{_datadir}/mysql/SELinux/RHEL4 %if %{WITH_TCMALLOC} From 2c9803580f3495895b9ccd86bff1492105416340 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 5 May 2010 13:49:03 +0200 Subject: [PATCH 112/207] Build all plugins. Try to fix ia64/icc builds. --- cmake/build_configurations/mysql_release.cmake | 3 --- config.h.cmake | 1 + plugin/audit_null/CMakeLists.txt | 3 ++- plugin/daemon_example/CMakeLists.txt | 3 ++- plugin/fulltext/CMakeLists.txt | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index eeef9f04544..dd1015ff9b9 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -80,9 +80,6 @@ IF(FEATURE_SET) ENDFOREACH() ENDIF() -SET(WITHOUT_AUDIT_NULL ON CACHE BOOL "") -SET(WITHOUT_DAEMON_EXAMPLE ON CACHE BOOL "") - OPTION(ENABLE_LOCAL_INFILE "" ON) SET(WITH_SSL bundled CACHE STRING "") SET(WITH_ZLIB bundled CACHE STRING "") diff --git a/config.h.cmake b/config.h.cmake index f0473c83af6..b3b234a153b 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -38,6 +38,7 @@ #cmakedefine HAVE_FPU_CONTROL_H 1 #cmakedefine HAVE_GRP_H 1 #cmakedefine HAVE_EXPLICIT_TEMPLATE_INSTANTIATION 1 +#cmakedefine HAVE_IA64INTRIN_H 1 #cmakedefine HAVE_IEEEFP_H 1 #cmakedefine HAVE_INTTYPES_H 1 #cmakedefine HAVE_LIMITS_H 1 diff --git a/plugin/audit_null/CMakeLists.txt b/plugin/audit_null/CMakeLists.txt index 9f32181a163..4baa1da35fe 100644 --- a/plugin/audit_null/CMakeLists.txt +++ b/plugin/audit_null/CMakeLists.txt @@ -13,4 +13,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -MYSQL_ADD_PLUGIN(audit_null audit_null.c) +MYSQL_ADD_PLUGIN(audit_null audit_null.c + MODULE_ONLY MODULE_OUTPUT_NAME "adt_null") diff --git a/plugin/daemon_example/CMakeLists.txt b/plugin/daemon_example/CMakeLists.txt index 1c21d57b326..abb9a0d49df 100644 --- a/plugin/daemon_example/CMakeLists.txt +++ b/plugin/daemon_example/CMakeLists.txt @@ -13,4 +13,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -MYSQL_ADD_PLUGIN(daemon_example daemon_example.cc MODULE_ONLY) +MYSQL_ADD_PLUGIN(daemon_example daemon_example.cc + MODULE_ONLY MODULE_NAME "libdaemon_example") diff --git a/plugin/fulltext/CMakeLists.txt b/plugin/fulltext/CMakeLists.txt index ea71552a37a..394cb8dc51d 100644 --- a/plugin/fulltext/CMakeLists.txt +++ b/plugin/fulltext/CMakeLists.txt @@ -13,5 +13,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -MYSQL_ADD_PLUGIN(ftexample plugin_example.c MODULE_ONLY MODULE_OUTPUT_NAME mypluglib) +MYSQL_ADD_PLUGIN(ftexample plugin_example.c + MODULE_ONLY MODULE_OUTPUT_NAME "mypluglib") From 9f282523859643a1c0b3c9825bd661e4a603aa5a Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 5 May 2010 14:28:02 +0200 Subject: [PATCH 113/207] fix syntax error --- plugin/daemon_example/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/daemon_example/CMakeLists.txt b/plugin/daemon_example/CMakeLists.txt index abb9a0d49df..de4310b0244 100644 --- a/plugin/daemon_example/CMakeLists.txt +++ b/plugin/daemon_example/CMakeLists.txt @@ -14,4 +14,4 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA MYSQL_ADD_PLUGIN(daemon_example daemon_example.cc - MODULE_ONLY MODULE_NAME "libdaemon_example") + MODULE_ONLY MODULE_OUTPUT_NAME "libdaemon_example") From f9d9388527f51825d6f81bf804b2f705533115dd Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 5 May 2010 15:23:34 +0200 Subject: [PATCH 114/207] Add all plugins --- support-files/mysql.spec.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 6f033bc8546..3ad9eebd657 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -732,12 +732,16 @@ fi %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/rcmysql +%attr(755, root, root) %{_libdir}/mysql/plugin/adt_null.so +%attr(755, root, root) %{_libdir}/mysql/plugin/libdaemon_example.so %attr(755, root, root) %{_libdir}/mysql/plugin/mypluglib.so -%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so +%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/adt_null.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/libdaemon_example.so %attr(755, root, root) %{_libdir}/mysql/plugin/debug/mypluglib.so -%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so +%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} From 63fbe9cce8bafbbb65a54294c958f5ce9c5f05ee Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 5 May 2010 17:50:22 +0200 Subject: [PATCH 115/207] Output the config.h defines to stdout --- support-files/mysql.spec.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 3ad9eebd657..e3944805368 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -396,6 +396,7 @@ mkdir debug -DFEATURE_SET="%{feature_set}" \ -DCOMPILATION_COMMENT="%{compilation_comment_debug}" \ -DMYSQL_SERVER_SUFFIX="%{server_suffix}" + echo BEGIN_DEBUG_CONFIG ; egrep '^#define' include/config.h ; echo END_DEBUG_CONFIG make VERBOSE=1 ) # Build full release @@ -410,6 +411,7 @@ mkdir release -DFEATURE_SET="%{feature_set}" \ -DCOMPILATION_COMMENT="%{compilation_comment_release}" \ -DMYSQL_SERVER_SUFFIX="%{server_suffix}" + echo BEGIN_NORMAL_CONFIG ; egrep '^#define' include/config.h ; echo END_NORMAL_CONFIG make VERBOSE=1 ) From c8432bfbcc6dcdc5c1bc106b6132d0814e739a1b Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 5 May 2010 19:27:21 +0200 Subject: [PATCH 116/207] Try an ia64 fix --- support-files/mysql.spec.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index e3944805368..540fef6def6 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -363,6 +363,9 @@ touch optional-files-devel # not require C++ features such as exceptions, and may need to be removed at # a later date. # +%if "%{_arch}" == "ia64" +RPM_OPT_FLAGS= +%endif export PATH=${MYSQL_BUILD_PATH:-$PATH} export CC=${MYSQL_BUILD_CC:-${CC:-gcc}} export CXX=${MYSQL_BUILD_CXX:-${CXX:-gcc}} From af941670abbb84b32cdb80a4c87e95a5d5594895 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 5 May 2010 23:03:38 +0200 Subject: [PATCH 117/207] Update comment --- support-files/mysql.spec.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 540fef6def6..fcdcb096d01 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -363,9 +363,14 @@ touch optional-files-devel # not require C++ features such as exceptions, and may need to be removed at # a later date. # + +# This is a hack, $RPM_OPT_FLAGS on ia64 hosts contains flags which break +# the compile in cmd-line-utils/readline - needs investigation, but for now +# we simply unset it and use those specified directly in cmake. %if "%{_arch}" == "ia64" RPM_OPT_FLAGS= %endif + export PATH=${MYSQL_BUILD_PATH:-$PATH} export CC=${MYSQL_BUILD_CC:-${CC:-gcc}} export CXX=${MYSQL_BUILD_CXX:-${CXX:-gcc}} From e31887f2ed9a5dd58345f8fd6d28e0729710ac96 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 6 May 2010 15:20:14 +0200 Subject: [PATCH 118/207] Tidy install layout. Remove 'ROOT' from sql-bench dir variable, it's unnecessary. --- cmake/install_layout.cmake | 195 +++++++++++++++++++++---------------- sql-bench/CMakeLists.txt | 6 +- 2 files changed, 113 insertions(+), 88 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 296bebd3bb0..ade6cdb747f 100755 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -40,18 +40,25 @@ # # - INSTALL_BINDIR (directory with client executables and scripts) # - INSTALL_SBINDIR (directory with mysqld) +# - INSTALL_SCRIPTDIR (several scripts, rarely used) +# # - INSTALL_LIBDIR (directory with client end embedded libraries) # - INSTALL_PLUGINDIR (directory for plugins) +# # - INSTALL_INCLUDEDIR (directory for MySQL headers) +# # - INSTALL_DOCDIR (documentation) -# - INSTALL_MANDIR (man pages) -# - INSTALL_SCRIPTDIR (several scripts, rarely used) -# - INSTALL_MYSQLSHAREDIR (MySQL character sets and localized error messages) -# - INSTALL_SHAREDIR (location of aclocal/mysql.m4) -# - INSTALL_SQLBENCHDIR (sql-bench) -# - INSTALL_MYSQLTESTDIR (mysql-test) # - INSTALL_DOCREADMEDIR (readme and similar) -# - INSTALL_SUPPORTFILESDIR (used only in standalone installer) +# - INSTALL_MANDIR (man pages) +# - INSTALL_INFODIR (info pages) +# +# - INSTALL_SHAREDIR (location of aclocal/mysql.m4) +# - INSTALL_MYSQLSHAREDIR (MySQL character sets and localized error messages) +# - INSTALL_MYSQLTESTDIR (mysql-test) +# - INSTALL_SQLBENCHDIR (sql-bench) +# - INSTALL_SUPPORTFILESDIR (various extra support files) +# +# - INSTALL_MYSQLDATADIR (data directory) IF(NOT INSTALL_LAYOUT) SET(DEFAULT_INSTALL_LAYOUT "STANDALONE") @@ -60,15 +67,6 @@ ENDIF() SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}" CACHE STRING "Installation directory layout. Options are: STANDALONE (as in zip or tar.gz installer) or UNIX") -#IF(NOT INSTALL_LAYOUT MATCHES "STANDALONE") -# IF(NOT INSTALL_LAYOUT MATCHES "UNIX") -# # XXX not keen on this, how many more will we need? prefer to just bail... -# IF(NOT INSTALL_LAYOUT MATCHES "SVR4") -# SET(INSTALL_LAYOUT "${DEFAULT_INSTALL_LAYOUT}") -# ENDIF() -# ENDIF() -#ENDIF() - IF(UNIX) IF(INSTALL_LAYOUT MATCHES "RPM") SET(default_prefix "/usr") @@ -90,84 +88,111 @@ IF(UNIX) MARK_AS_ADVANCED(SYSCONFDIR) ENDIF() +# # STANDALONE layout -SET(INSTALL_BINDIR_STANDALONE "bin") -SET(INSTALL_SBINDIR_STANDALONE "bin") -SET(INSTALL_LIBDIR_STANDALONE "lib") -SET(INSTALL_INCLUDEDIR_STANDALONE "include") -SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") -SET(INSTALL_DOCDIR_STANDALONE "docs") -SET(INSTALL_MANDIR_STANDALONE "man") -SET(INSTALL_INFODIR_STANDALONE "docs") -SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") -SET(INSTALL_SHAREDIR_STANDALONE "share") -SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") -SET(INSTALL_MYSQLTESTDIR_STANDALONE "mysql-test") -SET(INSTALL_SQLBENCHROOTDIR_STANDALONE ".") -SET(INSTALL_DOCREADMEDIR_STANDALONE ".") -SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") -SET(INSTALL_MYSQLDATADIR_STANDALONE "data") +# +SET(INSTALL_BINDIR_STANDALONE "bin") +SET(INSTALL_SBINDIR_STANDALONE "bin") +SET(INSTALL_SCRIPTDIR_STANDALONE "scripts") +# +SET(INSTALL_LIBDIR_STANDALONE "lib") +SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_STANDALONE "include") +# +SET(INSTALL_DOCDIR_STANDALONE "docs") +SET(INSTALL_DOCREADMEDIR_STANDALONE ".") +SET(INSTALL_MANDIR_STANDALONE "man") +SET(INSTALL_INFODIR_STANDALONE "docs") +# +SET(INSTALL_SHAREDIR_STANDALONE "share") +SET(INSTALL_MYSQLSHAREDIR_STANDALONE "share") +SET(INSTALL_MYSQLTESTDIR_STANDALONE "mysql-test") +SET(INSTALL_SQLBENCHDIR_STANDALONE ".") +SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files") +# +SET(INSTALL_MYSQLDATADIR_STANDALONE "data") # # RPM layout # -SET(INSTALL_BINDIR_RPM "bin") -SET(INSTALL_INCLUDEDIR_RPM "include/mysql") -IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") - SET(INSTALL_LIBDIR_RPM "lib64") -ELSE() - SET(INSTALL_LIBDIR_RPM "lib") -ENDIF() -SET(INSTALL_SBINDIR_RPM "sbin") -SET(INSTALL_SHAREDIR_RPM "share") +SET(INSTALL_BINDIR_RPM "bin") +SET(INSTALL_SBINDIR_RPM "sbin") +SET(INSTALL_SCRIPTDIR_RPM "bin") # -#SET(INSTALL_DOCDIR_RPM "XXXunset") -#SET(INSTALL_DOCREADMEDIR_RPM "${INSTALL_DOCDIR_RPM}") -SET(INSTALL_INFODIR_RPM "${INSTALL_SHAREDIR_RPM}/info") -SET(INSTALL_MANDIR_RPM "${INSTALL_SHAREDIR_RPM}/man") -SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") -SET(INSTALL_MYSQLSHAREDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") -SET(INSTALL_MYSQLTESTDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql-test") -SET(INSTALL_PLUGINDIR_RPM "${INSTALL_LIBDIR_RPM}/mysql/plugin") -SET(INSTALL_SCRIPTDIR_RPM "${INSTALL_BINDIR_RPM}") -SET(INSTALL_SQLBENCHROOTDIR_RPM "") -SET(INSTALL_SUPPORTFILESDIR_RPM "${INSTALL_SHAREDIR_RPM}/mysql") +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + SET(INSTALL_LIBDIR_RPM "lib64") + SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin") +ELSE() + SET(INSTALL_LIBDIR_RPM "lib") + SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin") +ENDIF() +# +SET(INSTALL_INCLUDEDIR_RPM "include/mysql") +# +#SET(INSTALL_DOCDIR_RPM unset - installed directly by RPM) +#SET(INSTALL_DOCREADMEDIR_RPM unset - installed directly by RPM) +SET(INSTALL_INFODIR_RPM "share/info") +SET(INSTALL_MANDIR_RPM "share/man") +# +SET(INSTALL_SHAREDIR_RPM "share") +SET(INSTALL_MYSQLSHAREDIR_RPM "share/mysql") +SET(INSTALL_MYSQLTESTDIR_RPM "share/mysql-test") +SET(INSTALL_SQLBENCHDIR_RPM "") +SET(INSTALL_SUPPORTFILESDIR_RPM "share/mysql") +# +SET(INSTALL_MYSQLDATADIR_RPM "/var/lib/mysql") +# # DEB layout -SET(INSTALL_BINDIR_DEB "bin") -SET(INSTALL_SBINDIR_DEB "bin") -SET(INSTALL_LIBDIR_DEB "lib") -SET(INSTALL_INCLUDEDIR_DEB "include") -SET(INSTALL_PLUGINDIR_DEB "lib/plugin") -SET(INSTALL_DOCDIR_DEB "docs") -SET(INSTALL_MANDIR_DEB "man") -SET(INSTALL_INFODIR_DEB "docs") -SET(INSTALL_MYSQLSHAREDIR_DEB "share") -SET(INSTALL_SHAREDIR_DEB "share") -SET(INSTALL_SCRIPTDIR_DEB "scripts") -SET(INSTALL_MYSQLTESTDIR_DEB "mysql-test") -SET(INSTALL_SQLBENCHROOTDIR_DEB ".") -SET(INSTALL_DOCREADMEDIR_DEB ".") -SET(INSTALL_SUPPORTFILESDIR_DEB "support-files") -SET(INSTALL_MYSQLDATADIR_DEB "data") +# +SET(INSTALL_BINDIR_DEB "bin") +SET(INSTALL_SBINDIR_DEB "bin") +SET(INSTALL_SCRIPTDIR_DEB "scripts") +# +SET(INSTALL_LIBDIR_DEB "lib") +SET(INSTALL_PLUGINDIR_DEB "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_DEB "include") +# +SET(INSTALL_DOCDIR_DEB "docs") +SET(INSTALL_DOCREADMEDIR_DEB ".") +SET(INSTALL_MANDIR_DEB "man") +SET(INSTALL_INFODIR_DEB "docs") +# +SET(INSTALL_SHAREDIR_DEB "share") +SET(INSTALL_MYSQLSHAREDIR_DEB "share") +SET(INSTALL_MYSQLTESTDIR_DEB "mysql-test") +SET(INSTALL_SQLBENCHDIR_DEB ".") +SET(INSTALL_SUPPORTFILESDIR_DEB "support-files") +# +SET(INSTALL_MYSQLDATADIR_DEB "data") +# # SVR4 layout -SET(INSTALL_BINDIR_SVR4 "bin") -SET(INSTALL_SBINDIR_SVR4 "bin") -SET(INSTALL_LIBDIR_SVR4 "lib") -SET(INSTALL_INCLUDEDIR_SVR4 "include") -SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") -SET(INSTALL_DOCDIR_SVR4 "docs") -SET(INSTALL_MANDIR_SVR4 "man") -SET(INSTALL_INFODIR_SVR4 "docs") -SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") -SET(INSTALL_SHAREDIR_SVR4 "share") -SET(INSTALL_SCRIPTDIR_SVR4 "scripts") -SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") -SET(INSTALL_SQLBENCHROOTDIR_SVR4 ".") -SET(INSTALL_DOCREADMEDIR_SVR4 ".") -SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") -SET(INSTALL_MYSQLDATADIR_SVR4 "/var/lib/mysql") +# +SET(INSTALL_BINDIR_SVR4 "bin") +SET(INSTALL_SBINDIR_SVR4 "bin") +SET(INSTALL_SCRIPTDIR_SVR4 "scripts") +# +SET(INSTALL_LIBDIR_SVR4 "lib") +SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin") +# +SET(INSTALL_INCLUDEDIR_SVR4 "include") +# +SET(INSTALL_DOCDIR_SVR4 "docs") +SET(INSTALL_DOCREADMEDIR_SVR4 ".") +SET(INSTALL_MANDIR_SVR4 "man") +SET(INSTALL_INFODIR_SVR4 "docs") +# +SET(INSTALL_SHAREDIR_SVR4 "share") +SET(INSTALL_MYSQLSHAREDIR_SVR4 "share") +SET(INSTALL_MYSQLTESTDIR_SVR4 "mysql-test") +SET(INSTALL_SQLBENCHDIR_SVR4 ".") +SET(INSTALL_SUPPORTFILESDIR_SVR4 "support-files") +# +SET(INSTALL_MYSQLDATADIR_SVR4 "/var/lib/mysql") + # Clear cached variables if install layout was changed IF(OLD_INSTALL_LAYOUT) @@ -181,7 +206,7 @@ SET(OLD_INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE INTERNAL "") # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE # layout is chosen) FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN - INFO MYSQLTEST SQLBENCHROOT DOCREADME SUPPORTFILES MYSQLDATA) + INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA) SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}} CACHE STRING "${var} installation directory" ${FORCE}) MARK_AS_ADVANCED(INSTALL_${var}DIR) diff --git a/sql-bench/CMakeLists.txt b/sql-bench/CMakeLists.txt index 4b7f9520cc1..be0aeca70b0 100644 --- a/sql-bench/CMakeLists.txt +++ b/sql-bench/CMakeLists.txt @@ -21,14 +21,14 @@ ${CMAKE_SOURCE_DIR}/sql-bench/Data/Wisconsin/* ${CMAKE_SOURCE_DIR}/sql-bench/limits/* ) -IF(NOT INSTALL_SQLBENCHROOTDIR) +IF(NOT INSTALL_SQLBENCHDIR) RETURN() ENDIF() -IF(INSTALL_SQLBENCHROOTDIR STREQUAL ".") +IF(INSTALL_SQLBENCHDIR STREQUAL ".") SET(prefix) ELSE() - SET(prefix ${INSTALL_SQLBENCHROOTDIR}/) + SET(prefix ${INSTALL_SQLBENCHDIR}/) ENDIF() GET_FILENAME_COMPONENT(basedir ${CMAKE_SOURCE_DIR} ABSOLUTE) From 5230aa7a5e7275c4b9da3b612ddad8f3370e10b5 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 7 May 2010 12:11:09 +0200 Subject: [PATCH 119/207] Explicitly set OSX flags, to match current release. --- cmake/build_configurations/mysql_release.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index dd1015ff9b9..97de0965f6b 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -141,8 +141,8 @@ IF(UNIX) # OSX flags IF(APPLE) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os ${CMAKE_C_FLAGS_RELWITHDEBINFO}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -Os -fno-common") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -Os -felide-constructors -fno-common") ENDIF() # Solaris flags From 5ac769be68fbe2c112ef65b3d5590a7e5d080319 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Fri, 7 May 2010 20:28:59 +0400 Subject: [PATCH 120/207] Draft patch that fixes and a sketches test cases for: Bug#20837 Apparent change of isolation level during transaction, Bug#46527 COMMIT AND CHAIN RELEASE does not make sense, Bug#53343 completion_type=1, COMMIT/ROLLBACK AND CHAIN don't preserve the isolation level Bug#53346 completion_type has strange effect in a stored procedure/prepared statement Make thd->tx_isolation mean strictly "current transaction isolation level" Make thd->variables.tx_isolation mean "current session isolation level". The current transaction isolation level is now established at transaction start. If there was a SET TRANSACTION ISOLATION LEVEL statement, the value is taken from it. Otherwise, the session value is used. A change in a session value, made while a transaction is active, whereas still allowed, no longer has any effect on the current transaction isolation level. This is an incompatible change. A change in a session isolation level, made while there is no active transaction, overrides SET TRANSACTION statement, if there was any. Changed the impelmentation to not look at @@session.completion_type in the parser, and thus fixed Bug#53346. Changed the parser to not allow AND NO CHAIN RELEASE, and thus fixed Bug#46527. Changed the transaction API to take the current transaction isolation level into account: - BEGIN/COMMIT now do preserve the current transaction isolation level if chaining is on. - implicit commit, XA COMMIT or XA ROLLBACK or autocommit don't. --- mysql-test/r/innodb-semi-consistent.result | 1 + mysql-test/r/parser.result | 45 +++++++++++ .../r/partition_innodb_semi_consistent.result | 1 + mysql-test/r/ps.result | 4 +- .../suite/binlog/r/binlog_innodb.result | 28 +++---- mysql-test/suite/binlog/t/binlog_innodb.test | 28 +++---- mysql-test/t/innodb-semi-consistent.test | 1 + mysql-test/t/parser.test | 76 +++++++++++++++++++ .../t/partition_innodb_semi_consistent.test | 1 + mysql-test/t/sp_trans.test | 8 ++ sql/handler.cc | 3 - sql/sql_class.cc | 4 +- sql/sql_class.h | 27 ++++++- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 52 +++++++++++-- sql/sql_priv.h | 5 ++ sql/sql_yacc.yy | 26 ++++--- sql/sys_vars.cc | 36 ++++++--- sql/sys_vars.h | 16 ++++ sql/transaction.cc | 27 ++++++- 20 files changed, 327 insertions(+), 64 deletions(-) diff --git a/mysql-test/r/innodb-semi-consistent.result b/mysql-test/r/innodb-semi-consistent.result index ca0e362ef80..989cb818cec 100644 --- a/mysql-test/r/innodb-semi-consistent.result +++ b/mysql-test/r/innodb-semi-consistent.result @@ -13,6 +13,7 @@ set autocommit=0; update t1 set a=10 where a=5; ERROR HY000: Lock wait timeout exceeded; try restarting transaction commit; +commit; set session transaction isolation level read committed; update t1 set a=10 where a=5; select * from t1 where a=2 for update; diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 467bb7c5cb8..0cfde6dd2a0 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -618,3 +618,48 @@ DROP TABLE t1, t2, t3; # # End of 5.1 tests # +# Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" +# +COMMIT AND CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT AND NO CHAIN RELEASE; +COMMIT RELEASE; +COMMIT CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +COMMIT NO CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +COMMIT AND NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT AND RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT NO RELEASE; +COMMIT CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +COMMIT NO CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +COMMIT AND RELEASE CHAIN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 +COMMIT AND NO CHAIN NO RELEASE; +ROLLBACK AND CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK AND NO CHAIN RELEASE; +ROLLBACK RELEASE; +ROLLBACK CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +ROLLBACK NO CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +ROLLBACK AND NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK AND RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK NO RELEASE; +ROLLBACK CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +ROLLBACK NO CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +ROLLBACK AND RELEASE CHAIN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 +ROLLBACK AND NO CHAIN NO RELEASE; +# +# End of 5.5 tests +# diff --git a/mysql-test/r/partition_innodb_semi_consistent.result b/mysql-test/r/partition_innodb_semi_consistent.result index 48a1bb3d258..b3253ff33ea 100644 --- a/mysql-test/r/partition_innodb_semi_consistent.result +++ b/mysql-test/r/partition_innodb_semi_consistent.result @@ -18,6 +18,7 @@ set autocommit=0; update t1 set a=10 where a=5; ERROR HY000: Lock wait timeout exceeded; try restarting transaction commit; +commit; set session transaction isolation level read committed; update t1 set a=10 where a=5; select * from t1 where a=2 for update; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 0b2002b1350..a1d85539484 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -695,11 +695,11 @@ REPEATABLE-READ set transaction isolation level read committed; execute stmt; @@tx_isolation -READ-COMMITTED +REPEATABLE-READ set transaction isolation level serializable; execute stmt; @@tx_isolation -SERIALIZABLE +REPEATABLE-READ set @@tx_isolation=default; execute stmt; @@tx_isolation diff --git a/mysql-test/suite/binlog/r/binlog_innodb.result b/mysql-test/suite/binlog/r/binlog_innodb.result index 65182405136..44c9614950d 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_innodb.result @@ -2,65 +2,65 @@ SET BINLOG_FORMAT=MIXED; RESET MASTER; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB; INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6); -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = a * a WHERE a > 3; COMMIT; SET BINLOG_FORMAT=STATEMENT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t1 SET b = 1*a WHERE a > 1; ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 2; ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; SET BINLOG_FORMAT=MIXED; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t1 SET b = 1*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 2; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; SET BINLOG_FORMAT=ROW; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t1 SET b = 1*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 2; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; show binlog events from ; diff --git a/mysql-test/suite/binlog/t/binlog_innodb.test b/mysql-test/suite/binlog/t/binlog_innodb.test index c33a31a30f2..13edf262026 100644 --- a/mysql-test/suite/binlog/t/binlog_innodb.test +++ b/mysql-test/suite/binlog/t/binlog_innodb.test @@ -8,14 +8,14 @@ RESET MASTER; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=INNODB; INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6); -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; # Should be logged as statement UPDATE t1 SET b = 2*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; # Should be logged as rows UPDATE t1 SET b = a * a WHERE a > 3; COMMIT; @@ -25,69 +25,69 @@ COMMIT; SET BINLOG_FORMAT=STATEMENT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE; UPDATE t1 SET b = 1*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE; UPDATE t1 SET b = 2*a WHERE a > 2; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; SET BINLOG_FORMAT=MIXED; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t1 SET b = 1*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 2; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; SET BINLOG_FORMAT=ROW; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t1 SET b = 1*a WHERE a > 1; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; UPDATE t1 SET b = 2*a WHERE a > 2; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; UPDATE t1 SET b = 3*a WHERE a > 3; COMMIT; -BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; UPDATE t1 SET b = 4*a WHERE a > 4; COMMIT; diff --git a/mysql-test/t/innodb-semi-consistent.test b/mysql-test/t/innodb-semi-consistent.test index 61ad7815ca9..28bf532ff1f 100644 --- a/mysql-test/t/innodb-semi-consistent.test +++ b/mysql-test/t/innodb-semi-consistent.test @@ -23,6 +23,7 @@ set session transaction isolation level repeatable read; set autocommit=0; -- error ER_LOCK_WAIT_TIMEOUT update t1 set a=10 where a=5; +commit; connection a; commit; connection b; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index e6c9c8b423f..43d3abb0649 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -732,3 +732,79 @@ DROP TABLE t1, t2, t3; --echo # --echo # End of 5.1 tests --echo # + +--echo # Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" +--echo # +--error ER_PARSE_ERROR +COMMIT AND CHAIN RELEASE; + +COMMIT AND NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +COMMIT RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +COMMIT CHAIN RELEASE; + +--error ER_PARSE_ERROR +COMMIT NO CHAIN RELEASE; + +--error ER_PARSE_ERROR +COMMIT AND NO RELEASE; +--error ER_PARSE_ERROR +COMMIT AND RELEASE; + +COMMIT NO RELEASE; +--error ER_PARSE_ERROR +COMMIT CHAIN NO RELEASE; +--error ER_PARSE_ERROR +COMMIT NO CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +COMMIT AND RELEASE CHAIN; + +COMMIT AND NO CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK AND CHAIN RELEASE; + +ROLLBACK AND NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +ROLLBACK RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +ROLLBACK CHAIN RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +ROLLBACK AND NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK AND RELEASE; + +ROLLBACK NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK NO CHAIN NO RELEASE; +--error ER_PARSE_ERROR +ROLLBACK AND RELEASE CHAIN; + +ROLLBACK AND NO CHAIN NO RELEASE; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 294521a45d5..f6cca8481d1 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -31,6 +31,7 @@ set session transaction isolation level repeatable read; set autocommit=0; -- error ER_LOCK_WAIT_TIMEOUT update t1 set a=10 where a=5; +commit; connection a; #DELETE FROM t1 WHERE a=5; commit; diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index c4915bdb87a..a75bb52d4c2 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -636,7 +636,15 @@ UPDATE t1_aux SET f2 = 2 WHERE f1 = f1_two_inserts()| DROP TABLE t1_aux, t1_not_null| DROP FUNCTION f1_two_inserts| +--echo # +--echo # Bug#53346 completion_type has strange effect in a stored +--echo # procedure/prepared statement +--echo # + +--echo # +--echo # End of 5.5 tests +--echo # # # BUG#NNNN: New bug synopsis # diff --git a/sql/handler.cc b/sql/handler.cc index c0a5e2ff55c..34590bd3b42 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1297,7 +1297,6 @@ int ha_commit_one_phase(THD *thd, bool all) if (thd->transaction.changed_tables) query_cache.invalidate(thd->transaction.changed_tables); #endif - thd->variables.tx_isolation=thd->session_tx_isolation; } } /* Free resources and perform other cleanup even for 'empty' transactions. */ @@ -1374,8 +1373,6 @@ int ha_rollback_trans(THD *thd, bool all) if (is_real_trans && thd->transaction_rollback_request && thd->transaction.xid_state.xa_state != XA_NOTR) thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno(); - if (all) - thd->variables.tx_isolation=thd->session_tx_isolation; } /* Always cleanup. Even if nht==0. There may be savepoints. */ if (is_real_trans) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3144192a971..7db70c36d73 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -320,7 +320,7 @@ int thd_sql_command(const THD *thd) extern "C" int thd_tx_isolation(const THD *thd) { - return (int) thd->variables.tx_isolation; + return (int) thd->tx_isolation; } extern "C" @@ -922,7 +922,7 @@ void THD::init(void) update_lock_default= (variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE); - session_tx_isolation= (enum_tx_isolation) variables.tx_isolation; + tx_isolation= (enum_tx_isolation) variables.tx_isolation; update_charset(); reset_current_stmt_binlog_format_row(); bzero((char *) &status_var, sizeof(status_var)); diff --git a/sql/sql_class.h b/sql/sql_class.h index ac1a10f57b9..ca20849dc89 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2043,8 +2043,31 @@ public: uint server_status,open_options; enum enum_thread_type system_thread; uint select_number; //number of select (used for EXPLAIN) - /* variables.transaction_isolation is reset to this after each commit */ - enum_tx_isolation session_tx_isolation; + /* + Current or next transaction isolation level. + When a connection is established, the value is taken from + @@session.tx_isolation (default transaction isolation for + the session), which is in turn taken from @@global.tx_isolation + (the global value). + If there is no transaction started, this variable + holds the value of the next transaction's isolation level. + When a transaction starts, the value stored in this variable + becomes "actual". + At transaction commit or rollback, we assign this variable + again from @@session.tx_isolation. + The only statement that can otherwise change the value + of this variable is SET TRANSACTION ISOLATION LEVEL. + Its purpose is to effect the isolation level of the next + transaction in this session. When this statement is executed, + the value in this variable is changed. However, since + this statement is only allowed when there is no active + transaction, this assignment (naturally) only affects the + upcoming transaction. + At the end of the current active transaction the value is + be reset again from @@session.tx_isolation, as described + above. + */ + enum_tx_isolation tx_isolation; enum_check_fields count_cuted_fields; DYNAMIC_ARRAY user_var_events; /* For user variables replication */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6f7acc4a609..1e83b221dac 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1971,7 +1971,7 @@ struct LEX: public Query_tables_list bool autocommit; bool verbose, no_write_to_binlog; - bool tx_chain, tx_release; + enum enum_yes_no_unknown tx_chain, tx_release; /* Special JOIN::prepare mode: changing of query is prohibited. When creating a view, we need to just check its syntax omitting diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c8faac7c91d..2443b71dbc9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4033,33 +4033,65 @@ end_with_restore_list: my_ok(thd); break; case SQLCOM_COMMIT: + { DBUG_ASSERT(thd->lock == NULL || thd->locked_tables_mode == LTM_LOCK_TABLES); + bool tx_chain= (lex->tx_chain == TVL_YES || + (thd->variables.completion_type == 1 && + lex->tx_chain != TVL_NO)); + bool tx_release= (lex->tx_release == TVL_YES || + (thd->variables.completion_type == 2 && + lex->tx_release != TVL_NO)); if (trans_commit(thd)) goto error; thd->mdl_context.release_transactional_locks(); /* Begin transaction with the same isolation level. */ - if (lex->tx_chain && trans_begin(thd)) + if (tx_chain) + { + if (trans_begin(thd)) goto error; + } + else + { + /* Reset the isolation level if no chaining transaction. */ + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; + } /* Disconnect the current client connection. */ - if (lex->tx_release) + if (tx_release) thd->killed= THD::KILL_CONNECTION; my_ok(thd); break; + } case SQLCOM_ROLLBACK: + { DBUG_ASSERT(thd->lock == NULL || thd->locked_tables_mode == LTM_LOCK_TABLES); + bool tx_chain= (lex->tx_chain == TVL_YES || + (thd->variables.completion_type == 1 && + lex->tx_chain != TVL_NO)); + bool tx_release= (lex->tx_release == TVL_YES || + (thd->variables.completion_type == 2 && + lex->tx_release != TVL_NO)); if (trans_rollback(thd)) goto error; thd->mdl_context.release_transactional_locks(); /* Begin transaction with the same isolation level. */ - if (lex->tx_chain && trans_begin(thd)) - goto error; + if (tx_chain) + { + if (trans_begin(thd)) + goto error; + } + else + { + /* Reset the isolation level if no chaining transaction. */ + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; + } /* Disconnect the current client connection. */ - if (lex->tx_release) + if (tx_release) thd->killed= THD::KILL_CONNECTION; my_ok(thd); break; + } case SQLCOM_RELEASE_SAVEPOINT: if (trans_release_savepoint(thd, lex->ident)) goto error; @@ -4561,12 +4593,22 @@ create_sp_error: if (trans_xa_commit(thd)) goto error; thd->mdl_context.release_transactional_locks(); + /* + We've just done a commit, reset transaction + isolation level to the session default. + */ + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; my_ok(thd); break; case SQLCOM_XA_ROLLBACK: if (trans_xa_rollback(thd)) goto error; thd->mdl_context.release_transactional_locks(); + /* + We've just done a rollback, reset transaction + isolation level to the session default. + */ + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; my_ok(thd); break; case SQLCOM_XA_RECOVER: diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 20893e0caa8..7e53935700c 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -215,6 +215,11 @@ enum enum_var_type class sys_var; +enum enum_yes_no_unknown +{ + TVL_YES, TVL_NO, TVL_UNKNOWN +}; + #ifdef MYSQL_SERVER #endif /* MYSQL_SERVER */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aa336f3c072..b49e271c06c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -766,6 +766,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type, enum index_hint_type index_hint; enum enum_filetype filetype; enum Foreign_key::fk_option m_fk_option; + enum enum_yes_no_unknown m_yes_no_unk; Diag_condition_item_name diag_condition_item_name; } @@ -1433,12 +1434,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_option opt_if_not_exists opt_no_write_to_binlog opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option - start_transaction_opts opt_chain opt_release + start_transaction_opts union_opt select_derived_init option_type2 opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt +%type + opt_chain opt_release + %type delete_option @@ -13546,16 +13550,16 @@ opt_work: opt_chain: /* empty */ - { $$= (YYTHD->variables.completion_type == 1); } - | AND_SYM NO_SYM CHAIN_SYM { $$=0; } - | AND_SYM CHAIN_SYM { $$=1; } + { $$= TVL_UNKNOWN; } + | AND_SYM NO_SYM CHAIN_SYM { $$= TVL_NO; } + | AND_SYM CHAIN_SYM { $$= TVL_YES; } ; opt_release: /* empty */ - { $$= (YYTHD->variables.completion_type == 2); } - | RELEASE_SYM { $$=1; } - | NO_SYM RELEASE_SYM { $$=0; } + { $$= TVL_UNKNOWN; } + | RELEASE_SYM { $$= TVL_YES; } + | NO_SYM RELEASE_SYM { $$= TVL_NO; } ; opt_savepoint: @@ -13568,7 +13572,9 @@ commit: { LEX *lex=Lex; lex->sql_command= SQLCOM_COMMIT; - lex->tx_chain= $3; + /* Don't allow AND CHAIN RELEASE. */ + MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES); + lex->tx_chain= $3; lex->tx_release= $4; } ; @@ -13578,7 +13584,9 @@ rollback: { LEX *lex=Lex; lex->sql_command= SQLCOM_ROLLBACK; - lex->tx_chain= $3; + /* Don't allow AND CHAIN RELEASE. */ + MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES); + lex->tx_chain= $3; lex->tx_release= $4; } | ROLLBACK_SYM opt_work diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index b8312fc3255..2062af88b1a 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2022,24 +2022,38 @@ static bool check_tx_isolation(sys_var *self, THD *thd, set_var *var) return FALSE; } -/* - If one doesn't use the SESSION modifier, the isolation level - is only active for the next command. -*/ -static bool fix_tx_isolation(sys_var *self, THD *thd, enum_var_type type) + +bool Sys_var_tx_isolation::session_update(THD *thd, set_var *var) { - if (type == OPT_SESSION) - thd->session_tx_isolation= (enum_tx_isolation)thd->variables.tx_isolation; - return false; + if (var->type == OPT_SESSION && Sys_var_enum::session_update(thd, var)) + return TRUE; + if (var->type == OPT_DEFAULT || !thd->in_active_multi_stmt_transaction()) + { + /* + Update the isolation level of the next transaction. + I.e. if one did: + COMMIT; + SET SESSION ISOLATION LEVEL ... + BEGIN; <-- this transaction has the new isolation + Note, that in case of: + COMMIT; + SET TRANSACTION ISOLATION LEVEL ... + SET SESSION ISOLATION LEVEL ... + BEGIN; <-- the session isolation level is used, not the + result of SET TRANSACTION statement. + */ + thd->tx_isolation= (enum_tx_isolation) var->save_result.ulonglong_value; + } + return FALSE; } + // NO_CMD_LINE - different name of the option -static Sys_var_enum Sys_tx_isolation( +static Sys_var_tx_isolation Sys_tx_isolation( "tx_isolation", "Default transaction isolation level", SESSION_VAR(tx_isolation), NO_CMD_LINE, tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation), - ON_UPDATE(fix_tx_isolation)); + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation)); static Sys_var_ulonglong Sys_tmp_table_size( "tmp_table_size", diff --git a/sql/sys_vars.h b/sql/sys_vars.h index c4855ef4fd3..fbc48573487 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -1599,6 +1599,22 @@ public: { return type != STRING_RESULT; } }; + +class Sys_var_tx_isolation: public Sys_var_enum +{ +public: + Sys_var_tx_isolation(const char *name_arg, + const char *comment, int flag_args, ptrdiff_t off, size_t size, + CMD_LINE getopt, + const char *values[], uint def_val, PolyLock *lock, + enum binlog_status_enum binlog_status_arg, + on_check_function on_check_func) + :Sys_var_enum(name_arg, comment, flag_args, off, size, getopt, + values, def_val, lock, binlog_status_arg, on_check_func) + {} + virtual bool session_update(THD *thd, set_var *var); +}; + /**************************************************************************** Used templates ****************************************************************************/ diff --git a/sql/transaction.cc b/sql/transaction.cc index 5047de1ccdc..78551d6fcf7 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -96,7 +96,18 @@ bool trans_begin(THD *thd, uint flags) DBUG_ASSERT(!thd->locked_tables_mode); - if (trans_commit_implicit(thd)) + if (thd->in_multi_stmt_transaction_mode() || + (thd->variables.option_bits & OPTION_TABLE_LOCK)) + { + thd->variables.option_bits&= ~OPTION_TABLE_LOCK; + thd->server_status&= ~SERVER_STATUS_IN_TRANS; + res= test(ha_commit_trans(thd, TRUE)); + } + + thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); + thd->transaction.all.modified_non_trans_table= FALSE; + + if (res) DBUG_RETURN(TRUE); /* @@ -182,6 +193,14 @@ bool trans_commit_implicit(THD *thd) thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->transaction.all.modified_non_trans_table= FALSE; + /* + Upon implicit commit, reset the current transaction + isolation level. We do not care about + @@session.completion_type since it's documented + to not have any effect on implicit commit. + */ + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; + DBUG_RETURN(res); } @@ -234,7 +253,11 @@ bool trans_commit_stmt(THD *thd) DBUG_ENTER("trans_commit_stmt"); int res= FALSE; if (thd->transaction.stmt.ha_list) + { res= ha_commit_trans(thd, FALSE); + if (! thd->in_active_multi_stmt_transaction()) + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; + } if (res) /* @@ -265,6 +288,8 @@ bool trans_rollback_stmt(THD *thd) ha_rollback_trans(thd, FALSE); if (thd->transaction_rollback_request && !thd->in_sub_stmt) ha_rollback_trans(thd, TRUE); + if (! thd->in_active_multi_stmt_transaction()) + thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; } RUN_HOOK(transaction, after_rollback, (thd, FALSE)); From b5164c140178132018a1d4bdff95048b4d8ff4dc Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 12 May 2010 14:12:20 +0200 Subject: [PATCH 121/207] Pointless commit to avoid unnecessary diffs and to trigger a new build --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index fcdcb096d01..2ed3b1ff788 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -10,7 +10,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the +# along with this program; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1301 USA. From 08e457cc52d52c8d43b3e38e69254ee01b09db8b Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 14 May 2010 13:00:37 +0200 Subject: [PATCH 122/207] Null commit to test changes. From bb6c611314e6fef51fb31e797b7c61598f33f671 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Tue, 18 May 2010 14:25:02 +0200 Subject: [PATCH 123/207] config.h.cmake - Added missing HAVE_SYS_TIMES_H, HAVE_SYS_TIME_H, HAVE_TIME_H, HAVE_TIME and HAVE_TIMES - Removed most #if constructs, keep logic in "configure.cmake" - Use space after # if inside #if, for consistency configure.cmake - Added MY_CHECK_TYPE_SIZE function that sets both SIZEOF_* and HAVE_* - If "sys/stream.h" exists, include it before "sys/ptem.h" in test - Set VOID_SIGHANDLER if RETSIGTYPE is set to "void" --- config.h.cmake | 127 ++++++++++++++---------------------------------- configure.cmake | 82 ++++++++++++++++--------------- 2 files changed, 78 insertions(+), 131 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index b3b234a153b..cd9305e2b4f 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -81,6 +81,8 @@ #cmakedefine HAVE_SYS_STREAM_H 1 #cmakedefine HAVE_SYS_TERMCAP_H 1 #cmakedefine HAVE_SYS_TIMEB_H 1 +#cmakedefine HAVE_SYS_TIMES_H 1 +#cmakedefine HAVE_SYS_TIME_H 1 #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_SYS_UN_H 1 #cmakedefine HAVE_SYS_VADVISE_H 1 @@ -88,6 +90,7 @@ #cmakedefine HAVE_TERMIOS_H 1 #cmakedefine HAVE_TERMIO_H 1 #cmakedefine HAVE_TERMCAP_H 1 +#cmakedefine HAVE_TIME_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_UTIME_H 1 #cmakedefine HAVE_VARARGS_H 1 @@ -261,6 +264,8 @@ #cmakedefine HAVE_TEMPNAM 1 #cmakedefine HAVE_THR_SETCONCURRENCY 1 #cmakedefine HAVE_THR_YIELD 1 +#cmakedefine HAVE_TIME 1 +#cmakedefine HAVE_TIMES 1 #cmakedefine HAVE_VALLOC 1 #define HAVE_VIO_READ_BUFF 1 #cmakedefine HAVE_VASPRINTF 1 @@ -293,11 +298,6 @@ /* Types we may use */ -#cmakedefine SIZEOF_CHAR @SIZEOF_CHAR@ -#if SIZEOF_CHAR -# define HAVE_CHAR 1 -#endif - #ifdef __APPLE__ /* Special handling required for OSX to support universal binaries that @@ -316,119 +316,64 @@ #cmakedefine SIZEOF_SIZE_T @SIZEOF_CHARP@ #endif -#if SIZEOF_LONG -# define HAVE_LONG 1 -#endif - - +#cmakedefine SIZEOF_CHAR @SIZEOF_CHAR@ +#cmakedefine HAVE_CHAR 1 +#cmakedefine HAVE_LONG 1 +#cmakedefine HAVE_CHARP 1 #if SIZEOF_CHARP -#define HAVE_CHARP 1 -#define SIZEOF_VOIDP SIZEOF_CHARP +# define SIZEOF_VOIDP SIZEOF_CHARP #endif - #cmakedefine SIZEOF_SHORT @SIZEOF_SHORT@ -#if SIZEOF_SHORT -# define HAVE_SHORT 1 -#endif - +#cmakedefine HAVE_SHORT 1 #cmakedefine SIZEOF_INT @SIZEOF_INT@ -#if SIZEOF_INT -# define HAVE_INT 1 -#endif - - +#cmakedefine HAVE_INT 1 #cmakedefine SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@ -#if SIZEOF_LONG_LONG -# define HAVE_LONG_LONG 1 -#endif - +#cmakedefine HAVE_LONG_LONG 1 #cmakedefine SIZEOF_OFF_T @SIZEOF_OFF_T@ -#if SIZEOF_OFF_T -#define HAVE_OFF_T 1 -#endif - +#cmakedefine HAVE_OFF_T 1 #cmakedefine SIZEOF_SIGSET_T @SIZEOF_SIGSET_T@ -#if SIZEOF_SIGSET_T -#define HAVE_SIGSET_T 1 -#endif - -#if SIZEOF_SIZE_T -#define HAVE_SIZE_T 1 -#endif - +#cmakedefine HAVE_SIGSET_T 1 +#cmakedefine SIZEOF_SIZE_T @SIZEOF_SIZE_T@ +#cmakedefine HAVE_SIZE_T 1 #cmakedefine SIZEOF_UCHAR @SIZEOF_UCHAR@ -#if SIZEOF_UCHAR -#define HAVE_UCHAR 1 -#endif - +#cmakedefine HAVE_UCHAR 1 #cmakedefine SIZEOF_UINT @SIZEOF_UINT@ -#if SIZEOF_UINT -#define HAVE_UINT 1 -#endif - +#cmakedefine HAVE_UINT 1 #cmakedefine SIZEOF_ULONG @SIZEOF_ULONG@ -#if SIZEOF_ULONG -#define HAVE_ULONG 1 -#endif - +#cmakedefine HAVE_ULONG 1 #cmakedefine SIZEOF_INT8 @SIZEOF_INT8@ -#if SIZEOF_INT8 -#define HAVE_INT8 1 -#endif +#cmakedefine HAVE_INT8 1 #cmakedefine SIZEOF_UINT8 @SIZEOF_UINT8@ -#if SIZEOF_UINT8 -#define HAVE_UINT8 1 -#endif - +#cmakedefine HAVE_UINT8 1 #cmakedefine SIZEOF_INT16 @SIZEOF_INT16@ -#if SIZEOF_INT16 -# define HAVE_INT16 1 -#endif +#cmakedefine HAVE_INT16 1 #cmakedefine SIZEOF_UINT16 @SIZEOF_UINT16@ -#if SIZEOF_UINT16 -#define HAVE_UINT16 1 -#endif - +#cmakedefine HAVE_UINT16 1 #cmakedefine SIZEOF_INT32 @SIZEOF_INT32@ -#if SIZEOF_INT32 -#define HAVE_INT32 1 -#endif +#cmakedefine HAVE_INT32 1 #cmakedefine SIZEOF_UINT32 @SIZEOF_UINT32@ -#if SIZEOF_UINT32 -#define HAVE_UINT32 1 -#endif +#cmakedefine HAVE_UINT32 1 #cmakedefine SIZEOF_U_INT32_T @SIZEOF_U_INT32_T@ -#if SIZEOF_U_INT32_T -#define HAVE_U_INT32_T 1 -#endif - +#cmakedefine HAVE_U_INT32_T 1 #cmakedefine SIZEOF_INT64 @SIZEOF_INT64@ -#if SIZEOF_INT64 -#define HAVE_INT64 1 -#endif +#cmakedefine HAVE_INT64 1 #cmakedefine SIZEOF_UINT64 @SIZEOF_UINT64@ -#if SIZEOF_UINT64 -#define HAVE_UINT64 1 -#endif +#cmakedefine HAVE_UINT64 1 +#cmakedefine SIZEOF_BOOL @SIZEOF_BOOL@ +#cmakedefine HAVE_BOOL 1 #cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@ -#cmakedefine SIZEOF_BOOL @SIZEOF_BOOL@ -#if SIZEOF_BOOL -#define HAVE_BOOL 1 -#endif #cmakedefine HAVE_MBSTATE_T #define MAX_INDEXES 64 #cmakedefine QSORT_TYPE_IS_VOID 1 -#define RETQSORTTYPE void +#cmakedefine RETQSORTTYPE @RETQSORTTYPE@ #cmakedefine SIGNAL_RETURN_TYPE_IS_VOID 1 -#define RETSIGTYPE void -#if SIGNAL_RETURN_TYPE_IS_VOID -#define VOID_SIGHANDLER 1 -#endif +#cmakedefine RETSIGTYPE @RETSIGTYPE@ +#cmakedefine VOID_SIGHANDLER 1 #define STRUCT_RLIMIT struct rlimit #ifdef __APPLE__ @@ -545,7 +490,7 @@ #cmakedefine strtoull @strtoull@ #cmakedefine vsnprintf @vsnprintf@ #if (_MSC_VER > 1310) -#define HAVE_SETENV +# define HAVE_SETENV #define setenv(a,b,c) _putenv_s(a,b) #endif @@ -635,7 +580,7 @@ #cmakedefine WITH_PERFSCHEMA_STORAGE_ENGINE 1 #cmakedefine WITH_NDBCLUSTER_STORAGE_ENGINE 1 #if (WITH_NDBCLUSTER_STORAGE_ENGINE) && !defined(EMBEDDED_LIBRARY) -#define HAVE_NDB_BINLOG 1 +# define HAVE_NDB_BINLOG 1 #endif #cmakedefine DEFAULT_MYSQL_HOME "@DEFAULT_MYSQL_HOME@" diff --git a/configure.cmake b/configure.cmake index 31e38aaa2cd..0dc32b08226 100644 --- a/configure.cmake +++ b/configure.cmake @@ -81,6 +81,13 @@ ENDIF(WITHOUT_DYNAMIC_PLUGINS) # Large files, common flag SET(_LARGEFILE_SOURCE 1) +# If finds the size of a type, set SIZEOF_ and HAVE_ +FUNCTION(MY_CHECK_TYPE_SIZE type defbase) + CHECK_TYPE_SIZE("${type}" SIZEOF_${defbase}) + IF(SIZEOF_${defbase}) + SET(HAVE_${defbase} 1 PARENT_SCOPE) + ENDIF() +ENDFUNCTION() # Searches function in libraries # if function is found, sets output parameter result to the name of the library @@ -186,7 +193,6 @@ CHECK_INCLUDE_FILES (select.h HAVE_SELECT_H) CHECK_INCLUDE_FILES (semaphore.h HAVE_SEMAPHORE_H) CHECK_INCLUDE_FILES (sys/dir.h HAVE_SYS_DIR_H) CHECK_INCLUDE_FILES (sys/pte.h HAVE_SYS_PTE_H) -CHECK_INCLUDE_FILES (sys/ptem.h HAVE_SYS_PTEM_H) CHECK_INCLUDE_FILES (stddef.h HAVE_STDDEF_H) CHECK_INCLUDE_FILES (stdint.h HAVE_STDINT_H) CHECK_INCLUDE_FILES (stdlib.h HAVE_STDLIB_H) @@ -226,6 +232,13 @@ CHECK_INCLUDE_FILES (fnmatch.h HAVE_FNMATCH_H) CHECK_INCLUDE_FILES (stdarg.h HAVE_STDARG_H) CHECK_INCLUDE_FILES("stdlib.h;sys/un.h" HAVE_SYS_UN_H) +IF(HAVE_SYS_STREAM_H) + # Needs sys/stream.h on Solaris + CHECK_INCLUDE_FILES (sys/stream.h sys/ptem.h HAVE_SYS_PTEM_H) +ELSE() + CHECK_INCLUDE_FILES (sys/ptem.h HAVE_SYS_PTEM_H) +ENDIF() + # Figure out threading library # FIND_PACKAGE (Threads) @@ -449,14 +462,11 @@ set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_LARGEFILE_SOURCE -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS) SET(CMAKE_EXTRA_INCLUDE_FILES signal.h) -CHECK_TYPE_SIZE(sigset_t SIZEOF_SIGSET_T) -IF(SIZEOF_SIGSET_T) - SET(HAVE_SIGSET_T 1) -ENDIF() +MY_CHECK_TYPE_SIZE(sigset_t SIGSET_T) IF(NOT SIZEOF_SIGSET_T) SET(sigset_t int) ENDIF() -CHECK_TYPE_SIZE(mode_t SIZEOF_MODE_T) +MY_CHECK_TYPE_SIZE(mode_t MODE_T) IF(NOT SIZEOF_MODE_T) SET(mode_t int) ENDIF() @@ -469,43 +479,40 @@ ENDIF(HAVE_STDINT_H) IF(NOT APPLE) # Prevent some checks on OSX, they return ambigious results # on universal 32/64 bit binariess - CHECK_TYPE_SIZE("char *" SIZEOF_CHARP) - CHECK_TYPE_SIZE(long SIZEOF_LONG) - CHECK_TYPE_SIZE(size_t SIZEOF_SIZE_T) + MY_CHECK_TYPE_SIZE("char *" CHARP) + MY_CHECK_TYPE_SIZE(long LONG) + MY_CHECK_TYPE_SIZE(size_t SIZE_T) ENDIF() -CHECK_TYPE_SIZE(char SIZEOF_CHAR) -CHECK_TYPE_SIZE(short SIZEOF_SHORT) -CHECK_TYPE_SIZE(int SIZEOF_INT) -CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG) +MY_CHECK_TYPE_SIZE(char CHAR) +MY_CHECK_TYPE_SIZE(short SHORT) +MY_CHECK_TYPE_SIZE(int INT) +MY_CHECK_TYPE_SIZE("long long" LONG_LONG) SET(CMAKE_EXTRA_INCLUDE_FILES stdio.h sys/types.h) -CHECK_TYPE_SIZE(off_t SIZEOF_OFF_T) -CHECK_TYPE_SIZE(uchar SIZEOF_UCHAR) -CHECK_TYPE_SIZE(uint SIZEOF_UINT) -CHECK_TYPE_SIZE(ulong SIZEOF_ULONG) -CHECK_TYPE_SIZE(int8 SIZEOF_INT8) -CHECK_TYPE_SIZE(uint8 SIZEOF_UINT8) -CHECK_TYPE_SIZE(int16 SIZEOF_INT16) -CHECK_TYPE_SIZE(uint16 SIZEOF_UINT16) -CHECK_TYPE_SIZE(int32 SIZEOF_INT32) -CHECK_TYPE_SIZE(uint32 SIZEOF_UINT32) -CHECK_TYPE_SIZE(u_int32_t SIZEOF_U_INT32_T) -CHECK_TYPE_SIZE(int64 SIZEOF_INT64) -CHECK_TYPE_SIZE(uint64 SIZEOF_UINT64) +MY_CHECK_TYPE_SIZE(off_t OFF_T) +MY_CHECK_TYPE_SIZE(uchar UCHAR) +MY_CHECK_TYPE_SIZE(uint UINT) +MY_CHECK_TYPE_SIZE(ulong ULONG) +MY_CHECK_TYPE_SIZE(int8 INT8) +MY_CHECK_TYPE_SIZE(uint8 UINT8) +MY_CHECK_TYPE_SIZE(int16 INT16) +MY_CHECK_TYPE_SIZE(uint16 UINT16) +MY_CHECK_TYPE_SIZE(int32 INT32) +MY_CHECK_TYPE_SIZE(uint32 UINT32) +MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T) +MY_CHECK_TYPE_SIZE(int64 INT64) +MY_CHECK_TYPE_SIZE(uint64 UINT64) SET (CMAKE_EXTRA_INCLUDE_FILES sys/types.h) -CHECK_TYPE_SIZE(bool SIZEOF_BOOL) +MY_CHECK_TYPE_SIZE(bool BOOL) SET(CMAKE_EXTRA_INCLUDE_FILES) IF(HAVE_SYS_SOCKET_H) SET(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) ENDIF(HAVE_SYS_SOCKET_H) -CHECK_TYPE_SIZE(socklen_t SIZEOF_SOCKLEN_T) +MY_CHECK_TYPE_SIZE(socklen_t SOCKLEN_T) SET(CMAKE_EXTRA_INCLUDE_FILES) IF(HAVE_IEEEFP_H) SET(CMAKE_EXTRA_INCLUDE_FILES ieeefp.h) - CHECK_TYPE_SIZE(fp_except SIZEOF_FP_EXCEPT) - IF(SIZEOF_FP_EXCEPT) - SET(HAVE_FP_EXCEPT TRUE) - ENDIF() + MY_CHECK_TYPE_SIZE(fp_except FP_EXCEPT) ENDIF() @@ -669,6 +676,7 @@ int main(int ac, char **av) {} " SIGNAL_RETURN_TYPE_IS_VOID) IF(SIGNAL_RETURN_TYPE_IS_VOID) SET(RETSIGTYPE void) + SET(VOID_SIGHANDLER 1) ELSE(SIGNAL_RETURN_TYPE_IS_VOID) SET(RETSIGTYPE int) ENDIF(SIGNAL_RETURN_TYPE_IS_VOID) @@ -973,14 +981,8 @@ ELSEIF(WIN32) SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} winsock2.h ws2ipdef.h) ENDIF() -CHECK_TYPE_SIZE("struct sockaddr_in6" SIZEOF_SOCKADDR_IN6) -CHECK_TYPE_SIZE("struct in6_addr" SIZEOF_IN6_ADDR) -IF(SIZEOF_SOCKADDR_IN6) - SET(HAVE_STRUCT_SOCKADDR_IN6 1) -ENDIF() -IF(SIZEOF_IN6_ADDR) - SET(HAVE_STRUCT_IN6_ADDR 1) -ENDIF() +MY_CHECK_TYPE_SIZE("struct sockaddr_in6" SOCKADDR_IN6) +MY_CHECK_TYPE_SIZE("struct in6_addr" IN6_ADDR) IF(HAVE_STRUCT_SOCKADDR_IN6 OR HAVE_STRUCT_IN6_ADDR) SET(HAVE_IPV6 TRUE CACHE INTERNAL "") From 89850be0f51a2f761aa88236e5ced7d5a7eddd03 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 19 May 2010 18:01:12 +0100 Subject: [PATCH 124/207] BUG#53560 CREATE TEMP./DROP TEMP. are not binglogged correctly after a failed statement This patch fixes two problems described as follows: 1 - If there is an on-going transaction and a temporary table is created or dropped, any failed statement that follows the "create" or "drop commands" triggers a rollback and by consequence the slave will go out sync because the binary log will have a wrong sequence of events. To fix the problem, we changed the expression that evaluates when the cache should be flushed after either the rollback of a statment or transaction. 2 - When a "CREATE TEMPORARY TABLE SELECT * FROM" was executed the OPTION_KEEP_LOG was not set into the thd->options. For that reason, if the transaction had updated only transactional engines and was rolled back at the end (.e.g due to a deadlock) the changes were not written to the binary log, including the creation of the temporary table. To fix the problem, we have set the OPTION_KEEP_LOG into the thd->options when a "CREATE TEMPORARY TABLE SELECT * FROM" is executed. --- .../r/binlog_stm_mix_innodb_myisam.result | 3 + .../suite/rpl/r/rpl_temporary_errors.result | 57 ++++++++++ .../suite/rpl/t/rpl_temporary_errors.test | 40 +++++++ sql/log.cc | 106 +++++++++++++----- sql/log.h | 5 + sql/log_event.cc | 6 - sql/log_event_old.cc | 10 -- sql/sql_parse.cc | 4 + 8 files changed, 190 insertions(+), 41 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index b3f9baed2dd..a26fcc1dc1a 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -364,6 +364,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (10,10) master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; INSERT INTO t2 values (100,100) master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 values (101,101) +master-bin.000001 # Query # # ROLLBACK master-bin.000001 # Query # # use `test`; DROP TABLE t1,t2 reset master; create table t1 (a int) engine=innodb; diff --git a/mysql-test/suite/rpl/r/rpl_temporary_errors.result b/mysql-test/suite/rpl/r/rpl_temporary_errors.result index d14380a6369..2bd1b691901 100644 --- a/mysql-test/suite/rpl/r/rpl_temporary_errors.result +++ b/mysql-test/suite/rpl/r/rpl_temporary_errors.result @@ -81,4 +81,61 @@ Last_SQL_Errno 0 Last_SQL_Error DROP TABLE t1; **** On Master **** +SET SQL_LOG_BIN= 0; DROP TABLE t1; +SET SQL_LOG_BIN= 1; +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t_myisam (id INT, PRIMARY KEY (id)) engine= MyIsam; +INSERT INTO t_myisam (id) VALUES(1); +CREATE TABLE t_innodb (id INT) engine= Innodb; +INSERT INTO t_innodb (id) VALUES(1); +BEGIN; +INSERT INTO t_innodb(id) VALUES(2); +INSERT INTO t_myisam(id) VALUES(3); +CREATE TEMPORARY TABLE x (id INT); +INSERT INTO t_myisam(id) VALUES(4),(1); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +INSERT INTO t_innodb(id) VALUES(5); +COMMIT; +SELECT * FROM t_innodb; +id +1 +2 +5 +SELECT * FROM t_myisam; +id +1 +3 +4 +SELECT * FROM t_innodb; +id +1 +2 +5 +SELECT * FROM t_myisam; +id +1 +3 +4 +BEGIN; +CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb; +INSERT INTO t_innodb(id) VALUES(1); +INSERT INTO t_innodb(id) VALUES(1); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(2) +master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam(id) VALUES(3) +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE x (id INT) +master-bin.000001 # Query # # use `test`; INSERT INTO t_myisam(id) VALUES(4),(1) +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(5) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(1) +master-bin.000001 # Query # # use `test`; INSERT INTO t_innodb(id) VALUES(1) +master-bin.000001 # Query # # ROLLBACK +DROP TABLE t_myisam, t_innodb; diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors.test b/mysql-test/suite/rpl/t/rpl_temporary_errors.test index 3b373e00a62..4bc374cdca7 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary_errors.test +++ b/mysql-test/suite/rpl/t/rpl_temporary_errors.test @@ -1,4 +1,5 @@ source include/master-slave.inc; +source include/have_innodb.inc; call mtr.add_suppression("Deadlock found"); @@ -30,4 +31,43 @@ DROP TABLE t1; --echo **** On Master **** connection master; +SET SQL_LOG_BIN= 0; DROP TABLE t1; +SET SQL_LOG_BIN= 1; + +# BUG#Bug #53259 Unsafe statement binlogged in statement format w/MyIsam temp tables +# +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t_myisam (id INT, PRIMARY KEY (id)) engine= MyIsam; +INSERT INTO t_myisam (id) VALUES(1); +CREATE TABLE t_innodb (id INT) engine= Innodb; +INSERT INTO t_innodb (id) VALUES(1); + +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +BEGIN; +INSERT INTO t_innodb(id) VALUES(2); +INSERT INTO t_myisam(id) VALUES(3); +CREATE TEMPORARY TABLE x (id INT); +--error 1062 +INSERT INTO t_myisam(id) VALUES(4),(1); +INSERT INTO t_innodb(id) VALUES(5); +COMMIT; + +SELECT * FROM t_innodb; +SELECT * FROM t_myisam; + +--sync_slave_with_master + +SELECT * FROM t_innodb; +SELECT * FROM t_myisam; + +--connection master + +BEGIN; +CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb; +INSERT INTO t_innodb(id) VALUES(1); +INSERT INTO t_innodb(id) VALUES(1); +ROLLBACK; +source include/show_binlog_events.inc; + +DROP TABLE t_myisam, t_innodb; diff --git a/sql/log.cc b/sql/log.cc index 7d820b48c43..79a6b4d6cb0 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1510,27 +1510,23 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) } /* - We commit the transaction if: + We flush the cache if: - - We are not in a transaction and committing a statement, or - - - We are in a transaction and a full transaction is committed + - we are committing a transaction; + - and no statement was committed before and just non-transactional + tables were updated. Otherwise, we accumulate the statement */ - ulonglong const in_transaction= - thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN); DBUG_PRINT("debug", - ("all: %d, empty: %s, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s", + ("all: %d, empty: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s", all, YESNO(trx_data->empty()), - YESNO(in_transaction), YESNO(thd->transaction.all.modified_non_trans_table), YESNO(thd->transaction.stmt.modified_non_trans_table))); - if (!in_transaction || all || - (!all && !trx_data->at_least_one_stmt_committed && - !stmt_has_updated_trans_table(thd) && - thd->transaction.stmt.modified_non_trans_table)) + if (ending_trans(thd, all) || + (trans_has_no_stmt_committed(thd, all) && + !stmt_has_updated_trans_table(thd) && stmt_has_updated_non_trans_table(thd))) { Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); @@ -1593,7 +1589,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) On the other hand, if a statement is transactional, we just safely roll it back. */ - if ((thd->transaction.stmt.modified_non_trans_table || + if ((stmt_has_updated_non_trans_table(thd) || (thd->options & OPTION_KEEP_LOG)) && mysql_bin_log.check_write_error(thd)) trx_data->set_incident(); @@ -1603,19 +1599,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) { /* We flush the cache with a rollback, wrapped in a beging/rollback if: - . aborting a transaction that modified a non-transactional table; + . aborting a transaction that modified a non-transactional table or + the OPTION_KEEP_LOG is activate. . aborting a statement that modified both transactional and non-transactional tables but which is not in the boundaries of any transaction or there was no early change; - . the OPTION_KEEP_LOG is activate. */ - if ((all && thd->transaction.all.modified_non_trans_table) || - (!all && thd->transaction.stmt.modified_non_trans_table && - !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) || - (!all && thd->transaction.stmt.modified_non_trans_table && - !trx_data->at_least_one_stmt_committed && - thd->current_stmt_binlog_row_based) || - ((thd->options & OPTION_KEEP_LOG))) + if ((ending_trans(thd, all) && + (trans_has_updated_non_trans_table(thd) || + (thd->options & OPTION_KEEP_LOG))) || + (trans_has_no_stmt_committed(thd, all) && + stmt_has_updated_non_trans_table(thd) && + thd->current_stmt_binlog_row_based)) { Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); @@ -1624,8 +1619,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) Otherwise, we simply truncate the cache as there is no change on non-transactional tables as follows. */ - else if ((all && !thd->transaction.all.modified_non_trans_table) || - (!all && !thd->transaction.stmt.modified_non_trans_table)) + else if (ending_trans(thd, all) || + (!(thd->options & OPTION_KEEP_LOG) && !stmt_has_updated_non_trans_table(thd))) error= binlog_end_trans(thd, trx_data, 0, all); } if (!all) @@ -1721,7 +1716,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) non-transactional table. Otherwise, truncate the binlog cache starting from the SAVEPOINT command. */ - if (unlikely(thd->transaction.all.modified_non_trans_table || + if (unlikely(trans_has_updated_non_trans_table(thd) || (thd->options & OPTION_KEEP_LOG))) { String log_query; @@ -3934,6 +3929,67 @@ bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param) query_id_param >= thd->binlog_evt_union.first_query_id); } +/** + This function checks if a transaction, either a multi-statement + or a single statement transaction is about to commit or not. + + @param thd The client thread that executed the current statement. + @param all Committing a transaction (i.e. TRUE) or a statement + (i.e. FALSE). + @return + @c true if committing a transaction, otherwise @c false. +*/ +bool ending_trans(const THD* thd, const bool all) +{ + return (all || (!all && !(thd->options & + (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))); +} + +/** + This function checks if a non-transactional table was updated by + the current transaction. + + @param thd The client thread that executed the current statement. + @return + @c true if a non-transactional table was updated, @c false + otherwise. +*/ +bool trans_has_updated_non_trans_table(const THD* thd) +{ + return (thd->transaction.all.modified_non_trans_table || + thd->transaction.stmt.modified_non_trans_table); +} + +/** + This function checks if any statement was committed and cached. + + @param thd The client thread that executed the current statement. + @param all Committing a transaction (i.e. TRUE) or a statement + (i.e. FALSE). + @return + @c true if at a statement was committed and cached, @c false + otherwise. +*/ +bool trans_has_no_stmt_committed(const THD* thd, bool all) +{ + binlog_trx_data *const trx_data= + (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton); + + return (!all && !trx_data->at_least_one_stmt_committed); +} + +/** + This function checks if a non-transactional table was updated by the + current statement. + + @param thd The client thread that executed the current statement. + @return + @c true if a non-transactional table was updated, @c false otherwise. +*/ +bool stmt_has_updated_non_trans_table(const THD* thd) +{ + return (thd->transaction.stmt.modified_non_trans_table); +} /* These functions are placed in this file since they need access to diff --git a/sql/log.h b/sql/log.h index 5af51e14d80..8d3880d9171 100644 --- a/sql/log.h +++ b/sql/log.h @@ -20,6 +20,11 @@ class Relay_log_info; class Format_description_log_event; +bool ending_trans(const THD* thd, const bool all); +bool trans_has_updated_non_trans_table(const THD* thd); +bool trans_has_no_stmt_committed(const THD* thd, const bool all); +bool stmt_has_updated_non_trans_table(const THD* thd); + /* Transaction Coordinator log - a base abstract class for two different implementations diff --git a/sql/log_event.cc b/sql/log_event.cc index a8e227fa99b..617d1188984 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7544,12 +7544,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) clear_all_errors(thd, const_cast(rli)); error= 0; } - - if (!cache_stmt) - { - DBUG_PRINT("info", ("Marked that we need to keep log")); - thd->options|= OPTION_KEEP_LOG; - } } // if (table) /* diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index df162761b35..be389acafe8 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -229,11 +229,6 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event", const_cast(rli)->abort_slave= 1;); error= do_after_row_operations(table, error); - if (!ev->cache_stmt) - { - DBUG_PRINT("info", ("Marked that we need to keep log")); - ev_thd->options|= OPTION_KEEP_LOG; - } } /* @@ -1755,11 +1750,6 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event", const_cast(rli)->abort_slave= 1;); error= do_after_row_operations(rli, error); - if (!cache_stmt) - { - DBUG_PRINT("info", ("Marked that we need to keep log")); - thd->options|= OPTION_KEEP_LOG; - } } // if (table) /* diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 93d80164ffb..98e7f187fc4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2713,6 +2713,10 @@ mysql_execute_command(THD *thd) } } + /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ + if (create_info.options & HA_LEX_CREATE_TMP_TABLE) + thd->options|= OPTION_KEEP_LOG; + /* select_create is currently not re-execution friendly and needs to be created for every execution of a PS/SP. From 497abee8f31732367ee3c7d74c0cd56313535609 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Fri, 21 May 2010 01:40:12 +0200 Subject: [PATCH 125/207] config.h.cmake - Set SIZEOF_VOIDP the same way as others - Unindent the no Mac OS settings, to let the checker scripts find the lines - Removed duplicate SIZEOF_SIZE_T setting - Added missing value for HAVE_CHARSET_ascii configure.cmake - Added HAVE_ prefix to library names, like HAVE_LIBM - Set HAVE_CXXABI_H if header is found, HAVE_ABI_CXA_DEMANGLE controls if useful - Set SIZEOF_VOIDP the same way as others --- config.h.cmake | 15 +++++++-------- configure.cmake | 9 ++++----- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index cd9305e2b4f..f93cc18a0bc 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -308,21 +308,21 @@ #else #define SIZEOF_LONG 4 #endif + #define SIZEOF_VOIDP SIZEOF_LONG #define SIZEOF_CHARP SIZEOF_LONG #define SIZEOF_SIZE_T SIZEOF_LONG #else - #cmakedefine SIZEOF_LONG @SIZEOF_LONG@ - #cmakedefine SIZEOF_CHARP @SIZEOF_CHARP@ - #cmakedefine SIZEOF_SIZE_T @SIZEOF_CHARP@ +# No indentation, to fetch the lines from verification scripts +#cmakedefine SIZEOF_LONG @SIZEOF_LONG@ +#cmakedefine SIZEOF_VOIDP @SIZEOF_VOIDP@ +#cmakedefine SIZEOF_CHARP @SIZEOF_CHARP@ +#cmakedefine SIZEOF_SIZE_T @SIZEOF_CHARP@ #endif #cmakedefine SIZEOF_CHAR @SIZEOF_CHAR@ #cmakedefine HAVE_CHAR 1 #cmakedefine HAVE_LONG 1 #cmakedefine HAVE_CHARP 1 -#if SIZEOF_CHARP -# define SIZEOF_VOIDP SIZEOF_CHARP -#endif #cmakedefine SIZEOF_SHORT @SIZEOF_SHORT@ #cmakedefine HAVE_SHORT 1 #cmakedefine SIZEOF_INT @SIZEOF_INT@ @@ -333,7 +333,6 @@ #cmakedefine HAVE_OFF_T 1 #cmakedefine SIZEOF_SIGSET_T @SIZEOF_SIGSET_T@ #cmakedefine HAVE_SIGSET_T 1 -#cmakedefine SIZEOF_SIZE_T @SIZEOF_SIZE_T@ #cmakedefine HAVE_SIZE_T 1 #cmakedefine SIZEOF_UCHAR @SIZEOF_UCHAR@ #cmakedefine HAVE_UCHAR 1 @@ -518,7 +517,7 @@ #cmakedefine FN_NO_CASE_SENSE 1 #cmakedefine HAVE_CHARSET_armscii8 1 -#cmakedefine HAVE_CHARSET_ascii +#cmakedefine HAVE_CHARSET_ascii 1 #cmakedefine HAVE_CHARSET_big5 1 #cmakedefine HAVE_CHARSET_cp1250 1 #cmakedefine HAVE_CHARSET_cp1251 1 diff --git a/configure.cmake b/configure.cmake index 0dc32b08226..6734b652676 100644 --- a/configure.cmake +++ b/configure.cmake @@ -105,7 +105,7 @@ FUNCTION(MY_SEARCH_LIBS func libs result) FOREACH(lib ${libs}) CHECK_LIBRARY_EXISTS(${lib} ${func} "" HAVE_${func}_IN_${lib}) IF(HAVE_${func}_IN_${lib}) - SET(${result} ${lib} PARENT_SCOPE) + SET(${result} HAVE_${lib} PARENT_SCOPE) RETURN() ENDIF() ENDFOREACH() @@ -167,6 +167,7 @@ CHECK_INCLUDE_FILES (alloca.h HAVE_ALLOCA_H) CHECK_INCLUDE_FILES (aio.h HAVE_AIO_H) CHECK_INCLUDE_FILES (arpa/inet.h HAVE_ARPA_INET_H) CHECK_INCLUDE_FILES (crypt.h HAVE_CRYPT_H) +CHECK_INCLUDE_FILES (cxxabi.h HAVE_CXXABI_H) CHECK_INCLUDE_FILES (dirent.h HAVE_DIRENT_H) CHECK_INCLUDE_FILES (dlfcn.h HAVE_DLFCN_H) CHECK_INCLUDE_FILES (execinfo.h HAVE_EXECINFO_H) @@ -479,6 +480,7 @@ ENDIF(HAVE_STDINT_H) IF(NOT APPLE) # Prevent some checks on OSX, they return ambigious results # on universal 32/64 bit binariess + MY_CHECK_TYPE_SIZE("void *" VOIDP) MY_CHECK_TYPE_SIZE("char *" CHARP) MY_CHECK_TYPE_SIZE(long LONG) MY_CHECK_TYPE_SIZE(size_t SIZE_T) @@ -776,7 +778,7 @@ ENDIF(NOT HAVE_POSIX_SIGNALS) # Assume regular sprintf SET(SPRINTFS_RETURNS_INT 1) -IF(CMAKE_COMPILER_IS_GNUXX) +IF(CMAKE_COMPILER_IS_GNUXX AND HAVE_CXXABI_H) CHECK_CXX_SOURCE_COMPILES(" #include int main(int argc, char **argv) @@ -786,9 +788,6 @@ CHECK_CXX_SOURCE_COMPILES(" return 0; }" HAVE_ABI_CXA_DEMANGLE) -IF(HAVE_ABI_CXA_DEMANGLE) - SET(HAVE_CXXABI_H 1) -ENDIF() ENDIF() CHECK_C_SOURCE_COMPILES(" From 447846cf3c96c1e729b32a240acfb3e3caa2618b Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 21 May 2010 19:31:55 +0200 Subject: [PATCH 126/207] Get rid ot the "net retry count" difference which is not needed any more with current versions of FreeBSD. (Entries 52410 and 52412 in the Bug DB) That change is based on Dan Nelson replying on the FreeBSD mailing list, freebsd-questions@freebsd.org in a thread running from 2010-Apr-29 to 2010-May-1 titled "Need info about FreeBSD and interrupted system calls for MySQL code" Also, ensure the cmake settings correspond to the autotools ones: Add "HAVE_BROKEN_REALPATH" to cmake. --- cmake/os/FreeBSD.cmake | 9 ++++++--- configure.in | 14 +++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/cmake/os/FreeBSD.cmake b/cmake/os/FreeBSD.cmake index 0b958c61315..be7af778e93 100644 --- a/cmake/os/FreeBSD.cmake +++ b/cmake/os/FreeBSD.cmake @@ -1,5 +1,5 @@ -# Copyright (C) 2010 Sun Microsystems, Inc +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,6 +15,9 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # This file includes FreeBSD specific options and quirks, related to system checks -#Legacy option, maybe not needed anymore , taken as is from autotools build -ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000) +# Should not be needed any more, but kept for easy resurrection if needed +# #Legacy option, maybe not needed anymore , taken as is from autotools build +# ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000) + +ADD_DEFINITIONS(-DHAVE_BROKEN_REALPATH) diff --git a/configure.in b/configure.in index 0a040cc60ee..1d95c11bd5b 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl -*- ksh -*- dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 2008-2009 Sun Microsystems, Inc +# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -1235,14 +1235,22 @@ case $SYSTEM_TYPE in fi ;; *freebsd*|*dragonfly*) - AC_MSG_WARN([Adding fix for interrupted reads]) + dnl These dependencies have not really been checked for some time OSVERSION=`sysctl -a | grep osreldate | awk '{ print $2 }'` - if test "$OSVERSION" -gt "480100" && \ + if test "$OSVERSION" -gt "600000" + then + # Post user-level threads, MYSQLD_NET_RETRY_COUNT is not needed any more + AC_MSG_WARN([Adding fix for broken realpath]) + CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH" + CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_REALPATH" + elif test "$OSVERSION" -gt "480100" && \ test "$OSVERSION" -lt "500000" || \ test "$OSVERSION" -gt "500109" then + AC_MSG_WARN([Adding fix for interrupted reads]) CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000" else + AC_MSG_WARN([Adding fix for interrupted reads and broken realpath]) CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH" CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH" fi From 92064b8116cf42d430d68a2ae13f203db5fb8882 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 24 May 2010 17:43:27 +0100 Subject: [PATCH 127/207] BUG#53657: Slave crashed with error 22 when trying to lock mutex at mf_iocache.c, line 1722 The slave crashed while two threads: IO thread and user thread raced for the same mutex (the append_buffer_lock protecting the relay log's IO_CACHE). The IO thread was trying to flush the cache, and for that was grabbing the append_buffer_lock. However, the other thread was closing and reopening the relay log when the IO thread tried to lock. Closing and reopening the log includes destroying and reinitialising the IO_CACHE mutex. Therefore, the IO thread tried to lock a destroyed mutex. We fix this by backporting patch for BUG#50364 which fixed this bug in mysql server 5.5+. The patch deploys missing synchronization when flush_master_info is called and the relay log is flushed by the IO thread. In detail the patch backports revision (from mysql-trunk): - luis.soares@sun.com-20100203165617-b1yydr0ee24ycpjm This patch already includes the post-push fix also in BUG#50364: - luis.soares@sun.com-20100222002629-0cijwqk6baxhj7gr --- sql/repl_failsafe.cc | 2 +- sql/rpl_mi.cc | 27 ++++++++++++++++++++++----- sql/rpl_mi.h | 5 +++-- sql/rpl_rli.cc | 2 +- sql/slave.cc | 4 ++-- sql/sql_repl.cc | 2 +- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index c6a05e93bf4..c25d43ea5ba 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -976,7 +976,7 @@ bool load_master_data(THD* thd) host was specified; there could have been a problem when replication started, which led to relay log's IO_CACHE to not be inited. */ - if (flush_master_info(active_mi, 0)) + if (flush_master_info(active_mi, FALSE, FALSE)) sql_print_error("Failed to flush master info file"); } mysql_free_result(master_status_res); diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 5e46837e948..63f1f21c957 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -312,7 +312,7 @@ file '%s')", fname); mi->inited = 1; // now change cache READ -> WRITE - must do this before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1); - if ((error=test(flush_master_info(mi, 1)))) + if ((error=test(flush_master_info(mi, TRUE, TRUE)))) sql_print_error("Failed to flush master info file"); pthread_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); @@ -338,10 +338,13 @@ err: 1 - flush master info failed 0 - all ok */ -int flush_master_info(Master_info* mi, bool flush_relay_log_cache) +int flush_master_info(Master_info* mi, + bool flush_relay_log_cache, + bool need_lock_relay_log) { IO_CACHE* file = &mi->file; char lbuf[22]; + int err= 0; DBUG_ENTER("flush_master_info"); DBUG_PRINT("enter",("master_pos: %ld", (long) mi->master_log_pos)); @@ -358,9 +361,23 @@ int flush_master_info(Master_info* mi, bool flush_relay_log_cache) When we come to this place in code, relay log may or not be initialized; the caller is responsible for setting 'flush_relay_log_cache' accordingly. */ - if (flush_relay_log_cache && - flush_io_cache(mi->rli.relay_log.get_log_file())) - DBUG_RETURN(2); + if (flush_relay_log_cache) + { + pthread_mutex_t *log_lock= mi->rli.relay_log.get_log_lock(); + IO_CACHE *log_file= mi->rli.relay_log.get_log_file(); + + if (need_lock_relay_log) + pthread_mutex_lock(log_lock); + + safe_mutex_assert_owner(log_lock); + err= flush_io_cache(log_file); + + if (need_lock_relay_log) + pthread_mutex_unlock(log_lock); + + if (err) + DBUG_RETURN(2); + } /* We flushed the relay log BEFORE the master.info file, because if we crash diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 93fb0a98198..023879f84fa 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -108,7 +108,8 @@ int init_master_info(Master_info* mi, const char* master_info_fname, bool abort_if_no_master_info_file, int thread_mask); void end_master_info(Master_info* mi); -int flush_master_info(Master_info* mi, bool flush_relay_log_cache); - +int flush_master_info(Master_info* mi, + bool flush_relay_log_cache, + bool need_lock_relay_log); #endif /* HAVE_REPLICATION */ #endif /* RPL_MI_H */ diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 1263b7c52d9..316e26f7e40 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -120,7 +120,7 @@ int init_relay_log_info(Relay_log_info* rli, /* The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. Note that the I/O thread flushes it to disk after writing every - event, in flush_master_info(mi, 1). + event, in flush_master_info(mi, 1, ?). */ /* diff --git a/sql/slave.cc b/sql/slave.cc index 2e4642d179e..af53bc65c0e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1480,7 +1480,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) " to the relay log, SHOW SLAVE STATUS may be" " inaccurate"); rli->relay_log.harvest_bytes_written(&rli->log_space_total); - if (flush_master_info(mi, 1)) + if (flush_master_info(mi, TRUE, TRUE)) sql_print_error("Failed to flush master info file"); delete ev; } @@ -2731,7 +2731,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); "could not queue event from master"); goto err; } - if (flush_master_info(mi, 1)) + if (flush_master_info(mi, TRUE, TRUE)) { sql_print_error("Failed to flush master info file"); goto err; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index c220f609c09..75a738a0073 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1282,7 +1282,7 @@ bool change_master(THD* thd, Master_info* mi) Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never a slave before). */ - if (flush_master_info(mi, 0)) + if (flush_master_info(mi, FALSE, FALSE)) { my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file"); unlock_slave_threads(mi); From 3dec34f4f71f721652c49e612cb6bc9c53cebefe Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Tue, 25 May 2010 10:14:07 +0200 Subject: [PATCH 128/207] configure.cmake - Reverted a faulty change of MY_SEARCH_LIBS - Added the proper change for MY_SEARCH_LIBS and HAVE_ --- config.h.cmake | 2 +- configure.cmake | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index f93cc18a0bc..3adc7b1e3f5 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -312,7 +312,7 @@ #define SIZEOF_CHARP SIZEOF_LONG #define SIZEOF_SIZE_T SIZEOF_LONG #else -# No indentation, to fetch the lines from verification scripts +/* No indentation, to fetch the lines from verification scripts */ #cmakedefine SIZEOF_LONG @SIZEOF_LONG@ #cmakedefine SIZEOF_VOIDP @SIZEOF_VOIDP@ #cmakedefine SIZEOF_CHARP @SIZEOF_CHARP@ diff --git a/configure.cmake b/configure.cmake index 6734b652676..eeefa054de0 100644 --- a/configure.cmake +++ b/configure.cmake @@ -105,7 +105,8 @@ FUNCTION(MY_SEARCH_LIBS func libs result) FOREACH(lib ${libs}) CHECK_LIBRARY_EXISTS(${lib} ${func} "" HAVE_${func}_IN_${lib}) IF(HAVE_${func}_IN_${lib}) - SET(${result} HAVE_${lib} PARENT_SCOPE) + SET(${result} ${lib} PARENT_SCOPE) + SET(HAVE_${result} 1 PARENT_SCOPE) RETURN() ENDIF() ENDFOREACH() From a3c080be7ac95ce7f6f384a07f9ff0b31fd33a0f Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Tue, 25 May 2010 16:35:01 +0400 Subject: [PATCH 129/207] Pre-requisite patch for bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". The goal of this patch is to decouple type of metadata lock acquired for table by open_tables() from type of table-level lock to be acquired on it. To achieve this we change approach to how we determine what type of metadata lock should be acquired on table to be open. Now instead of inferring it at open_tables() time from flags and type of table-level lock we rely on that type of metadata lock is properly set at parsing time and is not changed further. --- sql/ha_ndbcluster.cc | 7 +- sql/lock.cc | 7 +- sql/lock.h | 15 +- sql/mdl.h | 4 + sql/sp_head.cc | 11 +- sql/sp_head.h | 4 +- sql/sql_base.cc | 320 ++++++++++++++++++++++++------------------- sql/sql_class.h | 14 +- sql/sql_db.cc | 8 +- sql/sql_lex.cc | 1 + sql/sql_lex.h | 10 ++ sql/sql_parse.cc | 16 +-- sql/sql_prepare.cc | 2 +- sql/sql_show.cc | 4 +- sql/sql_table.cc | 26 +++- sql/sql_trigger.cc | 6 +- sql/sql_view.cc | 2 +- sql/sql_yacc.yy | 103 ++++++++++---- sql/table.cc | 7 - sql/table.h | 19 +-- 20 files changed, 359 insertions(+), 227 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2d082cc71f6..2af2b064020 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -7408,9 +7408,10 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str)); // Delete the table and all related files TABLE_LIST table_list; - bzero((char*) &table_list,sizeof(table_list)); - table_list.db= (char*) db; - table_list.alias= table_list.table_name= (char*)file_name_str; + table_list.init_one_table(db, strlen(db), file_name_str, + strlen(file_name_str), file_name_str, + TL_WRITE); + table_list.mdl_request.set_tpye(MDL_EXCLUSIVE); (void)mysql_rm_table_part2(thd, &table_list, FALSE, /* if_exists */ FALSE, /* drop_temporary */ diff --git a/sql/lock.cc b/sql/lock.cc index 758ea6cf914..8e91bd9360e 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -880,6 +880,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, before calling it. Also it cannot be called while holding LOCK_open mutex. Both these invariants are enforced by asserts in MDL_context::acquire_locks(). + @note Initialization of MDL_request members of TABLE_LIST elements + is a responsibility of the caller. @retval FALSE Success. @retval TRUE Failure (OOM or thread was killed). @@ -894,12 +896,7 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list) global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); for (lock_table= table_list; lock_table; lock_table= lock_table->next_local) - { - lock_table->mdl_request.init(MDL_key::TABLE, - lock_table->db, lock_table->table_name, - MDL_EXCLUSIVE); mdl_requests.push_front(&lock_table->mdl_request); - } mdl_requests.push_front(&global_request); diff --git a/sql/lock.h b/sql/lock.h index 19b23f1f42b..5425a6ccb13 100644 --- a/sql/lock.h +++ b/sql/lock.h @@ -15,33 +15,32 @@ typedef struct st_mysql_lock MYSQL_LOCK; #define MYSQL_OPEN_TEMPORARY_ONLY 0x0004 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY 0x0008 #define MYSQL_LOCK_LOG_TABLE 0x0010 -#define MYSQL_OPEN_TAKE_UPGRADABLE_MDL 0x0020 /** Do not try to acquire a metadata lock on the table: we already have one. */ -#define MYSQL_OPEN_HAS_MDL_LOCK 0x0040 +#define MYSQL_OPEN_HAS_MDL_LOCK 0x0020 /** If in locked tables mode, ignore the locked tables and get a new instance of the table. */ -#define MYSQL_OPEN_GET_NEW_TABLE 0x0080 +#define MYSQL_OPEN_GET_NEW_TABLE 0x0040 /** Don't look up the table in the list of temporary tables. */ -#define MYSQL_OPEN_SKIP_TEMPORARY 0x0100 +#define MYSQL_OPEN_SKIP_TEMPORARY 0x0080 /** Fail instead of waiting when conficting metadata lock is discovered. */ -#define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT 0x0200 +#define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT 0x0100 /** Open tables using MDL_SHARED lock instead of one specified in parser. */ -#define MYSQL_OPEN_FORCE_SHARED_MDL 0x0400 +#define MYSQL_OPEN_FORCE_SHARED_MDL 0x0200 /** Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified in parser. */ -#define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL 0x0800 +#define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL 0x0400 /** When opening or locking the table, use the maximum timeout (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value. */ -#define MYSQL_LOCK_IGNORE_TIMEOUT 0x1000 +#define MYSQL_LOCK_IGNORE_TIMEOUT 0x0800 /** Please refer to the internals manual. */ #define MYSQL_OPEN_REOPEN (MYSQL_OPEN_IGNORE_FLUSH |\ diff --git a/sql/mdl.h b/sql/mdl.h index 2fb21a5aa18..2e296b73057 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -308,6 +308,10 @@ public: MDL_key key; public: + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () + { return alloc_root(mem_root, size); } + static void operator delete(void *ptr, MEM_ROOT *mem_root) {} + void init(MDL_key::enum_mdl_namespace namespace_arg, const char *db_arg, const char *name_arg, enum_mdl_type mdl_type_arg); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2e66aec91e5..2d5b648e82e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -4010,6 +4010,11 @@ sp_head::add_used_tables_to_table_list(THD *thd, table->prelocking_placeholder= 1; table->belong_to_view= belong_to_view; table->trg_event_map= stab->trg_event_map; + /* + Since we don't allow DDL on base tables in prelocked mode it + is safe to infer the type of metadata lock from the type of + table lock. + */ table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, table->lock_type >= TL_WRITE_ALLOW_WRITE ? MDL_SHARED_WRITE : MDL_SHARED_READ); @@ -4040,7 +4045,8 @@ sp_head::add_used_tables_to_table_list(THD *thd, TABLE_LIST * sp_add_to_query_tables(THD *thd, LEX *lex, const char *db, const char *name, - thr_lock_type locktype) + thr_lock_type locktype, + enum_mdl_type mdl_type) { TABLE_LIST *table; @@ -4055,8 +4061,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex, table->select_lex= lex->current_select; table->cacheable_table= 1; table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, - table->lock_type >= TL_WRITE_ALLOW_WRITE ? - MDL_SHARED_WRITE : MDL_SHARED_READ); + mdl_type); lex->add_to_query_tables(table); return table; diff --git a/sql/sp_head.h b/sql/sp_head.h index 165f88321a9..8975c239810 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1346,7 +1346,9 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, TABLE_LIST * sp_add_to_query_tables(THD *thd, LEX *lex, const char *db, const char *name, - thr_lock_type locktype); + thr_lock_type locktype, + enum_mdl_type mdl_type); + Item * sp_prepare_func_item(THD* thd, Item **it_addr); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 28633365e28..85017886d24 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2358,82 +2358,90 @@ void table_share_release_hook(void *share) /** - A helper function that acquires an MDL lock for a table - being opened. + Try to acquire an MDL lock for a table being opened. + + @param[in,out] thd Session context, to report errors. + @param[out] ot_ctx Open table context, to hold the back off + state. If we failed to acquire a lock + due to a lock conflict, we add the + failed request to the open table context. + @param[in,out] mdl_request A request for an MDL lock. + If we managed to acquire a ticket + (no errors or lock conflicts occurred), + contains a reference to it on + return. However, is not modified if MDL + lock type- modifying flags were provided. + @param[in] flags flags MYSQL_OPEN_FORCE_SHARED_MDL, + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL or + MYSQL_OPEN_FAIL_ON_MDL_CONFLICT + @sa open_table(). + @param[out] mdl_ticket Only modified if there was no error. + If we managed to acquire an MDL + lock, contains a reference to the + ticket, otherwise is set to NULL. + + @retval TRUE An error occurred. + @retval FALSE No error, but perhaps a lock conflict, check mdl_ticket. */ static bool -open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list, +open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, MDL_request *mdl_request, - Open_table_context *ot_ctx, - uint flags) + uint flags, + MDL_ticket **mdl_ticket) { - if (table_list->lock_strategy) + if (flags & (MYSQL_OPEN_FORCE_SHARED_MDL | + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)) { - MDL_request_list mdl_requests; - MDL_request *global_request; /* - In case of CREATE TABLE .. If NOT EXISTS .. SELECT, the table - may not yet exist. Let's acquire an exclusive lock for that - case. If later it turns out the table existsed, we will - downgrade the lock to shared. Note that, according to the - locking protocol, all exclusive locks must be acquired before - shared locks. This invariant is preserved here and is also - enforced by asserts in metadata locking subsystem. + MYSQL_OPEN_FORCE_SHARED_MDL flag means that we are executing + PREPARE for a prepared statement and want to override + the type-of-operation aware metadata lock which was set + in the parser/during view opening with a simple shared + metadata lock. + This is necessary to allow concurrent execution of PREPARE + and LOCK TABLES WRITE statement against the same table. + + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag means that we open + the table in order to get information about it for one of I_S + queries and also want to override the type-of-operation aware + shared metadata lock which was set earlier (e.g. during view + opening) with a high-priority shared metadata lock. + This is necessary to avoid unnecessary waiting and extra + ER_WARN_I_S_SKIPPED_TABLE warnings when accessing I_S tables. + + These two flags are mutually exclusive. */ + DBUG_ASSERT(!(flags & MYSQL_OPEN_FORCE_SHARED_MDL) || + !(flags & MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)); - mdl_request->set_type(MDL_EXCLUSIVE); - DBUG_ASSERT(! thd->mdl_context.has_locks() || - thd->handler_tables_hash.records || - thd->global_read_lock.is_acquired()); + mdl_request= new (thd->mem_root) MDL_request(mdl_request); + if (mdl_request == NULL) + return TRUE; - if (!(global_request= ot_ctx->get_global_mdl_request(thd))) - return 1; - - mdl_requests.push_front(mdl_request); - mdl_requests.push_front(global_request); - - if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout())) - return 1; + mdl_request->set_type((flags & MYSQL_OPEN_FORCE_SHARED_MDL) ? + MDL_SHARED : MDL_SHARED_HIGH_PRIO); } - else + + ot_ctx->add_request(mdl_request); + + if (thd->mdl_context.try_acquire_lock(mdl_request)) + return TRUE; + + if (mdl_request->ticket == NULL) { - if (flags & MYSQL_OPEN_FORCE_SHARED_MDL) + if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) { - /* - While executing PREPARE for prepared statement we override - type-of-operation aware type of shared metadata lock which - was set in the parser with simple shared metadata lock. - This is necessary to allow concurrent execution of PREPARE - and LOCK TABLES WRITE statement which locks one of the tables - used in the statement being prepared. - */ - DBUG_ASSERT(!(flags & (MYSQL_OPEN_TAKE_UPGRADABLE_MDL | - MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))); - - mdl_request->set_type(MDL_SHARED); - } - else if (flags & MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL) - { - DBUG_ASSERT(!(flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL)); - mdl_request->set_type(MDL_SHARED_HIGH_PRIO); - } - - ot_ctx->add_request(mdl_request); - - if (thd->mdl_context.try_acquire_lock(mdl_request)) - return 1; - - if (mdl_request->ticket == NULL) - { - if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) - my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0), table_list->db, table_list->table_name); - else - ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK); - return 1; + my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0), + mdl_request->key.db_name(), mdl_request->key.name()); + return TRUE; } + if (ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK, + mdl_request, NULL)) + return TRUE; } - return 0; + *mdl_ticket= mdl_request->ticket; + return FALSE; } @@ -2468,11 +2476,9 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list, is never opened. In both cases, metadata locks are always taken according to the lock strategy. - This function will take a exclusive metadata lock on the table if - TABLE_LIST::lock_strategy is EXCLUSIVE_DOWNGRADABLE_MDL or EXCLUSIVE_MDL. - If the lock strategy is EXCLUSIVE_DOWNGRADABLE_MDL and opening the table - is successful, the exclusive metadata lock is downgraded to a shared - lock. + If the lock strategy is OTLS_DOWNGRADE_IF_EXISTS and opening the table + is successful, the exclusive metadata lock acquired by the caller + is downgraded to a shared lock. RETURN TRUE Open failed. "action" parameter may contain type of action @@ -2490,7 +2496,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char key[MAX_DBKEY_LENGTH]; uint key_length; char *alias= table_list->alias; - MDL_request *mdl_request; MDL_ticket *mdl_ticket; int error; TABLE_SHARE *share; @@ -2528,7 +2533,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (thd->version != refresh_version) { - (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, + NULL, NULL); DBUG_RETURN(TRUE); } } @@ -2701,23 +2707,25 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, This is the normal use case. */ - mdl_request= &table_list->mdl_request; if (! (flags & MYSQL_OPEN_HAS_MDL_LOCK)) { - if (open_table_get_mdl_lock(thd, table_list, mdl_request, ot_ctx, flags)) + if (open_table_get_mdl_lock(thd, ot_ctx, &table_list->mdl_request, + flags, &mdl_ticket) || + mdl_ticket == NULL) { DEBUG_SYNC(thd, "before_open_table_wait_refresh"); DBUG_RETURN(TRUE); } DEBUG_SYNC(thd, "after_open_table_mdl_shared"); } - - /* - Grab reference to the granted MDL lock ticket. Must be done after - open_table_get_mdl_lock as the lock on the table might have been - acquired previously (MYSQL_OPEN_HAS_MDL_LOCK). - */ - mdl_ticket= mdl_request->ticket; + else + { + /* + Grab reference to the MDL lock ticket that was acquired + by the caller. + */ + mdl_ticket= table_list->mdl_request.ticket; + } hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); mysql_mutex_lock(&LOCK_open); @@ -2737,7 +2745,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, { /* Someone did a refresh while thread was opening tables */ mysql_mutex_unlock(&LOCK_open); - (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, + NULL, NULL); DBUG_RETURN(TRUE); } @@ -2878,7 +2887,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, */ release_table_share(share); mysql_mutex_unlock(&LOCK_open); - (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, + NULL, NULL); DBUG_RETURN(TRUE); } /* Force close at once after usage */ @@ -2918,12 +2928,14 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (error == 7) { share->version= 0; - (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, + NULL, table_list); } else if (share->crashed) { share->version= 0; - (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR, + NULL, table_list); } goto err_unlock; @@ -2947,7 +2959,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table exists now we should downgrade our exclusive metadata lock on this table to SW metadata lock. */ - if (table_list->lock_strategy == TABLE_LIST::EXCLUSIVE_DOWNGRADABLE_MDL && + if (table_list->lock_strategy == TABLE_LIST::OTLS_DOWNGRADE_IF_EXISTS && !(flags & MYSQL_OPEN_HAS_MDL_LOCK)) mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_WRITE); @@ -3782,6 +3794,8 @@ end_with_lock_open: Open_table_context::Open_table_context(THD *thd, ulong timeout) :m_action(OT_NO_ACTION), + m_failed_mdl_request(NULL), + m_failed_table(NULL), m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()), m_has_locks((thd->in_multi_stmt_transaction_mode() && thd->mdl_context.has_locks()) || @@ -3801,10 +3815,8 @@ MDL_request *Open_table_context::get_global_mdl_request(THD *thd) { if (! m_global_mdl_request) { - char *buff; - if ((buff= (char*)thd->alloc(sizeof(MDL_request)))) + if ((m_global_mdl_request= new (thd->mem_root) MDL_request())) { - m_global_mdl_request= new (buff) MDL_request(); m_global_mdl_request->init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); } @@ -3823,7 +3835,8 @@ MDL_request *Open_table_context::get_global_mdl_request(THD *thd) bool Open_table_context:: -request_backoff_action(enum_open_table_action action_arg) +request_backoff_action(enum_open_table_action action_arg, + MDL_request *mdl_request, TABLE_LIST *table) { /* We are inside a transaction that already holds locks and have @@ -3847,6 +3860,19 @@ request_backoff_action(enum_open_table_action action_arg) return TRUE; } m_action= action_arg; + /* + If waiting for metadata lock is requested, a pointer to + MDL_request object for which we were unable to acquire the + lock is required. + */ + DBUG_ASSERT(m_action != OT_WAIT_MDL_LOCK || mdl_request); + m_failed_mdl_request= mdl_request; + /* + If auto-repair or discovery are requested, a pointer to table + list element must be provided. + */ + DBUG_ASSERT((m_action != OT_DISCOVER && m_action != OT_REPAIR) || table); + m_failed_table= table; return FALSE; } @@ -3855,10 +3881,6 @@ request_backoff_action(enum_open_table_action action_arg) Recover from failed attempt of open table by performing requested action. @param thd Thread context - @param mdl_request MDL_request of the object that caused the problem. - @param table Optional (can be NULL). Used only if action is OT_REPAIR. - In that case a TABLE_LIST for the table to be repaired. - @todo: It's unnecessary and should be removed. @pre This function should be called only with "action" != OT_NO_ACTION and after having called @sa close_tables_for_reopen(). @@ -3869,8 +3891,7 @@ request_backoff_action(enum_open_table_action action_arg) bool Open_table_context:: -recover_from_failed_open(THD *thd, MDL_request *mdl_request, - TABLE_LIST *table) +recover_from_failed_open(THD *thd) { bool result= FALSE; /* @@ -3882,7 +3903,8 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, switch (m_action) { case OT_WAIT_MDL_LOCK: - result= thd->mdl_context.wait_for_lock(mdl_request, get_timeout()); + result= thd->mdl_context.wait_for_lock(m_failed_mdl_request, + get_timeout()); break; case OT_WAIT_TDC: result= tdc_wait_for_old_versions(thd, &m_mdl_requests, get_timeout()); @@ -3891,7 +3913,7 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, case OT_DISCOVER: { MDL_request mdl_global_request; - MDL_request mdl_xlock_request(mdl_request); + MDL_request mdl_xlock_request(&m_failed_table->mdl_request); MDL_request_list mdl_requests; mdl_global_request.init(MDL_key::GLOBAL, "", "", @@ -3905,14 +3927,11 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, thd->mdl_context.acquire_locks(&mdl_requests, get_timeout()))) break; - DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE); mysql_mutex_lock(&LOCK_open); - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, - mdl_request->key.db_name(), - mdl_request->key.name()); - ha_create_table_from_engine(thd, - mdl_request->key.db_name(), - mdl_request->key.name()); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, + m_failed_table->table_name); + ha_create_table_from_engine(thd, m_failed_table->db, + m_failed_table->table_name); mysql_mutex_unlock(&LOCK_open); thd->warning_info->clear_warning_info(thd->query_id); @@ -3923,7 +3942,7 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, case OT_REPAIR: { MDL_request mdl_global_request; - MDL_request mdl_xlock_request(mdl_request); + MDL_request mdl_xlock_request(&m_failed_table->mdl_request); MDL_request_list mdl_requests; mdl_global_request.init(MDL_key::GLOBAL, "", "", @@ -3937,14 +3956,12 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, thd->mdl_context.acquire_locks(&mdl_requests, get_timeout()))) break; - DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE); mysql_mutex_lock(&LOCK_open); - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, - mdl_request->key.db_name(), - mdl_request->key.name()); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, + m_failed_table->table_name); mysql_mutex_unlock(&LOCK_open); - result= auto_repair_table(thd, table); + result= auto_repair_table(thd, m_failed_table); thd->mdl_context.release_transactional_locks(); break; } @@ -3953,6 +3970,13 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request, } /* Remove all old requests, they will be re-added. */ m_mdl_requests.empty(); + /* + Reset the pointers to conflicting MDL request and the + TABLE_LIST element, set when we need auto-discovery or repair, + for safety. + */ + m_failed_mdl_request= NULL; + m_failed_table= NULL; /* Prepare for possible another back-off. */ m_action= OT_NO_ACTION; return result; @@ -4081,7 +4105,8 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, if (rt->mdl_request.ticket == NULL) { /* A lock conflict. Someone's trying to modify SP metadata. */ - ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK); + ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK, + &rt->mdl_request, NULL); DBUG_RETURN(TRUE); } DEBUG_SYNC(thd, "after_shared_lock_pname"); @@ -4228,12 +4253,14 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, */ if (tables->view) { + MDL_ticket *mdl_ticket; /* We still need to take a MDL lock on the merged view to protect it from concurrent changes. */ - if (!open_table_get_mdl_lock(thd, tables, &tables->mdl_request, - ot_ctx, flags)) + if (!open_table_get_mdl_lock(thd, ot_ctx, &tables->mdl_request, + flags, &mdl_ticket) && + mdl_ticket != NULL) goto process_view_routines; /* Fall-through to return error. */ } @@ -4423,6 +4450,8 @@ end: should be acquired. @param tables_end End of list of tables. @param ot_ctx Context of open_tables() operation. + @param flags Bitmap of flags to modify how the tables will be + open, see open_table() description for details. @retval FALSE Success. @retval TRUE Failure (e.g. connection was killed) @@ -4431,31 +4460,30 @@ end: static bool open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, TABLE_LIST *tables_end, - Open_table_context *ot_ctx) + Open_table_context *ot_ctx, + uint flags) { MDL_request_list mdl_requests; TABLE_LIST *table; DBUG_ASSERT(!thd->locked_tables_mode); - DEBUG_SYNC(thd, "open_tables_acquire_upgradable_mdl"); for (table= tables_start; table && table != tables_end; table= table->next_global) { - if (table->lock_type >= TL_WRITE_ALLOW_WRITE && + if (table->mdl_request.type >= MDL_SHARED_NO_WRITE && !(table->open_type == OT_TEMPORARY_ONLY || + (flags & MYSQL_OPEN_TEMPORARY_ONLY) || (table->open_type != OT_BASE_ONLY && + ! (flags & MYSQL_OPEN_SKIP_TEMPORARY) && find_temporary_table(thd, table)))) - { - table->mdl_request.set_type(table->lock_type > TL_WRITE_ALLOW_READ ? - MDL_SHARED_NO_READ_WRITE : - MDL_SHARED_NO_WRITE); mdl_requests.push_front(&table->mdl_request); - } } if (! mdl_requests.is_empty()) { + DEBUG_SYNC(thd, "open_tables_acquire_upgradable_mdl"); + MDL_request *global_request= ot_ctx->get_global_mdl_request(thd); if (global_request == NULL) @@ -4469,11 +4497,8 @@ open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, for (table= tables_start; table && table != tables_end; table= table->next_global) { - if (table->lock_type >= TL_WRITE_ALLOW_WRITE) - { + if (table->mdl_request.type >= MDL_SHARED_NO_WRITE) table->mdl_request.ticket= NULL; - table->mdl_request.set_type(MDL_SHARED_WRITE); - } } return FALSE; @@ -4489,6 +4514,8 @@ open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, @param tables_start Start of list of tables on which upgradable locks should be searched for. @param tables_end End of list of tables. + @param flags Bitmap of flags to modify how the tables will be + open, see open_table() description for details. @retval FALSE Success. @retval TRUE Failure (e.g. connection was killed) @@ -4496,7 +4523,7 @@ open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, static bool open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, - TABLE_LIST *tables_end) + TABLE_LIST *tables_end, uint flags) { TABLE_LIST *table; @@ -4505,9 +4532,11 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, for (table= tables_start; table && table != tables_end; table= table->next_global) { - if (table->lock_type >= TL_WRITE_ALLOW_WRITE && + if (table->mdl_request.type >= MDL_SHARED_NO_WRITE && !(table->open_type == OT_TEMPORARY_ONLY || + (flags & MYSQL_OPEN_TEMPORARY_ONLY) || (table->open_type != OT_BASE_ONLY && + ! (flags & MYSQL_OPEN_SKIP_TEMPORARY) && find_temporary_table(thd, table)))) { /* @@ -4519,8 +4548,14 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start, lock, all other instances of TABLE for the same table will have the same ticket. - Note that find_table_for_mdl_upgrade() will report an error if a - ticket is not found. + Note that this works OK even for CREATE TABLE statements which + request X type of metadata lock. This is because under LOCK TABLES + such statements don't create the table but only check if it exists + or, in most complex case, only insert into it. + Thus SNRW lock should be enough. + + Note that find_table_for_mdl_upgrade() will report an error if + no suitable ticket is found. */ if (!find_table_for_mdl_upgrade(thd->open_tables, table->db, table->table_name, FALSE)) @@ -4612,21 +4647,19 @@ restart: (in non-LOCK TABLES mode) we might have to acquire upgradable semi-exclusive metadata locks (SNW or SNRW) on some of the tables to be opened. - So we acquire all such locks at once here as doing this in one + When executing CREATE TABLE .. If NOT EXISTS .. SELECT, the + table may not yet exist, in which case we acquire an exclusive + lock. + We acquire all such locks at once here as doing this in one by one fashion may lead to deadlocks or starvation. Later when we will be opening corresponding table pre-acquired metadata lock will be reused (thanks to the fact that in recursive case metadata locks are acquired without waiting). */ - if (flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL) + if (! (flags & (MYSQL_OPEN_HAS_MDL_LOCK | + MYSQL_OPEN_FORCE_SHARED_MDL | + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))) { - /* - open_tables_acquire_upgradable_mdl() does not currenly handle - these two flags. At this point, that does not matter as they - are not used together with MYSQL_OPEN_TAKE_UPGRADABLE_MDL. - */ - DBUG_ASSERT(!(flags & (MYSQL_OPEN_SKIP_TEMPORARY | - MYSQL_OPEN_TEMPORARY_ONLY))); if (thd->locked_tables_mode) { /* @@ -4634,7 +4667,8 @@ restart: need to check if appropriate locks were pre-acquired. */ if (open_tables_check_upgradable_mdl(thd, *start, - thd->lex->first_not_own_table())) + thd->lex->first_not_own_table(), + flags)) { error= TRUE; goto err; @@ -4642,7 +4676,7 @@ restart: } else if (open_tables_acquire_upgradable_mdl(thd, *start, thd->lex->first_not_own_table(), - &ot_ctx)) + &ot_ctx, flags)) { error= TRUE; goto err; @@ -4688,7 +4722,6 @@ restart: have failed to open since closing tables can trigger removal of elements from the table list (if MERGE tables are involved), */ - TABLE_LIST *failed_table= *table_to_open; close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp()); /* @@ -4696,8 +4729,7 @@ restart: TABLE_LIST element. Altough currently this assumption is valid it may change in future. */ - if (ot_ctx.recover_from_failed_open(thd, &failed_table->mdl_request, - failed_table)) + if (ot_ctx.recover_from_failed_open(thd)) goto err; error= FALSE; @@ -4741,7 +4773,7 @@ restart: { close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp()); - if (ot_ctx.recover_from_failed_open(thd, &rt->mdl_request, NULL)) + if (ot_ctx.recover_from_failed_open(thd)) goto err; error= FALSE; @@ -5163,6 +5195,9 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, /* open_ltable can be used only for BASIC TABLEs */ table_list->required_type= FRMTYPE_TABLE; + /* This function can't properly handle requests for such metadata locks. */ + DBUG_ASSERT(table_list->mdl_request.type < MDL_SHARED_NO_WRITE); + while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx, lock_flags)) && ot_ctx.can_recover_from_failed_open()) { @@ -5173,8 +5208,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, */ thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp()); table_list->mdl_request.ticket= 0; - if (ot_ctx.recover_from_failed_open(thd, &table_list->mdl_request, - table_list)) + if (ot_ctx.recover_from_failed_open(thd)) break; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 916b79f8353..d494fdf86b5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1329,9 +1329,9 @@ public: }; Open_table_context(THD *thd, ulong timeout); - bool recover_from_failed_open(THD *thd, MDL_request *mdl_request, - TABLE_LIST *table); - bool request_backoff_action(enum_open_table_action action_arg); + bool recover_from_failed_open(THD *thd); + bool request_backoff_action(enum_open_table_action action_arg, + MDL_request *mdl_request, TABLE_LIST *table); void add_request(MDL_request *request) { m_mdl_requests.push_front(request); } @@ -1362,6 +1362,14 @@ private: MDL_request_list m_mdl_requests; /** Back off action. */ enum enum_open_table_action m_action; + /** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */ + MDL_request *m_failed_mdl_request; + /** + For OT_DISCOVER and OT_REPAIR actions, the table list element for + the table which definition should be re-discovered or which + should be repaired. + */ + TABLE_LIST *m_failed_table; MDL_ticket *m_start_of_statement_svp; /** Whether we had any locks when this context was created. diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 15fdd842e34..2e48475f298 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1203,6 +1203,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix); + table_list->mdl_request.init(MDL_key::TABLE, table_list->db, + table_list->table_name, MDL_EXCLUSIVE); /* Link into list */ (*tot_list_next)= table_list; tot_list_next= &table_list->next_local; @@ -1918,9 +1920,11 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0); if (!old_ident || !new_ident || !sl->add_table_to_list(thd, old_ident, NULL, - TL_OPTION_UPDATING, TL_IGNORE) || + TL_OPTION_UPDATING, TL_IGNORE, + MDL_EXCLUSIVE) || !sl->add_table_to_list(thd, new_ident, NULL, - TL_OPTION_UPDATING, TL_IGNORE)) + TL_OPTION_UPDATING, TL_IGNORE, + MDL_EXCLUSIVE)) { error= 1; my_dirend(dirp); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1795bc272f1..48474609b9b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1978,6 +1978,7 @@ TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd, Table_ident *table, LEX_STRING *alias, ulong table_join_options, thr_lock_type flags, + enum_mdl_type mdl_type, List *hints, LEX_STRING *option) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2ce6bdeed42..38aac9a1042 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -502,6 +502,7 @@ public: LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, + enum_mdl_type mdl_type= MDL_SHARED_READ, List *hints= 0, LEX_STRING *option= 0); virtual void set_lock_for_tables(thr_lock_type lock_type) {} @@ -799,6 +800,7 @@ public: LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, + enum_mdl_type mdl_type= MDL_SHARED_READ, List *hints= 0, LEX_STRING *option= 0); TABLE_LIST* get_table_list(); @@ -2249,6 +2251,7 @@ public: yacc_yyvs= NULL; m_set_signal_info.clear(); m_lock_type= TL_READ_DEFAULT; + m_mdl_type= MDL_SHARED_READ; } ~Yacc_state(); @@ -2260,6 +2263,7 @@ public: void reset_before_substatement() { m_lock_type= TL_READ_DEFAULT; + m_mdl_type= MDL_SHARED_READ; } /** @@ -2299,6 +2303,12 @@ public: */ thr_lock_type m_lock_type; + /** + The type of requested metadata lock for tables added to + the statement table list. + */ + enum_mdl_type m_mdl_type; + /* TODO: move more attributes from the LEX structure here. */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 60b2ffa4179..4c3f44ea75c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1606,7 +1606,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, /* 'parent_lex' is used in init_query() so it must be before it. */ schema_select_lex->parent_lex= lex; schema_select_lex->init_query(); - if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ)) + if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ, + MDL_SHARED_READ)) DBUG_RETURN(1); lex->query_tables_last= query_tables_last; break; @@ -2544,7 +2545,7 @@ case SQLCOM_PREPARE: /* Set strategies: reset default or 'prepared' values. */ create_table->open_strategy= TABLE_LIST::OPEN_IF_EXISTS; - create_table->lock_strategy= TABLE_LIST::EXCLUSIVE_DOWNGRADABLE_MDL; + create_table->lock_strategy= TABLE_LIST::OTLS_DOWNGRADE_IF_EXISTS; /* Close any open handlers for the table @@ -3502,16 +3503,13 @@ end_with_restore_list: thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) goto error; - init_mdl_requests(all_tables); - thd->variables.option_bits|= OPTION_TABLE_LOCK; thd->in_lock_tables=1; { Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; - res= (open_and_lock_tables(thd, all_tables, FALSE, - MYSQL_OPEN_TAKE_UPGRADABLE_MDL, + res= (open_and_lock_tables(thd, all_tables, FALSE, 0, &lock_tables_prelocking_strategy) || thd->locked_tables_list.init_locked_tables(thd)); } @@ -6014,6 +6012,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc) - TL_OPTION_FORCE_INDEX : Force usage of index - TL_OPTION_ALIAS : an alias in multi table DELETE @param lock_type How table should be locked + @param mdl_type Type of metadata lock to acquire on the table. @param use_index List of indexed used in USE INDEX @param ignore_index List of indexed used in IGNORE INDEX @@ -6028,6 +6027,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, LEX_STRING *alias, ulong table_options, thr_lock_type lock_type, + enum_mdl_type mdl_type, List *index_hints_arg, LEX_STRING *option) { @@ -6175,9 +6175,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->next_name_resolution_table= NULL; /* Link table in global list (all used tables) */ lex->add_to_query_tables(ptr); - ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, - (ptr->lock_type >= TL_WRITE_ALLOW_WRITE) ? - MDL_SHARED_WRITE : MDL_SHARED_READ); + ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type); DBUG_RETURN(ptr); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c2d3c595d95..e5d7514d9f5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1690,7 +1690,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt) for the prepare phase. */ create_table->open_strategy= TABLE_LIST::OPEN_IF_EXISTS; - create_table->lock_strategy= TABLE_LIST::SHARED_MDL; + create_table->lock_strategy= TABLE_LIST::OTLS_NONE; if (select_lex->item_list.elements) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f1db513d0e2..a33bc5943da 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2358,7 +2358,7 @@ int make_table_list(THD *thd, SELECT_LEX *sel, Table_ident *table_ident; table_ident= new Table_ident(thd, *db_name, *table_name, 1); sel->init_query(); - if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ)) + if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, MDL_SHARED_READ)) return 1; return 0; } @@ -6582,7 +6582,7 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, strlen(schema_table->table_name), 0); if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */ !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0), - 0, 0, TL_READ)) + 0, 0, TL_READ, MDL_SHARED_READ)) { DBUG_RETURN(1); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2b8e7de3a60..b2a950ca4b0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4656,6 +4656,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, strxmov(table_name, db, ".", table->table_name, NullS); thd->open_options|= extra_open_options; table->lock_type= lock_type; + /* + To make code safe for re-execution we need to reset type of MDL + request as code below may change it. + To allow concurrent execution of read-only operations we acquire + weak metadata lock for them. + */ + table->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_READ) ? + MDL_SHARED_NO_READ_WRITE : MDL_SHARED_READ); /* open only one table from local list of command */ { TABLE_LIST *save_next_global, *save_next_local; @@ -4677,8 +4685,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (view_operator_func == NULL) table->required_type=FRMTYPE_TABLE; - open_error= open_and_lock_tables(thd, table, TRUE, - MYSQL_OPEN_TAKE_UPGRADABLE_MDL); + open_error= open_and_lock_tables(thd, table, TRUE, 0); thd->no_warnings_for_error= 0; table->next_global= save_next_global; table->next_local= save_next_local; @@ -5024,6 +5031,7 @@ send_result_message: /* Clear the ticket released in close_thread_tables(). */ table->mdl_request.ticket= NULL; DEBUG_SYNC(thd, "ha_admin_open_ltable"); + table->mdl_request.set_type(MDL_SHARED_WRITE); if ((table->table= open_ltable(thd, table, lock_type, 0))) { result_code= table->table->file->ha_analyze(thd, check_opt); @@ -5461,6 +5469,7 @@ mysql_discard_or_import_tablespace(THD *thd, not complain when we lock the table */ thd->tablespace_op= TRUE; + table_list->mdl_request.set_type(MDL_SHARED_WRITE); if (!(table=open_ltable(thd, table_list, TL_WRITE, 0))) { thd->tablespace_op=FALSE; @@ -6568,6 +6577,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) DBUG_RETURN(TRUE); + + /* + TODO/FIXME: Get rid of this code branch if possible. To add insult + to injury it breaks locking protocol. + */ + table_list->mdl_request.set_type(MDL_EXCLUSIVE); if (lock_table_names(thd, table_list)) { error= 1; @@ -6608,8 +6623,7 @@ view_err: Alter_table_prelocking_strategy alter_prelocking_strategy(alter_info); - error= open_and_lock_tables(thd, table_list, FALSE, - MYSQL_OPEN_TAKE_UPGRADABLE_MDL, + error= open_and_lock_tables(thd, table_list, FALSE, 0, &alter_prelocking_strategy); if (error) @@ -7904,6 +7918,10 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list) table_list->table= NULL; /* Same applies to MDL ticket. */ table_list->mdl_request.ticket= NULL; + /* Set lock type which is appropriate for ALTER TABLE. */ + table_list->lock_type= TL_WRITE_ALLOW_READ; + /* Same applies to MDL request. */ + table_list->mdl_request.set_type(MDL_SHARED_NO_WRITE); bzero((char*) &create_info, sizeof(create_info)); create_info.row_type=ROW_TYPE_NOT_USED; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 9ce62d9f2a4..ae09898ada2 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -489,8 +489,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) else { tables->table= open_n_lock_single_table(thd, tables, - TL_WRITE_ALLOW_READ, - MYSQL_OPEN_TAKE_UPGRADABLE_MDL); + TL_WRITE_ALLOW_READ, 0); if (! tables->table) goto end; tables->table->use_all_columns(); @@ -1667,7 +1666,8 @@ bool add_table_for_trigger(THD *thd, DBUG_RETURN(TRUE); *table= sp_add_to_query_tables(thd, lex, trg_name->m_db.str, - tbl_name.str, TL_IGNORE); + tbl_name.str, TL_IGNORE, + MDL_SHARED_NO_WRITE); DBUG_RETURN(*table ? FALSE : TRUE); } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3a6866f4a7e..4eee9502177 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -433,7 +433,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, lex->link_first_table_back(view, link_to_local); view->open_strategy= TABLE_LIST::OPEN_STUB; - view->lock_strategy= TABLE_LIST::EXCLUSIVE_MDL; + view->lock_strategy= TABLE_LIST::OTLS_NONE; view->open_type= OT_BASE_ONLY; if (open_and_lock_tables(thd, lex->query_tables, TRUE, 0)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aa336f3c072..e5875663d4e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -697,7 +697,8 @@ static bool add_create_index_prepare (LEX *lex, Table_ident *table) lex->sql_command= SQLCOM_CREATE_INDEX; if (!lex->current_select->add_table_to_list(lex->thd, table, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ)) + TL_WRITE_ALLOW_READ, + MDL_SHARED_NO_WRITE)) return TRUE; lex->alter_info.reset(); lex->alter_info.flags= ALTER_ADD_INDEX; @@ -2023,7 +2024,7 @@ create: lex->sql_command= SQLCOM_CREATE_TABLE; if (!lex->select_lex.add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING, - TL_WRITE)) + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; lex->alter_info.reset(); lex->col_list.empty(); @@ -4213,7 +4214,8 @@ create2: lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; src_table= lex->select_lex.add_table_to_list(thd, $2, NULL, 0, - TL_READ); + TL_READ, + MDL_SHARED_READ); if (! src_table) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ @@ -4227,7 +4229,8 @@ create2: lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; src_table= lex->select_lex.add_table_to_list(thd, $3, NULL, 0, - TL_READ); + TL_READ, + MDL_SHARED_READ); if (! src_table) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ @@ -6154,7 +6157,8 @@ alter: lex->duplicates= DUP_ERROR; if (!lex->select_lex.add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ)) + TL_WRITE_ALLOW_READ, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; lex->col_list.empty(); lex->select_lex.init_order(); @@ -6847,6 +6851,8 @@ checksum: { LEX *lex=Lex; lex->sql_command = SQLCOM_CHECKSUM; + /* Will be overriden during execution. */ + YYPS->m_lock_type= TL_UNLOCK; } table_list opt_checksum_type {} @@ -6866,6 +6872,8 @@ repair: lex->no_write_to_binlog= $2; lex->check_opt.init(); lex->alter_info.reset(); + /* Will be overriden during execution. */ + YYPS->m_lock_type= TL_UNLOCK; } table_list opt_mi_repair_type {} @@ -6895,6 +6903,8 @@ analyze: lex->no_write_to_binlog= $2; lex->check_opt.init(); lex->alter_info.reset(); + /* Will be overriden during execution. */ + YYPS->m_lock_type= TL_UNLOCK; } table_list {} @@ -6921,6 +6931,8 @@ check: lex->sql_command = SQLCOM_CHECK; lex->check_opt.init(); lex->alter_info.reset(); + /* Will be overriden during execution. */ + YYPS->m_lock_type= TL_UNLOCK; } table_list opt_mi_check_type {} @@ -6953,6 +6965,8 @@ optimize: lex->no_write_to_binlog= $2; lex->check_opt.init(); lex->alter_info.reset(); + /* Will be overriden during execution. */ + YYPS->m_lock_type= TL_UNLOCK; } table_list {} @@ -7001,9 +7015,9 @@ table_to_table: LEX *lex=Lex; SELECT_LEX *sl= lex->current_select; if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING, - TL_IGNORE) || + TL_IGNORE, MDL_EXCLUSIVE) || !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING, - TL_IGNORE)) + TL_IGNORE, MDL_EXCLUSIVE)) MYSQL_YYABORT; } ; @@ -7034,7 +7048,8 @@ keycache_list: assign_to_keycache: table_ident cache_keys_spec { - if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ, + if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, Select->pop_index_hints())) MYSQL_YYABORT; } @@ -7044,6 +7059,7 @@ assign_to_keycache_parts: table_ident adm_partition cache_keys_spec { if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, Select->pop_index_hints())) MYSQL_YYABORT; } @@ -7079,6 +7095,7 @@ preload_keys: table_ident cache_keys_spec opt_ignore_leaves { if (!Select->add_table_to_list(YYTHD, $1, NULL, $3, TL_READ, + MDL_SHARED_READ, Select->pop_index_hints())) MYSQL_YYABORT; } @@ -7088,6 +7105,7 @@ preload_keys_parts: table_ident adm_partition cache_keys_spec opt_ignore_leaves { if (!Select->add_table_to_list(YYTHD, $1, NULL, $4, TL_READ, + MDL_SHARED_READ, Select->pop_index_hints())) MYSQL_YYABORT; } @@ -9220,6 +9238,7 @@ table_factor: if (!($$= Select->add_table_to_list(YYTHD, $2, $3, Select->get_table_join_options(), YYPS->m_lock_type, + YYPS->m_mdl_type, Select->pop_index_hints()))) MYSQL_YYABORT; Select->add_joined_table($$); @@ -9291,7 +9310,7 @@ table_factor: MYSQL_YYABORT; if (!($$= sel->add_table_to_list(lex->thd, new Table_ident(unit), $5, 0, - TL_READ))) + TL_READ, MDL_SHARED_READ))) MYSQL_YYABORT; sel->add_joined_table($$); @@ -10126,13 +10145,17 @@ do: */ drop: - DROP opt_temporary table_or_tables if_exists table_list opt_restrict + DROP opt_temporary table_or_tables if_exists { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_TABLE; lex->drop_temporary= $2; lex->drop_if_exists= $4; + YYPS->m_lock_type= TL_IGNORE; + YYPS->m_mdl_type= MDL_EXCLUSIVE; } + table_list opt_restrict + {} | DROP INDEX_SYM ident ON table_ident {} { LEX *lex=Lex; @@ -10145,7 +10168,8 @@ drop: lex->alter_info.drop_list.push_back(ad); if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ)) + TL_WRITE_ALLOW_READ, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } | DROP DATABASE if_exists ident @@ -10215,12 +10239,16 @@ drop: { Lex->sql_command = SQLCOM_DROP_USER; } - | DROP VIEW_SYM if_exists table_list opt_restrict + | DROP VIEW_SYM if_exists { LEX *lex= Lex; lex->sql_command= SQLCOM_DROP_VIEW; lex->drop_if_exists= $3; + YYPS->m_lock_type= TL_IGNORE; + YYPS->m_mdl_type= MDL_EXCLUSIVE; } + table_list opt_restrict + {} | DROP EVENT_SYM if_exists sp_name { Lex->drop_if_exists= $3; @@ -10261,7 +10289,10 @@ table_list: table_name: table_ident { - if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING)) + if (!Select->add_table_to_list(YYTHD, $1, NULL, + TL_OPTION_UPDATING, + YYPS->m_lock_type, + YYPS->m_mdl_type)) MYSQL_YYABORT; } ; @@ -10276,7 +10307,8 @@ table_alias_ref: { if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, - YYPS->m_lock_type)) + YYPS->m_lock_type, + YYPS->m_mdl_type)) MYSQL_YYABORT; } ; @@ -10558,6 +10590,8 @@ delete: lex->sql_command= SQLCOM_DELETE; mysql_init_select(lex); YYPS->m_lock_type= TL_WRITE_DEFAULT; + YYPS->m_mdl_type= MDL_SHARED_WRITE; + lex->ignore= 0; lex->select_lex.init_order(); } @@ -10568,9 +10602,11 @@ single_multi: FROM table_ident { if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING, - YYPS->m_lock_type)) + YYPS->m_lock_type, + YYPS->m_mdl_type)) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_DEFAULT; + YYPS->m_mdl_type= MDL_SHARED_READ; } where_clause opt_order_clause delete_limit_clause {} @@ -10578,6 +10614,7 @@ single_multi: { mysql_init_multi_delete(Lex); YYPS->m_lock_type= TL_READ_DEFAULT; + YYPS->m_mdl_type= MDL_SHARED_READ; } FROM join_table_list where_clause { @@ -10588,6 +10625,7 @@ single_multi: { mysql_init_multi_delete(Lex); YYPS->m_lock_type= TL_READ_DEFAULT; + YYPS->m_mdl_type= MDL_SHARED_READ; } USING join_table_list where_clause { @@ -10611,7 +10649,8 @@ table_wild_one: ti, NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, - YYPS->m_lock_type)) + YYPS->m_lock_type, + YYPS->m_mdl_type)) MYSQL_YYABORT; } | ident '.' ident opt_wild @@ -10623,7 +10662,8 @@ table_wild_one: ti, NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, - YYPS->m_lock_type)) + YYPS->m_lock_type, + YYPS->m_mdl_type)) MYSQL_YYABORT; } ; @@ -11137,7 +11177,15 @@ flush: flush_options: table_or_tables - { Lex->type|= REFRESH_TABLES; } + { + Lex->type|= REFRESH_TABLES; + /* + Set type of metadata and table locks for + FLUSH TABLES table_list WITH READ LOCK. + */ + YYPS->m_lock_type= TL_READ_NO_INSERT; + YYPS->m_mdl_type= MDL_EXCLUSIVE; + } opt_table_list {} opt_with_read_lock {} | flush_options_list @@ -11301,7 +11349,7 @@ load: { LEX *lex=Lex; if (!Select->add_table_to_list(YYTHD, $12, NULL, TL_OPTION_UPDATING, - $4)) + $4, MDL_SHARED_WRITE)) MYSQL_YYABORT; lex->field_list.empty(); lex->update_list.empty(); @@ -13007,10 +13055,14 @@ table_lock: table_ident opt_table_alias lock_option { thr_lock_type lock_type= (thr_lock_type) $3; - if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type)) + bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE); + if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type, + (lock_for_write ? + MDL_SHARED_NO_READ_WRITE : + MDL_SHARED_READ))) MYSQL_YYABORT; /* If table is to be write locked, protect from a impending GRL. */ - if (lock_type >= TL_WRITE_ALLOW_WRITE) + if (lock_for_write) Lex->protect_against_global_read_lock= TRUE; } ; @@ -13765,6 +13817,7 @@ query_expression_option: if (check_simple_select()) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_HIGH_PRIORITY; + YYPS->m_mdl_type= MDL_SHARED_READ; Select->options|= SELECT_HIGH_PRIORITY; } | DISTINCT { Select->options|= SELECT_DISTINCT; } @@ -13894,7 +13947,10 @@ view_tail: LEX *lex= thd->lex; lex->sql_command= SQLCOM_CREATE_VIEW; /* first table in list is target VIEW name */ - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, TL_OPTION_UPDATING)) + if (!lex->select_lex.add_table_to_list(thd, $3, NULL, + TL_OPTION_UPDATING, + TL_IGNORE, + MDL_EXCLUSIVE)) MYSQL_YYABORT; } view_list_opt AS view_select @@ -14034,7 +14090,8 @@ trigger_tail: if (!lex->select_lex.add_table_to_list(YYTHD, $9, (LEX_STRING*) 0, TL_OPTION_UPDATING, - TL_IGNORE)) + TL_WRITE_ALLOW_READ, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } ; diff --git a/sql/table.cc b/sql/table.cc index 65918dd58f9..1e7cb747bc6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4659,13 +4659,6 @@ void TABLE_LIST::reinit_before_use(THD *thd) parent_embedding->nested_join->join_list.head() == embedded); mdl_request.ticket= NULL; - /* - Since we manipulate with the metadata lock type in open_table(), - we need to reset it to the parser default, to restore things back - to first-execution state. - */ - mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ? - MDL_SHARED_WRITE : MDL_SHARED_READ); } /* diff --git a/sql/table.h b/sql/table.h index fcff0cfb0d5..ea585208b83 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1581,20 +1581,21 @@ struct TABLE_LIST OPEN_STUB } open_strategy; /** - Indicates the locking strategy for the object being opened: - whether the associated metadata lock is shared or exclusive. + Indicates the locking strategy for the object being opened. */ enum { - /* Take a shared metadata lock before the object is opened. */ - SHARED_MDL= 0, /* - Take a exclusive metadata lock before the object is opened. - If opening is successful, downgrade to a shared lock. + Take metadata lock specified by 'mdl_request' member before + the object is opened. Do nothing after that. */ - EXCLUSIVE_DOWNGRADABLE_MDL, - /* Take a exclusive metadata lock before the object is opened. */ - EXCLUSIVE_MDL + OTLS_NONE= 0, + /* + Take (exclusive) metadata lock specified by 'mdl_request' member + before object is opened. If opening is successful, downgrade to + a shared lock. + */ + OTLS_DOWNGRADE_IF_EXISTS } lock_strategy; /* For transactional locking. */ int lock_timeout; /* NOWAIT or WAIT [X] */ From 3c279d9a5a45d734c7cdd2b641520e199e342f95 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 25 May 2010 17:01:38 -0300 Subject: [PATCH 130/207] Bug#42643: InnoDB does not support replication of TRUNCATE TABLE The problem was that TRUNCATE TABLE didn't take a exclusive lock on a table if it resorted to truncating via delete of all rows in the table. Specifically for InnoDB tables, this could break proper isolation as InnoDB ends up aborting some granted locks when truncating a table. The solution is to take a exclusive metadata lock before TRUNCATE TABLE can proceed. This guarantees that no other transaction is using the table. Incompatible change: Truncate via delete no longer fails if sql_safe_updates is activated (this was a undocumented side effect). --- .bzrignore | 6 + libmysqld/CMakeLists.txt | 3 +- libmysqld/Makefile.am | 2 +- .../extra/binlog_tests/binlog_truncate.test | 41 ++ mysql-test/include/mix1.inc | 41 ++ mysql-test/r/innodb_bug38231.result | 9 - mysql-test/r/innodb_mysql.result | 34 ++ mysql-test/r/mdl_sync.result | 39 ++ .../r/partition_innodb_semi_consistent.result | 2 + mysql-test/r/truncate.result | 8 +- .../binlog/r/binlog_truncate_innodb.result | 340 +++++++++++++ .../binlog/r/binlog_truncate_myisam.result | 90 ++++ .../binlog/t/binlog_truncate_innodb.test | 33 +- .../binlog/t/binlog_truncate_myisam.test | 18 +- mysql-test/suite/binlog/t/disabled.def | 1 - mysql-test/t/innodb_bug38231.test | 18 - mysql-test/t/mdl_sync.test | 78 +++ .../t/partition_innodb_semi_consistent.test | 2 + mysql-test/t/truncate.test | 8 +- sql/CMakeLists.txt | 2 +- sql/Makefile.am | 11 +- sql/datadict.cc | 161 ++++++ sql/datadict.h | 40 ++ sql/sql_base.cc | 5 +- sql/sql_bitmap.h | 1 + sql/sql_delete.cc | 314 +----------- sql/sql_delete.h | 4 +- sql/sql_parse.cc | 11 +- sql/sql_parse.h | 5 - sql/sql_rename.cc | 3 +- sql/sql_show.cc | 8 +- sql/sql_table.cc | 19 +- sql/sql_truncate.cc | 464 ++++++++++++++++++ sql/sql_truncate.h | 23 + sql/sql_view.cc | 51 +- sql/sql_view.h | 2 - sql/sql_yacc.yy | 6 +- sql/table.h | 9 +- 38 files changed, 1471 insertions(+), 441 deletions(-) create mode 100644 sql/datadict.cc create mode 100644 sql/datadict.h create mode 100644 sql/sql_truncate.cc create mode 100644 sql/sql_truncate.h diff --git a/.bzrignore b/.bzrignore index d51ffc7265b..b90eca9caf1 100644 --- a/.bzrignore +++ b/.bzrignore @@ -996,6 +996,8 @@ libmysqld/.deps/sql_crypt.Po libmysqld/.deps/sql_cursor.Po libmysqld/.deps/sql_db.Po libmysqld/.deps/sql_delete.Po +libmysqld/.deps/sql_truncate.Po +libmysqld/.deps/datadict.Po libmysqld/.deps/sql_derived.Po libmysqld/.deps/sql_do.Po libmysqld/.deps/sql_error.Po @@ -1172,6 +1174,8 @@ libmysqld/sql_cursor.cc libmysqld/sql_cursor.h libmysqld/sql_db.cc libmysqld/sql_delete.cc +libmysqld/sql_truncate.cc +libmysqld/datadict.cc libmysqld/sql_derived.cc libmysqld/sql_do.cc libmysqld/sql_error.cc @@ -2062,6 +2066,8 @@ sql/.deps/sql_crypt.Po sql/.deps/sql_cursor.Po sql/.deps/sql_db.Po sql/.deps/sql_delete.Po +sql/.deps/sql_truncate.Po +sql/.deps/datadict.Po sql/.deps/sql_derived.Po sql/.deps/sql_do.Po sql/.deps/sql_error.Po diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index fa5088f288b..1cdf8e41a74 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -63,7 +63,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/sql_class.cc ../sql/sql_crypt.cc ../sql/sql_cursor.cc ../sql/sql_db.cc ../sql/sql_delete.cc ../sql/sql_derived.cc ../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc - ../sql/sql_help.cc ../sql/sql_insert.cc + ../sql/sql_help.cc ../sql/sql_insert.cc ../sql/datadict.cc + ../sql/sql_truncate.cc ../sql/sql_lex.cc ../sql/keycaches.cc ../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc ../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 68c31fbf79c..d4f000864ea 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -63,7 +63,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ protocol.cc net_serv.cc opt_range.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \ sql_load.cc discover.cc sql_locale.cc \ - sql_profile.cc \ + sql_profile.cc sql_truncate.cc datadict.cc \ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \ sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \ sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \ diff --git a/mysql-test/extra/binlog_tests/binlog_truncate.test b/mysql-test/extra/binlog_tests/binlog_truncate.test index dce33b3cef0..24cf363f780 100644 --- a/mysql-test/extra/binlog_tests/binlog_truncate.test +++ b/mysql-test/extra/binlog_tests/binlog_truncate.test @@ -25,3 +25,44 @@ TRUNCATE TABLE t2; source include/show_binlog_events.inc; DROP TABLE t1,t2; + +--echo # +--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +--echo # + +eval CREATE TABLE t1 (a INT) ENGINE=$engine; +eval CREATE TABLE t2 (a INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1),(2); + +let $binlog_start = query_get_value("SHOW MASTER STATUS", Position, 1); +if (`select length('$before_truncate') > 0`) { + eval $before_truncate; +} + +--echo # Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; + +connect (truncate,localhost,root,,); +--echo # Connection: truncate +send TRUNCATE TABLE t1; + +connection default; +--echo # Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COMMIT; + +connection truncate; +--echo # Connection: truncate +--echo # Reaping TRUNCATE TABLE +--reap +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t2; + +connection default; +--echo # Connection: default + +source include/show_binlog_events.inc; +disconnect truncate; +DROP TABLE t1,t2; diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 66648aaf1bf..fe6abe13892 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1351,6 +1351,13 @@ connection con1; SELECT * FROM t1; ROLLBACK; +--echo # Switch to connection con2 +connection con2; +ROLLBACK; + +--echo # Switch to connection con1 +connection con1; + --echo # 2. test for serialized update: CREATE TABLE t2 (a INT); @@ -1435,6 +1442,7 @@ connection con2; --reap SELECT * FROM t1; +--enable_abort_on_error connection default; disconnect con1; disconnect con2; @@ -1556,3 +1564,36 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +--echo # +--echo # Check that a TRUNCATE TABLE statement, needing an exclusive meta +--echo # data lock, waits for a shared metadata lock owned by a concurrent +--echo # transaction. +--echo # + +eval CREATE TABLE t1 (a INT) ENGINE=$engine_type; +INSERT INTO t1 VALUES (1),(2),(3); +BEGIN; +SELECT * FROM t1 ORDER BY a; +--echo # Connection con1 +connect (con1, localhost, root,,); +--send TRUNCATE TABLE t1; +--echo # Connection default +connection default; +let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist + WHERE state='Waiting for table' AND info='TRUNCATE TABLE t1'; +--source include/wait_condition.inc +SELECT * FROM t1 ORDER BY a; +ROLLBACK; +--echo # Connection con1 +connection con1; +--echo # Reaping TRUNCATE TABLE +--reap +SELECT * FROM t1; +--echo # Disconnect con1 +disconnect con1; +--echo # Connection default +connection default; +DROP TABLE t1; diff --git a/mysql-test/r/innodb_bug38231.result b/mysql-test/r/innodb_bug38231.result index 2f909779755..a2a872e573f 100644 --- a/mysql-test/r/innodb_bug38231.result +++ b/mysql-test/r/innodb_bug38231.result @@ -1,11 +1,2 @@ SET storage_engine=InnoDB; -INSERT INTO bug38231 VALUES (1), (10), (300); -SET autocommit=0; -SELECT * FROM bug38231 FOR UPDATE; -a -1 -10 -300 -TRUNCATE TABLE bug38231; -COMMIT; DROP TABLE bug38231; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 0a3df1f99b5..4dba86752f0 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1590,6 +1590,9 @@ SELECT * FROM t1; a b 1 12 ROLLBACK; +# Switch to connection con2 +ROLLBACK; +# Switch to connection con1 # 2. test for serialized update: CREATE TABLE t2 (a INT); TRUNCATE t1; @@ -1764,6 +1767,37 @@ id select_type table type possible_keys key key_len ref rows Extra 2 DERIVED t1 index c3,c2 c2 14 NULL 5 DROP TABLE t1; End of 5.1 tests +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +# Check that a TRUNCATE TABLE statement, needing an exclusive meta +# data lock, waits for a shared metadata lock owned by a concurrent +# transaction. +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3); +BEGIN; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +# Connection con1 +TRUNCATE TABLE t1;; +# Connection default +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +ROLLBACK; +# Connection con1 +# Reaping TRUNCATE TABLE +SELECT * FROM t1; +a +# Disconnect con1 +# Connection default +DROP TABLE t1; drop table if exists t1, t2, t3; create table t1(a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index 984f0df3d0e..8e004ba23f7 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2381,3 +2381,42 @@ commit; # Reap ALTER TABLE. set debug_sync= 'RESET'; drop table t1; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +# Ensure that a acquired lock is not given up due to a conflict. +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3); +# Connection: con1 +SET debug_sync='lock_table_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; +TRUNCATE TABLE t1; +# Connection: default +SET debug_sync='now WAIT_FOR parked_truncate'; +# Connection: con2 +SET debug_sync='after_open_table_ignore_flush SIGNAL parked_show WAIT_FOR go_show'; +SHOW FIELDS FROM t1; +# Connection: default +SET debug_sync='now WAIT_FOR parked_show'; +# Connection: con3 +SET debug_sync='after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush'; +FLUSH TABLES t1; +# Connection: default +SET debug_sync='now WAIT_FOR parked_flush'; +SET debug_sync='now SIGNAL go_truncate'; +# Connection: con1 +# Reaping... +# Connection: default +SET debug_sync= 'now SIGNAL go_show'; +# Connection: con2 (SHOW FIELDS FROM t1) +# Reaping... +Field Type Null Key Default Extra +a int(11) YES NULL +# Connection: default +SET debug_sync= 'now SIGNAL go_flush'; +# Connection: con3 (FLUSH TABLES t1) +# Reaping... +# Connection: default +SET debug_sync= 'RESET'; +DROP TABLE t1; diff --git a/mysql-test/r/partition_innodb_semi_consistent.result b/mysql-test/r/partition_innodb_semi_consistent.result index 48a1bb3d258..ef9337fa65c 100644 --- a/mysql-test/r/partition_innodb_semi_consistent.result +++ b/mysql-test/r/partition_innodb_semi_consistent.result @@ -64,6 +64,7 @@ a b # Switch to connection con2 UPDATE t1 SET b = 21 WHERE a = 1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ROLLBACK; # Switch to connection con1 SELECT * FROM t1; a b @@ -99,6 +100,7 @@ a b SELECT * FROM t1; a b 1 init+con1+con2 +COMMIT; # Switch to connection con1 # 3. test for updated key column: TRUNCATE t1; diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result index 8f237c81e75..773075f9dae 100644 --- a/mysql-test/r/truncate.result +++ b/mysql-test/r/truncate.result @@ -99,7 +99,7 @@ LOCK TABLE t1 WRITE; SELECT * FROM v1; ERROR HY000: Table 'v1' was not locked with LOCK TABLES TRUNCATE v1; -ERROR 42S02: Table 'test.v1' doesn't exist +ERROR HY000: Table 'v1' was not locked with LOCK TABLES SELECT * FROM v1; ERROR HY000: Table 'v1' was not locked with LOCK TABLES UNLOCK TABLES; @@ -107,7 +107,7 @@ LOCK TABLE t1 WRITE, t2 WRITE; SELECT * FROM v1; ERROR HY000: Table 'v1' was not locked with LOCK TABLES TRUNCATE v1; -ERROR 42S02: Table 'test.v1' doesn't exist +ERROR HY000: Table 'v1' was not locked with LOCK TABLES SELECT * FROM v1; ERROR HY000: Table 'v1' was not locked with LOCK TABLES UNLOCK TABLES; @@ -117,7 +117,7 @@ c1 1 3 TRUNCATE v1; -ERROR 42S02: Table 'test.v1' doesn't exist +ERROR HY000: Table 'v1' was not locked with LOCK TABLES SELECT * FROM v1; c1 1 @@ -129,7 +129,7 @@ c1 1 3 TRUNCATE v1; -ERROR 42S02: Table 'test.v1' doesn't exist +ERROR HY000: Table 'v1' was not locked with LOCK TABLES SELECT * FROM v1; c1 1 diff --git a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result index ab237898a74..8beeeb1a428 100644 --- a/mysql-test/suite/binlog/r/binlog_truncate_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_truncate_innodb.result @@ -1,3 +1,6 @@ +SET @old_binlog_format=@@binlog_format; +SET BINLOG_FORMAT=ROW; +RESET MASTER; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t2 VALUES (1),(2),(3); @@ -9,6 +12,45 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +# Even though the isolation level might be permissive, truncate +# table follows a stricter isolation as its locking is based on +# (exclusive) metadata locks. CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t2 VALUES (1),(2),(3); @@ -22,6 +64,43 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t2 VALUES (1),(2),(3); @@ -35,6 +114,43 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t2 VALUES (1),(2),(3); @@ -48,6 +164,43 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; INSERT INTO t2 VALUES (1),(2),(3); @@ -61,3 +214,190 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +SET BINLOG_FORMAT=STATEMENT; +RESET MASTER; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(2),(3); +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +**** Truncate of empty table shall be logged +TRUNCATE TABLE t1; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +TRUNCATE TABLE t2; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 +DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +# Truncate is not supported for SBR if the isolation level is +# READ UNCOMMITTED or READ COMMITTED. These specific isolation +# levels are tested elsewhere. +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(2),(3); +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +**** Truncate of empty table shall be logged +TRUNCATE TABLE t1; +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +TRUNCATE TABLE t2; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 +DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(2),(3); +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +**** Truncate of empty table shall be logged +TRUNCATE TABLE t1; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +TRUNCATE TABLE t2; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 +DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +SET BINLOG_FORMAT=@old_binlog_format; diff --git a/mysql-test/suite/binlog/r/binlog_truncate_myisam.result b/mysql-test/suite/binlog/r/binlog_truncate_myisam.result index 9f01c015178..1f5b206fd6f 100644 --- a/mysql-test/suite/binlog/r/binlog_truncate_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_truncate_myisam.result @@ -1,3 +1,5 @@ +SET @old_binlog_format=@@binlog_format; +SET BINLOG_FORMAT=ROW; RESET MASTER; CREATE TABLE t1 (a INT) ENGINE=MyISAM; CREATE TABLE t2 (a INT) ENGINE=MyISAM; @@ -10,3 +12,91 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +CREATE TABLE t2 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +SET BINLOG_FORMAT=STATEMENT; +RESET MASTER; +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +CREATE TABLE t2 (a INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1),(2),(3); +**** Truncate of empty table shall be logged +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2 +DROP TABLE t1,t2; +# +# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +CREATE TABLE t2 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +# Connection: default +BEGIN; +INSERT INTO t2 SELECT * FROM t1; +# Connection: truncate +TRUNCATE TABLE t1; +# Connection: default +INSERT INTO t2 SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +COMMIT; +# Connection: truncate +# Reaping TRUNCATE TABLE +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +SELECT COUNT(*) FROM t2; +COUNT(*) +4 +# Connection: default +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1 +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1 +DROP TABLE t1,t2; +SET BINLOG_FORMAT=@old_binlog_format; diff --git a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test index be0918a43f0..56dd5bda505 100644 --- a/mysql-test/suite/binlog/t/binlog_truncate_innodb.test +++ b/mysql-test/suite/binlog/t/binlog_truncate_innodb.test @@ -1,20 +1,18 @@ source include/have_log_bin.inc; source include/have_innodb.inc; -# It is necessary to reset the master since otherwise the binlog test -# might show the wrong binary log. The default for SHOW BINLOG EVENTS -# is to show the first binary log, not the current one (which is -# actually a better idea). +let $engine = InnoDB; +SET @old_binlog_format=@@binlog_format; + +SET BINLOG_FORMAT=ROW; RESET MASTER; -let $engine = InnoDB; source extra/binlog_tests/binlog_truncate.test; -# Under transaction isolation level READ UNCOMMITTED and READ -# COMMITTED, InnoDB does not permit statement-based replication of -# row-deleting statement. In these cases, TRUNCATE TABLE should still -# be replicated as a statement. +--echo # Even though the isolation level might be permissive, truncate +--echo # table follows a stricter isolation as its locking is based on +--echo # (exclusive) metadata locks. let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; source extra/binlog_tests/binlog_truncate.test; @@ -27,3 +25,20 @@ source extra/binlog_tests/binlog_truncate.test; let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; source extra/binlog_tests/binlog_truncate.test; + +SET BINLOG_FORMAT=STATEMENT; +RESET MASTER; + +source extra/binlog_tests/binlog_truncate.test; + +--echo # Truncate is not supported for SBR if the isolation level is +--echo # READ UNCOMMITTED or READ COMMITTED. These specific isolation +--echo # levels are tested elsewhere. + +let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +source extra/binlog_tests/binlog_truncate.test; + +let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +source extra/binlog_tests/binlog_truncate.test; + +SET BINLOG_FORMAT=@old_binlog_format; diff --git a/mysql-test/suite/binlog/t/binlog_truncate_myisam.test b/mysql-test/suite/binlog/t/binlog_truncate_myisam.test index e0e4673e876..fc28bd7c7e2 100644 --- a/mysql-test/suite/binlog/t/binlog_truncate_myisam.test +++ b/mysql-test/suite/binlog/t/binlog_truncate_myisam.test @@ -1,11 +1,17 @@ source include/have_log_bin.inc; -# It is necessary to reset the master since otherwise the binlog test -# might show the wrong binary log. The default for SHOW BINLOG EVENTS -# is to show the first binary log, not the current one (which is -# actually a better idea). - -RESET MASTER; +SET @old_binlog_format=@@binlog_format; let $engine = MyISAM; + +SET BINLOG_FORMAT=ROW; +RESET MASTER; + source extra/binlog_tests/binlog_truncate.test; + +SET BINLOG_FORMAT=STATEMENT; +RESET MASTER; + +source extra/binlog_tests/binlog_truncate.test; + +SET BINLOG_FORMAT=@old_binlog_format; diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index a86136fec69..b12a0a1d96d 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -9,6 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763 binlog_unsafe : BUG#50312 2010-01-13 lsoares Warnings for unsafe sub-statement not returned to client diff --git a/mysql-test/t/innodb_bug38231.test b/mysql-test/t/innodb_bug38231.test index b3fcd89f371..f70a4c86dd1 100644 --- a/mysql-test/t/innodb_bug38231.test +++ b/mysql-test/t/innodb_bug38231.test @@ -49,27 +49,9 @@ UNLOCK TABLES; -- disconnect con1 -- disconnect con2 -# test that TRUNCATE works with with row-level locks - -- enable_query_log -- enable_result_log -INSERT INTO bug38231 VALUES (1), (10), (300); - --- connect (con4,localhost,root,,) - --- connection con4 -SET autocommit=0; -SELECT * FROM bug38231 FOR UPDATE; - -- connection default -TRUNCATE TABLE bug38231; - --- connection con4 -COMMIT; - --- connection default - --- disconnect con4 DROP TABLE bug38231; diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index ef434e33cfa..a5b631058c5 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -3468,6 +3468,84 @@ connection default; set debug_sync= 'RESET'; drop table t1; +--echo # +--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE +--echo # +--echo # Ensure that a acquired lock is not given up due to a conflict. +--echo # + +connect (con1,localhost,root,,test,,); +connect (con2,localhost,root,,test,,); +connect (con3,localhost,root,,test,,); + +connection default; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3); + +--echo # Connection: con1 +connection con1; +SET debug_sync='lock_table_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate'; +send TRUNCATE TABLE t1; + +connection default; +--echo # Connection: default +SET debug_sync='now WAIT_FOR parked_truncate'; + +connection con2; +--echo # Connection: con2 +SET debug_sync='after_open_table_ignore_flush SIGNAL parked_show WAIT_FOR go_show'; +send SHOW FIELDS FROM t1; + +connection default; +--echo # Connection: default +SET debug_sync='now WAIT_FOR parked_show'; + +connection con3; +--echo # Connection: con3 +SET debug_sync='after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush'; +send FLUSH TABLES t1; + +connection default; +--echo # Connection: default +SET debug_sync='now WAIT_FOR parked_flush'; +SET debug_sync='now SIGNAL go_truncate'; + +connection con1; +--echo # Connection: con1 +--echo # Reaping... +reap; + +connection default; +--echo # Connection: default +SET debug_sync= 'now SIGNAL go_show'; + +connection con2; +--echo # Connection: con2 (SHOW FIELDS FROM t1) +--echo # Reaping... +reap; + +connection default; +--echo # Connection: default +SET debug_sync= 'now SIGNAL go_flush'; + +connection con3; +--echo # Connection: con3 (FLUSH TABLES t1) +--echo # Reaping... +reap; + +disconnect con1; +disconnect con2; +disconnect con3; + +connection default; +--echo # Connection: default +SET debug_sync= 'RESET'; +DROP TABLE t1; # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 294521a45d5..00ea34c390a 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -101,6 +101,7 @@ connection con2; --error ER_LOCK_WAIT_TIMEOUT UPDATE t1 SET b = 21 WHERE a = 1; --disable_info +ROLLBACK; --echo # Switch to connection con1 connection con1; @@ -150,6 +151,7 @@ SELECT * FROM t1; connection con2; --reap SELECT * FROM t1; +COMMIT; --echo # Switch to connection con1 connection con1; diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test index cdfa448f78a..c7a066cc203 100644 --- a/mysql-test/t/truncate.test +++ b/mysql-test/t/truncate.test @@ -102,7 +102,7 @@ SELECT * FROM v1; LOCK TABLE t1 WRITE; --error ER_TABLE_NOT_LOCKED SELECT * FROM v1; ---error ER_NO_SUCH_TABLE +--error ER_TABLE_NOT_LOCKED TRUNCATE v1; --error ER_TABLE_NOT_LOCKED SELECT * FROM v1; @@ -111,7 +111,7 @@ UNLOCK TABLES; LOCK TABLE t1 WRITE, t2 WRITE; --error ER_TABLE_NOT_LOCKED SELECT * FROM v1; ---error ER_NO_SUCH_TABLE +--error ER_TABLE_NOT_LOCKED TRUNCATE v1; --error ER_TABLE_NOT_LOCKED SELECT * FROM v1; @@ -119,14 +119,14 @@ UNLOCK TABLES; # LOCK TABLE v1 WRITE; SELECT * FROM v1; ---error ER_NO_SUCH_TABLE +--error ER_TABLE_NOT_LOCKED TRUNCATE v1; SELECT * FROM v1; UNLOCK TABLES; # LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE; SELECT * FROM v1; ---error ER_NO_SUCH_TABLE +--error ER_TABLE_NOT_LOCKED TRUNCATE v1; SELECT * FROM v1; UNLOCK TABLES; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 357575c5b47..87461be88f3 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -75,7 +75,7 @@ SET (SQL_SOURCE sql_connect.cc scheduler.cc sql_profile.cc event_parse_data.cc sql_signal.cc rpl_handler.cc mdl.cc - transaction.cc sys_vars.cc + transaction.cc sys_vars.cc sql_truncate.cc datadict.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE}) diff --git a/sql/Makefile.am b/sql/Makefile.am index 93595a964eb..0fba8d12406 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -39,7 +39,9 @@ DTRACEFILES = filesort.o \ sql_connect.o \ sql_cursor.o \ sql_delete.o \ + sql_truncate.o \ sql_insert.o \ + datadict.o \ sql_parse.o \ sql_prepare.o \ sql_select.o \ @@ -56,7 +58,9 @@ DTRACEFILES_DEPEND = filesort.o \ sql_connect.o \ sql_cursor.o \ sql_delete.o \ + sql_truncate.o \ sql_insert.o \ + datadict.o \ sql_parse.o \ sql_prepare.o \ sql_select.o \ @@ -121,7 +125,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_audit.h \ contributors.h sql_servers.h sql_signal.h records.h \ sql_prepare.h rpl_handler.h replication.h mdl.h \ - sql_plist.h transaction.h sys_vars.h + sql_plist.h transaction.h sys_vars.h sql_truncate.h \ + datadict.h mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ @@ -136,10 +141,10 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_connect.cc scheduler.cc sql_parse.cc \ keycaches.cc set_var.cc sql_yacc.yy sys_vars.cc \ sql_base.cc table.cc sql_select.cc sql_insert.cc \ - sql_profile.cc \ + datadict.cc sql_profile.cc \ sql_prepare.cc sql_error.cc sql_locale.cc \ sql_update.cc sql_delete.cc uniques.cc sql_do.cc \ - procedure.cc sql_test.cc \ + procedure.cc sql_test.cc sql_truncate.cc \ log.cc init.cc derror.cc sql_acl.cc \ unireg.cc des_key_file.cc \ log_event.cc rpl_record.cc \ diff --git a/sql/datadict.cc b/sql/datadict.cc new file mode 100644 index 00000000000..5067c13a255 --- /dev/null +++ b/sql/datadict.cc @@ -0,0 +1,161 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "datadict.h" +#include "sql_priv.h" +#include "sql_class.h" +#include "sql_table.h" + + +/** + Check type of .frm if we are not going to parse it. + + @param path path to FRM file + + @retval FRMTYPE_ERROR error + @retval FRMTYPE_TABLE table + @retval FRMTYPE_VIEW view +*/ + +frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) +{ + File file; + uchar header[10]; //"TYPE=VIEW\n" it is 10 characters + size_t error; + DBUG_ENTER("dd_frm_type"); + + *dbt= DB_TYPE_UNKNOWN; + + if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0) + DBUG_RETURN(FRMTYPE_ERROR); + error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)); + mysql_file_close(file, MYF(MY_WME)); + + if (error) + DBUG_RETURN(FRMTYPE_ERROR); + if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header))) + DBUG_RETURN(FRMTYPE_VIEW); + + /* + This is just a check for DB_TYPE. We'll return default unknown type + if the following test is true (arg #3). This should not have effect + on return value from this function (default FRMTYPE_TABLE) + */ + if (header[0] != (uchar) 254 || header[1] != 1 || + (header[2] != FRM_VER && header[2] != FRM_VER+1 && + (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) + DBUG_RETURN(FRMTYPE_TABLE); + + *dbt= (enum legacy_db_type) (uint) *(header + 3); + + /* Probably a table. */ + DBUG_RETURN(FRMTYPE_TABLE); +} + + +/** + Given a table name, check if the storage engine for the + table referred by this name supports an option 'flag'. + Return an error if the table does not exist or is not a + base table. + + @pre Any metadata lock on the table. + + @param[in] thd The current session. + @param[in] db Table schema. + @param[in] table_name Table database. + @param[in] flag The option to check. + @param[out] yes_no The result. Undefined if error. +*/ + +bool dd_check_storage_engine_flag(THD *thd, + const char *db, const char *table_name, + uint32 flag, bool *yes_no) +{ + char path[FN_REFLEN + 1]; + enum legacy_db_type db_type; + handlerton *table_type; + LEX_STRING db_name = {(char *) db, strlen(db)}; + + if (check_db_name(&db_name)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); + return TRUE; + } + + if (check_table_name(table_name, strlen(table_name))) + { + my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name); + return TRUE; + } + + /* There should be at least some lock on the table. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, + table_name, MDL_SHARED)); + + (void) build_table_filename(path, sizeof(path) - 1, db, + table_name, reg_ext, 0); + + dd_frm_type(thd, path, &db_type); + + /* Type is unknown if the object is not found or is not a table. */ + if (db_type == DB_TYPE_UNKNOWN) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), db, table_name); + return TRUE; + } + + table_type= ha_resolve_by_legacy_type(thd, db_type); + *yes_no= ha_check_storage_engine_flag(table_type, flag); + + return FALSE; +} + + +/* + Regenerate a metadata locked table. + + @param thd Thread context. + @param db Name of the database to which the table belongs to. + @param name Table name. + + @retval FALSE Success. + @retval TRUE Error. +*/ + +bool dd_recreate_table(THD *thd, const char *db, const char *table_name) +{ + bool error= TRUE; + HA_CREATE_INFO create_info; + char path[FN_REFLEN + 1]; + DBUG_ENTER("dd_recreate_table"); + + /* There should be a exclusive metadata lock on the table. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, + MDL_EXCLUSIVE)); + + memset(&create_info, 0, sizeof(create_info)); + + /* Create a path to the table, but without a extension. */ + build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); + + /* Attempt to reconstruct the table. */ + mysql_mutex_lock(&LOCK_open); + error= ha_create_table(thd, path, db, table_name, &create_info, TRUE); + mysql_mutex_unlock(&LOCK_open); + + DBUG_RETURN(error); +} + diff --git a/sql/datadict.h b/sql/datadict.h new file mode 100644 index 00000000000..05b5a9bba4b --- /dev/null +++ b/sql/datadict.h @@ -0,0 +1,40 @@ +#ifndef DATADICT_INCLUDED +#define DATADICT_INCLUDED +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "handler.h" + +/* + Data dictionary API. +*/ + +enum frm_type_enum +{ + FRMTYPE_ERROR= 0, + FRMTYPE_TABLE, + FRMTYPE_VIEW +}; + + +frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt); + +bool dd_check_storage_engine_flag(THD *thd, + const char *db, const char *table_name, + uint32 flag, + bool *yes_no); +bool dd_recreate_table(THD *thd, const char *db, const char *table_name); + +#endif // DATADICT_INCLUDED diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 85017886d24..fa484abf0be 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -27,7 +27,7 @@ #include "sql_show.h" // append_identifier #include "strfunc.h" // find_type #include "parse_file.h" // sql_parse_prepare, File_parser -#include "sql_view.h" // mysql_frm_type, mysql_make_view, VIEW_ANY_ACL +#include "sql_view.h" // mysql_make_view, VIEW_ANY_ACL #include "sql_parse.h" // check_table_access #include "sql_insert.h" // kill_delayed_threads #include "sql_acl.h" // *_ACL, check_grant_all_columns, @@ -52,6 +52,7 @@ #include #include "rpl_filter.h" #include "sql_table.h" // build_table_filename +#include "datadict.h" // dd_frm_type() #ifdef __WIN__ #include #endif @@ -2678,7 +2679,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, during prelocking process (in this case in theory we still should hold shared metadata lock on it). */ - if (mysql_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) + if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) { if (!tdc_open_view(thd, table_list, alias, key, key_length, mem_root, 0)) diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 80a4712dd69..8d00c984d14 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -22,6 +22,7 @@ #ifndef SQL_BITMAP_INCLUDED #define SQL_BITMAP_INCLUDED +#include #include template class Bitmap diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 10bdb8a22a6..730cb711a05 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -14,7 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - Delete of records and truncate of tables. + Delete of records tables. Multi-table deletes were introduced by Monty and Sinisa */ @@ -48,8 +48,7 @@ */ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - SQL_LIST *order, ha_rows limit, ulonglong options, - bool reset_auto_increment) + SQL_LIST *order, ha_rows limit, ulonglong options) { bool will_batch; int error, loc_error; @@ -60,17 +59,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bool transactional_table, safe_update, const_cond; bool const_cond_result; ha_rows deleted= 0; - bool triggers_applicable; uint usable_index= MAX_KEY; SELECT_LEX *select_lex= &thd->lex->select_lex; THD::killed_state killed_status= THD::NOT_KILLED; + THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE; DBUG_ENTER("mysql_delete"); - bool save_binlog_row_based; - - THD::enum_binlog_query_type query_type= - thd->lex->sql_command == SQLCOM_TRUNCATE ? - THD::STMT_QUERY_TYPE : - THD::ROW_QUERY_TYPE; if (open_and_lock_tables(thd, table_list, TRUE, 0)) DBUG_RETURN(TRUE); @@ -130,25 +123,20 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, any side-effects (because of triggers), so we can use optimized handler::delete_all_rows() method. - We implement fast TRUNCATE for InnoDB even if triggers are - present. TRUNCATE ignores triggers. - We can use delete_all_rows() if and only if: - We allow new functions (not using option --skip-new), and are not in safe mode (not using option --safe-mode) - There is no limit clause - The condition is constant - If there is a condition, then it it produces a non-zero value - - If the current command is DELETE FROM with no where clause - (i.e., not TRUNCATE) then: - - We should not be binlogging this statement row-based, and + - If the current command is DELETE FROM with no where clause, then: + - We should not be binlogging this statement in row-based, and - there should be no delete triggers associated with the table. */ if (!using_limit && const_cond_result && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && - (thd->lex->sql_command == SQLCOM_TRUNCATE || (!thd->is_current_stmt_binlog_format_row() && - !(table->triggers && table->triggers->has_delete_triggers())))) + !(table->triggers && table->triggers->has_delete_triggers()))) { /* Update the table->file->stats.records number */ table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -161,16 +149,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, query in row format, so we have to log it in statement format. */ query_type= THD::STMT_QUERY_TYPE; - error= -1; // ok + error= -1; deleted= maybe_deleted; - save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); goto cleanup; } if (error != HA_ERR_WRONG_COMMAND) { table->file->print_error(error,MYF(0)); error=0; - save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); goto cleanup; } /* Handler didn't support fast delete; Delete rows one by one */ @@ -213,11 +199,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (thd->is_error()) DBUG_RETURN(TRUE); my_ok(thd, 0); - /* - We don't need to call reset_auto_increment in this case, because - mysql_truncate always gives a NULL conds argument, hence we never - get here. - */ DBUG_RETURN(0); // Nothing to delete } @@ -287,12 +268,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, init_ftfuncs(thd, select_lex, 1); thd_proc_info(thd, "updating"); - /* NOTE: TRUNCATE must not invoke triggers. */ - - triggers_applicable= table->triggers && - thd->lex->sql_command != SQLCOM_TRUNCATE; - - if (triggers_applicable && + if (table->triggers && table->triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)) { @@ -310,11 +286,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->mark_columns_needed_for_delete(); - save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); - if (thd->lex->sql_command == SQLCOM_TRUNCATE && - thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); - while (!(error=info.read_record(&info)) && !thd->killed && ! thd->is_error()) { @@ -322,7 +293,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(select && select->skip_record())&& ! thd->is_error() ) { - if (triggers_applicable && + if (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) { @@ -333,7 +304,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(error= table->file->ha_delete_row(table->record[0]))) { deleted++; - if (triggers_applicable && + if (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE)) { @@ -378,21 +349,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (options & OPTION_QUICK) (void) table->file->extra(HA_EXTRA_NORMAL); - if (reset_auto_increment && (error < 0)) - { - /* - We're really doing a truncate and need to reset the table's - auto-increment counter. - */ - int error2= table->file->ha_reset_auto_increment(0); - - if (error2 && (error2 != HA_ERR_WRONG_COMMAND)) - { - table->file->print_error(error2, MYF(0)); - error= 1; - } - } - cleanup: /* Invalidate the table in the query cache if something changed. This must @@ -413,34 +369,24 @@ cleanup: /* See similar binlogging code in sql_update.cc, for comments */ if ((error < 0) || thd->transaction.stmt.modified_non_trans_table) { - if (mysql_bin_log.is_open() && - !(thd->lex->sql_command == SQLCOM_TRUNCATE && - thd->is_current_stmt_binlog_format_row() && - find_temporary_table(thd, table_list))) + if (mysql_bin_log.is_open()) { - bool const is_trans= - thd->lex->sql_command == SQLCOM_TRUNCATE ? - FALSE : - transactional_table; - int errcode= 0; if (error < 0) thd->clear_error(); else errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); - + /* [binlog]: If 'handler::delete_all_rows()' was called and the storage engine does not inject the rows itself, we replicate statement-based; otherwise, 'ha_delete_row()' was used to delete specific rows which we might log row-based. - - Note that TRUNCATE TABLE is not transactional and should - therefore be treated as a DDL. */ int log_result= thd->binlog_query(query_type, thd->query(), thd->query_length(), - is_trans, FALSE, FALSE, errcode); + transactional_table, FALSE, FALSE, + errcode); if (log_result) { @@ -448,18 +394,12 @@ cleanup: } } } - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); free_underlaid_joins(thd, select_lex); if (error < 0 || (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) { - /* - If a TRUNCATE TABLE was issued, the number of rows should be reported as - zero since the exact number is unknown. - */ - my_ok(thd, reset_auto_increment ? 0 : deleted); + my_ok(thd, deleted); DBUG_PRINT("info",("%ld records deleted",(long) deleted)); } DBUG_RETURN(error >= 0 || thd->is_error()); @@ -1061,227 +1001,3 @@ bool multi_delete::send_eof() return 0; } - -/*************************************************************************** - TRUNCATE TABLE -****************************************************************************/ - -/* - Row-by-row truncation if the engine does not support table recreation. - Probably a InnoDB table. -*/ - -static bool mysql_truncate_by_delete(THD *thd, TABLE_LIST *table_list) -{ - bool error; - DBUG_ENTER("mysql_truncate_by_delete"); - table_list->lock_type= TL_WRITE; - table_list->mdl_request.set_type(MDL_SHARED_WRITE); - mysql_init_select(thd->lex); - /* Delete all rows from table */ - error= mysql_delete(thd, table_list, NULL, NULL, HA_POS_ERROR, LL(0), TRUE); - /* - All effects of a TRUNCATE TABLE operation are rolled back if a row by row - deletion fails. Otherwise, operation is automatically committed at the end. - */ - if (error) - { - DBUG_ASSERT(thd->stmt_da->is_error()); - trans_rollback_stmt(thd); - trans_rollback(thd); - } - DBUG_RETURN(error); -} - - -/* - Optimize delete of all rows by doing a full generate of the table - This will work even if the .ISM and .ISD tables are destroyed - - dont_send_ok should be set if: - - We should always wants to generate the table (even if the table type - normally can't safely do this. - - We don't want an ok to be sent to the end user. - - We don't want to log the truncate command - - If we want to keep exclusive metadata lock on the table (obtained by - caller) on exit without errors. -*/ - -bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) -{ - HA_CREATE_INFO create_info; - char path[FN_REFLEN + 1]; - TABLE *table; - bool error= TRUE; - uint path_length; - /* - Is set if we're under LOCK TABLES, and used - to downgrade the exclusive lock after the - table was truncated. - */ - MDL_ticket *mdl_ticket= NULL; - bool has_mdl_lock= FALSE; - bool is_temporary_table= false; - DBUG_ENTER("mysql_truncate"); - - bzero((char*) &create_info,sizeof(create_info)); - - /* Remove tables from the HANDLER's hash. */ - mysql_ha_rm_tables(thd, table_list); - - /* If it is a temporary table, close and regenerate it */ - if (!dont_send_ok && (table= find_temporary_table(thd, table_list))) - { - is_temporary_table= true; - handlerton *table_type= table->s->db_type(); - TABLE_SHARE *share= table->s; - /* Note that a temporary table cannot be partitioned */ - if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE)) - goto trunc_by_del; - - table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); - - close_temporary_table(thd, table, 0, 0); // Don't free share - ha_create_table(thd, share->normalized_path.str, - share->db.str, share->table_name.str, &create_info, 1); - // We don't need to call invalidate() because this table is not in cache - if ((error= (int) !(open_temporary_table(thd, share->path.str, - share->db.str, - share->table_name.str, 1)))) - (void) rm_temporary_table(table_type, path); - else - thd->thread_specific_used= TRUE; - - free_table_share(share); - my_free((char*) table,MYF(0)); - /* - If we return here we will not have logged the truncation to the bin log - and we will not my_ok() to the client. - */ - goto end; - } - - path_length= build_table_filename(path, sizeof(path) - 1, table_list->db, - table_list->table_name, reg_ext, 0); - - if (!dont_send_ok) - { - enum legacy_db_type table_type; - /* - FIXME: Code of TRUNCATE breaks the meta-data - locking protocol since it tries to find out the table storage - engine and therefore accesses table in some way without holding - any kind of meta-data lock. - */ - mysql_frm_type(thd, path, &table_type); - if (table_type == DB_TYPE_UNKNOWN) - { - my_error(ER_NO_SUCH_TABLE, MYF(0), - table_list->db, table_list->table_name); - DBUG_RETURN(TRUE); - } -#ifdef WITH_PARTITION_STORAGE_ENGINE - /* - TODO: Add support for TRUNCATE PARTITION for NDB and other engines - supporting native partitioning - */ - if (table_type != DB_TYPE_PARTITION_DB && - thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION) - { - my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0)); - DBUG_RETURN(TRUE); - } -#endif - if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, - table_type), - HTON_CAN_RECREATE) || - thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION) - goto trunc_by_del; - - - if (thd->locked_tables_mode) - { - if (!(table= find_table_for_mdl_upgrade(thd->open_tables, table_list->db, - table_list->table_name, FALSE))) - DBUG_RETURN(TRUE); - mdl_ticket= table->mdl_ticket; - if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) - goto end; - close_all_tables_for_name(thd, table->s, FALSE); - } - else - { - MDL_request mdl_global_request, mdl_request; - MDL_request_list mdl_requests; - /* - Even though we could use the previous execution branch - here just as well, we must not try to open the table: - MySQL manual documents that TRUNCATE can be used to - repair a damaged table, i.e. a table that can not be - fully "opened". In particular MySQL manual says: - - As long as the table format file tbl_name.frm is valid, - the table can be re-created as an empty table with TRUNCATE - TABLE, even if the data or index files have become corrupted. - */ - - mdl_global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); - mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, - MDL_EXCLUSIVE); - mdl_requests.push_front(&mdl_request); - mdl_requests.push_front(&mdl_global_request); - - if (thd->mdl_context.acquire_locks(&mdl_requests, - thd->variables.lock_wait_timeout)) - DBUG_RETURN(TRUE); - - has_mdl_lock= TRUE; - mysql_mutex_lock(&LOCK_open); - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, - table_list->table_name); - mysql_mutex_unlock(&LOCK_open); - } - } - - /* - Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this - crashes, replacement works. *(path + path_length - reg_ext_length)= - '\0'; - */ - path[path_length - reg_ext_length] = 0; - mysql_mutex_lock(&LOCK_open); - error= ha_create_table(thd, path, table_list->db, table_list->table_name, - &create_info, 1); - mysql_mutex_unlock(&LOCK_open); - query_cache_invalidate3(thd, table_list, 0); - -end: - if (!dont_send_ok) - { - if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd)) - thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); - /* - Even if we failed to reopen some tables, - the operation itself succeeded, write the binlog. - */ - if (!error) - { - /* In RBR, the statement is not binlogged if the table is temporary. */ - if (!is_temporary_table || !thd->is_current_stmt_binlog_format_row()) - error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - if (!error) - my_ok(thd); // This should return record count - } - if (has_mdl_lock) - thd->mdl_context.release_transactional_locks(); - if (mdl_ticket) - mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); - } - - DBUG_PRINT("exit", ("error: %d", error)); - DBUG_RETURN(error); - -trunc_by_del: - error= mysql_truncate_by_delete(thd, table_list); - DBUG_RETURN(error); -} diff --git a/sql/sql_delete.h b/sql/sql_delete.h index d1c1b363abd..c718323ce1e 100644 --- a/sql/sql_delete.h +++ b/sql/sql_delete.h @@ -27,8 +27,6 @@ typedef struct st_sql_list SQL_LIST; int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - SQL_LIST *order, ha_rows rows, ulonglong options, - bool reset_auto_increment); -bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); + SQL_LIST *order, ha_rows rows, ulonglong options); #endif /* SQL_DELETE_INCLUDED */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4c3f44ea75c..adab0b8e3d0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -49,6 +49,7 @@ // mysql_recreate_table, // mysql_backup_table, // mysql_restore_table +#include "sql_truncate.h" // mysql_truncate_table #include "sql_connect.h" // check_user, // decrease_user_connections, // thd_init_client_charset, check_mqh, @@ -253,7 +254,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | - CF_AUTO_COMMIT_TRANS; + CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL; sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL; @@ -3280,9 +3281,8 @@ end_with_restore_list: ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - goto error; - res= mysql_truncate(thd, first_table, 0); + if (! (res= mysql_truncate_table(thd, first_table))) + my_ok(thd); break; case SQLCOM_DELETE: { @@ -3295,8 +3295,7 @@ end_with_restore_list: MYSQL_DELETE_START(thd->query()); res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, - unit->select_limit_cnt, select_lex->options, - FALSE); + unit->select_limit_cnt, select_lex->options); MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func()); break; } diff --git a/sql/sql_parse.h b/sql/sql_parse.h index e1543a09549..ca804d5fab0 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -129,11 +129,6 @@ bool check_simple_select(); Item *negate_expression(THD *thd, Item *expr); bool check_stack_overrun(THD *thd, long margin, uchar *dummy); -bool begin_trans(THD *thd); -bool end_active_trans(THD *thd); -int end_trans(THD *thd, enum enum_mysql_completiontype completion); - - /* Variables */ extern const char* any_db; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index ea95b59b0c2..130a99a374f 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -29,6 +29,7 @@ // start_waiting_global_read_lock #include "sql_base.h" // tdc_remove_table #include "sql_handler.h" // mysql_ha_rm_tables +#include "datadict.h" static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); @@ -283,7 +284,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, build_table_filename(name, sizeof(name) - 1, ren_table->db, old_alias, reg_ext, 0); - frm_type= mysql_frm_type(thd, name, &table_type); + frm_type= dd_frm_type(thd, name, &table_type); switch (frm_type) { case FRMTYPE_TABLE: diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a33bc5943da..7fe84ce0dd4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -27,7 +27,6 @@ // primary_key_name, // build_table_filename #include "repl_failsafe.h" -#include "sql_view.h" // mysql_frm_type #include "sql_parse.h" // check_access, check_table_access #include "sql_partition.h" // partition_element #include "sql_db.h" // check_db_dir_existence, load_db_opt_by_name @@ -50,6 +49,8 @@ #endif #include #include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH +#include "debug_sync.h" +#include "datadict.h" // dd_frm_type() #define STR_OR_NIL(S) ((S) ? (S) : "") @@ -2959,6 +2960,9 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables, (can_deadlock ? MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0))); lex->sql_command= save_sql_command; + + DEBUG_SYNC(thd, "after_open_table_ignore_flush"); + /* get_all_tables() returns 1 on failure and 0 on success thus return only these and not the result code of ::process_table() @@ -3018,7 +3022,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table, char path[FN_REFLEN + 1]; (void) build_table_filename(path, sizeof(path) - 1, db_name->str, table_name->str, reg_ext, 0); - switch (mysql_frm_type(thd, path, ¬_used)) { + switch (dd_frm_type(thd, path, ¬_used)) { case FRMTYPE_ERROR: table->field[3]->store(STRING_WITH_LEN("ERROR"), system_charset_info); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b2a950ca4b0..bad88476c09 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -27,8 +27,8 @@ // start_waiting_global_read_lock, // unlock_table_names, mysql_unlock_tables #include "strfunc.h" // find_type2, find_set -#include "sql_view.h" // mysql_frm_type, view_checksum, mysql_frm_type -#include "sql_delete.h" // mysql_truncate +#include "sql_view.h" // view_checksum +#include "sql_truncate.h" // regenerate_locked_table #include "sql_partition.h" // mem_alloc_error, // generate_partition_syntax, // partition_info @@ -52,6 +52,7 @@ #include "sql_show.h" #include "transaction.h" #include "keycaches.h" +#include "datadict.h" // dd_frm_type() #ifdef __WIN__ #include @@ -2096,7 +2097,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ((access(path, F_OK) && ha_create_table_from_engine(thd, db, alias)) || (!drop_view && - mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) + dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) { // Table was not found on disk and table can't be created from engine if (if_exists) @@ -2116,7 +2117,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, */ if (frm_db_type == DB_TYPE_UNKNOWN) { - mysql_frm_type(thd, path, &frm_db_type); + dd_frm_type(thd, path, &frm_db_type); DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path)); } table_type= ha_resolve_by_legacy_type(thd, frm_db_type); @@ -4557,12 +4558,18 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, "Failed renaming data file"); goto end; } - if (mysql_truncate(thd, table_list, 1)) + if (dd_recreate_table(thd, table_list->db, table_list->table_name)) { error= send_check_errmsg(thd, table_list, "repair", "Failed generating table from .frm file"); goto end; } + /* + 'FALSE' for 'using_transactions' means don't postpone + invalidation till the end of a transaction, but do it + immediately. + */ + query_cache_invalidate3(thd, table_list, FALSE); if (mysql_file_rename(key_file_misc, tmp, from, MYF(MY_WME))) { error= send_check_errmsg(thd, table_list, "repair", @@ -6544,7 +6551,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, into the main table list, like open_tables does). This code is wrong and will be removed, please do not copy. */ - frm_type= mysql_frm_type(thd, new_name_buff, &table_type); + frm_type= dd_frm_type(thd, new_name_buff, &table_type); /* Rename a view */ /* Sic: there is a race here */ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc new file mode 100644 index 00000000000..47a98769d57 --- /dev/null +++ b/sql/sql_truncate.cc @@ -0,0 +1,464 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "sql_truncate.h" +#include "sql_priv.h" +#include "transaction.h" +#include "debug_sync.h" +#include "records.h" // READ_RECORD +#include "table.h" // TABLE +#include "sql_class.h" // THD +#include "sql_base.h" // open_and_lock_tables +#include "sql_table.h" // write_bin_log +#include "sql_handler.h" // mysql_ha_rm_tables +#include "datadict.h" // dd_recreate_table() +#include "lock.h" // MYSQL_OPEN_TEMPORARY_ONLY + + +/* + Delete all rows of a locked table. + + @param thd Thread context. + @param table_list Table list element for the table. + @param rows_deleted Whether rows might have been deleted. + + @retval FALSE Success. + @retval TRUE Error. +*/ + +static bool +delete_all_rows(THD *thd, TABLE *table) +{ + int error; + READ_RECORD info; + bool is_bulk_delete; + bool some_rows_deleted= FALSE; + bool save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + DBUG_ENTER("delete_all_rows"); + + /* Replication of truncate table must be statement based. */ + thd->clear_current_stmt_binlog_format_row(); + + /* + Attempt to delete all rows in the table. + If it is unsupported, switch to row by row deletion. + */ + if (! (error= table->file->ha_delete_all_rows())) + goto end; + + if (error != HA_ERR_WRONG_COMMAND) + { + /* + If a transactional engine fails in the middle of deletion, + we expect it to be able to roll it back. Some reasons + for the engine to fail would be media failure or corrupted + data dictionary (i.e. in case of a partitioned table). We + have sufficiently strong metadata locks to rule out any + potential deadlocks. + + If a non-transactional engine fails here (that would + not be MyISAM, since MyISAM does TRUNCATE by recreate), + and binlog is on, replication breaks, since nothing gets + written to the binary log. (XXX: is this a bug?) + */ + table->file->print_error(error, MYF(0)); + goto end; + } + + /* + A workaround for Bug#53696 "Performance schema engine violates the + PSEA API by calling my_error()". + */ + if (thd->is_error()) + goto end; + + /* Handler didn't support fast delete. Delete rows one by one. */ + + init_read_record(&info, thd, table, NULL, TRUE, TRUE, FALSE); + + /* + Start bulk delete. If the engine does not support it, go on, + it's not an error. + */ + is_bulk_delete= ! table->file->start_bulk_delete(); + + table->mark_columns_needed_for_delete(); + + while (!(error= info.read_record(&info)) && !thd->killed) + { + if ((error= table->file->ha_delete_row(table->record[0]))) + { + table->file->print_error(error, MYF(0)); + break; + } + + some_rows_deleted= TRUE; + } + + /* HA_ERR_END_OF_FILE */ + if (error == -1) + error= 0; + + /* Close down the bulk delete. */ + if (is_bulk_delete) + { + int bulk_delete_error= table->file->end_bulk_delete(); + if (bulk_delete_error && !error) + { + table->file->print_error(bulk_delete_error, MYF(0)); + error= bulk_delete_error; + } + } + + end_read_record(&info); + + /* + Regardless of the error status, the query must be written to the + binary log if rows of the table is non-transactional. + */ + if (some_rows_deleted && !table->file->has_transactions()) + { + thd->transaction.stmt.modified_non_trans_table= TRUE; + thd->transaction.all.modified_non_trans_table= TRUE; + } + + if (error || thd->killed) + goto end; + + /* Truncate resets the auto-increment counter. */ + error= table->file->ha_reset_auto_increment(0); + if (error) + { + if (error != HA_ERR_WRONG_COMMAND) + table->file->print_error(error, MYF(0)); + else + error= 0; + } + +end: + if (save_binlog_row_based) + thd->set_current_stmt_binlog_format_row(); + + DBUG_RETURN(error); +} + + +/* + Close and recreate a temporary table. In case of success, + write truncate statement into the binary log if in statement + mode. + + @param thd Thread context. + @param table The temporary table. + + @retval FALSE Success. + @retval TRUE Error. +*/ + +static bool recreate_temporary_table(THD *thd, TABLE *table) +{ + bool error= TRUE; + TABLE_SHARE *share= table->s; + HA_CREATE_INFO create_info; + handlerton *table_type= table->s->db_type(); + DBUG_ENTER("recreate_temporary_table"); + + memset(&create_info, 0, sizeof(create_info)); + + table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); + + /* Don't free share. */ + close_temporary_table(thd, table, FALSE, FALSE); + + /* + We must use share->normalized_path.str since for temporary tables it + differs from what dd_recreate_table() would generate based + on table and schema names. + */ + ha_create_table(thd, share->normalized_path.str, share->db.str, + share->table_name.str, &create_info, 1); + + if (open_temporary_table(thd, share->path.str, share->db.str, + share->table_name.str, 1)) + { + error= FALSE; + thd->thread_specific_used= TRUE; + } + else + rm_temporary_table(table_type, share->path.str); + + free_table_share(share); + my_free(table, MYF(0)); + + DBUG_RETURN(error); +} + + +/* + Handle opening and locking if a base table for truncate. + + @param[in] thd Thread context. + @param[in] table_ref Table list element for the table to + be truncated. + @param[out] hton_can_recreate Set to TRUE if table can be dropped + and recreated. + @param[out] ticket_downgrade Set if a lock must be downgraded after + truncate is done. + + @retval FALSE Success. + @retval TRUE Error. +*/ + +static bool open_and_lock_table_for_truncate(THD *thd, TABLE_LIST *table_ref, + bool *hton_can_recreate, + MDL_ticket **ticket_downgrade) +{ + TABLE *table= NULL; + MDL_ticket *mdl_ticket= NULL; + DBUG_ENTER("open_and_lock_table_for_truncate"); + + /* + Before doing anything else, acquire a metadata lock on the table, + or ensure we have one. We don't use open_and_lock_tables() + right away because we want to be able to truncate (and recreate) + corrupted tables, those that we can't fully open. + + MySQL manual documents that TRUNCATE can be used to repair a + damaged table, i.e. a table that can not be fully "opened". + In particular MySQL manual says: As long as the table format + file tbl_name.frm is valid, the table can be re-created as + an empty table with TRUNCATE TABLE, even if the data or index + files have become corrupted. + */ + if (thd->locked_tables_mode) + { + if (!(table= find_table_for_mdl_upgrade(thd->open_tables, table_ref->db, + table_ref->table_name, FALSE))) + DBUG_RETURN(TRUE); + + *hton_can_recreate= ha_check_storage_engine_flag(table->s->db_type(), + HTON_CAN_RECREATE); + } + else + { + /* + Even though we could use the previous execution branch here just as + well, we must not try to open the table: + */ + MDL_request mdl_global_request, mdl_request; + MDL_request_list mdl_requests; + + mdl_global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE); + mdl_request.init(MDL_key::TABLE, table_ref->db, table_ref->table_name, + MDL_SHARED_NO_READ_WRITE); + mdl_requests.push_front(&mdl_request); + mdl_requests.push_front(&mdl_global_request); + + if (thd->mdl_context.acquire_locks(&mdl_requests, + thd->variables.lock_wait_timeout)) + DBUG_RETURN(TRUE); + + mdl_ticket= mdl_request.ticket; + + if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name, + HTON_CAN_RECREATE, hton_can_recreate)) + DBUG_RETURN(TRUE); + } + + DEBUG_SYNC(thd, "lock_table_for_truncate"); + + if (*hton_can_recreate) + { + /* + Acquire an exclusive lock. The storage engine can recreate the + table only if there are no references to it from anywhere, i.e. + no cached TABLE in the table cache. To remove the table from the + cache we need an exclusive lock. + */ + if (thd->locked_tables_mode) + { + if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) + DBUG_RETURN(TRUE); + *ticket_downgrade= table->mdl_ticket; + close_all_tables_for_name(thd, table->s, FALSE); + } + else + { + ulong timeout= thd->variables.lock_wait_timeout; + if (thd->mdl_context.upgrade_shared_lock_to_exclusive(mdl_ticket, timeout)) + DBUG_RETURN(TRUE); + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_ref->db, + table_ref->table_name); + mysql_mutex_unlock(&LOCK_open); + } + } + else + { + /* + Can't recreate, we must mechanically delete all rows in + the table. Our metadata lock guarantees that no transaction + is reading or writing into the table. Yet, to open a write + cursor we need a thr_lock lock. Use open_and_lock_tables() + to do the necessary job. + */ + + /* Allow to open base tables only. */ + table_ref->required_type= FRMTYPE_TABLE; + /* We don't need to load triggers. */ + DBUG_ASSERT(table_ref->trg_event_map == 0); + /* Work around partition parser rules using alter table's. */ + if (thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION) + { + table_ref->lock_type= TL_WRITE; + table_ref->mdl_request.set_type(MDL_SHARED_WRITE); + } + /* Ensure proper lock types (e.g. from the parser). */ + DBUG_ASSERT(table_ref->lock_type == TL_WRITE); + DBUG_ASSERT(table_ref->mdl_request.type == MDL_SHARED_WRITE); + + /* + Open the table as it will handle some required preparations. + Ignore pending FLUSH TABLES since we don't want to release + the MDL lock taken above and otherwise there is no way to + wait for FLUSH TABLES in deadlock-free fashion. + */ + if (open_and_lock_tables(thd, table_ref, TL_WRITE, + MYSQL_OPEN_IGNORE_FLUSH | + MYSQL_OPEN_SKIP_TEMPORARY)) + DBUG_RETURN(TRUE); + } + + DBUG_RETURN(FALSE); +} + + +/* + Optimized delete of all rows by doing a full generate of the table. + + @remark Will work even if the .MYI and .MYD files are destroyed. + In other words, it works as long as the .FRM is intact and + the engine supports re-create. + + @param thd Thread context. + @param table_ref Table list element for the table to be truncated. + + @retval FALSE Success. + @retval TRUE Error. +*/ + +bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) +{ + TABLE *table; + bool error= TRUE, binlog_stmt; + MDL_ticket *mdl_ticket= NULL; + DBUG_ENTER("mysql_truncate_table"); + + /* Remove tables from the HANDLER's hash. */ + mysql_ha_rm_tables(thd, table_ref); + + /* If it is a temporary table, no need to take locks. */ + if ((table= find_temporary_table(thd, table_ref))) + { + /* In RBR, the statement is not binlogged if the table is temporary. */ + binlog_stmt= !thd->is_current_stmt_binlog_format_row(); + + /* Note that a temporary table cannot be partitioned. */ + if (ha_check_storage_engine_flag(table->s->db_type(), HTON_CAN_RECREATE)) + { + if ((error= recreate_temporary_table(thd, table))) + binlog_stmt= FALSE; /* No need to binlog failed truncate-by-recreate. */ + + DBUG_ASSERT(! thd->transaction.stmt.modified_non_trans_table); + } + else + { + /* + The engine does not support truncate-by-recreate. Open the + table and delete all rows. In such a manner this can in fact + open several tables if it's a temporary MyISAMMRG table. + */ + if (open_and_lock_tables(thd, table_ref, TL_WRITE, + MYSQL_OPEN_TEMPORARY_ONLY)) + DBUG_RETURN(TRUE); + + error= delete_all_rows(thd, table_ref->table); + } + + /* + No need to invalidate the query cache, queries with temporary + tables are not in the cache. No need to write to the binary + log a failed row-by-row delete even if under RBR as the table + might not exist on the slave. + */ + } + else /* It's not a temporary table. */ + { + bool hton_can_recreate; + + if (open_and_lock_table_for_truncate(thd, table_ref, + &hton_can_recreate, &mdl_ticket)) + DBUG_RETURN(TRUE); + + if (hton_can_recreate) + { + /* + The storage engine can truncate the table by creating an + empty table with the same structure. + */ + error= dd_recreate_table(thd, table_ref->db, table_ref->table_name); + + if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd)) + thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + + /* No need to binlog a failed truncate-by-recreate. */ + binlog_stmt= !error; + } + else + { + error= delete_all_rows(thd, table_ref->table); + + /* + Regardless of the error status, the query must be written to the + binary log if rows of a non-transactional table were deleted. + */ + binlog_stmt= !error || thd->transaction.stmt.modified_non_trans_table; + } + + query_cache_invalidate3(thd, table_ref, FALSE); + } + + /* DDL is logged in statement format, regardless of binlog format. */ + if (binlog_stmt) + error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); + + /* + All effects of a TRUNCATE TABLE operation are rolled back if a row + by row deletion fails. Otherwise, it is automatically committed at + the end. + */ + if (error) + { + trans_rollback_stmt(thd); + trans_rollback(thd); + } + + if (mdl_ticket) + mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); + + DBUG_PRINT("exit", ("error: %d", error)); + DBUG_RETURN(test(error)); +} + diff --git a/sql/sql_truncate.h b/sql/sql_truncate.h new file mode 100644 index 00000000000..a9eec384718 --- /dev/null +++ b/sql/sql_truncate.h @@ -0,0 +1,23 @@ +#ifndef SQL_TRUNCATE_INCLUDED +#define SQL_TRUNCATE_INCLUDED +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +class THD; +class TABLE_LIST; + +bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref); + +#endif diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4eee9502177..3c8de0a253c 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -32,6 +32,7 @@ #include "sp.h" #include "sp_head.h" #include "sp_cache.h" +#include "datadict.h" // dd_frm_type() #define MD5_BUFF_LENGTH 33 @@ -1663,7 +1664,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) view->db, view->table_name, reg_ext, 0); if (access(path, F_OK) || - FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used))) + FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used))) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); @@ -1741,54 +1742,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) } -/* - Check type of .frm if we are not going to parse it - - SYNOPSIS - mysql_frm_type() - path path to file - - RETURN - FRMTYPE_ERROR error - FRMTYPE_TABLE table - FRMTYPE_VIEW view -*/ - -frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) -{ - File file; - uchar header[10]; //"TYPE=VIEW\n" it is 10 characters - size_t error; - DBUG_ENTER("mysql_frm_type"); - - *dbt= DB_TYPE_UNKNOWN; - - if ((file= mysql_file_open(key_file_frm, - path, O_RDONLY | O_SHARE, MYF(0))) < 0) - DBUG_RETURN(FRMTYPE_ERROR); - error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)); - mysql_file_close(file, MYF(MY_WME)); - - if (error) - DBUG_RETURN(FRMTYPE_ERROR); - if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header))) - DBUG_RETURN(FRMTYPE_VIEW); - - /* - This is just a check for DB_TYPE. We'll return default unknown type - if the following test is true (arg #3). This should not have effect - on return value from this function (default FRMTYPE_TABLE) - */ - if (header[0] != (uchar) 254 || header[1] != 1 || - (header[2] != FRM_VER && header[2] != FRM_VER+1 && - (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) - DBUG_RETURN(FRMTYPE_TABLE); - - *dbt= (enum legacy_db_type) (uint) *(header + 3); - DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table -} - - /* check of key (primary or unique) presence in updatable view diff --git a/sql/sql_view.h b/sql/sql_view.h index 7d06abb9068..c15ecffccb8 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -43,8 +43,6 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view); bool insert_view_fields(THD *thd, List *list, TABLE_LIST *view); -frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt); - int view_checksum(THD *thd, TABLE_LIST *view); extern TYPELIB updatable_views_with_limit_typelib; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e5875663d4e..fdc8af942d1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10685,7 +10685,7 @@ opt_delete_option: ; truncate: - TRUNCATE_SYM opt_table_sym table_name + TRUNCATE_SYM opt_table_sym { LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; @@ -10693,7 +10693,11 @@ truncate: lex->select_lex.options= 0; lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; lex->select_lex.init_order(); + YYPS->m_lock_type= TL_WRITE; + YYPS->m_mdl_type= MDL_SHARED_WRITE; } + table_name + {} ; opt_table_sym: diff --git a/sql/table.h b/sql/table.h index ea585208b83..cb773052c8b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -20,6 +20,7 @@ #include "sql_plist.h" #include "sql_list.h" /* Sql_alloc */ #include "mdl.h" +#include "datadict.h" #ifndef MYSQL_CLIENT @@ -305,14 +306,6 @@ enum tmp_table_type NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE, INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE }; - -enum frm_type_enum -{ - FRMTYPE_ERROR= 0, - FRMTYPE_TABLE, - FRMTYPE_VIEW -}; - enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP }; typedef struct st_filesort_info From c070e5a1ede5c34dda7fdefe93d7c19be53ceb00 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 26 May 2010 16:18:08 +0400 Subject: [PATCH 131/207] Fix for bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". ALTER TABLE on InnoDB table (including partitioned tables) acquired exclusive locks on rows of table being altered. In cases when there was concurrent transaction which did locking reads from this table this sometimes led to a deadlock which was not detected by MDL subsystem nor by InnoDB engine (and was reported only after exceeding innodb_lock_wait_timeout). This problem stemmed from the fact that ALTER TABLE acquired TL_WRITE_ALLOW_READ lock on table being altered. This lock was interpreted as a write lock and thus for table being altered handler::external_lock() method was called with F_WRLCK as an argument. As result InnoDB engine treated ALTER TABLE as an operation which is going to change data and acquired LOCK_X locks on rows being read from old version of table. In case when there was a transaction which already acquired SR metadata lock on table and some LOCK_S locks on its rows (e.g. by using it in subquery of DML statement) concurrent ALTER TABLE was blocked at the moment when it tried to acquire LOCK_X lock before reading one of these rows. The transaction's attempt to acquire SW metadata lock on table being altered led to deadlock, since it had to wait for ALTER TABLE to release SNW lock. This deadlock was not detected and got resolved only after timeout expiring because waiting were happening in two different subsystems. Similar deadlocks could have occured in other situations. This patch tries to solve the problem by changing ALTER TABLE implementation to use TL_READ_NO_INSERT lock instead of TL_WRITE_ALLOW_READ. After this step handler::external_lock() is called with F_RDLCK as an argument and InnoDB engine correctly interprets ALTER TABLE as operation which only reads data from original version of table. Thanks to this ALTER TABLE acquires only LOCK_S locks on rows it reads. This, in its turn, causes inter-subsystem deadlocks to go away, as all potential lock conflicts and thus deadlocks will be limited to metadata locking subsystem: - When ALTER TABLE reads rows from table being altered it can't encounter any locks which conflict with LOCK_S row locks. There should be no concurrent transactions holding LOCK_X row locks. Such a transaction should have been acquired SW metadata lock on table first which would have conflicted with ALTER's SNW lock. - Vice versa, when DML which runs concurrently with ALTER TABLE tries to lock row it should be requesting only LOCK_S lock which is compatible with locks acquired by ALTER, as otherwise such DML must own an SW metadata lock on table which would be incompatible with ALTER's SNW lock. --- mysql-test/r/innodb_mysql_lock2.result | 65 +++++++++++ .../r/rpl_ndb_binlog_format_errors.result | 4 +- .../t/rpl_ndb_binlog_format_errors.test | 4 +- mysql-test/t/innodb_mysql_lock2.test | 103 ++++++++++++++++++ sql/ha_partition.cc | 2 +- sql/lock.cc | 4 +- sql/mdl.cc | 5 +- sql/sql_base.cc | 4 +- sql/sql_table.cc | 4 +- sql/sql_trigger.cc | 2 +- sql/sql_yacc.yy | 8 +- 11 files changed, 186 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/innodb_mysql_lock2.result b/mysql-test/r/innodb_mysql_lock2.result index aed704e6b3e..70cfbee6463 100644 --- a/mysql-test/r/innodb_mysql_lock2.result +++ b/mysql-test/r/innodb_mysql_lock2.result @@ -562,3 +562,68 @@ drop view v1, v2; drop procedure p1; drop procedure p2; drop table t1, t2, t3, t4, t5; +# +# Test for bug#51263 "Deadlock between transactional SELECT +# and ALTER TABLE ... REBUILD PARTITION". +# +drop table if exists t1, t2; +create table t1 (i int auto_increment not null primary key) engine=innodb; +create table t2 (i int) engine=innodb; +insert into t1 values (1), (2), (3), (4), (5); +begin; +# Acquire SR metadata lock on t1 and LOCK_S row-locks on its rows. +insert into t2 select count(*) from t1; +# Switching to connection 'con1'. +# Sending: +alter table t1 add column j int; +# Switching to connection 'default'. +# Wait until ALTER is blocked because it tries to upgrade SNW +# metadata lock to X lock. +# It should not be blocked during copying data to new version of +# table as it acquires LOCK_S locks on rows of old version, which +# are compatible with locks acquired by connection 'con1'. +# The below statement will deadlock because it will try to acquire +# SW lock on t1, which will conflict with ALTER's SNW lock. And +# ALTER will be waiting for this connection to release its SR lock. +# This deadlock should be detected by an MDL subsystem and this +# statement should be aborted with an appropriate error. +insert into t1 values (6); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +# Unblock ALTER TABLE. +commit; +# Switching to connection 'con1'. +# Reaping ALTER TABLE. +# Switching to connection 'default'. +# +# Now test for scenario in which bug was reported originally. +# +drop tables t1, t2; +create table t1 (i int auto_increment not null primary key) engine=innodb +partition by hash (i) partitions 4; +create table t2 (i int) engine=innodb; +insert into t1 values (1), (2), (3), (4), (5); +begin; +# Acquire SR metadata lock on t1. +select * from t1; +i +1 +2 +3 +4 +5 +# Switching to connection 'con1'. +# Sending: +alter table t1 rebuild partition p0; +# Switching to connection 'default'. +# Wait until ALTER is blocked because of active SR lock. +# The below statement should succeed as transaction +# has SR metadata lock on t1 and only going to read +# rows from it. +insert into t2 select count(*) from t1; +# Unblock ALTER TABLE. +commit; +# Switching to connection 'con1'. +# Reaping ALTER TABLE. +# Switching to connection 'default'. +# Clean-up. +drop tables t1, t2; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result index 36b8e022dd2..ab126026fe4 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result @@ -43,9 +43,9 @@ SELECT * FROM t /* Should be empty */; a * Modify both row-only and stmt-only table CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END; -ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging. INSERT INTO t_stmt VALUES (1); -ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging. +ERROR HY000: Cannot execute statement: impossible to write to binary log since both row-incapable engines and statement-incapable engines are involved. +DROP trigger trig_2; SELECT * FROM t_stmt /* should be empty */; a * Stmt-only table and binlog_format=row diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test index 481db5f6564..f6331cd0808 100644 --- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test @@ -97,10 +97,10 @@ SELECT * FROM t_self_logging /* Should be empty */; SELECT * FROM t /* Should be empty */; --echo * Modify both row-only and stmt-only table ---error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE --eval CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END ---error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE +--error ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE INSERT INTO t_stmt VALUES (1); +DROP trigger trig_2; SELECT * FROM t_stmt /* should be empty */; --echo * Stmt-only table and binlog_format=row diff --git a/mysql-test/t/innodb_mysql_lock2.test b/mysql-test/t/innodb_mysql_lock2.test index 5111d56225a..1f01f4cb010 100644 --- a/mysql-test/t/innodb_mysql_lock2.test +++ b/mysql-test/t/innodb_mysql_lock2.test @@ -3,7 +3,12 @@ # This test requires statement/mixed mode binary logging. # Row-based mode puts weaker serializability requirements # so weaker locks are acquired for it. +# Also in ROW mode LOCK_S row locks won't be acquired for DML +# and test for bug#51263 won't trigger execution path on which +# this bug was encountered. --source include/have_binlog_format_mixed_or_statement.inc +# Original test case for bug#51263 needs partitioning. +--source include/have_partition.inc # Save the initial number of concurrent sessions. --source include/count_sessions.inc @@ -760,6 +765,104 @@ drop procedure p2; drop table t1, t2, t3, t4, t5; disconnect con1; + +--echo # +--echo # Test for bug#51263 "Deadlock between transactional SELECT +--echo # and ALTER TABLE ... REBUILD PARTITION". +--echo # +connect (con1,localhost,root,,test,,); +connection default; +--disable_warnings +drop table if exists t1, t2; +--enable_warnings +create table t1 (i int auto_increment not null primary key) engine=innodb; +create table t2 (i int) engine=innodb; +insert into t1 values (1), (2), (3), (4), (5); + +begin; +--echo # Acquire SR metadata lock on t1 and LOCK_S row-locks on its rows. +insert into t2 select count(*) from t1; + +--echo # Switching to connection 'con1'. +connection con1; +--echo # Sending: +--send alter table t1 add column j int + +--echo # Switching to connection 'default'. +connection default; +--echo # Wait until ALTER is blocked because it tries to upgrade SNW +--echo # metadata lock to X lock. +--echo # It should not be blocked during copying data to new version of +--echo # table as it acquires LOCK_S locks on rows of old version, which +--echo # are compatible with locks acquired by connection 'con1'. +let $wait_condition= + select count(*) = 1 from information_schema.processlist where state = + "Waiting for table" and info = "alter table t1 add column j int"; +--source include/wait_condition.inc + +--echo # The below statement will deadlock because it will try to acquire +--echo # SW lock on t1, which will conflict with ALTER's SNW lock. And +--echo # ALTER will be waiting for this connection to release its SR lock. +--echo # This deadlock should be detected by an MDL subsystem and this +--echo # statement should be aborted with an appropriate error. +--error ER_LOCK_DEADLOCK +insert into t1 values (6); +--echo # Unblock ALTER TABLE. +commit; + +--echo # Switching to connection 'con1'. +connection con1; +--echo # Reaping ALTER TABLE. +--reap + +--echo # Switching to connection 'default'. +connection default; + +--echo # +--echo # Now test for scenario in which bug was reported originally. +--echo # +drop tables t1, t2; +create table t1 (i int auto_increment not null primary key) engine=innodb + partition by hash (i) partitions 4; +create table t2 (i int) engine=innodb; +insert into t1 values (1), (2), (3), (4), (5); + +begin; +--echo # Acquire SR metadata lock on t1. +select * from t1; + +--echo # Switching to connection 'con1'. +connection con1; +--echo # Sending: +--send alter table t1 rebuild partition p0 + +--echo # Switching to connection 'default'. +connection default; +--echo # Wait until ALTER is blocked because of active SR lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table" and info = "alter table t1 rebuild partition p0"; +--source include/wait_condition.inc + +--echo # The below statement should succeed as transaction +--echo # has SR metadata lock on t1 and only going to read +--echo # rows from it. +insert into t2 select count(*) from t1; +--echo # Unblock ALTER TABLE. +commit; + +--echo # Switching to connection 'con1'. +connection con1; +--echo # Reaping ALTER TABLE. +--reap + +--echo # Switching to connection 'default'. +connection default; +disconnect con1; +--echo # Clean-up. +drop tables t1, t2; + + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index b8831127e3f..cd12e5de4d6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1302,7 +1302,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl, assumes that external_lock() is last call that may fail here. Otherwise see description for cleanup_new_partition(). */ - if ((error= file->ha_external_lock(ha_thd(), m_lock_type))) + if ((error= file->ha_external_lock(ha_thd(), F_WRLCK))) goto error_external_lock; DBUG_PRINT("info", ("partition %s external locked", part_name)); diff --git a/sql/lock.cc b/sql/lock.cc index 8e91bd9360e..fbe15fde3b0 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -415,7 +415,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) THR_LOCK_DATA **lock=sql_lock->locks; for (i=found=0 ; i < sql_lock->lock_count ; i++) { - if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ) + if (sql_lock->locks[i]->type > TL_WRITE_ALLOW_WRITE) { swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]); lock++; @@ -435,7 +435,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) for (i=found=0 ; i < sql_lock->table_count ; i++) { DBUG_ASSERT(sql_lock->table[i]->lock_position == i); - if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ) + if ((uint) sql_lock->table[i]->reginfo.lock_type > TL_WRITE_ALLOW_WRITE) { swap_variables(TABLE *, *table, sql_lock->table[i]); table++; diff --git a/sql/mdl.cc b/sql/mdl.cc index ddf518fbb1c..ba938f8714b 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1689,9 +1689,8 @@ err: shared mode). @note There can be only one upgrader for a lock or we will have deadlock. - This invariant is ensured by code outside of metadata subsystem usually - by obtaining some sort of exclusive table-level lock (e.g. TL_WRITE, - TL_WRITE_ALLOW_READ) before performing upgrade of metadata lock. + This invariant is ensured by the fact that upgradeable locks SNW + and SNRW are not compatible with each other and themselves. @retval FALSE Success @retval TRUE Failure (thread was killed) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fa484abf0be..4203a556e65 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5081,8 +5081,8 @@ static bool check_lock_and_start_stmt(THD *thd, else lock_type= table_list->lock_type; - if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && - (int) table_list->table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) + if ((int) lock_type > (int) TL_WRITE_ALLOW_WRITE && + (int) table_list->table->reginfo.lock_type <= (int) TL_WRITE_ALLOW_WRITE) { my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias); DBUG_RETURN(1); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bad88476c09..c27ebce744f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4669,7 +4669,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, To allow concurrent execution of read-only operations we acquire weak metadata lock for them. */ - table->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_READ) ? + table->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ? MDL_SHARED_NO_READ_WRITE : MDL_SHARED_READ); /* open only one table from local list of command */ { @@ -7926,7 +7926,7 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list) /* Same applies to MDL ticket. */ table_list->mdl_request.ticket= NULL; /* Set lock type which is appropriate for ALTER TABLE. */ - table_list->lock_type= TL_WRITE_ALLOW_READ; + table_list->lock_type= TL_READ_NO_INSERT; /* Same applies to MDL request. */ table_list->mdl_request.set_type(MDL_SHARED_NO_WRITE); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index ae09898ada2..e9330574b34 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -489,7 +489,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) else { tables->table= open_n_lock_single_table(thd, tables, - TL_WRITE_ALLOW_READ, 0); + TL_READ_NO_INSERT, 0); if (! tables->table) goto end; tables->table->use_all_columns(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fdc8af942d1..879f65c0fa4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -697,7 +697,7 @@ static bool add_create_index_prepare (LEX *lex, Table_ident *table) lex->sql_command= SQLCOM_CREATE_INDEX; if (!lex->current_select->add_table_to_list(lex->thd, table, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ, + TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) return TRUE; lex->alter_info.reset(); @@ -6157,7 +6157,7 @@ alter: lex->duplicates= DUP_ERROR; if (!lex->select_lex.add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ, + TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; lex->col_list.empty(); @@ -10168,7 +10168,7 @@ drop: lex->alter_info.drop_list.push_back(ad); if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ, + TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } @@ -14094,7 +14094,7 @@ trigger_tail: if (!lex->select_lex.add_table_to_list(YYTHD, $9, (LEX_STRING*) 0, TL_OPTION_UPDATING, - TL_WRITE_ALLOW_READ, + TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } From 303fe45abf087f2ff68bb9db81af26151ed4ae7b Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 26 May 2010 23:58:16 +0400 Subject: [PATCH 132/207] Fix for bug #53238 "mdl_sync fails sporadically". The problem was that mdl_sync.test was failing sporadically, due to fact that part of the test didn't take into account effects of MyISAM's concurrent insert. This patch solves the problem by making test case robust against concurrent insert. --- mysql-test/r/mdl_sync.result | 6 +++--- mysql-test/t/mdl_sync.test | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index 8e004ba23f7..0eb8ad4dcf8 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -330,9 +330,9 @@ select column_name from information_schema.columns where table_schema='test' and table_name='t1'; column_name c1 -select count(*) from t1; -count(*) -4 +# Disable result log to make test robust against +# effects of concurrent insert. +select * from t1; insert into t1 values (1); # Check that SNW lock is not compatible with SW lock. # Again we use ALTER TABLE which fails after opening diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index a5b631058c5..1f622b34edf 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -462,7 +462,11 @@ handler t1 open; handler t1 close; select column_name from information_schema.columns where table_schema='test' and table_name='t1'; -select count(*) from t1; +--echo # Disable result log to make test robust against +--echo # effects of concurrent insert. +--disable_result_log +select * from t1; +--enable_result_log insert into t1 values (1); --echo # Check that SNW lock is not compatible with SW lock. --echo # Again we use ALTER TABLE which fails after opening From ce34f3d8093f131f5713437c299a72046753868f Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 27 May 2010 12:51:26 +0200 Subject: [PATCH 133/207] Split OEL/RHEL --- support-files/mysql.spec.sh | 65 ++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 2ed3b1ff788..c0edd3718bb 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -121,43 +121,62 @@ %define distro_specific 0 %endif %if %{distro_specific} - %if %(test -f /etc/redhat-release && echo 1 || echo 0) - %define elver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g') - %if "%elver" == "4" - %define distro_description Enterprise Linux 4 - %define distro_releasetag el4 + %if %(test -f /etc/enterprise-release && echo 1 || echo 0) + %define oelver %(rpm -qf --qf '%%{version}\\n' /etc/enterprise-release | sed -e 's/^\\([0-9]*\\).*/\\1/g') + %if "%oelver" == "4" + %define distro_description Oracle Enterprise Linux 4 + %define distro_releasetag oel4 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %if "%elver" == "5" - %define distro_description Enterprise Linux 5 - %define distro_releasetag el5 + %if "%oelver" == "5" + %define distro_description Oracle Enterprise Linux 5 + %define distro_releasetag oel5 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %{error:Enterprise Linux %{elver} is unsupported} + %{error:Oracle Enterprise Linux %{oelver} is unsupported} %endif %endif %else - %if %(test -f /etc/SuSE-release && echo 1 || echo 0) - %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release) - %if "%susever" == "10" - %define distro_description SUSE Linux Enterprise Server 10 - %define distro_releasetag sles10 - %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client readline-devel zlib-devel - %define distro_requires aaa_base coreutils grep procps pwdutils + %if %(test -f /etc/redhat-release && echo 1 || echo 0) + %define rhelver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g') + %if "%rhelver" == "4" + %define distro_description Red Hat Enterprise Linux 4 + %define distro_releasetag rhel4 + %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel + %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %if "%susever" == "11" - %define distro_description SUSE Linux Enterprise Server 11 - %define distro_releasetag sles11 - %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client procps pwdutils readline-devel zlib-devel - %define distro_requires aaa_base coreutils grep procps pwdutils + %if "%rhelver" == "5" + %define distro_description Red Hat Enterprise Linux 5 + %define distro_releasetag rhel5 + %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel + %define distro_requires chkconfig coreutils grep procps shadow-utils %else - %{error:SuSE %{susever} is unsupported} + %{error:Red Hat Enterprise Linux %{rhelver} is unsupported} %endif %endif %else - %{error:Unsupported distribution} + %if %(test -f /etc/SuSE-release && echo 1 || echo 0) + %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release) + %if "%susever" == "10" + %define distro_description SUSE Linux Enterprise Server 10 + %define distro_releasetag sles10 + %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client readline-devel zlib-devel + %define distro_requires aaa_base coreutils grep procps pwdutils + %else + %if "%susever" == "11" + %define distro_description SUSE Linux Enterprise Server 11 + %define distro_releasetag sles11 + %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client procps pwdutils readline-devel zlib-devel + %define distro_requires aaa_base coreutils grep procps pwdutils + %else + %{error:SuSE %{susever} is unsupported} + %endif + %endif + %else + %{error:Unsupported distribution} + %endif %endif %endif %else From 2d3e5019d451d5f6b88b3dfd549e88ba3e5dce92 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 27 May 2010 17:40:54 -0300 Subject: [PATCH 134/207] Bug#42643: InnoDB does not support replication of TRUNCATE TABLE Post-merge fix: Retrieve handler statistics to workaround quirks of the archive storage engine. --- mysql-test/r/archive.result | 8 ++++++++ mysql-test/t/archive.test | 10 ++++++++++ sql/sql_truncate.cc | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 783a54a6b8c..ea6311a721b 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12748,3 +12748,11 @@ SELECT * FROM t1; ERROR HY000: Can't find file: 't1' (errno: 2) DROP TABLE t1; ERROR 42S02: Unknown table 't1' +# +# Ensure that TRUNCATE fails for non-empty archive tables. +# +CREATE TABLE t1 (a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES (1); +TRUNCATE TABLE t1; +ERROR HY000: Table storage engine for 't1' doesn't have this option +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index b2545e98f3e..29f69f64d10 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1669,3 +1669,13 @@ FLUSH TABLE t1; SELECT * FROM t1; --error ER_BAD_TABLE_ERROR DROP TABLE t1; + +--echo # +--echo # Ensure that TRUNCATE fails for non-empty archive tables. +--echo # + +CREATE TABLE t1 (a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES (1); +--error ER_ILLEGAL_HA +TRUNCATE TABLE t1; +DROP TABLE t1; diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 47a98769d57..8fc04588aaa 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -51,6 +51,22 @@ delete_all_rows(THD *thd, TABLE *table) /* Replication of truncate table must be statement based. */ thd->clear_current_stmt_binlog_format_row(); + /* + Update handler statistics (e.g. table->file->stats.records). + Might be used by the storage engine to aggregate information + necessary to allow deletion. Currently, this seems to be + meaningful only to the archive storage engine, which uses + the info method to set the number of records. Although + archive does not support deletion, it becomes necessary in + order to return a error if the table is not empty. + */ + error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); + if (error && error != HA_ERR_WRONG_COMMAND) + { + table->file->print_error(error, MYF(0)); + goto end; + } + /* Attempt to delete all rows in the table. If it is unsupported, switch to row by row deletion. @@ -455,6 +471,11 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) trans_rollback(thd); } + /* + A locked table ticket was upgraded to a exclusive lock. After the + the query has been written to the binary log, downgrade the lock + to a shared one. + */ if (mdl_ticket) mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); From 3cc56cb5ad789bca8fac743007947d718980e774 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 27 May 2010 18:11:55 -0300 Subject: [PATCH 135/207] Bug#42643: InnoDB does not support replication of TRUNCATE TABLE Post-merge fix: Pass the right parameter type to open_and_lock_tables. Passing FALSE ensures that derived table handling is disabled, truncate only operates on base tables. --- sql/sql_truncate.cc | 4 ++-- sql/sql_truncate.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 8fc04588aaa..901ab8e987d 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -351,7 +351,7 @@ static bool open_and_lock_table_for_truncate(THD *thd, TABLE_LIST *table_ref, the MDL lock taken above and otherwise there is no way to wait for FLUSH TABLES in deadlock-free fashion. */ - if (open_and_lock_tables(thd, table_ref, TL_WRITE, + if (open_and_lock_tables(thd, table_ref, FALSE, MYSQL_OPEN_IGNORE_FLUSH | MYSQL_OPEN_SKIP_TEMPORARY)) DBUG_RETURN(TRUE); @@ -406,7 +406,7 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) table and delete all rows. In such a manner this can in fact open several tables if it's a temporary MyISAMMRG table. */ - if (open_and_lock_tables(thd, table_ref, TL_WRITE, + if (open_and_lock_tables(thd, table_ref, FALSE, MYSQL_OPEN_TEMPORARY_ONLY)) DBUG_RETURN(TRUE); diff --git a/sql/sql_truncate.h b/sql/sql_truncate.h index a9eec384718..11c07c7187c 100644 --- a/sql/sql_truncate.h +++ b/sql/sql_truncate.h @@ -16,7 +16,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class THD; -class TABLE_LIST; +struct TABLE_LIST; bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref); From a3d61b0bb28070f60867de5d748850edd6054ff6 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 27 May 2010 18:28:24 -0300 Subject: [PATCH 136/207] Fix type mismatch. Table names are represented as LEX_STRING objects whose length is stored in a size_t type. --- sql/log.cc | 4 ++-- sql/log.h | 4 ++-- sql/table.cc | 16 +++++++++------- sql/table.h | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 6c0ab33e87a..308b8349ad6 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -370,8 +370,8 @@ bool LOGGER::is_log_table_enabled(uint log_table_type) /* Check if a given table is opened log table */ -int check_if_log_table(uint db_len, const char *db, uint table_name_len, - const char *table_name, uint check_if_opened) +int check_if_log_table(size_t db_len, const char *db, size_t table_name_len, + const char *table_name, bool check_if_opened) { if (db_len == 5 && !(lower_case_table_names ? diff --git a/sql/log.h b/sql/log.h index 12e02969485..e12d2475d0b 100644 --- a/sql/log.h +++ b/sql/log.h @@ -499,8 +499,8 @@ public: }; -int check_if_log_table(uint db_len, const char *db, uint table_name_len, - const char *table_name, uint check_if_opened); +int check_if_log_table(size_t db_len, const char *db, size_t table_name_len, + const char *table_name, bool check_if_opened); class Log_to_csv_event_handler: public Log_event_handler { diff --git a/sql/table.cc b/sql/table.cc index 1e7cb747bc6..e19cd8cf6f4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2777,9 +2777,10 @@ bool check_db_name(LEX_STRING *org_name) */ -bool check_table_name(const char *name, uint length) +bool check_table_name(const char *name, size_t length) { - uint name_length= 0; // name length in symbols + // name length in symbols + size_t name_length= 0; const char *end= name+length; if (!length || length > NAME_LEN) return 1; @@ -2809,18 +2810,19 @@ bool check_table_name(const char *name, uint length) name_length++; } #if defined(USE_MB) && defined(USE_MB_IDENT) - return (last_char_is_space || name_length > NAME_CHAR_LEN) ; + return last_char_is_space || (name_length > NAME_CHAR_LEN); #else - return 0; + return FALSE; #endif } bool check_column_name(const char *name) { - uint name_length= 0; // name length in symbols + // name length in symbols + size_t name_length= 0; bool last_char_is_space= TRUE; - + while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) @@ -2845,7 +2847,7 @@ bool check_column_name(const char *name) name_length++; } /* Error if empty or too long column name */ - return last_char_is_space || (uint) name_length > NAME_CHAR_LEN; + return last_char_is_space || (name_length > NAME_CHAR_LEN); } diff --git a/sql/table.h b/sql/table.h index cb773052c8b..6430e505a13 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2001,7 +2001,7 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase); bool check_db_name(LEX_STRING *db); bool check_column_name(const char *name); -bool check_table_name(const char *name, uint length); +bool check_table_name(const char *name, size_t length); int rename_file_ext(const char * from,const char * to,const char * ext); char *get_field(MEM_ROOT *mem, Field *field); bool get_field(MEM_ROOT *mem, Field *field, class String *res); From 1fbdf160b4f24fd81f9009d1f3312bc676e63732 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Fri, 28 May 2010 09:25:11 +0400 Subject: [PATCH 137/207] Patch that addresses bug #53976 "ALTER TABLE RENAME is allowed on views (not documented, broken)". Remove support of ALTER TABLE RENAME for views as: a) this feature was not documented, c) does not add any compatibility with other databases, b) its implementation doesn't follow metadata locking protocol by accessing .FRM without holding any metadata lock, c) its implementation complicates ALTER TABLE's code by introducing yet another separate branch to it. After this patch one can rename a view by using the documented way - RENAME TABLE statement. --- mysql-test/r/rename.result | 11 ++--- mysql-test/r/view.result | 1 + mysql-test/t/rename.test | 14 +++--- mysql-test/t/view.test | 1 + sql/sql_table.cc | 87 -------------------------------------- 5 files changed, 14 insertions(+), 100 deletions(-) diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index 1257a668cce..edf05d0c5d3 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -55,14 +55,15 @@ t2 t4 drop table t2, t4; End of 4.1 tests +# +# Bug#14959: "ALTER TABLE isn't able to rename a view" +# Bug#53976: "ALTER TABLE RENAME is allowed on views +# (not documented, broken)" +# create table t1(f1 int); create view v1 as select * from t1; alter table v1 rename to v2; -alter table v1 rename to v2; -ERROR 42S02: Table 'test.v1' doesn't exist -rename table v2 to v1; -rename table v2 to v1; -ERROR 42S01: Table 'v1' already exists +ERROR HY000: 'test.v1' is not BASE TABLE drop view v1; drop table t1; End of 5.0 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index b7660dbcbd8..487ce54203d 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3954,6 +3954,7 @@ drop procedure p; CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT a FROM t1; ALTER TABLE v1; +ERROR HY000: 'test.v1' is not BASE TABLE DROP VIEW v1; DROP TABLE t1; # diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index 5aa1a51a90f..bb90cbafd74 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -79,17 +79,15 @@ connection default; --echo End of 4.1 tests -# -# Bug#14959: ALTER TABLE isn't able to rename a view -# +--echo # +--echo # Bug#14959: "ALTER TABLE isn't able to rename a view" +--echo # Bug#53976: "ALTER TABLE RENAME is allowed on views +--echo # (not documented, broken)" +--echo # create table t1(f1 int); create view v1 as select * from t1; +--error ER_WRONG_OBJECT alter table v1 rename to v2; ---error ER_NO_SUCH_TABLE -alter table v1 rename to v2; -rename table v2 to v1; ---error ER_TABLE_EXISTS_ERROR -rename table v2 to v1; drop view v1; drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index d1a4d78e58f..360bbc1552d 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3902,6 +3902,7 @@ drop procedure p; --echo # CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT a FROM t1; +--error ER_WRONG_OBJECT ALTER TABLE v1; DROP VIEW v1; DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c27ebce744f..113da3fe719 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6454,8 +6454,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; handlerton *old_db_type, *new_db_type, *save_old_db_type; - legacy_db_type table_type; - frm_type_enum frm_type; enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY; #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition= 0; @@ -6535,91 +6533,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Conditionally writes to binlog. */ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); - strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, - "/", table_name, reg_ext, NullS); - (void) unpack_filename(new_name_buff, new_name_buff); - /* - If this is just a rename of a view, short cut to the - following scenario: 1) lock LOCK_open 2) do a RENAME - 2) unlock LOCK_open. - This is a copy-paste added to make sure - ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled - as an independent branch in mysql_execute_command. The need - for a copy-paste arose because the main code flow of ALTER TABLE - ... RENAME tries to use open_ltable, which does not work for views - (open_ltable was never modified to merge table lists of child tables - into the main table list, like open_tables does). - This code is wrong and will be removed, please do not copy. - */ - frm_type= dd_frm_type(thd, new_name_buff, &table_type); - /* Rename a view */ - /* Sic: there is a race here */ - if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) - { - /* - The following branch handles "ALTER VIEW v1 /no arguments/;" - This feature is not documented one. - However, before "OPTIMIZE TABLE t1;" was implemented, - ALTER TABLE with no alter_specifications was used to force-rebuild - the table. That's why this grammar is allowed. That's why we ignore - it for views. So just do nothing in such a case. - */ - if (!new_name) - { - my_ok(thd); - DBUG_RETURN(FALSE); - } - - /* - Avoid problems with a rename on a table that we have locked or - if the user is trying to to do this in a transcation context - */ - - if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - DBUG_RETURN(TRUE); - } - - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - DBUG_RETURN(TRUE); - - /* - TODO/FIXME: Get rid of this code branch if possible. To add insult - to injury it breaks locking protocol. - */ - table_list->mdl_request.set_type(MDL_EXCLUSIVE); - if (lock_table_names(thd, table_list)) - { - error= 1; - goto view_err; - } - - mysql_mutex_lock(&LOCK_open); - - if (!do_rename(thd, table_list, new_db, new_name, new_name, 1)) - { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query(), thd->query_length(), - FALSE, TRUE, FALSE, 0); - if ((error= mysql_bin_log.write(&qinfo))) - goto view_err_unlock; - } - my_ok(thd); - } - -view_err_unlock: - mysql_mutex_unlock(&LOCK_open); - unlock_table_names(thd); - -view_err: - thd->global_read_lock.start_waiting_global_read_lock(thd); - DBUG_RETURN(error); - } - /* Code below can handle only base tables so ensure that we won't open a view. From 89205a3bf6bba245e312078b23168ff5f8560759 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Fri, 28 May 2010 16:50:23 +0200 Subject: [PATCH 138/207] post-merge fix 1 --- CMakeLists.txt | 13 ------------- scripts/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43c1c2ea095..fa691042026 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,19 +282,6 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc.in ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc) -INSTALL(FILES EXCEPTIONS-CLIENT DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT - Development) - - -INSTALL(FILES COPYING DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme OPTIONAL) -INSTALL(FILES README DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Readme) -IF(UNIX) - INSTALL(FILES Docs/INSTALL-BINARY DESTINATION ${INSTALL_DOCREADMEDIR} COMPONENT Documentation) -ENDIF() -# MYSQL_DOCS_LOCATON is used in "make dist", points to the documentation directory -SET(MYSQL_DOCS_LOCATION "" CACHE PATH "Location from where documentation is copied") -MARK_AS_ADVANCED(MYSQL_DOCS_LOCATION) -INSTALL(DIRECTORY Docs/ DESTINATION ${INSTALL_DOCDIR} COMPONENT Documentation) # Packaging IF(WIN32) SET(CPACK_GENERATOR "ZIP") diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 483e4bcef65..633b9b8ff90 100755 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -177,7 +177,7 @@ ENDIF() INSTALL_SCRIPT( "${CMAKE_CURRENT_BINARY_DIR}/mysql_install_db${EXT}" - DESTINATION ${INSTALL_BINDIR} + DESTINATION ${DEST} COMPONENT Server ) From d99aeb19fb3cebb1b0dc5eb73d73f754a07968e1 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Sun, 30 May 2010 11:43:19 +0400 Subject: [PATCH 139/207] Fixed typo which was introduced by pre-requisite patch for bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION" and has been causing compilation error when server was built with NDB support. --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2af2b064020..a327aa51b53 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -7411,7 +7411,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, table_list.init_one_table(db, strlen(db), file_name_str, strlen(file_name_str), file_name_str, TL_WRITE); - table_list.mdl_request.set_tpye(MDL_EXCLUSIVE); + table_list.mdl_request.set_type(MDL_EXCLUSIVE); (void)mysql_rm_table_part2(thd, &table_list, FALSE, /* if_exists */ FALSE, /* drop_temporary */ From c4b2cf2da5f1fc3ee5608d4078309edaaa2fce3c Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Sun, 30 May 2010 11:48:22 +0400 Subject: [PATCH 140/207] Follow-up for patch that addresses bug #53976 "ALTER TABLE RENAME is allowed on views (not documented, broken)". Adjusted test cases in funcs_1 suite after removing support of ALTER TABLE RENAME for views. --- mysql-test/suite/funcs_1/r/innodb_views.result | 1 + mysql-test/suite/funcs_1/r/memory_views.result | 1 + mysql-test/suite/funcs_1/r/myisam_views.result | 1 + mysql-test/suite/funcs_1/r/ndb_views.result | 1 + mysql-test/suite/funcs_1/views/views_master.inc | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index b4bce0b0d1b..86a61773a31 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -3521,6 +3521,7 @@ RENAME TABLE v1 TO v2; RENAME VIEW v2 TO v1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VIEW v2 TO v1' at line 1 ALTER TABLE v2 RENAME AS v1; +ERROR HY000: 'test.v2' is not BASE TABLE ALTER VIEW v1 RENAME AS v2; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RENAME AS v2' at line 1 DROP TABLE IF EXISTS t1, t2 ; diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index 2f7342088f8..7ed23c3a5c1 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -3522,6 +3522,7 @@ RENAME TABLE v1 TO v2; RENAME VIEW v2 TO v1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VIEW v2 TO v1' at line 1 ALTER TABLE v2 RENAME AS v1; +ERROR HY000: 'test.v2' is not BASE TABLE ALTER VIEW v1 RENAME AS v2; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RENAME AS v2' at line 1 DROP TABLE IF EXISTS t1, t2 ; diff --git a/mysql-test/suite/funcs_1/r/myisam_views.result b/mysql-test/suite/funcs_1/r/myisam_views.result index b77ea8a4bd9..ca4dba9f337 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views.result +++ b/mysql-test/suite/funcs_1/r/myisam_views.result @@ -4024,6 +4024,7 @@ RENAME TABLE v1 TO v2; RENAME VIEW v2 TO v1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VIEW v2 TO v1' at line 1 ALTER TABLE v2 RENAME AS v1; +ERROR HY000: 'test.v2' is not BASE TABLE ALTER VIEW v1 RENAME AS v2; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RENAME AS v2' at line 1 DROP TABLE IF EXISTS t1, t2 ; diff --git a/mysql-test/suite/funcs_1/r/ndb_views.result b/mysql-test/suite/funcs_1/r/ndb_views.result index 10cb7613f47..6c5a10845a0 100644 --- a/mysql-test/suite/funcs_1/r/ndb_views.result +++ b/mysql-test/suite/funcs_1/r/ndb_views.result @@ -3521,6 +3521,7 @@ RENAME TABLE v1 TO v2; RENAME VIEW v2 TO v1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VIEW v2 TO v1' at line 1 ALTER TABLE v2 RENAME AS v1; +ERROR HY000: 'test.v2' is not BASE TABLE ALTER VIEW v1 RENAME AS v2; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RENAME AS v2' at line 1 DROP TABLE IF EXISTS t1, t2 ; diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc index 4f8439efc3a..906f1f03b3b 100644 --- a/mysql-test/suite/funcs_1/views/views_master.inc +++ b/mysql-test/suite/funcs_1/views/views_master.inc @@ -298,7 +298,7 @@ RENAME TABLE v1 TO v2; # RENAME VIEW is not available even when we try it via rename table. --error ER_PARSE_ERROR RENAME VIEW v2 TO v1; -#--error ER_WRONG_OBJECT +--error ER_WRONG_OBJECT ALTER TABLE v2 RENAME AS v1; --error ER_PARSE_ERROR ALTER VIEW v1 RENAME AS v2; From c7395690c6d9f2823a5e34cd2b2f508f119d4ae1 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Sun, 30 May 2010 13:27:44 +0400 Subject: [PATCH 141/207] Yet another follow-up for the 5.5 version of fix for bug #46947 "Embedded SELECT without FOR UPDATE is causing a lock". Fixed comments in tests. Improved comments and performance of auxiliary scripts. --- mysql-test/include/check_concurrent_insert.inc | 18 +++++++++--------- .../include/check_no_concurrent_insert.inc | 14 +++++++------- mysql-test/include/check_no_row_lock.inc | 4 ++-- mysql-test/r/innodb_mysql_lock2.result | 5 ++--- mysql-test/r/lock_sync.result | 2 +- mysql-test/t/innodb_mysql_lock2.test | 5 ++--- mysql-test/t/lock_sync.test | 2 +- 7 files changed, 24 insertions(+), 26 deletions(-) diff --git a/mysql-test/include/check_concurrent_insert.inc b/mysql-test/include/check_concurrent_insert.inc index 6a9ada65562..f4bec3c9cdb 100644 --- a/mysql-test/include/check_concurrent_insert.inc +++ b/mysql-test/include/check_concurrent_insert.inc @@ -10,9 +10,9 @@ # $con_aux2 Name of the second auxiliary connection to be used by this # script. # $statement Statement to be checked. -# $restore_table Table which might be modified affected by statement to be -# checked and thus needs backing up before its execution -# and restoring after it (can be empty). +# $restore_table Table which might be modified by statement to be checked +# and thus needs backing up before its execution and +# restoring after it (can be empty). # # EXAMPLE # lock_sync.test @@ -25,7 +25,7 @@ set debug_sync= "RESET"; if (`SELECT '$restore_table' <> ''`) { ---eval create table t_backup select * from $restore_table; +--eval create temporary table t_backup select * from $restore_table; } connection $con_aux1; @@ -34,19 +34,19 @@ set debug_sync='after_lock_tables_takes_lock SIGNAL parked WAIT_FOR go'; connection $con_aux2; set debug_sync='now WAIT_FOR parked'; ---send_eval insert into $table values (0); +--send_eval insert into $table (i) values (0); --enable_result_log --enable_query_log connection default; # Wait until concurrent insert is successfully executed while # statement being checked has its tables locked. -# We use wait_condition.inc instead of simply executing +# We use wait_condition.inc instead of simply reaping # concurrent insert here in order to avoid deadlocks if test -# fails and timing out instead. +# fails and to time out gracefully instead. let $wait_condition= select count(*) = 0 from information_schema.processlist - where info = "insert into $table values (0)"; + where info = "insert into $table (i) values (0)"; --source include/wait_condition.inc --disable_result_log @@ -86,7 +86,7 @@ if (`SELECT '$restore_table' <> ''`) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; -drop table t_backup; +drop temporary table t_backup; } # Clean-up. Reset DEBUG_SYNC facility after use. diff --git a/mysql-test/include/check_no_concurrent_insert.inc b/mysql-test/include/check_no_concurrent_insert.inc index 278ffeffb1e..57772dddefc 100644 --- a/mysql-test/include/check_no_concurrent_insert.inc +++ b/mysql-test/include/check_no_concurrent_insert.inc @@ -10,9 +10,9 @@ # $con_aux2 Name of the second auxiliary connection to be used by this # script. # $statement Statement to be checked. -# $restore_table Table which might be modified affected by statement to be -# checked and thus needs backing up before its execution -# and restoring after it (can be empty). +# $restore_table Table which might be modified by statement to be checked +# and thus needs backing up before its execution and +# restoring after it (can be empty). # # EXAMPLE # lock_sync.test @@ -25,7 +25,7 @@ set debug_sync= "RESET"; if (`SELECT '$restore_table' <> ''`) { ---eval create table t_backup select * from $restore_table; +--eval create temporary table t_backup select * from $restore_table; } connection $con_aux1; @@ -34,7 +34,7 @@ set debug_sync='after_lock_tables_takes_lock SIGNAL parked WAIT_FOR go'; connection $con_aux2; set debug_sync='now WAIT_FOR parked'; ---send_eval insert into $table values (0); +--send_eval insert into $table (i) values (0); --enable_result_log --enable_query_log @@ -43,7 +43,7 @@ connection default; # of our statement. let $wait_condition= select count(*) = 1 from information_schema.processlist - where state = "Table lock" and info = "insert into $table values (0)"; + where state = "Table lock" and info = "insert into $table (i) values (0)"; --source include/wait_condition.inc --disable_result_log @@ -71,7 +71,7 @@ if (`SELECT '$restore_table' <> ''`) { --eval truncate table $restore_table; --eval insert into $restore_table select * from t_backup; -drop table t_backup; +drop temporary table t_backup; } # Clean-up. Reset DEBUG_SYNC facility after use. diff --git a/mysql-test/include/check_no_row_lock.inc b/mysql-test/include/check_no_row_lock.inc index 958161b9b7f..c08e7f35b10 100644 --- a/mysql-test/include/check_no_row_lock.inc +++ b/mysql-test/include/check_no_row_lock.inc @@ -29,9 +29,9 @@ connection default; # Wait until statement is successfully executed while # all rows in table are X-locked. This means that it # does not acquire any row locks. -# We use wait_condition.inc instead of simply executing +# We use wait_condition.inc instead of simply reaping # statement here in order to avoid deadlocks if test -# fails and timing out instead. +# fails and to time out gracefully instead. let $wait_condition= select count(*) = 0 from information_schema.processlist where info = "$statement"; diff --git a/mysql-test/r/innodb_mysql_lock2.result b/mysql-test/r/innodb_mysql_lock2.result index 70cfbee6463..17dd747de6f 100644 --- a/mysql-test/r/innodb_mysql_lock2.result +++ b/mysql-test/r/innodb_mysql_lock2.result @@ -178,8 +178,7 @@ end| # 1.1 Simple SELECT statement. # # No locks are necessary as this statement won't be written -# to the binary log and thanks to how MyISAM works SELECT -# will see version of the table prior to concurrent insert. +# to the binary log and InnoDB supports snapshots. Success: 'select * from t1' doesn't take row locks on 't1'. # # 1.2 Multi-UPDATE statement. @@ -484,7 +483,7 @@ Success: 'insert into t2 values (f13((select i+10 from t1 where i=1)))' takes sh # row locks on the data it reads. Success: 'call p2(@a)' doesn't take row locks on 't1'. # -# 5.2 Function that modifes data and uses CALL, +# 5.2 Function that modifies data and uses CALL, # which reads a table through SELECT. # # Since a call to such function is written to the binary diff --git a/mysql-test/r/lock_sync.result b/mysql-test/r/lock_sync.result index e6265f1cb5e..3682f0df26a 100644 --- a/mysql-test/r/lock_sync.result +++ b/mysql-test/r/lock_sync.result @@ -511,7 +511,7 @@ Success: 'insert into t2 values (f13((select i+10 from t1 where i=1)))' doesn't # strong locks on the data it reads. Success: 'call p2(@a)' allows concurrent inserts into 't1'. # -# 5.2 Function that modifes data and uses CALL, +# 5.2 Function that modifies data and uses CALL, # which reads a table through SELECT. # # Since a call to such function is written to the binary diff --git a/mysql-test/t/innodb_mysql_lock2.test b/mysql-test/t/innodb_mysql_lock2.test index 1f01f4cb010..048d712183f 100644 --- a/mysql-test/t/innodb_mysql_lock2.test +++ b/mysql-test/t/innodb_mysql_lock2.test @@ -204,8 +204,7 @@ let $table= t1; --echo # 1.1 Simple SELECT statement. --echo # --echo # No locks are necessary as this statement won't be written ---echo # to the binary log and thanks to how MyISAM works SELECT ---echo # will see version of the table prior to concurrent insert. +--echo # to the binary log and InnoDB supports snapshots. let $statement= select * from t1; --source include/check_no_row_lock.inc @@ -659,7 +658,7 @@ let $statement= call p2(@a); --source include/check_no_row_lock.inc --echo # ---echo # 5.2 Function that modifes data and uses CALL, +--echo # 5.2 Function that modifies data and uses CALL, --echo # which reads a table through SELECT. --echo # --echo # Since a call to such function is written to the binary diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test index 921ce991652..2f35da9d1ee 100644 --- a/mysql-test/t/lock_sync.test +++ b/mysql-test/t/lock_sync.test @@ -716,7 +716,7 @@ let $restore_table= ; --source include/check_concurrent_insert.inc --echo # ---echo # 5.2 Function that modifes data and uses CALL, +--echo # 5.2 Function that modifies data and uses CALL, --echo # which reads a table through SELECT. --echo # --echo # Since a call to such function is written to the binary From 08589ba9c9055aaa4f0c2bcc31fcd358e3dc19f1 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Tue, 1 Jun 2010 14:13:56 +0400 Subject: [PATCH 142/207] A follow up patch for the fix for Bug#51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Remove unused code - TL_WRITE_ALLOW_READ thr_lock.c lock. --- include/thr_lock.h | 6 -- mysys/CMakeLists.txt | 4 + mysys/thr_lock.c | 218 ++++--------------------------------------- sql/sql_test.cc | 1 - 4 files changed, 22 insertions(+), 207 deletions(-) diff --git a/include/thr_lock.h b/include/thr_lock.h index 1f4072ca0c5..37dc37f8017 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -53,12 +53,6 @@ enum thr_lock_type { TL_IGNORE=-1, reading/writing to the table. */ TL_WRITE_ALLOW_WRITE, - /* - Write lock, but allow other threads to read. - Used by ALTER TABLE in MySQL to allow readers - to use the table until ALTER TABLE is finished. - */ - TL_WRITE_ALLOW_READ, /* WRITE lock used by concurrent insert. Will allow READ, if one could use concurrent insert on table. diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 2fbaac7fe72..855c5a6234b 100755 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -66,3 +66,7 @@ ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES}) TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY} ${LIBNSL} ${LIBM} ${LIBRT}) DTRACE_INSTRUMENT(mysys) + +ADD_EXECUTABLE(thr_lock thr_lock.c) +TARGET_LINK_LIBRARIES(thr_lock mysys) +SET_TARGET_PROPERTIES(thr_lock PROPERTIES COMPILE_FLAGS "-DMAIN") diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 43db0470735..cff1b9b9845 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -29,7 +29,6 @@ TL_READ_WITH_SHARED_LOCKS TL_READ_HIGH_PRIORITY # High priority read TL_READ_NO_INSERT # Read without concurrent inserts TL_WRITE_ALLOW_WRITE # Write lock that allows other writers -TL_WRITE_ALLOW_READ # Write lock, but allow reading TL_WRITE_CONCURRENT_INSERT # Insert that can be mixed when selects TL_WRITE_DELAYED # Used by delayed insert @@ -41,7 +40,7 @@ TL_WRITE_ONLY # High priority write Locks are prioritized according to: -WRITE_ALLOW_WRITE, WRITE_ALLOW_READ, WRITE_CONCURRENT_INSERT, WRITE_DELAYED, +WRITE_ALLOW_WRITE, WRITE_CONCURRENT_INSERT, WRITE_DELAYED, WRITE_LOW_PRIORITY, READ, WRITE, READ_HIGH_PRIORITY and WRITE_ONLY Locks in the same privilege level are scheduled in first-in-first-out order. @@ -64,9 +63,8 @@ get_status: In MyISAM this stores the number of rows and size of the datafile for concurrent reads. -The lock algorithm allows one to have one TL_WRITE_ALLOW_READ, -TL_WRITE_CONCURRENT_INSERT or one TL_WRITE_DELAYED lock at the same time as -multiple read locks. +The lock algorithm allows one to have one TL_WRITE_CONCURRENT_INSERT or +one TL_WRITE_DELAYED lock at the same time as multiple read locks. */ @@ -238,7 +236,6 @@ static void check_locks(THR_LOCK *lock, const char *where, (((lock->write_wait.data->type == TL_WRITE_CONCURRENT_INSERT || lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE) && !lock->read_no_write_count) || - lock->write_wait.data->type == TL_WRITE_ALLOW_READ || (lock->write_wait.data->type == TL_WRITE_DELAYED && !lock->read.data))) { @@ -543,14 +540,14 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, Request /------- H|++++ WRITE_ALLOW_WRITE - e|++++ WRITE_ALLOW_READ - l|+++- WRITE_CONCURRENT_INSERT - d|++++ WRITE_DELAYED - |||| + e|+++- WRITE_CONCURRENT_INSERT + l|++++ WRITE_DELAYED + d |||| |||\= READ_NO_INSERT ||\ = READ_HIGH_PRIORITY |\ = READ_WITH_SHARED_LOCKS \ = READ + + = Request can be satisified. - = Request cannot be satisified. @@ -620,14 +617,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, result= THR_LOCK_ABORTED; /* Can't wait for this one */ goto end; } - /* - if there is a TL_WRITE_ALLOW_READ lock, we have to wait for a lock - (TL_WRITE_ALLOW_READ is used for ALTER TABLE in MySQL) - */ - if ((!lock->write.data || - lock->write.data->type != TL_WRITE_ALLOW_READ) && - !have_specific_lock(lock->write_wait.data,TL_WRITE_ALLOW_READ) && - (lock->write.data || lock->read.data)) + if (lock->write.data || lock->read.data) { /* Add delayed write lock to write_wait queue, and return at once */ (*lock->write_wait.last)=data; @@ -680,8 +670,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, it is OK to grant new lock without additional checks in such situation. **) The exceptions are situations when: - - old lock type is TL_WRITE_ALLOW_READ and new lock type is - TL_WRITE_ALLOW_WRITE - when old lock type is TL_WRITE_DELAYED But these should never happen within MySQL. Therefore it is OK to allow acquiring write lock on the table if @@ -695,9 +683,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, ((lock_type <= lock->write.data->type || (lock_type == TL_WRITE && lock->write.data->type == TL_WRITE_LOW_PRIORITY)) && - ! ((lock_type < TL_WRITE_ALLOW_READ && - lock->write.data->type == TL_WRITE_ALLOW_READ) || - lock->write.data->type == TL_WRITE_DELAYED))); + lock->write.data->type != TL_WRITE_DELAYED)); if ((lock_type == TL_WRITE_ALLOW_WRITE && ! lock->write_wait.data && @@ -1265,10 +1251,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) occurs also other waiters, both readers and writers can be allowed to start. The previous lock is often TL_WRITE_ONLY but can also be - TL_WRITE and TL_WRITE_ALLOW_READ. The normal downgrade variants are - TL_WRITE_ONLY => TL_WRITE_ALLOW_READ After a short exclusive lock - TL_WRITE_ALLOW_READ => TL_WRITE_ALLOW_WRITE After discovering that the - operation didn't need such a high lock. + TL_WRITE. The normal downgrade variants are: TL_WRITE_ONLY => TL_WRITE after a short exclusive lock while holding a write table lock TL_WRITE_ONLY => TL_WRITE_ALLOW_WRITE After a short exclusive lock after @@ -1288,11 +1271,6 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, THR_LOCK *lock=in_data->lock; #ifndef DBUG_OFF enum thr_lock_type old_lock_type= in_data->type; -#endif -#ifdef TO_BE_REMOVED - THR_LOCK_DATA *data, *next; - bool start_writers= FALSE; - bool start_readers= FALSE; #endif DBUG_ENTER("thr_downgrade_write_only_lock"); @@ -1302,165 +1280,6 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, in_data->type= new_lock_type; check_locks(lock,"after downgrading lock",0); -#if TO_BE_REMOVED - switch (old_lock_type) - { - case TL_WRITE_ONLY: - case TL_WRITE: - case TL_WRITE_LOW_PRIORITY: - /* - Previous lock was exclusive we are now ready to start up most waiting - threads. - */ - switch (new_lock_type) - { - case TL_WRITE_ALLOW_READ: - /* Still cannot start WRITE operations. Can only start readers. */ - start_readers= TRUE; - break; - case TL_WRITE: - case TL_WRITE_LOW_PRIORITY: - /* - Still cannot start anything, but new requests are no longer - aborted. - */ - break; - case TL_WRITE_ALLOW_WRITE: - /* - We can start both writers and readers. - */ - start_writers= TRUE; - start_readers= TRUE; - break; - case TL_WRITE_CONCURRENT_INSERT: - case TL_WRITE_DELAYED: - /* - This routine is not designed for those. Lock will be downgraded - but no start of waiters will occur. This is not the optimal but - should be a correct behaviour. - */ - break; - default: - DBUG_ASSERT(0); - } - break; - case TL_WRITE_DELAYED: - case TL_WRITE_CONCURRENT_INSERT: - /* - This routine is not designed for those. Lock will be downgraded - but no start of waiters will occur. This is not the optimal but - should be a correct behaviour. - */ - break; - case TL_WRITE_ALLOW_READ: - DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE); - /* - Previously writers were not allowed to start, now it is ok to - start them again. Readers are already allowed so no reason to - handle them. - */ - start_writers= TRUE; - break; - default: - DBUG_ASSERT(0); - break; - } - if (start_writers) - { - /* - At this time the only active writer can be ourselves. Thus we need - not worry about that there are other concurrent write operations - active on the table. Thus we only need to worry about starting - waiting operations. - We also only come here with TL_WRITE_ALLOW_WRITE as the new - lock type, thus we can start other writers also of the same type. - If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we - don't start any more operations that would be mean those operations - will have to wait for things started afterwards. - */ - DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE); - for (data=lock->write_wait.data; data ; data= next) - { - /* - All WRITE requests compatible with new lock type are also - started - */ - next= data->next; - if (start_writers && data->type == new_lock_type) - { - mysql_cond_t *cond= data->cond; - /* - It is ok to start this waiter. - Move from being first in wait queue to be last in write queue. - */ - if (((*data->prev)= data->next)) - data->next->prev= data->prev; - else - lock->write_wait.last= data->prev; - data->prev= lock->write.last; - lock->write.last= &data->next; - data->next= 0; - check_locks(lock, "Started write lock after downgrade",0); - data->cond= 0; - mysql_cond_signal(cond); - } - else - { - /* - We found an incompatible lock, we won't start any more write - requests to avoid letting writers pass other writers in the - queue. - */ - start_writers= FALSE; - if (data->type >= TL_WRITE_LOW_PRIORITY) - { - /* - We have an exclusive writer in the queue so we won't start - readers either. - */ - start_readers= FALSE; - } - } - } - } - if (start_readers) - { - DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE || - new_lock_type == TL_WRITE_ALLOW_READ); - /* - When we come here we know that the write locks are - TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads - are ok - */ - for (data=lock->read_wait.data; data ; data=next) - { - next= data->next; - /* - All reads are ok to start now except TL_READ_NO_INSERT when - write lock is TL_WRITE_ALLOW_READ. - */ - if (new_lock_type != TL_WRITE_ALLOW_READ || - data->type != TL_READ_NO_INSERT) - { - mysql_cond_t *cond= data->cond; - if (((*data->prev)= data->next)) - data->next->prev= data->prev; - else - lock->read_wait.last= data->prev; - data->prev= lock->read.last; - lock->read.last= &data->next; - data->next= 0; - - if (data->type == TL_READ_NO_INSERT) - lock->read_no_write_count++; - check_locks(lock, "Started read lock after downgrade",0); - data->cond= 0; - mysql_cond_signal(cond); - } - } - } - check_locks(lock,"after starting waiters after downgrading lock",0); -#endif mysql_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -1646,15 +1465,14 @@ struct st_test test_8[] = {{1,TL_READ_NO_INSERT},{2,TL_READ_NO_INSERT},{3,TL_REA struct st_test test_9[] = {{4,TL_READ_HIGH_PRIORITY}}; struct st_test test_10[] ={{4,TL_WRITE}}; struct st_test test_11[] = {{0,TL_WRITE_LOW_PRIORITY},{1,TL_WRITE_LOW_PRIORITY},{2,TL_WRITE_LOW_PRIORITY},{3,TL_WRITE_LOW_PRIORITY}}; /* Many writes */ -struct st_test test_12[] = {{0,TL_WRITE_ALLOW_READ},{1,TL_WRITE_ALLOW_READ},{2,TL_WRITE_ALLOW_READ},{3,TL_WRITE_ALLOW_READ}}; /* Many writes */ -struct st_test test_13[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_WRITE_CONCURRENT_INSERT},{2,TL_WRITE_CONCURRENT_INSERT},{3,TL_WRITE_CONCURRENT_INSERT}}; -struct st_test test_14[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_READ}}; -struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}}; -struct st_test test_16[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}}; +struct st_test test_12[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_WRITE_CONCURRENT_INSERT},{2,TL_WRITE_CONCURRENT_INSERT},{3,TL_WRITE_CONCURRENT_INSERT}}; +struct st_test test_13[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_READ}}; +struct st_test test_14[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}}; +struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}}; struct st_test *tests[] = {test_0,test_1,test_2,test_3,test_4,test_5,test_6, test_7,test_8,test_9,test_10,test_11,test_12, - test_13,test_14,test_15,test_16}; + test_13,test_14,test_15}; int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test), sizeof(test_1)/sizeof(struct st_test), sizeof(test_2)/sizeof(struct st_test), @@ -1670,8 +1488,7 @@ int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test), sizeof(test_12)/sizeof(struct st_test), sizeof(test_13)/sizeof(struct st_test), sizeof(test_14)/sizeof(struct st_test), - sizeof(test_15)/sizeof(struct st_test), - sizeof(test_16)/sizeof(struct st_test) + sizeof(test_15)/sizeof(struct st_test) }; @@ -1681,6 +1498,7 @@ static uint thread_count; static ulong sum=0; #define MAX_LOCK_COUNT 8 +#define TEST_TIMEOUT 100000 /* The following functions is for WRITE_CONCURRENT_INSERT */ @@ -1727,7 +1545,7 @@ static void *test_thread(void *arg) multi_locks[i]= &data[i]; data[i].type= tests[param][i].lock_type; } - thr_multi_lock(multi_locks, lock_counts[param], &owner); + thr_multi_lock(multi_locks, lock_counts[param], &owner, TEST_TIMEOUT); mysql_mutex_lock(&LOCK_thread_count); { int tmp=rand() & 7; /* Do something from 0-2 sec */ diff --git a/sql/sql_test.cc b/sql/sql_test.cc index d34aee854d0..2f3ed0030cd 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -45,7 +45,6 @@ static const char *lock_descriptions[] = /* TL_READ_HIGH_PRIORITY */ "High priority read lock", /* TL_READ_NO_INSERT */ "Read lock without concurrent inserts", /* TL_WRITE_ALLOW_WRITE */ "Write lock that allows other writers", - /* TL_WRITE_ALLOW_READ */ "Write lock, but allow reading", /* TL_WRITE_CONCURRENT_INSERT */ "Concurrent insert lock", /* TL_WRITE_DELAYED */ "Lock used by delayed insert", /* TL_WRITE_DEFAULT */ NULL, From 8b0c705c39d340c39105f24286933f63b343e16b Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Tue, 1 Jun 2010 14:19:05 +0400 Subject: [PATCH 143/207] A follow up patch for the fix for Bug#51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Move declarations of sql_base.cc classes to sql_base.h (previously declared in sql_class.h). Became possible after a header file split. --- sql/sql_base.cc | 2 +- sql/sql_base.h | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_class.h | 164 ------------------------------------------------ 3 files changed, 165 insertions(+), 165 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4203a556e65..3949e14253f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -16,11 +16,11 @@ /* Basic functions needed by many modules */ +#include "sql_base.h" // setup_table_map #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" #include "unireg.h" #include "debug_sync.h" -#include "sql_base.h" // setup_table_map #include "lock.h" // broadcast_refresh, mysql_lock_remove, // mysql_unlock_tables, // mysql_lock_have_duplicate diff --git a/sql/sql_base.h b/sql/sql_base.h index 0c16151e43a..a0a1ef856a6 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -322,6 +322,7 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table, db_name, table_name); } + inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array, List &item, enum_mark_columns mark_used_columns, @@ -336,6 +337,89 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array, return res; } +/** + An abstract class for a strategy specifying how the prelocking + algorithm should extend the prelocking set while processing + already existing elements in the set. +*/ + +class Prelocking_strategy +{ +public: + virtual ~Prelocking_strategy() { } + + virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, + Sroutine_hash_entry *rt, sp_head *sp, + bool *need_prelocking) = 0; + virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking) = 0; + virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking)= 0; +}; + + +/** + A Strategy for prelocking algorithm suitable for DML statements. + + Ensures that all tables used by all statement's SF/SP/triggers and + required for foreign key checks are prelocked and SF/SPs used are + cached. +*/ + +class DML_prelocking_strategy : public Prelocking_strategy +{ +public: + virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, + Sroutine_hash_entry *rt, sp_head *sp, + bool *need_prelocking); + virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking); + virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking); +}; + + +/** + A strategy for prelocking algorithm to be used for LOCK TABLES + statement. +*/ + +class Lock_tables_prelocking_strategy : public DML_prelocking_strategy +{ + virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking); +}; + + +/** + Strategy for prelocking algorithm to be used for ALTER TABLE statements. + + Unlike DML or LOCK TABLES strategy, it doesn't + prelock triggers, views or stored routines, since they are not + used during ALTER. +*/ + +class Alter_table_prelocking_strategy : public Prelocking_strategy +{ +public: + + Alter_table_prelocking_strategy(Alter_info *alter_info) + : m_alter_info(alter_info) + {} + + virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, + Sroutine_hash_entry *rt, sp_head *sp, + bool *need_prelocking); + virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking); + virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, + TABLE_LIST *table_list, bool *need_prelocking); + +private: + Alter_info *m_alter_info; +}; + + inline bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags) { @@ -355,4 +439,84 @@ inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, &prelocking_strategy); } + +/** + A context of open_tables() function, used to recover + from a failed open_table() or open_routine() attempt. +*/ + +class Open_table_context +{ +public: + enum enum_open_table_action + { + OT_NO_ACTION= 0, + OT_WAIT_MDL_LOCK, + OT_WAIT_TDC, + OT_DISCOVER, + OT_REPAIR + }; + Open_table_context(THD *thd, ulong timeout); + + bool recover_from_failed_open(THD *thd); + bool request_backoff_action(enum_open_table_action action_arg, + MDL_request *mdl_request, TABLE_LIST *table); + + void add_request(MDL_request *request) + { m_mdl_requests.push_front(request); } + + bool can_recover_from_failed_open() const + { return m_action != OT_NO_ACTION; } + + /** + When doing a back-off, we close all tables acquired by this + statement. Return an MDL savepoint taken at the beginning of + the statement, so that we can rollback to it before waiting on + locks. + */ + MDL_ticket *start_of_statement_svp() const + { + return m_start_of_statement_svp; + } + + MDL_request *get_global_mdl_request(THD *thd); + + inline ulong get_timeout() const + { + return m_timeout; + } + +private: + /** List of requests for all locks taken so far. Used for waiting on locks. */ + MDL_request_list m_mdl_requests; + /** Back off action. */ + enum enum_open_table_action m_action; + /** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */ + MDL_request *m_failed_mdl_request; + /** + For OT_DISCOVER and OT_REPAIR actions, the table list element for + the table which definition should be re-discovered or which + should be repaired. + */ + TABLE_LIST *m_failed_table; + MDL_ticket *m_start_of_statement_svp; + /** + Whether we had any locks when this context was created. + If we did, they are from the previous statement of a transaction, + and we can't safely do back-off (and release them). + */ + bool m_has_locks; + /** + Request object for global intention exclusive lock which is acquired during + opening tables for statements which take upgradable shared metadata locks. + */ + MDL_request *m_global_mdl_request; + /** + Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system + tables or to the "lock_wait_timeout" system variable for regular tables. + */ + uint m_timeout; +}; + + #endif /* SQL_BASE_INCLUDED */ diff --git a/sql/sql_class.h b/sql/sql_class.h index d494fdf86b5..f662181d52b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1226,170 +1226,6 @@ private: }; -/** - An abstract class for a strategy specifying how the prelocking - algorithm should extend the prelocking set while processing - already existing elements in the set. -*/ - -class Prelocking_strategy -{ -public: - virtual ~Prelocking_strategy() { } - - virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, - Sroutine_hash_entry *rt, sp_head *sp, - bool *need_prelocking) = 0; - virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking) = 0; - virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking)= 0; -}; - - -/** - A Strategy for prelocking algorithm suitable for DML statements. - - Ensures that all tables used by all statement's SF/SP/triggers and - required for foreign key checks are prelocked and SF/SPs used are - cached. -*/ - -class DML_prelocking_strategy : public Prelocking_strategy -{ -public: - virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, - Sroutine_hash_entry *rt, sp_head *sp, - bool *need_prelocking); - virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking); - virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking); -}; - - -/** - A strategy for prelocking algorithm to be used for LOCK TABLES - statement. -*/ - -class Lock_tables_prelocking_strategy : public DML_prelocking_strategy -{ - virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking); -}; - - -/** - Strategy for prelocking algorithm to be used for ALTER TABLE statements. - - Unlike DML or LOCK TABLES strategy, it doesn't - prelock triggers, views or stored routines, since they are not - used during ALTER. -*/ - -class Alter_table_prelocking_strategy : public Prelocking_strategy -{ -public: - - Alter_table_prelocking_strategy(Alter_info *alter_info) - : m_alter_info(alter_info) - {} - - virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx, - Sroutine_hash_entry *rt, sp_head *sp, - bool *need_prelocking); - virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking); - virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx, - TABLE_LIST *table_list, bool *need_prelocking); - -private: - Alter_info *m_alter_info; -}; - - -/** - A context of open_tables() function, used to recover - from a failed open_table() or open_routine() attempt. - - Implemented in sql_base.cc. -*/ - -class Open_table_context -{ -public: - enum enum_open_table_action - { - OT_NO_ACTION= 0, - OT_WAIT_MDL_LOCK, - OT_WAIT_TDC, - OT_DISCOVER, - OT_REPAIR - }; - Open_table_context(THD *thd, ulong timeout); - - bool recover_from_failed_open(THD *thd); - bool request_backoff_action(enum_open_table_action action_arg, - MDL_request *mdl_request, TABLE_LIST *table); - - void add_request(MDL_request *request) - { m_mdl_requests.push_front(request); } - - bool can_recover_from_failed_open() const - { return m_action != OT_NO_ACTION; } - - /** - When doing a back-off, we close all tables acquired by this - statement. Return an MDL savepoint taken at the beginning of - the statement, so that we can rollback to it before waiting on - locks. - */ - MDL_ticket *start_of_statement_svp() const - { - return m_start_of_statement_svp; - } - - MDL_request *get_global_mdl_request(THD *thd); - - inline ulong get_timeout() const - { - return m_timeout; - } - -private: - /** List of requests for all locks taken so far. Used for waiting on locks. */ - MDL_request_list m_mdl_requests; - /** Back off action. */ - enum enum_open_table_action m_action; - /** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */ - MDL_request *m_failed_mdl_request; - /** - For OT_DISCOVER and OT_REPAIR actions, the table list element for - the table which definition should be re-discovered or which - should be repaired. - */ - TABLE_LIST *m_failed_table; - MDL_ticket *m_start_of_statement_svp; - /** - Whether we had any locks when this context was created. - If we did, they are from the previous statement of a transaction, - and we can't safely do back-off (and release them). - */ - bool m_has_locks; - /** - Request object for global intention exclusive lock which is acquired during - opening tables for statements which take upgradable shared metadata locks. - */ - MDL_request *m_global_mdl_request; - /** - Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system - tables or to the "lock_wait_timeout" system variable for regular tables. - */ - uint m_timeout; -}; - - /** Tables that were locked with LOCK TABLES statement. From 559e3889f24c19a89e294057c8ada3a8148e259f Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Tue, 1 Jun 2010 14:49:35 +0400 Subject: [PATCH 144/207] A follow up patch for the fix for Bug#51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Make open flags part of Open_table_context. This allows to simplify some code and (in future) enforce the invariant that we don't, say, request a back off on the table when there is MYSQL_OPEN_IGNORE_FLUSH flag. --- sql/sql_base.cc | 51 +++++++++++++++++++---------------------------- sql/sql_base.h | 25 +++++++++++++---------- sql/sql_insert.cc | 10 ++++------ sql/sql_table.cc | 25 ++++++++++------------- 4 files changed, 49 insertions(+), 62 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3949e14253f..6d7dab15053 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2491,12 +2491,13 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, - Open_table_context *ot_ctx, uint flags) + Open_table_context *ot_ctx) { reg1 TABLE *table; char key[MAX_DBKEY_LENGTH]; uint key_length; char *alias= table_list->alias; + uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; int error; TABLE_SHARE *share; @@ -2806,26 +2807,15 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (open_new_frm(thd, share, alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | - (flags & OPEN_VIEW_NO_PARSE), thd->open_options, + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, + thd->open_options, 0, table_list, mem_root)) goto err_unlock; /* TODO: Don't free this */ release_table_share(share); - if (flags & OPEN_VIEW_NO_PARSE) - { - /* - VIEW not really opened, only frm were read. - Set 1 as a flag here - */ - table_list->view= (LEX*)1; - } - else - { - DBUG_ASSERT(table_list->view); - } + DBUG_ASSERT(table_list->view); mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(FALSE); @@ -3358,7 +3348,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) bool Locked_tables_list::reopen_tables(THD *thd) { - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); size_t reopen_count= 0; MYSQL_LOCK *lock; MYSQL_LOCK *merged_lock; @@ -3370,8 +3360,7 @@ Locked_tables_list::reopen_tables(THD *thd) continue; /* Links into thd->open_tables upon success */ - if (open_table(thd, table_list, thd->mem_root, &ot_ctx_unused, - MYSQL_OPEN_REOPEN)) + if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) { unlink_all_closed_tables(thd, 0, reopen_count); return TRUE; @@ -3793,16 +3782,18 @@ end_with_lock_open: /** Open_table_context */ -Open_table_context::Open_table_context(THD *thd, ulong timeout) - :m_action(OT_NO_ACTION), - m_failed_mdl_request(NULL), +Open_table_context::Open_table_context(THD *thd, uint flags) + :m_failed_mdl_request(NULL), m_failed_table(NULL), m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()), + m_global_mdl_request(NULL), + m_timeout(flags & MYSQL_LOCK_IGNORE_TIMEOUT ? + LONG_TIMEOUT : thd->variables.lock_wait_timeout), + m_flags(flags), + m_action(OT_NO_ACTION), m_has_locks((thd->in_multi_stmt_transaction_mode() && thd->mdl_context.has_locks()) || - thd->mdl_context.trans_sentinel()), - m_global_mdl_request(NULL), - m_timeout(timeout) + thd->mdl_context.trans_sentinel()) {} @@ -4290,12 +4281,12 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, */ Prelock_error_handler prelock_handler; thd->push_internal_handler(& prelock_handler); - error= open_table(thd, tables, new_frm_mem, ot_ctx, flags); + error= open_table(thd, tables, new_frm_mem, ot_ctx); thd->pop_internal_handler(); safe_to_ignore_table= prelock_handler.safely_trapped_errors(); } else - error= open_table(thd, tables, new_frm_mem, ot_ctx, flags); + error= open_table(thd, tables, new_frm_mem, ot_ctx); free_root(new_frm_mem, MYF(MY_KEEP_PREALLOC)); @@ -4610,8 +4601,7 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, TABLE_LIST **table_to_open; Sroutine_hash_entry **sroutine_to_open; TABLE_LIST *tables; - Open_table_context ot_ctx(thd, (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ? - LONG_TIMEOUT : thd->variables.lock_wait_timeout); + Open_table_context ot_ctx(thd, flags); bool error= FALSE; MEM_ROOT new_frm_mem; bool has_prelocking_list; @@ -5183,8 +5173,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, uint lock_flags) { TABLE *table; - Open_table_context ot_ctx(thd, (lock_flags & MYSQL_LOCK_IGNORE_TIMEOUT) ? - LONG_TIMEOUT : thd->variables.lock_wait_timeout); + Open_table_context ot_ctx(thd, lock_flags); bool error; DBUG_ENTER("open_ltable"); @@ -5199,7 +5188,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, /* This function can't properly handle requests for such metadata locks. */ DBUG_ASSERT(table_list->mdl_request.type < MDL_SHARED_NO_WRITE); - while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx, lock_flags)) && + while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx)) && ot_ctx.can_recover_from_failed_open()) { /* diff --git a/sql/sql_base.h b/sql/sql_base.h index a0a1ef856a6..f5751094ee0 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -89,7 +89,7 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, uint lock_flags); bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, - Open_table_context *ot_ctx, uint flags); + Open_table_context *ot_ctx); bool name_lock_locked_table(THD *thd, TABLE_LIST *tables); bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in); TABLE *table_cache_insert_placeholder(THD *thd, const char *key, @@ -456,7 +456,7 @@ public: OT_DISCOVER, OT_REPAIR }; - Open_table_context(THD *thd, ulong timeout); + Open_table_context(THD *thd, uint flags); bool recover_from_failed_open(THD *thd); bool request_backoff_action(enum_open_table_action action_arg, @@ -486,11 +486,10 @@ public: return m_timeout; } + uint get_flags() const { return m_flags; } private: /** List of requests for all locks taken so far. Used for waiting on locks. */ MDL_request_list m_mdl_requests; - /** Back off action. */ - enum enum_open_table_action m_action; /** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */ MDL_request *m_failed_mdl_request; /** @@ -500,12 +499,6 @@ private: */ TABLE_LIST *m_failed_table; MDL_ticket *m_start_of_statement_svp; - /** - Whether we had any locks when this context was created. - If we did, they are from the previous statement of a transaction, - and we can't safely do back-off (and release them). - */ - bool m_has_locks; /** Request object for global intention exclusive lock which is acquired during opening tables for statements which take upgradable shared metadata locks. @@ -515,7 +508,17 @@ private: Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system tables or to the "lock_wait_timeout" system variable for regular tables. */ - uint m_timeout; + ulong m_timeout; + /* open_table() flags. */ + uint m_flags; + /** Back off action. */ + enum enum_open_table_action m_action; + /** + Whether we had any locks when this context was created. + If we did, they are from the previous statement of a transaction, + and we can't safely do back-off (and release them). + */ + bool m_has_locks; }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1f9d69a798e..002180c74df 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3608,13 +3608,12 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); /* Here we open the destination table, on which we already have an exclusive metadata lock. */ - if (open_table(thd, create_table, thd->mem_root, - &ot_ctx_unused, MYSQL_OPEN_REOPEN)) + if (open_table(thd, create_table, thd->mem_root, &ot_ctx)) { mysql_mutex_lock(&LOCK_open); quick_rm_table(create_info->db_type, create_table->db, @@ -3627,9 +3626,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } else { - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); - if (open_table(thd, create_table, thd->mem_root, &ot_ctx_unused, - MYSQL_OPEN_TEMPORARY_ONLY)) + Open_table_context ot_ctx(thd, MYSQL_OPEN_TEMPORARY_ONLY); + if (open_table(thd, create_table, thd->mem_root, &ot_ctx)) { /* This shouldn't happen as creation of temporary table should make diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 113da3fe719..a3baeffa8a0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4426,10 +4426,10 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, char from[FN_REFLEN],tmp[FN_REFLEN+32]; const char **ext; MY_STAT stat_info; - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH | + MYSQL_OPEN_HAS_MDL_LOCK | + MYSQL_LOCK_IGNORE_TIMEOUT)); DBUG_ENTER("prepare_for_repair"); - uint reopen_for_repair_flags= (MYSQL_OPEN_IGNORE_FLUSH | - MYSQL_OPEN_HAS_MDL_LOCK); if (!(check_opt->sql_flags & TT_USEFRM)) DBUG_RETURN(0); @@ -4584,8 +4584,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, Now we should be able to open the partially repaired table to finish the repair in the handler later on. */ - if (open_table(thd, table_list, thd->mem_root, - &ot_ctx_unused, reopen_for_repair_flags)) + if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) { error= send_check_errmsg(thd, table_list, "repair", "Failed to open partially repaired table"); @@ -5374,7 +5373,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, char buf[2048]; String query(buf, sizeof(buf), system_charset_info); query.length(0); // Have to zero it since constructor doesn't - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); /* The condition avoids a crash as described in BUG#48506. Other @@ -5389,8 +5388,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, to work. The table will be closed by close_thread_table() at the end of this branch. */ - if (open_table(thd, table, thd->mem_root, &ot_ctx_unused, - MYSQL_OPEN_REOPEN)) + if (open_table(thd, table, thd->mem_root, &ot_ctx)) goto err; int result __attribute__((unused))= @@ -7139,14 +7137,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (table->s->tmp_table) { - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH | + MYSQL_LOCK_IGNORE_TIMEOUT)); TABLE_LIST tbl; bzero((void*) &tbl, sizeof(tbl)); tbl.db= new_db; tbl.table_name= tbl.alias= tmp_name; /* Table is in thd->temporary_tables */ - (void) open_table(thd, &tbl, thd->mem_root, &ot_ctx_unused, - MYSQL_OPEN_IGNORE_FLUSH); + (void) open_table(thd, &tbl, thd->mem_root, &ot_ctx); new_table= tbl.table; } else @@ -7425,7 +7423,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, To do this we need to obtain a handler object for it. NO need to tamper with MERGE tables. The real open is done later. */ - Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); TABLE *t_table; if (new_name != table_name || new_db != db) { @@ -7445,8 +7443,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, */ table_list->mdl_request.ticket= mdl_ticket; } - if (open_table(thd, table_list, thd->mem_root, - &ot_ctx_unused, MYSQL_OPEN_REOPEN)) + if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) { goto err_with_mdl; } From f3e12c7567cd11fcf118adb14d9fc22f84a51b84 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 2 Jun 2010 12:06:07 +0400 Subject: [PATCH 145/207] Add comments to a few MDL deadlock-search related variables and methods. --- sql/mdl.cc | 12 +++++++++++- sql/mdl.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sql/mdl.cc b/sql/mdl.cc index ba938f8714b..b3702997168 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -119,8 +119,18 @@ public: victim(NULL), current_search_depth(0) { } + /** + The context which has initiated the search. There + can be multiple searches happening in parallel at the same time. + */ MDL_context *start; + /** If a deadlock is found, the context that identifies the victim. */ MDL_context *victim; + /** Set to the MAX_SEARCH_DEPTH at start. Decreased whenever + we descend into another MDL context (aka traverse to the next + wait-for graph node). When 0 is reached, we assume that + a deadlock is found, even if we have not found a loop. + */ uint current_search_depth; /** Maximum depth for deadlock searches. After this depth is @@ -408,7 +418,7 @@ mdl_locks_key(const uchar *record, size_t *length, statement, the design capitalizes on that to later save on look ups in the table definition cache. This leads to reduced contention overall and on LOCK_open in particular. - Please see the description of MDL_context::acquire_shared_lock() + Please see the description of MDL_context::acquire_lock_impl() for details. */ diff --git a/sql/mdl.h b/sql/mdl.h index 2e296b73057..1a123d5baa9 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -322,6 +322,7 @@ public: DBUG_ASSERT(ticket == NULL); type= type_arg; } + /* A helper used to determine which lock request should be aborted. */ uint get_deadlock_weight() const; static MDL_request *create(MDL_key::enum_mdl_namespace mdl_namespace, From e8e1ea917c95259b280a39ea887092e1a56b546f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 2 Jun 2010 15:49:05 +0300 Subject: [PATCH 146/207] Adjust .bzr-mysql/default.conf that was reverted by a recent bzr pull --- .bzr-mysql/default.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 4eab3d239d0..df9a60f35ad 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-trunk-bugfixing" +post_commit_to = commits@lists.mysql.com, innodb_dev_ww@oracle.com +post_push_to = commits@lists.mysql.com, innodb_dev_ww@oracle.com +tree_name = "mysql-trunk-innodb" From 9cd413929b9f8f73bd8b959d3ef4526a2ffd814f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Jun 2010 13:28:40 +0300 Subject: [PATCH 147/207] Merge a change from mysql-5.1-innodb: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------------------------------------------------------ revno: 3500 revision-id: marko.makela@oracle.com-20100603095032-v5ptkkzt1bhz0m1d parent: marko.makela@oracle.com-20100603094859-8cibt7xns239jjvc committer: Marko Mäkelä branch nick: 5.1-innodb timestamp: Thu 2010-06-03 12:50:32 +0300 message: Move some InnoDB tests to mysql-test/suite/innodb. --- mysql-test/{ => suite/innodb}/r/innodb-autoinc-optimize.result | 0 mysql-test/{ => suite/innodb}/r/innodb-ucs2.result | 0 .../{ => suite/innodb}/r/innodb_autoinc_lock_mode_zero.result | 0 mysql-test/{ => suite/innodb}/r/innodb_bug30919.result | 0 mysql-test/{ => suite/innodb}/r/innodb_bug42419.result | 0 mysql-test/{ => suite/innodb}/r/innodb_gis.result | 0 mysql-test/{ => suite/innodb}/r/innodb_lock_wait_timeout_1.result | 0 mysql-test/{ => suite/innodb}/r/innodb_mysql.result | 0 mysql-test/{ => suite/innodb}/r/innodb_mysql_rbk.result | 0 mysql-test/{ => suite/innodb}/r/innodb_notembedded.result | 0 mysql-test/{ => suite/innodb}/r/innodb_timeout_rollback.result | 0 mysql-test/{ => suite/innodb}/t/innodb-autoinc-optimize.test | 0 mysql-test/{ => suite/innodb}/t/innodb-ucs2.test | 0 .../{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero-master.opt | 0 .../{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero.test | 0 mysql-test/{ => suite/innodb}/t/innodb_bug30919-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_bug30919.test | 0 mysql-test/{ => suite/innodb}/t/innodb_bug42419.test | 0 mysql-test/{ => suite/innodb}/t/innodb_gis.test | 0 .../{ => suite/innodb}/t/innodb_lock_wait_timeout_1-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1.test | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql.test | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk.test | 0 mysql-test/{ => suite/innodb}/t/innodb_notembedded.test | 0 .../{ => suite/innodb}/t/innodb_timeout_rollback-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback.test | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename mysql-test/{ => suite/innodb}/r/innodb-autoinc-optimize.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb-ucs2.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_autoinc_lock_mode_zero.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_bug30919.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_bug42419.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_gis.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_lock_wait_timeout_1.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_mysql.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_mysql_rbk.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_notembedded.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_timeout_rollback.result (100%) rename mysql-test/{ => suite/innodb}/t/innodb-autoinc-optimize.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb-ucs2.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug30919-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug30919.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug42419.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_gis.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_notembedded.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback.test (100%) diff --git a/mysql-test/r/innodb-autoinc-optimize.result b/mysql-test/suite/innodb/r/innodb-autoinc-optimize.result similarity index 100% rename from mysql-test/r/innodb-autoinc-optimize.result rename to mysql-test/suite/innodb/r/innodb-autoinc-optimize.result diff --git a/mysql-test/r/innodb-ucs2.result b/mysql-test/suite/innodb/r/innodb-ucs2.result similarity index 100% rename from mysql-test/r/innodb-ucs2.result rename to mysql-test/suite/innodb/r/innodb-ucs2.result diff --git a/mysql-test/r/innodb_autoinc_lock_mode_zero.result b/mysql-test/suite/innodb/r/innodb_autoinc_lock_mode_zero.result similarity index 100% rename from mysql-test/r/innodb_autoinc_lock_mode_zero.result rename to mysql-test/suite/innodb/r/innodb_autoinc_lock_mode_zero.result diff --git a/mysql-test/r/innodb_bug30919.result b/mysql-test/suite/innodb/r/innodb_bug30919.result similarity index 100% rename from mysql-test/r/innodb_bug30919.result rename to mysql-test/suite/innodb/r/innodb_bug30919.result diff --git a/mysql-test/r/innodb_bug42419.result b/mysql-test/suite/innodb/r/innodb_bug42419.result similarity index 100% rename from mysql-test/r/innodb_bug42419.result rename to mysql-test/suite/innodb/r/innodb_bug42419.result diff --git a/mysql-test/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result similarity index 100% rename from mysql-test/r/innodb_gis.result rename to mysql-test/suite/innodb/r/innodb_gis.result diff --git a/mysql-test/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result similarity index 100% rename from mysql-test/r/innodb_lock_wait_timeout_1.result rename to mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result similarity index 100% rename from mysql-test/r/innodb_mysql.result rename to mysql-test/suite/innodb/r/innodb_mysql.result diff --git a/mysql-test/r/innodb_mysql_rbk.result b/mysql-test/suite/innodb/r/innodb_mysql_rbk.result similarity index 100% rename from mysql-test/r/innodb_mysql_rbk.result rename to mysql-test/suite/innodb/r/innodb_mysql_rbk.result diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/suite/innodb/r/innodb_notembedded.result similarity index 100% rename from mysql-test/r/innodb_notembedded.result rename to mysql-test/suite/innodb/r/innodb_notembedded.result diff --git a/mysql-test/r/innodb_timeout_rollback.result b/mysql-test/suite/innodb/r/innodb_timeout_rollback.result similarity index 100% rename from mysql-test/r/innodb_timeout_rollback.result rename to mysql-test/suite/innodb/r/innodb_timeout_rollback.result diff --git a/mysql-test/t/innodb-autoinc-optimize.test b/mysql-test/suite/innodb/t/innodb-autoinc-optimize.test similarity index 100% rename from mysql-test/t/innodb-autoinc-optimize.test rename to mysql-test/suite/innodb/t/innodb-autoinc-optimize.test diff --git a/mysql-test/t/innodb-ucs2.test b/mysql-test/suite/innodb/t/innodb-ucs2.test similarity index 100% rename from mysql-test/t/innodb-ucs2.test rename to mysql-test/suite/innodb/t/innodb-ucs2.test diff --git a/mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt b/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt similarity index 100% rename from mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt rename to mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt diff --git a/mysql-test/t/innodb_autoinc_lock_mode_zero.test b/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero.test similarity index 100% rename from mysql-test/t/innodb_autoinc_lock_mode_zero.test rename to mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero.test diff --git a/mysql-test/t/innodb_bug30919-master.opt b/mysql-test/suite/innodb/t/innodb_bug30919-master.opt similarity index 100% rename from mysql-test/t/innodb_bug30919-master.opt rename to mysql-test/suite/innodb/t/innodb_bug30919-master.opt diff --git a/mysql-test/t/innodb_bug30919.test b/mysql-test/suite/innodb/t/innodb_bug30919.test similarity index 100% rename from mysql-test/t/innodb_bug30919.test rename to mysql-test/suite/innodb/t/innodb_bug30919.test diff --git a/mysql-test/t/innodb_bug42419.test b/mysql-test/suite/innodb/t/innodb_bug42419.test similarity index 100% rename from mysql-test/t/innodb_bug42419.test rename to mysql-test/suite/innodb/t/innodb_bug42419.test diff --git a/mysql-test/t/innodb_gis.test b/mysql-test/suite/innodb/t/innodb_gis.test similarity index 100% rename from mysql-test/t/innodb_gis.test rename to mysql-test/suite/innodb/t/innodb_gis.test diff --git a/mysql-test/t/innodb_lock_wait_timeout_1-master.opt b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt similarity index 100% rename from mysql-test/t/innodb_lock_wait_timeout_1-master.opt rename to mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt diff --git a/mysql-test/t/innodb_lock_wait_timeout_1.test b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test similarity index 100% rename from mysql-test/t/innodb_lock_wait_timeout_1.test rename to mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/suite/innodb/t/innodb_mysql-master.opt similarity index 100% rename from mysql-test/t/innodb_mysql-master.opt rename to mysql-test/suite/innodb/t/innodb_mysql-master.opt diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test similarity index 100% rename from mysql-test/t/innodb_mysql.test rename to mysql-test/suite/innodb/t/innodb_mysql.test diff --git a/mysql-test/t/innodb_mysql_rbk-master.opt b/mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt similarity index 100% rename from mysql-test/t/innodb_mysql_rbk-master.opt rename to mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt diff --git a/mysql-test/t/innodb_mysql_rbk.test b/mysql-test/suite/innodb/t/innodb_mysql_rbk.test similarity index 100% rename from mysql-test/t/innodb_mysql_rbk.test rename to mysql-test/suite/innodb/t/innodb_mysql_rbk.test diff --git a/mysql-test/t/innodb_notembedded.test b/mysql-test/suite/innodb/t/innodb_notembedded.test similarity index 100% rename from mysql-test/t/innodb_notembedded.test rename to mysql-test/suite/innodb/t/innodb_notembedded.test diff --git a/mysql-test/t/innodb_timeout_rollback-master.opt b/mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt similarity index 100% rename from mysql-test/t/innodb_timeout_rollback-master.opt rename to mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt diff --git a/mysql-test/t/innodb_timeout_rollback.test b/mysql-test/suite/innodb/t/innodb_timeout_rollback.test similarity index 100% rename from mysql-test/t/innodb_timeout_rollback.test rename to mysql-test/suite/innodb/t/innodb_timeout_rollback.test From cf8de25318003534d5542d96159bac9ff2f45726 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 3 Jun 2010 06:37:01 -0700 Subject: [PATCH 148/207] Remove the unneccesary innobase_strcasecmp() in innobase_get_mysql_key_number_for_index() created as a bug fix for #53592 since dict_table_t could already unique identify the table. --- storage/innobase/handler/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 86246e62eee..21d30dc4904 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7610,8 +7610,7 @@ innobase_get_mysql_key_number_for_index( /* If index does not belong to the table of share structure. Search index->table instead */ - if (index->table != ib_table - && innobase_strcasecmp(index->table->name, share->table_name)) { + if (index->table != ib_table) { i = 0; ind = dict_table_get_first_index(index->table); From f29298d91cba86c5181a449719a03712da539fec Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 3 Jun 2010 18:08:22 +0400 Subject: [PATCH 149/207] A code review comment for Bug#52289. Encapsulate the deadlock detection functionality into a visitor class, and separate it from the wait-for graph traversal code. Use "Internal iterator" and "Visitor" patterns to achieve the desired separation of responsibilities. Add comments. --- sql/mdl.cc | 258 +++++++++++++++++++++++++++++++++++++---------------- sql/mdl.h | 23 ++--- 2 files changed, 189 insertions(+), 92 deletions(-) diff --git a/sql/mdl.cc b/sql/mdl.cc index b3702997168..75970396af7 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -105,33 +105,46 @@ enum enum_deadlock_weight }; - /** A context of the recursive traversal through all contexts in all sessions in search for deadlock. */ -class Deadlock_detection_context +class Deadlock_detection_visitor { public: - Deadlock_detection_context(MDL_context *start_arg) - : start(start_arg), - victim(NULL), - current_search_depth(0) - { } + Deadlock_detection_visitor(MDL_context *start_node_arg) + : m_start_node(start_node_arg), + m_victim(NULL), + m_current_search_depth(0) + {} + bool enter_node(MDL_context * /* unused */); + void leave_node(MDL_context * /* unused */); + + bool inspect_edge(MDL_context *dest); + + MDL_context *get_victim() const { return m_victim; } + + /** + Change the deadlock victim to a new one if it has lower deadlock + weight. + */ + MDL_context *opt_change_victim_to(MDL_context *new_victim); +private: /** The context which has initiated the search. There can be multiple searches happening in parallel at the same time. */ - MDL_context *start; + MDL_context *m_start_node; /** If a deadlock is found, the context that identifies the victim. */ - MDL_context *victim; - /** Set to the MAX_SEARCH_DEPTH at start. Decreased whenever + MDL_context *m_victim; + /** Set to the 0 at start. Increased whenever we descend into another MDL context (aka traverse to the next - wait-for graph node). When 0 is reached, we assume that - a deadlock is found, even if we have not found a loop. + wait-for graph node). When MAX_SEARCH_DEPTH is reached, we + assume that a deadlock is found, even if we have not found a + loop. */ - uint current_search_depth; + uint m_current_search_depth; /** Maximum depth for deadlock searches. After this depth is achieved we will unconditionally declare that there is a @@ -149,6 +162,74 @@ public: }; +/** + Enter a node of a wait-for graph. After + a node is entered, inspect_edge() will be called + for all wait-for destinations of this node. Then + leave_node() will be called. + We call "enter_node()" for all nodes we inspect, + including the starting node. + + @retval TRUE Maximum search depth exceeded. + @retval FALSE OK. +*/ + +bool Deadlock_detection_visitor::enter_node(MDL_context * /* unused */) +{ + if (++m_current_search_depth >= MAX_SEARCH_DEPTH) + return TRUE; + return FALSE; +} + + +/** + Done inspecting this node. Decrease the search + depth. Clear the node for debug safety. +*/ + +void Deadlock_detection_visitor::leave_node(MDL_context * /* unused */) +{ + --m_current_search_depth; +} + + +/** + Inspect a wait-for graph edge from one MDL context to another. + + @retval TRUE A loop is found. + @retval FALSE No loop is found. +*/ + +bool Deadlock_detection_visitor::inspect_edge(MDL_context *node) +{ + return node == m_start_node; +} + + +/** + Change the deadlock victim to a new one if it has lower deadlock + weight. + + @retval new_victim Victim is not changed. + @retval !new_victim New victim became the current. +*/ + +MDL_context * +Deadlock_detection_visitor::opt_change_victim_to(MDL_context *new_victim) +{ + if (m_victim == NULL || + m_victim->get_deadlock_weight() >= new_victim->get_deadlock_weight()) + { + /* Swap victims, unlock the old one. */ + MDL_context *tmp= m_victim; + m_victim= new_victim; + return tmp; + } + /* No change, unlock the current context. */ + return new_victim; +} + + /** Get a bit corresponding to enum_mdl_type value in a granted/waiting bitmaps and compatibility matrices. @@ -282,7 +363,7 @@ public: void remove_ticket(Ticket_list MDL_lock::*queue, MDL_ticket *ticket); bool find_deadlock(MDL_ticket *waiting_ticket, - Deadlock_detection_context *deadlock_ctx); + Deadlock_detection_visitor *dvisitor); /** List of granted tickets for this lock. */ Ticket_list m_granted; @@ -760,13 +841,6 @@ MDL_request::create(MDL_key::enum_mdl_namespace mdl_namespace, const char *db, } -uint MDL_request::get_deadlock_weight() const -{ - return key.mdl_namespace() == MDL_key::GLOBAL || - type > MDL_SHARED_NO_WRITE ? - MDL_DEADLOCK_WEIGHT_DDL : MDL_DEADLOCK_WEIGHT_DML; -} - /** Auxiliary functions needed for creation/destruction of MDL_lock objects. @@ -814,6 +888,21 @@ void MDL_ticket::destroy(MDL_ticket *ticket) } +/** + Return the 'weight' of this ticket for the + victim selection algorithm. Requests with + lower weight are preferred to requests + with higher weight when choosing a victim. +*/ + +uint MDL_ticket::get_deadlock_weight() const +{ + return (m_lock->key.mdl_namespace() == MDL_key::GLOBAL || + m_type > MDL_SHARED_NO_WRITE ? + MDL_DEADLOCK_WEIGHT_DDL : MDL_DEADLOCK_WEIGHT_DML); +} + + /** Helper functions and macros to be used for killable waiting in metadata locking subsystem. @@ -1549,7 +1638,6 @@ bool MDL_context::acquire_lock_impl(MDL_request *mdl_request, mysql_prlock_unlock(&lock->m_rwlock); - set_deadlock_weight(mdl_request->get_deadlock_weight()); will_wait_for(ticket); /* There is a shared or exclusive lock on the object. */ @@ -1761,46 +1849,56 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket, bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, - Deadlock_detection_context *deadlock_ctx) + Deadlock_detection_visitor *dvisitor) { MDL_ticket *ticket; - bool result= FALSE; - - mysql_prlock_rdlock(&m_rwlock); - + MDL_context *src_ctx= waiting_ticket->get_ctx(); + bool result= TRUE; Ticket_iterator granted_it(m_granted); Ticket_iterator waiting_it(m_waiting); + + if (dvisitor->enter_node(src_ctx)) + return TRUE; + + mysql_prlock_rdlock(&m_rwlock); + + /* + We do a breadth-first search first -- that is, inspect all + edges of the current node, and only then follow up to the next + node. In workloads that involve wait-for graph loops this + has proven to be a more efficient strategy [citation missing]. + */ while ((ticket= granted_it++)) { - if (ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && - ticket->get_ctx() != waiting_ticket->get_ctx() && - ticket->get_ctx() == deadlock_ctx->start) + /* Filter out edges that point to the same node. */ + if (ticket->get_ctx() != src_ctx && + ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && + dvisitor->inspect_edge(ticket->get_ctx())) { - result= TRUE; goto end; } } while ((ticket= waiting_it++)) { - if (ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && - ticket->get_ctx() != waiting_ticket->get_ctx() && - ticket->get_ctx() == deadlock_ctx->start) + /* Filter out edges that point to the same node. */ + if (ticket->get_ctx() != src_ctx && + ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && + dvisitor->inspect_edge(ticket->get_ctx())) { - result= TRUE; goto end; } } + /* Recurse and inspect all adjacent nodes. */ granted_it.rewind(); while ((ticket= granted_it++)) { - if (ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && - ticket->get_ctx() != waiting_ticket->get_ctx() && - ticket->get_ctx()->find_deadlock(deadlock_ctx)) + if (ticket->get_ctx() != src_ctx && + ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && + ticket->get_ctx()->find_deadlock(dvisitor)) { - result= TRUE; goto end; } } @@ -1808,23 +1906,34 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, waiting_it.rewind(); while ((ticket= waiting_it++)) { - if (ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && - ticket->get_ctx() != waiting_ticket->get_ctx() && - ticket->get_ctx()->find_deadlock(deadlock_ctx)) + if (ticket->get_ctx() != src_ctx && + ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && + ticket->get_ctx()->find_deadlock(dvisitor)) { - result= TRUE; goto end; } } + result= FALSE; end: mysql_prlock_unlock(&m_rwlock); + dvisitor->leave_node(src_ctx); return result; } -bool MDL_context::find_deadlock(Deadlock_detection_context *deadlock_ctx) +/** + Recursively traverse the wait-for graph of MDL contexts + in search for deadlocks. + + @retval TRUE A deadlock is found. A victim is remembered + by the visitor. + @retval FALSE +*/ + +bool MDL_context::find_deadlock(Deadlock_detection_visitor *dvisitor) { + MDL_context *m_unlock_ctx= this; bool result= FALSE; mysql_prlock_rdlock(&m_waiting_for_lock); @@ -1839,57 +1948,55 @@ bool MDL_context::find_deadlock(Deadlock_detection_context *deadlock_ctx) */ if (peek_signal() != VICTIM_WAKE_UP) { - - if (++deadlock_ctx->current_search_depth > - deadlock_ctx->MAX_SEARCH_DEPTH) - result= TRUE; - else - result= m_waiting_for->m_lock->find_deadlock(m_waiting_for, - deadlock_ctx); - --deadlock_ctx->current_search_depth; + result= m_waiting_for->m_lock->find_deadlock(m_waiting_for, dvisitor); + if (result) + m_unlock_ctx= dvisitor->opt_change_victim_to(this); } } - - if (result) - { - if (! deadlock_ctx->victim) - deadlock_ctx->victim= this; - else if (deadlock_ctx->victim->m_deadlock_weight >= m_deadlock_weight) - { - mysql_prlock_unlock(&deadlock_ctx->victim->m_waiting_for_lock); - deadlock_ctx->victim= this; - } - else - mysql_prlock_unlock(&m_waiting_for_lock); - } - else - mysql_prlock_unlock(&m_waiting_for_lock); + /* + We may recurse into the same MDL_context more than once + in case this is not the starting node. Make sure we release the + read lock as it's been taken, except for 1 read lock for + the deadlock victim. + */ + if (m_unlock_ctx) + mysql_prlock_unlock(&m_unlock_ctx->m_waiting_for_lock); return result; } +/** + Try to find a deadlock. This function produces no errors. + + @retval TRUE A deadlock is found. + @retval FALSE No deadlock found. +*/ + bool MDL_context::find_deadlock() { while (1) { + MDL_context *victim; /* - The fact that we use fresh instance of deadlock_ctx for each + The fact that we use fresh instance of dvisitor for each search performed by find_deadlock() below is important, code responsible for victim selection relies on this. */ - Deadlock_detection_context deadlock_ctx(this); + Deadlock_detection_visitor dvisitor(this); - if (! find_deadlock(&deadlock_ctx)) + if (! find_deadlock(&dvisitor)) { /* No deadlocks are found! */ break; } - if (deadlock_ctx.victim != this) + victim= dvisitor.get_victim(); + + if (victim != this) { - deadlock_ctx.victim->awake(VICTIM_WAKE_UP); - mysql_prlock_unlock(&deadlock_ctx.victim->m_waiting_for_lock); + victim->awake(VICTIM_WAKE_UP); + mysql_prlock_unlock(&victim->m_waiting_for_lock); /* After adding new arc to waiting graph we found that it participates in some loop (i.e. there is a deadlock). We decided to destroy this @@ -1901,8 +2008,8 @@ bool MDL_context::find_deadlock() } else { - DBUG_ASSERT(&deadlock_ctx.victim->m_waiting_for_lock == &m_waiting_for_lock); - mysql_prlock_unlock(&deadlock_ctx.victim->m_waiting_for_lock); + DBUG_ASSERT(&victim->m_waiting_for_lock == &m_waiting_for_lock); + mysql_prlock_unlock(&victim->m_waiting_for_lock); return TRUE; } } @@ -1977,7 +2084,6 @@ MDL_context::wait_for_lock(MDL_request *mdl_request, ulong lock_wait_timeout) wait_reset(); mysql_prlock_unlock(&lock->m_rwlock); - set_deadlock_weight(MDL_DEADLOCK_WEIGHT_DML); will_wait_for(pending_ticket); bool is_deadlock= find_deadlock(); diff --git a/sql/mdl.h b/sql/mdl.h index 1a123d5baa9..0710155d10c 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -34,7 +34,7 @@ class THD; class MDL_context; class MDL_lock; class MDL_ticket; -class Deadlock_detection_context; +class Deadlock_detection_visitor; /** Type of metadata lock request. @@ -322,9 +322,6 @@ public: DBUG_ASSERT(ticket == NULL); type= type_arg; } - /* A helper used to determine which lock request should be aborted. */ - uint get_deadlock_weight() const; - static MDL_request *create(MDL_key::enum_mdl_namespace mdl_namespace, const char *db, const char *name, enum_mdl_type mdl_type, MEM_ROOT *root); @@ -418,6 +415,8 @@ public: bool is_incompatible_when_granted(enum_mdl_type type) const; bool is_incompatible_when_waiting(enum_mdl_type type) const; + /* A helper used to determine which lock request should be aborted. */ + uint get_deadlock_weight() const; private: friend class MDL_context; @@ -529,6 +528,9 @@ public: inline THD *get_thd() const { return m_thd; } + /** @pre Only valid if we started waiting for lock. */ + inline uint get_deadlock_weight() const + { return m_waiting_for->get_deadlock_weight(); } /** Wake up context which is waiting for a change of MDL_lock state. */ @@ -559,7 +561,7 @@ public: return m_needs_thr_lock_abort; } - bool find_deadlock(Deadlock_detection_context *deadlock_ctx); + bool find_deadlock(Deadlock_detection_visitor *dvisitor); private: /** All MDL tickets acquired by this connection. @@ -670,17 +672,6 @@ private: mysql_prlock_unlock(&m_waiting_for_lock); } - void set_deadlock_weight(uint weight) - { - /* - m_deadlock_weight should not be modified while m_waiting_for is - non-NULL as in this case this context might participate in deadlock - and so m_deadlock_weight can be accessed from other threads. - */ - DBUG_ASSERT(m_waiting_for == NULL); - m_deadlock_weight= weight; - } - void stop_waiting() { mysql_prlock_wrlock(&m_waiting_for_lock); From ec97ce952e319049b183d711ea5f847352b072c3 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 3 Jun 2010 18:32:56 +0400 Subject: [PATCH 150/207] A follow up for the previous patch, titled: A code review comment for Bug#52289. Encapsulate the deadlock detection functionality into a visitor class... Remove a race introduced by omission: initialize iterators under a read lock on the object. --- sql/mdl.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/mdl.cc b/sql/mdl.cc index 75970396af7..68ac0cc599d 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1854,15 +1854,16 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, MDL_ticket *ticket; MDL_context *src_ctx= waiting_ticket->get_ctx(); bool result= TRUE; - Ticket_iterator granted_it(m_granted); - Ticket_iterator waiting_it(m_waiting); - if (dvisitor->enter_node(src_ctx)) return TRUE; mysql_prlock_rdlock(&m_rwlock); + /* Must be initialized after taking a read lock. */ + Ticket_iterator granted_it(m_granted); + Ticket_iterator waiting_it(m_waiting); + /* We do a breadth-first search first -- that is, inspect all edges of the current node, and only then follow up to the next From 571acc878b4ff884e78c2a8373a9c22660ea180d Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Mon, 7 Jun 2010 11:06:55 +0400 Subject: [PATCH 151/207] Patch that changes approach to how we acquire metadata locks for DML statements and changes the way MDL locks are acquired/granted in contended case. Instead of backing-off when a lock conflict is encountered and waiting for it to go away before restarting open_tables() process we now wait for lock to be released without releasing any previously acquired locks. If conflicting lock goes away we resume opening tables. If waiting leads to a deadlock we try to resolve it by backing-off and restarting open_tables() immediately. As result both waiting for possibility to acquire and acquiring of a metadata lock now always happen within the same MDL API call. This has allowed to make release of a lock and granting it to the most appropriate pending request an atomic operation. Thanks to this it became possible to wake up during release of lock only those waiters which requests can be satisfied at the moment as well as wake up only one waiter in case when granting its request would prevent all other requests from being satisfied. This solves thundering herd problem which occured in cases when we were releasing some lock and woke up many waiters for SNRW or X locks (this was the issue in bug#52289 "performance regression for MyISAM in sysbench OLTP_RW test". This also allowed to implement more fair (FIFO) scheduling among waiters with the same priority. It also opens the door for introducing new types of requests for metadata locks such as low-prio SNRW lock which is necessary in order to support LOCK TABLES LOW_PRIORITY WRITE. Notice that after this sometimes can report ER_LOCK_DEADLOCK error in cases in which it has not happened before. Particularly we will always report this error if waiting for conflicting lock has happened in the middle of transaction and resulted in a deadlock. Before this patch the error was not reported if deadlock could have been resolved by backing off all metadata locks acquired by the current statement. --- mysql-test/r/mdl_sync.result | 95 ++- mysql-test/r/sp_sync.result | 31 +- .../perfschema/r/dml_setup_instruments.result | 2 +- mysql-test/suite/rpl/r/rpl_sp.result | 13 +- mysql-test/suite/rpl/t/rpl_sp.test | 16 +- mysql-test/t/mdl_sync.test | 133 ++- mysql-test/t/sp_sync.test | 35 +- sql/mdl.cc | 770 +++++++++++------- sql/mdl.h | 120 +-- sql/sql_base.cc | 250 ++++-- sql/sql_base.h | 6 +- sql/sql_plist.h | 100 ++- sql/sql_show.cc | 26 +- 13 files changed, 1076 insertions(+), 521 deletions(-) diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index f8b8d3f9d56..67d778211dd 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -1765,6 +1765,7 @@ drop tables t1, t2; # locking subsystem. # drop tables if exists t0, t1, t2, t3, t4, t5; +set debug_sync= 'RESET'; create table t1 (i int); create table t2 (j int); create table t3 (k int); @@ -1943,6 +1944,98 @@ commit; # Reap ALTER TABLE ... RENAME. drop table t2; # +# Test that in situation when MDL subsystem detects a deadlock +# but it turns out that it can be resolved by backing-off locks +# acquired by one of participating transactions (which is +# possible when one of transactions consists only of currently +# executed statement, e.g. in autocommit mode) no error is +# reported. +# +create table t1 (i int); +create table t2 (j int); +# Ensure that the below SELECT stops once it has acquired metadata +# lock on table 't2'. +set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +# Sending: +select * from t2, t1; +# +# Switching to connection 'deadlock_con1'. +# Wait till SELECT acquires MDL on 't2' and starts waiting for signal. +set debug_sync= 'now WAIT_FOR locked'; +# Sending: +lock tables t1 write, t2 write; +# +# Switching to connection 'deadlock_con2'. +# Wait until LOCK TABLES acquires SNRW lock on 't1' and is blocked +# while trying to acquire SNRW lock on 't1'. +# Resume SELECT execution, this should eventually unblock LOCK TABLES. +set debug_sync= 'now SIGNAL finish'; +# +# Switching to connection 'deadlock_con1'. +# Reaping LOCK TABLES. +unlock tables; +# +# Switching to connection 'default'. +# Reaping SELECT. It succeed and not report ER_LOCK_DEADLOCK error. +j i +drop tables t1, t2; +# +# Test coverage for situation in which a race has happened +# during deadlock detection process which led to unwarranted +# ER_LOCK_DEADLOCK error. +# +create table t1 (i int); +# Ensure that ALTER waits once it has acquired SNW lock. +set debug_sync='after_open_table_mdl_shared SIGNAL parked1 WAIT_FOR go1'; +# Sending: +alter table t1 add column j int; +# +# Switching to connection 'deadlock_con1'. +# Wait till ALTER acquires SNW lock and stops. +set debug_sync='now WAIT_FOR parked1'; +# Ensure that INSERT is paused once it detects that there is +# a conflicting metadata lock so it has to wait, but before +# deadlock detection is run. +set debug_sync='mdl_acquire_lock_wait SIGNAL parked2 WAIT_FOR go2'; +# Sending: +insert into t1 values (); +# +# Switching to connection 'deadlock_con2'. +# Wait till INSERT is paused. +set debug_sync='now WAIT_FOR parked2'; +# Resume ALTER execution. Eventually it will release its +# metadata lock and INSERT's request for SW lock will be +# satisified. +set debug_sync='now SIGNAL go1'; +# +# Switching to connection 'default'. +# Reaping ALTER TABLE. +# Add a new request for SNW lock to waiting graph. +# Sending: +alter table t1 drop column j; +# +# Switching to connection 'deadlock_con2'. +# Wait until ALTER is blocked. +# Resume INSERT so it can start deadlock detection. +# +# At this point there is a discrepancy between the fact that INSERT's +# SW lock is already satisfied, but INSERT's connection is still +# marked as waiting for it. Looking for a loop in waiters graph +# without additional checks has detected a deadlock (INSERT waits +# for SW lock; which is not granted because of pending SNW lock from +# ALTER; which waits for active SW lock from INSERT). Since requests +# for SW and SNW locks have same weight ALTER was selected as a victim +# and ended with ER_LOCK_DEADLOCK error. +set debug_sync='now SIGNAL go2'; +# +# Switching to connection 'deadlock_con1'. +# Reaping INSERT. +# +# Switching to connection 'default'. +# Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK. +drop table t1; +set debug_sync= 'RESET'; +# # Test for bug #46748 "Assertion in MDL_context::wait_for_locks() # on INSERT + CREATE TRIGGER". # @@ -2175,7 +2268,7 @@ alter table t1 add column e int, rename to t2;; # # Switching to connection 'default'. set debug_sync='now WAIT_FOR alter_table_locked'; -set debug_sync='before_open_table_wait_refresh SIGNAL alter_go'; +set debug_sync='mdl_acquire_lock_wait SIGNAL alter_go'; # The below statement should get ER_LOCK_DEADLOCK error # (i.e. it should not allow ALTER to proceed, and then # fail due to 't1' changing its name to 't2'). diff --git a/mysql-test/r/sp_sync.result b/mysql-test/r/sp_sync.result index a16babaef67..174b3c60745 100644 --- a/mysql-test/r/sp_sync.result +++ b/mysql-test/r/sp_sync.result @@ -59,30 +59,31 @@ SET DEBUG_SYNC= 'RESET'; # # Bug #48246 assert in close_thread_table # +CREATE TABLE t0 (b INTEGER); CREATE TABLE t1 (a INTEGER); CREATE FUNCTION f1(b INTEGER) RETURNS INTEGER RETURN 1; -CREATE PROCEDURE p1() SELECT COUNT(f1(a)) FROM t1; +CREATE PROCEDURE p1() SELECT COUNT(f1(a)) FROM t1, t0; +INSERT INTO t0 VALUES(1); INSERT INTO t1 VALUES(1), (2); # Connection 2 CALL p1(); COUNT(f1(a)) 2 -# Connection default -SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR called'; -# Sending: -CREATE TABLE t1 (a INTEGER); -# Connection 2 -SET DEBUG_SYNC= 'now WAIT_FOR locked'; -SET DEBUG_SYNC= 'before_open_table_wait_refresh SIGNAL called WAIT_FOR created'; -# This call used to cause an assertion. MDL locking conflict will -# cause back-off and retry. A variable indicating if a prelocking list -# exists, used to be not reset properly causing an eventual assert. +SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked_t1 WAIT_FOR go_for_t0'; +# This call used to cause an assertion. MDL deadlock with upcoming +# LOCK TABLES statement will cause back-off and retry. +# A variable indicating if a prelocking list exists, used to be not +# reset properly causing an eventual assert. # Sending: CALL p1(); # Connection default -# Reaping: CREATE TABLE t1 (a INTEGER) -ERROR 42S01: Table 't1' already exists -SET DEBUG_SYNC= 'now SIGNAL created'; +SET DEBUG_SYNC= 'now WAIT_FOR locked_t1'; +# Issue LOCK TABLES statement which will enter in MDL deadlock +# with CALL statement and as result will cause it to perform +# back-off and retry. +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL go_for_t0'; +LOCK TABLES t0 WRITE, t1 WRITE; +UNLOCK TABLES; # Connection 2 # Reaping: CALL p1() COUNT(f1(a)) @@ -90,5 +91,5 @@ COUNT(f1(a)) # Connection default DROP PROCEDURE p1; DROP FUNCTION f1; -DROP TABLE t1; +DROP TABLES t0, t1; SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result index 73dc1178a54..55256894743 100644 --- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result +++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result @@ -25,7 +25,7 @@ wait/synch/rwlock/sql/LOCK_system_variables_hash YES YES wait/synch/rwlock/sql/LOCK_sys_init_connect YES YES wait/synch/rwlock/sql/LOCK_sys_init_slave YES YES wait/synch/rwlock/sql/LOGGER::LOCK_logger YES YES -wait/synch/rwlock/sql/MDL_context::waiting_for_lock YES YES +wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for YES YES wait/synch/rwlock/sql/MDL_lock::rwlock YES YES wait/synch/rwlock/sql/Query_cache_query::lock YES YES wait/synch/rwlock/sql/THR_LOCK_servers YES YES diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 0af76e93ab4..42f7a9c7ed8 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -1215,18 +1215,23 @@ lock table t2 write; # Sending 'insert into t1 (a) values (f1())'... insert into t1 (a) values (f1()); # Waitng for 'insert into t1 ...' to get blocked on table lock... -# Sending 'drop function f1'. It will abort the table lock wait. -drop function f1; +# Sending 'drop function f1'. It will wait till insert finishes. +drop function f1;; # --> connection default +# Check that 'drop function f1' gets blocked. # Now let's let 'insert' go through... unlock tables; -# --> connection con1 +# --> connection master # Reaping 'insert into t1 (a) values (f1())'... -ERROR 42000: FUNCTION test.f1 does not exist +# --> connection master1 +# Reaping 'drop function f1' +# --> connection master select * from t1; a +1 select * from t1; a +1 drop table t1, t2; drop function f1; ERROR 42000: FUNCTION test.f1 does not exist diff --git a/mysql-test/suite/rpl/t/rpl_sp.test b/mysql-test/suite/rpl/t/rpl_sp.test index db21ffb42fd..8bf4d70e277 100644 --- a/mysql-test/suite/rpl/t/rpl_sp.test +++ b/mysql-test/suite/rpl/t/rpl_sp.test @@ -657,17 +657,25 @@ connection master1; let $wait_condition=select count(*)=1 from information_schema.processlist where state='Waiting for table' and info='insert into t1 (a) values (f1())'; --source include/wait_condition.inc ---echo # Sending 'drop function f1'. It will abort the table lock wait. -drop function f1; +--echo # Sending 'drop function f1'. It will wait till insert finishes. +--send drop function f1; --echo # --> connection default connection default; +--echo # Check that 'drop function f1' gets blocked. +let $wait_condition=select count(*)=1 from information_schema.processlist +where state='Waiting for table' and info='drop function f1'; +--source include/wait_condition.inc --echo # Now let's let 'insert' go through... unlock tables; ---echo # --> connection con1 +--echo # --> connection master connection master; --echo # Reaping 'insert into t1 (a) values (f1())'... ---error ER_SP_DOES_NOT_EXIST --reap +--echo # --> connection master1 +connection master1; +--echo # Reaping 'drop function f1' +--reap +--echo # --> connection master connection master; select * from t1; sync_slave_with_master; diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index 6b517bf1e03..19f9b396087 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -2411,6 +2411,7 @@ drop tables t1, t2; --disable_warnings drop tables if exists t0, t1, t2, t3, t4, t5; --enable_warnings +set debug_sync= 'RESET'; connect(deadlock_con1,localhost,root,,); connect(deadlock_con2,localhost,root,,); @@ -2700,6 +2701,136 @@ connection default; drop table t2; +--echo # +--echo # Test that in situation when MDL subsystem detects a deadlock +--echo # but it turns out that it can be resolved by backing-off locks +--echo # acquired by one of participating transactions (which is +--echo # possible when one of transactions consists only of currently +--echo # executed statement, e.g. in autocommit mode) no error is +--echo # reported. +--echo # +create table t1 (i int); +create table t2 (j int); +--echo # Ensure that the below SELECT stops once it has acquired metadata +--echo # lock on table 't2'. +set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +--echo # Sending: +--send select * from t2, t1 + +--echo # +--echo # Switching to connection 'deadlock_con1'. +connection deadlock_con1; +--echo # Wait till SELECT acquires MDL on 't2' and starts waiting for signal. +set debug_sync= 'now WAIT_FOR locked'; +--echo # Sending: +--send lock tables t1 write, t2 write + +--echo # +--echo # Switching to connection 'deadlock_con2'. +connection deadlock_con2; +--echo # Wait until LOCK TABLES acquires SNRW lock on 't1' and is blocked +--echo # while trying to acquire SNRW lock on 't1'. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table" and info = "lock tables t1 write, t2 write"; +--source include/wait_condition.inc +--echo # Resume SELECT execution, this should eventually unblock LOCK TABLES. +set debug_sync= 'now SIGNAL finish'; + +--echo # +--echo # Switching to connection 'deadlock_con1'. +connection deadlock_con1; +--echo # Reaping LOCK TABLES. +--reap +unlock tables; + +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Reaping SELECT. It succeed and not report ER_LOCK_DEADLOCK error. +--reap + +drop tables t1, t2; + +--echo # +--echo # Test coverage for situation in which a race has happened +--echo # during deadlock detection process which led to unwarranted +--echo # ER_LOCK_DEADLOCK error. +--echo # +create table t1 (i int); + +--echo # Ensure that ALTER waits once it has acquired SNW lock. +set debug_sync='after_open_table_mdl_shared SIGNAL parked1 WAIT_FOR go1'; +--echo # Sending: +--send alter table t1 add column j int + +--echo # +--echo # Switching to connection 'deadlock_con1'. +connection deadlock_con1; +--echo # Wait till ALTER acquires SNW lock and stops. +set debug_sync='now WAIT_FOR parked1'; +--echo # Ensure that INSERT is paused once it detects that there is +--echo # a conflicting metadata lock so it has to wait, but before +--echo # deadlock detection is run. +set debug_sync='mdl_acquire_lock_wait SIGNAL parked2 WAIT_FOR go2'; +--echo # Sending: +--send insert into t1 values () + +--echo # +--echo # Switching to connection 'deadlock_con2'. +connection deadlock_con2; +--echo # Wait till INSERT is paused. +set debug_sync='now WAIT_FOR parked2'; +--echo # Resume ALTER execution. Eventually it will release its +--echo # metadata lock and INSERT's request for SW lock will be +--echo # satisified. +set debug_sync='now SIGNAL go1'; + +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Reaping ALTER TABLE. +--reap +--echo # Add a new request for SNW lock to waiting graph. +--echo # Sending: +--send alter table t1 drop column j + +--echo # +--echo # Switching to connection 'deadlock_con2'. +connection deadlock_con2; +--echo # Wait until ALTER is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table" and info = "alter table t1 drop column j"; +--source include/wait_condition.inc +--echo # Resume INSERT so it can start deadlock detection. +--echo # +--echo # At this point there is a discrepancy between the fact that INSERT's +--echo # SW lock is already satisfied, but INSERT's connection is still +--echo # marked as waiting for it. Looking for a loop in waiters graph +--echo # without additional checks has detected a deadlock (INSERT waits +--echo # for SW lock; which is not granted because of pending SNW lock from +--echo # ALTER; which waits for active SW lock from INSERT). Since requests +--echo # for SW and SNW locks have same weight ALTER was selected as a victim +--echo # and ended with ER_LOCK_DEADLOCK error. +set debug_sync='now SIGNAL go2'; + +--echo # +--echo # Switching to connection 'deadlock_con1'. +connection deadlock_con1; +--echo # Reaping INSERT. +--reap + +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK. +--reap + +drop table t1; + +set debug_sync= 'RESET'; + disconnect deadlock_con1; disconnect deadlock_con2; disconnect deadlock_con3; @@ -3097,7 +3228,7 @@ set debug_sync='after_lock_tables_takes_lock SIGNAL alter_table_locked WAIT_FOR --echo # Switching to connection 'default'. connection default; set debug_sync='now WAIT_FOR alter_table_locked'; -set debug_sync='before_open_table_wait_refresh SIGNAL alter_go'; +set debug_sync='mdl_acquire_lock_wait SIGNAL alter_go'; --echo # The below statement should get ER_LOCK_DEADLOCK error --echo # (i.e. it should not allow ALTER to proceed, and then --echo # fail due to 't1' changing its name to 't2'). diff --git a/mysql-test/t/sp_sync.test b/mysql-test/t/sp_sync.test index 391298b604a..431db463b67 100644 --- a/mysql-test/t/sp_sync.test +++ b/mysql-test/t/sp_sync.test @@ -108,38 +108,35 @@ disconnect con3; --echo # Bug #48246 assert in close_thread_table --echo # +CREATE TABLE t0 (b INTEGER); CREATE TABLE t1 (a INTEGER); CREATE FUNCTION f1(b INTEGER) RETURNS INTEGER RETURN 1; -CREATE PROCEDURE p1() SELECT COUNT(f1(a)) FROM t1; +CREATE PROCEDURE p1() SELECT COUNT(f1(a)) FROM t1, t0; +INSERT INTO t0 VALUES(1); INSERT INTO t1 VALUES(1), (2); --echo # Connection 2 connect (con2, localhost, root); CALL p1(); ---echo # Connection default -connection default; -SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR called'; ---echo # Sending: ---send CREATE TABLE t1 (a INTEGER) - ---echo # Connection 2 -connection con2; -SET DEBUG_SYNC= 'now WAIT_FOR locked'; -SET DEBUG_SYNC= 'before_open_table_wait_refresh SIGNAL called WAIT_FOR created'; ---echo # This call used to cause an assertion. MDL locking conflict will ---echo # cause back-off and retry. A variable indicating if a prelocking list ---echo # exists, used to be not reset properly causing an eventual assert. +SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked_t1 WAIT_FOR go_for_t0'; +--echo # This call used to cause an assertion. MDL deadlock with upcoming +--echo # LOCK TABLES statement will cause back-off and retry. +--echo # A variable indicating if a prelocking list exists, used to be not +--echo # reset properly causing an eventual assert. --echo # Sending: --send CALL p1() --echo # Connection default connection default; ---echo # Reaping: CREATE TABLE t1 (a INTEGER) ---error ER_TABLE_EXISTS_ERROR ---reap -SET DEBUG_SYNC= 'now SIGNAL created'; +SET DEBUG_SYNC= 'now WAIT_FOR locked_t1'; +--echo # Issue LOCK TABLES statement which will enter in MDL deadlock +--echo # with CALL statement and as result will cause it to perform +--echo # back-off and retry. +SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL go_for_t0'; +LOCK TABLES t0 WRITE, t1 WRITE; +UNLOCK TABLES; --echo # Connection 2 connection con2; @@ -151,7 +148,7 @@ connection default; disconnect con2; DROP PROCEDURE p1; DROP FUNCTION f1; -DROP TABLE t1; +DROP TABLES t0, t1; SET DEBUG_SYNC= 'RESET'; diff --git a/sql/mdl.cc b/sql/mdl.cc index 68ac0cc599d..184b3c6051d 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -21,28 +21,28 @@ #ifdef HAVE_PSI_INTERFACE static PSI_mutex_key key_MDL_map_mutex; -static PSI_mutex_key key_MDL_context_signal_mutex; +static PSI_mutex_key key_MDL_wait_LOCK_wait_status; static PSI_mutex_info all_mdl_mutexes[]= { { &key_MDL_map_mutex, "MDL_map::mutex", PSI_FLAG_GLOBAL}, - { &key_MDL_context_signal_mutex, "MDL_context::signal", 0} + { &key_MDL_wait_LOCK_wait_status, "MDL_wait::LOCK_wait_status", 0} }; static PSI_rwlock_key key_MDL_lock_rwlock; -static PSI_rwlock_key key_MDL_context_waiting_for_rwlock; +static PSI_rwlock_key key_MDL_context_LOCK_waiting_for; static PSI_rwlock_info all_mdl_rwlocks[]= { { &key_MDL_lock_rwlock, "MDL_lock::rwlock", 0}, - { &key_MDL_context_waiting_for_rwlock, "MDL_context::waiting_for_lock", 0} + { &key_MDL_context_LOCK_waiting_for, "MDL_context::LOCK_waiting_for", 0} }; -static PSI_cond_key key_MDL_context_signal_cond; +static PSI_cond_key key_MDL_wait_COND_wait_status; static PSI_cond_info all_mdl_conds[]= { - { &key_MDL_context_signal_cond, "MDL_context::signal", 0} + { &key_MDL_wait_COND_wait_status, "MDL_context::COND_wait_status", 0} }; /** @@ -259,7 +259,9 @@ public: typedef I_P_List > + &MDL_ticket::prev_in_lock>, + I_P_List_null_counter, + I_P_List_fast_push_back > List; operator const List &() const { return m_list; } Ticket_list() :m_bitmap(0) {} @@ -345,21 +347,8 @@ public: } } - /** - Wake up contexts which are waiting to acquire lock on the object and - which may succeed now, when we released some lock on it or removed - some pending request from its waiters list (the latter can happen, - for example, when context trying to acquire exclusive on the object - lock is killed). - */ - void wake_up_waiters() - { - MDL_lock::Ticket_iterator it(m_waiting); - MDL_ticket *awake_ticket; + void reschedule_waiters(); - while ((awake_ticket= it++)) - awake_ticket->get_ctx()->awake(MDL_context::NORMAL_WAKE_UP); - } void remove_ticket(Ticket_list MDL_lock::*queue, MDL_ticket *ticket); bool find_deadlock(MDL_ticket *waiting_ticket, @@ -499,7 +488,7 @@ mdl_locks_key(const uchar *record, size_t *length, statement, the design capitalizes on that to later save on look ups in the table definition cache. This leads to reduced contention overall and on LOCK_open in particular. - Please see the description of MDL_context::acquire_lock_impl() + Please see the description of MDL_context::acquire_lock() for details. */ @@ -726,13 +715,9 @@ MDL_context::MDL_context() :m_trans_sentinel(NULL), m_thd(NULL), m_needs_thr_lock_abort(FALSE), - m_waiting_for(NULL), - m_deadlock_weight(0), - m_signal(NO_WAKE_UP) + m_waiting_for(NULL) { - mysql_prlock_init(key_MDL_context_waiting_for_rwlock, &m_waiting_for_lock); - mysql_mutex_init(key_MDL_context_signal_mutex, &m_signal_lock, NULL); - mysql_cond_init(key_MDL_context_signal_mutex, &m_signal_cond, NULL); + mysql_prlock_init(key_MDL_context_LOCK_waiting_for, &m_LOCK_waiting_for); } @@ -752,9 +737,7 @@ void MDL_context::destroy() { DBUG_ASSERT(m_tickets.is_empty()); - mysql_prlock_destroy(&m_waiting_for_lock); - mysql_mutex_destroy(&m_signal_lock); - mysql_cond_destroy(&m_signal_cond); + mysql_prlock_destroy(&m_LOCK_waiting_for); } @@ -964,27 +947,120 @@ static inline void mdl_exit_cond(THD *thd, } -MDL_context::mdl_signal_type MDL_context::timed_wait(struct timespec - *abs_timeout) +/** Construct an empty wait slot. */ + +MDL_wait::MDL_wait() + :m_wait_status(EMPTY) +{ + mysql_mutex_init(key_MDL_wait_LOCK_wait_status, &m_LOCK_wait_status, NULL); + mysql_cond_init(key_MDL_wait_COND_wait_status, &m_COND_wait_status, NULL); +} + + +/** Destroy system resources. */ + +MDL_wait::~MDL_wait() +{ + mysql_mutex_destroy(&m_LOCK_wait_status); + mysql_cond_destroy(&m_COND_wait_status); +} + + +/** + Set the status unless it's already set. Return FALSE if set, + TRUE otherwise. +*/ + +bool MDL_wait::set_status(enum_wait_status status_arg) +{ + bool was_occupied= TRUE; + mysql_mutex_lock(&m_LOCK_wait_status); + if (m_wait_status == EMPTY) + { + was_occupied= FALSE; + m_wait_status= status_arg; + mysql_cond_signal(&m_COND_wait_status); + } + mysql_mutex_unlock(&m_LOCK_wait_status); + return was_occupied; +} + + +/** Query the current value of the wait slot. */ + +MDL_wait::enum_wait_status MDL_wait::get_status() +{ + enum_wait_status result; + mysql_mutex_lock(&m_LOCK_wait_status); + result= m_wait_status; + mysql_mutex_unlock(&m_LOCK_wait_status); + return result; +} + + +/** Clear the current value of the wait slot. */ + +void MDL_wait::reset_status() +{ + mysql_mutex_lock(&m_LOCK_wait_status); + m_wait_status= EMPTY; + mysql_mutex_unlock(&m_LOCK_wait_status); +} + + +/** + Wait for the status to be assigned to this wait slot. + + @param abs_timeout Absolute time after which waiting should stop. + @param set_status_on_tiemout TRUE - If in case of timeout waiting + context should close the wait slot by + sending TIMEOUT to itself. + FALSE - Otherwise. + + @returns Signal posted. +*/ + +MDL_wait::enum_wait_status +MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, + bool set_status_on_timeout) { const char *old_msg; - mdl_signal_type result; + enum_wait_status result; st_my_thread_var *mysys_var= my_thread_var; int wait_result= 0; - mysql_mutex_lock(&m_signal_lock); + mysql_mutex_lock(&m_LOCK_wait_status); - old_msg= MDL_ENTER_COND(m_thd, mysys_var, &m_signal_cond, &m_signal_lock); + old_msg= MDL_ENTER_COND(thd, mysys_var, &m_COND_wait_status, + &m_LOCK_wait_status); - while (!m_signal && !mysys_var->abort && + while (!m_wait_status && !mysys_var->abort && wait_result != ETIMEDOUT && wait_result != ETIME) - wait_result= mysql_cond_timedwait(&m_signal_cond, &m_signal_lock, + wait_result= mysql_cond_timedwait(&m_COND_wait_status, &m_LOCK_wait_status, abs_timeout); - result= (m_signal != NO_WAKE_UP || mysys_var->abort) ? - m_signal : TIMEOUT_WAKE_UP; + if (m_wait_status == EMPTY) + { + /* + Wait has ended not due to a status being set from another + thread but due to this connection/statement being killed or a + time out. + To avoid races, which may occur if another thread sets + GRANTED status before the code which calls this method + processes the abort/timeout, we assign the status under + protection of the m_LOCK_wait_status, within the critical + section. An exception is when set_status_on_timeout is + false, which means that the caller intends to restart the + wait. + */ + if (mysys_var->abort) + m_wait_status= KILLED; + else if (set_status_on_timeout) + m_wait_status= TIMEOUT; + } + result= m_wait_status; - MDL_EXIT_COND(m_thd, mysys_var, &m_signal_lock, old_msg); + MDL_EXIT_COND(thd, mysys_var, &m_LOCK_wait_status, old_msg); return result; } @@ -1024,7 +1100,11 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) called by other threads. */ DBUG_ASSERT(ticket->get_lock()); - m_list.push_front(ticket); + /* + Add ticket to the *back* of the queue to ensure fairness + among requests with the same priority. + */ + m_list.push_back(ticket); m_bitmap|= MDL_BIT(ticket->get_type()); } @@ -1051,6 +1131,75 @@ void MDL_lock::Ticket_list::remove_ticket(MDL_ticket *ticket) } +/** + Determine waiting contexts which requests for the lock can be + satisfied, grant lock to them and wake them up. + + @note Together with MDL_lock::add_ticket() this method implements + fair scheduling among requests with the same priority. + It tries to grant lock from the head of waiters list, while + add_ticket() adds new requests to the back of this list. + +*/ + +void MDL_lock::reschedule_waiters() +{ + MDL_lock::Ticket_iterator it(m_waiting); + MDL_ticket *ticket; + + /* + Find the first (and hence the oldest) waiting request which + can be satisfied (taking into account priority). Grant lock to it. + Repeat the process for the remainder of waiters. + Note we don't need to re-start iteration from the head of the + list after satisfying the first suitable request as in our case + all compatible types of requests have the same priority. + + TODO/FIXME: We should: + - Either switch to scheduling without priorities + which will allow to stop iteration through the + list of waiters once we found the first ticket + which can't be satisfied + - Or implement some check using bitmaps which will + allow to stop iteration in cases when, e.g., we + grant SNRW lock and there are no pending S or + SH locks. + */ + while ((ticket= it++)) + { + if (can_grant_lock(ticket->get_type(), ticket->get_ctx())) + { + if (! ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED)) + { + /* + Satisfy the found request by updating lock structures. + It is OK to do so even after waking up the waiter since any + session which tries to get any information about the state of + this lock has to acquire MDL_lock::m_rwlock first and thus, + when manages to do so, already sees an updated state of the + MDL_lock object. + */ + m_waiting.remove_ticket(ticket); + m_granted.add_ticket(ticket); + + /* If we are granting an X lock, release the cached object. */ + if (ticket->get_type() == MDL_EXCLUSIVE && cached_object) + (*cached_object_release_hook)(cached_object); + cached_object= NULL; + } + /* + If we could not update the wait slot of the waiter, + it can be due to fact that its connection/statement was + killed or it has timed out (i.e. the slot is not empty). + Since in all such cases the waiter assumes that the lock was + not been granted, we should keep the request in the waiting + queue and look for another request to reschedule. + */ + } + } +} + + /** Compatibility (or rather "incompatibility") matrices for global metadata lock. Arrays of bitmaps which elements specify which granted/waiting locks @@ -1258,9 +1407,19 @@ void MDL_lock::remove_ticket(Ticket_list MDL_lock::*list, MDL_ticket *ticket) { /* There can be some contexts waiting to acquire a lock - which now might be able to do it. Wake them up! + which now might be able to do it. Grant the lock to + them and wake them up! + + We always try to reschedule locks, since there is no easy way + (i.e. by looking at the bitmaps) to find out whether it is + required or not. + In a general case, even when the queue's bitmap is not changed + after removal of the ticket, there is a chance that some request + can be satisfied (due to the fact that a granted request + reflected in the bitmap might belong to the same context as a + pending request). */ - wake_up_waiters(); + reschedule_waiters(); mysql_prlock_unlock(&m_rwlock); } } @@ -1360,29 +1519,6 @@ MDL_context::find_ticket(MDL_request *mdl_request, } -/** - Acquire one lock with waiting for conflicting locks to go away if needed. - - @note This is an internal method which should not be used outside of MDL - subsystem as in most cases simply waiting for conflicting locks to - go away will lead to deadlock. - - @param mdl_request [in/out] Lock request object for lock to be acquired - - @param lock_wait_timeout [in] Seconds to wait before timeout. - - @retval FALSE Success. MDL_request::ticket points to the ticket - for the lock. - @retval TRUE Failure (Out of resources or waiting is aborted), -*/ - -bool -MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) -{ - return acquire_lock_impl(mdl_request, lock_wait_timeout); -} - - /** Try to acquire one lock. @@ -1405,14 +1541,54 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) @retval FALSE Success. The lock may have not been acquired. Check the ticket, if it's NULL, a conflicting lock - exists and another attempt should be made after releasing - all current locks and waiting for conflicting lock go - away (using MDL_context::wait_for_lock()). + exists. @retval TRUE Out of resources, an error has been reported. */ bool MDL_context::try_acquire_lock(MDL_request *mdl_request) +{ + MDL_ticket *ticket; + + if (try_acquire_lock_impl(mdl_request, &ticket)) + return TRUE; + + if (! mdl_request->ticket) + { + /* + Our attempt to acquire lock without waiting has failed. + Let us release resources which were acquired in the process. + We can't get here if we allocated a new lock object so there + is no need to release it. + */ + DBUG_ASSERT(! ticket->m_lock->is_empty()); + mysql_prlock_unlock(&ticket->m_lock->m_rwlock); + MDL_ticket::destroy(ticket); + } + + return FALSE; +} + + +/** + Auxiliary method for acquiring lock without waiting. + + @param mdl_request [in/out] Lock request object for lock to be acquired + @param out_ticket [out] Ticket for the request in case when lock + has not been acquired. + + @retval FALSE Success. The lock may have not been acquired. + Check MDL_request::ticket, if it's NULL, a conflicting + lock exists. In this case "out_ticket" out parameter + points to ticket which was constructed for the request. + MDL_ticket::m_lock points to the corresponding MDL_lock + object and MDL_lock::m_rwlock write-locked. + @retval TRUE Out of resources, an error has been reported. +*/ + +bool +MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, + MDL_ticket **out_ticket) { MDL_lock *lock; MDL_key *key= &mdl_request->key; @@ -1473,10 +1649,16 @@ MDL_context::try_acquire_lock(MDL_request *mdl_request) return TRUE; } + ticket->m_lock= lock; + if (lock->can_grant_lock(mdl_request->type, this)) { - ticket->m_lock= lock; lock->m_granted.add_ticket(ticket); + + if (mdl_request->type == MDL_EXCLUSIVE && lock->cached_object) + (*lock->cached_object_release_hook)(lock->cached_object); + lock->cached_object= NULL; + mysql_prlock_unlock(&lock->m_rwlock); m_tickets.push_front(ticket); @@ -1484,12 +1666,7 @@ MDL_context::try_acquire_lock(MDL_request *mdl_request) mdl_request->ticket= ticket; } else - { - /* We can't get here if we allocated a new lock. */ - DBUG_ASSERT(! lock->is_empty()); - mysql_prlock_unlock(&lock->m_rwlock); - MDL_ticket::destroy(ticket); - } + *out_ticket= ticket; return FALSE; } @@ -1567,121 +1744,126 @@ void notify_shared_lock(THD *thd, MDL_ticket *conflicting_ticket) /** - Auxiliary method for acquiring an exclusive lock. + Acquire one lock with waiting for conflicting locks to go away if needed. - @param mdl_request Request for the lock to be acqured. + @param mdl_request [in/out] Lock request object for lock to be acquired - @param lock_wait_timeout Seconds to wait before timeout. + @param lock_wait_timeout [in] Seconds to wait before timeout. - @note Should not be used outside of MDL subsystem. Instead one - should call acquire_lock() or acquire_locks() - methods which ensure that conditions for deadlock-free - lock acquisition are fulfilled. - - @retval FALSE Success - @retval TRUE Failure + @retval FALSE Success. MDL_request::ticket points to the ticket + for the lock. + @retval TRUE Failure (Out of resources or waiting is aborted), */ -bool MDL_context::acquire_lock_impl(MDL_request *mdl_request, - ulong lock_wait_timeout) +bool +MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) { MDL_lock *lock; MDL_ticket *ticket; - bool not_used; - st_my_thread_var *mysys_var= my_thread_var; - MDL_key *key= &mdl_request->key; struct timespec abs_timeout; - struct timespec abs_shortwait; + MDL_wait::enum_wait_status wait_status; + /* Do some work outside the critical section. */ set_timespec(abs_timeout, lock_wait_timeout); - mysql_mutex_assert_not_owner(&LOCK_open); + if (try_acquire_lock_impl(mdl_request, &ticket)) + return TRUE; - DBUG_ASSERT(mdl_request->ticket == NULL); - /* Don't take chances in production. */ - mdl_request->ticket= NULL; - - /* - Check whether the context already holds an exclusive lock on the object, - and if so, grant the request. - */ - if ((ticket= find_ticket(mdl_request, ¬_used))) + if (mdl_request->ticket) { - DBUG_ASSERT(ticket->m_lock); - mdl_request->ticket= ticket; + /* + We have managed to acquire lock without waiting. + MDL_lock, MDL_context and MDL_request were updated + accordingly, so we can simply return success. + */ return FALSE; } - DBUG_ASSERT(mdl_request->type < MDL_SHARED_NO_WRITE || - is_lock_owner(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE)); - - /* Early allocation: ticket will be needed in any case. */ - if (!(ticket= MDL_ticket::create(this, mdl_request->type))) - return TRUE; - - /* The below call implicitly locks MDL_lock::m_rwlock on success. */ - if (!(lock= mdl_locks.find_or_insert(key))) - { - MDL_ticket::destroy(ticket); - return TRUE; - } - - ticket->m_lock= lock; + /* + Our attempt to acquire lock without waiting has failed. + As a result of this attempt we got MDL_ticket with m_lock + member pointing to the corresponding MDL_lock object which + has MDL_lock::m_rwlock write-locked. + */ + lock= ticket->m_lock; lock->m_waiting.add_ticket(ticket); - while (!lock->can_grant_lock(mdl_request->type, this)) - { - wait_reset(); + /* + Once we added a pending ticket to the waiting queue, + we must ensure that our wait slot is empty, so + that our lock request can be scheduled. Do that in the + critical section formed by the acquired write lock on MDL_lock. + */ + m_wait.reset_status(); - if (ticket->is_upgradable_or_exclusive()) - lock->notify_shared_locks(this); - - mysql_prlock_unlock(&lock->m_rwlock); - - will_wait_for(ticket); - - /* There is a shared or exclusive lock on the object. */ - DEBUG_SYNC(m_thd, "mdl_acquire_lock_wait"); - - bool is_deadlock= find_deadlock(); - bool is_timeout= FALSE; - if (!is_deadlock) - { - set_timespec(abs_shortwait, 1); - bool timeout_is_near= cmp_timespec(abs_shortwait, abs_timeout) > 0; - mdl_signal_type wait_result= - timed_wait(timeout_is_near ? &abs_timeout : &abs_shortwait); - - if (timeout_is_near && wait_result == TIMEOUT_WAKE_UP) - is_timeout= TRUE; - else if (wait_result == VICTIM_WAKE_UP) - is_deadlock= TRUE; - } - - stop_waiting(); - - if (mysys_var->abort || is_deadlock || is_timeout) - { - lock->remove_ticket(&MDL_lock::m_waiting, ticket); - MDL_ticket::destroy(ticket); - if (is_deadlock) - my_error(ER_LOCK_DEADLOCK, MYF(0)); - else if (is_timeout) - my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); - return TRUE; - } - mysql_prlock_wrlock(&lock->m_rwlock); - } - - lock->m_waiting.remove_ticket(ticket); - lock->m_granted.add_ticket(ticket); - - if (ticket->get_type() == MDL_EXCLUSIVE && lock->cached_object) - (*lock->cached_object_release_hook)(lock->cached_object); - lock->cached_object= NULL; + if (ticket->is_upgradable_or_exclusive()) + lock->notify_shared_locks(this); mysql_prlock_unlock(&lock->m_rwlock); + will_wait_for(ticket); + + /* There is a shared or exclusive lock on the object. */ + DEBUG_SYNC(m_thd, "mdl_acquire_lock_wait"); + + find_deadlock(); + + if (ticket->is_upgradable_or_exclusive()) + { + struct timespec abs_shortwait; + set_timespec(abs_shortwait, 1); + wait_status= MDL_wait::EMPTY; + + while (cmp_timespec(abs_shortwait, abs_timeout) <= 0) + { + /* abs_timeout is far away. Wait a short while and notify locks. */ + wait_status= m_wait.timed_wait(m_thd, &abs_shortwait, FALSE); + + if (wait_status != MDL_wait::EMPTY) + break; + + mysql_prlock_wrlock(&lock->m_rwlock); + lock->notify_shared_locks(this); + mysql_prlock_unlock(&lock->m_rwlock); + set_timespec(abs_shortwait, 1); + } + if (wait_status == MDL_wait::EMPTY) + wait_status= m_wait.timed_wait(m_thd, &abs_timeout, TRUE); + } + else + wait_status= m_wait.timed_wait(m_thd, &abs_timeout, TRUE); + + done_waiting_for(); + + if (wait_status != MDL_wait::GRANTED) + { + lock->remove_ticket(&MDL_lock::m_waiting, ticket); + MDL_ticket::destroy(ticket); + switch (wait_status) + { + case MDL_wait::VICTIM: + my_error(ER_LOCK_DEADLOCK, MYF(0)); + break; + case MDL_wait::TIMEOUT: + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); + break; + case MDL_wait::KILLED: + break; + default: + DBUG_ASSERT(0); + break; + } + return TRUE; + } + + /* + We have been granted our request. + State of MDL_lock object is already being appropriately updated by a + concurrent thread (@sa MDL_lock:reschedule_waiters()). + So all we need to do is to update MDL_context and MDL_request objects. + */ + DBUG_ASSERT(wait_status == MDL_wait::GRANTED); + m_tickets.push_front(ticket); mdl_request->ticket= ticket; @@ -1750,7 +1932,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++) { - if (acquire_lock_impl(*p_req, lock_wait_timeout)) + if (acquire_lock(*p_req, lock_wait_timeout)) goto err; } my_free(sort_buf, MYF(0)); @@ -1818,7 +2000,7 @@ MDL_context::upgrade_shared_lock_to_exclusive(MDL_ticket *mdl_ticket, mdl_xlock_request.init(&mdl_ticket->m_lock->key, MDL_EXCLUSIVE); - if (acquire_lock_impl(&mdl_xlock_request, lock_wait_timeout)) + if (acquire_lock(&mdl_xlock_request, lock_wait_timeout)) DBUG_RETURN(TRUE); is_new_ticket= ! has_lock(mdl_svp, mdl_xlock_request.ticket); @@ -1855,15 +2037,72 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, MDL_context *src_ctx= waiting_ticket->get_ctx(); bool result= TRUE; - if (dvisitor->enter_node(src_ctx)) - return TRUE; - mysql_prlock_rdlock(&m_rwlock); /* Must be initialized after taking a read lock. */ Ticket_iterator granted_it(m_granted); Ticket_iterator waiting_it(m_waiting); + /* + MDL_lock's waiting and granted queues and MDL_context::m_waiting_for + member are updated by different threads when the lock is granted + (see MDL_context::acquire_lock() and MDL_lock::reschedule_waiters()). + As a result, here we may encounter a situation when MDL_lock data + already reflects the fact that the lock was granted but + m_waiting_for member has not been updated yet. + + For example, imagine that: + + thread1: Owns SNW lock on table t1. + thread2: Attempts to acquire SW lock on t1, + but sees an active SNW lock. + Thus adds the ticket to the waiting queue and + sets m_waiting_for to point to the ticket. + thread1: Releases SNW lock, updates MDL_lock object to + grant SW lock to thread2 (moves the ticket for + SW from waiting to the active queue). + Attempts to acquire a new SNW lock on t1, + sees an active SW lock (since it is present in the + active queue), adds ticket for SNW lock to the waiting + queue, sets m_waiting_for to point to this ticket. + + At this point deadlock detection algorithm run by thread1 will see that: + - Thread1 waits for SNW lock on t1 (since m_waiting_for is set). + - SNW lock is not granted, because it conflicts with active SW lock + owned by thread 2 (since ticket for SW is present in granted queue). + - Thread2 waits for SW lock (since its m_waiting_for has not been + updated yet!). + - SW lock is not granted because there is pending SNW lock from thread1. + Therefore deadlock should exist [sic!]. + + To avoid detection of such false deadlocks we need to check the "actual" + status of the ticket being waited for, before analyzing its blockers. + We do this by checking the wait status of the context which is waiting + for it. To avoid races this has to be done under protection of + MDL_lock::m_rwlock lock. + */ + if (src_ctx->m_wait.get_status() != MDL_wait::EMPTY) + { + result= FALSE; + goto end; + } + + /* + To avoid visiting nodes which were already marked as victims of + deadlock detection (or whose requests were already satisfied) we + enter the node only after peeking at its wait status. + This is necessary to avoid active waiting in a situation + when previous searches for a deadlock already selected the + node we're about to enter as a victim (see the comment + in MDL_context::find_deadlock() for explanation why several searches + can be performed for the same wait). + There is no guarantee that the node isn't chosen a victim while we + are visiting it but this is OK: in the worst case we might do some + extra work and one more context might be chosen as a victim. + */ + if (dvisitor->enter_node(src_ctx)) + goto end; + /* We do a breadth-first search first -- that is, inspect all edges of the current node, and only then follow up to the next @@ -1877,7 +2116,7 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && dvisitor->inspect_edge(ticket->get_ctx())) { - goto end; + goto end_leave_node; } } @@ -1888,7 +2127,7 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && dvisitor->inspect_edge(ticket->get_ctx())) { - goto end; + goto end_leave_node; } } @@ -1900,7 +2139,7 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, ticket->is_incompatible_when_granted(waiting_ticket->get_type()) && ticket->get_ctx()->find_deadlock(dvisitor)) { - goto end; + goto end_leave_node; } } @@ -1911,14 +2150,17 @@ bool MDL_lock::find_deadlock(MDL_ticket *waiting_ticket, ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) && ticket->get_ctx()->find_deadlock(dvisitor)) { - goto end; + goto end_leave_node; } } result= FALSE; + +end_leave_node: + dvisitor->leave_node(src_ctx); + end: mysql_prlock_unlock(&m_rwlock); - dvisitor->leave_node(src_ctx); return result; } @@ -1937,22 +2179,13 @@ bool MDL_context::find_deadlock(Deadlock_detection_visitor *dvisitor) MDL_context *m_unlock_ctx= this; bool result= FALSE; - mysql_prlock_rdlock(&m_waiting_for_lock); + mysql_prlock_rdlock(&m_LOCK_waiting_for); if (m_waiting_for) { - /* - QQ: should we rather be checking for NO_WAKE_UP ? - - We want to do check signal only when m_waiting_for is set - to avoid reading left-overs from previous kills. - */ - if (peek_signal() != VICTIM_WAKE_UP) - { - result= m_waiting_for->m_lock->find_deadlock(m_waiting_for, dvisitor); - if (result) - m_unlock_ctx= dvisitor->opt_change_victim_to(this); - } + result= m_waiting_for->m_lock->find_deadlock(m_waiting_for, dvisitor); + if (result) + m_unlock_ctx= dvisitor->opt_change_victim_to(this); } /* We may recurse into the same MDL_context more than once @@ -1961,7 +2194,7 @@ bool MDL_context::find_deadlock(Deadlock_detection_visitor *dvisitor) the deadlock victim. */ if (m_unlock_ctx) - mysql_prlock_unlock(&m_unlock_ctx->m_waiting_for_lock); + mysql_prlock_unlock(&m_unlock_ctx->m_LOCK_waiting_for); return result; } @@ -1970,21 +2203,25 @@ bool MDL_context::find_deadlock(Deadlock_detection_visitor *dvisitor) /** Try to find a deadlock. This function produces no errors. + @note If during deadlock resolution context which performs deadlock + detection is chosen as a victim it will be informed about the + fact by setting VICTIM status to its wait slot. + @retval TRUE A deadlock is found. @retval FALSE No deadlock found. */ -bool MDL_context::find_deadlock() +void MDL_context::find_deadlock() { while (1) { - MDL_context *victim; /* The fact that we use fresh instance of dvisitor for each - search performed by find_deadlock() below is important, code - responsible for victim selection relies on this. + search performed by find_deadlock() below is important, + the code responsible for victim selection relies on this. */ Deadlock_detection_visitor dvisitor(this); + MDL_context *victim; if (! find_deadlock(&dvisitor)) { @@ -1994,125 +2231,31 @@ bool MDL_context::find_deadlock() victim= dvisitor.get_victim(); - if (victim != this) - { - victim->awake(VICTIM_WAKE_UP); - mysql_prlock_unlock(&victim->m_waiting_for_lock); - /* - After adding new arc to waiting graph we found that it participates - in some loop (i.e. there is a deadlock). We decided to destroy this - loop by removing some arc other than newly added. Since this doesn't - guarantee that all loops created by addition of this arc are - destroyed we have to repeat search. - */ - continue; - } - else - { - DBUG_ASSERT(&victim->m_waiting_for_lock == &m_waiting_for_lock); - mysql_prlock_unlock(&victim->m_waiting_for_lock); - return TRUE; - } - } - return FALSE; -} - - -/** - Wait until there will be no locks that conflict with lock requests - in the given list. - - This is a part of the locking protocol and must be used by the - acquirer of shared locks after a back-off. - - Does not acquire the locks! - - @param lock_wait_timeout Seconds to wait before timeout. - - @retval FALSE Success. One can try to obtain metadata locks. - @retval TRUE Failure (thread was killed or deadlock is possible). -*/ - -bool -MDL_context::wait_for_lock(MDL_request *mdl_request, ulong lock_wait_timeout) -{ - MDL_lock *lock; - st_my_thread_var *mysys_var= my_thread_var; - struct timespec abs_timeout; - set_timespec(abs_timeout, lock_wait_timeout); - - mysql_mutex_assert_not_owner(&LOCK_open); - - DBUG_ASSERT(mdl_request->ticket == NULL); - - while (TRUE) - { /* - We have to check if there are some HANDLERs open by this thread - which conflict with some pending exclusive locks. Otherwise we - might have a deadlock in situations when we are waiting for - pending writer to go away, which in its turn waits for HANDLER - open by our thread. - - TODO: investigate situations in which we need to broadcast on - COND_mdl because of above scenario. + Failure to change status of the victim is OK as it means + that the victim has received some other message and is + about to stop its waiting/to break deadlock loop. + Even when the initiator of the deadlock search is + chosen the victim, we need to set the respective wait + result in order to "close" it for any attempt to + schedule the request. + This is needed to avoid a possible race during + cleanup in case when the lock request on which the + context was waiting is concurrently satisfied. */ - mysql_ha_flush(m_thd); + (void) victim->m_wait.set_status(MDL_wait::VICTIM); + mysql_prlock_unlock(&victim->m_LOCK_waiting_for); - MDL_key *key= &mdl_request->key; - - /* The below call implicitly locks MDL_lock::m_rwlock on success. */ - if (! (lock= mdl_locks.find(key))) - return FALSE; - - if (lock->can_grant_lock(mdl_request->type, this)) - { - mysql_prlock_unlock(&lock->m_rwlock); - return FALSE; - } - - MDL_ticket *pending_ticket; - if (! (pending_ticket= MDL_ticket::create(this, mdl_request->type))) - { - mysql_prlock_unlock(&lock->m_rwlock); - return TRUE; - } - - pending_ticket->m_lock= lock; - - lock->m_waiting.add_ticket(pending_ticket); - - wait_reset(); - mysql_prlock_unlock(&lock->m_rwlock); - - will_wait_for(pending_ticket); - - bool is_deadlock= find_deadlock(); - bool is_timeout= FALSE; - if (!is_deadlock) - { - mdl_signal_type wait_result= timed_wait(&abs_timeout); - if (wait_result == TIMEOUT_WAKE_UP) - is_timeout= TRUE; - else if (wait_result == VICTIM_WAKE_UP) - is_deadlock= TRUE; - } - - stop_waiting(); - - lock->remove_ticket(&MDL_lock::m_waiting, pending_ticket); - MDL_ticket::destroy(pending_ticket); - - if (mysys_var->abort || is_deadlock || is_timeout) - { - if (is_deadlock) - my_error(ER_LOCK_DEADLOCK, MYF(0)); - else if (is_timeout) - my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); - return TRUE; - } + if (victim == this) + break; + /* + After adding a new edge to the waiting graph we found that it + creates a loop (i.e. there is a deadlock). We decided to destroy + this loop by removing an edge, but not the one that we added. + Since this doesn't guarantee that all loops created by addition + of the new edge are destroyed, we have to repeat the search. + */ } - return TRUE; } @@ -2241,7 +2384,7 @@ void MDL_ticket::downgrade_exclusive_lock(enum_mdl_type type) m_lock->m_granted.remove_ticket(this); m_type= type; m_lock->m_granted.add_ticket(this); - m_lock->wake_up_waiters(); + m_lock->reschedule_waiters(); mysql_prlock_unlock(&m_lock->m_rwlock); } @@ -2446,7 +2589,6 @@ void MDL_context::move_ticket_after_trans_sentinel(MDL_ticket *mdl_ticket) if (m_trans_sentinel == NULL) { m_trans_sentinel= mdl_ticket; - /* sic: linear from the number of transactional tickets acquired so-far! */ m_tickets.push_back(mdl_ticket); } else diff --git a/sql/mdl.h b/sql/mdl.h index ef133520140..43d88c143c0 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -447,6 +447,37 @@ private: }; +/** + A reliable way to wait on an MDL lock. +*/ + +class MDL_wait +{ +public: + MDL_wait(); + ~MDL_wait(); + + enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED }; + + bool set_status(enum_wait_status result_arg); + enum_wait_status get_status(); + void reset_status(); + enum_wait_status timed_wait(THD *thd, struct timespec *abs_timeout, + bool signal_timeout); +private: + /** + Condvar which is used for waiting until this context's pending + request can be satisfied or this thread has to perform actions + to resolve a potential deadlock (we subscribe to such + notification by adding a ticket corresponding to the request + to an appropriate queue of waiters). + */ + mysql_mutex_t m_LOCK_wait_status; + mysql_cond_t m_COND_wait_status; + enum_wait_status m_wait_status; +}; + + typedef I_P_List, @@ -464,16 +495,13 @@ public: typedef I_P_List > + &MDL_ticket::prev_in_context>, + I_P_List_null_counter, + I_P_List_fast_push_back > Ticket_list; typedef Ticket_list::Iterator Ticket_iterator; - enum mdl_signal_type { NO_WAKE_UP = 0, - NORMAL_WAKE_UP, - VICTIM_WAKE_UP, - TIMEOUT_WAKE_UP }; - MDL_context(); void destroy(); @@ -485,8 +513,6 @@ public: bool clone_ticket(MDL_request *mdl_request); - bool wait_for_lock(MDL_request *mdl_request, ulong lock_wait_timeout); - void release_all_locks_for_name(MDL_ticket *ticket); void release_lock(MDL_ticket *ticket); @@ -532,16 +558,13 @@ public: inline uint get_deadlock_weight() const { return m_waiting_for->get_deadlock_weight(); } /** - Wake up context which is waiting for a change of MDL_lock state. - */ - void awake(mdl_signal_type signal) - { - mysql_mutex_lock(&m_signal_lock); - m_signal= signal; - mysql_cond_signal(&m_signal_cond); - mysql_mutex_unlock(&m_signal_lock); - } + Post signal to the context (and wake it up if necessary). + @retval FALSE - Success, signal was posted. + @retval TRUE - Failure, signal was not posted since context + already has received some signal or closed + signal slot. + */ void init(THD *thd_arg) { m_thd= thd_arg; } void set_needs_thr_lock_abort(bool needs_thr_lock_abort) @@ -562,6 +585,12 @@ public: } bool find_deadlock(Deadlock_detection_visitor *dvisitor); +public: + /** + If our request for a lock is scheduled, or aborted by the deadlock + detector, the result is recorded in this class. + */ + MDL_wait m_wait; private: /** All MDL tickets acquired by this connection. @@ -643,60 +672,38 @@ private: important as deadlock detector won't work correctly otherwise. @sa Comment for MDL_lock::m_rwlock. */ - mysql_prlock_t m_waiting_for_lock; - MDL_ticket *m_waiting_for; - uint m_deadlock_weight; + mysql_prlock_t m_LOCK_waiting_for; /** - Condvar which is used for waiting until this context's pending - request can be satisfied or this thread has to perform actions - to resolve a potential deadlock (we subscribe to such - notification by adding a ticket corresponding to the request - to an appropriate queue of waiters). - */ - mysql_mutex_t m_signal_lock; - mysql_cond_t m_signal_cond; - mdl_signal_type m_signal; - + Tell the deadlock detector what lock this session is waiting for. + In principle, this is redundant, as information can be found + by inspecting waiting queues, but we'd very much like it to be + readily available to the wait-for graph iterator. + */ + MDL_ticket *m_waiting_for; private: MDL_ticket *find_ticket(MDL_request *mdl_req, bool *is_transactional); void release_locks_stored_before(MDL_ticket *sentinel); - bool acquire_lock_impl(MDL_request *mdl_request, ulong lock_wait_timeout); + bool try_acquire_lock_impl(MDL_request *mdl_request, + MDL_ticket **out_ticket); - bool find_deadlock(); + void find_deadlock(); + /** Inform the deadlock detector there is an edge in the wait-for graph. */ void will_wait_for(MDL_ticket *pending_ticket) { - mysql_prlock_wrlock(&m_waiting_for_lock); + mysql_prlock_wrlock(&m_LOCK_waiting_for); m_waiting_for= pending_ticket; - mysql_prlock_unlock(&m_waiting_for_lock); + mysql_prlock_unlock(&m_LOCK_waiting_for); } - void stop_waiting() + /** Remove the wait-for edge from the graph after we're done waiting. */ + void done_waiting_for() { - mysql_prlock_wrlock(&m_waiting_for_lock); + mysql_prlock_wrlock(&m_LOCK_waiting_for); m_waiting_for= NULL; - mysql_prlock_unlock(&m_waiting_for_lock); + mysql_prlock_unlock(&m_LOCK_waiting_for); } - - void wait_reset() - { - mysql_mutex_lock(&m_signal_lock); - m_signal= NO_WAKE_UP; - mysql_mutex_unlock(&m_signal_lock); - } - - mdl_signal_type timed_wait(struct timespec *abs_timeout); - - mdl_signal_type peek_signal() - { - mdl_signal_type result; - mysql_mutex_lock(&m_signal_lock); - result= m_signal; - mysql_mutex_unlock(&m_signal_lock); - return result; - } - private: MDL_context(const MDL_context &rhs); /* not implemented */ MDL_context &operator=(MDL_context &rhs); /* not implemented */ @@ -713,7 +720,6 @@ void mdl_destroy(); extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, bool needs_thr_lock_abort); -extern void mysql_ha_flush(THD *thd); extern "C" const char *set_thd_proc_info(void *thd_arg, const char *info, const char *calling_function, const char *calling_file, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bea10343eb6..3ac6b6ed635 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2364,6 +2364,66 @@ void table_share_release_hook(void *share) } +/** + An error handler which converts, if possible, ER_LOCK_DEADLOCK error + that can occur when we are trying to acquire a metadata lock to + a request for back-off and re-start of open_tables() process. +*/ + +class MDL_deadlock_handler : public Internal_error_handler +{ +public: + MDL_deadlock_handler(Open_table_context *ot_ctx_arg) + : m_ot_ctx(ot_ctx_arg), m_is_active(FALSE) + {} + + virtual ~MDL_deadlock_handler() {} + + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); + +private: + /** Open table context to be used for back-off request. */ + Open_table_context *m_ot_ctx; + /** + Indicates that we are already in the process of handling + ER_LOCK_DEADLOCK error. Allows to re-emit the error from + the error handler without falling into infinite recursion. + */ + bool m_is_active; +}; + + +bool MDL_deadlock_handler::handle_condition(THD *, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level, + const char*, + MYSQL_ERROR ** cond_hdl) +{ + *cond_hdl= NULL; + if (! m_is_active && sql_errno == ER_LOCK_DEADLOCK) + { + /* Disable the handler to avoid infinite recursion. */ + m_is_active= TRUE; + (void) m_ot_ctx->request_backoff_action(Open_table_context::OT_MDL_CONFLICT, + NULL); + m_is_active= FALSE; + /* + If the above back-off request failed, a new instance of + ER_LOCK_DEADLOCK error was emitted. Thus the current + instance of error condition can be treated as handled. + */ + return TRUE; + } + return FALSE; +} + + /** Try to acquire an MDL lock for a table being opened. @@ -2432,19 +2492,61 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, ot_ctx->add_request(mdl_request); - if (thd->mdl_context.try_acquire_lock(mdl_request)) - return TRUE; - - if (mdl_request->ticket == NULL) + if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) { - if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) + /* + When table is being open in order to get data for I_S table, + we might have some tables not only open but also locked (e.g. when + this happens under LOCK TABLES or in a stored function). + As a result by waiting on a conflicting metadata lock to go away + we may create a deadlock which won't entirely belong to the + MDL subsystem and thus won't be detectable by this subsystem's + deadlock detector. + To avoid such situation we skip the trouble-making table if + there is a conflicting lock. + */ + if (thd->mdl_context.try_acquire_lock(mdl_request)) + return TRUE; + if (mdl_request->ticket == NULL) { my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0), mdl_request->key.db_name(), mdl_request->key.name()); return TRUE; } - if (ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK, - mdl_request, NULL)) + } + else + { + /* + We are doing a normal table open. Let us try to acquire a metadata + lock on the table. If there is a conflicting lock, acquire_lock() + will wait for it to go away. Sometimes this waiting may lead to a + deadlock, with the following results: + 1) If a deadlock is entirely within MDL subsystem, it is + detected by the deadlock detector of this subsystem. + ER_LOCK_DEADLOCK error is produced. Then, the error handler + that is installed prior to the call to acquire_lock() attempts + to request a back-off and retry. Upon success, ER_LOCK_DEADLOCK + error is suppressed, otherwise propagated up the calling stack. + 2) Otherwise, a deadlock may occur when the wait-for graph + includes edges not visible to the MDL deadlock detector. + One such example is a wait on an InnoDB row lock, e.g. when: + conn C1 gets SR MDL lock on t1 with SELECT * FROM t1 + conn C2 gets a row lock on t2 with SELECT * FROM t2 FOR UPDATE + conn C3 gets in and waits on C1 with DROP TABLE t0, t1 + conn C2 continues and blocks on C3 with SELECT * FROM t0 + conn C1 deadlocks by waiting on C2 by issuing SELECT * FROM + t2 LOCK IN SHARE MODE. + Such circular waits are currently only resolved by timeouts, + e.g. @@innodb_lock_wait_timeout or @@lock_wait_timeout. + */ + MDL_deadlock_handler mdl_deadlock_handler(ot_ctx); + + thd->push_internal_handler(&mdl_deadlock_handler); + bool result= thd->mdl_context.acquire_lock(mdl_request, + ot_ctx->get_timeout()); + thd->pop_internal_handler(); + + if (result && !ot_ctx->can_recover_from_failed_open()) return TRUE; } *mdl_ticket= mdl_request->ticket; @@ -2542,7 +2644,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (thd->version != refresh_version) { (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, - NULL, NULL); + NULL); DBUG_RETURN(TRUE); } } @@ -2754,7 +2856,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, /* Someone did a refresh while thread was opening tables */ mysql_mutex_unlock(&LOCK_open); (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, - NULL, NULL); + NULL); DBUG_RETURN(TRUE); } @@ -2885,7 +2987,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, release_table_share(share); mysql_mutex_unlock(&LOCK_open); (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, - NULL, NULL); + NULL); DBUG_RETURN(TRUE); } /* Force close at once after usage */ @@ -2926,13 +3028,13 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, { share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, - NULL, table_list); + table_list); } else if (share->crashed) { share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR, - NULL, table_list); + table_list); } goto err_unlock; @@ -3789,8 +3891,7 @@ end_with_lock_open: /** Open_table_context */ Open_table_context::Open_table_context(THD *thd, uint flags) - :m_failed_mdl_request(NULL), - m_failed_table(NULL), + :m_failed_table(NULL), m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()), m_global_mdl_request(NULL), m_timeout(flags & MYSQL_LOCK_IGNORE_TIMEOUT ? @@ -3834,37 +3935,44 @@ MDL_request *Open_table_context::get_global_mdl_request(THD *thd) bool Open_table_context:: request_backoff_action(enum_open_table_action action_arg, - MDL_request *mdl_request, TABLE_LIST *table) + TABLE_LIST *table) { /* - We are inside a transaction that already holds locks and have - met a broken table or a table which needs re-discovery. - Performing any recovery action requires acquiring an exclusive - metadata lock on this table. Doing that with locks breaks the - metadata locking protocol and might lead to deadlocks, - so we report an error. + A back off action may be one of the three kinds: - However, if we have only met a conflicting lock or an old - TABLE version, and just need to wait for the conflict to - disappear/old version to go away, allow waiting. - While waiting, we use a simple empiric to detect - deadlocks: we never wait on someone who's waiting too. - Waiting will be done after releasing metadata locks acquired - by this statement. + * We met a broken table that needs repair, or a table that + is not present on this MySQL server and needs re-discovery. + To perform the action, we need an exclusive metadata lock on + the table. Acquiring an X lock while holding other shared + locks is very deadlock-prone. If this is a multi- statement + transaction that holds metadata locks for completed + statements, we don't do it, and report an error instead. + * Our attempt to acquire an MDL lock lead to a deadlock, + detected by the MDL deadlock detector. The current + session was chosen a victim. If this is a multi-statement + transaction that holds metadata locks for completed statements, + restarting locking for the current statement may lead + to a livelock. Thus, again, if m_has_locks is set, + we report an error. Otherwise, when there are no metadata + locks other than which belong to this statement, we can + try to recover from error by releasing all locks and + restarting the pre-locking. + * Finally, we could have met a TABLE_SHARE with old version. + Again, if this is a first statement in a transaction we can + close all tables, release all metadata locks and wait for + the old version to go away. Otherwise, waiting with MDL locks + may lead to criss-cross wait between this connection and a + connection that has an open table and waits on a metadata lock, + i.e. to a deadlock. + Since there is no way to detect such a deadlock, we prevent + it by reporting an error. */ - if (m_has_locks && action_arg != OT_WAIT_MDL_LOCK) + if (m_has_locks) { my_error(ER_LOCK_DEADLOCK, MYF(0)); return TRUE; } m_action= action_arg; - /* - If waiting for metadata lock is requested, a pointer to - MDL_request object for which we were unable to acquire the - lock is required. - */ - DBUG_ASSERT(m_action != OT_WAIT_MDL_LOCK || mdl_request); - m_failed_mdl_request= mdl_request; /* If auto-repair or discovery are requested, a pointer to table list element must be provided. @@ -3900,9 +4008,7 @@ recover_from_failed_open(THD *thd) /* Execute the action. */ switch (m_action) { - case OT_WAIT_MDL_LOCK: - result= thd->mdl_context.wait_for_lock(m_failed_mdl_request, - get_timeout()); + case OT_MDL_CONFLICT: break; case OT_WAIT_TDC: result= tdc_wait_for_old_versions(thd, &m_mdl_requests, get_timeout()); @@ -3973,7 +4079,6 @@ recover_from_failed_open(THD *thd) TABLE_LIST element, set when we need auto-discovery or repair, for safety. */ - m_failed_mdl_request= NULL; m_failed_table= NULL; /* Prepare for possible another back-off. */ m_action= OT_NO_ACTION; @@ -4097,16 +4202,25 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, */ DBUG_ASSERT(rt->mdl_request.type == MDL_SHARED); - if (thd->mdl_context.try_acquire_lock(&rt->mdl_request)) + /* + Waiting for a conflicting metadata lock to go away may + lead to a deadlock, detected by MDL subsystem. + If possible, we try to resolve such deadlocks by releasing all + metadata locks and restarting the pre-locking process. + To prevent the error from polluting the diagnostics area + in case of successful resolution, install a special error + handler for ER_LOCK_DEADLOCK error. + */ + MDL_deadlock_handler mdl_deadlock_handler(ot_ctx); + + thd->push_internal_handler(&mdl_deadlock_handler); + bool result= thd->mdl_context.acquire_lock(&rt->mdl_request, + ot_ctx->get_timeout()); + thd->pop_internal_handler(); + + if (result) DBUG_RETURN(TRUE); - if (rt->mdl_request.ticket == NULL) - { - /* A lock conflict. Someone's trying to modify SP metadata. */ - ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_MDL_LOCK, - &rt->mdl_request, NULL); - DBUG_RETURN(TRUE); - } DEBUG_SYNC(thd, "after_shared_lock_pname"); /* Ensures the routine is up-to-date and cached, if exists. */ @@ -4613,18 +4727,6 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, bool has_prelocking_list; DBUG_ENTER("open_tables"); - /* - Close HANDLER tables which are marked for flush or against which there - are pending exclusive metadata locks. Note that we do this not to avoid - deadlocks (calls to mysql_ha_flush() in mdl_wait_for_locks() and - tdc_wait_for_old_version() are enough for this) but in order to have - a point during statement execution at which such HANDLERs are closed - even if they don't create problems for current thread (i.e. to avoid - having DDL blocked by HANDLERs opened for long time). - */ - if (thd->handler_tables_hash.records) - mysql_ha_flush(thd); - /* temporary mem_root for new .frm parsing. TODO: variables for size @@ -4633,6 +4735,17 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, thd->current_tablenr= 0; restart: + /* + Close HANDLER tables which are marked for flush or against which there + are pending exclusive metadata locks. This is needed both in order to + avoid deadlocks and to have a point during statement execution at + which such HANDLERs are closed even if they don't create problems for + the current session (i.e. to avoid having a DDL blocked by HANDLERs + opened for a long time). + */ + if (thd->handler_tables_hash.records) + mysql_ha_flush(thd); + has_prelocking_list= thd->lex->requires_prelocking(); table_to_open= start; sroutine_to_open= (Sroutine_hash_entry**) &thd->lex->sroutines_list.first; @@ -5578,15 +5691,6 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, /* We have to cleanup translation tables of views. */ tmp->cleanup_items(); } - /* - Metadata lock requests for tables from extended part of prelocking set - are part of list of requests to be waited for in Open_table_context. - So to satisfy assumptions in MDL_context::wait_for_locks(), which will - performs the waiting, we have to reset MDL_request::ticket values for - them as well. - */ - for (tmp= first_not_own_table; tmp; tmp= tmp->next_global) - tmp->mdl_request.ticket= NULL; close_thread_tables(thd); thd->mdl_context.rollback_to_savepoint(start_of_statement_svp); } @@ -8692,8 +8796,12 @@ tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests, while (!thd->killed) { /* - Here we have situation as in mdl_wait_for_locks() we need to - get rid of offending HANDLERs to avoid deadlock. + We have to get rid of HANDLERs which are open by this thread + and have old TABLE versions. Otherwise we might get a deadlock + in situation when we are waiting for an old TABLE object which + corresponds to a HANDLER open by another session. And this + other session waits for our HANDLER object to get closed. + TODO: We should also investigate in which situations we have to broadcast on COND_refresh because of this. */ diff --git a/sql/sql_base.h b/sql/sql_base.h index 2abddb540b8..928b8339f15 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -451,7 +451,7 @@ public: enum enum_open_table_action { OT_NO_ACTION= 0, - OT_WAIT_MDL_LOCK, + OT_MDL_CONFLICT, OT_WAIT_TDC, OT_DISCOVER, OT_REPAIR @@ -460,7 +460,7 @@ public: bool recover_from_failed_open(THD *thd); bool request_backoff_action(enum_open_table_action action_arg, - MDL_request *mdl_request, TABLE_LIST *table); + TABLE_LIST *table); void add_request(MDL_request *request) { m_mdl_requests.push_front(request); } @@ -490,8 +490,6 @@ public: private: /** List of requests for all locks taken so far. Used for waiting on locks. */ MDL_request_list m_mdl_requests; - /** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */ - MDL_request *m_failed_mdl_request; /** For OT_DISCOVER and OT_REPAIR actions, the table list element for the table which definition should be re-discovered or which diff --git a/sql/sql_plist.h b/sql/sql_plist.h index eb239a63467..051fd216587 100644 --- a/sql/sql_plist.h +++ b/sql/sql_plist.h @@ -18,8 +18,10 @@ #include -template class I_P_List_iterator; +template +class I_P_List_iterator; class I_P_List_null_counter; +template class I_P_List_no_push_back; /** @@ -52,10 +54,17 @@ class I_P_List_null_counter; should be done. Instance of this class is also used as a place where information about number of list elements is stored. @sa I_P_List_null_counter, I_P_List_counter + @param I Policy class specifying whether I_P_List should support + efficient push_back() operation. Instance of this class + is used as place where we store information to support + this operation. + @sa I_P_List_no_push_back, I_P_List_fast_push_back. */ -template -class I_P_List : public C +template > +class I_P_List : public C, public I { T *first; @@ -65,31 +74,27 @@ class I_P_List : public C is a bad idea. */ public: - I_P_List() : first(NULL) { }; - inline void empty() { first= NULL; C::reset(); } + I_P_List() : I(&first), first(NULL) {}; + inline void empty() { first= NULL; C::reset(); I::set_last(&first); } inline bool is_empty() const { return (first == NULL); } inline void push_front(T* a) { *B::next_ptr(a)= first; if (first) *B::prev_ptr(first)= B::next_ptr(a); + else + I::set_last(B::next_ptr(a)); first= a; *B::prev_ptr(a)= &first; C::inc(); } inline void push_back(T *a) { - insert_after(back(), a); - } - inline T *back() - { - T *t= front(); - if (t) - { - while (*B::next_ptr(t)) - t= *B::next_ptr(t); - } - return t; + T **last= I::get_last(); + *B::next_ptr(a)= *last; + *last= a; + *B::prev_ptr(a)= last; + I::set_last(B::next_ptr(a)); } inline void insert_after(T *pos, T *a) { @@ -105,6 +110,8 @@ public: T *old_next= *B::next_ptr(a); *B::prev_ptr(old_next)= B::next_ptr(a); } + else + I::set_last(B::next_ptr(a)); } } inline void remove(T *a) @@ -112,6 +119,8 @@ public: T *next= *B::next_ptr(a); if (next) *B::prev_ptr(next)= *B::prev_ptr(a); + else + I::set_last(*B::prev_ptr(a)); **B::prev_ptr(a)= next; C::dec(); } @@ -120,16 +129,21 @@ public: void swap(I_P_List &rhs) { swap_variables(T *, first, rhs.first); + I::swap(rhs); if (first) *B::prev_ptr(first)= &first; + else + I::set_last(&first); if (rhs.first) *B::prev_ptr(rhs.first)= &rhs.first; + else + I::set_last(&rhs.first); C::swap(rhs); } #ifndef _lint - friend class I_P_List_iterator; + friend class I_P_List_iterator; #endif - typedef I_P_List_iterator Iterator; + typedef I_P_List_iterator Iterator; }; @@ -137,15 +151,19 @@ public: Iterator for I_P_List. */ -template +template > class I_P_List_iterator { - const I_P_List *list; + const I_P_List *list; T *current; public: - I_P_List_iterator(const I_P_List &a) : list(&a), current(a.first) {} - I_P_List_iterator(const I_P_List &a, T* current_arg) : list(&a), current(current_arg) {} - inline void init(const I_P_List &a) + I_P_List_iterator(const I_P_List &a) + : list(&a), current(a.first) {} + I_P_List_iterator(const I_P_List &a, T* current_arg) + : list(&a), current(current_arg) {} + inline void init(const I_P_List &a) { list= &a; current= a.first; @@ -203,4 +221,40 @@ public: uint elements() const { return m_counter; } }; + +/** + A null insertion policy class for I_P_List to be used + in cases when push_back() operation is not necessary. +*/ + +template class I_P_List_no_push_back +{ +protected: + I_P_List_no_push_back(T **a) {}; + void set_last(T **a) {} + /* + T** get_last() const method is intentionally left unimplemented + in order to prohibit usage of push_back() method in lists which + use this policy. + */ + void swap(I_P_List_no_push_back &rhs) {} +}; + + +/** + An insertion policy class for I_P_List which can + be used when fast push_back() operation is required. +*/ + +template class I_P_List_fast_push_back +{ + T **last; +protected: + I_P_List_fast_push_back(T **a) : last(a) { }; + void set_last(T **a) { last= a; } + T** get_last() const { return last; } + void swap(I_P_List_fast_push_back &rhs) + { swap_variables(T**, last, rhs.last); } +}; + #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 61b61106522..2a0c6425122 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3136,15 +3136,27 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table, bool error; table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name, MDL_SHARED_HIGH_PRIO); - while (!(error= - thd->mdl_context.try_acquire_lock(&table->mdl_request)) && - !table->mdl_request.ticket && !can_deadlock) + + if (can_deadlock) { - if ((error= - thd->mdl_context.wait_for_lock(&table->mdl_request, - thd->variables.lock_wait_timeout))) - break; + /* + When .FRM is being open in order to get data for an I_S table, + we might have some tables not only open but also locked. + E.g. this happens when a SHOW or I_S statement is run + under LOCK TABLES or inside a stored function. + By waiting for the conflicting metadata lock to go away we + might create a deadlock which won't entirely belong to the + MDL subsystem and thus won't be detectable by this subsystem's + deadlock detector. To avoid such situation, when there are + other locked tables, we prefer not to wait on a conflicting + lock. + */ + error= thd->mdl_context.try_acquire_lock(&table->mdl_request); } + else + error= thd->mdl_context.acquire_lock(&table->mdl_request, + thd->variables.lock_wait_timeout); + return error; } From eb75276544f660ec3d27c24f9e85c423b5a44988 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Mon, 7 Jun 2010 16:05:34 +0400 Subject: [PATCH 152/207] A fix for Bug#52432 "Crash in check_table_is_closed on an information_schema query. Porting a fix done for a feature tree by Ingo Struewing. No test case since the crash only occurs under a stress load. --- storage/myisam/mi_dbug.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c index 45882eda6af..e450e81cecb 100644 --- a/storage/myisam/mi_dbug.c +++ b/storage/myisam/mi_dbug.c @@ -164,7 +164,19 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg, } /* print_key */ -#ifdef EXTRA_DEBUG +#ifdef EXTRA_DEBUG +/** + Check if the named table is in the open list. + + @param[in] name table path as in MYISAM_SHARE::unique_file_name + @param[in] where verbal description of caller + + @retval TRUE table is in open list + @retval FALSE table is not in open list + + @note This function takes THR_LOCK_myisam. Do not call it when + this mutex is locked by this thread already. +*/ my_bool check_table_is_closed(const char *name, const char *where) { @@ -173,6 +185,7 @@ my_bool check_table_is_closed(const char *name, const char *where) DBUG_ENTER("check_table_is_closed"); (void) fn_format(filename,name,"",MI_NAME_IEXT,4+16+32); + mysql_mutex_lock(&THR_LOCK_myisam); for (pos=myisam_open_list ; pos ; pos=pos->next) { MI_INFO *info=(MI_INFO*) pos->data; @@ -181,12 +194,14 @@ my_bool check_table_is_closed(const char *name, const char *where) { if (share->last_version) { + mysql_mutex_unlock(&THR_LOCK_myisam); fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where); DBUG_PRINT("warning",("Table: %s is open on %s", name,where)); DBUG_RETURN(1); } } } + mysql_mutex_unlock(&THR_LOCK_myisam); DBUG_RETURN(0); } #endif /* EXTRA_DEBUG */ From 83121c6caed0945904554aba3b126ddee0359401 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Mon, 7 Jun 2010 17:40:52 +0400 Subject: [PATCH 153/207] Follow-up for bug#52289 "performance regression for MyISAM in sysbench OLTP_RW test". Fixes compilation warnings about local variable shadowing I_P_List_fast_push_back::last member. Renamed I_P_List_fast_push_back::last member to m_last. Also to keep member naming consistent renamed I_P_List::first member to m_first. --- sql/sql_plist.h | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/sql/sql_plist.h b/sql/sql_plist.h index 051fd216587..db85266be15 100644 --- a/sql/sql_plist.h +++ b/sql/sql_plist.h @@ -66,7 +66,7 @@ template > class I_P_List : public C, public I { - T *first; + T *m_first; /* Do not prohibit copying of I_P_List object to simplify their usage in @@ -74,18 +74,18 @@ class I_P_List : public C, public I is a bad idea. */ public: - I_P_List() : I(&first), first(NULL) {}; - inline void empty() { first= NULL; C::reset(); I::set_last(&first); } - inline bool is_empty() const { return (first == NULL); } + I_P_List() : I(&m_first), m_first(NULL) {}; + inline void empty() { m_first= NULL; C::reset(); I::set_last(&m_first); } + inline bool is_empty() const { return (m_first == NULL); } inline void push_front(T* a) { - *B::next_ptr(a)= first; - if (first) - *B::prev_ptr(first)= B::next_ptr(a); + *B::next_ptr(a)= m_first; + if (m_first) + *B::prev_ptr(m_first)= B::next_ptr(a); else I::set_last(B::next_ptr(a)); - first= a; - *B::prev_ptr(a)= &first; + m_first= a; + *B::prev_ptr(a)= &m_first; C::inc(); } inline void push_back(T *a) @@ -124,20 +124,20 @@ public: **B::prev_ptr(a)= next; C::dec(); } - inline T* front() { return first; } - inline const T *front() const { return first; } + inline T* front() { return m_first; } + inline const T *front() const { return m_first; } void swap(I_P_List &rhs) { - swap_variables(T *, first, rhs.first); + swap_variables(T *, m_first, rhs.m_first); I::swap(rhs); - if (first) - *B::prev_ptr(first)= &first; + if (m_first) + *B::prev_ptr(m_first)= &m_first; else - I::set_last(&first); - if (rhs.first) - *B::prev_ptr(rhs.first)= &rhs.first; + I::set_last(&m_first); + if (rhs.m_first) + *B::prev_ptr(rhs.m_first)= &rhs.m_first; else - I::set_last(&rhs.first); + I::set_last(&rhs.m_first); C::swap(rhs); } #ifndef _lint @@ -160,13 +160,13 @@ class I_P_List_iterator T *current; public: I_P_List_iterator(const I_P_List &a) - : list(&a), current(a.first) {} + : list(&a), current(a.m_first) {} I_P_List_iterator(const I_P_List &a, T* current_arg) : list(&a), current(current_arg) {} inline void init(const I_P_List &a) { list= &a; - current= a.first; + current= a.m_first; } inline T* operator++(int) { @@ -182,7 +182,7 @@ public: } inline void rewind() { - current= list->first; + current= list->m_first; } }; @@ -248,13 +248,13 @@ protected: template class I_P_List_fast_push_back { - T **last; + T **m_last; protected: - I_P_List_fast_push_back(T **a) : last(a) { }; - void set_last(T **a) { last= a; } - T** get_last() const { return last; } + I_P_List_fast_push_back(T **a) : m_last(a) { }; + void set_last(T **a) { m_last= a; } + T** get_last() const { return m_last; } void swap(I_P_List_fast_push_back &rhs) - { swap_variables(T**, last, rhs.last); } + { swap_variables(T**, m_last, rhs.m_last); } }; #endif From 666f5544c2ce8d8c5ab2e276412d8c2e0a4a3a1a Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Mon, 7 Jun 2010 18:52:44 +0400 Subject: [PATCH 154/207] Apply: 3413 Davi Arnaut 2010-06-03 Don't enable safemalloc for valgrind builds, it's too slow. to trunk-runtime. --- BUILD/SETUP.sh | 2 +- BUILD/build_mccge.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 0bc16f120e5..626f932e045 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -122,7 +122,7 @@ fi # Override -DFORCE_INIT_OF_VARS from debug_cflags. It enables the macro # LINT_INIT(), which is only useful for silencing spurious warnings # of static analysis tools. We want LINT_INIT() to be a no-op in Valgrind. -valgrind_flags="-UFORCE_INIT_OF_VARS -DHAVE_purify " +valgrind_flags="-USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify " valgrind_flags="$valgrind_flags -DMYSQL_SERVER_SUFFIX=-valgrind-max" valgrind_configs="--with-valgrind" # diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index 2d7c0d2a2c2..c3803610e73 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -1010,7 +1010,7 @@ set_ccache_usage() set_valgrind_flags() { if test "x$valgrind_flag" = "xyes" ; then - loc_valgrind_flags="-UFORCE_INIT_OF_VARS -DHAVE_purify " + loc_valgrind_flags="-USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify " loc_valgrind_flags="$loc_valgrind_flags -DMYSQL_SERVER_SUFFIX=-valgrind-max" compiler_flags="$compiler_flags $loc_valgrind_flags" with_flags="$with_flags --with-valgrind" From 5196821127d48dcf767c1751570b2a8a468bc5f3 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Mon, 7 Jun 2010 18:53:50 +0400 Subject: [PATCH 155/207] Backport two small cleanups from trunk-iplus tree: 1) No mutex and no function call if we're not using plugins. 2) If we're above the table definition cache limit, delete the oldest unused share, not the share on our hands. --- sql/sql_base.cc | 14 ++++++-------- sql/sql_lex.cc | 7 +++++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3ac6b6ed635..657688499db 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -686,7 +686,6 @@ static TABLE_SHARE void release_table_share(TABLE_SHARE *share) { - bool to_be_deleted= 0; DBUG_ENTER("release_table_share"); DBUG_PRINT("enter", ("share: 0x%lx table: %s.%s ref_count: %u version: %lu", @@ -700,7 +699,7 @@ void release_table_share(TABLE_SHARE *share) { if (share->version != refresh_version || table_def_shutdown_in_progress) - to_be_deleted=1; + my_hash_delete(&table_def_cache, (uchar*) share); else { /* Link share last in used_table_share list */ @@ -712,15 +711,14 @@ void release_table_share(TABLE_SHARE *share) end_of_unused_share.prev= &share->next; share->next= &end_of_unused_share; - to_be_deleted= (table_def_cache.records > table_def_size); + if (table_def_cache.records > table_def_size) + { + /* Delete the least used share to preserve LRU order. */ + my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share); + } } } - if (to_be_deleted) - { - DBUG_PRINT("info", ("Deleting share")); - my_hash_delete(&table_def_cache, (uchar*) share); - } DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e87204ffd40..3f3c650d1e8 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -435,8 +435,11 @@ void lex_end(LEX *lex) DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex)); /* release used plugins */ - plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, - lex->plugins.elements); + if (lex->plugins.elements) /* No function call and no mutex if no plugins. */ + { + plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, + lex->plugins.elements); + } reset_dynamic(&lex->plugins); DBUG_VOID_RETURN; From b5a038a590c2b9339704dcd8e21defc0c5cb8092 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 7 Jun 2010 17:27:40 +0200 Subject: [PATCH 156/207] Bug #54282 Crash in MDL_context::upgrade_shared_lock_to_exclusive This crash happened if a table was listed twice in a DROP TABLE statement, and the statement was executed while in LOCK TABLES mode. Since the two elements of table list were identical, they were assigned the same TABLE object. During processing of the first table element, the TABLE instance was destroyed and the second table list element was left with a dangling reference. When this reference was later accessed, the server crashed. Listing the same table twice in DROP TABLES should give an ER_NONUNIQ_TABLE error. However, this did not happen as the check for unique table names was skipped due to the lock type for table list elements being set to TL_IGNORE. Previously TL_UNLOCK was used and the unique check was performed. This bug was a regression introduced by a pre-requisite patch for Bug#51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". The regression only existed in an internal team tree and never in any released code. This patch reverts DROP TABLE (and DROP VIEW) to the old behavior of using TL_UNLOCK locks. Test case added to drop.test. --- mysql-test/r/drop.result | 10 ++++++++++ mysql-test/t/drop.test | 17 +++++++++++++++++ sql/sql_yacc.yy | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 17ec2b09a0a..f1712a650b1 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -157,3 +157,13 @@ Error 1051 Unknown table 't1' # -- # -- End of Bug#37431. # -- +# +# Bug#54282 Crash in MDL_context::upgrade_shared_lock_to_exclusive +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT); +LOCK TABLE t1 WRITE; +DROP TABLE t1, t1; +ERROR 42000: Not unique table/alias: 't1' +UNLOCK TABLES; +DROP TABLE t1; diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 5ef4a28b202..b5ca0817b6f 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -256,3 +256,20 @@ SHOW WARNINGS; --echo # -- --echo # -- End of Bug#37431. --echo # -- + + +--echo # +--echo # Bug#54282 Crash in MDL_context::upgrade_shared_lock_to_exclusive +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT); +LOCK TABLE t1 WRITE; +--error ER_NONUNIQ_TABLE +DROP TABLE t1, t1; + +UNLOCK TABLES; +DROP TABLE t1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 34e20374042..84412469252 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10151,7 +10151,7 @@ drop: lex->sql_command = SQLCOM_DROP_TABLE; lex->drop_temporary= $2; lex->drop_if_exists= $4; - YYPS->m_lock_type= TL_IGNORE; + YYPS->m_lock_type= TL_UNLOCK; YYPS->m_mdl_type= MDL_EXCLUSIVE; } table_list opt_restrict @@ -10244,7 +10244,7 @@ drop: LEX *lex= Lex; lex->sql_command= SQLCOM_DROP_VIEW; lex->drop_if_exists= $3; - YYPS->m_lock_type= TL_IGNORE; + YYPS->m_lock_type= TL_UNLOCK; YYPS->m_mdl_type= MDL_EXCLUSIVE; } table_list opt_restrict From 4b6b69d22e33b1fadf1546492b17c81dfed20766 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Tue, 8 Jun 2010 12:08:46 +0400 Subject: [PATCH 157/207] WL#4441 "LOCK_open: Remove requirement of mutex protecting thd->open_tables" thd->open_tables list is not normally accessed concurrently except for one case: when the connection has open SQL HANDLER tables, and we want to perform a DDL on the table, we want to abort waits on MyISAM thr_lock of those connections that prevent the DDL from proceeding, and iterate over thd->open_tables list to find out the tables on which the thread is waiting. In 5.5 we mostly use deadlock detection and soft deadlock prevention, as opposed to "hard" deadlock prevention of 5.1, which would abort any transaction that may cause a deadlock. The only remaining case when neither deadlock detection nor deadlock prevention is implemented in 5.5 is HANDLER SQL, where we use old good thr_lock_abort() technique form 5.1. Thus, replace use of LOCK_open to protect thd->open_tables with thd->LOCK_ha_data (a lock protecting various session private data). This is a port of the work done for 5.5.4 for review and inclusion into 5.5.5. --- sql/sql_base.cc | 65 ++++++++++++++++++++-------------------------- sql/sql_class.h | 6 +++++ sql/sql_cursor.cc | 8 +++--- sql/sql_handler.cc | 12 ++++----- sql/sql_table.cc | 4 --- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 657688499db..3b94388d6b8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1294,23 +1294,16 @@ static void close_open_tables(THD *thd) mysql_mutex_assert_not_owner(&LOCK_open); - mysql_mutex_lock(&LOCK_open); - DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables)); while (thd->open_tables) found_old_table|= close_thread_table(thd, &thd->open_tables); - /* Free tables to hold down open files */ - while (table_cache_count > table_cache_size && unused_tables) - free_cache_entry(unused_tables); if (found_old_table) { /* Tell threads waiting for refresh that something has happened */ broadcast_refresh(); } - - mysql_mutex_unlock(&LOCK_open); } @@ -1342,13 +1335,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, memcpy(key, share->table_cache_key.str, key_length); mysql_mutex_assert_not_owner(&LOCK_open); - /* - We need to hold LOCK_open while changing the open_tables - list, since another thread may work on it. - @sa mysql_notify_thread_having_shared_lock() - */ - mysql_mutex_lock(&LOCK_open); - for (TABLE **prev= &thd->open_tables; *prev; ) { TABLE *table= *prev; @@ -1356,10 +1342,9 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length)) { - /* Inform handler that table will be dropped after close */ - if (table->db_stat) - table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); - + thd->locked_tables_list.unlink_from_list(thd, + table->pos_in_locked_tables, + remove_from_locked_tables); /* Does nothing if the table is not locked. This allows one to use this function after a table @@ -1367,12 +1352,11 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, */ mysql_lock_remove(thd, thd->lock, table); - thd->locked_tables_list.unlink_from_list(thd, - table->pos_in_locked_tables, - remove_from_locked_tables); - /* Make sure the table is removed from the cache */ table->s->version= 0; + /* Inform handler that table will be dropped after close */ + if (table->db_stat) /* Not true for partitioned tables. */ + table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); close_thread_table(thd, prev); } else @@ -1383,7 +1367,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, } /* We have been removing tables from the table cache. */ broadcast_refresh(); - mysql_mutex_unlock(&LOCK_open); } @@ -1582,17 +1565,22 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) DBUG_ENTER("close_thread_table"); DBUG_ASSERT(table->key_read == 0); DBUG_ASSERT(!table->file || table->file->inited == handler::NONE); - mysql_mutex_assert_owner(&LOCK_open); - - *table_ptr=table->next; + mysql_mutex_assert_not_owner(&LOCK_open); table->mdl_ticket= NULL; + + mysql_mutex_lock(&thd->LOCK_thd_data); + *table_ptr=table->next; + mysql_mutex_unlock(&thd->LOCK_thd_data); + + mysql_mutex_lock(&LOCK_open); + if (table->s->needs_reopen() || thd->version != refresh_version || table->needs_reopen() || table_def_shutdown_in_progress) { free_cache_entry(table); - found_old_table=1; + found_old_table= 1; } else { @@ -1602,10 +1590,17 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) /* Free memory and reset for next loop */ free_field_buffers_larger_than(table,MAX_TDC_BLOB_SIZE); - + table->file->ha_reset(); table_def_unuse_table(table); + /* + We free the least used table, not the subject table, + to keep the LRU order. + */ + if (table_cache_count > table_cache_size) + free_cache_entry(unused_tables); } + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(found_old_table); } @@ -2229,11 +2224,9 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, /* Ensure the table is removed from the cache. */ table->s->version= 0; - mysql_mutex_lock(&LOCK_open); table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); close_thread_table(thd, &thd->open_tables); quick_rm_table(table_type, db_name, table_name, 0); - mysql_mutex_unlock(&LOCK_open); } DBUG_VOID_RETURN; } @@ -3062,8 +3055,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->mdl_ticket= mdl_ticket; - table->next=thd->open_tables; /* Link into simple list */ - thd->open_tables=table; + table->next= thd->open_tables; /* Link into simple list */ + thd->set_open_tables(table); table->reginfo.lock_type=TL_READ; /* Assume read */ @@ -3403,7 +3396,6 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) */ if (reopen_count) { - mysql_mutex_lock(&LOCK_open); while (reopen_count--) { /* @@ -3420,7 +3412,6 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) close_thread_table(thd, &thd->open_tables); } broadcast_refresh(); - mysql_mutex_unlock(&LOCK_open); } /* Exclude all closed tables from the LOCK TABLES list. */ for (TABLE_LIST *table_list= m_locked_tables; table_list; table_list= @@ -8655,10 +8646,10 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, mysql_mutex_unlock(&in_use->mysys_var->mutex); signalled= TRUE; } - mysql_mutex_lock(&LOCK_open); if (needs_thr_lock_abort) { + mysql_mutex_lock(&in_use->LOCK_thd_data); for (TABLE *thd_table= in_use->open_tables; thd_table ; thd_table= thd_table->next) @@ -8669,10 +8660,11 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, and do not remove such instances from the THD::open_tables for some time, during which other thread can see those instances (e.g. see partitioning code). - */ + */ if (!thd_table->needs_reopen()) signalled|= mysql_lock_abort_for_thread(thd, thd_table); } + mysql_mutex_unlock(&in_use->LOCK_thd_data); } /* Wake up threads waiting in tdc_wait_for_old_versions(). @@ -8685,7 +8677,6 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, a multi-statement transaction. */ broadcast_refresh(); - mysql_mutex_unlock(&LOCK_open); return signalled; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a25112b577..8b5fde2ccff 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2682,6 +2682,12 @@ public: void set_query_and_id(char *query_arg, uint32 query_length_arg, query_id_t new_query_id); void set_query_id(query_id_t new_query_id); + void set_open_tables(TABLE *open_tables_arg) + { + mysql_mutex_lock(&LOCK_thd_data); + open_tables= open_tables_arg; + mysql_mutex_unlock(&LOCK_thd_data); + } void enter_locked_tables_mode(enum_locked_tables_mode mode_arg) { DBUG_ASSERT(locked_tables_mode == LTM_NONE); diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 59bf0764ada..ca724ec262f 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -357,7 +357,7 @@ void Sensitive_cursor::reset_thd(THD *thd) { thd->derived_tables= 0; - thd->open_tables= 0; + thd->set_open_tables(NULL); thd->lock= 0; thd->free_list= 0; thd->change_list.empty(); @@ -436,7 +436,7 @@ Sensitive_cursor::fetch(ulong num_rows) thd->lock == 0); thd->derived_tables= derived_tables; - thd->open_tables= open_tables; + thd->set_open_tables(open_tables); thd->lock= lock; thd->set_query_id(query_id); change_list.move_elements_to(&thd->change_list); @@ -519,14 +519,14 @@ Sensitive_cursor::close() TABLE *tmp_derived_tables= thd->derived_tables; MYSQL_LOCK *tmp_lock= thd->lock; - thd->open_tables= open_tables; + thd->set_open_tables(open_tables); thd->derived_tables= derived_tables; thd->lock= lock; /* Is expected to at least close tables and empty thd->change_list */ stmt_arena->cleanup_stmt(); - thd->open_tables= tmp_derived_tables; + thd->set_open_tables(tmp_derived_tables); thd->derived_tables= tmp_derived_tables; thd->lock= tmp_lock; } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 23177b8f51a..d07c7eaa277 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -131,13 +131,11 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) /* Non temporary table. */ tables->table->file->ha_index_or_rnd_end(); tables->table->open_by_handler= 0; - mysql_mutex_lock(&LOCK_open); if (close_thread_table(thd, &tables->table)) { /* Tell threads waiting for refresh that something has happened */ broadcast_refresh(); } - mysql_mutex_unlock(&LOCK_open); thd->mdl_context.release_lock(tables->mdl_request.ticket); } else if (tables->table) @@ -278,7 +276,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) See open_table() back-off comments for more details. */ backup_open_tables= thd->open_tables; - thd->open_tables= NULL; + thd->set_open_tables(NULL); mdl_savepoint= thd->mdl_context.mdl_savepoint(); /* @@ -312,7 +310,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) if (error) { close_thread_tables(thd); - thd->open_tables= backup_open_tables; + thd->set_open_tables(backup_open_tables); thd->mdl_context.rollback_to_savepoint(mdl_savepoint); if (!reopen) my_hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables); @@ -325,7 +323,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) DBUG_PRINT("exit",("ERROR")); DBUG_RETURN(TRUE); } - thd->open_tables= backup_open_tables; + thd->set_open_tables(backup_open_tables); if (hash_tables->mdl_request.ticket) { thd->mdl_context. @@ -559,7 +557,7 @@ retry: mysql_lock_tables() needs thd->open_tables to be set correctly to be able to handle aborts properly. */ - thd->open_tables= hash_tables->table; + thd->set_open_tables(hash_tables->table); sql_handler_lock_error.init(); @@ -575,7 +573,7 @@ retry: */ DBUG_ASSERT(hash_tables->table == thd->open_tables); /* Restore previous context. */ - thd->open_tables= backup_open_tables; + thd->set_open_tables(backup_open_tables); if (sql_handler_lock_error.need_reopen()) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6fbee4f856e..843fb5b35d2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5429,14 +5429,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, goto err; DBUG_ASSERT(thd->open_tables == table->table); - mysql_mutex_lock(&LOCK_open); /* When opening the table, we ignored the locked tables (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table without risking to close some locked table. */ close_thread_table(thd, &thd->open_tables); - mysql_mutex_unlock(&LOCK_open); } } else // Case 1 @@ -7490,9 +7488,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info); DBUG_ASSERT(thd->open_tables == t_table); - mysql_mutex_lock(&LOCK_open); close_thread_table(thd, &thd->open_tables); - mysql_mutex_unlock(&LOCK_open); table_list->table= 0; if (error) From 570a4ae8fefc6c2acdc6e6c25b82953ba4ed16c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Jun 2010 14:47:34 +0300 Subject: [PATCH 158/207] =?UTF-8?q?Merge=20a=20change=20from=20mysql-5.1-i?= =?UTF-8?q?nnodb:=20------------------------------------------------------?= =?UTF-8?q?------=20revno:=203502=20revision-id:=20marko.makela@oracle.com?= =?UTF-8?q?-20100608114055-7b04ytuqz0lde6v1=20parent:=20jimmy.yang@oracle.?= =?UTF-8?q?com-20100603134448-itzduhwgbw0b8nlh=20committer:=20Marko=20M?= =?UTF-8?q?=C3=A4kel=C3=A4=20=20branch=20nick:=20?= =?UTF-8?q?5.1-innodb=20timestamp:=20Tue=202010-06-08=2014:40:55=20+0300?= =?UTF-8?q?=20message:=20=20=20buf=5Fpage=5Fget=5Fgen():=20Pass=20file,lin?= =?UTF-8?q?e=20to=20rw=5Flock=5Fx=5Flock().?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- storage/innobase/buf/buf0buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index ae228732270..4b6b0a82486 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -2957,7 +2957,7 @@ wait_until_unfixed: block->page.buf_fix_count = 1; buf_block_set_io_fix(block, BUF_IO_READ); - rw_lock_x_lock(&block->lock); + rw_lock_x_lock_func(&block->lock, 0, file, line); UNIV_MEM_INVALID(bpage, sizeof *bpage); From fe0037b996d5c0d816e329b9151517903550976f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Jun 2010 15:26:45 +0300 Subject: [PATCH 159/207] =?UTF-8?q?Merge=20a=20change=20from=20mysql-5.1-i?= =?UTF-8?q?nnodb:=20------------------------------------------------------?= =?UTF-8?q?------=20revno:=203503=20revision-id:=20marko.makela@oracle.com?= =?UTF-8?q?-20100608121041-l7t9r6lrpx6lh361=20parent:=20marko.makela@oracl?= =?UTF-8?q?e.com-20100608114055-7b04ytuqz0lde6v1=20committer:=20Marko=20M?= =?UTF-8?q?=C3=A4kel=C3=A4=20=20branch=20nick:=20?= =?UTF-8?q?5.1-innodb=20timestamp:=20Tue=202010-06-08=2015:10:41=20+0300?= =?UTF-8?q?=20message:=20=20=20Bug#54009:=20Server=20crashes=20when=20data?= =?UTF-8?q?=20is=20selected=20from=20non=20backed=20up=20table=20=20=20for?= =?UTF-8?q?=20InnoDB=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dict_load_table(): Pass the correct tablespace flags to fil_open_single_table_tablespace(). For ROW_FORMAT=COMPACT and REDUNDANT, the tablespace flags are 0. The table flags would be 0 or DICT_TF_COMPACT. --- storage/innobase/dict/dict0load.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index b061fe696c1..6bf2c1d9d81 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -1694,6 +1694,7 @@ err_exit: /* Try to open the tablespace */ if (!fil_open_single_table_tablespace( TRUE, table->space, + table->flags == DICT_TF_COMPACT ? 0 : table->flags & ~(~0 << DICT_TF_BITS), name)) { /* We failed to find a sensible tablespace file */ From b976fb144407d3fbc892d080fce9bcd3c3922c93 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 9 Jun 2010 12:39:09 +0400 Subject: [PATCH 160/207] A review comment for WL#4441 " LOCK_open: Remove requirement of mutex protecting thd->open_tables". We should not manipulate with table->s->version outside the table definition cache code, but use the TDC API to achieve the desired result. Fix one violation: close_all_tables_for_name(). --- sql/sql_base.cc | 24 ++++++++++++++++++------ sql/sql_handler.cc | 29 +++++++++++++++++++++++++++++ sql/sql_handler.h | 1 + 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3b94388d6b8..39e6f976f3b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1022,6 +1022,9 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, TABLE_LIST *tables_to_reopen= (tables ? tables : thd->locked_tables_list.locked_tables()); + /* Close open HANLER instances to avoid self-deadlock. */ + mysql_ha_flush_tables(thd, tables_to_reopen); + for (TABLE_LIST *table_list= tables_to_reopen; table_list; table_list= table_list->next_global) { @@ -1049,7 +1052,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, { found= FALSE; /* - To avoid self and other kinds of deadlock we have to flush open HANDLERs. + To a self-deadlock or deadlocks with other FLUSH threads + waiting on our open HANDLERs, we have to flush them. */ mysql_ha_flush(thd); DEBUG_SYNC(thd, "after_flush_unlock"); @@ -1308,8 +1312,7 @@ static void close_open_tables(THD *thd) /** - Close all open instances of the table but keep the MDL lock, - if any. + Close all open instances of the table but keep the MDL lock. Works both under LOCK TABLES and in the normal mode. Removes all closed instances of the table from the table cache. @@ -1323,6 +1326,8 @@ static void close_open_tables(THD *thd) In that case the documented behaviour is to implicitly remove the table from LOCK TABLES list. + + @pre Must be called with an X MDL lock on the table. */ void @@ -1331,6 +1336,8 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, { char key[MAX_DBKEY_LENGTH]; uint key_length= share->table_cache_key.length; + const char *db= key; + const char *table_name= db + share->db.length + 1; memcpy(key, share->table_cache_key.str, key_length); @@ -1352,8 +1359,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, */ mysql_lock_remove(thd, thd->lock, table); - /* Make sure the table is removed from the cache */ - table->s->version= 0; /* Inform handler that table will be dropped after close */ if (table->db_stat) /* Not true for partitioned tables. */ table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); @@ -1365,7 +1370,14 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, prev= &table->next; } } - /* We have been removing tables from the table cache. */ + /* Remove the table share from the cache. */ + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name); + mysql_mutex_unlock(&LOCK_open); + /* + There could be a FLUSH thread waiting + on the table to go away. Wake it up. + */ broadcast_refresh(); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index d07c7eaa277..b2e793b5938 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -833,6 +833,35 @@ void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables) } +/** + Close cursors of matching tables from the HANDLER's hash table. + + @param thd Thread identifier. + @param tables The list of tables to flush. +*/ + +void mysql_ha_flush_tables(THD *thd, TABLE_LIST *all_tables) +{ + DBUG_ENTER("mysql_ha_flush_tables"); + + for (TABLE_LIST *table_list= all_tables; table_list; + table_list= table_list->next_global) + { + TABLE_LIST *hash_tables= mysql_ha_find(thd, table_list); + /* Close all aliases of the same table. */ + while (hash_tables) + { + TABLE_LIST *next_local= hash_tables->next_local; + if (hash_tables->table) + mysql_ha_close_table(thd, hash_tables); + hash_tables= next_local; + } + } + + DBUG_VOID_RETURN; +} + + /** Flush (close and mark for re-open) all tables that should be should be reopen. diff --git a/sql/sql_handler.h b/sql/sql_handler.h index 8666d5a8d7b..c5da3c4d468 100644 --- a/sql/sql_handler.h +++ b/sql/sql_handler.h @@ -28,6 +28,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables); bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List *,enum ha_rkey_function,Item *,ha_rows,ha_rows); void mysql_ha_flush(THD *thd); +void mysql_ha_flush_tables(THD *thd, TABLE_LIST *all_tables); void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables); void mysql_ha_cleanup(THD *thd); void mysql_ha_move_tickets_after_trans_sentinel(THD *thd); From fdd7c28bd80339921fdbf1a8db537a0d41e0084c Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Wed, 9 Jun 2010 10:46:24 +0200 Subject: [PATCH 161/207] Post-commit fixes after the push for Bug#20837 et. al. --- mysql-test/r/parser.result | 45 ----------- mysql-test/r/parser_not_embedded.result | 45 +++++++++++ .../innodb/r/innodb-semi-consistent.result | 1 + .../innodb/r/innodb_information_schema.result | 2 +- .../innodb/t/innodb-semi-consistent.test | 1 + mysql-test/t/parser.test | 75 ------------------- mysql-test/t/parser_not_embedded.test | 75 +++++++++++++++++++ 7 files changed, 123 insertions(+), 121 deletions(-) diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 0cfde6dd2a0..467bb7c5cb8 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -618,48 +618,3 @@ DROP TABLE t1, t2, t3; # # End of 5.1 tests # -# Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" -# -COMMIT AND CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -COMMIT AND NO CHAIN RELEASE; -COMMIT RELEASE; -COMMIT CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 -COMMIT NO CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 -COMMIT AND NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -COMMIT AND RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -COMMIT NO RELEASE; -COMMIT CHAIN NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 -COMMIT NO CHAIN NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 -COMMIT AND RELEASE CHAIN; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 -COMMIT AND NO CHAIN NO RELEASE; -ROLLBACK AND CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -ROLLBACK AND NO CHAIN RELEASE; -ROLLBACK RELEASE; -ROLLBACK CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 -ROLLBACK NO CHAIN RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 -ROLLBACK AND NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -ROLLBACK AND RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 -ROLLBACK NO RELEASE; -ROLLBACK CHAIN NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 -ROLLBACK NO CHAIN NO RELEASE; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 -ROLLBACK AND RELEASE CHAIN; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 -ROLLBACK AND NO CHAIN NO RELEASE; -# -# End of 5.5 tests -# diff --git a/mysql-test/r/parser_not_embedded.result b/mysql-test/r/parser_not_embedded.result index 140b13c9864..5a5ae9f8178 100644 --- a/mysql-test/r/parser_not_embedded.result +++ b/mysql-test/r/parser_not_embedded.result @@ -47,3 +47,48 @@ +----------+--------+ | 4 | 4 | +----------+--------+ +# Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" +# +COMMIT AND CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT AND NO CHAIN RELEASE; +COMMIT RELEASE; +COMMIT CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +COMMIT NO CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +COMMIT AND NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT AND RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +COMMIT NO RELEASE; +COMMIT CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +COMMIT NO CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +COMMIT AND RELEASE CHAIN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 +COMMIT AND NO CHAIN NO RELEASE; +ROLLBACK AND CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK AND NO CHAIN RELEASE; +ROLLBACK RELEASE; +ROLLBACK CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +ROLLBACK NO CHAIN RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN RELEASE' at line 1 +ROLLBACK AND NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK AND RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE' at line 1 +ROLLBACK NO RELEASE; +ROLLBACK CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +ROLLBACK NO CHAIN NO RELEASE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAIN NO RELEASE' at line 1 +ROLLBACK AND RELEASE CHAIN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RELEASE CHAIN' at line 1 +ROLLBACK AND NO CHAIN NO RELEASE; +# +# End of 5.5 tests +# diff --git a/mysql-test/suite/innodb/r/innodb-semi-consistent.result b/mysql-test/suite/innodb/r/innodb-semi-consistent.result index ca0e362ef80..989cb818cec 100644 --- a/mysql-test/suite/innodb/r/innodb-semi-consistent.result +++ b/mysql-test/suite/innodb/r/innodb-semi-consistent.result @@ -13,6 +13,7 @@ set autocommit=0; update t1 set a=10 where a=5; ERROR HY000: Lock wait timeout exceeded; try restarting transaction commit; +commit; set session transaction isolation level read committed; update t1 set a=10 where a=5; select * from t1 where a=2 for update; diff --git a/mysql-test/suite/innodb/r/innodb_information_schema.result b/mysql-test/suite/innodb/r/innodb_information_schema.result index ad8729804df..1737dab2ff0 100644 --- a/mysql-test/suite/innodb/r/innodb_information_schema.result +++ b/mysql-test/suite/innodb/r/innodb_information_schema.result @@ -63,4 +63,4 @@ RUNNING 4 0 0 7 1 0 REPEATABLE READ 1 1 trx_isolation_level trx_unique_checks trx_foreign_key_checks SERIALIZABLE 0 0 trx_state trx_isolation_level trx_last_foreign_key_error -RUNNING SERIALIZABLE `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`) +RUNNING REPEATABLE READ `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`) diff --git a/mysql-test/suite/innodb/t/innodb-semi-consistent.test b/mysql-test/suite/innodb/t/innodb-semi-consistent.test index 61ad7815ca9..28bf532ff1f 100644 --- a/mysql-test/suite/innodb/t/innodb-semi-consistent.test +++ b/mysql-test/suite/innodb/t/innodb-semi-consistent.test @@ -23,6 +23,7 @@ set session transaction isolation level repeatable read; set autocommit=0; -- error ER_LOCK_WAIT_TIMEOUT update t1 set a=10 where a=5; +commit; connection a; commit; connection b; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 43d3abb0649..d477843b22b 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -733,78 +733,3 @@ DROP TABLE t1, t2, t3; --echo # End of 5.1 tests --echo # ---echo # Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" ---echo # ---error ER_PARSE_ERROR -COMMIT AND CHAIN RELEASE; - -COMMIT AND NO CHAIN RELEASE; -disconnect default; -connect(default, localhost, root,,); - -COMMIT RELEASE; -disconnect default; -connect(default, localhost, root,,); - ---error ER_PARSE_ERROR -COMMIT CHAIN RELEASE; - ---error ER_PARSE_ERROR -COMMIT NO CHAIN RELEASE; - ---error ER_PARSE_ERROR -COMMIT AND NO RELEASE; ---error ER_PARSE_ERROR -COMMIT AND RELEASE; - -COMMIT NO RELEASE; ---error ER_PARSE_ERROR -COMMIT CHAIN NO RELEASE; ---error ER_PARSE_ERROR -COMMIT NO CHAIN NO RELEASE; - ---error ER_PARSE_ERROR -COMMIT AND RELEASE CHAIN; - -COMMIT AND NO CHAIN NO RELEASE; - ---error ER_PARSE_ERROR -ROLLBACK AND CHAIN RELEASE; - -ROLLBACK AND NO CHAIN RELEASE; -disconnect default; -connect(default, localhost, root,,); - -ROLLBACK RELEASE; -disconnect default; -connect(default, localhost, root,,); - ---error ER_PARSE_ERROR -ROLLBACK CHAIN RELEASE; - ---error ER_PARSE_ERROR -ROLLBACK NO CHAIN RELEASE; -disconnect default; -connect(default, localhost, root,,); - ---error ER_PARSE_ERROR -ROLLBACK AND NO RELEASE; - ---error ER_PARSE_ERROR -ROLLBACK AND RELEASE; - -ROLLBACK NO RELEASE; - ---error ER_PARSE_ERROR -ROLLBACK CHAIN NO RELEASE; - ---error ER_PARSE_ERROR -ROLLBACK NO CHAIN NO RELEASE; ---error ER_PARSE_ERROR -ROLLBACK AND RELEASE CHAIN; - -ROLLBACK AND NO CHAIN NO RELEASE; - ---echo # ---echo # End of 5.5 tests ---echo # diff --git a/mysql-test/t/parser_not_embedded.test b/mysql-test/t/parser_not_embedded.test index 8ebeb9a8301..22e9ae5a140 100644 --- a/mysql-test/t/parser_not_embedded.test +++ b/mysql-test/t/parser_not_embedded.test @@ -24,3 +24,78 @@ EOF --exec $MYSQL --comment --force --table test <$MYSQLTEST_VARDIR/tmp/bug39559.sql --remove_file $MYSQLTEST_VARDIR/tmp/bug39559.sql +--echo # Bug#46527 "COMMIT AND CHAIN RELEASE does not make sense" +--echo # +--error ER_PARSE_ERROR +COMMIT AND CHAIN RELEASE; + +COMMIT AND NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +COMMIT RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +COMMIT CHAIN RELEASE; + +--error ER_PARSE_ERROR +COMMIT NO CHAIN RELEASE; + +--error ER_PARSE_ERROR +COMMIT AND NO RELEASE; +--error ER_PARSE_ERROR +COMMIT AND RELEASE; + +COMMIT NO RELEASE; +--error ER_PARSE_ERROR +COMMIT CHAIN NO RELEASE; +--error ER_PARSE_ERROR +COMMIT NO CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +COMMIT AND RELEASE CHAIN; + +COMMIT AND NO CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK AND CHAIN RELEASE; + +ROLLBACK AND NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +ROLLBACK RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +ROLLBACK CHAIN RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK NO CHAIN RELEASE; +disconnect default; +connect(default, localhost, root,,); + +--error ER_PARSE_ERROR +ROLLBACK AND NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK AND RELEASE; + +ROLLBACK NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK CHAIN NO RELEASE; + +--error ER_PARSE_ERROR +ROLLBACK NO CHAIN NO RELEASE; +--error ER_PARSE_ERROR +ROLLBACK AND RELEASE CHAIN; + +ROLLBACK AND NO CHAIN NO RELEASE; + +--echo # +--echo # End of 5.5 tests +--echo # From df9ab0ffea2eb603179f2bd2abcc66d2c652cdda Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 10 Jun 2010 15:31:19 +0400 Subject: [PATCH 162/207] A pre-requisite patch for WL#5419 "LOCK_open scalability: make tdc_refresh_version an atomic counter". To avoid orphaned TABLE_SHARE objects left in the cache, make sure that wherever we set table->s->version we take care of removing all unused table share objects from the table cache. Always set table->s->version under LOCK_open, to make sure that no other connection sees an old value of the version and adds the table to unused_tables list. Add an assert to table_def_unuse_table() that we never 'unuse' a talbe of a share that has an old version. With this patch, only three places are left in the code that manipulate with table->s->version: - tdc_remove_table(). In most cases we have an X mdl lock in tdc_remove_table(), the two remaining cases when we don't are 'FLUSH TABLE' and mysql_admin_table(). - sql_view.cc - a crude hack that needs a separate fix - initial assignment from refresh_version in table.cc. --- sql/sql_base.cc | 41 ++++++++++++++++---------------- sql/sql_table.cc | 62 ++++++++++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 39e6f976f3b..47d709e8225 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -439,6 +439,9 @@ static void table_def_unuse_table(TABLE *table) { DBUG_ASSERT(table->in_use); + /* We shouldn't put the table to 'unused' list if the share is old. */ + DBUG_ASSERT(table->s->version == refresh_version); + table->in_use= 0; /* Remove table from the list of tables used in this share. */ table->s->used_tables.remove(table); @@ -2233,11 +2236,14 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, DBUG_ASSERT(table == thd->open_tables); handlerton *table_type= table->s->db_type(); - /* Ensure the table is removed from the cache. */ - table->s->version= 0; table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); close_thread_table(thd, &thd->open_tables); + /* Remove the table share from the table cache. */ + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db_name, table_name); + mysql_mutex_unlock(&LOCK_open); + /* Remove the table from the storage engine and rm the .frm. */ quick_rm_table(table_type, db_name, table_name, 0); } DBUG_VOID_RETURN; @@ -3028,17 +3034,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, my_free(table, MYF(0)); if (error == 7) - { - share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); - } else if (share->crashed) - { - share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR, table_list); - } goto err_unlock; } @@ -3824,7 +3824,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) TABLE_SHARE *share; TABLE *entry; int not_used; - bool result= FALSE; + bool result= TRUE; my_hash_value_type hash_value; cache_key_length= create_table_def_key(thd, cache_key, table_list, 0); @@ -3839,20 +3839,19 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) cache_key_length, OPEN_VIEW, ¬_used, hash_value))) - { - mysql_mutex_unlock(&LOCK_open); - return TRUE; - } + goto end_unlock; if (share->is_view) - goto end_with_lock_open; + { + release_table_share(share); + goto end_unlock; + } if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) { - result= TRUE; - goto end_with_lock_open; + release_table_share(share); + goto end_unlock; } - share->version= 0; mysql_mutex_unlock(&LOCK_open); if (open_table_from_share(thd, share, table_list->alias, @@ -3871,19 +3870,21 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) share->table_name.str); if (entry->file) closefrm(entry, 0); - result= TRUE; } else { thd->clear_error(); // Clear error message closefrm(entry, 0); + result= FALSE; } my_free(entry, MYF(0)); mysql_mutex_lock(&LOCK_open); - -end_with_lock_open: release_table_share(share); + /* Remove the repaired share from the table cache. */ + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, + table_list->db, table_list->table_name); +end_unlock: mysql_mutex_unlock(&LOCK_open); return result; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 843fb5b35d2..3e9d26bd253 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -85,19 +85,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); -#ifndef DBUG_OFF - -/* Wait until we get a 'mysql_kill' signal */ - -static void wait_for_kill_signal(THD *thd) -{ - while (thd->killed == 0) - sleep(1); - // Reset signal and continue as if nothing happend - thd->killed= THD::NOT_KILLED; -} -#endif - /** @brief Helper function for explain_filename @@ -4877,18 +4864,30 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, /* purecov: end */ } - /* Close all instances of the table to allow repair to rename files */ - if (lock_type == TL_WRITE && table->table->s->version) + /* + Close all instances of the table to allow MyISAM "repair" + to rename files. + @todo: This code does not close all instances of the table. + It only closes instances in other connections, but if this + connection has LOCK TABLE t1 a READ, t1 b WRITE, + both t1 instances will be kept open. + There is no need to execute this branch for InnoDB, which does + repair by recreate. There is no need to do it for OPTIMIZE, + which doesn't move files around. + Hence, this code should be moved to prepare_for_repair(), + and executed only for MyISAM engine. + */ + if (lock_type == TL_WRITE && !table->table->s->tmp_table) { if (wait_while_table_is_used(thd, table->table, HA_EXTRA_PREPARE_FOR_RENAME)) goto err; - DBUG_EXECUTE_IF("wait_in_mysql_admin_table", - wait_for_kill_signal(thd); - if (thd->killed) - goto err;); /* Flush entries in the query cache involving this table. */ query_cache_invalidate3(thd, table->table, 0); + /* + XXX: hack: switch off open_for_modify to skip the + flush that is made later in the execution flow. + */ open_for_modify= 0; } @@ -5148,20 +5147,21 @@ send_result_message: } if (table->table) { - if (fatal_error) - table->table->s->version=0; // Force close of table - else if (open_for_modify) + if (table->table->s->tmp_table) { - if (table->table->s->tmp_table) + if (open_for_modify) table->table->file->info(HA_STATUS_CONST); - else - { - TABLE_LIST *save_next_global= table->next_global; - table->next_global= 0; - close_cached_tables(thd, table, FALSE, FALSE); - table->next_global= save_next_global; - } - /* May be something modified consequently we have to invalidate cache */ + } + else if (open_for_modify || fatal_error) + { + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, + table->db, table->table_name); + mysql_mutex_unlock(&LOCK_open); + /* + May be something modified. Consequently, we have to + invalidate the query cache. + */ query_cache_invalidate3(thd, table->table, 0); } } From 41d95c504976746e4d117a4f97e18004f36eb70e Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Thu, 10 Jun 2010 15:43:32 +0400 Subject: [PATCH 163/207] A pre-requisite for WL#5419 "LOCK_open scalability: make tdc_refresh_version an atomic counter". Backport the trivial changes from mysql-trunk-iplus. --- libmysqld/lib_sql.cc | 1 - sql/event_scheduler.cc | 1 - sql/ha_ndbcluster.cc | 1 - sql/ha_ndbcluster_binlog.cc | 5 ++--- sql/slave.cc | 1 - sql/sql_base.cc | 21 +++++++++++---------- sql/sql_base.h | 2 +- sql/sql_connect.cc | 1 - sql/sql_insert.cc | 1 - sql/sql_manager.cc | 2 +- sql/sql_parse.cc | 1 - sql/table.h | 2 +- 12 files changed, 16 insertions(+), 23 deletions(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index e727122293c..b36a97759d2 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -634,7 +634,6 @@ void *create_embedded_thd(int client_flag) thd->variables.option_bits |= OPTION_BIG_SELECTS; thd->proc_info=0; // Remove 'login' thd->command=COM_SLEEP; - thd->version=refresh_version; thd->set_time(); thd->init_for_queries(); thd->client_capabilities= client_flag; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 33b9a1cafda..c646642dbba 100755 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -203,7 +203,6 @@ pre_init_event_thread(THD* thd) */ thd->proc_info= "Initialized"; - thd->version= refresh_version; thd->set_time(); /* Do not use user-supplied timeout value for system threads. */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 099763b3fe9..68b98c79a50 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -9510,7 +9510,6 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) if (thd->store_globals()) goto ndb_util_thread_fail; thd->init_for_queries(); - thd->version=refresh_version; thd->main_security_ctx.host_or_ip= ""; thd->client_capabilities = 0; my_net_init(&thd->net, 0); diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index d38544f9b9f..0db7956fe28 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -3678,7 +3678,6 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) thd->init_for_queries(); thd->command= COM_DAEMON; thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG; - thd->version= refresh_version; thd->main_security_ctx.host_or_ip= ""; thd->client_capabilities= 0; my_net_init(&thd->net, 0); @@ -3965,9 +3964,9 @@ restart: !ndb_binlog_running)) break; /* Shutting down server */ - if (ndb_binlog_index && ndb_binlog_index->s->version < refresh_version) + if (ndb_binlog_index && ndb_binlog_index->s->needs_reopen()) { - if (ndb_binlog_index->s->version < refresh_version) + if (ndb_binlog_index->s->needs_reopen()) { close_thread_tables(thd); ndb_binlog_index= 0; diff --git a/sql/slave.cc b/sql/slave.cc index 6ebdea4a42a..bcb01d77e15 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2055,7 +2055,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) thd_proc_info(thd, "Waiting for the next event in relay log"); else thd_proc_info(thd, "Waiting for master update"); - thd->version=refresh_version; thd->set_time(); /* Do not use user-supplied timeout value for system threads. */ thd->variables.lock_wait_timeout= LONG_TIMEOUT; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 47d709e8225..c227fd12f5b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -440,7 +440,7 @@ static void table_def_unuse_table(TABLE *table) DBUG_ASSERT(table->in_use); /* We shouldn't put the table to 'unused' list if the share is old. */ - DBUG_ASSERT(table->s->version == refresh_version); + DBUG_ASSERT(! table->s->needs_reopen()); table->in_use= 0; /* Remove table from the list of tables used in this share. */ @@ -562,7 +562,9 @@ found: DBUG_RETURN(0); } - if (!share->ref_count++ && share->prev) + ++share->ref_count; + + if (share->ref_count == 1 && share->prev) { /* Share was not used before and it was in the old_unused_share list @@ -700,8 +702,7 @@ void release_table_share(TABLE_SHARE *share) DBUG_ASSERT(share->ref_count); if (!--share->ref_count) { - if (share->version != refresh_version || - table_def_shutdown_in_progress) + if (share->needs_reopen() || table_def_shutdown_in_progress) my_hash_delete(&table_def_cache, (uchar*) share); else { @@ -836,7 +837,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) I_P_List_iterator it(share->used_tables); while (it++) ++(*start_list)->in_use; - (*start_list)->locked= (share->version == 0) ? 1 : 0; + (*start_list)->locked= 0; /* Obsolete. */ start_list= &(*start_list)->next; *start_list=0; } @@ -1071,7 +1072,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, { TABLE_SHARE *share=(TABLE_SHARE*) my_hash_element(&table_def_cache, idx); - if (share->version != refresh_version) + if (share->needs_reopen()) { found= TRUE; break; @@ -1083,7 +1084,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, for (TABLE_LIST *table= tables; table; table= table->next_local) { TABLE_SHARE *share= get_cached_table_share(table->db, table->table_name); - if (share && share->version != refresh_version) + if (share && share->needs_reopen()) { found= TRUE; break; @@ -2979,7 +2980,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } #endif - if (share->version != refresh_version) + if (share->needs_reopen()) { if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) { @@ -8608,7 +8609,7 @@ my_bool mysql_rm_tmp_tables(void) all not used tables. */ -void flush_tables() +void tdc_flush_unused_tables() { mysql_mutex_lock(&LOCK_open); while (unused_tables) @@ -8820,7 +8821,7 @@ tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests, if ((share= get_cached_table_share(mdl_request->key.db_name(), mdl_request->key.name())) && - share->version != refresh_version) + share->needs_reopen()) break; } if (!mdl_request) diff --git a/sql/sql_base.h b/sql/sql_base.h index 928b8339f15..38194f94a37 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -233,7 +233,6 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db, const char *table_name); void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table); void remove_db_from_cache(const char *db); -void flush_tables(); bool is_equal(const LEX_STRING *a, const LEX_STRING *b); /* Functions to work with system tables. */ @@ -263,6 +262,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type, bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, char *cache_key, uint cache_key_length, MEM_ROOT *mem_root, uint flags); +void tdc_flush_unused_tables(); TABLE *find_table_for_mdl_upgrade(TABLE *list, const char *db, const char *table_name, bool no_error); diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index c0081c13366..481715098b7 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1083,7 +1083,6 @@ static void prepare_new_connection_state(THD* thd) embedded server library. TODO: refactor this to avoid code duplication there */ - thd->version= refresh_version; thd->proc_info= 0; thd->command= COM_SLEEP; thd->set_time(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 998d3c53e04..24a418f8f25 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1814,7 +1814,6 @@ public: thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user; thd.security_ctx->host=(char*) my_localhost; thd.current_tablenr=0; - thd.version=refresh_version; thd.command=COM_DELAYED_INSERT; thd.lex->current_select= 0; // for my_message_sql thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index e9c9402a89a..2189b1e124f 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -108,7 +108,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) if (error == ETIMEDOUT || error == ETIME) { - flush_tables(); + tdc_flush_unused_tables(); error = 0; reset_flush_time = TRUE; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1b1016233f8..6ff631ad7c7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -497,7 +497,6 @@ static void handle_bootstrap_impl(THD *thd) #endif /* EMBEDDED_LIBRARY */ thd_proc_info(thd, 0); - thd->version=refresh_version; thd->security_ctx->priv_user= thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME)); thd->security_ctx->priv_host[0]=0; diff --git a/sql/table.h b/sql/table.h index 52fc0f1a7d9..30cac15f8d1 100644 --- a/sql/table.h +++ b/sql/table.h @@ -740,7 +740,7 @@ struct TABLE_SHARE /* Must all TABLEs be reopened? */ - inline bool needs_reopen() + inline bool needs_reopen() const { return version != refresh_version; } From 2b0c42f808d93706daa1492c3e3b05c45622624d Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Fri, 11 Jun 2010 10:14:38 +0200 Subject: [PATCH 164/207] This patch backports test coverage for: Bug #22909 Using CREATE ... LIKE is possible to create field with invalid default value Bug #35935 CREATE TABLE under LOCK TABLES ignores FLUSH TABLES WITH READ LOCK Bug #37371 CREATE TABLE LIKE merge loses UNION parameter These bugs were originally fixed in the 6.1-fk tree and the fixes were backported as part of the fix for Bug #42546 "Backup: RESTORE fails, thinking it finds an existing table". This patch backports test coverage missing in the original backport. The patch contains no code changes. --- mysql-test/r/create.result | 55 +++++++++++++++++++++++++++++++ mysql-test/r/merge.result | 19 +++++++++++ mysql-test/t/create.test | 67 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/merge.test | 15 +++++++++ 4 files changed, 156 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index e37f9d580ba..fce775c5952 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -99,6 +99,14 @@ create table t1 (`` int); ERROR 42000: Incorrect column name '' create table t1 (i int, index `` (i)); ERROR 42000: Incorrect index name '' +create table t1 (i int); +lock tables t1 read; +create table t2 (j int); +ERROR HY000: Table 't2' was not locked with LOCK TABLES +create temporary table t2 (j int); +drop temporary table t2; +unlock tables; +drop table t1; create table t1 (a int auto_increment not null primary key, B CHAR(20)); insert into t1 (b) values ("hello"),("my"),("world"); create table t2 (key (b)) select * from t1; @@ -377,6 +385,17 @@ ERROR 42S01: Table 't3' already exists drop table t1, t2, t3; drop table t3; drop database mysqltest; +create table t1 (i int); +create table t2 (j int); +lock tables t1 read; +create table t3 like t1; +ERROR HY000: Table 't3' was not locked with LOCK TABLES +create temporary table t3 like t1; +drop temporary table t3; +create temporary table t3 like t2; +ERROR HY000: Table 't2' was not locked with LOCK TABLES +unlock tables; +drop tables t1, t2; SET SESSION storage_engine="heap"; SELECT @@storage_engine; @@storage_engine @@ -2033,3 +2052,39 @@ ID 3 DROP TABLE t1; DROP TEMPORARY TABLE t2; +# +# Bug #22909 "Using CREATE ... LIKE is possible to create field +# with invalid default value" +# +# Altough original bug report suggests to use older version of MySQL +# for producing .FRM with invalid defaults we use sql_mode to achieve +# the same effect. +drop tables if exists t1, t2; +# Attempt to create table with invalid default should fail in normal mode +create table t1 (dt datetime default '2008-02-31 00:00:00'); +ERROR 42000: Invalid default value for 'dt' +set @old_mode= @@sql_mode; +set @@sql_mode='ALLOW_INVALID_DATES'; +# The same should be possible in relaxed mode +create table t1 (dt datetime default '2008-02-31 00:00:00'); +set @@sql_mode= @old_mode; +# In normal mode attempt to create copy of table with invalid +# default should fail +create table t2 like t1; +ERROR 42000: Invalid default value for 'dt' +set @@sql_mode='ALLOW_INVALID_DATES'; +# But should work in relaxed mode +create table t2 like t1; +# Check that table definitions match +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `dt` datetime DEFAULT '2008-02-31 00:00:00' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `dt` datetime DEFAULT '2008-02-31 00:00:00' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set @@sql_mode= @old_mode; +drop tables t1, t2; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index e46d8e75ab1..8f7ebb06c06 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2699,4 +2699,23 @@ LOCK TABLE m1 WRITE; ALTER TABLE m1 ADD INDEX (c1); UNLOCK TABLES; DROP TABLE m1, t1; +# +# Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter" +# +drop tables if exists t1, m1, m2; +create table t1 (i int) engine=myisam; +create table m1 (i int) engine=mrg_myisam union=(t1) insert_method=first; +create table m2 like m1; +# Table definitions should match +show create table m1; +Table Create Table +m1 CREATE TABLE `m1` ( + `i` int(11) DEFAULT NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`) +show create table m2; +Table Create Table +m2 CREATE TABLE `m2` ( + `i` int(11) DEFAULT NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`) +drop tables m1, m2, t1; End of 6.0 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 383ba98ae6d..887ae4da404 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -101,6 +101,22 @@ create table t1 (`` int); --error 1280 create table t1 (i int, index `` (i)); +# +# CREATE TABLE under LOCK TABLES +# +# We don't allow creation of non-temporary tables under LOCK TABLES +# as following meta-data locking protocol in this case can lead to +# deadlock. +create table t1 (i int); +lock tables t1 read; +--error ER_TABLE_NOT_LOCKED +create table t2 (j int); +# OTOH creating of temporary table should be OK +create temporary table t2 (j int); +drop temporary table t2; +unlock tables; +drop table t1; + # # Test of CREATE ... SELECT with indexes # @@ -314,6 +330,26 @@ drop table t1, t2, t3; drop table t3; drop database mysqltest; +# +# CREATE TABLE LIKE under LOCK TABLES +# +# Similarly to ordinary CREATE TABLE we don't allow creation of +# non-temporary tables under LOCK TABLES. Also we require source +# table to be locked. +create table t1 (i int); +create table t2 (j int); +lock tables t1 read; +--error ER_TABLE_NOT_LOCKED +create table t3 like t1; +# OTOH creating of temporary table should be OK +create temporary table t3 like t1; +drop temporary table t3; +# Source table should be locked +--error ER_TABLE_NOT_LOCKED +create temporary table t3 like t2; +unlock tables; +drop tables t1, t2; + # # Test default table type # @@ -1731,3 +1767,34 @@ DROP TABLE t1; DROP TEMPORARY TABLE t2; + +--echo # +--echo # Bug #22909 "Using CREATE ... LIKE is possible to create field +--echo # with invalid default value" +--echo # +--echo # Altough original bug report suggests to use older version of MySQL +--echo # for producing .FRM with invalid defaults we use sql_mode to achieve +--echo # the same effect. +--disable_warnings +drop tables if exists t1, t2; +--enable_warnings +--echo # Attempt to create table with invalid default should fail in normal mode +--error ER_INVALID_DEFAULT +create table t1 (dt datetime default '2008-02-31 00:00:00'); +set @old_mode= @@sql_mode; +set @@sql_mode='ALLOW_INVALID_DATES'; +--echo # The same should be possible in relaxed mode +create table t1 (dt datetime default '2008-02-31 00:00:00'); +set @@sql_mode= @old_mode; +--echo # In normal mode attempt to create copy of table with invalid +--echo # default should fail +--error ER_INVALID_DEFAULT +create table t2 like t1; +set @@sql_mode='ALLOW_INVALID_DATES'; +--echo # But should work in relaxed mode +create table t2 like t1; +--echo # Check that table definitions match +show create table t1; +show create table t2; +set @@sql_mode= @old_mode; +drop tables t1, t2; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index a9d98da0403..29c0eae1df6 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2187,5 +2187,20 @@ UNLOCK TABLES; DROP TABLE m1, t1; +--echo # +--echo # Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter" +--echo # +--disable_warnings +drop tables if exists t1, m1, m2; +--enable_warnings +create table t1 (i int) engine=myisam; +create table m1 (i int) engine=mrg_myisam union=(t1) insert_method=first; +create table m2 like m1; +--echo # Table definitions should match +show create table m1; +show create table m2; +drop tables m1, m2, t1; + + --echo End of 6.0 tests From 218bf86cd9bcea47da1bd6db935223ae15d3129f Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Fri, 11 Jun 2010 17:32:12 +0400 Subject: [PATCH 165/207] Fix for bug #46785 "main.truncate_coverage fails sporadically". Races in truncate_coverage.test have caused its sporadical failures. In the test case we have tried to kill truncate statement being executed in the first connection which was waiting for X metadata lock on table being locked by the second connection. Since we have released metadata lock held by the second connection right after issuing KILL statement sometimes TRUNCATE TABLE managed to acquire X lock before it has noticed that it was killed. In this case TRUNCATE TABLE was successfully executed till its end and this fact has caused test failure since this statement didn't return expected error in such case. This patch addresses the problem by not releasing metadata locks in the second connections prematurely. --- mysql-test/r/truncate_coverage.result | 13 ++++++++++--- mysql-test/t/truncate_coverage.test | 20 +++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/truncate_coverage.result b/mysql-test/r/truncate_coverage.result index 7a5021f55e2..a7a4b9c70f4 100644 --- a/mysql-test/r/truncate_coverage.result +++ b/mysql-test/r/truncate_coverage.result @@ -18,13 +18,15 @@ TRUNCATE TABLE t1; SET DEBUG_SYNC='now WAIT_FOR waiting'; KILL QUERY @id; # +# connection default +ERROR 70100: Query execution was interrupted +UNLOCK TABLES; +# # connection con1 # Release shared metadata lock by closing HANDLER. HANDLER t1 CLOSE; # # connection default -ERROR 70100: Query execution was interrupted -UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; CREATE TABLE t1 (c1 INT); @@ -64,10 +66,15 @@ TRUNCATE TABLE t1; # connection con1 SET DEBUG_SYNC='now WAIT_FOR waiting'; KILL QUERY @id; -COMMIT; # # connection default ERROR 70100: Query execution was interrupted +# +# connection con1 +# Release SW lock by committing transaction. +COMMIT; +# +# connection default UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; diff --git a/mysql-test/t/truncate_coverage.test b/mysql-test/t/truncate_coverage.test index b7c08b03c8b..c9c4bd90ca4 100644 --- a/mysql-test/t/truncate_coverage.test +++ b/mysql-test/t/truncate_coverage.test @@ -55,6 +55,12 @@ let $invisible_assignment_in_select = `SELECT @id := $ID`; KILL QUERY @id; --disconnect con2 --echo # +--echo # connection default +--connection default +--error ER_QUERY_INTERRUPTED +reap; +UNLOCK TABLES; +--echo # --echo # connection con1 --connection con1 --echo # Release shared metadata lock by closing HANDLER. @@ -63,9 +69,6 @@ HANDLER t1 CLOSE; --echo # --echo # connection default --connection default ---error ER_QUERY_INTERRUPTED -reap; -UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; ######## @@ -151,13 +154,20 @@ send TRUNCATE TABLE t1; SET DEBUG_SYNC='now WAIT_FOR waiting'; let $invisible_assignment_in_select = `SELECT @id := $ID`; KILL QUERY @id; -COMMIT; ---disconnect con1 --echo # --echo # connection default --connection default --error ER_QUERY_INTERRUPTED reap; +--echo # +--echo # connection con1 +--connection con1 +--echo # Release SW lock by committing transaction. +COMMIT; +--disconnect con1 +--echo # +--echo # connection default +--connection default UNLOCK TABLES; DROP TABLE t1; SET DEBUG_SYNC='RESET'; From b14045660153fc48065774a9bc8a955b2eba093d Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Fri, 11 Jun 2010 19:28:18 +0400 Subject: [PATCH 166/207] WL#5419 "LOCK_open scalability: make tdc_refresh_version an atomic counter" Split the large LOCK_open section in open_table(). Do not call open_table_from_share() under LOCK_open. Remove thd->version. This fixes Bug#50589 "Server hang on a query evaluated using a temporary table" Bug#51557 "LOCK_open and kernel_mutex are not happy together" Bug#49463 "LOCK_table and innodb are not nice when handler instances are created". This patch has effect on storage engines that rely on ha_open() PSEA method being called under LOCK_open. In particular: 1) NDB is broken and left unfixed. NDB relies on LOCK_open being kept as part of ha_open(), since it uses auto-discovery. While previously the NDB open code was race-prone, now it simply fails on asserts. 2) HEAP engine had a race in ha_heap::open() when a share for the same table could be added twice to the list of shares, or a dangling reference to a share stored in HEAP handler. This patch aims to address this problem by 'pinning' the newly created share in the internal HEAP engine share list until at least one handler instance is created using that share. --- include/heap.h | 17 ++++- sql/lock.cc | 3 +- sql/repl_failsafe.cc | 1 - sql/sql_base.cc | 104 ++++++++++++++---------------- sql/sql_base.h | 1 + sql/sql_class.cc | 2 +- sql/sql_class.h | 10 --- sql/sql_plugin.cc | 9 +-- sql/sql_udf.cc | 2 +- sql/table.h | 1 - sql/tztime.cc | 5 +- storage/heap/CMakeLists.txt | 6 ++ storage/heap/ha_heap.cc | 123 ++++++++++++++++++++++-------------- storage/heap/hp_create.c | 20 ++++-- storage/heap/hp_open.c | 21 ++++++ storage/heap/hp_test1.c | 11 +++- storage/heap/hp_test2.c | 17 +++-- 17 files changed, 207 insertions(+), 146 deletions(-) diff --git a/include/heap.h b/include/heap.h index 27aefb5beda..a585371e18f 100644 --- a/include/heap.h +++ b/include/heap.h @@ -184,12 +184,22 @@ typedef struct st_heap_info typedef struct st_heap_create_info { + HP_KEYDEF *keydef; + ulong max_records; + ulong min_records; uint auto_key; /* keynr [1 - maxkey] for auto key */ uint auto_key_type; + uint keys; + uint reclength; ulonglong max_table_size; ulonglong auto_increment; my_bool with_auto_increment; my_bool internal_table; + /* + TRUE if heap_create should 'pin' the created share by setting + open_count to 1. Is only looked at if not internal_table. + */ + my_bool pin_share; } HP_CREATE_INFO; /* Prototypes for heap-functions */ @@ -197,6 +207,7 @@ typedef struct st_heap_create_info extern HP_INFO *heap_open(const char *name, int mode); extern HP_INFO *heap_open_from_share(HP_SHARE *share, int mode); extern HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode); +extern void heap_release_share(HP_SHARE *share, my_bool internal_table); extern int heap_close(HP_INFO *info); extern int heap_write(HP_INFO *info,const uchar *buff); extern int heap_update(HP_INFO *info,const uchar *old,const uchar *newdata); @@ -205,9 +216,9 @@ extern int heap_scan_init(HP_INFO *info); extern int heap_scan(register HP_INFO *info, uchar *record); extern int heap_delete(HP_INFO *info,const uchar *buff); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); -extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, - uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info, HP_SHARE **share); +extern int heap_create(const char *name, + HP_CREATE_INFO *create_info, HP_SHARE **share, + my_bool *created_new_share); extern int heap_delete_table(const char *name); extern void heap_drop_table(HP_INFO *info); extern int heap_extra(HP_INFO *info,enum ha_extra_function function); diff --git a/sql/lock.cc b/sql/lock.cc index d35f2c359fb..52d97a2422b 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1298,7 +1298,8 @@ wait_if_global_read_lock(THD *thd, bool abort_on_refresh, old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, "Waiting for release of readlock"); while (must_wait && ! thd->killed && - (!abort_on_refresh || thd->version == refresh_version)) + (!abort_on_refresh || !thd->open_tables || + thd->open_tables->s->version == refresh_version)) { DBUG_PRINT("signal", ("Waiting for COND_global_read_lock")); mysql_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index cddf798aac0..81366d55fc6 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -102,7 +102,6 @@ static int init_failsafe_rpl_thread(THD* thd) thd->mem_root->free= thd->mem_root->used= 0; thd_proc_info(thd, "Thread initialized"); - thd->version=refresh_version; thd->set_time(); DBUG_RETURN(0); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c227fd12f5b..78862985e97 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1589,10 +1589,18 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) *table_ptr=table->next; mysql_mutex_unlock(&thd->LOCK_thd_data); + if (! table->needs_reopen()) + { + /* Avoid having MERGE tables with attached children in unused_tables. */ + table->file->extra(HA_EXTRA_DETACH_CHILDREN); + /* Free memory and reset for next loop. */ + free_field_buffers_larger_than(table, MAX_TDC_BLOB_SIZE); + table->file->ha_reset(); + } + mysql_mutex_lock(&LOCK_open); - if (table->s->needs_reopen() || - thd->version != refresh_version || table->needs_reopen() || + if (table->s->needs_reopen() || table->needs_reopen() || table_def_shutdown_in_progress) { free_cache_entry(table); @@ -1600,14 +1608,7 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) } else { - /* Avoid to have MERGE tables with attached children in unused_tables. */ DBUG_ASSERT(table->file); - table->file->extra(HA_EXTRA_DETACH_CHILDREN); - - /* Free memory and reset for next loop */ - free_field_buffers_larger_than(table,MAX_TDC_BLOB_SIZE); - - table->file->ha_reset(); table_def_unuse_table(table); /* We free the least used table, not the subject table, @@ -2305,7 +2306,7 @@ void wait_for_condition(THD *thd, mysql_mutex_t *mutex, mysql_cond_t *cond) @param[out] exists Out parameter which is set to TRUE if table exists and to FALSE otherwise. - @note This function assumes that caller owns LOCK_open mutex. + @note This function acquires LOCK_open internally. It also assumes that the fact that there are no exclusive metadata locks on the table was checked beforehand. @@ -2313,28 +2314,30 @@ void wait_for_condition(THD *thd, mysql_mutex_t *mutex, mysql_cond_t *cond) of engines (e.g. it was created on another node of NDB cluster) this function will fetch and create proper .FRM file for it. - @retval TRUE Some error occured + @retval TRUE Some error occurred @retval FALSE No error. 'exists' out parameter set accordingly. */ bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) { char path[FN_REFLEN + 1]; - int rc; + int rc= 0; DBUG_ENTER("check_if_table_exists"); - mysql_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_not_owner(&LOCK_open); *exists= TRUE; + mysql_mutex_lock(&LOCK_open); + if (get_cached_table_share(table->db, table->table_name)) - DBUG_RETURN(FALSE); + goto end; build_table_filename(path, sizeof(path) - 1, table->db, table->table_name, reg_ext, 0); if (!access(path, F_OK)) - DBUG_RETURN(FALSE); + goto end; /* .FRM file doesn't exist. Check if some engine can provide it. */ @@ -2344,19 +2347,17 @@ bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) { /* Table does not exists in engines as well. */ *exists= FALSE; - DBUG_RETURN(FALSE); + rc= 0; } - else if (!rc) - { - /* Table exists in some engine and .FRM for it was created. */ - DBUG_RETURN(FALSE); - } - else /* (rc > 0) */ + else if (rc) { my_printf_error(ER_UNKNOWN_ERROR, "Failed to open '%-.64s', error while " "unpacking from engine", MYF(0), table->table_name); - DBUG_RETURN(TRUE); } + +end: + mysql_mutex_unlock(&LOCK_open); + DBUG_RETURN(test(rc)); } @@ -2651,7 +2652,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (thd->global_read_lock.wait_if_global_read_lock(thd, 1, 1)) DBUG_RETURN(TRUE); - if (thd->version != refresh_version) + if (thd->open_tables && thd->open_tables->s->version != refresh_version) { (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, NULL); @@ -2848,48 +2849,24 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); - /* - If it's the first table from a list of tables used in a query, - remember refresh_version (the version of open_cache state). - If the version changes while we're opening the remaining tables, - we will have to back off, close all the tables opened-so-far, - and try to reopen them. - Note: refresh_version is currently changed only during FLUSH TABLES. - */ - if (!thd->open_tables) - thd->version=refresh_version; - else if ((thd->version != refresh_version) && - ! (flags & MYSQL_OPEN_IGNORE_FLUSH)) - { - /* Someone did a refresh while thread was opening tables */ - mysql_mutex_unlock(&LOCK_open); - (void) ot_ctx->request_backoff_action(Open_table_context::OT_WAIT_TDC, - NULL); - DBUG_RETURN(TRUE); - } if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS) { bool exists; if (check_if_table_exists(thd, table_list, &exists)) - goto err_unlock2; + DBUG_RETURN(TRUE); if (!exists) - { - mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(FALSE); - } + /* Table exists. Let us try to open it. */ } else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB) - { - mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(FALSE); - } + mysql_mutex_lock(&LOCK_open); #ifdef DISABLED_UNTIL_GRL_IS_MADE_PART_OF_MDL if (!(share= (TABLE_SHARE *) mdl_ticket->get_cached_object())) #endif @@ -2911,7 +2888,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, my_error(ER_WRONG_MRG_TABLE, MYF(0)); goto err_unlock; } - + /* This table is a view. Validate its metadata version: in particular, that it was a view when the statement was prepared. @@ -2980,7 +2957,15 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } #endif - if (share->needs_reopen()) + + /* + If the version changes while we're opening the tables, + we have to back off, close all the tables opened-so-far, + and try to reopen them. Note: refresh_version is currently + changed only during FLUSH TABLES. + */ + if (share->needs_reopen() || + (thd->open_tables && thd->open_tables->s->version != share->version)) { if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) { @@ -3000,8 +2985,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, NULL); DBUG_RETURN(TRUE); } - /* Force close at once after usage */ - thd->version= share->version; } if (!share->free_tables.is_empty()) @@ -3017,9 +3000,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, while (table_cache_count > table_cache_size && unused_tables) free_cache_entry(unused_tables); + mysql_mutex_unlock(&LOCK_open); + /* make a new table */ if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME)))) - goto err_unlock; + goto err_lock; error= open_table_from_share(thd, share, alias, (uint) (HA_OPEN_KEYFILE | @@ -3041,16 +3026,17 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR, table_list); - goto err_unlock; + goto err_lock; } if (open_table_entry_fini(thd, share, table)) { closefrm(table, 0); my_free((uchar*)table, MYF(0)); - goto err_unlock; + goto err_lock; } + mysql_mutex_lock(&LOCK_open); /* Add table to the share's used tables list. */ table_def_add_used_table(thd, table); } @@ -3112,6 +3098,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->file->extra(HA_EXTRA_DETACH_CHILDREN); DBUG_RETURN(FALSE); +err_lock: + mysql_mutex_lock(&LOCK_open); err_unlock: release_table_share(share); err_unlock2: diff --git a/sql/sql_base.h b/sql/sql_base.h index 38194f94a37..20a068e27d7 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -267,6 +267,7 @@ TABLE *find_table_for_mdl_upgrade(TABLE *list, const char *db, const char *table_name, bool no_error); void mark_tmp_table_for_reuse(TABLE *table); +bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); extern uint table_cache_count; extern TABLE *unused_tables; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b5d38bebd73..03d365115cf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -592,7 +592,7 @@ THD::THD() *scramble= '\0'; /* Call to init() below requires fully initialized Open_tables_state. */ - init_open_tables_state(this, refresh_version); + reset_open_tables_state(this); init(); #if defined(ENABLED_PROFILING) diff --git a/sql/sql_class.h b/sql/sql_class.h index 6cc22b22d6c..44af0b7d66e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1006,7 +1006,6 @@ public: of the main statement is called. */ enum enum_locked_tables_mode locked_tables_mode; - ulong version; uint current_tablenr; enum enum_flags { @@ -1025,15 +1024,6 @@ public: */ Open_tables_state() : state_flags(0U) { } - /** - Prepare Open_tables_state instance for operations dealing with tables. - */ - void init_open_tables_state(THD *thd, ulong version_arg) - { - reset_open_tables_state(thd); - version= version_arg; - } - void set_open_tables_state(Open_tables_state *state) { *this= *state; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 0282053ce7e..bd6ff3a951d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -261,11 +261,6 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); -#ifdef EMBEDDED_LIBRARY -/* declared in sql_base.cc */ -extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); -#endif /* EMBEDDED_LIBRARY */ - static void report_error(int where_to, uint error, ...) { va_list args; @@ -1475,10 +1470,8 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) When building an embedded library, if the mysql.plugin table does not exist, we silently ignore the missing table */ - mysql_mutex_lock(&LOCK_open); if (check_if_table_exists(new_thd, &tables, &table_exists)) table_exists= FALSE; - mysql_mutex_unlock(&LOCK_open); if (!table_exists) goto end; #endif /* EMBEDDED_LIBRARY */ @@ -1519,7 +1512,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) if (error > 0) sql_print_error(ER(ER_GET_ERRNO), my_errno); end_read_record(&read_record_info); - new_thd->version--; // Force close to free memory + table->m_needs_reopen= TRUE; // Force close to free memory end: close_thread_tables(new_thd); /* Remember that we don't have a THD */ diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 9ec17a67533..3d197303fb1 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -248,7 +248,7 @@ void udf_init() if (error > 0) sql_print_error("Got unknown error: %d", my_errno); end_read_record(&read_record_info); - new_thd->version--; // Force close to free memory + table->m_needs_reopen= TRUE; // Force close to free memory end: close_thread_tables(new_thd); diff --git a/sql/table.h b/sql/table.h index 30cac15f8d1..1307770d8e1 100644 --- a/sql/table.h +++ b/sql/table.h @@ -590,7 +590,6 @@ struct TABLE_SHARE enum enum_ha_unused unused2; uint ref_count; /* How many TABLE objects uses this */ - uint open_count; /* Number of tables in open list */ uint blob_ptr_size; /* 4 or 8 */ uint key_block_size; /* create key_block_size, if used */ uint null_bytes, last_null_bit_pos; diff --git a/sql/tztime.cc b/sql/tztime.cc index b23456b5465..79f3b83553e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1692,7 +1692,11 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) } for (TABLE_LIST *tl= tz_tables; tl; tl= tl->next_global) + { tl->table->use_all_columns(); + /* Force close at the end of the function to free memory. */ + tl->table->m_needs_reopen= TRUE; + } /* Now we are going to load leap seconds descriptions that are shared @@ -1781,7 +1785,6 @@ end_with_setting_default_tz: end_with_close: if (time_zone_tables_exist) { - thd->version--; /* Force close to free memory */ close_thread_tables(thd); thd->mdl_context.release_transactional_locks(); } diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt index 32359759abc..32510ba0c79 100755 --- a/storage/heap/CMakeLists.txt +++ b/storage/heap/CMakeLists.txt @@ -23,3 +23,9 @@ SET(HEAP_SOURCES _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c) MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED) + +ADD_EXECUTABLE(hp_test1 hp_test1.c) +TARGET_LINK_LIBRARIES(hp_test1 mysys heap) + +ADD_EXECUTABLE(hp_test2 hp_test2.c) +TARGET_LINK_LIBRARIES(hp_test2 mysys heap) diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 3abffc7087f..541650bd5e8 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -29,6 +29,10 @@ static handler *heap_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); +static int +heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table, + HP_CREATE_INFO *hp_create_info); + int heap_panic(handlerton *hton, ha_panic_function flag) { @@ -96,43 +100,48 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || - (!(file= heap_open(name, mode)) && my_errno == ENOENT)) + internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); + if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT)) { - HA_CREATE_INFO create_info; - internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); - bzero(&create_info, sizeof(create_info)); + HP_CREATE_INFO create_info; + my_bool created_new_share; + int rc; file= 0; - if (!create(name, table, &create_info)) + if (heap_prepare_hp_create_info(table, internal_table, &create_info)) + goto end; + create_info.pin_share= TRUE; + + rc= heap_create(name, &create_info, &internal_share, &created_new_share); + my_free((uchar*) create_info.keydef, MYF(0)); + if (rc) + goto end; + + implicit_emptied= test(created_new_share); + if (internal_table) + file= heap_open_from_share(internal_share, mode); + else + file= heap_open_from_share_and_register(internal_share, mode); + + if (!file) { - file= internal_table ? - heap_open_from_share(internal_share, mode) : - heap_open_from_share_and_register(internal_share, mode); - if (!file) - { - /* Couldn't open table; Remove the newly created table */ - mysql_mutex_lock(&THR_LOCK_heap); - hp_free(internal_share); - mysql_mutex_unlock(&THR_LOCK_heap); - } - implicit_emptied= 1; + heap_release_share(internal_share, internal_table); + goto end; } } + ref_length= sizeof(HEAP_PTR); - if (file) - { - /* Initialize variables for the opened table */ - set_keys_for_scanning(); - /* - We cannot run update_key_stats() here because we do not have a - lock on the table. The 'records' count might just be changed - temporarily at this moment and we might get wrong statistics (Bug - #10178). Instead we request for update. This will be done in - ha_heap::info(), which is always called before key statistics are - used. + /* Initialize variables for the opened table */ + set_keys_for_scanning(); + /* + We cannot run update_key_stats() here because we do not have a + lock on the table. The 'records' count might just be changed + temporarily at this moment and we might get wrong statistics (Bug + #10178). Instead we request for update. This will be done in + ha_heap::info(), which is always called before key statistics are + used. */ - key_stat_version= file->s->key_stat_version-1; - } + key_stat_version= file->s->key_stat_version-1; +end: return (file ? 0 : 1); } @@ -624,18 +633,20 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, } -int ha_heap::create(const char *name, TABLE *table_arg, - HA_CREATE_INFO *create_info) +static int +heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table, + HP_CREATE_INFO *hp_create_info) { uint key, parts, mem_per_row= 0, keys= table_arg->s->keys; uint auto_key= 0, auto_key_type= 0; ha_rows max_rows; HP_KEYDEF *keydef; HA_KEYSEG *seg; - int error; TABLE_SHARE *share= table_arg->s; bool found_real_auto_increment= 0; + bzero(hp_create_info, sizeof(*hp_create_info)); + for (key= parts= 0; key < keys; key++) parts+= table_arg->key_info[key].key_parts; @@ -715,29 +726,45 @@ int ha_heap::create(const char *name, TABLE *table_arg, } } mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*)); - max_rows = (ha_rows) (table_arg->in_use->variables.max_heap_table_size / - (ulonglong) mem_per_row); if (table_arg->found_next_number_field) { keydef[share->next_number_index].flag|= HA_AUTO_KEY; found_real_auto_increment= share->next_number_key_offset == 0; } + hp_create_info->auto_key= auto_key; + hp_create_info->auto_key_type= auto_key_type; + hp_create_info->max_table_size=current_thd->variables.max_heap_table_size; + hp_create_info->with_auto_increment= found_real_auto_increment; + hp_create_info->internal_table= internal_table; + + max_rows= (ha_rows) (hp_create_info->max_table_size / mem_per_row); + if (share->max_rows && share->max_rows < max_rows) + max_rows= share->max_rows; + + hp_create_info->max_records= (ulong) max_rows; + hp_create_info->min_records= (ulong) share->min_rows; + hp_create_info->keys= share->keys; + hp_create_info->reclength= share->reclength; + hp_create_info->keydef= keydef; + return 0; +} + + +int ha_heap::create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) +{ + int error; + my_bool created; HP_CREATE_INFO hp_create_info; - hp_create_info.auto_key= auto_key; - hp_create_info.auto_key_type= auto_key_type; + + error= heap_prepare_hp_create_info(table_arg, internal_table, + &hp_create_info); + if (error) + return error; hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); - hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; - hp_create_info.with_auto_increment= found_real_auto_increment; - hp_create_info.internal_table= internal_table; - max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); - error= heap_create(name, - keys, keydef, share->reclength, - (ulong) ((share->max_rows < max_rows && - share->max_rows) ? - share->max_rows : max_rows), - (ulong) share->min_rows, &hp_create_info, &internal_share); - my_free((uchar*) keydef, MYF(0)); + error= heap_create(name, &hp_create_info, &internal_share, &created); + my_free((uchar*) hp_create_info.keydef, MYF(0)); DBUG_ASSERT(file == 0); return (error); } diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 85e632e5aad..cf0f5d5ba6d 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -21,24 +21,30 @@ static void init_block(HP_BLOCK *block,uint reclength,ulong min_records, /* Create a heap table */ -int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, - uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info, HP_SHARE **res) +int heap_create(const char *name, HP_CREATE_INFO *create_info, + HP_SHARE **res, my_bool *created_new_share) { uint i, j, key_segs, max_length, length; HP_SHARE *share= 0; HA_KEYSEG *keyseg; + HP_KEYDEF *keydef= create_info->keydef; + uint reclength= create_info->reclength; + uint keys= create_info->keys; + ulong min_records= create_info->min_records; + ulong max_records= create_info->max_records; DBUG_ENTER("heap_create"); if (!create_info->internal_table) { mysql_mutex_lock(&THR_LOCK_heap); - if ((share= hp_find_named_heap(name)) && share->open_count == 0) + share= hp_find_named_heap(name); + if (share && share->open_count == 0) { hp_free(share); share= 0; } - } + } + *created_new_share= (share == NULL); if (!share) { @@ -200,7 +206,11 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, share->delete_on_close= 1; } if (!create_info->internal_table) + { + if (create_info->pin_share) + ++share->open_count; mysql_mutex_unlock(&THR_LOCK_heap); + } *res= share; DBUG_RETURN(0); diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c index feafa5d5cf1..ef2ce15f9b3 100644 --- a/storage/heap/hp_open.c +++ b/storage/heap/hp_open.c @@ -74,12 +74,33 @@ HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode) { info->open_list.data= (void*) info; heap_open_list= list_add(heap_open_list,&info->open_list); + /* Unpin the share, it is now pinned by the file. */ + share->open_count--; } mysql_mutex_unlock(&THR_LOCK_heap); DBUG_RETURN(info); } +/** + Dereference a HEAP share and free it if it's not referenced. + We don't check open_count for internal tables since they + are always thread-local, i.e. referenced by a single thread. +*/ +void heap_release_share(HP_SHARE *share, my_bool internal_table) +{ + /* Couldn't open table; Remove the newly created table */ + if (internal_table) + hp_free(share); + else + { + mysql_mutex_lock(&THR_LOCK_heap); + if (--share->open_count == 0) + hp_free(share); + mysql_mutex_unlock(&THR_LOCK_heap); + } +} + /* Open heap table based on name diff --git a/storage/heap/hp_test1.c b/storage/heap/hp_test1.c index 911e3a285a2..535db60e237 100644 --- a/storage/heap/hp_test1.c +++ b/storage/heap/hp_test1.c @@ -38,6 +38,7 @@ int main(int argc, char **argv) HA_KEYSEG keyseg[4]; HP_CREATE_INFO hp_create_info; HP_SHARE *tmp_share; + my_bool unused; MY_INIT(argv[0]); filename= "test1"; @@ -45,6 +46,11 @@ int main(int argc, char **argv) bzero(&hp_create_info, sizeof(hp_create_info)); hp_create_info.max_table_size= 1024L*1024L; + hp_create_info.keys= 1; + hp_create_info.keydef= keyinfo; + hp_create_info.reclength= 30; + hp_create_info.max_records= (ulong) flag*100000L; + hp_create_info.min_records= 10UL; keyinfo[0].keysegs=1; keyinfo[0].seg=keyseg; @@ -55,13 +61,12 @@ int main(int argc, char **argv) keyinfo[0].seg[0].charset= &my_charset_latin1; keyinfo[0].seg[0].null_bit= 0; keyinfo[0].flag = HA_NOSAME; - + deleted=0; bzero((uchar*) flags,sizeof(flags)); printf("- Creating heap-file\n"); - if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L, - &hp_create_info, &tmp_share) || + if (heap_create(filename, &hp_create_info, &tmp_share, &unused) || !(file= heap_open(filename, 2))) goto err; printf("- Writing records:s\n"); diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 8216c7360b4..733dff40c1a 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -65,15 +65,21 @@ int main(int argc, char *argv[]) HEAP_PTR UNINIT_VAR(position); HP_CREATE_INFO hp_create_info; CHARSET_INFO *cs= &my_charset_latin1; + my_bool unused; MY_INIT(argv[0]); /* init my_sys library & pthreads */ filename= "test2"; filename2= "test2_2"; file=file2=0; get_options(argc,argv); - + bzero(&hp_create_info, sizeof(hp_create_info)); hp_create_info.max_table_size= 1024L*1024L; + hp_create_info.keys= keys; + hp_create_info.keydef= keyinfo; + hp_create_info.reclength= reclength; + hp_create_info.max_records= (ulong) flag*100000L; + hp_create_info.min_records= (ulong) recant/2; write_count=update=opt_delete=0; key_check=0; @@ -125,8 +131,7 @@ int main(int argc, char *argv[]) bzero((char*) key3,sizeof(key3)); printf("- Creating heap-file\n"); - if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L, - (ulong) recant/2, &hp_create_info, &tmp_share) || + if (heap_create(filename, &hp_create_info, &tmp_share, &unused) || !(file= heap_open(filename, 2))) goto err; signal(SIGINT,endprog); @@ -563,8 +568,10 @@ int main(int argc, char *argv[]) heap_close(file2); printf("- Creating output heap-file 2\n"); - if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info, - &tmp_share) || + hp_create_info.keys= 1; + hp_create_info.max_records= 0; + hp_create_info.min_records= 0; + if (heap_create(filename2, &hp_create_info, &tmp_share, &unused) || !(file2= heap_open_from_share_and_register(tmp_share, 2))) goto err; From 7c634812495496c2e03b8962161bd001350cbe4f Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Sat, 12 Jun 2010 00:50:41 +0400 Subject: [PATCH 167/207] Fix the cmake rule that builds heap tests, added to cmake build with the patch for WL#5419. Add missing libraries. --- storage/heap/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt index 32510ba0c79..2c0b65b0cc4 100755 --- a/storage/heap/CMakeLists.txt +++ b/storage/heap/CMakeLists.txt @@ -25,7 +25,7 @@ SET(HEAP_SOURCES _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED) ADD_EXECUTABLE(hp_test1 hp_test1.c) -TARGET_LINK_LIBRARIES(hp_test1 mysys heap) +TARGET_LINK_LIBRARIES(hp_test1 mysys heap dbug strings) ADD_EXECUTABLE(hp_test2 hp_test2.c) -TARGET_LINK_LIBRARIES(hp_test2 mysys heap) +TARGET_LINK_LIBRARIES(hp_test2 mysys heap dbug strings) From 44df5a6d519f952530b0aca53b672174e8def12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 14 Jun 2010 09:35:01 +0300 Subject: [PATCH 168/207] Merge a change from mysql-5.1-innodb: ------------------------------------------------------------ revno: 3506 revision-id: sergey.glukhov@sun.com-20100609121718-04mpk5kjxvnrxdu8 parent: sergey.glukhov@sun.com-20100609120734-ndy2281wau9067zv committer: Sergey Glukhov branch nick: mysql-5.1-innodb timestamp: Wed 2010-06-09 16:17:18 +0400 message: Bug#38999 valgrind warnings for update statement in function compare_record() (InnoDB plugin branch) @ mysql-test/suite/innodb_plugin/r/innodb_mysql.result test case @ mysql-test/suite/innodb_plugin/t/innodb_mysql.test test case @ storage/innodb_plugin/row/row0sel.c init null bytes with default values as they might be left uninitialized in some cases and these uninited bytes might be copied into mysql record buffer that leads to valgrind warnings on next use of the buffer. --- mysql-test/suite/innodb/r/innodb_mysql.result | 12 ++++++++++++ mysql-test/suite/innodb/t/innodb_mysql.test | 14 ++++++++++++++ storage/innobase/row/row0sel.c | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 1845b32564d..90ced3c8b16 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2413,6 +2413,18 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1,t2; +# +# Bug#38999 valgrind warnings for update statement in function compare_record() +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); +SELECT * FROM t1 WHERE a = 2; +a +2 +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; +DROP TABLE t1,t2; End of 5.1 tests # # Test for bug #39932 "create table fails if column for FK is in different diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index f2c770cce42..c49b215887b 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -649,6 +649,20 @@ EXPLAIN SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0 DROP TABLE t1,t2; +--echo # +--echo # Bug#38999 valgrind warnings for update statement in function compare_record() +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); + +SELECT * FROM t1 WHERE a = 2; +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; + +DROP TABLE t1,t2; + --echo End of 5.1 tests diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a5bf361661b..2861235a995 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2678,6 +2678,12 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } + /* init null bytes with default values as they might be + left uninitialized in some cases and these uninited bytes + might be copied into mysql record buffer that leads to + valgrind warnings */ + memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); + for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 549d52dff61d15e98a9865cc8dc553989050c374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 14 Jun 2010 09:50:30 +0300 Subject: [PATCH 169/207] =?UTF-8?q?Merge=20a=20change=20from=20mysql-5.1-i?= =?UTF-8?q?nnodb:=20------------------------------------------------------?= =?UTF-8?q?------=20revno:=203507=20revision-id:=20marko.makela@oracle.com?= =?UTF-8?q?-20100610125623-ar6qf4w2pv2kr7mb=20parent:=20sergey.glukhov@sun?= =?UTF-8?q?.com-20100609121718-04mpk5kjxvnrxdu8=20committer:=20Marko=20M?= =?UTF-8?q?=C3=A4kel=C3=A4=20=20branch=20nick:=20?= =?UTF-8?q?5.1-innodb=20timestamp:=20Thu=202010-06-10=2015:56:23=20+0300?= =?UTF-8?q?=20message:=20=20=20Bug=20#38999:=20Re-enable=20innodb=5Fmulti?= =?UTF-8?q?=5Fupdate.test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysql-test/suite/innodb/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def index da04138fd0a..888298bbb09 100644 --- a/mysql-test/suite/innodb/t/disabled.def +++ b/mysql-test/suite/innodb/t/disabled.def @@ -9,4 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -innodb_multi_update: Bug #38999 2010-05-05 mmakela Valgrind warnings From d482162638446b398aecb7d75ee19f032c7eed29 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Tue, 15 Jun 2010 15:15:42 +0400 Subject: [PATCH 170/207] Fix a build break with cmake: remove the custom defines that prevented hp_test2 to link in non-debug builds. --- storage/heap/hp_test2.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 733dff40c1a..5b0c8d8685d 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -15,16 +15,6 @@ /* Test av isam-databas: stor test */ -#ifndef USE_MY_FUNC /* We want to be able to dbug this !! */ -#define USE_MY_FUNC -#endif -#ifdef DBUG_OFF -#undef DBUG_OFF -#endif -#ifndef SAFEMALLOC -#define SAFEMALLOC -#endif - #include "heapdef.h" /* Because of hp_find_block */ #include From 66c8b4eafce8c82420b137e8038b8ccec8e9d5a9 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 15 Jun 2010 17:51:57 +0300 Subject: [PATCH 171/207] Increment InnoDB version number from 1.1.1 to 1.1.2, the 1.1.1 release will be included inside MySQL 5.5.5 and is up to (inclusive): vasil.dimov@oracle.com-20100602124314-21l3cb27w4rbfqrq --- storage/innobase/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 11cec113fc8..15acb81f0d8 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#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; From 451a3810eeb963fea9fa6081147a3758620e0da3 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 16 Jun 2010 13:04:30 +0400 Subject: [PATCH 172/207] Small clean-up and pre-requisite for making TABLE_SHARE a class. Remove unused members in TABLE_SHARE. --- sql/table.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sql/table.h b/sql/table.h index 1307770d8e1..4492a26b62b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -573,9 +573,7 @@ struct TABLE_SHARE key_map keys_for_keyread; ha_rows min_rows, max_rows; /* create information */ ulong avg_row_length; /* create information */ - ulong raid_chunksize; ulong version, mysql_version; - ulong timestamp_offset; /* Set to offset+1 of record */ ulong reclength; /* Recordlength */ plugin_ref db_plugin; /* storage engine plugin */ @@ -586,8 +584,6 @@ struct TABLE_SHARE } enum row_type row_type; /* How rows are stored */ enum tmp_table_type tmp_table; - enum enum_ha_unused unused1; - enum enum_ha_unused unused2; uint ref_count; /* How many TABLE objects uses this */ uint blob_ptr_size; /* 4 or 8 */ @@ -605,7 +601,6 @@ struct TABLE_SHARE uint db_create_options; /* Create options from database */ uint db_options_in_use; /* Options in use */ uint db_record_offset; /* if HA_REC_IN_SEQ */ - uint raid_type, raid_chunks; uint rowid_field_offset; /* Field_nr +1 to rowid field */ /* Index of auto-updated TIMESTAMP field in field array */ uint primary_key; From c7170276efa491d4c6a04a454710701ae78eb53d Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 16 Jun 2010 11:25:55 +0200 Subject: [PATCH 173/207] BUG#52737: plugin_dir is set to /usr/local/mysql/lib/plugin while starting via mysqld_safe Incremental patch to fix plugin_dir from .../lib/plugin to .../lib/mysql/plugin. --- scripts/mysqld_safe.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 5d7f0760b82..562732e7387 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -704,7 +704,7 @@ fi cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" -plugin_dir="${PLUGIN_DIR:-$MY_BASEDIR_VERSION/lib/plugin}${PLUGIN_VARIANT}" +plugin_dir="${PLUGIN_DIR:-$MY_BASEDIR_VERSION/lib/mysql/plugin}${PLUGIN_VARIANT}" for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \ "--datadir=$DATADIR" "--plugin-dir=$plugin_dir" "$USER_OPTION" From 24e30932d6b8dc76b249bfca0fb33dbd960d11fb Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Thu, 17 Jun 2010 11:06:13 +1000 Subject: [PATCH 174/207] Revert a change that should have been a part of 3008.2.76..3008.2.78. --- storage/innobase/srv/srv0srv.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index b1f3a543b07..5bdeca7b01d 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -2371,30 +2371,6 @@ loop: OS_THREAD_DUMMY_RETURN; } -/******************************************************************//** -Increment the server activity count. */ -UNIV_INLINE -void -srv_inc_activity_count_low(void) -/*============================*/ -{ - mutex_enter(&kernel_mutex); - - ++srv_activity_count; - - mutex_exit(&kernel_mutex); -} - -/******************************************************************//** -Increment the server activity count. */ -UNIV_INTERN -void -srv_inc_activity_count(void) -/*========================*/ -{ - srv_inc_activity_count_low(); -} - /**********************************************************************//** Check whether any background thread is active. @return FALSE if all are are suspended or have exited. */ @@ -2431,9 +2407,7 @@ void srv_active_wake_master_thread(void) /*===============================*/ { - ut_ad(!mutex_own(&kernel_mutex)); - - srv_inc_activity_count_low(); + srv_activity_count++; if (srv_n_threads_active[SRV_MASTER] == 0) { From 689d245782350e9296e4e44a090fb6c1e38e6d15 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 17 Jun 2010 02:13:53 -0700 Subject: [PATCH 175/207] This change splits innodb_file_format_check into innodb_file_format_check and innodb_file_format_max two system variables. And this also fixes bug #53654 after 2nd shutdown innodb_file_format_check attains strange values. rb://366 approved by Marko --- mysql-test/suite/innodb/r/innodb-index.result | 2 +- mysql-test/suite/innodb/r/innodb-zip.result | 20 +- .../suite/innodb/r/innodb_bug47167.result | 42 ++-- .../suite/innodb/r/innodb_bug52745.result | 2 +- .../suite/innodb/r/innodb_bug53591.result | 2 +- .../suite/innodb/r/innodb_file_format.result | 35 ++-- .../suite/innodb/t/innodb-autoinc-44030.test | 4 +- mysql-test/suite/innodb/t/innodb-autoinc.test | 4 +- mysql-test/suite/innodb/t/innodb-index.test | 6 +- mysql-test/suite/innodb/t/innodb-zip.test | 16 +- .../suite/innodb/t/innodb_bug36172.test | 4 +- .../suite/innodb/t/innodb_bug47167.test | 45 ++-- .../suite/innodb/t/innodb_bug52745.test | 4 +- .../suite/innodb/t/innodb_bug53591.test | 4 +- .../suite/innodb/t/innodb_file_format.test | 28 ++- mysql-test/suite/sys_vars/r/all_vars.result | 2 + .../r/innodb_file_format_check_basic.result | 84 ++++---- .../t/innodb_file_format_check_basic.test | 46 ++--- storage/innobase/handler/ha_innodb.cc | 195 ++++++++---------- storage/innobase/include/dict0mem.h | 4 + storage/innobase/include/srv0srv.h | 2 +- storage/innobase/srv/srv0srv.c | 2 +- storage/innobase/srv/srv0start.c | 2 +- storage/innobase/trx/trx0sys.c | 8 +- 24 files changed, 277 insertions(+), 286 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 5d67a06b80f..e43f70a2365 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -920,7 +920,7 @@ create index t1u on t1 (u(1)); drop table t1; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; -set global innodb_file_format_check=Antelope; +set global innodb_file_format_max=Antelope; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; CREATE TABLE t1( diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index bcd3849238f..6c93f4bb6ca 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -397,25 +397,25 @@ set global innodb_file_per_table=0; set global innodb_file_format=Antelope; set global innodb_file_per_table=on; set global innodb_file_format=`Barracuda`; -set global innodb_file_format_check=`Antelope`; +set global innodb_file_format_max=`Antelope`; create table normal_table ( c1 int ) engine = innodb; -select @@innodb_file_format_check; -@@innodb_file_format_check +select @@innodb_file_format_max; +@@innodb_file_format_max Antelope create table zip_table ( c1 int ) engine = innodb key_block_size = 8; -select @@innodb_file_format_check; -@@innodb_file_format_check +select @@innodb_file_format_max; +@@innodb_file_format_max Barracuda -set global innodb_file_format_check=`Antelope`; -select @@innodb_file_format_check; -@@innodb_file_format_check +set global innodb_file_format_max=`Antelope`; +select @@innodb_file_format_max; +@@innodb_file_format_max Antelope show table status; -select @@innodb_file_format_check; -@@innodb_file_format_check +select @@innodb_file_format_max; +@@innodb_file_format_max Barracuda drop table normal_table, zip_table; diff --git a/mysql-test/suite/innodb/r/innodb_bug47167.result b/mysql-test/suite/innodb/r/innodb_bug47167.result index cf8cb0c0d7b..656a4846a52 100644 --- a/mysql-test/suite/innodb/r/innodb_bug47167.result +++ b/mysql-test/suite/innodb/r/innodb_bug47167.result @@ -1,24 +1,24 @@ -set @old_innodb_file_format_check=@@innodb_file_format_check; -select @old_innodb_file_format_check; -@old_innodb_file_format_check +set @old_innodb_file_format_max=@@innodb_file_format_max; +select @old_innodb_file_format_max; +@old_innodb_file_format_max Antelope -set global innodb_file_format_check = Barracuda; -select @@innodb_file_format_check; -@@innodb_file_format_check +set global innodb_file_format_max = Barracuda; +select @@innodb_file_format_max; +@@innodb_file_format_max Barracuda -set global innodb_file_format_check = DEFAULT; -select @@innodb_file_format_check; -@@innodb_file_format_check -Barracuda -set global innodb_file_format_check = @old_innodb_file_format_check; -select @@innodb_file_format_check; -@@innodb_file_format_check +set global innodb_file_format_max = DEFAULT; +select @@innodb_file_format_max; +@@innodb_file_format_max Antelope -set global innodb_file_format_check = cheetah; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'cheetah' -set global innodb_file_format_check = Bear; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'Bear' -set global innodb_file_format_check = on; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'ON' -set global innodb_file_format_check = off; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'off' +set global innodb_file_format_max = @old_innodb_file_format_max; +select @@innodb_file_format_max; +@@innodb_file_format_max +Antelope +set global innodb_file_format_max = cheetah; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'cheetah' +set global innodb_file_format_max = Bear; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'Bear' +set global innodb_file_format_max = on; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'ON' +set global innodb_file_format_max = off; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'off' diff --git a/mysql-test/suite/innodb/r/innodb_bug52745.result b/mysql-test/suite/innodb/r/innodb_bug52745.result index 254c6525257..d746fb427b5 100644 --- a/mysql-test/suite/innodb/r/innodb_bug52745.result +++ b/mysql-test/suite/innodb/r/innodb_bug52745.result @@ -126,5 +126,5 @@ Warning 1265 Data truncated for column 'col79' at row 1 Warning 1264 Out of range value for column 'col84' at row 1 DROP TABLE bug52745; SET GLOBAL innodb_file_format=Antelope; -SET GLOBAL innodb_file_format_check=Antelope; +SET GLOBAL innodb_file_format_max=Antelope; SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_bug53591.result b/mysql-test/suite/innodb/r/innodb_bug53591.result index 1f05b6d2a57..d3f8dfeafc2 100644 --- a/mysql-test/suite/innodb/r/innodb_bug53591.result +++ b/mysql-test/suite/innodb/r/innodb_bug53591.result @@ -12,5 +12,5 @@ Error 1118 Row size too large. The maximum row size for the used table type, not Error 1030 Got error 139 from storage engine DROP TABLE bug53591; SET GLOBAL innodb_file_format=Antelope; -SET GLOBAL innodb_file_format_check=Antelope; +SET GLOBAL innodb_file_format_max=Antelope; SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/suite/innodb/r/innodb_file_format.result index 6a573d8658e..70cfc9e4f47 100644 --- a/mysql-test/suite/innodb/r/innodb_file_format.result +++ b/mysql-test/suite/innodb/r/innodb_file_format.result @@ -3,6 +3,9 @@ select @@innodb_file_format; Antelope select @@innodb_file_format_check; @@innodb_file_format_check +1 +select @@innodb_file_format_max; +@@innodb_file_format_max Antelope set global innodb_file_format=antelope; set global innodb_file_format=barracuda; @@ -22,22 +25,26 @@ ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'off' select @@innodb_file_format; @@innodb_file_format Antelope -set global innodb_file_format_check=antelope; -set global innodb_file_format_check=barracuda; -set global innodb_file_format_check=cheetah; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'cheetah' -select @@innodb_file_format_check; -@@innodb_file_format_check -Barracuda -set global innodb_file_format_check=default; -select @@innodb_file_format_check; -@@innodb_file_format_check +set global innodb_file_format_max=antelope; +set global innodb_file_format_max=barracuda; +set global innodb_file_format_max=cheetah; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'cheetah' +select @@innodb_file_format_max; +@@innodb_file_format_max Barracuda +set global innodb_file_format_max=default; +select @@innodb_file_format_max; +@@innodb_file_format_max +Antelope set global innodb_file_format=on; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'ON' set global innodb_file_format=off; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'off' -select @@innodb_file_format_check; -@@innodb_file_format_check -Barracuda -set global innodb_file_format_check=antelope; +select @@innodb_file_format_max; +@@innodb_file_format_max +Antelope +set global innodb_file_format_max=antelope; +set global innodb_file_format_check=off; +ERROR HY000: Variable 'innodb_file_format_check' is a read only variable +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format_max=Antelope; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-44030.test b/mysql-test/suite/innodb/t/innodb-autoinc-44030.test index 17c836004a1..790646fe13b 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc-44030.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc-44030.test @@ -2,7 +2,7 @@ # embedded server ignores 'delayed', so skip this -- source include/not_embedded.inc -let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; --disable_warnings drop table if exists t1; @@ -40,4 +40,4 @@ DROP TABLE t1; # -- disable_query_log -eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index c1cae16153e..a8e853baef7 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -2,7 +2,7 @@ # embedded server ignores 'delayed', so skip this -- source include/not_embedded.inc -let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; --disable_warnings drop table if exists t1; @@ -671,4 +671,4 @@ DROP TABLE t1; # -- disable_query_log -eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index f7cf3050704..05d1d37c422 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -2,7 +2,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; -let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb; insert into t1 values (5,5,'oo','oo'),(4,4,'tr','tr'),(3,4,'ad','ad'),(2,3,'ak','ak'); @@ -403,7 +403,7 @@ create index t1u on t1 (u(1)); drop table t1; eval set global innodb_file_per_table=$per_table; eval set global innodb_file_format=$format; -eval set global innodb_file_format_check=$format; +eval set global innodb_file_format_max=$format; # # Test to check whether CREATE INDEX handles implicit foreign key @@ -550,4 +550,4 @@ DROP TABLE t1; # -- disable_query_log -eval SET GLOBAL innodb_file_format_check=$innodb_file_format_check_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test index 8ba83517b44..3acd7e42fa6 100644 --- a/mysql-test/suite/innodb/t/innodb-zip.test +++ b/mysql-test/suite/innodb/t/innodb-zip.test @@ -2,7 +2,7 @@ let $per_table=`select @@innodb_file_per_table`; let $format=`select @@innodb_file_format`; -let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; set global innodb_file_per_table=off; set global innodb_file_format=`0`; @@ -316,21 +316,21 @@ eval set global innodb_file_format=$format; -- disable_info set global innodb_file_per_table=on; set global innodb_file_format=`Barracuda`; -set global innodb_file_format_check=`Antelope`; +set global innodb_file_format_max=`Antelope`; create table normal_table ( c1 int ) engine = innodb; -select @@innodb_file_format_check; +select @@innodb_file_format_max; create table zip_table ( c1 int ) engine = innodb key_block_size = 8; -select @@innodb_file_format_check; -set global innodb_file_format_check=`Antelope`; -select @@innodb_file_format_check; +select @@innodb_file_format_max; +set global innodb_file_format_max=`Antelope`; +select @@innodb_file_format_max; -- disable_result_log show table status; -- enable_result_log -select @@innodb_file_format_check; +select @@innodb_file_format_max; drop table normal_table, zip_table; -- disable_result_log @@ -341,4 +341,4 @@ drop table normal_table, zip_table; -- disable_query_log eval set global innodb_file_format=$format; eval set global innodb_file_per_table=$per_table; -eval set global innodb_file_format_check=$innodb_file_format_check_orig; +eval set global innodb_file_format_max=$innodb_file_format_max_orig; diff --git a/mysql-test/suite/innodb/t/innodb_bug36172.test b/mysql-test/suite/innodb/t/innodb_bug36172.test index c6c4e6fae47..6f5dd7629ff 100644 --- a/mysql-test/suite/innodb/t/innodb_bug36172.test +++ b/mysql-test/suite/innodb/t/innodb_bug36172.test @@ -15,7 +15,7 @@ SET storage_engine=InnoDB; -- disable_result_log let $file_format=`select @@innodb_file_format`; -let $file_format_check=`select @@innodb_file_format_check`; +let $file_format_max=`select @@innodb_file_format_max`; let $file_per_table=`select @@innodb_file_per_table`; SET GLOBAL innodb_file_format='Barracuda'; SET GLOBAL innodb_file_per_table=on; @@ -28,5 +28,5 @@ INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.90 CHECK TABLE table0 EXTENDED; DROP TABLE table0; EVAL SET GLOBAL innodb_file_format=$file_format; -EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +EVAL SET GLOBAL innodb_file_format_max=$file_format_max; EVAL SET GLOBAL innodb_file_per_table=$file_per_table; diff --git a/mysql-test/suite/innodb/t/innodb_bug47167.test b/mysql-test/suite/innodb/t/innodb_bug47167.test index 9b8bff0292f..622182acefa 100644 --- a/mysql-test/suite/innodb/t/innodb_bug47167.test +++ b/mysql-test/suite/innodb/t/innodb_bug47167.test @@ -1,45 +1,44 @@ -# This is the unit test for bug *47167. -# It tests setting the global variable -# "innodb_file_format_check" with a -# user-Defined Variable. +# This is the unit test for bug #47167. +# It tests setting the global variable "innodb_file_format_max" ( +# originally "innodb_file_format_check") with a user-Defined Variable. --source include/have_innodb.inc -# Save the value (Antelope) in 'innodb_file_format_check' to -# 'old_innodb_file_format_check' -set @old_innodb_file_format_check=@@innodb_file_format_check; +# Save the value (Antelope) in 'innodb_file_format_max' to +# 'old_innodb_file_format_max' +set @old_innodb_file_format_max=@@innodb_file_format_max; -# @old_innodb_file_format_check shall have the value of 'Antelope' -select @old_innodb_file_format_check; +# @old_innodb_file_format_max shall have the value of 'Antelope' +select @old_innodb_file_format_max; -# Reset the value in 'innodb_file_format_check' to 'Barracuda' -set global innodb_file_format_check = Barracuda; +# Reset the value in 'innodb_file_format_max' to 'Barracuda' +set global innodb_file_format_max = Barracuda; -select @@innodb_file_format_check; +select @@innodb_file_format_max; -# Set 'innodb_file_format_check' to its default value, which +# Set 'innodb_file_format_max' to its default value, which # is the latest file format supported in the current release. -set global innodb_file_format_check = DEFAULT; +set global innodb_file_format_max = DEFAULT; -select @@innodb_file_format_check; +select @@innodb_file_format_max; -# Put the saved value back to 'innodb_file_format_check' -set global innodb_file_format_check = @old_innodb_file_format_check; +# Put the saved value back to 'innodb_file_format_max' +set global innodb_file_format_max = @old_innodb_file_format_max; -# Check whether 'innodb_file_format_check' get its original value. -select @@innodb_file_format_check; +# Check whether 'innodb_file_format_max' get its original value. +select @@innodb_file_format_max; # Following are negative tests, all should fail. --disable_warnings --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check = cheetah; +set global innodb_file_format_max = cheetah; --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check = Bear; +set global innodb_file_format_max = Bear; --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check = on; +set global innodb_file_format_max = on; --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check = off; +set global innodb_file_format_max = off; --enable_warnings diff --git a/mysql-test/suite/innodb/t/innodb_bug52745.test b/mysql-test/suite/innodb/t/innodb_bug52745.test index d2de869648b..686ca705ab7 100644 --- a/mysql-test/suite/innodb/t/innodb_bug52745.test +++ b/mysql-test/suite/innodb/t/innodb_bug52745.test @@ -1,7 +1,7 @@ -- source include/have_innodb.inc let $file_format=`select @@innodb_file_format`; -let $file_format_check=`select @@innodb_file_format_check`; +let $file_format_max=`select @@innodb_file_format_max`; let $file_per_table=`select @@innodb_file_per_table`; SET GLOBAL innodb_file_format='Barracuda'; SET GLOBAL innodb_file_per_table=on; @@ -105,5 +105,5 @@ SHOW WARNINGS; DROP TABLE bug52745; EVAL SET GLOBAL innodb_file_format=$file_format; -EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +EVAL SET GLOBAL innodb_file_format_max=$file_format_max; EVAL SET GLOBAL innodb_file_per_table=$file_per_table; diff --git a/mysql-test/suite/innodb/t/innodb_bug53591.test b/mysql-test/suite/innodb/t/innodb_bug53591.test index 58a7596dff9..e0e568034d8 100644 --- a/mysql-test/suite/innodb/t/innodb_bug53591.test +++ b/mysql-test/suite/innodb/t/innodb_bug53591.test @@ -1,7 +1,7 @@ -- source include/have_innodb.inc let $file_format=`select @@innodb_file_format`; -let $file_format_check=`select @@innodb_file_format_check`; +let $file_format_max=`select @@innodb_file_format_max`; let $file_per_table=`select @@innodb_file_per_table`; SET GLOBAL innodb_file_format='Barracuda'; @@ -18,5 +18,5 @@ SHOW WARNINGS; DROP TABLE bug53591; EVAL SET GLOBAL innodb_file_format=$file_format; -EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +EVAL SET GLOBAL innodb_file_format_max=$file_format_max; EVAL SET GLOBAL innodb_file_per_table=$file_per_table; diff --git a/mysql-test/suite/innodb/t/innodb_file_format.test b/mysql-test/suite/innodb/t/innodb_file_format.test index 5d094cb9dba..26c3646c0dd 100644 --- a/mysql-test/suite/innodb/t/innodb_file_format.test +++ b/mysql-test/suite/innodb/t/innodb_file_format.test @@ -1,7 +1,11 @@ -- source include/have_innodb.inc +let $innodb_file_format_orig=`select @@innodb_file_format`; +let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; + select @@innodb_file_format; select @@innodb_file_format_check; +select @@innodb_file_format_max; set global innodb_file_format=antelope; set global innodb_file_format=barracuda; --error ER_WRONG_VALUE_FOR_VAR @@ -14,16 +18,24 @@ set global innodb_file_format=on; --error ER_WRONG_VALUE_FOR_VAR set global innodb_file_format=off; select @@innodb_file_format; -set global innodb_file_format_check=antelope; -set global innodb_file_format_check=barracuda; +set global innodb_file_format_max=antelope; +set global innodb_file_format_max=barracuda; --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check=cheetah; -select @@innodb_file_format_check; -set global innodb_file_format_check=default; -select @@innodb_file_format_check; +set global innodb_file_format_max=cheetah; +select @@innodb_file_format_max; +set global innodb_file_format_max=default; +select @@innodb_file_format_max; --error ER_WRONG_VALUE_FOR_VAR set global innodb_file_format=on; --error ER_WRONG_VALUE_FOR_VAR set global innodb_file_format=off; -select @@innodb_file_format_check; -set global innodb_file_format_check=antelope; +select @@innodb_file_format_max; +set global innodb_file_format_max=antelope; + +# innodb_file_format_check is read only variable, can be +# set as server startup parameter +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +set global innodb_file_format_check=off; + +eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; +eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 0f741ff930a..7f6dca3eb7b 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,5 +10,7 @@ There should be *no* long test name listed below: select variable_name as `There should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; There should be *no* variables listed below: +INNODB_FILE_FORMAT_MAX +INNODB_FILE_FORMAT_MAX drop table t1; drop table t2; diff --git a/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result b/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result index 29be30cf096..c59e1b802f4 100644 --- a/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result @@ -1,59 +1,59 @@ -SET @start_global_value = @@global.innodb_file_format_check; +SET @start_global_value = @@global.innodb_file_format_max; SELECT @start_global_value; @start_global_value Antelope Valid values are 'Antelope' and 'Barracuda' -select @@global.innodb_file_format_check in ('Antelope', 'Barracuda'); -@@global.innodb_file_format_check in ('Antelope', 'Barracuda') +select @@global.innodb_file_format_max in ('Antelope', 'Barracuda'); +@@global.innodb_file_format_max in ('Antelope', 'Barracuda') 1 -select @@global.innodb_file_format_check; -@@global.innodb_file_format_check +select @@global.innodb_file_format_max; +@@global.innodb_file_format_max Antelope -select @@session.innodb_file_format_check; -ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable -show global variables like 'innodb_file_format_check'; +select @@session.innodb_file_format_max; +ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable +show global variables like 'innodb_file_format_max'; Variable_name Value -innodb_file_format_check Antelope -show session variables like 'innodb_file_format_check'; +innodb_file_format_max Antelope +show session variables like 'innodb_file_format_max'; Variable_name Value -innodb_file_format_check Antelope -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; +innodb_file_format_max Antelope +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Antelope -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; +INNODB_FILE_FORMAT_MAX Antelope +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Antelope -set global innodb_file_format_check='Antelope'; -select @@global.innodb_file_format_check; -@@global.innodb_file_format_check +INNODB_FILE_FORMAT_MAX Antelope +set global innodb_file_format_max='Antelope'; +select @@global.innodb_file_format_max; +@@global.innodb_file_format_max Antelope -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Antelope -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; +INNODB_FILE_FORMAT_MAX Antelope +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Antelope -set @@global.innodb_file_format_check='Barracuda'; -select @@global.innodb_file_format_check; -@@global.innodb_file_format_check +INNODB_FILE_FORMAT_MAX Antelope +set @@global.innodb_file_format_max='Barracuda'; +select @@global.innodb_file_format_max; +@@global.innodb_file_format_max Barracuda -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Barracuda -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; +INNODB_FILE_FORMAT_MAX Barracuda +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT_CHECK Barracuda -set session innodb_file_format_check='Salmon'; -ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable and should be set with SET GLOBAL -set @@session.innodb_file_format_check='Salmon'; -ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable and should be set with SET GLOBAL -set global innodb_file_format_check=1.1; -ERROR 42000: Incorrect argument type to variable 'innodb_file_format_check' -set global innodb_file_format_check=1e1; -ERROR 42000: Incorrect argument type to variable 'innodb_file_format_check' -set global innodb_file_format_check='Salmon'; -ERROR 42000: Variable 'innodb_file_format_check' can't be set to the value of 'Salmon' -SET @@global.innodb_file_format_check = @start_global_value; -SELECT @@global.innodb_file_format_check; -@@global.innodb_file_format_check +INNODB_FILE_FORMAT_MAX Barracuda +set session innodb_file_format_max='Salmon'; +ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL +set @@session.innodb_file_format_max='Salmon'; +ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL +set global innodb_file_format_max=1.1; +ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max' +set global innodb_file_format_max=1e1; +ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max' +set global innodb_file_format_max='Salmon'; +ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'Salmon' +SET @@global.innodb_file_format_max = @start_global_value; +SELECT @@global.innodb_file_format_max; +@@global.innodb_file_format_max Antelope diff --git a/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test b/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test index 4c60957561c..e087cc738b0 100644 --- a/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test @@ -5,51 +5,51 @@ --source include/have_innodb.inc -SET @start_global_value = @@global.innodb_file_format_check; +SET @start_global_value = @@global.innodb_file_format_max; SELECT @start_global_value; # # exists as global only # --echo Valid values are 'Antelope' and 'Barracuda' -select @@global.innodb_file_format_check in ('Antelope', 'Barracuda'); -select @@global.innodb_file_format_check; +select @@global.innodb_file_format_max in ('Antelope', 'Barracuda'); +select @@global.innodb_file_format_max; --error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.innodb_file_format_check; -show global variables like 'innodb_file_format_check'; -show session variables like 'innodb_file_format_check'; -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; +select @@session.innodb_file_format_max; +show global variables like 'innodb_file_format_max'; +show session variables like 'innodb_file_format_max'; +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; # # show that it's writable # -set global innodb_file_format_check='Antelope'; -select @@global.innodb_file_format_check; -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; -set @@global.innodb_file_format_check='Barracuda'; -select @@global.innodb_file_format_check; -select * from information_schema.global_variables where variable_name='innodb_file_format_check'; -select * from information_schema.session_variables where variable_name='innodb_file_format_check'; +set global innodb_file_format_max='Antelope'; +select @@global.innodb_file_format_max; +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; +set @@global.innodb_file_format_max='Barracuda'; +select @@global.innodb_file_format_max; +select * from information_schema.global_variables where variable_name='innodb_file_format_max'; +select * from information_schema.session_variables where variable_name='innodb_file_format_max'; --error ER_GLOBAL_VARIABLE -set session innodb_file_format_check='Salmon'; +set session innodb_file_format_max='Salmon'; --error ER_GLOBAL_VARIABLE -set @@session.innodb_file_format_check='Salmon'; +set @@session.innodb_file_format_max='Salmon'; # # incorrect types # --error ER_WRONG_TYPE_FOR_VAR -set global innodb_file_format_check=1.1; +set global innodb_file_format_max=1.1; --error ER_WRONG_TYPE_FOR_VAR -set global innodb_file_format_check=1e1; +set global innodb_file_format_max=1e1; --error ER_WRONG_VALUE_FOR_VAR -set global innodb_file_format_check='Salmon'; +set global innodb_file_format_max='Salmon'; # # Cleanup # -SET @@global.innodb_file_format_check = @start_global_value; -SELECT @@global.innodb_file_format_check; +SET @@global.innodb_file_format_max = @start_global_value; +SELECT @@global.innodb_file_format_max; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 21d30dc4904..675edc61ac7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -149,10 +149,10 @@ static char* innobase_log_group_home_dir = NULL; static char* innobase_file_format_name = NULL; static char* innobase_change_buffering = NULL; -/* Note: This variable can be set to on/off and any of the supported -file formats in the configuration file, but can only be set to any -of the supported file formats during runtime. */ -static char* innobase_file_format_check = NULL; +/* The highest file format being used in the database. The value can be +set by user, however, it will be adjusted to the newer file format if +a table of such format is created/opened. */ +static char* innobase_file_format_max = NULL; static char* innobase_file_flush_method = NULL; @@ -160,6 +160,7 @@ static char* innobase_file_flush_method = NULL; values */ static ulong innobase_fast_shutdown = 1; +static my_bool innobase_file_format_check = TRUE; #ifdef UNIV_LOG_ARCHIVE static my_bool innobase_log_archive = FALSE; static char* innobase_log_arch_dir = NULL; @@ -171,6 +172,7 @@ 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 char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; @@ -366,22 +368,13 @@ innobase_file_format_name_lookup( name */ /************************************************************//** Validate the file format check config parameters, as a side effect it -sets the srv_check_file_format_at_startup variable. -@return true if one of "on" or "off" */ -static -bool -innobase_file_format_check_on_off( -/*==============================*/ - const char* format_check); /*!< in: parameter value */ -/************************************************************//** -Validate the file format check config parameters, as a side effect it -sets the srv_check_file_format_at_startup variable. +sets the srv_max_file_format_at_startup variable. @return the format_id if valid config value, otherwise, return -1 */ static int innobase_file_format_validate_and_set( -/*================================*/ - const char* format_check); /*!< in: parameter value */ +/*==================================*/ + const char* format_max); /*!< in: parameter value */ /****************************************************************//** Return alter table flags supported in an InnoDB database. */ static @@ -2264,32 +2257,35 @@ mem_free_and_error: innobase_file_format_name is used in the MySQL set variable interface and so can't be const. */ - innobase_file_format_name = + innobase_file_format_name = (char*) trx_sys_file_format_id_to_name(format_id); - /* Process innobase_file_format_check variable */ - ut_a(innobase_file_format_check != NULL); + /* Check innobase_file_format_check variable */ + if (!innobase_file_format_check) { - /* As a side effect it will set srv_check_file_format_at_startup - on valid input. First we check for "on"/"off". */ - if (!innobase_file_format_check_on_off(innobase_file_format_check)) { + /* Set the value to disable checking. */ + srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1; - /* Did the user specify a format name that we support ? - As a side effect it will update the variable - srv_check_file_format_at_startup */ - if (innobase_file_format_validate_and_set( - innobase_file_format_check) < 0) { + } else { - sql_print_error("InnoDB: invalid " - "innodb_file_format_check value: " - "should be either 'on' or 'off' or " - "any value up to %s or its " - "equivalent numeric id", - trx_sys_file_format_id_to_name( - DICT_TF_FORMAT_MAX)); + /* Set the value to the lowest supported format. */ + srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN; + } - goto mem_free_and_error; - } + /* Did the user specify a format name that we support? + As a side effect it will update the variable + srv_max_file_format_at_startup */ + if (innobase_file_format_validate_and_set( + innobase_file_format_max) < 0) { + + sql_print_error("InnoDB: invalid " + "innodb_file_format_max value: " + "should be any value up to %s or its " + "equivalent numeric id", + trx_sys_file_format_id_to_name( + DICT_TF_FORMAT_MAX)); + + goto mem_free_and_error; } if (innobase_change_buffering) { @@ -2451,7 +2447,7 @@ innobase_change_buffering_inited_ok: #endif /* MYSQL_DYNAMIC_PLUGIN */ /* Get the current high water mark format. */ - innobase_file_format_check = (char*) trx_sys_file_format_max_get(); + innobase_file_format_max = (char*) trx_sys_file_format_max_get(); DBUG_RETURN(FALSE); error: @@ -3836,7 +3832,7 @@ retry: space, if this table has higher file format setting. */ trx_sys_file_format_max_upgrade( - (const char**) &innobase_file_format_check, + (const char**) &innobase_file_format_max, dict_table_get_format(prebuilt->table)); } @@ -6959,7 +6955,7 @@ ha_innobase::create( space, if this table has higher file format setting. */ trx_sys_file_format_max_upgrade( - (const char**) &innobase_file_format_check, + (const char**) &innobase_file_format_max, dict_table_get_format(innobase_table)); } @@ -10347,50 +10343,22 @@ innobase_file_format_name_lookup( return(DICT_TF_FORMAT_MAX + 1); } -/************************************************************//** -Validate the file format check value, is it one of "on" or "off", -as a side effect it sets the srv_check_file_format_at_startup variable. -@return true if config value one of "on" or "off" */ -static -bool -innobase_file_format_check_on_off( -/*==============================*/ - const char* format_check) /*!< in: parameter value */ -{ - bool ret = true; - - if (!innobase_strcasecmp(format_check, "off")) { - - /* Set the value to disable checking. */ - srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1; - - } else if (!innobase_strcasecmp(format_check, "on")) { - - /* Set the value to the lowest supported format. */ - srv_check_file_format_at_startup = DICT_TF_FORMAT_51; - } else { - ret = FALSE; - } - - return(ret); -} - /************************************************************//** Validate the file format check config parameters, as a side effect it -sets the srv_check_file_format_at_startup variable. +sets the srv_max_file_format_at_startup variable. @return the format_id if valid config value, otherwise, return -1 */ static int innobase_file_format_validate_and_set( -/*================================*/ - const char* format_check) /*!< in: parameter value */ +/*==================================*/ + const char* format_max) /*!< in: parameter value */ { uint format_id; - format_id = innobase_file_format_name_lookup(format_check); + format_id = innobase_file_format_name_lookup(format_max); if (format_id < DICT_TF_FORMAT_MAX + 1) { - srv_check_file_format_at_startup = format_id; + srv_max_file_format_at_startup = format_id; return((int) format_id); } else { @@ -10478,15 +10446,14 @@ innodb_file_format_name_update( *static_cast(var_ptr) = trx_sys_file_format_id_to_name(srv_file_format); } - /*************************************************************//** -Check if valid argument to innodb_file_format_check. This -function is registered as a callback with MySQL. +Check if valid argument to innodb_file_format_max. This function +is registered as a callback with MySQL. @return 0 for valid file format */ static int -innodb_file_format_check_validate( -/*==============================*/ +innodb_file_format_max_validate( +/*============================*/ THD* thd, /*!< in: thread handle */ struct st_mysql_sys_var* var, /*!< in: pointer to system variable */ @@ -10506,39 +10473,27 @@ innodb_file_format_check_validate( if (file_format_input != NULL) { - /* Check if user set on/off, we want to print a suitable - message if they did so. */ + format_id = innobase_file_format_validate_and_set( + file_format_input); + + if (format_id >= 0) { + /* Save a pointer to the name in the + 'file_format_name_map' constant array. */ + *static_cast(save) = + trx_sys_file_format_id_to_name( + (uint)format_id); + + return(0); - if (innobase_file_format_check_on_off(file_format_input)) { - push_warning_printf(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "InnoDB: invalid innodb_file_format_check " - "value; on/off can only be set at startup or " - "in the configuration file"); } else { - format_id = innobase_file_format_validate_and_set( - file_format_input); - - if (format_id >= 0) { - /* Save a pointer to the name in the - 'file_format_name_map' constant array. */ - *static_cast(save) = - trx_sys_file_format_id_to_name( - (uint)format_id); - - return(0); - - } else { - push_warning_printf(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "InnoDB: invalid innodb_file_format_check " - "value; can be any format up to %s " - "or its equivalent numeric id", - trx_sys_file_format_id_to_name( - DICT_TF_FORMAT_MAX)); - } + push_warning_printf(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_ARGUMENTS, + "InnoDB: invalid innodb_file_format_max " + "value; can be any format up to %s " + "or equivalent id of %d", + trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX), + DICT_TF_FORMAT_MAX); } } @@ -10547,12 +10502,12 @@ innodb_file_format_check_validate( } /****************************************************************//** -Update the system variable innodb_file_format_check using the "saved" +Update the system variable innodb_file_format_max using the "saved" value. This function is registered as a callback with MySQL. */ static void -innodb_file_format_check_update( -/*============================*/ +innodb_file_format_max_update( +/*==========================*/ THD* thd, /*!< in: thread handle */ struct st_mysql_sys_var* var, /*!< in: pointer to system variable */ @@ -10862,15 +10817,26 @@ static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name, innodb_file_format_name_validate, innodb_file_format_name_update, "Antelope"); +/* "innobase_file_format_check" decides whether we would continue +booting the server if the file format stamped on the system +table space exceeds the maximum file format supported +by the server. Can be set during server startup at command +line or configure file, and a read only variable after +server startup */ +static MYSQL_SYSVAR_BOOL(file_format_check, innobase_file_format_check, + PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, + "Whether to perform system file format check.", + NULL, NULL, TRUE); + /* If a new file format is introduced, the file format name needs to be updated accordingly. Please refer to file_format_name_map[] defined in trx0sys.c for the next file format name. */ -static MYSQL_SYSVAR_STR(file_format_check, innobase_file_format_check, +static MYSQL_SYSVAR_STR(file_format_max, innobase_file_format_max, PLUGIN_VAR_OPCMDARG, "The highest file format in the tablespace.", - innodb_file_format_check_validate, - innodb_file_format_check_update, "Barracuda"); + innodb_file_format_max_validate, + innodb_file_format_max_update, "Antelope"); static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit, PLUGIN_VAR_OPCMDARG, @@ -11118,6 +11084,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(file_per_table), MYSQL_SYSVAR(file_format), MYSQL_SYSVAR(file_format_check), + MYSQL_SYSVAR(file_format_max), MYSQL_SYSVAR(flush_log_at_trx_commit), MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index f93b2f8c8a3..57e5b5394ee 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -88,6 +88,10 @@ combination of types */ new BLOB treatment */ /** Maximum supported file format */ #define DICT_TF_FORMAT_MAX DICT_TF_FORMAT_ZIP + +/** Minimum supported file format */ +#define DICT_TF_FORMAT_MIN DICT_TF_FORMAT_51 + /* @} */ #define DICT_TF_BITS 6 /*!< number of flag bits */ #if (1 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT)) <= DICT_TF_FORMAT_MAX diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 98e127d41e2..18f7c07c3c6 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -101,7 +101,7 @@ extern ulint srv_file_format; /** Whether to check file format during startup. A value of DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to set it to the highest format we support. */ -extern ulint srv_check_file_format_at_startup; +extern ulint srv_max_file_format_at_startup; /** Place locks to records only i.e. do not use next-key locking except on duplicate key checking and foreign key checking */ extern ibool srv_locks_unsafe_for_binlog; diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 5bdeca7b01d..6354689105a 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -127,7 +127,7 @@ UNIV_INTERN ulint srv_file_format = 0; /** Whether to check file format during startup. A value of DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to set it to the highest format we support. */ -UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX; +UNIV_INTERN ulint srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX; #if DICT_TF_FORMAT_51 # error "DICT_TF_FORMAT_51 must be 0!" diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 1b96a2f4708..4a0ecc5154f 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1590,7 +1590,7 @@ innobase_start_or_create_for_mysql(void) consistent state, this is REQUIRED for the recovery process to work. */ err = trx_sys_file_format_max_check( - srv_check_file_format_at_startup); + srv_max_file_format_at_startup); if (err != DB_SUCCESS) { return(err); diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 9c531e64662..e2f0ff6d532 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -135,7 +135,7 @@ UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key; #ifndef UNIV_HOTBACKUP /** This is used to track the maximum file format id known to InnoDB. It's -updated via SET GLOBAL innodb_file_format_check = 'x' or when we open +updated via SET GLOBAL innodb_file_format_max = 'x' or when we open or create a table. */ static file_format_t file_format_max; @@ -1160,7 +1160,7 @@ trx_sys_file_format_max_check( if (format_id == ULINT_UNDEFINED) { /* Format ID was not set. Set it to minimum possible value. */ - format_id = DICT_TF_FORMAT_51; + format_id = DICT_TF_FORMAT_MIN; } ut_print_timestamp(stderr); @@ -1240,7 +1240,7 @@ trx_sys_file_format_tag_init(void) /* If format_id is not set then set it to the minimum. */ if (format_id == ULINT_UNDEFINED) { - trx_sys_file_format_max_set(DICT_TF_FORMAT_51, NULL); + trx_sys_file_format_max_set(DICT_TF_FORMAT_MIN, NULL); } } @@ -1296,7 +1296,7 @@ trx_sys_file_format_init(void) /* We don't need a mutex here, as this function should only be called once at start up. */ - file_format_max.id = DICT_TF_FORMAT_51; + file_format_max.id = DICT_TF_FORMAT_MIN; file_format_max.name = trx_sys_file_format_id_to_name( file_format_max.id); From 9989cc8e99fc45a2e462d437cc5f5d10d48ce3ee Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 17 Jun 2010 12:35:23 +0300 Subject: [PATCH 176/207] Decrement version number from 1.1.2 to 1.1.1, this latest tree is going to be 1.1.1. --- storage/innobase/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 15acb81f0d8..11cec113fc8 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#define INNODB_VERSION_BUGFIX 2 +#define INNODB_VERSION_BUGFIX 1 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From e368a0646473de55f049bfbd10ad7993af2f0b9c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 17 Jun 2010 12:59:53 +0300 Subject: [PATCH 177/207] Adjust innodb_mysql.result after the resolved conflict from the merge --- mysql-test/suite/innodb/r/innodb_mysql.result | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 1624a9e64b7..124370fa630 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2414,8 +2414,8 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1,t2; # -# # Bug#38999 valgrind warnings for update statement in function compare_record() +# CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 values (1),(2),(3),(4),(5); @@ -2425,7 +2425,9 @@ a 2 UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; DROP TABLE t1,t2; +# # Bug #53830: !table || (!table->read_set || bitmap_is_set(table->read_set, field_index)) +# CREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), KEY(b,d)) ENGINE=InnoDB; From 3ac6a4b451f61b8edf9cb326111157a86f1bdc1c Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Thu, 17 Jun 2010 22:51:35 +0200 Subject: [PATCH 178/207] WL#5349 Change default storage engine to InnoDB The default storage engine is changed from MyISAM to InnoDB, in all builds except for the embedded server. In addition, the following system variables are changed: * innodb_file_per_table is enabled * innodb_strict_mode is enabled * innodb_file_format_name_update is changed to 'Barracuda' The test suite is changed so that tests that do not explicitly include the have_innodb.inc are run with --default-storage-engine=MyISAM. This is to ease the transition, so that most regression tests are run with the same engine as before. Some tests are disabled for the embedded server regression test, as the output of certain statements will be different that for the regular server (i.e SELECT @@default_storage_engine). This is to ease transition. --- mysql-test/lib/mtr_cases.pm | 17 +- mysql-test/mysql-test-run.pl | 6 +- mysql-test/r/bug46760.result | 2 +- mysql-test/r/mysqld--help-notwin.result | 2 +- mysql-test/r/mysqld--help-win.result | 2 +- mysql-test/r/partition_innodb.result | 4 +- .../binlog/t/binlog_row_binlog-master.opt | 2 +- .../t/binlog_row_mix_innodb_myisam-master.opt | 2 +- .../binlog/t/binlog_stm_binlog-master.opt | 2 +- .../t/binlog_stm_mix_innodb_myisam-master.opt | 2 +- .../suite/funcs_1/r/is_engines_innodb.result | 2 +- mysql-test/suite/funcs_1/views/func_view.inc | 4 +- mysql-test/suite/innodb/r/innodb-index.result | 6 +- mysql-test/suite/innodb/r/innodb-zip.result | 5 +- .../suite/innodb/r/innodb_bug52745.result | 4 +- .../suite/innodb/r/innodb_bug53591.result | 4 +- .../suite/innodb/r/innodb_file_format.result | 8 +- .../innodb/t/innodb-use-sys-malloc-master.opt | 4 +- mysql-test/suite/innodb/t/innodb-zip.test | 6 +- .../suite/innodb/t/innodb_bug47167.test | 1 + .../suite/innodb/t/innodb_file_format.test | 1 + .../suite/innodb/t/innodb_mysql-master.opt | 2 +- .../parts/r/partition_alter3_innodb.result | 94 ++++ .../parts/r/partition_basic_innodb.result | 432 ++++++++++++++++++ .../rpl/r/rpl_row_loaddata_concurrent.result | 4 +- mysql-test/suite/rpl/r/rpl_slave_skip.result | 8 +- mysql-test/suite/rpl/r/rpl_stm_innodb.result | 2 +- .../rpl/r/rpl_stm_loaddata_concurrent.result | 4 +- .../rpl/t/rpl_row_basic_11bugs-master.opt | 2 +- .../rpl_row_binlog_max_cache_size-master.opt | 2 +- mysql-test/suite/rpl/t/rpl_slave_skip.test | 4 +- .../rpl/t/rpl_stm_loaddata_concurrent.test | 2 +- .../r/default_storage_engine_basic.result | 12 +- .../t/default_storage_engine_basic.test | 1 + .../t/innodb_file_format_check_basic.test | 2 +- .../sys_vars/t/storage_engine_basic.test | 1 + mysql-test/t/bootstrap-master.opt | 1 + mysql-test/t/bootstrap.test | 4 +- mysql-test/t/bug46760.test | 2 +- mysql-test/t/ctype_utf8-master.opt | 1 + mysql-test/t/ctype_utf8mb4-master.opt | 1 + mysql-test/t/ctype_utf8mb4_innodb-master.opt | 1 + mysql-test/t/implicit_commit-master.opt | 1 + mysql-test/t/mdl_sync-master.opt | 1 + mysql-test/t/mysqldump-max-master.opt | 1 + mysql-test/t/partition_innodb.test | 1 + ...artition_innodb_semi_consistent-master.opt | 2 +- mysql-test/t/ps_3innodb-master.opt | 1 + mysql-test/t/strict-master.opt | 1 + sql/mysqld.cc | 8 + storage/innobase/CMakeLists.txt | 1 + storage/innobase/handler/ha_innodb.cc | 6 +- 52 files changed, 629 insertions(+), 62 deletions(-) create mode 100644 mysql-test/t/bootstrap-master.opt create mode 100644 mysql-test/t/ctype_utf8-master.opt create mode 100644 mysql-test/t/ctype_utf8mb4-master.opt create mode 100644 mysql-test/t/ctype_utf8mb4_innodb-master.opt create mode 100644 mysql-test/t/implicit_commit-master.opt create mode 100644 mysql-test/t/mdl_sync-master.opt create mode 100644 mysql-test/t/mysqldump-max-master.opt create mode 100644 mysql-test/t/ps_3innodb-master.opt create mode 100644 mysql-test/t/strict-master.opt diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 4039825be55..29626e38396 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -41,6 +41,12 @@ our $opt_with_ndbcluster_only; our $defaults_file; our $defaults_extra_file; our $quick_collect; +# Set to 1 if you want the tests to override +# default storage engine settings, and use MyISAM +# as default. (temporary option used in connection +# with the change of default storage engine to InnoDB) +our $default_myisam= 1; + sub collect_option { my ($opt, $value)= @_; @@ -591,6 +597,9 @@ sub optimize_cases { my $default_engine= mtr_match_prefix($opt, "--default-storage-engine="); + # Allow use of uppercase, convert to all lower case + $default_engine =~ tr/A-Z/a-z/; + if (defined $default_engine){ #print " $tinfo->{name}\n"; @@ -948,10 +957,12 @@ sub collect_one_test_case { return $tinfo unless $do_innodb_plugin; } } - else + elsif ($default_myisam) { - push(@{$tinfo->{'master_opt'}}, "--loose-skip-innodb"); - push(@{$tinfo->{'slave_opt'}}, "--loose-skip-innodb"); + # This is a temporary fix to allow non-innodb tests to run even if + # the default storage engine is innodb. + push(@{$tinfo->{'master_opt'}}, "--default-storage-engine=MyISAM"); + push(@{$tinfo->{'slave_opt'}}, "--default-storage-engine=MyISAM"); } if ( $tinfo->{'need_binlog'} ) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 23a92828e2a..acb5fa3ed0f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -944,6 +944,7 @@ sub command_line_setup { 'timestamp' => \&report_option, 'timediff' => \&report_option, 'max-connections=i' => \$opt_max_connections, + 'default-myisam!' => \&collect_option, 'help|h' => \$opt_usage, 'list-options' => \$opt_list_options, @@ -2843,7 +2844,6 @@ sub mysql_install_db { mtr_add_arg($args, "--bootstrap"); mtr_add_arg($args, "--basedir=%s", $install_basedir); mtr_add_arg($args, "--datadir=%s", $install_datadir); - mtr_add_arg($args, "--loose-innodb=OFF"); mtr_add_arg($args, "--loose-skip-falcon"); mtr_add_arg($args, "--loose-skip-ndbcluster"); mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); @@ -5560,7 +5560,9 @@ Misc options timediff With --timestamp, also print time passed since *previous* test started max-connections=N Max number of open connection to server in mysqltest - + default-myisam Set default storage engine to MyISAM for non-innodb + tests. This is needed after switching default storage + engine to InnoDB. HERE exit(1); diff --git a/mysql-test/r/bug46760.result b/mysql-test/r/bug46760.result index 413df050b10..46b8c23b95c 100644 --- a/mysql-test/r/bug46760.result +++ b/mysql-test/r/bug46760.result @@ -25,7 +25,7 @@ DROP TABLE t1; # MySQL Bug#39200: optimize table does not recognize # ROW_FORMAT=COMPRESSED # -CREATE TABLE t1 (a INT) ROW_FORMAT=compressed; +CREATE TABLE t1 (a INT) ROW_FORMAT=compressed, ENGINE=MyISAM; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index 5f1a25324ed..533f35c1113 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -746,7 +746,7 @@ connect-timeout 10 console FALSE date-format %Y-%m-%d datetime-format %Y-%m-%d %H:%i:%s -default-storage-engine MyISAM +default-storage-engine InnoDB default-time-zone (No default value) default-week-format 0 delay-key-write ON diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result index 5d517f06add..9b6b0f53b01 100644 --- a/mysql-test/r/mysqld--help-win.result +++ b/mysql-test/r/mysqld--help-win.result @@ -750,7 +750,7 @@ connect-timeout 10 console FALSE date-format %Y-%m-%d datetime-format %Y-%m-%d %H:%i:%s -default-storage-engine MyISAM +default-storage-engine InnoDB default-time-zone (No default value) default-week-format 0 delay-key-write ON diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 2df8b19e00c..8ae16238a18 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -266,12 +266,12 @@ engine = x partition by key (a); Warnings: Warning 1286 Unknown storage engine 'x' -Warning 1266 Using storage engine MyISAM for table 't1' +Warning 1266 Using storage engine InnoDB for table 't1' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (a) */ drop table t1; create table t1 (a int) diff --git a/mysql-test/suite/binlog/t/binlog_row_binlog-master.opt b/mysql-test/suite/binlog/t/binlog_row_binlog-master.opt index f8e46a44854..099f07e5d4e 100644 --- a/mysql-test/suite/binlog/t/binlog_row_binlog-master.opt +++ b/mysql-test/suite/binlog/t/binlog_row_binlog-master.opt @@ -1 +1 @@ ---max_binlog_size=4096 +--max_binlog_size=4096 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt b/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt index e76299453d3..9655b180fbd 100644 --- a/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt +++ b/mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam-master.opt @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--innodb_lock_wait_timeout=2 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt index f8e46a44854..099f07e5d4e 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt +++ b/mysql-test/suite/binlog/t/binlog_stm_binlog-master.opt @@ -1 +1 @@ ---max_binlog_size=4096 +--max_binlog_size=4096 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt index 5d0037fdc97..5c4f0b5c198 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt +++ b/mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam-master.opt @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 --binlog-direct-non-transactional-updates=FALSE +--innodb_lock_wait_timeout=2 --binlog-direct-non-transactional-updates=FALSE --default-storage-engine=MyISAM diff --git a/mysql-test/suite/funcs_1/r/is_engines_innodb.result b/mysql-test/suite/funcs_1/r/is_engines_innodb.result index 5713b417cd1..57e53b60bbd 100644 --- a/mysql-test/suite/funcs_1/r/is_engines_innodb.result +++ b/mysql-test/suite/funcs_1/r/is_engines_innodb.result @@ -1,7 +1,7 @@ SELECT * FROM information_schema.engines WHERE ENGINE = 'InnoDB'; ENGINE InnoDB -SUPPORT YES +SUPPORT DEFAULT COMMENT Supports transactions, row-level locking, and foreign keys TRANSACTIONS YES XA YES diff --git a/mysql-test/suite/funcs_1/views/func_view.inc b/mysql-test/suite/funcs_1/views/func_view.inc index 4aed5845a84..660efde8927 100644 --- a/mysql-test/suite/funcs_1/views/func_view.inc +++ b/mysql-test/suite/funcs_1/views/func_view.inc @@ -171,7 +171,7 @@ CREATE TABLE t1_selects disable_result ENUM('Yes','No') NOT NULL default 'No', PRIMARY KEY(id), UNIQUE (my_select) -); +) ENGINE=MyISAM; # MODES to be checked CREATE TABLE t1_modes @@ -180,7 +180,7 @@ CREATE TABLE t1_modes my_mode VARCHAR(200) NOT NULL, PRIMARY KEY(id), UNIQUE (my_mode) -); +) ENGINE=MyISAM; --enable_query_log # The table to be used in the FROM parts of the SELECTs diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index e43f70a2365..1aeca2c226a 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -918,9 +918,9 @@ ERROR HY000: Too big row alter table t1 row_format=compact; create index t1u on t1 (u(1)); drop table t1; -set global innodb_file_per_table=0; -set global innodb_file_format=Antelope; -set global innodb_file_format_max=Antelope; +set global innodb_file_per_table=1; +set global innodb_file_format=Barracuda; +set global innodb_file_format_max=Barracuda; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; CREATE TABLE t1( diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index 6c93f4bb6ca..da2be2bb07d 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -1,3 +1,4 @@ +set session innodb_strict_mode=0; set global innodb_file_per_table=off; set global innodb_file_format=`0`; create table t0(a int primary key) engine=innodb row_format=compressed; @@ -393,8 +394,8 @@ table_schema table_name row_format test t8 Compact test t9 Redundant drop table t8, t9; -set global innodb_file_per_table=0; -set global innodb_file_format=Antelope; +set global innodb_file_per_table=1; +set global innodb_file_format=Barracuda; set global innodb_file_per_table=on; set global innodb_file_format=`Barracuda`; set global innodb_file_format_max=`Antelope`; diff --git a/mysql-test/suite/innodb/r/innodb_bug52745.result b/mysql-test/suite/innodb/r/innodb_bug52745.result index d746fb427b5..16dd356997e 100644 --- a/mysql-test/suite/innodb/r/innodb_bug52745.result +++ b/mysql-test/suite/innodb/r/innodb_bug52745.result @@ -125,6 +125,6 @@ Warning 1264 Out of range value for column 'col78' at row 1 Warning 1265 Data truncated for column 'col79' at row 1 Warning 1264 Out of range value for column 'col84' at row 1 DROP TABLE bug52745; -SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=0; +SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb/r/innodb_bug53591.result b/mysql-test/suite/innodb/r/innodb_bug53591.result index d3f8dfeafc2..8573fb60718 100644 --- a/mysql-test/suite/innodb/r/innodb_bug53591.result +++ b/mysql-test/suite/innodb/r/innodb_bug53591.result @@ -11,6 +11,6 @@ Error 139 Too big row Error 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs Error 1030 Got error 139 from storage engine DROP TABLE bug53591; -SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=0; +SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/suite/innodb/r/innodb_file_format.result index 70cfc9e4f47..447e13f0d60 100644 --- a/mysql-test/suite/innodb/r/innodb_file_format.result +++ b/mysql-test/suite/innodb/r/innodb_file_format.result @@ -1,6 +1,6 @@ select @@innodb_file_format; @@innodb_file_format -Antelope +Barracuda select @@innodb_file_format_check; @@innodb_file_format_check 1 @@ -17,14 +17,14 @@ Barracuda set global innodb_file_format=default; select @@innodb_file_format; @@innodb_file_format -Antelope +Barracuda set global innodb_file_format=on; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'ON' set global innodb_file_format=off; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'off' select @@innodb_file_format; @@innodb_file_format -Antelope +Barracuda set global innodb_file_format_max=antelope; set global innodb_file_format_max=barracuda; set global innodb_file_format_max=cheetah; @@ -46,5 +46,5 @@ Antelope set global innodb_file_format_max=antelope; set global innodb_file_format_check=off; ERROR HY000: Variable 'innodb_file_format_check' is a read only variable -SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_format_max=Antelope; diff --git a/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt b/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt index acf3b8729ed..041b063645b 100644 --- a/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt +++ b/mysql-test/suite/innodb/t/innodb-use-sys-malloc-master.opt @@ -1 +1,3 @@ ---innodb-use-sys-malloc=true +--default-storage-engine=MyISAM +--loose-innodb-use-sys-malloc=true +--loose-innodb-use-sys-malloc=true diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test index 3acd7e42fa6..8e00a8b019b 100644 --- a/mysql-test/suite/innodb/t/innodb-zip.test +++ b/mysql-test/suite/innodb/t/innodb-zip.test @@ -3,9 +3,12 @@ let $per_table=`select @@innodb_file_per_table`; let $format=`select @@innodb_file_format`; let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; +let $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; + +set session innodb_strict_mode=0; set global innodb_file_per_table=off; set global innodb_file_format=`0`; - + create table t0(a int primary key) engine=innodb row_format=compressed; create table t00(a int primary key) engine=innodb key_block_size=4 row_format=compressed; @@ -342,3 +345,4 @@ drop table normal_table, zip_table; eval set global innodb_file_format=$format; eval set global innodb_file_per_table=$per_table; eval set global innodb_file_format_max=$innodb_file_format_max_orig; +eval set session innodb_strict_mode=$innodb_strict_mode_orig; diff --git a/mysql-test/suite/innodb/t/innodb_bug47167.test b/mysql-test/suite/innodb/t/innodb_bug47167.test index 622182acefa..8fcd129cf94 100644 --- a/mysql-test/suite/innodb/t/innodb_bug47167.test +++ b/mysql-test/suite/innodb/t/innodb_bug47167.test @@ -2,6 +2,7 @@ # It tests setting the global variable "innodb_file_format_max" ( # originally "innodb_file_format_check") with a user-Defined Variable. +--source include/not_embedded.inc --source include/have_innodb.inc # Save the value (Antelope) in 'innodb_file_format_max' to diff --git a/mysql-test/suite/innodb/t/innodb_file_format.test b/mysql-test/suite/innodb/t/innodb_file_format.test index 26c3646c0dd..aa411258da0 100644 --- a/mysql-test/suite/innodb/t/innodb_file_format.test +++ b/mysql-test/suite/innodb/t/innodb_file_format.test @@ -1,3 +1,4 @@ +-- source include/not_embedded.inc -- source include/have_innodb.inc let $innodb_file_format_orig=`select @@innodb_file_format`; diff --git a/mysql-test/suite/innodb/t/innodb_mysql-master.opt b/mysql-test/suite/innodb/t/innodb_mysql-master.opt index 205c733455d..c46f5079568 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql-master.opt +++ b/mysql-test/suite/innodb/t/innodb_mysql-master.opt @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--innodb-lock-wait-timeout=2 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/parts/r/partition_alter3_innodb.result b/mysql-test/suite/parts/r/partition_alter3_innodb.result index cb104d4be54..dc6008842a3 100644 --- a/mysql-test/suite/parts/r/partition_alter3_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result @@ -57,6 +57,7 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm +t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -78,6 +79,7 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -96,6 +98,7 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (DAYOFYEAR(f_date)) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -112,6 +115,7 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -137,6 +141,9 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -161,6 +168,10 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -186,6 +197,14 @@ t1 CREATE TABLE `t1` ( PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB, PARTITION p7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#p6.ibd +t1#P#p7.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -222,6 +241,13 @@ t1 CREATE TABLE `t1` ( PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#p6.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -244,6 +270,12 @@ t1 CREATE TABLE `t1` ( PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -265,6 +297,11 @@ t1 CREATE TABLE `t1` ( PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -285,6 +322,10 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -304,6 +345,9 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -322,6 +366,8 @@ t1 CREATE TABLE `t1` ( /*!50100 PARTITION BY HASH (YEAR(f_date)) (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -339,6 +385,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (YEAR(f_date)) (PARTITION p0 ENGINE = InnoDB) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; @@ -359,6 +406,7 @@ t1 CREATE TABLE `t1` ( `f_varchar` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm +t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) FROM t1 WHERE f_date = '1000-02-10'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -398,6 +446,7 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm +t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where @@ -420,6 +469,7 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -448,6 +498,9 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -472,6 +525,10 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -500,6 +557,14 @@ t1 CREATE TABLE `t1` ( PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB, PARTITION p7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#p6.ibd +t1#P#p7.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -534,6 +599,13 @@ t1 CREATE TABLE `t1` ( PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB, PARTITION p6 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#p6.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -559,6 +631,12 @@ t1 CREATE TABLE `t1` ( PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB, PARTITION p5 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#p5.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -583,6 +661,11 @@ t1 CREATE TABLE `t1` ( PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB, PARTITION p4 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#p4.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -606,6 +689,10 @@ t1 CREATE TABLE `t1` ( PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB, PARTITION part2 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -628,6 +715,9 @@ t1 CREATE TABLE `t1` ( (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB, PARTITION part7 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd +t1#P#part7.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -649,6 +739,8 @@ t1 CREATE TABLE `t1` ( /*!50100 PARTITION BY KEY (f_int1) (PARTITION p0 ENGINE = InnoDB, PARTITION part1 ENGINE = InnoDB) */ +t1#P#p0.ibd +t1#P#part1.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -669,6 +761,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY KEY (f_int1) (PARTITION p0 ENGINE = InnoDB) */ +t1#P#p0.ibd t1.frm t1.par EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; @@ -692,6 +785,7 @@ t1 CREATE TABLE `t1` ( `f_charbig` varchar(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 t1.frm +t1.ibd EXPLAIN PARTITIONS SELECT COUNT(*) <> 1 FROM t1 WHERE f_int1 = 3; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 20 Using where diff --git a/mysql-test/suite/parts/r/partition_basic_innodb.result b/mysql-test/suite/parts/r/partition_basic_innodb.result index 21c5d70e6e3..c6a89e970b3 100644 --- a/mysql-test/suite/parts/r/partition_basic_innodb.result +++ b/mysql-test/suite/parts/r/partition_basic_innodb.result @@ -77,6 +77,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -532,6 +534,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -1002,6 +1009,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -1468,6 +1483,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -1930,6 +1951,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -2405,6 +2434,14 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -2882,6 +2919,14 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -3345,6 +3390,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -3802,6 +3856,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -4257,6 +4313,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -4727,6 +4788,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -5193,6 +5262,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -5655,6 +5730,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -6128,6 +6211,14 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -6601,6 +6692,14 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -7064,6 +7163,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -7527,6 +7635,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -8019,6 +8129,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -8526,6 +8641,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -9029,6 +9152,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -9528,6 +9657,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -10040,6 +10177,14 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -10554,6 +10699,14 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -11054,6 +11207,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -11547,6 +11709,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -12039,6 +12203,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -12546,6 +12715,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -13049,6 +13226,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -13548,6 +13731,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -14060,6 +14251,14 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -14574,6 +14773,14 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -15074,6 +15281,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -15567,6 +15783,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -16075,6 +16293,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -16598,6 +16821,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -17117,6 +17348,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -17632,6 +17869,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -18160,6 +18405,14 @@ SUBPARTITION BY KEY (f_int1) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -18690,6 +18943,14 @@ SUBPARTITION BY HASH (f_int1 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -19206,6 +19467,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -19720,6 +19990,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -20212,6 +20484,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -20719,6 +20996,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -21222,6 +21507,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -21721,6 +22012,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -22231,6 +22530,14 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -22741,6 +23048,14 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -23241,6 +23556,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -23734,6 +24058,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -24226,6 +24552,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -24733,6 +25064,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -25236,6 +25575,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -25735,6 +26080,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -26245,6 +26598,14 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -26755,6 +27116,14 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -27255,6 +27624,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par @@ -27748,6 +28126,8 @@ t1 CREATE TABLE `t1` ( PARTITIONS 2 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd t1.frm t1.par @@ -28256,6 +28636,11 @@ t1 CREATE TABLE `t1` ( PARTITIONS 5 */ unified filelist +t1#P#p0.ibd +t1#P#p1.ibd +t1#P#p2.ibd +t1#P#p3.ibd +t1#P#p4.ibd t1.frm t1.par @@ -28779,6 +29164,14 @@ t1 CREATE TABLE `t1` ( PARTITION part3 VALUES IN (3) ENGINE = InnoDB) */ unified filelist +t1#P#part0.ibd +t1#P#part1.ibd +t1#P#part2.ibd +t1#P#part3.ibd +t1#P#part_1.ibd +t1#P#part_2.ibd +t1#P#part_3.ibd +t1#P#part_N.ibd t1.frm t1.par @@ -29298,6 +29691,12 @@ t1 CREATE TABLE `t1` ( PARTITION partf VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta.ibd +t1#P#partb.ibd +t1#P#partc.ibd +t1#P#partd.ibd +t1#P#parte.ibd +t1#P#partf.ibd t1.frm t1.par @@ -29813,6 +30212,14 @@ SUBPARTITIONS 2 PARTITION partd VALUES LESS THAN (2147483646) ENGINE = InnoDB) */ unified filelist +t1#P#parta#SP#partasp0.ibd +t1#P#parta#SP#partasp1.ibd +t1#P#partb#SP#partbsp0.ibd +t1#P#partb#SP#partbsp1.ibd +t1#P#partc#SP#partcsp0.ibd +t1#P#partc#SP#partcsp1.ibd +t1#P#partd#SP#partdsp0.ibd +t1#P#partd#SP#partdsp1.ibd t1.frm t1.par @@ -30339,6 +30746,14 @@ SUBPARTITION BY KEY (f_int2) SUBPARTITION subpart42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#subpart11.ibd +t1#P#part1#SP#subpart12.ibd +t1#P#part2#SP#subpart21.ibd +t1#P#part2#SP#subpart22.ibd +t1#P#part3#SP#subpart31.ibd +t1#P#part3#SP#subpart32.ibd +t1#P#part4#SP#subpart41.ibd +t1#P#part4#SP#subpart42.ibd t1.frm t1.par @@ -30865,6 +31280,14 @@ SUBPARTITION BY HASH (f_int2 + 1) SUBPARTITION sp42 ENGINE = InnoDB)) */ unified filelist +t1#P#part1#SP#sp11.ibd +t1#P#part1#SP#sp12.ibd +t1#P#part2#SP#sp21.ibd +t1#P#part2#SP#sp22.ibd +t1#P#part3#SP#sp31.ibd +t1#P#part3#SP#sp32.ibd +t1#P#part4#SP#sp41.ibd +t1#P#part4#SP#sp42.ibd t1.frm t1.par @@ -31381,6 +31804,15 @@ SUBPARTITIONS 3 PARTITION part3 VALUES IN (NULL) ENGINE = InnoDB) */ unified filelist +t1#P#part1#SP#part1sp0.ibd +t1#P#part1#SP#part1sp1.ibd +t1#P#part1#SP#part1sp2.ibd +t1#P#part2#SP#part2sp0.ibd +t1#P#part2#SP#part2sp1.ibd +t1#P#part2#SP#part2sp2.ibd +t1#P#part3#SP#part3sp0.ibd +t1#P#part3#SP#part3sp1.ibd +t1#P#part3#SP#part3sp2.ibd t1.frm t1.par diff --git a/mysql-test/suite/rpl/r/rpl_row_loaddata_concurrent.result b/mysql-test/suite/rpl/r/rpl_row_loaddata_concurrent.result index abeb92a7d21..cb095ad561e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_loaddata_concurrent.result +++ b/mysql-test/suite/rpl/r/rpl_row_loaddata_concurrent.result @@ -7,11 +7,11 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (c1 char(50)) master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # COMMIT +master-bin.000001 # Xid # # COMMIT /* XID */ DROP TABLE t1; stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/suite/rpl/r/rpl_slave_skip.result b/mysql-test/suite/rpl/r/rpl_slave_skip.result index d6513d838c3..5feba69b64d 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_skip.result +++ b/mysql-test/suite/rpl/r/rpl_slave_skip.result @@ -8,15 +8,15 @@ start slave; STOP SLAVE; **** On Master **** SET SESSION BINLOG_FORMAT=ROW; -CREATE TABLE t1 (a INT, b INT); -CREATE TABLE t2 (c INT, d INT); +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1),(2,4),(3,9); INSERT INTO t2 VALUES (1,1),(2,8),(3,27); UPDATE t1,t2 SET b = d, d = b * 2 WHERE a = c; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) -master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (c INT, d INT) +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM +master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F diff --git a/mysql-test/suite/rpl/r/rpl_stm_innodb.result b/mysql-test/suite/rpl/r/rpl_stm_innodb.result index 825238c66fe..f99457faaf0 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_stm_innodb.result @@ -66,7 +66,7 @@ SHOW CREATE TABLE mysqltest1.tmp2; Table Create Table tmp2 CREATE TEMPORARY TABLE `tmp2` ( `a` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ######### Must return no rows here ######### SELECT COUNT(*) FROM mysqltest1.t1; COUNT(*) diff --git a/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result b/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result index e204d67181a..417da0e2237 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result +++ b/mysql-test/suite/rpl/r/rpl_stm_loaddata_concurrent.result @@ -1,10 +1,10 @@ RESET MASTER; -CREATE TABLE t1 (c1 char(50)); +CREATE TABLE t1 (c1 char(50)) ENGINE=MyISAM; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (c1 char(50)) +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (c1 char(50)) ENGINE=MyISAM master-bin.000001 # Query # # BEGIN master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`c1`) ;file_id=# diff --git a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs-master.opt b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs-master.opt index de86b63f230..bd7728134c7 100644 --- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs-master.opt +++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs-master.opt @@ -1,2 +1,2 @@ ---binlog_ignore_db=test_ignore +--binlog_ignore_db=test_ignore --default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt index 45631525481..eb56e5c0a09 100644 --- a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt +++ b/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size-master.opt @@ -1 +1 @@ ---binlog_cache_size=4096 --max_binlog_cache_size=7680 +--binlog_cache_size=4096 --max_binlog_cache_size=7680 --default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_slave_skip.test b/mysql-test/suite/rpl/t/rpl_slave_skip.test index fc0936cea09..66762d4dad0 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_skip.test +++ b/mysql-test/suite/rpl/t/rpl_slave_skip.test @@ -17,8 +17,8 @@ STOP SLAVE; connection master; SET SESSION BINLOG_FORMAT=ROW; -CREATE TABLE t1 (a INT, b INT); -CREATE TABLE t2 (c INT, d INT); +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1),(2,4),(3,9); INSERT INTO t2 VALUES (1,1),(2,8),(3,27); let $master_log_pos= query_get_value(SHOW MASTER STATUS, Position, 1); diff --git a/mysql-test/suite/rpl/t/rpl_stm_loaddata_concurrent.test b/mysql-test/suite/rpl/t/rpl_stm_loaddata_concurrent.test index 2ea95a63fb5..7add76c0ef5 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_loaddata_concurrent.test +++ b/mysql-test/suite/rpl/t/rpl_stm_loaddata_concurrent.test @@ -4,7 +4,7 @@ RESET MASTER; let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); -CREATE TABLE t1 (c1 char(50)); +CREATE TABLE t1 (c1 char(50)) ENGINE=MyISAM; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1; -- source include/show_binlog_events.inc diff --git a/mysql-test/suite/sys_vars/r/default_storage_engine_basic.result b/mysql-test/suite/sys_vars/r/default_storage_engine_basic.result index 541c0b6b328..c2acc7ab5ac 100644 --- a/mysql-test/suite/sys_vars/r/default_storage_engine_basic.result +++ b/mysql-test/suite/sys_vars/r/default_storage_engine_basic.result @@ -1,22 +1,22 @@ SET @start_global_value = @@global.default_storage_engine; SELECT @start_global_value; @start_global_value -MyISAM +InnoDB SET @start_session_value = @@session.default_storage_engine; SELECT @start_session_value; @start_session_value -MyISAM +InnoDB '#--------------------FN_DYNVARS_005_01-------------------------#' SET @@global.default_storage_engine = INNODB; SET @@global.default_storage_engine = DEFAULT; SELECT @@global.default_storage_engine; @@global.default_storage_engine -MyISAM +InnoDB SET @@session.default_storage_engine = INNODB; SET @@session.default_storage_engine = DEFAULT; SELECT @@session.default_storage_engine; @@session.default_storage_engine -MyISAM +InnoDB '#--------------------FN_DYNVARS_005_02-------------------------#' SET @@global.default_storage_engine = MYISAM; SELECT @@global.default_storage_engine; @@ -110,8 +110,8 @@ SET @@default_storage_engine = @start_global_value; SET @@global.default_storage_engine = @start_global_value; SELECT @@global.default_storage_engine; @@global.default_storage_engine -MyISAM +InnoDB SET @@session.default_storage_engine = @start_session_value; SELECT @@session.default_storage_engine; @@session.default_storage_engine -MyISAM +InnoDB diff --git a/mysql-test/suite/sys_vars/t/default_storage_engine_basic.test b/mysql-test/suite/sys_vars/t/default_storage_engine_basic.test index 17f2d2cc852..f47453eb234 100644 --- a/mysql-test/suite/sys_vars/t/default_storage_engine_basic.test +++ b/mysql-test/suite/sys_vars/t/default_storage_engine_basic.test @@ -15,6 +15,7 @@ # # ######################################################################## +--source include/not_embedded.inc --source include/have_innodb.inc --source include/load_sysvars.inc diff --git a/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test b/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test index e087cc738b0..cbf25af2442 100644 --- a/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test @@ -2,7 +2,7 @@ # 2010-01-25 - Added # - +--source include/not_embedded.inc --source include/have_innodb.inc SET @start_global_value = @@global.innodb_file_format_max; diff --git a/mysql-test/suite/sys_vars/t/storage_engine_basic.test b/mysql-test/suite/sys_vars/t/storage_engine_basic.test index 7ec071e6414..49e8a52efea 100644 --- a/mysql-test/suite/sys_vars/t/storage_engine_basic.test +++ b/mysql-test/suite/sys_vars/t/storage_engine_basic.test @@ -21,6 +21,7 @@ # # ######################################################################## +--source include/not_embedded.inc --source include/have_innodb.inc --source include/load_sysvars.inc diff --git a/mysql-test/t/bootstrap-master.opt b/mysql-test/t/bootstrap-master.opt new file mode 100644 index 00000000000..31a799e4d9b --- /dev/null +++ b/mysql-test/t/bootstrap-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM --skip-innodb diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test index db89269b35d..e98afb81ff1 100644 --- a/mysql-test/t/bootstrap.test +++ b/mysql-test/t/bootstrap.test @@ -8,8 +8,7 @@ drop table if exists t1; # Add the datadir to the bootstrap command let $MYSQLD_DATADIR= `select @@datadir`; -let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR; - +let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR --default-storage-engine=MyISAM --skip-innodb; # # Check that --bootstrap reads from stdin # @@ -20,7 +19,6 @@ EOF --exec $MYSQLD_BOOTSTRAP_CMD < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 drop table t1; remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql; - # # Check that --bootstrap of file with SQL error returns error # diff --git a/mysql-test/t/bug46760.test b/mysql-test/t/bug46760.test index f55edbbfa42..e7f57549250 100644 --- a/mysql-test/t/bug46760.test +++ b/mysql-test/t/bug46760.test @@ -29,7 +29,7 @@ DROP TABLE t1; --echo # ROW_FORMAT=COMPRESSED --echo # -CREATE TABLE t1 (a INT) ROW_FORMAT=compressed; +CREATE TABLE t1 (a INT) ROW_FORMAT=compressed, ENGINE=MyISAM; SHOW CREATE TABLE t1; OPTIMIZE TABLE t1; SHOW CREATE TABLE t1; diff --git a/mysql-test/t/ctype_utf8-master.opt b/mysql-test/t/ctype_utf8-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/ctype_utf8-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/ctype_utf8mb4-master.opt b/mysql-test/t/ctype_utf8mb4-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/ctype_utf8mb4-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/ctype_utf8mb4_innodb-master.opt b/mysql-test/t/ctype_utf8mb4_innodb-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/ctype_utf8mb4_innodb-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/implicit_commit-master.opt b/mysql-test/t/implicit_commit-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/implicit_commit-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/mdl_sync-master.opt b/mysql-test/t/mdl_sync-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/mdl_sync-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/mysqldump-max-master.opt b/mysql-test/t/mysqldump-max-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/mysqldump-max-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index 6400017dfb7..ccca4df9882 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -1,3 +1,4 @@ +--source include/not_embedded.inc --source include/have_partition.inc --source include/have_innodb.inc diff --git a/mysql-test/t/partition_innodb_semi_consistent-master.opt b/mysql-test/t/partition_innodb_semi_consistent-master.opt index e76299453d3..9655b180fbd 100644 --- a/mysql-test/t/partition_innodb_semi_consistent-master.opt +++ b/mysql-test/t/partition_innodb_semi_consistent-master.opt @@ -1 +1 @@ ---innodb_lock_wait_timeout=2 +--innodb_lock_wait_timeout=2 --default-storage-engine=MyISAM diff --git a/mysql-test/t/ps_3innodb-master.opt b/mysql-test/t/ps_3innodb-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/ps_3innodb-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/t/strict-master.opt b/mysql-test/t/strict-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/strict-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7968d637223..28cad51aa41 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3435,8 +3435,16 @@ static int init_common_variables() compiler error in the Sun Studio 12 compiler. As a work-around we set the def_value member to 0 in my_long_options and initialize it to the correct value here. + + From MySQL 5.5 onwards, the default storage engine is InnoDB + (except in the embedded server, where the default continues to + be MyISAM) */ +#ifdef EMBEDDED_LIBRARY default_storage_engine= const_cast("MyISAM"); +#else + default_storage_engine= const_cast("InnoDB"); +#endif /* Add server status variables to the dynamic list of diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 6aec52032f3..90246aaa99d 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -272,6 +272,7 @@ ELSEIF (MYSQL_VERSION_ID LESS "50137") ELSE() # New plugin support, cross-platform , base name for shared module is "ha_innodb" MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE + DEFAULT MODULE_OUTPUT_NAME ha_innodb LINK_LIBRARIES ${ZLIB_LIBRARY}) ENDIF() diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 675edc61ac7..b3445f86274 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -429,7 +429,7 @@ static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG, static MYSQL_THDVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG, "Use strict mode when evaluating create options.", - NULL, NULL, FALSE); + NULL, NULL, TRUE); static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG, "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.", @@ -10809,13 +10809,13 @@ static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, static MYSQL_SYSVAR_BOOL(file_per_table, srv_file_per_table, PLUGIN_VAR_NOCMDARG, "Stores each InnoDB table to an .ibd file in the database dir.", - NULL, NULL, FALSE); + NULL, NULL, TRUE); static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name, PLUGIN_VAR_RQCMDARG, "File format to use for new tables in .ibd files.", innodb_file_format_name_validate, - innodb_file_format_name_update, "Antelope"); + innodb_file_format_name_update, "Barracuda"); /* "innobase_file_format_check" decides whether we would continue booting the server if the file format stamped on the system From 9b07b12b3d335f77b0916e16d4f13cdab4f6eada Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Sun, 20 Jun 2010 02:02:58 +0400 Subject: [PATCH 179/207] Fix for bug #54575: crash when joining tables with unique set column Problem: a flaw (derefencing a NULL pointer) in the LIKE optimization code may lead to a server crash in some rare cases. Fix: check the pointer before its dereferencing. --- mysql-test/r/func_like.result | 14 ++++++++++++++ mysql-test/t/func_like.test | 18 ++++++++++++++++-- sql/item_cmpfunc.cc | 7 ++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 9338a76e320..21da211160b 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -169,3 +169,17 @@ select 'andre%' like 'andre select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê'; _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê' 1 +End of 4.1 tests +# +# Bug #54575: crash when joining tables with unique set column +# +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +1 +DROP TABLE t1, t2; +End of 5.1 tests diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 741ea5533da..1204d04d9a0 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -112,5 +112,19 @@ select 'andre%' like 'andre # select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê'; -# -# End of 4.1 tests + +--echo End of 4.1 tests + + +--echo # +--echo # Bug #54575: crash when joining tables with unique set column +--echo # +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +DROP TABLE t1, t2; + + +--echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6e38220abd1..ca225f129ee 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4568,13 +4568,14 @@ Item_func::optimize_type Item_func_like::select_optimize() const if (args[1]->const_item()) { String* res2= args[1]->val_str((String *)&cmp.value2); + const char *ptr2; - if (!res2) + if (!res2 || !(ptr2= res2->ptr())) return OPTIMIZE_NONE; - if (*res2->ptr() != wild_many) + if (*ptr2 != wild_many) { - if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one) + if (args[0]->result_type() != STRING_RESULT || *ptr2 != wild_one) return OPTIMIZE_OP; } } From eda2ff8103c480c1ebc8ae44d75fe040c66c4eba Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Sun, 20 Jun 2010 22:43:34 +0200 Subject: [PATCH 180/207] Post-push fixup for WL#5349 InnoDB came in a new version "simultanously" with the commit. This patch is a minor change to the new innodb regression test suite. --- .../innodb/t/innodb-autoinc-44030-master.opt | 3 +++ .../suite/innodb/t/innodb-autoinc-master.opt | 3 +++ mysql-test/suite/innodb/t/innodb-master.opt | 3 +++ .../innodb/t/innodb-system-table-view-master.opt | 3 +++ .../suite/rpl/t/rpl_invoked_features-master.opt | 1 + .../suite/rpl/t/rpl_mixed_row_innodb-master.opt | 1 + .../suite/rpl/t/rpl_row_log_innodb-master.opt | 1 + mysql-test/suite/rpl/t/rpl_sync-master.opt | 2 ++ mysql-test/suite/rpl/t/rpl_sync-slave.opt | 2 +- .../suite/rpl/t/rpl_temp_temporary-master.opt | 1 + .../sys_vars/r/innodb_file_format_basic.result | 14 +++++++------- .../sys_vars/r/innodb_strict_mode_basic.result | 16 ++++++++-------- .../suite/sys_vars/r/storage_engine_basic.result | 12 ++++++------ mysql-test/t/crash_commit_before-master.opt | 3 ++- mysql-test/t/lock_sync-master.opt | 1 + 15 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 mysql-test/suite/innodb/t/innodb-autoinc-44030-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb-autoinc-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb-system-table-view-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_invoked_features-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sync-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_temp_temporary-master.opt create mode 100644 mysql-test/t/lock_sync-master.opt diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-44030-master.opt b/mysql-test/suite/innodb/t/innodb-autoinc-44030-master.opt new file mode 100644 index 00000000000..303ec1be1d0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-autoinc-44030-master.opt @@ -0,0 +1,3 @@ +--default-storage-engine=MyISAM +--innodb-strict-mode=0 +--innodb-file-per-table=0 diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-master.opt b/mysql-test/suite/innodb/t/innodb-autoinc-master.opt new file mode 100644 index 00000000000..303ec1be1d0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-autoinc-master.opt @@ -0,0 +1,3 @@ +--default-storage-engine=MyISAM +--innodb-strict-mode=0 +--innodb-file-per-table=0 diff --git a/mysql-test/suite/innodb/t/innodb-master.opt b/mysql-test/suite/innodb/t/innodb-master.opt index 4901efb416c..8b247193a4e 100644 --- a/mysql-test/suite/innodb/t/innodb-master.opt +++ b/mysql-test/suite/innodb/t/innodb-master.opt @@ -1 +1,4 @@ --binlog_cache_size=32768 --innodb_lock_wait_timeout=1 +--default-storage-engine=MyISAM +--innodb-strict-mode=0 +--innodb-file-per-table=0 diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt b/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt new file mode 100644 index 00000000000..303ec1be1d0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt @@ -0,0 +1,3 @@ +--default-storage-engine=MyISAM +--innodb-strict-mode=0 +--innodb-file-per-table=0 diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt b/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_row_log_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_row_log_innodb-master.opt index e0d075c3fbd..773ec62bef2 100644 --- a/mysql-test/suite/rpl/t/rpl_row_log_innodb-master.opt +++ b/mysql-test/suite/rpl/t/rpl_row_log_innodb-master.opt @@ -1 +1,2 @@ --skip-external-locking +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_sync-master.opt b/mysql-test/suite/rpl/t/rpl_sync-master.opt new file mode 100644 index 00000000000..ad327ce0454 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_sync-master.opt @@ -0,0 +1,2 @@ +--default-storage-engine=MyISAM +--innodb-file-per-table=0 diff --git a/mysql-test/suite/rpl/t/rpl_sync-slave.opt b/mysql-test/suite/rpl/t/rpl_sync-slave.opt index 972f9ef8af9..7d6147ed59a 100644 --- a/mysql-test/suite/rpl/t/rpl_sync-slave.opt +++ b/mysql-test/suite/rpl/t/rpl_sync-slave.opt @@ -1 +1 @@ ---sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check='ON' +--sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check='ON' --default-storage-engine=MyISAM --innodb-file-per-table=0 diff --git a/mysql-test/suite/rpl/t/rpl_temp_temporary-master.opt b/mysql-test/suite/rpl/t/rpl_temp_temporary-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_temp_temporary-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result index 58e009ea705..41369038cf6 100644 --- a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result @@ -1,28 +1,28 @@ SET @start_global_value = @@global.innodb_file_format; SELECT @start_global_value; @start_global_value -Antelope +Barracuda Valid values are 'Antelope' and 'Barracuda' select @@global.innodb_file_format in ('Antelope', 'Barracuda'); @@global.innodb_file_format in ('Antelope', 'Barracuda') 1 select @@global.innodb_file_format; @@global.innodb_file_format -Antelope +Barracuda select @@session.innodb_file_format; ERROR HY000: Variable 'innodb_file_format' is a GLOBAL variable show global variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Antelope +innodb_file_format Barracuda show session variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Antelope +innodb_file_format Barracuda select * from information_schema.global_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Antelope +INNODB_FILE_FORMAT Barracuda select * from information_schema.session_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Antelope +INNODB_FILE_FORMAT Barracuda set global innodb_file_format='Antelope'; select @@global.innodb_file_format; @@global.innodb_file_format @@ -56,4 +56,4 @@ ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'Salmon' SET @@global.innodb_file_format = @start_global_value; SELECT @@global.innodb_file_format; @@global.innodb_file_format -Antelope +Barracuda diff --git a/mysql-test/suite/sys_vars/r/innodb_strict_mode_basic.result b/mysql-test/suite/sys_vars/r/innodb_strict_mode_basic.result index 200f9166215..5e55faa99c9 100644 --- a/mysql-test/suite/sys_vars/r/innodb_strict_mode_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_strict_mode_basic.result @@ -1,32 +1,32 @@ SET @start_global_value = @@global.innodb_strict_mode; SELECT @start_global_value; @start_global_value -0 +1 Valid values are 'ON' and 'OFF' select @@global.innodb_strict_mode in (0, 1); @@global.innodb_strict_mode in (0, 1) 1 select @@global.innodb_strict_mode; @@global.innodb_strict_mode -0 +1 select @@session.innodb_strict_mode in (0, 1); @@session.innodb_strict_mode in (0, 1) 1 select @@session.innodb_strict_mode; @@session.innodb_strict_mode -0 +1 show global variables like 'innodb_strict_mode'; Variable_name Value -innodb_strict_mode OFF +innodb_strict_mode ON show session variables like 'innodb_strict_mode'; Variable_name Value -innodb_strict_mode OFF +innodb_strict_mode ON select * from information_schema.global_variables where variable_name='innodb_strict_mode'; VARIABLE_NAME VARIABLE_VALUE -INNODB_STRICT_MODE OFF +INNODB_STRICT_MODE ON select * from information_schema.session_variables where variable_name='innodb_strict_mode'; VARIABLE_NAME VARIABLE_VALUE -INNODB_STRICT_MODE OFF +INNODB_STRICT_MODE ON set global innodb_strict_mode='OFF'; set session innodb_strict_mode='OFF'; select @@global.innodb_strict_mode; @@ -117,4 +117,4 @@ INNODB_STRICT_MODE ON SET @@global.innodb_strict_mode = @start_global_value; SELECT @@global.innodb_strict_mode; @@global.innodb_strict_mode -0 +1 diff --git a/mysql-test/suite/sys_vars/r/storage_engine_basic.result b/mysql-test/suite/sys_vars/r/storage_engine_basic.result index 5e80f1343b7..6f10ec475a0 100644 --- a/mysql-test/suite/sys_vars/r/storage_engine_basic.result +++ b/mysql-test/suite/sys_vars/r/storage_engine_basic.result @@ -1,22 +1,22 @@ SET @start_global_value = @@global.storage_engine; SELECT @start_global_value; @start_global_value -MyISAM +InnoDB SET @start_session_value = @@session.storage_engine; SELECT @start_session_value; @start_session_value -MyISAM +InnoDB '#--------------------FN_DYNVARS_005_01-------------------------#' SET @@global.storage_engine = INNODB; SET @@global.storage_engine = DEFAULT; SELECT @@global.storage_engine; @@global.storage_engine -MyISAM +InnoDB SET @@session.storage_engine = INNODB; SET @@session.storage_engine = DEFAULT; SELECT @@session.storage_engine; @@session.storage_engine -MyISAM +InnoDB '#--------------------FN_DYNVARS_005_02-------------------------#' SET @@global.storage_engine = MYISAM; SELECT @@global.storage_engine; @@ -110,8 +110,8 @@ SET @@storage_engine = @start_global_value; SET @@global.storage_engine = @start_global_value; SELECT @@global.storage_engine; @@global.storage_engine -MyISAM +InnoDB SET @@session.storage_engine = @start_session_value; SELECT @@session.storage_engine; @@session.storage_engine -MyISAM +InnoDB diff --git a/mysql-test/t/crash_commit_before-master.opt b/mysql-test/t/crash_commit_before-master.opt index a745693594e..cd2ae9b1455 100644 --- a/mysql-test/t/crash_commit_before-master.opt +++ b/mysql-test/t/crash_commit_before-master.opt @@ -1,2 +1,3 @@ --skip-stack-trace --skip-core-file - +--default-storage-engine=MyISAM +--innodb-file-per-table=0 diff --git a/mysql-test/t/lock_sync-master.opt b/mysql-test/t/lock_sync-master.opt new file mode 100644 index 00000000000..96f0ce3f36c --- /dev/null +++ b/mysql-test/t/lock_sync-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM From 36348425da94591ab4ab6257cc641ba03aa58e4e Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Mon, 21 Jun 2010 11:56:43 +0400 Subject: [PATCH 181/207] Fix tree name. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index be5e1c348fa..4eab3d239d0 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-trunk-runtime" +tree_name = "mysql-trunk-bugfixing" From 915bfb505e4bd24081945259f887e652ae2709ce Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Mon, 21 Jun 2010 10:59:54 +0200 Subject: [PATCH 182/207] Fixed a readability optimization in CMake code that broke IPv6 support. --- configure.cmake | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/configure.cmake b/configure.cmake index 1a44d0e85f4..462e359ee7d 100644 --- a/configure.cmake +++ b/configure.cmake @@ -98,6 +98,14 @@ FUNCTION(MY_CHECK_TYPE_SIZE type defbase) ENDIF() ENDFUNCTION() +# Same for structs, setting HAVE_STRUCT_ instead +FUNCTION(MY_CHECK_STRUCT_SIZE type defbase) + CHECK_TYPE_SIZE("struct ${type}" SIZEOF_${defbase}) + IF(SIZEOF_${defbase}) + SET(HAVE_STRUCT_${defbase} 1 PARENT_SCOPE) + ENDIF() +ENDFUNCTION() + # Searches function in libraries # if function is found, sets output parameter result to the name of the library # if function is found in libc, result will be empty @@ -991,8 +999,8 @@ ELSEIF(WIN32) SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} winsock2.h ws2ipdef.h) ENDIF() -MY_CHECK_TYPE_SIZE("struct sockaddr_in6" SOCKADDR_IN6) -MY_CHECK_TYPE_SIZE("struct in6_addr" IN6_ADDR) +MY_CHECK_STRUCT_SIZE("sockaddr_in6" SOCKADDR_IN6) +MY_CHECK_STRUCT_SIZE("in6_addr" IN6_ADDR) IF(HAVE_STRUCT_SOCKADDR_IN6 OR HAVE_STRUCT_IN6_ADDR) SET(HAVE_IPV6 TRUE CACHE INTERNAL "") From b4f77c40ec7f63ccafce0eada0ba80ae61de434a Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Tue, 22 Jun 2010 12:13:47 +0200 Subject: [PATCH 183/207] Post-push fixups for WL#5349 --- cmake/create_initial_db.cmake.in | 3 ++- mysql-test/suite/perfschema/t/no_threads-master.opt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/create_initial_db.cmake.in b/cmake/create_initial_db.cmake.in index 01b2da665a6..881afe265ef 100644 --- a/cmake/create_initial_db.cmake.in +++ b/cmake/create_initial_db.cmake.in @@ -57,6 +57,7 @@ SET(BOOTSTRAP_COMMAND --lc-messages-dir=${CMAKE_CURRENT_BINARY_DIR}/share --basedir=. --datadir=. + --default-storage-engine=MyISAM --loose-skip-innodb --loose-skip-ndbcluster --max_allowed_packet=8M @@ -79,4 +80,4 @@ EXECUTE_PROCESS ( IF(NOT RESULT EQUAL 0) MESSAGE(FATAL_ERROR "Could not create initial database \n ${OUT} \n ${ERR}") ENDIF() - \ No newline at end of file + diff --git a/mysql-test/suite/perfschema/t/no_threads-master.opt b/mysql-test/suite/perfschema/t/no_threads-master.opt index b15ab02821d..0dfb498094a 100644 --- a/mysql-test/suite/perfschema/t/no_threads-master.opt +++ b/mysql-test/suite/perfschema/t/no_threads-master.opt @@ -1 +1 @@ ---one-thread --thread-handling=no-threads --loose-performance-schema-max-thread_instances=10 +--one-thread --thread-handling=no-threads --loose-performance-schema-max-thread_instances=10 --default-storage-engine=MyISAM --skip-innodb From 07e95b39c46708b4aa7aa27459ecc3feee7aa61c Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 22 Jun 2010 22:53:08 +0400 Subject: [PATCH 184/207] Bug#54477: Crash on IN / CASE with NULL arguments Incorrect handling of NULL arguments could lead to a crash on the IN or CASE operations when either NULL arguments were passed explicitly as arguments (IN) or implicitly generated by the WITH ROLLUP modifier (both IN and CASE). Item_func_case::find_item() assumed all necessary comparators to be instantiated in fix_length_and_dec(). However, in the presence of WITH ROLLUP modifier, arguments could be substituted with an Item_null leading to an "unexpected" STRING_RESULT comparator being invoked. In addition to the problem identical to the above, Item_func_in::val_int() could crash even with explicitly passed NULL arguments due to an optimization in fix_length_and_dec() leading to NULL arguments being ignored during comparators creation. --- mysql-test/r/func_in.result | 20 ++++++++++++++++++++ mysql-test/t/func_in.test | 15 +++++++++++++++ sql/item_cmpfunc.cc | 10 ++++++++++ 3 files changed, 45 insertions(+) diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index ffdacc43735..fdeec2755ca 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -750,4 +750,24 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables DROP TABLE t1; # +# Bug#54477: Crash on IN / CASE with NULL arguments +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); +SELECT 1 IN (NULL, a) FROM t1; +1 IN (NULL, a) +1 +NULL +SELECT a IN (a, a) FROM t1 GROUP BY a WITH ROLLUP; +a IN (a, a) +1 +1 +NULL +SELECT CASE a WHEN a THEN a END FROM t1 GROUP BY a WITH ROLLUP; +CASE a WHEN a THEN a END +1 +2 +NULL +DROP TABLE t1; +# End of 5.1 tests diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 61ae812d874..6efeb2866e6 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -539,6 +539,21 @@ EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, NULL); DROP TABLE t1; +--echo # +--echo # Bug#54477: Crash on IN / CASE with NULL arguments +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1), (2); + +SELECT 1 IN (NULL, a) FROM t1; + +SELECT a IN (a, a) FROM t1 GROUP BY a WITH ROLLUP; + +SELECT CASE a WHEN a THEN a END FROM t1 GROUP BY a WITH ROLLUP; + +DROP TABLE t1; + --echo # --echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6e38220abd1..9ff72d56050 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2773,6 +2773,8 @@ Item *Item_func_case::find_item(String *str) /* Compare every WHEN argument with it and return the first match */ for (uint i=0 ; i < ncases ; i+=2) { + if (args[i]->real_item()->type() == NULL_ITEM) + continue; cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); DBUG_ASSERT(cmp_type != ROW_RESULT); DBUG_ASSERT(cmp_items[(uint)cmp_type]); @@ -4002,9 +4004,17 @@ longlong Item_func_in::val_int() return (longlong) (!null_value && tmp != negated); } + if ((null_value= args[0]->real_item()->type() == NULL_ITEM)) + return 0; + have_null= 0; for (uint i= 1 ; i < arg_count ; i++) { + if (args[i]->real_item()->type() == NULL_ITEM) + { + have_null= TRUE; + continue; + } Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); in_item= cmp_items[(uint)cmp_type]; DBUG_ASSERT(in_item); From ef745c9112c49def969875060bf3c2bb26eceba6 Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 23 Jun 2010 10:23:41 +0200 Subject: [PATCH 185/207] Made the changes as per Kent/wlad to include http://lists.mysql.com/commits/111802 --- cmake/ssl.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index b101c26e241..d1f48888092 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -25,7 +25,7 @@ MACRO (MYSQL_USE_BUNDLED_SSL) SET(SSL_LIBRARIES yassl taocrypt) SET(SSL_INCLUDE_DIRS ${INC_DIRS}) SET(SSL_INTERNAL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL) - SET(SSL_DEFINES"-DHAVE_YASSL -DYASSL_PURE_C -DYASSL_PREFIX -DHAVE_OPENSSL -DYASSL_THREAD_SAFE") + SET(SSL_DEFINES "-DHAVE_YASSL -DYASSL_PURE_C -DYASSL_PREFIX -DHAVE_OPENSSL -DYASSL_THREAD_SAFE") CHANGE_SSL_SETTINGS("bundled") #Remove -fno-implicit-templates #(yassl sources cannot be compiled with it) From e0aba0c84b920dab5d8f726d3fc1c96f8d476a50 Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 23 Jun 2010 10:31:33 +0200 Subject: [PATCH 186/207] Updated the version number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 5de43fc7951..78138ac284e 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.5.5-m3], [], [mysql]) +AC_INIT([MySQL Server], [5.5.6-m3], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From e233dc2bfd9d49bc1479d89e322879e2e84bcb5f Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 24 Jun 2010 12:00:48 +0400 Subject: [PATCH 187/207] Fix for bug #54459: Assertion failed: param.sort_length, file .\filesort.cc, line 149 (part II) Problem: the server didn't disregard sort order for some zero length tuples. Fix: skip sort order in such a case (zero length NOT NULL string functions). --- mysql-test/r/select.result | 15 +++++++++++++++ mysql-test/t/select.test | 15 +++++++++++++++ sql/sql_select.cc | 18 +++++++++++++----- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index fb4175ed5ca..fb3de514f62 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4782,4 +4782,19 @@ a b c SELECT * FROM t1 WHERE 102 < c; a b c DROP TABLE t1; +# +# Bug #54459: Assertion failed: param.sort_length, +# file .\filesort.cc, line 149 (part II) +# +CREATE TABLE t1(a ENUM('') NOT NULL); +INSERT INTO t1 VALUES (), (), (); +EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +1 +1 +1 +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index f61db538fb4..37f3675780b 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4077,4 +4077,19 @@ SELECT * FROM t1 WHERE 102 < c; DROP TABLE t1; +--echo # +--echo # Bug #54459: Assertion failed: param.sort_length, +--echo # file .\filesort.cc, line 149 (part II) +--echo # +CREATE TABLE t1(a ENUM('') NOT NULL); +INSERT INTO t1 VALUES (), (), (); +EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; +DROP TABLE t1; + +create table t1(a enum('a'))engine=myisam charset=latin1; +insert into t1 values (''),(''),(''),(NULL); +select a, substr(a, 0, 0) from t1 order by substr(a, 0, 0); +select a, a collate latin1_german2_ci from t1 order by a collate latin1_german2_ci; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 296b18631e5..c9cca2e601f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -564,13 +564,21 @@ JOIN::prepare(Item ***rref_pointer_array, { Item *item= *ord->item; /* - Disregard sort order if there's only "{VAR}CHAR(0) NOT NULL" fields - there. Such fields don't contain any data to sort. + Disregard sort order if there's only + zero length NOT NULL fields (e.g. {VAR}CHAR(0) NOT NULL") or + zero length NOT NULL string functions there. + Such tuples don't contain any data to sort. */ if (!real_order && - (item->type() != Item::FIELD_ITEM || - ((Item_field *) item)->field->maybe_null() || - ((Item_field *) item)->field->sort_length())) + /* Not a zero length NOT NULL field */ + ((item->type() != Item::FIELD_ITEM || + ((Item_field *) item)->field->maybe_null() || + ((Item_field *) item)->field->sort_length()) && + /* AND not a zero length NOT NULL string function. */ + (item->type() != Item::FUNC_ITEM || + item->maybe_null || + item->result_type() != STRING_RESULT || + item->max_length))) real_order= TRUE; if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) From 0d7eb317b54b192077d390b54ce294a10b22147e Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 24 Jun 2010 12:31:01 +0400 Subject: [PATCH 188/207] Accidentally pushed test changes (#54459) removed. --- mysql-test/t/select.test | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 37f3675780b..a0c7a96efd9 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4087,9 +4087,4 @@ EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; DROP TABLE t1; -create table t1(a enum('a'))engine=myisam charset=latin1; -insert into t1 values (''),(''),(''),(NULL); -select a, substr(a, 0, 0) from t1 order by substr(a, 0, 0); -select a, a collate latin1_german2_ci from t1 order by a collate latin1_german2_ci; - --echo End of 5.1 tests From dac59fa9c3dab835872b9e9581ed5414d113e09e Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 24 Jun 2010 15:21:23 +0200 Subject: [PATCH 189/207] Bug#41660: Sort-index_merge for non-first join table may require O(#scans) memory When an index merge operation was restarted, it would re-allocate the Unique object controlling the duplicate row ID elimination. Fixed by making the Unique object a member of QUICK_INDEX_MERGE_SELECT and thus reusing it throughout the lifetime of this object. --- mysql-test/r/error_simulation.result | 35 ++++++++++++++++++++++++++ mysql-test/t/error_simulation.test | 29 ++++++++++++++++++++++ sql/opt_range.cc | 37 ++++++++++++++-------------- sql/opt_range.h | 3 ++- sql/sql_class.h | 3 +++ 5 files changed, 88 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result index fc58687cc86..b6b79cb596b 100644 --- a/mysql-test/r/error_simulation.result +++ b/mysql-test/r/error_simulation.result @@ -48,5 +48,40 @@ Got one of the listed errors SET SESSION debug=DEFAULT; DROP TABLE t1; # +# Bug#41660: Sort-index_merge for non-first join table may require +# O(#scans) memory +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +CREATE TABLE t2 (a INT, b INT, filler CHAR(100), KEY(a), KEY(b)); +INSERT INTO t2 SELECT 1000, 1000, 'filler' FROM t1 A, t1 B, t1 C; +INSERT INTO t2 VALUES (1, 1, 'data'); +# the example query uses LEFT JOIN only for the sake of being able to +# demonstrate the issue with a very small dataset. (left outer join +# disables the use of join buffering, so we get the second table +# re-scanned for every record in the outer table. if we used inner join, +# we would need to have thousands of records and/or more columns in both +# tables so that the join buffer is filled and re-scans are triggered). +SET SESSION debug = '+d,only_one_Unique_may_be_created'; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 ); +id select_type table type possible_keys key key_len ref rows Extra +x x x x x x x x x +x x x x x x x x x Using sort_union(a,b); Using where +SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 ); +a a b filler +0 1 1 data +1 1 1 data +2 1 1 data +3 1 1 data +4 1 1 data +5 1 1 data +6 1 1 data +7 1 1 data +8 1 1 data +9 1 1 data +SET SESSION debug = DEFAULT; +DROP TABLE t1, t2; +# # End of 5.1 tests # diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test index 7a48a2e3231..8e65c338f36 100644 --- a/mysql-test/t/error_simulation.test +++ b/mysql-test/t/error_simulation.test @@ -45,6 +45,35 @@ SHOW CREATE TABLE t1; SELECT * FROM t1; DROP TABLE t1; +-- echo # +-- echo # Bug#41660: Sort-index_merge for non-first join table may require +-- echo # O(#scans) memory +-- echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); + +CREATE TABLE t2 (a INT, b INT, filler CHAR(100), KEY(a), KEY(b)); +INSERT INTO t2 SELECT 1000, 1000, 'filler' FROM t1 A, t1 B, t1 C; +INSERT INTO t2 VALUES (1, 1, 'data'); + +--echo # the example query uses LEFT JOIN only for the sake of being able to +--echo # demonstrate the issue with a very small dataset. (left outer join +--echo # disables the use of join buffering, so we get the second table +--echo # re-scanned for every record in the outer table. if we used inner join, +--echo # we would need to have thousands of records and/or more columns in both +--echo # tables so that the join buffer is filled and re-scans are triggered). + +SET SESSION debug = '+d,only_one_Unique_may_be_created'; + +--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 ); +SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 ); + +SET SESSION debug = DEFAULT; + +DROP TABLE t1, t2; --echo # --echo # Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2f4281d539f..f2f14a2dcc9 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1194,7 +1194,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT() QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param, TABLE *table) - :pk_quick_select(NULL), thd(thd_param) + :unique(NULL), pk_quick_select(NULL), thd(thd_param) { DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT"); index= MAX_KEY; @@ -1236,6 +1236,7 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() List_iterator_fast quick_it(quick_selects); QUICK_RANGE_SELECT* quick; DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT"); + delete unique; quick_it.rewind(); while ((quick= quick_it++)) quick->file= NULL; @@ -8153,7 +8154,6 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() List_iterator_fast cur_quick_it(quick_selects); QUICK_RANGE_SELECT* cur_quick; int result; - Unique *unique; handler *file= head->file; DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge"); @@ -8172,9 +8172,22 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); - unique= new Unique(refpos_order_cmp, (void *)file, - file->ref_length, - thd->variables.sortbuff_size); + if (unique == NULL) + { + DBUG_EXECUTE_IF("index_merge_may_not_create_a_Unique", abort(); ); + DBUG_EXECUTE_IF("only_one_Unique_may_be_created", + DBUG_SET("+d,index_merge_may_not_create_a_Unique"); ); + + unique= new Unique(refpos_order_cmp, (void *)file, + file->ref_length, + thd->variables.sortbuff_size); + } + else + unique->reset(); + + DBUG_ASSERT(file->ref_length == unique->get_size()); + DBUG_ASSERT(thd->variables.sortbuff_size == unique->get_max_in_memory_size()); + if (!unique) DBUG_RETURN(1); for (;;) @@ -8189,10 +8202,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (cur_quick->file->inited != handler::NONE) cur_quick->file->ha_index_end(); if (cur_quick->init() || cur_quick->reset()) - { - delete unique; DBUG_RETURN(1); - } } if (result) @@ -8200,17 +8210,13 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (result != HA_ERR_END_OF_FILE) { cur_quick->range_end(); - delete unique; DBUG_RETURN(result); } break; } if (thd->killed) - { - delete unique; DBUG_RETURN(1); - } /* skip row if it will be retrieved by clustered PK scan */ if (pk_quick_select && pk_quick_select->row_in_ranges()) @@ -8219,10 +8225,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() cur_quick->file->position(cur_quick->record); result= unique->unique_add((char*)cur_quick->file->ref); if (result) - { - delete unique; DBUG_RETURN(1); - } } /* @@ -8231,7 +8234,6 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() sequence. */ result= unique->get(head); - delete unique; doing_pk_scan= FALSE; /* index_merge currently doesn't support "using index" at all */ head->set_keyread(FALSE); @@ -10277,7 +10279,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, uint use_index, double read_cost_arg, ha_rows records_arg, uint key_infix_len_arg, uchar *key_infix_arg, MEM_ROOT *parent_alloc) - :join(join_arg), index_info(index_info_arg), + :file(table->file), join(join_arg), index_info(index_info_arg), group_prefix_len(group_prefix_len_arg), group_key_parts(group_key_parts_arg), have_min(have_min_arg), have_max(have_max_arg), seen_first_key(FALSE), @@ -10286,7 +10288,6 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, max_functions_it(NULL) { head= table; - file= head->file; index= use_index; record= head->record[0]; tmp_record= head->record[1]; diff --git a/sql/opt_range.h b/sql/opt_range.h index e7d8297faf8..edae1e4114a 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -500,6 +500,7 @@ public: class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I { + Unique *unique; public: QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table); ~QUICK_INDEX_MERGE_SELECT(); @@ -684,7 +685,7 @@ private: class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I { private: - handler *file; /* The handler used to get data. */ + handler * const file; /* The handler used to get data. */ JOIN *join; /* Descriptor of the current query */ KEY *index_info; /* The index chosen for data access */ uchar *record; /* Buffer where the next record is returned. */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 19a433746e4..4c1d4a98db0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2935,6 +2935,9 @@ public: void reset(); bool walk(tree_walk_action action, void *walk_action_arg); + uint get_size() const { return size; } + ulonglong get_max_in_memory_size() const { return max_in_memory_size; } + friend int unique_write_to_file(uchar* key, element_count count, Unique *unique); friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique); }; From 479d24a2130e629306ce8c2e02bad3b0aa7b57e6 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 24 Jun 2010 21:13:08 +0400 Subject: [PATCH 190/207] Accidentally pushed test changes (#54459) removed. --- mysql-test/t/select.test | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 37f3675780b..db08aad0df0 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4087,9 +4087,5 @@ EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; DROP TABLE t1; -create table t1(a enum('a'))engine=myisam charset=latin1; -insert into t1 values (''),(''),(''),(NULL); -select a, substr(a, 0, 0) from t1 order by substr(a, 0, 0); -select a, a collate latin1_german2_ci from t1 order by a collate latin1_german2_ci; --echo End of 5.1 tests From 700f8add127dbb6f566e95ea1dd682c054d75c9c Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 25 Jun 2010 12:01:47 +0400 Subject: [PATCH 191/207] Bug#54422 query with = 'variables' During creation of the table list of processed tables hidden I_S table 'VARIABLES' is erroneously added into the table list. it leads to ER_UNKNOWN_TABLE error in TABLE_LIST::add_table_to_list() function. The fix is to skip addition of hidden I_S tables into the table list. --- mysql-test/r/information_schema.result | 10 ++++++++++ mysql-test/t/information_schema.test | 9 +++++++++ sql/sql_show.cc | 4 +++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 4ed7e4e700b..b7b65598c6d 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1747,4 +1747,14 @@ COUNT(*) DROP USER nonpriv; DROP TABLE db1.t1; DROP DATABASE db1; + +Bug#54422 query with = 'variables' + +CREATE TABLE variables(f1 INT); +SELECT COLUMN_DEFAULT, TABLE_NAME +FROM INFORMATION_SCHEMA.COLUMNS +WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables'; +COLUMN_DEFAULT TABLE_NAME +NULL variables +DROP TABLE variables; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f3ce3d87252..fa4b880aead 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1445,6 +1445,15 @@ DROP USER nonpriv; DROP TABLE db1.t1; DROP DATABASE db1; +--echo +--echo Bug#54422 query with = 'variables' +--echo + +CREATE TABLE variables(f1 INT); +SELECT COLUMN_DEFAULT, TABLE_NAME +FROM INFORMATION_SCHEMA.COLUMNS +WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables'; +DROP TABLE variables; --echo End of 5.1 tests. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f634c149fd9..33abf356718 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2921,7 +2921,9 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, { if (with_i_schema) { - if (find_schema_table(thd, lookup_field_vals->table_value.str)) + ST_SCHEMA_TABLE *schema_table= + find_schema_table(thd, lookup_field_vals->table_value.str); + if (schema_table && !schema_table->hidden) { if (table_names->push_back(&lookup_field_vals->table_value)) return 1; From 9fa66b6440a8d0642094600b4f23a12eb3500221 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Sat, 26 Jun 2010 19:36:00 +0200 Subject: [PATCH 192/207] Bug #54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER This deadlock happened if DROP DATABASE was blocked due to an open HANDLER table from a different connection. While DROP DATABASE is blocked, it holds the LOCK_mysql_create_db mutex. This results in a deadlock if the connection with the open HANDLER table tries to execute a CREATE/ALTER/DROP DATABASE statement as they all try to acquire LOCK_mysql_create_db. This patch makes this deadlock scenario very unlikely by closing and marking for re-open all HANDLER tables for which there are pending conflicing locks, before LOCK_mysql_create_db is acquired. However, there is still a very slight possibility that a connection could access one of these HANDLER tables between closing/marking for re-open and the acquisition of LOCK_mysql_create_db. This patch is for 5.1 only, a separate and complete fix will be made for 5.5+. Test case added to schema.test. --- mysql-test/r/schema.result | 19 +++++++++++++++ mysql-test/t/schema.test | 47 ++++++++++++++++++++++++++++++++++++++ sql/sql_db.cc | 36 +++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result index 564fb3626df..e6af4e312a3 100644 --- a/mysql-test/r/schema.result +++ b/mysql-test/r/schema.result @@ -11,3 +11,22 @@ mtr mysql test drop schema foo; +# +# Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +INSERT INTO db1.t1 VALUES (1), (2); +# Connection con1 +HANDLER db1.t1 OPEN; +# Connection default +# Sending: +DROP DATABASE db1; +# Connection con2 +# Waiting for 'DROP DATABASE db1' to sync in. +# Connection con1 +CREATE DATABASE db2; +ALTER DATABASE db2 DEFAULT CHARACTER SET utf8; +DROP DATABASE db2; +# Connection default +# Reaping: DROP DATABASE db1 diff --git a/mysql-test/t/schema.test b/mysql-test/t/schema.test index a08d9b38935..a63402bbb83 100644 --- a/mysql-test/t/schema.test +++ b/mysql-test/t/schema.test @@ -4,6 +4,9 @@ # Drop mysqltest1 database, as it can left from the previous tests. # +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + --disable_warnings drop database if exists mysqltest1; --enable_warnings @@ -12,3 +15,47 @@ create schema foo; show create schema foo; show schemas; drop schema foo; + + +--echo # +--echo # Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER +--echo # + +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +INSERT INTO db1.t1 VALUES (1), (2); + +--echo # Connection con1 +connect (con1, localhost, root); +HANDLER db1.t1 OPEN; + +--echo # Connection default +connection default; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection con2 +connect (con2, localhost, root); +--echo # Waiting for 'DROP DATABASE db1' to sync in. +let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist + WHERE state='Waiting for table' AND info='DROP DATABASE db1'; +--source include/wait_condition.inc + +--echo # Connection con1 +connection con1; +# All these statements before resulted in deadlock. +CREATE DATABASE db2; +ALTER DATABASE db2 DEFAULT CHARACTER SET utf8; +DROP DATABASE db2; + +--echo # Connection default +connection default; +--echo # Reaping: DROP DATABASE db1 +--reap +disconnect con1; +disconnect con2; + + +# Check that all connections opened by test cases in this file are really +# gone so execution of other tests won't be affected by their presence. +--source include/wait_until_count_sessions.inc diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 0e65f97e10b..d3435b891b1 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -642,6 +642,18 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, goto exit2; } + /* + Close and mark for re-open all HANDLER tables which are marked for flush + or which there are pending conflicing locks against. This is needed to + prevent deadlocks. + */ + if (thd->handler_tables_hash.records) + { + pthread_mutex_lock(&LOCK_open); + mysql_ha_flush(thd); + pthread_mutex_unlock(&LOCK_open); + } + VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /* Check directory */ @@ -788,6 +800,18 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) if ((error=wait_if_global_read_lock(thd,0,1))) goto exit2; + /* + Close and mark for re-open all HANDLER tables which are marked for flush + or which there are pending conflicing locks against. This is needed to + prevent deadlocks. + */ + if (thd->handler_tables_hash.records) + { + pthread_mutex_lock(&LOCK_open); + mysql_ha_flush(thd); + pthread_mutex_unlock(&LOCK_open); + } + VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /* @@ -886,6 +910,18 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) goto exit2; } + /* + Close and mark for re-open all HANDLER tables which are marked for flush + or which there are pending conflicing locks against. This is needed to + prevent deadlocks. + */ + if (thd->handler_tables_hash.records) + { + pthread_mutex_lock(&LOCK_open); + mysql_ha_flush(thd); + pthread_mutex_unlock(&LOCK_open); + } + VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); From 899a1d694f1086425037388f40e8be80e08039d5 Mon Sep 17 00:00:00 2001 From: Date: Sun, 27 Jun 2010 12:42:06 +0800 Subject: [PATCH 193/207] The following statements support the CURRENT_USER() where a user is needed. DROP USER RENAME USER CURRENT_USER() ... GRANT ... TO CURRENT_USER() REVOKE ... FROM CURRENT_USER() ALTER DEFINER = CURRENT_USER() EVENTbut, When these statements are binlogged, CURRENT_USER() just is binlogged as 'CURRENT_USER()', it is not expanded to the real user name. When slave executes the log event, 'CURRENT_USER()' is expand to the user of slave SQL thread, but SQL thread's user name always NULL. This breaks the replication. After this patch, session's user will be written into query log events if these statements call CURREN_USER() or 'ALTER EVENT' does not assign a definer. --- mysql-test/include/diff_tables.inc | 18 +- mysql-test/include/rpl_diff_tables.inc | 35 +++ .../suite/rpl/r/rpl_current_user.result | 205 +++++++++++++++ .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/t/rpl_current_user.cnf | 9 + mysql-test/suite/rpl/t/rpl_current_user.test | 238 ++++++++++++++++++ sql/log_event.cc | 67 ++++- sql/log_event.h | 7 +- sql/sql_acl.cc | 23 +- sql/sql_class.cc | 1 + sql/sql_class.h | 16 ++ sql/sql_parse.cc | 2 +- 12 files changed, 602 insertions(+), 21 deletions(-) create mode 100644 mysql-test/include/rpl_diff_tables.inc create mode 100644 mysql-test/suite/rpl/r/rpl_current_user.result create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.test diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index d15dd56b35d..e11e69b3023 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -64,17 +64,13 @@ let $_diff_table=$diff_table_2; let $_diff_i=2; while ($_diff_i) { - # Parse out any leading "master:" or "slave:" from the table - # specification and connect the appropriate server. - let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`; - if ($_diff_conn_master) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`; - connection master; - } - let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`; - if ($_diff_conn_slave) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`; - connection slave; + # Parse out any leading "master:" or "slave:" from the table specification +# and connect the appropriate server. + let $_pos= `SELECT LOCATE(':', '$_diff_table')`; + let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; + if (`SELECT "XX$_diff_conn" <> "XX"`) { + let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; + connection $_diff_conn; } # Sanity-check the input. diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc new file mode 100644 index 00000000000..c3a45578a79 --- /dev/null +++ b/mysql-test/include/rpl_diff_tables.inc @@ -0,0 +1,35 @@ +# ############################################################################# +# Check whether the given table is consistent between different master and +# slaves +# +# Usage: +# --let $diff_table= test.t1 +# --let $diff_server_list= master, slave, slave2 +# --source include/rpl_diff_tables.inc +# ############################################################################# + +if (`SELECT "XX$diff_table" = "XX"`) +{ + --die diff_table is null. +} + +--let $_servers= master, slave +if (`SELECT "XX$diff_server_list" <> "XX"`) +{ + --let $_servers= $diff_server_list +} + +--let $_master= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` +--let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_master') + 2))` +connection $_master; +while (`SELECT "XX$_servers" <> "XX"`) +{ + --let $_slave= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` + --let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_slave') + 2))` + + --sync_slave_with_master $_slave + --let $diff_table_1= $_master:$diff_table + --let $diff_table_2= $_slave:$diff_table + --source include/diff_tables.inc + connection $_slave; +} diff --git a/mysql-test/suite/rpl/r/rpl_current_user.result b/mysql-test/suite/rpl/r/rpl_current_user.result new file mode 100644 index 00000000000..85490c2571c --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_current_user.result @@ -0,0 +1,205 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +# On slave2 +# Connect slave2 to slave +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=SLAVE_MYPORT;, +MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; + +# [On master] +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +# bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +# Make sure the max lengths of user and host +# the user name is too lengh +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +ERROR HY000: String '01234567890123456' is too long for user name (should be no longer than 16) +# the host name is too lengh +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; +ERROR HY000: String '0123456789012345678901234567890123456789012345678901234567890' is too long for host name (should be no longer than 60) + +# User 'bug48321_1-01234' connects to master by conn1 +# [On conn1] +# Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ... ON TABLE ...' statement +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'GRANT ... ON PROCEDURE...' statement +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'GRANT ... ON *.* ...' statement +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON TABLE ...' statement +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON PROCEDURE...' statement +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON *.* ...' statement +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ...' statement in the procedure +CREATE PROCEDURE my_grant() +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON TABLE ...' statement in the procedure +CREATE PROCEDURE my_revoke() +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'RENAME USER ...' statement +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'DROP USER ...' statement +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +DROP USER CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'ALTER EVENT...' statement +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; +# Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Session user will be set as definer, if the statement does not assign +# a definer +ALTER EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Verify that this patch does not affect the calling of CURRENT_USER() +# in the other statements +# [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +1234 +# [On slave] +SELECT * FROM t1; +c1 +@ +1234 +# [On slave2] +SELECT * FROM t1; +c1 +@ +1234 +# [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +@ +# [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +# [On slave] +SELECT * FROM t1; +c1 +# [On slave2] +SELECT * FROM t1; +c1 +# [On master] +CREATE TABLE t2(c1 char(100)); +CREATE FUNCTION my_user() RETURNS VARCHAR(64) +SQL SECURITY INVOKER +BEGIN +INSERT INTO t2 VALUES(CURRENT_USER()); +RETURN CURRENT_USER(); +END | +INSERT INTO t1 VALUES(my_user()); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +SELECT * FROM t2; +c1 +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ + +# END +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 26f2545dd72..35f4cd3ecbb 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf new file mode 100644 index 00000000000..999ee727a88 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.cnf @@ -0,0 +1,9 @@ +!include ../my.cnf + +[mysqld.3] +server-id=3 +log-bin=slave-bin + +[ENV] +SLAVE_MYPORT1= @mysqld.3.port +SLAVE_MYSOCK1= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test new file mode 100644 index 00000000000..72581ed7049 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.test @@ -0,0 +1,238 @@ +############################################################################## +# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER, +# REVOKE, GRANT, ALTER EVENT +# +# Calling CURRENT_USER() results into inconsistency between slave and master, +# as the slave SQL thread has different user with common users. +# +# After the patch for bug#48321, session's user will be written into query log +# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT', +# 'ALTER EVENT'. +# +############################################################################## +source include/master-slave.inc; +source include/have_binlog_format_statement.inc; + +--echo +--echo # On slave2 +connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,); +connection slave2; + +--echo # Connect slave2 to slave +--replace_result $SLAVE_MYPORT SLAVE_MYPORT; +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, + MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; +source include/wait_for_slave_to_start.inc; + +--echo +--echo # [On master] +connection master; +--disable_warnings +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +--enable_warnings +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +--echo # bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +--echo +--echo # Make sure the max lengths of user and host +--echo # the user name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +--echo # the host name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; + +--echo +--echo # User 'bug48321_1-01234' connects to master by conn1 +connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,); +connection conn1; +--echo # [On conn1] +--echo # Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +let $diff_table= test.v_user; +let $diff_server_list= master, slave, slave2; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON TABLE ...' statement +connection conn1; +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON PROCEDURE...' statement +connection conn1; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON *.* ...' statement +connection conn1; +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement +connection conn1; +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON PROCEDURE...' statement +connection conn1; +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON *.* ...' statement +connection conn1; +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_grant() + GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_revoke() + REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'RENAME USER ...' statement +connection conn1; +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +disconnect conn1; + +--echo +--echo # Verify 'DROP USER ...' statement +connection master; +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,); +connection conn1; +DROP USER CURRENT_USER(); +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'ALTER EVENT...' statement +connection master; +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; + +--echo # Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +let $diff_table= test.v_event; +source include/rpl_diff_tables.inc; + +connection master; +--echo +--echo # Session user will be set as definer, if the statement does not assign +--echo # a definer +ALTER EVENT e1 ENABLE; +sync_slave_with_master; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify that this patch does not affect the calling of CURRENT_USER() +--echo # in the other statements +connection master; +--echo # [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +--echo # [On slave2] +sync_slave_with_master slave2; +SELECT * FROM t1; + +connection master; +--echo # [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +CREATE TABLE t2(c1 char(100)); + +DELIMITER |; +CREATE FUNCTION my_user() RETURNS VARCHAR(64) + SQL SECURITY INVOKER +BEGIN + INSERT INTO t2 VALUES(CURRENT_USER()); + RETURN CURRENT_USER(); +END | +DELIMITER ;| + +INSERT INTO t1 VALUES(my_user()); +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo # END +connection master; +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; +sync_slave_with_master; +sync_slave_with_master slave2; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index 9c6de5bb42e..cdf059b5e1f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2307,6 +2307,53 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } + if (thd && thd->is_current_user_used()) + { + LEX_STRING user; + LEX_STRING host; + bzero(&user, sizeof(user)); + bzero(&host, sizeof(host)); + + if (thd->slave_thread) + { + /* user will be null, if master is older than this patch */ + user= thd->variables.current_user.user; + host= thd->variables.current_user.host; + } + else if (thd->security_ctx->priv_user) + { + Security_context *ctx= thd->security_ctx; + + user.length= strlen(ctx->priv_user); + user.str= ctx->priv_user; + if (ctx->priv_host[0] != '\0') + { + host.str= ctx->priv_host; + host.length= strlen(ctx->priv_host); + } + } + + if (user.length > 0) + { + *start++= Q_INVOKER; + + /* + Store user length and user. The max length of use is 16, so 1 byte is + enough to store the user's length. + */ + *start++= (uchar)user.length; + memcpy(start, user.str, user.length); + start+= user.length; + + /* + Store host length and host. The max length of host is 60, so 1 byte is + enough to store the host's length. + */ + *start++= (uchar)host.length; + memcpy(start, host.str, host.length); + start+= host.length; + } + } /* NOTE: When adding new status vars, please don't forget to update the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function @@ -2575,6 +2622,8 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, bool catalog_nz= 1; DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); + bzero(&user, sizeof(user)); + bzero(&host, sizeof(host)); common_header_len= description_event->common_header_len; post_header_len= description_event->post_header_len[event_type-1]; DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", @@ -2729,6 +2778,20 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, data_written= master_data_written= uint4korr(pos); pos+= 4; break; + case Q_INVOKER: + { + CHECK_SPACE(pos, end, 1); + user.length= *pos++; + CHECK_SPACE(pos, end, user.length); + user.str= my_strndup((const char *)pos, user.length, MYF(0)); + pos+= user.length; + + CHECK_SPACE(pos, end, 1); + host.length= *pos++; + CHECK_SPACE(pos, end, host.length); + host.str= my_strndup((const char *)pos, host.length, MYF(0)); + pos+= host.length; + } default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -3178,7 +3241,9 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, thd->variables.collation_database= thd->db_charset; thd->table_map_for_update= (table_map)table_map_for_update; - + thd->variables.current_user.user= user; + thd->variables.current_user.host= host; + thd->variables.current_user.password= {0, 0}; /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon); diff --git a/sql/log_event.h b/sql/log_event.h index e3ca4ca3321..816a241e55d 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -264,7 +264,8 @@ struct sql_ex_info 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ 1 + 8 /* type, table_map_for_update */ + \ - 1 + 4 /* type, master_data_written */) + 1 + 4 /* type, master_data_written */ + \ + 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -333,6 +334,8 @@ struct sql_ex_info #define Q_MASTER_DATA_WRITTEN_CODE 10 +#define Q_INVOKER 11 + /* Intvar event post-header */ /* Intvar event data */ @@ -1546,6 +1549,8 @@ protected: */ class Query_log_event: public Log_event { + LEX_STRING user; + LEX_STRING host; protected: Log_event::Byte* data_buf; public: diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index dd256c70ecb..acf14fc91c4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,6 +194,7 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); +static inline void get_grantor(THD *thd, char* grantor); /* Convert scrambled password to binary form, according to scramble type, @@ -2704,6 +2705,20 @@ end: DBUG_RETURN(result); } +static inline void get_grantor(THD *thd, char *grantor) +{ + const char *user= thd->security_ctx->user; + const char *host= thd->security_ctx->host_or_ip; + +#if defined(HAVE_REPLICATION) + if (thd->slave_thread && thd->variables.current_user.user.length > 0) + { + user= thd->variables.current_user.user.str; + host= thd->variables.current_user.host.str; + } +#endif + strxmov(grantor, user, "@", host, NullS); +} static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, TABLE *table, const LEX_USER &combo, @@ -2718,9 +2733,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, uchar user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* The following should always succeed as new users are created before this function is called! @@ -2850,9 +2863,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, DBUG_RETURN(-1); } - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* New users are created before this function is called. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 93aa6a8268c..cd2bb2a51df 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1236,6 +1236,7 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; + clean_current_user_used(); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 4c1d4a98db0..72ffa2e6ba4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -401,6 +401,7 @@ struct system_variables DATE_TIME_FORMAT *datetime_format; DATE_TIME_FORMAT *time_format; my_bool sysdate_is_now; + LEX_USER current_user; }; @@ -2340,6 +2341,19 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); + void set_current_user_used() { current_user_used= TRUE; } + bool is_current_user_used() { return current_user_used; } + void clean_current_user_used() { current_user_used= FALSE; } + void get_definer(LEX_USER *definer) + { + set_current_user_used(); +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + if (slave_thread && variables.current_user.user.length) + *definer= variables.current_user; + else +#endif + get_default_definer(this, definer); + } private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; @@ -2359,6 +2373,8 @@ private: tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; + + bool current_user_used; }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c4d4f2c9d9d..ec9199b33a5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7650,7 +7650,7 @@ LEX_USER *create_default_definer(THD *thd) if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; - get_default_definer(thd, definer); + thd->get_definer(definer); return definer; } From 07767edcce4709b42bae5d3d9ca7be9ceacb95da Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 28 Jun 2010 12:21:28 -0300 Subject: [PATCH 194/207] Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run The problem was that a user could supply supply data in chunks via the COM_STMT_SEND_LONG_DATA command to prepared statement parameter other than of type TEXT or BLOB. This posed a problem since other parameter types aren't setup to handle long data, which would lead to a crash when attempting to use the supplied data. Given that long data can be supplied at any stage of a prepared statement, coupled with the fact that the type of a parameter marker might change between consecutive executions, the solution is to validate at execution time each parameter marker for which a data stream was provided. If the parameter type is not TEXT or BLOB (that is, if the type is not able to handle a data stream), a error is returned. --- sql/sql_prepare.cc | 28 +++++++++++++++++++ tests/mysql_client_test.c | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 06f77f9689c..c2fecd63777 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -674,6 +674,18 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, } #ifndef EMBEDDED_LIBRARY + +/** + Check whether this parameter data type is compatible with long data. + Used to detect whether a long data stream has been supplied to a + incompatible data type. +*/ +inline bool is_param_long_data_type(Item_param *param) +{ + return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) && + (param->param_type <= MYSQL_TYPE_STRING)); +} + /* Routines to assign parameters from data supplied by the client. @@ -737,6 +749,14 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, DBUG_RETURN(1); } } + /* + A long data stream was supplied for this parameter marker. + This was done after prepare, prior to providing a placeholder + type (the types are supplied at execute). Check that the + supplied type of placeholder can accept a data stream. + */ + else if (!is_param_long_data_type(param)) + DBUG_RETURN(1); res= param->query_val_str(&str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -775,6 +795,14 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, DBUG_RETURN(1); } } + /* + A long data stream was supplied for this parameter marker. + This was done after prepare, prior to providing a placeholder + type (the types are supplied at execute). Check that the + supplied type of placeholder can accept a data stream. + */ + else if (is_param_long_data_type(param)) + DBUG_RETURN(1); if (param->convert_str_value(stmt->thd)) DBUG_RETURN(1); /* out of memory */ } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b50c1efe92b..43a418c8300 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16757,6 +16757,63 @@ static void test_bug53907() } +/** + Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run +*/ + +static void test_bug54041() +{ + int rc; + MYSQL_STMT *stmt; + MYSQL_BIND bind; + + DBUG_ENTER("test_bug54041"); + myheader("test_bug54041"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)"); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (a) VALUES (?)"); + check_stmt(stmt); + verify_param_count(stmt, 1); + + memset(&bind, 0, sizeof(bind)); + + /* Any type that does not support long data handling. */ + bind.buffer_type= MYSQL_TYPE_LONG; + + rc= mysql_stmt_bind_param(stmt, &bind); + check_execute(stmt, rc); + + /* + Trick the client API into sending a long data packet for + the parameter. Long data is only supported for string and + binary types. + */ + stmt->params[0].buffer_type= MYSQL_TYPE_STRING; + + rc= mysql_stmt_send_long_data(stmt, 0, "data", 5); + check_execute(stmt, rc); + + /* Undo API violation. */ + stmt->params[0].buffer_type= MYSQL_TYPE_LONG; + + rc= mysql_stmt_execute(stmt); + /* Incorrect arguments. */ + check_execute_r(stmt, rc); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -17062,6 +17119,7 @@ static struct my_tests_st my_tests[]= { { "test_bug45010", test_bug45010 }, { "test_bug53371", test_bug53371 }, { "test_bug53907", test_bug53907 }, + { "test_bug54041", test_bug54041 }, { 0, 0 } }; From 20cc561dfa143c090321b1c656672e5ac5600b5e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 28 Jun 2010 16:20:28 -0300 Subject: [PATCH 195/207] Bug#54457: Test suite broken for 32-bit build The default value of the myisam_max_extra_sort_file_size could be higher than the maximum accepted value, leading to warnings upon the server start. The solution is to simply set the value to the maximum value in a 32-bit built (2147483647, one less than the current). This should be harmless as the option is currently unused in 5.1. --- include/myisam.h | 2 -- sql/mysqld.cc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/myisam.h b/include/myisam.h index 5334fd6afc4..e502daa2f17 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -55,8 +55,6 @@ extern "C" { #define MI_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */ #define MI_NAME_IEXT ".MYI" #define MI_NAME_DEXT ".MYD" -/* Max extra space to use when sorting keys */ -#define MI_MAX_TEMP_LENGTH 2*1024L*1024L*1024L /* Possible values for myisam_block_size (must be power of 2) */ #define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index daa1bbe8ccc..adf9ff19326 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6928,7 +6928,7 @@ thread is in the relay logs.", "It will be removed in MySQL " VER_CELOSIA, &global_system_variables.myisam_max_extra_sort_file_size, &max_system_variables.myisam_max_extra_sort_file_size, - 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH, + 0, GET_ULL, REQUIRED_ARG, (ulonglong) INT_MAX32, 0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0}, {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE, "Don't use the fast sort index method to created index if the temporary " From 1b504ab0b133e81c4e1aec6b948341e885cadadd Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 28 Jun 2010 17:59:41 -0300 Subject: [PATCH 196/207] Revert Bug#48321 due to build breakage and failing tests. --- mysql-test/include/diff_tables.inc | 18 +- mysql-test/include/rpl_diff_tables.inc | 35 --- .../suite/rpl/r/rpl_current_user.result | 205 --------------- .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/t/rpl_current_user.cnf | 9 - mysql-test/suite/rpl/t/rpl_current_user.test | 238 ------------------ sql/log_event.cc | 67 +---- sql/log_event.h | 7 +- sql/sql_acl.cc | 23 +- sql/sql_class.cc | 1 - sql/sql_class.h | 16 -- sql/sql_parse.cc | 2 +- 12 files changed, 21 insertions(+), 602 deletions(-) delete mode 100644 mysql-test/include/rpl_diff_tables.inc delete mode 100644 mysql-test/suite/rpl/r/rpl_current_user.result delete mode 100644 mysql-test/suite/rpl/t/rpl_current_user.cnf delete mode 100644 mysql-test/suite/rpl/t/rpl_current_user.test diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index e11e69b3023..d15dd56b35d 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -64,13 +64,17 @@ let $_diff_table=$diff_table_2; let $_diff_i=2; while ($_diff_i) { - # Parse out any leading "master:" or "slave:" from the table specification -# and connect the appropriate server. - let $_pos= `SELECT LOCATE(':', '$_diff_table')`; - let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; - if (`SELECT "XX$_diff_conn" <> "XX"`) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; - connection $_diff_conn; + # Parse out any leading "master:" or "slave:" from the table + # specification and connect the appropriate server. + let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`; + if ($_diff_conn_master) { + let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`; + connection master; + } + let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`; + if ($_diff_conn_slave) { + let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`; + connection slave; } # Sanity-check the input. diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc deleted file mode 100644 index c3a45578a79..00000000000 --- a/mysql-test/include/rpl_diff_tables.inc +++ /dev/null @@ -1,35 +0,0 @@ -# ############################################################################# -# Check whether the given table is consistent between different master and -# slaves -# -# Usage: -# --let $diff_table= test.t1 -# --let $diff_server_list= master, slave, slave2 -# --source include/rpl_diff_tables.inc -# ############################################################################# - -if (`SELECT "XX$diff_table" = "XX"`) -{ - --die diff_table is null. -} - ---let $_servers= master, slave -if (`SELECT "XX$diff_server_list" <> "XX"`) -{ - --let $_servers= $diff_server_list -} - ---let $_master= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` ---let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_master') + 2))` -connection $_master; -while (`SELECT "XX$_servers" <> "XX"`) -{ - --let $_slave= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` - --let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_slave') + 2))` - - --sync_slave_with_master $_slave - --let $diff_table_1= $_master:$diff_table - --let $diff_table_2= $_slave:$diff_table - --source include/diff_tables.inc - connection $_slave; -} diff --git a/mysql-test/suite/rpl/r/rpl_current_user.result b/mysql-test/suite/rpl/r/rpl_current_user.result deleted file mode 100644 index 85490c2571c..00000000000 --- a/mysql-test/suite/rpl/r/rpl_current_user.result +++ /dev/null @@ -1,205 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; - -# On slave2 -# Connect slave2 to slave -CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=SLAVE_MYPORT;, -MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; -START SLAVE; - -# [On master] -DROP VIEW IF EXISTS v_user; -DROP VIEW IF EXISTS v_tables_priv; -DROP VIEW IF EXISTS v_procs_priv; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS my_grant; -DROP PROCEDURE IF EXISTS my_revoke; -DROP FUNCTION IF EXISTS my_user; -DROP EVENT IF EXISTS e1; -CREATE TABLE t1(c1 char(100)); -CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; -CREATE PROCEDURE p1() SELECT 1; -# bug48321_1-01234 has the max length(16) of user. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; - -# Make sure the max lengths of user and host -# the user name is too lengh -GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; -ERROR HY000: String '01234567890123456' is too long for user name (should be no longer than 16) -# the host name is too lengh -GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; -ERROR HY000: String '0123456789012345678901234567890123456789012345678901234567890' is too long for host name (should be no longer than 60) - -# User 'bug48321_1-01234' connects to master by conn1 -# [On conn1] -# Verify 'REVOKE ALL' statement -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); -Comparing tables master:test.v_user and slave:test.v_user -Comparing tables master:test.v_user and slave2:test.v_user - -# Verify 'GRANT ... ON TABLE ...' statement -GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); -Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv -Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv - -# Verify 'GRANT ... ON PROCEDURE...' statement -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); -Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv -Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv - -# Verify 'GRANT ... ON *.* ...' statement -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; -Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv -Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv - -# Verify 'REVOKE ... ON TABLE ...' statement -REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); -Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv -Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv - -# Verify 'REVOKE ... ON PROCEDURE...' statement -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); -Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv -Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv - -# Verify 'REVOKE ... ON *.* ...' statement -REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); -Comparing tables master:test.v_user and slave:test.v_user -Comparing tables master:test.v_user and slave2:test.v_user - -# Verify 'GRANT ...' statement in the procedure -CREATE PROCEDURE my_grant() -GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); -call my_grant; -Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv -Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv - -# Verify 'REVOKE ... ON TABLE ...' statement in the procedure -CREATE PROCEDURE my_revoke() -REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); -call my_revoke; -Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv -Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv - -# Verify 'RENAME USER ...' statement -RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; -Comparing tables master:test.v_user and slave:test.v_user -Comparing tables master:test.v_user and slave2:test.v_user - -# Verify 'DROP USER ...' statement -GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; -DROP USER CURRENT_USER(); -Comparing tables master:test.v_user and slave:test.v_user -Comparing tables master:test.v_user and slave2:test.v_user - -# Verify 'ALTER EVENT...' statement -CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; -# Explicitly assign CURRENT_USER() to definer -ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; -Comparing tables master:test.v_event and slave:test.v_event -Comparing tables master:test.v_event and slave2:test.v_event - -# Session user will be set as definer, if the statement does not assign -# a definer -ALTER EVENT e1 ENABLE; -Comparing tables master:test.v_event and slave:test.v_event -Comparing tables master:test.v_event and slave2:test.v_event - -# Verify that this patch does not affect the calling of CURRENT_USER() -# in the other statements -# [On master] -INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); -Warnings: -Note 1592 Statement may not be safe to log in statement format. -SELECT * FROM t1; -c1 -root@localhost -1234 -# [On slave] -SELECT * FROM t1; -c1 -@ -1234 -# [On slave2] -SELECT * FROM t1; -c1 -@ -1234 -# [On master] -UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; -Warnings: -Note 1592 Statement may not be safe to log in statement format. -SELECT * FROM t1; -c1 -root@localhost -root@localhost -# [On slave] -SELECT * FROM t1; -c1 -@ -@ -# [On slave2] -SELECT * FROM t1; -c1 -@ -@ -# [On master] -DELETE FROM t1 WHERE c1=CURRENT_USER(); -Warnings: -Note 1592 Statement may not be safe to log in statement format. -SELECT * FROM t1; -c1 -# [On slave] -SELECT * FROM t1; -c1 -# [On slave2] -SELECT * FROM t1; -c1 -# [On master] -CREATE TABLE t2(c1 char(100)); -CREATE FUNCTION my_user() RETURNS VARCHAR(64) -SQL SECURITY INVOKER -BEGIN -INSERT INTO t2 VALUES(CURRENT_USER()); -RETURN CURRENT_USER(); -END | -INSERT INTO t1 VALUES(my_user()); -Warnings: -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -SELECT * FROM t1; -c1 -root@localhost -SELECT * FROM t2; -c1 -root@localhost -# [On slave] -SELECT * FROM t1; -c1 -@ -SELECT * FROM t2; -c1 -@ -# [On slave2] -SELECT * FROM t1; -c1 -@ -SELECT * FROM t2; -c1 -@ - -# END -DROP TABLE t1, t2; -DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; -DROP PROCEDURE p1; -DROP PROCEDURE my_grant; -DROP PROCEDURE my_revoke; -DROP FUNCTION my_user; -DROP EVENT e1; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 35f4cd3ecbb..26f2545dd72 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf deleted file mode 100644 index 999ee727a88..00000000000 --- a/mysql-test/suite/rpl/t/rpl_current_user.cnf +++ /dev/null @@ -1,9 +0,0 @@ -!include ../my.cnf - -[mysqld.3] -server-id=3 -log-bin=slave-bin - -[ENV] -SLAVE_MYPORT1= @mysqld.3.port -SLAVE_MYSOCK1= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test deleted file mode 100644 index 72581ed7049..00000000000 --- a/mysql-test/suite/rpl/t/rpl_current_user.test +++ /dev/null @@ -1,238 +0,0 @@ -############################################################################## -# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER, -# REVOKE, GRANT, ALTER EVENT -# -# Calling CURRENT_USER() results into inconsistency between slave and master, -# as the slave SQL thread has different user with common users. -# -# After the patch for bug#48321, session's user will be written into query log -# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT', -# 'ALTER EVENT'. -# -############################################################################## -source include/master-slave.inc; -source include/have_binlog_format_statement.inc; - ---echo ---echo # On slave2 -connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,); -connection slave2; - ---echo # Connect slave2 to slave ---replace_result $SLAVE_MYPORT SLAVE_MYPORT; -eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, - MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; -START SLAVE; -source include/wait_for_slave_to_start.inc; - ---echo ---echo # [On master] -connection master; ---disable_warnings -DROP VIEW IF EXISTS v_user; -DROP VIEW IF EXISTS v_tables_priv; -DROP VIEW IF EXISTS v_procs_priv; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS my_grant; -DROP PROCEDURE IF EXISTS my_revoke; -DROP FUNCTION IF EXISTS my_user; -DROP EVENT IF EXISTS e1; ---enable_warnings -CREATE TABLE t1(c1 char(100)); -CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; -CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; -CREATE PROCEDURE p1() SELECT 1; ---echo # bug48321_1-01234 has the max length(16) of user. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; - ---echo ---echo # Make sure the max lengths of user and host ---echo # the user name is too lengh ---error 1470 -GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; ---echo # the host name is too lengh ---error 1470 -GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; - ---echo ---echo # User 'bug48321_1-01234' connects to master by conn1 -connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,); -connection conn1; ---echo # [On conn1] ---echo # Verify 'REVOKE ALL' statement -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); -let $diff_table= test.v_user; -let $diff_server_list= master, slave, slave2; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'GRANT ... ON TABLE ...' statement -connection conn1; -GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); -let $diff_table= test.v_tables_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'GRANT ... ON PROCEDURE...' statement -connection conn1; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); -let $diff_table= test.v_procs_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'GRANT ... ON *.* ...' statement -connection conn1; -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'REVOKE ... ON TABLE ...' statement -connection conn1; -REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); -let $diff_table= test.v_tables_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'REVOKE ... ON PROCEDURE...' statement -connection conn1; -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); -let $diff_table= test.v_procs_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'REVOKE ... ON *.* ...' statement -connection conn1; -REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); -let $diff_table= test.v_user; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'GRANT ...' statement in the procedure -connection conn1; -CREATE PROCEDURE my_grant() - GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); -call my_grant; -let $diff_table= test.v_tables_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure -connection conn1; -CREATE PROCEDURE my_revoke() - REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); -call my_revoke; -let $diff_table= test.v_tables_priv; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'RENAME USER ...' statement -connection conn1; -RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; -let $diff_table= test.v_user; -source include/rpl_diff_tables.inc; - -disconnect conn1; - ---echo ---echo # Verify 'DROP USER ...' statement -connection master; -GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; -connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,); -connection conn1; -DROP USER CURRENT_USER(); -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify 'ALTER EVENT...' statement -connection master; -CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; - ---echo # Explicitly assign CURRENT_USER() to definer -ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; -let $diff_table= test.v_event; -source include/rpl_diff_tables.inc; - -connection master; ---echo ---echo # Session user will be set as definer, if the statement does not assign ---echo # a definer -ALTER EVENT e1 ENABLE; -sync_slave_with_master; -source include/rpl_diff_tables.inc; - ---echo ---echo # Verify that this patch does not affect the calling of CURRENT_USER() ---echo # in the other statements -connection master; ---echo # [On master] -INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); -SELECT * FROM t1; -sync_slave_with_master; ---echo # [On slave] -SELECT * FROM t1; ---echo # [On slave2] -sync_slave_with_master slave2; -SELECT * FROM t1; - -connection master; ---echo # [On master] -UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; -SELECT * FROM t1; -sync_slave_with_master; ---echo # [On slave] -SELECT * FROM t1; -sync_slave_with_master slave2; ---echo # [On slave2] -SELECT * FROM t1; - -connection master; ---echo # [On master] -DELETE FROM t1 WHERE c1=CURRENT_USER(); -SELECT * FROM t1; -sync_slave_with_master; ---echo # [On slave] -SELECT * FROM t1; -sync_slave_with_master slave2; ---echo # [On slave2] -SELECT * FROM t1; - -connection master; ---echo # [On master] -CREATE TABLE t2(c1 char(100)); - -DELIMITER |; -CREATE FUNCTION my_user() RETURNS VARCHAR(64) - SQL SECURITY INVOKER -BEGIN - INSERT INTO t2 VALUES(CURRENT_USER()); - RETURN CURRENT_USER(); -END | -DELIMITER ;| - -INSERT INTO t1 VALUES(my_user()); -SELECT * FROM t1; -SELECT * FROM t2; -sync_slave_with_master; ---echo # [On slave] -SELECT * FROM t1; -SELECT * FROM t2; -sync_slave_with_master slave2; ---echo # [On slave2] -SELECT * FROM t1; -SELECT * FROM t2; - ---echo ---echo # END -connection master; -DROP TABLE t1, t2; -DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; -DROP PROCEDURE p1; -DROP PROCEDURE my_grant; -DROP PROCEDURE my_revoke; -DROP FUNCTION my_user; -DROP EVENT e1; -sync_slave_with_master; -sync_slave_with_master slave2; -source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index c5bbe324ae8..5ff4b50c6df 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2307,53 +2307,6 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } - if (thd && thd->is_current_user_used()) - { - LEX_STRING user; - LEX_STRING host; - bzero(&user, sizeof(user)); - bzero(&host, sizeof(host)); - - if (thd->slave_thread) - { - /* user will be null, if master is older than this patch */ - user= thd->variables.current_user.user; - host= thd->variables.current_user.host; - } - else if (thd->security_ctx->priv_user) - { - Security_context *ctx= thd->security_ctx; - - user.length= strlen(ctx->priv_user); - user.str= ctx->priv_user; - if (ctx->priv_host[0] != '\0') - { - host.str= ctx->priv_host; - host.length= strlen(ctx->priv_host); - } - } - - if (user.length > 0) - { - *start++= Q_INVOKER; - - /* - Store user length and user. The max length of use is 16, so 1 byte is - enough to store the user's length. - */ - *start++= (uchar)user.length; - memcpy(start, user.str, user.length); - start+= user.length; - - /* - Store host length and host. The max length of host is 60, so 1 byte is - enough to store the host's length. - */ - *start++= (uchar)host.length; - memcpy(start, host.str, host.length); - start+= host.length; - } - } /* NOTE: When adding new status vars, please don't forget to update the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function @@ -2622,8 +2575,6 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, bool catalog_nz= 1; DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); - bzero(&user, sizeof(user)); - bzero(&host, sizeof(host)); common_header_len= description_event->common_header_len; post_header_len= description_event->post_header_len[event_type-1]; DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", @@ -2778,20 +2729,6 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, data_written= master_data_written= uint4korr(pos); pos+= 4; break; - case Q_INVOKER: - { - CHECK_SPACE(pos, end, 1); - user.length= *pos++; - CHECK_SPACE(pos, end, user.length); - user.str= my_strndup((const char *)pos, user.length, MYF(0)); - pos+= user.length; - - CHECK_SPACE(pos, end, 1); - host.length= *pos++; - CHECK_SPACE(pos, end, host.length); - host.str= my_strndup((const char *)pos, host.length, MYF(0)); - pos+= host.length; - } default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -3241,9 +3178,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, thd->variables.collation_database= thd->db_charset; thd->table_map_for_update= (table_map)table_map_for_update; - thd->variables.current_user.user= user; - thd->variables.current_user.host= host; - thd->variables.current_user.password= {0, 0}; + /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon); diff --git a/sql/log_event.h b/sql/log_event.h index 816a241e55d..e3ca4ca3321 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -264,8 +264,7 @@ struct sql_ex_info 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ 1 + 8 /* type, table_map_for_update */ + \ - 1 + 4 /* type, master_data_written */ + \ - 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */) + 1 + 4 /* type, master_data_written */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -334,8 +333,6 @@ struct sql_ex_info #define Q_MASTER_DATA_WRITTEN_CODE 10 -#define Q_INVOKER 11 - /* Intvar event post-header */ /* Intvar event data */ @@ -1549,8 +1546,6 @@ protected: */ class Query_log_event: public Log_event { - LEX_STRING user; - LEX_STRING host; protected: Log_event::Byte* data_buf; public: diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index acf14fc91c4..dd256c70ecb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,7 +194,6 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); -static inline void get_grantor(THD *thd, char* grantor); /* Convert scrambled password to binary form, according to scramble type, @@ -2705,20 +2704,6 @@ end: DBUG_RETURN(result); } -static inline void get_grantor(THD *thd, char *grantor) -{ - const char *user= thd->security_ctx->user; - const char *host= thd->security_ctx->host_or_ip; - -#if defined(HAVE_REPLICATION) - if (thd->slave_thread && thd->variables.current_user.user.length > 0) - { - user= thd->variables.current_user.user.str; - host= thd->variables.current_user.host.str; - } -#endif - strxmov(grantor, user, "@", host, NullS); -} static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, TABLE *table, const LEX_USER &combo, @@ -2733,7 +2718,9 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, uchar user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); - get_grantor(thd, grantor); + strxmov(grantor, thd->security_ctx->user, "@", + thd->security_ctx->host_or_ip, NullS); + /* The following should always succeed as new users are created before this function is called! @@ -2863,7 +2850,9 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, DBUG_RETURN(-1); } - get_grantor(thd, grantor); + strxmov(grantor, thd->security_ctx->user, "@", + thd->security_ctx->host_or_ip, NullS); + /* New users are created before this function is called. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cd2bb2a51df..93aa6a8268c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1236,7 +1236,6 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; - clean_current_user_used(); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 72ffa2e6ba4..4c1d4a98db0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -401,7 +401,6 @@ struct system_variables DATE_TIME_FORMAT *datetime_format; DATE_TIME_FORMAT *time_format; my_bool sysdate_is_now; - LEX_USER current_user; }; @@ -2341,19 +2340,6 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); - void set_current_user_used() { current_user_used= TRUE; } - bool is_current_user_used() { return current_user_used; } - void clean_current_user_used() { current_user_used= FALSE; } - void get_definer(LEX_USER *definer) - { - set_current_user_used(); -#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) - if (slave_thread && variables.current_user.user.length) - *definer= variables.current_user; - else -#endif - get_default_definer(this, definer); - } private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; @@ -2373,8 +2359,6 @@ private: tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; - - bool current_user_used; }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f3d29ffec0..ed2c76fdcb8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7654,7 +7654,7 @@ LEX_USER *create_default_definer(THD *thd) if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; - thd->get_definer(definer); + get_default_definer(thd, definer); return definer; } From 8a2f3f4b5ed8778c00b6ad169aaad28a4eb6058c Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 29 Jun 2010 10:28:17 +0200 Subject: [PATCH 197/207] Fix of bad merge of test case for Bug#41660 (test case moved). --- mysql-test/t/error_simulation.test | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test index 8e65c338f36..f6edacfaa29 100644 --- a/mysql-test/t/error_simulation.test +++ b/mysql-test/t/error_simulation.test @@ -45,6 +45,20 @@ SHOW CREATE TABLE t1; SELECT * FROM t1; DROP TABLE t1; +--echo # +--echo # Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string +--echo # + +CREATE TABLE t1(a BLOB); + +SET SESSION debug="+d,bug42064_simulate_oom"; +# May fail with either ER_OUT_OF_RESOURCES or EE_OUTOFMEMORY +--error ER_OUT_OF_RESOURCES, 5 +INSERT INTO t1 VALUES(""); +SET SESSION debug=DEFAULT; + +DROP TABLE t1; + -- echo # -- echo # Bug#41660: Sort-index_merge for non-first join table may require -- echo # O(#scans) memory @@ -75,20 +89,6 @@ SET SESSION debug = DEFAULT; DROP TABLE t1, t2; ---echo # ---echo # Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string ---echo # - -CREATE TABLE t1(a BLOB); - -SET SESSION debug="+d,bug42064_simulate_oom"; -# May fail with either ER_OUT_OF_RESOURCES or EE_OUTOFMEMORY ---error ER_OUT_OF_RESOURCES, 5 -INSERT INTO t1 VALUES(""); -SET SESSION debug=DEFAULT; - -DROP TABLE t1; - --echo # --echo # End of 5.1 tests --echo # From 3b3983a4083eab3b86c1817f61be9f7471b8f1b5 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 30 Jun 2010 11:16:06 +0200 Subject: [PATCH 198/207] Bug #53899 Wrong mysql_stmt_errno() after connection loss with automatic reconnect A client with automatic reconnect enabled will see the error message "Lost connection to MySQL server during query" if the connection is lost between mysql_stmt_prepare() and mysql_stmt_execute(). The mysql_stmt_errno() number, however, is 0 -- not the corresponding value 2013. This patch checks for the case where the prepared statement has been pruned due to a connection loss (i.e., stmt->mysql has been set to NULL) during a call to cli_advanced_command(), and avoids changing the last_errno to the result of the last reconnect attempt. --- libmysql/libmysql.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6ea777a0702..0ba85c1ac07 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2495,7 +2495,12 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) stmt->insert_id= mysql->insert_id; if (res) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -2706,7 +2711,12 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row) buff, sizeof(buff), (uchar*) 0, 0, 1, stmt)) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); return 1; } if ((*mysql->methods->read_rows_from_cursor)(stmt)) @@ -3387,7 +3397,12 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number, buff, sizeof(buff), (uchar*) data, length, 1, stmt)) { - set_stmt_errmsg(stmt, &mysql->net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, &mysql->net); DBUG_RETURN(1); } } @@ -4823,7 +4838,12 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff), (uchar*) 0, 0, 1, stmt)) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } } From a6220d8279d80f012edd4e76f34220e8c80c25b4 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 30 Jun 2010 17:06:25 +0400 Subject: [PATCH 199/207] Bug#51431 Wrong sort order after import of dump file The problem is that QUICK_SELECT_DESC behaviour depends on used_key_parts value which can be bigger than selected best_key_parts value if an engine supports clustered key. But used_key_parts is overwritten with best_key_parts value that prevents from correct selection of index access method. The fix is to preserve used_key_parts value for further use in QUICK_SELECT_DESC. --- mysql-test/r/innodb_mysql.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/innodb_mysql.test | 30 ++++++++++++++++++++++++++++++ sql/sql_select.cc | 11 ++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 2af3db75adc..e2f28b96f7e 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2455,4 +2455,36 @@ AND f5 = 'abcdefghijklmnopwrst' AND f2 = 1221457 AND f4 = 0 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2 idx2,idx1,PRIMARY 7,60,4 NULL 1 Using intersect(idx2,idx1,PRIMARY); Using where DROP TABLE t1; +# +# Bug#51431 Wrong sort order after import of dump file +# +CREATE TABLE t1 ( +f1 INT(11) NOT NULL, +f2 int(11) NOT NULL, +f3 int(11) NOT NULL, +f4 tinyint(1) NOT NULL, +PRIMARY KEY (f1), +UNIQUE KEY (f2, f3), +KEY (f4) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,1,991,1), (2,1,992,1), (3,1,993,1), (4,1,994,1), (5,1,995,1), +(6,1,996,1), (7,1,997,1), (8,1,998,1), (10,1,999,1), (11,1,9910,1), +(16,1,9911,1), (17,1,9912,1), (18,1,9913,1), (19,1,9914,1), (20,1,9915,1), +(21,1,9916,1), (22,1,9917,1), (23,1,9918,1), (24,1,9919,1), (25,1,9920,1), +(26,1,9921,1), (27,1,9922,1); +FLUSH TABLES; +SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +f1 f2 f3 f4 +27 1 9922 1 +26 1 9921 1 +25 1 9920 1 +24 1 9919 1 +23 1 9918 1 +EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 47135578697..72795392e50 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -694,4 +694,34 @@ AND f5 = 'abcdefghijklmnopwrst' AND f2 = 1221457 AND f4 = 0 ; DROP TABLE t1; +--echo # +--echo # Bug#51431 Wrong sort order after import of dump file +--echo # + +CREATE TABLE t1 ( + f1 INT(11) NOT NULL, + f2 int(11) NOT NULL, + f3 int(11) NOT NULL, + f4 tinyint(1) NOT NULL, + PRIMARY KEY (f1), + UNIQUE KEY (f2, f3), + KEY (f4) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +(1,1,991,1), (2,1,992,1), (3,1,993,1), (4,1,994,1), (5,1,995,1), +(6,1,996,1), (7,1,997,1), (8,1,998,1), (10,1,999,1), (11,1,9910,1), +(16,1,9911,1), (17,1,9912,1), (18,1,9913,1), (19,1,9914,1), (20,1,9915,1), +(21,1,9916,1), (22,1,9917,1), (23,1,9918,1), (24,1,9919,1), (25,1,9920,1), +(26,1,9921,1), (27,1,9922,1); + +FLUSH TABLES; + +SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b61f7d1eb37..b20726fc151 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13419,6 +13419,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, uint nr; key_map keys; uint best_key_parts= 0; + uint saved_best_key_parts= 0; int best_key_direction= 0; ha_rows best_records= 0; double read_time; @@ -13579,6 +13580,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, { best_key= nr; best_key_parts= keyinfo->key_parts; + saved_best_key_parts= used_key_parts; best_records= quick_records; is_best_covering= is_covering; best_key_direction= direction; @@ -13665,8 +13667,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ } } - used_key_parts= best_key_parts; order_direction= best_key_direction; + /* + saved_best_key_parts is actual number of used keyparts found by the + test_if_order_by_key function. It could differ from keyinfo->key_parts, + thus we have to restore it in case of desc order as it affects + QUICK_SELECT_DESC behaviour. + */ + used_key_parts= (order_direction == -1) ? + saved_best_key_parts : best_key_parts; } else DBUG_RETURN(0); From ac89d92625a0ebf7ba70de0412b38e5cefdf2dda Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 1 Jul 2010 12:02:00 +0400 Subject: [PATCH 200/207] Bug#54667: Unnecessary signal handler redefinition POSIX requires that a signal handler defined with sigaction() is not reset on delivering a signal unless SA_NODEFER or SA_RESETHAND is set. It is therefore unnecessary to redefine the handler on signal delivery on platforms where sigaction() is used without those flags. --- include/my_alarm.h | 4 ++-- include/my_global.h | 4 ++-- libmysql/libmysql.c | 2 +- mysys/thr_alarm.c | 10 +++++----- sql/mysqld.cc | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/my_alarm.h b/include/my_alarm.h index 750135d64ed..c41c1d65e27 100644 --- a/include/my_alarm.h +++ b/include/my_alarm.h @@ -36,14 +36,14 @@ extern ulong my_time_to_wait_for_lock; #define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \ VOID(alarm(alarm_old)); #define ALARM_TEST my_have_got_alarm -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY #define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \ VOID(signal(SIGALRM,my_set_alarm_variable));\ my_have_got_alarm=0; #else #define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \ my_have_got_alarm=0; -#endif /* DONT_REMEMBER_SIGNAL */ +#endif /* SIGNAL_HANDLER_RESET_ON_DELIVERY */ #else #define ALARM_VARIABLES long alarm_pos=0,alarm_end_pos=MY_HOW_OFTEN_TO_WRITE-1 #define ALARM_INIT diff --git a/include/my_global.h b/include/my_global.h index e284acce186..e13c7c37b62 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -541,8 +541,8 @@ extern "C" int madvise(void *addr, size_t len, int behav); #endif /* Does the system remember a signal handler after a signal ? */ -#ifndef HAVE_BSD_SIGNALS -#define DONT_REMEMBER_SIGNAL +#if !defined(HAVE_BSD_SIGNALS) && !defined(HAVE_SIGACTION) +#define SIGNAL_HANDLER_RESET_ON_DELIVERY #endif /* Define void to stop lint from generating "null effekt" comments */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6ea777a0702..cfbeb99508f 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -328,7 +328,7 @@ sig_handler my_pipe_sig_handler(int sig __attribute__((unused))) { DBUG_PRINT("info",("Hit by signal %d",sig)); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY (void) signal(SIGPIPE, my_pipe_sig_handler); #endif } diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index b710a7eee39..386691be4de 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -306,7 +306,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) #if defined(MAIN) && !defined(__bsdi__) printf("thread_alarm in process_alarm\n"); fflush(stdout); #endif -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */ #endif return; @@ -325,7 +325,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) #endif process_alarm_part2(sig); #ifndef USE_ALARM_THREAD -#if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) +#if defined(SIGNAL_HANDLER_RESET_ON_DELIVERY) && !defined(USE_ONE_SIGNAL_HAND) my_sigset(THR_SERVER_ALARM,process_alarm); #endif pthread_mutex_unlock(&LOCK_alarm); @@ -523,12 +523,12 @@ void thr_alarm_info(ALARM_INFO *info) */ -static sig_handler thread_alarm(int sig) +static sig_handler thread_alarm(int sig __attribute__((unused))) { #ifdef MAIN printf("thread_alarm\n"); fflush(stdout); #endif -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,thread_alarm); /* int. thread system calls */ #endif } @@ -797,7 +797,7 @@ static sig_handler print_signal_warning(int sig) { printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name()); fflush(stdout); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif if (sig == SIGALRM) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index daa1bbe8ccc..cac17889638 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1232,7 +1232,7 @@ extern "C" sig_handler print_signal_warning(int sig) { if (global_system_variables.log_warnings) sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id()); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif #if !defined(__WIN__) && !defined(__NETWARE__) From 93fb8bb23544a4b5b2a4a6e43e1c25d74ca9a6f0 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 2 Jul 2010 15:30:47 -0300 Subject: [PATCH 201/207] Bug#53445: Build with -Wall and fix warnings that it generates Apart strict-aliasing warnings, fix the remaining warnings generated by GCC 4.4.4 -Wall and -Wextra flags. One major source of warnings was the in-house function my_bcmp which (unconventionally) took pointers to unsigned characters as the byte sequences to be compared. Since my_bcmp and bcmp are deprecated functions whose only difference with memcmp is the return value, every use of the function is replaced with memcmp as the special return value wasn't actually being used by any caller. There were also various other warnings, mostly due to type mismatches, missing return values, missing prototypes, dead code (unreachable) and ignored return values. --- BUILD/SETUP.sh | 13 ++-- BUILD/check-cpu | 23 ++++--- client/mysql.cc | 1 - client/mysqltest.cc | 21 +++--- cmd-line-utils/readline/Makefile.am | 2 +- cmd-line-utils/readline/input.c | 2 + configure.in | 2 +- extra/comp_err.c | 6 +- extra/replace.c | 12 ++-- extra/yassl/src/crypto_wrapper.cpp | 5 +- extra/yassl/taocrypt/include/blowfish.hpp | 6 +- extra/yassl/taocrypt/include/runtime.hpp | 16 +---- extra/yassl/taocrypt/src/aes.cpp | 3 +- extra/yassl/taocrypt/src/algebra.cpp | 6 +- extra/yassl/taocrypt/src/blowfish.cpp | 3 +- extra/yassl/taocrypt/src/integer.cpp | 32 +++++---- extra/yassl/taocrypt/src/misc.cpp | 23 ++++--- extra/yassl/taocrypt/src/twofish.cpp | 3 +- extra/yassl/testsuite/test.hpp | 5 ++ include/m_string.h | 21 ------ include/my_bitmap.h | 16 ----- include/my_global.h | 21 ++++-- libmysql/Makefile.shared | 2 +- libmysql/libmysql.c | 1 - mysql-test/lib/My/SafeProcess/safe_process.cc | 2 +- mysys/mf_loadpath.c | 2 +- mysys/mf_pack.c | 12 ++-- mysys/my_bitmap.c | 6 +- mysys/my_gethwaddr.c | 2 +- mysys/my_getopt.c | 14 ++-- mysys/my_handler.c | 1 - mysys/safemalloc.c | 2 +- mysys/thr_lock.c | 3 +- regex/regcomp.c | 1 - sql/field.cc | 8 ++- sql/item.cc | 3 +- sql/item_create.cc | 26 +++----- sql/log.cc | 2 +- sql/log_event.cc | 21 +++--- sql/log_event_old.cc | 6 +- sql/mysqld.cc | 31 +++++---- sql/rpl_rli.cc | 3 +- sql/set_var.cc | 35 +++++----- sql/set_var.h | 2 +- sql/slave.cc | 6 +- sql/sql_base.cc | 6 +- sql/sql_class.h | 15 +++-- sql/sql_repl.cc | 3 +- sql/udf_example.c | 2 + sql/unireg.h | 4 +- storage/heap/hp_hash.c | 4 +- storage/heap/hp_test2.c | 4 +- storage/innobase/os/os0file.c | 3 + storage/myisam/mi_open.c | 2 +- storage/myisam/mi_page.c | 2 +- storage/myisam/mi_search.c | 6 +- storage/myisam/mi_test2.c | 22 +++---- storage/myisam/mi_unique.c | 2 +- storage/myisammrg/ha_myisammrg.cc | 7 +- strings/CMakeLists.txt | 2 +- strings/Makefile.am | 8 +-- strings/bcmp.c | 66 ------------------- strings/ctype-ucs2.c | 6 +- strings/make-ccc | 2 +- strings/str_test.c | 10 +-- strings/xml.c | 8 +-- tests/mysql_client_test.c | 2 +- 67 files changed, 257 insertions(+), 362 deletions(-) delete mode 100644 strings/bcmp.c diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 626f932e045..08ae4de2e23 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -90,22 +90,19 @@ SSL_LIBRARY=--with-ssl if [ "x$warning_mode" != "xpedantic" ]; then # Both C and C++ warnings - warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W" - warnings="$warnings -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare" - warnings="$warnings -Wwrite-strings -Wunused-function -Wunused-label -Wunused-value -Wunused-variable" + warnings="-Wall -Wextra -Wunused -Wwrite-strings" # For more warnings, uncomment the following line -# warnings="$global_warnings -Wshadow" +# warnings="$warnings -Wshadow" # C warnings - c_warnings="$warnings -Wunused-parameter" + c_warnings="$warnings" # C++ warnings - cxx_warnings="$warnings" + cxx_warnings="$warnings -Wno-unused-parameter" # cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo" - cxx_warnings="$cxx_warnings -Wreorder" cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor" # Added unless --with-debug=full - debug_extra_cflags="-O0 -g3 -gdwarf-2" #1 -Wuninitialized" + debug_extra_cflags="-O0 -g3 -gdwarf-2" else warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE" c_warnings="$warnings" diff --git a/BUILD/check-cpu b/BUILD/check-cpu index c0e87a675cb..390ba545405 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -181,14 +181,17 @@ check_cpu () { cc=$CC fi - cc_ver=`$cc --version | sed 1q` - cc_verno=`echo $cc_ver | sed -e 's/^.*(GCC)//g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` - set -- `echo $cc_verno | tr '.' ' '` - cc_major=$1 - cc_minor=$2 - cc_patch=$3 - cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` - + # check if compiler is gcc and dump its version + cc_verno=`$cc -dumpversion 2>/dev/null` + if test "x$?" = "x0" ; then + set -- `echo $cc_verno | tr '.' ' '` + cc_ver="GCC" + cc_major=$1 + cc_minor=$2 + cc_patch=$3 + cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` + fi + case "$cc_ver--$cc_verno" in *GCC*) # different gcc backends (and versions) have different CPU flags @@ -229,7 +232,7 @@ check_cpu () { fi while [ "$cpu_arg" ] ; do printf "testing $cpu_arg ... " >&2 - + # compile check eval "$cc -c $check_cpu_cflags __test.c" 2>/dev/null if test "x$?" = "x0" ; then @@ -243,5 +246,5 @@ check_cpu () { done rm __test.* } - + check_cpu diff --git a/client/mysql.cc b/client/mysql.cc index 14a6ceed51d..edcc72b60bf 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -93,7 +93,6 @@ extern "C" { #endif #endif -#undef bcmp // Fix problem with new readline #if defined(__WIN__) #include #elif !defined(__NETWARE__) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 359de9880e7..6a8d119a7c4 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5780,7 +5780,7 @@ int read_command(struct st_command** command_ptr) (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME|MY_ZEROFILL))) || insert_dynamic(&q_lines, (uchar*) &command)) - die(NullS); + die("Out of memory"); command->type= Q_UNKNOWN; read_command_buf[0]= 0; @@ -6260,7 +6260,7 @@ void init_win_path_patterns() } if (insert_dynamic(&patterns, (uchar*) &p)) - die(NullS); + die("Out of memory"); DBUG_PRINT("info", ("p: %s", p)); while (*p) @@ -9331,8 +9331,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, for (i=1 ; i <= found_sets ; i++) { pos=from[found_set[i-1].table_offset]; - rep_str[i].found= !bcmp((const uchar*) pos, - (const uchar*) "\\^", 3) ? 2 : 1; + rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1; rep_str[i].replace_string=to_array[found_set[i-1].table_offset]; rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos); rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+ @@ -9460,8 +9459,8 @@ void copy_bits(REP_SET *to,REP_SET *from) int cmp_bits(REP_SET *set1,REP_SET *set2) { - return bcmp((uchar*) set1->bits,(uchar*) set2->bits, - sizeof(uint) * set1->size_of_bits); + return memcmp(set1->bits, set2->bits, + sizeof(uint) * set1->size_of_bits); } @@ -9530,17 +9529,15 @@ int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) uint start_at_word(char * pos) { - return (((!bcmp((const uchar*) pos, (const uchar*) "\\b",2) && pos[2]) || - !bcmp((const uchar*) pos, (const uchar*) "\\^", 2)) ? 1 : 0); + return (((!memcmp(pos, "\\b",2) && pos[2]) || + !memcmp(pos, "\\^", 2)) ? 1 : 0); } uint end_of_word(char * pos) { char * end=strend(pos); - return ((end > pos+2 && !bcmp((const uchar*) end-2, - (const uchar*) "\\b", 2)) || - (end >= pos+2 && !bcmp((const uchar*) end-2, - (const uchar*) "\\$",2))) ? 1 : 0; + return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) || + (end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0; } /**************************************************************************** diff --git a/cmd-line-utils/readline/Makefile.am b/cmd-line-utils/readline/Makefile.am index e5f5717858d..e1e9645e238 100644 --- a/cmd-line-utils/readline/Makefile.am +++ b/cmd-line-utils/readline/Makefile.am @@ -31,7 +31,7 @@ noinst_HEADERS = readline.h chardefs.h keymaps.h \ EXTRA_DIST= emacs_keymap.c vi_keymap.c -DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR +DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR -D_GNU_SOURCE=1 # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c index 84c0422059a..af81d9cd3b0 100644 --- a/cmd-line-utils/readline/input.c +++ b/cmd-line-utils/readline/input.c @@ -318,7 +318,9 @@ _rl_input_available () return (_kbhit ()); #endif +#if !defined (HAVE_SELECT) return 0; +#endif } int diff --git a/configure.in b/configure.in index 74e575fad8c..539d597fd07 100644 --- a/configure.in +++ b/configure.in @@ -2102,7 +2102,7 @@ MYSQL_TYPE_QSORT AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF -AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ +AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync fesetround finite fpresetsticky fpsetmask fsync ftruncate \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ diff --git a/extra/comp_err.c b/extra/comp_err.c index bd03f20a755..c02c7ca3d2a 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -639,9 +639,9 @@ static struct message *find_message(struct errors *err, const char *lang, static ha_checksum checksum_format_specifier(const char* msg) { ha_checksum chksum= 0; - const char* p= msg; - const char* start= 0; - int num_format_specifiers= 0; + const uchar* p= (const uchar*) msg; + const uchar* start= NULL; + uint32 num_format_specifiers= 0; while (*p) { diff --git a/extra/replace.c b/extra/replace.c index 9b7695eddcb..fd2d860c212 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -648,7 +648,7 @@ static REPLACE *init_replace(char * *from, char * *to,uint count, for (i=1 ; i <= found_sets ; i++) { pos=from[found_set[i-1].table_offset]; - rep_str[i].found= (my_bool) (!bcmp(pos,"\\^",3) ? 2 : 1); + rep_str[i].found= (my_bool) (!memcmp(pos,"\\^",3) ? 2 : 1); rep_str[i].replace_string=to_array[found_set[i-1].table_offset]; rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos); rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+ @@ -776,8 +776,8 @@ static void copy_bits(REP_SET *to,REP_SET *from) static int cmp_bits(REP_SET *set1,REP_SET *set2) { - return bcmp((uchar*) set1->bits,(uchar*) set2->bits, - sizeof(uint) * set1->size_of_bits); + return memcmp(set1->bits, set2->bits, + sizeof(uint) * set1->size_of_bits); } @@ -849,14 +849,14 @@ static short find_found(FOUND_SET *found_set,uint table_offset, static uint start_at_word(char * pos) { - return (((!bcmp(pos,"\\b",2) && pos[2]) || !bcmp(pos,"\\^",2)) ? 1 : 0); + return (((!memcmp(pos,"\\b",2) && pos[2]) || !memcmp(pos,"\\^",2)) ? 1 : 0); } static uint end_of_word(char * pos) { char * end=strend(pos); - return ((end > pos+2 && !bcmp(end-2,"\\b",2)) || - (end >= pos+2 && !bcmp(end-2,"\\$",2))) ? + return ((end > pos+2 && !memcmp(end-2,"\\b",2)) || + (end >= pos+2 && !memcmp(end-2,"\\$",2))) ? 1 : 0; } diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 28d7f1b5693..b968ec1e6c3 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -953,8 +953,9 @@ x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info) info->set = true; } } - fgets(line,sizeof(line), file); // get blank line - begin = ftell(file); + // get blank line + if (fgets(line, sizeof(line), file)) + begin = ftell(file); } } diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 90d2c014b4c..94bbab7aea8 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -51,7 +51,7 @@ public: enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 }; Blowfish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE), sbox_(pbox_ + ROUNDS + 2) {} #ifdef DO_BLOWFISH_ASM void Process(byte*, const byte*, word32); @@ -62,8 +62,8 @@ private: static const word32 p_init_[ROUNDS + 2]; static const word32 s_init_[4 * 256]; - word32 pbox_[ROUNDS + 2]; - word32 sbox_[4 * 256]; + word32 pbox_[ROUNDS + 2 + 4 * 256]; + word32* sbox_; void crypt_block(const word32 in[2], word32 out[2]) const; void AsmProcess(const byte* in, byte* out) const; diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp index 99bbe3ac8a3..9d12b253dd6 100644 --- a/extra/yassl/taocrypt/include/runtime.hpp +++ b/extra/yassl/taocrypt/include/runtime.hpp @@ -35,10 +35,7 @@ // Handler for pure virtual functions namespace __Crun { - static void pure_error(void) - { - assert("Pure virtual method called." == "Aborted"); - } + void pure_error(void); } // namespace __Crun #endif // __sun @@ -54,16 +51,7 @@ extern "C" { #else #include "kernelc.hpp" #endif - -/* Disallow inline __cxa_pure_virtual() */ -static int __cxa_pure_virtual() __attribute__((noinline, used)); -static int __cxa_pure_virtual() -{ - // oops, pure virtual called! - assert("Pure virtual method called." == "Aborted"); - return 0; -} - + int __cxa_pure_virtual () __attribute__ ((weak)); } // extern "C" #endif // __GNUC__ > 2 diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index b2b42d3dcf0..63eff1d91fc 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -51,7 +51,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_AES_ASM diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index c221ce3d6cb..47a660d5c96 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -186,10 +186,10 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x, struct WindowSlider { - WindowSlider(const Integer &exp, bool fastNegate, + WindowSlider(const Integer &expIn, bool fastNegateIn, unsigned int windowSizeIn=0) - : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn), - windowBegin(0), fastNegate(fastNegate), firstTime(true), + : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), + windowBegin(0), fastNegate(fastNegateIn), firstTime(true), finished(false) { if (windowSize == 0) diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 66ff4d829d7..2097b045278 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -53,7 +53,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_BLOWFISH_ASM diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 85733b88aa9..b054e98bef4 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -283,21 +283,23 @@ DWord() {} word GetHighHalfAsBorrow() const {return 0-halfs_.high;} private: + struct dword_struct + { + #ifdef LITTLE_ENDIAN_ORDER + word low; + word high; + #else + word high; + word low; + #endif + }; + union { #ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE dword whole_; #endif - struct - { - #ifdef LITTLE_ENDIAN_ORDER - word low; - word high; - #else - word high; - word low; - #endif - } halfs_; + struct dword_struct halfs_; }; }; @@ -1214,20 +1216,24 @@ public: #define AS1(x) #x ";" #define AS2(x, y) #x ", " #y ";" #define AddPrologue \ + word res; \ __asm__ __volatile__ \ ( \ "push %%ebx;" /* save this manually, in case of -fPIC */ \ - "mov %2, %%ebx;" \ + "mov %3, %%ebx;" \ ".intel_syntax noprefix;" \ "push ebp;" #define AddEpilogue \ "pop ebp;" \ ".att_syntax prefix;" \ "pop %%ebx;" \ - : \ + "mov %%eax, %0;" \ + : "=g" (res) \ : "c" (C), "d" (A), "m" (B), "S" (N) \ : "%edi", "memory", "cc" \ - ); + ); \ + return res; + #define MulPrologue \ __asm__ __volatile__ \ ( \ diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 402645c93fd..11dd4dc6d66 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -84,12 +84,23 @@ namespace STL = STL_NAMESPACE; } -#if defined(__ICC) || defined(__INTEL_COMPILER) +#ifdef __sun + +// Handler for pure virtual functions +namespace __Crun { + void pure_error() { + assert(!"Aborted: pure virtual method called."); + } +} + +#endif + +#if defined(__ICC) || defined(__INTEL_COMPILER) || (__GNUC__ > 2) extern "C" { int __cxa_pure_virtual() { - assert("Pure virtual method called." == "Aborted"); + assert(!"Aborted: pure virtual method called."); return 0; } @@ -166,14 +177,6 @@ word Crop(word value, unsigned int size) #ifdef TAOCRYPT_X86ASM_AVAILABLE -#ifndef _MSC_VER - static jmp_buf s_env; - static void SigIllHandler(int) - { - longjmp(s_env, 1); - } -#endif - bool HaveCpuId() { diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index 84dd35f9191..71601c08162 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -54,7 +54,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -82,6 +82,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_TWOFISH_ASM diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index c921f8f9c69..970ba5bf367 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -160,6 +160,11 @@ inline void err_sys(const char* msg) } +extern "C" { + static int PasswordCallBack(char*, int, int, void*); +} + + static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) { strncpy(passwd, "12345678", sz); diff --git a/include/m_string.h b/include/m_string.h index b2a1d9ff2f4..d027047f501 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -33,10 +33,6 @@ /* need by my_vsnprintf */ #include -#ifdef _AIX -#undef HAVE_BCMP -#endif - /* This is needed for the definitions of bzero... on solaris */ #if defined(HAVE_STRINGS_H) #include @@ -60,14 +56,6 @@ /* Unixware 7 */ #if !defined(HAVE_BFILL) # define bfill(A,B,C) memset((A),(C),(B)) -# define bmove_align(A,B,C) memcpy((A),(B),(C)) -#endif - -#if !defined(HAVE_BCMP) -# define bcopy(s, d, n) memcpy((d), (s), (n)) -# define bcmp(A,B,C) memcmp((A),(B),(C)) -# define bzero(A,B) memset((A),0,(B)) -# define bmove_align(A,B,C) memcpy((A),(B),(C)) #endif #if defined(__cplusplus) @@ -120,15 +108,6 @@ extern void bfill(uchar *dst,size_t len,pchar fill); extern void bzero(uchar * dst,size_t len); #endif -#if !defined(bcmp) && !defined(HAVE_BCMP) -extern size_t bcmp(const uchar *s1,const uchar *s2,size_t len); -#endif -#ifdef HAVE_purify -extern size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len); -#undef bcmp -#define bcmp(A,B,C) my_bcmp((A),(B),(C)) -#endif /* HAVE_purify */ - #ifndef bmove512 extern void bmove512(uchar *dst,const uchar *src,size_t len); #endif diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 78642df3362..ab69b2d671d 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -159,22 +159,6 @@ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) #define bitmap_set_all(MAP) \ (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) -/** - check, set and clear a bit of interest of an integer. - - If the bit is out of range @retval -1. Otherwise - bit_is_set @return 0 or 1 reflecting the bit is set or not; - bit_do_set @return 1 (bit is set 1) - bit_do_clear @return 0 (bit is cleared to 0) -*/ - -#define bit_is_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - (((I) & (ULL(1) << (B))) == 0 ? 0 : 1) : -1) -#define bit_do_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - ((I) |= (ULL(1) << (B)), 1) : -1) -#define bit_do_clear(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - ((I) &= ~(ULL(1) << (B)), 0) : -1) - #ifdef __cplusplus } #endif diff --git a/include/my_global.h b/include/my_global.h index e13c7c37b62..572df6a584d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -556,22 +556,30 @@ int __void__; #endif #endif /* DONT_DEFINE_VOID */ -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) -#define LINT_INIT(var) var=0 /* No uninitialize-warning */ +/* + Deprecated workaround for false-positive uninitialized variables + warnings. Those should be silenced using tool-specific heuristics. + + Enabled by default for g++ due to the bug referenced below. +*/ +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + (defined(__GNUC__) && defined(__cplusplus)) +#define LINT_INIT(var) var= 0 #else #define LINT_INIT(var) #endif -/* +/* Suppress uninitialized variable warning without generating code. The _cplusplus is a temporary workaround for C++ code pending a fix - for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). + for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). */ -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(__cplusplus) || \ - !defined(__GNUC__) +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + defined(__cplusplus) || !defined(__GNUC__) #define UNINIT_VAR(x) x= 0 #else +/* GCC specific self-initialization which inhibits the warning. */ #define UNINIT_VAR(x) x= x #endif @@ -595,7 +603,6 @@ typedef unsigned short ushort; #define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0) #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0) #define test_all_bits(a,b) (((a) & (b)) == (b)) -#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1)) #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) /* Define some general constants */ diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 3e93b7daf84..39c1975888a 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -38,7 +38,7 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \ strmake.lo strend.lo strtod.lo \ strnlen.lo strfill.lo is_prefix.lo \ int2str.lo str2int.lo strinstr.lo strcont.lo \ - strcend.lo bcmp.lo ctype-latin1.lo \ + strcend.lo ctype-latin1.lo \ bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \ strtoull.lo strtoll.lo llstr.lo my_vsnprintf.lo \ ctype.lo ctype-simple.lo ctype-bin.lo ctype-mb.lo \ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 21cbfaf6dbb..e0cc119bd16 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4425,7 +4425,6 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field) field->max_length= 10; /* 2003-11-11 */ param->skip_result= skip_result_with_length; break; - break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: param->skip_result= skip_result_with_length; diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index 50c433b9b39..1c778362975 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -159,7 +159,7 @@ int main(int argc, char* const argv[] ) signal(SIGCHLD, handle_signal); signal(SIGABRT, handle_abort); - sprintf(safe_process_name, "safe_process[%d]", own_pid); + sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid); message("Started"); diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c index 1df613a1733..b329d103d94 100644 --- a/mysys/mf_loadpath.c +++ b/mysys/mf_loadpath.c @@ -42,7 +42,7 @@ char * my_load_path(char * to, const char *path, if (is_cur) is_cur=2; /* Remove current dir */ if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0))) - VOID(strncat(buff, path+is_cur, FN_REFLEN)); + VOID(strncat(buff, path+is_cur, FN_REFLEN-1)); else VOID(strnmov(buff, path, FN_REFLEN)); /* Return org file name */ } diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 4f7cd90e8aa..86fd61537e7 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -52,7 +52,7 @@ void pack_dirname(char * to, const char *from) buff_length= strlen(buff); d_length= (size_t) (start-to); if ((start == to || - (buff_length == d_length && !bcmp(buff,start,d_length))) && + (buff_length == d_length && !memcmp(buff,start,d_length))) && *start != FN_LIBCHAR && *start) { /* Put current dir before */ bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1); @@ -70,7 +70,7 @@ void pack_dirname(char * to, const char *from) } if (length > 1 && length < d_length) { /* test if /xx/yy -> ~/yy */ - if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR) + if (memcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR) { to[0]=FN_HOMELIB; /* Filename begins with ~ */ (void) strmov_overlapp(to+1,to+length); @@ -80,7 +80,7 @@ void pack_dirname(char * to, const char *from) { /* Test if cwd is ~/... */ if (length > 1 && length < buff_length) { - if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR) + if (memcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR) { buff[0]=FN_HOMELIB; (void) strmov_overlapp(buff+1,buff+length); @@ -166,7 +166,7 @@ size_t cleanup_dirname(register char *to, const char *from) *pos = FN_LIBCHAR; if (*pos == FN_LIBCHAR) { - if ((size_t) (pos-start) > length && bcmp(pos-length,parent,length) == 0) + if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0) { /* If .../../; skip prev */ pos-=length; if (pos != start) @@ -197,7 +197,7 @@ size_t cleanup_dirname(register char *to, const char *from) end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; - if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0) + if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; @@ -206,7 +206,7 @@ size_t cleanup_dirname(register char *to, const char *from) } } else if ((size_t) (pos-start) == length-1 && - !bcmp(start,parent+1,length-1)) + !memcmp(start,parent+1,length-1)) start=pos; /* Starts with "../" */ else if (pos-start > 0 && pos[-1] == FN_LIBCHAR) { diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index e127b2584ae..b7258080337 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -508,10 +508,8 @@ uint bitmap_get_first_set(const MY_BITMAP *map) if (*byte_ptr & (1 << k)) return (i*32) + (j*8) + k; } - DBUG_ASSERT(0); } } - DBUG_ASSERT(0); } } return MY_BIT_NONE; @@ -534,7 +532,7 @@ uint bitmap_get_first(const MY_BITMAP *map) { byte_ptr= (uchar*)data_ptr; for (j=0; ; j++, byte_ptr++) - { + { if (*byte_ptr != 0xFF) { for (k=0; ; k++) @@ -542,10 +540,8 @@ uint bitmap_get_first(const MY_BITMAP *map) if (!(*byte_ptr & (1 << k))) return (i*32) + (j*8) + k; } - DBUG_ASSERT(0); } } - DBUG_ASSERT(0); } } return MY_BIT_NONE; diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c7f138c7337..00e0e90f1e4 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -47,7 +47,7 @@ my_bool my_gethwaddr(uchar *to) uchar *buf, *next, *end, *addr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; - int i, res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; + int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) goto err; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 26b1cc75af0..b0e7175d0b9 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -30,7 +30,7 @@ my_error_reporter my_getopt_error_reporter= &default_reporter; static int findopt(char *optpat, uint length, const struct my_option **opt_res, - char **ffname); + const char **ffname); my_bool getopt_compare_strings(const char *s, const char *t, uint length); @@ -115,8 +115,8 @@ int handle_options(int *argc, char ***argv, uint opt_found, argvpos= 0, length; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; - char **pos, **pos_end, *optend, *UNINIT_VAR(prev_found), - *opt_str, key_name[FN_REFLEN]; + char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN]; + const char *UNINIT_VAR(prev_found); const struct my_option *optp; void *value; int error, i; @@ -225,7 +225,6 @@ int handle_options(int *argc, char ***argv, Find first the right option. Return error in case of an ambiguous, or unknown option */ - LINT_INIT(prev_found); optp= longopts; if (!(opt_found= findopt(opt_str, length, &optp, &prev_found))) { @@ -709,10 +708,10 @@ static int setval(const struct my_option *opts, void *value, char *argument, static int findopt(char *optpat, uint length, const struct my_option **opt_res, - char **ffname) + const char **ffname) { uint count; - struct my_option *opt= (struct my_option *) *opt_res; + const struct my_option *opt= *opt_res; for (count= 0; opt->name; opt++) { @@ -723,8 +722,9 @@ static int findopt(char *optpat, uint length, return 1; if (!count) { + /* We only need to know one prev */ count= 1; - *ffname= (char *) opt->name; /* We only need to know one prev */ + *ffname= opt->name; } else if (strcmp(*ffname, opt->name)) { diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 3bc27b622cb..7aa8177040d 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -269,7 +269,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; - break; } break; case HA_KEYTYPE_INT8: diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 2c72026ab5a..76faa33e804 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -163,7 +163,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH)); } DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", - sf_malloc_max_memory,lineno, filename)); + (ulong) sf_malloc_max_memory, lineno, filename)); DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_SET("-d,simulate_out_of_memory");); if (MyFlags & MY_FAE) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 0e0e93cf220..b925c5588be 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -125,8 +125,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, { THR_LOCK_DATA *data,**prev; uint count=0; - THR_LOCK_OWNER *first_owner; - LINT_INIT(first_owner); + THR_LOCK_OWNER *UNINIT_VAR(first_owner); prev= &list->data; if (list->data) diff --git a/regex/regcomp.c b/regex/regcomp.c index b203d4941e1..8280fbfd6c8 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -690,7 +690,6 @@ register cset *cs; case '-': SETERROR(REG_ERANGE); return; /* NOTE RETURN */ - break; default: c = '\0'; break; diff --git a/sql/field.cc b/sql/field.cc index 7360a013ffb..2229bc19b3c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8691,7 +8691,13 @@ int Field_set::store(longlong nr, bool unsigned_val) { ASSERT_COLUMN_MARKED_FOR_WRITE; int error= 0; - ulonglong max_nr= set_bits(ulonglong, typelib->count); + ulonglong max_nr; + + if (sizeof(ulonglong)*8 <= typelib->count) + max_nr= ULONGLONG_MAX; + else + max_nr= (ULL(1) << typelib->count) - 1; + if ((ulonglong) nr > max_nr) { nr&= max_nr; diff --git a/sql/item.cc b/sql/item.cc index 5f0ca4374df..db2c4c0974b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4130,8 +4130,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) context->first_name_resolution_table, context->last_name_resolution_table, reference, REPORT_ALL_ERRORS, - !any_privileges && - TRUE, TRUE); + !any_privileges, TRUE); } return -1; } diff --git a/sql/item_create.cc b/sql/item_create.cc index fd8f13d6dc5..5726e987ef6 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5051,8 +5051,6 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, CHARSET_INFO *cs) { Item *UNINIT_VAR(res); - ulong len; - uint dec; switch (cast_type) { case ITEM_CAST_BINARY: @@ -5075,11 +5073,10 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, break; case ITEM_CAST_DECIMAL: { - if (c_len == NULL) - { - len= 0; - } - else + ulong len= 0; + uint dec= 0; + + if (c_len) { ulong decoded_size; errno= 0; @@ -5093,11 +5090,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, len= decoded_size; } - if (c_dec == NULL) - { - dec= 0; - } - else + if (c_dec) { ulong decoded_size; errno= 0; @@ -5133,12 +5126,9 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, } case ITEM_CAST_CHAR: { + int len= -1; CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection); - if (c_len == NULL) - { - len= LL(-1); - } - else + if (c_len) { ulong decoded_size; errno= 0; @@ -5148,7 +5138,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH); return NULL; } - len= decoded_size; + len= (int) decoded_size; } res= new (thd->mem_root) Item_char_typecast(a, len, real_cs); break; diff --git a/sql/log.cc b/sql/log.cc index b3554d2a068..d8d5f6fa418 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1862,7 +1862,7 @@ static int find_uniq_filename(char *name) file_info= dir_info->dir_entry; for (i=dir_info->number_off_files ; i-- ; file_info++) { - if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 && + if (memcmp(file_info->name, start, length) == 0 && test_if_number(file_info->name+length, &number,0)) { set_if_bigger(max_found,(ulong) number); diff --git a/sql/log_event.cc b/sql/log_event.cc index 5ff4b50c6df..d53f13e0b6b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2905,7 +2905,7 @@ void Query_log_event::print_query_header(IO_CACHE* file, if (likely(charset_inited) && (unlikely(!print_event_info->charset_inited || - bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6)))) + memcmp(print_event_info->charset, charset, 6)))) { CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME)); if (cs_info) @@ -2928,8 +2928,8 @@ void Query_log_event::print_query_header(IO_CACHE* file, } if (time_zone_len) { - if (bcmp((uchar*) print_event_info->time_zone_str, - (uchar*) time_zone_str, time_zone_len+1)) + if (memcmp(print_event_info->time_zone_str, + time_zone_str, time_zone_len+1)) { my_b_printf(file,"SET @@session.time_zone='%s'%s\n", time_zone_str, print_event_info->delimiter); @@ -7503,8 +7503,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { int actual_error= convert_handler_error(error, thd, table); bool idempotent_error= (idempotent_error_code(error) && - ((bit_is_set(slave_exec_mode, - SLAVE_EXEC_MODE_IDEMPOTENT)) == 1)); + (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT)); bool ignored_error= (idempotent_error == 0 ? ignored_error_code(actual_error) : 0); @@ -8332,7 +8331,7 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability todo: to introduce a property for the event (handler?) which forces applying the event in the replace (idempotent) fashion. */ - if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) || m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) { /* @@ -8411,7 +8410,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability * int local_error= 0; m_table->next_number_field=0; m_table->auto_increment_field_not_null= FALSE; - if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) || m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) { m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); @@ -8514,7 +8513,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, TABLE *table= m_table; // pointer to event's table int error; - int keynum; + int UNINIT_VAR(keynum); auto_afree_ptr key(NULL); /* fill table->record[0] with default values */ @@ -8712,10 +8711,8 @@ int Write_rows_log_event::do_exec_row(const Relay_log_info *const rli) { DBUG_ASSERT(m_table != NULL); - int error= - write_row(rli, /* if 1 then overwrite */ - bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1); - + int error= write_row(rli, (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT)); + if (error && !thd->is_error()) { DBUG_ASSERT(0); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 202b81989a8..e901f44286c 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -441,7 +441,7 @@ copy_extra_record_fields(TABLE *table, DBUG_ASSERT(master_reclength <= table->s->reclength); if (master_reclength < table->s->reclength) - bmove_align(table->record[0] + master_reclength, + memcpy(table->record[0] + master_reclength, table->record[1] + master_reclength, table->s->reclength - master_reclength); @@ -720,7 +720,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) rnd_pos() returns the record in table->record[0], so we have to move it to table->record[1]. */ - bmove_align(table->record[1], table->record[0], table->s->reclength); + memcpy(table->record[1], table->record[0], table->s->reclength); DBUG_RETURN(error); } @@ -1213,7 +1213,7 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) overwriting the default values that where put there by the unpack_row() function. */ - bmove_align(table->record[0], m_after_image, table->s->reclength); + memcpy(table->record[0], m_after_image, table->s->reclength); copy_extra_record_fields(table, m_master_reclength, m_width); /* diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5514c356bd1..99f16b36dfa 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -559,7 +559,7 @@ ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; ulong slave_exec_mode_options; -const char *slave_exec_mode_str= "STRICT"; +static const char *slave_exec_mode_str= "STRICT"; ulong thread_cache_size=0, thread_pool_size= 0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; @@ -2464,7 +2464,6 @@ extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; struct tm tm; - THD *thd=current_thd; /* Strictly speaking, one needs a mutex here @@ -2523,13 +2522,15 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE + THD *thd=current_thd; + if (!(test_flags & TEST_NO_STACKTRACE)) { - fprintf(stderr,"thd: 0x%lx\n",(long) thd); - fprintf(stderr,"\ -Attempting backtrace. You can use the following information to find out\n\ -where mysqld died. If you see no messages after this, something went\n\ -terribly wrong...\n"); + fprintf(stderr, "thd: 0x%lx\n",(long) thd); + fprintf(stderr, "Attempting backtrace. You can use the following " + "information to find out\nwhere mysqld died. If " + "you see no messages after this, something went\n" + "terribly wrong...\n"); my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, my_thread_stack_size); } @@ -7879,10 +7880,11 @@ static int mysql_init_variables(void) /* Things with default values that are not zero */ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; - slave_exec_mode_options= 0; - slave_exec_mode_options= (uint) - find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL, - &error); + slave_exec_mode_options= find_bit_type_or_exit(slave_exec_mode_str, + &slave_exec_mode_typelib, + NULL, &error); + /* Default mode string must not yield a error. */ + DBUG_ASSERT(!error); if (error) return 1; opt_specialflag= SPECIAL_ENGLISH; @@ -8118,8 +8120,9 @@ mysqld_get_one_option(int optid, init_slave_skip_errors(argument); break; case OPT_SLAVE_EXEC_MODE: - slave_exec_mode_options= (uint) - find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error); + slave_exec_mode_options= find_bit_type_or_exit(argument, + &slave_exec_mode_typelib, + "", &error); if (error) return 1; break; @@ -8773,7 +8776,7 @@ static int get_options(int *argc,char **argv) /* Set global MyISAM variables from delay_key_write_options */ fix_delay_key_write((THD*) 0, OPT_GLOBAL); /* Set global slave_exec_mode from its option */ - fix_slave_exec_mode(OPT_GLOBAL); + fix_slave_exec_mode(); #ifndef EMBEDDED_LIBRARY if (mysqld_chroot) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 316e26f7e40..99a42bbe818 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1120,8 +1120,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const { DBUG_ENTER("Relay_log_info::cached_charset_compare"); - if (bcmp((uchar*) cached_charset, (uchar*) charset, - sizeof(cached_charset))) + if (memcmp(cached_charset, charset, sizeof(cached_charset))) { memcpy(const_cast(cached_charset), charset, sizeof(cached_charset)); DBUG_RETURN(1); diff --git a/sql/set_var.cc b/sql/set_var.cc index 241126e1e6f..c5517da92f8 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -92,14 +92,13 @@ TYPELIB delay_key_write_typelib= delay_key_write_type_names, NULL }; -const char *slave_exec_mode_names[]= -{ "STRICT", "IDEMPOTENT", NullS }; -static const unsigned int slave_exec_mode_names_len[]= -{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 }; +static const char *slave_exec_mode_names[]= { "STRICT", "IDEMPOTENT", NullS }; +static unsigned int slave_exec_mode_names_len[]= { sizeof("STRICT") - 1, + sizeof("IDEMPOTENT") - 1, 0 }; TYPELIB slave_exec_mode_typelib= { array_elements(slave_exec_mode_names)-1, "", - slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len + slave_exec_mode_names, slave_exec_mode_names_len }; static int sys_check_ftb_syntax(THD *thd, set_var *var); @@ -1215,16 +1214,14 @@ uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type, void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type) { - slave_exec_mode_options= 0; - bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); + slave_exec_mode_options= SLAVE_EXEC_MODE_STRICT; } bool sys_var_set_slave_mode::check(THD *thd, set_var *var) { bool rc= sys_var_set::check(thd, var); - if (!rc && - bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 && - bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + if (!rc && (var->save_result.ulong_value & SLAVE_EXEC_MODE_STRICT) && + (var->save_result.ulong_value & SLAVE_EXEC_MODE_IDEMPOTENT)) { rc= true; my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), ""); @@ -1241,20 +1238,18 @@ bool sys_var_set_slave_mode::update(THD *thd, set_var *var) return rc; } -void fix_slave_exec_mode(enum_var_type type) +void fix_slave_exec_mode(void) { DBUG_ENTER("fix_slave_exec_mode"); - compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT - > SLAVE_EXEC_MODE_LAST_BIT - 1); - if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 && - bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + + if ((slave_exec_mode_options & SLAVE_EXEC_MODE_STRICT) && + (slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT)) { - sql_print_error("Ambiguous slave modes combination." - " STRICT will be used"); - bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT); + sql_print_error("Ambiguous slave modes combination. STRICT will be used"); + slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT; } - if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0) - bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); + if (!(slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT)) + slave_exec_mode_options|= SLAVE_EXEC_MODE_STRICT; DBUG_VOID_RETURN; } diff --git a/sql/set_var.h b/sql/set_var.h index bc94c6b85c4..68cd94a5670 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -1446,7 +1446,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length=0); int sql_set_variables(THD *thd, List *var_list); bool not_all_support_one_shot(List *var_list); void fix_delay_key_write(THD *thd, enum_var_type type); -void fix_slave_exec_mode(enum_var_type type); +void fix_slave_exec_mode(void); ulong fix_sql_mode(ulong sql_mode); extern sys_var_const_str sys_charset_system; extern sys_var_str sys_init_connect; diff --git a/sql/slave.cc b/sql/slave.cc index af53bc65c0e..795bc481071 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2113,7 +2113,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli) DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu", FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT), FLAGSTR(thd->options, OPTION_BEGIN), - rli->last_event_start_time)); + (ulong) rli->last_event_start_time)); /* Execute the event to change the database and update the binary @@ -2885,8 +2885,8 @@ pthread_handler_t handle_slave_sql(void *arg) char llbuff[22],llbuff1[22]; char saved_log_name[FN_REFLEN]; char saved_master_log_name[FN_REFLEN]; - my_off_t saved_log_pos; - my_off_t saved_master_log_pos; + my_off_t UNINIT_VAR(saved_log_pos); + my_off_t UNINIT_VAR(saved_master_log_pos); my_off_t saved_skip= 0; Relay_log_info* rli = &((Master_info*)arg)->rli; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3a51b5c5610..d2392bdd9b1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8403,15 +8403,15 @@ my_bool mysql_rm_tmp_tables(void) (file->name[1] == '.' && !file->name[2]))) continue; - if (!bcmp((uchar*) file->name, (uchar*) tmp_file_prefix, - tmp_file_prefix_length)) + if (!memcmp(file->name, tmp_file_prefix, + tmp_file_prefix_length)) { char *ext= fn_ext(file->name); uint ext_len= strlen(ext); uint filePath_len= my_snprintf(filePath, sizeof(filePath), "%s%c%s", tmpdir, FN_LIBCHAR, file->name); - if (!bcmp((uchar*) reg_ext, (uchar*) ext, ext_len)) + if (!memcmp(reg_ext, ext, ext_len)) { handler *handler_file= 0; /* We should cut file extention before deleting of table */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 4c1d4a98db0..023367cb747 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -83,9 +83,10 @@ enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE }; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; -enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT, - SLAVE_EXEC_MODE_IDEMPOTENT, - SLAVE_EXEC_MODE_LAST_BIT}; + +#define SLAVE_EXEC_MODE_STRICT (1U << 0) +#define SLAVE_EXEC_MODE_IDEMPOTENT (1U << 1) + enum enum_mark_columns { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE}; @@ -2418,7 +2419,7 @@ class select_result :public Sql_alloc { protected: THD *thd; SELECT_LEX_UNIT *unit; - uint nest_level; + int nest_level; public: select_result(); virtual ~select_result() {}; @@ -2559,7 +2560,7 @@ public: Creates a select_export to represent INTO OUTFILE with a defined level of subquery nesting. */ - select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex) + select_export(sql_exchange *ex, int nest_level_arg) :select_to_file(ex) { nest_level= nest_level_arg; } @@ -2576,7 +2577,7 @@ public: Creates a select_export to represent INTO DUMPFILE with a defined level of subquery nesting. */ - select_dump(sql_exchange *ex, uint nest_level_arg) : + select_dump(sql_exchange *ex, int nest_level_arg) : select_to_file(ex) { nest_level= nest_level_arg; @@ -3046,7 +3047,7 @@ public: Creates a select_dumpvar to represent INTO with a defined level of subquery nesting. */ - select_dumpvar(uint nest_level_arg) + select_dumpvar(int nest_level_arg) { var_list.empty(); row_count= 0; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 75a738a0073..f6045e4704e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -218,8 +218,7 @@ bool log_in_use(const char* log_name) if ((linfo = tmp->current_linfo)) { pthread_mutex_lock(&linfo->lock); - result = !bcmp((uchar*) log_name, (uchar*) linfo->log_file_name, - log_name_len); + result = !memcmp(log_name, linfo->log_file_name, log_name_len); pthread_mutex_unlock(&linfo->lock); if (result) break; diff --git a/sql/udf_example.c b/sql/udf_example.c index 82af58ec502..637293209e0 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -141,7 +141,9 @@ typedef long long longlong; #ifdef HAVE_DLOPEN +#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST) static pthread_mutex_t LOCK_hostname; +#endif /* These must be right or mysqld will not find the symbol! */ diff --git a/sql/unireg.h b/sql/unireg.h index 3ff7f058e3c..4f6b647964d 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -129,8 +129,8 @@ #define SPECIAL_LOG_QUERIES_NOT_USING_INDEXES 4096 /* Obsolete */ /* Extern defines */ -#define store_record(A,B) bmove_align((A)->B,(A)->record[0],(size_t) (A)->s->reclength) -#define restore_record(A,B) bmove_align((A)->record[0],(A)->B,(size_t) (A)->s->reclength) +#define store_record(A,B) memcpy((A)->B,(A)->record[0],(size_t) (A)->s->reclength) +#define restore_record(A,B) memcpy((A)->record[0],(A)->B,(size_t) (A)->s->reclength) #define cmp_record(A,B) memcmp((A)->record[0],(A)->B,(size_t) (A)->s->reclength) #define empty_record(A) { \ restore_record((A),s->default_values); \ diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index aaaa0fe833f..f56df42aab3 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -577,7 +577,7 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, } else { - if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) + if (memcmp(rec1+seg->start,rec2+seg->start,seg->length)) return 1; } } @@ -660,7 +660,7 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) } else { - if (bcmp(rec+seg->start,key,seg->length)) + if (memcmp(rec+seg->start,key,seg->length)) return 1; } } diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 5c548b6be74..bf06cf03035 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -406,7 +406,7 @@ int main(int argc, char *argv[]) bmove(record2,record,reclength); if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2)) goto err; - if (bcmp(record2,record,reclength)) + if (memcmp(record2,record,reclength)) { puts("heap_rsame didn't find right record"); goto end; @@ -415,7 +415,7 @@ int main(int argc, char *argv[]) puts("- Test of read through position"); if (heap_rrnd(file,record,position)) goto err; - if (bcmp(record3,record,reclength)) + if (memcmp(record3,record,reclength)) { puts("heap_frnd didn't find right record"); goto end; diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 7373a97cfb0..3396d1adf2f 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -3974,6 +3974,9 @@ os_aio_simulated_handle( ulint n; ulint i; + /* Fix compiler warning */ + *consecutive_ios = NULL; + segment = os_aio_get_array_and_local_segment(&array, global_segment); restart: diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index f2f390862bd..8ecb07d75e8 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -139,7 +139,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (uchar*) myisam_file_magic, 4)) { DBUG_PRINT("error",("Wrong header in %s",name_buff)); - DBUG_DUMP("error_dump",(char*) share->state.header.file_version, + DBUG_DUMP("error_dump", share->state.header.file_version, head_length); my_errno=HA_ERR_NOT_A_TABLE; goto err; diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c index 76fac8688a7..90e31e72532 100644 --- a/storage/myisam/mi_page.c +++ b/storage/myisam/mi_page.c @@ -49,7 +49,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, { DBUG_PRINT("error",("page %lu had wrong page length: %u", (ulong) page, page_size)); - DBUG_DUMP("page", (char*) tmp, keyinfo->block_length); + DBUG_DUMP("page", tmp, keyinfo->block_length); info->last_keypage = HA_OFFSET_ERROR; mi_print_error(info->s, HA_ERR_CRASHED); my_errno = HA_ERR_CRASHED; diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 95f817e47aa..9c842fba544 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -819,7 +819,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, DBUG_PRINT("error", ("Found too long null packed key: %u of %u at 0x%lx", length, keyseg->length, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; return 0; @@ -876,7 +876,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, { DBUG_PRINT("error",("Found too long packed key: %u of %u at 0x%lx", length, keyseg->length, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; return 0; /* Error */ @@ -948,7 +948,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, DBUG_PRINT("error", ("Found too long binary packed key: %u of %u at 0x%lx", length, keyinfo->maxlength, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; DBUG_RETURN(0); /* Wrong key */ diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 23c58638166..d7c168d01b0 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -415,7 +415,7 @@ int main(int argc, char *argv[]) } ant=0; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys) { printf("prev: Found: %d records of %d\n",ant,dupp_keys); @@ -453,7 +453,7 @@ int main(int argc, char *argv[]) goto end; } if (mi_rlast(file,read_record2,0) || - bcmp(read_record2,read_record3,reclength)) + memcmp(read_record2,read_record3,reclength)) { printf("Can't find last record\n"); DBUG_DUMP("record2",(uchar*) read_record2,reclength); @@ -468,7 +468,7 @@ int main(int argc, char *argv[]) printf("prev: I found: %d records of %d\n",ant,write_count); goto end; } - if (bcmp(read_record,read_record3,reclength)) + if (memcmp(read_record,read_record3,reclength)) { printf("Can't find first record\n"); goto end; @@ -483,7 +483,7 @@ int main(int argc, char *argv[]) mi_rprev(file,read_record3,0) == 0 || mi_rnext(file,read_record3,0)) goto err; - if (bcmp(read_record,read_record3,reclength) != 0) + if (memcmp(read_record,read_record3,reclength) != 0) printf("Can't find first record\n"); if (!silent) @@ -495,7 +495,7 @@ int main(int argc, char *argv[]) mi_rnext(file,read_record3,0) == 0 || mi_rprev(file,read_record3,0)) goto err; - if (bcmp(read_record2,read_record3,reclength)) + if (memcmp(read_record2,read_record3,reclength)) printf("Can't find last record\n"); #ifdef NOT_ANYMORE if (!silent) @@ -509,7 +509,7 @@ int main(int argc, char *argv[]) bzero((char*) file->lastkey,file->s->base.max_key_length*2); if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX)) goto err; - if (bcmp(read_record+start,key,(uint) i)) + if (memcmp(read_record+start,key,(uint) i)) { puts("Didn't find right record"); goto end; @@ -528,7 +528,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=1; while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-1) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1); @@ -546,7 +546,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=1; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-2) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2); @@ -566,7 +566,7 @@ int main(int argc, char *argv[]) if (mi_rnext(file,read_record,0)) goto err; /* Skall finnas poster */ while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-3) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3); @@ -581,7 +581,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=0; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-4) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4); @@ -604,7 +604,7 @@ int main(int argc, char *argv[]) for (i=min(2,keys) ; i-- > 0 ;) { if (mi_rsame(file,read_record2,(int) i)) goto err; - if (bcmp(read_record,read_record2,reclength) != 0) + if (memcmp(read_record,read_record2,reclength) != 0) { printf("is_rsame didn't find same record\n"); goto end; diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c index 02fcd9289dd..fdba84a2e67 100644 --- a/storage/myisam/mi_unique.c +++ b/storage/myisam/mi_unique.c @@ -56,7 +56,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, uchar *record, if (_mi_search_next(info,info->s->keyinfo+def->key, info->lastkey, MI_UNIQUE_HASH_LENGTH, SEARCH_BIGGER, info->s->state.key_root[def->key]) || - bcmp((char*) info->lastkey, (char*) key_buff, MI_UNIQUE_HASH_LENGTH)) + memcmp(info->lastkey, key_buff, MI_UNIQUE_HASH_LENGTH)) { info->page_changed=1; /* Can't optimize read next */ info->lastpos=lastpos; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 7886cc2a5a2..8e18924c5b8 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -293,8 +293,9 @@ static int myisammrg_parent_open_callback(void *callback_param, } } - DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", child_l->db_length, child_l->db, - child_l->table_name_length, child_l->table_name)); + DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int) child_l->db_length, + child_l->db, (int) child_l->table_name_length, + child_l->table_name)); /* Convert to lowercase if required. */ if (lower_case_table_names && child_l->table_name_length) @@ -341,7 +342,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) TABLE *parent; TABLE *child; TABLE_LIST *child_l; - MI_INFO *myisam; + MI_INFO *UNINIT_VAR(myisam); DBUG_ENTER("myisammrg_attach_children_callback"); my_errno= 0; diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt index 3d9de566670..67e8ad22783 100755 --- a/strings/CMakeLists.txt +++ b/strings/CMakeLists.txt @@ -18,7 +18,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUT INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) -SET(STRINGS_SOURCES bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c +SET(STRINGS_SOURCES bchange.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c ctype-czech.c ctype-euc_kr.c ctype-eucjpms.c ctype-extra.c ctype-gb2312.c ctype-gbk.c ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c int2str.c diff --git a/strings/Makefile.am b/strings/Makefile.am index db9016b7148..1303af91820 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -21,19 +21,19 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov.c else #no assembler ASRCS = # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile -CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c +CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c endif endif @@ -57,7 +57,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc CHARSET_INFO.txt libmystrings_a_LIBADD= -conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c +conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c conf_to_src_LDADD= #force static linking of conf_to_src - essential when linking against #custom installation of libc diff --git a/strings/bcmp.c b/strings/bcmp.c deleted file mode 100644 index 1b6ed22fc22..00000000000 --- a/strings/bcmp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are - identical to the "len" bytes starting at "s2", non-zero if they are - different. - Now only used with purify because purify gives wrong warnings when - comparing a shorter string with bcmp. -*/ - -#include -#include "m_string.h" - -#ifdef HAVE_purify -#undef bcmp -#undef HAVE_BCMP -#endif - -#if !defined(bcmp) && !defined(HAVE_BCMP) - -#if defined(MC68000) && defined(DS90) - -int bcmp(s1,s2, len) -const char *s1; -const char *s2; -uint len; /* 0 <= len <= 65535 */ -{ - asm(" movl 12(a7),d0 "); - asm(" subqw #1,d0 "); - asm(" blt .L5 "); - asm(" movl 4(a7),a1 "); - asm(" movl 8(a7),a0 "); - asm(".L4: cmpmb (a0)+,(a1)+ "); - asm(" dbne d0,.L4 "); - asm(".L5: addqw #1,d0 "); -} - -#else - -#ifndef HAVE_purify -size_t bcmp(register const uchar *s1,register const uchar *s2, - register size_t len) -#else -size_t my_bcmp(register const uchar *s1,register const uchar *s2, - register size_t len) -#endif -{ - while (len-- != 0 && *s1++ == *s2++) ; - return len+1; -} - -#endif -#endif /* BSD_FUNCS */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index cead55f8a0a..865a19b0828 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; MY_UNICASE_INFO **uni_plane= cs->caseinfo; @@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, const char *s, const char *t, size_t len) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const char *se=s+len; const char *te=t+len; MY_UNICASE_INFO **uni_plane= cs->caseinfo; @@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; diff --git a/strings/make-ccc b/strings/make-ccc index 78d5ad1ce42..93be2bbf862 100755 --- a/strings/make-ccc +++ b/strings/make-ccc @@ -1,3 +1,3 @@ -ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bcmp.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c +ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c rm libmystrings.a ar -cr libmystrings.a atof.o diff --git a/strings/str_test.c b/strings/str_test.c index 3ddfca39419..a476809e22d 100644 --- a/strings/str_test.c +++ b/strings/str_test.c @@ -50,10 +50,10 @@ int main(void) errors=tests=0; init_strings(); - test_arg("bcmp(from,to,5)",(long) my_test(bcmp(from,to,5)),1L); - test_arg("bcmp(from,from,5)",(long) bcmp(from,from,5),0L); + test_arg("memcmp(from,to,5)",(long) my_test(memcmp(from,to,5)),1L); + test_arg("memcmp(from,from,5)",(long) memcmp(from,from,5),0L); - test_arg("bcmp(from,to,0)",(long) bcmp(from,to,0),0L); + test_arg("memcmp(from,to,0)",(long) memcmp(from,to,0),0L); test_arg("strend(from)",(long) strend(from),(long) from+F_LEN); test_arg("strchr(v1,'M')",(long) strchr(v1,'M'),(long) v1); test_arg("strchr(v1,'y')",(long) strchr(v1,'y'),(long) v1+4); @@ -93,7 +93,7 @@ int main(void) test_strarg("bmove_upp(to+6,from+6,3)",(bmove_upp(to+6,from+6,3),0L),INT_MAX32, 3,T_CHAR,3,F_CHAR,0,0); test_strarg("bmove_upp(to,from,0)",(bmove_upp(to,from,0),0L),INT_MAX32,0,0); - test_strarg("bmove_align(to,from,8)",(bmove_align(to,from,8),0L),INT_MAX32, + test_strarg("memcpy(to,from,8)",(memcpy(to,from,8),0L),INT_MAX32, 8,F_CHAR,0,0); test_strarg("strappend(to,3,' ')",(strappend(to,3,' '),0L),INT_MAX32, 3,T_CHAR,1,0,T_LEN-4,T_CHAR,1,0,0,0); @@ -233,7 +233,7 @@ int compare_buff(const char *message, char * b1, char * b2, int length, { int i,error=0; - if (bcmp(b1,b2,length)) + if (memcmp(b1,b2,length)) { errors++; printf("func: '%s' Buffers differ\nIs: ",message); diff --git a/strings/xml.c b/strings/xml.c index 1b697ec6b26..f3cfaad54fa 100644 --- a/strings/xml.c +++ b/strings/xml.c @@ -123,16 +123,16 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) a->beg=p->cur; a->end=p->cur; - if ((p->end - p->cur > 3) && !bcmp(p->cur,"", 3); p->cur++) + for (; (p->cur < p->end) && memcmp(p->cur, "-->", 3); p->cur++) {} - if (!bcmp(p->cur, "-->", 3)) + if (!memcmp(p->cur, "-->", 3)) p->cur+=3; a->end=p->cur; lex=MY_XML_COMMENT; } - else if (!bcmp(p->cur, "cur, "cur+= 9; for (; p->cur < p->end - 2 ; p->cur++) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 97d146ff9ef..c492db723b0 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18096,7 +18096,7 @@ static void test_bug53371() static void test_bug53907() { int rc; - char buf[] = "\x4test\x14../client_test_db/t1"; + uchar buf[] = "\x4test\x14../client_test_db/t1"; myheader("test_bug53907"); From 082036ac6bef777ce112515a8804ee5d66368715 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 2 Jul 2010 18:42:32 -0300 Subject: [PATCH 202/207] Bug#53445: Build with -Wall and fix warnings that it generates If bzero is not available, resort to memset. Also, remove dead bzero.c --- include/m_string.h | 8 ++--- strings/bzero.c | 82 ---------------------------------------------- 2 files changed, 4 insertions(+), 86 deletions(-) delete mode 100644 strings/bzero.c diff --git a/include/m_string.h b/include/m_string.h index d027047f501..3e5cd063b7b 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -58,6 +58,10 @@ # define bfill(A,B,C) memset((A),(C),(B)) #endif +#if !defined(bzero) && !defined(HAVE_BZERO) +# define bzero(A,B) memset((A),0,(B)) +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -104,10 +108,6 @@ extern const double log_10[309]; extern void bfill(uchar *dst,size_t len,pchar fill); #endif -#if !defined(bzero) && !defined(HAVE_BZERO) -extern void bzero(uchar * dst,size_t len); -#endif - #ifndef bmove512 extern void bmove512(uchar *dst,const uchar *src,size_t len); #endif diff --git a/strings/bzero.c b/strings/bzero.c deleted file mode 100644 index b720de65eed..00000000000 --- a/strings/bzero.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* File : bzero.c - Author : Richard A. O'Keefe. - Michael Widenius; ifdef MC68000 - Updated: 23 April 1984 - Defines: bzero() - - bzero(dst, len) moves "len" 0 bytes to "dst". - Thus to clear a disc buffer to 0s do bzero(buffer, BUFSIZ). - - Note: the "b" routines are there to exploit certain VAX order codes, - The asm code is presented for your interest and amusement. -*/ - -#ifndef BSD_FUNCS -#include "strings.h" - -#ifdef bzero -#undef bzero /* remove macro */ -#endif - -#if VaxAsm - -static void _bzero64 _A((char *dst,int len)); - -void bzero(dst, len) -char *dst; -uint len; -{ - while ((int) len >= 64*K) - { - _bzero64(dst, 64*K-1); - dst += 64*K-1; - len -= 64*K-1; - } - _bzero64(dst, len); -} - -_bzero64(dst, len) -char *dst; -int len; -{ - asm("movc5 $0,*4(ap),$0,8(ap),*4(ap)"); -} - -#else - -#if defined(MC68000) && defined(DS90) - -void bzero(dst, len) -char *dst; -uint len; -{ - bfill(dst,len,0); /* This is very optimized ! */ -} /* bzero */ - -#else - -void bzero(dst, len) -register char *dst; -register uint len; -{ - while (len-- != 0) *dst++ = 0; -} /* bzero */ - -#endif -#endif -#endif /* BSD_FUNCS */ From 7b449cd8e06e89b6a56e1898af8f9842c9e3670a Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 3 Jul 2010 09:28:27 -0300 Subject: [PATCH 203/207] Post-merge fix: restore promotion to unsigned long long side-effect of bit_is_set. --- sql/rpl_utility.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index e7d3ce6d073..7479e58fd98 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -517,10 +517,12 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_ bool is_conversion_ok(int order, Relay_log_info *rli) { DBUG_ENTER("is_conversion_ok"); - bool allow_non_lossy= - slave_type_conversions_options & SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY; - bool allow_lossy= - slave_type_conversions_options & SLAVE_TYPE_CONVERSIONS_ALL_LOSSY; + bool allow_non_lossy, allow_lossy; + + allow_non_lossy = slave_type_conversions_options & + (ULL(1) << SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY); + allow_lossy= slave_type_conversions_options & + (ULL(1) << SLAVE_TYPE_CONVERSIONS_ALL_LOSSY); DBUG_PRINT("enter", ("order: %d, flags:%s%s", order, allow_non_lossy ? " ALL_NON_LOSSY" : "", From fb8df6c7b4403e1d21db6d24e45ce6a17f66ba26 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 3 Jul 2010 10:20:05 -0300 Subject: [PATCH 204/207] Fix somewhat bogus GCC warning. Although needless as the base class is mostly empty, initialize the base class explicitly in the copy constructor. --- sql/sql_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_list.h b/sql/sql_list.h index 3e0ba2b2ede..c61846c22cd 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -74,7 +74,7 @@ public: SQL_I_List() { empty(); } - SQL_I_List(const SQL_I_List &tmp) + SQL_I_List(const SQL_I_List &tmp) : Sql_alloc() { elements= tmp.elements; first= tmp.first; From 245645e225b677ab18fc1f612d58377f0052ae46 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 3 Jul 2010 20:17:03 -0300 Subject: [PATCH 205/207] Unset the execute bit where it's not needed. --- CMakeLists.txt | 0 client/CMakeLists.txt | 0 cmake/install_layout.cmake | 0 dbug/CMakeLists.txt | 0 extra/CMakeLists.txt | 0 extra/yassl/CMakeLists.txt | 0 extra/yassl/taocrypt/CMakeLists.txt | 0 libmysql/CMakeLists.txt | 0 mysql-test/include/parser_bug21114.inc | 0 mysql-test/include/show_msg.inc | 0 mysql-test/include/show_msg80.inc | 0 mysql-test/lib/My/Handles.pm | 0 mysql-test/lib/My/SafeProcess/safe_kill_win.cc | 0 mysql-test/lib/My/SafeProcess/safe_process_win.cc | 0 mysql-test/r/bug46080.result | 0 mysql-test/r/ctype_eucjpms.result | 0 mysql-test/r/lowercase_mixed_tmpdir_innodb.result | 0 mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result | 0 mysql-test/suite/ibmdb2i/include/have_i54.inc | 0 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result | 0 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result | 0 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test | 0 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test | 0 mysql-test/t/mysql_delimiter_19799.sql | 0 mysql-test/t/windows.test | 0 mysys/CMakeLists.txt | 0 regex/CMakeLists.txt | 0 scripts/CMakeLists.txt | 0 sql/CMakeLists.txt | 0 sql/event_scheduler.cc | 0 sql/examples/CMakeLists.txt | 0 storage/heap/CMakeLists.txt | 0 storage/myisam/CMakeLists.txt | 0 storage/myisammrg/CMakeLists.txt | 0 strings/CMakeLists.txt | 0 tests/CMakeLists.txt | 0 vio/CMakeLists.txt | 0 win/mysql_manifest.cmake | 0 zlib/CMakeLists.txt | 0 39 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CMakeLists.txt mode change 100755 => 100644 client/CMakeLists.txt mode change 100755 => 100644 cmake/install_layout.cmake mode change 100755 => 100644 dbug/CMakeLists.txt mode change 100755 => 100644 extra/CMakeLists.txt mode change 100755 => 100644 extra/yassl/CMakeLists.txt mode change 100755 => 100644 extra/yassl/taocrypt/CMakeLists.txt mode change 100755 => 100644 libmysql/CMakeLists.txt mode change 100755 => 100644 mysql-test/include/parser_bug21114.inc mode change 100755 => 100644 mysql-test/include/show_msg.inc mode change 100755 => 100644 mysql-test/include/show_msg80.inc mode change 100755 => 100644 mysql-test/lib/My/Handles.pm mode change 100755 => 100644 mysql-test/lib/My/SafeProcess/safe_kill_win.cc mode change 100755 => 100644 mysql-test/lib/My/SafeProcess/safe_process_win.cc mode change 100755 => 100644 mysql-test/r/bug46080.result mode change 100755 => 100644 mysql-test/r/ctype_eucjpms.result mode change 100755 => 100644 mysql-test/r/lowercase_mixed_tmpdir_innodb.result mode change 100755 => 100644 mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result mode change 100755 => 100644 mysql-test/suite/ibmdb2i/include/have_i54.inc mode change 100755 => 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result mode change 100755 => 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result mode change 100755 => 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test mode change 100755 => 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test mode change 100755 => 100644 mysql-test/t/mysql_delimiter_19799.sql mode change 100755 => 100644 mysql-test/t/windows.test mode change 100755 => 100644 mysys/CMakeLists.txt mode change 100755 => 100644 regex/CMakeLists.txt mode change 100755 => 100644 scripts/CMakeLists.txt mode change 100755 => 100644 sql/CMakeLists.txt mode change 100755 => 100644 sql/event_scheduler.cc mode change 100755 => 100644 sql/examples/CMakeLists.txt mode change 100755 => 100644 storage/heap/CMakeLists.txt mode change 100755 => 100644 storage/myisam/CMakeLists.txt mode change 100755 => 100644 storage/myisammrg/CMakeLists.txt mode change 100755 => 100644 strings/CMakeLists.txt mode change 100755 => 100644 tests/CMakeLists.txt mode change 100755 => 100644 vio/CMakeLists.txt mode change 100755 => 100644 win/mysql_manifest.cmake mode change 100755 => 100644 zlib/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake old mode 100755 new mode 100644 diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/mysql-test/include/parser_bug21114.inc b/mysql-test/include/parser_bug21114.inc old mode 100755 new mode 100644 diff --git a/mysql-test/include/show_msg.inc b/mysql-test/include/show_msg.inc old mode 100755 new mode 100644 diff --git a/mysql-test/include/show_msg80.inc b/mysql-test/include/show_msg80.inc old mode 100755 new mode 100644 diff --git a/mysql-test/lib/My/Handles.pm b/mysql-test/lib/My/Handles.pm old mode 100755 new mode 100644 diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc old mode 100755 new mode 100644 diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc old mode 100755 new mode 100644 diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result old mode 100755 new mode 100644 diff --git a/mysql-test/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result old mode 100755 new mode 100644 diff --git a/mysql-test/r/lowercase_mixed_tmpdir_innodb.result b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result old mode 100755 new mode 100644 diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result old mode 100755 new mode 100644 diff --git a/mysql-test/suite/ibmdb2i/include/have_i54.inc b/mysql-test/suite/ibmdb2i/include/have_i54.inc old mode 100755 new mode 100644 diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44232.result old mode 100755 new mode 100644 diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result old mode 100755 new mode 100644 diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44232.test old mode 100755 new mode 100644 diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test old mode 100755 new mode 100644 diff --git a/mysql-test/t/mysql_delimiter_19799.sql b/mysql-test/t/mysql_delimiter_19799.sql old mode 100755 new mode 100644 diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test old mode 100755 new mode 100644 diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc old mode 100755 new mode 100644 diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/storage/myisammrg/CMakeLists.txt b/storage/myisammrg/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/win/mysql_manifest.cmake b/win/mysql_manifest.cmake old mode 100755 new mode 100644 diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt old mode 100755 new mode 100644 From 42eecc539a5ba7ffd639192d63273c2d2dc1fc9a Mon Sep 17 00:00:00 2001 From: Date: Sun, 4 Jul 2010 12:02:49 +0800 Subject: [PATCH 206/207] The following statements support the CURRENT_USER() where a user is needed. DROP USER RENAME USER CURRENT_USER() ... GRANT ... TO CURRENT_USER() REVOKE ... FROM CURRENT_USER() ALTER DEFINER = CURRENT_USER() EVENTbut, When these statements are binlogged, CURRENT_USER() just is binlogged as 'CURRENT_USER()', it is not expanded to the real user name. When slave executes the log event, 'CURRENT_USER()' is expand to the user of slave SQL thread, but SQL thread's user name always NULL. This breaks the replication. After this patch, session's user will be written into query log events if these statements call CURREN_USER() or 'ALTER EVENT' does not assign a definer. --- mysql-test/include/diff_tables.inc | 18 +- mysql-test/include/rpl_diff_tables.inc | 35 +++ .../suite/rpl/r/rpl_current_user.result | 205 +++++++++++++++ .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/t/rpl_current_user.cnf | 9 + mysql-test/suite/rpl/t/rpl_current_user.test | 238 ++++++++++++++++++ sql/log_event.cc | 65 ++++- sql/log_event.h | 7 +- sql/sql_acl.cc | 23 +- sql/sql_class.cc | 20 ++ sql/sql_class.h | 31 +++ sql/sql_parse.cc | 2 +- 12 files changed, 634 insertions(+), 21 deletions(-) create mode 100644 mysql-test/include/rpl_diff_tables.inc create mode 100644 mysql-test/suite/rpl/r/rpl_current_user.result create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.test diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index d15dd56b35d..e11e69b3023 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -64,17 +64,13 @@ let $_diff_table=$diff_table_2; let $_diff_i=2; while ($_diff_i) { - # Parse out any leading "master:" or "slave:" from the table - # specification and connect the appropriate server. - let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`; - if ($_diff_conn_master) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`; - connection master; - } - let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`; - if ($_diff_conn_slave) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`; - connection slave; + # Parse out any leading "master:" or "slave:" from the table specification +# and connect the appropriate server. + let $_pos= `SELECT LOCATE(':', '$_diff_table')`; + let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; + if (`SELECT "XX$_diff_conn" <> "XX"`) { + let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; + connection $_diff_conn; } # Sanity-check the input. diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc new file mode 100644 index 00000000000..c3a45578a79 --- /dev/null +++ b/mysql-test/include/rpl_diff_tables.inc @@ -0,0 +1,35 @@ +# ############################################################################# +# Check whether the given table is consistent between different master and +# slaves +# +# Usage: +# --let $diff_table= test.t1 +# --let $diff_server_list= master, slave, slave2 +# --source include/rpl_diff_tables.inc +# ############################################################################# + +if (`SELECT "XX$diff_table" = "XX"`) +{ + --die diff_table is null. +} + +--let $_servers= master, slave +if (`SELECT "XX$diff_server_list" <> "XX"`) +{ + --let $_servers= $diff_server_list +} + +--let $_master= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` +--let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_master') + 2))` +connection $_master; +while (`SELECT "XX$_servers" <> "XX"`) +{ + --let $_slave= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` + --let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_slave') + 2))` + + --sync_slave_with_master $_slave + --let $diff_table_1= $_master:$diff_table + --let $diff_table_2= $_slave:$diff_table + --source include/diff_tables.inc + connection $_slave; +} diff --git a/mysql-test/suite/rpl/r/rpl_current_user.result b/mysql-test/suite/rpl/r/rpl_current_user.result new file mode 100644 index 00000000000..85490c2571c --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_current_user.result @@ -0,0 +1,205 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +# On slave2 +# Connect slave2 to slave +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=SLAVE_MYPORT;, +MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; + +# [On master] +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +# bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +# Make sure the max lengths of user and host +# the user name is too lengh +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +ERROR HY000: String '01234567890123456' is too long for user name (should be no longer than 16) +# the host name is too lengh +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; +ERROR HY000: String '0123456789012345678901234567890123456789012345678901234567890' is too long for host name (should be no longer than 60) + +# User 'bug48321_1-01234' connects to master by conn1 +# [On conn1] +# Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ... ON TABLE ...' statement +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'GRANT ... ON PROCEDURE...' statement +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'GRANT ... ON *.* ...' statement +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON TABLE ...' statement +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON PROCEDURE...' statement +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON *.* ...' statement +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ...' statement in the procedure +CREATE PROCEDURE my_grant() +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON TABLE ...' statement in the procedure +CREATE PROCEDURE my_revoke() +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'RENAME USER ...' statement +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'DROP USER ...' statement +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +DROP USER CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'ALTER EVENT...' statement +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; +# Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Session user will be set as definer, if the statement does not assign +# a definer +ALTER EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Verify that this patch does not affect the calling of CURRENT_USER() +# in the other statements +# [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +1234 +# [On slave] +SELECT * FROM t1; +c1 +@ +1234 +# [On slave2] +SELECT * FROM t1; +c1 +@ +1234 +# [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +@ +# [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +# [On slave] +SELECT * FROM t1; +c1 +# [On slave2] +SELECT * FROM t1; +c1 +# [On master] +CREATE TABLE t2(c1 char(100)); +CREATE FUNCTION my_user() RETURNS VARCHAR(64) +SQL SECURITY INVOKER +BEGIN +INSERT INTO t2 VALUES(CURRENT_USER()); +RETURN CURRENT_USER(); +END | +INSERT INTO t1 VALUES(my_user()); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +SELECT * FROM t2; +c1 +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ + +# END +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 26f2545dd72..35f4cd3ecbb 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf new file mode 100644 index 00000000000..999ee727a88 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.cnf @@ -0,0 +1,9 @@ +!include ../my.cnf + +[mysqld.3] +server-id=3 +log-bin=slave-bin + +[ENV] +SLAVE_MYPORT1= @mysqld.3.port +SLAVE_MYSOCK1= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test new file mode 100644 index 00000000000..72581ed7049 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.test @@ -0,0 +1,238 @@ +############################################################################## +# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER, +# REVOKE, GRANT, ALTER EVENT +# +# Calling CURRENT_USER() results into inconsistency between slave and master, +# as the slave SQL thread has different user with common users. +# +# After the patch for bug#48321, session's user will be written into query log +# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT', +# 'ALTER EVENT'. +# +############################################################################## +source include/master-slave.inc; +source include/have_binlog_format_statement.inc; + +--echo +--echo # On slave2 +connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,); +connection slave2; + +--echo # Connect slave2 to slave +--replace_result $SLAVE_MYPORT SLAVE_MYPORT; +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, + MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; +source include/wait_for_slave_to_start.inc; + +--echo +--echo # [On master] +connection master; +--disable_warnings +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +--enable_warnings +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +--echo # bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +--echo +--echo # Make sure the max lengths of user and host +--echo # the user name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +--echo # the host name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; + +--echo +--echo # User 'bug48321_1-01234' connects to master by conn1 +connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,); +connection conn1; +--echo # [On conn1] +--echo # Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +let $diff_table= test.v_user; +let $diff_server_list= master, slave, slave2; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON TABLE ...' statement +connection conn1; +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON PROCEDURE...' statement +connection conn1; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON *.* ...' statement +connection conn1; +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement +connection conn1; +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON PROCEDURE...' statement +connection conn1; +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON *.* ...' statement +connection conn1; +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_grant() + GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_revoke() + REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'RENAME USER ...' statement +connection conn1; +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +disconnect conn1; + +--echo +--echo # Verify 'DROP USER ...' statement +connection master; +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,); +connection conn1; +DROP USER CURRENT_USER(); +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'ALTER EVENT...' statement +connection master; +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; + +--echo # Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +let $diff_table= test.v_event; +source include/rpl_diff_tables.inc; + +connection master; +--echo +--echo # Session user will be set as definer, if the statement does not assign +--echo # a definer +ALTER EVENT e1 ENABLE; +sync_slave_with_master; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify that this patch does not affect the calling of CURRENT_USER() +--echo # in the other statements +connection master; +--echo # [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +--echo # [On slave2] +sync_slave_with_master slave2; +SELECT * FROM t1; + +connection master; +--echo # [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +CREATE TABLE t2(c1 char(100)); + +DELIMITER |; +CREATE FUNCTION my_user() RETURNS VARCHAR(64) + SQL SECURITY INVOKER +BEGIN + INSERT INTO t2 VALUES(CURRENT_USER()); + RETURN CURRENT_USER(); +END | +DELIMITER ;| + +INSERT INTO t1 VALUES(my_user()); +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo # END +connection master; +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; +sync_slave_with_master; +sync_slave_with_master slave2; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index d53f13e0b6b..0e4d4bd512b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2307,6 +2307,53 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } + if (thd && thd->is_current_user_used()) + { + LEX_STRING user; + LEX_STRING host; + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); + + if (thd->slave_thread && thd->has_invoker()) + { + /* user will be null, if master is older than this patch */ + user= thd->get_invoker_user(); + host= thd->get_invoker_host(); + } + else if (thd->security_ctx->priv_user) + { + Security_context *ctx= thd->security_ctx; + + user.length= strlen(ctx->priv_user); + user.str= ctx->priv_user; + if (ctx->priv_host[0] != '\0') + { + host.str= ctx->priv_host; + host.length= strlen(ctx->priv_host); + } + } + + if (user.length > 0) + { + *start++= Q_INVOKER; + + /* + Store user length and user. The max length of use is 16, so 1 byte is + enough to store the user's length. + */ + *start++= (uchar)user.length; + memcpy(start, user.str, user.length); + start+= user.length; + + /* + Store host length and host. The max length of host is 60, so 1 byte is + enough to store the host's length. + */ + *start++= (uchar)host.length; + memcpy(start, host.str, host.length); + start+= host.length; + } + } /* NOTE: When adding new status vars, please don't forget to update the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function @@ -2575,6 +2622,8 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, bool catalog_nz= 1; DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); common_header_len= description_event->common_header_len; post_header_len= description_event->post_header_len[event_type-1]; DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", @@ -2729,6 +2778,20 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, data_written= master_data_written= uint4korr(pos); pos+= 4; break; + case Q_INVOKER: + { + CHECK_SPACE(pos, end, 1); + user.length= *pos++; + CHECK_SPACE(pos, end, user.length); + user.str= my_strndup((const char *)pos, user.length, MYF(0)); + pos+= user.length; + + CHECK_SPACE(pos, end, 1); + host.length= *pos++; + CHECK_SPACE(pos, end, host.length); + host.str= my_strndup((const char *)pos, host.length, MYF(0)); + pos+= host.length; + } default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -3178,7 +3241,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, thd->variables.collation_database= thd->db_charset; thd->table_map_for_update= (table_map)table_map_for_update; - + thd->set_invoker(&user, &host); /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon); diff --git a/sql/log_event.h b/sql/log_event.h index e3ca4ca3321..816a241e55d 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -264,7 +264,8 @@ struct sql_ex_info 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ 1 + 8 /* type, table_map_for_update */ + \ - 1 + 4 /* type, master_data_written */) + 1 + 4 /* type, master_data_written */ + \ + 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -333,6 +334,8 @@ struct sql_ex_info #define Q_MASTER_DATA_WRITTEN_CODE 10 +#define Q_INVOKER 11 + /* Intvar event post-header */ /* Intvar event data */ @@ -1546,6 +1549,8 @@ protected: */ class Query_log_event: public Log_event { + LEX_STRING user; + LEX_STRING host; protected: Log_event::Byte* data_buf; public: diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index dd256c70ecb..9640b8db1b2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,6 +194,7 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); +static inline void get_grantor(THD *thd, char* grantor); /* Convert scrambled password to binary form, according to scramble type, @@ -2704,6 +2705,20 @@ end: DBUG_RETURN(result); } +static inline void get_grantor(THD *thd, char *grantor) +{ + const char *user= thd->security_ctx->user; + const char *host= thd->security_ctx->host_or_ip; + +#if defined(HAVE_REPLICATION) + if (thd->slave_thread && thd->has_invoker()) + { + user= thd->get_invoker_user().str; + host= thd->get_invoker_host().str; + } +#endif + strxmov(grantor, user, "@", host, NullS); +} static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, TABLE *table, const LEX_USER &combo, @@ -2718,9 +2733,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, uchar user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* The following should always succeed as new users are created before this function is called! @@ -2850,9 +2863,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, DBUG_RETURN(-1); } - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* New users are created before this function is called. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 93aa6a8268c..2ce03708a9a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -736,6 +736,9 @@ THD::THD() thr_lock_owner_init(&main_lock_id, &lock_info); m_internal_handler= NULL; + current_user_used= FALSE; + memset(&invoker_user, 0, sizeof(invoker_user)); + memset(&invoker_host, 0, sizeof(invoker_host)); } @@ -1236,6 +1239,7 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; + clean_current_user_used(); } @@ -3267,6 +3271,22 @@ void THD::set_query(char *query_arg, uint32 query_length_arg) pthread_mutex_unlock(&LOCK_thd_data); } +void THD::get_definer(LEX_USER *definer) +{ + set_current_user_used(); +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + if (slave_thread && has_invoker()) + { + definer->user = invoker_user; + definer->host= invoker_host; + definer->password.str= NULL; + definer->password.length= 0; + } + else +#endif + get_default_definer(this, definer); +} + /** Mark transaction to rollback and mark error as fatal to a sub-statement. diff --git a/sql/sql_class.h b/sql/sql_class.h index 023367cb747..5155ffe0603 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2341,6 +2341,18 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); + void set_current_user_used() { current_user_used= TRUE; } + bool is_current_user_used() { return current_user_used; } + void clean_current_user_used() { current_user_used= FALSE; } + void get_definer(LEX_USER *definer); + void set_invoker(const LEX_STRING *user, const LEX_STRING *host) + { + invoker_user= *user; + invoker_host= *host; + } + LEX_STRING get_invoker_user() { return invoker_user; } + LEX_STRING get_invoker_host() { return invoker_host; } + bool has_invoker() { return invoker_user.length > 0; } private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; @@ -2360,6 +2372,25 @@ private: tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; + + /** + It will be set TURE if CURRENT_USER() is called in account management + statements or default definer is set in CREATE/ALTER SP, SF, Event, + TRIGGER or VIEW statements. + + Current user will be binlogged into Query_log_event if current_user_used + is TRUE; It will be stored into invoker_host and invoker_user by SQL thread. + */ + bool current_user_used; + + /** + It points to the invoker in the Query_log_event. + SQL thread use it as the default definer in CREATE/ALTER SP, SF, Event, + TRIGGER or VIEW statements or current user in account management + statements if it is not NULL. + */ + LEX_STRING invoker_user; + LEX_STRING invoker_host; }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ed2c76fdcb8..1f3d29ffec0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7654,7 +7654,7 @@ LEX_USER *create_default_definer(THD *thd) if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; - get_default_definer(thd, definer); + thd->get_definer(definer); return definer; } From 363a2ccc0c0c500b4c146bae4f829873623836d3 Mon Sep 17 00:00:00 2001 From: Date: Sun, 4 Jul 2010 16:17:53 +0800 Subject: [PATCH 207/207] Postfix for bug#48321 Some test cases set ANSI_QUOTES in sql_mode. So we have to use single quotes to quote literal strings. --- mysql-test/include/diff_tables.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index e11e69b3023..81362e8643b 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -68,7 +68,7 @@ while ($_diff_i) { # and connect the appropriate server. let $_pos= `SELECT LOCATE(':', '$_diff_table')`; let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; - if (`SELECT "XX$_diff_conn" <> "XX"`) { + if (`SELECT 'XX$_diff_conn' <> 'XX'`) { let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; connection $_diff_conn; }