Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
a820c732
Commit
a820c732
authored
Oct 14, 2009
by
Georgi Kodinov
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
88aa7af8
adab17b9
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
393 additions
and
164 deletions
+393
-164
mysql-test/extra/binlog_tests/binlog.test
mysql-test/extra/binlog_tests/binlog.test
+39
-0
mysql-test/r/func_group.result
mysql-test/r/func_group.result
+44
-0
mysql-test/suite/binlog/r/binlog_row_binlog.result
mysql-test/suite/binlog/r/binlog_row_binlog.result
+24
-0
mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
...test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
+8
-8
mysql-test/suite/binlog/r/binlog_stm_binlog.result
mysql-test/suite/binlog/r/binlog_stm_binlog.result
+21
-0
mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
...l-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
+8
-4
mysql-test/t/func_group.test
mysql-test/t/func_group.test
+48
-0
sql/log_event.cc
sql/log_event.cc
+33
-33
sql/log_event_old.cc
sql/log_event_old.cc
+50
-54
sql/opt_sum.cc
sql/opt_sum.cc
+2
-1
sql/slave.cc
sql/slave.cc
+26
-31
sql/slave.h
sql/slave.h
+1
-2
sql/sql_binlog.cc
sql/sql_binlog.cc
+27
-24
sql/sql_class.h
sql/sql_class.h
+26
-1
sql/sql_select.cc
sql/sql_select.cc
+22
-5
sql/sql_select.h
sql/sql_select.h
+14
-1
No files found.
mysql-test/extra/binlog_tests/binlog.test
View file @
a820c732
...
...
@@ -270,3 +270,42 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE
TABLE
test
.
t2
SELECT
*
FROM
test
.
t1
;
USE
test
;
DROP
TABLES
t1
,
t2
;
#
# Bug#46640
# This test verifies if the server_id stored in the "format
# description BINLOG statement" will override the server_id
# of the server executing the statements.
#
connect
(
fresh
,
localhost
,
root
,,
test
);
connection
fresh
;
RESET
MASTER
;
CREATE
TABLE
t1
(
a
INT
PRIMARY
KEY
);
# Format description event, with server_id = 10;
BINLOG
'
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'
;
# What server_id is logged for a statement? Should be our own, not the
# one from the format description event.
INSERT
INTO
t1
VALUES
(
1
);
# INSERT INTO t1 VALUES (2), with server_id=20. Check that this is logged
# with our own server id, not the 20 from the BINLOG statement.
BINLOG
'
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
'
;
# Show binlog events to check that server ids are correct.
--
replace_column
1
# 2 # 5 #
--
replace_regex
/
Server
ver
:
.*
,
Binlog
ver
:
.*/
Server
ver
:
#, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
SHOW
BINLOG
EVENTS
;
DROP
TABLE
t1
;
disconnect
fresh
;
mysql-test/r/func_group.result
View file @
a820c732
...
...
@@ -1477,3 +1477,47 @@ COUNT(*)
SET SQL_MODE=default;
DROP TABLE t1;
End of 5.0 tests
#
# BUG#47280 - strange results from count(*) with order by multiple
# columns without where/group
#
#
# Initialize test
#
CREATE TABLE t1 (
pk INT NOT NULL,
i INT,
PRIMARY KEY (pk)
);
INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
#
# Start test
# All the following queries shall return 1 record
#
# Masking all correct values {11...13} for column i in this result.
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
max i
3 #
EXPLAIN
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
# Only 11 is correct for collumn i in this result
SELECT MAX(pk) as max, i
FROM t1
WHERE pk<2
ORDER BY max;
max i
1 11
#
# Cleanup
#
DROP TABLE t1;
End of 5.1 tests
mysql-test/suite/binlog/r/binlog_row_binlog.result
View file @
a820c732
...
...
@@ -1309,3 +1309,27 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY);
BINLOG '
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
INSERT INTO t1 VALUES (1);
BINLOG '
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
';
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # Server ver: #, Binlog ver: #
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
DROP TABLE t1;
mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
View file @
a820c732
Verbose statements from : write-partial-row.binlog
select
tx
t from raw_binlog_rows where txt like '###%';
tx
t
select
replace(txt,'\r', '') as stm
t from raw_binlog_rows where txt like '###%';
stm
t
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=1
...
...
@@ -37,8 +37,8 @@ txt
### @1=2
drop table raw_binlog_rows;
Verbose statements from : write-full-row.binlog
select
tx
t from raw_binlog_rows where txt like '###%';
tx
t
select
replace(txt,'\r', '') as stm
t from raw_binlog_rows where txt like '###%';
stm
t
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=2
...
...
@@ -76,8 +76,8 @@ txt
### @1=2
drop table raw_binlog_rows;
Verbose statements from : update-partial-row.binlog
select
tx
t from raw_binlog_rows where txt like '###%';
tx
t
select
replace(txt,'\r', '') as stm
t from raw_binlog_rows where txt like '###%';
stm
t
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=3
...
...
@@ -117,8 +117,8 @@ txt
### @1=2
drop table raw_binlog_rows;
Verbose statements from : update-full-row.binlog
select
tx
t from raw_binlog_rows where txt like '###%';
tx
t
select
replace(txt,'\r', '') as stm
t from raw_binlog_rows where txt like '###%';
stm
t
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=4
...
...
mysql-test/suite/binlog/r/binlog_stm_binlog.result
View file @
a820c732
...
...
@@ -784,3 +784,24 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY);
BINLOG '
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
INSERT INTO t1 VALUES (1);
BINLOG '
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
';
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # Server ver: #, Binlog ver: #
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
# # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
DROP TABLE t1;
mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
View file @
a820c732
...
...
@@ -45,7 +45,8 @@ create table raw_binlog_rows (txt varchar(1000));
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_verbose
.
sql
--
enable_query_log
--
echo
Verbose
statements
from
:
$binlog_file
select
txt
from
raw_binlog_rows
where
txt
like
'###%'
;
# Output --verbose lines, with extra Windows CR's trimmed
select
replace
(
txt
,
'\r'
,
''
)
as
stmt
from
raw_binlog_rows
where
txt
like
'###%'
;
drop
table
raw_binlog_rows
;
--
disable_query_log
...
...
@@ -56,7 +57,8 @@ create table raw_binlog_rows (txt varchar(1000));
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_verbose
.
sql
--
enable_query_log
--
echo
Verbose
statements
from
:
$binlog_file
select
txt
from
raw_binlog_rows
where
txt
like
'###%'
;
# Output --verbose lines, with extra Windows CR's trimmed
select
replace
(
txt
,
'\r'
,
''
)
as
stmt
from
raw_binlog_rows
where
txt
like
'###%'
;
drop
table
raw_binlog_rows
;
--
disable_query_log
...
...
@@ -67,7 +69,8 @@ create table raw_binlog_rows (txt varchar(1000));
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_verbose
.
sql
--
enable_query_log
--
echo
Verbose
statements
from
:
$binlog_file
select
txt
from
raw_binlog_rows
where
txt
like
'###%'
;
# Output --verbose lines, with extra Windows CR's trimmed
select
replace
(
txt
,
'\r'
,
''
)
as
stmt
from
raw_binlog_rows
where
txt
like
'###%'
;
drop
table
raw_binlog_rows
;
--
disable_query_log
...
...
@@ -78,5 +81,6 @@ create table raw_binlog_rows (txt varchar(1000));
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_verbose
.
sql
--
enable_query_log
--
echo
Verbose
statements
from
:
$binlog_file
select
txt
from
raw_binlog_rows
where
txt
like
'###%'
;
# Output --verbose lines, with extra Windows CR's trimmed
select
replace
(
txt
,
'\r'
,
''
)
as
stmt
from
raw_binlog_rows
where
txt
like
'###%'
;
drop
table
raw_binlog_rows
;
mysql-test/t/func_group.test
View file @
a820c732
...
...
@@ -1006,3 +1006,51 @@ DROP TABLE t1;
###
--
echo
End
of
5.0
tests
--
echo
#
--
echo
# BUG#47280 - strange results from count(*) with order by multiple
--
echo
# columns without where/group
--
echo
#
--
echo
#
--
echo
# Initialize test
--
echo
#
CREATE
TABLE
t1
(
pk
INT
NOT
NULL
,
i
INT
,
PRIMARY
KEY
(
pk
)
);
INSERT
INTO
t1
VALUES
(
1
,
11
),(
2
,
12
),(
3
,
13
);
--
echo
#
--
echo
# Start test
--
echo
# All the following queries shall return 1 record
--
echo
#
--
echo
--
echo
# Masking all correct values {11...13} for column i in this result.
--
replace_column
2
#
SELECT
MAX
(
pk
)
as
max
,
i
FROM
t1
ORDER
BY
max
;
--
echo
EXPLAIN
SELECT
MAX
(
pk
)
as
max
,
i
FROM
t1
ORDER
BY
max
;
--
echo
--
echo
# Only 11 is correct for collumn i in this result
SELECT
MAX
(
pk
)
as
max
,
i
FROM
t1
WHERE
pk
<
2
ORDER
BY
max
;
--
echo
#
--
echo
# Cleanup
--
echo
#
DROP
TABLE
t1
;
--
echo
End
of
5.1
tests
sql/log_event.cc
View file @
a820c732
...
...
@@ -3859,6 +3859,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int
Format_description_log_event
::
do_apply_event
(
Relay_log_info
const
*
rli
)
{
int
ret
=
0
;
DBUG_ENTER
(
"Format_description_log_event::do_apply_event"
);
#ifdef USING_TRANSACTIONS
...
...
@@ -3900,17 +3901,21 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
0, then 96, then jump to first really asked event (which is
>96). So this is ok.
*/
DBUG_RETURN
(
Start_log_event_v3
::
do_apply_event
(
rli
)
);
ret
=
Start_log_event_v3
::
do_apply_event
(
rli
);
}
DBUG_RETURN
(
0
);
if
(
!
ret
)
{
/* Save the information describing this binlog */
delete
rli
->
relay_log
.
description_event_for_exec
;
const_cast
<
Relay_log_info
*>
(
rli
)
->
relay_log
.
description_event_for_exec
=
this
;
}
DBUG_RETURN
(
ret
);
}
int
Format_description_log_event
::
do_update_pos
(
Relay_log_info
*
rli
)
{
/* save the information describing this binlog */
delete
rli
->
relay_log
.
description_event_for_exec
;
rli
->
relay_log
.
description_event_for_exec
=
this
;
if
(
server_id
==
(
uint32
)
::
server_id
)
{
/*
...
...
@@ -7506,6 +7511,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
thd
->
reset_current_stmt_binlog_row_based
();
const_cast
<
Relay_log_info
*>
(
rli
)
->
cleanup_context
(
thd
,
error
);
thd
->
is_slave_error
=
1
;
DBUG_RETURN
(
error
);
}
/*
This code would ideally be placed in do_update_pos() instead, but
...
...
@@ -7534,6 +7540,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast
<
Relay_log_info
*>
(
rli
)
->
last_event_start_time
=
my_time
(
0
);
}
if
(
get_flags
(
STMT_END_F
))
if
(
error
=
rows_event_stmt_cleanup
(
rli
,
thd
))
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`"
,
get_type_str
(),
m_table
->
s
->
db
.
str
,
m_table
->
s
->
table_name
.
str
);
DBUG_RETURN
(
error
);
}
...
...
@@ -7632,33 +7646,19 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
if
(
get_flags
(
STMT_END_F
))
{
if
((
error
=
rows_event_stmt_cleanup
(
rli
,
thd
))
==
0
)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli
->
stmt_done
(
log_pos
,
when
);
/*
Clear any errors pushed in thd->net.last_err* if for example "no key
found" (as this is allowed). This is a safety measure; apparently
those errors (e.g. when executing a Delete_rows_log_event of a
non-existing row, like in rpl_row_mystery22.test,
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
do not become visible. We still prefer to wipe them out.
*/
thd
->
clear_error
();
}
else
{
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`"
,
get_type_str
(),
m_table
->
s
->
db
.
str
,
m_table
->
s
->
table_name
.
str
);
}
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli
->
stmt_done
(
log_pos
,
when
);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
thd->net.last_err* are allowed. Examples of errors are "key not
found", which is produced in the test case rpl_row_conflicts.test
*/
thd
->
clear_error
();
}
else
{
...
...
sql/log_event_old.cc
View file @
a820c732
...
...
@@ -1814,33 +1814,6 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast
<
Relay_log_info
*>
(
rli
)
->
last_event_start_time
=
my_time
(
0
);
}
DBUG_RETURN
(
0
);
}
Log_event
::
enum_skip_reason
Old_rows_log_event
::
do_shall_skip
(
Relay_log_info
*
rli
)
{
/*
If the slave skip counter is 1 and this event does not end a
statement, then we should not start executing on the next event.
Otherwise, we defer the decision to the normal skipping logic.
*/
if
(
rli
->
slave_skip_counter
==
1
&&
!
get_flags
(
STMT_END_F
))
return
Log_event
::
EVENT_SKIP_IGNORE
;
else
return
Log_event
::
do_shall_skip
(
rli
);
}
int
Old_rows_log_event
::
do_update_pos
(
Relay_log_info
*
rli
)
{
DBUG_ENTER
(
"Old_rows_log_event::do_update_pos"
);
int
error
=
0
;
DBUG_PRINT
(
"info"
,
(
"flags: %s"
,
get_flags
(
STMT_END_F
)
?
"STMT_END_F "
:
""
));
if
(
get_flags
(
STMT_END_F
))
{
/*
...
...
@@ -1869,7 +1842,12 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
are involved, commit the transaction and flush the pending event to the
binlog.
*/
error
=
ha_autocommit_or_rollback
(
thd
,
0
);
if
(
error
=
ha_autocommit_or_rollback
(
thd
,
0
))
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`"
,
get_type_str
(),
m_table
->
s
->
db
.
str
,
m_table
->
s
->
table_name
.
str
);
/*
Now what if this is not a transactional engine? we still need to
...
...
@@ -1882,33 +1860,51 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
*/
thd
->
reset_current_stmt_binlog_row_based
();
rli
->
cleanup_context
(
thd
,
0
);
if
(
error
==
0
)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli
->
stmt_done
(
log_pos
,
when
);
const_cast
<
Relay_log_info
*>
(
rli
)
->
cleanup_context
(
thd
,
0
);
}
/*
Clear any errors pushed in thd->net.client_last_err* if for
example "no key found" (as this is allowed). This is a safety
measure; apparently those errors (e.g. when executing a
Delete_rows_log_event_old of a non-existing row, like in
rpl_row_mystery22.test, thd->net.last_error = "Can't
find record in 't1'" and last_errno=1032) do not become
visible. We still prefer to wipe them out.
*/
thd
->
clear_error
();
}
else
rli
->
report
(
ERROR_LEVEL
,
error
,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`"
,
get_type_str
(),
m_table
->
s
->
db
.
str
,
m_table
->
s
->
table_name
.
str
);
DBUG_RETURN
(
error
);
}
Log_event
::
enum_skip_reason
Old_rows_log_event
::
do_shall_skip
(
Relay_log_info
*
rli
)
{
/*
If the slave skip counter is 1 and this event does not end a
statement, then we should not start executing on the next event.
Otherwise, we defer the decision to the normal skipping logic.
*/
if
(
rli
->
slave_skip_counter
==
1
&&
!
get_flags
(
STMT_END_F
))
return
Log_event
::
EVENT_SKIP_IGNORE
;
else
return
Log_event
::
do_shall_skip
(
rli
);
}
int
Old_rows_log_event
::
do_update_pos
(
Relay_log_info
*
rli
)
{
DBUG_ENTER
(
"Old_rows_log_event::do_update_pos"
);
int
error
=
0
;
DBUG_PRINT
(
"info"
,
(
"flags: %s"
,
get_flags
(
STMT_END_F
)
?
"STMT_END_F "
:
""
));
if
(
get_flags
(
STMT_END_F
))
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli
->
stmt_done
(
log_pos
,
when
);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
thd->net.last_err* are allowed. Examples of errors are "key not
found", which is produced in the test case rpl_row_conflicts.test
*/
thd
->
clear_error
();
}
else
{
...
...
sql/opt_sum.cc
View file @
a820c732
...
...
@@ -97,7 +97,8 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
@note
This function is only called for queries with sum functions and no
GROUP BY part.
GROUP BY part. This means that the result set shall contain a single
row only
@retval
0 no errors
...
...
sql/slave.cc
View file @
a820c732
...
...
@@ -2082,8 +2082,7 @@ static int has_temporary_error(THD *thd)
@retval 2 No error calling ev->apply_event(), but error calling
ev->update_pos().
*/
int
apply_event_and_update_pos
(
Log_event
*
ev
,
THD
*
thd
,
Relay_log_info
*
rli
,
bool
skip
)
int
apply_event_and_update_pos
(
Log_event
*
ev
,
THD
*
thd
,
Relay_log_info
*
rli
)
{
int
exec_res
=
0
;
...
...
@@ -2128,37 +2127,33 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
ev
->
when
=
my_time
(
0
);
ev
->
thd
=
thd
;
// because up to this point, ev->thd == 0
if
(
skip
)
{
int
reason
=
ev
->
shall_skip
(
rli
);
if
(
reason
==
Log_event
::
EVENT_SKIP_COUNT
)
--
rli
->
slave_skip_counter
;
pthread_mutex_unlock
(
&
rli
->
data_lock
);
if
(
reason
==
Log_event
::
EVENT_SKIP_NOT
)
exec_res
=
ev
->
apply_event
(
rli
);
int
reason
=
ev
->
shall_skip
(
rli
);
if
(
reason
==
Log_event
::
EVENT_SKIP_COUNT
)
--
rli
->
slave_skip_counter
;
pthread_mutex_unlock
(
&
rli
->
data_lock
);
if
(
reason
==
Log_event
::
EVENT_SKIP_NOT
)
exec_res
=
ev
->
apply_event
(
rli
);
#ifndef DBUG_OFF
/*
This only prints information to the debug trace.
/*
This only prints information to the debug trace.
TODO: Print an informational message to the error log?
*/
static
const
char
*
const
explain
[]
=
{
// EVENT_SKIP_NOT,
"not skipped"
,
// EVENT_SKIP_IGNORE,
"skipped because event should be ignored"
,
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
DBUG_PRINT
(
"info"
,
(
"OPTION_BEGIN: %d; IN_STMT: %d"
,
thd
->
options
&
OPTION_BEGIN
?
1
:
0
,
rli
->
get_flag
(
Relay_log_info
::
IN_STMT
)));
DBUG_PRINT
(
"skip_event"
,
(
"%s event was %s"
,
ev
->
get_type_str
(),
explain
[
reason
]));
TODO: Print an informational message to the error log?
*/
static
const
char
*
const
explain
[]
=
{
// EVENT_SKIP_NOT,
"not skipped"
,
// EVENT_SKIP_IGNORE,
"skipped because event should be ignored"
,
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
DBUG_PRINT
(
"info"
,
(
"OPTION_BEGIN: %d; IN_STMT: %d"
,
thd
->
options
&
OPTION_BEGIN
?
1
:
0
,
rli
->
get_flag
(
Relay_log_info
::
IN_STMT
)));
DBUG_PRINT
(
"skip_event"
,
(
"%s event was %s"
,
ev
->
get_type_str
(),
explain
[
reason
]));
#endif
}
else
exec_res
=
ev
->
apply_event
(
rli
);
DBUG_PRINT
(
"info"
,
(
"apply_event error = %d"
,
exec_res
));
if
(
exec_res
==
0
)
...
...
@@ -2278,7 +2273,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
delete
ev
;
DBUG_RETURN
(
1
);
}
exec_res
=
apply_event_and_update_pos
(
ev
,
thd
,
rli
,
TRUE
);
exec_res
=
apply_event_and_update_pos
(
ev
,
thd
,
rli
);
/*
Format_description_log_event should not be deleted because it will be
...
...
sql/slave.h
View file @
a820c732
...
...
@@ -190,8 +190,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
void
set_slave_thread_options
(
THD
*
thd
);
void
set_slave_thread_default_charset
(
THD
*
thd
,
Relay_log_info
const
*
rli
);
void
rotate_relay_log
(
Master_info
*
mi
);
int
apply_event_and_update_pos
(
Log_event
*
ev
,
THD
*
thd
,
Relay_log_info
*
rli
,
bool
skip
);
int
apply_event_and_update_pos
(
Log_event
*
ev
,
THD
*
thd
,
Relay_log_info
*
rli
);
pthread_handler_t
handle_slave_io
(
void
*
arg
);
pthread_handler_t
handle_slave_sql
(
void
*
arg
);
...
...
sql/sql_binlog.cc
View file @
a820c732
...
...
@@ -56,17 +56,20 @@ void mysql_client_binlog_statement(THD* thd)
Format_description_event.
*/
my_bool
have_fd_event
=
TRUE
;
if
(
!
thd
->
rli_fake
)
int
err
;
Relay_log_info
*
rli
;
rli
=
thd
->
rli_fake
;
if
(
!
rli
)
{
thd
->
rli_fake
=
new
Relay_log_info
;
rli
=
thd
->
rli_fake
=
new
Relay_log_info
;
#ifdef HAVE_purify
thd
->
rli_fake
->
is_fake
=
TRUE
;
rli
->
is_fake
=
TRUE
;
#endif
have_fd_event
=
FALSE
;
}
if
(
thd
->
rli_fake
&&
!
thd
->
rli_fake
->
relay_log
.
description_event_for_exec
)
if
(
rli
&&
!
rli
->
relay_log
.
description_event_for_exec
)
{
thd
->
rli_fake
->
relay_log
.
description_event_for_exec
=
rli
->
relay_log
.
description_event_for_exec
=
new
Format_description_log_event
(
4
);
have_fd_event
=
FALSE
;
}
...
...
@@ -78,16 +81,16 @@ void mysql_client_binlog_statement(THD* thd)
/*
Out of memory check
*/
if
(
!
(
thd
->
rli_fake
&&
thd
->
rli_fake
->
relay_log
.
description_event_for_exec
&&
if
(
!
(
rli
&&
rli
->
relay_log
.
description_event_for_exec
&&
buf
))
{
my_error
(
ER_OUTOFMEMORY
,
MYF
(
0
),
1
);
/* needed 1 bytes */
goto
end
;
}
thd
->
rli_fake
->
sql_thd
=
thd
;
thd
->
rli_fake
->
no_storage
=
TRUE
;
rli
->
sql_thd
=
thd
;
rli
->
no_storage
=
TRUE
;
for
(
char
const
*
strptr
=
thd
->
lex
->
comment
.
str
;
strptr
<
thd
->
lex
->
comment
.
str
+
thd
->
lex
->
comment
.
length
;
)
...
...
@@ -170,8 +173,7 @@ void mysql_client_binlog_statement(THD* thd)
}
ev
=
Log_event
::
read_log_event
(
bufptr
,
event_len
,
&
error
,
thd
->
rli_fake
->
relay_log
.
description_event_for_exec
);
rli
->
relay_log
.
description_event_for_exec
);
DBUG_PRINT
(
"info"
,(
"binlog base64 err=%s"
,
error
));
if
(
!
ev
)
...
...
@@ -209,18 +211,10 @@ void mysql_client_binlog_statement(THD* thd)
reporting.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
if
(
apply_event_and_update_pos
(
ev
,
thd
,
thd
->
rli_fake
,
FALSE
))
{
delete
ev
;
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
*/
my_error
(
ER_UNKNOWN_ERROR
,
MYF
(
0
),
"Error executing BINLOG statement"
);
goto
end
;
}
err
=
ev
->
apply_event
(
rli
);
#else
err
=
0
;
#endif
/*
Format_description_log_event should not be deleted because it
will be used to read info about the relay log's format; it
...
...
@@ -228,8 +222,17 @@ void mysql_client_binlog_statement(THD* thd)
i.e. when this thread terminates.
*/
if
(
ev
->
get_type_code
()
!=
FORMAT_DESCRIPTION_EVENT
)
delete
ev
;
delete
ev
;
ev
=
0
;
if
(
err
)
{
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
*/
my_error
(
ER_UNKNOWN_ERROR
,
MYF
(
0
),
"Error executing BINLOG statement"
);
goto
end
;
}
}
}
...
...
@@ -238,7 +241,7 @@ void mysql_client_binlog_statement(THD* thd)
my_ok
(
thd
);
end:
thd
->
rli_fake
->
clear_tables_to_lock
();
rli
->
clear_tables_to_lock
();
my_free
(
buf
,
MYF
(
MY_ALLOW_ZERO_PTR
));
DBUG_VOID_RETURN
;
}
sql/sql_class.h
View file @
a820c732
...
...
@@ -2647,7 +2647,32 @@ public:
MI_COLUMNDEF
*
recinfo
,
*
start_recinfo
;
KEY
*
keyinfo
;
ha_rows
end_write_records
;
uint
field_count
,
sum_func_count
,
func_count
;
/**
Number of normal fields in the query, including those referred to
from aggregate functions. Hence, "SELECT `field1`,
SUM(`field2`) from t1" sets this counter to 2.
@see count_field_types
*/
uint
field_count
;
/**
Number of fields in the query that have functions. Includes both
aggregate functions (e.g., SUM) and non-aggregates (e.g., RAND).
Also counts functions referred to from aggregate functions, i.e.,
"SELECT SUM(RAND())" sets this counter to 2.
@see count_field_types
*/
uint
func_count
;
/**
Number of fields in the query that have aggregate functions. Note
that the optimizer may choose to optimize away these fields by
replacing them with constants, in which case sum_func_count will
need to be updated.
@see opt_sum_query, count_field_types
*/
uint
sum_func_count
;
uint
hidden_field_count
;
uint
group_parts
,
group_length
,
group_null_parts
;
uint
quick_group
;
...
...
sql/sql_select.cc
View file @
a820c732
...
...
@@ -644,8 +644,11 @@ JOIN::prepare(Item ***rref_pointer_array,
this
->
group
=
group_list
!=
0
;
unit
=
unit_arg
;
if
(
tmp_table_param
.
sum_func_count
&&
!
group_list
)
implicit_grouping
=
TRUE
;
#ifdef RESTRICTED_GROUP
if
(
sum_func_count
&&
!
group_list
&&
(
func_count
||
field_count
)
)
if
(
implicit_grouping
)
{
my_message
(
ER_WRONG_SUM_SELECT
,
ER
(
ER_WRONG_SUM_SELECT
),
MYF
(
0
));
goto
err
;
...
...
@@ -881,15 +884,23 @@ JOIN::optimize()
}
#endif
/* Optimize count(*), min() and max() */
if
(
tables_list
&&
tmp_table_param
.
sum_func_count
&&
!
group_list
)
/*
Try to optimize count(*), min() and max() to const fields if
there is implicit grouping (aggregate functions but no
group_list). In this case, the result set shall only contain one
row.
*/
if
(
tables_list
&&
implicit_grouping
)
{
int
res
;
/*
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
to the WHERE conditions,
or 1 if all items were resolved,
or 1 if all items were resolved
(optimized away)
,
or 0, or an error number HA_ERR_...
If all items were resolved by opt_sum_query, there is no need to
open any tables.
*/
if
((
res
=
opt_sum_query
(
select_lex
->
leaf_tables
,
all_fields
,
conds
)))
{
...
...
@@ -2024,7 +2035,7 @@ JOIN::exec()
count_field_types
(
select_lex
,
&
curr_join
->
tmp_table_param
,
*
curr_all_fields
,
0
);
if
(
curr_join
->
group
||
curr_join
->
tmp_table_param
.
sum_func_count
||
if
(
curr_join
->
group
||
curr_join
->
implicit_grouping
||
(
procedure
&&
(
procedure
->
flags
&
PROC_GROUP
)))
{
if
(
make_group_fields
(
this
,
curr_join
))
...
...
@@ -10811,6 +10822,12 @@ Next_select_func setup_end_select_func(JOIN *join)
}
else
{
/*
Choose method for presenting result to user. Use end_send_group
if the query requires grouping (has a GROUP BY clause and/or one or
more aggregate functions). Use end_send if the query should not
be grouped.
*/
if
((
join
->
sort_and_group
||
(
join
->
procedure
&&
join
->
procedure
->
flags
&
PROC_GROUP
))
&&
!
tmp_tbl
->
precomputed_group_by
)
...
...
sql/sql_select.h
View file @
a820c732
...
...
@@ -278,7 +278,14 @@ public:
TABLE
**
table
,
**
all_tables
,
*
sort_by_table
;
uint
tables
,
const_tables
;
uint
send_group_parts
;
bool
sort_and_group
,
first_record
,
full_join
,
group
,
no_field_update
;
/**
Indicates that grouping will be performed on the result set during
query execution. This field belongs to query execution.
@see make_group_fields, alloc_group_fields, JOIN::exec
*/
bool
sort_and_group
;
bool
first_record
,
full_join
,
group
,
no_field_update
;
bool
do_send_rows
;
/**
TRUE when we want to resume nested loop iterations when
...
...
@@ -428,6 +435,7 @@ public:
tables
=
0
;
const_tables
=
0
;
join_list
=
0
;
implicit_grouping
=
FALSE
;
sort_and_group
=
0
;
first_record
=
0
;
do_send_rows
=
1
;
...
...
@@ -533,6 +541,11 @@ public:
select_lex
==
unit
->
fake_select_lex
));
}
private:
/**
TRUE if the query contains an aggregate function but has no GROUP
BY clause.
*/
bool
implicit_grouping
;
bool
make_simple_join
(
JOIN
*
join
,
TABLE
*
tmp_table
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment