From 3b774da463986509975aacb933acd7f4fb31a774 Mon Sep 17 00:00:00 2001 From: "Miguel@light.local" <> Date: Tue, 25 Sep 2001 01:13:19 -0300 Subject: [PATCH 01/38] Changes on NT service for a more faster stop of the service on Win2k and free the main thread of the service. --- BitKeeper/etc/logging_ok | 22 +--------------------- sql/mysqld.cc | 2 +- sql/nt_servc.cc | 3 ++- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 390c414d29c..efa9faefd05 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1,21 +1 @@ -davida@isil.mysql.com -heikki@donna.mysql.fi -jani@hynda.mysql.fi -jani@janikt.pp.saunalahti.fi -jcole@tetra.spaceapes.com -miguel@light.local -monty@bitch.mysql.fi -monty@hundin.mysql.fi -monty@tik.mysql.fi -monty@work.mysql.com -mwagner@evoq.mwagner.org -paul@central.snake.net -paul@teton.kitebird.com -sasha@mysql.sashanet.com -serg@serg.mysql.com -tim@bitch.mysql.fi -tim@threads.polyesthetic.msg -tim@white.box -tim@work.mysql.com -tonu@x153.internalnet -tfr@sarvik.tfr.cafe.ee +Miguel@light.local diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a124eea7807..435ee51a0e0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2006,7 +2006,7 @@ The server will not act as a slave."); { if(start_mode) { - if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) + if (WaitForSingleObject(hEventShutdown,1000)==WAIT_TIMEOUT) Service.Stop(); } else diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 5884300fe95..3a36f5740a9 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -246,7 +246,8 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) WaitForSingleObject (pService->hExitEvent, INFINITE); // wait for thread to exit - WaitForSingleObject (pService->hThreadHandle, 30000); + if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT) + CloseHandle(pService->hThreadHandle); pService->Exit(0); } From d45bf758ad6eff99532242fd87ed2854cef4f0dc Mon Sep 17 00:00:00 2001 From: "serg@serg.mysql.com" <> Date: Wed, 26 Sep 2001 12:56:19 +0200 Subject: [PATCH 02/38] manual cleanups --- BitKeeper/etc/logging_ok | 1 + Docs/manual.texi | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index efa9faefd05..18c9c43349e 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1 +1,2 @@ Miguel@light.local +serg@serg.mysql.com diff --git a/Docs/manual.texi b/Docs/manual.texi index 6dd44a79288..88e4adceb9b 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -30991,7 +30991,8 @@ mysql> select ATAN(-2); @end example @findex ATAN2() -@item ATAN2(Y,X) +@item ATAN(Y,X) +@itemx ATAN2(Y,X) Returns the arc tangent of the two variables @code{X} and @code{Y}. It is similar to calculating the arc tangent of @code{Y / X}, except that the signs of both arguments are used to determine the quadrant of the @@ -30999,7 +31000,7 @@ result: @example mysql> select ATAN(-2,2); -> -0.785398 -mysql> select ATAN(PI(),0); +mysql> select ATAN2(PI(),0); -> 1.570796 @end example @@ -32203,6 +32204,18 @@ MySQL will directly use disk-based temporary tables if needed. MySQL will also, in this case, prefer sorting to doing a temporary table with a key on the @code{GROUP BY} elements. +@item +@code{SQL_BUFFER_RESULT} will force the result to be put into a temporary +table. This will help MySQL free the table locks early and will help +in cases where it takes a long time to send the result set to the client. + +@item +@code{SQL_SMALL_RESULT}, a MySQL-specific option, can be used +with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the +result set will be small. In this case, MySQL will use fast +temporary tables to store the resulting table instead of using sorting. In +MySQL Version 3.23 this shouldn't normally be needed. + @item @cindex @code{GROUP BY}, extensions to ANSI SQL If you use @code{GROUP BY}, the output rows will be sorted according to the @@ -32221,18 +32234,6 @@ If you are not getting the results you expect from your query, please read the @code{GROUP BY} description. @xref{Group by functions}. -@item -@code{SQL_BUFFER_RESULT} will force the result to be put into a temporary -table. This will help MySQL free the table locks early and will help -in cases where it takes a long time to send the result set to the client. - -@item -@code{SQL_SMALL_RESULT}, a MySQL-specific option, can be used -with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the -result set will be small. In this case, MySQL will use fast -temporary tables to store the resulting table instead of using sorting. In -MySQL Version 3.23 this shouldn't normally be needed. - @item @code{STRAIGHT_JOIN} forces the optimizer to join the tables in the order in which they are listed in the @code{FROM} clause. You can use this to speed up From 3e4ff5dcccb7d1e016d12048de2ee94f972d6d13 Mon Sep 17 00:00:00 2001 From: "paul@central.snake.net" <> Date: Thu, 27 Sep 2001 12:25:36 -0500 Subject: [PATCH 03/38] manual.texi correct date error in manual. --- BitKeeper/etc/logging_ok | 1 + Docs/manual.texi | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index efa9faefd05..02c76aa4b4a 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1 +1,2 @@ Miguel@light.local +paul@central.snake.net diff --git a/Docs/manual.texi b/Docs/manual.texi index 6dd44a79288..8b51e73f9a2 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -12788,7 +12788,7 @@ this may be different than what you are used to.) @item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab @item Buffy @tab Harold @tab dog @tab f @tab 1989-05-13 @tab @item Fang @tab Benny @tab dog @tab m @tab 1990-08-27 @tab -@item Bowser @tab Diane @tab dog @tab m @tab 1989-08-31 @tab 1995-07-29 +@item Bowser @tab Diane @tab dog @tab m @tab 1998-08-31 @tab 1995-07-29 @item Chirpy @tab Gwen @tab bird @tab f @tab 1998-09-11 @tab @item Whistler @tab Gwen @tab bird @tab @tab 1997-12-09 @tab @item Slim @tab Benny @tab snake @tab m @tab 1996-04-29 @tab From 0a03293ed0a7fbbb676cd555d6907f4d70704386 Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Thu, 27 Sep 2001 12:31:40 -0500 Subject: [PATCH 04/38] manual.texi correct date error in tutorial. --- Docs/manual.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index c88455289c8..d0947065b2d 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -12844,7 +12844,7 @@ this may be different than what you are used to.) @item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab @item Buffy @tab Harold @tab dog @tab f @tab 1989-05-13 @tab @item Fang @tab Benny @tab dog @tab m @tab 1990-08-27 @tab -@item Bowser @tab Diane @tab dog @tab m @tab 1989-08-31 @tab 1995-07-29 +@item Bowser @tab Diane @tab dog @tab m @tab 1998-08-31 @tab 1995-07-29 @item Chirpy @tab Gwen @tab bird @tab f @tab 1998-09-11 @tab @item Whistler @tab Gwen @tab bird @tab @tab 1997-12-09 @tab @item Slim @tab Benny @tab snake @tab m @tab 1996-04-29 @tab From 89f92db6b8a33832a1adb8ecb65fa883e688479c Mon Sep 17 00:00:00 2001 From: "paul@central.snake.net" <> Date: Thu, 27 Sep 2001 12:31:59 -0500 Subject: [PATCH 05/38] manual.texi typo fixes. --- Docs/manual.texi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 8b51e73f9a2..46e7ffcf6c7 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -17191,7 +17191,7 @@ knowing your 'scrambled' password is enough to be able to connect to the MySQL server! @end itemize -MySQL users and they privileges are normally created with the +MySQL users and their privileges are normally created with the @code{GRANT} command. @xref{GRANT}. When you login to a MySQL server with a command line client you @@ -17217,13 +17217,14 @@ mysql -u monty -p database_name Note that in the last example the password is @strong{NOT} 'database_name'. -If you want to use the @code{-p} option to supply a password you should do like this: +If you want to use the @code{-p} option to supply a password you should do so +like this: @example mysql -u monty -pguess database_name @end example -On some system the library call that MySQL uses to prompt for a +On some systems, the library call that MySQL uses to prompt for a password will automatically cut the password to 8 characters. Internally MySQL doesn't have any limit for the length of the password. From a80e32a4073eaa7428347af5fda8ca6b873d90bb Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Thu, 27 Sep 2001 12:36:28 -0500 Subject: [PATCH 06/38] manual.texi typo fixes. --- Docs/manual.texi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index d0947065b2d..908230a4745 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -17248,7 +17248,7 @@ knowing your 'scrambled' password is enough to be able to connect to the MySQL server! @end itemize -MySQL users and they privileges are normally created with the +MySQL users and their privileges are normally created with the @code{GRANT} command. @xref{GRANT}. When you login to a MySQL server with a command line client you @@ -17274,13 +17274,14 @@ mysql -u monty -p database_name Note that in the last example the password is @strong{NOT} 'database_name'. -If you want to use the @code{-p} option to supply a password you should do like this: +If you want to use the @code{-p} option to supply a password you should do so +like this: @example mysql -u monty -pguess database_name @end example -On some system the library call that MySQL uses to prompt for a +On some systems, the library call that MySQL uses to prompt for a password will automatically cut the password to 8 characters. Internally MySQL doesn't have any limit for the length of the password. From 99b58a5aa9ae729d95b00650b8360820bafe3887 Mon Sep 17 00:00:00 2001 From: "monty@tik.mysql.fi" <> Date: Thu, 27 Sep 2001 21:35:35 +0300 Subject: [PATCH 07/38] Cleaned up udf_example.cc and mysql_fix_privilege_tables --- acinclude.m4 | 2 +- scripts/mysql_fix_privilege_tables.sh | 13 ++++++------- sql/udf_example.cc | 25 +++++++++++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 86eed5e69c7..1eb95e1e9c9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1106,7 +1106,7 @@ changequote([, ])dnl AC_DEFUN(AC_SYS_LARGEFILE, [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, - [ --disable-large-files Omit support for large files]) + [ --disable-largefile Omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, getconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 8e9ef509d66..86312fdab52 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -3,8 +3,8 @@ echo "This scripts updates the mysql.user, mysql.db, mysql.host and the" echo "mysql.func table to MySQL 3.22.14 and above." echo "" -echo "This is needed if you want to use the new GRANT functions or" -echo "want to use the more secure passwords." +echo "This is needed if you want to use the new GRANT functions," +echo "CREATE AGGREAGATE FUNCTION or want to use the more secure passwords in 3.23" echo "" echo "If you get Access denied errors, you should run this script again" echo "and give the MySQL root user password as a argument!" @@ -15,13 +15,12 @@ host="localhost" # Fix old password format, add File_priv and func table echo "" echo "If your tables are already up to date or partially up to date you will" -echo "get some warnings about 'Duplicated column name' or" -echo "'Table 'func' already exists'. You can safely ignore these!" +echo "get some warnings about 'Duplicated column name'. You can safely ignore these!" @bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <h_name) - result); return result; } +#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) /* ** Syntax for the new aggregate commands are: @@ -777,13 +790,6 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, ** (this example is provided by Andreas F. Bobak ) */ -extern "C" { -my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); -void avgcost_deinit( UDF_INIT* initid ); -void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -} struct avgcost_data { @@ -810,7 +816,7 @@ avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) return 1; } - if ((args->arg_type[0] != INT_RESULT) && (args->arg_type[1] != REAL_RESULT) ) + if ((args->arg_type[0] != INT_RESULT) || (args->arg_type[1] != REAL_RESULT) ) { strcpy( message, @@ -917,5 +923,4 @@ avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error ) return data->totalprice/double(data->totalquantity); } -#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) #endif /* HAVE_DLOPEN */ From e05bf277d6529b61bf74cf0b8b3e6efd994869a0 Mon Sep 17 00:00:00 2001 From: "monty@tik.mysql.fi" <> Date: Thu, 27 Sep 2001 21:45:48 +0300 Subject: [PATCH 08/38] Final fixes for INSERT into MERGE tables. Move MAX_BLOB_WIDTH to be global Added full support for unsigned BIGINT Fixed spelling errors --- BUILD/compile-pentium-debug-max | 2 +- Docs/manual.texi | 285 ++++++++++++++++++++------------ acinclude.m4 | 13 +- configure.in | 10 +- include/mysql_com.h | 2 + myisammrg/myrg_create.c | 2 +- myisammrg/myrg_static.c | 2 +- mysql-test/r/bigint.result | 16 ++ mysql-test/r/merge.result | 202 ++++++++++++++++++++++ mysql-test/r/type_ranges.result | 2 +- mysql-test/t/bigint.test | 15 ++ mysql-test/t/merge.test | 56 ++++++- mysys/typelib.c | 3 +- sql/field.h | 7 +- sql/ha_berkeley.cc | 2 +- sql/ha_gemini.cc | 2 +- sql/ha_myisam.cc | 2 +- sql/ha_myisammrg.cc | 8 +- sql/item.cc | 6 +- sql/item.h | 1 + sql/item_func.cc | 28 +++- sql/item_strfunc.cc | 4 +- sql/item_sum.cc | 131 +++++++++++---- sql/item_sum.h | 4 +- sql/mf_iocache.cc | 2 +- sql/mysql_priv.h | 1 - sql/mysqld.cc | 6 +- sql/opt_range.cc | 2 +- sql/sql_base.cc | 11 +- sql/sql_insert.cc | 4 +- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 4 +- sql/sql_select.cc | 4 +- sql/structs.h | 2 +- sql/time.cc | 2 +- sql/unireg.cc | 6 +- 36 files changed, 653 insertions(+), 198 deletions(-) diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index ccd6faa0448..4149267811d 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-vio --with-openssl --with-embedded-server" +extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server" . "$path/FINISH.sh" diff --git a/Docs/manual.texi b/Docs/manual.texi index c88455289c8..b1815b4eac9 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -4368,6 +4368,7 @@ precision, @code{IF}, and @code{ELT()} with @code{BIGINT} or @code{DOUBLE} precision and the rest with @code{DOUBLE} precision. One should try to avoid using bigger unsigned long long values than 63 bits (9223372036854775807) for anything else than bit fields! +MySQL 4.0 has better @code{BIGINT} handling than 3.23. @item All string columns, except @code{BLOB} and @code{TEXT} columns, automatically @@ -5690,6 +5691,15 @@ implemented in the 4.0 tree. @xref{News-4.0.x}. @itemize @bullet @item +Allow users to change startup options without taking down the server. +@item +Fail safe replication. +@item +More functions for full-text search. +@xref{Fulltext Features to Appear in MySQL 4.0}. +@item +New key cache +@item New table definition file format (@code{.frm} files) This will enable us to not run out of bits when adding more table options. One will still be able to use the old @code{.frm} file format with 4.0. All newly created @@ -5698,19 +5708,6 @@ tables will, however, use the new format. The new file format will enable us to add new column types, more options for keys and @code{FOREIGN KEY} support. @item -@code{mysqld} as a library. This will have the same interface as the -standard MySQL client (with an extra function to just set up -startup parameters) but will be faster (no TCP/IP or socket overhead), -smaller and much easier to use for embedded products. - -One will be able to define at link time if one wants to use the -client/server model or a stand-alone application just by defining which -library to link with. - -The @code{mysqld} will support all standard MySQL features and -one can use it in a threaded client to run different queries in each -thread. -@item Replication should work with @code{RAND()} and user variables @code{@@var}. @item Online backup with very low performance penalty. The online backup will @@ -5720,15 +5717,8 @@ Allow @code{DELETE} on @code{MyISAM} tables to use the record cache. To do this, we need to update the threads record cache when we update the @code{.MYD} file. @item -Better replication. -@item -More functions for full-text search. -@xref{Fulltext Features to Appear in MySQL 4.0}. -@item Character set casts and syntax for handling multiple character sets. @item -Allow users to change startup options without taking down the server. -@item Help for all commands from the client. @item Secure connections (with SSL). @@ -5737,8 +5727,6 @@ Secure connections (with SSL). expansions of column names) should not open the table, but only the definition file. This will require less memory and be much faster. @item -New key cache -@item When using @code{SET CHARACTER SET} we should translate the whole query at once and not only strings. This will enable users to use the translated characters in database, table and column names. @@ -5760,11 +5748,12 @@ of @code{analyze} is run on all sub tables. @itemize @bullet @item -Fail safe replication. -@item Subqueries. @code{select id from t where grp in (select grp from g where u > 100)} @item +Atomic multi-table updates, eg @code{update items,month set +items.price=month.price where items.id=month.id;}; +@item Derived tables. @example select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a, @@ -6046,9 +6035,6 @@ if it exists and @code{INSERT} a new row if the row didn't exist. @item Implement function: @code{get_changed_tables(timeout,table1,table2,...)} @item -Atomic multi-table updates, eg @code{update items,month set -items.price=month.price where items.id=month.id;}; -@item Change reading through tables to use memmap when possible. Now only compressed tables use memmap. @item @@ -6144,8 +6130,6 @@ Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant. @end itemize - - @node Installing, Tutorial, Introduction, Top @chapter MySQL Installation @@ -9349,7 +9333,7 @@ you have to use @code{mysqldump}. Old clients should work with a Version 4.0 server without any problems. The following lists tell what you have to watch out for when upgrading to -Version 4.0; +version 4.0; @itemize @bullet @item @@ -9366,6 +9350,15 @@ from a table and you don't care of how many rows where deleted. You will get an error if you have an active @code{LOCK TABLES} or transaction when trying to execute @code{TRUNCATE TABLE} or @code{DROP DATABASE}. +@item +You should use integers to store values in BIGINT columns (instead of using +strings as you did in MySQL 3.23). Using strings will still work, but using +integers is more efficient. +@item +Format of @code{SHOW OPEN TABLE} has changed. +@item +Multithreaded clients should use @code{mysql_thread_init()} and +@code{mysql_thread_end()}. @xref{Threaded clients}. @end itemize @node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade @@ -20270,19 +20263,13 @@ operations. @item @code{table_cache} The number of open tables for all threads. Increasing this value increases the number of file descriptors that @code{mysqld} requires. -MySQL needs two file descriptors for each unique open table. -See below for comments on file descriptor limits. You can check if you -need to increase the table cache by checking the @code{Opened_tables} -variable. @xref{SHOW}. If this variable is big and you don't do -@code{FLUSH TABLES} a lot (which just forces all tables to be closed and -reopenend), then you should increase the value of this variable. +You can check if you need to increase the table cache by checking the +@code{Opened_tables} variable. @xref{SHOW}. If this variable is big and +you don't do @code{FLUSH TABLES} a lot (which just forces all tables to +be closed and reopenend), then you should increase the value of this +variable. -Make sure that your operating system can handle the number of open file -descriptors implied by the @code{table_cache} setting. If @code{table_cache} -is set too high, MySQL may run out of file descriptors and refuse -connections, fail to perform queries, and be very unreliable. - -For information about how the table cache works, see @ref{Table cache}. +For more information about the table cache, see @ref{Table cache}. @item @code{table_type} The default table type @@ -26430,6 +26417,16 @@ at least @code{200 * n}, where @code{n} is the maximum number of tables in a join. You also need to reserve some extra file descriptors for temporary tables and files. +Make sure that your operating system can handle the number of open file +descriptors implied by the @code{table_cache} setting. If +@code{table_cache} is set too high, MySQL may run out of file +descriptors and refuse connections, fail to perform queries, and be very +unreliable. You also have to take into account that the MyISAM table +handler needs two file descriptors for each unique open table. You can +in increase the number of file descriptors available for MySQL with +the @code{--open-files-limit=#} startup option. @xref{Not enough file +handles}. + The cache of open tables can grow to a maximum of @code{table_cache} (default 64; this can be changed with the @code{-O table_cache=#} option to @code{mysqld}). A table is never closed, except when the @@ -26461,6 +26458,12 @@ use of the table takes only one file descriptor. The extra descriptor for the first open is used for the index file; this descriptor is shared among all threads. +If you are opening a table with the @code{HANDLER table_name OPEN} +statement, a dedicated table object is allocated for the thread. +This table object is not shared by other threads an will not be closed +until the thread calls @code{HANDLER table_name CLOSE} or the thread dies. +@xref{HANDLER}. + You can check if your table cache is too small by checking the mysqld variable @code{opened_tables}. If this is quite big, even if you haven't done a lot of @code{FLUSH TABLES}, you should increase your table @@ -28116,14 +28119,23 @@ values, so you shouldn't use unsigned big integers larger than @code{9223372036854775807} (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting the @code{BIGINT} to a @code{DOUBLE}. + +MySQL 4.0 can handle @code{BIGINT} in the following cases: +@itemize @bullet +@item +Use integers to store big unsigned values in a @code{BIGINT} column. +@item +In @code{MIN(big_int_column)} and @code{MAX(big_int_column)}. +@item +When using operators (@code{+}, @code{-}, @code{*} etc) where +both operands are integers. +@end itemize + @item You can always store an exact integer value in a @code{BIGINT} column by storing it as a string, as there is in this case there will be no intermediate double representation. @item -In MySQL 4.0 you can use integers to store big unsigned values in a -@code{BIGINT} string. -@item @samp{-}, @samp{+}, and @samp{*} will use @code{BIGINT} arithmetic when both arguments are @code{INTEGER} values! This means that if you multiply two big integers (or results from functions that return @@ -33818,6 +33830,7 @@ or DELAY_KEY_WRITE = @{0 | 1@} or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=# or UNION = (table_name,[table_name...]) +or INSERT_METHOD= @{NO | FIRST | LAST @} or DATA DIRECTORY="directory" or INDEX DIRECTORY="directory" @@ -34160,13 +34173,13 @@ original tables, MySQL will not allow concurrent inserts during @code{CREATE TABLE .... SELECT}. @item The @code{RAID_TYPE} option will help you to break the 2G/4G limit for -the MyISAM data file (not the index file) on -operating systems that don't support big files. You can get also more speed -from the I/O bottleneck by putting @code{RAID} directories on different -physical disks. @code{RAID_TYPE} will work on any OS, as long as you have -configured MySQL with @code{--with-raid}. For now the only allowed -@code{RAID_TYPE} is @code{STRIPED} (@code{1} and @code{RAID0} are aliases -for this). +the MyISAM data file (not the index file) on operating systems that +don't support big files. +You can get more speed from the I/O bottleneck by putting +@code{RAID} directories on different physical disks. @code{RAID_TYPE} +will work on any OS, as long as you have configured MySQL with +@code{--with-raid}. For now the only allowed @code{RAID_TYPE} is +@code{STRIPED} (@code{1} and @code{RAID0} are aliases for this). If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table, @code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00, @@ -34182,6 +34195,12 @@ tables as one. This only works with MERGE tables. @xref{MERGE}. For the moment you need to have @code{SELECT}, @code{UPDATE}, and @code{DELETE} privileges on the tables you map to a @code{MERGE} table. All mapped tables must be in the same database as the @code{MERGE} table. + +@item +If you want to insert data in a @code{MERGE} table, you have to specify with +@code{INSERT_METHOD} into with table the row should be inserted. +@xref{MERGE}. + @item In the created table the @code{PRIMARY} key will be placed first, followed by all @code{UNIQUE} keys and then the normal keys. This helps the @@ -35005,6 +35024,8 @@ interface, bypassing SQL optimizer. Thus, it is faster then SELECT. The first form of @code{HANDLER} statement opens a table, making in accessible via the following @code{HANDLER ... READ} routines. +This table object is not shared by other threads an will not be closed +until the thread calls @code{HANDLER table_name CLOSE} or the thread dies. The second form fetches one (or, specified by @code{LIMIT} clause) row where the index specified complies to the condition and @code{WHERE} @@ -35023,8 +35044,8 @@ in data file) matching @code{WHERE} condition. It is faster than The last form closes the table, opened with @code{HANDLER ... OPEN}. @code{HANDLER} is somewhat low-level statement, for example it does not -provide consistency. That is @code{HANDLER ... OPEN} does @strong{not} -takes a snapshot of the table, and does @strong{not} locks the table. The +provide consistency. That is @code{HANDLER ... OPEN} does @strong{NOT} +takes a snapshot of the table, and does @strong{NOT} locks the table. The above means, that after @code{HANDLER ... OPEN} table data can be modified (by this or other thread) and these modifications may appear only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans. @@ -35885,7 +35906,7 @@ specification. Note that @code{DELETE FROM merge_table} used without a @code{WHERE} will only clear the mapping for the table, not delete everything in the -mapped tables. (We plan to fix this in 4.0). +mapped tables. (We plan to fix this in 4.1). With identical tables we mean that all tables are created with identical column and key information. You can't put a MERGE over tables where the @@ -35945,11 +35966,12 @@ The disadvantages with @code{MERGE} tables are: @itemize @bullet @item -You can't use @code{INSERT} on @code{MERGE} tables, as MySQL -can't know in which of the tables we should insert the row. -@item You can only use identical @code{MyISAM} tables for a @code{MERGE} table. @item +@code{AUTO_INCREMENT} columns are not automaticly updated on @code{INSERT}. +@item +@code{REPLACE} doesn't work. +@item @code{MERGE} tables uses more file descriptors. If you are using a @strong{MERGE} that maps over 10 tables and 10 users are using this, you are using 10*10 + 10 file descriptors. (10 data files for 10 users @@ -35971,6 +35993,14 @@ mapped by a @code{MERGE} table that is 'open'. If you do this, the get unexpected results. @end itemize +When you create a @code{MERGE} table you have to specify with +@code{UNION(list-of-tables)} which tables you want to use as +one. Optionally you can specify with @code{INSERT_METHOD} if you want +insert for the @code{MERGE} table to happen in the first or last table +in the @code{UNION} list. If you don't specify @code{INSERT_METHOD} or +specify @code{NO}, then all @code{INSERT} commands on the @code{MERGE} +table will return an error. + The following example shows you how to use @code{MERGE} tables: @example @@ -35978,7 +36008,7 @@ CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1"); INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2"); -CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2); +CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; @end example Note that we didn't create a @code{UNIQUE} or @code{PRIMARY KEY} in the @@ -38908,19 +38938,37 @@ Note that if you are using MySQL Version 3.22, you must to apply the MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around this problem. @item -Set the ``Return matching rows'' MyODBC option field when connecting to -MySQL. -@item -You should have a primary key in the table. If not, new or updated rows -may show up as @code{#Deleted#}. +For all Access versions, you should enable the MyODBC option flag +@code{Return matching rows}. For Access 2.0, you should additionally enable +@code{Simulate ODBC 1.0}. @item You should have a timestamp in all tables you want to be able to update. For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} is recommended instead of other @code{TIMESTAMP(X)} variations. @item -Only use double float fields. Access fails when comparing with single floats. -The symptom usually is that new or updated rows may show up as @code{#Deleted#} -or that you can't find or update rows. +You should have a primary key in the table. If not, new or updated rows +may show up as @code{#DELETED#}. +@item +Only use @code{DOUBLE} float fields. Access fails when comparing with +single floats. The symptom usually is that new or updated rows may show +up as @code{#DELETED#} or that you can't find or update rows. +@item +If you are linking a table through MyODBC, which has @code{BIGINT} as +one of the column, then the results will be displayed as @code{#DELETED}. The +work around solution is: +@itemize @bullet +@item +Have one more dummy column with @code{TIMESTAMP} as the data type, preferably +@code{TIMESTAMP(14)}. +@item +Check the @code{'Change BIGINT columns to INT'} in connection options dialog in +ODBC DSN Administrator +@item +Delete the table link from access and re-create it. +@end itemize + +It still displays the previous records as @code{#DELETED#}, but newly +added/updated records will be displayed properly. @item If you still get the error @code{Another user has changed your data} after adding a @code{TIMESTAMP} column, the following trick may help you: @@ -38931,6 +38979,10 @@ set the @code{DefaultValue} property for the @code{TIMESTAMP} column to @code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column from view so your users are not confused. @item +In some cases, Access may generate illegal SQL queries that +MySQL can't understand. You can fix this by selecting +@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. +@item Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If you want to have @code{MEMO} columns instead, you should change the column to @code{TEXT} with @code{ALTER TABLE}. @@ -38938,19 +38990,9 @@ column to @code{TEXT} with @code{ALTER TABLE}. Access can't always handle @code{DATE} columns properly. If you have a problem with these, change the columns to @code{DATETIME}. @item -In some cases, Access may generate illegal SQL queries that -MySQL can't understand. You can fix this by selecting -@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. -@item -If you have in Access a column defined as BYTE, Access will try to export this -as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you -problems if you have values > 127 in the column! -@item -If you are using Access 7.0, You should use the option flag @code{Return -matching rows}. -@item -If you are using Access 2.0, You should use the option flags @code{Return -matching rows} and @code{Simulate ODBC 1.0}. +If you have in Access a column defined as @code{BYTE}, Access will try +to export this as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. +This will give you problems if you have values > 127 in the column! @end itemize @cindex ADO program @@ -42971,6 +43013,10 @@ functions}. For the UDF mechanism to work, functions must be written in C or C++, your operating system must support dynamic loading and you must have compiled @code{mysqld} dynamically (not statically). +Note that to make @code{AGGREGATE} work, you must have a +@code{mysql.func} table that contains the column @code{type}. If this +is not the case, you should run the script +@code{mysql_fix_privilege_tables} to get this fixed. @node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions @@ -43135,6 +43181,10 @@ digits. For real functions, the default is 13 plus the number of decimals indicated by @code{initid->decimals}. (For numeric functions, the length includes any sign or decimal point characters.) +If you want to return a blob, you can set this to 65K or 16M; This +memory is not allocated but used to decide which column type to use if +there is a need to temporary store the data. + @item char *ptr A pointer that the function can use for its own purposes. For example, functions can use @code{initid->ptr} to communicate allocated memory @@ -43275,7 +43325,8 @@ terminal screen. The return value of the main function @code{xxx()} is the function value, for @code{long long} and @code{double} functions. A string functions should return a pointer to the result and store the length of the string in the -@code{length} arguments. @code{result} is a buffer at least 255 bytes long. +@code{length} arguments. + Set these to the contents and length of the return value. For example: @example @@ -43283,8 +43334,12 @@ memcpy(result, "result string", 13); *length = 13; @end example -If your string functions that needs to return a string longer than 255 -bytes, you must allocate the space for it with @code{malloc()} in your +The @code{result} buffer that is passed to the calc function is 255 byte +big. If your result fits in this, you don't have to worry about memory +allocation for results. + +If your string function needs to return a string longer than 255 bytes, +you must allocate the space for it with @code{malloc()} in your @code{xxx_init()} function or your @code{xxx()} function and free it in your @code{xxx_deinit()} function. You can store the allocated memory in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by @@ -43389,6 +43444,7 @@ mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so"; @end example Functions can be deleted using @code{DROP FUNCTION}: @@ -43399,6 +43455,7 @@ mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup; +mysql> DROP FUNCTION avgcost; @end example The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the @@ -47308,6 +47365,9 @@ Configure updates for Tru64, large file support and better TCP wrappers support. @item John Birrell Emulation of pthread_mutex() for OS/2. +@item Benjamin Pflugmann +Extended @code{MERGE} tables to handle @code{INSERTS}. Active member +on the MySQL mailing lists. @end table Other contributors, bugfinders, and testers: James H. Thompson, Maurizio @@ -47434,16 +47494,16 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item -Added documentation for @code{libmysqld}, the embedded -MySQL server library. Also added example programs (a -@code{mysql} client and @code{mysqltest} test program) which use -@code{libmysqld}. +Added documentation for @code{libmysqld}, the embedded MySQL server +library. Also added example programs (a @code{mysql} client and +@code{mysqltest} test program) which use @code{libmysqld}. @item Removed @code{my_thread_init()} and @code{my_thread_end()} from mysql_com.h, and added @code{mysql_thread_init()} and @code{mysql_thread_end()} to mysql.h. @item -Fixed handling of big unsigned bigint constants. +Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()} +now handles signed and unsigned @code{BIGINT} numbers correctly. @item New character set @code{latin_de} which provides correct German sorting. @item @@ -47454,45 +47514,40 @@ the number of deleted rows. @code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in the database, which fixes a problem with InnoDB tables. @item +Added support for @code{UNION}. +@item +A new @code{HANDLER} interface to @code{MyISAM} tables. +@item +Added support for @code{INSERT} on @code{MERGE} tables. Patch from +Benjamin Pflugmann. +@item Changed @code{WEEK(#,0)} to match the calender in the USA. @item -Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} -@item -Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization. +@code{COUNT(DISTINCT)} is about 30% faster. @item Speed up all internal list handling. @item -Added support for @code{UNION}. -@item -Allow ANSI SQL syntax @code{X'hexadecimal-number'} +Creating full text indexes are now much faster. @item Tree-like cache to speed up bulk inserts and @code{myisam_bulk_insert_tree_size} variable. @item -Added @code{ALTER TABLE table_name DISABLE KEYS} and -@code{ALTER TABLE table_name ENABLE KEYS} commands. +Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster. +@item +Optimized queries of type: +@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #} +@item +@code{ORDER BY ... DESC} can now use keys. @item @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave. @item Renamed @code{safe_mysqld} to @code{mysqld_safe}. @item -Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands. -@item -@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}. -@item Added support for symbolic links to @code{MyISAM} tables. Symlink handling is now enabled by default for Windows. @item @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave. @item -A new @code{HANDLER} interface to @code{MyISAM} tables. -@item -@code{COUNT(DISTINCT)} is about 30% faster. -@item -Creating full text indexes are now much faster. -@item -Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster. -@item Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it possible to know how many rows a query would have returned without a @code{LIMIT} clause. @@ -47505,8 +47560,18 @@ Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like Sybase). @item Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}. @item -Optimized queries of type: -@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #} +@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}. +@item +Added @code{ALTER TABLE table_name DISABLE KEYS} and +@code{ALTER TABLE table_name ENABLE KEYS} commands. +@item +Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands. +@item +Allow ANSI SQL syntax @code{X'hexadecimal-number'} +@item +Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} +@item +Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization. @end itemize diff --git a/acinclude.m4 b/acinclude.m4 index d7e492856bb..8a7413b9b08 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -715,6 +715,8 @@ AC_MSG_CHECKING(for OpenSSL) [openssl="$withval"], [openssl=no]) + openssl_libs="" + openssl_includes="" if test "$openssl" = "yes" then if test -n "$vio_dir" @@ -722,14 +724,12 @@ AC_MSG_CHECKING(for OpenSSL) AC_MSG_RESULT(yes) openssl_libs="-L/usr/local/ssl/lib -lssl -lcrypto" openssl_includes="-I/usr/local/ssl/include" + AC_DEFINE(HAVE_OPENSSL) else - AC_MSG_ERROR([OpenSSL requires Virtual IO support (--with-vio)]) + AC_MSG_RESULT("disabled because --with-vio wasn't used") fi - AC_DEFINE(HAVE_OPENSSL) else AC_MSG_RESULT(no) - openssl_libs="" - openssl_includes="" fi NON_THREADED_CLIENT_LIBS="$NON_THREADED_CLIENT_LIBS $openssl_libs" AC_SUBST(openssl_libs) @@ -748,16 +748,15 @@ dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@ dnl get substituted. MYSQL_CHECK_ORBIT + fs_dirs="" if test "$mysqlfs" = "yes" then if test -n "$orbit_exec_prefix" then fs_dirs=fs else - AC_MSG_ERROR([mysqlfs requires ORBit, the CORBA ORB]) + AC_MSG_RESULT("disabled because ORBIT, the CORBA ORB, wasn't found"]) fi - else - fs_dirs= fi AC_SUBST([fs_dirs]) ]) diff --git a/configure.in b/configure.in index 14816515e97..df9c6bbec4d 100644 --- a/configure.in +++ b/configure.in @@ -1758,11 +1758,15 @@ AC_ARG_WITH(extra-tools, [with_tools=yes] ) +tools_dirs="" if test "$with_tools" = "yes" then - tools_dirs="tools" -else - tools_dirs="" + if test "$THREAD_SAFE_CLIENT" = "no" + then + echo "Warning: extra-tools disabled because --enable-thread-safe-client wasn't used" + else + tools_dirs="tools" + fi fi AC_SUBST(tools_dirs) diff --git a/include/mysql_com.h b/include/mysql_com.h index 63fbc05b0cb..47908c5f7be 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -104,6 +104,8 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, struct st_vio; /* Only C */ typedef struct st_vio Vio; +#define MAX_BLOB_WIDTH 8192 // Default width for blob + typedef struct st_net { Vio* vio; my_socket fd; /* For Perl DBI/dbd */ diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c index 5c6638b6ef2..d1ea018741d 100644 --- a/myisammrg/myrg_create.c +++ b/myisammrg/myrg_create.c @@ -54,7 +54,7 @@ int myrg_create(const char *name, const char **table_names, if (insert_method != MERGE_INSERT_DISABLED) { end=strxmov(buff,"#INSERT_METHOD=", - get_type(&merge_insert_method,insert_method),"\n",NullS); + get_type(&merge_insert_method,insert_method-1),"\n",NullS); if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP))) goto err; } diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c index ad57ea847d5..d667c5a5475 100644 --- a/myisammrg/myrg_static.c +++ b/myisammrg/myrg_static.c @@ -26,5 +26,5 @@ LIST *myrg_open_list=0; static const char *merge_insert_methods[] = { "FIRST", "LAST", NullS }; -TYPELIB merge_insert_method= { array_elements(merge_insert_methods),"", +TYPELIB merge_insert_method= { array_elements(merge_insert_methods)-1,"", merge_insert_methods}; diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 46ce0fda2c1..a29a9af06da 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -13,3 +13,19 @@ a 18446744073709551615 a 18446744073709551614 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 653e25af799..704b541e25e 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -81,6 +81,56 @@ a 412 412 411 +a b +1 Testing +1 Testing +2 table +2 table +4 Testing +4 Testing +5 table +5 table +6 t2 +6 t1 +7 Testing +7 Testing +8 table +8 table +9 t2 +9 t2 +a b +1 Testing +1 Testing +2 table +2 table +4 Testing +4 Testing +5 table +5 table +9 t2 +9 t2 +a b +1 Testing +1 Testing +2 table +2 table +3 t2 +3 t2 +4 Testing +4 Testing +5 table +5 table +a b +1 Testing +1 Testing +2 table +2 table +3 t2 +3 t2 +4 Testing +4 Testing +5 table +5 table Table Create Table t3 CREATE TABLE `t3` ( `a` int(11) NOT NULL default '0', @@ -130,3 +180,155 @@ a a b 1 1 1 2 +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MyISAM +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM UNION=(t1,t2) +Table Create Table +t5 CREATE TABLE `t5` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2) +Table Create Table +t6 CREATE TABLE `t6` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1,t2) +a b +a b +1 1 +2 1 +1 2 +a b +2 2 +1 3 +2 3 +a b +1 4 +2 4 +a b +1 1 +1 2 +1 3 +1 4 +5 1 +5 2 +a b +2 1 +2 2 +2 3 +2 4 +6 1 +6 2 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +5 1 +5 2 +6 1 +6 2 +a b +3 1 +3 2 +3 3 +3 4 +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM UNION=(t1,t2,t3) +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +3 1 +3 2 +3 3 +3 4 +5 1 +5 2 +6 1 +6 2 +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2,t3) +a b +1 1 +1 2 +1 3 +1 4 +4 1 +4 2 +5 1 +5 2 +a b +2 1 +2 2 +2 3 +2 4 +6 1 +6 2 +a b +3 1 +3 2 +3 3 +3 4 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +3 1 +3 2 +3 3 +3 4 +4 1 +4 2 +5 1 +5 2 +6 1 +6 2 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +4 1 +4 2 +5 1 +5 2 +6 1 +6 2 diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index abb8ef8cb09..96643cc8710 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -131,7 +131,7 @@ auto auto auto auto 16 16 Field Type Null Key Default Extra Privileges -auto bigint(17) PRI 0 select,insert,update,references +auto bigint(17) unsigned PRI 0 select,insert,update,references t1 bigint(1) 0 select,insert,update,references t2 char(1) select,insert,update,references t3 mediumtext select,insert,update,references diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 6470b6f6a30..52ae9ad35db 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -14,3 +14,18 @@ select * from t1 where a='18446744073709551615'; delete from t1 where a=18446744073709551615; select * from t1; drop table t1; + +create table t1 ( a int not null default 1, big bigint ); +insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615); +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 modify big bigint unsigned not null; +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 add key (big); +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 modify big bigint not null; +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +drop table t1; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 188f699cd64..5bd78769a05 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2,7 +2,7 @@ # test of MERGE TABLES # -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5,t6; create table t1 (a int not null primary key auto_increment, message char(20)); create table t2 (a int not null primary key auto_increment, message char(20)); INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1"); @@ -31,6 +31,14 @@ select * from t3 where a > 10 and a < 20; explain select a from t3 order by a desc limit 10; select a from t3 order by a desc limit 10; select a from t3 order by a desc limit 300,10; +delete from t3 where a=3; +select * from t3 where a < 10; +delete from t3 where a >= 6 and a <= 8; +select * from t3 where a < 10; +update t3 set a=3 where a=9; +select * from t3 where a < 10; +update t3 set a=6 where a=7; +select * from t3 where a < 10; show create table t3; # The following should give errors @@ -114,3 +122,49 @@ insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6); flush tables; select * from t3 where a=1 order by b limit 2; drop table t3,t1,t2; + +# +# [phi] testing INSERT_METHOD stuff +# + +drop table if exists t6, t5, t4, t3, t2, t1; +# first testing of common stuff with new parameters +create table t1 (a int not null, b int not null, key(a,b)); +create table t2 (a int not null, b int not null, key(a,b)); +create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO; +create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO; +create table t5 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST; +create table t6 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; +show create table t3; +show create table t4; +show create table t5; +show create table t6; +insert into t1 values (1,1),(1,2),(1,3),(1,4); +insert into t2 values (2,1),(2,2),(2,3),(2,4); +select * from t3 order by b,a limit 3; +select * from t4 order by b,a limit 3; +select * from t5 order by b,a limit 3,3; +select * from t6 order by b,a limit 6,3; +# now testing inserts and where the data gets written +insert into t5 values (5,1),(5,2); +insert into t6 values (6,1),(6,2); +select * from t1 order by a,b; +select * from t2 order by a,b; +select * from t4 order by a,b; +# preperation for next test +insert into t3 values (3,1),(3,2),(3,3),(3,4); +select * from t3 order by a,b; +# now testing whether options are kept by alter table +alter table t4 UNION=(t1,t2,t3); +show create table t4; +select * from t4 order by a,b; +# testing switching off insert method and inserts again +alter table t4 INSERT_METHOD=FIRST; +show create table t4; +insert into t4 values (4,1),(4,2); +select * from t1 order by a,b; +select * from t2 order by a,b; +select * from t3 order by a,b; +select * from t4 order by a,b; +select * from t5 order by a,b; +drop table if exists t6, t5, t4, t3, t2, t1; diff --git a/mysys/typelib.c b/mysys/typelib.c index b18959442ae..f4b638e047e 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -84,7 +84,8 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name) /* Get name of type nr 'nr' */ /* Warning first type is 1, 0 = empty field */ -void make_type(register my_string to, register uint nr, register TYPELIB *typelib) +void make_type(register my_string to, register uint nr, + register TYPELIB *typelib) { DBUG_ENTER("make_type"); if (!nr) diff --git a/sql/field.h b/sql/field.h index b9d8e1957c9..8f60b7e008b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -415,10 +415,11 @@ public: unireg_check_arg, field_name_arg, table_arg, 0, zero_arg,unsigned_arg) {} - Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg) + Field_longlong(uint32 len_arg,bool maybe_null_arg, + const char *field_name_arg, + struct st_table *table_arg, bool unsigned_arg) :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,0) + NONE, field_name_arg, table_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } enum_field_types type() const { return FIELD_TYPE_LONGLONG;} diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index e9cd3f57122..b10939227ff 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -90,7 +90,7 @@ const char *berkeley_lock_names[] = { "DEFAULT", "OLDEST","RANDOM","YOUNGEST",0 }; u_int32_t berkeley_lock_types[]= { DB_LOCK_DEFAULT, DB_LOCK_OLDEST, DB_LOCK_RANDOM }; -TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names),"", +TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names)-1,"", berkeley_lock_names}; static void berkeley_print_error(const char *db_errpfx, char *buffer); diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc index e8130c55fc7..a60841c3fe6 100644 --- a/sql/ha_gemini.cc +++ b/sql/ha_gemini.cc @@ -68,7 +68,7 @@ ulong gemini_recovery_options = GEMINI_RECOVERY_FULL; /* bits in gemini_recovery_options */ const char *gemini_recovery_names[] = { "FULL", "NONE", "FORCE" }; -TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names),"", +TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names)-1,"", gemini_recovery_names}; const int start_of_name = 2; /* Name passed as .// diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 812e0b77077..36d06022d58 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -36,7 +36,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = { "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; -TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", +TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names}; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 92c1372a7a1..88ae8d22f73 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -187,6 +187,11 @@ void ha_myisammrg::info(uint flag) int ha_myisammrg::extra(enum ha_extra_function operation) { + /* As this is just a mapping, we don't have to force the underlying + tables to be closed */ + if (operation == HA_EXTRA_FORCE_REOPEN || + operation == HA_EXTRA_PREPARE_FOR_DELETE) + return 0; return myrg_extra(file,operation); } @@ -285,8 +290,7 @@ void ha_myisammrg::append_create_info(String *packet) if (file->merge_insert_method != MERGE_INSERT_DISABLED) { packet->append(" INSERT_METHOD=",15); - const char *tmp = get_type(&merge_insert_method,file->merge_insert_method); - packet->append(tmp); + packet->append(get_type(&merge_insert_method,file->merge_insert_method-1)); } packet->append(" UNION=(",8); MYRG_TABLE *table,*first; diff --git a/sql/item.cc b/sql/item.cc index dbb9c4ec38d..5eae3a9b542 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -37,7 +37,7 @@ void item_init(void) Item::Item() { marker=0; - binary=maybe_null=null_value=with_sum_func=0; + binary=maybe_null=null_value=with_sum_func=unsigned_flag=0; name=0; decimals=0; max_length=0; next=current_thd->free_list; // Put in free list @@ -116,6 +116,7 @@ void Item_field::set_field(Field *field_par) table_name=field_par->table_name; field_name=field_par->field_name; binary=field_par->binary(); + unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); } const char *Item_ident::full_name() const @@ -326,6 +327,8 @@ void Item::init_make_field(Send_field *tmp_field, tmp_field->type=field_type; tmp_field->length=max_length; tmp_field->decimals=decimals; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; } /* ARGSUSED */ @@ -345,6 +348,7 @@ void Item_uint::make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_LONGLONG); tmp_field->flags|= UNSIGNED_FLAG; + unsigned_flag=1; } void Item_real::make_field(Send_field *tmp_field) diff --git a/sql/item.h b/sql/item.h index 98abdc834d9..9ab41af3398 100644 --- a/sql/item.h +++ b/sql/item.h @@ -43,6 +43,7 @@ public: my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ my_bool binary; + my_bool unsigned_flag; my_bool with_sum_func; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3ef5ed5d7a3..a4d0e1a7ed1 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -184,8 +184,10 @@ String *Item_num_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -213,18 +215,26 @@ String *Item_int_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } -/* Change from REAL_RESULT (default) to INT_RESULT if both arguments are integers */ +/* + Change from REAL_RESULT (default) to INT_RESULT if both arguments are + integers +*/ void Item_num_op::find_num_type(void) { if (args[0]->result_type() == INT_RESULT && args[1]->result_type() == INT_RESULT) + { hybrid_type=INT_RESULT; + unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; + } } String *Item_num_op::val_str(String *str) @@ -234,8 +244,10 @@ String *Item_num_op::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -667,8 +679,10 @@ String *Item_func_min_max::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } case REAL_RESULT: @@ -1306,8 +1320,10 @@ String *Item_func_udf_int::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 12561fe4326..355f28d5432 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -17,7 +17,7 @@ /* This file defines all string functions ** Warning: Some string functions doesn't always put and end-null on a String -** (This shouldn't be neaded) +** (This shouldn't be needed) */ #ifdef __GNUC__ @@ -384,7 +384,7 @@ void Item_func_reverse::fix_length_and_dec() /* ** Replace all occurences of string2 in string1 with string3. -** Don't reallocate val_str() if not neaded +** Don't reallocate val_str() if not needed */ /* TODO: Fix that this works with binary strings when using USE_MB */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 812fc636fef..712c0fa308e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -52,6 +52,8 @@ void Item_sum::make_field(Send_field *tmp_field) tmp_field->flags=0; if (!maybe_null) tmp_field->flags|= NOT_NULL_FLAG; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; tmp_field->length=max_length; tmp_field->decimals=decimals; tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG : @@ -150,7 +152,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) return 1; hybrid_type=item->result_type(); if (hybrid_type == INT_RESULT) - max_length=21; + max_length=20; else if (hybrid_type == REAL_RESULT) max_length=float_length(decimals); else @@ -158,6 +160,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) decimals=item->decimals; maybe_null=item->maybe_null; binary=item->binary; + unsigned_flag=item->unsigned_flag; result_field=0; null_value=1; fix_length_and_dec(); @@ -323,12 +326,27 @@ double Item_sum_hybrid::val() { if (null_value) return 0.0; - if (hybrid_type == STRING_RESULT) - { + switch (hybrid_type) { + case STRING_RESULT: String *res; res=val_str(&str_value); return res ? atof(res->c_ptr()) : 0.0; + case INT_RESULT: + if (unsigned_flag) + return ulonglong2double(sum_int); + return (double) sum_int; + case REAL_RESULT: + return sum; } - return sum; + return 0; // Keep compiler happy +} + +longlong Item_sum_hybrid::val_int() +{ + if (null_value) + return 0; + if (hybrid_type == INT_RESULT) + return sum_int; + return (longlong) Item_sum_hybrid::val(); } @@ -337,25 +355,26 @@ Item_sum_hybrid::val_str(String *str) { if (null_value) return 0; - if (hybrid_type == STRING_RESULT) + switch (hybrid_type) { + case STRING_RESULT: return &value; - str->set(sum,decimals); - return str; + case REAL_RESULT: + str->set(sum,decimals); + break; + case INT_RESULT: + if (unsigned_flag) + str->set((ulonglong) sum_int); + else + str->set((longlong) sum_int); + break; + } + return str; // Keep compiler happy } - bool Item_sum_min::add() { - if (hybrid_type != STRING_RESULT) - { - double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr < sum)) - { - sum=nr; - null_value=0; - } - } - else + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -366,22 +385,39 @@ bool Item_sum_min::add() null_value=0; } } + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr < (ulonglong) sum_int) || + (!unsigned_flag && nr < sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: + { + double nr=args[0]->val(); + if (!args[0]->null_value && (null_value || nr < sum)) + { + sum=nr; + null_value=0; + } + } + break; + } return 0; } bool Item_sum_max::add() { - if (hybrid_type != STRING_RESULT) - { - double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr > sum)) - { - sum=nr; - null_value=0; - } - } - else + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -392,6 +428,31 @@ bool Item_sum_max::add() null_value=0; } } + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr > (ulonglong) sum_int) || + (!unsigned_flag && nr > sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: + { + double nr=args[0]->val(); + if (!args[0]->null_value && (null_value || nr > sum)) + { + sum=nr; + null_value=0; + } + } + break; + } return 0; } @@ -676,9 +737,17 @@ Item_sum_hybrid::min_max_update_int_field(int offset) nr=args[0]->val_int(); if (!args[0]->null_value) { - if (result_field->is_null(offset) || - (cmp_sign > 0 ? old_nr > nr : old_nr < nr)) + if (result_field->is_null(offset)) old_nr=nr; + else + { + bool res=(unsigned_flag ? + (ulonglong) old_nr > (ulonglong) nr : + old_nr > nr); + /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */ + if (cmp_sign > 0 ^ !res) + old_nr=nr; + } result_field->set_notnull(); } else if (result_field->is_null(offset)) @@ -1079,7 +1148,7 @@ void Item_udf_sum::reset() bool Item_udf_sum::add() { - DBUG_ENTER("Item_udf_sum::reset"); + DBUG_ENTER("Item_udf_sum::add"); udf.add(&null_value); DBUG_RETURN(0); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 7356eeda28c..18b0c3ff577 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -271,6 +271,7 @@ class Item_sum_hybrid :public Item_sum protected: String value,tmp_value; double sum; + longlong sum_int; Item_result hybrid_type; int cmp_sign; table_map used_table_cache; @@ -286,12 +287,13 @@ class Item_sum_hybrid :public Item_sum void reset() { sum=0.0; + sum_int=0; value.length(0); null_value=1; add(); } double val(); - longlong val_int() { return (longlong) val(); } /* Real as default */ + longlong val_int(); void reset_field(); String *val_str(String *); void make_const() { used_table_cache=0; } diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index 24af439961e..40b98983291 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -81,7 +81,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1) { cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; - use_async_io=0; /* No nead to use async */ + use_async_io=0; /* No need to use async */ } } } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 34fae62ad56..7a32a253d6c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -71,7 +71,6 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define HASH_PASSWORD_LENGTH 16 #define HOST_CACHE_SIZE 128 #define MAX_ACCEPT_RETRY 10 // Test accept this many times -#define MAX_BLOB_WIDTH 8192 // Default width for blob #define MAX_FIELDS_BEFORE_HASH 32 #define USER_VARS_HASH_SIZE 16 #define STACK_MIN_SIZE 8192 // Abort if less stack during eval. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 67b5ba882d2..5b25b1fe660 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -342,7 +342,7 @@ ulong opt_sql_mode = 0L; const char *sql_mode_names[] = { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; -TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", +TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"", sql_mode_names}; MY_BITMAP temp_pool; @@ -1738,7 +1738,7 @@ int main(int argc, char **argv) pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); #if defined( SET_RLIMIT_NOFILE) || defined( OS2) - /* connections and databases neads lots of files */ + /* connections and databases needs lots of files */ { uint wanted_files=10+(uint) max(max_connections*5, max_connections+table_cache_size*2); @@ -1906,7 +1906,7 @@ The server will not act as a slave."); (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); #ifndef __WIN__ if (!opt_bootstrap) - (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore + (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore #endif exit(1); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0831634a9a6..cc659623f1d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -607,7 +607,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, if (limit < records) read_time=(double) records+scan_time+1; // Force to use index else if (read_time <= 2.0 && !force_quick_range) - DBUG_RETURN(0); /* No nead for quick select */ + DBUG_RETURN(0); /* No need for quick select */ DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time)); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 89910d3745e..4c012804c3e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Basic functions neaded by many modules */ +/* Basic functions needed by many modules */ #include "mysql_priv.h" #include "sql_acl.h" @@ -165,14 +165,15 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) open_list=0; // Out of memory break; } - (*start_list)->table=(strmov((*start_list)->db=(char*) ((*start_list)+1), - entry->table_cache_key)+1, - entry->real_name); + strmov((*start_list)->table= + strmov(((*start_list)->db= (char*) ((*start_list)+1)), + entry->table_cache_key)+1, + entry->real_name); (*start_list)->in_use= entry->in_use ? 1 : 0; (*start_list)->locked= entry->locked_by_name ? 1 : 0; start_list= &(*start_list)->next; + *start_list=0; } - *start_list=0; VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(open_list); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1d2805d8e90..54c3e91bcc3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -391,7 +391,7 @@ int write_record(TABLE *table,COPY_INFO *info) } else { - if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not neaded with NISAM */ + if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */ { error=my_errno; goto err; @@ -534,7 +534,7 @@ public: } ~delayed_insert() { - /* The following is not really neaded, but just for safety */ + /* The following is not really needed, but just for safety */ delayed_row *row; while ((row=rows.get())) delete row; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ff404cce0d6..ec147c38e9b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -22,7 +22,7 @@ class Table_ident; class sql_exchange; class LEX_COLUMN; -// The following hack is neaded because mysql_yacc.cc does not define +// The following hack is needed because mysql_yacc.cc does not define // YYSTYPE before including this file #ifdef MYSQL_YACC diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c6e23eb927a..929891da889 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -855,7 +855,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("info",("query ready")); break; } - case COM_FIELD_LIST: // This isn't actually neaded + case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ break; @@ -2390,7 +2390,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize) /**************************************************************************** - Initialize global thd variables neaded for query + Initialize global thd variables needed for query ****************************************************************************/ static void diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3aa534222e7..c122ba51a96 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3306,7 +3306,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, item->name,table,item_sum->decimals); case INT_RESULT: return new Field_longlong(item_sum->max_length,maybe_null, - item->name,table); + item->name,table,item->unsigned_flag); case STRING_RESULT: if (item_sum->max_length > 255) return new Field_blob(item_sum->max_length,maybe_null, @@ -3357,7 +3357,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, break; case INT_RESULT: new_field=new Field_longlong(item->max_length,maybe_null, - item->name,table); + item->name,table, item->unsigned_flag); break; case STRING_RESULT: if (item->max_length > 255) diff --git a/sql/structs.h b/sql/structs.h index 12ba5004a2e..469d3feea08 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -170,7 +170,7 @@ typedef struct st_lex_user { /* Bits in form->status */ #define STATUS_NO_RECORD (1+2) /* Record isn't usably */ #define STATUS_GARBAGE 1 -#define STATUS_NOT_FOUND 2 /* No record in database when neaded */ +#define STATUS_NOT_FOUND 2 /* No record in database when needed */ #define STATUS_NO_PARENT 4 /* Parent record wasn't found */ #define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_UPDATED 16 /* Record is updated by formula */ diff --git a/sql/time.cc b/sql/time.cc index d1e0aee0fa4..440cba457f4 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -24,7 +24,7 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037"; - /* Init some variabels neaded when using my_local_time */ + /* Init some variabels needed when using my_local_time */ /* Currently only my_time_zone is inited */ static long my_time_zone=0; diff --git a/sql/unireg.cc b/sql/unireg.cc index c5bfbbbea88..b0dd3471a64 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -20,7 +20,7 @@ struct. In the following functions FIELD * is an ordinary field-structure with the following exeptions: - sc_length,typepos,row,kol,dtype,regnr and field nead not to be set. + sc_length,typepos,row,kol,dtype,regnr and field need not to be set. str is a (long) to record position where 0 is the first position. */ @@ -391,8 +391,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, int2store(forminfo+272,int_parts); int2store(forminfo+274,int_length); int2store(forminfo+276,time_stamp_pos); - int2store(forminfo+278,80); /* Columns neaded */ - int2store(forminfo+280,22); /* Rows neaded */ + int2store(forminfo+278,80); /* Columns needed */ + int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); DBUG_RETURN(0); } /* pack_header */ From a4bc23add63c1eb20e6bb6cd65fa761b2ec2c19b Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Thu, 27 Sep 2001 22:02:37 +0300 Subject: [PATCH 09/38] Fixed bug in counting open files when using many files Fixed bug in JOIN --- Docs/manual.texi | 3 +++ mysql-test/r/join.result | 2 ++ mysql-test/r/null_key.result | 2 +- mysql-test/t/join.test | 23 +++++++++++++++++++++++ mysys/my_open.c | 5 ++--- sql/sql_select.cc | 24 ++++++++++++++---------- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 6dd44a79288..050fd76ab47 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46853,6 +46853,9 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.43 @itemize @bullet @item +Fixed unlikely bug, which returned not matching rows, in SELECT with +many tables and multi-column indexes and 'range' type. +@item Fixed a unlikely core-dump bug when doing @code{EXPLAIN SELECT} when using many tables and @code{ORDER BY}. @item diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 3c5a72edc68..7db456a1af5 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -20,3 +20,5 @@ id catid stateid countyid a 1 2 +a a b +2 2 3 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index ead1dc29326..d0d59cdebf8 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -11,7 +11,7 @@ t1 index NULL a 9 NULL 12 where used; Using index table type possible_keys key key_len ref rows Extra t1 range a,b a 9 NULL 3 where used; Using index table type possible_keys key key_len ref rows Extra -t1 ref a,b b 4 const 2 where used +t1 range a,b a 9 NULL 2 where used; Using index table type possible_keys key key_len ref rows Extra t1 ref a,b a 5 const 3 where used; Using index table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 6fff628ccb9..224db1dd8f0 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -89,3 +89,26 @@ select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using --error 1116 select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a); drop table t1; + +# +# Simple join test. This failed in 3.23.42, there should have been +# no matches, still three matches were found. +# + +CREATE TABLE t1 ( + a int(11) NOT NULL, + b int(11) NOT NULL, + PRIMARY KEY (a,b) +) TYPE=MyISAM; + +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3); + +CREATE TABLE t2 ( + a int(11) default NULL +) TYPE=MyISAM; + +INSERT INTO t2 VALUES (2),(3); + +SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3; + +DROP TABLE t1, t2; diff --git a/mysys/my_open.c b/mysys/my_open.c index 2ed1af1eca1..748113528a1 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -75,8 +75,8 @@ int my_close(File fd, myf MyFlags) pthread_mutex_destroy(&my_file_info[fd].mutex); #endif my_file_info[fd].type = UNOPEN; - my_file_opened--; } + my_file_opened--; pthread_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(err); } /* my_close */ @@ -96,9 +96,8 @@ File my_register_filename(File fd, const char *FileName, enum file_type my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), FileName, my_errno); return(-1); -#else - thread_safe_increment(my_file_opened,&THR_LOCK_open); #endif + thread_safe_increment(my_file_opened,&THR_LOCK_open); return(fd); /* safeguard */ } pthread_mutex_lock(&THR_LOCK_open); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 56ba4baed30..e97fa3b0abf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2258,7 +2258,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { JOIN_TAB *tab=join->join_tab+i; table_map current_map= tab->table->map; + bool use_quick_range=0; used_tables|=current_map; + + if (tab->type == JT_REF && tab->quick && + tab->ref.key_length < tab->quick->max_used_key_length) + { + /* Range uses longer key; Use this instead of ref on key */ + tab->type=JT_ALL; + use_quick_range=1; + tab->use_quick=1; + tab->ref.key_parts=0; // Don't use ref key. + join->best_positions[i].records_read=tab->quick->records; + } + COND *tmp=make_cond_for_table(cond,used_tables,current_map); if (!tmp && tab->quick) { // Outer join @@ -2301,7 +2314,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tab->const_keys && tab->table->reginfo.impossible_range) DBUG_RETURN(1); } - else if (tab->type == JT_ALL) + else if (tab->type == JT_ALL && ! use_quick_range) { if (tab->const_keys && tab->table->reginfo.impossible_range) @@ -2356,15 +2369,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } } } - if (tab->type == JT_REF && sel->quick && - tab->ref.key_length < sel->quick->max_used_key_length) - { - /* Range uses longer key; Use this instead of ref on key */ - tab->type=JT_ALL; - tab->use_quick=1; - tab->ref.key_parts=0; // Don't use ref key. - join->best_positions[i].records_read=sel->quick->records; - } } } } From 384ae2eff0f543e775a9ae7b8b4e34cdde8f2347 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 07:21:24 +0300 Subject: [PATCH 10/38] Fixed that one can always get a name for a compiled characterset --- Docs/manual.texi | 58 ++++++++++++++++++++++++++++++++++++++------- acinclude.m4 | 8 +++++-- include/m_ctype.h | 2 ++ mysys/charset.c | 35 +++++++++++---------------- sql/gen_lex_hash.cc | 2 +- 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index b1815b4eac9..5f1e4480005 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -19777,6 +19777,10 @@ joins that don't use keys properly. @item If @code{Threads_created} is big, you may want to increase the @code{thread_cache_size} variable. +@item +If @code{Created_tmp_disk_tables} is big, you may want to increase the +@code{tmp_table_size} variable to get the temporary tables memory based +instead of disk based. @end itemize @@ -20411,6 +20415,7 @@ Create Table: CREATE TABLE t ( * Character arrays:: The character definition arrays * String collating:: String Collating Support * Multi-byte characters:: Multi-byte Character Support +* Problems with character sets:: @end menu @@ -20744,7 +20749,7 @@ the maximum ratio the strings may grow during @code{my_strxfrm_MYSET} (it must be a positive integer). -@node Multi-byte characters, , String collating, Localization +@node Multi-byte characters, Problems with character sets, String collating, Localization @subsection Multi-byte Character Support @cindex characters, multi-byte @@ -20763,6 +20768,41 @@ You must specify the @code{mbmaxlen_MYSET=N} value in the special comment at the top of the source file. @code{N} should be set to the size in bytes of the largest character in the set. +@node Problems with character sets, , Multi-byte characters, Localization +@subsection Problems With Character Sets + +If you try to use a character set that is not compiled into your binary, +you can run into a couple of different problems: + +@itemize @bullet +@item +Your program has a wrong path to where the character sets are stored. +(Default @file{/usr/local/mysql/share/mysql/charsets}). +This can be fixed by using the @code{--character-sets-dir} +option to the program in question. +@item +The character set is a multi-byte-character set that can't be loaded +dynamicly. In this case you have to recompiled the program with the +support for the character set. +@item +The character set is a dynamic character set, but you don't have a +configure file for it. In this case you should install the configure +file for the character set from a new MySQL distribution. +@item +Your @file{Index} file doesn't contain the name for the character set. + +@example +ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found +(Errcode: 2) +@end example + +In this case you should either get a new @code{Index} file or add +by hand the name of any missing character sets. +@end itemize + +For MyISAM tables, you can check the character set name and number for a +table with @code{myisamchk -dvv table_name}. + @node Server-Side Scripts, Client-Side Scripts, Localization, MySQL Database Administration @section MySQL Server-Side Scripts and Utilities @@ -39313,7 +39353,7 @@ likely it is that we can fix the problem! * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions * C Thread functions:: C Thread Functions -* C Embedded Server functions:: C Embedded Server Functions +* C Embedded Server functions:: C Embedded Server functions. C Embedded Server Functions * C API problems:: Common questions and problems when using the C API * Building clients:: Building Client Programs * Threaded clients:: How to Make a Threaded Client @@ -42014,9 +42054,9 @@ You need to use the following functions when you want to create a threaded client. @xref{Threaded clients}. @menu -* my_init():: @code{my_init()} -* mysql_thread_init():: @code{mysql_thread_init()} -* mysql_thread_end():: @code{mysql_thread_end()} +* my_init():: @code{my_init()} +* mysql_thread_init():: @code{mysql_thread_init()} +* mysql_thread_end():: @code{mysql_thread_end()} @end menu @node my_init(), mysql_thread_init(), C Thread functions, C Thread functions @@ -42084,8 +42124,8 @@ possible to choose between using the embedded MySQL server and a stand-alone server without modifying any code. @menu -* mysql_server_init():: -* mysql_server_end():: +* mysql_server_init():: +* mysql_server_end():: @end menu @node mysql_server_init(), mysql_server_end(), C Embedded Server functions, C Embedded Server functions @@ -42338,7 +42378,7 @@ For clients that use MySQL header files, you may need to specify a files. -@node Threaded clients, libmysqld , Building clients, C +@node Threaded clients, libmysqld, Building clients, C @subsection How to Make a Threaded Client @cindex clients, threaded @@ -42812,7 +42852,7 @@ clean: rm -f $(targets) $(objects) *.core @end example -@node libmysqld licensing, , libmysqld example, libmysqld +@node libmysqld licensing, , libmysqld example, libmysqld @subsubsection Licensing the Embedded Server The MySQL source code is covered by the GNU GPL license diff --git a/acinclude.m4 b/acinclude.m4 index 8a7413b9b08..260e9b127b9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -726,7 +726,7 @@ AC_MSG_CHECKING(for OpenSSL) openssl_includes="-I/usr/local/ssl/include" AC_DEFINE(HAVE_OPENSSL) else - AC_MSG_RESULT("disabled because --with-vio wasn't used") + AC_MSG_RESULT(disabled because --with-vio wasn not used) fi else AC_MSG_RESULT(no) @@ -748,15 +748,19 @@ dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@ dnl get substituted. MYSQL_CHECK_ORBIT + AC_MSG_CHECKING(if we should build MySQLFS) fs_dirs="" if test "$mysqlfs" = "yes" then if test -n "$orbit_exec_prefix" then fs_dirs=fs + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT("disabled because ORBIT, the CORBA ORB, wasn't found"]) + AC_MSG_RESULT(disabled because ORBIT, the CORBA ORB, was not found) fi + else + AC_MSG_RESULT([no]) fi AC_SUBST([fs_dirs]) ]) diff --git a/include/m_ctype.h b/include/m_ctype.h index b41323e10b9..86a67541d73 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -57,6 +57,8 @@ extern CHARSET_INFO *default_charset_info; extern CHARSET_INFO *find_compiled_charset(uint cs_number); extern CHARSET_INFO *find_compiled_charset_by_name(const char *name); extern CHARSET_INFO compiled_charsets[]; +extern uint compiled_charset_number(const char *name); +extern const char *compiled_charset_name(uint charset_number); #define MY_CHARSET_UNDEFINED 0 #define MY_CHARSET_CURRENT (default_charset_info->number) diff --git a/mysys/charset.c b/mysys/charset.c index f778afb4144..1bbf7e58c77 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -44,13 +44,6 @@ struct simpleconfig_buf_st { char *p; }; -/* Defined in strings/ctype.c */ - -CHARSET_INFO *find_compiled_charset(uint cs_number); -uint compiled_charset_number(const char *name); -const char *compiled_charset_name(uint charset_number); - - static uint num_from_csname(CS_ID **cs, const char *name) { CS_ID **c; @@ -264,22 +257,22 @@ static my_bool read_charset_file(uint cs_number, CHARSET_INFO *set, uint get_charset_number(const char *charset_name) { - my_bool error; - error = init_available_charsets(MYF(0)); /* If it isn't initialized */ - if (error) - return compiled_charset_number(charset_name); - else - return num_from_csname(available_charsets, charset_name); + uint number=compiled_charset_number(charset_name); + if (number) + return number; + if (init_available_charsets(MYF(0))) /* If it isn't initialized */ + return 0; + return num_from_csname(available_charsets, charset_name); } const char *get_charset_name(uint charset_number) { - my_bool error; - error = init_available_charsets(MYF(0)); /* If it isn't initialized */ - if (error) - return compiled_charset_name(charset_number); - else - return name_from_csnum(available_charsets, charset_number); + char *name=compiled_charset_name(charset_number); + if (*name != '?') + return name; + if (init_available_charsets(MYF(0))) /* If it isn't initialized */ + return "?"; + return name_from_csnum(available_charsets, charset_number); } @@ -293,8 +286,8 @@ static CHARSET_INFO *find_charset(CHARSET_INFO **table, uint cs_number, return NULL; } -static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name, - size_t tablesz) +static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, + const char *name, size_t tablesz) { uint i; for (i = 0; i < tablesz; ++i) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 6530e5dd4cf..2358dde7b6d 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -474,7 +474,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=1060872L; best_t1=7930739L; best_t2=4311642L; best_type=3; /* mode=5333 add=6 type: 0 */ + start_value=1109118L; best_t1=6657025L; best_t2=6114496L; best_type=1; /* mode=4903 add=3 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); From f8828f0977c6dfc7abc1c0195309a032cda002e8 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 07:42:18 +0300 Subject: [PATCH 11/38] Portability fix --- mysys/charset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/charset.c b/mysys/charset.c index 1bbf7e58c77..ddabb22539e 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -267,7 +267,7 @@ uint get_charset_number(const char *charset_name) const char *get_charset_name(uint charset_number) { - char *name=compiled_charset_name(charset_number); + const char *name=compiled_charset_name(charset_number); if (*name != '?') return name; if (init_available_charsets(MYF(0))) /* If it isn't initialized */ From e17d59d34ae2189cc3059dd3df3dc5158152327f Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 14:33:52 +0300 Subject: [PATCH 12/38] Fix that postscript generation of the manual works again --- Docs/manual.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index eb28dcfcb23..128fd814e31 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -1,4 +1,4 @@ -input texinfo @c -*-texinfo-*- +\input texinfo @c -*-texinfo-*- @c Copyright 1997-2001 TcX AB, Detron HB and MySQL Finland AB @c @c ********************************************************* From a99b7e77cdd839a46f90efdab57c9cc843805393 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 14:34:52 +0300 Subject: [PATCH 13/38] Update version number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a67f05d342f..cfdbe51b987 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 3.23.42) +AM_INIT_AUTOMAKE(mysql, 3.23.43) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 530882c55b39839bb1aab52012073d71c1660951 Mon Sep 17 00:00:00 2001 From: "paul@central.snake.net" <> Date: Fri, 28 Sep 2001 10:49:31 -0500 Subject: [PATCH 14/38] manual.texi typos --- Docs/manual.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 128fd814e31..cd730aa321a 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -13948,8 +13948,8 @@ MySQL. Some of the examples use the table @code{shop} to hold the price of each article (item number) for certain traders (dealers). Supposing that each -trader has a single fixed price per article, then (@code{item}, -@code{trader}) is a primary key for the records. +trader has a single fixed price per article, then (@code{article}, +@code{dealer}) is a primary key for the records. Start the command line tool @code{mysql} and select a database: @@ -14158,7 +14158,7 @@ splitting of the concatenated column in the client. @subsection Using user variables You can use MySQL user variables to remember results without -having to store them in a temporary variables in the client. +having to store them in temporary variables in the client. @xref{Variables}. For example, to find the articles with the highest and lowest price you From ba26a07692f147999824b9199fa29b5873259082 Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Fri, 28 Sep 2001 10:54:10 -0500 Subject: [PATCH 15/38] manual.texi typos --- Docs/manual.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 8349f8c9ef4..054283f8bfc 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -13997,8 +13997,8 @@ MySQL. Some of the examples use the table @code{shop} to hold the price of each article (item number) for certain traders (dealers). Supposing that each -trader has a single fixed price per article, then (@code{item}, -@code{trader}) is a primary key for the records. +trader has a single fixed price per article, then (@code{article}, +@code{dealer}) is a primary key for the records. Start the command line tool @code{mysql} and select a database: @@ -14207,7 +14207,7 @@ splitting of the concatenated column in the client. @subsection Using user variables You can use MySQL user variables to remember results without -having to store them in a temporary variables in the client. +having to store them in temporary variables in the client. @xref{Variables}. For example, to find the articles with the highest and lowest price you From 18eccc553ea135c780fb0dfc09b951ec4d42ee62 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 20:09:00 +0300 Subject: [PATCH 16/38] Added hints and information about ROW_FORMAT to manual --- Docs/manual.texi | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 3491ed83102..f49a2b77b87 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -3384,6 +3384,7 @@ around some differences. @node Extensions to ANSI, Differences from ANSI, Compatibility, Compatibility @subsection MySQL Extensions to ANSI SQL92 +@cindex hints MySQL includes some extensions that you probably will not find in other SQL databases. Be warned that if you use them, your code will not be portable to other SQL servers. In some cases, you can write code that @@ -32392,11 +32393,13 @@ read the @code{GROUP BY} description. @xref{Group by functions}. @item +@cindex hints @code{SQL_BUFFER_RESULT} will force the result to be put into a temporary table. This will help MySQL free the table locks early and will help in cases where it takes a long time to send the result set to the client. @item +@cindex hints @code{SQL_SMALL_RESULT}, a MySQL-specific option, can be used with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the result set will be small. In this case, MySQL will use fast @@ -32404,6 +32407,7 @@ temporary tables to store the resulting table instead of using sorting. In MySQL Version 3.23 this shouldn't normally be needed. @item +@cindex hints @code{STRAIGHT_JOIN} forces the optimizer to join the tables in the order in which they are listed in the @code{FROM} clause. You can use this to speed up a query if the optimizer joins the tables in non-optimal order. @@ -32621,11 +32625,13 @@ portable across databases, it's recommended to use @code{LEFT JOIN} instead of @code{RIGHT JOIN}. @item +@cindex hints @code{STRAIGHT_JOIN} is identical to @code{JOIN}, except that the left table is always read before the right table. This can be used for those (few) cases where the join optimizer puts the tables in the wrong order. @item +@cindex hints As of MySQL Version 3.23.12, you can give hints about which index MySQL should use when retrieving information from a table. This is useful if @code{EXPLAIN} shows that MySQL is @@ -34129,7 +34135,7 @@ The options work for all table types, if not otherwise indicated: @item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). @item @code{PASSWORD} @tab Encrypt the @code{.frm} file with a password. This option doesn't do anything in the standard MySQL version. @item @code{DELAY_KEY_WRITE} @tab Set this to 1 if want to delay key table updates until the table is closed (MyISAM). -@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently you can only use the DYNAMIC and STATIC options for MyISAM tables. +@item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently this option only works with MyISAM tables, which supports the @code{DYNAMIC} and @code{FIXED} row formats. @xref{MyISAM table formats}. @end multitable When you use a @code{MyISAM} table, MySQL uses the product of @@ -35649,6 +35655,13 @@ high-byte first. automatically depending on the type of columns you are using. The third, compressed tables, can only be created with the @code{myisampack} tool. +When you @code{CREATE} or @code{ALTER} a table you can for tables that +doesn't have @code{BLOB}'s force the table format to @code{DYNAMIC} or +@code{FIXED} with the @code{ROW_FORMAT=#} table option. In the future +you will be able to compress/decompress tables by specifying +@code{ROW_FORMAT=compressed | default} to @code{ALTER TABLE}. +@xref{CREATE TABLE}. + @menu * Static format:: Static (Fixed-length) table characteristics * Dynamic format:: Dynamic table characteristics From ae2893b221ad680ed8d1b5088376630bfb7624ed Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 20:28:59 +0300 Subject: [PATCH 17/38] Changed flags to a portable file format --- Docs/Flags/belgium.eps | Bin 13481 -> 11665 bytes Docs/Flags/belgium.gif | Bin Docs/Flags/mexico.eps | Bin 13844 -> 11908 bytes Docs/Flags/mexico.gif | Bin Docs/Flags/philippines.eps | Bin 12465 -> 10721 bytes Docs/Flags/philippines.gif | Bin Docs/Flags/turkey.eps | Bin 12154 -> 10511 bytes Docs/Flags/turkey.gif | Bin 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Docs/Flags/belgium.gif mode change 100755 => 100644 Docs/Flags/mexico.eps mode change 100755 => 100644 Docs/Flags/mexico.gif mode change 100755 => 100644 Docs/Flags/philippines.eps mode change 100755 => 100644 Docs/Flags/philippines.gif mode change 100755 => 100644 Docs/Flags/turkey.gif diff --git a/Docs/Flags/belgium.eps b/Docs/Flags/belgium.eps index 9d2fdcf2295bc0006073a9426511822e0e7b8b67..295021fae58616f512c2dcfe28096699ffafda8e 100644 GIT binary patch delta 2206 zcmeHI&2Jl35LfwV;t6SS9NTd|Us4?M(PZtln}(=>;!WE05Gjo-A(V31cwg*QHv6`_ z>x9U%q8>PKD3Fdg0YW_>ksCdL)B{HjNN_I~u80GI6A}kh=Dm%RG_?N!Vy&Nc-pqS5 zZ+#1Q%2%a;`q@{Lkj>t-Lx<0?b?#K{`qnh}0`$&~ z?~$b>>aJzG)slF3j^*fA(3!52VaZk2o^+m&9q%ZY8fm3dhAB8w97a@#}-4v*DDD1w^s=2%`Y&fspFf!`9& zv>Uicc%SeiAs#c@Aj@*};BagbAID<&QLO!W($RYC9<<9P{xH~5v3o!kFpv`t2)_~X z9R~j0F^Zpb4B$g08#w=xf$tH%CvzFG zcM}@;dm;@iH+_jYA>C0fG3f5^fG7;3F!*VAPdjK1-{y{v=aUS7?jFOoKA zWGa-oKa1r^ib5T(Z&ux`2*4H~~qvbLbgyLzpJLp^D{+~eN@&9f^(=;x&q zded-5jw7}HbamnB>f)1XgiHb7$c$qxGf{#CUJ({&4tJ|zjp=kF>Y)WQG|QsySI8ht zi`ga)b{YAs}{W~9JB`!3p`mFzHB;lBKk370-xY*w8OBD{$Y`^WY`xs!u@BGh4s6HXe?YLM1( zMqPiXJob4)SvU%GLRmagMnpER9F8PZ>b_4DC|0RVtxtH#c1?eGjz!O>?zrn+)dUrzf4<0oM){3L}VX@~7`~w(d(v1KB literal 13481 zcmeHNdypK(d7r(Pj?>+tvm~H!IT>UQ94hFhyXUEjk>`od7_8{Pq(ZQ=x}7_1wAwv( z_w?{tWgZ3>b{RhaV@%l?1HqU$74UN24t}-dxpcqh$@kz)w*o8|Nuw|ln^6Q?N z-PyZcM=JhFB|B5Q)BSy4fBp6Ed-QDIeftOdA3J?Ol0LRxYFvMW*0Fv`ilWKMbEHA^ zMy20NeNrx!$n}c0jD9X@pMrKz(&lo#nf5@^23Z=*#d_|7{lbr<9ql(K?Qfv{wnV-M?aAwM(sO;1^cdRwy7JhNwCe2U({v^;?0reFR!N)i%t<}z zlk@sU1P>adJwo;s(dP>nmyj6}O)QP~&R!*YLk&oJ#JJZ4b(1tPGXqWu-#`{uE}`6U z>t`AiD(HWS?^H$;lyjRDq4OyEk~GJ?(eCPffwS9jqUeqA#F}FS_*${urG&B3kE9Pu!-Io^Ck+mtbkgwH%Au8GYfl~?K6&kFt5>gGz52AVVR0poxU=*- zH?nf&$mqzb(a}|FMn^~2@UPJ|@sP3OQ4oDo8XLp{L=V487N^tf~cU}9{n;-r6!>```wQv9Mr?0(dX4iF}`rEHR_SDaQ zW1N5K?CuZUa?gX`dHUzS9g})`U~QkUX~jUlCQLYkyr~ZsT(NF-KfUS`Yq$m9+VaE^ zcILK&)vG`0POY7;sV|QYa06DHr9JW_jJWgEf`5r#4-Yj==xo8+O%tO3kcNB3oMX~P z>DPC^xbe`_cfI;|&t1Fkp-TaMI`<1mv0H*ziZ3K&V1M8_0QjMzxw^}URmAo%mc5#_{96pGcNejzmGAFQ4JXQ!Tg<413Jc45=KS6*jcefnAX_f0(g{ok#-{h0ET*FSR0?coRf ze}4UjW7kd{y=e0BTdu$9`qw`D_>?0+y?9Qbnd;#r(V-Q$MTy0H2Ue8FJa7m(V>Btq9ZpNX#X%ee9i7?(Z7V(lkqb)Pn|1L^IW!Gk^Rk6 z0dI^9jgPz4Fki1!H^_o5Z{A+1S8CfUbMkw_YOPo)%i4O4%UxWom%&%{-pPQ?OwVGF{pPw(5-OA3nuw2X6F)P>WmkS{649j(4kQ2@p%bTl}Qe`&bHamhh z71rnH5?0!t+?k&Zv4s4F*ecnSnM_1mUbl^FEOLo;7#8bKLE0b_s_G!i%v7mrsh+}o zPib5PE!9lAyaQNT`{_8YLs6B?SoFkYn5m4y0+#6Fk5q4i)MAIK*bN4J!P}`GYKU&i z=5h^!up{QsR37tcsc>vR4Rl=bINeR!yf3aq2XtoTY+_j!pQ|BDUGi zYBoj)Pj^`Wk@}k^A(lSDY>p)fQ;bO4gzIR^C~l&UyC-PT%|l&WB=J%5Fx93VOhr5s zjxz}Y&kO>eHx<=Zb>tEsK%fTx<~bAR4P>~G&+Sl&uIhnKbwq~VNGqYsL3(hTT_C`3 z3m+HXmf{kkILHl$h_w(+3BYlcfM~=d47Vn}O~`S2a<}$Us^SVv8&XaBk`_T`JGec? zS3E4pSA3!XVLaot5H;dnxBQ?QnyDy9_#jDEAD!#1ulgvv@I;RAJrqErQk@V+QTX6us^~m)=7#tl{Q8{r;xDKSf0nnGBf~e(thzlGV(ZDg{u^UiZ^DP$m)DxK69DmpIP0jEe z%Q9i5>Y1Jkd{yTAwq*vu(6oKi&^^z?>O9{I3>q-3#C%TBhYQ6AY%hfoq!_Fo&3QPp1#9qcp)pSfFa{7$ zkmYv7=pt@(ljG`8+f|%^dbU9^)U&V>6IIagm<_}N+l4+fUsed})hsI@jvc@$ zKBCX|0U;nWTn2u_x7+Fjtni#;YB_}o^ZKnP2N$i z?8e*kLL1g>SeL^+;WXZVXY2bQGm|gX!hLdaCge{LCTjJ3eZE#GPS;!J$&e@Js+DQH zvkS|b({+~kpJ!caMr_Z>P$8Td8B!Hlm?PfRfy7qvzAo4H*6QI-!I_9Dd>%1kVrwm| z&sOt$TZB?tMr?Y%TE&lxWujSnMjRUI)qJ@&6IPdMZqPI0iIxT{Yw=QEbJ(_0zPtlJ zp|&m+;f@;_BJCM+ctx`IayX0MPY5NU2rliQN>wC4byM}|3B(mYu8b6m1nIle6aKL)>R#Uzp2JhjLO=;;Px$e7t#_3zb8c%S{P6 z9Or~He^}Zs)t3#3!I+pUPS@&HamIot&V`Z%#&pWp*oMwJ(A8yhoN5&cIMI<8lJ(3K zOJN+{oV7jNlc+~#Bv}@35mZi*Oty?tC0~d$Y+)hUUoI^c>f7O{;_UXi>=f&@&0&?F zO97yAT^4S_1F^HM|cqxQ16Jo0^jq~kA~FV%~4C2?FDhj2|6p%&Yc z36sm9DNXY<9XWbwiZ7=z)b}K9V<9y|K%R~a2`j`)Xp$$~#MHFR+;HmBsreq8QfZ6c zl$xEsDciJxS5T}H)2BYp)=ESfUfAOUVy9TnSNCp^<4ePjF$7uT92tAl8@&E+Ye>&L zvrqgSUUn<^mDV0e4`(M!@Ai_NG_;p)NA0A+b(Y`ES$=n3MRxsZdpQa&PVqX~uoMH{ zZ?}fd8rn;@qjs`kISOtY6c|oyJ84MQo_%(4h|%cc(8Zyf7g+?l@sLHMTOYdd(2a*I z0^NAXqS37n-FWE6Ll%K=6)`xC9bmJk5KsO$;X#9Vy5A9CB+S59nXtkGaNB!TS xfgfz+Us2*?ZT!I!|Buc8L@MLV8~=_X{{A3eT+QQ8Z1}@v!pw*z|FP0w{5Jq?Na+9o diff --git a/Docs/Flags/belgium.gif b/Docs/Flags/belgium.gif old mode 100755 new mode 100644 diff --git a/Docs/Flags/mexico.eps b/Docs/Flags/mexico.eps old mode 100755 new mode 100644 index 716851cfe7e6108d1dc5a9ae0fb908d50faa8b4d..907642cfec20acf8a4492c7b19cae6b4421cf19f GIT binary patch delta 2142 zcmchYO>7%Q6o7?NVtbl|HgUZ1FXJTsjT0w!8ilA*el~3r1R`pR5Gp}zyc2t=v+M4z z^P{a54n6S`DqaPLNLBa|5*$z^IB;nx5)wD4fCIM%l~YtC4j}cwfj7I3^HXs`>fzJ8 z_h#OknfKo8UN2u=fX!wBK5b5TNi23jG0SX>F0(bIpbfB!0r#6z(CYHLadJjE&kQ)> z^1)eGWC9ImR9V!PmzioBs75eD5Nn8?@2KgfhfgsUF0iNq+p>luY{;)XfW12;Wx_y!p#Cr}sRI`S(L zIxfO%$R|jpB@S&ZVaT*_S%j~Uhsfzx5#B()L)>j5JcnFEenGmP65$nO8~Ghco)Dpo z+(iCDMo)@x1-XM9YZqY#c^kQlcsmlO2~W@5-o;4KkX9It(KB=N)RsxMBpC(FmQJ!V zTTu#3QI|BjT4FkbD;*Ko>gY)kYe^~_tVWe3#z$gh4O23!hO87!XDzWRT7^Q3H}K>o zRa;eoc+<~3>USiL6OYJji3|@?JK7?z9~j)YEWSp7Tb-_^J^5Z|u!lJNIWCI2!gQ0#F5GPGmc2QDgIzkOo z)9uG9zWS!pb>n5j*rCPlZLY z({|sSKQ~2c)XKIy>N#D)V>$_kkNmnovK6IZnEDV8jH99!`DV}`5E^s&BXbJ@0jhyK zd=^N-cqlzZrddIg87(ulXqIRW4}iTmEt%3h7O8*}nj}+&Uytv7Wcdg#2QfIDBBowt zG>@sozW=Y)qt5Cc_&(U3a6EYO4|yY7bjU4v440&aTe^=KZGO0ShoGNUBu^GFOH5~A>#}_a>tazUaOm+ zH!wsX8shUuK#H3Kwb^PYrX~R0e zACbUuvY&C7I5l~QZQ2JfM1AloorG;&67C|q(J15-6!#9pnAfw7|ZZ&g785m4!1Mt?zk-UbC)oD*zcU| wK8`!dD5M4`JUj5XGWKXyj#RUiIREe|MV0h*`1w@aPl`ITKXrS*x4KIH1ux&r$N&HU delta 4425 zcmds3dsq`!7N5zBFl0gkB!B@O9svav0|>0GHK4rO)hhUEt!+axfvh2kNf0TEL07F` zAGUhkYWHi`^}SsdsoF}}+G1-<+ubU@QE9c-SFMk>wzi73*>mqCfUNF*`{(X_Uw(7W z@0@$?IrpA>GmB@hvim;Vf2d=*jG~riP`%G!kX*p|{iUU8lpHiA^$R7T=%5EJCNc*) z9gwvkivlwC6Zey40U2mYO$%{iAijnc`$!->K-(`+biipQ@PlY6@!1KoE+D@P^3Z_4 z2;|bGG*u?0s1A_v)A%z(sZ#sic?G2t#aD<)MU}vtrbNQqM~Sde!V;qda6WPVp6IxA z@(>?}h>$DRQdLA_NN!jpam3dNTS8@6tzfYOLY?r?0cPFHf9Pd0f%nnWqwoqkjV7)m z`WTYT4bWjn@P^#&5r2ivceD8Y|HmN?_z7zui2{~_#sC}fRbW+o z2UvzkGaJ&Dr=u!y`}Y|t_we@DUk@$mH0?jAu{P` zl0$+aLINqwO^lRgE?g0XQ+TiJz_(e+6{p>cR*o;%m_6Cw>18;Bkd)EyAA~G6L|Y1{ z<#_oodvmyV3aNcL_)ky@G3-ASuBOIOyD#1zN8gC)Trhf)=PxGDvx7?Y%_}DzIn_|o z({{Z+ebX%K!w>Cw=S;$0<@RSz8jnxuZoB+I`m&4d*XCvXJkfW3#O&!QIgTd|f40kR z9rO3gAN&4#qT|Avt!QF(%c1sTmv%bq(|tV|2d32Ae5)>QYpJqgdg<1&Blet4^(E~q zd9e8DuC_P*R7dLgo_Aij?$f1i`Qhg=6WfMA`{&J@ubP|MdLAhsd*tmC=gzm~9lP?; z8_%qfo0lc5w?@}>^*Clc)U$e0{K<9AZC7fn$LB1p$$jd2<_o?p6KfsEE1P=u{t*Iy z`fgLp>1*xlKfhhPprG0E%JPy|3zvP>6TWBe8Q=YjI~9DfzGQi)fB)`_H*<5vu^S?~ z=yJ+6I{(Mk&vGB@8hPvM;;DO^Ha&Wxr^ssjmGZtz3pna>Q+LmAzkb3`70!S3p^R0h zZ+)_L$ieRAe(FNrt{1{jo_j3!(#?i_88=U^KGEJ$T=r@Ey8ZunYWm~pMdkACT@^2( zi>EH%o|T($%h&$;uFjOMSL*XOeWAUt>=E(9>00K&eZTps=<{)PSAWrc^i$}J_ys%8 z{rHyeLeDAxadP*GZ6s|tFDG|jGvPSvuEUO(05wew@RYJR@W>>SCvJnV|HVPLM04aMdXTN&?Ju|UgXrM$-F za`PU~1gE#yWOIynR=aqI$KsO7Vwoe$7HwD?yL-0`xIg;=e;$q zfJu;%icX6GMi^S<^g2CNPS+UDkd>3kqRI4lnnj4S90{Dk$HHhN699IeHR)&&SDwBnKo1;jW5tP=f@cmtZTw9)e?~m~SLF zR+@q?O5;J7$uL_=@Hv8=1S3K)KaJoTg53lM%Q0^vxRKxmf@z_cuO|39!S4y?Fqp3+ zxQn2lU_lt>mk|7zV3-0klN71>P&n+!u+*%o18IlQj05ULSUmKntv&^pzy5G-MNzbX|@DweV4 zSLvhh%=Ouv+3Bil;M}~6H+flPR^wG%LU0SgPY7O8<8@U>!~&*8=zNfX+ga=3GBX1U z0(p42tbhh@FnG)+J6s5MejabnbCr$R@bY zxJKM|9+%0?bLJYi8*UA}>1bEPOcTU#*~}iV+khvAx6M%*$VT8Z@4;u?gU=qoBUfY= z)Vm=PZaVa7WE!-~1m5hl@SL4@RC=qpOsIuLp;2-FV#y(vyr^tA6JB=>&t<_vLnXFq zQzbbb14HEn1|-2$Z$%}h1%~1MxpNrrur%N*dshk3nsgyQ!0DP{Dp(hCCdgc{)aZFl zGTeFfM9*ws(cd(Ba6P4o|21BE($EIjIebEe!^C8i;ykC;xp-((q2p)REKo7oW`QW- zZIxACXkuss%%B48a0u(r#whx2HH%)<>VR(24$i}yZt|MSoi%RQ&RLLBaR1!A$zlN$ zzA%D&*TKvq{*M|x zeHau!1ph@E;u6r~L`sOk^)YBI(b|Xf)h9#oTr&9PbN#usglo~oqc4agjF+K=1ng^w zi$@hi3i8bygPIctk+q9QXM1f!5{32CAxk2@z_9<2L@C;wh)+O^PKVC-^38fVN>9Sq zpCL|%s*-~Ko04#h&ZJ;|smWNMk{r}uBYF#bM_f+Emp`5(T_2p+r4PnwCLEsgS}&K8 zg8lNj!KgL`pZs7wttq%pT>lLs3A_+9IPd>QzX;XbfpCGrM+yEaDX=+A?m89~j!e

g0&M0oJQs1HVr(S#5oJ`iIRc+#i=&&+IFtUS1z zFLUp?=bn4+`I&i7x;g<@TKw=w%VwahK^ST650XTpq|PZ7S*e!PLnAbY|6-07a`1d> zFPv=c-HsZgN<~y>XPIIemOiV>%DAr9)T*<#GPYMHm^r683-%D2+EPB!*fp)1sxhr< zBQ&4iIt*f)2rnXEAsbyHOdziymyoDiyoV$x+;k=2C3mPXrtq@c1sB}`_{A*(Ped?~ zkCDHSZS5i)LAJGX@N0Vn+V2(NF$9qBkTfugU!4#uLgUMKBUMA1XEZ@a$0w*gCj7KylrdmB;VW!jE;Ct~ zQt82IrZZC4RE^#tHeCe%#b?l?(!3w%MQ_+iJnnC#;39mD&9hno z4tObS_a;F`jw7FVBlnX*Dk~Lsh~g<*Xr5x3)&8#x0^NNu(wzws-e6{Vc45Yjxf2&^ z#TgEF55O7ZGScoF@Sy4XAT6uf!Xnj~#v~IS_QgO&jw2r;KlnJf?F&NC9~vXPt{yb7 zJDdohdBf@!D;##yP@^o>7;)}L>tw&ARIs7&E_K51urt5s!4e$y`{7l;{uJRgxontv z-ZFwuY(mGdBQD%sT)ew@@ZVyn1&VMw&<|e*Qe9*RE2|YoYfPz{)3ksdfjbypD<8Jx zBf&vXgTA$ETb#8xoDas}YS7n7m{M7^++D6lAU$d8G?04wHxS;gC3#k=GFpcdJ)7L5 zZqEvf@I_AouJ=U7h`pcW3wKl>;dfel9$(NHrr$2KC*%q`Z3o+)Kg8tfw27sGsXzhj z4P|14FUh7c&UAcHX{v&+Dl8vMdnE<%PAIg8@Q=*ZOj)b39g-Ql8Uwys6!~n2qIkb4gYtePM(;zrn4;MY5UE#=N%G6EVl? zmA)3Z91Arp`{It}j&w8Z#qp`A4I?t}olkfX@gNGB(>k)ffn zoHz=TTmUq#6%KLXbz~Uc;JV=~PS0}9@DXQS;|k}68#uecCGD#eHYZ`Q<&?ps#7;n8#k>S+N!MQ$TP zMt~z3VI3KRGg&Jc9=Mfp;pQ7z4z%8l@W4Pjn(YHE(*e&7bl{4{r{H|170wNG*fE^M zEZxHS-vb_;b1;+*;SMW@mIG(Ajsw4C9S1Ue2A<>vcn!IXM03J=;(W86;sGtk1xZzB NhN_*{W;#YI_psjT8Uqe20NMV*3AT=2nbL9EUG=TG{ugS)e*)9?O| z^Z(~N|9|eeIWcdm6o2!;p?$~Ig!EUEkx>NFUa%z+&CQi09W)&oA}YcS&)}3Ovw2)f zHi4{2$!wl-jI2q?EZo2)^F$!OnN!9w5evu}lgN^qGzaYYoEqo6401tA-UG5dHD3X8 z^F18dq9SA;$ZV__Nflh2{fwvGem z@F)UTrj_eaBT4xbQdpmf7fEu)LDa*!39v!h%gD1|B1@IW2R0A?cri@yU z%q7qX>0%AJ(omjc?kjl`iT~w`|F=Ngb+QI*x3F`?jO2f^1}fHc0tW+pI9JP5nmA7M*ETgb5l+F8_$=0k#5Y9e@rT=F;$Hy)T;fA=H_@i2 zr)Q*VGcvS>Og__K&eCeL%(+IR*=Wo)XmO+-No728LT09*6ZATr-lWs%Obm3UWQbun zL417FSUvF?F{Hy5ij-UlQ5ZO-flGW0+f^jq;Oc;;n!^E%*?@OKp;Bwo(lhu>ZoCr? zoO0NyC!C5?DpU$}nkJsER%%_~H7HfZ*;Q&!i)1Y6URkX%t>3uSTWU4WeZ9@)j;!jh zPb=Fn@4FLce9@YmCtkeE)XqwFjKb@4`@eHp+fGDQZK$7T_C?)i$~25YnyqHp|5V!o)vFvw@m-x=1I@3y6NJ>ME6biWNz$;l2kwSM zVz3}|?6hz(zAJ6#k<(ma**3CtXpl@87$mw=TS(gO^JEq1+~z+M&EYL#{s-Gg>*Ay2 zm4$xAyYFvP#*S^9(z^I|^N!7L-0|*$JJ(q_VZEgs;F>&u)(U_XOnRgUV0%%Mz?YRZ zhWz#6#f#-oEXq``+z|-PiG+jUj+A#)LEk(%*3*@8C1q;nDmj7HaXEnVxq85d5kEvM zQZS2z_!Q!oh?Poae?eJF^~!X*NU6_gN)2XZzH^ARDkk?L?m|qc>Q%r%r2Xn5dW%|3 zJJl0l%4+pb%o_Twx)98n8W#U+#Px`W5iM!Vz5wx$h{q92)0w>;@j1lPh>i?qk08E; zcnR?rJhLxHe4Vdf#F#lpN3FAJQ~@8~k^tvo~Pw2+1DS+=~O);^&%iN+b+|}DBM&vG8iV0NEvnn_c zTM(oA5@?K*X6emzi#`jyJN0?-(GE8+mO5l{mMr<@$VjUr;iXZr8Vbw`?SQUFMOR9L zCpe-$DJTm()}dNlCh%=i$S*qCzCm#`;Q5$4(<|_O;;~tgHe~%=Lx{klACf zG($jFz!!~0s@W>=41_vTODFBFpRv2g*=c^Z3v$lRW|dl!T?rRSgX|0YWicp+I%1t- zH4tP6u|bMS^TIt5A9%u&UktD!FmB@mYFPlSGnP`d(J)!yW04+NbV1SKJ^0z6X~RLl zqRm)RnF?dQ`e~RP^7pZg4!l3?6S>3MxylGFdZW1E^QSY4w}f z`*W{p!u71u*siMTvF`=%Xl8r6p|?wh^O)>sYrqe+z^*0@v*bWWXADj&be&n~Y18B~ zSlb(jMd!#7xQDyKA-IX*Ok==EvjsZcT;PD2vwMQEKvz&6Eo@Z8S|t}4HH!-cy3%Yk z!zPA%9)Yvxhlap*o;BNlEAWfhDtKX}y0;L{KN?}BF{$9BC3C=wmdYV^vD<5WX0+1c z9P`3qpL--CRX12}_;&I2L?WF}b)&<9&T|U?ifv(N* zKrgz*JbFAw6)uYd4iCYk*!Xo-YZfR=H>0G-47ckL^Ja%c!&tp>`L_C6+o6jsa zB0ie$fy<<+p^2W!E!~i>qxu3Zi+AMNfC^7%7wDPV1?svy4P9F>mdlM+LEF&etZ#%} zv3&t88&ww;K=zj066!5vH>^~ctU*5ARaibu?NTA5W}U!XGU79cUn1Izm_2~F3Go!- z1 zm|@e<>E+pDNOqTxkbJ&;gygC6VUiX0B*`4wZfEz(dOKrx(C*Q~7a=t~ZrFV_99dP$ s=)JneLe!kz8%3cwwIizN@gK%c0v6~MyZe^&8HEc`g% zzw@2%{J!s=^!GEDPr!vXFTC6~;vs@?QZ*~=AT<|_vut@UtJdIVTO9su^E=RaR6W6J zSKIp_*FJC<^+~NH>*vlf&8(p|!OE&OW#|>XZ2LB4%QMZ)#j5SFM0l+|(MOuQ7Iagu zE$G#QG$kDvhacKypu1%#A>Ky(f{+|Cm=3vx2ozQv;~+X6aM&4vRfhv^AVjANbs3&V ze1Yg7GE5;}Ld@=o!e1l=!984-;Z4L(h|vxis)!E}zab8F%5V|!Il|E;!{dl6h;IMbnk_C5#M*`oJ5?fDB4*n!K%CO0Rq?D zK0kYg^39^g%8IGt)vORw=P_PrxOcZ~$k*I~2(izzx2W0@GfY-`m~L*yRIuibfwLzD zX~axV>`5Zd>x%}SQ_oUWE3s!O%HuReajGihKiFWsCk!o~QII@-c+@l2N+gj5sWjD;GV28&AU`ih6aqK@C=AiV3~FLokk*L0mvw?~Seyo2I%rr)VXbqcu}E ztln*Q|JXUD%;-_3l$fzG28MpVM$^~?PA3jTjb>~G7c|$3N`;XMTVjVaG3%;Qddj}`~z8y>}HTWeqFM89L<+E(%r*$a$hn=Ku zY3T-B^$YNkKlBJv#u-ngw@p70kMSFvT&^;lGpiv_s3p9w)fP)X%GC0Li8F{zLj#2S zN8xzCPuOY<=fxIq$l6vxw6^o#uiS!~-DZ8P}!Hk)JMRFu$zAGvKxL8CkmDnil6_lhPFY;SUYHb!6NLmH%&dE7BTgbr2G!K6uWv{mB6<_EePLTo(fHTvR}bm-R_B0Y69cFglV44e|bn zUDWLNa;5;+gZrQwYuimG({fhEs6Z4O<*{nW!tGcG(vq@> z;0;}f_o8Q`nQz5?@M$~`Yhw`*5(8E}yq6m^y`HdX^1*r{hTcmd4-6(ptqeWb>oJr# ziEBy0s_g3|zx$=Z|82m+nBE>PtFY#5-yM_SM$pws?EhybR829K;eZ&0SrMo8Z&U8& Aa{vGU delta 4051 zcmb_edvFuy5x>*JmQOlavMftBwmCm!8-uZA$;OZ-#1D)OVdC1n5*~?=&bEq>gmeNN zLkww}PD|ThK2n-?C?TPRDW;`~fpn&1FeQ+tOfU&=YNikEFSdL!zx(Zh4-P!5W|%vpn0rqyP)~y_7HeuMWi-I)nY)aNVG|at zlG13$#_4pR6>%EvltbvGIE~AVtn9}C{>`kin>xY;8ABXd;zrFN&tlcoW*5*S;`CcU zm&ENAKsUX>GE-Cxa{y?3R^H(lL-GB0b#2o$)qYXglRFo{aoxMb7IKfNcZ08KZ`JPEIa zQ6(sg=M8$jAziQ6 zrz7ao7UOLM4ezUemQFJ4uVl-{%Hx3vX@ z=9c~iPFMK3BX!BPwXN6B-S9*zGhTiD+eP(cx_8pP*Q6@T`!mjqH{W>v47&8U*Z^Y?Q2`V@-q=MX#1=#@RlfSJU$yA$iE*bq8H@CW<WtozHSrv7{_8QgPiIr}D2t|}eXJ2)~naG_=HzNuxO%->);RJe9y>=ZqQU(z-w z;b=3=vF*G10=G|}+&Oi0@4V>g%fHDu-Rqk(v#+;z``?Zp|JdHqRo1)bo!ch|zA>$D z`=555?EBU+|LHk1wpLbl`L}QQVc*WjK3zBX`K**>&eE$#2M1^R*H~D-$5NcZb2i&_ zpX3)O2vRh>Q0yElh9Z1V%P3HHWu~CI(bpnIdY;V?k!g*FLSZoysSiq%-M&Cwa8XDM zMBI`u7(n%;fEPrI#DEk*wpMKS1)9S_f3Q8Sz0Xixt0+Z7ag|IH16yhZiM+HUCLT)yItTcqB$PH$`~k(o6w{JXK7-;< zD4wC1t3kP&;%17MD3+$6d=bSR6mO-}J%I_@<)_N-h*R(aIaIniQ5~LZkGPkJf=!sz z+$vC-=gK?W5f4;845U|F;`4~UKwD5)+98HTo_vqXg?L-If+C*lYIFM|;tIjnCgK|e z8uNmQE;p4MxN0QYFe z0$!n*sjC9|aotEI&pAlH&SDi83)De*Kx~H*gB>pLy8{b(@|G@3V;@^7_@x!dRPsD0 zN2K=TuFeXcGWZg}NB9z$;&Q*ZMD#mJE{~1=5nnPNWNpD{7(#Tp1Yf`_E)#&R790YM zs~?j7pM)e;p9g{L`Z0iW^_hTCeVLl)?1F=I>fv;e!}>D7JNh!1b{8h$35GgX2w^cK zx+SQ9U?=WWlg=STq+pnKhbQw=v2@)OH>KuNf7FbePEGCRIa(f}t9*ew;1#Ndth_fM zO^e*^qR=S1y<+&@q=bV@BSHmq3A?eUMp=oJOO7-*L|gbGNIC+CdW|E8&;8bg|E49`j7s3pPTCYl#n2-u1X%@qHa|Z)(QNzsB1@~Ht=RaP@IWVr!X8M~K4>T?6mwX|=SnrnH zt#E=oVnm=Nl*8T^3v<9zqTgYdIIr6(x$$~QG+P#;j2ufZnay)F2EBlWB#;O^#4`-t zR~<`kAryoU$#Bn9N**_x=O%P6IANHIE7z z34;8%##cGv1mI;xTgG#w-|QkgvUJcj)>=cck__bQ6rk!Uv6ELU1|<8N-yR8CP;{CMOB0E7eX6KQO#VE}avd9K&F;I@e9Ad~wCQUZ{1hKHL$(Dx^p0Z?- zeYPSb*+Pgr!T|brGSN>;7UC3&t0^9$$Xewj1`4#v4ri^i7S_s{Xvs4p%&=y!WfXaH z1m37hbWI1(%h$W9l61l#Q9n<$(iLU;@Qn%V;vYAcL9|la~szfWoE?6eOC)70TtoY*=e1 zSzU-9rZ)=dw)@Q{qOoDEuxd@VGK?_6=EBJU;ci>p>i;l092qd#w4 Date: Sat, 29 Sep 2001 00:44:23 +0300 Subject: [PATCH 18/38] Fixes for RPM build --- Build-tools/Do-rpm | 4 +--- acinclude.m4 | 10 +++++----- configure.in | 5 ++--- support-files/mysql.spec.sh | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index 138953ab188..046ba93a1dd 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -210,7 +210,7 @@ if [ $? != 0 ]; then tail $log fi -if [ ! x$local_build=x1 ]; then +if [ x$local_build != x1 ]; then # Build perl RPM (we currently need to be root to do this and that is # not possible) @@ -228,5 +228,3 @@ if [ ! x$local_build=x1 ]; then #scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS fi ) > $log 2>&1 - - diff --git a/acinclude.m4 b/acinclude.m4 index 5b216a06df5..0a767227ce4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -690,7 +690,7 @@ fi AC_DEFUN(MYSQL_CHECK_VIO, [ AC_ARG_WITH([vio], - [ --with-vio Include the Virtual IO support], + [ --with-vio Include the Virtual IO support], [vio="$withval"], [vio=no]) @@ -1054,9 +1054,9 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_INNODB], [ AC_ARG_WITH([innodb], [\ - --with-innodb Use Innodb], + --without-innodb Do not include the InnoDB table handler], [innodb="$withval"], - [innodb=no]) + [innodb=yes]) AC_MSG_CHECKING([for Innodb]) @@ -1132,7 +1132,7 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_GEMINI], [ AC_ARG_WITH([gemini], [\ - --with-gemini[=DIR] Use Gemini DB located in DIR], + --with-gemini[=DIR] Use Gemini DB located in DIR], [gemini="$withval"], [gemini=no]) @@ -1251,7 +1251,7 @@ changequote([, ])dnl AC_DEFUN(AC_SYS_LARGEFILE, [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, - [ --disable-largefile Omit support for large files]) + [ --disable-largefile Omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, getconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) diff --git a/configure.in b/configure.in index df9c6bbec4d..8528ff0b9a3 100644 --- a/configure.in +++ b/configure.in @@ -699,7 +699,7 @@ int main() AC_MSG_RESULT($atom_ops) AC_ARG_WITH(pstack, - [ --with-pstack Use the pstack backtrace library], + [ --with-pstack Use the pstack backtrace library], [ USE_PSTACK=$withval ], [ USE_PSTACK=no ]) pstack_libs= @@ -1752,8 +1752,7 @@ AC_ARG_WITH(embedded-server, ) AC_ARG_WITH(extra-tools, - [ --without-extra-tools Skip building utilites in the tools \ - directory.], + [ --without-extra-tools Skip building utilites in the tools directory.], [with_tools=$withval], [with_tools=yes] ) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index f5ce41a1c70..287fa76fb42 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -219,7 +219,7 @@ automake BuildMySQL "--disable-shared" \ "--with-mysqld-ldflags='-all-static'" \ "--with-client-ldflags='-all-static'" \ - "--without-berkeley-db --without-innodb" + "--without-berkeley-db --with-innodb" nm --numeric-sort sql/mysqld > sql/mysqld.sym %install -n mysql-%{mysql_version} From 5293d2ea2d115e73b089ee54789fe927e1638405 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sat, 29 Sep 2001 05:14:09 +0300 Subject: [PATCH 19/38] Fix for make dist --- configure.in | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 8528ff0b9a3..8f0b0ee6439 100644 --- a/configure.in +++ b/configure.in @@ -2181,7 +2181,17 @@ EOF then sql_server_dirs="innobase $sql_server_dirs" echo "CONFIGURING FOR INNODB" - (cd innobase && sh ./configure) \ + if test ! -d "innobase"; then + # This should only happen when doing a VPATH build + echo "NOTICE: I have to make the Innobase directory: `pwd`/innobase" + mkdir "innobase" || exit 1 + fi + rel_srcdir= + case "$srcdir" in + /* ) rel_srcdir="$srcdir" ;; + * ) rel_srcdir="../$srcdir" ;; + esac + (cd innobase && sh $rel_srcdir/innobase/configure) \ || AC_MSG_ERROR([could not configure INNODB]) echo "END OF INNODB CONFIGURATION" From 12aa7e5e84900f893e4b49f85eeced383b37e193 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sat, 29 Sep 2001 15:37:53 +0300 Subject: [PATCH 20/38] Fix for make dist --- innobase/include/Makefile.am | 2 ++ innobase/include/Makefile.i | 2 +- libmysql/Makefile.am | 6 +++--- support-files/mysql.server.sh | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am index fd5cc8b1a80..8664f6dfc17 100644 --- a/innobase/include/Makefile.am +++ b/innobase/include/Makefile.am @@ -55,5 +55,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ ut0dbg.h ut0lst.h ut0mem.h ut0mem.ic ut0rnd.h ut0rnd.ic \ ut0sort.h ut0ut.h ut0ut.ic +EXTRA_DIST = Makefile.i + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/innobase/include/Makefile.i b/innobase/include/Makefile.i index 8c7e9910f26..985ec525950 100644 --- a/innobase/include/Makefile.i +++ b/innobase/include/Makefile.i @@ -2,7 +2,7 @@ libsdir = ../libs -INCLUDES = -I../../include -I../include +INCLUDES = -I$(srcdir)/../include -I$(srcdir)/../../include -I../../include # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 02291d75e7c..050cf2041d3 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -71,11 +71,11 @@ link_sources: # keep only the stubs for safemalloc.c and debug.c # # A list of needed headers collected from the deps information 000213 -nh = global.h config-win32.h dbug.h errmsg.h global.h \ +nh = my_global.h config-win32.h dbug.h errmsg.h \ m_ctype.h m_string.h \ my_alarm.h my_config.h my_dir.h my_list.h my_net.h my_sys.h \ - mysql.h mysql_com.h mysql_version.h mysqld_error.h mysys_err.h \ - my_pthread.h thr_alarm.h violite.h hash.h + mysql.h mysql_com.h mysql_version.h mysqld_error.h \ + mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h # Get a list of the needed objects lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index ee5a9adaf8b..eed749bf5b2 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -118,7 +118,7 @@ case "$mode" in 'stop') # Stop daemon. We use a signal here to avoid having to know the # root password. - if test -f "$pid_file" + if test -s "$pid_file" then mysqld_pid=`cat $pid_file` echo "Killing mysqld with pid $mysqld_pid" From 5658ff8237dc6e08e07154ef2a9a7c0ce3e0a453 Mon Sep 17 00:00:00 2001 From: "tonu@volk.internalnet" <> Date: Sun, 30 Sep 2001 10:46:20 +0800 Subject: [PATCH 21/38] SSL compiles and works as far as can see. Continue testing.. --- BUILD/compile-pentium-max | 2 +- Docs/manual.ja.texi | 2 +- Docs/manual.texi | 130 ++++++++++++++- acinclude.m4 | 6 +- client/mysql.cc | 4 +- client/mysqladmin.c | 2 +- client/mysqlcheck.c | 2 +- client/mysqldump.c | 2 +- client/mysqlimport.c | 2 +- client/mysqlshow.c | 2 +- include/mysql.h | 3 +- include/mysqld_error.h | 5 +- include/sslopt-case.h | 6 + include/sslopt-longopts.h | 2 + include/sslopt-usage.h | 3 +- include/sslopt-vars.h | 1 + include/violite.h | 18 +-- libmysql/libmysql.c | 20 ++- libmysqld/lib_sql.cc | 2 +- mysql-test/install_test_db.sh | 2 +- scripts/mysql_install_db.sh | 16 +- sql/lex.h | 2 + sql/mini_client.cc | 2 +- sql/mysqld.cc | 48 +++--- sql/share/czech/errmsg.txt | 3 + sql/share/danish/errmsg.txt | 3 + sql/share/dutch/errmsg.txt | 3 + sql/share/english/errmsg.txt | 3 + sql/share/estonian/errmsg.txt | 3 + sql/share/french/errmsg.txt | 3 + sql/share/german/errmsg.txt | 3 + sql/share/greek/errmsg.txt | 3 + sql/share/hungarian/errmsg.txt | 3 + sql/share/italian/errmsg.txt | 3 + sql/share/japanese/errmsg.txt | 3 + sql/share/korean/errmsg.txt | 3 + sql/share/norwegian-ny/errmsg.txt | 3 + sql/share/norwegian/errmsg.txt | 3 + sql/share/polish/errmsg.txt | 3 + sql/share/portuguese/errmsg.txt | 3 + sql/share/romanian/errmsg.txt | 3 + sql/share/russian/errmsg.txt | 3 + sql/share/slovak/errmsg.txt | 3 + sql/share/spanish/errmsg.txt | 3 + sql/share/swedish/errmsg.txt | 3 + sql/share/ukrainian/errmsg.txt | 3 + sql/sql_acl.cc | 258 +++++++++++++++++++++++++----- sql/sql_acl.h | 2 +- sql/sql_lex.h | 5 +- sql/sql_parse.cc | 4 +- sql/sql_show.cc | 45 ++++++ sql/sql_yacc.yy | 52 +++--- sql/structs.h | 6 +- vio/test-ssl.c | 9 +- vio/test-sslclient.c | 6 +- vio/test-sslserver.c | 7 +- vio/viosocket.c | 2 +- vio/viossl.c | 122 +++----------- vio/viosslfactories.c | 45 +++--- 59 files changed, 646 insertions(+), 267 deletions(-) diff --git a/BUILD/compile-pentium-max b/BUILD/compile-pentium-max index 55f88ef4748..9838e6a287b 100755 --- a/BUILD/compile-pentium-max +++ b/BUILD/compile-pentium-max @@ -8,6 +8,6 @@ extra_configs="$pentium_configs" strip=yes extra_configs="$extra_configs --with-innodb --with-berkeley-db \ - --enable-thread-safe-client" + --enable-thread-safe-client --with-openssl --with-vio" . "$path/FINISH.sh" diff --git a/Docs/manual.ja.texi b/Docs/manual.ja.texi index d3ee43acd29..dea7046b538 100644 --- a/Docs/manual.ja.texi +++ b/Docs/manual.ja.texi @@ -3187,7 +3187,7 @@ encounter per year, but we are as always very flexible towards our customers! @c @image{Flags/estonia} Estonia [Tradenet] @ @c @uref{http://mysql.tradenet.ee, WWW} @item -@c EMAIL: tonu@spamm.ee (Tonu Samuel) +@c EMAIL: tonu@spam.ee (Tonu Samuel) @image{Flags/estonia} Estonia [OKinteractive] @ @uref{http://mysql.mirror.ok.ee, WWW} @item diff --git a/Docs/manual.texi b/Docs/manual.texi index c88455289c8..7253029e5ad 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -15583,7 +15583,7 @@ Users of Java JDBC: Do not transmit plain (unencrypted) data over the Internet. These data are accessible to everyone who has the time and ability to intercept it and use it for their own purposes. Instead, use an encrypted protocol such as SSL or -SSH. MySQL supports internal SSL connections as of Version 3.23.9. +SSH. MySQL supports internal SSL connections as of Version 4.0.0. SSH port-forwarding can be used to create an encrypted (and compressed) tunnel for the communication. @item @@ -16985,7 +16985,11 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON @{tbl_name | * | *.* | db_name.*@} TO user_name [IDENTIFIED BY 'password'] [, user_name [IDENTIFIED BY 'password'] ...] - [REQUIRE @{SSL|X509@} [ISSUER issuer] [SUBJECT subject]] + [REQUIRE + [@{SSL| X509@}] + [CIPHER cipher [AND]] + [ISSUER issuer [AND]] + [SUBJECT subject]] [WITH GRANT OPTION] REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] @@ -17208,6 +17212,120 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the MySQL grant tables. @end itemize +----------- +@cindex SSL and X509 Basics +MySQL has support for SSL encrypted connetions. To understand how MySQL uses +SSL we need to explain some basics about SSL and X509. People who are already +aware of it can skip this chapter. + +By default, MySQL uses unencrypted connections between client and server. This means +that anyone on the way can listen and read all your data which moves there. Even +more, some people can change content of data while it is moving between client and +server. Sometime you may need to move really secret data over public networks and +such publicity is unacceptable. + +SSL is a protocol which uses different encryption algorithms to ensure that data +which comes from public network can be trusted. It have mechanisms to detect any +change, loss or replay of data. SSL also incorpores algorithms to recognize and +verification of identity using X509 standard. + +@cindex What is encryption +Encryption is the way to make any kind of data unreadable. Even more, today's +practice require many additional security elements from encryption algorithms. +They should resist many kind of known attacks like just messing with order +of encrypted messages or replaying data twice. + +@cindex What is X509/Certificate? +X509 is standard which makes possible to identity someone in the Internet. Mostly +it is used in e-commerce over the Internet. Shortly speaking there should be some +company called "Certificate Authority" which assigns electronic certificates to +everyone who needs. Certificates rely on asymmetric encryption algorithms which +have two encryption keys - public and secret. Certificate owner can prove his +identity showing certificate to other party. Certificate consists his owner public +key. Any data encrypted with it can be decrypted only by secret key holder. + +@cindex Possible questions: +Q: Why MySQL not uses encrypted connections by default? +A: Because it makes MySQL slower. Any kind of additional functionality requires +computer to do additional work and encrypting data is CPU-intensive operation which +can overcome MySQL own work and consumed time. MySQL is tuned to be fast by default. + +Q: I need more information about SSL/X509/encrpytion/whatever +A: Use your favourite internet search engine and search for keywords you are interested in. + +------------ + + +@cindex SSL related options + +MySQL can check x509 certificate attributes additionally to most used username/password +cheme. All usual options are still required (username, password, IP address mask, database/table name). + +There are different possibilities to limit connections: + +@itemize @bullet +@item +Without any SSL/X509 options all kind of encrypted/unencrypted connections are allowed if + username and password are valid. + +@item +@code{REQUIRE SSL} option makes SSL encrypted connection must. Note that this requirement +can be omitted of there are any other ACL record which allows non-SSL connection. + +Example: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SSL +@end example + + +@item +* @code{REQUIRE X509} Requiring X509 certificate means that client should have valid certificate +but we do not care about exact certificate, issuer or subject. Only restriction is it should +be possible to verify its signature with some of our CA certificates. + +Example: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509 +@end example + +@item +@code{REQUIRE ISSUER issuer} makes connection more restrictive: now client must present + valid x509 certificate issued by CA "issuer". Using x509 certificates always implies encryption, + so option "SSL" is not neccessary anymore. + +Example: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" +@end example + +@item +@code{REQUIRE SUBJECT subject} requires client to have valid x509 certificate with subject "subject" on it. If client have valid certificate but having different "subject" then connection is still +not allowed. + +Example: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" +@end example + +@item +@code{REQUIRE CIPHER cipher} is needed to assure enough strong ciphers and keylengths to be used. SSL himself can be weak if old algorithms with short encryption keys are used. Using this option we can ask for some exact cipher to allow connection. + +Example: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA" +@end example + +Also it is allowed to combine those options with each other like this: +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" + REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" + AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" + AND CIPHER "EDH-RSA-DES-CBC3-SHA" +@end example + +But it is not allowed to use any of options twice. Only different options can be mixed. +@end itemize +----------- @node User names, Privilege changes, GRANT, User Account Management @subsection MySQL User Names and Passwords @@ -19830,7 +19948,7 @@ differ somewhat: | have_bdb | YES | | have_innodb | YES | | have_raid | YES | -| have_ssl | NO | +| have_openssl | NO | | init_file | | | interactive_timeout | 28800 | | join_buffer_size | 131072 | @@ -20017,7 +20135,7 @@ if @code{--skip-bdb} is used. if @code{--skip-innodb} is used. @item @code{have_raid} @code{YES} if @code{mysqld} supports the @code{RAID} option. -@item @code{have_ssl} +@item @code{have_openssl} @code{YES} if @code{mysqld} supports SSL (encryption) on the client/server protocol. @@ -21651,7 +21769,7 @@ mysql> show variables like "have_%"; | have_innodb | NO | | have_isam | YES | | have_raid | NO | -| have_ssl | NO | +| have_openssl | NO | +---------------+-------+ @end example @@ -48296,7 +48414,7 @@ Allow hex constants in the @code{--fields-*-by} and Added option @code{--safe-show-database} to @code{mysqld}. @item Added @code{have_bdb}, @code{have_gemini}, @code{have_innobase}, -@code{have_raid} and @code{have_ssl} to @code{SHOW VARIABLES} to make it +@code{have_raid} and @code{have_openssl} to @code{SHOW VARIABLES} to make it easy to test for supported extensions. @item Added option @code{--open-files-limit} to @code{mysqld}. diff --git a/acinclude.m4 b/acinclude.m4 index d7e492856bb..54ac76ee2bb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -663,7 +663,7 @@ if test "$cpu_vendor" = "AuthenticAMD"; then fi elif test "$cpu_vendor" = "GenuineIntel"; then if test $cpu_family>=6; then - cpu_set=" pentiumpro pentium i486 i386"; + cpu_set="pentiumpro pentium i486 i386"; elif test $cpu_family=5; then cpu_set="pentium i486 i386"; elif test $cpu_family=4; then @@ -682,9 +682,9 @@ done if test "$mysql_cv_cpu" = "unknown" then CFLAGS="$ac_save_CFLAGS" - AC_MSG_RESULT(none) + AC_MSG_RESULT(none) else - AC_MSG_RESULT($mysql_cv_cpu) + AC_MSG_RESULT($mysql_cv_cpu) fi ])) diff --git a/client/mysql.cc b/client/mysql.cc index 6382fd66f35..dbaff8e57f5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -24,6 +24,7 @@ * Jani Tolonen * Matt Wagner * Jeremy Cole + * Tonu Samuel * **/ @@ -1232,6 +1233,7 @@ You can turn off this feature to get a quicker startup with -A\n\n"); } } } + /* FIXME: free() on small chunks is sloooowwww. glibc bug */ if (field_names) { for (i=0; field_names[i]; i++) { for (j=0; field_names[i][j]; j++) { @@ -2219,7 +2221,7 @@ sql_real_connect(char *host,char *database,char *user,char *password, #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (safe_updates) { diff --git a/client/mysqladmin.c b/client/mysqladmin.c index ca568a914f2..87a5be2aad2 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -265,7 +265,7 @@ int main(int argc,char *argv[]) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif /* HAVE_OPENSSL */ if (sql_connect(&mysql,host,user,opt_password,option_wait)) error = 1; diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 0f7bfb37ecf..75190e34267 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -591,7 +591,7 @@ static int dbConnect(char *host, char *user, char *passwd) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd, NULL, opt_mysql_port, opt_mysql_unix_port, 0))) diff --git a/client/mysqldump.c b/client/mysqldump.c index 9d80fd9a6c9..3c9e36e8a70 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -523,7 +523,7 @@ static int dbConnect(char *host, char *user,char *passwd) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index d8f763b9653..1883b2a062e 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -400,7 +400,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, database,opt_mysql_port,opt_mysql_unix_port, diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 8bce1203df8..9c682047c0e 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -87,7 +87,7 @@ int main(int argc, char **argv) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (!(mysql_real_connect(&mysql,host,user,opt_password, argv[0],opt_mysql_port,opt_mysql_unix_port, diff --git a/include/mysql.h b/include/mysql.h index a1bd96540e8..7867dea2c31 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -135,6 +135,7 @@ struct st_mysql_options { char *ssl_cert; /* PEM cert file */ char *ssl_ca; /* PEM CA file */ char *ssl_capath; /* PEM directory of CA-s? */ + char *ssl_cipher; /* cipher to use */ my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; /* @@ -262,7 +263,7 @@ const char * STDCALL mysql_character_set_name(MYSQL *mysql); MYSQL * STDCALL mysql_init(MYSQL *mysql); int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, - const char *capath); + const char *capath, const char *cipher); int STDCALL mysql_ssl_clear(MYSQL *mysql); my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db); diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 8f78d6190b1..cb555eb8066 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -221,4 +221,7 @@ #define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1218 #define ER_CANT_UPDATE_WITH_READLOCK 1219 #define ER_MIXING_NOT_ALLOWED 1220 -#define ER_ERROR_MESSAGES 221 +#define ER_GRANT_DUPL_SUBJECT 1221 +#define ER_GRANT_DUPL_ISSUER 1222 +#define ER_GRANT_DUPL_CIPHER 1223 +#define ER_ERROR_MESSAGES 224 diff --git a/include/sslopt-case.h b/include/sslopt-case.h index d995e31044e..b5720286778 100644 --- a/include/sslopt-case.h +++ b/include/sslopt-case.h @@ -39,4 +39,10 @@ my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); opt_ssl_ca = my_strdup(optarg, MYF(0)); break; + case OPT_SSL_CIPHER: + opt_use_ssl = 1; /* true */ + my_free(opt_ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); + opt_ssl_cipher = my_strdup(optarg, MYF(0)); + break; + #endif diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index 2f58f0e9265..697c2f647bf 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -22,10 +22,12 @@ #define OPT_SSL_CERT 202 #define OPT_SSL_CA 203 #define OPT_SSL_CAPATH 204 +#define OPT_SSL_CIPHER 205 {"ssl", no_argument, 0, OPT_SSL_SSL}, {"ssl-key", required_argument, 0, OPT_SSL_KEY}, {"ssl-cert", required_argument, 0, OPT_SSL_CERT}, {"ssl-ca", required_argument, 0, OPT_SSL_CA}, {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH}, + {"ssl-cipher", required_argument, 0, OPT_SSL_CIPHER}, #endif /* HAVE_OPENSSL */ diff --git a/include/sslopt-usage.h b/include/sslopt-usage.h index 5b2b4a88709..cd6a06fb459 100644 --- a/include/sslopt-usage.h +++ b/include/sslopt-usage.h @@ -21,5 +21,6 @@ --ssl-key X509 key in PEM format (implies --ssl)\n\ --ssl-cert X509 cert in PEM format (implies --ssl)\n\ --ssl-ca CA file in PEM format (check OpenSSL docs, implies --ssl)\n\ - --ssl-capath CA directory (check OpenSSL docs, implies --ssl)"); + --ssl-capath CA directory (check OpenSSL docs, implies --ssl)\n\ + --ssl-cipher SSL cipher to use (implies --ssl)"); #endif diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h index 597ab4d9fa6..756a35589aa 100644 --- a/include/sslopt-vars.h +++ b/include/sslopt-vars.h @@ -21,4 +21,5 @@ static char *opt_ssl_key = 0; static char *opt_ssl_cert = 0; static char *opt_ssl_ca = 0; static char *opt_ssl_capath = 0; +static char *opt_ssl_cipher = 0; #endif diff --git a/include/violite.h b/include/violite.h index 947b874c46a..c59f6124838 100644 --- a/include/violite.h +++ b/include/violite.h @@ -169,9 +169,6 @@ struct st_VioSSLAcceptorFd state_connect = 1, state_accept = 2 }; -// BIO* bio_; -// char desc_[100]; -// Vio* sd_; /* function pointers which are only once for SSL server Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */ @@ -184,15 +181,17 @@ struct st_VioSSLConnectorFd SSL_METHOD* ssl_method_; /* function pointers which are only once for SSL client */ }; -void sslaccept(struct st_VioSSLAcceptorFd*, Vio*); -void sslconnect(struct st_VioSSLConnectorFd*, Vio*); +void sslaccept(struct st_VioSSLAcceptorFd*, Vio*, long timeout); +void sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout); struct st_VioSSLConnectorFd *new_VioSSLConnectorFd(const char* key_file, const char* cert_file, - const char* ca_file, const char* ca_path); + const char* ca_file, const char* ca_path, + const char* cipher); struct st_VioSSLAcceptorFd *new_VioSSLAcceptorFd(const char* key_file, const char* cert_file, - const char* ca_file,const char* ca_path); + const char* ca_file,const char* ca_path, + const char* cipher); Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state); #ifdef __cplusplus @@ -200,6 +199,9 @@ Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state); #endif #endif /* HAVE_OPENSSL */ +/* This enumerator is used in parser - should be always visible */ +enum SSL_type {SSL_TYPE_NONE, SSL_TYPE_ANY, SSL_TYPE_X509, SSL_TYPE_SPECIFIED}; + #ifndef EMBEDDED_LIBRARY /* This structure is for every connection on both sides */ struct st_vio @@ -229,10 +231,8 @@ struct st_vio my_bool (*poll_read)(Vio*,uint); #ifdef HAVE_OPENSSL - BIO* bio_; SSL* ssl_; my_bool open_; - char *ssl_cip_; #endif /* HAVE_OPENSSL */ #endif /* HAVE_VIO */ }; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 03162bc1dfa..5924a4f13c2 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -695,7 +695,7 @@ mysql_free_result(MYSQL_RES *result) static const char *default_options[]= {"port","socket","compress","password","pipe", "timeout", "user", "init-command", "host", "database", "debug", "return-found-rows", - "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", + "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", "ssl-cipher" "character-set-dir", "default-character-set", "interactive-timeout", "connect_timeout", "replication-probe", "enable-reads-from-master", "repl-parse-query", @@ -1368,15 +1368,17 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , const char *key __attribute__((unused)), const char *cert __attribute__((unused)), const char *ca __attribute__((unused)), - const char *capath __attribute__((unused))) + const char *capath __attribute__((unused)), + const char *cipher __attribute__((unused))) { #ifdef HAVE_OPENSSL mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0)); mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0)); mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0)); mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0)); + mysql->options.ssl_cipher = cipher==0 ? 0 : my_strdup(cipher,MYF(0)); mysql->options.use_ssl = TRUE; - mysql->connector_fd = (gptr)new_VioSSLConnectorFd(key, cert, ca, capath); + mysql->connector_fd = (gptr)new_VioSSLConnectorFd(key, cert, ca, capath, cipher); DBUG_PRINT("info",("mysql_ssl_set, context: %p",((struct st_VioSSLConnectorFd *)(mysql->connector_fd))->ssl_context_)); #endif return 0; @@ -1396,10 +1398,12 @@ mysql_ssl_clear(MYSQL *mysql __attribute__((unused))) my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); mysql->options.ssl_key = 0; mysql->options.ssl_cert = 0; mysql->options.ssl_ca = 0; mysql->options.ssl_capath = 0; + mysql->options.ssl_cipher= 0; mysql->options.use_ssl = FALSE; my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); mysql->connector_fd = 0; @@ -1797,7 +1801,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, /* Do the SSL layering. */ DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); - sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio); + sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio, (long)(mysql->options.connect_timeout)); DBUG_PRINT("info", ("IO layer change done!")); } #endif /* HAVE_OPENSSL */ @@ -1887,7 +1891,7 @@ static my_bool mysql_reconnect(MYSQL *mysql) if (!mysql->reconnect || (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) { - /* Allov reconnect next time */ + /* Allow reconnect next time */ mysql->server_status&= ~SERVER_STATUS_IN_TRANS; DBUG_RETURN(1); } @@ -1995,13 +1999,13 @@ mysql_close(MYSQL *mysql) my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); +#ifdef HAVE_OPENSSL + mysql_ssl_clear(mysql); +#endif /* HAVE_OPENSSL */ /* Clear pointers for better safety */ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; bzero((char*) &mysql->options,sizeof(mysql->options)); mysql->net.vio = 0; -#ifdef HAVE_OPENSSL - mysql_ssl_clear(mysql); -#endif /* HAVE_OPENSSL */ /* free/close slave list */ if (mysql->rpl_pivot) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index e7da577ab0c..116219372fd 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -257,7 +257,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, send_error(net,ER_OUT_OF_RESOURCES); return 1; } - thd->master_access=acl_getroot(thd->host, thd->ip, thd->user, + thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, protocol_version == 9 || !(thd->client_capabilities & diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 0535b66e289..f810d2d9ad4 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -134,7 +134,7 @@ then c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u ssl_type enum('none', 'cipher', 'x509','issuer','subject') NOT NULL," + c_u="$c_u ssl_type enum('NONE','ANY', 'X509', 'SPECIFIED') NOT NULL," c_u="$c_u ssl_cipher char(60) NULL," c_u="$c_u x509_issuer blob NULL," c_u="$c_u x509_subject blob NULL," diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 7e232692ba1..f064e6ca0ca 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -224,18 +224,22 @@ then c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_u="$c_u ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL," + c_u="$c_u ssl_cipher BLOB NULL," + c_u="$c_u x509_issuer BLOB NULL," + c_u="$c_u x509_subject BLOB NULL," c_u="$c_u PRIMARY KEY Host (Host,User)" c_u="$c_u )" c_u="$c_u comment='Users and global privileges';" - i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); - INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); + i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL); + INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL); - REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); - REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); + REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL); + REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL); - INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N'); - INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');" + INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE',NULL,NULL,NULL); + INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE',NULL,NULL,NULL);" fi if test ! -f $mdata/func.frm diff --git a/sql/lex.h b/sql/lex.h index 5decf089e68..72d77e18910 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -319,6 +319,7 @@ static SYMBOL symbols[] = { { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0}, + { "SSL", SYM(SSL_SYM),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, { "START", SYM(START_SYM),0,0}, { "STARTING", SYM(STARTING),0,0}, @@ -362,6 +363,7 @@ static SYMBOL symbols[] = { { "WRITE", SYM(WRITE_SYM),0,0}, { "WHEN", SYM(WHEN_SYM),0,0}, { "WHERE", SYM(WHERE),0,0}, + { "X509", SYM(X509_SYM),0,0}, { "YEAR", SYM(YEAR_SYM),0,0}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0}, { "ZEROFILL", SYM(ZEROFILL),0,0}, diff --git a/sql/mini_client.cc b/sql/mini_client.cc index d60a3bce880..266a292fe1d 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -803,7 +803,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, /* Do the SSL layering. */ DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); - sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio); + sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio,60L); DBUG_PRINT("info", ("IO layer change done!")); } #endif /* HAVE_OPENSSL */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 67b5ba882d2..477c231ec3c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -242,16 +242,11 @@ static char **defaults_argv,time_zone[30]; static const char *default_table_type_name; static char glob_hostname[FN_REFLEN]; +#include "sslopt-vars.h" #ifdef HAVE_OPENSSL -static bool opt_use_ssl = FALSE; -static char *opt_ssl_key = 0; -static char *opt_ssl_cert = 0; -static char *opt_ssl_ca = 0; -static char *opt_ssl_capath = 0; struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0; #endif /* HAVE_OPENSSL */ - I_List replicate_rewrite_db; I_List replicate_do_db, replicate_ignore_db; // allow the user to tell us which db to replicate and which to ignore @@ -725,6 +720,7 @@ void clean_up(bool print_message) my_free(opt_ssl_cert,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR)); + my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR)); opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0; #endif /* HAVE_OPENSSL */ free_defaults(defaults_argv); @@ -1712,7 +1708,7 @@ int main(int argc, char **argv) if (opt_use_ssl) { ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, - opt_ssl_ca, opt_ssl_capath); + opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd)); if (!ssl_acceptor_fd) opt_use_ssl=0; @@ -3110,21 +3106,29 @@ struct show_var_st status_vars[]= { {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, #ifdef HAVE_OPENSSL - {"SSL_CTX_sess_accept", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, - {"SSL_CTX_sess_accept_good", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, - {"SSL_CTX_sess_accept_renegotiate", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, - {"SSL_CTX_sess_cb_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, - {"SSL_CTX_sess_number", (char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, - {"SSL_CTX_get_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, - {"SSL_CTX_sess_get_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, - {"SSL_CTX_get_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, - {"SSL_CTX_get_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, - {"SSL_get_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, - {"SSL_get_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, - {"SSL_session_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, - {"SSL_get_version", (char*) 0, SHOW_SSL_GET_VERSION}, - {"SSL_get_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, - {"SSL_get_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, + {"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, + {"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, + {"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD}, + {"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, + {"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE}, + {"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, + {"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS}, + {"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES}, + {"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS}, + {"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, + {"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT}, + {"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL}, + {"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, + {"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, + {"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, + {"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, + {"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, + {"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, + {"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, + {"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION}, + {"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, + {"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST}, + {"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index b92297abbf8..9a6768d7025 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -231,3 +231,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 9adc2f5fb73..42ff7206046 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -225,3 +225,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 61db11f39f8..0819e355422 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -228,3 +228,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index bd328dbb6e4..f5888440743 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 166637c43e1..7ad829d1f04 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -226,3 +226,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 0db8b69622e..2ac778877f6 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index a9ba1f41c42..6cf9d8dd2a1 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -225,3 +225,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index aa8d659b263..65954ce1c2e 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 5cc5ac663b1..28ee01934c0 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -224,3 +224,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 7c44e0bf4c7..2d778692e9a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 5d6f0158ea2..248c5e1b566 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -224,3 +224,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6288ac535d4..3a2086accf1 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index de783f93d1a..f701bdd1ade 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -224,3 +224,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 3cbc5b6138d..00c23acaca9 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -224,3 +224,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index c144dda47ae..56573f93a00 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -226,3 +226,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index c11adc3af70..f15cbc930cb 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -222,3 +222,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 32b6eddfeeb..9f83e98828e 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -226,3 +226,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index fbff74993fb..8851866b249 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -225,3 +225,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index d60dbf0956c..08b5bfe6ba9 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -230,3 +230,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 9234de04786..6348f416277 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -223,3 +223,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 25309cd0598..83e08254f90 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -222,3 +222,6 @@ "SELECT kommandona har olika antal kolumner" "Kan inte utföra kommandot emedan du har ett READ lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 49ab4399664..776103cf681 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -227,3 +227,6 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Duplicate SUBJECT option in GRANT clause", +"Duplicate ISSUER option in GRANT clause", +"Duplicate CIPHER option in GRANT clause", diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4c128a882c6..2f6c126e693 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -62,8 +62,9 @@ public: char *user,*password; ulong salt[2]; #ifdef HAVE_OPENSSL - char *ssl_type, *ssl_cipher, *x509_issuer, *x509_subject; -#endif + enum SSL_type ssl_type; + const char *ssl_cipher, *x509_issuer, *x509_subject; +#endif /* HAVE_OPENSSL */ }; class ACL_DB :public ACL_ACCESS @@ -204,13 +205,19 @@ int acl_init(bool dont_read_acl_tables) user.password=get_field(&mem, table,2); #ifdef HAVE_OPENSSL DBUG_PRINT("info",("table->fields=%d",table->fields)); - if (table->fields >= 21) { - user.ssl_type=get_field(&mem, table,17); + if (table->fields >= 21) { /* From 4.0.0 we have more fields */ + if(!strcmp(get_field(&mem, table,17),"ANY")) + user.ssl_type=SSL_TYPE_ANY; + else if(!strcmp(get_field(&mem, table,17),"X509")) + user.ssl_type=SSL_TYPE_X509; + else if(!strcmp(get_field(&mem, table,17),"SPECIFIED")) + user.ssl_type=SSL_TYPE_SPECIFIED; + else user.ssl_type=SSL_TYPE_NONE; user.ssl_cipher=get_field(&mem, table,18); user.x509_issuer=get_field(&mem, table,19); user.x509_subject=get_field(&mem, table,20); } -#endif +#endif /* HAVE_OPENSSL */ if (user.password && (length=(uint) strlen(user.password)) == 8 && protocol_version == PROTOCOL_VERSION) { @@ -410,15 +417,14 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) } -/* Get master privilges for user (priviliges for all tables) */ - - -uint acl_getroot(const char *host, const char *ip, const char *user, +/* Get master privilges for user (priviliges for all tables). Required to connect */ +uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message,char **priv_user, bool old_ver) { uint user_access=NO_ACCESS; *priv_user=(char*) user; + char *ptr=0; if (!initialized) return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ @@ -440,7 +446,88 @@ uint acl_getroot(const char *host, const char *ip, const char *user, !check_scramble(password,message,acl_user->salt, (my_bool) old_ver))) { +#ifdef HAVE_OPENSSL +#define vio (thd->net.vio) + /* In this point we know that user is allowed to connect + * from given host by given username/password pair. Now + * we check if SSL is required, if user is using SSL and + * if X509 certificate attributes are OK + */ + switch(acl_user->ssl_type) { + case SSL_TYPE_NONE: /* SSL is not required to connect */ + user_access=acl_user->access; + break; + case SSL_TYPE_ANY: /* Any kind of SSL is good enough */ + if(vio_type(vio) == VIO_TYPE_SSL) + user_access=acl_user->access; + break; + case SSL_TYPE_X509: /* Client should have any valid certificate. */ + /* Connections with non-valid certificates are dropped already + * in sslaccept() anyway, so we do not check validity here. + */ + if(SSL_get_peer_certificate(vio->ssl_)) + user_access=acl_user->access; + break; + case SSL_TYPE_SPECIFIED: /* Client should have attributes as specified */ + /* We do not check for absence of SSL because without SSL it does not + * pass all checks here anyway. + */ + /* If cipher name is specified, we compare it to actual cipher in use */ + if(acl_user->ssl_cipher) + DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", + acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))); + if(!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + break; + } + /* Prepare certificate (if exists) */ + DBUG_PRINT("info",("checkpoint 1")); + X509* cert=SSL_get_peer_certificate(vio->ssl_); + DBUG_PRINT("info",("checkpoint 2")); + /* If X509 issuer is speified, we check it... */ + if(acl_user->x509_issuer) + { + DBUG_PRINT("info",("checkpoint 3")); + ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", + acl_user->x509_issuer, ptr)); + if(!strcmp(acl_user->x509_issuer,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 4")); + /* X509 subject is specified, we check it .. */ + if(acl_user->x509_subject) + { + ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", + acl_user->x509_subject, ptr)); + if(!strcmp(acl_user->x509_subject,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 5")); + break; + } + DBUG_PRINT("info",("checkpoint 6")); +#else /* HAVE_OPENSSL */ user_access=acl_user->access; +#endif /* HAVE_OPENSSL */ if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ break; @@ -469,7 +556,14 @@ static byte* check_get_key(ACL_USER *buff,uint *length, } static void acl_update_user(const char *user, const char *host, - const char *password, uint privileges) + const char *password, +#ifdef HAVE_OPENSSL + enum SSL_type ssl_type, + const char *ssl_cipher, + const char *x509_issuer, + const char *x509_subject, +#endif /* HAVE_OPENSSL */ + uint privileges) { for (uint i=0 ; i < acl_users.elements ; i++) { @@ -482,6 +576,12 @@ static void acl_update_user(const char *user, const char *host, acl_user->host.hostname && !strcmp(host,acl_user->host.hostname)) { acl_user->access=privileges; +#ifdef HAVE_OPENSSL + acl_user->ssl_type=ssl_type; + acl_user->ssl_cipher=ssl_cipher; + acl_user->x509_issuer=x509_issuer; + acl_user->x509_subject=x509_subject; +#endif /* HAVE_OPENSSL */ if (password) { if (!password[0]) @@ -500,7 +600,13 @@ static void acl_update_user(const char *user, const char *host, static void acl_insert_user(const char *user, const char *host, - const char *password, + const char *password, +#ifdef HAVE_OPENSSL + enum SSL_type ssl_type, + const char *ssl_cipher, + const char *x509_issuer, + const char *x509_subject, +#endif /* HAVE_OPENSSL */ uint privileges) { ACL_USER acl_user; @@ -510,6 +616,12 @@ static void acl_insert_user(const char *user, const char *host, acl_user.access=privileges; acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); +#ifdef HAVE_OPENSSL + acl_user.ssl_type=ssl_type; + acl_user.ssl_cipher=ssl_cipher; + acl_user.x509_issuer=x509_issuer; + acl_user.x509_subject=x509_subject; +#endif /* HAVE_OPENSSL */ if (password) { acl_user.password=(char*) ""; // Just point at something @@ -984,7 +1096,7 @@ static bool test_if_create_new_users(THD *thd) ** Handle GRANT commands ****************************************************************************/ -static int replace_user_table(TABLE *table, const LEX_USER &combo, +static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, uint rights, char what, bool create_user) { int error = -1; @@ -1044,7 +1156,40 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo, table->field[i]->store(&what,1); } rights=get_access(table,3); - +#ifdef HAVE_OPENSSL + /* We write down SSL related ACL stuff */ + DBUG_PRINT("info",("table->fields=%d",table->fields)); + if (table->fields >= 21) { /* From 4.0.0 we have more fields */ + switch (thd->lex.ssl_type) { + case SSL_TYPE_ANY: + table->field[17]->store("ANY",3); + table->field[18]->store("",0); + table->field[19]->store("",0); + table->field[20]->store("",0); + break; + case SSL_TYPE_X509: + table->field[17]->store("X509",4); + table->field[18]->store("",0); + table->field[19]->store("",0); + table->field[20]->store("",0); + break; + case SSL_TYPE_SPECIFIED: + table->field[17]->store("SPECIFIED",9); + if(thd->lex.ssl_cipher) + table->field[18]->store(thd->lex.ssl_cipher,strlen(thd->lex.ssl_cipher)); + if(thd->lex.x509_issuer) + table->field[19]->store(thd->lex.x509_issuer,strlen(thd->lex.x509_issuer)); + if(thd->lex.x509_subject) + table->field[20]->store(thd->lex.x509_subject,strlen(thd->lex.x509_subject)); + break; + default: + table->field[17]->store("NONE",4); + table->field[18]->store("",0); + table->field[19]->store("",0); + table->field[20]->store("",0); + } + } +#endif /* HAVE_OPENSSL */ if (old_row_exists) { /* @@ -1078,9 +1223,23 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo, if (!combo.password.str) password=0; // No password given on command if (old_row_exists) - acl_update_user(combo.user.str,combo.host.str,password,rights); + acl_update_user(combo.user.str,combo.host.str,password, +#ifdef HAVE_OPENSSL + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, +#endif /* HAVE_OPENSSL */ + rights); else - acl_insert_user(combo.user.str,combo.host.str,password,rights); + acl_insert_user(combo.user.str,combo.host.str,password, +#ifdef HAVE_OPENSSL + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, +#endif /* HAVE_OPENSSL */ + rights); } table->file->index_end(); DBUG_RETURN(error); @@ -1626,6 +1785,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, TABLE_LIST tables[3]; bool create_new_users=0; DBUG_ENTER("mysql_table_grant"); + DBUG_PRINT("info",("ssl_cipher=%s",thd->lex.ssl_cipher)); + DBUG_PRINT("info",("x509_issuer=%s",thd->lex.x509_issuer)); + DBUG_PRINT("info",("x509_subject=%s",thd->lex.x509_subject)); if (!initialized) { @@ -1715,9 +1877,10 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, continue; } /* Create user if needed */ - if (replace_user_table(tables[0].table, - *Str, - 0, + if (replace_user_table(thd, + tables[0].table, + *Str, + 0, revoke_grant ? 'N' : 'Y', create_new_users)) { @@ -1810,7 +1973,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, pthread_mutex_unlock(&LOCK_grant); if (!result) send_ok(&thd->net); - /* Tables are automaticly closed */ + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -1871,7 +2034,8 @@ int mysql_grant (THD *thd, const char *db, List &list, uint rights, result= -1; continue; } - if ((replace_user_table(tables[0].table, + if ((replace_user_table(thd, + tables[0].table, *Str, (!db ? rights : 0), what, create_new_users))) result= -1; @@ -2332,6 +2496,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) { uint counter, want_access,index; int error = 0; + int ssl_options = 0; ACL_USER *acl_user; ACL_DB *acl_db; char buff[1024]; DBUG_ENTER("mysql_show_grants"); @@ -2426,30 +2591,37 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append('\''); } #ifdef HAVE_OPENSSL -/* SSL grant stuff */ - DBUG_PRINT("info",("acl_user->ssl_type=%s",acl_user->ssl_type)); - DBUG_PRINT("info",("acl_user->ssl_cipher=%s",acl_user->ssl_cipher)); - DBUG_PRINT("info",("acl_user->x509_subject=%s",acl_user->x509_subject)); - DBUG_PRINT("info",("acl_user->x509_issuer=%s",acl_user->x509_issuer)); - if(acl_user->ssl_type) { - if(!strcmp(acl_user->ssl_type,"ssl")) - global.append(" REQUIRE SSL",12); - else if(!strcmp(acl_user->ssl_type,"x509")) - { - global.append(" REQUIRE X509 ",14); - if(acl_user->x509_issuer) { - global.append("SUBJECT \"",9); - global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); - global.append("\"",1); - } - if(acl_user->x509_subject) { - global.append("ISSUER \"",8); - global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); - global.append("\"",1); - } - } +/* "show grants" SSL related stuff */ + if(acl_user->ssl_type==SSL_TYPE_ANY) + global.append(" REQUIRE SSL",12); + else if(acl_user->ssl_type==SSL_TYPE_X509) + global.append(" REQUIRE X509",13); + else if(acl_user->ssl_type==SSL_TYPE_SPECIFIED) + { + global.append(" REQUIRE ",9); + if(acl_user->x509_issuer) { + if(ssl_options++) + global.append(" AND ",5); + global.append("ISSUER \"",8); + global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); + global.append("\"",1); } -#endif + if(acl_user->x509_subject) { + if(ssl_options++) + global.append(" AND ",5); + global.append("SUBJECT \"",9); + global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); + global.append("\"",1); + } + if(acl_user->ssl_cipher) { + if(ssl_options++) + global.append(" AND ",5); + global.append("CIPHER \"",8); + global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); + global.append("\"",1); + } + } +#endif /* HAVE_OPENSSL */ if (want_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); thd->packet.length(0); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index cf9696d51e7..e6a39f1b269 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -59,7 +59,7 @@ void acl_reload(void); void acl_free(bool end=0); uint acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); -uint acl_getroot(const char *host, const char *ip, const char *user, +uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble,char **priv_user, bool old_ver); bool acl_check_host(const char *host, const char *ip); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ff404cce0d6..c5c73cb85dd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -56,7 +56,7 @@ enum enum_sql_command { SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA, SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, - SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, + SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER }; enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, @@ -145,7 +145,8 @@ typedef struct st_lex { char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ - char* ssl_subject,*ssl_issuer,*ssl_chipher; + char* x509_subject,*x509_issuer,*ssl_cipher; + enum SSL_type ssl_type; /* defined in violite.h */ String *wild; sql_exchange *exchange; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c6e23eb927a..5629c473eac 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -115,7 +115,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, send_error(net,ER_OUT_OF_RESOURCES); return 1; } - thd->master_access=acl_getroot(thd->host, thd->ip, thd->user, + thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, protocol_version == 9 || !(thd->client_capabilities & @@ -433,7 +433,7 @@ check_connections(THD *thd) DBUG_PRINT("info", ("Agreed to change IO layer to SSL") ); /* Do the SSL layering. */ DBUG_PRINT("info", ("IO layer change in progress...")); - sslaccept(ssl_acceptor_fd, net->vio); + sslaccept(ssl_acceptor_fd, net->vio, (long)60L); DBUG_PRINT("info", ("Reading user information over SSL layer")); if ((pkt_len=my_net_read(net)) == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 67713b85720..28d405690bd 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1173,18 +1173,46 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) net_store_data(&packet2,(uint32) SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT_GOOD: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE: net_store_data(&packet2,(uint32) SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_CB_HITS: net_store_data(&packet2,(uint32) SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_HITS: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_CACHE_FULL: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_MISSES: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_TIMEOUTS: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_NUMBER: net_store_data(&packet2,(uint32) SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE: net_store_data(&packet2,(uint32) SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_)); @@ -1246,6 +1274,23 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) break; case SHOW_SSL_GET_CIPHER: net_store_data(&packet2, thd->net.vio->ssl_ ? SSL_get_cipher(thd->net.vio->ssl_) : ""); + case SHOW_SSL_GET_CIPHER_LIST: + if(thd->net.vio->ssl_) + { + char buf[1024]=""; + for (int i=0; ; i++) + { + const char *p=SSL_get_cipher_list(thd->net.vio->ssl_,i); + if (p == NULL) + break; + if (i != 0) + strcat(buf,":"); + strcat(buf,p); + DBUG_PRINT("info",("cipher to add: %s,%s",p,buf)); + } + net_store_data(&packet2, buf); + } else + net_store_data(&packet2, ""); break; #endif /* HAVE_OPENSSL */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1995c1295f1..27f4d56b3a3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -285,6 +285,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SERIALIZABLE_SYM %token SESSION_SYM %token SHUTDOWN +%token SSL_SYM %token STARTING %token STATUS_SYM %token STRAIGHT_JOIN @@ -316,6 +317,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token WHERE %token WITH %token WRITE_SYM +%token X509_SYM %token COMPRESSED_SYM %token BIGINT @@ -3265,10 +3267,11 @@ grant: lex->columns.empty(); lex->grant= lex->grant_tot_col=0; lex->select->db=0; - lex->ssl_chipher=lex->ssl_subject=lex->ssl_issuer=0; + lex->ssl_type=SSL_TYPE_NONE; + lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0; } grant_privileges ON opt_table TO_SYM user_list - grant_option require_clause + require_clause grant_option grant_privileges: grant_privilege_list {} @@ -3302,25 +3305,32 @@ grant_privilege: | FILE_SYM { Lex->grant |= FILE_ACL;} | GRANT OPTION { Lex->grant |= GRANT_ACL;} -require_clause: /* empty */ - | REQUIRE_SYM require_list - - require_list: require_list_element AND require_list | require_list_element - require_list_element: SUBJECT_SYM TEXT_STRING { - Lex->ssl_subject=$2.str; + if (Lex->x509_subject) { + send_error(&Lex->thd->net,ER_GRANT_DUPL_SUBJECT); + YYABORT; + } else + Lex->x509_subject=$2.str; } | ISSUER_SYM TEXT_STRING { - Lex->ssl_issuer=$2.str; + if (Lex->x509_issuer) { + send_error(&Lex->thd->net,ER_GRANT_DUPL_ISSUER); + YYABORT; + } else + Lex->x509_issuer=$2.str; } | CIPHER_SYM TEXT_STRING { - Lex->ssl_chipher=$2.str; + if (Lex->ssl_cipher) { + send_error(&Lex->thd->net,ER_GRANT_DUPL_CIPHER); + YYABORT; + } else + Lex->ssl_cipher=$2.str; } opt_table: @@ -3429,16 +3439,18 @@ column_list_id: require_clause: /* empty */ - | REQUIRE_SYM require_list { /* do magic */} - -require_list: require_list_element AND require_list - { /* do magic */} - | require_list_element {/*do magic*/} - -require_list_element: SUBJECT_SYM TEXT_STRING - | ISSUER TEXT_STRING - | CIPHER TEXT_STRING - + | REQUIRE_SYM require_list + { + Lex->ssl_type=SSL_TYPE_SPECIFIED; + } + | REQUIRE_SYM SSL_SYM + { + Lex->ssl_type=SSL_TYPE_ANY; + } + | REQUIRE_SYM X509_SYM + { + Lex->ssl_type=SSL_TYPE_X509; + } grant_option: /* empty */ {} diff --git a/sql/structs.h b/sql/structs.h index 12ba5004a2e..efdcb1af401 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -134,7 +134,11 @@ enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL, ,SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER ,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE ,SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH - ,SHOW_SSL_CTX_GET_VERIFY_DEPTH + ,SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT + ,SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD + ,SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES + ,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL + ,SHOW_SSL_GET_CIPHER_LIST #endif /* HAVE_OPENSSL */ }; diff --git a/vio/test-ssl.c b/vio/test-ssl.c index 0ae90f5001f..61d92bb7b84 100644 --- a/vio/test-ssl.c +++ b/vio/test-ssl.c @@ -41,6 +41,7 @@ main( int argc, char* server_key = 0, *server_cert = 0; char* client_key = 0, *client_cert = 0; char* ca_file = 0, *ca_path = 0; + char* cipher=0; int child_pid,sv[2]; struct st_VioSSLAcceptorFd* ssl_acceptor=0; struct st_VioSSLConnectorFd* ssl_connector=0; @@ -74,17 +75,17 @@ main( int argc, if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1) fatal_error("socketpair"); - ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path); - ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path); + ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher); + ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher); client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; client_vio->vioblocking(client_vio,0); - sslconnect(ssl_connector,client_vio); + sslconnect(ssl_connector,client_vio,60L); server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; server_vio->vioblocking(client_vio,0); - sslaccept(ssl_acceptor,server_vio); + sslaccept(ssl_acceptor,server_vio,60L); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c index c19a3589009..b50b0722b17 100644 --- a/vio/test-sslclient.c +++ b/vio/test-sslclient.c @@ -32,7 +32,7 @@ main( int argc __attribute__((unused)), char** argv) { char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem"; - char ca_file[] = "../SSL/cacert.pem", *ca_path = 0; + char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0; struct st_VioSSLConnectorFd* ssl_connector=0; struct sockaddr_in sa; Vio* client_vio=0; @@ -48,7 +48,7 @@ main( int argc __attribute__((unused)), if (ca_path!=0) printf("CApath : %s\n", ca_path); - ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path); + ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher); if(!ssl_connector) { fatal_error("client:new_VioSSLConnectorFd failed"); } @@ -69,7 +69,7 @@ main( int argc __attribute__((unused)), /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ read(client_vio->sd,xbuf, sizeof(xbuf)); - sslconnect(ssl_connector,client_vio); + sslconnect(ssl_connector,client_vio,60L); err = client_vio->read(client_vio,xbuf, sizeof(xbuf)); if (err<=0) { my_free((gptr)ssl_connector,MYF(0)); diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c index bad141dff17..610a4173875 100644 --- a/vio/test-sslserver.c +++ b/vio/test-sslserver.c @@ -46,7 +46,7 @@ do_ssl_stuff( TH_ARGS* args) /* TCP connection is ready. Do server side SSL. */ err = write(server_vio->sd,(gptr)s, strlen(s)); - sslaccept(args->ssl_acceptor,server_vio); + sslaccept(args->ssl_acceptor,server_vio,60L); err = server_vio->write(server_vio,(gptr)s, strlen(s)); DBUG_VOID_RETURN; } @@ -65,7 +65,8 @@ main( int argc __attribute__((unused)), char server_key[] = "../SSL/server-key.pem", server_cert[] = "../SSL/server-cert.pem"; char ca_file[] = "../SSL/cacert.pem", - *ca_path = 0; + *ca_path = 0, + *cipher = 0; struct st_VioSSLAcceptorFd* ssl_acceptor; pthread_t th; TH_ARGS th_args; @@ -89,7 +90,7 @@ main( int argc __attribute__((unused)), if (ca_path!=0) printf("CApath : %s\n", ca_path); - th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path); + th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path,cipher); /* ----------------------------------------------- */ /* Prepare TCP socket for receiving connections */ diff --git a/vio/viosocket.c b/vio/viosocket.c index 667e9b2b118..60272db3171 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -137,7 +137,7 @@ int vio_write(Vio * vio, const gptr buf, int size) } -int vio_blocking(Vio * vio, my_bool set_blocking_mode) +int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode) { int r=0; DBUG_ENTER("vio_blocking"); diff --git a/vio/viossl.c b/vio/viossl.c index c6f70081d18..e80dc0ce807 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -118,8 +118,11 @@ int vio_ssl_read(Vio * vio, gptr buf, int size) #endif /* DBUG_OFF */ r = SSL_read(vio->ssl_, buf, size); #ifndef DBUG_OFF - if ( r< 0) + if ( r<= 0) { + r=SSL_get_error(vio->ssl_, r); + DBUG_PRINT("info",("SSL_get_error returned %d",r)); report_errors(); + } #endif /* DBUG_OFF */ DBUG_PRINT("exit", ("%d", r)); DBUG_RETURN(r); @@ -207,7 +210,6 @@ int vio_ssl_close(Vio * vio) r = SSL_shutdown(vio->ssl_); SSL_free(vio->ssl_); vio->ssl_= 0; - vio->bio_ = 0; } if (shutdown(vio->sd,2)) r= -1; @@ -298,12 +300,11 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout) #endif } -void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio) +void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) { - X509* client_cert; + X509* client_cert; char *str; - int i; -// const int blocking = vio_is_blocking(vio); + char buf[1024]; DBUG_ENTER("sslaccept"); DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr)); vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); @@ -316,49 +317,12 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio) DBUG_VOID_RETURN; } DBUG_PRINT("info", ("ssl_=%p",vio->ssl_)); + SSL_clear(vio->ssl_); vio_blocking(vio, FALSE); + SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd(vio->ssl_,vio->sd); SSL_set_accept_state(vio->ssl_); - - /* FIXME possibly infinite loop */ - while (SSL_is_init_finished(vio->ssl_)) { - DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1")); - if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE) - { - DBUG_PRINT("info",("*** errno %d",errno)); - switch (SSL_get_error(vio->ssl_,i)) - { - case SSL_ERROR_NONE: - DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished")); - break; - case SSL_ERROR_SSL: - DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error ")); - break; - case SSL_ERROR_WANT_CONNECT: - DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established")); - break; - case SSL_ERROR_WANT_READ: - DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available")); - break; - case SSL_ERROR_WANT_WRITE: - DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write")); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */")); - break; - case SSL_ERROR_SYSCALL: - DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno)); - break; - case SSL_ERROR_ZERO_RETURN: - DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */")); - break; - default: - DBUG_PRINT("info",("Unknown SSL error returned")); - break; - } - } - usleep(100); - } + SSL_do_handshake(vio->ssl_); vio->open_ = TRUE; #ifndef DBUF_OFF DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" @@ -374,23 +338,28 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio) DBUG_PRINT("info",("\t issuer: %s", str)); free (str); - /* We could do all sorts of certificate verification stuff here before - * deallocating the certificate. */ - X509_free (client_cert); } else DBUG_PRINT("info",("Client does not have certificate.")); + + str=SSL_get_shared_ciphers(vio->ssl_, buf, sizeof(buf)); + if(str) + { + DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str)); + } + else + { + DBUG_PRINT("info",("no shared ciphers!")); + } + #endif DBUG_VOID_RETURN; } -void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio) +void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) { char *str; -// char s[]="abc"; -int i; X509* server_cert; - const int blocking = vio_is_blocking(vio); DBUG_ENTER("sslconnect"); DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_)); vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); @@ -403,50 +372,13 @@ int i; report_errors(); DBUG_VOID_RETURN; } - DBUG_PRINT("info", ("ssl_=%p",vio->ssl_)); + DBUG_PRINT("info",("ssl_=%p",vio->ssl_)); + SSL_clear(vio->ssl_); vio_blocking(vio, FALSE); + SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd (vio->ssl_, vio->sd); SSL_set_connect_state(vio->ssl_); - - /* FIXME possibly infinite loop */ - while (SSL_is_init_finished(vio->ssl_)) { - DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1")); - if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE) - { - DBUG_PRINT("info",("*** errno %d",errno)); - switch (SSL_get_error(vio->ssl_,i)) - { - case SSL_ERROR_NONE: - DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished")); - break; - case SSL_ERROR_SSL: - DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error ")); - break; - case SSL_ERROR_WANT_CONNECT: - DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established")); - break; - case SSL_ERROR_WANT_READ: - DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available")); - break; - case SSL_ERROR_WANT_WRITE: - DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write")); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */")); - break; - case SSL_ERROR_SYSCALL: - DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno)); - break; - case SSL_ERROR_ZERO_RETURN: - DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */")); - break; - default: - DBUG_PRINT("info",("Unknown SSL error returned")); - break; - } - } - usleep(100); - } + SSL_do_handshake(vio->ssl_); vio->open_ = TRUE; #ifndef DBUG_OFF DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" @@ -469,9 +401,7 @@ int i; } else DBUG_PRINT("info",("Server does not have certificate.")); #endif - vio_blocking(vio, blocking); DBUG_VOID_RETURN; } - #endif /* HAVE_OPENSSL */ diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 077807726fe..579f37f3dda 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -168,15 +168,17 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx) struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, const char* cert_file, const char* ca_file, - const char* ca_path) + const char* ca_path, + const char* cipher) { int verify = SSL_VERIFY_PEER; struct st_VioSSLConnectorFd* ptr; + int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLConnectorFd"); DBUG_PRINT("enter", - ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s", - key_file, cert_file, ca_path, ca_file)); + ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", + key_file, cert_file, ca_path, ca_file, cipher)); ptr=(struct st_VioSSLConnectorFd*)my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)); ptr->ssl_context_=0; ptr->ssl_method_=0; @@ -206,8 +208,12 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, /* * SSL_CTX_set_options * SSL_CTX_set_info_callback - * SSL_CTX_set_cipher_list */ + if(cipher) + { + result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher); + DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); + } SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback); if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1) { @@ -231,14 +237,6 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh); DH_free(dh); -/*if (cipher != NULL) - if(!SSL_CTX_set_cipher_list(ctx,cipher)) { - BIO_printf(bio_err,"error setting cipher list\n"); - ERR_print_errors(bio_err); - goto end; - } -*/ - DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); @@ -253,18 +251,20 @@ struct st_VioSSLAcceptorFd* new_VioSSLAcceptorFd(const char* key_file, const char* cert_file, const char* ca_file, - const char* ca_path) + const char* ca_path, + const char* cipher) { int verify = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE); struct st_VioSSLAcceptorFd* ptr; + int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLAcceptorFd"); DBUG_PRINT("enter", - ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s", - key_file, cert_file, ca_path, ca_file)); + ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", + key_file, cert_file, ca_path, ca_file, cipher)); ptr=(struct st_VioSSLAcceptorFd*)my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)); ptr->ssl_context_=0; @@ -293,12 +293,19 @@ new_VioSSLAcceptorFd(const char* key_file, report_errors(); goto ctor_failure; } + if(cipher) + { + result=SSL_CTX_set_cipher_list(ptr->ssl_context_, cipher); + DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); + } /* * SSL_CTX_set_quiet_shutdown(ctx,1); * */ SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128); + + /* DH? */ SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback); @@ -328,14 +335,6 @@ new_VioSSLAcceptorFd(const char* key_file, SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh); DH_free(dh); -/*if (cipher != NULL) - if(!SSL_CTX_set_cipher_list(ctx,cipher)) { - BIO_printf(bio_err,"error setting cipher list\n"); - ERR_print_errors(bio_err); - goto end; - } -*/ - DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); From 34c3484fae0ef57d145f60190d9740e9535a7178 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 30 Sep 2001 05:47:34 +0300 Subject: [PATCH 22/38] Fixes to get openssl code to compile --- include/violite.h | 2 +- libmysqld/lib_sql.cc | 62 ++++------ sql/mysqld.cc | 4 +- sql/sql_acl.cc | 279 ++++++++++++++++++++++--------------------- 4 files changed, 166 insertions(+), 181 deletions(-) diff --git a/include/violite.h b/include/violite.h index c59f6124838..d5f697b26c4 100644 --- a/include/violite.h +++ b/include/violite.h @@ -108,7 +108,6 @@ my_bool vio_poll_read(Vio *vio,uint timeout); #ifdef __cplusplus } #endif -#endif /* vio_violite_h_ */ #if defined(HAVE_VIO) && !defined(DONT_MAP_VIO) #define vio_delete(vio) (vio)->viodelete(vio) @@ -237,3 +236,4 @@ struct st_vio #endif /* HAVE_VIO */ }; #endif /* EMBEDDED_LIBRARY */ +#endif /* vio_violite_h_ */ diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 116219372fd..f2599fe4016 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -19,13 +19,16 @@ #include "../regex/regex.h" #include "my_sys.h" +/* + The following is needed to not cause conflicts when we include mysqld.cc +*/ + #define main main1 #define mysql_unix_port mysql_inix_port1 #define mysql_port mysql_port1 #define net_read_timeout net_read_timeout1 #define net_write_timeout net_write_timeout1 #define changeable_vars changeable_vars1 -//#define mysql_tmpdir mysql_tmpdir1 extern "C" { @@ -36,38 +39,23 @@ extern "C" class THD; -static int -check_connections1(THD * thd); - -static bool -check_user(THD *thd, enum_server_command command,const char *user, const char *passwd, const char *db, bool check_count); - -static int -check_connections2(THD * thd); - -extern void free_defaults(char ** argv); -void free_defaults_internal(char ** argv){if (argv) free_defaults(argv);} +static int check_connections1(THD * thd); +static int check_connections2(THD * thd); +static bool check_user(THD *thd, enum_server_command command, + const char *user, const char *passwd, const char *db, + bool check_count); +void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);} #define free_defaults free_defaults_internal char mysql_data_home[FN_REFLEN]; -char * get_mysql_data_home(){return mysql_data_home;}; +char * get_mysql_data_home() { return mysql_data_home; } #define mysql_data_home mysql_data_home_internal #include "../sql/mysqld.cc" #define SCRAMBLE_LENGTH 8 extern "C" { - -/* -void -free_defaults(char ** argv) {}; -void -load_defaults(const char *, const char **, int *, char ***) {}; -*/ - -char * -get_mysql_home(){ return mysql_home;}; -char * -get_mysql_real_data_home(){ return mysql_real_data_home;}; +char * get_mysql_home(){ return mysql_home;}; +char * get_mysql_real_data_home(){ return mysql_real_data_home;}; bool lib_dispatch_command(enum enum_server_command command, NET *net, @@ -83,9 +71,7 @@ bool lib_dispatch_command(enum enum_server_command command, NET *net, } - -void -lib_connection_phase(NET * net, int phase) +void lib_connection_phase(NET * net, int phase) { THD * thd; thd = (THD *)(net->vio->dest_thd); @@ -99,7 +85,9 @@ lib_connection_phase(NET * net, int phase) } } } -} +} /* extern "C" */ + + void start_embedded_conn1(NET * net) { THD * thd = new THD; @@ -660,16 +648,14 @@ void mysql_thread_end() void start_embedded_connection(NET * net) { - start_embedded_conn1(net); -} -//==================================================================== + start_embedded_conn1(net); } + +} /* extern "C" */ + int embedded_do_command(NET * net) { - THD * thd = (THD *) net ->vio; - do_command(thd); - return 0; + THD * thd = (THD *) net ->vio; + do_command(thd); + return 0; } - - - diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b27cb8a6bf3..c14ae3aa61a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -677,9 +677,7 @@ static sig_handler print_signal_warning(int sig) void unireg_end(int signal_number __attribute__((unused))) { clean_up(); -#if defined(EMBEDDED_LIBRARY) - exit(0); // XXX QQ: this is a temporary hack (I hope) -#else +#ifndef EMBEDDED_LIBRARY pthread_exit(0); // Exit is in main thread #endif } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 2f6c126e693..888ccf7b482 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -205,17 +205,20 @@ int acl_init(bool dont_read_acl_tables) user.password=get_field(&mem, table,2); #ifdef HAVE_OPENSSL DBUG_PRINT("info",("table->fields=%d",table->fields)); - if (table->fields >= 21) { /* From 4.0.0 we have more fields */ - if(!strcmp(get_field(&mem, table,17),"ANY")) + if (table->fields >= 21) /* From 4.0.0 we have more fields */ + { + char *ssl_type=get_field(&mem, table,17); + if (!strcmp(ssl_type, "ANY")) user.ssl_type=SSL_TYPE_ANY; - else if(!strcmp(get_field(&mem, table,17),"X509")) + else if (!strcmp(ssl_type, "X509")) user.ssl_type=SSL_TYPE_X509; - else if(!strcmp(get_field(&mem, table,17),"SPECIFIED")) + else if (!strcmp(ssl_type, "SPECIFIED")) user.ssl_type=SSL_TYPE_SPECIFIED; - else user.ssl_type=SSL_TYPE_NONE; - user.ssl_cipher=get_field(&mem, table,18); - user.x509_issuer=get_field(&mem, table,19); - user.x509_subject=get_field(&mem, table,20); + else + user.ssl_type=SSL_TYPE_NONE; + user.ssl_cipher=get_field(&mem, table, 18); + user.x509_issuer=get_field(&mem, table, 19); + user.x509_subject=get_field(&mem, table, 20); } #endif /* HAVE_OPENSSL */ if (user.password && (length=(uint) strlen(user.password)) == 8 && @@ -447,82 +450,87 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, (my_bool) old_ver))) { #ifdef HAVE_OPENSSL -#define vio (thd->net.vio) - /* In this point we know that user is allowed to connect - * from given host by given username/password pair. Now - * we check if SSL is required, if user is using SSL and - * if X509 certificate attributes are OK - */ + Vio *vio=thd->net.vio; + /* + In this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK + */ switch(acl_user->ssl_type) { case SSL_TYPE_NONE: /* SSL is not required to connect */ - user_access=acl_user->access; - break; + user_access=acl_user->access; + break; case SSL_TYPE_ANY: /* Any kind of SSL is good enough */ - if(vio_type(vio) == VIO_TYPE_SSL) - user_access=acl_user->access; - break; + if (vio_type(vio) == VIO_TYPE_SSL) + user_access=acl_user->access; + break; case SSL_TYPE_X509: /* Client should have any valid certificate. */ - /* Connections with non-valid certificates are dropped already - * in sslaccept() anyway, so we do not check validity here. - */ - if(SSL_get_peer_certificate(vio->ssl_)) - user_access=acl_user->access; - break; - case SSL_TYPE_SPECIFIED: /* Client should have attributes as specified */ - /* We do not check for absence of SSL because without SSL it does not - * pass all checks here anyway. - */ - /* If cipher name is specified, we compare it to actual cipher in use */ - if(acl_user->ssl_cipher) - DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", - acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))); - if(!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))) - user_access=acl_user->access; - else - { - user_access=NO_ACCESS; - break; - } - /* Prepare certificate (if exists) */ - DBUG_PRINT("info",("checkpoint 1")); - X509* cert=SSL_get_peer_certificate(vio->ssl_); - DBUG_PRINT("info",("checkpoint 2")); - /* If X509 issuer is speified, we check it... */ - if(acl_user->x509_issuer) - { - DBUG_PRINT("info",("checkpoint 3")); - ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); - DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", - acl_user->x509_issuer, ptr)); - if(!strcmp(acl_user->x509_issuer,ptr)) - user_access=acl_user->access; - else - { - user_access=NO_ACCESS; - free(ptr); - break; - } - free(ptr); - } - DBUG_PRINT("info",("checkpoint 4")); - /* X509 subject is specified, we check it .. */ - if(acl_user->x509_subject) - { - ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); - DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", - acl_user->x509_subject, ptr)); - if(!strcmp(acl_user->x509_subject,ptr)) - user_access=acl_user->access; - else - { - user_access=NO_ACCESS; - free(ptr); - break; - } - free(ptr); - } - DBUG_PRINT("info",("checkpoint 5")); - break; + /* + Connections with non-valid certificates are dropped already + in sslaccept() anyway, so we do not check validity here. + */ + if (SSL_get_peer_certificate(vio->ssl_)) + user_access=acl_user->access; + break; + case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ + /* + We do not check for absence of SSL because without SSL it does + not pass all checks here anyway. + If cipher name is specified, we compare it to actual cipher in + use. + */ + if (acl_user->ssl_cipher) + DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", + acl_user->ssl_cipher, + SSL_get_cipher(vio->ssl_))); + if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + break; + } + /* Prepare certificate (if exists) */ + DBUG_PRINT("info",("checkpoint 1")); + X509* cert=SSL_get_peer_certificate(vio->ssl_); + DBUG_PRINT("info",("checkpoint 2")); + /* If X509 issuer is speified, we check it... */ + if (acl_user->x509_issuer) + { + DBUG_PRINT("info",("checkpoint 3")); + ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", + acl_user->x509_issuer, ptr)); + if (!strcmp(acl_user->x509_issuer,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 4")); + /* X509 subject is specified, we check it .. */ + if (acl_user->x509_subject) + { + ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", + acl_user->x509_subject, ptr)); + if (!strcmp(acl_user->x509_subject,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 5")); + break; } DBUG_PRINT("info",("checkpoint 6")); #else /* HAVE_OPENSSL */ @@ -557,12 +565,10 @@ static byte* check_get_key(ACL_USER *buff,uint *length, static void acl_update_user(const char *user, const char *host, const char *password, -#ifdef HAVE_OPENSSL enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, -#endif /* HAVE_OPENSSL */ uint privileges) { for (uint i=0 ; i < acl_users.elements ; i++) @@ -601,12 +607,10 @@ static void acl_update_user(const char *user, const char *host, static void acl_insert_user(const char *user, const char *host, const char *password, -#ifdef HAVE_OPENSSL enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, -#endif /* HAVE_OPENSSL */ uint privileges) { ACL_USER acl_user; @@ -1158,37 +1162,35 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, rights=get_access(table,3); #ifdef HAVE_OPENSSL /* We write down SSL related ACL stuff */ - DBUG_PRINT("info",("table->fields=%d",table->fields)); - if (table->fields >= 21) { /* From 4.0.0 we have more fields */ - switch (thd->lex.ssl_type) { - case SSL_TYPE_ANY: - table->field[17]->store("ANY",3); - table->field[18]->store("",0); - table->field[19]->store("",0); - table->field[20]->store("",0); - break; - case SSL_TYPE_X509: - table->field[17]->store("X509",4); - table->field[18]->store("",0); - table->field[19]->store("",0); - table->field[20]->store("",0); - break; - case SSL_TYPE_SPECIFIED: - table->field[17]->store("SPECIFIED",9); - if(thd->lex.ssl_cipher) - table->field[18]->store(thd->lex.ssl_cipher,strlen(thd->lex.ssl_cipher)); - if(thd->lex.x509_issuer) - table->field[19]->store(thd->lex.x509_issuer,strlen(thd->lex.x509_issuer)); - if(thd->lex.x509_subject) - table->field[20]->store(thd->lex.x509_subject,strlen(thd->lex.x509_subject)); - break; - default: - table->field[17]->store("NONE",4); - table->field[18]->store("",0); - table->field[19]->store("",0); - table->field[20]->store("",0); - } + DBUG_PRINT("info",("table->fields=%d",table->fields)); + if (table->fields >= 21) /* From 4.0.0 we have more fields */ + { + table->field[18]->store("",0); + table->field[19]->store("",0); + table->field[20]->store("",0); + switch (thd->lex.ssl_type) { + case SSL_TYPE_ANY: + table->field[17]->store("ANY",3); + break; + case SSL_TYPE_X509: + table->field[17]->store("X509",4); + break; + case SSL_TYPE_SPECIFIED: + table->field[17]->store("SPECIFIED",9); + if (thd->lex.ssl_cipher) + table->field[18]->store(thd->lex.ssl_cipher, + strlen(thd->lex.ssl_cipher)); + if (thd->lex.x509_issuer) + table->field[19]->store(thd->lex.x509_issuer, + strlen(thd->lex.x509_issuer)); + if (thd->lex.x509_subject) + table->field[20]->store(thd->lex.x509_subject, + strlen(thd->lex.x509_subject)); + break; + default: + table->field[17]->store("NONE",4); } + } #endif /* HAVE_OPENSSL */ if (old_row_exists) { @@ -1216,7 +1218,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } error=0; // Privileges granted / revoked - end: +end: if (!error) { acl_cache->clear(1); // Clear privilege cache @@ -1224,22 +1226,18 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, password=0; // No password given on command if (old_row_exists) acl_update_user(combo.user.str,combo.host.str,password, -#ifdef HAVE_OPENSSL - thd->lex.ssl_type, - thd->lex.ssl_cipher, - thd->lex.x509_issuer, - thd->lex.x509_subject, -#endif /* HAVE_OPENSSL */ - rights); + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, + rights); else acl_insert_user(combo.user.str,combo.host.str,password, -#ifdef HAVE_OPENSSL - thd->lex.ssl_type, - thd->lex.ssl_cipher, - thd->lex.x509_issuer, - thd->lex.x509_subject, -#endif /* HAVE_OPENSSL */ - rights); + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, + rights); } table->file->index_end(); DBUG_RETURN(error); @@ -2591,30 +2589,33 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append('\''); } #ifdef HAVE_OPENSSL -/* "show grants" SSL related stuff */ - if(acl_user->ssl_type==SSL_TYPE_ANY) + /* "show grants" SSL related stuff */ + if (acl_user->ssl_type == SSL_TYPE_ANY) global.append(" REQUIRE SSL",12); - else if(acl_user->ssl_type==SSL_TYPE_X509) + else if (acl_user->ssl_type==SSL_TYPE_X509) global.append(" REQUIRE X509",13); - else if(acl_user->ssl_type==SSL_TYPE_SPECIFIED) + else if (acl_user->ssl_type==SSL_TYPE_SPECIFIED) { global.append(" REQUIRE ",9); - if(acl_user->x509_issuer) { - if(ssl_options++) + if (acl_user->x509_issuer) + { + if (ssl_options++) global.append(" AND ",5); global.append("ISSUER \"",8); global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); global.append("\"",1); } - if(acl_user->x509_subject) { - if(ssl_options++) + if (acl_user->x509_subject) + { + if (ssl_options++) global.append(" AND ",5); global.append("SUBJECT \"",9); global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); global.append("\"",1); } - if(acl_user->ssl_cipher) { - if(ssl_options++) + if (acl_user->ssl_cipher) + { + if (ssl_options++) global.append(" AND ",5); global.append("CIPHER \"",8); global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); From 2350609bce82a814456168a79546c7003fbaf0fd Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 30 Sep 2001 05:47:35 +0300 Subject: [PATCH 23/38] Fixed that SHOW CREATE TABLE shows all attributes --- Docs/manual.texi | 19 +++++++++++-------- mysql-test/r/show_check.result | 18 ++++++++++++++++++ mysql-test/t/show_check.test | 8 ++++++++ sql/handler.h | 8 ++++++-- sql/sql_show.cc | 13 ++++++++++++- sql/sql_table.cc | 28 +++++++++++++++++----------- sql/sql_yacc.yy | 10 ++++++---- sql/table.cc | 2 ++ 8 files changed, 80 insertions(+), 26 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index d3dcb6ee0db..a8a7844589c 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -33982,14 +33982,14 @@ reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT table_options: - TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MYISAM @} + TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM @} or AUTO_INCREMENT = # or AVG_ROW_LENGTH = # or CHECKSUM = @{0 | 1@} or COMMENT = "string" or MAX_ROWS = # or MIN_ROWS = # -or PACK_KEYS = @{0 | 1@} +or PACK_KEYS = @{0 | 1 | DEFAULT@} or PASSWORD = "string" or DELAY_KEY_WRITE = @{0 | 1@} or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} @@ -34229,6 +34229,7 @@ The different table types are: @item ISAM @tab The original table handler. @xref{ISAM}. @item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}. @item MERGE @tab A collection of MyISAM tables used as one table. @xref{MERGE}. +@item MRG_MERGE @tab An alias for MERGE tables @item MyISAM @tab The new binary portable table handler that is replacing ISAM. @xref{MyISAM}. @end multitable @xref{Table types}. @@ -34250,7 +34251,7 @@ The options work for all table types, if not otherwise indicated: @item @code{COMMENT} @tab A 60-character comment for your table. @item @code{MAX_ROWS} @tab Max number of rows you plan to store in the table. @item @code{MIN_ROWS} @tab Minimum number of rows you plan to store in the table. -@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). +@item @code{PACK_KEYS} @tab Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM). Setting this to 0 will disable all packing of keys. Setting this to @code{DEFAULT} (MySQL 4.0) will tell the table handler to only pack long @code{CHAR}/@code{VARCHAR} columns. @item @code{PASSWORD} @tab Encrypt the @code{.frm} file with a password. This option doesn't do anything in the standard MySQL version. @item @code{DELAY_KEY_WRITE} @tab Set this to 1 if want to delay key table updates until the table is closed (MyISAM). @item @code{ROW_FORMAT} @tab Defines how the rows should be stored. Currently this option only works with MyISAM tables, which supports the @code{DYNAMIC} and @code{FIXED} row formats. @xref{MyISAM table formats}. @@ -36070,11 +36071,11 @@ is not signaled to the other servers. @code{MERGE} tables are new in MySQL Version 3.23.25. The code is still in gamma, but should be resonable stable. -A @code{MERGE} table is a collection of identical @code{MyISAM} tables -that can be used as one. You can only @code{SELECT}, @code{DELETE}, and -@code{UPDATE} from the collection of tables. If you @code{DROP} the -@code{MERGE} table, you are only dropping the @code{MERGE} -specification. +A @code{MERGE} table (also known as a @code{MRG_MyISAM} table) is a +collection of identical @code{MyISAM} tables that can be used as one. +You can only @code{SELECT}, @code{DELETE}, and @code{UPDATE} from the +collection of tables. If you @code{DROP} the @code{MERGE} table, you +are only dropping the @code{MERGE} specification. Note that @code{DELETE FROM merge_table} used without a @code{WHERE} will only clear the mapping for the table, not delete everything in the @@ -47709,6 +47710,8 @@ Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster. Optimized queries of type: @code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #} @item +@code{SHOW CREATE TABLE} now shows all table attributes. +@item @code{ORDER BY ... DESC} can now use keys. @item @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave. diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index a8be3f04249..2e323f73793 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -93,3 +93,21 @@ t1 CREATE TABLE `t1` ( Database Table In_use Name_locked Database Table In_use Name_locked test t1 0 0 +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` char(10) default NULL, + KEY `b` (`b`) +) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test' +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` varchar(10) default NULL, + KEY `b` (`b`) +) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test' +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` varchar(10) default NULL, + KEY `b` (`b`) +) TYPE=MyISAM diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 0e0d79e7d16..6bbad3dea59 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -79,3 +79,11 @@ create table t1(n int); insert into t1 values (1); show open tables; drop table t1; + +create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed; +show create table t1; +alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0; +show create table t1; +ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default; +show create table t1; +drop table t1; diff --git a/sql/handler.h b/sql/handler.h index dee71e8ebda..f0806ea3bea 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -114,8 +114,8 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI, DB_TYPE_DEFAULT }; -enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, - ROW_TYPE_COMPRESSED }; +enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, + ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED}; /* struct to hold information about the table that should be created */ @@ -124,6 +124,10 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, #define HA_CREATE_USED_RAID 2 #define HA_CREATE_USED_UNION 4 #define HA_CREATE_USED_INSERT_METHOD 8 +#define HA_CREATE_USED_MIN_ROWS 16 +#define HA_CREATE_USED_MAX_ROWS 32 +#define HA_CREATE_USED_AVG_ROW_LENGTH 64 +#define HA_CREATE_USED_PACK_KEYS 128 typedef struct st_thd_trans { void *bdb_tid; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 28d405690bd..438d6b7eed6 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -390,7 +390,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); if (table->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " format=", ha_row_type[(uint) table->row_type], + ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) table->row_type], NullS); if (file->raid_type) { @@ -919,6 +919,12 @@ store_create_info(THD *thd, TABLE *table, String *packet) p = longlong10_to_str(table->max_rows, buff, 10); packet->append(buff, (uint) (p - buff)); } + if (table->avg_row_length) + { + packet->append(" AVG_ROW_LENGTH="); + p=longlong10_to_str(table->avg_row_length, buff,10); + packet->append(buff, (uint) (p - buff)); + } if (table->db_create_options & HA_OPTION_PACK_KEYS) packet->append(" PACK_KEYS=1", 12); @@ -928,6 +934,11 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" CHECKSUM=1", 11); if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) packet->append(" DELAY_KEY_WRITE=1",18); + if (table->row_type != ROW_TYPE_DEFAULT) + { + packet->append(" ROW_FORMAT=",12); + packet->append(ha_row_type[(uint) table->row_type]); + } table->file->append_create_info(packet); if (table->comment && table->comment[0]) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ad9bf532268..a5e9eec03b1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1110,7 +1110,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, bool use_timestamp=0; ha_rows copied,deleted; ulonglong next_insert_id; - uint save_time_stamp,db_create_options; + uint save_time_stamp,db_create_options, used_fields; enum db_type old_db_type,new_db_type; DBUG_ENTER("mysql_alter_table"); @@ -1119,6 +1119,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, db=table_list->db; if (!new_db) new_db=db; + used_fields=create_info->used_fields; if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -1164,7 +1165,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->db_type == DB_TYPE_DEFAULT) create_info->db_type=old_db_type; new_db_type=create_info->db_type= ha_checktype(create_info->db_type); - if (create_info->row_type == ROW_TYPE_DEFAULT) + if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; /* In some simple cases we need not to recreate the table */ @@ -1252,7 +1253,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* Reset auto_increment value if it was dropped */ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(create_info->used_fields & HA_CREATE_USED_AUTO)) + !(used_fields & HA_CREATE_USED_AUTO)) { create_info->auto_increment_value=0; create_info->used_fields|=HA_CREATE_USED_AUTO; @@ -1438,20 +1439,25 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } + db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD); (void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid, thd->thread_id); create_info->db_type=new_db_type; - if (!create_info->max_rows) - create_info->max_rows=table->max_rows; - if (!create_info->avg_row_length) - create_info->avg_row_length=table->avg_row_length; - table->file->update_create_info(create_info); if (!create_info->comment) create_info->comment=table->comment; + /* let new create options override the old ones */ - db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD); - if (create_info->table_options & - (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) + if (!(used_fields & HA_CREATE_USED_MIN_ROWS)) + create_info->min_rows=table->min_rows; + if (!(used_fields & HA_CREATE_USED_MAX_ROWS)) + create_info->max_rows=table->max_rows; + if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) + create_info->avg_row_length=table->avg_row_length; + + table->file->update_create_info(create_info); + if ((create_info->table_options & + (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) || + (used_fields & HA_CREATE_USED_PACK_KEYS)) db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); if (create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 27f4d56b3a3..95b7c0def7f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -774,13 +774,14 @@ create_table_options: create_table_option: TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; } - | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; } - | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; } - | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; } + | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} + | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} + | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} | PASSWORD EQ TEXT_STRING { Lex->create_info.password=$3.str; } | COMMENT_SYM EQ TEXT_STRING { Lex->create_info.comment=$3.str; } | AUTO_INC EQ ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} - | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; } + | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} + | PACK_KEYS_SYM EQ DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | CHECKSUM_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; } | DELAY_KEY_WRITE_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; } | ROW_FORMAT_SYM EQ row_types { Lex->create_info.row_type= $3; } @@ -1118,6 +1119,7 @@ alter: lex->select->db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; + lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } diff --git a/sql/table.cc b/sql/table.cc index 6c2f0e27c95..1ed856f7854 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -998,6 +998,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) { + DBUG_ENTER("update_create_info_from_table"); create_info->max_rows=table->max_rows; create_info->min_rows=table->min_rows; create_info->table_options=table->db_create_options; @@ -1006,6 +1007,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->raid_type=table->raid_type; create_info->raid_chunks=table->raid_chunks; create_info->raid_chunksize=table->raid_chunksize; + DBUG_VOID_RETURN; } int From 9f04e0e6d2370aa964f946f7464b3f8fa8daf99e Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 30 Sep 2001 18:35:08 +0300 Subject: [PATCH 24/38] Portability fix --- acinclude.m4 | 3 ++- client/mysql.cc | 1 - readline/rlstdc.h | 4 ++++ strings/Makefile.am | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 1535f0df5f7..b7f43fcb8e6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -767,7 +767,8 @@ dnl get substituted. AC_DEFUN(MYSQL_CHECK_ORBIT, [ AC_MSG_CHECKING(for ORBit) -if test `which orbit-config` +orbit_config_path=`which orbit-config` +if test -n "$orbit_config_path" then orbit_exec_prefix=`orbit-config --exec-prefix` orbit_includes=`orbit-config --cflags server` diff --git a/client/mysql.cc b/client/mysql.cc index dbaff8e57f5..06b76ac81e9 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -75,7 +75,6 @@ extern "C" { #endif #undef bcmp // Fix problem with new readline -#undef bzero #if defined( __WIN__) || defined(OS2) #include #else diff --git a/readline/rlstdc.h b/readline/rlstdc.h index d2c5f874d7a..f79cf89fe76 100644 --- a/readline/rlstdc.h +++ b/readline/rlstdc.h @@ -76,4 +76,8 @@ #endif /* !__STDC__ */ +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +#define __attribute__(A) +#endif + #endif /* !_RL_STDC_H_ */ diff --git a/strings/Makefile.am b/strings/Makefile.am index 6bf21d630f3..d198318a0f8 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -43,7 +43,7 @@ noinst_PROGRAMS = conf_to_src # Default charset definitions EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c \ - ctype-tis620.c ctype-ujis.c \ + ctype-tis620.c ctype-ujis.c ctype-latin1_de.c \ ctype_autoconf.c \ strto.c strings-x86.s longlong2str-x86.s \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ From b5622e11dd4122959ec3deeac12686ff573a4f77 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 30 Sep 2001 22:04:56 +0300 Subject: [PATCH 25/38] Portability fixes --- mysql-test/mysql-test-run.sh | 4 ++-- mysql-test/r/rpl000002.result | 2 +- mysql-test/t/rpl000002.test | 1 + sql/sql_class.h | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 3bfdbb0349a..97767a33687 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -345,7 +345,7 @@ prompt_user () read unused } -# We can't use diff -u as this isn't portable +# We can't use diff -u or diff -a as these are not portable show_failed_diff () { @@ -362,7 +362,7 @@ show_failed_diff () then echo "Below are the diffs between actual and expected results:" echo "-------------------------------------------------------" - $DIFF -c -a $result_file $reject_file + $DIFF -c $result_file $reject_file echo "-------------------------------------------------------" echo "Please follow the instructions outlined at" echo "http://www.mysql.com/doc/R/e/Reporting_mysqltest_bugs.html" diff --git a/mysql-test/r/rpl000002.result b/mysql-test/r/rpl000002.result index 7f518a7339e..89119708499 100644 --- a/mysql-test/r/rpl000002.result +++ b/mysql-test/r/rpl000002.result @@ -3,7 +3,7 @@ n 2001 2002 Server_id Host Port -2 127.0.0.1 9307 +2 127.0.0.1 9999 id created 1 1970-01-01 06:25:45 id created diff --git a/mysql-test/t/rpl000002.test b/mysql-test/t/rpl000002.test index 865aa5e5bab..5840b1998a8 100644 --- a/mysql-test/t/rpl000002.test +++ b/mysql-test/t/rpl000002.test @@ -11,6 +11,7 @@ use test; sync_with_master; select * from t1; connection master; +--replace_result 9307 9999 3350 9999 3351 9999 show slave hosts; drop table t1; save_master_pos; diff --git a/sql/sql_class.h b/sql/sql_class.h index 0104a251f2c..b34b97b29a0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -51,6 +51,7 @@ typedef struct st_log_info ~st_log_info() { pthread_mutex_destroy(&lock);} } LOG_INFO; +class Log_event; class MYSQL_LOG { private: From 993be5c8a0cf55282e9917fd1e67d8472278b1a5 Mon Sep 17 00:00:00 2001 From: "serg@serg.mysql.com" <> Date: Mon, 1 Oct 2001 14:37:15 +0200 Subject: [PATCH 26/38] three column types (added to parser - but not to the manual - long time ago) documented --- Docs/manual.texi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Docs/manual.texi b/Docs/manual.texi index e9b9e885ff7..cf2f18eb80e 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -28179,6 +28179,13 @@ column that only can take 2 values: A @code{CHAR(0)}, that is not defined as @code{NOT NULL}, will only occupy one bit and can only take 2 values: @code{NULL} or @code{""}. @xref{CHAR}. +@tindex BOOL +@tindex BIT +@item BIT +@itemx BOOL +@itemx CHAR +These three are synonyms for @code{CHAR(1)}. + @tindex CHARACTER VARYING @tindex CHAR VARYING @tindex VARCHAR From 3aceb88ea84f26d1314e9b36686325cc64d5e2d9 Mon Sep 17 00:00:00 2001 From: "tfr@sarvik.tfr.cafe.ee" <> Date: Mon, 1 Oct 2001 19:21:52 +0200 Subject: [PATCH 27/38] manual.texi: Add a mirror --- Docs/manual.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Docs/manual.texi b/Docs/manual.texi index a8a7844589c..355df06069e 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6924,6 +6924,12 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @uref{http://mysql.mirrortree.com/, WWW} @uref{ftp://mysql.mirrortree.com/pub/mysql/, FTP} +@item +@c EMAIL: darrinw@nixc.net (Darrin Walton) +@image{Flags/usa} USA [NIXC/Vienna, VA] @ +@uref{http://www.nixc.net/mysql/, WWW} +@uref{ftp://www.nixc.net/pub/mysql/, FTP} + @end itemize @strong{South America:} From 5e4b84594a6185d56ec0cd7b8bb0fdfa2d6e8aa5 Mon Sep 17 00:00:00 2001 From: "tfr@sarvik.tfr.cafe.ee" <> Date: Mon, 1 Oct 2001 21:44:02 +0200 Subject: [PATCH 28/38] manual.texi: Added a mirror in France --- Docs/manual.texi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Docs/manual.texi b/Docs/manual.texi index 355df06069e..83053c5c485 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6507,6 +6507,11 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @image{Flags/finland} Finland [KPNQwest] @ @uref{http://mysql.kpnqwest.fi/, WWW} +@item +@c EMAIL: root@omegatomic.com (John Berry) +@image{Flags/france} France [Omegatomic] @ +@uref{http://mysql.omegatomic.com/, WWW} + @item @c Added 981208 @c EMAIL: noel@uni-bonn.de (Noel Koethe) From 7b5d0db08f909d8e80af9111f5200bd089897649 Mon Sep 17 00:00:00 2001 From: "tim@work.mysql.com" <> Date: Mon, 1 Oct 2001 23:14:06 +0200 Subject: [PATCH 29/38] Re-arrange support information in manual.texi so that no details about pricing and support levels are given. Also some style changes. --- Docs/manual.texi | 941 ++++++++++++++++------------------------------- 1 file changed, 314 insertions(+), 627 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 83053c5c485..02e6a521553 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -219,7 +219,7 @@ The @code{mysqlbug} script should be used to generate bug reports. For source distributions, the @code{mysqlbug} script can be found in the @file{scripts} directory. For binary distributions, @code{mysqlbug} can be found in the @file{bin} directory. If you have found a sensitive -security bug in MySQL, you should send an email to +security bug in MySQL, you should send an e-mail to @email{security@@mysql.com}. @cindex errors, reporting @@ -239,7 +239,7 @@ MySQL, see @ref{MySQL-Books}. @menu * MySQL and MySQL AB:: MySQL, MySQL AB, and Open Source * MySQL Information Sources:: MySQL Information Sources -* Licensing and Support:: MySQL Licensing and Support +* Licensing and Support:: MySQL Support and Licensing * Compatibility:: How Standards-compatible Is MySQL? * Comparisons:: How MySQL Compares to Other Databases * TODO:: MySQL and the future (The TODO) @@ -317,15 +317,15 @@ us. MySQL is very fast, reliable, and easy to use. If that is what you are looking for, you should give it a try. MySQL also has a -very practical set of features developed in very close cooperation with +practical set of features developed in close cooperation with our users. You can find a performance comparison of MySQL to some other database managers on our benchmark page. @xref{MySQL Benchmarks}. -MySQL was originally developed to handle very large databases +MySQL was originally developed to handle large databases much faster than existing solutions and has been successfully used in highly demanding production environments for several years. Though -under constant development, MySQL today offers a rich and very +under constant development, MySQL today offers a rich and useful set of functions. The connectivity, speed, and security make MySQL highly suited for accessing databases on the Internet. @@ -366,16 +366,20 @@ to the MySQL server source code and the MySQL trademark. A significant amount of revenues from our services goes to developing MySQL. @xref{What-is}. +@menu +* Contact information:: Contact information +@end menu + MySQL AB has been profitable providing MySQL from the start. We don't get any outside funding, but have earned all our money ourselves. -We are searching after partners that would like to support our development -of MySQL so that we could accelerate the development pace. If you -are interested in doing this, you can email @email{partner@@mysql.com} about -this! +We are searching for partners that would like to support our development +of MySQL so that we can accelerate the pace of development. If you +are interested in doing this, please e-mail @email{partner@@mysql.com}! -MySQL AB has currently 20+ people -(@uref{http://www.mysql.com/development/team.html}) on its payroll and is growing rapidly. +MySQL AB currently has over twenty people +(@uref{http://www.mysql.com/development/team.html}) +on its payroll and is growing rapidly. Our main sources of income are: @@ -385,21 +389,21 @@ Our main sources of income are: Commercial high quality support for MySQL provided by the MySQL developers themselves. If you are interested in purchasing a support contract, please visit @uref{https://order.mysql.com/} to view our -support options or to order support. +support options and order support. @item Consulting services. We have developers and consultants in 12 countries and partners in many other countries that can help you with almost any MySQL related issues. If you need consulting services, please -email a good description of your needs to @email{info@@mysql.com}! If we +e-mail a good description of your needs to @email{info@@mysql.com}! If we can't handle this ourselves we can usually find a partner or a developer that can help you with your problems. @item -We sell licenses for using MySQL as an embedded database. -@xref{Cost}. If you have a commercial product for which you need a fast, +Licensing MySQL for use as an embedded database. @xref{Licensing policy}. +If you have a commercial product for which you need a fast, high quality database, but you can't afford to make your product Open Source, -you can buy the right to use the MySQL server under a normal +you can buy the right to use the MySQL server under a commercial copyright. If you are interested in this you can buy MySQL licenses at @uref{https://order.mysql.com/} or contact us at @email{licensing@@mysql.com}. @@ -407,26 +411,26 @@ at @email{licensing@@mysql.com}. @item Advertising. @uref{http://www.mysql.com/} is a very popular web site with more than 10,000,000 page views per months (January 2001). By putting a -banner on this you are guaranteed to reach a lot of potential customers -in the Open source, Linux and database community. If you are interested -in this email @email{advertising@@mysql.com}. +banner on this site you are guaranteed to reach a lot of potential customers +in the open source, Linux and database communities. If you are interested +in this e-mail @email{advertising@@mysql.com}. @item We are building a partner program to be able to provide MySQL services in every country. If you are interested in becoming a partner of MySQL AB please visit -@uref{http://www.mysql.com/information/partners.html} or email +@uref{http://www.mysql.com/information/partners.html} or e-mail @email{partner@@mysql.com}. @item We provide MySQL training through our partner programs. For more -information, please email @email{info@@mysql.com}. +information, please e-mail @email{info@@mysql.com}. @item The MySQL brand has, since 1995, been associated with speed and reliability, and is known to be something you can depend upon. If you are interested in using the MySQL trademark in your marketing, you -can email @email{info@@mysql.com} about this. +can e-mail @email{info@@mysql.com} about this. @end itemize The MySQL core values show our dedication to MySQL and @@ -436,13 +440,13 @@ We want MySQL to be: @itemize @bullet @item -The best and the most used database in the world. +The best and the most widely used database in the world. @item Available and affordable for all. @item Easy to use. @item -Continuously improved while remaining fast and safe. +Continuously improving while remaining fast and safe. @item Fun to use and improve. @item @@ -459,13 +463,56 @@ Aim to be good citizens. @item Prefer partners that share our values and mind-set. @item -Answer mail and give support. +Answer e-mail and provide support. @item Are a virtual company, networking with others. @item Work against software patents. @end itemize +@node Contact information, , What is MySQL AB, What is MySQL AB +@subsubsection Contact Information + +@cindex contact information +@cindex licensing, contact information +@cindex advertising, contact information +@cindex employment, contact information +@cindex partnering with MySQL +@cindex employment with MySQL +@cindex jobs at MySQL + +For commercial licensing, please contact the MySQL licensing +team. The much preferred method is by e-mail to +@email{licensing@@mysql.com}. Fax is also possible but handling of +these may take much longer (Fax +46-8-729 69 05). + +If you represent a business that is interested in partnering with +MySQL, please send e-mail to @email{partner@@mysql.com}. + +For timely, precise answers to technical questions about MySQL +you should @uref{https://order.mysql.com/, order} one of our +@uref{http://www.mysql.com/support/arrangements/types.html, support contracts}. +MySQL support is provided by the MySQL developers so the +standard is extremely high. + +If you are interested in placing a banner advertisement on our Web site, +please send e-mail to @email{advertising@@mysql.com}. + +If you are interested in any of the jobs listed in our +@uref{http://www.mysql.com/development/jobs/, jobs} section, please send e-mail +to @email{jobs@@mysql.com}. + +For general discussion amongst our many users, please direct your attention to +the appropriate @uref{http://www.mysql.com/documentation/lists.html, mailing +list}. + +For general information inquires, please send e-mail to +@email{info@@mysql.com}. + +For questions or comments about the workings or content of the Web site, +please send e-mail to @email{webmaster@@mysql.com}. + + @node Manual-info, Manual conventions, What is MySQL AB, MySQL and MySQL AB @subsection About This Manual @@ -550,7 +597,7 @@ shell> setenv VARNAME value shell> some_command @end example -Often, database, table, and column names must be substituted into commands. To +Often database, table, and column names must be substituted into commands. To indicate that such substitution is necessary, this manual uses @code{db_name}, @code{tbl_name} and @code{col_name}. For example, you might see a statement like this: @@ -933,10 +980,10 @@ using this with good results. @item BDB Tables -- Beta The Berkeley DB code is very stable, but we are still improving the interface between MySQL and BDB tables, so it will take some time before this -is as tested as the other table types. +is tested as well as the other table types. @item InnoDB Tables -- Beta -This is a recent addition to @code{MySQL}. They appear to work good and +This is a recent addition to @code{MySQL}. They appear to work well and can be used after some initial testing. @item Automatic recovery of MyISAM tables - Beta @@ -944,15 +991,15 @@ This only affects the new code that checks if the table was closed properly on open and executes an automatic check/repair of the table if it wasn't. @item MERGE tables -- Beta / Gamma -The usage of keys on @code{MERGE} tables is still not that tested. The -other part of the @code{MERGE} code is quite well tested. +The usage of keys on @code{MERGE} tables is still not well tested. The +other parts of the @code{MERGE} code are quite well tested. @item FULLTEXT -- Beta Text search seems to work, but is still not widely used. @end table -MySQL AB provides e-mail support for paying customers, but the +MySQL AB provides high-quality support for paying customers, but the MySQL mailing list usually provides answers to common questions. Bugs are usually fixed right away with a patch; for serious bugs, there is almost always a new release. @@ -1598,8 +1645,8 @@ FutureForum Web Discussion Software. @table @asis @item @uref{http://www.supportwizard.com/} -SupportWizard; Interactive helpdesk on the Web (This product includes a -licensed copy of MySQL.) +SupportWizard; Interactive helpdesk on the Web. This product includes a +licensed copy of MySQL. @item @uref{http://www.sonork.com/} Sonork, Instant Messenger that is not only Internet oriented. It's @@ -1664,7 +1711,7 @@ A free report writer in Java @item @uref{http://www.javaframework.de} MySQLExport - Export of MySQL create statements and data in a lot of -different formats (SQL, HTML, CVS, text, ZIP, GZIP...) +different formats (SQL, HTML, CVS, text, ZIP, GZIP...). @item @uref{http://dlabs.4t2.com} M2D, a MySQL Administration client for Windows. M2D supports @@ -1712,7 +1759,7 @@ SmartWorker is a platform for Web application development. @item @uref{http://xsp.lentus.se/} XSP: e(X)tendible (S)erver (P)ages and is a HTML embedded tag language -written in Java (previously known as XTAGS.) +written in Java (previously known as XTAGS). @cindex dbServ @item @uref{http://www.dbServ.de/} @@ -2033,9 +2080,6 @@ Stopbit - A technology news site using MySQL and PHP. KDE based calendar manager - The calendar manager has both single user (file based) and multi-user (MySQL database) support. -@item @uref{http://tim.desert.net/~tim/imger/} -Example of storing/retrieving images with MySQL and CGI. - @item @uref{http://www.penguinservices.com/scripts} Online shopping cart system. @@ -2112,7 +2156,7 @@ some guidelines as to how to use them. @subsubsection The MySQL Mailing Lists @cindex mailing lists -@cindex email lists +@cindex e-mail lists To subscribe to the main MySQL mailing list, send a message to the electronic mail address @email{mysql-subscribe@@lists.mysql.com}. @@ -2242,15 +2286,15 @@ guarantee the quality on these. @table @code @item @email{mysql-france-subscribe@@yahoogroups.com} A French mailing list @item @email{list@@tinc.net} A Korean mailing list -Email @code{subscribe mysql your@@email.address} to this list. +Email @code{subscribe mysql your@@e-mail.address} to this list. @item @email{mysql-de-request@@lists.4t2.com} A German mailing list -Email @code{subscribe mysql-de your@@email.address} to this list. +Email @code{subscribe mysql-de your@@e-mail.address} to this list. You can find information about this mailing list at @uref{http://www.4t2.com/mysql}. @item @email{mysql-br-request@@listas.linkway.com.br} A Portugese mailing list -Email @code{subscribe mysql-br your@@email.address} to this list. +Email @code{subscribe mysql-br your@@e-mail.address} to this list. @item @email{mysql-alta@@elistas.net} A Spanish mailing list -Email @code{subscribe mysql your@@email.address} to this list. +Email @code{subscribe mysql your@@e-mail.address} to this list. @end table @@ -2320,7 +2364,7 @@ missing, please include it with your message! Please read this section carefully and make sure that all the information described here is included in your report. -@cindex bug reports, email address +@cindex bug reports, e-mail address The normal place to report bugs and problems is @email{mysql@@lists.mysql.com}. If you can make a test case that clearly demonstrates the bug, you should post it to the @email{bugs@@lists.mysql.com} @@ -2619,38 +2663,133 @@ Many users don't read mail with a browser! @node Licensing and Support, Compatibility, MySQL Information Sources, Introduction -@section MySQL Licensing and Support +@section MySQL Support and Licensing @cindex licensing terms @cindex support terms @menu -* Licensing policy:: MySQL licensing policy +* Support:: Support offered by MySQL AB * Copyright:: Copyrights used by MySQL +* Licensing policy:: MySQL licensing policy * Licensing examples:: Example licensing situations -* Cost:: MySQL licensing and support costs -* Support:: Types of commercial support +* Payment information:: Payment information @end menu -This section describes MySQL support and licensing -arrangements: +This section describes MySQL support and licensing arrangements: @itemize @bullet +@item Support costs and benefits +(@pxref{Support}) + @item The copyrights under which MySQL is distributed (@pxref{Copyright}) +@item When and why you should license MySQL +(@pxref{Licensing policy}) + @item Sample situations illustrating when a license is required (@pxref{Licensing examples}) -@item Support costs (@pxref{Cost}) and support benefits -(@pxref{Support}) +@item How to make payments +(@pxref{Payment information}) -@item Commercial licensing costs @end itemize -@node Licensing policy, Copyright, Licensing and Support, Licensing and Support +@node Support, Copyright, Licensing and Support, Licensing and Support +@subsection Support offered by MySQL AB + +@cindex support, types +@cindex types, of support +@cindex commercial support, types +@cindex costs, licensing and support +@cindex licensing costs +@cindex support costs +@cindex prices, licensing and support + +MySQL AB offers several support options. A description +of what each level of support includes is given at +@uref{http://www.mysql.com/support/arrangements/types.html}. As +a support customer, you have access to the people who develop the +MySQL source code. The standard is high for both quality and +speed. + +Our current support and license prices are available from our +web site. For options and pricing, and to order support and +licenses, please see +@uref{https://order.mysql.com/}. + +A license is not a support agreement and includes very minimal +support. This means that we try to answer any questions relevant +to installation. If the answer is in the documentation, we will +direct you to the appropriate section. If you have not purchased +a license or support, we will simply direct you to the freely +available public resources. + +We consider reliability to be crucial to MySQL's success, and +fixing bugs is important to us. If you discover a bug that can +be repeated reliably, we will fix it in any case. But if you pay +for support we will also notify you about the fix status instead +of just fixing it in a later release. + + +@node Copyright, Licensing policy, Support, Licensing and Support +@subsection Copyrights Used by MySQL + +@cindex copyrights + +@menu +* Copyright changes:: Possible future copyright changes +@end menu + +There are several different copyrights on the MySQL distribution: + +@enumerate +@item +The MySQL-specific source needed to build the @code{mysqlclient} +library is licensed under the @code{LGPL} and the programs in the +@file{client} directory are under the @code{GPL}. Each file states at +the beginning which license it is under. + +@item The client library, and the GNU @code{getopt} library, are covered +by the ``GNU LIBRARY GENERAL PUBLIC LICENSE.'' @xref{LGPL license}. + +@item Some parts of the source (the @code{regexp} library) are covered +by a Berkeley-style copyright. + +@item +All the source in the server, and the GNU @code{readline} library, +are covered by the ``GNU GENERAL PUBLIC LICENSE.'' @xref{GPL license}. +This is also available as the file @file{COPYING} in the distributions. + +@end enumerate + +One goal is that the SQL client library should be free enough that it is +possible to add MySQL support into commercial products +without a license. For this reason, we chose the LGPL license for the +client code. +@cindex licensing, free +@cindex free licensing + +This means that you can use MySQL for free with any program that uses +any of the free software licenses. MySQL is also free for any end +user for his own or company usage. + +However, if you use MySQL for something important to you, you may +want to help secure its development by purchasing licenses or a support +contract. @xref{Support}. + + +@node Copyright changes, , Copyright, Copyright +@subsubsection Copyright Changes + +Version 3.22 of MySQL is still using a more strict license. +See the documentation for that version for more information. + + +@node Licensing policy, Licensing examples, Copyright, Licensing and Support @subsection MySQL Licensing Policy @cindex licensing policy @@ -2661,12 +2800,6 @@ arrangements: The formal terms of the GPL license can be found at @ref{GPL license}. Basically, our licensing policy and interpretation of the GPL is as follows: -Note that older versions of MySQL are still using a more -@uref{http://www.mysql.com/support/arrangements/mypl.html, strict license}. -See the documentation for that version for more information. If you need a -commercial MySQL license, because the GPL license doesn't suit your -application, you can buy one at @uref{https://order.mysql.com/}. - For normal internal use, MySQL costs nothing. You do not have to pay us if you do not want to. @@ -2694,23 +2827,24 @@ source code for your copy of the MySQL server, as defined in the GPL license. @end itemize -A license is @strong{NOT} required if: +A license is @strong{not} required if: @itemize @minus @item -You do not need a license to include the client code in commercial -programs. The client part of MySQL licensed with the +You include the MySQL client code in a commercial +program. The client part of MySQL is licensed under the LGPL @code{GNU Library General Public License}. The @code{mysql} command-line -client includes code from the @code{readline} library that is under -the @code{GPL}. +client does include code from the @code{readline} library that is under +the @code{GPL}, however. + +@end itemize -@item If your use of MySQL does not require a license, but you like MySQL and want to encourage further development, you are certainly welcome to purchase a license or MySQL support anyway. +@xref{Support}. -@item If you use MySQL in a commercial context such that you profit by its use, we ask that you further the development of MySQL by purchasing some level of support. We feel that if MySQL helps @@ -2718,14 +2852,18 @@ your business, it is reasonable to ask that you help MySQL. (Otherwise, if you ask us support questions, you are not only using for free something into which we've put a lot a work, you're asking us to provide free support, too.) -@end itemize + +Note that older versions of MySQL are still using a more +@uref{http://www.mysql.com/support/arrangements/mypl.html, strict license}. +See the documentation for the specific version for more +information. For circumstances under which a MySQL license is required, you need a license per machine that runs the @code{mysqld} server. However, a multiple-CPU machine counts as a single machine, and there is no restriction on the number of MySQL servers that run on one machine, or on the number of clients concurrently connected to a server -running on that machine! +running on that machine. If you have any questions as to whether or not a license is required for your particular use of MySQL, please read this again and then @@ -2737,61 +2875,7 @@ is to use the license form on MySQL's secure server at discussed in @ref{Payment information}. -@node Copyright, Licensing examples, Licensing policy, Licensing and Support -@subsection Copyrights Used by MySQL - -@cindex copyrights - -@menu -* Copyright changes:: Possible future copyright changes -@end menu - -There are several different copyrights on the MySQL distribution: - -@enumerate -@item -The MySQL-specific source needed to build the -@code{mysqlclient} library is licensed under the @code{LGPL} and -programs in the @file{client} directory is GPL. Each file has a header -that shows which copyright is used for that file. - -@item The client library and the (GNU @code{getopt}) library are covered -by the ``GNU LIBRARY GENERAL PUBLIC LICENSE.'' @xref{LGPL license}. - -@item Some parts of the source (the @code{regexp} library) are covered -by a Berkeley-style copyright. - -@item -All the source in the server and the (GNU @code{readline}) library -is covered by the ``GNU GENERAL PUBLIC LICENSE.'' @xref{GPL license}. -This is also available as the file @file{COPYING} in the distributions. - -@end enumerate - -One goal is that the SQL client library should be free enough that it is -possible to add MySQL support into commercial products -without a license. For this reason, we chose the LGPL license for the -client code. -@cindex licensing, free -@cindex free licensing - -This means that you can use MySQL for free with any program that uses -any of the free software licenses. MySQL is also free for any end -user for his own or company usage. - -However, if you use MySQL for something important to you, you may -want to help secure its development by purchasing licenses or a support -contract. @xref{Support}. - - -@node Copyright changes, , Copyright, Copyright -@subsubsection Copyright Changes - -Version 3.22 of MySQL is still using a more strict license. -See the documentation for that version for more information. - - -@node Licensing examples, Cost, Copyright, Licensing and Support +@node Licensing examples, Payment information, Licensing policy, Licensing and Support @subsection Example Licensing Situations @menu @@ -2876,12 +2960,12 @@ will be able to solve the problem for them (in some cases with the help from the MySQL development team). All ISPs that want to keep themselves up-to-date should subscribe -to our @code{announce} mailing list so that they can be aware of fatal issues +to our @code{announce} mailing list so that they can be aware of critical issues that may be relevant for their MySQL installations. Note that if the ISP doesn't have a license for MySQL, it should give its customers at least read access to the source of -the MySQL installation so that its customer can verify that +the MySQL installation so that its customers can verify that it is patched correctly. @@ -2891,7 +2975,7 @@ it is patched correctly. @cindex web server, running @cindex running, a web server -If you use MySQL in conjunction with a Web server on Unix, you +If you use MySQL in conjunction with a Web server, you don't have to pay for a license. This is true even if you run a commercial Web server that uses @@ -2900,97 +2984,22 @@ version yourself. However, in this case we would like you to purchase MySQL support, because MySQL is helping your enterprise. -@node Cost, Support, Licensing examples, Licensing and Support -@subsection MySQL Licensing and Support Costs - -@cindex costs, licensing and support -@cindex licensing costs -@cindex support costs -@cindex prices, licensing and support - -@menu -* Payment information:: Payment information -* Contact information:: Contact information -@end menu - -Our current license prices are shown below. To make a purchase, please visit -@uref{https://order.mysql.com/}. - -If you pay by credit card, the currency is EURO (European Union Euro) so the -prices will differ slightly. - -@multitable @columnfractions .3 .3 .3 -@item @strong{Number of licenses} @tab @strong{Per copy} -@item 1-9 @tab 230 EURO -@item 10-24 @tab 138 EURO -@item 25-49 @tab 117 EURO -@item 50-99 @tab 102 EURO -@item 100-249 @tab 91 EURO -@item 250-499 @tab 76 EURO -@item 500-999 @tab 66 EURO -@end multitable - -For high volume (OEM) purchases, please contact -@email{sales@@mysql.com}. - -For OEM purchases, you must act as the middle-man for eventual problems -or extension requests from your users. We also require that OEM -customers have at least an extended e-mail support contract. Note that -OEM licenses only apply for products where the user doesn't have direct -access to the MySQL server (embedded system). In other words, -the MySQL server should only be used with the application -that was supplied you. - -If you have a low-margin, high-volume product, you can always talk to us -about other terms (for example, a percent of the sale price). If you do, -please be informative about your product, pricing, market, and any other -information that may be relevant. - -A full-price license is not a support agreement and includes very minimal -support. This means that we try to answer any relevant questions. If the -answer is in the documentation, we will direct you to the appropriate -section. If you have not purchased a license or support, we probably will -not answer at all. - -If you discover what we consider a real bug, we are likely to fix it in -any case. But if you pay for support we will notify you about the fix -status instead of just fixing it in a later release. - -More comprehensive support is sold separately. Descriptions of what each -level of support includes are given in @ref{Support}. Costs for the various -types of commercial support are shown below. Support level prices are in -EURO (European Union Euro). One EURO is about 1.06 USD. - -@multitable @columnfractions .5 .5 -@item @strong{Type of support} @tab @strong{Cost per year} -@item Basic e-mail support. @xref{Basic email support}. @tab EURO 200 -@item Extended e-mail support @xref{Extended email support}. @tab EURO 1000 -@item Login support @xref{Login support}. @tab EURO 2000 -@item Extended login support @xref{Extended login support}. @tab EURO 5000 -@item Telephone support @xref{Telephone support}. @tab EURO 12000 -@end multitable - -You may upgrade from any lower level of support to a higher level of -support for the difference in price between the two support levels. - -We do also provide telephone support (mostly emergency support but also -24/7 support). This support option doesn't however have a fixed price -but is negotiated for case to case. If you are interested in this option -you can email @email{sales@@mysql.com} and tell us about your needs. - -Note that as our sales staff is very busy, it may take some time until -your request is handled. Our support staff does however always answer -promptly to support questions! - - -@node Payment information, Contact information, Cost, Cost -@subsubsection Payment information +@node Payment information, , Licensing examples, Licensing and Support +@subsection Payment information @cindex payment information -Currently we can take SWIFT payments, checks, or credit cards. +The most efficient way to pay for support and licenses is through +@uref{https://order.mysql.com/, MySQL AB's secure license form}. +Please check this site for the latest support options and +pricing details. -Payment should be made to: +Also, we can take SWIFT payments, checks, or credit cards. + +@itemize @bullet + +@item +SWIFT payments should be made to: @example Postgirot Bank AB @@ -3006,9 +3015,10 @@ Account number: 96 77 06 - 3 Specify: license and/or support and your name and e-mail address. -In Europe and Japan you can use EuroGiro (that should be less expensive) to the -same account. +In Europe and Japan you can use EuroGiro (which should be less +expensive) to the same account. +@item If you want to pay by check, make it payable to ``MySQL Finland AB'' and mail it to the address below: @@ -3018,344 +3028,21 @@ BOX 6434, Torsgatan 21 11382 STOCKHOLM, SWEDEN @end example -If you want to pay by credit card over the Internet, you can use -@uref{https://order.mysql.com/, MySQL AB's secure license form}. - +@item You can also print a copy of the license form, fill it in, and send it by fax to: +46-8-729 69 05 +@item If you want us to bill you, you can use the license form and write ``bill us'' in the comment field. You can also mail a message to @email{sales@@mysql.com} (@strong{not} @code{mysql@@lists.mysql.com}!) with your company information and ask us to bill you. - -@node Contact information, , Payment information, Cost -@subsubsection Contact Information - -@cindex contact information -@cindex licensing, contact information -@cindex advertising, contact information -@cindex employment, contact information -@cindex partnering with MySQL -@cindex employment with MySQL -@cindex jobs at MySQL - -For commercial licensing, please contact the MySQL licensing -team. The much preferred method is by e-mail to -@email{licensing@@mysql.com}. Fax is also possible but handling of -these may take much longer (Fax +46-8-729 69 05). - -If you represent a business that is interested in partnering with -MySQL, please send e-mail to @email{partner@@mysql.com}. - -For timely, precise answers to technical questions about MySQL -you should @uref{https://order.mysql.com/, order} one of our -@uref{http://www.mysql.com/support/arrangements/types.html, support contracts}. -MySQL support is provided by the MySQL developers so the -standard is extremely high. - -If you are interested in placing a banner advertisement on our Web site, -please send e-mail to @email{advertising@@mysql.com}. - -If you are interested in any of the jobs listed in our -@uref{http://www.mysql.com/development/jobs/, jobs} section, please send e-mail -to @email{jobs@@mysql.com}. - -For general discussion amongst our many users, please direct your attention to -the appropriate @uref{http://www.mysql.com/documentation/lists.html, mailing -list}. - -For general information inquires, please send e-mail to -@email{info@@mysql.com}. - -For questions or comments about the workings or content of the Web site, -please send e-mail to @email{webmaster@@mysql.com}. - - -@node Support, , Cost, Licensing and Support -@subsection Types of Commercial Support - -@cindex support, types -@cindex types, of support -@cindex commercial support, types - -@menu -* Basic email support:: Basic email support -* Extended email support:: Extended email support -* Login support:: Login support -* Extended login support:: Extended login support -* Telephone support:: Telephone support -* Table handler support:: Support for other table handlers -@end menu - -The following is true of all support options: - -@itemize @bullet -@item -The support is per year. -@item -We will fix, or provide a reasonable workaround for any repeatable bug. -@item -We will give a reasonable effort to find and fix any other MySQL related bug. -@item -The higher level of support contract the more effort we will put into finding -a solution to your problems. -@item -The following is true for all support contracts except Basic email support: - -For non-bug related things, like helping you optimize your queries or -your system, extending MySQL with new functionality, etc., we charge 200 -EURO/hour, which is deducted from your support contract. In other words, -if you have login support (2000 EURO), you can expect us to work up to -10 hours to help you with things like this. @end itemize -@node Basic email support, Extended email support, Support, Support -@subsubsection Basic E-mail Support - -@cindex email, technical support -@cindex technical support, by email - -Basic e-mail support is a very inexpensive support option and should be -thought of more as a way to support our development of MySQL -than as a real support option. We at MySQL do give a lot of free -support in all the different MySQL lists, and the money we get from -basic e-mail support is largely used to make this possible. - -At this support level, the MySQL mailing lists are the preferred -means of communication. Questions normally should be mailed to the primary -mailing list (@email{mysql@@lists.mysql.com}) or one of the other regular -lists (for example, @email{win32@@lists.mysql.com} for Windows-related -MySQL questions), as someone else already may have experienced and -solved the problem you have. @xref{Asking questions}. - -However, by purchasing basic e-mail support, you also have access to the -support address @email{mysql-support@@mysql.com}, which is not available -as part of the minimal support that you get by purchasing a MySQL -license. This means that for especially critical questions, you can -cross-post your message to @email{mysql-support@@mysql.com}. (If the -message contains sensitive data, you should post only to -@email{mysql-support@@mysql.com}.) - -@strong{REMEMBER!} to ALWAYS include your registration number and expiration -date when you send a message to @email{mysql-support@@mysql.com}. - -Note that if you have encountered a critical, repeatable bug, and follow -the rules outlined in the manual section of how to report bugs and send -it to @email{bugs@@lists.mysql.com}, we promise to try to fix this as -soon as possible, regardless of your support level! @xref{Bug reports}. - -Basic e-mail support includes the following types of service: - -@itemize @bullet -@item -If your question is already answered in the manual, we will inform you of the -correct section in which you can find the answer. If the answer is not in -the manual, we will point you in the right direction to solve your problem. - -@item -We guarantee a timely answer for your e-mail messages. We can't guarantee -that we can solve any problem, but at least you will receive an answer if we -can contact you by e-mail. - -@item -We will help with unexpected problems when you install MySQL from a -binary distribution on supported platforms. This level of support does not -cover installing MySQL from a source distribution. Supported -platforms are those for which MySQL is known to work. -@xref{Which OS}. - -@item -We will help you with bugs and missing features. Any bugs that are found are -fixed for the next MySQL release. If the bug is critical for -you, we will mail you a patch for it as soon the bug is fixed. Critical -bugs always have the highest priority for us, and we ensure that they are -fixed as soon as possible. - -@item -Your suggestions for the further development of MySQL will be -taken into consideration. By taking email support you have already -helped the further development of MySQL. If you want to have -more input, upgrade to a higher level of support. - -@item -If you want us to help optimize your system, you must upgrade to a -higher level of support. -@end itemize - - -@node Extended email support, Login support, Basic email support, Support -@subsubsection Extended E-mail Support - -@cindex extended email support - -Extended e-mail support includes everything in basic e-mail support with -these additions: - -@itemize @bullet -@item -Your e-mail will be dealt with before mail from basic e-mail support users and -non-registered users. - -@item -Your suggestions for the further development of MySQL will -receive strong consideration. Simple extensions that suit the basic -goals of MySQL are implemented in a matter of days. By taking -extended e-mail support you have already helped the further development -of MySQL. - -@item -Typical situations that are covered by extended e-mail support are: - -@itemize @minus -@item -We will answer and (within reason) solve questions that relate to possible -bugs in MySQL. As soon as the bug is found and corrected, we -will mail a patch for it. - -@item -We will help with unexpected problems when you install MySQL from a -source or binary distribution on supported platforms. - -@item -We will answer questions about missing features and offer hints how to work -around them. - -@item -We will provide hints on optimizing @code{mysqld} for your situation. -@end itemize - -@item -You are allowed to influence the priority of items on the MySQL -TODO List. @xref{TODO}. This will ensure that the features you really need -will be implemented sooner than they might be otherwise. -@end itemize - - -@node Login support, Extended login support, Extended email support, Support -@subsubsection Login Support - -@cindex login support - -Login support includes everything in extended e-mail support with -these additions: - -@itemize @bullet -@item -Your e-mail will be dealt with even before e-mail from extended e-mail -support users. - -@item -Your suggestions for the further development of MySQL will -be taken into very high consideration. Realistic extensions that can be -implemented in a couple of hours and that suit the basic goals of -MySQL will be implemented as soon as possible. - -@item -If you have a very specific problem, we can try to log in on your system -to solve the problem ``in place.'' - -@item -Like any database vendor, we can't guarantee that we can rescue any data from -crashed tables, but if the worst happens, we will help you rescue as much as -possible. MySQL has proven itself very reliable, but anything is -possible due to circumstances beyond our control (for example, if your system -crashes or someone kills the server by executing a @code{kill -9} command). - -@item -We will provide hints on optimizing your system and your queries. - -@item -You are allowed to call a MySQL developer (in moderation) and -discuss your MySQL-related problems. This option is however -only to be used as a last result during an emergency after we have -failed to grasp the total problem with email. To make efficient -use of our time we need to first get all facts about the problem, -before talking on phone, to be able to work as efficiently as possible on -solving the problem. -@end itemize - - -@node Extended login support, Telephone support, Login support, Support -@subsubsection Extended Login Support - -Extended login support includes everything in login support with these -additions: - -@itemize @bullet -@item -Your e-mail has the highest possible priority. - -@item -We will actively examine your system and help you optimize it and your -queries. We may also optimize and/or extend MySQL to better -suit your needs. - -@item -You may also request special extensions just for you. For example: -@example -mysql> select MY_FUNC(col1,col2) from table; -@end example - -@item -We will provide a binary distribution of all important MySQL -releases for your system, as long as we can get an account on a -similar system. In the worst case, we may require access to your system -to be able to create a binary distribution. - -@item -If you can provide accommodations and pay for traveler fares, you can -even get a MySQL developer to visit you and offer you help with -your troubles. Extended login support entitles you to one personal -encounter per year, but we are always very flexible towards our -customers! If the visit takes 16 hours or more, the first 8 hours is -without charge. For the hours above 8 hours, you will be charged with a -rate that is at least 20 % less than our standard rates. -@end itemize - - -@node Telephone support, Table handler support, Extended login support, Support -@subsubsection Telephone Support - -Telephone support includes everything in extended login support with -these additions: - -@itemize @bullet -@item -We will provide you with a dynamic web page showing the current list of -@code{MySQL} developers that you can phone when you have a critical -problem. -@item -For non critical problem, you can request a MySQL developer to -phone back within 48 hours to discuss @code{MySQL} related issues. -@end itemize - - -@node Table handler support, , Telephone support, Support -@subsubsection Support for other table handlers - -@cindex support, BDB Tables -@cindex support, InnoDB Tables - -To get support for @code{BDB} tables, @code{InnoDB} tables you have -to pay an additional 30% on the standard support price for each of -the table handlers you would like to have support for. - -We at @code{MySQL AB} will help you create a proper bug report for the -table handler and submit it to the developers for the specific table -handler. We will also do our best to ensure that you will get a timely -answer or solution from the developers of the table handler. - -Even if we are quite confident that we can solve most problems within a -timely manner, we can't guarantee a quick solution for any problems you -can get with the different table handlers. We will however do our best -to help you get the problem solved. - - @node Compatibility, Comparisons, Licensing and Support, Introduction @section How Standards-compatible Is MySQL? @@ -4346,7 +4033,7 @@ characters in database, table and column names. @item @code{DELETE FROM merge_table} used without a @code{WHERE} will only clear the mapping for the table, not delete everything in the -mapped tables +mapped tables. @item You cannot build in another directory when using @@ -6648,7 +6335,7 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @c @item @c EMAIL: melo@co.telenet.pt (Pedro Melo) -@c Temp out of service (email from Pedro) +@c Temp out of service (e-mail from Pedro) @c @image{Flags/portugal} Portugal [IP] @ @c @uref{http://mysql.ip.pt, WWW} @@ -8333,7 +8020,7 @@ You can examine the change history for the tree with all the diffs by using @code{bk sccstool}. If you see some funny diffs or code that you have a question about, do not hesitate to send e-mail to @email{internals@@lists.mysql.com}. Also, if you think you have a better idea -on how to do something, send an email to the same address with a patch. +on how to do something, send an e-mail to the same address with a patch. @code{bk diffs} will produce a patch for you after you have made changes to the source. If you do not have the time to code your idea, just send a description. @@ -9125,7 +8812,7 @@ correctly, check the log file to see if you can find out why. Log files are located in the data directory (typically @file{/usr/local/mysql/data} for a binary distribution, @file{/usr/local/var} for a source distribution, -@file{\mysql\data\mysql.err} on Windows.) Look in the data directory for +@file{\mysql\data\mysql.err} on Windows). Look in the data directory for files with names of the form @file{host_name.err} and @file{host_name.log} where @code{host_name} is the name of your server host. Then check the last few lines of these files: @@ -11630,7 +11317,7 @@ the IBM C compiler). If you are using @code{gcc} or @code{egcs} to compile MySQL, you @strong{MUST} use the @code{-fno-exceptions} flag, as the exception handling in @code{gcc}/@code{egcs} is not thread safe! (This is tested with -@code{egcs} 1.1.). There are also some known problems with IBM's assembler, +@code{egcs} 1.1.) There are also some known problems with IBM's assembler, which may cause it to generate bad code when used with gcc. We recommend the following @code{configure} line with @code{egcs} and @@ -11897,7 +11584,7 @@ Please submit a full bug report. To fix this you should change to the @code{sql} directory and do a ``cut and paste'' of the last @code{gcc} line, but change @code{-O3} to @code{-O0} (or add @code{-O0} immediately after @code{gcc} if you don't -have any @code{-O} option on your compile line.) After this is done you +have any @code{-O} option on your compile line). After this is done you can just change back to the top-level directly and run @code{make} again. @@ -14248,7 +13935,7 @@ You don't need foreign keys to join 2 tables. The only thing MySQL doesn't do is @code{CHECK} to make sure that the keys you use really exist in the table(s) you're referencing and it -doesn't automatically delete rows from table with a foreign key +doesn't automatically delete rows from a table with a foreign key definition. If you use your keys like normal, it'll work just fine: @@ -14330,8 +14017,8 @@ SELECT s.* FROM persons p, shirts s @cindex keys, searching on two MySQL doesn't yet optimize when you search on two different -keys combined with @code{OR} (Searching on one key with different @code{OR} -parts is optimized quite good): +keys combined with @code{OR} (searching on one key with different @code{OR} +parts is optimized quite well): @example SELECT field1_index, field2_index FROM test_table WHERE field1_index = '1' @@ -14340,7 +14027,7 @@ OR field2_index = '1' The reason is that we haven't yet had time to come up with an efficient way to handle this in the general case. (The @code{AND} handling is, -in comparison, now completely general and works very well). +in comparison, now completely general and works very well.) For the moment you can solve this very efficiently by using a @code{TEMPORARY} table. This type of optimization is also very good if @@ -14356,7 +14043,7 @@ SELECT * from tmp; DROP TABLE tmp; @end example -The above way to solve this query is in effect an @code{UNION} of two queries. +The above way to solve this query is in effect a @code{UNION} of two queries. @node Calculating days, , Searching on two keys, Examples @@ -14868,7 +14555,7 @@ also set this explicitely to @code{""} if you want to disable this option. If this option is used, @code{mysqld} will on open check if the table is marked as crashed or if if the table wasn't closed properly. (The last option only works if you are running with -@code{--skip-locking}). If this is the case @code{mysqld} will run +@code{--skip-locking}.) If this is the case @code{mysqld} will run check on the table. If the table was corrupted, @code{mysqld} will attempt to repair it. @@ -14926,7 +14613,7 @@ command, if the user doesn't have @code{INSERT} privilege to the @item --skip-concurrent-insert Turn off the ability to select and insert at the same time on @code{MyISAM} tables. (This is only to be used if you think you have found a bug in this -feature). +feature.) @item --skip-delay-key-write Ignore the @code{delay_key_write} option for all tables. @@ -15601,7 +15288,7 @@ shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings @end example (This works under Linux and should work with small modifications under -other systems). Warning: If you do not see data this doesn't always +other systems.) Warning: If you do not see data this doesn't always actually mean that it is encrypted. If you need high security, you should consult with a security expert. @end itemize @@ -15679,8 +15366,8 @@ For more details, see @ref{Changing MySQL user, , Changing MySQL user}. @item -Don't support symlinks to tables (This can be disabled with the -@code{--skip-symlink} option. This is especially important if you run +Don't support symlinks to tables (this can be disabled with the +@code{--skip-symlink} option). This is especially important if you run @code{mysqld} as root as anyone that has write access to the mysqld data directories could then delete any file in the system! @xref{Symbolic links to tables}. @@ -16126,7 +15813,7 @@ currently executing queries, including queries that set or change passwords. Privileges on the @code{mysql} database can be used to change passwords and other access privilege information. (Passwords are stored encrypted, so a malicious user cannot simply read them to know the plain -text password). If they can access the @code{mysql.user} password +text password.) If they can access the @code{mysql.user} password column, they can use it to log into the MySQL server for the given user. (With sufficient privileges, the same user can replace a password with a different one.) @@ -16322,7 +16009,7 @@ MySQL does not store passwords in plaintext form for anyone to see. Rather, the password supplied by a user who is attempting to connect is encrypted (using the @code{PASSWORD()} function). The encrypted password is then used when the client/server is checking if -the password is correct (This is done without the encrypted password +the password is correct. (This is done without the encrypted password ever traveling over the connection.) Note that from MySQL's point of view the encrypted password is the REAL password, so you should not give anyone access to it! In particular, don't give normal users @@ -17969,8 +17656,8 @@ you executed @code{mysqldump}. If you have to restore something, try to recover your tables using @code{REPAIR TABLE} or @code{myisamchk -r} first. That should work in 99.9% of all cases. If @code{myisamchk} fails, try the following -procedure: (This will only work if you have started MySQL with -@code{--log-update}. @xref{Update log}.): +procedure (this will only work if you have started MySQL with +@code{--log-update}, @pxref{Update log}): @enumerate @item @@ -18155,18 +17842,18 @@ the indexes and not in the data part. All of the above check types checks the indexes throughly and should thus find most errors. If you just want to check a table that you assume is ok, you should use -no check options or the @code{QUICK} option. The later should be used +no check options or the @code{QUICK} option. The latter should be used when you are in a hurry and can take the very small risk that -@code{QUICK} didn't find an error in the data file (In most cases +@code{QUICK} didn't find an error in the data file. (In most cases MySQL should find, under normal usage, any error in the data file. If this happens then the table will be marked as 'corrupted', -in which case the table can't be used until it's repaired). +in which case the table can't be used until it's repaired.) @code{FAST} and @code{CHANGED} are mostly intended to be used from a script (for example to be executed from cron) if you want to check your table from time to time. In most cases you @code{FAST} is to be prefered over @code{CHANGED}. (The only case when it isn't is when you suspect a -bug you have found a bug in the @code{MyISAM} code.). +bug you have found a bug in the @code{MyISAM} code.) @code{EXTENDED} is only to be used after you have run a normal check but still get strange errors from a table when MySQL tries to @@ -18626,7 +18313,7 @@ index file is truncated at start, so one usually ignore this space. This space is needed on the same disk as the original index file! @item When using @code{--recover} or @code{--sort-recover} -(but not when using @code{--safe-recover}, you will need space for a +(but not when using @code{--safe-recover}), you will need space for a sort buffer for: @code{(largest_key + row_pointer_length)*number_of_rows * 2}. You can check the length of the keys and the row_pointer_length with @@ -19490,7 +19177,7 @@ error message @code{Host ... is blocked}. When more than connection to the MySQL server, MySQL assumes something is wrong and blocks the host from further connection requests. Flushing the host tables allows the host to attempt to connect -again. @xref{Blocked host}.) You can start @code{mysqld} with +again. @xref{Blocked host}. You can start @code{mysqld} with @code{-O max_connection_errors=999999999} to avoid this error message. @item @code{LOGS} @tab Closes and reopens all log files. @@ -20716,7 +20403,7 @@ Assign an unique number to it. @item Create the file @file{sql/share/charsets/MYSET.conf}. -(You can use @file{sql/share/charsets/latin1.conf} as a base for this). +(You can use @file{sql/share/charsets/latin1.conf} as a base for this.) The syntax for the file very simple: @@ -21281,7 +20968,7 @@ shell> mysql -u root -S /tmp/mysql.sock -proot_password -e @xref{Privileges}. @end example You will have to do the above for each @code{mysqld} running in each -data directory, that you have (just change the socket, -S=...) +data directory, that you have (just change the socket, -S=...). @item @code{pid-file} is very important, if you are using @code{safe_mysqld} to start @code{mysqld} (e.g. --mysqld=safe_mysqld) Every @code{mysqld} @@ -21317,7 +21004,7 @@ more flexibility. The order in which the @code{mysqlds} are started or stopped depends on the order in which they appear in the config file. @item When you want to refer to a certain group using GNR with this program, -just use the number in the end of the group name ( [mysqld# <== ). +just use the number in the end of the group name ([mysqld# <== ). @item You may want to use option '--user' for @code{mysqld}, but in order to do this you need to be root when you start the @code{mysqld_multi} @@ -22088,7 +21775,7 @@ Continue even if we get a SQL error. @cindex @code{no-named-commands}, @code{mysql} option @item -g, --no-named-commands Named commands are disabled. Use \* form only, or use named commands -only in the beginning of a line ending with a semicolon (;). Since +only in the beginning of a line ending with a semicolon (@samp{;}). Since Version 10.9, the client now starts with this option ENABLED by default! With the -g option, long format commands will still work from the first line, however. @@ -22742,7 +22429,7 @@ tables. output. The above line will be added otherwise, if --databases or --all-databases option was given. @item -t, --no-create-info -Don't write table creation information (The @code{CREATE TABLE} statement.) +Don't write table creation information (the @code{CREATE TABLE} statement). @item -d, --no-data Don't write any row information for the table. This is very useful if you just want to get a dump of the structure for a table! @@ -23192,7 +22879,7 @@ switch to a new log) by executing @code{FLUSH LOGS}. @xref{FLUSH}. @code{mysqld} writes all errors to the stderr, which the @code{safe_mysqld} script redirects to a file called @code{'hostname'.err}. (On Windows, @code{mysqld} writes this directly -to @file{\mysql\data\mysql.err}). +to @file{\mysql\data\mysql.err}.) This contains information indicating when @code{mysqld} was started and stopped and also any critical errors found when running. If @code{mysqld} @@ -23444,7 +23131,7 @@ The above command does the following: @itemize @bullet @item If standard logging (@code{--log}) or slow query logging -(@code{--log-slow-queries}) is used, closes and reopens the log file. +(@code{--log-slow-queries}) is used, closes and reopens the log file (@file{mysql.log} and @file{`hostname`-slow.log} as default). @item If update logging (@code{--log-update}) is used, closes the update log and @@ -23504,7 +23191,7 @@ Starting in Version 3.23.15, MySQL supports one-way replication internally. One server acts as the master, while the other acts as the slave. Note that one server could play the roles of master in one pair and slave in the other. The master server keeps a binary log of updates -(@xref{Binary log}.) and an index file to binary logs to keep track of +(@pxref{Binary log}) and an index file to binary logs to keep track of log rotation. The slave, upon connecting, informs the master where it left off since the last successfully propagated update, catches up on the updates, and then blocks and waits for the master to notify it of @@ -23525,7 +23212,7 @@ master. @xref{Backup}. MySQL replication is based on the server keeping track of all changes to your database (updates, deletes, etc) in the binary -log. (@xref{Binary log}.) and the slave server(s) reading the saved +log (@pxref{Binary log}) and the slave server(s) reading the saved queries from the master server's binary log so that the slave can execute the same queries on its copy of the data. @@ -25339,7 +25026,7 @@ To help MySQL optimize queries better, run @code{myisamchk --analyze} on a table after it has been loaded with relevant data. This updates a value for each index part that indicates the average number of rows that have the same value. (For unique indexes, this is always 1, -of course.). MySQL will use this to decide which index to +of course.) MySQL will use this to decide which index to choose when you connect two tables with 'a non-constant expression'. You can check the result from the @code{analyze} run by doing @code{SHOW INDEX FROM table_name} and examining the @code{Cardinality} column. @@ -26442,7 +26129,7 @@ would be available. Some of the cases where this happens are: @item If the use of the index would require MySQL to access more than 30 % of the rows in the table. (In this case a table scan is -probably much faster, as this will require us to do much fewer seeks). +probably much faster, as this will require us to do much fewer seeks.) Note that if such a query uses @code{LIMIT} to only retrieve part of the rows, MySQL will use an index anyway, as it can much more quickly find the few rows to return in the result. @@ -26510,7 +26197,7 @@ supported. See @ref{Fulltext Search} for details. MySQL can create indexes on multiple columns. An index may consist of up to 15 columns. (On @code{CHAR} and @code{VARCHAR} columns you -can also use a prefix of the column as a part of an index). +can also use a prefix of the column as a part of an index.) A multiple-column index can be considered a sorted array containing values that are created by concatenating the values of the indexed columns. @@ -26920,7 +26607,7 @@ when we tested them, neither was sufficiently bug free to allow MySQL to be compiled with optimizations on. When you compile MySQL you should only include support for the -character sets that you are going to use. (Option @code{--with-charset=xxx}). +character sets that you are going to use. (Option @code{--with-charset=xxx}.) The standard MySQL binary distributions are compiled with support for all character sets. @@ -26943,7 +26630,7 @@ the resulting binary can be up to 4 % faster. @item If you connect using TCP/IP rather than Unix sockets, the result is 7.5% slower on the same computer. (If you are connection to @code{localhost}, -MySQL will, by default, use sockets). +MySQL will, by default, use sockets.) @item If you connect using TCP/IP from another computer over a 100M Ethernet, @@ -27644,7 +27331,7 @@ A tab character. ASCII(26) (Control-Z). This character can be encoded to allow you to go around the problem that ASCII(26) stands for END-OF-FILE on Windows. (ASCII(26) will cause problems if you try to use -@code{mysql database < filename}). +@code{mysql database < filename}.) @findex \\ (escape) @findex escape (\\) @@ -28447,7 +28134,7 @@ are @code{1901} to @code{2155}, @code{0000} in the 4-digit year format, and 1970-2069 if you use the 2-digit format (70-69). MySQL displays @code{YEAR} values in @code{YYYY} format, but allows you to assign values to @code{YEAR} columns using either strings or numbers. (The @code{YEAR} type is -new in MySQL Version 3.22.). @xref{YEAR}. +new in MySQL Version 3.22.) @xref{YEAR}. @tindex NATIONAL CHAR @tindex NCHAR @@ -29084,7 +28771,7 @@ You can specify @code{TIME} values in a variety of formats: @itemize @bullet @item As a string in @code{'D HH:MM:SS.fraction'} format. (Note that -MySQL doesn't yet store the fraction for the time column). One +MySQL doesn't yet store the fraction for the time column.) One can also use one of the following ``relaxed'' syntax: @code{HH:MM:SS.fraction}, @code{HH:MM:SS}, @code{HH:MM}, @code{D HH:MM:SS}, @@ -34028,7 +33715,7 @@ you create a table. A temporary table will automatically be deleted if a connection dies and the name is per connection. This means that two different connections can both use the same temporary table name without conflicting with each other or with an existing table of the same name. (The existing table -is hidden until the temporary table is deleted). +is hidden until the temporary table is deleted.) In MySQL Version 3.23 or later, you can use the keywords @code{IF NOT EXISTS} so that an error does not occur if the table already @@ -34284,13 +33971,13 @@ many numbers that are the same. Prefix compression means that every key needs one extra byte to indicate how many bytes of the previous key are the same for the next key (note that the pointer to the row is stored in high-byte-first-order directly after the key, to improve -compression.) This means that if you have many equal keys on two rows +compression). This means that if you have many equal keys on two rows in a row, all following 'same' keys will usually only take 2 bytes (including the pointer to the row). Compare this to the ordinary case where the following keys will take storage_size_for_key + pointer_size (usually 4). On the other hand, if all keys are totally different, you will lose 1 byte per key, if the key isn't a -key that can have @code{NULL} values (In this case the packed key length will +key that can have @code{NULL} values. (In this case the packed key length will be stored in the same byte that is used to mark if a key is @code{NULL}.) @item @@ -34832,7 +34519,7 @@ columns. For @code{CHAR} and @code{VARCHAR} columns, indexes can be created that use only part of a column, using @code{col_name(length)} syntax. (On -@code{BLOB} and @code{TEXT} columns the length is required). The +@code{BLOB} and @code{TEXT} columns the length is required.) The statement shown below creates an index using the first 10 characters of the @code{name} column: @@ -35387,7 +35074,7 @@ The argument to @code{AGAINST} must be a constant string. Unfortunately, full-text search has no user-tunable parameters yet, although adding some is very high on the TODO. However, if you have a -MySQL source distribution (@xref{Installing source}.), you can +MySQL source distribution (@pxref{Installing source}), you can somewhat alter the full-text search behavior. Note that full-text search was carefully tuned for the best searching @@ -35529,7 +35216,7 @@ You can convert tables between different types with the @code{ALTER TABLE} statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}. Note that MySQL supports two different kinds of -tables. Transaction-safe tables (@code{BDB}, @code{InnoDB} +tables: transaction-safe tables (@code{BDB} and @code{InnoDB}) and not transaction-safe tables (@code{HEAP}, @code{ISAM}, @code{MERGE}, and @code{MyISAM}). @@ -36057,9 +35744,9 @@ In other words, the only ways this can go out of sync are: The @code{MyISAM} tables are copied without a @code{LOCK} and @code{FLUSH TABLES}. @item -MySQL has crashed between an update and the final close +MySQL has crashed between an update and the final close. (Note that the table may still be ok, as MySQL always issues writes -for everything between each statement). +for everything between each statement.) @item Someone has done a @code{myisamchk --repair} or @code{myisamchk --update-state}on a table that was in use by @code{mysqld}. @@ -36403,7 +36090,7 @@ problem. As this is a two stage operation, any problems with BDB tables may take a little longer for us to fix than for other table handlers. However, as the BerkeleyDB code itself has been used by many other applications than MySQL, we don't envision any big problems with -this. @xref{Table handler support}. +this. @xref{Support}. @node BDB install, BDB start, BDB overview, BDB @@ -39035,13 +38722,13 @@ same order as they appear in the @strong{MyODBC} connect screen: @item 32 @tab Simulate a ODBC 1.0 driver in some context. @item 64 @tab Ignore use of database name in 'database.table.column'. @item 128 @tab Force use of ODBC manager cursors (experimental). -@item 256 @tab Disable the use of extended fetch (experimental) +@item 256 @tab Disable the use of extended fetch (experimental). @item 512 @tab Pad CHAR fields to full column length. @item 1024 @tab SQLDescribeCol() will return fully qualifed column names @item 2048 @tab Use the compressed server/client protocol @item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords! @item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT. -@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG). +@item 16384 @tab Change LONGLONG columns to INT columns (some applications can't handle LONGLONG). @item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental) @item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf} @item 131072 @tab Add some extra safety checks (should not bee needed but...) @@ -39497,7 +39184,7 @@ likely it is that we can fix the problem! * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions * C Thread functions:: C Thread Functions -* C Embedded Server functions:: C Embedded Server functions. C Embedded Server Functions +* C Embedded Server functions:: C Embedded Server Functions * C API problems:: Common questions and problems when using the C API * Building clients:: Building Client Programs * Threaded clients:: How to Make a Threaded Client @@ -43032,7 +42719,7 @@ Two APIs are available in the MySQL You can compile the MySQL Windows source with Borland C++ 5.02. (The Windows source includes only projects for Microsoft VC++, for -Borland C++ you have to do the project files yourself). +Borland C++ you have to do the project files yourself.) One known problem with Borland C++ is that it uses a different structure alignment than VC++. This means that you will run into problems if you @@ -43231,7 +42918,7 @@ you are using @code{--with-mysqld-ldflags=-all-static} If you want to use an UDF that needs to access symbols from @code{mysqld} (like the @code{methaphone} example in @file{sql/udf_example.cc} that uses @code{default_charset_info}), you must link the program with -@code{-rdynamic}. (see @code{man dlopen}). +@code{-rdynamic} (see @code{man dlopen}). For each function that you want to use in SQL statements, you should define corresponding C (or C++) functions. In the discussion below, the name @@ -43732,7 +43419,7 @@ can take a look at @code{Item_func_mod::fix_length_and_dec} for a typical example of how to do this. @end enumerate -All functions must be thread safe (In other words, don't use any global or +All functions must be thread safe (in other words, don't use any global or static variables in the functions without protecting them with mutexes). If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()} @@ -43962,7 +43649,7 @@ The tests are located in @code{mysql-test/t/*.test} A test case consists of @code{;} terminated statements and is similar to the input of @code{mysql} command line client. A statement by default is a query to be sent to MySQL server, unless it is recognized as internal -command ( eg. @code{sleep} ). +command (eg. @code{sleep}). @item All queries that produce results, e.g. @code{SELECT}, @code{SHOW}, @@ -44836,7 +44523,7 @@ number 256 to affect the number of file descriptors available to @code{ulimit} (and @code{open-files-limit}) can increase the number of file descriptors, but only up to the limit imposed by the operating system. There is also a 'hard' limit that can only be overrided if you -start @code{safe_mysqld} or @code{mysqld} as root (Just remember that +start @code{safe_mysqld} or @code{mysqld} as root (just remember that you need to also use the @code{--user=..} option in this case). If you need to increase the OS limit on the number of file descriptors available to each process, consult the documentation for your operating @@ -46099,7 +45786,7 @@ the MySQL database @item @uref{http://io.incluso.com, Ionline - online publication:} MySQL, PHP, Java, Web programming, DB development -@item @uref{http://www.baboo.com, BaBoo(Browse and bookmark). Free Web-based bookmark manager and Calendar} +@item @uref{http://www.baboo.com, BaBoo (Browse and Bookmark). Free Web-based bookmark manager and Calendar} @item @uref{http://www.courses.pjc.cc.fl.us/Schedule/index.php, Course Schedule System at Pensacola Junior College} @@ -46443,7 +46130,7 @@ MySQL C++ API. By Satish @email{spitfire@@pn3.vsnl.net.in}. Inspired by Roland Haenel's C++ API and Ed Carp's MyC library. @item @uref{http://www.mysql.com/download_mysql++.html, mysql++} -MySQL C++ API (More than just a wrapper library.) Originally by +MySQL C++ API (more than just a wrapper library). Originally by @email{kevina@@clark.net}. Nowadays maintained by Sinisa at MySQL AB. @item @uref{http://nelsonjr.homepage.com/NJrAPI,NJrAPI} @@ -47193,7 +46880,7 @@ handlers with index compression and different record formats). The @code{HEAP} library. A memory table system with our superior full dynamic hashing. In use since 1981 and published around 1984. @item -The @code{replace} program (look into it, it's COOL!). +The @code{replace} program (take a look at it, it's @strong{COOL}!). @item @strong{MyODBC}, the ODBC driver for Windows95. @item @@ -47225,7 +46912,7 @@ Lots of testing of new features. @item Our in-house ``free'' software lawyer. @item -Mailing list maintainer (who never has the time to do it right...) +Mailing list maintainer (who never has the time to do it right...). @item Our original portability code (more than 10 years old now). Nowadays only some parts of @code{mysys} are left. @@ -47261,9 +46948,9 @@ Maintainer of mysql++. @item Our security expert. @item -Vio interface (The foundation for the encrypted client/server protocol). +Vio interface (the foundation for the encrypted client/server protocol). @item -MySQL Filesystem (A way to use MySQL databases as files +MySQL Filesystem (a way to use MySQL databases as files and directories). @item The CASE Expression. @@ -47354,7 +47041,7 @@ Jonas Norrman - Handles licensing questions sent to @email{info@@mysql.com}. @item Erik Granberg - Handles MySQL partners (and a lot of other stuff). @item -Allan Larsson (The BOSS for TCX DataKonsult AB). +Allan Larsson (the BOSS for TCX DataKonsult AB). @end table @@ -48207,7 +47894,7 @@ Fixed bug when thread creation failed (could happen when doing a LOT of connections in a short time). @item Fixed some problems with @code{FLUSH TABLES} and @code{TEMPORARY} tables. -(Problem with freeing the key cache and error @code{Can't reopen table...}). +(Problem with freeing the key cache and error @code{Can't reopen table...}.) @item Fixed a problem in Innobase with other character sets than @code{latin1} and another problem when using many columns. @@ -48229,7 +47916,7 @@ Fixed a bug in @code{CONCAT_WS()} where it returned wrong results. @item Changed @code{CREATE ... INSERT} and @code{INSERT ... SELECT} to not allow concurrent inserts as this could make the binary log hard to repeat. -(Concurrent inserts are enabled if you are not using the binary or update log). +(Concurrent inserts are enabled if you are not using the binary or update log.) @item Changed some macros to be able to use fast mutex with glibc 2.2. @end itemize @@ -49158,8 +48845,8 @@ More variables in @code{SHOW SLAVE STATUS} and @code{SHOW MASTER STATUS}. @item @code{SLAVE STOP} now will not return until the slave thread actually exits. @item -Full text search via the @code{MATCH} function and @code{FULLTEXT} index type. -(For MyISAM files). This makes @code{FULLTEXT} a reserved word. +Full text search via the @code{MATCH} function and @code{FULLTEXT} index type +(for MyISAM files). This makes @code{FULLTEXT} a reserved word. @end itemize @@ -49232,13 +48919,13 @@ Fixed @code{chown} warning in @code{safe_mysqld}. Fixed a bug in @code{ORDER BY} that was introduced in 3.23.19. @item Only optimize the @code{DELETE FROM tbl_name} to do a drop+create of -the table if we are in @code{AUTOCOMMIT} mode. (Needed for BDB tables). +the table if we are in @code{AUTOCOMMIT} mode (needed for BDB tables). @item Added extra checks to avoid index corruption when the @code{ISAM}/@code{MyISAM} index files gets full during an @code{INSERT}/@code{UPDATE}. @item @code{myisamchk} didn't correctly update row checksum when used with -@code{-ro} (This only gave an warning in subsequent runs). +@code{-ro} (this only gave an warning in subsequent runs). @item Fixed bug in @code{REPAIR TABLE} so that it works with tables without indexes. @item @@ -49341,7 +49028,7 @@ Added 4 sample @code{my.cnf} example files in the @file{support-files} directory. @item Fixed @code{duplicated key} problem when doing big @code{GROUP BY}'s. -(This bug was probably introduced in 3.23.15). +(This bug was probably introduced in 3.23.15.) @item Changed syntax for @code{INNER JOIN} to match ANSI SQL. @item @@ -49644,7 +49331,7 @@ Added variables @code{select_limit} and @code{max_join_size} to @code{mysql}. Added sql variables: @code{SQL_MAX_JOIN_SIZE} and @code{SQL_SAFE_UPDATES}. @item Added @code{READ LOCAL} lock that doesn't lock the table for concurrent -inserts. (This is used by @code{mysqldump}). +inserts. (This is used by @code{mysqldump}.) @item Changed that @code{LOCK TABLES ... READ} doesn't anymore allow concurrent inserts. @@ -49705,7 +49392,7 @@ is many keys to choose from. @item Changed optimizer to prefer a range key instead of a ref key when the range key can uses more columns than the ref key (which only can use -columns with =). For example, the following type of queries should now +columns with @code{=}). For example, the following type of queries should now be faster: @code{SELECT * from key_part_1=const and key_part_2 > const2} @item Fixed bug that a change of all @code{VARCHAR} columns to @code{CHAR} columns @@ -50008,7 +49695,7 @@ an empty value list to insert a row in which each column is set to its default value. @item Changed @code{SUBSTRING(text FROM pos)} to conform to ANSI SQL. (Before this -construct returned the rightmost 'pos' characters). +construct returned the rightmost 'pos' characters.) @item @code{SUM()} with @code{GROUP BY} returned 0 on some systems. @item @@ -50180,7 +49867,7 @@ You can specify a netmask using the @code{IP/NETMASK} syntax. @item If you compare a @code{NOT NULL DATE/DATETIME} column with @code{IS NULL}, this is changed to a compare against @code{0} to satisfy some ODBC -applications. (By @email{shreeve@@uci.edu}). +applications. (By @email{shreeve@@uci.edu}.) @item @code{NULL IN (...)} now returns @code{NULL} instead of @code{0}. This will ensure that @code{null_column NOT IN (...)} doesn't match @@ -50457,7 +50144,7 @@ Fixed core dump with empty @code{BLOB/TEXT} column to @code{REVERSE()}. Extended @code{/*! */} with version numbers. @item Changed @code{SUBSTRING(text FROM pos)} to conform to ANSI SQL. (Before this -construct returned the rightmost 'pos' characters). +construct returned the rightmost 'pos' characters.) @item Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table} @item @@ -50578,7 +50265,7 @@ Fixed a problem with @code{Host '...' is not allowed to connect to this MySQL server} after one had inserted a new MySQL user with a @code{GRANT} command. @item -Changed to use @code{TCP_NODELAY} also on Linux (Should give faster TCP/IP +Changed to use @code{TCP_NODELAY} also on Linux (should give faster TCP/IP connections). @end itemize @@ -50856,7 +50543,7 @@ Changed @code{+}, @code{-} (sign and minus), @code{*}, @code{/}, @code{%}, Fixed a bug in @code{ALTER TABLE} that caused @code{mysqld} to crash. @item MySQL now always reports the conflicting key values when a -duplicate key entry occurs. (Before this was only reported for @code{INSERT}). +duplicate key entry occurs. (Before this was only reported for @code{INSERT}.) @item New syntax: @code{INSERT INTO tbl_name SET col_name=value, col_name=value, ...} @item @@ -51596,7 +51283,7 @@ Fixed problem in range optimizer (core dump) for a very complex query. Fixed problem when using @code{MIN(integer)} or @code{MAX(integer)} in @code{GROUP BY}. @item -Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha). +Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha.) @item Fixed bug in @code{WEEK("XXXX-xx-01")}. @end itemize @@ -52306,7 +51993,7 @@ Added @code{--pid-file=#} option to @code{mysqld}. @item Added date formatting to @code{FROM_UNIXTIME()}, originally by Zeev Suraski. @item -Fixed bug in @code{BETWEEN} in range optimizer (Did only test = of the first +Fixed bug in @code{BETWEEN} in range optimizer (did only test = of the first argument). @item Added machine-dependent files for MIT-pthreads i386-SCO. There is probably @@ -53918,8 +53605,8 @@ Copy on demand is in many case much better than page or row level locking; The worst case does, however, use much more memory than when using normal locks. -Instead of using row level locks one can use application level locks. -(Like get_lock/release_lock in MySQL). This works of course +Instead of using row level locks one can use application level locks +(like get_lock/release_lock in MySQL). This works of course only in well-behaved applications. In many cases one can do an educated guess which locking type is best @@ -54432,7 +54119,7 @@ Unireg is currently only available in Swedish and Finnish. The price tag for Unireg is 10,000 Swedish kr (about $1500 US), but this includes support. Unireg is distributed as a binary. (But all the ISAM -sources can be found in MySQL). Usually we compile the binary for the +sources can be found in MySQL.) Usually we compile the binary for the customer at their site. All new development is concentrated to MySQL. From 352101129b46d3fd4a9466a9fa7e42e49b1ed6a6 Mon Sep 17 00:00:00 2001 From: "tim@work.mysql.com" <> Date: Tue, 2 Oct 2001 00:23:28 +0200 Subject: [PATCH 30/38] manual.texi Fix some details of the Support and Licensing section. --- Docs/manual.texi | 116 ++++++++++++----------------------------------- 1 file changed, 30 insertions(+), 86 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 02e6a521553..e3fd896d694 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -490,8 +490,8 @@ If you represent a business that is interested in partnering with MySQL, please send e-mail to @email{partner@@mysql.com}. For timely, precise answers to technical questions about MySQL -you should @uref{https://order.mysql.com/, order} one of our -@uref{http://www.mysql.com/support/arrangements/types.html, support contracts}. +you should order one of our +@uref{https://order.mysql.com/, support contracts}. MySQL support is provided by the MySQL developers so the standard is extremely high. @@ -2673,7 +2673,6 @@ Many users don't read mail with a browser! * Copyright:: Copyrights used by MySQL * Licensing policy:: MySQL licensing policy * Licensing examples:: Example licensing situations -* Payment information:: Payment information @end menu This section describes MySQL support and licensing arrangements: @@ -2692,9 +2691,6 @@ This section describes MySQL support and licensing arrangements: @item Sample situations illustrating when a license is required (@pxref{Licensing examples}) -@item How to make payments -(@pxref{Payment information}) - @end itemize @@ -2709,30 +2705,33 @@ This section describes MySQL support and licensing arrangements: @cindex support costs @cindex prices, licensing and support -MySQL AB offers several support options. A description +MySQL AB offers several commercial support options. A description of what each level of support includes is given at -@uref{http://www.mysql.com/support/arrangements/types.html}. As -a support customer, you have access to the people who develop the -MySQL source code. The standard is high for both quality and -speed. +@uref{https://order.mysql.com}. If you have restricted access to the +Internet, contact our sales staff at @email{sales@@mysql.com}. -Our current support and license prices are available from our -web site. For options and pricing, and to order support and -licenses, please see -@uref{https://order.mysql.com/}. +Technical support from MySQL AB means personal answers to your +personal problems direct from the software engineers who code the +MySQL database engine. It is often very helpful to receive +quick, personally prepared answers tailored to your exact needs. +This is what MySQL AB paid technical support offers. Our pricing +model ensures that basic support is affordable even for those on +limited budgets. -A license is not a support agreement and includes very minimal -support. This means that we try to answer any questions relevant -to installation. If the answer is in the documentation, we will -direct you to the appropriate section. If you have not purchased -a license or support, we will simply direct you to the freely -available public resources. +We try to take a broad and inclusive view of technical support. +Almost any problem involving MySQL is important to us if it's +important to you. Typically customers seek help on how to get +different commands and utilities to work, remove performance +bottlenecks, restore crashed systems, understand operating system +or networking impacts on MySQL, establish best practises for backup +and recovery, utilize APIs, etc. We consider reliability to be crucial to MySQL's success, and fixing bugs is important to us. If you discover a bug that can be repeated reliably, we will fix it in any case. But if you pay for support we will also notify you about the fix status instead of just fixing it in a later release. +@xref{Bug reports}. @node Copyright, Licensing policy, Support, Licensing and Support @@ -2766,7 +2765,7 @@ This is also available as the file @file{COPYING} in the distributions. @end enumerate -One goal is that the SQL client library should be free enough that it is +The SQL client library should be free enough that it is possible to add MySQL support into commercial products without a license. For this reason, we chose the LGPL license for the client code. @@ -2775,7 +2774,7 @@ client code. This means that you can use MySQL for free with any program that uses any of the free software licenses. MySQL is also free for any end -user for his own or company usage. +user for personal or company usage. However, if you use MySQL for something important to you, you may want to help secure its development by purchasing licenses or a support @@ -2798,6 +2797,9 @@ See the documentation for that version for more information. @cindex General Public License, MySQL The formal terms of the GPL license can be found at @ref{GPL license}. +For pricing and ordering information, see +@uref{https://order.mysql.com/}. + Basically, our licensing policy and interpretation of the GPL is as follows: For normal internal use, MySQL costs nothing. You do not have @@ -2871,11 +2873,12 @@ contact us. @xref{Contact information}. If you require a MySQL license, the easiest way to pay for it is to use the license form on MySQL's secure server at -@uref{https://order.mysql.com/}. Other forms of payment are -discussed in @ref{Payment information}. +@uref{https://order.mysql.com/}. +You can also get the latest pricing and ordering information by sending +an e-mail to @email{sales@@mysql.com}. -@node Licensing examples, Payment information, Licensing policy, Licensing and Support +@node Licensing examples, , Licensing policy, Licensing and Support @subsection Example Licensing Situations @menu @@ -2976,7 +2979,7 @@ it is patched correctly. @cindex running, a web server If you use MySQL in conjunction with a Web server, you -don't have to pay for a license. +do not have to pay for a license. This is true even if you run a commercial Web server that uses MySQL, because you are not selling an embedded MySQL @@ -2984,65 +2987,6 @@ version yourself. However, in this case we would like you to purchase MySQL support, because MySQL is helping your enterprise. -@node Payment information, , Licensing examples, Licensing and Support -@subsection Payment information - -@cindex payment information - -The most efficient way to pay for support and licenses is through -@uref{https://order.mysql.com/, MySQL AB's secure license form}. -Please check this site for the latest support options and -pricing details. - -Also, we can take SWIFT payments, checks, or credit cards. - -@itemize @bullet - -@item -SWIFT payments should be made to: - -@example -Postgirot Bank AB -105 06 STOCKHOLM, SWEDEN - -MySQL AB -BOX 6434 -11382 STOCKHOLM, SWEDEN - -SWIFT address: PGSI SESS -Account number: 96 77 06 - 3 -@end example - -Specify: license and/or support and your name and e-mail address. - -In Europe and Japan you can use EuroGiro (which should be less -expensive) to the same account. - -@item -If you want to pay by check, make it payable to ``MySQL Finland AB'' and -mail it to the address below: - -@example -MySQL AB -BOX 6434, Torsgatan 21 -11382 STOCKHOLM, SWEDEN -@end example - -@item -You can also print a copy of the license form, fill it in, and send it by fax -to: - -+46-8-729 69 05 - -@item -If you want us to bill you, you can use the license form and write ``bill -us'' in the comment field. You can also mail a message to -@email{sales@@mysql.com} (@strong{not} @code{mysql@@lists.mysql.com}!) -with your company information and ask us to bill you. - -@end itemize - - @node Compatibility, Comparisons, Licensing and Support, Introduction @section How Standards-compatible Is MySQL? From 4ec3eda716ee7fac4db46df2cbf444a822d5d675 Mon Sep 17 00:00:00 2001 From: "tim@work.mysql.com" <> Date: Tue, 2 Oct 2001 00:30:30 +0200 Subject: [PATCH 31/38] manual.texi Fix typo in support section. --- Docs/manual.texi | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index e3fd896d694..21888a24b46 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -2723,16 +2723,9 @@ Almost any problem involving MySQL is important to us if it's important to you. Typically customers seek help on how to get different commands and utilities to work, remove performance bottlenecks, restore crashed systems, understand operating system -or networking impacts on MySQL, establish best practises for backup +or networking impacts on MySQL, establish best practices for backup and recovery, utilize APIs, etc. -We consider reliability to be crucial to MySQL's success, and -fixing bugs is important to us. If you discover a bug that can -be repeated reliably, we will fix it in any case. But if you pay -for support we will also notify you about the fix status instead -of just fixing it in a later release. -@xref{Bug reports}. - @node Copyright, Licensing policy, Support, Licensing and Support @subsection Copyrights Used by MySQL From d3385bf98935770d9faf395089c9e8d9a161db2d Mon Sep 17 00:00:00 2001 From: "Administrator@fred." <> Date: Tue, 2 Oct 2001 12:51:12 +1000 Subject: [PATCH 32/38] Added Arjen to doc maintainer list. Initial cleanup of SSL/X509 explanation. --- BitKeeper/etc/logging_ok | 1 + Docs/manual.texi | 50 ++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 5d7b0e25c86..16af71fd78d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -30,3 +30,4 @@ tonu@hundin.mysql.fi tonu@volk.internalnet tonu@x153.internalnet tonu@x3.internalnet +Administrator@fred. diff --git a/Docs/manual.texi b/Docs/manual.texi index 83053c5c485..09d50175b61 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -481,8 +481,8 @@ and @code{dvips}. The PDF version is produced with @code{pdftex}. @cindex Texinfo This manual is written and maintained by David Axmark, Michael (Monty) -Widenius, Jeremy Cole, and Paul DuBois. For other contributors, -see @ref{Credits}. +Widenius, Jeremy Cole, Arjen Lentz, and Paul DuBois. For other +contributors, see @ref{Credits}. @node Manual conventions, History, Manual-info, MySQL and MySQL AB @@ -17224,36 +17224,38 @@ SSL we need to explain some basics about SSL and X509. People who are already aware of it can skip this chapter. By default, MySQL uses unencrypted connections between client and server. This means -that anyone on the way can listen and read all your data which moves there. Even -more, some people can change content of data while it is moving between client and -server. Sometime you may need to move really secret data over public networks and -such publicity is unacceptable. +that someone could watch all your traffic and look at the data being sent/received. +Actually, they could even change the data while it is in transit between client +and server. Sometimes you need to move really secret data over public networks and +in such a case using an unencrypted connection is unacceptable. SSL is a protocol which uses different encryption algorithms to ensure that data -which comes from public network can be trusted. It have mechanisms to detect any +which comes from public network can be trusted. It has mechanisms to detect any change, loss or replay of data. SSL also incorpores algorithms to recognize and -verification of identity using X509 standard. +provide identity verification using the X509 standard. @cindex What is encryption -Encryption is the way to make any kind of data unreadable. Even more, today's -practice require many additional security elements from encryption algorithms. +Encryption is the way to make any kind of data unreadable. In fact, today's +practice requires many additional security elements from encryption algorithms. They should resist many kind of known attacks like just messing with order of encrypted messages or replaying data twice. @cindex What is X509/Certificate? -X509 is standard which makes possible to identity someone in the Internet. Mostly -it is used in e-commerce over the Internet. Shortly speaking there should be some -company called "Certificate Authority" which assigns electronic certificates to -everyone who needs. Certificates rely on asymmetric encryption algorithms which -have two encryption keys - public and secret. Certificate owner can prove his -identity showing certificate to other party. Certificate consists his owner public -key. Any data encrypted with it can be decrypted only by secret key holder. +X509 is a standard that makes it possible to identify someone in the Internet. +It is most commonly used in e-commerce applications. In basic terms, there should +be some company called "Certificate Authority" which assigns electronic certificates +to anyone who needs them. Certificates rely on asymmetric encryption algorithms +which have two encryption keys - public and secret. A certificate owner can prove +his identity by showing his certificate to other party. A certificate consists of +his owner's public key. Any data encrypted with this public key can only be +decrypted using the corresponding secret key, which is held by the owner of the +certificate. @cindex Possible questions: -Q: Why MySQL not uses encrypted connections by default? +Q: Why doesn't MySQL use encrypted connections by default? A: Because it makes MySQL slower. Any kind of additional functionality requires computer to do additional work and encrypting data is CPU-intensive operation which -can overcome MySQL own work and consumed time. MySQL is tuned to be fast by default. +require time and can delay MySQL main tasks. MySQL is tuned to be fast by default. Q: I need more information about SSL/X509/encrpytion/whatever A: Use your favourite internet search engine and search for keywords you are interested in. @@ -17264,14 +17266,15 @@ A: Use your favourite internet search engine and search for keywords you are int @cindex SSL related options MySQL can check x509 certificate attributes additionally to most used username/password -cheme. All usual options are still required (username, password, IP address mask, database/table name). +scheme. All the usual options are still required (username, password, IP address mask, +database/table name). There are different possibilities to limit connections: @itemize @bullet @item Without any SSL/X509 options all kind of encrypted/unencrypted connections are allowed if - username and password are valid. +username and password are valid. @item @code{REQUIRE SSL} option makes SSL encrypted connection must. Note that this requirement @@ -17304,8 +17307,9 @@ GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQ @end example @item -@code{REQUIRE SUBJECT subject} requires client to have valid x509 certificate with subject "subject" on it. If client have valid certificate but having different "subject" then connection is still -not allowed. +@code{REQUIRE SUBJECT subject} requires clients to have valid x509 certificate with +subject "subject" on it. If client have valid certificate but having different +"subject" then connection is still not allowed. Example: @example From 880026ccf667bf6e6adbd6cfa0abcf4268d68e4c Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Tue, 2 Oct 2001 05:53:00 +0300 Subject: [PATCH 33/38] Cleaned up SSL documentation Fixes for embedded server Made key_cache more configurable Fixed that one can change key blocksize in MyISAM A lot of optimizations to make MyISAM slightly faster --- Docs/manual.texi | 333 ++++++++++++++++---------- client/mysql.cc | 7 +- client/mysqltest.c | 37 +-- include/my_global.h | 9 + include/my_sys.h | 9 +- include/myisam.h | 7 +- include/mysql.h | 8 +- libmysql/libmysql.c | 6 +- libmysqld/Makefile.am | 2 + libmysqld/embedded_priv.h | 32 +++ libmysqld/examples/test-run | 4 +- libmysqld/lib_sql.cc | 230 +++++++----------- libmysqld/libmysqld.c | 42 +--- myisam/ft_boolean_search.c | 2 +- myisam/ft_nlq_search.c | 2 +- myisam/ft_search.c | 2 +- myisam/mi_changed.c | 2 +- myisam/mi_check.c | 27 +-- myisam/mi_create.c | 17 +- myisam/mi_delete.c | 3 +- myisam/mi_delete_all.c | 2 +- myisam/mi_dynrec.c | 7 +- myisam/mi_info.c | 2 +- myisam/mi_key.c | 2 +- myisam/mi_locking.c | 10 +- myisam/mi_open.c | 4 +- myisam/mi_page.c | 4 +- myisam/mi_range.c | 16 +- myisam/mi_rkey.c | 12 +- myisam/mi_rnext.c | 4 +- myisam/mi_rnext_same.c | 2 +- myisam/mi_rprev.c | 4 +- myisam/mi_rsame.c | 5 +- myisam/mi_search.c | 40 ++-- myisam/mi_static.c | 2 +- myisam/mi_statrec.c | 7 +- myisam/mi_test2.c | 144 ++++++----- myisam/mi_test_all.res | 90 +++---- myisam/mi_test_all.sh | 20 ++ myisam/mi_write.c | 10 +- myisam/myisamchk.c | 28 ++- myisam/myisamdef.h | 11 +- mysys/Makefile.am | 2 +- mysys/mf_keycache.c | 54 ++--- mysys/my_bit.c | 32 +++ mysys/my_init.c | 3 +- scripts/mysql_fix_privilege_tables.sh | 19 ++ scripts/mysql_install_db.sh | 6 +- sql/derror.cc | 6 +- sql/item_cmpfunc.cc | 10 +- sql/item_cmpfunc.h | 9 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 54 +++-- 53 files changed, 793 insertions(+), 611 deletions(-) create mode 100644 libmysqld/embedded_priv.h create mode 100644 mysys/my_bit.c diff --git a/Docs/manual.texi b/Docs/manual.texi index a8a7844589c..f03c8aee889 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -5722,8 +5722,6 @@ Character set casts and syntax for handling multiple character sets. @item Help for all commands from the client. @item -Secure connections (with SSL). -@item @code{SHOW COLUMNS FROM table_name} (used by @code{mysql} client to allow expansions of column names) should not open the table, but only the definition file. This will require less memory and be much faster. @@ -9928,11 +9926,12 @@ that you also probably need to raise the @code{core file size} by adding @code{ulimit -c 1000000} to @code{safe_mysqld} or starting @code{safe_mysqld} with @code{--core-file-sizes=1000000}. @xref{safe_mysqld, , @code{safe_mysqld}}. -To get a core dump on Linux if @code{mysqld} dies with a SIGSEGV signal, you can -start @code{mysqld} with the @code{--core-file} option. Note that you also probably -need to raise the @code{core file size} by adding @code{ulimit -c 1000000} to -@code{safe_mysqld} or starting @code{safe_mysqld} with -@code{--core-file-sizes=1000000}. @xref{safe_mysqld, , @code{safe_mysqld}}. +To get a core dump on Linux if @code{mysqld} dies with a SIGSEGV signal, +you can start @code{mysqld} with the @code{--core-file} option. Note +that you also probably need to raise the @code{core file size} by adding +@code{ulimit -c 1000000} to @code{safe_mysqld} or starting +@code{safe_mysqld} with @code{--core-file-sizes=1000000}. +@xref{safe_mysqld, , @code{safe_mysqld}}. If you are linking your own MySQL client and get the error: @@ -14741,6 +14740,17 @@ FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' @cindex options, command-line @cindex mysqld options +In most cases you should manage mysqld options through option files. +@xref{Option files}. + +@code{mysqld} and @code{mysqld.server} reads options from the +@code{mysqld} and @code{server} groups. @code{mysqld_safe} read options +from the @code{mysqld}, @code{server}, @code{mysqld_safe} and +@code{safe_mysqld} groups. An embedded MySQL server usually reads +options from the @code{server}, @code{embedded} and +@code{xxxxx_SERVER}, where @code{xxxxx} is the name of the application. + + @code{mysqld} accepts the following command-line options: @table @code @@ -15057,8 +15067,9 @@ Options specified on the command line or in option files take precedence over environment variable values. @xref{Environment variables}. The following programs support option files: @code{mysql}, -@code{mysqladmin}, @code{mysqld}, @code{mysqldump}, @code{mysqlimport}, -@code{mysql.server}, @code{myisamchk}, and @code{myisampack}. +@code{mysqladmin}, @code{mysqld}, @code{mysqld_safe}, @code{mysql.server}, +@code{mysqldump}, @code{mysqlimport}, @code{mysqlshow}, @code{mysqlcheck}, +@code{myisamchk}, and @code{myisampack}. You can use option files to specify any long option that a program supports! Run the program with @code{--help} to get a list of available options. @@ -15620,6 +15631,10 @@ to make things much harder. To make things even more secure you should use @uref{http://www.ssh.com}. With this, you can get an encrypted TCP/IP connection between a MySQL server and a MySQL client. +If you are using MySQL 4.0, you can also use internal openssl support. +@xref{Secure connections}. + + To make a MySQL system secure, you should strongly consider the following suggestions: @@ -16959,6 +16974,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run * Adding users:: Adding New Users to MySQL * Passwords:: Setting Up Passwords * Password security:: Keeping Your Password Secure +* Secure connections:: Using Secure Connections @end menu @@ -17206,120 +17222,8 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the MySQL grant tables. @end itemize ------------ -@cindex SSL and X509 Basics -MySQL has support for SSL encrypted connetions. To understand how MySQL uses -SSL we need to explain some basics about SSL and X509. People who are already -aware of it can skip this chapter. +For a description of using @code{REQUIRE}, see @xref{Secure connections}. -By default, MySQL uses unencrypted connections between client and server. This means -that anyone on the way can listen and read all your data which moves there. Even -more, some people can change content of data while it is moving between client and -server. Sometime you may need to move really secret data over public networks and -such publicity is unacceptable. - -SSL is a protocol which uses different encryption algorithms to ensure that data -which comes from public network can be trusted. It have mechanisms to detect any -change, loss or replay of data. SSL also incorpores algorithms to recognize and -verification of identity using X509 standard. - -@cindex What is encryption -Encryption is the way to make any kind of data unreadable. Even more, today's -practice require many additional security elements from encryption algorithms. -They should resist many kind of known attacks like just messing with order -of encrypted messages or replaying data twice. - -@cindex What is X509/Certificate? -X509 is standard which makes possible to identity someone in the Internet. Mostly -it is used in e-commerce over the Internet. Shortly speaking there should be some -company called "Certificate Authority" which assigns electronic certificates to -everyone who needs. Certificates rely on asymmetric encryption algorithms which -have two encryption keys - public and secret. Certificate owner can prove his -identity showing certificate to other party. Certificate consists his owner public -key. Any data encrypted with it can be decrypted only by secret key holder. - -@cindex Possible questions: -Q: Why MySQL not uses encrypted connections by default? -A: Because it makes MySQL slower. Any kind of additional functionality requires -computer to do additional work and encrypting data is CPU-intensive operation which -can overcome MySQL own work and consumed time. MySQL is tuned to be fast by default. - -Q: I need more information about SSL/X509/encrpytion/whatever -A: Use your favourite internet search engine and search for keywords you are interested in. - ------------- - - -@cindex SSL related options - -MySQL can check x509 certificate attributes additionally to most used username/password -cheme. All usual options are still required (username, password, IP address mask, database/table name). - -There are different possibilities to limit connections: - -@itemize @bullet -@item -Without any SSL/X509 options all kind of encrypted/unencrypted connections are allowed if - username and password are valid. - -@item -@code{REQUIRE SSL} option makes SSL encrypted connection must. Note that this requirement -can be omitted of there are any other ACL record which allows non-SSL connection. - -Example: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SSL -@end example - - -@item -* @code{REQUIRE X509} Requiring X509 certificate means that client should have valid certificate -but we do not care about exact certificate, issuer or subject. Only restriction is it should -be possible to verify its signature with some of our CA certificates. - -Example: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509 -@end example - -@item -@code{REQUIRE ISSUER issuer} makes connection more restrictive: now client must present - valid x509 certificate issued by CA "issuer". Using x509 certificates always implies encryption, - so option "SSL" is not neccessary anymore. - -Example: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" -@end example - -@item -@code{REQUIRE SUBJECT subject} requires client to have valid x509 certificate with subject "subject" on it. If client have valid certificate but having different "subject" then connection is still -not allowed. - -Example: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" -@end example - -@item -@code{REQUIRE CIPHER cipher} is needed to assure enough strong ciphers and keylengths to be used. SSL himself can be weak if old algorithms with short encryption keys are used. Using this option we can ask for some exact cipher to allow connection. - -Example: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA" -@end example - -Also it is allowed to combine those options with each other like this: -@example -GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" - REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" - AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" - AND CIPHER "EDH-RSA-DES-CBC3-SHA" -@end example - -But it is not allowed to use any of options twice. Only different options can be mixed. -@end itemize ------------ @node User names, Privilege changes, GRANT, User Account Management @subsection MySQL User Names and Passwords @@ -17814,7 +17718,7 @@ your Unix password and your MySQL password are the same, that Unix password file. @xref{User names}. -@node Password security, , Passwords, User Account Management +@node Password security, Secure connections, Passwords, User Account Management @subsection Keeping Your Password Secure It is inadvisable to specify your password in a way that exposes it to @@ -17890,6 +17794,170 @@ All in all, the safest methods are to have the client program prompt for the password or to specify the password in a properly protected @file{.my.cnf} file. +@node Secure connections, , Password security, User Account Management +@subsection Using Secure Connections + +@cindex openssl +@cindex SSL and X509 Basics + +@menu +* Secure basics:: Basics +* Secure requirements:: Requirements +* Secure GRANT:: GRANT OPTIONS +@end menu + +@node Secure basics, Secure requirements, Secure connections, Secure connections +@subsubsection Basics + +MySQL has support for SSL encrypted connetions. To understand how MySQL +uses SSL we need to explain some basics about SSL and X509. People who +are already aware of it can skip this chapter. + +By default, MySQL uses unencrypted connections between client and +server. This means that anyone on the way can listen and read all your +data which moves there. Even more, some people can change content of +data while it is moving between client and server. Sometime you may need +to move really secret data over public networks and such publicity is +unacceptable. + +SSL is a protocol which uses different encryption algorithms to ensure +that data which comes from public network can be trusted. It have +mechanisms to detect any change, loss or replay of data. SSL also +incorpores algorithms to recognize and verification of identity using +X509 standard. + +@cindex What is encryption +Encryption is the way to make any kind of data unreadable. Even more, +today's practice require many additional security elements from +encryption algorithms. They should resist many kind of known attacks +like just messing with order of encrypted messages or replaying data +twice. + +@cindex What is X509/Certificate? +X509 is standard which makes possible to identity someone in the +Internet. Mostly it is used in e-commerce over the Internet. Shortly +speaking there should be some company called "Certificate Authority" +which assigns electronic certificates to everyone who +needs. Certificates rely on asymmetric encryption algorithms which have +two encryption keys - public and secret. Certificate owner can prove his +identity showing certificate to other party. Certificate consists his +owner public key. Any data encrypted with it can be decrypted only by +secret key holder. + +@cindex Possible questions: + +MySQL doesn't use encrypted on connections by default because this would +make the client/server protocol much slower. Any kind of additional +functionality requires computer to do additional work and encrypting +data is CPU-intensive operation which can overcome MySQL own work and +consumed time. By default MySQL is tuned to be fast as possible. + +If you need more information about SSL/X509/encryption, you should use +your favourite internet search engine and search for keywords you are +interested in. + +@node Secure requirements, Secure GRANT, Secure basics, Secure connections +@subsubsection Requirements + +To get secure connections to work with MySQL you must do the following: + +@enumerate +@item +Install the openssh library. We have tested MySQL with openssl 0.9.6. +@uref{http://www.openssh.org}. +@item +Configure MySQL with @code{--with-vio --with-openssl}. +@item +If you are using an old MySQL installation, you have to update your +@code{mysql.user} table with some new columns. You can do this by +running the @code{mysql_fix_privilege_tables.sh} script. +@item +You can check if a running mysqld server supports @code{openssl} by +examining if @code{show variables like 'have_openssl'} returns @code{YES}. +@end enumerate + + +@node Secure GRANT, , Secure requirements, Secure connections +@subsubsection GRANT options + +@cindex SSL related options +@findex REQUIRE GRANT option +@findex GRANT statemenet + +MySQL can check x509 certificate attributes additionally to most used +username/password cheme. All usual options are still required (username, +password, IP address mask, database/table name). + +There are different possibilities to limit connections: + +@itemize @bullet +@item +Without any SSL/X509 options all kind of encrypted/unencrypted +connections are allowed if username and password are valid. + +@item +@code{REQUIRE SSL} option makes SSL encrypted connection must. Note that +this requirement can be omitted of there are any other ACL record which +allows non-SSL connection. + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY +"goodsecret" REQUIRE SSL +@end example + +@item +@code{REQUIRE X509} Requiring X509 certificate means that client +should have valid certificate but we do not care about exact +certificate, issuer or subject. Only restriction is it should be +possible to verify its signature with some of our CA certificates. + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509 +@end example + +@item +@code{REQUIRE ISSUER issuer} makes connection more restrictive: now +client must present valid x509 certificate issued by CA "issuer". Using +x509 certificates always implies encryption, so option "SSL" is not +neccessary anymore. + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" +@end example + +@item +@code{REQUIRE SUBJECT subject} requires client to have valid x509 +certificate with subject "subject" on it. If client have valid +certificate but having different "subject" then connection is still not +allowed. + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" +@end example + +@item +@code{REQUIRE CIPHER cipher} is needed to assure enough strong ciphers +and keylengths to be used. SSL himself can be weak if old algorithms +with short encryption keys are used. Using this option we can ask for +some exact cipher to allow connection. + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA" +@end example + +Also it is allowed to combine those options with each other like this: + +@example +GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" +REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" +AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" +AND CIPHER "EDH-RSA-DES-CBC3-SHA" +@end example + +But it is not allowed to use any of options twice. Only different +options can be mixed. +@end itemize + @node Disaster Prevention, Database Administration, User Account Management, MySQL Database Administration @section Disaster Prevention and Recovery @@ -20077,10 +20145,10 @@ The default character set. The supported character sets. @item @code{concurrent_inserts} -If @code{ON} (the default), MySQL will allow you to use @code{INSERT} -on @code{MyISAM} tables at the same time as you run @code{SELECT} queries -on them. You can turn this option off by starting @code{mysqld} with @code{--safe} -or @code{--skip-new}. +If @code{ON} (the default), MySQL will allow you to use @code{INSERT} on +@code{MyISAM} tables at the same time as you run @code{SELECT} queries +on them. You can turn this option off by starting @code{mysqld} with +@code{--safe} or @code{--skip-new}. @cindex timeout @item @code{connect_timeout} @@ -39486,7 +39554,7 @@ likely it is that we can fix the problem! * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions * C Thread functions:: C Thread Functions -* C Embedded Server functions:: C Embedded Server functions. C Embedded Server Functions +* C Embedded Server functions:: C Embedded Server functions. C Embedded Server functions. C Embedded Server functions. C Embedded Server functions. C Embedded Server functions. C Embedded Server Functions * C API problems:: Common questions and problems when using the C API * Building clients:: Building Client Programs * Threaded clients:: How to Make a Threaded Client @@ -42266,7 +42334,7 @@ a stand-alone server without modifying any code. @findex @code{mysql_server_init()} -@code{void mysql_server_init(int argc, const char **argv, const char **groups)} +@code{int mysql_server_init(int argc, const char **argv, const char **groups)} @subsubheading Description @@ -42274,7 +42342,8 @@ This function @strong{must} be called once in the program before calling any other MySQL function. It starts up the server and initializes any subsystems (@code{mysys}, InnoDB, etc.) that the server uses. If this function is not called, the program will -crash. +crash. If you are using the DBUG package that comes with MySQL, +you should call this after you have called @code{MY_INIT()}. The @code{argc} and @code{argv} arguments are analogous to the arguments to @code{main()}. The first element of @code{argv} @@ -42319,7 +42388,7 @@ int main(void) @{ @subsubheading Return Values -none. +0 if ok, 1 if an error occurred. @node mysql_server_end(), , mysql_server_init(), C Embedded Server functions @subsubsection @code{mysql_server_end()} @@ -47675,6 +47744,8 @@ Removed @code{my_thread_init()} and @code{my_thread_end()} from mysql_com.h, and added @code{mysql_thread_init()} and @code{mysql_thread_end()} to mysql.h. @item +Secure connections (with SSL). +@item Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()} now handles signed and unsigned @code{BIGINT} numbers correctly. @item diff --git a/client/mysql.cc b/client/mysql.cc index 06b76ac81e9..91711752b09 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -243,7 +243,8 @@ static COMMANDS commands[] = { }; static const char *load_default_groups[]= { "mysql","client",0 }; -static const char *server_default_groups[]= { "server", "mysql_SERVER", 0 }; +static const char *server_default_groups[]= +{ "server", "embedded", "mysql_SERVER", 0 }; #ifdef HAVE_READLINE extern "C" void add_history(char *command); /* From readline directory */ @@ -271,7 +272,6 @@ int main(int argc,char *argv[]) { char buff[80]; - mysql_server_init(0, NULL, server_default_groups); MY_INIT(argv[0]); DBUG_ENTER("main"); DBUG_PROCESS(argv[0]); @@ -302,6 +302,7 @@ int main(int argc,char *argv[]) !(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin))) exit(1); glob_buffer.realloc(512); + mysql_server_init(0, NULL, server_default_groups); completion_hash_init(&ht,50); bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, @@ -368,7 +369,6 @@ int main(int argc,char *argv[]) if (opt_outfile) end_tee(); mysql_end(0); - mysql_server_end(); #ifndef _lint DBUG_RETURN(0); // Keep compiler happy #endif @@ -398,6 +398,7 @@ sig_handler mysql_end(int sig) my_free(current_db,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); my_free(current_user,MYF(MY_ALLOW_ZERO_PTR)); + mysql_server_end(); my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(status.exit_status); } diff --git a/client/mysqltest.c b/client/mysqltest.c index 9a2d3e4c137..5942843c6ce 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -306,17 +306,18 @@ static void close_cons() static void close_files() { - do + DBUG_ENTER("close_files"); + for (; cur_file != file_stack ; cur_file--) { if (*cur_file != stdin && *cur_file) my_fclose(*cur_file,MYF(0)); - } while (cur_file-- != file_stack); + } + DBUG_VOID_RETURN; } static void free_used_memory() { uint i; - DBUG_ENTER("free_used_memory"); close_cons(); close_files(); hash_free(&var_hash); @@ -336,8 +337,8 @@ static void free_used_memory() dynstr_free(&ds_res); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); + mysql_server_end(); my_end(MY_CHECK_ERROR); - DBUG_VOID_RETURN; } static void die(const char* fmt, ...) @@ -1303,15 +1304,11 @@ int read_line(char* buf, int size) { if ((*cur_file) != stdin) my_fclose(*cur_file,MYF(0)); - + cur_file--; + lineno--; if (cur_file == file_stack) return 1; - else - { - cur_file--; - lineno--; - continue; - } + continue; } switch(state) { @@ -1592,7 +1589,7 @@ int parse_args(int argc, char **argv) result_file = optarg; break; case 'x': - if (!(*cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME)))) + if (!(*++cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME)))) die("Could not open %s: errno = %d", optarg, errno); break; case 'p': @@ -1949,9 +1946,10 @@ int main(int argc, char** argv) struct st_query* q; my_bool require_file=0, q_send_flag=0; char save_file[FN_REFLEN]; - mysql_server_init(sizeof(embedded_server_args) / sizeof(char *) - 1, - embedded_server_args, embedded_server_groups); MY_INIT(argv[0]); + { + DBUG_ENTER("main"); + DBUG_PROCESS(argv[0]); save_file[0]=0; TMPDIR[0]=0; @@ -1976,9 +1974,12 @@ int main(int argc, char** argv) *block_ok = 1; init_dynamic_string(&ds_res, "", 0, 65536); parse_args(argc, argv); + if (mysql_server_init(sizeof(embedded_server_args) / sizeof(char *) - 1, + embedded_server_args, embedded_server_groups)) + die("Can't initialize MySQL server"); init_var_hash(); - if (!*cur_file) - *cur_file = stdin; + if (cur_file == file_stack) + *++cur_file = stdin; *lineno=1; if (!( mysql_init(&cur_con->mysql))) @@ -2114,10 +2115,10 @@ int main(int argc, char** argv) printf("ok\n"); } - mysql_server_end(); free_used_memory(); exit(error ? 1 : 0); - return error ? 1 : 0; /* Keep compiler happy */ + DBUG_RETURN(error ? 1 : 0); /* Keep compiler happy */ + } } diff --git a/include/my_global.h b/include/my_global.h index 7cd79b3e078..e8527e83e28 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -965,4 +965,13 @@ typedef union { #define statistic_add(V,C,L) (V)+=(C) #endif +/* Macros to make switching between C and C++ mode easier */ +#ifdef __cplusplus +#define C_MODE_START extern "C" { +#define C_MODE_END } +#else +#define C_MODE_START +#define C_MODE_END +#endif + #endif /* _global_h */ diff --git a/include/my_sys.h b/include/my_sys.h index b70d123a66a..0ab39f1146b 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -106,7 +106,8 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */ #define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */ #define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */ -#define KEYCACHE_BLOCK_SIZE 1024 +#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024 +#define MAX_KEYCACHE_BLOCK_SIZE 16384 /* root_alloc flags */ #define MY_KEEP_PREALLOC 1 @@ -190,9 +191,10 @@ extern char *get_charsets_dir(char *buf); /* statistics */ extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests, _my_cache_read; -extern ulong _my_blocks_used,_my_blocks_changed; +extern ulong _my_blocks_used,_my_blocks_changed; +extern uint key_cache_block_size; extern ulong my_file_opened,my_stream_opened, my_tmp_file_created; -extern my_bool key_cache_inited; +extern my_bool key_cache_inited, my_init_done; /* Point to current my_message() */ extern void (*my_sigtstp_cleanup)(void), @@ -602,6 +604,7 @@ my_bool my_compress(byte *, ulong *, ulong *); my_bool my_uncompress(byte *, ulong *, ulong *); byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen); ulong checksum(const byte *mem, uint count); +uint my_bit_log2(ulong value); #if defined(_MSC_VER) && !defined(__WIN__) extern void sleep(int sec); diff --git a/include/myisam.h b/include/myisam.h index 78dbfd62cbe..36c0de5034f 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -46,6 +46,11 @@ extern "C" { /* Max extra space to use when sorting keys */ #define MI_MAX_TEMP_LENGTH 256*1024L*1024L +/* Possible values for myisam_block_size (must be power of 2) */ +#define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */ +#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */ +#define MI_MAX_KEY_BLOCK_LENGTH 16384 + #define mi_portable_sizeof_char_ptr 8 typedef uint32 ha_checksum; @@ -192,7 +197,7 @@ extern uint myisam_block_size; extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; extern my_bool myisam_concurrent_insert; extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length; -extern uint myisam_bulk_insert_tree_size; +extern ulong myisam_bulk_insert_tree_size; /* Prototypes for myisam-functions */ diff --git a/include/mysql.h b/include/mysql.h index 7867dea2c31..a82a35efc4b 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -26,11 +26,9 @@ #undef __WIN__ #endif -#ifndef MYSQL_SERVER #ifdef __cplusplus extern "C" { #endif -#endif #ifndef _global_h /* If not standard header */ #include @@ -229,7 +227,7 @@ typedef struct st_mysql_res { /* Set up and bring down the server; to ensure that applications will * work when linked against either the standard client library or the * embedded server library, these functions should be called. */ -void mysql_server_init(int argc, const char **argv, const char **groups); +int mysql_server_init(int argc, const char **argv, const char **groups); void mysql_server_end(); /* Set up and bring down a thread; these function should be called @@ -382,10 +380,8 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); #define HAVE_MYSQL_REAL_CONNECT -#ifndef MYSQL_SERVER #ifdef __cplusplus } #endif -#endif -#endif +#endif /* _mysql_h */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 5924a4f13c2..c25e213f16b 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -91,10 +91,12 @@ static sig_handler pipe_sig_handler(int sig); static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); -void mysql_server_init(int argc __attribute__((unused)), +int mysql_server_init(int argc __attribute__((unused)), const char **argv __attribute__((unused)), const char **groups __attribute__((unused))) -{} +{ + return 0; +} void mysql_server_end() {} diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 1f0b15d15b6..e39cebff04a 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -39,6 +39,8 @@ libmysqlsources = errmsg.c get_password.c password.c ## XXX: we should not have to duplicate info from the sources list libmysqlobjects = errmsg.lo get_password.lo password.lo +noinst_HEADERS = embedded_priv.h + sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ ha_innobase.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \ diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h new file mode 100644 index 00000000000..96d2c96ed0b --- /dev/null +++ b/libmysqld/embedded_priv.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +/* Prototypes for the embedded version of MySQL */ + +#include +#include +#include +#include +#include +#include + +C_MODE_START +extern void start_embedded_connection(NET * net); +extern void end_embedded_connection(NET * net); +extern void lib_connection_phase(NET *net, int phase); +extern bool lib_dispatch_command(enum enum_server_command command, NET *net, + const char *arg, ulong length); +C_MODE_END diff --git a/libmysqld/examples/test-run b/libmysqld/examples/test-run index 1e15126b126..58c21349519 100755 --- a/libmysqld/examples/test-run +++ b/libmysqld/examples/test-run @@ -43,6 +43,7 @@ usage: $0 [-g|-h|-r] [test-name ...] EOF } +init_args="" while test $# -gt 0 do arg= @@ -56,6 +57,7 @@ do -h | --help | -\? ) usage; exit 0;; -l | --list ) list=1 ; shift ;; -r | --run ) run="${cr}run"; shift;; + --debug) init_args="$init_args --debug" ; shift ;; -s | --start=* ) test $argset -eq 0 && { shift; arg="$1"; } start="$arg" @@ -103,7 +105,7 @@ do echo "test '$b' doesn't exist" >&2 continue } - args="-v -S /tmp/mysql.sock -R $r -x $t test" + args="$init_args -v -S /tmp/mysql.sock -R $r -x $t test" echo "set args $args$run" > test-gdbinit #if false && test -n "$run" if test -n "$run" -o $gdb -eq 1 diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index f2599fe4016..5641e920c9d 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -12,9 +12,7 @@ * modified is included with the above copyright notice. * */ -#include "my_global.h" -#include "mysql_embed.h" -#include "my_pthread.h" +#include "embedded_priv.h" #include "sys/types.h" #include "../regex/regex.h" #include "my_sys.h" @@ -47,13 +45,11 @@ static bool check_user(THD *thd, enum_server_command command, void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);} #define free_defaults free_defaults_internal -char mysql_data_home[FN_REFLEN]; -char * get_mysql_data_home() { return mysql_data_home; } -#define mysql_data_home mysql_data_home_internal #include "../sql/mysqld.cc" #define SCRAMBLE_LENGTH 8 -extern "C" { +C_MODE_START + char * get_mysql_home(){ return mysql_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;}; @@ -85,7 +81,7 @@ void lib_connection_phase(NET * net, int phase) } } } -} /* extern "C" */ +C_MODE_END void start_embedded_conn1(NET * net) @@ -105,7 +101,6 @@ void start_embedded_conn1(NET * net) if (v) { v -> dest_thd = thd; - /* v -> dest_net = &thd->net; XXX: Probably not needed? */ } thd->net.vio = v; if (thd->store_globals()) @@ -296,10 +291,14 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, } -extern "C"{ -void mysql_server_init(int argc, const char **argv, const char **groups) +extern "C" { - char hostname[FN_REFLEN]; + +static my_bool inited, org_my_init_done; + +int mysql_server_init(int argc, const char **argv, const char **groups) +{ + char glob_hostname[FN_REFLEN]; /* This mess is to allow people to call the init function without * having to mess with a fake argv */ @@ -323,7 +322,16 @@ void mysql_server_init(int argc, const char **argv, const char **groups) my_umask=0660; // Default umask for new files my_umask_dir=0700; // Default umask for new directories - MY_INIT((char *)"mysqld_server"); // init my_sys library & pthreads + + /* Only call MY_INIT() if it hasn't been called before */ + if (!inited) + { + inited=1; + org_my_init_done=my_init_done; + } + if (!org_my_init_done) + MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads + tzset(); // Set tzname start_time=time((time_t*) 0); @@ -332,49 +340,34 @@ void mysql_server_init(int argc, const char **argv, const char **groups) { struct tm tm_tmp; localtime_r(&start_time,&tm_tmp); - strmov(time_zone,tzname[tm_tmp.tm_isdst == 1 ? 1 : 0]); + strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]); } #else { struct tm *start_tm; start_tm=localtime(&start_time); - strmov(time_zone=tzname[start_tm->tm_isdst == 1 ? 1 : 0]); + strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]); } #endif #endif - if (gethostname(hostname,sizeof(hostname)-4) < 0) - strmov(hostname,"mysql"); - strmov(pidfile_name,hostname); - strmov(strcend(pidfile_name,'.'),".pid"); // Add extension -#ifdef DEMO_VERSION - strcat(server_version,"-demo"); -#endif -#ifdef SHAREWARE_VERSION - strcat(server_version,"-shareware"); -#endif + if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) + strmov(glob_hostname,"mysql"); #ifndef DBUG_OFF strcat(server_version,"-debug"); #endif - strcat(server_version,"-library-ver"); -#ifdef _CUSTOMSTARTUPCONFIG_ - if (_cust_check_startup()) - { - /* _cust_check_startup will report startup failure error */ - exit( 1 ); - } -#endif + strcat(server_version,"-embedded"); load_defaults("my", groups, argcp, argvp); defaults_argv=*argvp; mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ -#ifdef __WIN__ +#if defined( __WIN__) || defined(OS2) if (!mysql_tmpdir) mysql_tmpdir=getenv("TEMP"); if (!mysql_tmpdir) mysql_tmpdir=getenv("TMP"); #endif if (!mysql_tmpdir || !mysql_tmpdir[0]) - mysql_tmpdir=strdup((char*) P_tmpdir); + mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ set_options(); get_options(*argcp, *argvp); @@ -415,23 +408,20 @@ void mysql_server_init(int argc, const char **argv, const char **groups) (void) pthread_cond_init(&COND_slave_start, NULL); if (set_default_charset_by_name(default_charset, MYF(MY_WME))) - unireg_abort(1); + { + mysql_server_end(); + return 1; + } charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); - - if (!(opt_specialflag & SPECIAL_NO_PRIOR)) - my_pthread_setprio(pthread_self(),CONNECT_PRIOR); /* Parameter for threads created for connections */ (void) pthread_attr_init(&connection_attrib); (void) pthread_attr_setdetachstate(&connection_attrib, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&connection_attrib,thread_stack); - - if (!(opt_specialflag & SPECIAL_NO_PRIOR)) - my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR); pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); -#ifdef SET_RLIMIT_NOFILE +#if defined( SET_RLIMIT_NOFILE) || defined( OS2) /* connections and databases neads lots of files */ { uint wanted_files=10+(uint) max(max_connections*5, @@ -456,64 +446,57 @@ void mysql_server_init(int argc, const char **argv, const char **groups) #ifdef USE_REGEX regex_init(); #endif - select_thread=pthread_self(); - select_thread_in_use=1; + if (use_temp_pool && bitmap_init(&temp_pool,1024)) + { + mysql_server_end(); + return 1; + } /* ** We have enough space for fiddling with the argv, continue */ umask(((~my_umask) & 0666)); -// strcpy(mysql_real_data_home, "/usr/local"); - //if (my_setwd(mysql_real_data_home,MYF(MY_WME))) - //{ - // unireg_abort(1); /* purecov: inspected */ - //} - //mysql_data_home[0]=FN_CURLIB; // all paths are relative from here - //mysql_data_home[1]=0; - - strcpy(get_mysql_data_home(), mysql_real_data_home); - - //server_init(); table_cache_init(); hostname_cache_init(); sql_cache_init(); randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2); reset_floating_point_exceptions(); init_thr_lock(); + init_slave_list(); /* Setup log files */ if (opt_log) - open_log(&mysql_log, hostname, opt_logname, ".log", LOG_NORMAL); + open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); if (opt_update_log) - open_log(&mysql_update_log, hostname, opt_update_logname, "", + { + open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", LOG_NEW); + using_update_log=1; + } if (opt_bin_log) { - if(server_id) - { - if (!opt_bin_logname) - { - char tmp[FN_REFLEN]; - strnmov(tmp,hostname,FN_REFLEN-5); - strmov(strcend(tmp,'.'),"-bin"); - opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); - } - mysql_bin_log.set_index_file_name(opt_binlog_index_name); - open_log(&mysql_bin_log, hostname, opt_bin_logname, "-bin", - LOG_BIN); - } - else - sql_print_error("Server id is not set - binary logging disabled"); + if (!opt_bin_logname) + { + char tmp[FN_REFLEN]; + strmake(tmp,glob_hostname,FN_REFLEN-5); + strmov(strcend(tmp,'.'),"-bin"); + opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); + } + mysql_bin_log.set_index_file_name(opt_binlog_index_name); + open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", + LOG_BIN); + using_update_log=1; } if (opt_slow_log) - open_log(&mysql_slow_log, hostname, opt_slow_logname, "-slow.log", + open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", LOG_NORMAL); if (ha_init()) { sql_print_error("Can't init databases"); exit(1); } + ha_key_cache(); #ifdef HAVE_MLOCKALL if (locked_in_memory && !geteuid()) { @@ -544,105 +527,61 @@ void mysql_server_init(int argc, const char **argv, const char **groups) sql_print_error("Can't create thread-keys"); exit(1); } - //init_signals(); - opt_noacl = 1; + opt_noacl = 1; // No permissions if (acl_init(opt_noacl)) { - select_thread_in_use=0; - (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); - exit(1); + mysql_server_end(); + return 1; } - if (!opt_noacl) - (void) grant_init(); #ifdef HAVE_DLOPEN if (!opt_noacl) udf_init(); #endif - if (opt_bootstrap) - { - int error=bootstrap(stdin); - end_thr_alarm(); // Don't allow alarms - unireg_abort(error ? 1 : 0); - } - if (opt_init_file) - { - if (read_init_file(opt_init_file)) - { - end_thr_alarm(); // Don't allow alarms - unireg_abort(1); - } - } (void) thr_setconcurrency(concurrency); // 10 by default - if (flush_time && flush_time != ~(ulong) 0L) + if ( +#ifdef HAVE_BERKELEY_DB + !berkeley_skip || +#endif + (flush_time && flush_time != ~(ulong) 0L)) { pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) + { sql_print_error("Warning: Can't create thread to manage maintenance"); + mysql_server_end(); + return 1; + } } - - // slave thread - if(master_host) - { - if(server_id) - { - pthread_t hThread; - if(!opt_skip_slave_start && - pthread_create(&hThread, &connection_attrib, handle_slave, 0)) - sql_print_error("Warning: Can't create thread to handle slave"); - } - else - sql_print_error("Server id is not set, slave thread will not be started"); - } - - //printf(ER(ER_READY),my_progname,server_version,""); - //printf("%s initialized.\n", server_version); - fflush(stdout); + return 0; } + void mysql_server_end() { - /* (void) pthread_attr_destroy(&connection_attrib); */ - - DBUG_PRINT("quit",("Exiting main thread")); - -#ifdef EXTRA_DEBUG - sql_print_error("Before Lock_thread_count"); + clean_up(0); +#ifdef THREAD + /* Don't call my_thread_end() if the application is using MY_INIT() */ + if (!org_my_init_done) + my_thread_end(); #endif - (void) pthread_mutex_lock(&LOCK_thread_count); - select_thread_in_use=0; // For close_connections - (void) pthread_cond_broadcast(&COND_thread_count); - (void) pthread_mutex_unlock(&LOCK_thread_count); -#ifdef EXTRA_DEBUG - sql_print_error("After lock_thread_count"); -#endif - -// /* Wait until cleanup is done */ -// (void) pthread_mutex_lock(&LOCK_thread_count); -// while (!ready_to_exit) -// { -// pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); -// } -// (void) pthread_mutex_unlock(&LOCK_thread_count); - unireg_end(0); - my_thread_end(); } my_bool mysql_thread_init() { #ifdef THREAD - return my_thread_init(); + return my_thread_init(); #else - return 0; + return 0; #endif } void mysql_thread_end() { #ifdef THREAD - my_thread_end(); + my_thread_end(); #endif } @@ -651,11 +590,10 @@ void start_embedded_connection(NET * net) start_embedded_conn1(net); } -} /* extern "C" */ - -int embedded_do_command(NET * net) +void end_embedded_connection(NET * net) { - THD * thd = (THD *) net ->vio; - do_command(thd); - return 0; + THD *thd = (THD *) net->vio->dest_thd; + delete thd; } + +} /* extern "C" */ diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 8931bc3cd48..c6860098ed8 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -15,15 +15,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#if defined(__WIN__) || defined(_WIN32) || defined(_WIN64) -#include -#include -#endif -#include "mysql_embed.h" -#include "mysql.h" -#include "mysql_version.h" -#include "mysqld_error.h" +#include "embedded_priv.h" #include #include #include @@ -51,9 +43,6 @@ #ifdef HAVE_SYS_UN_H # include #endif -#if defined(THREAD) && !defined(__WIN__) -#include /* because of signal() */ -#endif #ifndef INADDR_NONE #define INADDR_NONE -1 #endif @@ -74,12 +63,6 @@ my_string mysql_unix_port=0; #define closesocket(A) close(A) #endif -/* XXX: this is real ugly... */ -extern void start_embedded_connection(NET * net); -extern void lib_connection_phase(NET *net, int phase); -extern bool lib_dispatch_command(enum enum_server_command command, NET *net, - const char *arg, ulong length); - static void mysql_once_init(void); static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, uint field_count); @@ -89,7 +72,6 @@ static void end_server(MYSQL *mysql); static void read_user_name(char *name); static void append_wild(char *to,char *end,const char *wild); static int send_file_to_server(MYSQL *mysql,const char *filename); -static sig_handler pipe_sig_handler(int sig); static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); @@ -402,22 +384,6 @@ mysql_debug(const char *debug) #endif } - -/************************************************************************** -** Close the server connection if we get a SIGPIPE - ARGSUSED -**************************************************************************/ - -static sig_handler -pipe_sig_handler(int sig __attribute__((unused))) -{ - DBUG_PRINT("info",("Hit by signal %d",sig)); -#ifdef DONT_REMEMBER_SIGNAL - (void) signal(SIGPIPE,pipe_sig_handler); -#endif -} - - /************************************************************************** ** Shut down connection **************************************************************************/ @@ -428,11 +394,7 @@ end_server(MYSQL *mysql) DBUG_ENTER("end_server"); if (mysql->net.vio != 0) { - init_sigpipe_variables - DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio))); - set_sigpipe(mysql); - vio_delete(mysql->net.vio); - reset_sigpipe(mysql); + end_embedded_connection(&mysql->net); mysql->net.vio= 0; /* Marker */ } net_end(&mysql->net); diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index ef248b5d62b..8f3138af989 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -173,7 +173,7 @@ int do_boolean(ALL_IN_ONE *aio, uint nested __attribute__((unused)), aio->key_root); else r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey, - aio->info->lastkey_length, SEARCH_BIGGER, + USE_WHOLE_KEY, SEARCH_BIGGER, aio->key_root); } break; diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index 350a60708f6..644becb27ab 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -126,7 +126,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) aio->key_root); else r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey, - aio->info->lastkey_length, SEARCH_BIGGER, + USE_WHOLE_KEY, SEARCH_BIGGER, aio->key_root); } if(doc_cnt) { diff --git a/myisam/ft_search.c b/myisam/ft_search.c index c5a43734d9a..6970fa2835d 100644 --- a/myisam/ft_search.c +++ b/myisam/ft_search.c @@ -34,7 +34,7 @@ FT_DOCLIST *ft_init_search(void *info, uint keynr, byte *query, /* black magic ON */ if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0) return NULL; - if (_mi_readinfo((MI_INFO *)info,F_RDLCK,1)) + if (fast_mi_readinfo((MI_INFO *) info)) return NULL; /* black magic OFF */ diff --git a/myisam/mi_changed.c b/myisam/mi_changed.c index bd6b14b0c6c..5b9003798b0 100644 --- a/myisam/mi_changed.c +++ b/myisam/mi_changed.c @@ -24,7 +24,7 @@ int mi_is_changed(MI_INFO *info) { int result; DBUG_ENTER("mi_is_changed"); - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(-1); VOID(_mi_writeinfo(info,0)); result=(int) info->data_changed; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 4ea52c1b565..656e6aa995f 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -231,7 +231,7 @@ wrong: static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr) { my_off_t next_link; - uint block_size=(nr+1)*MI_KEY_BLOCK_LENGTH; + uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH; ha_rows records; char llbuff[21],*buff; DBUG_ENTER("check_k_link"); @@ -1205,8 +1205,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, param->glob_crc=0; if (param->testflag & T_CALC_CHECKSUM) param->calc_checksum=1; - if (!rep_quick) - share->state.checksum=0; info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); for (i=0 ; i < info->s->base.keys ; i++) @@ -1301,9 +1299,9 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, else { info->state->data_file_length=sort_info->max_pos; - if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; } + if (param->testflag & T_CALC_CHECKSUM) + share->state.checksum=param->glob_crc; if (!(param->testflag & T_SILENT)) { @@ -1886,8 +1884,6 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, param->glob_crc=0; if (param->testflag & T_CALC_CHECKSUM) param->calc_checksum=1; - if (! rep_quick) - share->state.checksum=0; rec_per_key_part= param->rec_per_key_part; for (sort_info->key=0 ; sort_info->key < share->base.keys ; @@ -2018,7 +2014,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, "Can't change size of datafile, error: %d", my_errno); } - else if (param->testflag & T_CALC_CHECKSUM) + if (param->testflag & T_CALC_CHECKSUM) share->state.checksum=param->glob_crc; if (my_chsize(share->kfile,info->state->key_file_length,MYF(0))) @@ -2115,6 +2111,7 @@ static int sort_key_read(SORT_INFO *sort_info, void *key) DBUG_RETURN(sort_write_record(sort_info)); } /* sort_key_read */ + static int sort_ft_key_read(SORT_INFO *sort_info, void *key) { int error; @@ -2540,7 +2537,7 @@ int sort_write_record(SORT_INFO *sort_info) DBUG_RETURN(1); } sort_info->filepos+=share->base.pack_reclength; - info->s->state.checksum+=mi_static_checksum(info, sort_info->record); + /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */ break; case DYNAMIC_RECORD: if (! info->blobs) @@ -2564,7 +2561,7 @@ int sort_write_record(SORT_INFO *sort_info) } info->checksum=mi_checksum(info,sort_info->record); reclength=_mi_rec_pack(info,from,sort_info->record); - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ block_length=reclength+ 3 + test(reclength >= (65520-3)); if (block_length < share->base.min_block_length) block_length=share->base.min_block_length; @@ -2578,7 +2575,7 @@ int sort_write_record(SORT_INFO *sort_info) DBUG_RETURN(1); } sort_info->filepos+=block_length; - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ break; case COMPRESSED_RECORD: reclength=info->packed_length; @@ -2591,7 +2588,7 @@ int sort_write_record(SORT_INFO *sort_info) mi_check_print_error(param,"%d when writing to datafile",my_errno); DBUG_RETURN(1); } - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ sort_info->filepos+=reclength+length; break; } @@ -2808,9 +2805,9 @@ static int sort_delete_record(MI_CHECK *param) DBUG_RETURN(1); } } - if (info->s->calc_checksum) - info->s->state.checksum-=(*info->s->calc_checksum)(info, - sort_info->record); + if (param->calc_checksum) + param->glob_crc-=(*info->s->calc_checksum)(info, + sort_info->record); } error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info); info->dfile=old_file; /* restore actual value */ diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 7033cd59639..aad0300c978 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -227,8 +227,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, share.state.key_del=key_del; if (uniques) { - max_key_block_length= MI_KEY_BLOCK_LENGTH; - max_key_length= MI_UNIQUE_HASH_LENGTH; + max_key_block_length= myisam_block_size; + max_key_length= MI_UNIQUE_HASH_LENGTH; } for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++) @@ -370,7 +370,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, share.state.rec_per_key_part[key_segs-1]=1L; length+=key_length; keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE); - if (keydef->block_length/MI_KEY_BLOCK_LENGTH > MI_MAX_KEY_BLOCK_SIZE) + if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH) { my_errno=HA_WRONG_CREATE_OPTION; goto err; @@ -386,7 +386,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, (length*2)))* (ulong) keydef->block_length; } - for (i=max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; ) + for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) key_del[i]=HA_OFFSET_ERROR; unique_key_parts=0; @@ -401,7 +401,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_segs+=uniques; /* Each unique has 1 key seg */ base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE + - max_key_block_length/MI_KEY_BLOCK_LENGTH*MI_STATE_KEYBLOCK_SIZE+ + max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH* + MI_STATE_KEYBLOCK_SIZE+ key_segs*MI_STATE_KEYSEG_SIZE); info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+ keys * MI_KEYDEF_SIZE+ @@ -420,7 +421,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, mi_int2store(share.state.header.base_pos,base_pos); share.state.header.language= (ci->language ? ci->language : MY_CHARSET_CURRENT); - share.state.header.max_block_size=max_key_block_length/MI_KEY_BLOCK_LENGTH; + share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; share.state.dellink = HA_OFFSET_ERROR; share.state.process= (ulong) getpid(); @@ -433,7 +434,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, share.base.rec_reflength=pointer; share.base.key_reflength= mi_get_pointer_length((tot_length + max_key_block_length * keys * - MI_INDEX_BLOCK_MARGIN) / MI_KEY_BLOCK_LENGTH, + MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH, 3); share.base.keys= share.state.header.keys = keys; share.state.header.uniques= uniques; @@ -575,7 +576,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { tmp_keydef.keysegs=1; tmp_keydef.flag= HA_UNIQUE_CHECK; - tmp_keydef.block_length= MI_KEY_BLOCK_LENGTH; + tmp_keydef.block_length= myisam_block_size; tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer; tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; tmp_keyseg.type= MI_UNIQUE_HASH_TYPE; diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index 445e745b07d..65d245e64f9 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -196,7 +196,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, DBUG_ENTER("d_search"); DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff)); - flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,key_length,SEARCH_SAME, + flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, USE_WHOLE_KEY, + SEARCH_SAME, &keypos, lastkey, &last_key); if (flag == MI_FOUND_WRONG_KEY) { diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c index 2c506da865f..6467246e779 100644 --- a/myisam/mi_delete_all.c +++ b/myisam/mi_delete_all.c @@ -43,7 +43,7 @@ int mi_delete_all_rows(MI_INFO *info) info->state->empty=info->state->key_empty=0; state->checksum=0; - for (i=share->base.max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; ) + for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) state->key_del[i]= HA_OFFSET_ERROR; for (i=0 ; i < share->base.keys ; i++) state->key_root[i]= HA_OFFSET_ERROR; diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index c9fe493744d..c07fa5aa080 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -1059,11 +1059,11 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) } while (left_length); info->update|= HA_STATE_AKTIV; /* We have a aktive record */ - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) != MY_FILE_ERROR ? 0 : -1); } - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); DBUG_RETURN(-1); /* Wrong data to read */ panic: @@ -1393,8 +1393,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, } while (left_len); info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; - if (share->r_locks == 0 && share->w_locks == 0) - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) != MY_FILE_ERROR) DBUG_RETURN(0); diff --git a/myisam/mi_info.c b/myisam/mi_info.c index 867718de326..c55707ea00c 100644 --- a/myisam/mi_info.c +++ b/myisam/mi_info.c @@ -45,7 +45,7 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag) { pthread_mutex_lock(&share->intern_lock); VOID(_mi_readinfo(info,F_RDLCK,0)); - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); pthread_mutex_unlock(&share->intern_lock); } if (flag & HA_STATUS_VARIABLE) diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 9f4e2cb1524..67772c250ac 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -346,7 +346,7 @@ err: int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf) { - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); if (filepos != HA_OFFSET_ERROR) { if (info->lastinx >= 0) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 8ef5db1d344..b8ffc300fa9 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -50,6 +50,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) count= --share->r_locks; else count= --share->w_locks; + --share->tot_locks; if (info->lock_type == F_WRLCK && !share->w_locks && !share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP)) { @@ -153,6 +154,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) } VOID(_mi_test_if_changed(info)); share->r_locks++; + share->tot_locks++; info->lock_type=lock_type; break; case F_WRLCK: @@ -200,6 +202,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) VOID(_mi_test_if_changed(info)); info->lock_type=lock_type; share->w_locks++; + share->tot_locks++; break; default: break; /* Impossible */ @@ -295,13 +298,12 @@ my_bool mi_check_status(void* param) int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer) { - MYISAM_SHARE *share; DBUG_ENTER("_mi_readinfo"); - share=info->s; if (info->lock_type == F_UNLCK) { - if (!share->r_locks && !share->w_locks) + MYISAM_SHARE *share=info->s; + if (!share->tot_locks) { if ((info->tmp_lock_type=lock_type) != F_RDLCK) if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, @@ -339,7 +341,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation) DBUG_ENTER("_mi_writeinfo"); error=0; - if (share->r_locks == 0 && share->w_locks == 0) + if (share->tot_locks == 0) { olderror=my_errno; /* Remember last error */ if (operation) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index c34f2aa43f4..675dac38d41 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -217,7 +217,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (mi_safe_mul(share->base.reclength, (ulonglong) 1 << (share->base.rec_reflength*8))-1); max_key_file_length= - mi_safe_mul(MI_KEY_BLOCK_LENGTH, + mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH, ((ulonglong) 1 << (share->base.key_reflength*8))-1); #if SIZEOF_OFF_T == 4 set_if_smaller(max_data_file_length, INT_MAX32); @@ -913,7 +913,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) keydef->keylength = mi_uint2korr(ptr); ptr +=2; keydef->minlength = mi_uint2korr(ptr); ptr +=2; keydef->maxlength = mi_uint2korr(ptr); ptr +=2; - keydef->block_size = keydef->block_length/MI_KEY_BLOCK_LENGTH-1; + keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1; keydef->underflow_block_length=keydef->block_length/3; keydef->version = 0; /* Not saved */ return ptr; diff --git a/myisam/mi_page.c b/myisam/mi_page.c index f8e2a977754..d62970c7d98 100644 --- a/myisam/mi_page.c +++ b/myisam/mi_page.c @@ -64,9 +64,9 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, #ifndef FAST /* Safety check */ if (page < info->s->base.keystart || page+keyinfo->block_length > info->state->key_file_length || - page & (myisam_block_size-1)) + (page & (MI_MIN_KEY_BLOCK_LENGTH-1))) { - DBUG_PRINT("error",("Trying to write outside key region: %lu", + DBUG_PRINT("error",("Trying to write inside key status region: %lu", (long) page)); my_errno=EINVAL; return(-1); diff --git a/myisam/mi_range.c b/myisam/mi_range.c index 038f9abc3a6..6bf3356e449 100644 --- a/myisam/mi_range.c +++ b/myisam/mi_range.c @@ -45,7 +45,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key, if ((inx = _mi_check_index(info,inx)) < 0) DBUG_RETURN(HA_POS_ERROR); - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(HA_POS_ERROR); info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED); if (info->s->concurrent_insert) @@ -58,7 +58,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key, info->state->records+ (ha_rows) 1); if (info->s->concurrent_insert) rw_unlock(&info->s->key_root_lock[inx]); - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) DBUG_RETURN(HA_POS_ERROR); DBUG_PRINT("info",("records: %ld",(ulong) (end_pos-start_pos))); @@ -72,7 +72,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key, static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len, enum ha_rkey_function search_flag) { - uint inx=(uint) info->lastinx; + uint inx=(uint) info->lastinx, nextflag; MI_KEYDEF *keyinfo=info->s->keyinfo+inx; uchar *key_buff; double pos; @@ -86,8 +86,12 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len, key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len); DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg, (uchar*) key_buff,key_len);); + nextflag=myisam_read_vec[search_flag]; + if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) + key_len=USE_WHOLE_KEY; + pos=_mi_search_pos(info,keyinfo,key_buff,key_len, - myisam_read_vec[search_flag] | SEARCH_SAVE_BUFF, + nextflag | SEARCH_SAVE_BUFF, info->s->state.key_root[inx]); if (pos >= 0.0) { @@ -145,9 +149,9 @@ static double _mi_search_pos(register MI_INFO *info, ** Matches keynr+1 */ offset=1.0; /* Matches keynr+1 */ - if (nextflag & SEARCH_FIND && + if ((nextflag & SEARCH_FIND) && nod_flag && ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME || - key_len) && nod_flag) + key_len != USE_WHOLE_KEY)) { /* ** There may be identical keys in the tree. Try to match on of those. diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c index 0df390412b9..86547d3ef04 100644 --- a/myisam/mi_rkey.c +++ b/myisam/mi_rkey.c @@ -27,7 +27,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, { uchar *key_buff; MYISAM_SHARE *share=info->s; - uint pack_key_length; + uint pack_key_length, use_key_length, nextflag; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d", info,inx,search_flag)); @@ -55,11 +55,17 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, bmove(key_buff,key,key_len); } - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) goto err; if (share->concurrent_insert) rw_rdlock(&share->key_root_lock[inx]); - if (!_mi_search(info,info->s->keyinfo+inx,key_buff,pack_key_length, + + nextflag=myisam_read_vec[search_flag]; + use_key_length=pack_key_length; + if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) + use_key_length=USE_WHOLE_KEY; + + if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length, myisam_read_vec[search_flag],info->s->state.key_root[inx])) { while (info->lastpos >= info->state->data_file_length) diff --git a/myisam/mi_rnext.c b/myisam/mi_rnext.c index f297740af60..6d135462f96 100644 --- a/myisam/mi_rnext.c +++ b/myisam/mi_rnext.c @@ -35,7 +35,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx) if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND) flag=0; /* Read first */ - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(my_errno); if (info->s->concurrent_insert) rw_rdlock(&info->s->key_root_lock[inx]); @@ -51,7 +51,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx) info->s->state.key_root[inx]); else error=_mi_search(info,info->s->keyinfo+inx,info->lastkey, - info->lastkey_length,flag, info->s->state.key_root[inx]); + USE_WHOLE_KEY,flag, info->s->state.key_root[inx]); if (!error) { diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c index 0e172894cdf..44943ea9137 100644 --- a/myisam/mi_rnext_same.c +++ b/myisam/mi_rnext_same.c @@ -35,7 +35,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); keyinfo=info->s->keyinfo+inx; flag=SEARCH_BIGGER; /* Read next */ - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(my_errno); memcpy(info->lastkey2,info->lastkey,info->last_rkey_length); diff --git a/myisam/mi_rprev.c b/myisam/mi_rprev.c index fff2d2257b6..4807e636252 100644 --- a/myisam/mi_rprev.c +++ b/myisam/mi_rprev.c @@ -36,7 +36,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx) if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND) flag=0; /* Read last */ - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(my_errno); changed=_mi_test_if_changed(info); if (share->concurrent_insert) @@ -50,7 +50,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx) share->state.key_root[inx]); else error=_mi_search(info,share->keyinfo+inx,info->lastkey, - info->lastkey_length, flag, share->state.key_root[inx]); + USE_WHOLE_KEY, flag, share->state.key_root[inx]); if (!error) { diff --git a/myisam/mi_rsame.c b/myisam/mi_rsame.c index a4092b53c0b..511c247760e 100644 --- a/myisam/mi_rsame.c +++ b/myisam/mi_rsame.c @@ -41,7 +41,7 @@ int mi_rsame(MI_INFO *info, byte *record, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); /* Read row from data file */ - if (_mi_readinfo(info,F_RDLCK,1)) + if (fast_mi_readinfo(info)) DBUG_RETURN(my_errno); if (inx >= 0) @@ -51,7 +51,8 @@ int mi_rsame(MI_INFO *info, byte *record, int inx) info->lastpos); if (info->s->concurrent_insert) rw_rdlock(&info->s->key_root_lock[inx]); - VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey,0,SEARCH_SAME, + VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY, + SEARCH_SAME, info->s->state.key_root[inx])); if (info->s->concurrent_insert) rw_unlock(&info->s->key_root_lock[inx]); diff --git a/myisam/mi_search.c b/myisam/mi_search.c index b9895e9d6cd..96ddd9d789d 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -107,14 +107,15 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, } else { - if (nextflag & SEARCH_FIND && (!(keyinfo->flag & HA_NOSAME) - || key_len) && nod_flag) + if ((nextflag & SEARCH_FIND) && nod_flag && + ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME || + key_len != USE_WHOLE_KEY)) { if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND, _mi_kpos(nod_flag,keypos))) >= 0 || my_errno != HA_ERR_KEY_NOT_FOUND) DBUG_RETURN(error); - info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */ + info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */ } } if (pos != info->last_keypage) @@ -283,8 +284,6 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, LINT_INIT(saved_vseg); t_buff[0]=0; /* Avoid bugs */ - if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) - key_len=USE_WHOLE_KEY; end= page+mi_getint(page); nod_flag=mi_test_if_nod(page); page+=2+nod_flag; @@ -477,11 +476,11 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key) switch (nod_flag) { #if SIZEOF_OFF_T > 4 case 7: - return mi_uint7korr(after_key)*MI_KEY_BLOCK_LENGTH; + return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; case 6: - return mi_uint6korr(after_key)*MI_KEY_BLOCK_LENGTH; + return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; case 5: - return mi_uint5korr(after_key)*MI_KEY_BLOCK_LENGTH; + return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH; #else case 7: after_key++; @@ -491,13 +490,13 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key) after_key++; #endif case 4: - return ((my_off_t) mi_uint4korr(after_key))*MI_KEY_BLOCK_LENGTH; + return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH; case 3: - return ((my_off_t) mi_uint3korr(after_key))*MI_KEY_BLOCK_LENGTH; + return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH; case 2: - return (my_off_t) (mi_uint2korr(after_key)*MI_KEY_BLOCK_LENGTH); + return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH); case 1: - return (uint) (*after_key)*MI_KEY_BLOCK_LENGTH; + return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH; case 0: /* At leaf page */ default: /* Impossible */ return(HA_OFFSET_ERROR); @@ -509,7 +508,7 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key) void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos) { - pos/=MI_KEY_BLOCK_LENGTH; + pos/=MI_MIN_KEY_BLOCK_LENGTH; switch (info->s->base.key_reflength) { #if SIZEOF_OFF_T > 4 case 7: mi_int7store(buff,pos); break; @@ -719,10 +718,7 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, double d_1,d_2; uint next_key_length; - if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST))) - key_length=USE_WHOLE_KEY; *diff_pos=0; - for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) { uchar *end; @@ -1446,7 +1442,7 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo, info->page_changed || (info->int_keytree_version != keyinfo->version && (info->int_nod_flag || info->buff_used))) - DBUG_RETURN(_mi_search(info,keyinfo,key,key_length, + DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY, nextflag | SEARCH_SAVE_BUFF, pos)); if (info->buff_used) @@ -1459,17 +1455,17 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo, /* Last used buffer is in info->buff */ nod_flag=mi_test_if_nod(info->buff); - memcpy(lastkey,key,key_length); if (nextflag & SEARCH_BIGGER) /* Next key */ { my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos); if (tmp_pos != HA_OFFSET_ERROR) { - if ((error=_mi_search(info,keyinfo,key,key_length, + if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY, nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0) DBUG_RETURN(error); } + memcpy(lastkey,key,key_length); if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag, &info->int_keypos,lastkey))) DBUG_RETURN(-1); @@ -1483,12 +1479,14 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo, if (!info->int_keypos) DBUG_RETURN(-1); if (info->int_keypos == info->buff+2) - DBUG_RETURN(_mi_search(info,keyinfo,key,key_length, + DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY, nextflag | SEARCH_SAVE_BUFF, pos)); - if ((error=_mi_search(info,keyinfo,key,0,nextflag | SEARCH_SAVE_BUFF, + if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY, + nextflag | SEARCH_SAVE_BUFF, _mi_kpos(nod_flag,info->int_keypos))) <= 0) DBUG_RETURN(error); + /* QQ: We should be able to optimize away the following call */ if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey, info->int_keypos,&info->lastkey_length)) DBUG_RETURN(-1); diff --git a/myisam/mi_static.c b/myisam/mi_static.c index 389aac3142a..43e21340f5f 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -40,7 +40,7 @@ my_bool myisam_concurrent_insert=0; #endif my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH; my_off_t myisam_max_temp_length= MAX_FILE_SIZE; -uint myisam_bulk_insert_tree_size=8192*1024; +ulong myisam_bulk_insert_tree_size=8192*1024; /* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ */ /* Position is , == , >= , <= , > , < */ diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c index e0fce6d3e1c..2712c125f4e 100644 --- a/myisam/mi_statrec.c +++ b/myisam/mi_statrec.c @@ -181,8 +181,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos, error=my_pread(info->dfile,(char*) record,info->s->base.reclength, pos,MYF(MY_NABP)) != 0; - if (info->s->r_locks == 0 && info->s->w_locks == 0) - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); if (! error) { if (!*record) @@ -195,7 +194,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos, } return(-1); /* Error on read */ } - VOID(_mi_writeinfo(info,0)); /* No such record */ + fast_mi_writeinfo(info); /* No such record */ return(-1); } @@ -257,7 +256,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf, DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld", filepos/share->base.reclength,filepos, info->state->records, info->state->del)); - VOID(_mi_writeinfo(info,0)); + fast_mi_writeinfo(info); DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE); } info->lastpos= filepos; diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c index b66b02afdf9..cb60aeb8618 100644 --- a/myisam/mi_test2.c +++ b/myisam/mi_test2.c @@ -343,68 +343,72 @@ int main(int argc, char *argv[]) } if (testflag==3) goto end; - if (!silent) - printf("- Same key: first - next -> last - prev -> first\n"); - DBUG_PRINT("progpos",("first - next -> last - prev -> first")); for (i=999, dupp_keys=j=0 ; i>0 ; i--) { - if (key1[i] >dupp_keys) { dupp_keys=key1[i]; j=i; } + if (key1[i] > dupp_keys) { dupp_keys=key1[i]; j=i; } } sprintf(key,"%6d",j); - if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys); - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err; - if (mi_rsame(file,read_record2,-1)) goto err; - if (memcmp(read_record,read_record2,reclength) != 0) + if (dupp_keys) { - printf("mi_rsame didn't find same record\n"); - goto end; - } - info.recpos=mi_position(file); - if (mi_rfirst(file,read_record2,0) || - mi_rsame_with_pos(file,read_record2,0,info.recpos) || - memcmp(read_record,read_record2,reclength) != 0) - { - printf("mi_rsame_with_pos didn't find same record\n"); - goto end; - } - { - int skr=mi_rnext(file,read_record2,0); - if ((skr && my_errno != HA_ERR_END_OF_FILE) || - mi_rprev(file,read_record2,-1) || - memcmp(read_record,read_record2,reclength) != 0) + if (!silent) + printf("- Same key: first - next -> last - prev -> first\n"); + DBUG_PRINT("progpos",("first - next -> last - prev -> first")); + if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys); + + if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err; + if (mi_rsame(file,read_record2,-1)) goto err; + if (memcmp(read_record,read_record2,reclength) != 0) { - printf("mi_rsame_with_pos lost position\n"); + printf("mi_rsame didn't find same record\n"); + goto end; + } + info.recpos=mi_position(file); + if (mi_rfirst(file,read_record2,0) || + mi_rsame_with_pos(file,read_record2,0,info.recpos) || + memcmp(read_record,read_record2,reclength) != 0) + { + printf("mi_rsame_with_pos didn't find same record\n"); + goto end; + } + { + int skr=mi_rnext(file,read_record2,0); + if ((skr && my_errno != HA_ERR_END_OF_FILE) || + mi_rprev(file,read_record2,-1) || + memcmp(read_record,read_record2,reclength) != 0) + { + printf("mi_rsame_with_pos lost position\n"); + goto end; + } + } + ant=1; + start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length; + while (mi_rnext(file,read_record2,0) == 0 && + memcmp(read_record2+start,key,length) == 0) ant++; + if (ant != dupp_keys) + { + printf("next: Found: %d keys of %d\n",ant,dupp_keys); + goto end; + } + ant=0; + while (mi_rprev(file,read_record3,0) == 0 && + bcmp(read_record3+start,key,length) == 0) ant++; + if (ant != dupp_keys) + { + printf("prev: Found: %d records of %d\n",ant,dupp_keys); goto end; } - } - ant=1; - start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length; - while (mi_rnext(file,read_record2,0) == 0 && - memcmp(read_record2+start,key,length) == 0) ant++; - if (ant != dupp_keys) - { - printf("next: Found: %d keys of %d\n",ant,dupp_keys); - goto end; - } - ant=0; - while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; - if (ant != dupp_keys) - { - printf("prev: Found: %d records of %d\n",ant,dupp_keys); - goto end; - } - /* Check of mi_rnext_same */ - if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) - goto err; - ant=1; - while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10) - ant++; - if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE) - { - printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys); - goto end; + /* Check of mi_rnext_same */ + if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) + goto err; + ant=1; + while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10) + ant++; + if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE) + { + printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys); + goto end; + } } if (!silent) @@ -776,9 +780,13 @@ end: printf("\nFollowing test have been made:\n"); printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); if (rec_pointer_size) - printf("Record pointer size: %d\n",rec_pointer_size); + printf("Record pointer size: %d\n",rec_pointer_size); + printf("myisam_block_size: %u\n", myisam_block_size); if (key_cacheing) + { puts("Key cacheing used"); + printf("key_cache_block_size: %u\n", key_cache_block_size); + } if (write_cacheing) puts("Write cacheing used"); if (write_cacheing) @@ -801,7 +809,7 @@ reads: %10lu\n", end_key_cache(); if (blob_buffer) my_free(blob_buffer,MYF(0)); - my_end(MY_CHECK_ERROR | MY_GIVE_INFO); + my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO); return(0); err: printf("got error: %d when using MyISAM-database\n",my_errno); @@ -861,7 +869,29 @@ static void get_options(int argc, char **argv) verbose=1; break; case 'm': /* records */ - recant=atoi(++pos); + if ((recant=atoi(++pos)) < 10) + { + fprintf(stderr,"record count must be >= 10\n"); + exit(1); + } + break; + case 'e': /* myisam_block_length */ + if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || + myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH) + { + fprintf(stderr,"Wrong myisam_block_length\n"); + exit(1); + } + myisam_block_size=1 << my_bit_log2(myisam_block_size); + break; + case 'E': /* myisam_block_length */ + if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || + key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH) + { + fprintf(stderr,"Wrong key_cache_block_size\n"); + exit(1); + } + key_cache_block_size=1 << my_bit_log2(key_cache_block_size); break; case 'f': if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) @@ -904,7 +934,7 @@ static void get_options(int argc, char **argv) case 'V': printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); puts("By Monty, for your professional use\n"); - printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-t#]\n", + printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n", progname); exit(0); case '#': diff --git a/myisam/mi_test_all.res b/myisam/mi_test_all.res index d6b4703d702..94355bf1aa2 100644 --- a/myisam/mi_test_all.res +++ b/myisam/mi_test_all.res @@ -1,48 +1,50 @@ -Maximum memory usage: 545477 bytes (533k) -Maximum memory usage: 545477 bytes (533k) -Maximum memory usage: 545369 bytes (533k) -mi_test2-i686 -s -L -K -R1 -m2000 ; Should give error 135 +mi_test2 -s -L -K -R1 -m2000 ; Should give error 135 Error: 135 in write at record: 1105 got error: 135 when using MyISAM-database -Maximum memory usage: 29439 bytes (29k) -Maximum memory usage: 66541 bytes (65k) -Maximum memory usage: 5101 bytes (5k) -Maximum memory usage: 545488 bytes (533k) +myisamchk: MyISAM file test2 +myisamchk: warning: Datafile is almost full, 65532 of 65534 used +MyISAM-table 'test2' is usable but should be fixed Commands Used count Errors Recover errors -open 1 0 0 -write 50 0 0 -update 5 0 0 -delete 50 0 0 -close 1 0 0 -extra 6 0 0 -Total 113 0 0 -Maximum memory usage: 545744 bytes (533k) +open 17 0 0 +write 850 0 0 +update 85 0 0 +delete 850 0 0 +close 17 0 0 +extra 102 0 0 +Total 1921 0 0 Commands Used count Errors Recover errors -open 2 0 0 -write 100 0 0 -update 10 0 0 -delete 100 0 0 -close 2 0 0 -extra 12 0 0 -Total 226 0 0 -Maximum memory usage: 5101 bytes (5k) -1.12user 0.52system 0:01.71elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (214major+25minor)pagefaults 0swaps -Maximum memory usage: 21189 bytes (21k) -1.29user 0.55system 0:01.82elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (215major+29minor)pagefaults 0swaps -Maximum memory usage: 66541 bytes (65k) -1.10user 0.51system 0:01.66elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (216major+40minor)pagefaults 0swaps -Maximum memory usage: 82629 bytes (81k) -1.33user 0.24system 0:01.54elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (216major+44minor)pagefaults 0swaps -Maximum memory usage: 545477 bytes (533k) -1.31user 0.24system 0:01.55elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (216major+173minor)pagefaults 0swaps -Maximum memory usage: 545389 bytes (533k) -1.37user 0.18system 0:01.57elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (218major+180minor)pagefaults 0swaps -Maximum memory usage: 109165 bytes (107k) -1.42user 0.38system 0:01.78elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k -0inputs+0outputs (218major+51minor)pagefaults 0swaps +open 18 0 0 +write 900 0 0 +update 90 0 0 +delete 900 0 0 +close 18 0 0 +extra 108 0 0 +Total 2034 0 0 + +real 0m1.054s +user 0m0.410s +sys 0m0.640s + +real 0m1.077s +user 0m0.550s +sys 0m0.530s + +real 0m1.100s +user 0m0.420s +sys 0m0.680s + +real 0m0.783s +user 0m0.590s +sys 0m0.200s + +real 0m0.764s +user 0m0.560s +sys 0m0.210s + +real 0m0.699s +user 0m0.570s +sys 0m0.130s + +real 0m0.991s +user 0m0.630s +sys 0m0.350s diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh index ccc9c39c64e..a2d57ea1a83 100755 --- a/myisam/mi_test_all.sh +++ b/myisam/mi_test_all.sh @@ -66,6 +66,14 @@ myisamchk$suffix -rs test1 myisamchk$suffix -se test1 myisamchk$suffix -rqs test1 myisamchk$suffix -se test1 +myisamchk$suffix -rs --correct-checksum test1 +myisamchk$suffix -se test1 +myisamchk$suffix -rqs --correct-checksum test1 +myisamchk$suffix -se test1 +myisamchk$suffix -ros --correct-checksum test1 +myisamchk$suffix -se test1 +myisamchk$suffix -rqos --correct-checksum test1 +myisamchk$suffix -se test1 # check of myisampack / myisamchk myisampack$suffix --force -s test1 @@ -105,13 +113,25 @@ mi_test1$suffix $silent --key_multiple -P -S myisamchk$suffix -sm test1 mi_test2$suffix $silent -L -K -W -P +myisamchk$suffix -sm test2 mi_test2$suffix $silent -L -K -W -P -A +myisamchk$suffix -sm test2 mi_test2$suffix $silent -L -K -W -P -S -R1 -m500 echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135" +myisamchk$suffix -sm test2 mi_test2$suffix $silent -L -K -R1 -m2000 +myisamchk$suffix -sm test2 mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000 +myisamchk$suffix -sm test2 mi_test2$suffix $silent -L -B +myisamchk$suffix -sm test2 mi_test2$suffix $silent -D -B -c +myisamchk$suffix -sm test2 +mi_test2$suffix $silent -m10000 -e8192 -K +myisamchk$suffix -sm test2 +mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L +myisamchk$suffix -sm test2 + mi_test2$suffix $silent -L -K -W -P -m50 -l myisamlog$suffix mi_test2$suffix $silent -L -K -W -P -m50 -l -b100 diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 096d5829fed..e3de13d2d9a 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -291,7 +291,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, my_bool insert_last) { int error,flag; - uint comp_flag,nod_flag; + uint comp_flag,nod_flag, search_key_length; uchar *temp_buff,*keypos; uchar keybuff[MI_MAX_KEY_BUFF]; my_bool was_last_key; @@ -299,10 +299,14 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, DBUG_ENTER("w_search"); DBUG_PRINT("enter",("page: %ld",page)); + search_key_length=USE_WHOLE_KEY; if (keyinfo->flag & HA_SORT_ALLOWS_SAME) comp_flag=SEARCH_BIGGER; /* Put after same key */ else if (keyinfo->flag & HA_NOSAME) + { comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */ + search_key_length= key_length; + } else comp_flag=SEARCH_SAME; /* Keys in rec-pos order */ @@ -312,8 +316,8 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0)) goto err; - flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,key_length,comp_flag, - &keypos, keybuff, &was_last_key); + flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length, + comp_flag, &keypos, keybuff, &was_last_key); nod_flag=mi_test_if_nod(temp_buff); if (flag == 0) { diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 319539b44d4..b4c9e2f0fd6 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -40,6 +40,7 @@ static char **default_argv; static const char *load_default_groups[]= { "myisamchk", 0 }; static const char *set_charset_name; static CHARSET_INFO *set_charset; +static long opt_myisam_block_size; static const char *type_names[]= { "?","char","binary", "short", "long", "float", @@ -141,6 +142,9 @@ int main(int argc, char **argv) static CHANGEABLE_VAR changeable_vars[] = { { "key_buffer_size",(long*) &check_param.use_buffers,(long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE }, + { "myisam_block_size", (long*) &opt_myisam_block_size, + MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, + 0, MI_MIN_KEY_BLOCK_LENGTH }, { "read_buffer_size", (long*) &check_param.read_buffer_length,(long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L }, { "write_buffer_size", (long*) &check_param.write_buffer_length,(long) READ_BUFFER_INIT, @@ -159,7 +163,10 @@ static CHANGEABLE_VAR changeable_vars[] = { 20, 4, HA_FT_MAXLEN, 0, 1 }, { NullS,(long*) 0,0L,0L,0L,0L,0L,} }; -enum options {OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS}; +enum options { + OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS, + OPT_CORRECT_CHECKSUM +}; static struct option long_options[] = @@ -167,9 +174,10 @@ static struct option long_options[] = {"analyze", no_argument, 0, 'a'}, {"block-search", required_argument,0, 'b'}, {"backup", no_argument, 0, 'B'}, - {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, + {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, {"check", no_argument, 0, 'c'}, {"check-only-changed",no_argument, 0, 'C'}, + {"correct-checksum", no_argument, 0, OPT_CORRECT_CHECKSUM}, #ifndef DBUG_OFF {"debug", optional_argument, 0, '#'}, #endif @@ -205,7 +213,7 @@ static struct option long_options[] = static void print_version(void) { - printf("%s Ver 1.51 for %s at %s\n",my_progname,SYSTEM_TYPE, + printf("%s Ver 1.52 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); } @@ -248,6 +256,7 @@ static void usage(void) puts("Repair options (When using -r or -o) \n\ -B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\ + --correct-checksum Correct checksum information for table. \n\ -D, --data-file-length=# Max length of data file (when recreating data\n\ file when it's full)\n\ -e, --extend-check Try to recover every possible row from the data file\n\ @@ -433,6 +442,9 @@ static void get_options(register int *argc,register char ***argv) case 'V': print_version(); exit(0); + case OPT_CORRECT_CHECKSUM: + check_param.testflag|=T_CALC_CHECKSUM; + break; case OPT_CHARSETS_DIR: charsets_dir = optarg; break; @@ -449,6 +461,11 @@ static void get_options(register int *argc,register char ***argv) exit(0); } } + /* If using repair, then update checksum if one uses --update-state */ + if ((check_param.testflag & T_UPDATE_STATE) && + (check_param.testflag & (T_REP | T_REP_BY_SORT))) + check_param.testflag|= T_CALC_CHECKSUM; + (*argc)-=optind; (*argv)+=optind; if (*argc == 0) @@ -456,6 +473,7 @@ static void get_options(register int *argc,register char ***argv) usage(); exit(-1); } + if ((check_param.testflag & T_UNPACK) && (check_param.opt_rep_quick || (check_param.testflag & T_SORT_RECORDS))) { @@ -479,6 +497,7 @@ static void get_options(register int *argc,register char ***argv) if (!(set_charset=get_charset_by_name(set_charset_name, MYF(MY_WME)))) exit(1); + myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); return; } /* get options */ @@ -605,7 +624,8 @@ static int myisamchk(MI_CHECK *param, my_string filename) (((ulonglong) 1L << share->base.keys)-1)) || test_if_almost_full(info) || info->s->state.header.file_version[3] != myisam_file_magic[3] || - (set_charset && set_charset->number != share->state.header.language))) + (set_charset && set_charset->number != share->state.header.language) || + myisam_block_size != MI_KEY_BLOCK_LENGTH)) { if (set_charset) check_param.language=set_charset->number; diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index a2a30ae50ce..33837dfda00 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -173,7 +173,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */ File data_file; /* Shared data file */ int mode; /* mode of file on open */ uint reopen; /* How many times reopened */ - uint w_locks,r_locks; /* Number of read/write locks */ + uint w_locks,r_locks,tot_locks; /* Number of read/write locks */ uint blocksize; /* blocksize of keyfile */ ulong min_pack_length; /* Theese are used by packed data */ ulong max_pack_length; @@ -365,10 +365,8 @@ struct st_myisam_info { #define PACK_TYPE_ZERO_FILL 4 #define MI_FOUND_WRONG_KEY 32738 /* Impossible value from _mi_key_cmp */ -#define MI_KEY_BLOCK_LENGTH 1024 /* Min key block length */ -#define MI_MAX_KEY_BLOCK_LENGTH 8192 -#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_KEY_BLOCK_LENGTH) -#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/MI_KEY_BLOCK_LENGTH+1)*MI_KEY_BLOCK_LENGTH) +#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH) +#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/myisam_block_size+1)*myisam_block_size) #define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ #define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ @@ -589,6 +587,9 @@ enum myisam_log_commands { #define myisam_log_command(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_command(a,b,c,d,e) #define myisam_log_record(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_record(a,b,c,d,e) +#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0) +#define fast_mi_readinfo(INFO) (!(INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1) + #ifdef __cplusplus extern "C" { #endif diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 9a44d569e45..2a9841975ed 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -45,7 +45,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ my_quick.c my_lockmem.c my_static.c \ getopt.c getopt1.c getvar.c my_mkdir.c \ default.c my_compress.c checksum.c raid.cc my_net.c \ - my_vsnprintf.c charset.c my_bitmap.c + my_vsnprintf.c charset.c my_bitmap.c my_bit.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 5b8ec96b4d1..d223a4779a0 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -53,7 +53,6 @@ typedef struct sec_link { } SEC_LINK; -static uint find_next_bigger_power(uint value); static SEC_LINK *find_key_block(int file,my_off_t filepos,int *error); /* static variables in this file */ @@ -61,9 +60,11 @@ static SEC_LINK *_my_block_root,**_my_hash_root, *_my_used_first,*_my_used_last; static int _my_disk_blocks; static uint _my_disk_blocks_used, _my_hash_blocks; +static uint key_cache_shift; ulong _my_blocks_used,_my_blocks_changed; ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests, _my_cache_read; +uint key_cache_block_size=DEFAULT_KEYCACHE_BLOCK_SIZE; static byte HUGE_PTR *_my_block_mem; static SEC_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; static SEC_LINK *file_blocks[CHANGED_BLOCKS_HASH]; @@ -92,12 +93,16 @@ int init_key_cache(ulong use_mem, { key_cache_inited=TRUE; _my_disk_blocks= -1; + key_cache_shift=my_bit_log2(key_cache_block_size); + DBUG_PRINT("info",("key_cache_block_size: %u key_cache_shift: %u", + key_cache_block_size, key_cache_shift)); #ifndef DBUG_OFF _my_printed=0; #endif } - blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+KEYCACHE_BLOCK_SIZE)); + blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+ + key_cache_block_size)); /* No use to have very few blocks */ if (blocks >= 8 && _my_disk_blocks < 0) { @@ -107,13 +112,15 @@ int init_key_cache(ulong use_mem, #endif for (;;) { - if ((_my_hash_blocks=find_next_bigger_power((uint) blocks)) < blocks*5/4) - _my_hash_blocks<<=1; + /* Set my_hash_blocks to the next bigger 2 power */ + _my_hash_blocks=(uint) 1 << (my_bit_log2(blocks*5/4)+1); while ((length=(uint) blocks*sizeof(SEC_LINK)+ - sizeof(SEC_LINK*)*_my_hash_blocks)+(ulong) blocks*KEYCACHE_BLOCK_SIZE > + sizeof(SEC_LINK*)*_my_hash_blocks)+ + ((ulong) blocks << key_cache_shift) > use_mem) blocks--; - if ((_my_block_mem=my_malloc_lock((ulong) blocks * KEYCACHE_BLOCK_SIZE,MYF(0)))) + if ((_my_block_mem=my_malloc_lock((ulong) blocks << key_cache_shift, + MYF(0)))) { if ((_my_block_root=(SEC_LINK*) my_malloc((uint) length,MYF(0))) != 0) break; @@ -170,17 +177,6 @@ void end_key_cache(void) } /* end_key_cache */ -static uint find_next_bigger_power(uint value) -{ - uint old_value=1; - while (value) - { - old_value=value; - value&= value-1; - } - return (old_value << 1); -} - static inline void link_into_file_blocks(SEC_LINK *next, int file) { reg1 SEC_LINK **ptr= &file_blocks[(uint) file & CHANGED_BLOCKS_MASK]; @@ -243,7 +239,7 @@ static void test_key_cache(const char *where, my_bool lock); /* ** read a key_buffer - ** filepos must point at a even KEYCACHE_BLOCK_SIZE block + ** filepos must point at a even key_cache_block_size block ** if return_buffer is set then the intern buffer is returned if ** it can be used ** Returns adress to where data is read @@ -257,7 +253,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, int error=0; #ifndef THREAD - if (block_length > KEYCACHE_BLOCK_SIZE) + if (block_length > key_cache_block_size) return_buffer=0; #endif if (_my_disk_blocks > 0) @@ -268,7 +264,8 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, do { _my_cache_r_requests++; - read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length; + read_length= (length > key_cache_block_size ? key_cache_block_size : + length); if (!(next=find_key_block(file,filepos,&error))) { pthread_mutex_unlock(&THR_LOCK_keycache); @@ -310,7 +307,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, /* write a key_buffer */ /* We don't have to use pwrite because of write locking */ - /* buff must point at a even KEYCACHE_BLOCK_SIZE block */ + /* buff must point at a even key_cache_block_size block */ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length, uint block_length __attribute__((unused)), @@ -336,7 +333,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length, _my_cache_w_requests++; do { - read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length; + read_length= length > key_cache_block_size ? key_cache_block_size : length; if (!(next=find_key_block(file,filepos,&error))) goto end; /* Fatal error */ if (!dont_write) /* If we wrote buff at start */ @@ -385,7 +382,7 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error) #endif *error=0; - next= *(start= &_my_hash_root[((ulong) (filepos/KEYCACHE_BLOCK_SIZE)+(ulong) file) & + next= *(start= &_my_hash_root[((ulong) (filepos >> key_cache_shift)+(ulong) file) & (_my_hash_blocks-1)]); while (next && (next->diskpos != filepos || next->file != file)) next= next->next_hash; @@ -411,7 +408,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error) { /* There are unused blocks */ next= &_my_block_root[_my_blocks_used++]; /* Link in hash-chain */ next->buffer=ADD_TO_PTR(_my_block_mem, - (ulong) _my_disk_blocks_used*KEYCACHE_BLOCK_SIZE,byte*); + ((ulong) _my_disk_blocks_used << key_cache_shift), + byte*); /* link first in file_blocks */ next->changed=0; link_into_file_blocks(next,file); @@ -426,7 +424,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error) next= _my_used_first; if (next->changed) { - if (my_pwrite(next->file,next->buffer,KEYCACHE_BLOCK_SIZE,next->diskpos, + if (my_pwrite(next->file,next->buffer,key_cache_block_size, + next->diskpos, MYF(MY_NABP | MY_WAIT_IF_FULL))) { *error=1; @@ -505,7 +504,8 @@ static int flush_cached_blocks(File file, SEC_LINK **cache, uint count) qsort((byte*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link); for ( ; count-- ; cache++) { - if (my_pwrite(file,(*cache)->buffer,KEYCACHE_BLOCK_SIZE,(*cache)->diskpos, + if (my_pwrite(file,(*cache)->buffer,key_cache_block_size, + (*cache)->diskpos, MYF(MY_NABP | MY_WAIT_IF_FULL))) { if (!last_errno) @@ -646,7 +646,7 @@ static void test_key_cache(const char *where, my_bool lock) i,(ulong) pos,(ulong) prev,(ulong) pos->prev_hash)); } - if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i) + if (((pos->diskpos >> key_cache_shift)+pos->file) % _my_hash_blocks != i) { DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld", i,(ulong) pos,(ulong) pos->diskpos)); diff --git a/mysys/my_bit.c b/mysys/my_bit.c new file mode 100644 index 00000000000..19ffb74a5c5 --- /dev/null +++ b/mysys/my_bit.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA */ + +/* Some useful bit functions */ + +#include "mysys_priv.h" + +/* + Find smallest X in 2^X >= value + This can be used to divide a number with value by doing a shift instead +*/ + +uint my_bit_log2(ulong value) +{ + uint bit; + for (bit=0 ; value > 1 ; value>>=1, bit++) ; + return bit; +} diff --git a/mysys/my_init.c b/mysys/my_init.c index c3b9cecf86e..f39b3f0ed6d 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -45,9 +45,8 @@ static my_bool win32_init_tcp_ip(); #else #define my_win_init() #endif -static my_bool my_init_done=0; - +my_bool my_init_done=0; static ulong atoi_octal(const char *str) { diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 86312fdab52..7226840b475 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -56,6 +56,13 @@ END_OF_DATA echo "" fi +echo "Adding columns needed by GRANT .. REQUIRE (openssl)" +echo "You can ignore any Duplicate column errors" +@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <val(); + if (internal_result_type == REAL_RESULT) + (void) args[0]->val(); + else + (void) args[0]->val_int(); return (args[0]->null_value) ? 1 : 0; } longlong Item_func_isnotnull::val_int() { - (void) args[0]->val(); + if (internal_result_type == REAL_RESULT) + (void) args[0]->val(); + else + (void) args[0]->val_int(); return !(args[0]->null_value) ? 1 : 0; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 5ee0687c064..9c9336264f7 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -429,6 +429,7 @@ class Item_func_in :public Item_int_func class Item_func_isnull :public Item_bool_func { + enum Item_result internal_result_type; public: Item_func_isnull(Item *a) :Item_bool_func(a) {} longlong val_int(); @@ -437,6 +438,7 @@ public: { decimals=0; max_length=1; maybe_null=0; Item_func_isnull::update_used_tables(); + internal_result_type=args[0]->result_type(); } const char *func_name() const { return "isnull"; } /* Optimize case of not_null_column IS NULL */ @@ -455,11 +457,16 @@ public: class Item_func_isnotnull :public Item_bool_func { + enum Item_result internal_result_type; public: Item_func_isnotnull(Item *a) :Item_bool_func(a) {} longlong val_int(); enum Functype functype() const { return ISNOTNULL_FUNC; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } + void fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=0; + internal_result_type=args[0]->result_type(); + } const char *func_name() const { return "isnotnull"; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7a32a253d6c..851e33fca04 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -506,7 +506,7 @@ void sql_print_error(const char *format,...) __attribute__ ((format (printf, 1, 2))); extern uint32 server_id; -extern char mysql_data_home[2],server_version[SERVER_VERSION_LENGTH], +extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], max_sort_char, mysql_real_data_home[]; extern my_string mysql_unix_port,mysql_tmpdir; extern const char *first_keyword, *localhost, *delayed_user; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c14ae3aa61a..bd5769c3237 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -214,8 +214,9 @@ SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES; static bool opt_skip_slave_start = 0; // if set, slave is not autostarted static bool opt_do_pstack = 0; static ulong opt_specialflag=SPECIAL_ENGLISH; -static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static ulong back_log,connect_timeout,concurrency; +static ulong opt_myisam_block_size; +static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static my_string opt_logname=0,opt_update_logname=0, opt_binlog_index_name = 0,opt_slow_logname=0; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; @@ -310,10 +311,16 @@ ulong slow_launch_threads = 0; ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size; char mysql_real_data_home[FN_REFLEN], - mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN], + language[LIBLEN],reg_ext[FN_EXTLEN], default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list, blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; +#ifndef EMBEDDED_LIBRARY +char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff; +#else +char *mysql_data_home=mysql_real_data_home; +#endif + char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; const char *first_keyword="first"; @@ -677,9 +684,8 @@ static sig_handler print_signal_warning(int sig) void unireg_end(int signal_number __attribute__((unused))) { clean_up(); -#ifndef EMBEDDED_LIBRARY + my_thread_end(); pthread_exit(0); // Exit is in main thread -#endif } @@ -688,6 +694,7 @@ void unireg_abort(int exit_code) if (exit_code) sql_print_error("Aborting\n"); clean_up(); /* purecov: inspected */ + my_thread_end(); exit(exit_code); /* purecov: inspected */ } @@ -730,14 +737,13 @@ void clean_up(bool print_message) free_max_user_conn(); end_slave_list(); -#ifndef __WIN__ +#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif if (print_message) sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname); x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */ - my_thread_end(); /* Tell main we are ready */ (void) pthread_mutex_lock(&LOCK_thread_count); @@ -1782,10 +1788,6 @@ int main(int argc, char **argv) init_thr_lock(); init_slave_list(); - /* Fix varibles that are base 1024*1024 */ - myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); - myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); - /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); @@ -1796,17 +1798,18 @@ int main(int argc, char **argv) using_update_log=1; } - //make sure slave thread gets started - // if server_id is set, valid master.info is present, and master_host has - // not been specified - if(server_id && !master_host) - { - char fname[FN_REFLEN+128]; - MY_STAT stat_area; - fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); - if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi)) - master_host = glob_mi.host; - } + /* + make sure slave thread gets started if server_id is set, + valid master.info is present, and master_host has not been specified + */ + if (server_id && !master_host) + { + char fname[FN_REFLEN+128]; + MY_STAT stat_area; + fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); + if (my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi)) + master_host = glob_mi.host; + } if (opt_bin_log && !server_id) { @@ -2882,6 +2885,9 @@ CHANGEABLE_VAR changeable_vars[] = { ~0L, 1, ~0L, 0, 1 }, { "myisam_bulk_insert_tree_size", (long*) &myisam_bulk_insert_tree_size, 8192*1024, 4, ~0L, 0, 1 }, + { "myisam_block_size", (long*) &opt_myisam_block_size, + MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, + 0, MI_MIN_KEY_BLOCK_LENGTH }, { "myisam_max_extra_sort_file_size", (long*) &myisam_max_extra_sort_file_size, (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 }, @@ -4025,6 +4031,12 @@ static void get_options(int argc,char **argv) /* To be deleted in MySQL 4.0 */ if (!record_rnd_cache_size) record_rnd_cache_size=my_default_record_cache_size; + + /* Fix variables that are base 1024*1024 */ + myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); + myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); + + myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); } From d28f23c14ffc8b0a738a2c3bda3d0d4d9c075e9b Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Tue, 2 Oct 2001 21:08:08 +0300 Subject: [PATCH 34/38] Fixed bug in INSERT DELAYED Fixed some problems in SHOW CREATE TABLE Fixed calculation of checksums in myisamchk --- Docs/manual.texi | 3 +++ client/mysql.cc | 2 +- myisam/mi_check.c | 24 ++++++++++-------------- sql/sql_insert.cc | 11 +++++++++-- sql/sql_show.cc | 13 ++++++++++++- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 128fd814e31..be415284e7e 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46854,6 +46854,9 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.43 @itemize @bullet @item +Fixed a bug in @code{INSERT DELAYED} and @code{FLUSH TABLES} introduced +in 3.23.42. +@item Fixed unlikely bug, which returned not matching rows, in SELECT with many tables and multi-column indexes and 'range' type. @item diff --git a/client/mysql.cc b/client/mysql.cc index 96536c9d5f0..5ae8df39863 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -937,7 +937,7 @@ static bool add_line(String &buffer,char *line,char *in_string) { // mSQL or postgreSQL style command ? if (!(inchar = (uchar) *++pos)) break; // readline adds one '\' - if (*in_string || inchar == 'N') + if (*in_string || inchar == 'N') // \N is short for NULL { // Don't allow commands in string *out++='\\'; *out++= (char) inchar; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index fa4687e27f5..93598ce2d76 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1194,8 +1194,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, param->glob_crc=0; if (param->testflag & T_CALC_CHECKSUM) param->calc_checksum=1; - if (!rep_quick) - share->state.checksum=0; info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); for (i=0 ; i < info->s->base.keys ; i++) @@ -1290,9 +1288,9 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, else { info->state->data_file_length=sort_info->max_pos; - if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; } + if (param->testflag & T_CALC_CHECKSUM) + share->state.checksum=param->glob_crc; if (!(param->testflag & T_SILENT)) { @@ -1878,8 +1876,6 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, param->glob_crc=0; if (param->testflag & T_CALC_CHECKSUM) param->calc_checksum=1; - if (! rep_quick) - share->state.checksum=0; rec_per_key_part= param->rec_per_key_part; for (sort_info->key=0 ; sort_info->key < share->base.keys ; @@ -1999,7 +1995,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, "Can't change size of datafile, error: %d", my_errno); } - else if (param->testflag & T_CALC_CHECKSUM) + if (param->testflag & T_CALC_CHECKSUM) share->state.checksum=param->glob_crc; if (my_chsize(share->kfile,info->state->key_file_length,MYF(0))) @@ -2478,7 +2474,7 @@ int sort_write_record(SORT_INFO *sort_info) DBUG_RETURN(1); } sort_info->filepos+=share->base.pack_reclength; - info->s->state.checksum+=mi_static_checksum(info, sort_info->record); + /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */ break; case DYNAMIC_RECORD: if (! info->blobs) @@ -2502,7 +2498,7 @@ int sort_write_record(SORT_INFO *sort_info) } info->checksum=mi_checksum(info,sort_info->record); reclength=_mi_rec_pack(info,from,sort_info->record); - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ block_length=reclength+ 3 + test(reclength >= (65520-3)); if (block_length < share->base.min_block_length) block_length=share->base.min_block_length; @@ -2516,7 +2512,7 @@ int sort_write_record(SORT_INFO *sort_info) DBUG_RETURN(1); } sort_info->filepos+=block_length; - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ break; case COMPRESSED_RECORD: reclength=info->packed_length; @@ -2529,7 +2525,7 @@ int sort_write_record(SORT_INFO *sort_info) mi_check_print_error(param,"%d when writing to datafile",my_errno); DBUG_RETURN(1); } - info->s->state.checksum+=info->checksum; + /* sort_info->param->glob_crc+=info->checksum; */ sort_info->filepos+=reclength+length; break; } @@ -2746,9 +2742,9 @@ static int sort_delete_record(MI_CHECK *param) DBUG_RETURN(1); } } - if (info->s->calc_checksum) - info->s->state.checksum-=(*info->s->calc_checksum)(info, - sort_info->record); + if (param->calc_checksum) + param->glob_crc-=(*info->s->calc_checksum)(info, + sort_info->record); } error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info); info->dfile=old_file; /* restore actual value */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index cd738999383..f7ff3ed159c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -841,6 +841,7 @@ void kill_delayed_threads(void) delayed_insert *tmp; while ((tmp=it++)) { + /* Ensure that the thread doesn't kill itself while we are looking at it */ pthread_mutex_lock(&tmp->mutex); tmp->thd.killed=1; if (tmp->thd.mysys_var) @@ -848,9 +849,15 @@ void kill_delayed_threads(void) pthread_mutex_lock(&tmp->thd.mysys_var->mutex); if (tmp->thd.mysys_var->current_cond) { - pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); + /* + We need the following test because the main mutex may be locked + in handle_delayed_insert() + */ + if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) + pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); pthread_cond_broadcast(tmp->thd.mysys_var->current_cond); - pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); + if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) + pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); } pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5869feefdc3..6ae7eeb41d3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -390,7 +390,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); if (table->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " format=", ha_row_type[(uint) table->row_type], + ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) table->row_type], NullS); if (file->raid_type) { @@ -910,6 +910,12 @@ store_create_info(THD *thd, TABLE *table, String *packet) p = longlong10_to_str(table->max_rows, buff, 10); packet->append(buff, (uint) (p - buff)); } + if (table->avg_row_length) + { + packet->append(" AVG_ROW_LENGTH="); + p=longlong10_to_str(table->avg_row_length, buff,10); + packet->append(buff, (uint) (p - buff)); + } if (table->db_create_options & HA_OPTION_PACK_KEYS) packet->append(" PACK_KEYS=1", 12); @@ -919,6 +925,11 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" CHECKSUM=1", 11); if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) packet->append(" DELAY_KEY_WRITE=1",18); + if (table->row_type != ROW_TYPE_DEFAULT) + { + packet->append(" ROW_FORMAT=",12); + packet->append(ha_row_type[(uint) table->row_type]); + } table->file->append_create_info(packet); if (table->comment && table->comment[0]) { From db82d30bf0419d509101110ade2f8f7902900fa1 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Tue, 2 Oct 2001 22:21:14 +0300 Subject: [PATCH 35/38] Fix for make dist Made replication test portable Fixed buffer overrun bug in replication --- client/Makefile.am | 4 ++-- mysql-test/t/rpl000017-slave.sh | 4 ++-- sql/slave.cc | 8 ++++---- strings/strmake.c | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index 380c9f2acbe..d1b16870f67 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -19,13 +19,13 @@ INCLUDES = -I$(srcdir)/../include \ -I../include -I$(srcdir)/.. -I$(top_srcdir) \ -I.. -noinst_HEADERS = client_priv.h LIBS = @CLIENT_LIBS@ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ mysqldump mysqlimport mysqltest mysqlbinlog noinst_PROGRAMS = insert_test select_test thread_test -noinst_HEADERS = sql_string.h completion_hash.h my_readline.h +noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ + client_priv.h mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) diff --git a/mysql-test/t/rpl000017-slave.sh b/mysql-test/t/rpl000017-slave.sh index 269e144e278..0588859c591 100755 --- a/mysql-test/t/rpl000017-slave.sh +++ b/mysql-test/t/rpl000017-slave.sh @@ -3,7 +3,7 @@ master-bin.001 4 127.0.0.1 replicate -aaaaaaaaaaaaaaab -9306 +aaaaaaaaaaaaaaabthispartofthepasswordisnotused +$MASTER_MYPORT 1 EOF diff --git a/sql/slave.cc b/sql/slave.cc index 52cde738b9a..2e0861bbd56 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -299,7 +299,7 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f, } else if (default_val) { - strmake(var, default_val, max_size); + strmake(var, default_val, max_size-1); return 0; } return 1; @@ -530,14 +530,14 @@ int init_master_info(MASTER_INFO* mi) } mi->log_file_name[length-1]= 0; // kill \n - char buf[FN_REFLEN]; - if(!my_b_gets(&mi->file, buf, sizeof(buf))) + /* Reuse fname buffer */ + if(!my_b_gets(&mi->file, fname, sizeof(fname))) { msg="Error reading log file position from master info file"; goto error; } + mi->pos = strtoull(fname,(char**) 0, 10); - mi->pos = strtoull(buf,(char**) 0, 10); mi->fd = fd; if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, master_host) || diff --git a/strings/strmake.c b/strings/strmake.c index d4edce689a5..66a230338a1 100644 --- a/strings/strmake.c +++ b/strings/strmake.c @@ -22,7 +22,8 @@ strmake(dst,src,length) moves length characters, or until end, of src to dst and appends a closing NUL to dst. - strmake() returns pointer to closing null; + Note that is strlen(src) >= length then dst[length] will be set to \0 + strmake() returns pointer to closing null */ #include From 4e5028663233ea24fff868f086cde080a67aaa8d Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Tue, 2 Oct 2001 23:14:48 +0300 Subject: [PATCH 36/38] Portability fix --- Build-tools/Do-rpm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index 138953ab188..046ba93a1dd 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -210,7 +210,7 @@ if [ $? != 0 ]; then tail $log fi -if [ ! x$local_build=x1 ]; then +if [ x$local_build != x1 ]; then # Build perl RPM (we currently need to be root to do this and that is # not possible) @@ -228,5 +228,3 @@ if [ ! x$local_build=x1 ]; then #scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS fi ) > $log 2>&1 - - From f5a53594c81c403e3cd13a13b8d2f82165f8f873 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Wed, 3 Oct 2001 16:27:20 +0300 Subject: [PATCH 37/38] Added usage of --master-retry-count to make mysql-test-run safer. --- Build-tools/Do-compile | 6 ++--- Docs/manual.texi | 24 +++--------------- mysql-test/mysql-test-run.sh | 8 +++++- sql/mysqld.cc | 7 +++++- sql/slave.cc | 49 ++++++++++++++++++++++++------------ sql/slave.h | 2 +- 6 files changed, 53 insertions(+), 43 deletions(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 4cf2477f5bd..2f8a884af76 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -4,10 +4,10 @@ use Getopt::Long; $opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env=""; $opt_dbd_options=$opt_perl_options=$opt_suffix=""; $opt_tmp=$version_suffix=""; -$opt_help=$opt_Information=$opt_no_delete=$opt_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0; +$opt_help=$opt_Information=$opt_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0; $opt_innodb=$opt_bdb=0; -GetOptions("Information","help","distribution=s","user=s","result=s","no-delete","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip") || usage(); +GetOptions("Information","help","distribution=s","user=s","result=s","delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip") || usage(); usage() if ($opt_help || $opt_Information); usage() if (!$opt_distribution); @@ -143,7 +143,7 @@ if ($opt_stage <= 1) if ($opt_stage <= 2) { - unlink($opt_distribution) if (!$opt_delete && !$opt_use_old_distribution); + unlink($opt_distribution) if ($opt_delete && !$opt_use_old_distribution); safe_system("$make"); } diff --git a/Docs/manual.texi b/Docs/manual.texi index 86b1780178e..97c186a9a07 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -10151,31 +10151,13 @@ work). You must also use the @code{egcs} C++ compiler @node Linux-IA64, , Linux-MIPS, Linux @subsubsection Linux IA64 Notes -To get MySQL to compile on Linux Ia64, we had to do the following -(we assume that this will be easier when next gcc version for ia64 is -released). - -Using @code{gcc-2.9-final}: +To get MySQL to compile on Linux Ia64, we use the following compile line: +Using @code{gcc-2.96}: @example -CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex +CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex @end example -After @code{make} you will get an error that @code{sql/opt_range.cc} -will not compile (internal compiler error). To fix this, go to the sql -directory and type @code{make} again. Copy the compile line, but change --O2 to -O0. The file should now compile. - -Now you can do: - -@example -cd .. -make -make_install -@end example - -and @code{mysqld} should be ready to run. - On Ia64 the MySQL client binaries are using shared libraries. This means that if you install our binary distribution in some other place than @file{/usr/local/mysql} you need to either modify @file{/etc/ld.so.conf} diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 3263494ef66..35b29307895 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -113,6 +113,11 @@ SLAVE_LOAD_TMPDIR=../../var/tmp #needs to be same length to test logging RES_SPACE=" " MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \ myisammrg heap sql" +# +# Set LD_LIBRARY_PATH if we are using shared libraries +# +LD_LIBRARY_PATH="$BASEDIR/lib:$LD_LIBRARY_PATH" +export LD_LIBRARY_PATH MASTER_RUNNING=0 MASTER_MYPORT=9306 @@ -574,17 +579,18 @@ start_slave() slave_args="--no-defaults $master_info \ --exit-info=256 \ --log-bin=slave-bin --log-slave-updates \ + --log=$SLAVE_MYLOG \ --basedir=$MY_BASEDIR \ --datadir=$SLAVE_MYDDIR \ --pid-file=$SLAVE_MYPID \ --port=$SLAVE_MYPORT \ --socket=$SLAVE_MYSOCK \ - --log=$SLAVE_MYLOG \ --character-sets-dir=$CHARSETSDIR \ --core \ --tmpdir=$MYSQL_TMP_DIR \ --language=$LANGUAGE \ --skip-innodb --skip-slave-start \ + --master-retry-count=5 \ $SMALL_SERVER \ $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT" if [ x$DO_DDD = x1 ] diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 435ee51a0e0..2207fe81e94 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -276,7 +276,7 @@ const char *localhost=LOCAL_HOST; const char *delayed_user="DELAYED"; uint master_port = MYSQL_PORT, master_connect_retry = 60; -ulong max_tmp_tables,max_heap_table_size; +ulong max_tmp_tables,max_heap_table_size,master_retry_count=0; ulong bytes_sent = 0L, bytes_received = 0L; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; @@ -2534,6 +2534,7 @@ enum options { OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, + OPT_MASTER_RETRY_COUNT, OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, @@ -2635,6 +2636,7 @@ static struct option long_options[] = { {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD}, {"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, + {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT}, {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER}, {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, @@ -3859,6 +3861,9 @@ static void get_options(int argc,char **argv) case OPT_MASTER_CONNECT_RETRY: master_connect_retry= atoi(optarg); break; + case OPT_MASTER_RETRY_COUNT: + master_retry_count= atoi(optarg); + break; case OPT_SAFE_SHOW_DB: opt_safe_show_db=1; break; diff --git a/sql/slave.cc b/sql/slave.cc index 2e0861bbd56..5836ac441e1 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -504,7 +504,7 @@ int init_master_info(MASTER_INFO* mi) if (master_user) strmake(mi->user, master_user, sizeof(mi->user) - 1); if (master_password) - strmake(mi->password, master_password, sizeof(mi->password) - 1); + strmake(mi->password, master_password, HASH_PASSWORD_LENGTH); mi->port = master_port; mi->connect_retry = master_connect_retry; } @@ -543,7 +543,7 @@ int init_master_info(MASTER_INFO* mi) master_host) || init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, master_user) || - init_strvar_from_file(mi->password, sizeof(mi->password), &mi->file, + init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file, master_password) || init_intvar_from_file((int*)&mi->port, &mi->file, master_port) || init_intvar_from_file((int*)&mi->connect_retry, &mi->file, @@ -927,7 +927,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) (actual_error = thd->net.last_errno) && expected_error) { const char* errmsg = "Slave: did not get the expected error\ - running query from master - expected: '%s'(%d), got '%s'(%d)"; + running query from master - expected: '%s' (%d), got '%s' (%d)"; sql_print_error(errmsg, ER_SAFE(expected_error), expected_error, actual_error ? thd->net.last_error:"no error", @@ -1435,7 +1435,7 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) { - sql_print_error("Slave thread: error connecting to master:%s(%d),\ + sql_print_error("Slave thread: error connecting to master: %s (%d),\ retry in %d sec", mc_mysql_error(mysql), errno, mi->connect_retry); safe_sleep(thd, mi->connect_retry); } @@ -1452,38 +1452,55 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) return slave_was_killed; } -/* try to connect until successful or slave killed */ +/* + Try to connect until successful or slave killed or we have retried + master_retry_count times +*/ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { int slave_was_killed; + int last_errno= -2; // impossible error + ulong err_count=0; char llbuff[22]; - // if we lost connection after reading a state set event - // we will be re-reading it, so pending needs to be cleared + /* + If we lost connection after reading a state set event + we will be re-reading it, so pending needs to be cleared + */ mi->pending = 0; #ifndef DBUG_OFF events_till_disconnect = disconnect_slave_event_count; #endif - while(!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql)) + while (!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql)) { - sql_print_error("Slave thread: error re-connecting to master:\ + /* Don't repeat last error */ + if (mc_mysql_errno(mysql) != last_errno) + { + sql_print_error("Slave thread: error re-connecting to master: \ %s, last_errno=%d, retry in %d sec", - mc_mysql_error(mysql), errno, mi->connect_retry); - safe_sleep(thd, mi->connect_retry); + mc_mysql_error(mysql), last_errno=mc_mysql_errno(mysql), + mi->connect_retry); + safe_sleep(thd, mi->connect_retry); + } + if (err_count++ == master_retry_count) + { + slave_was_killed=1; + break; + } } - if(!slave_was_killed) - { - sql_print_error("Slave: reconnected to master '%s@%s:%d',\ + if (!slave_was_killed) + { + sql_print_error("Slave: reconnected to master '%s@%s:%d',\ replication resumed in log '%s' at position %s", glob_mi.user, glob_mi.host, glob_mi.port, RPL_LOG_NAME, llstr(glob_mi.pos,llbuff)); #ifdef SIGNAL_WITH_VIO_CLOSE - thd->set_active_vio(mysql->net.vio); + thd->set_active_vio(mysql->net.vio); #endif - } + } return slave_was_killed; } diff --git a/sql/slave.h b/sql/slave.h index 1932bcb04fe..09887ecd82c 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -3,7 +3,7 @@ #define SLAVE_NET_TIMEOUT 3600 -extern ulong slave_net_timeout; +extern ulong slave_net_timeout, master_retry_count; typedef struct st_master_info { From 0aa358b571384f36f4effefe226941b14a1a85e8 Mon Sep 17 00:00:00 2001 From: "monty@work.mysql.com" <> Date: Wed, 3 Oct 2001 17:38:30 +0200 Subject: [PATCH 38/38] Cleanup between compilations --- BitKeeper/etc/logging_ok | 1 + Build-tools/Do-compile | 2 ++ 2 files changed, 3 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 062ef5c951e..c3643d477b3 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -2,3 +2,4 @@ Miguel@light.local monty@hundin.mysql.fi paul@central.snake.net serg@serg.mysql.com +monty@work.mysql.com diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 4cf2477f5bd..ba5a9403ecc 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -113,6 +113,8 @@ if ($opt_stage <= 1) $opt_config_options.=" --with-low-memory" if ($opt_with_low_memory); # Fix files if this is in another timezone than work.mysql.com unlink("config.cache"); + unlink("bdb/build_unix/config.cache"); + unlink("innobase/config.cache"); log_system("$make clean") if ($opt_use_old_distribution); if ($opt_static_server) {