diff options
35 files changed, 509 insertions, 261 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index 3de6d9f462f..34090190b44 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -19751,92 +19751,130 @@ The output resembles that shown here, though the format and numbers may differ somewhat: @example -+------------------------------+---------------------------+ -| Variable_name | Value | -+------------------------------+---------------------------+ -| ansi_mode | OFF | -| back_log | 50 | -| basedir | /my/monty/ | -| bdb_cache_size | 16777216 | -| bdb_log_buffer_size | 32768 | -| bdb_home | /my/monty/data/ | -| bdb_max_lock | 10000 | -| bdb_logdir | | -| bdb_shared_data | OFF | -| bdb_tmpdir | /tmp/ | -| binlog_cache_size | 32768 | -| bulk_insert_buffer_size | 8388608 | -| concurrent_insert | ON | -| connect_timeout | 5 | -| datadir | /my/monty/data/ | -| delay_key_write | ON | -| delayed_insert_limit | 100 | -| delayed_insert_timeout | 300 | -| delayed_queue_size | 1000 | -| flush | OFF | -| flush_time | 0 | -| ft_min_word_len | 4 | -| ft_max_word_len | 254 | -| ft_max_word_len_for_sort | 20 | -| ft_boolean_syntax | + -><()~* | -| have_bdb | YES | -| have_innodb | YES | -| have_raid | YES | -| have_openssl | NO | -| init_file | | -| interactive_timeout | 28800 | -| join_buffer_size | 131072 | -| key_buffer_size | 16776192 | -| language | /my/monty/share/english/ | -| large_files_support | ON | -| log | OFF | -| log_update | OFF | -| log_bin | OFF | -| log_slave_updates | OFF | -| long_query_time | 10 | -| low_priority_updates | OFF | -| lower_case_table_names | 0 | -| max_allowed_packet | 1048576 | -| max_binlog_cache_size | 4294967295 | -| max_connections | 100 | -| max_connect_errors | 10 | -| max_delayed_threads | 20 | -| max_heap_table_size | 16777216 | -| max_join_size | 4294967295 | -| max_sort_length | 1024 | -| max_tmp_tables | 32 | -| max_write_lock_count | 4294967295 | -| myisam_recover_options | DEFAULT | -| myisam_sort_buffer_size | 8388608 | -| net_buffer_length | 16384 | -| net_read_timeout | 30 | -| net_retry_count | 10 | -| net_write_timeout | 60 | -| open_files_limit | 0 | -| pid_file | /my/monty/data/donna.pid | -| port | 3306 | -| protocol_version | 10 | -| read_buffer_size | 131072 | -| query_cache_limit | 1048576 | -| query_cache_size | 16768060 | -| query_cache_type | 1 | -| safe_show_database | OFF | -| server_id | 0 | -| skip_locking | ON | -| skip_networking | OFF | -| skip_show_database | OFF | -| slow_launch_time | 2 | -| socket | /tmp/mysql.sock | -| sort_buffer | 2097116 | -| table_cache | 64 | -| table_type | MYISAM | -| thread_cache_size | 4 | -| thread_stack | 65536 | -| tmp_table_size | 1048576 | -| tmpdir | /tmp/ | -| version | 3.23.29a-gamma-debug | -| wait_timeout | 28800 | -+------------------------------+---------------------------+ ++---------------------------------+------------------------------+ +| Variable_name | Value | ++---------------------------------+------------------------------| +| back_log | 50 | +| basedir | /usr/local/mysql | +| bdb_cache_size | 8388572 | +| bdb_log_buffer_size | 32768 | +| bdb_home | /usr/local/mysql | +| bdb_max_lock | 10000 | +| bdb_logdir | | +| bdb_shared_data | OFF | +| bdb_tmpdir | /tmp/ | +| bdb_version | Sleepycat Software: ... | +| binlog_cache_size | 32768 | +| bulk_insert_buffer_size | 8388608 | +| character_set | latin1 | +| character_sets | latin1 big5 czech euc_kr | +| concurrent_insert | ON | +| connect_timeout | 5 | +| convert_character_set | | +| datadir | /usr/local/mysql/data/ | +| delay_key_write | ON | +| delayed_insert_limit | 100 | +| delayed_insert_timeout | 300 | +| delayed_queue_size | 1000 | +| flush | OFF | +| flush_time | 0 | +| ft_min_word_len | 4 | +| ft_max_word_len | 254 | +| ft_max_word_len_for_sort | 20 | +| ft_boolean_syntax | + -><()~*:""&| | +| have_bdb | YES | +| have_innodb | YES | +| have_isam | YES | +| have_raid | NO | +| have_symlink | DISABLED | +| have_openssl | YES | +| have_query_cache | YES | +| init_file | | +| innodb_additional_mem_pool_size | 1048576 | +| innodb_buffer_pool_size | 8388608 | +| innodb_data_file_path | ibdata1:10M:autoextend | +| innodb_data_home_dir | | +| innodb_file_io_threads | 4 | +| innodb_force_recovery | 0 | +| innodb_thread_concurrency | 8 | +| innodb_flush_log_at_trx_commit | 0 | +| innodb_fast_shutdown | ON | +| innodb_flush_method | | +| innodb_lock_wait_timeout | 50 | +| innodb_log_arch_dir | | +| innodb_log_archive | OFF | +| innodb_log_buffer_size | 1048576 | +| innodb_log_file_size | 5242880 | +| innodb_log_files_in_group | 2 | +| innodb_log_group_home_dir | ./ | +| innodb_mirrored_log_groups | 1 | +| interactive_timeout | 28800 | +| join_buffer_size | 131072 | +| key_buffer_size | 16773120 | +| language | /usr/local/mysql/share/... | +| large_files_support | ON | +| local_infile | ON | +| locked_in_memory | OFF | +| log | OFF | +| log_update | OFF | +| log_bin | OFF | +| log_slave_updates | OFF | +| log_slow_queries | OFF | +| log_warnings | OFF | +| long_query_time | 10 | +| low_priority_updates | OFF | +| lower_case_table_names | OFF | +| max_allowed_packet | 1047552 | +| max_binlog_cache_size | 4294967295 | +| max_binlog_size | 1073741824 | +| max_connections | 100 | +| max_connect_errors | 10 | +| max_delayed_threads | 20 | +| max_heap_table_size | 16777216 | +| max_join_size | 4294967295 | +| max_sort_length | 1024 | +| max_user_connections | 0 | +| max_tmp_tables | 32 | +| max_write_lock_count | 4294967295 | +| myisam_max_extra_sort_file_size | 268435456 | +| myisam_max_sort_file_size | 2147483647 | +| myisam_recover_options | force | +| myisam_sort_buffer_size | 8388608 | +| net_buffer_length | 16384 | +| net_read_timeout | 30 | +| net_retry_count | 10 | +| net_write_timeout | 60 | +| open_files_limit | 0 | +| pid_file | /usr/local/mysql/name.pid | +| port | 3306 | +| protocol_version | 10 | +| read_buffer_size | 131072 | +| read_rnd_buffer_size | 262144 | +| rpl_recovery_rank | 0 | +| query_cache_limit | 1048576 | +| query_cache_size | 0 | +| query_cache_type | ON | +| safe_show_database | OFF | +| server_id | 0 | +| slave_net_timeout | 3600 | +| skip_external_locking | ON | +| skip_networking | OFF | +| skip_show_database | OFF | +| slow_launch_time | 2 | +| socket | /tmp/mysql.sock | +| sort_buffer_size | 2097116 | +| sql_mode | 0 | +| table_cache | 64 | +| table_type | MYISAM | +| thread_cache_size | 3 | +| thread_stack | 131072 | +| tx_isolation | READ-COMMITTED | +| timezone | EEST | +| tmp_table_size | 33554432 | +| tmpdir | /tmp/ | +| version | 4.0.4-beta | +| wait_timeout | 28800 | ++---------------------------------+------------------------------+ @end example Each option is described here. Values for buffer sizes, lengths, and stack @@ -20339,8 +20377,13 @@ The directory used for temporary files and temporary tables. The version number for the server. @item @code{wait_timeout} -The number of seconds the server waits for activity on a connection before -closing it. See also @code{interactive_timeout}. +The number of seconds the server waits for activity on a not interactive +connection before closing it. + +On thread startup @code{SESSION.WAIT_TIMEOUT} is initialised from +@code{GLOBAL.WAIT_TIMEOUT} or @code{GLOBAL.INTERACTIVE_TIMEOUT} depending +on the type of client (as defined by the @code{CLIENT_INTERACTIVE} connect +option). See also @code{interactive_timeout}. @end itemize The manual section that describes tuning MySQL contains some @@ -20721,7 +20764,7 @@ When defining the character set, every word must be a number in hexadecimal format @item The @code{ctype} array takes up the first 257 words. The -@code{to_lower}, @code{to_upper} and @code{sort_order} arrays take up +@code{to_lower[]}, @code{to_upper[]} and @code{sort_order[]} arrays take up 256 words each after that. @end itemize @@ -20882,9 +20925,10 @@ multi-byte characters, you need to use the multi-byte character functions. Right now the best documentation on this is the character sets that are -already implemented. Look at the euc_kr, gb2312, gbk, sjis and ujis -character sets for examples. These are implemented in the -@code{ctype-'charset'.c} files in the @file{strings} directory. +already implemented. Look at the @code{euc_kr}, @code{gb2312}, +@code{gbk}, @code{sjis}, and @code{ujis} character sets for +examples. These are implemented in the @file{ctype-'charset'.c} files +in the @file{strings} directory. 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 @@ -20903,7 +20947,7 @@ Your program has a wrong path to where the character sets are stored. 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 +The character set is a multi-byte character set that can't be loaded dynamically. In this case you have to recompile the program with the support for the character set. @item @@ -20922,7 +20966,7 @@ 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 +For @code{MyISAM} tables, you can check the character set name and number for a table with @code{myisamchk -dvv table_name}. @@ -37076,7 +37120,8 @@ You can set the default global isolation level for @code{mysqld} with As of Version 3.23.23, MySQL has support for full-text indexing and searching. Full-text indexes in MySQL are an index of type -@code{FULLTEXT}. @code{FULLTEXT} indexes can be created from @code{VARCHAR} +@code{FULLTEXT}. @code{FULLTEXT} indexes are used with MyISAM tables +and can be created from @code{VARCHAR} and @code{TEXT} columns at @code{CREATE TABLE} time or added later with @code{ALTER TABLE} or @code{CREATE INDEX}. For large datasets, it will be much faster to load your data into a table that has no @code{FULLTEXT} @@ -39500,6 +39545,9 @@ transaction. * InnoDB Locks set:: Locks Set by Different SQL Statements in InnoDB * InnoDB Deadlock detection:: Deadlock Detection and Rollback * InnoDB Consistent read example:: An Example of How the Consistent Read Works in InnoDB +* Innodb deadlocks:: +* Innodb tuning:: +* Innodb Monitor:: @end menu @@ -39720,7 +39768,7 @@ set by the SQL statement may be preserved. This is because InnoDB stores row locks in a format where it cannot afterwards know which was set by which SQL statement. -@node InnoDB Consistent read example, , InnoDB Deadlock detection, InnoDB transaction model +@node InnoDB Consistent read example, Innodb deadlocks, InnoDB Deadlock detection, InnoDB transaction model @subsubsection An Example of How the Consistent Read Works in InnoDB When you issue a consistent read, that is, an ordinary @code{SELECT} @@ -39769,6 +39817,7 @@ use a locking read: SELECT * FROM t LOCK IN SHARE MODE; @end example +@node Innodb deadlocks, Innodb tuning, InnoDB Consistent read example, InnoDB transaction model @subsubsection How to cope with deadlocks? Deadlocks are a classic problem in transactional databases, @@ -39813,7 +39862,8 @@ and @code{UNLOCK TABLES} implicitly ends the transaction in a @code{COMMIT}. @end itemize -@subsection Performance Tuning Tips +@node Innodb tuning, Innodb Monitor, Innodb deadlocks, InnoDB transaction model +@subsubsection Performance Tuning Tips @strong{1.} If the Unix @file{top} or the Windows @file{Task Manager} shows that @@ -39900,11 +39950,12 @@ INSERT INTO yourtable VALUES (1, 2), (5, 5); This tip is of course valid for inserts into any table type, not just InnoDB. +@node Innodb Monitor, , Innodb tuning, InnoDB transaction model @subsubsection The InnoDB Monitor Starting from version 3.23.41 InnoDB includes the InnoDB Monitor which prints information on the InnoDB internal state. -When swithed on, InnoDB Monitor +When switched on, InnoDB Monitor will make the MySQL server @file{mysqld} to print data (note: the MySQL client will not print anything) to the standard @@ -40151,13 +40202,12 @@ index. Note that if the primary key is long, the secondary indexes will use more space. @menu -* InnoDB physical structure:: Physical Structure of an Index -* InnoDB Insert buffering:: Insert Buffering -* InnoDB Adaptive hash:: Adaptive Hash Indexes -* InnoDB Physical record:: Physical Record Structure +* InnoDB physical structure:: +* InnoDB Insert buffering:: +* InnoDB Adaptive hash:: +* InnoDB Physical record:: @end menu - @node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index @subsubsection Physical Structure of an Index @@ -41662,10 +41712,10 @@ through the @code{InConnectionString} argument in the @item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment} @item user @tab ODBC (on Windows) @tab The username used to connect to MySQL. @item server @tab localhost @tab The hostname of the MySQL server. -@item database @tab @tab The default database +@item database @tab @tab The default database. @item option @tab 0 @tab A integer by which you can specify how @code{MyODBC} should work. See below. @item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}. -@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}. +@item stmt @tab @tab A statement that will be executed when connecting to @code{MySQL}. @item password @tab @tab The password for the @code{server} @code{user} combination. @item socket @tab @tab The socket or Windows pipe to connect to. @end multitable @@ -44393,14 +44443,14 @@ if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) @end example By using @code{mysql_options()} the MySQL library will read the -@code{[client]} and @code{your_prog_name} sections in the @file{my.cnf} +@code{[client]} and @code{[your_prog_name]} sections in the @file{my.cnf} file which will ensure that your program will work, even if someone has set up MySQL in some non-standard way. Note that upon connection, @code{mysql_real_connect()} sets the @code{reconnect} -flag (part of the MYSQL structure) to a value of @code{1}. This flag indicates, -in the event that a query cannot be performed because of a lost connection, to -try reconnecting to the server before giving up. +flag (part of the @code{MYSQL} structure) to a value of @code{1}. This +flag indicates, in the event that a query cannot be performed because +of a lost connection, to try reconnecting to the server before giving up. @node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions @@ -46133,7 +46183,7 @@ is not the case, you should run the script @menu * UDF calling:: UDF Calling Sequences -* UDF aggr. calling :: UDF Calling Sequences for aggregate functions +* UDF aggr. calling:: * UDF arguments:: Argument Processing * UDF return values:: Return Values and Error Handling * UDF compiling:: Compiling and Installing User-definable Functions @@ -46250,7 +46300,7 @@ change! If you need memory, you should allocate it in @code{xxx_init()} and free it in @code{xxx_deinit()}. -@node UDF calling, UDF aggr. calling , Adding UDF, Adding UDF +@node UDF calling, UDF aggr. calling, Adding UDF, Adding UDF @subsubsection UDF Calling Sequences for simple functions @cindex calling sequences for simple functions, UDF @@ -46393,7 +46443,7 @@ into @code{*error}! This is just a 1 byte flag! If @code{isnull} or @code{error} are set after @code{xxx()} then MySQL will return @code{NULL} as the result for the group function. -@node UDF arguments, UDF return values, UDF aggr. calling , Adding UDF +@node UDF arguments, UDF return values, UDF aggr. calling, Adding UDF @subsubsection Argument Processing @cindex argument processing @@ -47555,7 +47605,7 @@ You can check which tables you have in the current database with @node Cannot initialize character set, Not enough file handles, Cannot find table, Common errors @appendixsubsec @code{Can't initialize character set xxx} error -@cindex multibyte character sets +@cindex multi-byte character sets If you get an error like: @@ -47663,7 +47713,7 @@ limits! In this case you should start @code{safe_mysqld} with @code{sh}! @menu * Link errors:: Problems When Linking with the MySQL Client Library * Changing MySQL user:: How to Run MySQL As a Normal User -* File permissions :: Problems with File Permissions +* File permissions:: @end menu @node Link errors, Changing MySQL user, Installation Issues, Installation Issues @@ -47736,7 +47786,7 @@ before linking your code. In the second case you should be sure that no other programs are using the dynamic libraries! -@node Changing MySQL user, File permissions , Link errors, Installation Issues +@node Changing MySQL user, File permissions, Link errors, Installation Issues @appendixsubsec How to Run MySQL As a Normal User @cindex starting, @code{mysqld} @@ -47930,12 +47980,6 @@ check whether things that work for others crash for you. Please try the following things: @itemize @bullet -@item -Cleaned up @code{NULL} handling for default values in @code{DESCRIBE -table_name}. -@item -Fixed @code{truncate()} to round up negative values to the nearest integer. -@item Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run @code{myisamchk --silent --force */*.MYI} on all tables, and restart the @code{mysqld} daemon. This will ensure that you are running from a clean @@ -50399,6 +50443,13 @@ each individual 4.0.x release. Fixed bug in @code{MATCH ... AGAINST( ... IN BOOLEAN MODE)} used with @code{ORDER BY}. @item +Added @code{LOCK TABLES} and @code{CREATE TEMPORARY TABLES} privilege on +the database level. One must run the @code{ mysql_fix_privilege_tables} +script on old installations to activate these. +@item +In @code{SHOW TABLE ... STATUS} compressed tables showed sometimes up as +@code{dynamic}. +@item @code{SELECT @@@@[global|session].var_name} didn't report @code{global | session} in the result column name. @item @@ -50614,6 +50665,11 @@ other databases. It is synonymous with @code{LOG(X)}. @itemize @bullet @item +Cleaned up @code{NULL} handling for default values in @code{DESCRIBE +table_name}. +@item +Fixed @code{truncate()} to round up negative values to the nearest integer. +@item Changed @code{--chroot=path} option to execute @code{chroot()} immediately after all options have been parsed. @item @@ -51193,6 +51249,9 @@ Multithreaded stress tests for InnoDB. @appendixsubsec Changes in release 3.23.52 (14 Aug 2002) @itemize @bullet @item +Wrap @code{BEGIN}/@code{COMMIT} around transaction in the binary log. +This makes replication honour transactions. +@item Fixed security bug when having an empty database name in the @code{user.db} table. @item @@ -51294,6 +51353,9 @@ Linux-x86 binaries. @itemize @bullet @item +Fixed buffer overflow problem if someone specified a too long datadir +parameter to mysqld +@item Add missing @code{<row>} tags for @code{mysqldump} XML output. @item Fixed problem with @code{crash-me} and @code{gcc} 3.0.4. diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 58b49a748ec..0b7add434c9 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2001 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ static FILE *result_file; static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif -void sql_print_error(const char *format,...); +void sql_print_error(const char *format, ...); static bool one_database = 0; static const char* database; @@ -138,7 +138,7 @@ This software comes with NO WARRANTY: This is free software,\n\ and you are welcome to modify and redistribute it under the GPL license\n"); printf("\ -Dumps a MySQL binary log in a format usable for viewing or for pipeing to\n\ +Dumps a MySQL binary log in a format usable for viewing or for piping to\n\ the mysql command line client\n\n"); printf("Usage: %s [options] log-files\n", my_progname); my_print_help(my_long_options); diff --git a/include/violite.h b/include/violite.h index 0e53a13aca0..f4f40dcb64b 100644 --- a/include/violite.h +++ b/include/violite.h @@ -175,7 +175,7 @@ struct st_VioSSLConnectorFd }; void sslaccept(struct st_VioSSLAcceptorFd*, Vio*, long timeout); -void sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout); +int sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout); struct st_VioSSLConnectorFd *new_VioSSLConnectorFd(const char* key_file, const char* cert_file, diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 25a7060883c..e35ff2ca69e 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -302,6 +302,9 @@ btr_cur_search_to_nth_level( rw_lock_s_unlock(&btr_search_latch); } + /* Store the position of the tree latch we push to mtr so that we + know how to release it when we have latched leaf node(s) */ + savepoint = mtr_set_savepoint(mtr); tree = index->tree; @@ -506,12 +509,18 @@ btr_cur_open_at_index_side( ulint root_height = 0; /* remove warning */ rec_t* node_ptr; ulint estimate; + ulint savepoint; estimate = latch_mode & BTR_ESTIMATE; latch_mode = latch_mode & ~BTR_ESTIMATE; tree = index->tree; + /* Store the position of the tree latch we push to mtr so that we + know how to release it when we have latched the leaf node */ + + savepoint = mtr_set_savepoint(mtr); + if (latch_mode == BTR_MODIFY_TREE) { mtr_x_lock(dict_tree_get_lock(tree), mtr); } else { @@ -544,6 +553,22 @@ btr_cur_open_at_index_side( if (height == 0) { btr_cur_latch_leaves(tree, page, space, page_no, latch_mode, cursor, mtr); + + /* In versions <= 3.23.52 we had forgotten to + release the tree latch here. If in an index scan + we had to scan far to find a record visible to the + current transaction, that could starve others + waiting for the tree latch. */ + + if ((latch_mode != BTR_MODIFY_TREE) + && (latch_mode != BTR_CONT_MODIFY_TREE)) { + + /* Release the tree s-latch */ + + mtr_release_s_latch_at_savepoint( + mtr, savepoint, + dict_tree_get_lock(tree)); + } } if (from_left) { diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 0297388c413..6f122f38107 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -2278,7 +2278,7 @@ consecutive_loop: ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: ERROR: The page to be written seems corrupt!\n"); - page_print(combined_buf + len2); + buf_page_print(combined_buf + len2); fprintf(stderr, "InnoDB: ERROR: The page to be written seems corrupt!\n"); } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index c1345de0d55..14677ede20f 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -49,6 +49,12 @@ os_event_create( TRUE, /* Manual reset */ FALSE, /* Initial state nonsignaled */ name); + if (!event) { + fprintf(stderr, +"InnoDB: Could not create a Windows event semaphore; Windows error %lu\n", + (ulint)GetLastError()); + } + ut_a(event); return(event); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index d0ac011e60f..95bcd2351cd 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2825,7 +2825,11 @@ background_loop: srv_main_thread_op_info = (char*)"purging"; - n_pages_purged = trx_purge(); + if (srv_fast_shutdown && srv_shutdown_state > 0) { + n_pages_purged = 0; + } else { + n_pages_purged = trx_purge(); + } srv_main_thread_op_info = (char*)"reserving kernel mutex"; @@ -2837,7 +2841,12 @@ background_loop: mutex_exit(&kernel_mutex); srv_main_thread_op_info = (char*)"doing insert buffer merge"; - n_bytes_merged = ibuf_contract_for_n_pages(TRUE, 20); + + if (srv_fast_shutdown && srv_shutdown_state > 0) { + n_bytes_merged = 0; + } else { + n_bytes_merged = ibuf_contract_for_n_pages(TRUE, 20); + } srv_main_thread_op_info = (char*)"reserving kernel mutex"; diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 4d14c32b1ae..4854b40409e 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -924,7 +924,7 @@ sync_array_print_long_waits(void) } if (cell->wait_object != NULL - && difftime(time(NULL), cell->reservation_time) > 420) { + && difftime(time(NULL), cell->reservation_time) > 600) { fprintf(stderr, "InnoDB: Error: semaphore wait has lasted > 600 seconds\n" diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index 6303c5bbcdd..34f56dba130 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -401,6 +401,10 @@ trx_undo_seg_create( slot_no = trx_rsegf_undo_find_free(rseg_hdr, mtr); if (slot_no == ULINT_UNDEFINED) { + ut_print_timestamp(stderr); + fprintf(stderr, +"InnoDB: Warning: cannot find a free slot for an undo log. Do you have too\n" +"InnoDB: many active transactions running concurrently?"); return(NULL); } @@ -1532,9 +1536,6 @@ trx_undo_assign_undo( mutex_exit(&(rseg->mutex)); mtr_commit(&mtr); - fprintf(stderr, "InnoDB: no undo log slots free\n"); - ut_a(0); - return(NULL); } } diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index f1083991d07..1afcc0d3147 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -514,6 +514,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) if (!opt_noacl) (void) grant_init(); init_max_user_conn(); + init_update_queries(); #ifdef HAVE_DLOPEN if (!opt_noacl) diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 104242cc3b1..8f90301d2d8 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (C) 1997, 1998, 1999 TCX DataKonsult AB & Monty Program KB & Detron HB +# Copyright (C) 1997-2002 MySQL AB # For a more info consult the file COPYRIGHT distributed with this file # This scripts creates the privilege tables db, host, user, tables_priv, @@ -85,13 +85,15 @@ then c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d PRIMARY KEY Host (Host,Db,User)," c_d="$c_d KEY User (User)" c_d="$c_d )" c_d="$c_d comment='Database privileges';" - i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y'); - INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');" + i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); + INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');" fi if test ! -f $mdata/host.frm @@ -109,6 +111,8 @@ then c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h PRIMARY KEY Host (Host,Db)" c_h="$c_h )" c_h="$c_h comment='Host privileges; Merged with database privileges';" diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index c77884adfb0..a1a0c91a575 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -34,3 +34,27 @@ Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA' delete from mysql.user where user='mysqltest_1'; flush privileges; +grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION; +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +delete from mysql.user where user='mysqltest_1'; +flush privileges; diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result new file mode 100644 index 00000000000..1caaf317c96 --- /dev/null +++ b/mysql-test/r/lowercase_table.result @@ -0,0 +1,15 @@ +drop table if exists t1,t2,t3; +create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); +INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); +SELECT * FROM t1; +id Word +1 a +2 b +3 c +RENAME TABLE T1 TO T2; +ALTER TABLE T2 ADD new_col int not null; +ALTER TABLE T2 RENAME T3; +show tables like 't_'; +Tables_in_test (t_) +t3 +drop table t3; diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index 40b4ca72f01..71a714c51d2 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -14,4 +14,4 @@ slave start; flush logs; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9307 60 slave-bin.001 79 mashka-relay-bin.001 119 slave-bin.001 Yes Yes 0 0 79 119 +127.0.0.1 root 9307 60 slave-bin.001 79 relay-log.001 119 slave-bin.001 Yes Yes 0 0 79 119 diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index c75069f8c55..7ee3b08cc3b 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -20,3 +20,22 @@ revoke all privileges on mysqltest.* from mysqltest_1@localhost; show grants for mysqltest_1@localhost; delete from mysql.user where user='mysqltest_1'; flush privileges; + +# +# Test that the new db privileges are stored/retrieved correctly +# + +grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +flush privileges; +show grants for mysqltest_1@localhost; +revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION; +flush privileges; +show grants for mysqltest_1@localhost; +revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +delete from mysql.user where user='mysqltest_1'; +flush privileges; diff --git a/mysql-test/t/lowercase_table-master.opt b/mysql-test/t/lowercase_table-master.opt new file mode 100644 index 00000000000..c718e2feb1b --- /dev/null +++ b/mysql-test/t/lowercase_table-master.opt @@ -0,0 +1 @@ +--lower_case_table_names diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test new file mode 100644 index 00000000000..0d04e6c7df7 --- /dev/null +++ b/mysql-test/t/lowercase_table.test @@ -0,0 +1,14 @@ +# +# Test of --lower-case-table-names +# + +drop table if exists t1,t2,t3; +create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); +INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); +SELECT * FROM t1; +RENAME TABLE T1 TO T2; +ALTER TABLE T2 ADD new_col int not null; +ALTER TABLE T2 RENAME T3; +show tables like 't_'; +drop table t3; + diff --git a/mysql-test/t/rpl_flush_log_loop-master.opt b/mysql-test/t/rpl_flush_log_loop-master.opt index eb35347af33..4f6e0f3d00c 100644 --- a/mysql-test/t/rpl_flush_log_loop-master.opt +++ b/mysql-test/t/rpl_flush_log_loop-master.opt @@ -1 +1 @@ --O max_binlog_size=1M +-O max_binlog_size=1M --relay-log=$MYSQL_TEST_DIR/var/master-data/relay-log diff --git a/mysql-test/t/rpl_flush_log_loop-master.sh b/mysql-test/t/rpl_flush_log_loop-master.sh new file mode 100755 index 00000000000..9e56af99f5c --- /dev/null +++ b/mysql-test/t/rpl_flush_log_loop-master.sh @@ -0,0 +1,5 @@ +rm -f $MYSQL_TEST_DIR/var/slave-data/*-bin.* +rm -f $MYSQL_TEST_DIR/var/slave-data/master.info +rm -f $MYSQL_TEST_DIR/var/slave-data/*.index + + diff --git a/mysql-test/t/rpl_flush_log_loop-slave.opt b/mysql-test/t/rpl_flush_log_loop-slave.opt index eb35347af33..d1373f139b1 100644 --- a/mysql-test/t/rpl_flush_log_loop-slave.opt +++ b/mysql-test/t/rpl_flush_log_loop-slave.opt @@ -1 +1 @@ --O max_binlog_size=1M +-O max_binlog_size=1M --relay-log=$MYSQL_TEST_DIR/var/slave-data/relay-log diff --git a/mysql-test/t/rpl_flush_log_loop-slave.sh b/mysql-test/t/rpl_flush_log_loop-slave.sh new file mode 100755 index 00000000000..b8814e059a9 --- /dev/null +++ b/mysql-test/t/rpl_flush_log_loop-slave.sh @@ -0,0 +1,4 @@ +rm -f $MYSQL_TEST_DIR/var/master-data/master.info +rm -f $MYSQL_TEST_DIR/var/master-data/*-bin.* +rm -f $MYSQL_TEST_DIR/var/master-data/*.index + diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index a492066235b..74e00e2c75a 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -137,7 +137,7 @@ EOF echo "" # -# Change the user table to MySQL 4.0 format +# Change the user,db and host tables to MySQL 4.0 format # echo "Adding new fields used by MySQL 4.0.2 to the privilege tables" @@ -174,3 +174,16 @@ add max_questions int(11) NOT NULL AFTER x509_subject, add max_updates int(11) unsigned NOT NULL AFTER max_questions, add max_connections int(11) unsigned NOT NULL AFTER max_updates; END_OF_DATA + +# +# Add Create_tmp_table_priv and Lock_tables_priv to db and host +# + +@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA +alter table db +add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, +add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; +alter table host +add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, +add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; +END_OF_DATA diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 6ac54256124..2f27f5d7c1a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -171,13 +171,15 @@ then c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_d="$c_d PRIMARY KEY Host (Host,Db,User)," c_d="$c_d KEY User (User)" c_d="$c_d )" c_d="$c_d comment='Database privileges';" - i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y'); - INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');" + i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); + INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');" fi if test ! -f $mdata/host.frm @@ -197,6 +199,8 @@ then c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," c_h="$c_h PRIMARY KEY Host (Host,Db)" c_h="$c_h )" c_h="$c_h comment='Host privileges; Merged with database privileges';" diff --git a/sql/filesort.cc b/sql/filesort.cc index c6782aa0d93..d8fcb0292ff 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -370,13 +370,18 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, { if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile)) DBUG_RETURN(HA_POS_ERROR); - idx=0; indexpos++; + idx=0; if (param->ref_length == param->sort_length && my_b_tell(tempfile)/param->sort_length >= param->max_rows) { + /* + We are writing the result index file and have found all + rows that we need. Abort the sort and return the result. + */ error=HA_ERR_END_OF_FILE; break; /* Found enough records */ } + indexpos++; } make_sortkey(param,sort_keys[idx++],ref_pos); } @@ -391,7 +396,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ } - if (indexpos && + if (indexpos && idx && write_keys(param,sort_keys,idx,buffpek_pointers,tempfile)) DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ DBUG_RETURN(my_b_inited(tempfile) ? @@ -759,7 +764,11 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, } buffpek->key+=sort_length; buffpek->mem_count--; - max_rows--; + if (!--max_rows) + { + error=0; /* purecov: inspected */ + goto end; /* purecov: inspected */ + } queue_replaced(&queue); // Top element has been used } else diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 64c9ecbcb7a..e1ffb06d5fc 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -101,11 +101,18 @@ char* innobase_unix_file_flush_method = NULL; /* Below we have boolean-valued start-up parameters, and their default values */ -uint innobase_flush_log_at_trx_commit = 0; my_bool innobase_log_archive = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; +/* innodb_flush_log_at_trx_commit can now have 3 values: +0 : write to the log file once per second and flush it to disk; +1 : write to the log file at each commit and flush it to disk; +2 : write to the log file at each commit, but flush to disk only once per +second */ + +uint innobase_flush_log_at_trx_commit = 0; + /* Set default InnoDB data file size to 10 MB and let it be auto-extending. Thus users can use InnoDB without having to @@ -2004,7 +2011,11 @@ convert_search_mode_to_innobase( case HA_READ_AFTER_KEY: return(PAGE_CUR_G); case HA_READ_BEFORE_KEY: return(PAGE_CUR_L); case HA_READ_PREFIX: return(PAGE_CUR_GE); - case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE); + case HA_READ_PREFIX_LAST: ut_a(0); return(PAGE_CUR_LE); + /* InnoDB does not yet support ..PREFIX_LAST! + We have to add a new search flag + PAGE_CUR_LE_OR_PREFIX to InnoDB. */ + /* the above PREFIX flags mean that the last field in the key value may just be a prefix of the complete fixed length field */ @@ -2079,7 +2090,10 @@ ha_innobase::index_read( start or end of index; this can also contain an InnoDB row id, in which case key_len is the InnoDB - row id length */ + row id length; the key value can + also be a prefix of a full key value, + and the last column can be a prefix + of a full column */ uint key_len,/* in: key value length */ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */ { @@ -2169,24 +2183,24 @@ ha_innobase::index_read( DBUG_RETURN(error); } - -/* - The following functions works like index_read, but it find the last - row with the current index prefix. - This code is disabled until Heikki has verified that InnoDB support the - HA_READ_PREFIX_LAST flag and removed the HA_NOT_READ_PREFIX_LAST - flag from ha_innodb.h -*/ +/*********************************************************************** +The following functions works like index_read, but it find the last +row with the current key value or prefix. */ int -ha_innobase::index_read_last(mysql_byte *buf, - const mysql_byte *key_ptr, - uint key_len) +ha_innobase::index_read_last( +/*=========================*/ + /* out: 0, HA_ERR_KEY_NOT_FOUND, or an + error code */ + mysql_byte* buf, /* out: fetched row */ + const mysql_byte* key_ptr, /* in: key value, or a prefix of a full + key value */ + uint key_len) /* in: length of the key val or prefix + in bytes */ { - return index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST); + return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST)); } - /************************************************************************ Changes the active index of a handle. */ diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index d70a58c75f1..8994359c2a7 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -96,7 +96,7 @@ class ha_innobase: public handler ulong index_flags(uint idx) const { return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | - HA_NOT_READ_PREFIX_LAST | HA_KEY_READ_ONLY); + HA_KEY_READ_ONLY | HA_NOT_READ_PREFIX_LAST); } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f2a59a8e77e..05157cbd9b8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -309,6 +309,7 @@ void mysql_init_select(LEX *lex); bool mysql_new_select(LEX *lex); void mysql_init_multi_delete(LEX *lex); void init_max_user_conn(void); +void init_update_queries(void); void free_max_user_conn(void); pthread_handler_decl(handle_one_connection,arg); pthread_handler_decl(handle_bootstrap,arg); @@ -676,11 +677,14 @@ extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb; - #ifndef __WIN__ extern pthread_t signal_thread; #endif +#ifdef HAVE_OPENSSL +extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; +#endif /* HAVE_OPENSSL */ + MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count); void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 75e6368712a..94d9efa9108 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2049,6 +2049,7 @@ int main(int argc, char **argv) if (!opt_noacl) (void) grant_init(); init_max_user_conn(); + init_update_queries(); #ifdef HAVE_DLOPEN if (!opt_noacl) @@ -3036,10 +3037,10 @@ struct my_option my_long_options[] = "Set to 1 if you want to have logs archived", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, - "Set to 0 if you don't want to flush logs", + "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second)", (gptr*) &innobase_flush_log_at_trx_commit, (gptr*) &innobase_flush_log_at_trx_commit, - 0, GET_INT, OPT_ARG, 0, 0, 2, 0, 0, 0}, + 0, GET_UINT, OPT_ARG, 0, 0, 2, 0, 0, 0}, {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD, "With which method to flush data", (gptr*) &innobase_unix_file_flush_method, (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index c44fe2d053d..8d90611adb7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -114,32 +114,6 @@ static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, const char *ip); -extern char uc_update_queries[SQLCOM_END]; - -static void init_update_queries(void) -{ - uc_update_queries[SQLCOM_CREATE_TABLE]=1; - uc_update_queries[SQLCOM_CREATE_INDEX]=1; - uc_update_queries[SQLCOM_ALTER_TABLE]=1; - uc_update_queries[SQLCOM_UPDATE]=1; - uc_update_queries[SQLCOM_INSERT]=1; - uc_update_queries[SQLCOM_INSERT_SELECT]=1; - uc_update_queries[SQLCOM_DELETE]=1; - uc_update_queries[SQLCOM_TRUNCATE]=1; - uc_update_queries[SQLCOM_DROP_TABLE]=1; - uc_update_queries[SQLCOM_LOAD]=1; - uc_update_queries[SQLCOM_CREATE_DB]=1; - uc_update_queries[SQLCOM_DROP_DB]=1; - uc_update_queries[SQLCOM_REPLACE]=1; - uc_update_queries[SQLCOM_REPLACE_SELECT]=1; - uc_update_queries[SQLCOM_RENAME_TABLE]=1; - uc_update_queries[SQLCOM_BACKUP_TABLE]=1; - uc_update_queries[SQLCOM_RESTORE_TABLE]=1; - uc_update_queries[SQLCOM_DELETE_MULTI]=1; - uc_update_queries[SQLCOM_DROP_INDEX]=1; - uc_update_queries[SQLCOM_MULTI_UPDATE]=1; -} - /* Read grant privileges from the privilege tables in the 'mysql' database. @@ -214,7 +188,7 @@ my_bool acl_init(bool dont_read_acl_tables) if (table->fields == 8) { // Without grant if (host.access & CREATE_ACL) - host.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL; + host.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL; } #endif VOID(push_dynamic(&acl_hosts,(gptr) &host)); @@ -350,7 +324,6 @@ my_bool acl_init(bool dont_read_acl_tables) mysql_unlock_tables(thd, lock); initialized=1; - init_update_queries(); thd->version--; // Force close to free memory return_val=0; @@ -1339,6 +1312,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, strlen(thd->lex.x509_subject)); break; case SSL_TYPE_NOT_SPECIFIED: + case SSL_TYPE_NONE: // Impossible break; // Nothing to do } diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 0448adc8b1c..326a55ddd0c 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -40,7 +40,7 @@ #define DB_ACLS \ (UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL) + GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | LOCK_TABLES_ACL) #define TABLE_ACLS \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ @@ -59,10 +59,21 @@ #define EXTRA_ACL (1L << 29) #define NO_ACCESS (1L << 30) -/* defines to change the above bits to how things are stored in tables */ +/* + Defines to change the above bits to how things are stored in tables + This is needed as the 'host' and 'db' table is missing a few privileges +*/ + +/* Continius bit-segments that needs to be shifted */ +#define DB_REL1 (RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL) +#define DB_REL2 (GRANT_ACL | REFERENCES_ACL) + +/* Privileges that needs to be reallocated (in continous chunks) */ +#define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL) +#define DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL) -#define fix_rights_for_db(A) (((A) & 63) | (((A) & ~63) << 4)) -#define get_rights_for_db(A) (((A) & 63) | (((A) & ~63) >> 4)) +#define fix_rights_for_db(A) (((A) & 63) | (((A) & DB_REL1) << 4) | (((A) & DB_REL2) << 6)) +#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6)) #define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4)) #define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4)) #define fix_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) << 7)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2973e7bd1b1..d394cfa91bb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -80,10 +80,6 @@ const char *command_name[]={ bool volatile abort_slave = 0; -#ifdef HAVE_OPENSSL -extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; -#endif /* HAVE_OPENSSL */ - #ifdef __WIN__ static void test_signal(int sig_ptr) { @@ -331,6 +327,38 @@ void free_max_user_conn(void) /* + Mark all commands that somehow changes a table + This is used to check number of updates / hour +*/ + +char uc_update_queries[SQLCOM_END]; + +void init_update_queries(void) +{ + uc_update_queries[SQLCOM_CREATE_TABLE]=1; + uc_update_queries[SQLCOM_CREATE_INDEX]=1; + uc_update_queries[SQLCOM_ALTER_TABLE]=1; + uc_update_queries[SQLCOM_UPDATE]=1; + uc_update_queries[SQLCOM_INSERT]=1; + uc_update_queries[SQLCOM_INSERT_SELECT]=1; + uc_update_queries[SQLCOM_DELETE]=1; + uc_update_queries[SQLCOM_TRUNCATE]=1; + uc_update_queries[SQLCOM_DROP_TABLE]=1; + uc_update_queries[SQLCOM_LOAD]=1; + uc_update_queries[SQLCOM_CREATE_DB]=1; + uc_update_queries[SQLCOM_DROP_DB]=1; + uc_update_queries[SQLCOM_REPLACE]=1; + uc_update_queries[SQLCOM_REPLACE_SELECT]=1; + uc_update_queries[SQLCOM_RENAME_TABLE]=1; + uc_update_queries[SQLCOM_BACKUP_TABLE]=1; + uc_update_queries[SQLCOM_RESTORE_TABLE]=1; + uc_update_queries[SQLCOM_DELETE_MULTI]=1; + uc_update_queries[SQLCOM_DROP_INDEX]=1; + uc_update_queries[SQLCOM_MULTI_UPDATE]=1; +} + + +/* Check if maximum queries per hour limit has been reached returns 0 if OK. @@ -339,7 +367,6 @@ void free_max_user_conn(void) a couple of queries, this isn't critical. */ -char uc_update_queries[SQLCOM_END]; static bool check_mqh(THD *thd, uint check_command) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index bf9abaaa32d..7f6905279d0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -322,10 +322,10 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); net_store_data(packet, convert, file->table_type()); net_store_data(packet, convert, + (table->db_options_in_use & HA_OPTION_COMPRESS_RECORD) ? + "Compressed" : (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - "Dynamic" : - (table->db_options_in_use & HA_OPTION_COMPRESS_RECORD) - ? "Compressed" : "Fixed"); + "Dynamic" : "Fixed"); net_store_data(packet, (longlong) file->records); net_store_data(packet, (uint32) file->mean_rec_length); net_store_data(packet, (longlong) file->data_file_length); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 021f3f07ad5..cf03288860f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -866,7 +866,7 @@ bool close_cached_table(THD *thd,TABLE *table) if (table) { - DBUG_PRINT("enter",("table: %s", table->table_name)); + DBUG_PRINT("enter",("table: %s", table->real_name)); VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files /* Mark all tables that are in use as 'old' */ mysql_lock_abort(thd,table); // end threads waiting on lock @@ -874,7 +874,7 @@ bool close_cached_table(THD *thd,TABLE *table) #if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2) /* Wait until all there are no other threads that has this table open */ while (remove_table_from_cache(thd,table->table_cache_key, - table->table_name)) + table->real_name)) { dropping_tables++; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); @@ -882,7 +882,7 @@ bool close_cached_table(THD *thd,TABLE *table) } #else (void) remove_table_from_cache(thd,table->table_cache_key, - table->table_name); + table->real_name); #endif /* When lock on LOCK_open is freed other threads can continue */ pthread_cond_broadcast(&COND_refresh); @@ -932,7 +932,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, { char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char* table_name = table->name; + char* table_name = table->real_name; char* db = thd->db ? thd->db : table->db; if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, diff --git a/vio/viosocket.c b/vio/viosocket.c index 2c6cdb5a7fd..f69eebd413a 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -120,7 +120,6 @@ int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode, DBUG_PRINT("enter", ("set_blocking_mode: %d old_mode: %d", (int) set_blocking_mode, (int) *old_mode)); -#if !defined(HAVE_OPENSSL) #if !defined(___WIN__) && !defined(__EMX__) #if !defined(NO_FCNTL_NONBLOCK) if (vio->sd >= 0) @@ -161,7 +160,6 @@ int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode, r= test(!(vio->fcntl_mode & O_NONBLOCK)) != set_blocking_mode; #endif /* __EMX__ */ #endif /* !defined(__WIN__) && !defined(__EMX__) */ -#endif /* !defined (HAVE_OPENSSL) */ DBUG_PRINT("exit", ("%d", r)); DBUG_RETURN(r); } diff --git a/vio/viossl.c b/vio/viossl.c index 6d4f5450148..56d3da8a1ac 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -44,28 +44,30 @@ report_errors() unsigned long l; const char* file; const char* data; - int line,flags, any_ssl_error = 0; + int line,flags; DBUG_ENTER("report_errors"); - while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) + while ((l=ERR_get_error_line_data(&file,&line,&data,&flags))) { - char buf[200]; - any_ssl_error = 1; + char buf[512]; DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf), file,line,(flags&ERR_TXT_STRING)?data:"")) ; } - if (!any_ssl_error) { - DBUG_PRINT("info", ("No OpenSSL errors.")); - } - DBUG_PRINT("info", ("BTW, errno=%d", socket_errno)); + DBUG_PRINT("info", ("errno: %d", socket_errno)); DBUG_VOID_RETURN; } +/* + Delete a vio object + + SYNPOSIS + vio_ssl_delete() + vio Vio object. May be 0. +*/ + void vio_ssl_delete(Vio * vio) { - /* It must be safe to delete null pointers. */ - /* This matches the semantics of C++'s delete operator. */ if (vio) { if (vio->type != VIO_CLOSED) @@ -74,6 +76,7 @@ void vio_ssl_delete(Vio * vio) } } + int vio_ssl_errno(Vio *vio __attribute__((unused))) { return socket_errno; /* On Win32 this mapped to WSAGetLastError() */ @@ -87,17 +90,12 @@ int vio_ssl_read(Vio * vio, gptr buf, int size) DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d, ssl_=%p", vio->sd, buf, size, vio->ssl_)); -#ifndef DBUG_OFF - errno = 0; -#endif /* DBUG_OFF */ - r = SSL_read(vio->ssl_, buf, size); -#ifndef DBUG_OFF - if ( r<= 0) { - r=SSL_get_error(vio->ssl_, r); - DBUG_PRINT("info",("SSL_get_error returned %d",r)); + if ((r= SSL_read(vio->ssl_, buf, size)) < 0) + { + int err= SSL_get_error(vio->ssl_, r); + DBUG_PRINT("error",("SSL_read(): %d SSL_get_error(): %d", r, err)); report_errors(); } -#endif /* DBUG_OFF */ DBUG_PRINT("exit", ("%d", r)); DBUG_RETURN(r); } @@ -109,14 +107,8 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size) DBUG_ENTER("vio_ssl_write"); DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); -#ifndef DBUG_OFF - errno = 0; -#endif /* DBUG_OFF */ - r = SSL_write(vio->ssl_, buf, size); -#ifndef DBUG_OFF - if (r<0) + if ((r= SSL_write(vio->ssl_, buf, size)) < 0) report_errors(); -#endif /* DBUG_OFF */ DBUG_PRINT("exit", ("%d", r)); DBUG_RETURN(r); } @@ -124,7 +116,7 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size) int vio_ssl_fastsend(Vio * vio __attribute__((unused))) { - int r=0; + int r= 0; DBUG_ENTER("vio_ssl_fastsend"); #ifdef IPTOS_THROUGHPUT @@ -148,19 +140,18 @@ int vio_ssl_fastsend(Vio * vio __attribute__((unused))) DBUG_RETURN(r); } + int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive) { int r=0; - uint opt = 0; DBUG_ENTER("vio_ssl_keepalive"); DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int) set_keep_alive)); if (vio->type != VIO_TYPE_NAMEDPIPE) { - if (set_keep_alive) - opt = 1; - r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, - sizeof(opt)); + uint opt = (set_keep_alive) ? 1 : 0; + r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, + sizeof(opt)); } DBUG_RETURN(r); } @@ -186,10 +177,13 @@ int vio_ssl_close(Vio * vio) SSL_free(vio->ssl_); vio->ssl_= 0; } - if (shutdown(vio->sd,2)) - r= -1; - if (closesocket(vio->sd)) - r= -1; + if (vio->sd >= 0) + { + if (shutdown(vio->sd, 2)) + r= -1; + if (closesocket(vio->sd)) + r= -1; + } if (r) { DBUG_PRINT("error", ("close() failed, error: %d",socket_errno)); @@ -254,6 +248,10 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in) } +/* + TODO: Add documentation and error handling +*/ + void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) { char *str; @@ -263,6 +261,7 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) DBUG_ENTER("sslaccept"); DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr)); + vio_blocking(vio, 1, &unused); /* Must be called before reset */ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio->ssl_=0; vio->open_=FALSE; @@ -274,7 +273,6 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) } DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout)); SSL_clear(vio->ssl_); - vio_blocking(vio, FALSE, &unused); SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd(vio->ssl_,vio->sd); SSL_set_accept_state(vio->ssl_); @@ -284,7 +282,8 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" ,SSL_get_cipher_name(vio->ssl_))); client_cert = SSL_get_peer_certificate (vio->ssl_); - if (client_cert != NULL) { + if (client_cert != NULL) + { DBUG_PRINT("info",("Client certificate:")); str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); DBUG_PRINT("info",("\t subject: %s", str)); @@ -295,11 +294,12 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) free (str); X509_free (client_cert); - } else + } + else DBUG_PRINT("info",("Client does not have certificate.")); str=SSL_get_shared_ciphers(vio->ssl_, buf, sizeof(buf)); - if(str) + if (str) { DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str)); } @@ -313,7 +313,7 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) } -void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) +int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) { char *str; X509* server_cert; @@ -321,6 +321,7 @@ void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) DBUG_ENTER("sslconnect"); DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_)); + vio_blocking(vio, 1, &unused); /* Must be called before reset */ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio->ssl_=0; vio->open_=FALSE; @@ -328,11 +329,10 @@ void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) { DBUG_PRINT("error", ("SSL_new failure")); report_errors(); - DBUG_VOID_RETURN; + DBUG_RETURN(1); } DBUG_PRINT("info", ("ssl_=%p timeout=%ld",vio->ssl_, timeout)); SSL_clear(vio->ssl_); - vio_blocking(vio, FALSE, &unused); SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd (vio->ssl_, vio->sd); SSL_set_connect_state(vio->ssl_); @@ -342,24 +342,27 @@ void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" ,SSL_get_cipher_name(vio->ssl_))); server_cert = SSL_get_peer_certificate (vio->ssl_); - if (server_cert != NULL) { + if (server_cert != NULL) + { DBUG_PRINT("info",("Server certificate:")); str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0); DBUG_PRINT("info",("\t subject: %s", str)); - free (str); + free(str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0); DBUG_PRINT("info",("\t issuer: %s", str)); - free (str); - - /* We could do all sorts of certificate verification stuff here before - * deallocating the certificate. */ + free(str); + /* + We could do all sorts of certificate verification stuff here before + deallocating the certificate. + */ X509_free (server_cert); - } else + } + else DBUG_PRINT("info",("Server does not have certificate.")); #endif - DBUG_VOID_RETURN; + DBUG_RETURN(0); } |