This patch has two purposes:
(1) To refactor the code so that
{Write|Update|Delete}_rows_log_event_old does not use code from
{Write|Update|Delete}_rows_log_event. Before refactoring there
was the following problem: whenever we modifed the code for new
events, it affected the old events. This is bad, as it makes
maintainance difficult. After refactoring, we can safely edit the
new code without affecting old events. So, if we for instance
modify the binary format of new events, we no longer need to worry
about how the new code reads old events.
(2) To fix BUG#31581.
These two objectives are reached by the following changes:
- Merged Rows_log_event into Old_rows_log_event and
{Write|Update|Delete}_rows_log_event into
{Write|Update|Delete}_rows_log_event_old.
- Fixed the bug by replacing {WRITE|UPDATE|DELETE}_ROWS_EVENT by
PRE_GA_{WRITE|UPDATE|DELETE}_ROWS_EVENT.
- Added comments to log_event_old.h
(This patch is identical to the previously committed patch which was
a collapse of three changesets, except that it adds assert(0) to
constructors for old types of row log events that should never be
called.)
Fixes the following bugs:
- Bug #29560: InnoDB >= 5.0.30 hangs on adaptive hash rw-lock 'waiting for an X-lock'
Fixed a race condition in the rw_lock where an os_event_reset()
can overwrite an earlier os_event_set() triggering an indefinite
wait.
NOTE: This fix for windows is different from that for other platforms.
NOTE2: This bug is introduced in the scalability fix to the
sync0arr which was applied to 5.0 only. Therefore, it need not be
applied to the 5.1 tree. If we decide to port the scalability fix
to 5.1 then this fix should be ported as well.
- Bug #32125: Database crash due to ha_innodb.cc:3896: ulint convert_search_mode_to_innobase
When unknown find_flag is encountered in convert_search_mode_to_innobase()
do not call assert(0); instead queue a MySQL error using my_error() and
return the error code PAGE_CUR_UNSUPP. Change the functions that call
convert_search_mode_to_innobase() to handle that error code by "canceling"
execution and returning appropriate error code further upstream.
only on some occasions
Referencing an element from the SELECT list in a WHERE
clause is not permitted. The namespace of the WHERE
clause is the table columns only. This was not enforced
correctly when resolving outer references in sub-queries.
Fixed by not allowing references to aliases in a
sub-query in WHERE.
The problem is that DROP TABLE and other DDL statements failed to
automatically close handlers associated with tables that were marked
for reopen (FLUSH TABLES).
The current implementation fails to properly discard handlers of
dropped tables (that were marked for reopen) because it searches
on the open handler tables list and using the current alias of the
table being dropped. The problem is that it must not use the open
handler tables list to search because the table might have been
closed (marked for reopen) by a flush tables command and also it
must not use the current table alias at all since multiple different
aliases may be associated with a single table. This is specially
visible when a user has two open handlers (using alias) of a same
table and a flush tables command is issued before the table is
dropped (see test case). Scanning the handler table list is also
useless for dropping handlers associated with temporary tables,
because temporary tables are not kept in the THD::handler_tables
list.
The solution is to simple scan the handlers hash table searching
for, and deleting all handlers with matching table names if the
reopen flag is not passed to the flush function, indicating that
the handlers should be deleted. All matching handlers are deleted
even if the associated the table is not open.
8bit escape characters, termination and enclosed characters
were silently ignored by SELECT INTO query, but LOAD DATA INFILE
algorithm is 8bit-clean, so data was corrupted during
encoding.
Loose index scan does the grouping so the temp table does
not need to do it, even when sorting.
Fixed by checking if the grouping is already done before
doing sorting and grouping in a temp table and do only
sorting.
Problem was for LINEAR HASH/KEY. Crashes because of wrong partition id
returned when creating the new altered partitions. (because of wrong
linear hash mask)
Solution: Update the linear hash mask before using it for the new
altered table.
The problem: ha_partition::read_range_first() could return a record that is
outside of the scanned range. If that record happened to be in the next
subsequent range, it would satisfy the WHERE and appear in the output twice.
(we would get it the second time when scanning the next subsequent range)
Fix:
Made ha_partition::read_range_first() check if the returned recod is within
the scanned range, like other read_range_first() implementations do.
led to creating corrupted index.
Corrected fix. The new method called prepare2 is added to the select_create
class. As all preparations are done by the select_create::prepare function
it doesn't do anything. Slightly changed algorithm of calling the
start_bulk_insert function. Now it's called from the select_insert::prepare2
function when the SQL_BUFFER_RESULT flags is set.
The is_bulk_insert_mode flag is removed as it is not needed anymore.
This bug is actually two. The first one manifests itself on an EXPLAIN
SELECT query with nested subqueries that employs the filesort algorithm.
The whole SELECT under explain is marked as UNCACHEABLE_EXPLAIN to preserve
some temporary structures for explain. As a side-effect of this values of
nested subqueries weren't cached and subqueries were re-evaluated many
times. Each time buffer for filesort was allocated but wasn't freed because
freeing occurs at the end of topmost SELECT. Thus all available memory was
eaten up step by step and OOM event occur.
The second bug manifests itself on SELECT queries with conditions where
a subquery result is compared with a key field and the subquery itself also
has such condition. When a long chain of such nested subqueries is present
the stack overrun occur. This happens because at some point the range optimizer
temporary puts the PARAM structure on the stack. Its size if about 8K and
the stack is exhausted very fast.
Now the subselect_single_select_engine::exec function allows subquery result
caching when the UNCACHEABLE_EXPLAIN flag is set.
Now the SQL_SELECT::test_quick_select function calls the check_stack_overrun
function for stack checking purposes to prevent server crash.
When the server was out of memory it crashed because of invalid memory access.
This patch adds detection for failed memory allocations and make the server
output a proper error message.
Comparison of a BIGINT NOT NULL column with a constant arithmetic
expression that evaluates to NULL caused error 1048: "Column '...'
cannot be null".
Made convert_constant_item() check if the constant expression is NULL
before attempting to store it in a field. Attempts to store NULL in a
NOT NULL field caused query errors.
Server failed in assert() when we tried to create a DECIMAL() temp field
with a scale of more than the allowed 30. Now we limit the scale to the
allowed maximum. A truncation warning is thrown as necessary.
Problem: there's no guarantee that the user variable item's result_field
is assigned when we're adjusting its table read map.
Fix: check the result_field before using it.
DROP DATABASE statement writes changes to mysql.proc table under RBR
When replicating a DROP DATABASE statement with a database holding
stored procedures, the changes to the mysql.proc table was recorded
in the binary log under row-based replication.
With this patch, the thread uses statement-logging format for the
duration of the DROP DATABASE statement. The logging format is
(already) reset at the end of the statement, so no additional code
for resetting the logging format is necessary.