patch enclosed)
One call to my_error_unregister_all() would free pointers, but leave one
pointer to just-freed memory still assigned. That's the bug. Subsequent
calls of this function would try to follow pointers into deallocated,
garbage memory and almost certainly SEGV.
Now, after freeing a linked list, unset the initial pointer.
Took the Xfree implementation (based on the same rewrite as the NDB one)
and added it instead of the current implementation.
Added a macro to make the calls to MD5 more streamlined.
When disk is full, server may waiting for free space while
writing binlog, relay-log or MyISAM tables. The server will
continue after user have freed some space. But the error
message printed was not quite clear about the how often the
error message is printed, and there will be a delay before
the server continue and user freeing space. And caused users
thinking that the server was hanging forever.
This patch fixed the problem by making the error messages
printed more clear. The error message is split into two part,
the first part will only be printed once, and the second part
will be printed very 10 times.
Message first part:
Disk is full writing '<filename>' (Errcode: <errorno>). Waiting
for someone to free space... (Expect up to 60 secs delay for
server to continue after freeing disk space)
Message second part:
Retry in 60 secs, Message reprinted in 600 secs
in load_defaults()
load_defaults(), my_search_option_files() and
my_print_default_files() utilized a global variable
containing a pointer to thread local memory. This could lead
to race conditions when those functions were called with high
concurrency.
Fixed by changing the interface of the said functions to avoid
the necessity for using a global variable.
Since we cannot change load_defaults() prototype for API
compatibility reasons, it was renamed my_load_defaults().
Now load_defaults() is a thread-unsafe wrapper around
a thread-safe version, my_load_defaults().
- Remove bothersome warning messages. This change focuses on the warnings
that are covered by the ignore file: support-files/compiler_warnings.supp.
- Strings are guaranteed to be max uint in length
- Remove bothersome warning messages. This change focuses on the warnings
that are covered by the ignore file: support-files/compiler_warnings.supp.
- Strings are guaranteed to be max uint in length
code backported from 6.0
per-file messages:
include/my_global.h
Remove SC_MAXWIDTH. This is unused and irrelevant nowadays.
include/my_sys.h
Remove errbuf declaration and unused definitions.
mysys/my_error.c
Remove errbuf definition and move and adjust ERRMSGSIZE.
mysys/my_init.c
Declare buffer on the stack and use my_snprintf.
mysys/safemalloc.c
Use size explicitly. It's more than enough for the message at hand.
sql/sql_error.cc
Use size explicitly. It's more than enough for the message at hand.
sql/sql_parse.cc
Declare buffer on the stack. Use my_snprintf as it will result in
less stack space being used than by a system provided sprintf --
this allows us to put the buffer on the stack without causing much
trouble. Also, the use of errbuff here was not thread-safe as the
function can be entered concurrently from multiple threads.
sql/sql_table.cc
Use MYSQL_ERRMSG_SIZE. Extra space is not needed as my_snprintf will
nul terminate strings.
storage/myisam/ha_myisam.cc
Use MYSQL_ERRMSG_SIZE.
sql/share/errmsg.txt
Error message truncation in test "innodb" in embedded mode
filename in the error message can safely take up to 210 symbols.
upgrading lock, even with low_priority_updates
The problem is that there is no mechanism to control whether a
delayed insert takes a high or low priority lock on a table.
The solution is to modify the delayed insert thread ("handler")
to take into account the global value of low_priority_updates
when taking table locks. The value of low_priority_updates is
retrieved when the insert delayed thread is created and will
remain the same for the duration of the thread.
Replaced abs_top_srcdir with top_srcdir, not sure it's an
improvement but at least it's known that abs_top_srcdir
in cases have a problem and this is a more common variable
to use for the same purpose.
Problem:
Custom UCA collations didn't set the MY_CS_STRNXFRM flag,
which resulted in "prefix_search" method instead of
the required "seq_search".
Problem2: (not metioned in the bug report)
Custom UCA collations didn't also set the MY_CS_UNICODE flag,
so an attempt to compare a column with a custom UCA collation
to another column with a non-Unicode character set led to
the "illegal mix of collation" error.
Fix:
the two missing flags was added into collation initialization.
Upgrade:
- All fulltext indexes with custom UCA collations should be rebuilt.
- Non-fulltext custom UCA indexes should likely be rebuild as well.
conflicts:
Text conflict in client/mysqltest.cc
Text conflict in mysql-test/include/wait_until_connected_again.inc
Text conflict in mysql-test/lib/mtr_report.pm
Text conflict in mysql-test/mysql-test-run.pl
Text conflict in mysql-test/r/events_bugs.result
Text conflict in mysql-test/r/log_state.result
Text conflict in mysql-test/r/myisam_data_pointer_size_func.result
Text conflict in mysql-test/r/mysqlcheck.result
Text conflict in mysql-test/r/query_cache.result
Text conflict in mysql-test/r/status.result
Text conflict in mysql-test/suite/binlog/r/binlog_index.result
Text conflict in mysql-test/suite/binlog/r/binlog_innodb.result
Text conflict in mysql-test/suite/rpl/r/rpl_packet.result
Text conflict in mysql-test/suite/rpl/t/rpl_packet.test
Text conflict in mysql-test/t/disabled.def
Text conflict in mysql-test/t/events_bugs.test
Text conflict in mysql-test/t/log_state.test
Text conflict in mysql-test/t/myisam_data_pointer_size_func.test
Text conflict in mysql-test/t/mysqlcheck.test
Text conflict in mysql-test/t/query_cache.test
Text conflict in mysql-test/t/rpl_init_slave_func.test
Text conflict in mysql-test/t/status.test
Bug#36428: MY_MUTEX_INIT_FAST is used before initialization
On some thread implementations, we need a fake mutex attri-
bute as a placeholder, which we define as a global variable,
"my_fast_mutexattr". Well. that must be initialized before
used in any mutexes, and the ordering of initializations in
the API function my_init() was wrong.
Now, put my_thread_global_init(), which initializes the attri-
butes that mutexes require.
Bounds-checks and blocksize corrections were applied to user-input,
but constants in the server were trusted implicitly. If these values
did not actually meet the requirements, the user could not set change
a variable, then set it back to the (wonky) factory default or maximum
by explicitly specifying it (SET <var>=<value> vs SET <var>=DEFAULT).
Now checks also apply to the server's presets. Wonky values and maxima
get corrected at startup. Consequently all non-offsetted values the user
sees are valid, and users can set the variable to that exact value if
they so desire.
The problem here is that embedded server starts handle_thread manager
thread on mysql_library_init() does not stop it on mysql_library_end().
At shutdown, my_thread_global_end() waits for thread count to become 0,
but since we did not stop the thread it will give up after 5 seconds.
Solution is to move shutdown for handle_manager thread from kill_server()
(mysqld specific) to clean_up() that is used by both embedded and mysqld.
This patch also contains some refactorings - to avoid duplicate code,
start_handle_manager() and stop_handle_manager() functions are introduced.
Unused variables are eliminated. handle_manager does not rely on global
variable abort_loop anymore to stop (abort_loop is not set for embedded).
Note: Specifically on Windows and when using DBUG version of libmysqld,
the complete solution requires removing obsolete code my_thread_init()
from my_thread_var(). This has a side effect that a DBUG statement
after my_thread_end() can cause thread counter to be incremented, and
embedded will hang for some seconds. Or worse, my_thread_init() will
crash if critical sections have been deleted by the global cleanup
routine that runs in a different thread.
This patch also fixes and revert prior changes for Bug#38293
"Libmysqld crash in mysql_library_init if language file missing".
Root cause of the crash observed in Bug#38293 was bug in my_thread_init()
described above
That's a Win-specific error.
When we create libmysqld.dll we have many libraries like mysys, dbug,
strings, etc linked into that dll, so the application built upon
this library shouldn't link these libraries to itself, rather use
those inside the dll.
Fixed by redirecting calls into the libmysqld.dll
per-file comments:
dbug/dbug.c
Bug#38293 Libmysqld crash in mysql_library_init if language file missing
fake _db_something definitions added
include/my_dbug.h
Bug#38293 Libmysqld crash in mysql_library_init if language file missing
fake _db_something declarations added
libmysqld/examples/CMakeLists.txt
Bug#38293 Libmysqld crash in mysql_library_init if language file missing
superfluous libraries removed from linking
libmysqld/libmysqld.def
Bug#38293 Libmysqld crash in mysql_library_init if language file missing
set of mysys functions added to the export section
japanese characters.
Fix - removed obsolvete setlocale from my_init.c . In MBCS
environments it caused unwanted character-to-byte translations
in fputc() in client code and wrong output as result.
#ifdef HAVE_purify removed
per-file comments:
mysql-test/t/partition_not_windows.test
Bug#39102 valgrind build does not compile in realpath, which make DATA/INDEX DIR fail
test reenabled
mysys/my_symlink.c
Bug#39102 valgrind build does not compile in realpath, which make DATA/INDEX DIR fail
superfluous ifdef removed, comments fixed
Several functions (mostly in mysqld.cc) directly call
exit() function in case of errors, which is not a desired
behaviour expecially in the embedded-server library.
Fixed by making these functions return error sign instead
of exiting.
per-file comments:
include/my_getopt.h
Bug#39289 libmysqld.a calls exit() upon error
added 'error' retvalue for my_getopt_register_get_addr
libmysqld/lib_sql.cc
Bug#39289 libmysqld.a calls exit() upon error
unireg_clear() function implemented
mysys/default.c
Bug#39289 libmysqld.a calls exit() upon error
error returned instead of exit() call
mysys/mf_tempdir.c
Bug#39289 libmysqld.a calls exit() upon error
free_tmpdir() - fixed so it's not produce crash on uninitialized
tmpdir structure
mysys/my_getopt.c
Bug#39289 libmysqld.a calls exit() upon error
error returned instead of exit() call
sql/mysql_priv.h
Bug#39289 libmysqld.a calls exit() upon error
unireg_abort definition fixed for the embedded server
sql/mysqld.cc
Bug#39289 libmysqld.a calls exit() upon error
various functions fixed
error returned instead of exit() call
The problem is that MySQL's 'fast' mutex implementation uses the
random() routine to determine the spin delay. Unfortunately, the
routine interface is not thead-safe and some implementations (eg:
glibc) might use a internal lock to protect the RNG state, causing
excessive locking contention if lots of threads are spinning on
a MySQL's 'fast' mutex. The code was also misusing the value
of the RAND_MAX macro, this macro represents the largest value
that can be returned from the rand() function, not random().
The solution is to use the quite simple Park-Miller random number
generator. The initial seed is set to 1 because the previously used
generator wasn't being seeded -- the initial seed is 1 if srandom()
is not called.
Futhermore, the 'fast' mutex implementation has several shortcomings
and provides no measurable performance benefit. Therefore, its use is
not recommended unless it provides directly measurable results.
This patch contains fixes for two problems:
1. As originally reported, the server crashed on Mac OS X when trying to access
an EXAMPLE table after the EXAMPLE plugin was installed.
It turned out that the dynamically loaded EXAMPLE plugin called the
function hash_earch() from a Mac OS X system library, instead of
hash_earch() from MySQL's mysys library. Makefile.am in storage/example
does not include libmysys. So the Mac OS X linker arranged the hash_search()
function to be linked to the system library when the shared object is
loaded.
One possible solution would be to include libmysys into the linkage of
dynamic plugins. But then we must have a libmysys.so, which must be
used by the server too. This could have a minimal performance impact,
but foremost the change seems to bee too risky at the current state of
MySQL 5.1.
The selected solution is to rename MySQL's hash_search() to my_hash_search()
like it has been done before with hash_insert() and hash_reset().
Since this is the third time, we need to rename a hash_*() function,
I did renamed all hash_*() functions to my_hash_*().
To avoid changing a zillion calls to these functions, and announcing
this to hundreds of developers, I added defines that map the old names
to the new names.
This change is in hash.h and hash.c.
2. The other problem was improper implementation of the handlerton-to-plugin
mapping. We use a fixed-size array to hold a plugin reference for each
handlerton. On every install of a handler plugin, we allocated a new slot
of the array. On uninstall we did not free it. After some uninstall/install
cycles the array overflowed. We did not check for overflow.
One fix is to check for overflow to stop the crashes.
Another fix is to free the array slot at uninstall and search for a free slot
at plugin install.
This change is in handler.cc.
Dumping information about locks in use by sending a SIGHUP signal
to the server or by invoking the "mysqladmin debug" command may
lead to a server crash in debug builds or to undefined behavior in
production builds.
The problem was that a mutex that protects a lock object (THR_LOCK)
might have been destroyed before the lock object was actually removed
from the list of locks in use, causing a race condition with other
threads iterating over the list. The solution is to destroy the mutex
only after removing lock object from the list.
test_if_data_home_dir fixed to look into real path.
Checks added to mi_open for symlinks into data home directory.
per-file messages:
include/my_sys.h
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
my_is_symlink interface added
include/myisam.h
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
myisam_test_invalid_symlink interface added
myisam/mi_check.c
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
mi_open_datafile calls modified
myisam/mi_open.c
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
code added to mi_open to check for symlinks into data home directory.
mi_open_datafile now accepts 'original' file path to check if it's
an allowed symlink.
myisam/mi_static.c
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
myisam_test_invlaid_symlink defined
myisam/myisamchk.c
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
mi_open_datafile call modified
myisam/myisamdef.h
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
mi_open_datafile interface modified - 'real_path' parameter added
mysql-test/r/symlink.test
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
error codes corrected as some patch now rejected pointing inside datahome
mysql-test/r/symlink.result
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
error messages corrected in the result
mysys/my_symlink.c
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
my_is_symlink() implementsd
my_realpath() now returns the 'realpath' even if a file isn't a symlink
sql/mysql_priv.h
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
test_if_data_home_dir interface
sql/mysqld.cc
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
myisam_test_invalid_symlik set with the 'test_if_data_home_dir'
sql/sql_parse.cc
Bug#32167 another privilege bypass with DATA/INDEX DIRECTORY.
error messages corrected
test_if_data_home_dir code fixed
We could allocate chunks larger than 4GB, but did our
size-accounting in 32-bit values. This could lead to
spurious warnings, inaccurate accounting, and, in
theory, data loss.
Affected: 64-bit platforms. Debug-build (with safemalloc).
At least one buffer larger than 4GB. For potential data
loss, a re-alloc on such a buffer would be necessary.
Tilde expansion could fail when it was to expand to an empty string (such as
when HOME is set to an empty string), especially on systems where size_t is
unsigned.
This fix is for 5.0 only : back porting the 6.0 patch manually
The parser code in sql/sql_yacc.yy needs to be more robust to out of
memory conditions, so that when parsing a query fails due to OOM,
the thread gracefully returns an error.
Before this fix, a new/alloc returning NULL could:
- cause a crash, if dereferencing the NULL pointer,
- produce a corrupted parsed tree, containing NULL nodes,
- alter the semantic of a query, by silently dropping token values or nodes
With this fix:
- C++ constructors are *not* executed with a NULL "this" pointer
when operator new fails.
This is achieved by declaring "operator new" with a "throw ()" clause,
so that a failed new gracefully returns NULL on OOM conditions.
- calls to new/alloc are tested for a NULL result,
- The thread diagnostic area is set to an error status when OOM occurs.
This ensures that a request failing in the server properly returns an
ER_OUT_OF_RESOURCES error to the client.
- OOM conditions cause the parser to stop immediately (MYSQL_YYABORT).
This prevents causing further crashes when using a partially built parsed
tree in further rules in the parser.
No test scripts are provided, since automating OOM failures is not
instrumented in the server.
Tested under the debugger, to verify that an error in alloc_root cause the
thread to returns gracefully all the way to the client application, with
an ER_OUT_OF_RESOURCES error.
manually resolved conflicts:
Text conflict in client/mysqltest.c
Contents conflict in mysql-test/include/have_bug25714.inc
Text conflict in mysql-test/include/have_ndbapi_examples.inc
Text conflict in mysql-test/mysql-test-run.pl
Text conflict in mysql-test/suite/parts/inc/partition_check_drop.inc
Text conflict in mysql-test/suite/parts/inc/partition_layout.inc
Text conflict in mysql-test/suite/parts/inc/partition_layout_check1.inc
Text conflict in mysql-test/suite/parts/inc/partition_layout_check2.inc
Text conflict in mysql-test/suite/parts/r/partition_alter1_1_2_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_alter1_1_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_alter1_2_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_alter2_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_alter3_innodb.result
Text conflict in mysql-test/suite/parts/r/partition_alter3_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_basic_innodb.result
Text conflict in mysql-test/suite/parts/r/partition_basic_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_basic_symlink_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_engine_myisam.result
Text conflict in mysql-test/suite/parts/r/partition_syntax_myisam.result
Text conflict in mysql-test/suite/rpl_ndb/t/disabled.def
Text conflict in mysql-test/t/disabled.def
Pull out some of unpack_dirname() into normalize_dirname(); this
new function does not expand "~" to the home directory. Use this
function in unpack_dirname(), and use it during init_default_directories()
to remove duplicate entries without losing track of which directory
is a user's home dir.
Another problem is that the backtrace facility wasn't being
enabled for non-Linux targets even if the target OS has the
backtrace functions. Also, the stacktrace functions inside
mysqltest were being used without proper checks for their
presence in the build.
The problem was that when a embedded linked version of mysqltest
crashed there was no way to obtain a stack trace if no core file
is available. Another problem is that the embedded version of
libmysql was not behaving (crash) the same as the non-embedded with
respect to sending commands to a explicitly closed connection.
The solution is to generate a mysqltest's stack trace on crash
and to enable "reconnect" if the connection handle was explicitly
closed so the behavior matches the non-embedded one.
We could allocate chunks larger than 4GB, but did our size-accounting in 32-bit
values. This could lead to spurious warnings, inaccurate accounting, and, in
theory, data loss.
Affected: 64-bit platforms. Debug-build (with safemalloc). At least one buffer
larger than 4GB. For potential data loss, a re-alloc on such a buffer would be
necessary.
When trying to get the requested amount of memory for the keybuffer,
the out of memory could be signaled if one of the tentative allocations
fail. Later the server would crash (debug assert) when trying to send
a ok packet with a error set.
The solution is only to signal the error if all tentative allocations
for the keybuffer fail.
Each time the server reloads privileges containing table grants, the
system will allocate too much memory than needed because of badly
chosen growth prediction in the underlying dynamic arrays.
This patch introduces a new signature to the hash container initializer
which enables a much more pessimistic approach in favour for more
efficient memory useage.
This patch was supplied by Google Inc.
with errno 17
my_create() did not perform any checks for the case when a file is
successfully created by a call to open(), but the call to
my_register_filename() later fails because the number of open files
has exceeded the my_open_files limit. This can happen on platforms
which do not have getrlimit(), and hence we do not know the real limit
for open files. In such a case an error was returned to a caller
although the file has actually been created. Since callers assume
my_create() to return an error only when it failed to create a file,
they did not perform any cleanups, leaving an 'orphaned' file on the
file system.
Fixed by adding a check for the above case to my_create() and ensuring
the newly created file is deleted before returning an error.
Creating a deterministic test case in the test suite is impossible,
because the exact steps required to reproduce the above situation
depend on the platform and/or environment (OS per-user limits, queries
executed by previous tests, startup parameters). The patch was
manually tested on Windows using examples posted in the bug report.
Bug#34678 @@debug variable's incremental mode
The problem is that the per-thread debugging settings stack wasn't
being deallocated before the thread termination, leaking the stack
memory. The chosen solution is to push a new state if the current
is set to the initial settings and pop it (free) once the thread
finishes.
value" error even though the value was correct): a C function in my_getopt.c
was taking bool* in parameter and was called from C++ sql_plugin.cc,
but on some Mac OS X sizeof(bool) is 1 in C and 4 in C++, giving funny
mismatches. Fixed, all other occurences of bool in C are removed, future
ones are blocked by a "C-bool-catcher" in my_global.h (use my_bool).
The problem is that the Table_locks_waited was incremented only
when the lock request succeed. If a thread waiting for the lock
gets killed or the lock request is aborted, the variable would
not be incremented, leading to inaccurate values in the variable.
The solution is to increment the Table_locks_waited whenever the
lock request is queued. This reflects better the intended behavior
of the variable -- show how many times a lock was waited.
Fixed that return value of malloc was not checked.
Fixed wrong argument count (compilation failure) to base64_decode()
function.
Note:
- there is no test case for this fix as this code is never compiled
into mysql clients/server;
- as this code is used for internal testing purposes only, no changelog
entry needed.
additional fixes for 64-bit
---
Merge mysql.com:/misc/mysql/31177/50-31177
into mysql.com:/misc/mysql/31177/51-31177
---
Bug#31177: Server variables can't be set to their current values
additional 5.1 fixes (for plugins)
Default values of variables were not subject to upper/lower bounds
and step, while setting variables was. Bounds and step are also
applied to defaults now; defaults are corrected quietly, values
given by the user are corrected, and a correction-warning is thrown
as needed. Lastly, very large values could wrap around, starting
from 0 again. They are bounded at the maximum value for the
respective data-type now if no lower maximum is specified in the
variable's definition.
corrupts a MERGE table
Post-pushbuild fix. The merge test failed on Windows.
The MoveFile() function returned the error code
ERROR_ACCESS_DENIED.
The fix is to use a different name for the file to be
deleted. This is the same trick as we use for the error
code ERROR_ALREADY_EXISTS.
Added ERROR_ACCESS_DENIED to the list of error codes that
require to change the name of the file to be deleted.
corrupts a MERGE table
Bug 26867 - LOCK TABLES + REPAIR + merge table result in
memory/cpu hogging
Bug 26377 - Deadlock with MERGE and FLUSH TABLE
Bug 25038 - Waiting TRUNCATE
Bug 25700 - merge base tables get corrupted by
optimize/analyze/repair table
Bug 30275 - Merge tables: flush tables or unlock tables
causes server to crash
Bug 19627 - temporary merge table locking
Bug 27660 - Falcon: merge table possible
Bug 30273 - merge tables: Can't lock file (errno: 155)
The problems were:
Bug 26379 - Combination of FLUSH TABLE and REPAIR TABLE
corrupts a MERGE table
1. A thread trying to lock a MERGE table performs busy waiting while
REPAIR TABLE or a similar table administration task is ongoing on
one or more of its MyISAM tables.
2. A thread trying to lock a MERGE table performs busy waiting until all
threads that did REPAIR TABLE or similar table administration tasks
on one or more of its MyISAM tables in LOCK TABLES segments do UNLOCK
TABLES. The difference against problem #1 is that the busy waiting
takes place *after* the administration task. It is terminated by
UNLOCK TABLES only.
3. Two FLUSH TABLES within a LOCK TABLES segment can invalidate the
lock. This does *not* require a MERGE table. The first FLUSH TABLES
can be replaced by any statement that requires other threads to
reopen the table. In 5.0 and 5.1 a single FLUSH TABLES can provoke
the problem.
Bug 26867 - LOCK TABLES + REPAIR + merge table result in
memory/cpu hogging
Trying DML on a MERGE table, which has a child locked and
repaired by another thread, made an infinite loop in the server.
Bug 26377 - Deadlock with MERGE and FLUSH TABLE
Locking a MERGE table and its children in parent-child order
and flushing the child deadlocked the server.
Bug 25038 - Waiting TRUNCATE
Truncating a MERGE child, while the MERGE table was in use,
let the truncate fail instead of waiting for the table to
become free.
Bug 25700 - merge base tables get corrupted by
optimize/analyze/repair table
Repairing a child of an open MERGE table corrupted the child.
It was necessary to FLUSH the child first.
Bug 30275 - Merge tables: flush tables or unlock tables
causes server to crash
Flushing and optimizing locked MERGE children crashed the server.
Bug 19627 - temporary merge table locking
Use of a temporary MERGE table with non-temporary children
could corrupt the children.
Temporary tables are never locked. So we do now prohibit
non-temporary chidlren of a temporary MERGE table.
Bug 27660 - Falcon: merge table possible
It was possible to create a MERGE table with non-MyISAM children.
Bug 30273 - merge tables: Can't lock file (errno: 155)
This was a Windows-only bug. Table administration statements
sometimes failed with "Can't lock file (errno: 155)".
These bugs are fixed by a new implementation of MERGE table open.
When opening a MERGE table in open_tables() we do now add the
child tables to the list of tables to be opened by open_tables()
(the "query_list"). The children are not opened in the handler at
this stage.
After opening the parent, open_tables() opens each child from the
now extended query_list. When the last child is opened, we remove
the children from the query_list again and attach the children to
the parent. This behaves similar to the old open. However it does
not open the MyISAM tables directly, but grabs them from the already
open children.
When closing a MERGE table in close_thread_table() we detach the
children only. Closing of the children is done implicitly because
they are in thd->open_tables.
For more detail see the comment at the top of ha_myisammrg.cc.
Changed from open_ltable() to open_and_lock_tables() in all places
that can be relevant for MERGE tables. The latter can handle tables
added to the list on the fly. When open_ltable() was used in a loop
over a list of tables, the list must be temporarily terminated
after every table for open_and_lock_tables().
table_list->required_type is set to FRMTYPE_TABLE to avoid open of
special tables. Handling of derived tables is suppressed.
These details are handled by the new function
open_n_lock_single_table(), which has nearly the same signature as
open_ltable() and can replace it in most cases.
In reopen_tables() some of the tables open by a thread can be
closed and reopened. When a MERGE child is affected, the parent
must be closed and reopened too. Closing of the parent is forced
before the first child is closed. Reopen happens in the order of
thd->open_tables. MERGE parents do not attach their children
automatically at open. This is done after all tables are reopened.
So all children are open when attaching them.
Special lock handling like mysql_lock_abort() or mysql_lock_remove()
needs to be suppressed for MERGE children or forwarded to the parent.
This depends on the situation. In loops over all open tables one
suppresses child lock handling. When a single table is touched,
forwarding is done.
Behavioral changes:
===================
This patch changes the behavior of temporary MERGE tables.
Temporary MERGE must have temporary children.
The old behavior was wrong. A temporary table is not locked. Hence
even non-temporary children were not locked. See
Bug 19627 - temporary merge table locking.
You cannot change the union list of a non-temporary MERGE table
when LOCK TABLES is in effect. The following does *not* work:
CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...;
LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE;
ALTER TABLE m1 ... UNION=(t1,t2) ...;
However, you can do this with a temporary MERGE table.
You cannot create a MERGE table with CREATE ... SELECT, neither
as a temporary MERGE table, nor as a non-temporary MERGE table.
CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;
Gives error message: table is not BASE TABLE.
It's not InnoDB specific bug.
Error is in QUEUE code, about the way we handle queue->max_at_top.
It's either '0' or '-2' and we do '^' operation to get the proper
direction. Though queue->compare() function can return '-2' as
a result of comparison sometimes. So we'll get
queue->compare() ^ queue->max_at_top == 0 (when max_at_top is -2)
and _downheap() function code will go wrong way here:
...
if (next_index < elements &&
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
queue->root[next_index+1]+offset_to_key) ^
queue->max_at_top) > 0)
next_index++;
...
Fixed by changing max_at_top to be either 1 or -1, doing
'* max_at_top' to get proper direction.
A user could not override system-wide settings in their ~/.my.cnf,
because the DEFAULT_SYSCONFDIR was being searched last. Also, in
some configurations (especially when the --sysconfdir compile-time
option is set to /etc or /etc/mysql), the system-wide my.cnf file
was read multiple times, causing confusion and potential problems.
Rearrange default directories to conform to the manual and logic.
Move --sysconfdir=<path> (DEFAULT_SYSCONFDIR) from the last default
directory to the middle of the list. $HOME/.my.cnf should be last,
so the user is able to override the system-wide settings.
Change init_default_directories() to remove duplicates from the
list.
RENAME TABLE against a table with DATA/INDEX DIRECTORY overwrites
the file to which the symlink points.
This is security issue, because it is possible to create a table with
some name in some non-system database and set DATA/INDEX DIRECTORY
to mysql system database. Renaming this table to one of mysql system
tables (e.g. user, host) would overwrite the system table.
Return an error when the file to which the symlink points exist.
some platforms
Since the behavior of write(fd, buf, 0) is undefined, it may fail with
EFAULT on some architectures when buf == NULL. The error was propagated
up to a caller, since my_write() code did not handle it properly.
Fixed by checking the 'number of bytes' argument in my_write() and
returning before calling the write() system call when there is nothing
to write.
ucs2 doesn't provide required by fulltext ctype array. Crash
happens because fulltext attempts to use unitialized ctype
array.
Fixed by converting ucs2 fields to compatible utf8 analogue.
CPUs / Intel's ICC compile
The bug is a combination of two problems:
1. IA64/ICC MySQL binaries use glibc's qsort(), not the one in mysys.
2. The order relation implemented by join_tab_cmp() is not transitive,
i.e. it is possible to choose such a, b and c that (a < b) && (b < c)
but (c < a). This implies that result of a sort using the relation
implemented by join_tab_cmp() depends on the order in which
elements are compared, i.e. the result is implementation-specific. Since
choose_plan() uses qsort() to pre-sort the
join tables using join_tab_cmp() as a compare function, the results of
the sorting may vary depending on qsort() implementation.
It is neither possible nor important to implement a better ordering
algorithm in join_tab_cmp(). Therefore the only way to fix it is to
force our own qsort() to be used by renaming it to my_qsort(), so we don't depend
on linker to decide that.
This patch also "fixes" bug #20530: qsort redefinition violates the
standard.
- Reserver namespace and place in frm for TABLE_CHECKSUM and PAGE_CHECKSUM create options
- Added syncing of directory when creating .frm files
- Portability fixes
- Added missing cast that could cause bugs
- Code cleanups
- Made some bit functions inline
- Moved things out of myisam.h to my_handler.h to make them more accessable
- Renamed some myisam variables and defines to make them more globaly usable (as they are used outside of MyISAM)
- Fixed bugs in error conditions
- Use compiler time asserts instead of run time
- Fixed indentation
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_DROP as the old name was wrong
(Added a define for old value to ensure we don't break any old code)
Added HA_EXTRA_PREPARE_FOR_RENAME as a signal for rename (before we used a DROP signal which is wrong)
- Initialize error messages early to get better errors when mysqld or an engine fails to start
- Fix windows bug that query_performance_frequency was not initialized if registry code failed
- thread_stack -> my_thread_stack_size
"Disabled plugin is provoking Valgrind error"
If there are any auto-alloced string plug-in options, memory is
allocated during the call for handle_options(). We must free this
memory if we are not installing the plug-in.
This is for bug #29446 "Specifying a myisam_sort_buffer > 4GB on 64 bit machines not possible". Support for myisam_sort_buffer_size > 4 GB on 64-bit Windows will be looked at later in 5.2.
It's not possible to use WaitForSingleObject to wait
on a CRITICAL_SECTION, instead use the TryEnterCriticalSection function.
- if "mutex" was already taken => return EBUSY
- if "mutex" was aquired => return 0
When locking a "fast" mutex a static variable cpu_count
was used as a flag to initialize itself on the first usage
by calling sysconf() and setting non-zero value.
This is not thread and optimization safe on some
platforms. That's why the global initialization needs
to be done once in a designated function.
This will also speed up the usage (by a small bit)
because it won't have to check if it's initialized on
every call.
Fixed by moving the fast mutexes initialization out of
my_pthread_fastmutex_lock() to fastmutex_global_init()
and call it from my_init()
Faster thr_alarm()
Added 'Opened_files' status variable to track calls to my_open()
Don't give warnings when running mysql_install_db
Added option --source-install to mysql_install_db
I had to do the following renames() as used polymorphism didn't work with Forte compiler on 64 bit systems
index_read() -> index_read_map()
index_read_idx() -> index_read_idx_map()
index_read_last() -> index_read_last_map()
Fix a typing error in a conditional compiling directive
(reported by Vasil Dimov: Thanks !),
and improve their nesting ("MAIN" independent of platform).
Additional changes for bug#29903
- Changed to do embedded build part as normal build, when
WITH_EMBEDDED_SERVER is set.
- Allow both normal and debug build with embedded.
- Build static embedded library by pointing out all source and compile
it all, i.e. not building libraries from libraries, not portable.
- Let embedded use generated files from the "sql" directory, added
dependencies to make sure built before embedded.
- Mark library "dbug" in TARGET_LINK_LIBRARIES() with "debug", so only
linked in when debug target is used.
- Removed change of target name with "mysqld${MYSQLD_EXE_SUFFIX}", as
others can't depend on it, not defined at configure time. Instead
set the output file name.
- Created work around for bug in CMake 2.4.6 and output names, to
set the "mysqld<suffix>.pdb" name to the same base name.
- Set the correct manifest "name" (patch by iggy)
statement being KILLed".
When statement which was trying to obtain write lock on then table and
which was blocked by existing read lock was killed, concurrent statements
that were trying to obtain read locks on the same table and that were
blocked by the presence of this pending write lock were not woken up and
had to wait until this first read lock goes away.
This problem was caused by the fact that we forgot to wake up threads
which pending requests could have been satisfied after removing lock
request for the killed thread.
The patch solves the problem by waking up those threads in such situation.
Test for this bug will be added to 5.1 only as it has much better
facilities for its implementation. Particularly, by using I_S.PROCESSLIST
and wait_condition.inc script we can wait until thread will be blocked on
certain table lock without relying on unconditional sleep (which usage
increases time needed for test runs and might cause spurious test
failures on slower platforms).
(Regression, caused by a patch for the bug 22646).
Problem: when result type of date_format() was changed from
binary string to character string, mixing date_format()
with a ascii column in CONCAT() stopped to work.
Fix:
- adding "repertoire" flag into DTCollation class,
to mark items which can return only pure ASCII strings.
- allow character set conversion from pure ASCII to other character sets.
Aligned client library build and use with the Unix version when it
comes to what source to include directly in the builds, and what
libraries to link with (bug#30118).
Also reviewed, corrected and made more clear when static or dynamic
Thread Local Storage is to be used. Some code duplication was removed,
and some redundant library usage were removed, reducing the risk of
incorrect TLS usage.
Fixed bug in query cache that made it impossible to run mysqld with --debug
Fixed memory leaks in mysqldump and mysqltest
Memory leaks associated with wrong usage of mysqltest is not fixed. To find these, run
mysql-test-run --debug mysqltest
Fixed compiler warnings, errors and link errors
Fixed new bug on Solaris with gethrtime()
Added --debug-check option to all mysql clients to print errors and memory leaks
Added --debug-info to all clients. This now works as --debug-check but also prints memory and cpu usage
They had been introduced in 5.1 and were only later backported to 5.0;
as a consequence, the files in the 5.1 tree do not depend on the 5.0 ones,
and changes in 5.0 do not propagate into the 5.1 files.
To fix this, the (previous) files in 5.1 now are deleted ("bk rm"),
and the previously deleted files depending on 5.0 are now moved to the
respective source directories ("bk mv").
The current 5.1 contents is restored in these files.
If you need the previous history of the 5.1 files ("bk revtool"),
access those in "BitKeeper/deleted".
Contrary to the original plan, I did not introduce the name
"CMakeLists.historic" - mostly in order not to clutter the source tree.
This fixes bug#29982.
Backport of correction for Mac OS X build problem, global variable not
initiated is "common" and can't be used in shared libraries, unless
special flags are used (bug#26218)
--long-query-time is now given in seconds with microseconds as decimals
--min_examined_row_limit added for slow query log
long_query_time user variable is now double with 6 decimals
Added functions to get time in microseconds
Added faster time() functions for system that has gethrtime() (Solaris)
We now do less time() calls.
Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers
set_var.cc and my_getopt() can now handle DOUBLE variables.
All time() calls changed to my_time()
my_time() now does retry's if time() call fails.
Added debug function for stopping in mysql_admin_table() when tables are locked
Some trivial function and struct variable renames to avoid merge errors.
Fixed compiler warnings
Initialization of some time variables on windows moved to my_init()
Now we don't take any mutexes when creating or dropping internal HEAP tables during SELECT.
Change buffer sizes to size_t to make keycache 64 bit safe on platforms where sizeof(ulong) != sizeof(size_t)