developers
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2009
- 18 participants
- 235 discussions
Hi Alexander,
Please find the rest of the review below:
On Tue, Oct 20, 2009 at 10:46:08AM +0400, Alexi1952 wrote:
> The diff is due to run-dependent data in log-events (e.g. in Table map table_id = 23 in my test run and = 60 in your test run).
> It's me got a kink that --replace_regex will correct this in BINLOG :) Actually to correct this, mysqlbinlog should be called with
> --base64-output=decode-rows options.
>
> Attached is corrected version of the test and result.
Overall comments:
--help message
==============
The new syntax is not fully documented in --help --verbose output. It says:
--rewrite-db=name Updates to a database with a different name than the
original.
and doesn't specify what is the syntax of the 'name'. I think ideally we would
want to have it print
--rewrite-db='from->to'
but this seems to be difficult to achieve within the option parsing framework,
so we could follow the approach used by the server's counterpart:
--replicate-rewrite-db=name
Updates to a database with a different name than the
original. Example:
replicate-rewrite-db=master_db_name->slave_db_name.
Coding style
============
The patch violates adopted coding style in several places (We follow MySQL's
coding conventions). To speed things up, I've made the fixes myself.
Testing
=======
Please add a checks for
1. that text form of RBR events shows rewritten database names
2. that everything works when mysqlbinlog reads events from the server.
(they both seem to work, we just need test coverage).
Memory errors
=============
When I tried to get events from the server, using a command line like this:
mysqlbinlog -uroot --verbose --base64-output=decode-rows -R -t \
--start-position=0 --host=localhost --rewrite-db='trepl->xx' \
--debug pslp2-bin.000020
I got these errors among the output:
Error: Freeing wrong aligned pointer at line 1022, 'log_event.h'
Error: Freeing wrong aligned pointer at line 1022, 'log_event.h'
Error: Freeing wrong aligned pointer at line 1022, 'log_event.h' --(1)
...
Warning: Memory that was not free'ed (456 bytes):
456 bytes at 0x86f84d8, allocated at line 201 in 'my_alloc.c' --(2)
Problem (2) is repeatable with the mainline, so I've only reported it to MySQL
as BUG#48281.
Problem (1) is not repeatable on mainline or MariaDB. I've investigated it:
=== Wrong aligned pointer investigation ====
The messages are not produced when dumping local files. The message is
produced from Log_event::free_temp_buf() which is called from
Table_map_log_event::rewrite_db.
When dumping local log, it calls dump_local_log_entries() which calls
Log_event* Log_event::read_log_event(IO_CACHE* file,
const Format_description_log_event
*description_event)
which has this code:
// some events use the extra byte to null-terminate strings
if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
{
error = "Out of memory";
goto err;
}
buf[data_len] = 0;
memcpy(buf, head, header_size);
if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
{
error = "read error";
goto err;
}
if ((res= read_log_event(buf, data_len, &error, description_event)))
'buf' is what eventually will be passed to Table_map_log_event constructor. We
can see that buf points to a start of chunk of my_malloc'ed memory.
For the case when we read the remote log, it runs this code:
static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
const char* logname)
{
...
net= &mysql->net;
...
if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 ,
len - 1, &error_msg,
glob_description_event)))
{
error("Could not construct log event object: %s", error_msg);
DBUG_RETURN(ERROR_STOP);
}
/*
If reading from a remote host, ensure the temp_buf for the
Log_event class is pointing to the incoming stream.
*/
ev->register_temp_buf((char *) net->read_pos + 1);
The first argument to Log_event::read_log_event() will get passed
as buffer pointer Table_map_log_event constructor. It points to
NET::read_pos + 1, which is not an address we've got from my_malloc and
hence it's not something we should be calling my_free() for.
I've fixed thos problem too.
== Comments to the code ==
> --- maria-5.1-wl36-orig/client/mysqlbinlog.cc 2009-10-20 00:28:26.000000000 +0400
> +++ maria-5.1-wl36/client/mysqlbinlog.cc 2009-10-20 00:25:52.000000000 +0400
...
> @@ -35,6 +35,18 @@
> #include "log_event.h"
> #include "sql_common.h"
>
> +/* Needed for Rlp_filter */
> +struct TABLE_LIST;
> +
> +/* Needed for Rpl_filter */
> +CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci;
> +
> +#include "../sql/sql_string.h" // needed for Rpl_filter
Why use server versions of sql_string when there are client/sql_string.*?
I've tried switching to client/sql_string.* and it worked.
> @@ -2095,6 +2211,21 @@
> DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
> }
>
>
> +/* Redefinition for Rpl_filter::tables_ok() */
> +struct TABLE_LIST
> +{
> + TABLE_LIST() {}
> + TABLE_LIST *next_global, **prev_global;
> + bool updating;
> + char* db;
> + char* table_name;
> +};
I think it's a bad idea to add such "similar" and unused structures:
- it creates confusion
- Other than getting rpl_filter.* to compile, we don't have any use for it
(and if we implement per-table filtering later on, there is no warranty
that representation for list of used tables will be linked list of
TABLE_LIST)
I've tried to #ifdef-away Rpl_filter::tables_ok() from the client and then
this stopped to be needed.
As mentioned above, I've had to actually apply some of the fixes to make sure
they work. I've pushed the result into
lp:~maria-captains/maria/maria-5.1-wl36
and added that tree into buildbot:
http://askmonty.org/buildbot/grid?branch=maria-5.1-wl36
The remaining issues (need for testcases, help message) are obvious, so I can
tell that I'll be happy with the patch if buildbot doesn't reveal any problems.
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
1
[Maria-developers] Rev 2752: MWL#36: Add a mysqlbinlog option to change the used database in file:///home/psergey/dev/maria-5.1-wl36-r3/
by Sergey Petrunya 24 Oct '09
by Sergey Petrunya 24 Oct '09
24 Oct '09
At file:///home/psergey/dev/maria-5.1-wl36-r3/
------------------------------------------------------------
revno: 2752
revision-id: psergey(a)askmonty.org-20091024214858-5whjzap4t0qvv41j
parent: psergey(a)askmonty.org-20091024194339-tauuslposi16t7uv
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-wl36-r3
timestamp: Sun 2009-10-25 01:48:58 +0400
message:
MWL#36: Add a mysqlbinlog option to change the used database
- Apply Alexander Ivanov's fix to testsuite
=== modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2009-10-16 14:22:56 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2009-10-24 21:48:58 +0000
@@ -22,19 +22,21 @@
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
DELETE FROM test3.t3 WHERE a=1;
flush logs;
+#
+# mysqlbinlog output
+# --base64-output = decode-rows
+# --rewrite-db = test1->new_test1
+# --rewrite-db = test3->new_test3
+#
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
ROLLBACK/*!*/;
-BINLOG '
-AMqaOw8BAAAAZgAAAGoAAAAAAAQANS4xLjM4LU1hcmlhREItYmV0YTEtZGVidWctbG9nAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAypo7EzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
-'/*!*/;
# at #
use new_test1/*!*/;
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=#/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
@@ -47,19 +49,14 @@
CREATE TABLE t1 (a INT, b INT)
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALwAAADgBAAAAABcAAAAAAAAACW5ld190ZXN0MQACdDEAAgMDAAM=
-AMqaOxcBAAAALwAAAGcBAAAQABcAAAAAAAEAAv/8AQAAAAEAAAD8AgAAAAIAAAA=
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
### INSERT INTO new_test1.t1
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
@@ -69,30 +66,25 @@
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2=2 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
use test2/*!*/;
SET TIMESTAMP=1000000000/*!*/;
CREATE TABLE t2 (a INT)
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `test2`.`t2` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAAKgAAAHMCAAAAABgAAAAAAAAABXRlc3QyAAJ0MgABAwAB
-AMqaOxcBAAAAJwAAAJoCAAAQABgAAAAAAAEAAf/+AQAAAP4CAAAA
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
### INSERT INTO test2.t2
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
@@ -100,53 +92,43 @@
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Delete_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALwAAAFADAAAAABcAAAAAAAAACW5ld190ZXN0MQACdDEAAgMDAAM=
-AMqaOxkBAAAAJgAAAHYDAAAQABcAAAAAAAEAAv/8AQAAAAEAAAA=
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
### DELETE FROM new_test1.t1
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
use new_test3/*!*/;
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
CREATE TABLE t3 (a INT)
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test3`.`t3` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALgAAAIIEAAAAABkAAAAAAAAACW5ld190ZXN0MwACdDMAAQMAAQ==
-AMqaOxcBAAAAJwAAAKkEAAAQABkAAAAAAAEAAf/+AQAAAP4CAAAA
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
### INSERT INTO new_test3.t3
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
@@ -154,49 +136,38 @@
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALwAAAF8FAAAAABcAAAAAAAAACW5ld190ZXN0MQACdDEAAgMDAAM=
-AMqaOxcBAAAAJgAAAIUFAAAQABcAAAAAAAEAAv/8AwAAAAMAAAA=
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
### INSERT INTO new_test1.t1
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2=3 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
use new_test1/*!*/;
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALwAAADsGAAAAABcAAAAAAAAACW5ld190ZXN0MQACdDEAAgMDAAM=
-AMqaOxcBAAAASgAAAIUGAAAQABcAAAAAAAEAAv/8AgAAAAIAAAD8AwAAAAMAAAD8BAAAAAQAAAD8
-BQAAAAUAAAD8BgAAAAYAAAA=
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
### INSERT INTO new_test1.t1
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
@@ -218,34 +189,29 @@
### @1=6 /* INT meta=0 nullable=1 is_null=0 */
### @2=6 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
# at #
-#010909 4:46:40 server id 1 end_log_pos # Table_map: `new_test3`.`t3` mapped to number #
-#010909 4:46:40 server id 1 end_log_pos # Delete_rows: table id # flags: STMT_END_F
-
-BINLOG '
-AMqaOxMBAAAALgAAADoHAAAAABkAAAAAAAAACW5ld190ZXN0MwACdDMAAQMAAQ==
-AMqaOxkBAAAAIgAAAFwHAAAQABkAAAAAAAEAAf/+AQAAAA==
-'/*!*/;
+#010909 4:46:40 server id # end_log_pos # Table_map: `new_test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
### DELETE FROM new_test3.t3
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at #
-#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
COMMIT
/*!*/;
# at #
-#010909 4:46:40 server id 1 end_log_pos # Rotate to master-bin.000002 pos: 4
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
=== modified file 'mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test'
--- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test 2009-10-16 14:22:56 +0000
+++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_options.test 2009-10-24 21:48:58 +0000
@@ -51,9 +51,16 @@
flush logs;
+--echo #
+--echo # mysqlbinlog output
+--echo # --base64-output = decode-rows
+--echo # --rewrite-db = test1->new_test1
+--echo # --rewrite-db = test3->new_test3
+--echo #
+
let $MYSQLD_DATADIR= `select @@datadir`;
---replace_regex /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
---exec $MYSQL_BINLOG --rewrite-db="test1->new_test1" --rewrite-db="test3->new_test3" -v -v $MYSQLD_DATADIR/master-bin.000001
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows --rewrite-db="test1->new_test1" --rewrite-db="test3->new_test3" -v -v $MYSQLD_DATADIR/master-bin.000001
DROP DATABASE test1;
DROP DATABASE test2;
1
0
[Maria-developers] Rev 2751: MWL#36: Add a mysqlbinlog option to change the used database in file:///home/psergey/dev/maria-5.1-wl36-r3/
by Sergey Petrunya 24 Oct '09
by Sergey Petrunya 24 Oct '09
24 Oct '09
At file:///home/psergey/dev/maria-5.1-wl36-r3/
------------------------------------------------------------
revno: 2751
revision-id: psergey(a)askmonty.org-20091024194339-tauuslposi16t7uv
parent: alexi1952(a)yandex.ru-20091017061257-v142dpem8x7rrh35
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-wl36-r3
timestamp: Sat 2009-10-24 23:43:39 +0400
message:
MWL#36: Add a mysqlbinlog option to change the used database
- Review fixes
=== modified file 'client/Makefile.am'
--- a/client/Makefile.am 2009-07-31 19:28:15 +0000
+++ b/client/Makefile.am 2009-10-24 19:43:39 +0000
@@ -107,7 +107,8 @@
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
log_event.cc my_decimal.h my_decimal.cc \
log_event_old.h log_event_old.cc \
- rpl_record_old.h rpl_record_old.cc
+ rpl_record_old.h rpl_record_old.cc \
+ sql_list.h rpl_filter.h sql_list.cc rpl_filter.cc
strings_src=decimal.c
link_sources:
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc 2009-10-16 14:04:12 +0000
+++ b/client/mysqlbinlog.cc 2009-10-24 19:43:39 +0000
@@ -35,13 +35,10 @@
#include "log_event.h"
#include "sql_common.h"
-/* Needed for Rlp_filter */
-struct TABLE_LIST;
-
/* Needed for Rpl_filter */
CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci;
-#include "../sql/sql_string.h" // needed for Rpl_filter
+#include "sql_string.h" // needed for Rpl_filter
#include "sql_list.h" // needed for Rpl_filter
#include "rpl_filter.h"
@@ -628,12 +625,13 @@
/**
- Prints "use <db>" statement when current db is to be changed.
+ Print "use <db>" statement when current db is to be changed.
We have to control emiting USE statements according to rewrite-db options.
We have to do it here (see process_event() below) and to suppress
producing USE statements by corresponding log event print-functions.
*/
+
void print_use_stmt(PRINT_EVENT_INFO* pinfo, const char* db, size_t db_len)
{
// pinfo->db is the current db.
@@ -1021,14 +1019,16 @@
retval= ERROR_STOP;
end:
rec_count++;
+
/*
- Destroy the log_event object. If reading from a remote host,
- set the temp_buf to NULL so that memory isn't freed twice.
+ Destroy the log_event object.
+ MariaDB MWL#36: mainline does this:
+ If reading from a remote host,
+ set the temp_buf to NULL so that memory isn't freed twice.
+ We no longer do that, we use Rpl_filter::event_owns_temp_buf instead.
*/
if (ev)
{
- if (remote_opt)
- ev->temp_buf= 0;
if (destroy_evt) /* destroy it later if not set (ignored table map) */
delete ev;
}
@@ -1385,6 +1385,7 @@
break;
case OPT_REWRITE_DB: // db_from->db_to
{
+ /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */
char* ptr;
char* key= argument; // db-from
char* val; // db-to
@@ -1395,20 +1396,22 @@
// Where val begins
if (!(ptr= strstr(argument, "->")))
- { sql_print_error("Bad syntax in rewrite-db: missing '->'!\n");
+ {
+ sql_print_error("Bad syntax in rewrite-db: missing '->'!\n");
return 1;
}
val= ptr + 2;
while (*val && my_isspace(&my_charset_latin1, *val))
val++;
- // Write /0 and skip blanks at the end of key
+ // Write \0 and skip blanks at the end of key
*ptr-- = 0;
while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument)
*ptr-- = 0;
if (!*key)
- { sql_print_error("Bad syntax in rewrite-db: empty db-from!\n");
+ {
+ sql_print_error("Bad syntax in rewrite-db: empty db-from!\n");
return 1;
}
@@ -1419,7 +1422,8 @@
*ptr= 0;
if (!*val)
- { sql_print_error("Bad syntax in rewrite-db: empty db-to!\n");
+ {
+ sql_print_error("Bad syntax in rewrite-db: empty db-to!\n");
return 1;
}
@@ -1691,7 +1695,7 @@
If reading from a remote host, ensure the temp_buf for the
Log_event class is pointing to the incoming stream.
*/
- ev->register_temp_buf((char *) net->read_pos + 1);
+ ev->register_temp_buf((char *) net->read_pos + 1, FALSE);
Log_event_type type= ev->get_type_code();
if (glob_description_event->binlog_version >= 3 ||
@@ -2211,15 +2215,6 @@
DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
}
-/* Redefinition for Rpl_filter::tables_ok() */
-struct TABLE_LIST
-{
- TABLE_LIST() {}
- TABLE_LIST *next_global, **prev_global;
- bool updating;
- char* db;
- char* table_name;
-};
void *sql_alloc(size_t size)
{
@@ -2236,7 +2231,7 @@
#include "my_decimal.cc"
#include "log_event.cc"
#include "log_event_old.cc"
-#include "../sql/sql_string.cc"
+#include "sql_string.cc"
#include "sql_list.cc"
#include "rpl_filter.cc"
=== modified file 'client/sql_string.h'
--- a/client/sql_string.h 2007-03-08 03:27:41 +0000
+++ b/client/sql_string.h 2009-10-24 19:43:39 +0000
@@ -15,6 +15,9 @@
/* This file is originally from the mysql distribution. Coded by monty */
+#ifndef CLIENT_SQL_STRING_H
+#define CLIENT_SQL_STRING_H
+
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@@ -353,3 +356,5 @@
return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
}
};
+
+#endif
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2009-10-16 11:58:16 +0000
+++ b/sql/log_event.cc 2009-10-24 19:43:39 +0000
@@ -1121,7 +1121,7 @@
goto err;
}
if ((res= read_log_event(buf, data_len, &error, description_event)))
- res->register_temp_buf(buf);
+ res->register_temp_buf(buf, TRUE);
err:
UNLOCK_MUTEX;
@@ -8007,16 +8007,26 @@
#ifdef MYSQL_CLIENT
+
/*
- Reset db name. This function assumes that temp_buf member contains event
- representation taken from a binary log. It resets m_dbnam and m_dblen and
- rewrites temp_buf with new db name.
- On success returns 0, on failure return non-zero value.
+ Rewrite database name for the event to name specified by new_db
+ SYNOPSIS
+ new_db Database name to change to
+ new_len Length
+ desc Event describing binlog that we're writing to.
+
+ DESCRIPTION
+ Reset db name. This function assumes that temp_buf member contains event
+ representation taken from a binary log. It resets m_dbnam and m_dblen and
+ rewrites temp_buf with new db name.
+
+ RETURN
+ 0 - Success
+ other - Error
*/
-int Table_map_log_event::rewrite_db(
- const char* new_db,
- size_t new_len,
- const Format_description_log_event* desc)
+
+int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
+ const Format_description_log_event* desc)
{
DBUG_ENTER("Table_map_log_event::rewrite_db");
DBUG_ASSERT(temp_buf);
@@ -8039,8 +8049,9 @@
if (!new_temp_buf)
{
- sql_print_error("Table_map_log_event::rewrite_dbname: "
- "failed to allocate new temp_buf (%d bytes required)", event_new_len);
+ sql_print_error("Table_map_log_event::rewrite_db: "
+ "failed to allocate new temp_buf (%d bytes required)",
+ event_new_len);
DBUG_RETURN(-1);
}
@@ -8065,7 +8076,7 @@
// Reregister temp buf
free_temp_buf();
- register_temp_buf(new_temp_buf);
+ register_temp_buf(new_temp_buf, TRUE);
// Reset m_dbnam and m_dblen members
m_dblen= new_len;
@@ -8083,9 +8094,9 @@
if (!m_memory)
{
- sql_print_error("Table_map_log_event::rewrite_dbname: "
- "failed to allocate new m_memory (%d + %d + %d bytes required)",
- m_dblen + 1, m_tbllen + 1, m_colcnt);
+ sql_print_error("Table_map_log_event::rewrite_db: "
+ "failed to allocate new m_memory (%d + %d + %d bytes required)",
+ m_dblen + 1, m_tbllen + 1, m_colcnt);
DBUG_RETURN(-1);
}
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2009-10-16 11:58:16 +0000
+++ b/sql/log_event.h 2009-10-24 19:43:39 +0000
@@ -873,6 +873,13 @@
event's type, and its content is distributed in the event-specific fields.
*/
char *temp_buf;
+
+ /*
+ TRUE <=> this event 'owns' temp_buf and should call my_free() when done
+ with it
+ */
+ bool event_owns_temp_buf;
+
/*
Timestamp on the master(for debugging and replication of
NOW()/TIMESTAMP). It is important for queries and LOAD DATA
@@ -1014,12 +1021,17 @@
Log_event(const char* buf, const Format_description_log_event
*description_event);
virtual ~Log_event() { free_temp_buf();}
- void register_temp_buf(char* buf) { temp_buf = buf; }
+ void register_temp_buf(char* buf, bool must_free)
+ {
+ temp_buf= buf;
+ event_owns_temp_buf= must_free;
+ }
void free_temp_buf()
{
if (temp_buf)
{
- my_free(temp_buf, MYF(0));
+ if (event_owns_temp_buf)
+ my_free(temp_buf, MYF(0));
temp_buf = 0;
}
}
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-10-07 13:07:10 +0000
+++ b/sql/mysqld.cc 2009-10-24 19:43:39 +0000
@@ -8188,6 +8188,7 @@
}
case (int)OPT_REPLICATE_REWRITE_DB:
{
+ /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
char* key = argument,*p, *val;
if (!(p= strstr(argument, "->")))
=== modified file 'sql/rpl_filter.cc'
--- a/sql/rpl_filter.cc 2009-10-16 13:28:13 +0000
+++ b/sql/rpl_filter.cc 2009-10-24 19:43:39 +0000
@@ -45,6 +45,7 @@
}
+#ifndef MYSQL_CLIENT
/*
Returns true if table should be logged/replicated
@@ -129,6 +130,7 @@
!do_table_inited && !wild_do_table_inited);
}
+#endif
/*
Checks whether a db matches some do_db and ignore_db rules
=== modified file 'sql/rpl_filter.h'
--- a/sql/rpl_filter.h 2009-10-16 13:28:13 +0000
+++ b/sql/rpl_filter.h 2009-10-24 19:43:39 +0000
@@ -42,7 +42,9 @@
/* Checks - returns true if ok to replicate/log */
- bool tables_ok(const char* db, TABLE_LIST* tables);
+#ifndef MYSQL_CLIENT
+ bool tables_ok(const char* db, TABLE_LIST *tables);
+#endif
bool db_ok(const char* db);
bool db_ok_with_wild_table(const char *db);
=== modified file 'sql/sql_string.cc'
--- a/sql/sql_string.cc 2009-10-17 06:12:57 +0000
+++ b/sql/sql_string.cc 2009-10-24 19:43:39 +0000
@@ -28,6 +28,9 @@
#endif
#include "sql_string.h"
+#ifdef MYSQL_CLIENT
+#error Attempt to use server-side sql_string on client. Use client/sql_string.cc
+#endif
/*****************************************************************************
** String functions
*****************************************************************************/
=== modified file 'sql/sql_string.h'
--- a/sql/sql_string.h 2009-10-16 11:20:09 +0000
+++ b/sql/sql_string.h 2009-10-24 19:43:39 +0000
@@ -25,6 +25,10 @@
#define NOT_FIXED_DEC 31
#endif
+#ifdef MYSQL_CLIENT
+#error Attempt to use server-side sql_string on client. Use client/sql_string.h
+#endif
+
class String;
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
1
0
[Maria-developers] New (by Bothorsen): Provide key cache statistics (58)
by worklog-noreplyï¼ askmonty.org 24 Oct '09
by worklog-noreplyï¼ askmonty.org 24 Oct '09
24 Oct '09
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Provide key cache statistics
CREATION DATE..: Thu, 22 Oct 2009, 12:28
SUPERVISOR.....: Bothorsen
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 58 (http://askmonty.org/worklog/?tid=58)
VERSION........: WorkLog-3.4
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
DESCRIPTION:
Provide the key cache
statistics available for the default cache (key blocks used,
unflushed, etc.) for all named caches.
Monty answers in an email:
This is a much simpler task and something that is important to get
done. We would have to introduce a 'show keycache statistics' command
that would iterate over all keycaches and provide the statistics.
The raw coding is probably 1-2 days, but on top if this we need
testing, a test environment and building of biniaries for you.
Henrik/Bo and Igor will come back to you with a more exact estimate.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
3
3
Hi!
I just finished applying / modifying / rewriting the userstats patch
to MariaDB 5.2 and will commit this in a moment.
As far as I know, the patch was originally made by Mark and his team,
then addopted by Percona and fixed/updated by Arjen & Weldon.
I send this patch in advance here, so that people that has been
involved with the patch can comment on what/if still needs to be
done and what would be the next steps.
I will write extensive comments in the commit message, but here are
the highlights:
- Almost all counters are done through 'thd->status_var' (no separate
counters used). This was done by creating a copy of thd->status_var
at start of execution and adding the difference to user stats.
The benefit of the above is:
- Less code
- No double counters (faster execution)
- Trivial to add new counters to the statistics tables
(There is a lot of counters already that can be used)
- No need to reset counters
- If 'userstat' is not set, very little overhead.
- Changed all of MariaBB code to use handler::ha_read... instead if
handler::read. This allowed me to have all counters in the
ha_... wrapper
The benefit are:
- No need to change engine code
- All engines are now measured
- Formatted code to 'MariaDB' style.
- Removed not called functions.
- A lot of small speed improvements
- Optimized hash keys to not have to do strlen().
- Store unique keys in 'keyinfo' to not have to generate
keys on the fly.
- Replaced 'if's with DBUG_ASSERT for things that I thought was
impossible.
- Change naming of some variables to be more consistent
- userstat_running -> user_stat
- Rows_fetched -> Rows changed
- Added statistics variables (for user and client statistics)
Rows_updated, Rows_deleted, Rows_inserted
- Changed busy and cpu timing to double (as in Weldon's patch)
- Changed position of a few columns in the information schemas to
group things in a more logical way.
Things that I would like to have comments one from the original
authors are:
- I did not remove from sql_parse.cc:
if (options & REFRESH_USER_RESOURCES)
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
Don't understand why this should be removed.
- Don't call 'set_concurrent_connections_stats()' (as per Weldon's
patch) to collect information from the running threads as this leads
will lead to wrong counting as all variables are not updated until
the whole command is run.
Here follows the patch (without the new test cases, the test cases
will be in the commit).
Note that I am now about to do a 'bzr gcommit'
and I may fix some minor issues while I do that.
You should be able to apply this directly to MariaDB 5.1 or you can
pull MariaDB 5.2 later today if you want to test this.
(MariaDB 5.2 is basicly MariaDB 5.1 + stable patches, so it's should
be safe to use).
=== modified file 'configure.in'
--- configure.in 2009-10-08 09:43:31 +0000
+++ configure.in 2009-10-16 13:25:43 +0000
@@ -829,7 +829,7 @@ AC_CHECK_HEADERS(fcntl.h fenv.h float.h
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
- sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \
+ sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h linux/unistd.h \
execinfo.h)
AC_CHECK_HEADERS([xfs/xfs.h])
@@ -2096,7 +2096,18 @@ case "$target" in
# We also disable for SCO for the time being, the headers for the
# thread library we use conflicts with other headers.
;;
- *) AC_CHECK_FUNCS(clock_gettime)
+*)
+ # most systems require the program be linked with librt library to use
+ # the function clock_gettime
+ my_save_LIBS="$LIBS"
+ LIBS=""
+ AC_CHECK_LIB(rt,clock_gettime)
+ LIBRT=$LIBS
+ LIBS="$my_save_LIBS"
+ AC_SUBST(LIBRT)
+
+ LIBS="$LIBS $LIBRT"
+ AC_CHECK_FUNCS(clock_gettime)
;;
esac
@@ -2786,7 +2797,7 @@ then
fi
sql_client_dirs="$sql_client_dirs client"
-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
+CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
AC_SUBST(CLIENT_LIBS)
AC_SUBST(CLIENT_THREAD_LIBS)
=== modified file 'include/my_sys.h'
--- include/my_sys.h 2009-09-07 20:50:10 +0000
+++ include/my_sys.h 2009-10-16 13:21:53 +0000
@@ -904,6 +904,7 @@ void my_free_open_file_info(void);
extern time_t my_time(myf flags);
extern ulonglong my_getsystime(void);
+extern ulonglong my_getrealtime(void);
extern ulonglong my_micro_time();
extern ulonglong my_micro_time_and_time(time_t *time_arg);
time_t my_time_possible_from_micro(ulonglong microtime);
=== modified file 'include/mysql_com.h'
--- include/mysql_com.h 2008-10-10 15:28:41 +0000
+++ include/mysql_com.h 2009-10-15 18:24:26 +0000
@@ -29,6 +29,7 @@
#define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 5
+#define LIST_PROCESS_HOST_LEN 64
/*
USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
@@ -115,6 +116,11 @@ enum enum_server_command
thread */
#define REFRESH_MASTER 128 /* Remove all bin logs in the index
and truncate the index */
+#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */
+#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */
+#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */
+#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/
+#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */
/* The following can't be set with mysql_refresh() */
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
=== modified file 'mysql-test/r/information_schema.result'
--- mysql-test/r/information_schema.result 2009-09-29 20:19:43 +0000
+++ mysql-test/r/information_schema.result 2009-10-18 19:37:52 +0000
@@ -45,6 +45,7 @@ NOT (table_schema = 'INFORMATION_SCHEMA'
select * from v1 ORDER BY c COLLATE utf8_bin;
c
CHARACTER_SETS
+CLIENT_STATISTICS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
@@ -54,6 +55,7 @@ EVENTS
FILES
GLOBAL_STATUS
GLOBAL_VARIABLES
+INDEX_STATISTICS
INNODB_BUFFER_POOL_PAGES
INNODB_BUFFER_POOL_PAGES_BLOB
INNODB_BUFFER_POOL_PAGES_INDEX
@@ -82,8 +84,10 @@ STATISTICS
TABLES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
+TABLE_STATISTICS
TRIGGERS
USER_PRIVILEGES
+USER_STATISTICS
VIEWS
XTRADB_ENHANCEMENTS
columns_priv
@@ -121,6 +125,7 @@ c table_name
TABLES TABLES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
+TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
@@ -140,6 +145,7 @@ c table_name
TABLES TABLES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
+TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
@@ -159,6 +165,7 @@ c table_name
TABLES TABLES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
+TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
@@ -640,12 +647,13 @@ from information_schema.tables
where table_schema='information_schema' limit 2;
TABLE_NAME TABLE_TYPE ENGINE
CHARACTER_SETS SYSTEM VIEW MEMORY
-COLLATIONS SYSTEM VIEW MEMORY
+CLIENT_STATISTICS SYSTEM VIEW MEMORY
show tables from information_schema like "T%";
Tables_in_information_schema (T%)
TABLES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
+TABLE_STATISTICS
TRIGGERS
create database information_schema;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@@ -655,6 +663,7 @@ Tables_in_information_schema (T%) Table_
TABLES SYSTEM VIEW
TABLE_CONSTRAINTS SYSTEM VIEW
TABLE_PRIVILEGES SYSTEM VIEW
+TABLE_STATISTICS SYSTEM VIEW
TRIGGERS SYSTEM VIEW
create table t1(a int);
ERROR 42S02: Unknown table 't1' in information_schema
@@ -667,6 +676,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
+TABLE_STATISTICS
TRIGGERS
select table_name from tables where table_name='user';
table_name
@@ -856,6 +866,7 @@ TABLE_NAME COLUMN_NAME PRIVILEGES
COLUMNS TABLE_NAME select
COLUMN_PRIVILEGES TABLE_NAME select
FILES TABLE_NAME select
+INDEX_STATISTICS TABLE_NAME select
KEY_COLUMN_USAGE TABLE_NAME select
PARTITIONS TABLE_NAME select
REFERENTIAL_CONSTRAINTS TABLE_NAME select
@@ -863,6 +874,7 @@ STATISTICS TABLE_NAME select
TABLES TABLE_NAME select
TABLE_CONSTRAINTS TABLE_NAME select
TABLE_PRIVILEGES TABLE_NAME select
+TABLE_STATISTICS TABLE_NAME select
VIEWS TABLE_NAME select
INNODB_BUFFER_POOL_PAGES_INDEX table_name select
INNODB_INDEX_STATS table_name select
=== modified file 'mysql-test/r/information_schema_all_engines.result'
--- mysql-test/r/information_schema_all_engines.result 2009-08-03 20:09:53 +0000
+++ mysql-test/r/information_schema_all_engines.result 2009-10-19 01:26:40 +0000
@@ -2,6 +2,7 @@ use INFORMATION_SCHEMA;
show tables;
Tables_in_information_schema
CHARACTER_SETS
+CLIENT_STATISTICS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
@@ -11,6 +12,7 @@ EVENTS
FILES
GLOBAL_STATUS
GLOBAL_VARIABLES
+INDEX_STATISTICS
KEY_COLUMN_USAGE
PARTITIONS
PLUGINS
@@ -26,8 +28,10 @@ STATISTICS
TABLES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
+TABLE_STATISTICS
TRIGGERS
USER_PRIVILEGES
+USER_STATISTICS
VIEWS
INNODB_BUFFER_POOL_PAGES
PBXT_STATISTICS
@@ -60,6 +64,7 @@ c2.column_name LIKE '%SCHEMA%'
);
table_name column_name
CHARACTER_SETS CHARACTER_SET_NAME
+CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
COLUMNS TABLE_SCHEMA
@@ -69,6 +74,7 @@ EVENTS EVENT_SCHEMA
FILES TABLE_SCHEMA
GLOBAL_STATUS VARIABLE_NAME
GLOBAL_VARIABLES VARIABLE_NAME
+INDEX_STATISTICS TABLE_SCHEMA
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME
@@ -84,8 +90,10 @@ STATISTICS TABLE_SCHEMA
TABLES TABLE_SCHEMA
TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
+TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USER_PRIVILEGES GRANTEE
+USER_STATISTICS USER
VIEWS TABLE_SCHEMA
INNODB_BUFFER_POOL_PAGES page_type
PBXT_STATISTICS ID
@@ -118,6 +126,7 @@ c2.column_name LIKE '%SCHEMA%'
);
table_name column_name
CHARACTER_SETS CHARACTER_SET_NAME
+CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
COLUMNS TABLE_SCHEMA
@@ -127,6 +136,7 @@ EVENTS EVENT_SCHEMA
FILES TABLE_SCHEMA
GLOBAL_STATUS VARIABLE_NAME
GLOBAL_VARIABLES VARIABLE_NAME
+INDEX_STATISTICS TABLE_SCHEMA
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME
@@ -142,8 +152,10 @@ STATISTICS TABLE_SCHEMA
TABLES TABLE_SCHEMA
TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
TABLE_PRIVILEGES TABLE_SCHEMA
+TABLE_STATISTICS TABLE_SCHEMA
TRIGGERS TRIGGER_SCHEMA
USER_PRIVILEGES GRANTEE
+USER_STATISTICS USER
VIEWS TABLE_SCHEMA
INNODB_BUFFER_POOL_PAGES page_type
PBXT_STATISTICS ID
@@ -182,6 +194,7 @@ group by c2.column_type order by num lim
group by t.table_name order by num1, t.table_name;
table_name group_concat(t.table_schema, '.', t.table_name) num1
CHARACTER_SETS information_schema.CHARACTER_SETS 1
+CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
COLLATIONS information_schema.COLLATIONS 1
COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
COLUMNS information_schema.COLUMNS 1
@@ -191,6 +204,7 @@ EVENTS information_schema.EVENTS 1
FILES information_schema.FILES 1
GLOBAL_STATUS information_schema.GLOBAL_STATUS 1
GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1
+INDEX_STATISTICS information_schema.INDEX_STATISTICS 1
INNODB_BUFFER_POOL_PAGES information_schema.INNODB_BUFFER_POOL_PAGES 1
INNODB_BUFFER_POOL_PAGES_BLOB information_schema.INNODB_BUFFER_POOL_PAGES_BLOB 1
INNODB_BUFFER_POOL_PAGES_INDEX information_schema.INNODB_BUFFER_POOL_PAGES_INDEX 1
@@ -220,8 +234,10 @@ STATISTICS information_schema.STATISTICS
TABLES information_schema.TABLES 1
TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
+TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
+USER_STATISTICS information_schema.USER_STATISTICS 1
VIEWS information_schema.VIEWS 1
XTRADB_ENHANCEMENTS information_schema.XTRADB_ENHANCEMENTS 1
Database: information_schema
@@ -229,6 +245,7 @@ Database: information_schema
| Tables |
+---------------------------------------+
| CHARACTER_SETS |
+| CLIENT_STATISTICS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
@@ -238,6 +255,7 @@ Database: information_schema
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
+| INDEX_STATISTICS |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -253,8 +271,10 @@ Database: information_schema
| TABLES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
+| TABLE_STATISTICS |
| TRIGGERS |
| USER_PRIVILEGES |
+| USER_STATISTICS |
| VIEWS |
| INNODB_BUFFER_POOL_PAGES |
| PBXT_STATISTICS |
@@ -277,6 +297,7 @@ Database: INFORMATION_SCHEMA
| Tables |
+---------------------------------------+
| CHARACTER_SETS |
+| CLIENT_STATISTICS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
@@ -286,6 +307,7 @@ Database: INFORMATION_SCHEMA
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
+| INDEX_STATISTICS |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
@@ -301,8 +323,10 @@ Database: INFORMATION_SCHEMA
| TABLES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
+| TABLE_STATISTICS |
| TRIGGERS |
| USER_PRIVILEGES |
+| USER_STATISTICS |
| VIEWS |
| INNODB_BUFFER_POOL_PAGES |
| PBXT_STATISTICS |
@@ -328,5 +352,5 @@ Wildcard: inf_rmation_schema
+--------------------+
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 43
+information_schema 47
mysql 22
=== modified file 'mysql-test/r/information_schema_db.result'
--- mysql-test/r/information_schema_db.result 2009-09-07 20:50:10 +0000
+++ mysql-test/r/information_schema_db.result 2009-10-18 19:38:24 +0000
@@ -7,6 +7,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_CONSTRAINTS
TABLE_PRIVILEGES
+TABLE_STATISTICS
TRIGGERS
create database `inf%`;
create database mbase;
=== modified file 'mysql-test/r/log_slow.result'
--- mysql-test/r/log_slow.result 2009-09-03 14:05:38 +0000
+++ mysql-test/r/log_slow.result 2009-10-18 18:59:33 +0000
@@ -56,5 +56,6 @@ last_insert_id int(11) NO NULL
insert_id int(11) NO NULL
server_id int(10) unsigned NO NULL
sql_text mediumtext NO NULL
+flush slow query logs;
set @@log_slow_filter=default;
set @@log_slow_verbosity=default;
=== modified file 'mysql-test/t/log_slow.test'
--- mysql-test/t/log_slow.test 2009-09-03 14:05:38 +0000
+++ mysql-test/t/log_slow.test 2009-10-18 18:25:56 +0000
@@ -36,6 +36,12 @@ select @@log_slow_verbosity;
show fields from mysql.slow_log;
+#
+# Check flush command
+#
+
+flush slow query logs;
+
# Reset used variables
set @@log_slow_filter=default;
=== modified file 'mysys/my_getsystime.c'
--- mysys/my_getsystime.c 2008-04-28 16:24:05 +0000
+++ mysys/my_getsystime.c 2009-10-16 14:05:22 +0000
@@ -28,6 +28,10 @@
#ifdef __NETWARE__
#include <nks/time.h>
#endif
+#ifdef HAVE_LINUX_UNISTD_H
+#include <linux/unistd.h>
+#endif
+
ulonglong my_getsystime()
{
@@ -222,3 +226,25 @@ time_t my_time_possible_from_micro(ulong
return (time_t) (microtime / 1000000);
#endif /* defined(__WIN__) */
}
+
+
+/*
+ Return real time in milliseconds * 10
+*/
+
+ulonglong my_getrealtime()
+{
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec tp;
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp))
+ return 0;
+ return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
+#elif defined(__NR_clock_gettime)
+ struct timespec tp;
+ if (syscall(__NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &tp))
+ return 0;
+ return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
+#else
+ return 0;
+#endif /* HAVE_CLOCK_GETTIME */
+}
=== modified file 'sql/authors.h'
--- sql/authors.h 2007-03-16 06:39:07 +0000
+++ sql/authors.h 2009-10-16 11:22:55 +0000
@@ -34,23 +34,35 @@ struct show_table_authors_st {
*/
struct show_table_authors_st show_table_authors[]= {
+ { "Michael (Monty) Widenius", "Tusby, Finland",
+ "Lead developer and main author" },
+ { "David Axmark", "London, England",
+ "MySQL founder; Small stuff long time ago, Monty ripped it out!" },
+ { "Sergei Golubchik", "Kerpen, Germany",
+ "Full-text search, precision math" },
+ { "Igor Babaev", "Bellevue, USA", "Optimizer, keycache, core work"},
+ { "Sergey Petrunia", "St. Petersburg, Russia", "Optimizer"},
+ { "Oleksandr Byelkin", "Lugansk, Ukraine",
+ "Query Cache (4.0), Subqueries (4.1), Views (5.0)" },
{ "Brian (Krow) Aker", "Seattle, WA, USA",
"Architecture, archive, federated, bunch of little stuff :)" },
- { "Venu Anuganti", "", "Client/server protocol (4.1)" },
- { "David Axmark", "Uppsala, Sweden",
- "Small stuff long time ago, Monty ripped it out!" },
+ { "Kristian Nielsen", "Copenhagen, Denmark",
+ "General build stuff," },
{ "Alexander (Bar) Barkov", "Izhevsk, Russia",
"Unicode and character sets (4.1)" },
+ { "Guilhem Bichot", "Bordeaux, France", "Replication (since 4.0)" },
+ { "Venu Anuganti", "", "Client/server protocol (4.1)" },
+ { "Konstantin Osipov", "Moscow, Russia",
+ "Prepared statements (4.1), Cursors (5.0)" },
+ { "Dmitri Lenev", "Moscow, Russia",
+ "Time zones support (4.1), Triggers (5.0)" },
{ "Omer BarNir", "Sunnyvale, CA, USA",
"Testing (sometimes) and general QA stuff" },
- { "Guilhem Bichot", "Bordeaux, France", "Replication (since 4.0)" },
{ "John Birrell", "", "Emulation of pthread_mutex() for OS/2" },
{ "Andreas F. Bobak", "", "AGGREGATE extension to user-defined functions" },
{ "Alexey Botchkov (Holyfoot)", "Izhevsk, Russia",
"GIS extensions (4.1), embedded server (4.1), precision math (5.0)"},
{ "Reggie Burnett", "Nashville, TN, USA", "Windows development, Connectors" },
- { "Oleksandr Byelkin", "Lugansk, Ukraine",
- "Query Cache (4.0), Subqueries (4.1), Views (5.0)" },
{ "Kent Boortz", "Orebro, Sweden", "Test platform, and general build stuff" },
{ "Tim Bunce", "", "mysqlhotcopy" },
{ "Yves Carlier", "", "mysqlaccess" },
@@ -67,8 +79,6 @@ struct show_table_authors_st show_table_
{ "Yuri Dario", "", "OS/2 port" },
{ "Andrei Elkin", "Espoo, Finland", "Replication" },
{ "Patrick Galbraith", "Sharon, NH", "Federated Engine, mysqlslap" },
- { "Sergei Golubchik", "Kerpen, Germany",
- "Full-text search, precision math" },
{ "Lenz Grimmer", "Hamburg, Germany",
"Production (build and release) engineering" },
{ "Nikolay Grishakin", "Austin, TX, USA", "Testing - Server" },
@@ -83,8 +93,6 @@ struct show_table_authors_st show_table_
{ "Hakan Küçükyılmaz", "Walldorf, Germany", "Testing - Server" },
{ "Greg (Groggy) Lehey", "Uchunga, SA, Australia", "Backup" },
{ "Matthias Leich", "Berlin, Germany", "Testing - Server" },
- { "Dmitri Lenev", "Moscow, Russia",
- "Time zones support (4.1), Triggers (5.0)" },
{ "Arjen Lentz", "Brisbane, Australia",
"Documentation (2001-2004), Dutch error messages, LOG2()" },
{ "Marc Liyanage", "", "Created Mac OS X packages" },
@@ -96,8 +104,6 @@ struct show_table_authors_st show_table_
{ "Jonathan (Jeb) Miller", "Kyle, TX, USA",
"Testing - Cluster, Replication" },
{ "Elliot Murphy", "Cocoa, FL, USA", "Replication and backup" },
- { "Kristian Nielsen", "Copenhagen, Denmark",
- "General build stuff" },
{ "Pekka Nouisiainen", "Stockholm, Sweden",
"NDB Cluster: BLOB support, character set support, ordered indexes" },
{ "Alexander Nozdrin", "Moscow, Russia",
@@ -105,8 +111,6 @@ struct show_table_authors_st show_table_
{ "Per Eric Olsson", "", "Testing of dynamic record format" },
{ "Jonas Oreland", "Stockholm, Sweden",
"NDB Cluster, Online Backup, lots of other things" },
- { "Konstantin Osipov", "Moscow, Russia",
- "Prepared statements (4.1), Cursors (5.0)" },
{ "Alexander (Sasha) Pachev", "Provo, UT, USA",
"Statement-based replication, SHOW CREATE TABLE, mysql-bench" },
{ "Irena Pancirov", "", "Port to Windows with Borland compiler" },
@@ -144,9 +148,9 @@ struct show_table_authors_st show_table_
{ "Sergey Vojtovich", "Izhevsk, Russia", "Plugins infrastructure (5.1)" },
{ "Matt Wagner", "Northfield, MN, USA", "Bug fixing" },
{ "Jim Winstead Jr.", "Los Angeles, CA, USA", "Bug fixing" },
- { "Michael (Monty) Widenius", "Tusby, Finland",
- "Lead developer and main author" },
{ "Peter Zaitsev", "Tacoma, WA, USA",
"SHA1(), AES_ENCRYPT(), AES_DECRYPT(), bug fixing" },
+ {"Mark Mark Callaghan", "Texas, USA", "Statistics patches"},
+ {"Percona", "CA, USA", "Microslow patches"},
{NULL, NULL, NULL}
};
=== modified file 'sql/event_data_objects.cc'
--- sql/event_data_objects.cc 2009-09-15 10:46:35 +0000
+++ sql/event_data_objects.cc 2009-10-18 14:30:18 +0000
@@ -1366,7 +1366,7 @@ Event_job_data::execute(THD *thd, bool d
DBUG_ENTER("Event_job_data::execute");
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
/*
MySQL parser currently assumes that current database is either
=== modified file 'sql/event_db_repository.cc'
--- sql/event_db_repository.cc 2009-02-15 10:58:34 +0000
+++ sql/event_db_repository.cc 2009-10-17 08:09:24 +0000
@@ -404,17 +404,18 @@ Event_db_repository::index_read_for_db_f
}
key_copy(key_buf, event_table->record[0], key_info, key_len);
- if (!(ret= event_table->file->index_read_map(event_table->record[0], key_buf,
- (key_part_map)1,
- HA_READ_PREFIX)))
+ if (!(ret= event_table->file->ha_index_read_map(event_table->record[0],
+ key_buf,
+ (key_part_map)1,
+ HA_READ_PREFIX)))
{
DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret));
do
{
ret= copy_event_to_schema_table(thd, schema_table, event_table);
if (ret == 0)
- ret= event_table->file->index_next_same(event_table->record[0],
- key_buf, key_len);
+ ret= event_table->file->ha_index_next_same(event_table->record[0],
+ key_buf, key_len);
} while (ret == 0);
}
DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
@@ -883,8 +884,9 @@ Event_db_repository::find_named_event(LE
key_copy(key, table->record[0], table->key_info, table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0, key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
DBUG_PRINT("info", ("Row not found"));
DBUG_RETURN(TRUE);
=== modified file 'sql/filesort.cc'
--- sql/filesort.cc 2009-09-03 14:05:38 +0000
+++ sql/filesort.cc 2009-10-17 08:13:46 +0000
@@ -577,11 +577,11 @@ static ha_rows find_all_keys(SORTPARAM *
error= my_errno ? my_errno : -1; /* Abort */
break;
}
- error=file->rnd_pos(sort_form->record[0],next_pos);
+ error=file->ha_rnd_pos(sort_form->record[0],next_pos);
}
else
{
- error=file->rnd_next(sort_form->record[0]);
+ error=file->ha_rnd_next(sort_form->record[0]);
if (!flag)
{
my_store_ptr(ref_pos,ref_length,record); // Position to row
=== modified file 'sql/ha_partition.cc'
--- sql/ha_partition.cc 2009-09-07 20:50:10 +0000
+++ sql/ha_partition.cc 2009-10-17 08:13:46 +0000
@@ -1636,7 +1636,7 @@ int ha_partition::copy_partitions(ulongl
goto error;
while (TRUE)
{
- if ((result= file->rnd_next(m_rec0)))
+ if ((result= file->ha_rnd_next(m_rec0)))
{
if (result == HA_ERR_RECORD_DELETED)
continue; //Probably MyISAM
@@ -3495,7 +3495,7 @@ int ha_partition::rnd_next(uchar *buf)
while (TRUE)
{
- result= file->rnd_next(buf);
+ result= file->ha_rnd_next(buf);
if (!result)
{
m_last_part= part_id;
@@ -4345,8 +4345,8 @@ int ha_partition::handle_unordered_next(
}
else if (is_next_same)
{
- if (!(error= file->index_next_same(buf, m_start_key.key,
- m_start_key.length)))
+ if (!(error= file->ha_index_next_same(buf, m_start_key.key,
+ m_start_key.length)))
{
m_last_part= m_part_spec.start_part;
DBUG_RETURN(0);
@@ -4354,7 +4354,7 @@ int ha_partition::handle_unordered_next(
}
else
{
- if (!(error= file->index_next(buf)))
+ if (!(error= file->ha_index_next(buf)))
{
m_last_part= m_part_spec.start_part;
DBUG_RETURN(0); // Row was in range
@@ -4409,24 +4409,26 @@ int ha_partition::handle_unordered_scan_
break;
case partition_index_read:
DBUG_PRINT("info", ("index_read on partition %d", i));
- error= file->index_read_map(buf, m_start_key.key,
- m_start_key.keypart_map,
- m_start_key.flag);
+ error= file->ha_index_read_map(buf, m_start_key.key,
+ m_start_key.keypart_map,
+ m_start_key.flag);
break;
case partition_index_first:
DBUG_PRINT("info", ("index_first on partition %d", i));
- /* MyISAM engine can fail if we call index_first() when indexes disabled */
- /* that happens if the table is empty. */
- /* Here we use file->stats.records instead of file->records() because */
- /* file->records() is supposed to return an EXACT count, and it can be */
- /* possibly slow. We don't need an exact number, an approximate one- from*/
- /* the last ::info() call - is sufficient. */
+ /*
+ MyISAM engine can fail if we call index_first() when indexes disabled
+ that happens if the table is empty.
+ Here we use file->stats.records instead of file->records() because
+ file->records() is supposed to return an EXACT count, and it can be
+ possibly slow. We don't need an exact number, an approximate one- from
+ the last ::info() call - is sufficient.
+ */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
- error= file->index_first(buf);
+ error= file->ha_index_first(buf);
break;
case partition_index_first_unordered:
/*
@@ -4507,45 +4509,49 @@ int ha_partition::handle_ordered_index_s
switch (m_index_scan_type) {
case partition_index_read:
- error= file->index_read_map(rec_buf_ptr,
- m_start_key.key,
- m_start_key.keypart_map,
- m_start_key.flag);
+ error= file->ha_index_read_map(rec_buf_ptr,
+ m_start_key.key,
+ m_start_key.keypart_map,
+ m_start_key.flag);
break;
case partition_index_first:
- /* MyISAM engine can fail if we call index_first() when indexes disabled */
- /* that happens if the table is empty. */
- /* Here we use file->stats.records instead of file->records() because */
- /* file->records() is supposed to return an EXACT count, and it can be */
- /* possibly slow. We don't need an exact number, an approximate one- from*/
- /* the last ::info() call - is sufficient. */
+ /*
+ MyISAM engine can fail if we call index_first() when indexes disabled
+ that happens if the table is empty.
+ Here we use file->stats.records instead of file->records() because
+ file->records() is supposed to return an EXACT count, and it can be
+ possibly slow. We don't need an exact number, an approximate one- from
+ the last ::info() call - is sufficient.
+ */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
- error= file->index_first(rec_buf_ptr);
+ error= file->ha_index_first(rec_buf_ptr);
reverse_order= FALSE;
break;
case partition_index_last:
- /* MyISAM engine can fail if we call index_last() when indexes disabled */
- /* that happens if the table is empty. */
- /* Here we use file->stats.records instead of file->records() because */
- /* file->records() is supposed to return an EXACT count, and it can be */
- /* possibly slow. We don't need an exact number, an approximate one- from*/
- /* the last ::info() call - is sufficient. */
+ /*
+ MyISAM engine can fail if we call index_last() when indexes disabled
+ that happens if the table is empty.
+ Here we use file->stats.records instead of file->records() because
+ file->records() is supposed to return an EXACT count, and it can be
+ possibly slow. We don't need an exact number, an approximate one- from
+ the last ::info() call - is sufficient.
+ */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
- error= file->index_last(rec_buf_ptr);
+ error= file->ha_index_last(rec_buf_ptr);
reverse_order= TRUE;
break;
case partition_index_read_last:
- error= file->index_read_last_map(rec_buf_ptr,
- m_start_key.key,
- m_start_key.keypart_map);
+ error= file->ha_index_read_last_map(rec_buf_ptr,
+ m_start_key.key,
+ m_start_key.keypart_map);
reverse_order= TRUE;
break;
case partition_read_range:
@@ -4647,10 +4653,10 @@ int ha_partition::handle_ordered_next(uc
memcpy(rec_buf(part_id), table->record[0], m_rec_length);
}
else if (!is_next_same)
- error= file->index_next(rec_buf(part_id));
+ error= file->ha_index_next(rec_buf(part_id));
else
- error= file->index_next_same(rec_buf(part_id), m_start_key.key,
- m_start_key.length);
+ error= file->ha_index_next_same(rec_buf(part_id), m_start_key.key,
+ m_start_key.length);
if (error)
{
if (error == HA_ERR_END_OF_FILE)
@@ -4695,7 +4701,7 @@ int ha_partition::handle_ordered_prev(uc
handler *file= m_file[part_id];
DBUG_ENTER("ha_partition::handle_ordered_prev");
- if ((error= file->index_prev(rec_buf(part_id))))
+ if ((error= file->ha_index_prev(rec_buf(part_id))))
{
if (error == HA_ERR_END_OF_FILE)
{
=== modified file 'sql/handler.cc'
--- sql/handler.cc 2009-09-09 21:06:57 +0000
+++ sql/handler.cc 2009-10-19 01:38:34 +0000
@@ -1195,6 +1195,7 @@ int ha_commit_trans(THD *thd, bool all)
if (cookie)
tc_log->unlog(cookie, xid);
DBUG_EXECUTE_IF("crash_commit_after", DBUG_ABORT(););
+
end:
if (rw_trans)
start_waiting_global_read_lock(thd);
@@ -1236,6 +1237,7 @@ int ha_commit_one_phase(THD *thd, bool a
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
error=1;
}
+ /* Should this be done only if is_real_trans is set ? */
status_var_increment(thd->status_var.ha_commit_count);
ha_info_next= ha_info->next();
ha_info->reset(); /* keep it conveniently zero-filled */
@@ -2092,6 +2094,8 @@ int handler::ha_open(TABLE *table_arg, c
dup_ref=ref+ALIGN_SIZE(ref_length);
cached_table_flags= table_flags();
}
+ rows_read= rows_changed= 0;
+ memset(index_rows_read, 0, sizeof(index_rows_read));
DBUG_RETURN(error);
}
@@ -2513,9 +2517,10 @@ void handler::get_auto_increment(ulonglo
key_copy(key, table->record[0],
table->key_info + table->s->next_number_index,
table->s->next_number_key_offset);
- error= index_read_map(table->record[1], key,
- make_prev_keypart_map(table->s->next_number_keypart),
- HA_READ_PREFIX_LAST);
+ error= ha_index_read_map(table->record[1], key,
+ make_prev_keypart_map(table->s->
+ next_number_keypart),
+ HA_READ_PREFIX_LAST);
/*
MySQL needs to call us for next row: assume we are inserting ("a",null)
here, we return 3, and next this statement will want to insert
@@ -3549,6 +3554,122 @@ void handler::get_dynamic_partition_info
}
+/*
+ Updates the global table stats with the TABLE this handler represents
+*/
+
+void handler::update_global_table_stats()
+{
+ TABLE_STATS * table_stats;
+
+ status_var_add(table->in_use->status_var.rows_read, rows_read);
+
+ if (!opt_userstat_running)
+ {
+ rows_read= rows_changed= 0;
+ return;
+ }
+
+ if (rows_read + rows_changed == 0)
+ return; // Nothing to update.
+
+ DBUG_ASSERT(table->s && table->s->table_cache_key.str);
+
+ pthread_mutex_lock(&LOCK_global_table_stats);
+ /* Gets the global table stats, creating one if necessary. */
+ if (!(table_stats= (TABLE_STATS*)
+ hash_search(&global_table_stats,
+ (uchar*) table->s->table_cache_key.str,
+ table->s->table_cache_key.length)))
+ {
+ if (!(table_stats = ((TABLE_STATS*)
+ my_malloc(sizeof(TABLE_STATS),
+ MYF(MY_WME | MY_ZEROFILL)))))
+ {
+ /* Out of memory error already given */
+ goto end;
+ }
+ memcpy(table_stats->table, table->s->table_cache_key.str,
+ table->s->table_cache_key.length);
+ table_stats->table_name_length= table->s->table_cache_key.length;
+ table_stats->engine_type= ht->db_type;
+ /* No need to set variables to 0, as we use MY_ZEROFILL above */
+
+ if (my_hash_insert(&global_table_stats, (uchar*) table_stats))
+ {
+ /* Out of memory error is already given */
+ my_free(table_stats, 0);
+ goto end;
+ }
+ }
+ // Updates the global table stats.
+ table_stats->rows_read+= rows_read;
+ table_stats->rows_changed+= rows_changed;
+ table_stats->rows_changed_x_indexes+= (rows_changed *
+ (table->s->keys ? table->s->keys :
+ 1));
+ rows_read= rows_changed= 0;
+end:
+ pthread_mutex_unlock(&LOCK_global_table_stats);
+}
+
+
+/*
+ Updates the global index stats with this handler's accumulated index reads.
+*/
+
+void handler::update_global_index_stats()
+{
+ DBUG_ASSERT(table->s);
+
+ if (!table->in_use->userstat_running)
+ {
+ /* Reset all index read values */
+ bzero(index_rows_read, sizeof(index_rows_read[0]) * table->s->keys);
+ return;
+ }
+
+ for (uint index = 0; index < table->s->keys; index++)
+ {
+ if (index_rows_read[index])
+ {
+ INDEX_STATS* index_stats;
+ uint key_length;
+ KEY *key_info = &table->key_info[index]; // Rows were read using this
+
+ DBUG_ASSERT(key_info->cache_name);
+ if (!key_info->cache_name)
+ continue;
+ key_length= table->s->table_cache_key.length + key_info->name_length + 1;
+ pthread_mutex_lock(&LOCK_global_index_stats);
+ // Gets the global index stats, creating one if necessary.
+ if (!(index_stats= (INDEX_STATS*) hash_search(&global_index_stats,
+ key_info->cache_name,
+ key_length)))
+ {
+ if (!(index_stats = ((INDEX_STATS*)
+ my_malloc(sizeof(INDEX_STATS),
+ MYF(MY_WME | MY_ZEROFILL)))))
+ goto end; // Error is already given
+
+ memcpy(index_stats->index, key_info->cache_name, key_length);
+ index_stats->index_name_length= key_length;
+ if (my_hash_insert(&global_index_stats, (uchar*) index_stats))
+ {
+ my_free(index_stats, 0);
+ goto end;
+ }
+ }
+ /* Updates the global index stats. */
+ index_stats->rows_read+= index_rows_read[index];
+ index_rows_read[index]= 0;
+end:
+ pthread_mutex_unlock(&LOCK_global_index_stats);
+ }
+ }
+}
+
+
/****************************************************************************
** Some general functions that isn't in the handler class
****************************************************************************/
@@ -4207,17 +4328,16 @@ int handler::read_range_first(const key_
range_key_part= table->key_info[active_index].key_part;
if (!start_key) // Read first record
- result= index_first(table->record[0]);
+ result= ha_index_first(table->record[0]);
else
- result= index_read_map(table->record[0],
- start_key->key,
- start_key->keypart_map,
- start_key->flag);
+ result= ha_index_read_map(table->record[0],
+ start_key->key,
+ start_key->keypart_map,
+ start_key->flag);
if (result)
DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND)
? HA_ERR_END_OF_FILE
: result);
-
DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
}
@@ -4243,11 +4363,11 @@ int handler::read_range_next()
if (eq_range)
{
/* We trust that index_next_same always gives a row in range */
- DBUG_RETURN(index_next_same(table->record[0],
- end_range->key,
- end_range->length));
+ DBUG_RETURN(ha_index_next_same(table->record[0],
+ end_range->key,
+ end_range->length));
}
- result= index_next(table->record[0]);
+ result= ha_index_next(table->record[0]);
if (result)
DBUG_RETURN(result);
DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
@@ -4629,6 +4749,7 @@ int handler::ha_write_row(uchar *buf)
if (unlikely(error= write_row(buf)))
DBUG_RETURN(error);
+ rows_changed++;
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
DBUG_RETURN(error); /* purecov: inspected */
DBUG_RETURN(0);
@@ -4650,6 +4771,7 @@ int handler::ha_update_row(const uchar *
if (unlikely(error= update_row(old_data, new_data)))
return error;
+ rows_changed++;
if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func)))
return error;
return 0;
@@ -4664,6 +4786,7 @@ int handler::ha_delete_row(const uchar *
if (unlikely(error= delete_row(buf)))
return error;
+ rows_changed++;
if (unlikely(error= binlog_log_row(table, buf, 0, log_func)))
return error;
return 0;
=== modified file 'sql/handler.h'
--- sql/handler.h 2009-09-07 20:50:10 +0000
+++ sql/handler.h 2009-10-18 20:53:48 +0000
@@ -30,6 +30,10 @@
#define USING_TRANSACTIONS
+#if MAX_KEY > 128
+#error MAX_KEY is too large. Values up to 128 are supported.
+#endif
+
// the following is for checking tables
#define HA_ADMIN_ALREADY_DONE 1
@@ -601,8 +605,9 @@ struct handlerton
SHOW_COMP_OPTION state;
/*
- Historical number used for frm file to determine the correct storage engine.
- This is going away and new engines will just use "name" for this.
+ Historical number used for frm file to determine the correct
+ storage engine. This is going away and new engines will just use
+ "name" for this.
*/
enum legacy_db_type db_type;
/*
@@ -1138,6 +1143,11 @@ public:
Interval returned by get_auto_increment() and being consumed by the
inserter.
*/
+ /* Statistics variables */
+ ulonglong rows_read;
+ ulonglong rows_changed;
+ ulonglong index_rows_read[MAX_KEY];
+
Discrete_interval auto_inc_interval_for_cur_row;
/**
Number of reserved auto-increment intervals. Serves as a heuristic
@@ -1156,7 +1166,10 @@ public:
locked(FALSE), implicit_emptied(0),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
auto_inc_intervals_count(0)
- {}
+ {
+ reset_statistics();
+ }
+
virtual ~handler(void)
{
DBUG_ASSERT(locked == FALSE);
@@ -1278,10 +1291,16 @@ public:
virtual void print_error(int error, myf errflag);
virtual bool get_error_message(int error, String *buf);
uint get_dup_key(int error);
+ void reset_statistics()
+ {
+ rows_read= rows_changed= 0;
+ bzero(index_rows_read, sizeof(index_rows_read));
+ }
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
{
table= table_arg;
table_share= share;
+ reset_statistics();
}
virtual double scan_time()
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
@@ -1390,22 +1409,23 @@ public:
}
/**
@brief
- Positions an index cursor to the index specified in the handle. Fetches the
- row if available. If the key value is null, begin at the first key of the
- index.
+ Positions an index cursor to the index specified in the
+ handle. Fetches the row if available. If the key value is null,
+ begin at the first key of the index.
*/
+protected:
virtual int index_read_map(uchar * buf, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
uint key_len= calculate_key_len(table, active_index, key, keypart_map);
- return index_read(buf, key, key_len, find_flag);
+ return index_read(buf, key, key_len, find_flag);
}
/**
@brief
- Positions an index cursor to the index specified in the handle. Fetches the
- row if available. If the key value is null, begin at the first key of the
- index.
+ Positions an index cursor to the index specified in the
+ handle. Fetches the row if available. If the key value is null,
+ begin at the first key of the index.
*/
virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
@@ -1430,6 +1450,81 @@ public:
uint key_len= calculate_key_len(table, active_index, key, keypart_map);
return index_read_last(buf, key, key_len);
}
+ inline void update_index_statistics()
+ {
+ if (active_index != MAX_KEY)
+ index_rows_read[active_index]++;
+ rows_read++;
+ }
+public:
+
+ /* Similar functions like the above, but does statistics counting */
+ inline int ha_index_read_map(uchar * buf, const uchar * key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag)
+ {
+ int error= index_read_map(buf, key, keypart_map, find_flag);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_read_idx_map(uchar * buf, uint index, const uchar * key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag)
+ {
+ int error= index_read_idx_map(buf, index, key, keypart_map, find_flag);
+ if (!error)
+ {
+ rows_read++;
+ if (index != MAX_KEY)
+ index_rows_read[index]++;
+ }
+ return error;
+ }
+ inline int ha_index_next(uchar * buf)
+ {
+ int error= index_next(buf);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_prev(uchar * buf)
+ {
+ int error= index_prev(buf);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_first(uchar * buf)
+ {
+ int error= index_first(buf);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_last(uchar * buf)
+ {
+ int error= index_last(buf);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_next_same(uchar *buf, const uchar *key, uint keylen)
+ {
+ int error= index_next_same(buf, key, keylen);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+ inline int ha_index_read_last_map(uchar * buf, const uchar * key,
+ key_part_map keypart_map)
+ {
+ int error= index_read_last_map(buf, key, keypart_map);
+ if (!error)
+ update_index_statistics();
+ return error;
+ }
+
virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE *ranges, uint range_count,
bool sorted, HANDLER_BUFFER *buffer);
@@ -1443,6 +1538,7 @@ public:
void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
+private:
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
@@ -1453,11 +1549,50 @@ public:
handlers for random position.
*/
virtual int rnd_pos_by_record(uchar *record)
- {
- position(record);
- return rnd_pos(record, ref);
- }
+ {
+ position(record);
+ return rnd_pos(record, ref);
+ }
virtual int read_first_row(uchar *buf, uint primary_key);
+public:
+
+ /* Same as above, but with statistics */
+ inline int ha_ft_read(uchar *buf)
+ {
+ int error= ft_read(buf);
+ if (!error)
+ rows_read++;
+ return error;
+ }
+ inline int ha_rnd_next(uchar *buf)
+ {
+ int error= rnd_next(buf);
+ if (!error)
+ rows_read++;
+ return error;
+ }
+ inline int ha_rnd_pos(uchar *buf, uchar *pos)
+ {
+ int error= rnd_pos(buf, pos);
+ if (!error)
+ rows_read++;
+ return error;
+ }
+ inline int ha_rnd_pos_by_record(uchar *buf)
+ {
+ int error= rnd_pos_by_record(buf);
+ if (!error)
+ rows_read++;
+ return error;
+ }
+ inline int ha_read_first_row(uchar *buf, uint primary_key)
+ {
+ int error= read_first_row(buf, primary_key);
+ if (!error)
+ rows_read++;
+ return error;
+ }
+
/**
The following 3 function is only needed for tables that may be
internal temporary tables during joins.
@@ -1626,6 +1761,9 @@ public:
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
+ void update_global_table_stats();
+ void update_global_index_stats();
+
#define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1
#define CHF_RENAME_FLAG 2
@@ -1944,6 +2082,7 @@ private:
{ return HA_ERR_WRONG_COMMAND; }
virtual int rename_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
+ friend class ha_partition;
};
=== modified file 'sql/item_subselect.cc'
--- sql/item_subselect.cc 2009-09-15 10:46:35 +0000
+++ sql/item_subselect.cc 2009-10-17 08:13:46 +0000
@@ -2048,7 +2048,7 @@ int subselect_uniquesubquery_engine::sca
table->null_row= 0;
for (;;)
{
- error=table->file->rnd_next(table->record[0]);
+ error=table->file->ha_rnd_next(table->record[0]);
if (error && error != HA_ERR_END_OF_FILE)
{
error= report_error(table, error);
@@ -2222,10 +2222,11 @@ int subselect_uniquesubquery_engine::exe
if (!table->file->inited)
table->file->ha_index_init(tab->ref.key, 0);
- error= table->file->index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->
+ ref.key_parts),
+ HA_READ_KEY_EXACT);
if (error &&
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
error= report_error(table, error);
@@ -2343,10 +2344,11 @@ int subselect_indexsubquery_engine::exec
if (!table->file->inited)
table->file->ha_index_init(tab->ref.key, 1);
- error= table->file->index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->
+ ref.key_parts),
+ HA_READ_KEY_EXACT);
if (error &&
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
error= report_error(table, error);
@@ -2367,9 +2369,9 @@ int subselect_indexsubquery_engine::exec
((Item_in_subselect *) item)->value= 1;
break;
}
- error= table->file->index_next_same(table->record[0],
- tab->ref.key_buff,
- tab->ref.key_length);
+ error= table->file->ha_index_next_same(table->record[0],
+ tab->ref.key_buff,
+ tab->ref.key_length);
if (error && error != HA_ERR_END_OF_FILE)
{
error= report_error(table, error);
=== modified file 'sql/lex.h'
--- sql/lex.h 2009-09-07 20:50:10 +0000
+++ sql/lex.h 2009-10-16 08:46:41 +0000
@@ -106,6 +106,7 @@ static SYMBOL symbols[] = {
{ "CHECKSUM", SYM(CHECKSUM_SYM)},
{ "CIPHER", SYM(CIPHER_SYM)},
{ "CLIENT", SYM(CLIENT_SYM)},
+ { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)},
{ "CLOSE", SYM(CLOSE_SYM)},
{ "COALESCE", SYM(COALESCE)},
{ "CODE", SYM(CODE_SYM)},
@@ -245,6 +246,7 @@ static SYMBOL symbols[] = {
{ "IN", SYM(IN_SYM)},
{ "INDEX", SYM(INDEX_SYM)},
{ "INDEXES", SYM(INDEXES)},
+ { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)},
{ "INFILE", SYM(INFILE)},
{ "INITIAL_SIZE", SYM(INITIAL_SIZE_SYM)},
{ "INNER", SYM(INNER_SYM)},
@@ -478,6 +480,7 @@ static SYMBOL symbols[] = {
{ "SIGNED", SYM(SIGNED_SYM)},
{ "SIMPLE", SYM(SIMPLE_SYM)},
{ "SLAVE", SYM(SLAVE)},
+ { "SLOW", SYM(SLOW_SYM)},
{ "SNAPSHOT", SYM(SNAPSHOT_SYM)},
{ "SMALLINT", SYM(SMALLINT)},
{ "SOCKET", SYM(SOCKET_SYM)},
@@ -526,6 +529,7 @@ static SYMBOL symbols[] = {
{ "TABLE", SYM(TABLE_SYM)},
{ "TABLES", SYM(TABLES)},
{ "TABLESPACE", SYM(TABLESPACE)},
+ { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)},
{ "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
{ "TEMPORARY", SYM(TEMPORARY)},
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
@@ -569,6 +573,7 @@ static SYMBOL symbols[] = {
{ "USE", SYM(USE_SYM)},
{ "USER", SYM(USER)},
{ "USER_RESOURCES", SYM(RESOURCES)},
+ { "USER_STATISTICS", SYM(USER_STATS_SYM)},
{ "USE_FRM", SYM(USE_FRM)},
{ "USING", SYM(USING)},
{ "UTC_DATE", SYM(UTC_DATE_SYM)},
=== modified file 'sql/log.cc'
--- sql/log.cc 2009-09-15 10:46:35 +0000
+++ sql/log.cc 2009-10-17 14:18:58 +0000
@@ -821,6 +821,13 @@ void Log_to_file_event_handler::flush()
mysql_slow_log.reopen_file();
}
+void Log_to_file_event_handler::flush_slow_log()
+{
+ /* reopen slow log file */
+ if (opt_slow_log)
+ mysql_slow_log.reopen_file();
+}
+
/*
Log error with all enabled log event handlers
@@ -916,8 +923,6 @@ void LOGGER::init_log_tables()
bool LOGGER::flush_logs(THD *thd)
{
- int rc= 0;
-
/*
Now we lock logger, as nobody should be able to use logging routines while
log tables are closed
@@ -929,7 +934,24 @@ bool LOGGER::flush_logs(THD *thd)
/* end of log flush */
logger.unlock();
- return rc;
+ return 0;
+}
+
+
+bool LOGGER::flush_slow_log(THD *thd)
+{
+ /*
+ Now we lock logger, as nobody should be able to use logging routines while
+ log tables are closed
+ */
+ logger.lock_exclusive();
+
+ /* reopen log files */
+ file_log_handler->flush_slow_log();
+
+ /* end of log flush */
+ logger.unlock();
+ return 0;
}
@@ -4070,6 +4092,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
if (likely(is_open()))
{
IO_CACHE *file= &log_file;
+ my_off_t my_org_b_tell;
#ifdef HAVE_REPLICATION
/*
In the future we need to add to the following if tests like
@@ -4077,7 +4100,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
binlog_[wild_]{do|ignore}_table?" (WL#1049)"
*/
const char *local_db= event_info->get_db();
- if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
+ if ((!(thd->options & OPTION_BIN_LOG)) ||
(!binlog_filter->db_ok(local_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -4085,6 +4108,8 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
}
#endif /* HAVE_REPLICATION */
+ my_org_b_tell= my_b_tell(file);
+
#if defined(USING_TRANSACTIONS)
/*
Should we write to the binlog cache or to the binlog on disk?
@@ -4095,7 +4120,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
trans/non-trans table types the best possible in binlogging)
- or if the event asks for it (cache_stmt == TRUE).
*/
- if (opt_using_transactions && thd)
+ if (opt_using_transactions)
{
if (thd->binlog_setup_trx_data())
goto err;
@@ -4136,7 +4161,6 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
If row-based binlogging, Insert_id, Rand and other kind of "setting
context" events are not needed.
*/
- if (thd)
{
if (!thd->current_stmt_binlog_row_based)
{
@@ -4183,16 +4207,16 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
}
}
- /*
- Write the SQL command
- */
-
+ /* Write the SQL command */
if (event_info->write(file) ||
DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
goto err;
if (file == &log_file) // we are writing to the real log (disk)
{
+ ulonglong data_written= (my_b_tell(file) - my_org_b_tell);
+ status_var_add(thd->status_var.binlog_bytes_written, data_written);
+
if (flush_and_sync())
goto err;
signal_update();
@@ -4318,6 +4342,7 @@ uint MYSQL_BIN_LOG::next_file_id()
SYNOPSIS
write_cache()
+ thd Current_thread
cache Cache to write to the binary log
lock_log True if the LOCK_log mutex should be aquired, false otherwise
sync_log True if the log should be flushed and sync:ed
@@ -4327,7 +4352,8 @@ uint MYSQL_BIN_LOG::next_file_id()
be reset as a READ_CACHE to be able to read the contents from it.
*/
-int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
+int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
+ bool sync_log)
{
Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
@@ -4375,6 +4401,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE
/* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
return ER_ERROR_ON_WRITE;
+ status_var_add(thd->status_var.binlog_bytes_written, carry);
/*
copy fixed second half of header to cache so the correct
@@ -4443,6 +4470,8 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE
/* Write data to the binary log file */
if (my_b_write(&log_file, cache->read_pos, length))
return ER_ERROR_ON_WRITE;
+ status_var_add(thd->status_var.binlog_bytes_written, length);
+
cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length= my_b_fill(cache)));
@@ -4494,6 +4523,8 @@ bool MYSQL_BIN_LOG::write_incident(THD *
if (lock)
pthread_mutex_lock(&LOCK_log);
ev.write(&log_file);
+ status_var_add(thd->status_var.binlog_bytes_written, ev.data_written);
+
if (lock)
{
if (!error && !(error= flush_and_sync()))
@@ -4565,21 +4596,28 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
*/
if (qinfo.write(&log_file))
goto err;
+ status_var_add(thd->status_var.binlog_bytes_written, qinfo.data_written);
DBUG_EXECUTE_IF("crash_before_writing_xid",
{
- if ((write_error= write_cache(cache, false, true)))
+ if ((write_error= write_cache(thd, cache, FALSE,
+ TRUE)))
DBUG_PRINT("info", ("error writing binlog cache: %d",
write_error));
DBUG_PRINT("info", ("crashing before writing xid"));
abort();
});
- if ((write_error= write_cache(cache, false, false)))
+ if ((write_error= write_cache(thd, cache, FALSE, FALSE)))
goto err;
- if (commit_event && commit_event->write(&log_file))
- goto err;
+ if (commit_event)
+ {
+ if (commit_event->write(&log_file))
+ goto err;
+ status_var_add(thd->status_var.binlog_bytes_written,
+ commit_event->data_written);
+ }
if (incident && write_incident(thd, FALSE))
goto err;
=== modified file 'sql/log.h'
--- sql/log.h 2009-06-18 13:52:46 +0000
+++ sql/log.h 2009-10-17 14:15:43 +0000
@@ -359,7 +359,8 @@ public:
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
bool write_incident(THD *thd, bool lock);
- int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
+ int write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
+ bool flush_and_sync);
void set_write_error(THD *thd);
bool check_write_error(THD *thd);
@@ -487,6 +488,7 @@ public:
const char *sql_text, uint sql_text_len,
CHARSET_INFO *client_cs);
void flush();
+ void flush_slow_log();
void init_pthread_objects();
MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
@@ -531,6 +533,7 @@ public:
void init_base();
void init_log_tables();
bool flush_logs(THD *thd);
+ bool flush_slow_log(THD *thd);
/* Perform basic logger cleanup. this will leave e.g. error log open. */
void cleanup_base();
/* Free memory. Nothing could be logged after this function is called */
=== modified file 'sql/log_event.cc'
--- sql/log_event.cc 2009-09-07 20:50:10 +0000
+++ sql/log_event.cc 2009-10-18 14:27:40 +0000
@@ -4465,7 +4465,7 @@ int Load_log_event::do_apply_event(NET*
as the present method does not call mysql_parse().
*/
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
if (!use_rli_only_for_errors)
{
@@ -6262,7 +6262,7 @@ int Append_block_log_event::do_apply_eve
as the present method does not call mysql_parse().
*/
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
my_delete(fname, MYF(0)); // old copy may exist already
if ((fd= my_create(fname, CREATE_MODE,
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
@@ -7202,7 +7202,7 @@ int Rows_log_event::do_apply_event(Relay
we need to do any changes to that value after this function.
*/
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
/*
The current statement is just about to begin and
has not yet modified anything. Note, all.modified is reset
@@ -8465,7 +8465,7 @@ Rows_log_event::write_row(const Relay_lo
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
- error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
+ error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
@@ -8497,10 +8497,10 @@ Rows_log_event::write_row(const Relay_lo
key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
0);
- error= table->file->index_read_idx_map(table->record[1], keynum,
- (const uchar*)key.get(),
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_idx_map(table->record[1], keynum,
+ (const uchar*)key.get(),
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error)));
@@ -8768,13 +8768,14 @@ int Rows_log_event::find_row(const Relay
length. Something along these lines should work:
ADD>>> store_record(table,record[1]);
- int error= table->file->rnd_pos(table->record[0], table->file->ref);
+ int error= table->file->ha_rnd_pos(table->record[0],
+ table->file->ref);
ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
table->s->reclength) == 0);
*/
DBUG_PRINT("info",("locating record using primary key (position)"));
- int error= table->file->rnd_pos_by_record(table->record[0]);
+ int error= table->file->ha_rnd_pos_by_record(table->record[0]);
if (error)
{
DBUG_PRINT("info",("rnd_pos returns error %d",error));
@@ -8834,9 +8835,9 @@ int Rows_log_event::find_row(const Relay
table->record[0][table->s->null_bytes - 1]|=
256U - (1U << table->s->last_null_bit_pos);
- if ((error= table->file->index_read_map(table->record[0], m_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_map(table->record[0], m_key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
@@ -8898,7 +8899,7 @@ int Rows_log_event::find_row(const Relay
256U - (1U << table->s->last_null_bit_pos);
}
- while ((error= table->file->index_next(table->record[0])))
+ while ((error= table->file->ha_index_next(table->record[0])))
{
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
@@ -8934,7 +8935,7 @@ int Rows_log_event::find_row(const Relay
do
{
restart_rnd_next:
- error= table->file->rnd_next(table->record[0]);
+ error= table->file->ha_rnd_next(table->record[0]);
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
switch (error) {
=== modified file 'sql/log_event_old.cc'
--- sql/log_event_old.cc 2009-05-19 09:28:05 +0000
+++ sql/log_event_old.cc 2009-10-18 14:27:39 +0000
@@ -63,7 +63,7 @@ Old_rows_log_event::do_apply_event(Old_r
we need to do any changes to that value after this function.
*/
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
/*
Check if the slave is set to use SBR. If so, it should switch
@@ -553,7 +553,7 @@ replace_record(THD *thd, TABLE *table,
*/
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
- error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
+ error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
@@ -579,10 +579,10 @@ replace_record(THD *thd, TABLE *table,
key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
0);
- error= table->file->index_read_idx_map(table->record[1], keynum,
- (const uchar*)key.get(),
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_idx_map(table->record[1], keynum,
+ (const uchar*)key.get(),
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info", ("index_read_idx() returns error %d", error));
@@ -694,13 +694,13 @@ static int find_and_fetch_row(TABLE *tab
length. Something along these lines should work:
ADD>>> store_record(table,record[1]);
- int error= table->file->rnd_pos(table->record[0], table->file->ref);
+ int error= table->file->ha_rnd_pos(table->record[0], table->file->ref);
ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
table->s->reclength) == 0);
*/
table->file->position(table->record[0]);
- int error= table->file->rnd_pos(table->record[0], table->file->ref);
+ int error= table->file->ha_rnd_pos(table->record[0], table->file->ref);
/*
rnd_pos() returns the record in table->record[0], so we have to
move it to table->record[1].
@@ -738,8 +738,9 @@ static int find_and_fetch_row(TABLE *tab
my_ptrdiff_t const pos=
table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
table->record[1][pos]= 0xFF;
- if ((error= table->file->index_read_map(table->record[1], key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_map(table->record[1], key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
@@ -793,7 +794,7 @@ static int find_and_fetch_row(TABLE *tab
256U - (1U << table->s->last_null_bit_pos);
}
- while ((error= table->file->index_next(table->record[1])))
+ while ((error= table->file->ha_index_next(table->record[1])))
{
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
@@ -822,7 +823,7 @@ static int find_and_fetch_row(TABLE *tab
do
{
restart_rnd_next:
- error= table->file->rnd_next(table->record[1]);
+ error= table->file->ha_rnd_next(table->record[1]);
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
@@ -2115,7 +2116,7 @@ Old_rows_log_event::write_row(const Rela
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
- error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
+ error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
@@ -2147,10 +2148,10 @@ Old_rows_log_event::write_row(const Rela
key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
0);
- error= table->file->index_read_idx_map(table->record[1], keynum,
- (const uchar*)key.get(),
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_idx_map(table->record[1], keynum,
+ (const uchar*)key.get(),
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info",("index_read_idx() returns error %d", error));
@@ -2301,13 +2302,13 @@ int Old_rows_log_event::find_row(const R
length. Something along these lines should work:
ADD>>> store_record(table,record[1]);
- int error= table->file->rnd_pos(table->record[0], table->file->ref);
+ int error= table->file->ha_rnd_pos(table->record[0], table->file->ref);
ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
table->s->reclength) == 0);
*/
DBUG_PRINT("info",("locating record using primary key (position)"));
- int error= table->file->rnd_pos_by_record(table->record[0]);
+ int error= table->file->ha_rnd_pos_by_record(table->record[0]);
if (error)
{
DBUG_PRINT("info",("rnd_pos returns error %d",error));
@@ -2367,9 +2368,9 @@ int Old_rows_log_event::find_row(const R
table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
table->record[0][pos]= 0xFF;
- if ((error= table->file->index_read_map(table->record[0], m_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_map(table->record[0], m_key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
@@ -2431,7 +2432,7 @@ int Old_rows_log_event::find_row(const R
256U - (1U << table->s->last_null_bit_pos);
}
- while ((error= table->file->index_next(table->record[0])))
+ while ((error= table->file->ha_index_next(table->record[0])))
{
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
@@ -2467,7 +2468,7 @@ int Old_rows_log_event::find_row(const R
do
{
restart_rnd_next:
- error= table->file->rnd_next(table->record[0]);
+ error= table->file->ha_rnd_next(table->record[0]);
switch (error) {
=== modified file 'sql/mysql_priv.h'
--- sql/mysql_priv.h 2009-10-06 14:53:46 +0000
+++ sql/mysql_priv.h 2009-10-18 12:46:24 +0000
@@ -1063,6 +1063,7 @@ bool setup_connection_thread_globals(THD
bool login_connection(THD *thd);
void end_connection(THD *thd);
void prepare_new_connection_state(THD* thd);
+void update_global_user_stats(THD* thd, bool create_user, time_t now);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
@@ -1099,14 +1100,22 @@ bool is_update_query(enum enum_sql_comma
bool is_log_table_write_query(enum enum_sql_command command);
bool alloc_query(THD *thd, const char *packet, uint packet_length);
void mysql_init_select(LEX *lex);
-void mysql_reset_thd_for_next_command(THD *thd);
+void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat);
bool mysql_new_select(LEX *lex, bool move_down);
void create_select_for_variable(const char *var_name);
void mysql_init_multi_delete(LEX *lex);
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
void init_max_user_conn(void);
void init_update_queries(void);
+void init_global_user_stats(void);
+void init_global_table_stats(void);
+void init_global_index_stats(void);
+void init_global_client_stats(void);
void free_max_user_conn(void);
+void free_global_user_stats(void);
+void free_global_table_stats(void);
+void free_global_index_stats(void);
+void free_global_client_stats(void);
pthread_handler_t handle_bootstrap(void *arg);
int mysql_execute_command(THD *thd);
bool do_command(THD *thd);
@@ -1967,6 +1976,7 @@ extern ulong max_connect_errors, connect
extern ulong extra_max_connections;
extern ulong slave_net_timeout, slave_trans_retries;
extern uint max_user_connections;
+extern ulonglong denied_connections;
extern ulong what_to_log,flush_time;
extern ulong query_buff_size;
extern ulong max_prepared_stmt_count, prepared_stmt_count;
@@ -2020,6 +2030,7 @@ extern my_bool opt_safe_show_db, opt_loc
extern my_bool opt_slave_compressed_protocol, use_temp_pool;
extern ulong slave_exec_mode_options;
extern my_bool opt_readonly, lower_case_file_system;
+extern my_bool opt_userstat_running;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;
extern char* opt_secure_file_priv;
@@ -2060,6 +2071,11 @@ extern pthread_mutex_t LOCK_des_key_file
#endif
extern pthread_mutex_t LOCK_server_started;
extern pthread_cond_t COND_server_started;
+extern pthread_mutex_t LOCK_global_user_client_stats;
+extern pthread_mutex_t LOCK_global_table_stats;
+extern pthread_mutex_t LOCK_global_index_stats;
+extern pthread_mutex_t LOCK_stats;
+
extern int mysqld_server_started;
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern rw_lock_t LOCK_system_variables_hash;
@@ -2086,6 +2102,11 @@ extern KNOWN_DATE_TIME_FORMAT known_date
extern String null_string;
extern HASH open_cache, lock_db_cache;
+extern HASH global_user_stats;
+extern HASH global_client_stats;
+extern HASH global_table_stats;
+extern HASH global_index_stats;
+
extern TABLE *unused_tables;
extern const char* any_db;
extern struct my_option my_long_options[];
=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc 2009-10-07 13:07:10 +0000
+++ sql/mysqld.cc 2009-10-18 18:48:55 +0000
@@ -416,6 +416,7 @@ static pthread_cond_t COND_thread_cache,
bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
my_bool opt_log, opt_slow_log;
+my_bool opt_userstat_running;
ulong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
@@ -548,6 +549,7 @@ ulong binlog_cache_use= 0, binlog_cache_
ulong max_connections, max_connect_errors;
ulong extra_max_connections;
uint max_user_connections= 0;
+ulonglong denied_connections;
/**
Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks.
@@ -649,6 +651,9 @@ pthread_mutex_t LOCK_mysql_create_db, LO
LOCK_global_system_variables,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
LOCK_connection_count, LOCK_uuid_generator;
+pthread_mutex_t LOCK_stats, LOCK_global_user_client_stats;
+pthread_mutex_t LOCK_global_table_stats, LOCK_global_index_stats;
+
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -1342,6 +1347,10 @@ void clean_up(bool print_message)
x_free(opt_secure_file_priv);
bitmap_free(&temp_pool);
free_max_user_conn();
+ free_global_user_stats();
+ free_global_client_stats();
+ free_global_table_stats();
+ free_global_index_stats();
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
@@ -1428,6 +1437,11 @@ static void clean_up_mutexes()
(void) pthread_mutex_destroy(&LOCK_bytes_received);
(void) pthread_mutex_destroy(&LOCK_user_conn);
(void) pthread_mutex_destroy(&LOCK_connection_count);
+ (void) pthread_mutex_destroy(&LOCK_stats);
+ (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
+ (void) pthread_mutex_destroy(&LOCK_global_table_stats);
+ (void) pthread_mutex_destroy(&LOCK_global_index_stats);
+
Events::destroy_mutexes();
#ifdef HAVE_OPENSSL
(void) pthread_mutex_destroy(&LOCK_des_key_file);
@@ -3203,6 +3217,7 @@ SHOW_VAR com_status_vars[]= {
{"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
{"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
{"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
+ {"show_client_stats", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS},
{"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
{"show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
{"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
@@ -3225,6 +3240,7 @@ SHOW_VAR com_status_vars[]= {
{"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
{"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
{"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
+ {"show_index_stats", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
{"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
{"show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
{"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
@@ -3241,9 +3257,11 @@ SHOW_VAR com_status_vars[]= {
{"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
{"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
{"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
+ {"show_table_stats", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
{"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
{"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
{"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
+ {"show_user_stats", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
{"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
{"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
{"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
@@ -3642,6 +3660,12 @@ static int init_thread_environment()
(void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_user_client_stats,
+ MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
+
#ifdef HAVE_OPENSSL
(void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
#ifndef HAVE_YASSL
@@ -4005,6 +4029,9 @@ server.");
/* call ha_init_key_cache() on all key caches to init them */
process_key_caches(&ha_init_key_cache);
+ init_global_table_stats();
+ init_global_index_stats();
+
/* Allow storage engine to give real error messages */
if (ha_init_errors())
DBUG_RETURN(1);
@@ -4210,6 +4237,8 @@ server.");
init_max_user_conn();
init_update_queries();
+ init_global_user_stats();
+ init_global_client_stats();
DBUG_RETURN(0);
}
@@ -5019,6 +5048,7 @@ static void create_new_thread(THD *thd)
DBUG_PRINT("error",("Too many connections"));
close_connection(thd, ER_CON_COUNT_ERROR, 1);
+ statistic_increment(denied_connections, &LOCK_status);
delete thd;
DBUG_VOID_RETURN;
}
@@ -5810,6 +5840,7 @@ enum options_mysqld
OPT_LOG_SLOW_RATE_LIMIT,
OPT_LOG_SLOW_VERBOSITY,
OPT_LOG_SLOW_FILTER,
+ OPT_USERSTAT,
OPT_GENERAL_LOG_FILE,
OPT_SLOW_QUERY_LOG_FILE,
OPT_IGNORE_BUILTIN_INNODB
@@ -7209,6 +7240,10 @@ The minimum value for this variable is 4
(uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
0, 1, 0},
+ {"userstat", OPT_USERSTAT,
+ "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
+ (uchar**) &opt_userstat_running, (uchar**) &opt_userstat_running,
+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -7579,19 +7614,24 @@ static int show_ssl_get_cipher_list(THD
SHOW_VAR status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
+ {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
{"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
{"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
+ {"Busy_time", (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS},
{"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
+ {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
{"Com", (char*) com_status_vars, SHOW_ARRAY},
{"Compression", (char*) &show_net_compression, SHOW_FUNC},
{"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
+ {"Cpu_time", (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS},
{"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
{"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
{"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
{"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
+ {"Empty_queries", (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS},
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
@@ -7626,6 +7666,8 @@ SHOW_VAR status_vars[]= {
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
{"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
{"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
+ {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONG_STATUS},
+ {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONG_STATUS},
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -9110,6 +9152,8 @@ void refresh_status(THD *thd)
/* Reset thread's status variables */
bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
+ bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var));
+ thd->start_bytes_received= 0;
/* Reset some global variables */
reset_status_vars();
=== modified file 'sql/opt_range.cc'
--- sql/opt_range.cc 2009-09-09 21:59:28 +0000
+++ sql/opt_range.cc 2009-10-17 08:13:46 +0000
@@ -8230,7 +8230,7 @@ int QUICK_ROR_INTERSECT_SELECT::get_next
/* We get here if we got the same row ref in all scans. */
if (need_to_fetch_row)
- error= head->file->rnd_pos(head->record[0], last_rowid);
+ error= head->file->ha_rnd_pos(head->record[0], last_rowid);
} while (error == HA_ERR_RECORD_DELETED);
DBUG_RETURN(error);
}
@@ -8296,7 +8296,7 @@ int QUICK_ROR_UNION_SELECT::get_next()
cur_rowid= prev_rowid;
prev_rowid= tmp;
- error= head->file->rnd_pos(quick->record, prev_rowid);
+ error= head->file->ha_rnd_pos(quick->record, prev_rowid);
} while (error == HA_ERR_RECORD_DELETED);
DBUG_RETURN(error);
}
@@ -8521,10 +8521,12 @@ int QUICK_RANGE_SELECT::get_next_prefix(
key_range start_key, end_key;
if (last_range)
{
- /* Read the next record in the same range with prefix after cur_prefix. */
+ /*
+ Read the next record in the same range with prefix after cur_prefix.
+ */
DBUG_ASSERT(cur_prefix != 0);
- result= file->index_read_map(record, cur_prefix, keypart_map,
- HA_READ_AFTER_KEY);
+ result= file->ha_index_read_map(record, cur_prefix, keypart_map,
+ HA_READ_AFTER_KEY);
if (result || (file->compare_key(file->end_range) <= 0))
DBUG_RETURN(result);
}
@@ -8580,8 +8582,8 @@ int QUICK_RANGE_SELECT_GEOM::get_next()
if (last_range)
{
// Already read through key
- result= file->index_next_same(record, last_range->min_key,
- last_range->min_length);
+ result= file->ha_index_next_same(record, last_range->min_key,
+ last_range->min_length);
if (result != HA_ERR_END_OF_FILE)
DBUG_RETURN(result);
}
@@ -8595,10 +8597,10 @@ int QUICK_RANGE_SELECT_GEOM::get_next()
}
last_range= *(cur_range++);
- result= file->index_read_map(record, last_range->min_key,
- last_range->min_keypart_map,
- (ha_rkey_function)(last_range->flag ^
- GEOM_FLAG));
+ result= file->ha_index_read_map(record, last_range->min_key,
+ last_range->min_keypart_map,
+ (ha_rkey_function)(last_range->flag ^
+ GEOM_FLAG));
if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
DBUG_RETURN(result);
last_range= 0; // Not found, to next range
@@ -8710,9 +8712,9 @@ int QUICK_SELECT_DESC::get_next()
{ // Already read through key
result = ((last_range->flag & EQ_RANGE &&
used_key_parts <= head->key_info[index].key_parts) ?
- file->index_next_same(record, last_range->min_key,
+ file->ha_index_next_same(record, last_range->min_key,
last_range->min_length) :
- file->index_prev(record));
+ file->ha_index_prev(record));
if (!result)
{
if (cmp_prev(*rev_it.ref()) == 0)
@@ -8728,7 +8730,7 @@ int QUICK_SELECT_DESC::get_next()
if (last_range->flag & NO_MAX_RANGE) // Read last record
{
int local_error;
- if ((local_error=file->index_last(record)))
+ if ((local_error=file->ha_index_last(record)))
DBUG_RETURN(local_error); // Empty table
if (cmp_prev(last_range) == 0)
DBUG_RETURN(0);
@@ -8740,9 +8742,9 @@ int QUICK_SELECT_DESC::get_next()
used_key_parts <= head->key_info[index].key_parts)
{
- result = file->index_read_map(record, last_range->max_key,
- last_range->max_keypart_map,
- HA_READ_KEY_EXACT);
+ result= file->ha_index_read_map(record, last_range->max_key,
+ last_range->max_keypart_map,
+ HA_READ_KEY_EXACT);
}
else
{
@@ -8750,11 +8752,11 @@ int QUICK_SELECT_DESC::get_next()
(last_range->flag & EQ_RANGE &&
used_key_parts > head->key_info[index].key_parts) ||
range_reads_after_key(last_range));
- result=file->index_read_map(record, last_range->max_key,
- last_range->max_keypart_map,
- ((last_range->flag & NEAR_MAX) ?
- HA_READ_BEFORE_KEY :
- HA_READ_PREFIX_LAST_OR_PREV));
+ result= file->ha_index_read_map(record, last_range->max_key,
+ last_range->max_keypart_map,
+ ((last_range->flag & NEAR_MAX) ?
+ HA_READ_BEFORE_KEY :
+ HA_READ_PREFIX_LAST_OR_PREV));
}
if (result)
{
@@ -10467,7 +10469,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(vo
DBUG_RETURN(result);
if (quick_prefix_select && quick_prefix_select->reset())
DBUG_RETURN(1);
- result= file->index_last(record);
+ result= file->ha_index_last(record);
if (result == HA_ERR_END_OF_FILE)
DBUG_RETURN(0);
/* Save the prefix of the last group. */
@@ -10569,9 +10571,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next
first sub-group with the extended prefix.
*/
if (!have_min && !have_max && key_infix_len > 0)
- result= file->index_read_map(record, group_prefix,
- make_prev_keypart_map(real_key_parts),
- HA_READ_KEY_EXACT);
+ result= file->ha_index_read_map(record, group_prefix,
+ make_prev_keypart_map(real_key_parts),
+ HA_READ_KEY_EXACT);
result= have_min ? min_res : have_max ? max_res : result;
} while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
@@ -10633,9 +10635,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
/* Apply the constant equality conditions to the non-group select fields */
if (key_infix_len > 0)
{
- if ((result= file->index_read_map(record, group_prefix,
- make_prev_keypart_map(real_key_parts),
- HA_READ_KEY_EXACT)))
+ if ((result=
+ file->ha_index_read_map(record, group_prefix,
+ make_prev_keypart_map(real_key_parts),
+ HA_READ_KEY_EXACT)))
DBUG_RETURN(result);
}
@@ -10650,9 +10653,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
{
/* Find the first subsequent record without NULL in the MIN/MAX field. */
key_copy(tmp_record, record, index_info, 0);
- result= file->index_read_map(record, tmp_record,
- make_keypart_map(real_key_parts),
- HA_READ_AFTER_KEY);
+ result= file->ha_index_read_map(record, tmp_record,
+ make_keypart_map(real_key_parts),
+ HA_READ_AFTER_KEY);
/*
Check if the new record belongs to the current group by comparing its
prefix with the group's prefix. If it is from the next group, then the
@@ -10707,9 +10710,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
if (min_max_ranges.elements > 0)
result= next_max_in_range();
else
- result= file->index_read_map(record, group_prefix,
- make_prev_keypart_map(real_key_parts),
- HA_READ_PREFIX_LAST);
+ result= file->ha_index_read_map(record, group_prefix,
+ make_prev_keypart_map(real_key_parts),
+ HA_READ_PREFIX_LAST);
DBUG_RETURN(result);
}
@@ -10752,7 +10755,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_pre
{
if (!seen_first_key)
{
- result= file->index_first(record);
+ result= file->ha_index_first(record);
if (result)
DBUG_RETURN(result);
seen_first_key= TRUE;
@@ -10760,9 +10763,9 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_pre
else
{
/* Load the first key in this group into record. */
- result= file->index_read_map(record, group_prefix,
- make_prev_keypart_map(group_key_parts),
- HA_READ_AFTER_KEY);
+ result= file->ha_index_read_map(record, group_prefix,
+ make_prev_keypart_map(group_key_parts),
+ HA_READ_AFTER_KEY);
if (result)
DBUG_RETURN(result);
}
@@ -10839,7 +10842,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min
HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
}
- result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
+ result= file->ha_index_read_map(record, group_prefix, keypart_map,
+ find_flag);
if (result)
{
if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
@@ -10978,7 +10982,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max
HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
}
- result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
+ result= file->ha_index_read_map(record, group_prefix, keypart_map,
+ find_flag);
if (result)
{
=== modified file 'sql/opt_range.h'
--- sql/opt_range.h 2009-09-02 08:40:18 +0000
+++ sql/opt_range.h 2009-10-17 14:09:21 +0000
@@ -727,7 +727,7 @@ public:
~FT_SELECT() { file->ft_end(); }
int init() { return error=file->ft_init(); }
int reset() { return 0; }
- int get_next() { return error=file->ft_read(record); }
+ int get_next() { return error= file->ha_ft_read(record); }
int get_type() { return QS_TYPE_FULLTEXT; }
};
=== modified file 'sql/opt_sum.cc'
--- sql/opt_sum.cc 2009-09-07 20:50:10 +0000
+++ sql/opt_sum.cc 2009-10-17 08:09:24 +0000
@@ -254,7 +254,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
error= table->file->ha_index_init((uint) ref.key, 1);
if (!ref.key_length)
- error= table->file->index_first(table->record[0]);
+ error= table->file->ha_index_first(table->record[0]);
else
{
/*
@@ -276,10 +276,10 @@ int opt_sum_query(TABLE_LIST *tables, Li
Closed interval: Either The MIN argument is non-nullable, or
we have a >= predicate for the MIN argument.
*/
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_KEY_OR_NEXT);
+ error= table->file->ha_index_read_map(table->record[0],
+ ref.key_buff,
+ make_prev_keypart_map(ref.key_parts),
+ HA_READ_KEY_OR_NEXT);
else
{
/*
@@ -288,10 +288,10 @@ int opt_sum_query(TABLE_LIST *tables, Li
2) there is a > predicate on it, nullability is irrelevant.
We need to scan the next bigger record first.
*/
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_AFTER_KEY);
+ error= table->file->ha_index_read_map(table->record[0],
+ ref.key_buff,
+ make_prev_keypart_map(ref.key_parts),
+ HA_READ_AFTER_KEY);
/*
If the found record is outside the group formed by the search
prefix, or there is no such record at all, check if all
@@ -314,10 +314,10 @@ int opt_sum_query(TABLE_LIST *tables, Li
key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len)))
{
DBUG_ASSERT(item_field->field->real_maybe_null());
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_KEY_EXACT);
+ error= table->file->ha_index_read_map(table->record[0],
+ ref.key_buff,
+ make_prev_keypart_map(ref.key_parts),
+ HA_READ_KEY_EXACT);
}
}
}
@@ -402,13 +402,13 @@ int opt_sum_query(TABLE_LIST *tables, Li
error= table->file->ha_index_init((uint) ref.key, 1);
if (!ref.key_length)
- error= table->file->index_last(table->record[0]);
+ error= table->file->ha_index_last(table->record[0]);
else
- error= table->file->index_read_map(table->record[0], key_buff,
- make_prev_keypart_map(ref.key_parts),
- range_fl & NEAR_MAX ?
- HA_READ_BEFORE_KEY :
- HA_READ_PREFIX_LAST_OR_PREV);
+ error= table->file->ha_index_read_map(table->record[0], key_buff,
+ make_prev_keypart_map(ref.key_parts),
+ range_fl & NEAR_MAX ?
+ HA_READ_BEFORE_KEY :
+ HA_READ_PREFIX_LAST_OR_PREV);
if (!error && reckey_in_range(1, &ref, item_field->field,
conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND;
=== modified file 'sql/records.cc'
--- sql/records.cc 2009-05-06 12:03:24 +0000
+++ sql/records.cc 2009-10-17 08:13:46 +0000
@@ -342,7 +342,7 @@ static int rr_quick(READ_RECORD *info)
static int rr_index_first(READ_RECORD *info)
{
- int tmp= info->file->index_first(info->record);
+ int tmp= info->file->ha_index_first(info->record);
info->read_record= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -368,7 +368,7 @@ static int rr_index_first(READ_RECORD *i
static int rr_index(READ_RECORD *info)
{
- int tmp= info->file->index_next(info->record);
+ int tmp= info->file->ha_index_next(info->record);
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -378,7 +378,7 @@ static int rr_index(READ_RECORD *info)
int rr_sequential(READ_RECORD *info)
{
int tmp;
- while ((tmp=info->file->rnd_next(info->record)))
+ while ((tmp=info->file->ha_rnd_next(info->record)))
{
if (info->thd->killed)
{
@@ -406,7 +406,7 @@ static int rr_from_tempfile(READ_RECORD
{
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
return -1; /* End of file */
- if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos)))
+ if (!(tmp=info->file->ha_rnd_pos(info->record,info->ref_pos)))
break;
/* The following is extremely unlikely to happen */
if (tmp == HA_ERR_RECORD_DELETED ||
@@ -457,7 +457,7 @@ static int rr_from_pointers(READ_RECORD
cache_pos= info->cache_pos;
info->cache_pos+= info->ref_length;
- if (!(tmp=info->file->rnd_pos(info->record,cache_pos)))
+ if (!(tmp=info->file->ha_rnd_pos(info->record,cache_pos)))
break;
/* The following is extremely unlikely to happen */
@@ -590,7 +590,7 @@ static int rr_from_cache(READ_RECORD *in
record=uint3korr(position);
position+=3;
record_pos=info->cache+record*info->reclength;
- if ((error=(int16) info->file->rnd_pos(record_pos,info->ref_pos)))
+ if ((error=(int16) info->file->ha_rnd_pos(record_pos,info->ref_pos)))
{
record_pos[info->error_offset]=1;
shortstore(record_pos,error);
=== modified file 'sql/set_var.cc'
--- sql/set_var.cc 2009-09-15 10:46:35 +0000
+++ sql/set_var.cc 2009-10-18 16:39:56 +0000
@@ -511,6 +511,9 @@ static sys_var_const sys_prot
static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size",
&SV::read_buff_size);
static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly);
+static sys_var_bool_ptr sys_userstat(&vars, "userstat",
+ &opt_userstat_running);
+
static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
&SV::read_rnd_buff_size);
static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
=== modified file 'sql/sp.cc'
--- sql/sp.cc 2009-07-28 22:39:58 +0000
+++ sql/sp.cc 2009-10-17 08:09:24 +0000
@@ -344,8 +344,9 @@ db_find_routine_aux(THD *thd, int type,
key_copy(key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0, key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
DBUG_RETURN(SP_KEY_NOT_FOUND);
DBUG_RETURN(SP_OK);
@@ -1101,9 +1102,9 @@ sp_drop_db_routines(THD *thd, char *db)
ret= SP_OK;
table->file->ha_index_init(0, 1);
- if (! table->file->index_read_map(table->record[0],
- (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
- (key_part_map)1, HA_READ_KEY_EXACT))
+ if (! table->file->ha_index_read_map(table->record[0],
+ (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
+ (key_part_map)1, HA_READ_KEY_EXACT))
{
int nxtres;
bool deleted= FALSE;
@@ -1118,9 +1119,11 @@ sp_drop_db_routines(THD *thd, char *db)
nxtres= 0;
break;
}
- } while (! (nxtres= table->file->index_next_same(table->record[0],
- (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
- key_len)));
+ } while (!(nxtres= table->file->
+ ha_index_next_same(table->record[0],
+ (uchar *)table->field[MYSQL_PROC_FIELD_DB]->
+ ptr,
+ key_len)));
if (nxtres != HA_ERR_END_OF_FILE)
ret= SP_KEY_NOT_FOUND;
if (deleted)
=== modified file 'sql/sql_acl.cc'
--- sql/sql_acl.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_acl.cc 2009-10-17 08:13:46 +0000
@@ -1834,9 +1834,9 @@ static bool update_user_table(THD *thd,
key_copy((uchar *) user_key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0], 0,
- (uchar *) user_key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar *) user_key, HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH),
MYF(0)); /* purecov: deadcode */
@@ -1927,9 +1927,9 @@ static int replace_user_table(THD *thd,
key_copy(user_key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0], 0, user_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0, user_key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
/* what == 'N' means revoke */
if (what == 'N')
@@ -2151,9 +2151,9 @@ static int replace_db_table(TABLE *table
key_copy(user_key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0],0, user_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0],0, user_key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
if (what == 'N')
{ // no row, no revoke
@@ -2369,8 +2369,9 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TA
col_privs->field[4]->store("",0, &my_charset_latin1);
col_privs->file->ha_index_init(0, 1);
- if (col_privs->file->index_read_map(col_privs->record[0], (uchar*) key,
- (key_part_map)15, HA_READ_KEY_EXACT))
+ if (col_privs->file->ha_index_read_map(col_privs->record[0], (uchar*) key,
+ (key_part_map)15,
+ HA_READ_KEY_EXACT))
{
cols = 0; /* purecov: deadcode */
col_privs->file->ha_index_end();
@@ -2391,7 +2392,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TA
return; /* purecov: deadcode */
}
my_hash_insert(&hash_columns, (uchar *) mem_check);
- } while (!col_privs->file->index_next(col_privs->record[0]) &&
+ } while (!col_privs->file->ha_index_next(col_privs->record[0]) &&
!key_cmp_if_same(col_privs,key,0,key_prefix_len));
col_privs->file->ha_index_end();
}
@@ -2532,8 +2533,8 @@ static int replace_column_table(GRANT_TA
key_copy(user_key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_map(table->record[0], user_key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_map(table->record[0], user_key,
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT))
{
if (revoke_grant)
{
@@ -2610,9 +2611,9 @@ static int replace_column_table(GRANT_TA
key_copy(user_key, table->record[0], table->key_info,
key_prefix_length);
- if (table->file->index_read_map(table->record[0], user_key,
- (key_part_map)15,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_map(table->record[0], user_key,
+ (key_part_map)15,
+ HA_READ_KEY_EXACT))
goto end;
/* Scan through all rows with the same host,db,user and table */
@@ -2663,7 +2664,7 @@ static int replace_column_table(GRANT_TA
hash_delete(&g_t->hash_columns,(uchar*) grant_column);
}
}
- } while (!table->file->index_next(table->record[0]) &&
+ } while (!table->file->ha_index_next(table->record[0]) &&
!key_cmp_if_same(table, key, 0, key_prefix_length));
}
@@ -2713,9 +2714,9 @@ static int replace_table_table(THD *thd,
key_copy(user_key, table->record[0], table->key_info,
table->key_info->key_length);
- if (table->file->index_read_idx_map(table->record[0], 0, user_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0, user_key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
/*
The following should never happen as we first check the in memory
@@ -2840,10 +2841,10 @@ static int replace_routine_table(THD *th
TRUE);
store_record(table,record[1]); // store at pos 1
- if (table->file->index_read_idx_map(table->record[0], 0,
- (uchar*) table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar*) table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
/*
The following should never happen as we first check the in memory
@@ -3548,7 +3549,7 @@ static my_bool grant_load_procs_priv(TAB
p_table->file->ha_index_init(0, 1);
p_table->use_all_columns();
- if (!p_table->file->index_first(p_table->record[0]))
+ if (!p_table->file->ha_index_first(p_table->record[0]))
{
memex_ptr= &memex;
my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr);
@@ -3600,7 +3601,7 @@ static my_bool grant_load_procs_priv(TAB
goto end_unlock;
}
}
- while (!p_table->file->index_next(p_table->record[0]));
+ while (!p_table->file->ha_index_next(p_table->record[0]));
}
/* Return ok */
return_val= 0;
@@ -3650,7 +3651,7 @@ static my_bool grant_load(THD *thd, TABL
t_table->use_all_columns();
c_table->use_all_columns();
- if (!t_table->file->index_first(t_table->record[0]))
+ if (!t_table->file->ha_index_first(t_table->record[0]))
{
memex_ptr= &memex;
my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr);
@@ -3685,7 +3686,7 @@ static my_bool grant_load(THD *thd, TABL
goto end_unlock;
}
}
- while (!t_table->file->index_next(t_table->record[0]));
+ while (!t_table->file->ha_index_next(t_table->record[0]));
}
return_val=0; // Return ok
@@ -3957,6 +3958,8 @@ err:
{
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
+ status_var_increment(thd->status_var.access_denied_errors);
+
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command,
sctx->priv_user,
@@ -5203,9 +5206,9 @@ static int handle_grant_table(TABLE_LIST
table->key_info->key_part[1].store_length);
key_copy(user_key, table->record[0], table->key_info, key_prefix_length);
- if ((error= table->file->index_read_idx_map(table->record[0], 0,
- user_key, (key_part_map)3,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_idx_map(table->record[0], 0,
+ user_key, (key_part_map)3,
+ HA_READ_KEY_EXACT)))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
{
@@ -5240,7 +5243,7 @@ static int handle_grant_table(TABLE_LIST
DBUG_PRINT("info",("scan table: '%s' search: '%s'@'%s'",
table->s->table_name.str, user_str, host_str));
#endif
- while ((error= table->file->rnd_next(table->record[0])) !=
+ while ((error= table->file->ha_rnd_next(table->record[0])) !=
HA_ERR_END_OF_FILE)
{
if (error)
=== modified file 'sql/sql_base.cc'
--- sql/sql_base.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_base.cc 2009-10-19 02:07:41 +0000
@@ -1373,6 +1373,12 @@ bool close_thread_table(THD *thd, TABLE
DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
table->s->table_name.str, (long) table));
+ if (table->file)
+ {
+ table->file->update_global_table_stats();
+ table->file->update_global_index_stats();
+ }
+
*table_ptr=table->next;
/*
When closing a MERGE parent or child table, detach the children first.
@@ -1902,6 +1908,13 @@ void close_temporary(TABLE *table, bool
DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
table->s->db.str, table->s->table_name.str));
+ /* in_use is not set for replication temporary tables during shutdown */
+ if (table->in_use)
+ {
+ table->file->update_global_table_stats();
+ table->file->update_global_index_stats();
+ }
+
free_io_cache(table);
closefrm(table, 0);
if (delete_table)
=== modified file 'sql/sql_class.cc'
--- sql/sql_class.cc 2009-09-15 10:46:35 +0000
+++ sql/sql_class.cc 2009-10-18 17:24:57 +0000
@@ -615,6 +615,7 @@ THD::THD()
mysys_var=0;
binlog_evt_union.do_union= FALSE;
enable_slow_log= 0;
+
#ifndef DBUG_OFF
dbug_sentry=THD_SENTRY_MAGIC;
#endif
@@ -817,7 +818,63 @@ void THD::init(void)
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
+ bzero((char *) &org_status_var, sizeof(org_status_var));
sql_log_bin_toplevel= options & OPTION_BIN_LOG;
+ select_commands= update_commands= other_commands= 0;
+ /* Set to handle counting of aborted connections */
+ userstat_running= opt_userstat_running;
+ last_global_update_time= current_connect_time= time(NULL);
+}
+
+
+/* Updates some status variables to be used by update_global_user_stats */
+
+void THD::update_stats(void)
+{
+ /* sql_command == SQLCOM_END in case of parse errors or quit */
+ if (lex->sql_command != SQLCOM_END)
+ {
+ /* The replication thread has the COM_CONNECT command */
+ DBUG_ASSERT(command == COM_QUERY || command == COM_CONNECT);
+
+ /* A SQL query. */
+ if (lex->sql_command == SQLCOM_SELECT)
+ select_commands++;
+ else if (! sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+ {
+ /* Ignore 'SHOW ' commands */
+ }
+ else if (is_update_query(lex->sql_command))
+ update_commands++;
+ else
+ other_commands++;
+ }
+}
+
+
+void THD::update_all_stats()
+{
+ time_t save_time;
+ ulonglong end_cpu_time, end_utime;
+ double busy_time, cpu_time;
+
+ /* This is set at start of query if opt_userstat_running was set */
+ if (!userstat_running)
+ return;
+
+ end_cpu_time= my_getrealtime();
+ end_utime= my_micro_time_and_time(&save_time);
+ busy_time= (end_utime - start_utime) / 1000000.0;
+ cpu_time= (end_cpu_time - start_cpu_time) / 10000000.0;
+ /* In case there are bad values, 2629743 is the #seconds in a month. */
+ if (cpu_time > 2629743.0)
+ cpu_time= 0;
+ status_var_add(status_var.cpu_time, cpu_time);
+ status_var_add(status_var.busy_time, busy_time);
+
+ /* Updates THD stats and the global user stats. */
+ update_stats();
+ update_global_user_stats(this, TRUE, save_time);
}
@@ -984,9 +1041,8 @@ THD::~THD()
from_var from this array
NOTES
- This function assumes that all variables are long/ulong.
- If this assumption will change, then we have to explictely add
- the other variables after the while loop
+ This function assumes that all variables at start are long/ulong and
+ other types are handled explicitely
*/
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
@@ -998,6 +1054,13 @@ void add_to_status(STATUS_VAR *to_var, S
while (to != end)
*(to++)+= *(from++);
+
+ /* Handle the not ulong variables. See end of system_status_var */
+ to_var->bytes_received= from_var->bytes_received;
+ to_var->bytes_sent+= from_var->bytes_sent;
+ to_var->binlog_bytes_written= from_var->binlog_bytes_written;
+ to_var->cpu_time+= from_var->cpu_time;
+ to_var->busy_time+= from_var->busy_time;
}
/*
@@ -1010,7 +1073,8 @@ void add_to_status(STATUS_VAR *to_var, S
dec_var minus this array
NOTE
- This function assumes that all variables are long/ulong.
+ This function assumes that all variables at start are long/ulong and
+ other types are handled explicitely
*/
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
@@ -1023,6 +1087,14 @@ void add_diff_to_status(STATUS_VAR *to_v
while (to != end)
*(to++)+= *(from++) - *(dec++);
+
+ to_var->bytes_received= (from_var->bytes_received -
+ dec_var->bytes_received);
+ to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
+ to_var->binlog_bytes_written= (from_var->binlog_bytes_written -
+ dec_var->binlog_bytes_written);
+ to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time;
+ to_var->busy_time+= from_var->busy_time - dec_var->busy_time;
}
#define SECONDS_TO_WAIT_FOR_KILL 2
@@ -2773,7 +2845,8 @@ void thd_increment_bytes_sent(ulong leng
{
THD *thd=current_thd;
if (likely(thd != 0))
- { /* current_thd==0 when close_connection() calls net_send_error() */
+ {
+ /* current_thd == 0 when close_connection() calls net_send_error() */
thd->status_var.bytes_sent+= length;
}
}
=== modified file 'sql/sql_class.h'
--- sql/sql_class.h 2009-09-15 10:46:35 +0000
+++ sql/sql_class.h 2009-10-18 17:18:46 +0000
@@ -415,8 +415,6 @@ struct system_variables
typedef struct system_status_var
{
- ulonglong bytes_received;
- ulonglong bytes_sent;
ulong com_other;
ulong com_stat[(uint) SQLCOM_END];
ulong created_tmp_disk_tables;
@@ -455,6 +453,9 @@ typedef struct system_status_var
ulong select_range_count;
ulong select_range_check_count;
ulong select_scan_count;
+ ulong rows_examined;
+ ulong rows_read;
+ ulong rows_sent;
ulong long_query_count;
ulong filesort_merge_passes;
ulong filesort_range_count;
@@ -472,6 +473,9 @@ typedef struct system_status_var
Number of statements sent from the client
*/
ulong questions;
+ ulong empty_queries;
+ ulong access_denied_errors; /* Can only be 0 or 1 */
+ ulong lost_connections;
/*
IMPORTANT!
SEE last_system_status_var DEFINITION BELOW.
@@ -480,12 +484,16 @@ typedef struct system_status_var
Status variables which it does not make sense to add to
global status variable counter
*/
+ ulonglong bytes_received;
+ ulonglong bytes_sent;
+ ulonglong binlog_bytes_written;
double last_query_cost;
+ double cpu_time, busy_time;
} STATUS_VAR;
/*
This is used for 'SHOW STATUS'. It must be updated to the last ulong
- variable in system_status_var which is makes sens to add to the global
+ variable in system_status_var which is makes sense to add to the global
counter
*/
@@ -1299,6 +1307,7 @@ public:
struct my_rnd_struct rand; // used for authentication
struct system_variables variables; // Changeable local variables
struct system_status_var status_var; // Per thread statistic vars
+ struct system_status_var org_status_var; // For user statistics
struct system_status_var *initial_status_var; /* used by show status */
THR_LOCK_INFO lock_info; // Locking info of this thread
THR_LOCK_OWNER main_lock_id; // To use for conventional queries
@@ -1399,6 +1408,8 @@ public:
uint in_sub_stmt;
/* TRUE when the current top has SQL_LOG_BIN ON */
bool sql_log_bin_toplevel;
+ /* True when opt_userstat_running is set at start of query */
+ bool userstat_running;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
@@ -1752,6 +1763,7 @@ public:
/* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation;
enum_check_fields count_cuted_fields;
+ ha_rows updated_row_count;
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
@@ -1842,6 +1854,26 @@ public:
*/
LOG_INFO* current_linfo;
NET* slave_net; // network connection from slave -> m.
+
+ /*
+ Used to update global user stats. The global user stats are updated
+ occasionally with the 'diff' variables. After the update, the 'diff'
+ variables are reset to 0.
+ */
+ /* Time when the current thread connected to MySQL. */
+ time_t current_connect_time;
+ /* Last time when THD stats were updated in global_user_stats. */
+ time_t last_global_update_time;
+ /* Number of commands not reflected in global_user_stats yet. */
+ uint select_commands, update_commands, other_commands;
+ ulonglong start_cpu_time;
+ ulonglong start_bytes_received;
+ /*
+ Per account query delay in miliseconds. When not 0, sleep this number of
+ milliseconds before every SQL command.
+ */
+ ulonglong query_delay_millis;
+
/* Used by the sys_var class to store temporary values */
union
{
@@ -1902,6 +1934,12 @@ public:
alloc_root.
*/
void init_for_queries();
+ void update_all_stats();
+ void reset_stats(void);
+ void reset_diff_stats(void);
+ // ran_command is true when this is called immediately after a
+ // command has been run.
+ void update_stats(void);
void change_user(void);
void cleanup(void);
void cleanup_after_query();
@@ -2319,7 +2357,6 @@ private:
MEM_ROOT main_mem_root;
};
-
/** A short cut for thd->main_da.set_ok_status(). */
inline void
=== modified file 'sql/sql_connect.cc'
--- sql/sql_connect.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_connect.cc 2009-10-18 19:37:12 +0000
@@ -20,6 +20,13 @@
#include "mysql_priv.h"
+HASH global_user_stats, global_client_stats, global_table_stats;
+HASH global_index_stats;
+/* Protects the above global stats */
+extern pthread_mutex_t LOCK_global_user_client_stats;
+extern pthread_mutex_t LOCK_global_table_stats;
+extern pthread_mutex_t LOCK_global_index_stats;
+
#ifdef HAVE_OPENSSL
/*
Without SSL the handshake consists of one packet. This packet
@@ -459,6 +466,7 @@ check_user(THD *thd, enum enum_server_co
check_for_max_user_connections(thd, thd->user_connect))
{
/* The error is set in check_for_max_user_connections(). */
+ status_var_increment(denied_connections);
DBUG_RETURN(1);
}
@@ -470,6 +478,7 @@ check_user(THD *thd, enum enum_server_co
/* mysql_change_db() has pushed the error message. */
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
+ status_var_increment(thd->status_var.access_denied_errors);
DBUG_RETURN(1);
}
}
@@ -493,6 +502,8 @@ check_user(THD *thd, enum enum_server_co
thd->main_security_ctx.user,
thd->main_security_ctx.host_or_ip,
passwd_len ? ER(ER_YES) : ER(ER_NO));
+ status_var_increment(thd->status_var.access_denied_errors);
+
DBUG_RETURN(1);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
@@ -520,10 +531,14 @@ extern "C" void free_user(struct user_co
void init_max_user_conn(void)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
- 0,0,
- (hash_get_key) get_key_conn, (hash_free_key) free_user,
- 0);
+ if (hash_init(&hash_user_connections,system_charset_info,max_connections,
+ 0,0,
+ (hash_get_key) get_key_conn, (hash_free_key) free_user,
+ 0))
+ {
+ sql_print_error("Initializing hash_user_connections failed.");
+ exit(1);
+ }
#endif
}
@@ -576,6 +591,449 @@ void reset_mqh(LEX_USER *lu, bool get_th
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
+/*****************************************************************************
+ Handle users statistics
+*****************************************************************************/
+
+/* 'mysql_system_user' is used for when the user is not defined for a THD. */
+static const char mysql_system_user[]= "#mysql_system#";
+
+// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise.
+static const char * get_valid_user_string(char* user)
+{
+ return user ? user : mysql_system_user;
+}
+
+/*
+ Returns string as 'IP' for the client-side of the connection represented by
+ 'client'. Does not allocate memory. May return "".
+*/
+
+static const char *get_client_host(THD *client)
+{
+ return client->security_ctx->host_or_ip[0] ?
+ client->security_ctx->host_or_ip :
+ client->security_ctx->host ? client->security_ctx->host : "";
+}
+
+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length= user_stats->user_name_length;
+ return (uchar*) user_stats->user;
+}
+
+void free_user_stats(USER_STATS* user_stats)
+{
+ my_free(user_stats, MYF(0));
+}
+
+void init_user_stats(USER_STATS *user_stats,
+ const char *user,
+ size_t user_length,
+ const char *priv_user,
+ uint total_connections,
+ uint concurrent_connections,
+ time_t connected_time,
+ double busy_time,
+ double cpu_time,
+ ulonglong bytes_received,
+ ulonglong bytes_sent,
+ ulonglong binlog_bytes_written,
+ ha_rows rows_sent,
+ ha_rows rows_read,
+ ha_rows rows_inserted,
+ ha_rows rows_deleted,
+ ha_rows rows_updated,
+ ulonglong select_commands,
+ ulonglong update_commands,
+ ulonglong other_commands,
+ ulonglong commit_trans,
+ ulonglong rollback_trans,
+ ulonglong denied_connections,
+ ulonglong lost_connections,
+ ulonglong access_denied_errors,
+ ulonglong empty_queries)
+{
+ DBUG_ENTER("init_user_stats");
+ DBUG_PRINT("info",
+ ("Add user_stats entry for user %s - priv_user %s",
+ user, priv_user));
+ user_length= min(user_length, sizeof(user_stats->user)-1);
+ memcpy(user_stats->user, user, user_length);
+ user_stats->user[user_length]= 0;
+ user_stats->user_name_length= user_length;
+ strmake(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user)-1);
+
+ user_stats->total_connections= total_connections;
+ user_stats->concurrent_connections= concurrent_connections;
+ user_stats->connected_time= connected_time;
+ user_stats->busy_time= busy_time;
+ user_stats->cpu_time= cpu_time;
+ user_stats->bytes_received= bytes_received;
+ user_stats->bytes_sent= bytes_sent;
+ user_stats->binlog_bytes_written= binlog_bytes_written;
+ user_stats->rows_sent= rows_sent;
+ user_stats->rows_updated= rows_updated;
+ user_stats->rows_read= rows_read;
+ user_stats->select_commands= select_commands;
+ user_stats->update_commands= update_commands;
+ user_stats->other_commands= other_commands;
+ user_stats->commit_trans= commit_trans;
+ user_stats->rollback_trans= rollback_trans;
+ user_stats->denied_connections= denied_connections;
+ user_stats->lost_connections= lost_connections;
+ user_stats->access_denied_errors= access_denied_errors;
+ user_stats->empty_queries= empty_queries;
+ DBUG_VOID_RETURN;
+}
+
+
+#ifdef COMPLEAT_PATCH_NOT_ADDED_YET
+
+void add_user_stats(USER_STATS *user_stats,
+ uint total_connections,
+ uint concurrent_connections,
+ time_t connected_time,
+ double busy_time,
+ double cpu_time,
+ ulonglong bytes_received,
+ ulonglong bytes_sent,
+ ulonglong binlog_bytes_written,
+ ha_rows rows_sent,
+ ha_rows rows_read,
+ ha_rows rows_inserted,
+ ha_rows rows_deleted,
+ ha_rows rows_updated,
+ ulonglong select_commands,
+ ulonglong update_commands,
+ ulonglong other_commands,
+ ulonglong commit_trans,
+ ulonglong rollback_trans,
+ ulonglong denied_connections,
+ ulonglong lost_connections,
+ ulonglong access_denied_errors,
+ ulonglong empty_queries)
+{
+ user_stats->total_connections+= total_connections;
+ user_stats->concurrent_connections+= concurrent_connections;
+ user_stats->connected_time+= connected_time;
+ user_stats->busy_time+= busy_time;
+ user_stats->cpu_time+= cpu_time;
+ user_stats->bytes_received+= bytes_received;
+ user_stats->bytes_sent+= bytes_sent;
+ user_stats->binlog_bytes_written+= binlog_bytes_written;
+ user_stats->rows_sent+= rows_sent;
+ user_stats->rows_inserted+= rows_inserted;
+ user_stats->rows_deleted+= rows_deleted;
+ user_stats->rows_updated+= rows_updated;
+ user_stats->rows_read+= rows_read;
+ user_stats->select_commands+= select_commands;
+ user_stats->update_commands+= update_commands;
+ user_stats->other_commands+= other_commands;
+ user_stats->commit_trans+= commit_trans;
+ user_stats->rollback_trans+= rollback_trans;
+ user_stats->denied_connections+= denied_connections;
+ user_stats->lost_connections+= lost_connections;
+ user_stats->access_denied_errors+= access_denied_errors;
+ user_stats->empty_queries+= empty_queries;
+}
+#endif
+
+
+void init_global_user_stats(void)
+{
+ if (hash_init(&global_user_stats, system_charset_info, max_connections,
+ 0, 0, (hash_get_key) get_key_user_stats,
+ (hash_free_key)free_user_stats, 0))
+ {
+ sql_print_error("Initializing global_user_stats failed.");
+ exit(1);
+ }
+}
+
+void init_global_client_stats(void)
+{
+ if (hash_init(&global_client_stats, system_charset_info, max_connections,
+ 0, 0, (hash_get_key) get_key_user_stats,
+ (hash_free_key)free_user_stats, 0))
+ {
+ sql_print_error("Initializing global_client_stats failed.");
+ exit(1);
+ }
+}
+
+extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length= table_stats->table_name_length;
+ return (uchar*) table_stats->table;
+}
+
+extern "C" void free_table_stats(TABLE_STATS* table_stats)
+{
+ my_free(table_stats, MYF(0));
+}
+
+void init_global_table_stats(void)
+{
+ if (hash_init(&global_table_stats, system_charset_info, max_connections,
+ 0, 0, (hash_get_key) get_key_table_stats,
+ (hash_free_key)free_table_stats, 0)) {
+ sql_print_error("Initializing global_table_stats failed.");
+ exit(1);
+ }
+}
+
+extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length= index_stats->index_name_length;
+ return (uchar*) index_stats->index;
+}
+
+extern "C" void free_index_stats(INDEX_STATS* index_stats)
+{
+ my_free(index_stats, MYF(0));
+}
+
+void init_global_index_stats(void)
+{
+ if (hash_init(&global_index_stats, system_charset_info, max_connections,
+ 0, 0, (hash_get_key) get_key_index_stats,
+ (hash_free_key)free_index_stats, 0))
+ {
+ sql_print_error("Initializing global_index_stats failed.");
+ exit(1);
+ }
+}
+
+
+void free_global_user_stats(void)
+{
+ hash_free(&global_user_stats);
+}
+
+void free_global_table_stats(void)
+{
+ hash_free(&global_table_stats);
+}
+
+void free_global_index_stats(void)
+{
+ hash_free(&global_index_stats);
+}
+
+void free_global_client_stats(void)
+{
+ hash_free(&global_client_stats);
+}
+
+/*
+ Increments the global stats connection count for an entry from
+ global_client_stats or global_user_stats. Returns 0 on success
+ and 1 on error.
+*/
+
+static int increment_count_by_name(const char *name, size_t name_length,
+ const char *role_name,
+ HASH *users_or_clients, THD *thd)
+{
+ USER_STATS *user_stats;
+
+ if (!(user_stats= (USER_STATS*) hash_search(users_or_clients, (uchar*) name,
+ name_length)))
+ {
+ // First connection for this user or client
+ if (!(user_stats= ((USER_STATS*)
+ my_malloc(sizeof(USER_STATS),
+ MYF(MY_WME | MY_ZEROFILL)))))
+ {
+ return 1; // Out of memory
+ }
+
+ init_user_stats(user_stats, name, name_length, role_name,
+ 0, 0, // connections
+ 0, 0, 0, // time
+ 0, 0, 0, // bytes sent, received and written
+ 0, 0, // Rows sent and read
+ 0, 0, 0, // rows inserted, deleted and updated
+ 0, 0, 0, // select, update and other commands
+ 0, 0, // commit and rollback trans
+ thd->status_var.access_denied_errors,
+ 0, // lost connections
+ 0, // access denied errors
+ 0); // empty queries
+
+ if (my_hash_insert(users_or_clients, (uchar*)user_stats))
+ {
+ my_free(user_stats, 0);
+ return 1; // Out of memory
+ }
+ }
+ user_stats->total_connections++;
+ return 0;
+}
+
+
+/*
+ Increments the global user and client stats connection count.
+
+ @param use_lock if true, LOCK_global_user_client_stats will be locked
+
+ @retval 0 ok
+ @retval 1 error.
+*/
+
+static int increment_connection_count(THD* thd, bool use_lock)
+{
+ const char *user_string= get_valid_user_string(thd->main_security_ctx.user);
+ const char *client_string= get_client_host(thd);
+ int return_value= 0;
+
+ if (!thd->userstat_running)
+ return 0;
+
+ if (use_lock)
+ pthread_mutex_lock(&LOCK_global_user_client_stats);
+
+ if (increment_count_by_name(user_string, strlen(user_string), user_string,
+ &global_user_stats, thd))
+ {
+ return_value= 1;
+ goto end;
+ }
+ if (increment_count_by_name(client_string, strlen(client_string),
+ user_string, &global_client_stats, thd))
+ {
+ return_value= 1;
+ goto end;
+ }
+
+end:
+ if (use_lock)
+ pthread_mutex_unlock(&LOCK_global_user_client_stats);
+ return return_value;
+}
+
+
+/*
+ Used to update the global user and client stats
+*/
+
+static void update_global_user_stats_with_user(THD *thd,
+ USER_STATS *user_stats,
+ time_t now)
+{
+ DBUG_ASSERT(thd->userstat_running);
+
+ user_stats->connected_time+= now - thd->last_global_update_time;
+ user_stats->busy_time+= (thd->status_var.busy_time -
+ thd->org_status_var.busy_time);
+ user_stats->cpu_time+= (thd->status_var.cpu_time -
+ thd->org_status_var.cpu_time);
+ /*
+ This is handle specially as bytes_recieved is incremented BEFORE
+ org_status_var is copied.
+ */
+ user_stats->bytes_received+= (thd->org_status_var.bytes_received-
+ thd->start_bytes_received);
+ user_stats->bytes_sent+= (thd->status_var.bytes_sent -
+ thd->org_status_var.bytes_sent);
+ user_stats->binlog_bytes_written+=
+ (thd->status_var.binlog_bytes_written -
+ thd->org_status_var.binlog_bytes_written);
+ user_stats->rows_read+= (thd->status_var.rows_read -
+ thd->org_status_var.rows_read);
+ user_stats->rows_sent+= (thd->status_var.rows_sent -
+ thd->org_status_var.rows_sent);
+ user_stats->rows_inserted+= (thd->status_var.ha_write_count -
+ thd->org_status_var.ha_write_count);
+ user_stats->rows_deleted+= (thd->status_var.ha_delete_count -
+ thd->org_status_var.ha_delete_count);
+ user_stats->rows_updated+= (thd->status_var.ha_update_count -
+ thd->org_status_var.ha_update_count);
+ user_stats->select_commands+= thd->select_commands;
+ user_stats->update_commands+= thd->update_commands;
+ user_stats->other_commands+= thd->other_commands;
+ user_stats->commit_trans+= (thd->status_var.ha_commit_count -
+ thd->org_status_var.ha_commit_count);
+ user_stats->rollback_trans+= (thd->status_var.ha_rollback_count +
+ thd->status_var.ha_savepoint_rollback_count -
+ thd->org_status_var.ha_rollback_count -
+ thd->org_status_var.
+ ha_savepoint_rollback_count);
+ user_stats->access_denied_errors+=
+ (thd->status_var.access_denied_errors -
+ thd->org_status_var.access_denied_errors);
+ user_stats->empty_queries+= (thd->status_var.empty_queries -
+ thd->org_status_var.empty_queries);
+
+ /* The following can only contain 0 or 1 and then connection ends */
+ user_stats->denied_connections+= thd->status_var.access_denied_errors;
+ user_stats->lost_connections+= thd->status_var.lost_connections;
+}
+
+
+/* Updates the global stats of a user or client */
+void update_global_user_stats(THD *thd, bool create_user, time_t now)
+{
+ const char *user_string, *client_string;
+ USER_STATS *user_stats;
+ size_t user_string_length, client_string_length;
+
+ if (!thd->userstat_running)
+ return;
+
+ user_string= get_valid_user_string(thd->main_security_ctx.user);
+ user_string_length= strlen(user_string);
+ client_string= get_client_host(thd);
+ client_string_length= strlen(client_string);
+
+ pthread_mutex_lock(&LOCK_global_user_client_stats);
+
+ // Update by user name
+ if ((user_stats= (USER_STATS*) hash_search(&global_user_stats,
+ (uchar*) user_string,
+ user_string_length)))
+ {
+ /* Found user. */
+ update_global_user_stats_with_user(thd, user_stats, now);
+ }
+ else
+ {
+ /* Create the entry */
+ if (create_user)
+ {
+ increment_count_by_name(user_string, user_string_length, user_string,
+ &global_user_stats, thd);
+ }
+ }
+
+ /* Update by client IP */
+ if ((user_stats= (USER_STATS*)hash_search(&global_client_stats,
+ (uchar*) client_string,
+ client_string_length)))
+ {
+ // Found by client IP
+ update_global_user_stats_with_user(thd, user_stats, now);
+ }
+ else
+ {
+ // Create the entry
+ if (create_user)
+ {
+ increment_count_by_name(client_string, client_string_length,
+ user_string, &global_client_stats, thd);
+ }
+ }
+ /* Reset variables only used for counting */
+ thd->select_commands= thd->update_commands= thd->other_commands= 0;
+ thd->last_global_update_time= now;
+
+ pthread_mutex_unlock(&LOCK_global_user_client_stats);
+}
+
void thd_init_client_charset(THD *thd, uint cs_number)
{
@@ -970,6 +1428,14 @@ bool login_connection(THD *thd)
/* Connect completed, set read/write timeouts back to default */
my_net_set_read_timeout(net, thd->variables.net_read_timeout);
my_net_set_write_timeout(net, thd->variables.net_write_timeout);
+
+ /* Updates global user connection stats. */
+ if (increment_connection_count(thd, TRUE))
+ {
+ net_send_error(thd, ER_OUTOFMEMORY); // Out of memory
+ DBUG_RETURN(1);
+ }
+
DBUG_RETURN(0);
}
@@ -991,6 +1457,7 @@ void end_connection(THD *thd)
if (thd->killed || (net->error && net->vio != 0))
{
statistic_increment(aborted_threads,&LOCK_status);
+ status_var_increment(thd->status_var.lost_connections);
}
if (net->error && net->vio != 0)
@@ -1117,10 +1584,14 @@ pthread_handler_t handle_one_connection(
for (;;)
{
NET *net= &thd->net;
+ bool create_user= TRUE;
lex_start(thd);
if (login_connection(thd))
+ {
+ create_user= FALSE;
goto end_thread;
+ }
prepare_new_connection_state(thd);
@@ -1134,12 +1605,13 @@ pthread_handler_t handle_one_connection(
end_thread:
close_connection(thd, 0, 1);
+ update_global_user_stats(thd, create_user, time(NULL));
+
if (thd->scheduler->end_thread(thd,1))
return 0; // Probably no-threads
/*
- If end_thread() returns, we are either running with
- thread-handler=no-threads or this thread has been schedule to
+ If end_thread() returns, this thread has been schedule to
handle the next connection.
*/
thd= current_thd;
=== modified file 'sql/sql_cursor.cc'
--- sql/sql_cursor.cc 2008-12-10 14:16:21 +0000
+++ sql/sql_cursor.cc 2009-10-17 08:13:46 +0000
@@ -655,7 +655,7 @@ void Materialized_cursor::fetch(ulong nu
result->begin_dataset();
for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++)
{
- if ((res= table->file->rnd_next(table->record[0])))
+ if ((res= table->file->ha_rnd_next(table->record[0])))
break;
/* Send data only if the read was successful. */
result->send_data(item_list);
=== modified file 'sql/sql_handler.cc'
--- sql/sql_handler.cc 2009-07-15 23:23:57 +0000
+++ sql/sql_handler.cc 2009-10-17 08:09:24 +0000
@@ -565,8 +565,8 @@ retry:
if (table->file->inited != handler::NONE)
{
error=keyname ?
- table->file->index_next(table->record[0]) :
- table->file->rnd_next(table->record[0]);
+ table->file->ha_index_next(table->record[0]) :
+ table->file->ha_rnd_next(table->record[0]);
break;
}
/* else fall through */
@@ -575,13 +575,13 @@ retry:
{
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno, 1);
- error= table->file->index_first(table->record[0]);
+ error= table->file->ha_index_first(table->record[0]);
}
else
{
table->file->ha_index_or_rnd_end();
if (!(error= table->file->ha_rnd_init(1)))
- error= table->file->rnd_next(table->record[0]);
+ error= table->file->ha_rnd_next(table->record[0]);
}
mode=RNEXT;
break;
@@ -589,7 +589,7 @@ retry:
DBUG_ASSERT(keyname != 0);
if (table->file->inited != handler::NONE)
{
- error=table->file->index_prev(table->record[0]);
+ error=table->file->ha_index_prev(table->record[0]);
break;
}
/* else fall through */
@@ -597,13 +597,13 @@ retry:
DBUG_ASSERT(keyname != 0);
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno, 1);
- error= table->file->index_last(table->record[0]);
+ error= table->file->ha_index_last(table->record[0]);
mode=RPREV;
break;
case RNEXT_SAME:
/* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */
DBUG_ASSERT(keyname != 0);
- error= table->file->index_next_same(table->record[0], key, key_len);
+ error= table->file->ha_index_next_same(table->record[0], key, key_len);
break;
case RKEY:
{
@@ -643,8 +643,8 @@ retry:
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno, 1);
key_copy(key, table->record[0], table->key_info + keyno, key_len);
- error= table->file->index_read_map(table->record[0],
- key, keypart_map, ha_rkey_mode);
+ error= table->file->ha_index_read_map(table->record[0],
+ key, keypart_map, ha_rkey_mode);
mode=rkey_to_rnext[(int)ha_rkey_mode];
break;
}
=== modified file 'sql/sql_help.cc'
--- sql/sql_help.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_help.cc 2009-10-17 08:09:23 +0000
@@ -294,13 +294,13 @@ int get_topics_for_keyword(THD *thd, TAB
rkey_id->store((longlong) key_id, TRUE);
rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW);
- int key_res= relations->file->index_read_map(relations->record[0],
- buff, (key_part_map) 1,
- HA_READ_KEY_EXACT);
+ int key_res= relations->file->ha_index_read_map(relations->record[0],
+ buff, (key_part_map) 1,
+ HA_READ_KEY_EXACT);
for ( ;
!key_res && key_id == (int16) rkey_id->val_int() ;
- key_res= relations->file->index_next(relations->record[0]))
+ key_res= relations->file->ha_index_next(relations->record[0]))
{
uchar topic_id_buff[8];
longlong topic_id= rtopic_id->val_int();
@@ -308,8 +308,8 @@ int get_topics_for_keyword(THD *thd, TAB
field->store((longlong) topic_id, TRUE);
field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW);
- if (!topics->file->index_read_map(topics->record[0], topic_id_buff,
- (key_part_map)1, HA_READ_KEY_EXACT))
+ if (!topics->file->ha_index_read_map(topics->record[0], topic_id_buff,
+ (key_part_map)1, HA_READ_KEY_EXACT))
{
memorize_variant_topic(thd,topics,count,find_fields,
names,name,description,example);
=== modified file 'sql/sql_insert.cc'
--- sql/sql_insert.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_insert.cc 2009-10-17 14:12:45 +0000
@@ -1425,7 +1425,7 @@ int write_record(THD *thd, TABLE *table,
goto err;
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
{
- if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
+ if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))
goto err;
}
else
@@ -1446,9 +1446,10 @@ int write_record(THD *thd, TABLE *table,
}
}
key_copy((uchar*) key,table->record[0],table->key_info+key_nr,0);
- if ((error=(table->file->index_read_idx_map(table->record[1],key_nr,
- (uchar*) key, HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))))
+ if ((error=(table->file->ha_index_read_idx_map(table->record[1],key_nr,
+ (uchar*) key,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))))
goto err;
}
if (info->handle_duplicates == DUP_UPDATE)
=== modified file 'sql/sql_lex.h'
--- sql/sql_lex.h 2009-09-15 10:46:35 +0000
+++ sql/sql_lex.h 2009-10-16 10:20:13 +0000
@@ -118,6 +118,8 @@ enum enum_sql_command {
SQLCOM_SHOW_CREATE_TRIGGER,
SQLCOM_ALTER_DB_UPGRADE,
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
+ SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
+ SQLCOM_SHOW_CLIENT_STATS,
/*
When a command is added here, be sure it's also added in mysqld.cc
=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc 2009-09-15 10:46:35 +0000
+++ sql/sql_parse.cc 2009-10-18 17:19:36 +0000
@@ -549,7 +549,6 @@ end:
DBUG_RETURN(0);
}
-
/**
@brief Check access privs for a MERGE table and fix children lock types.
@@ -801,6 +800,8 @@ bool do_command(THD *thd)
net_new_transaction(net);
+ /* Save for user statistics */
+ thd->start_bytes_received= thd->status_var.bytes_received;
packet_length= my_net_read(net);
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query();
@@ -1324,7 +1325,7 @@ bool dispatch_command(enum enum_server_c
table_list.select_lex= &(thd->lex->select_lex);
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
thd->lex->
select_lex.table_list.link_in_list((uchar*) &table_list,
@@ -1609,6 +1610,9 @@ bool dispatch_command(enum enum_server_c
/* Free tables */
close_thread_tables(thd);
+ /* Update status; Must be done after close_thread_tables */
+ thd->update_all_stats();
+
log_slow_statement(thd);
thd_proc_info(thd, "cleaning up");
@@ -1777,6 +1781,11 @@ int prepare_schema_table(THD *thd, LEX *
thd->profiling.discard_current_query();
#endif
break;
+ case SCH_USER_STATS:
+ case SCH_CLIENT_STATS:
+ return check_global_access(thd, SUPER_ACL | PROCESS_ACL);
+ case SCH_TABLE_STATS:
+ case SCH_INDEX_STATS:
case SCH_OPEN_TABLES:
case SCH_VARIABLES:
case SCH_STATUS:
@@ -5059,6 +5068,10 @@ static bool execute_sqlcom_select(THD *t
delete result;
}
}
+ /* Count number of empty select queries */
+ if (!thd->sent_row_count)
+ status_var_increment(thd->status_var.empty_queries);
+ status_var_add(thd->status_var.rows_sent, thd->sent_row_count);
return res;
}
@@ -5220,6 +5233,7 @@ check_access(THD *thd, ulong want_access
if (!no_errors)
{
const char *db_name= db ? db : thd->db;
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host, db_name);
}
@@ -5252,12 +5266,15 @@ check_access(THD *thd, ulong want_access
{ // We can never grant this
DBUG_PRINT("error",("No possible access"));
if (!no_errors)
+ {
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user,
sctx->priv_host,
(thd->password ?
ER(ER_YES) :
ER(ER_NO))); /* purecov: tested */
+ }
DBUG_RETURN(TRUE); /* purecov: tested */
}
@@ -5283,11 +5300,14 @@ check_access(THD *thd, ulong want_access
DBUG_PRINT("error",("Access denied"));
if (!no_errors)
+ {
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host,
(db ? db : (thd->db ?
thd->db :
"unknown"))); /* purecov: tested */
+ }
DBUG_RETURN(TRUE); /* purecov: tested */
}
@@ -5316,6 +5336,7 @@ static bool check_show_access(THD *thd,
if (!thd->col_access && check_grant_db(thd, dst_db_name))
{
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user,
thd->security_ctx->priv_host,
@@ -5378,14 +5399,14 @@ check_table_access(THD *thd, ulong want_
{
TABLE_LIST *org_tables= tables;
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
- uint i= 0;
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
+ uint i;
/*
The check that first_not_own_table is not reached is for the case when
the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0.
*/
- for (; i < number && tables != first_not_own_table;
+ for (i=0; i < number && tables != first_not_own_table;
tables= tables->next_global, i++)
{
if (tables->security_ctx)
@@ -5397,9 +5418,12 @@ check_table_access(THD *thd, ulong want_
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
{
if (!no_errors)
+ {
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host,
INFORMATION_SCHEMA_NAME.str);
+ }
return TRUE;
}
/*
@@ -5563,6 +5587,7 @@ bool check_global_access(THD *thd, ulong
return 0;
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
+ status_var_increment(thd->status_var.access_denied_errors);
return 1;
#else
return 0;
@@ -5666,7 +5691,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE
Call it after we use THD for queries, not before.
*/
-void mysql_reset_thd_for_next_command(THD *thd)
+void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat)
{
DBUG_ENTER("mysql_reset_thd_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
@@ -5711,6 +5736,16 @@ void mysql_reset_thd_for_next_command(TH
thd->total_warn_count=0; // Warnings for this query
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
+ thd->updated_row_count=0;
+
+ /* Copy data for user stats */
+ if ((thd->userstat_running= calculate_userstat))
+ {
+ thd->start_cpu_time= my_getrealtime();
+ memcpy(&thd->org_status_var, &thd->status_var, sizeof(thd->status_var));
+ thd->select_commands= thd->update_commands= thd->other_commands= 0;
+ }
+
thd->query_plan_flags= QPLAN_INIT;
thd->query_plan_fsort_passes= 0;
@@ -5909,7 +5944,6 @@ void mysql_parse(THD *thd, const char *i
const char ** found_semicolon)
{
DBUG_ENTER("mysql_parse");
-
DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
/*
@@ -5929,7 +5963,7 @@ void mysql_parse(THD *thd, const char *i
FIXME: cleanup the dependencies in the code to simplify this.
*/
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
{
@@ -6001,10 +6035,11 @@ void mysql_parse(THD *thd, const char *i
}
else
{
+ /* Update statistics for getting the query from the cache */
+ thd->lex->sql_command= SQLCOM_SELECT;
/* There are no multi queries in the cache. */
*found_semicolon= NULL;
}
-
DBUG_VOID_RETURN;
}
@@ -6028,7 +6063,7 @@ bool mysql_test_parse_for_slave(THD *thd
Parser_state parser_state(thd, inBuf, length);
lex_start(thd);
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, 0);
if (!parse_sql(thd, & parser_state, NULL) &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
@@ -6867,6 +6902,12 @@ bool reload_acl_and_cache(THD *thd, ulon
if (flush_error_log())
result=1;
}
+ if (options & REFRESH_SLOW_QUERY_LOG)
+ {
+ /* We are only flushing slow query log */
+ logger.flush_slow_log(thd);
+ }
+
#ifdef HAVE_QUERY_CACHE
if (options & REFRESH_QUERY_CACHE_FREE)
{
@@ -6949,26 +6990,55 @@ bool reload_acl_and_cache(THD *thd, ulon
}
#endif
#ifdef OPENSSL
- if (options & REFRESH_DES_KEY_FILE)
- {
- if (des_key_file && load_des_key_file(des_key_file))
- result= 1;
- }
+ if (options & REFRESH_DES_KEY_FILE)
+ {
+ if (des_key_file && load_des_key_file(des_key_file))
+ result= 1;
+ }
#endif
#ifdef HAVE_REPLICATION
- if (options & REFRESH_SLAVE)
- {
- tmp_write_to_binlog= 0;
- pthread_mutex_lock(&LOCK_active_mi);
- if (reset_slave(thd, active_mi))
- result=1;
- pthread_mutex_unlock(&LOCK_active_mi);
- }
-#endif
- if (options & REFRESH_USER_RESOURCES)
- reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
- *write_to_binlog= tmp_write_to_binlog;
- return result;
+ if (options & REFRESH_SLAVE)
+ {
+ tmp_write_to_binlog= 0;
+ pthread_mutex_lock(&LOCK_active_mi);
+ if (reset_slave(thd, active_mi))
+ result=1;
+ pthread_mutex_unlock(&LOCK_active_mi);
+ }
+#endif
+ if (options & REFRESH_USER_RESOURCES)
+ reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
+ if (options & REFRESH_TABLE_STATS)
+ {
+ pthread_mutex_lock(&LOCK_global_table_stats);
+ free_global_table_stats();
+ init_global_table_stats();
+ pthread_mutex_unlock(&LOCK_global_table_stats);
+ }
+ if (options & REFRESH_INDEX_STATS)
+ {
+ pthread_mutex_lock(&LOCK_global_index_stats);
+ free_global_index_stats();
+ init_global_index_stats();
+ pthread_mutex_unlock(&LOCK_global_index_stats);
+ }
+ if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS))
+ {
+ pthread_mutex_lock(&LOCK_global_user_client_stats);
+ if (options & REFRESH_USER_STATS)
+ {
+ free_global_user_stats();
+ init_global_user_stats();
+ }
+ if (options & REFRESH_CLIENT_STATS)
+ {
+ free_global_client_stats();
+ init_global_client_stats();
+ }
+ pthread_mutex_unlock(&LOCK_global_user_client_stats);
+ }
+ *write_to_binlog= tmp_write_to_binlog;
+ return result;
}
@@ -7004,7 +7074,6 @@ uint kill_one_thread(THD *thd, ulong id,
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{
-
/*
If we're SUPER, we can KILL anything, including system-threads.
No further checks.
=== modified file 'sql/sql_plugin.cc'
--- sql/sql_plugin.cc 2009-10-01 21:27:39 +0000
+++ sql/sql_plugin.cc 2009-10-17 08:09:23 +0000
@@ -1790,10 +1790,10 @@ bool mysql_uninstall_plugin(THD *thd, co
table->use_all_columns();
table->field[0]->store(name->str, name->length, system_charset_info);
- if (! table->file->index_read_idx_map(table->record[0], 0,
- (uchar *)table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (! table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar *)table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
int error;
/*
=== modified file 'sql/sql_prepare.cc'
--- sql/sql_prepare.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_prepare.cc 2009-10-18 16:38:12 +0000
@@ -2067,14 +2067,13 @@ void mysqld_stmt_prepare(THD *thd, const
Prepared_statement *stmt;
bool error;
DBUG_ENTER("mysqld_stmt_prepare");
-
DBUG_PRINT("prep_query", ("%s", packet));
/* First of all clear possible warnings from the previous command */
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
if (! (stmt= new Prepared_statement(thd)))
- DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
+ goto end; /* out of memory: error is set in Sql_alloc */
if (thd->stmt_map.insert(thd, stmt))
{
@@ -2082,7 +2081,7 @@ void mysqld_stmt_prepare(THD *thd, const
The error is set in the insert. The statement itself
will be also deleted there (this is how the hash works).
*/
- DBUG_VOID_RETURN;
+ goto end;
}
/* Reset warnings from previous command */
@@ -2109,6 +2108,7 @@ void mysqld_stmt_prepare(THD *thd, const
thd->protocol= save_protocol;
/* check_prepared_statemnt sends the metadata packet in case of success */
+end:
DBUG_VOID_RETURN;
}
@@ -2450,7 +2450,7 @@ void mysqld_stmt_execute(THD *thd, char
packet+= 9; /* stmt_id + 5 bytes of flags */
/* First of all clear possible warnings from the previous command */
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
@@ -2549,7 +2549,8 @@ void mysqld_stmt_fetch(THD *thd, char *p
DBUG_ENTER("mysqld_stmt_fetch");
/* First of all clear possible warnings from the previous command */
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
+
status_var_increment(thd->status_var.com_stmt_fetch);
if (!(stmt= find_prepared_statement(thd, stmt_id)))
{
@@ -2615,7 +2616,7 @@ void mysqld_stmt_reset(THD *thd, char *p
DBUG_ENTER("mysqld_stmt_reset");
/* First of all clear possible warnings from the previous command */
- mysql_reset_thd_for_next_command(thd);
+ mysql_reset_thd_for_next_command(thd, opt_userstat_running);
status_var_increment(thd->status_var.com_stmt_reset);
if (!(stmt= find_prepared_statement(thd, stmt_id)))
=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc 2009-09-15 10:46:35 +0000
+++ sql/sql_select.cc 2009-10-17 14:09:17 +0000
@@ -10949,7 +10949,7 @@ create_internal_tmp_table_from_heap2(THD
is safe as this is a temporary MyISAM table without timestamp/autoincrement
or partitioning.
*/
- while (!table->file->rnd_next(new_table.record[1]))
+ while (!table->file->ha_rnd_next(new_table.record[1]))
{
write_err= new_table.file->ha_write_row(new_table.record[1]);
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
@@ -11746,10 +11746,10 @@ int safe_index_read(JOIN_TAB *tab)
{
int error;
TABLE *table= tab->table;
- if ((error=table->file->index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT)))
+ if ((error=table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->ref.key_parts),
+ HA_READ_KEY_EXACT)))
return report_error(table, error);
return 0;
}
@@ -11858,8 +11858,8 @@ join_read_system(JOIN_TAB *tab)
int error;
if (table->status & STATUS_GARBAGE) // If first read
{
- if ((error=table->file->read_first_row(table->record[0],
- table->s->primary_key)))
+ if ((error=table->file->ha_read_first_row(table->record[0],
+ table->s->primary_key)))
{
if (error != HA_ERR_END_OF_FILE)
return report_error(table, error);
@@ -11901,10 +11901,10 @@ join_read_const(JOIN_TAB *tab)
error=HA_ERR_KEY_NOT_FOUND;
else
{
- error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
- (uchar*) tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT);
+ error=table->file->ha_index_read_idx_map(table->record[0],tab->ref.key,
+ (uchar*) tab->ref.key_buff,
+ make_prev_keypart_map(tab->ref.key_parts),
+ HA_READ_KEY_EXACT);
}
if (error)
{
@@ -11949,10 +11949,10 @@ join_read_key(JOIN_TAB *tab)
table->status=STATUS_NOT_FOUND;
return -1;
}
- error=table->file->index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT);
+ error=table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->ref.key_parts),
+ HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
}
@@ -12005,10 +12005,10 @@ join_read_always_key(JOIN_TAB *tab)
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
- if ((error=table->file->index_read_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts),
- HA_READ_KEY_EXACT)))
+ if ((error=table->file->ha_index_read_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->ref.key_parts),
+ HA_READ_KEY_EXACT)))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
@@ -12039,9 +12039,9 @@ join_read_last_key(JOIN_TAB *tab)
}
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
- if ((error=table->file->index_read_last_map(table->record[0],
- tab->ref.key_buff,
- make_prev_keypart_map(tab->ref.key_parts))))
+ if ((error= table->file->ha_index_read_last_map(table->record[0],
+ tab->ref.key_buff,
+ make_prev_keypart_map(tab->ref.key_parts))))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
@@ -12066,9 +12066,9 @@ join_read_next_same(READ_RECORD *info)
TABLE *table= info->table;
JOIN_TAB *tab=table->reginfo.join_tab;
- if ((error=table->file->index_next_same(table->record[0],
- tab->ref.key_buff,
- tab->ref.key_length)))
+ if ((error= table->file->ha_index_next_same(table->record[0],
+ tab->ref.key_buff,
+ tab->ref.key_length)))
{
if (error != HA_ERR_END_OF_FILE)
return report_error(table, error);
@@ -12086,7 +12086,7 @@ join_read_prev_same(READ_RECORD *info)
TABLE *table= info->table;
JOIN_TAB *tab=table->reginfo.join_tab;
- if ((error=table->file->index_prev(table->record[0])))
+ if ((error= table->file->ha_index_prev(table->record[0])))
return report_error(table, error);
if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
tab->ref.key_length))
@@ -12158,7 +12158,7 @@ join_read_first(JOIN_TAB *tab)
error= table->file->ha_index_init(tab->index, tab->sorted);
if (!error)
error= table->file->prepare_index_scan();
- if (error || (error=tab->table->file->index_first(tab->table->record[0])))
+ if (error || (error=tab->table->file->ha_index_first(tab->table->record[0])))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
report_error(table, error);
@@ -12172,7 +12172,7 @@ static int
join_read_next(READ_RECORD *info)
{
int error;
- if ((error=info->file->index_next(info->record)))
+ if ((error= info->file->ha_index_next(info->record)))
return report_error(info->table, error);
return 0;
}
@@ -12199,7 +12199,7 @@ join_read_last(JOIN_TAB *tab)
error= table->file->ha_index_init(tab->index, 1);
if (!error)
error= table->file->prepare_index_scan();
- if (error || (error= tab->table->file->index_last(tab->table->record[0])))
+ if (error || (error= tab->table->file->ha_index_last(tab->table->record[0])))
return report_error(table, error);
return 0;
}
@@ -12209,7 +12209,7 @@ static int
join_read_prev(READ_RECORD *info)
{
int error;
- if ((error= info->file->index_prev(info->record)))
+ if ((error= info->file->ha_index_prev(info->record)))
return report_error(info->table, error);
return 0;
}
@@ -12234,7 +12234,7 @@ join_ft_read_first(JOIN_TAB *tab)
#endif
table->file->ft_init();
- if ((error= table->file->ft_read(table->record[0])))
+ if ((error= table->file->ha_ft_read(table->record[0])))
return report_error(table, error);
return 0;
}
@@ -12243,7 +12243,7 @@ static int
join_ft_read_next(READ_RECORD *info)
{
int error;
- if ((error= info->file->ft_read(info->table->record[0])))
+ if ((error= info->file->ha_ft_read(info->table->record[0])))
return report_error(info->table, error);
return 0;
}
@@ -12590,10 +12590,10 @@ end_update(JOIN *join, JOIN_TAB *join_ta
if (item->maybe_null)
group->buff[-1]= (char) group->field->is_null();
}
- if (!table->file->index_read_map(table->record[1],
- join->tmp_table_param.group_buff,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (!table->file->ha_index_read_map(table->record[1],
+ join->tmp_table_param.group_buff,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{ /* Update old record */
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
@@ -12671,7 +12671,7 @@ end_unique_update(JOIN *join, JOIN_TAB *
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
}
- if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
+ if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -14016,7 +14016,7 @@ static int remove_dup_with_compare(THD *
new_record=(char*) table->record[1]+offset;
file->ha_rnd_init(1);
- error=file->rnd_next(record);
+ error=file->ha_rnd_next(record);
for (;;)
{
if (thd->killed)
@@ -14037,7 +14037,7 @@ static int remove_dup_with_compare(THD *
{
if ((error=file->ha_delete_row(record)))
goto err;
- error=file->rnd_next(record);
+ error=file->ha_rnd_next(record);
continue;
}
if (copy_blobs(first_field))
@@ -14052,7 +14052,7 @@ static int remove_dup_with_compare(THD *
bool found=0;
for (;;)
{
- if ((error=file->rnd_next(record)))
+ if ((error=file->ha_rnd_next(record)))
{
if (error == HA_ERR_RECORD_DELETED)
continue;
@@ -14152,7 +14152,7 @@ static int remove_dup_with_hash_index(TH
error=0;
goto err;
}
- if ((error=file->rnd_next(record)))
+ if ((error= file->ha_rnd_next(record)))
{
if (error == HA_ERR_RECORD_DELETED)
continue;
=== modified file 'sql/sql_servers.cc'
--- sql/sql_servers.cc 2009-03-20 14:27:53 +0000
+++ sql/sql_servers.cc 2009-10-17 08:09:23 +0000
@@ -520,10 +520,10 @@ int insert_server_record(TABLE *table, F
system_charset_info);
/* read index until record is that specified in server_name */
- if ((error= table->file->index_read_idx_map(table->record[0], 0,
- (uchar *)table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar *)table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
/* if not found, err */
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -863,10 +863,10 @@ update_server_record(TABLE *table, FOREI
server->server_name_length,
system_charset_info);
- if ((error= table->file->index_read_idx_map(table->record[0], 0,
- (uchar *)table->field[0]->ptr,
- ~(longlong)0,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar *)table->field[0]->ptr,
+ ~(longlong)0,
+ HA_READ_KEY_EXACT)))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
table->file->print_error(error, MYF(0));
@@ -920,10 +920,10 @@ delete_server_record(TABLE *table,
/* set the field that's the PK to the value we're looking for */
table->field[0]->store(server_name, server_name_length, system_charset_info);
- if ((error= table->file->index_read_idx_map(table->record[0], 0,
- (uchar *)table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT)))
+ if ((error= table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar *)table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT)))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
table->file->print_error(error, MYF(0));
=== modified file 'sql/sql_show.cc'
--- sql/sql_show.cc 2009-09-23 11:03:47 +0000
+++ sql/sql_show.cc 2009-10-18 19:28:52 +0000
@@ -714,6 +714,7 @@ bool mysqld_show_create_db(THD *thd, cha
sctx->master_access);
if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
{
+ status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->host_or_ip, dbname);
general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
@@ -2100,11 +2101,6 @@ void remove_status_vars(SHOW_VAR *list)
}
}
-inline void make_upper(char *buf)
-{
- for (; *buf; buf++)
- *buf= my_toupper(system_charset_info, *buf);
-}
static bool show_status_array(THD *thd, const char *wild,
SHOW_VAR *variables,
@@ -2143,7 +2139,7 @@ static bool show_status_array(THD *thd,
strnmov(prefix_end, variables->name, len);
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
if (ucase_names)
- make_upper(name_buffer);
+ my_caseup_str(system_charset_info, name_buffer);
restore_record(table, s->default_values);
table->field[0]->store(name_buffer, strlen(name_buffer),
@@ -2270,6 +2266,323 @@ end:
DBUG_RETURN(res);
}
+#ifdef COMPLEAT_PATCH_NOT_ADDED_YET
+/*
+ Aggregate values for mapped_user entries by their role.
+
+ SYNOPSIS
+ aggregate_user_stats
+ all_user_stats - input to aggregate
+ agg_user_stats - returns aggregated values
+
+ RETURN
+ 0 - OK
+ 1 - error
+*/
+
+static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats)
+{
+ DBUG_ENTER("aggregate_user_stats");
+ if (hash_init(agg_user_stats, system_charset_info,
+ max(all_user_stats->records, 1),
+ 0, 0, (hash_get_key)get_key_user_stats,
+ (hash_free_key)free_user_stats, 0))
+ {
+ sql_print_error("Malloc in aggregate_user_stats failed");
+ DBUG_RETURN(1);
+ }
+
+ for (uint i= 0; i < all_user_stats->records; i++)
+ {
+ USER_STATS *user= (USER_STATS*)hash_element(all_user_stats, i);
+ USER_STATS *agg_user;
+ uint name_length= strlen(user->priv_user);
+
+ if (!(agg_user= (USER_STATS*) hash_search(agg_user_stats,
+ (uchar*)user->priv_user,
+ name_length)))
+ {
+ // First entry for this role.
+ if (!(agg_user= (USER_STATS*) my_malloc(sizeof(USER_STATS),
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ sql_print_error("Malloc in aggregate_user_stats failed");
+ DBUG_RETURN(1);
+ }
+
+ init_user_stats(agg_user, user->priv_user, name_length,
+ user->priv_user,
+ user->total_connections, user->concurrent_connections,
+ user->connected_time, user->busy_time, user->cpu_time,
+ user->bytes_received, user->bytes_sent,
+ user->binlog_bytes_written,
+ user->rows_sent, user->rows_read,
+ user->rows_inserted, user->rows_deleted,
+ user->rows_updated,
+ user->select_commands, user->update_commands,
+ user->other_commands,
+ user->commit_trans, user->rollback_trans,
+ user->denied_connections, user->lost_connections,
+ user->access_denied_errors, user->empty_queries);
+
+ if (my_hash_insert(agg_user_stats, (uchar*) agg_user))
+ {
+ /* Out of memory */
+ my_free(agg_user, 0);
+ sql_print_error("Malloc in aggregate_user_stats failed");
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ /* Aggregate with existing values for this role. */
+ add_user_stats(agg_user,
+ user->total_connections, user->concurrent_connections,
+ user->connected_time, user->busy_time, user->cpu_time,
+ user->bytes_received, user->bytes_sent,
+ user->binlog_bytes_written,
+ user->rows_sent, user->rows_read,
+ user->rows_inserted, user->rows_deleted,
+ user->rows_updated,
+ user->select_commands, user->update_commands,
+ user->other_commands,
+ user->commit_trans, user->rollback_trans,
+ user->denied_connections, user->lost_connections,
+ user->access_denied_errors, user->empty_queries);
+ }
+ }
+ DBUG_PRINT("exit", ("aggregated %lu input into %lu output entries",
+ all_user_stats->records, agg_user_stats->records));
+ DBUG_RETURN(0);
+}
+#endif
+
+/*
+ Write result to network for SHOW USER_STATISTICS
+
+ SYNOPSIS
+ send_user_stats
+ all_user_stats - values to return
+ table - I_S table
+
+ RETURN
+ 0 - OK
+ 1 - error
+*/
+
+int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
+{
+ DBUG_ENTER("send_user_stats");
+
+ for (uint i= 0; i < all_user_stats->records; i++)
+ {
+ uint j= 0;
+ USER_STATS *user_stats= (USER_STATS*) hash_element(all_user_stats, i);
+
+ table->field[j++]->store(user_stats->user, user_stats->user_name_length,
+ system_charset_info);
+ table->field[j++]->store((longlong)user_stats->total_connections,TRUE);
+ table->field[j++]->store((longlong)user_stats->concurrent_connections);
+ table->field[j++]->store((longlong)user_stats->connected_time);
+ table->field[j++]->store((double)user_stats->busy_time);
+ table->field[j++]->store((double)user_stats->cpu_time);
+ table->field[j++]->store((longlong)user_stats->bytes_received, TRUE);
+ table->field[j++]->store((longlong)user_stats->bytes_sent, TRUE);
+ table->field[j++]->store((longlong)user_stats->binlog_bytes_written, TRUE);
+ table->field[j++]->store((longlong)user_stats->rows_read, TRUE);
+ table->field[j++]->store((longlong)user_stats->rows_sent, TRUE);
+ table->field[j++]->store((longlong)user_stats->rows_deleted, TRUE);
+ table->field[j++]->store((longlong)user_stats->rows_inserted, TRUE);
+ table->field[j++]->store((longlong)user_stats->rows_updated, TRUE);
+ table->field[j++]->store((longlong)user_stats->select_commands, TRUE);
+ table->field[j++]->store((longlong)user_stats->update_commands, TRUE);
+ table->field[j++]->store((longlong)user_stats->other_commands, TRUE);
+ table->field[j++]->store((longlong)user_stats->commit_trans, TRUE);
+ table->field[j++]->store((longlong)user_stats->rollback_trans, TRUE);
+ table->field[j++]->store((longlong)user_stats->denied_connections, TRUE);
+ table->field[j++]->store((longlong)user_stats->lost_connections, TRUE);
+ table->field[j++]->store((longlong)user_stats->access_denied_errors, TRUE);
+ table->field[j++]->store((longlong)user_stats->empty_queries, TRUE);
+ if (schema_table_store_record(thd, table))
+ {
+ DBUG_PRINT("error", ("store record error"));
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+/*
+ Process SHOW USER_STATISTICS
+
+ SYNOPSIS
+ mysqld_show_user_stats
+ thd - current thread
+ wild - limit results to the entry for this user
+ with_roles - when true, display role for mapped users
+
+ RETURN
+ 0 - OK
+ 1 - error
+*/
+
+int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
+{
+ TABLE *table= tables->table;
+ int result;
+ DBUG_ENTER("fill_schema_user_stats");
+
+ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
+ DBUG_RETURN(1);
+
+ /*
+ Iterates through all the global stats and sends them to the client.
+ Pattern matching on the client IP is supported.
+ */
+
+ pthread_mutex_lock(&LOCK_global_user_client_stats);
+ result= send_user_stats(thd, &global_user_stats, table) != 0;
+ pthread_mutex_unlock(&LOCK_global_user_client_stats);
+
+ DBUG_PRINT("exit", ("result: %d", result));
+ DBUG_RETURN(result);
+}
+
+/*
+ Process SHOW CLIENT_STATISTICS
+
+ SYNOPSIS
+ mysqld_show_client_stats
+ thd - current thread
+ wild - limit results to the entry for this client
+
+ RETURN
+ 0 - OK
+ 1 - error
+*/
+
+int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
+{
+ TABLE *table= tables->table;
+ int result;
+ DBUG_ENTER("fill_schema_client_stats");
+
+ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
+ DBUG_RETURN(1);
+
+ /*
+ Iterates through all the global stats and sends them to the client.
+ Pattern matching on the client IP is supported.
+ */
+
+ pthread_mutex_lock(&LOCK_global_user_client_stats);
+ result= send_user_stats(thd, &global_client_stats, table) != 0;
+ pthread_mutex_unlock(&LOCK_global_user_client_stats);
+
+ DBUG_PRINT("exit", ("result: %d", result));
+ DBUG_RETURN(result);
+}
+
+
+/* Sends the global table stats back to the client. */
+
+int fill_schema_table_stats(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ TABLE *table= tables->table;
+ DBUG_ENTER("fill_schema_table_stats");
+
+ pthread_mutex_lock(&LOCK_global_table_stats);
+ for (uint i= 0; i < global_table_stats.records; i++)
+ {
+ char *end_of_schema;
+ TABLE_STATS *table_stats=
+ (TABLE_STATS*)hash_element(&global_table_stats, i);
+ TABLE_LIST tmp_table;
+ size_t schema_length, table_name_length;
+
+ end_of_schema= strend(table_stats->table);
+ schema_length= (size_t) (end_of_schema - table_stats->table);
+ table_name_length= strlen(table_stats->table + schema_length + 1);
+
+ bzero((char*) &tmp_table,sizeof(tmp_table));
+ tmp_table.db= table_stats->table;
+ tmp_table.table_name= end_of_schema+1;
+ tmp_table.grant.privilege= 0;
+ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
+ &tmp_table.grant.privilege, 0, 0,
+ is_schema_db(tmp_table.db)) ||
+ check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX,
+ 1))
+ continue;
+
+ table->field[0]->store(table_stats->table, schema_length,
+ system_charset_info);
+ table->field[1]->store(table_stats->table + schema_length+1,
+ table_name_length, system_charset_info);
+ table->field[2]->store((longlong)table_stats->rows_read, TRUE);
+ table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
+ table->field[4]->store((longlong)table_stats->rows_changed_x_indexes,
+ TRUE);
+ if (schema_table_store_record(thd, table))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
+ DBUG_RETURN(1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_global_table_stats);
+ DBUG_RETURN(0);
+}
+
+
+/* Sends the global index stats back to the client */
+
+int fill_schema_index_stats(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ TABLE *table= tables->table;
+ DBUG_ENTER("fill_schema_index_stats");
+
+ pthread_mutex_lock(&LOCK_global_index_stats);
+ for (uint i= 0; i < global_index_stats.records; i++)
+ {
+ INDEX_STATS *index_stats =
+ (INDEX_STATS*) hash_element(&global_index_stats, i);
+ TABLE_LIST tmp_table;
+ char *index_name;
+ size_t schema_name_length, table_name_length, index_name_length;
+
+ bzero((char*) &tmp_table,sizeof(tmp_table));
+ tmp_table.db= index_stats->index;
+ tmp_table.table_name= strend(index_stats->index)+1;
+ tmp_table.grant.privilege= 0;
+ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
+ &tmp_table.grant.privilege, 0, 0,
+ is_schema_db(tmp_table.db)) ||
+ check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
+ continue;
+
+ index_name= strend(tmp_table.table_name)+1;
+ schema_name_length= (tmp_table.table_name - index_stats->index) -1;
+ table_name_length= (index_name - tmp_table.table_name)-1;
+ index_name_length= (index_stats->index_name_length - schema_name_length -
+ table_name_length - 3);
+
+ table->field[0]->store(tmp_table.db, schema_name_length,
+ system_charset_info);
+ table->field[1]->store(tmp_table.table_name, table_name_length,
+ system_charset_info);
+ table->field[2]->store(index_name, index_name_length, system_charset_info);
+ table->field[3]->store((longlong)index_stats->rows_read, TRUE);
+
+ if (schema_table_store_record(thd, table))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
+ DBUG_RETURN(1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_global_index_stats);
+ DBUG_RETURN(0);
+}
+
/* collect status for all running threads */
@@ -4206,7 +4519,7 @@ int fill_schema_proc(THD *thd, TABLE_LIS
DBUG_RETURN(1);
}
proc_table->file->ha_index_init(0, 1);
- if ((res= proc_table->file->index_first(proc_table->record[0])))
+ if ((res= proc_table->file->ha_index_first(proc_table->record[0])))
{
res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
goto err;
@@ -4216,7 +4529,7 @@ int fill_schema_proc(THD *thd, TABLE_LIS
res= 1;
goto err;
}
- while (!proc_table->file->index_next(proc_table->record[0]))
+ while (!proc_table->file->ha_index_next(proc_table->record[0]))
{
if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
{
@@ -5462,6 +5775,81 @@ struct schema_table_ref
ST_SCHEMA_TABLE *schema_table;
};
+ST_FIELD_INFO user_stats_fields_info[]=
+{
+ {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
+ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections",SKIP_OPEN_TABLE},
+ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections",SKIP_OPEN_TABLE},
+ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time",SKIP_OPEN_TABLE},
+ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Busy_time",SKIP_OPEN_TABLE},
+ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Cpu_time",SKIP_OPEN_TABLE},
+ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received",SKIP_OPEN_TABLE},
+ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent",SKIP_OPEN_TABLE},
+ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written",SKIP_OPEN_TABLE},
+ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE},
+ {"ROWS_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_sent",SKIP_OPEN_TABLE},
+ {"ROWS_DELETED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_deleted",SKIP_OPEN_TABLE},
+ {"ROWS_INSERTED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_inserted",SKIP_OPEN_TABLE},
+ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated",SKIP_OPEN_TABLE},
+ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands",SKIP_OPEN_TABLE},
+ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands",SKIP_OPEN_TABLE},
+ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands",SKIP_OPEN_TABLE},
+ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions",SKIP_OPEN_TABLE},
+ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions",SKIP_OPEN_TABLE},
+ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections",SKIP_OPEN_TABLE},
+ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE},
+ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE},
+ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
+};
+
+ST_FIELD_INFO client_stats_fields_info[]=
+{
+ {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client",SKIP_OPEN_TABLE},
+ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections",SKIP_OPEN_TABLE},
+ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections",SKIP_OPEN_TABLE},
+ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time",SKIP_OPEN_TABLE},
+ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Busy_time",SKIP_OPEN_TABLE},
+ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_DOUBLE, 0, 0, "Cpu_time",SKIP_OPEN_TABLE},
+ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received",SKIP_OPEN_TABLE},
+ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent",SKIP_OPEN_TABLE},
+ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written",SKIP_OPEN_TABLE},
+ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE},
+ {"ROWS_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_sent",SKIP_OPEN_TABLE},
+ {"ROWS_DELETED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_deleted",SKIP_OPEN_TABLE},
+ {"ROWS_INSERTED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_inserted",SKIP_OPEN_TABLE},
+ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated",SKIP_OPEN_TABLE},
+ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands",SKIP_OPEN_TABLE},
+ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands",SKIP_OPEN_TABLE},
+ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands",SKIP_OPEN_TABLE},
+ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions",SKIP_OPEN_TABLE},
+ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions",SKIP_OPEN_TABLE},
+ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections",SKIP_OPEN_TABLE},
+ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE},
+ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE},
+ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
+};
+
+
+ST_FIELD_INFO table_stats_fields_info[]=
+{
+ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema",SKIP_OPEN_TABLE},
+ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name",SKIP_OPEN_TABLE},
+ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE},
+ {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed",SKIP_OPEN_TABLE},
+ {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes",SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
+};
+
+ST_FIELD_INFO index_stats_fields_info[]=
+{
+ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema",SKIP_OPEN_TABLE},
+ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name",SKIP_OPEN_TABLE},
+ {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name",SKIP_OPEN_TABLE},
+ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read",SKIP_OPEN_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0,0}
+};
/*
Find schema_tables elment by name
@@ -6683,6 +7071,8 @@ ST_SCHEMA_TABLE schema_tables[]=
{
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
+ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
+ fill_schema_client_stats, make_old_format, 0, -1, -1, 0, 0},
{"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
@@ -6707,6 +7097,8 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_status, make_old_format, 0, 0, -1, 0, 0},
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, 0, -1, 0, 0},
+ {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
+ fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
OPEN_TABLE_ONLY},
@@ -6748,11 +7140,15 @@ ST_SCHEMA_TABLE schema_tables[]=
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
+ {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
+ fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
{"TRIGGERS", triggers_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
OPEN_TABLE_ONLY},
{"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
+ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
+ fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, 0, -1, 1, 0},
{"VIEWS", view_fields_info, create_schema_table,
=== modified file 'sql/sql_table.cc'
--- sql/sql_table.cc 2009-09-18 01:04:43 +0000
+++ sql/sql_table.cc 2009-10-17 08:13:46 +0000
@@ -7815,7 +7815,7 @@ bool mysql_checksum_table(THD *thd, TABL
goto err;
}
ha_checksum row_crc= 0;
- int error= t->file->rnd_next(t->record[0]);
+ int error= t->file->ha_rnd_next(t->record[0]);
if (unlikely(error))
{
if (error == HA_ERR_RECORD_DELETED)
=== modified file 'sql/sql_udf.cc'
--- sql/sql_udf.cc 2009-05-15 12:57:51 +0000
+++ sql/sql_udf.cc 2009-10-17 08:09:23 +0000
@@ -567,10 +567,10 @@ int mysql_drop_function(THD *thd,const L
goto err;
table->use_all_columns();
table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin);
- if (!table->file->index_read_idx_map(table->record[0], 0,
- (uchar*) table->field[0]->ptr,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ if (!table->file->ha_index_read_idx_map(table->record[0], 0,
+ (uchar*) table->field[0]->ptr,
+ HA_WHOLE_KEY,
+ HA_READ_KEY_EXACT))
{
int error;
if ((error = table->file->ha_delete_row(table->record[0])))
=== modified file 'sql/sql_update.cc'
--- sql/sql_update.cc 2009-09-07 20:50:10 +0000
+++ sql/sql_update.cc 2009-10-17 14:13:49 +0000
@@ -142,7 +142,7 @@ static void prepare_record_for_error_mes
/* Tell the engine about the new set. */
table->file->column_bitmaps_signal();
/* Read record that is identified by table->file->ref. */
- (void) table->file->rnd_pos(table->record[1], table->file->ref);
+ (void) table->file->ha_rnd_pos(table->record[1], table->file->ref);
/* Copy the newly read columns into the new record. */
for (field_p= table->field; (field= *field_p); field_p++)
if (bitmap_is_set(&unique_map, field->field_index))
@@ -1928,7 +1928,7 @@ int multi_update::do_updates()
{
if (thd->killed && trans_safe)
goto err;
- if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
+ if ((local_error= tmp_table->file->ha_rnd_next(tmp_table->record[0])))
{
if (local_error == HA_ERR_END_OF_FILE)
break;
@@ -1943,12 +1943,12 @@ int multi_update::do_updates()
uint field_num= 0;
do
{
- if((local_error=
- tbl->file->rnd_pos(tbl->record[0],
- (uchar *) tmp_table->field[field_num]->ptr)))
+ if ((local_error=
+ tbl->file->ha_rnd_pos(tbl->record[0],
+ (uchar*) tmp_table->field[field_num]->ptr)))
goto err;
field_num++;
- } while((tbl= check_opt_it++));
+ } while ((tbl= check_opt_it++));
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
=== modified file 'sql/sql_yacc.yy'
--- sql/sql_yacc.yy 2009-09-07 20:50:10 +0000
+++ sql/sql_yacc.yy 2009-10-17 07:26:29 +0000
@@ -598,6 +598,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token CHECK_SYM /* SQL-2003-R */
%token CIPHER_SYM
%token CLIENT_SYM
+%token CLIENT_STATS_SYM
%token CLOSE_SYM /* SQL-2003-R */
%token COALESCE /* SQL-2003-N */
%token CODE_SYM
@@ -744,6 +745,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token IMPORT
%token INDEXES
%token INDEX_SYM
+%token INDEX_STATS_SYM
%token INFILE
%token INITIAL_SIZE_SYM
%token INNER_SYM /* SQL-2003-R */
@@ -985,6 +987,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token SIGNED_SYM
%token SIMPLE_SYM /* SQL-2003-N */
%token SLAVE
+%token SLOW_SYM
%token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM
%token SOCKET_SYM
@@ -1029,6 +1032,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token TABLES
%token TABLESPACE
%token TABLE_REF_PRIORITY
+%token TABLE_STATS_SYM
%token TABLE_SYM /* SQL-2003-R */
%token TABLE_CHECKSUM_SYM
%token TEMPORARY /* SQL-2003-N */
@@ -1076,6 +1080,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token UPGRADE_SYM
%token USAGE /* SQL-2003-N */
%token USER /* SQL-2003-R */
+%token USER_STATS_SYM
%token USE_FRM
%token USE_SYM
%token USING /* SQL-2003-R */
@@ -9995,12 +10000,12 @@ show_param:
if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
MYSQL_YYABORT;
}
- | AUTHORS_SYM
+ | AUTHORS_SYM wild_and_where
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_AUTHORS;
}
- | CONTRIBUTORS_SYM
+ | CONTRIBUTORS_SYM wild_and_where
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_CONTRIBUTORS;
@@ -10131,6 +10136,34 @@ show_param:
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
}
+ | CLIENT_STATS_SYM wild_and_where
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SHOW_CLIENT_STATS;
+ if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
+ MYSQL_YYABORT;
+ }
+ | USER_STATS_SYM wild_and_where
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SHOW_USER_STATS;
+ if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
+ MYSQL_YYABORT;
+ }
+ | TABLE_STATS_SYM wild_and_where
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
+ if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
+ MYSQL_YYABORT;
+ }
+ | INDEX_STATS_SYM wild_and_where
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
+ if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
+ MYSQL_YYABORT;
+ }
| CREATE PROCEDURE sp_name
{
LEX *lex= Lex;
@@ -10339,6 +10372,16 @@ flush_option:
{ Lex->type|= REFRESH_STATUS; }
| SLAVE
{ Lex->type|= REFRESH_SLAVE; }
+ | SLOW_SYM QUERY_SYM LOGS_SYM
+ { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
+ | CLIENT_STATS_SYM
+ { Lex->type|= REFRESH_CLIENT_STATS; }
+ | USER_STATS_SYM
+ { Lex->type|= REFRESH_USER_STATS; }
+ | TABLE_STATS_SYM
+ { Lex->type|= REFRESH_TABLE_STATS; }
+ | INDEX_STATS_SYM
+ { Lex->type|= REFRESH_INDEX_STATS; }
| MASTER_SYM
{ Lex->type|= REFRESH_MASTER; }
| DES_KEY_FILE
@@ -11447,6 +11490,7 @@ keyword_sp:
| CHAIN_SYM {}
| CHANGED {}
| CIPHER_SYM {}
+ | CLIENT_STATS_SYM {}
| CLIENT_SYM {}
| COALESCE {}
| CODE_SYM {}
@@ -11508,6 +11552,7 @@ keyword_sp:
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
+ | INDEX_STATS_SYM {}
| INVOKER_SYM {}
| IMPORT {}
| INDEXES {}
@@ -11631,6 +11676,7 @@ keyword_sp:
| SIMPLE_SYM {}
| SHARE_SYM {}
| SHUTDOWN {}
+ | SLOW_SYM {}
| SNAPSHOT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
@@ -11650,6 +11696,7 @@ keyword_sp:
| SUSPEND_SYM {}
| SWAPS_SYM {}
| SWITCHES_SYM {}
+ | TABLE_STATS_SYM {}
| TABLES {}
| TABLE_CHECKSUM_SYM {}
| TABLESPACE {}
@@ -11675,6 +11722,7 @@ keyword_sp:
| UNKNOWN_SYM {}
| UNTIL_SYM {}
| USER {}
+ | USER_STATS_SYM {}
| USE_FRM {}
| VARIABLES {}
| VIEW_SYM {}
=== modified file 'sql/structs.h'
--- sql/structs.h 2009-06-26 19:57:42 +0000
+++ sql/structs.h 2009-10-18 15:39:18 +0000
@@ -76,6 +76,7 @@ typedef struct st_key {
uint extra_length;
uint usable_key_parts; /* Should normally be = key_parts */
uint block_size;
+ uint name_length;
enum ha_key_alg algorithm;
/*
Note that parser is used when the table is opened for use, and
@@ -88,6 +89,8 @@ typedef struct st_key {
};
KEY_PART_INFO *key_part;
char *name; /* Name of key */
+ /* Unique name for cache; db + \0 + table_name + \0 + key_name + \0 */
+ uchar *cache_name;
/*
Array of AVG(#records with the same field value) for 1st ... Nth key part.
0 means 'not known'.
@@ -231,6 +234,111 @@ typedef struct user_conn {
USER_RESOURCES user_resources;
} USER_CONN;
+typedef struct st_user_stats
+{
+ char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
+ // Account name the user is mapped to when this is a user from mapped_user.
+ // Otherwise, the same value as user.
+ char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
+ uint user_name_length;
+ uint total_connections;
+ uint concurrent_connections;
+ time_t connected_time; // in seconds
+ double busy_time; // in seconds
+ double cpu_time; // in seconds
+ ulonglong bytes_received;
+ ulonglong bytes_sent;
+ ulonglong binlog_bytes_written;
+ ha_rows rows_examined, rows_read, rows_sent;
+ ha_rows rows_updated, rows_deleted, rows_inserted;
+ ulonglong select_commands, update_commands, other_commands;
+ ulonglong commit_trans, rollback_trans;
+ ulonglong denied_connections, lost_connections;
+ ulonglong access_denied_errors;
+ ulonglong empty_queries;
+} USER_STATS;
+
+/* Lookup function for hash tables with USER_STATS entries */
+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
+ my_bool not_used __attribute__((unused)));
+
+/* Free all memory for a hash table with USER_STATS entries */
+extern void free_user_stats(USER_STATS* user_stats);
+
+/* Intialize an instance of USER_STATS */
+extern void
+init_user_stats(USER_STATS *user_stats,
+ const char *user,
+ size_t user_length,
+ const char *priv_user,
+ uint total_connections,
+ uint concurrent_connections,
+ time_t connected_time,
+ double busy_time,
+ double cpu_time,
+ ulonglong bytes_received,
+ ulonglong bytes_sent,
+ ulonglong binlog_bytes_written,
+ ha_rows rows_sent,
+ ha_rows rows_read,
+ ha_rows rows_inserted,
+ ha_rows rows_deleted,
+ ha_rows rows_updated,
+ ulonglong select_commands,
+ ulonglong update_commands,
+ ulonglong other_commands,
+ ulonglong commit_trans,
+ ulonglong rollback_trans,
+ ulonglong denied_connections,
+ ulonglong lost_connections,
+ ulonglong access_denied_errors,
+ ulonglong empty_queries);
+
+/* Increment values of an instance of USER_STATS */
+extern void
+add_user_stats(USER_STATS *user_stats,
+ uint total_connections,
+ uint concurrent_connections,
+ time_t connected_time,
+ double busy_time,
+ double cpu_time,
+ ulonglong bytes_received,
+ ulonglong bytes_sent,
+ ulonglong binlog_bytes_written,
+ ha_rows rows_sent,
+ ha_rows rows_read,
+ ha_rows rows_inserted,
+ ha_rows rows_deleted,
+ ha_rows rows_updated,
+ ulonglong select_commands,
+ ulonglong update_commands,
+ ulonglong other_commands,
+ ulonglong commit_trans,
+ ulonglong rollback_trans,
+ ulonglong denied_connections,
+ ulonglong lost_connections,
+ ulonglong access_denied_errors,
+ ulonglong empty_queries);
+
+typedef struct st_table_stats
+{
+ char table[NAME_LEN * 2 + 2]; // [db] + '\0' + [table] + '\0'
+ uint table_name_length;
+ ulonglong rows_read, rows_changed;
+ ulonglong rows_changed_x_indexes;
+ /* Stores enum db_type, but forward declarations cannot be done */
+ int engine_type;
+} TABLE_STATS;
+
+typedef struct st_index_stats
+{
+ // [db] + '\0' + [table] + '\0' + [index] + '\0'
+ char index[NAME_LEN * 3 + 3];
+ uint index_name_length; /* Length of 'index' */
+ ulonglong rows_read;
+} INDEX_STATS;
+
+
/* Bits in form->update */
#define REG_MAKE_DUPP 1 /* Make a copy of record when read */
#define REG_NEW_RECORD 2 /* Write a new record if not found */
=== modified file 'sql/table.cc'
--- sql/table.cc 2009-09-09 21:06:57 +0000
+++ sql/table.cc 2009-10-17 14:00:24 +0000
@@ -1325,6 +1325,19 @@ static int open_binary_frm(THD *thd, TAB
{
uint usable_parts= 0;
keyinfo->name=(char*) share->keynames.type_names[key];
+ keyinfo->name_length= strlen(keyinfo->name);
+ keyinfo->cache_name=
+ (uchar*) alloc_root(&share->mem_root,
+ share->table_cache_key.length+
+ keyinfo->name_length + 1);
+ if (keyinfo->cache_name) // If not out of memory
+ {
+ uchar *pos= keyinfo->cache_name;
+ memcpy(pos, share->table_cache_key.str, share->table_cache_key.length);
+ memcpy(pos + share->table_cache_key.length, keyinfo->name,
+ keyinfo->name_length+1);
+ }
+
/* Fix fulltext keys for old .frm files */
if (share->key_info[key].flags & HA_FULLTEXT)
share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
=== modified file 'sql/table.h'
--- sql/table.h 2009-09-15 10:46:35 +0000
+++ sql/table.h 2009-10-17 07:32:14 +0000
@@ -878,6 +878,7 @@ typedef struct st_foreign_key_info
enum enum_schema_tables
{
SCH_CHARSETS= 0,
+ SCH_CLIENT_STATS,
SCH_COLLATIONS,
SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
SCH_COLUMNS,
@@ -887,6 +888,7 @@ enum enum_schema_tables
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
+ SCH_INDEX_STATS,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
SCH_PARTITIONS,
@@ -905,8 +907,10 @@ enum enum_schema_tables
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
+ SCH_TABLE_STATS,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
+ SCH_USER_STATS,
SCH_VARIABLES,
SCH_VIEWS
};
=== modified file 'sql/tztime.cc'
--- sql/tztime.cc 2009-09-07 20:50:10 +0000
+++ sql/tztime.cc 2009-10-17 08:09:23 +0000
@@ -1676,7 +1676,7 @@ my_tz_init(THD *org_thd, const char *def
tz_leapcnt= 0;
- res= table->file->index_first(table->record[0]);
+ res= table->file->ha_index_first(table->record[0]);
while (!res)
{
@@ -1698,7 +1698,7 @@ my_tz_init(THD *org_thd, const char *def
tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans,
tz_lsis[tz_leapcnt-1].ls_corr));
- res= table->file->index_next(table->record[0]);
+ res= table->file->ha_index_next(table->record[0]);
}
(void)table->file->ha_index_end();
@@ -1865,8 +1865,8 @@ tz_load_from_open_tables(const String *t
*/
(void)table->file->ha_index_init(0, 1);
- if (table->file->index_read_map(table->record[0], table->field[0]->ptr,
- HA_WHOLE_KEY, HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_map(table->record[0], table->field[0]->ptr,
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT))
{
#ifdef EXTRA_DEBUG
/*
@@ -1893,8 +1893,8 @@ tz_load_from_open_tables(const String *t
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
- if (table->file->index_read_map(table->record[0], table->field[0]->ptr,
- HA_WHOLE_KEY, HA_READ_KEY_EXACT))
+ if (table->file->ha_index_read_map(table->record[0], table->field[0]->ptr,
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT))
{
sql_print_error("Can't find description of time zone '%u'", tzid);
goto end;
@@ -1920,8 +1920,8 @@ tz_load_from_open_tables(const String *t
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
- res= table->file->index_read_map(table->record[0], table->field[0]->ptr,
- (key_part_map)1, HA_READ_KEY_EXACT);
+ res= table->file->ha_index_read_map(table->record[0], table->field[0]->ptr,
+ (key_part_map)1, HA_READ_KEY_EXACT);
while (!res)
{
ttid= (uint)table->field[1]->val_int();
@@ -1968,8 +1968,8 @@ tz_load_from_open_tables(const String *t
tmp_tz_info.typecnt= ttid + 1;
- res= table->file->index_next_same(table->record[0],
- table->field[0]->ptr, 4);
+ res= table->file->ha_index_next_same(table->record[0],
+ table->field[0]->ptr, 4);
}
if (res != HA_ERR_END_OF_FILE)
@@ -1991,8 +1991,8 @@ tz_load_from_open_tables(const String *t
table->field[0]->store((longlong) tzid, TRUE);
(void)table->file->ha_index_init(0, 1);
- res= table->file->index_read_map(table->record[0], table->field[0]->ptr,
- (key_part_map)1, HA_READ_KEY_EXACT);
+ res= table->file->ha_index_read_map(table->record[0], table->field[0]->ptr,
+ (key_part_map)1, HA_READ_KEY_EXACT);
while (!res)
{
ttime= (my_time_t)table->field[1]->val_int();
@@ -2021,8 +2021,8 @@ tz_load_from_open_tables(const String *t
("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u",
tzid, (ulong) ttime, ttid));
- res= table->file->index_next_same(table->record[0],
- table->field[0]->ptr, 4);
+ res= table->file->ha_index_next_same(table->record[0],
+ table->field[0]->ptr, 4);
}
/*
-----------
Regards,
Monty
3
14
[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2792)
by Michael Widenius 23 Oct '09
by Michael Widenius 23 Oct '09
23 Oct '09
#At lp:maria based on revid:knielsen@knielsen-hq.org-20091023114317-mypsimwtn0ehksnq
2792 Michael Widenius 2009-10-23 [merge]
Automatic merge
modified:
Docs/INSTALL-BINARY
Docs/mysql.info
README
configure.in
libmysql/libmysql.c
scripts/make_binary_distribution.sh
scripts/mysql_secure_installation.sh
sql/mysqld.cc
storage/maria/Makefile.am
storage/myisam/Makefile.am
support-files/Makefile.am
support-files/config.huge.ini.sh*
support-files/config.medium.ini.sh*
support-files/config.small.ini.sh*
support-files/mysql.server.sh
=== modified file 'Docs/INSTALL-BINARY'
--- a/Docs/INSTALL-BINARY 2009-09-16 12:03:18 +0000
+++ b/Docs/INSTALL-BINARY 2009-10-23 16:48:54 +0000
@@ -1,25 +1,20 @@
+MariaDB and MySQL have identical install methods. In this document we
+describe how to install MariaDB; However all documentation at www.mysql.com
+also applies.
-2.9. Installing MySQL from tar.gz Packages on Other Unix-Like Systems
- This section covers the installation of MySQL binary distributions
- that are provided for various platforms in the form of compressed
- tar files (files with a .tar.gz extension). See Section 2.1.2.4,
- "MySQL Binaries Compiled by Sun Microsystems, Inc.," for a
- detailed list.
+2.9. Installing MariaDB from tar.gz Packages on Other Unix-Like Systems
- To obtain MySQL, see Section 2.1.3, "How to Get MySQL."
+ This section covers the installation of MariaDB binary distributions
+ that are provided for various platforms in the form of compressed
+ tar files (files with a .tar.gz extension).
- MySQL tar file binary distributions have names of the form
- mysql-VERSION-OS.tar.gz, where VERSION is a number (for example,
+ MariaDB tar file binary distributions have names of the form
+ mariadb-VERSION-OS.tar.gz, where VERSION is a number (for example,
5.1.39), and OS indicates the type of operating system for which
the distribution is intended (for example, pc-linux-i686).
- In addition to these generic packages, we also offer binaries in
- platform-specific package formats for selected platforms. See
- Section 2.2, "Standard MySQL Installation Using a Binary
- Distribution," for more information on how to install these.
-
- You need the following tools to install a MySQL tar file binary
+ You need the following tools to install a MariaDB tar file binary
distribution:
* GNU gunzip to uncompress the distribution.
@@ -33,11 +28,14 @@
program. On other systems with a deficient tar, you should
install GNU tar first.
- If you run into problems and need to file a bug report, please use
- the instructions in Section 1.6, "How to Report Bugs or Problems."
+ If you run into problems and need to file a bug report,
+ please report them to: http://bugs.launchpad.net/maria
+
+ See the instructions in Section 1.6, "How to Report Bugs or Problems."
The basic commands that you must execute to install and use a
- MySQL binary distribution are:
+ MariaDB binary distribution are:
+
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
@@ -53,7 +51,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
- This procedure does not set up any passwords for MySQL accounts.
+ This procedure does not set up any passwords for MariaDB accounts.
After following the procedure, proceed to Section 2.11,
"Post-Installation Setup and Testing."
@@ -80,8 +78,8 @@ shell> useradd -g mysql mysql
shell> cd /usr/local
3. Obtain a distribution file using the instructions in Section
- 2.1.3, "How to Get MySQL." For a given release, binary
- distributions for all platforms are built from the same MySQL
+ 2.1.3, "How to Get MariaDB." For a given release, binary
+ distributions for all platforms are built from the same MariaDB
source distribution.
4. Unpack the distribution, which creates the installation
@@ -106,7 +104,7 @@ shell> cd mysql
+ The bin directory contains client programs and the
server. You should add the full path name of this
directory to your PATH environment variable so that your
- shell finds the MySQL programs properly. See Section
+ shell finds the MariaDB programs properly. See Section
2.14, "Environment Variables."
+ The scripts directory contains the mysql_install_db
@@ -126,8 +124,8 @@ shell> chgrp -R mysql .
the mysql user. The second changes the group attribute to the
mysql group.
- 7. If you have not installed MySQL before, you must create the
- MySQL data directory and initialize the grant tables:
+ 7. If you have not installed MariaDB before, you must create the
+ MariaDB data directory and initialize the grant tables:
shell> scripts/mysql_install_db --user=mysql
If you run the command as root, include the --user option as
shown. If you run the command while logged in as that user,
@@ -137,25 +135,26 @@ shell> scripts/mysql_install_db --user=m
After creating or updating the grant tables, you need to
restart the server manually.
- 8. Most of the MySQL installation can be owned by root if you
+ 8. Most of the MariaDB installation can be owned by root if you
like. The exception is that the data directory must be owned
by mysql. To accomplish this, run the following commands as
root in the installation directory:
+
shell> chown -R root .
shell> chown -R mysql data
- 9. If you want MySQL to start automatically when you boot your
+ 9. If you want MariaDB to start automatically when you boot your
machine, you can copy support-files/mysql.server to the
location where your system has its startup files. More
information can be found in the support-files/mysql.server
script itself and in Section 2.11.2.2, "Starting and Stopping
- MySQL Automatically."
+ MariaDB Automatically."
10. You can set up new accounts using the bin/mysql_setpermission
script if you install the DBI and DBD::mysql Perl modules. See
Section 4.6.14, "mysql_setpermission --- Interactively Set
Permissions in Grant Tables." For Perl module installation
instructions, see Section 2.15, "Perl Installation Notes."
- 11. If you would like to use mysqlaccess and have the MySQL
+ 11. If you would like to use mysqlaccess and have the MariaDB
distribution in some nonstandard location, you must change the
location where mysqlaccess expects to find the mysql client.
Edit the bin/mysqlaccess script at approximately line 18.
@@ -166,7 +165,7 @@ $MYSQL = '/usr/local/bin/mysql';
error will occur when you run mysqlaccess.
After everything has been unpacked and installed, you should test
- your distribution. To start the MySQL server, use the following
+ your distribution. To start the MariaDB server, use the following
command:
shell> bin/mysqld_safe --user=mysql &
@@ -185,7 +184,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
- The accounts that are listed in the MySQL grant tables initially
+ The accounts that are listed in the MariaDB grant tables initially
have no passwords. After starting the server, you should set up
passwords for them using the instructions in Section 2.11,
"Post-Installation Setup and Testing."
=== modified file 'Docs/mysql.info'
--- a/Docs/mysql.info 2007-11-02 11:29:13 +0000
+++ b/Docs/mysql.info 2009-10-23 16:48:54 +0000
@@ -1,3 +1,10 @@
+MariaDB is in most aspects identical to MySQL.
+
+Differences between MySQL and MariaDB can be found at:
+http://askmonty.org/wiki/index.php/MariaDB_versus_MySQL
+
+The MariaDB references manual can be found at:
+http://askmonty.org/wiki/index.php/Manual
The MySQL Reference Manual is available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
=== modified file 'README'
--- a/README 2009-09-15 10:46:35 +0000
+++ b/README 2009-10-23 16:48:54 +0000
@@ -1,5 +1,4 @@
This is a release of MariaDB, a branch of MySQL.
-MySQL is brought to you by the MySQL team at Sun Microsystems, Inc.
MariaDB is a drop-in replacement of MySQL, with more features, less
bugs and better performance.
=== modified file 'configure.in'
--- a/configure.in 2009-10-16 06:18:37 +0000
+++ b/configure.in 2009-10-23 19:26:26 +0000
@@ -2897,13 +2897,11 @@ AC_CONFIG_COMMANDS_POST(ac_configure_arg
AC_OUTPUT
echo
-echo "MySQL has a Web site at http://www.mysql.com/ which carries details on the"
-echo "latest release, upcoming features, and other information to make your"
-echo "work or play with MySQL more productive. There you can also find"
-echo "information about mailing lists for MySQL discussion."
+echo "You can find information about MariaDB at"
+echo http://askmonty.org/wiki/index.php/MariaDB
echo
echo "Remember to check the platform specific part of the reference manual for"
-echo "hints about installing MySQL on your platform. Also have a look at the"
+echo "hints about installing MariaDB on your platform. Also have a look at the"
echo "files in the Docs directory."
echo
@@ -2922,5 +2920,5 @@ echo "---"
# The following text is checked in ./Do-compile to verify that configure
# ended sucessfully - don't remove it.
-echo "Thank you for choosing MySQL!"
+echo "Thank you for choosing MariaDB!"
echo
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2009-10-02 10:36:28 +0000
+++ b/libmysql/libmysql.c 2009-10-23 16:48:54 +0000
@@ -1432,7 +1432,8 @@ mysql_get_server_info(MYSQL *mysql)
my_bool STDCALL mariadb_connection(MYSQL *mysql)
{
- return strinstr(mysql->server_version, "MariaDB") != 0;
+ return (strinstr(mysql->server_version, "MariaDB") != 0 ||
+ strinstr(mysql->server_version, "-maria-") != 0);
}
const char * STDCALL
=== modified file 'scripts/make_binary_distribution.sh'
--- a/scripts/make_binary_distribution.sh 2009-10-20 23:32:21 +0000
+++ b/scripts/make_binary_distribution.sh 2009-10-23 16:48:54 +0000
@@ -239,8 +239,8 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
# ----------------------------------------------------------------------
cd scripts
- rm -f mysql_install_db
- @MAKE@ mysql_install_db \
+ rm -f mysql_install_db mysqld_safe mysql_fix_privilege_tables
+ @MAKE@ mysql_install_db mysqld_safe mysql_fix_privilege_tables \
prefix=. \
bindir=./bin \
sbindir=./bin \
@@ -257,7 +257,7 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
sbindir=./bin \
scriptdir=./bin \
libexecdir=./bin \
- pkgdatadir=@pkgdatadir@
+ pkgdatadir=./share
cd ..
# ----------------------------------------------------------------------
@@ -320,6 +320,33 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
mkdir $DEST/data $DEST/data/mysql $DEST/data/test
chmod o-rwx $DEST/data $DEST/data/mysql $DEST/data/test
+ # Remove not needed files
+ rm $DEST/share/mysql/errmsg.txt
+
+ # Remove NDB files
+ rm -f $DEST/share/mysql/ndb-config-2-node.ini \
+ $DEST/share/mysql/config*
+
+ #
+ # Move things to make them easier to find in tar installation
+ #
+ mv $DEST/libexec/* $DEST/bin
+ mv $DEST/share/man $DEST
+ mv $DEST/share/mysql/binary-configure $DEST/configure
+ mv $DEST/share/mysql/*.sql $DEST/share
+ mv $DEST/share/mysql/*.cnf $DEST/share/mysql/*.server $DEST/share/mysql/mysql-log-rotate $DEST/support-files
+ rmdir $DEST/libexec
+
+ #
+ # Move some scripts that are only run once to 'scripts' directory
+ # but add symbolic links instead to old place for compatibility
+ #
+ for i in mysql_secure_installation mysql_fix_extensions mysql_fix_privilege_tables
+ do
+ mv $DEST/bin/$i $DEST/scripts
+ ln -s "../scripts/$i" $DEST/bin/$i
+ done
+
# ----------------------------------------------------------------------
# Create the result tar file
# ----------------------------------------------------------------------
@@ -496,12 +523,21 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in
$BASE/bin/mysql_install_db $BASE/bin/make_binary_distribution \
$BASE/bin/make_win_* \
$BASE/bin/setsomevars $BASE/support-files/Makefile* \
- $BASE/support-files/*.sh
+ $BASE/support-files/*.sh \
+ $BASE/share/mysql/errmsg.txt
+
+# Remove NDB files
+rm -f $BASE/share/ndb-config-2-node.ini \
+ $BASE/share/mysql/config*
#
-# Copy system dependent files
+# Move things to make things easier to find in tar installation
#
-./scripts/fill_help_tables < ./Docs/manual.texi >> ./netware/init_db.sql
+
+mv $BASE/share/man $BASE
+mv $BASE/share/mysql/binary-configure $BASE/configure
+mv $BASE/share/mysql/*.sql $BASE/share
+mv $BASE/share/mysql/*.cnf $BASE/share/mysql/*.server $BASE/share/mysql/mysql-log-rotate $BASE/support-files
#
# Remove system dependent files
@@ -515,12 +551,6 @@ rm -f $BASE/support-files/magic \
$BASE/support-files/MySQL-shared-compat.spec \
$BASE/INSTALL-BINARY
-# Clean up if we did this from a bk tree
-if [ -d $BASE/sql-bench/SCCS ] ; then
- find $BASE/share -name SCCS -print | xargs rm -rf
- find $BASE/sql-bench -name SCCS -print | xargs rm -rf
-fi
-
BASE2=$TMP/$NEW_NAME
rm -rf $BASE2
mv $BASE $BASE2
=== modified file 'scripts/mysql_secure_installation.sh'
--- a/scripts/mysql_secure_installation.sh 2007-01-01 04:31:23 +0000
+++ b/scripts/mysql_secure_installation.sh 2009-10-23 16:48:54 +0000
@@ -23,6 +23,157 @@ trap "interrupt" 2
rootpass=""
echo_n=
echo_c=
+basedir=
+bindir=
+
+parse_arg()
+{
+ echo "$1" | sed -e 's/^[^=]*=//'
+}
+
+parse_arguments()
+{
+ # We only need to pass arguments through to the server if we don't
+ # handle them here. So, we collect unrecognized options (passed on
+ # the command line) into the args variable.
+ pick_args=
+ if test "$1" = PICK-ARGS-FROM-ARGV
+ then
+ pick_args=1
+ shift
+ fi
+
+ for arg
+ do
+ case "$arg" in
+ --basedir=*) basedir=`parse_arg "$arg"` ;;
+ --no-defaults|--defaults-file=*|--defaults-extra-file=*)
+ defaults="$arg" ;;
+ *)
+ if test -n "$pick_args"
+ then
+ # This sed command makes sure that any special chars are quoted,
+ # so the arg gets passed exactly to the server.
+ # XXX: This is broken; true fix requires using eval and proper
+ # quoting of every single arg ($basedir, $ldata, etc.)
+ #args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
+ args="$args $arg"
+ fi
+ ;;
+ esac
+ done
+}
+
+# Try to find a specific file within --basedir which can either be a binary
+# release or installed source directory and return the path.
+find_in_basedir()
+{
+ return_dir=
+ case "$1" in
+ --dir)
+ return_dir=1; shift
+ ;;
+ esac
+
+ file=$1; shift
+
+ for dir in "$@"
+ do
+ if test -f "$basedir/$dir/$file"
+ then
+ if test -n "$return_dir"
+ then
+ echo "$basedir/$dir"
+ else
+ echo "$basedir/$dir/$file"
+ fi
+ break
+ fi
+ done
+}
+
+cannot_find_file()
+{
+ echo
+ echo "FATAL ERROR: Could not find $1"
+
+ shift
+ if test $# -ne 0
+ then
+ echo
+ echo "The following directories were searched:"
+ echo
+ for dir in "$@"
+ do
+ echo " $dir"
+ done
+ fi
+
+ echo
+ echo "If you compiled from source, you need to run 'make install' to"
+ echo "copy the software into the correct location ready for operation."
+ echo
+ echo "If you are using a binary release, you must either be at the top"
+ echo "level of the extracted archive, or pass the --basedir option"
+ echo "pointing to that location."
+ echo
+}
+
+# Ok, let's go. We first need to parse arguments which are required by
+# my_print_defaults so that we can execute it first, then later re-parse
+# the command line to add any extra bits that we need.
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+#
+# We can now find my_print_defaults. This script supports:
+#
+# --srcdir=path pointing to compiled source tree
+# --basedir=path pointing to installed binary location
+#
+# or default to compiled-in locations.
+#
+
+if test -n "$basedir"
+then
+ print_defaults=`find_in_basedir my_print_defaults bin extra`
+ echo "print: $print_defaults"
+ if test -z "$print_defaults"
+ then
+ cannot_find_file my_print_defaults $basedir/bin $basedir/extra
+ exit 1
+ fi
+else
+ print_defaults="@bindir@/my_print_defaults"
+fi
+
+if test ! -x "$print_defaults"
+then
+ cannot_find_file "$print_defaults"
+ exit 1
+fi
+
+# Now we can get arguments from the group [client]
+# in the my.cfg file, then re-run to merge with command line arguments.
+parse_arguments `$print_defaults $defaults client`
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+# Configure paths to support files
+if test -n "$basedir"
+then
+ bindir="$basedir/bin"
+elif test -f "./bin/mysql"
+ then
+ bindir="./bin"
+else
+ bindir="@bindir@"
+fi
+
+mysql_command=`find_in_basedir mysql $bindir`
+if test -z "$print_defaults"
+then
+ cannot_find_file mysql $bindir
+ exit 1
+fi
set_echo_compat() {
case `echo "testing\c"`,`echo -n testing` in
@@ -39,7 +190,7 @@ prepare() {
do_query() {
echo $1 >$command
- mysql --defaults-file=$config <$command
+ $bindir/mysql --defaults-file=$config <$command
return $?
}
@@ -185,14 +336,9 @@ prepare
set_echo_compat
echo
-echo
-echo
-echo
echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL"
echo " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!"
echo
-echo
-
echo "In order to log into MySQL to secure it, we'll need the current"
echo "password for the root user. If you've just installed MySQL, and"
echo "you haven't set the root password yet, the password will be blank,"
@@ -310,13 +456,8 @@ echo
cleanup
echo
-echo
-echo
echo "All done! If you've completed all of the above steps, your MySQL"
echo "installation should now be secure."
echo
echo "Thanks for using MySQL!"
-echo
-echo
-
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-10-23 11:43:17 +0000
+++ b/sql/mysqld.cc 2009-10-23 19:26:26 +0000
@@ -4560,7 +4560,13 @@ we force server id to 2, but this MySQL
{
select_thread_in_use= 0; // Allow 'kill' to work
bootstrap(stdin);
- unireg_abort(bootstrap_error ? 1 : 0);
+ if (!kill_in_progress)
+ unireg_abort(bootstrap_error ? 1 : 0);
+ else
+ {
+ sleep(2); // Wait for kill
+ exit(0);
+ }
}
if (opt_init_file)
{
=== modified file 'storage/maria/Makefile.am'
--- a/storage/maria/Makefile.am 2008-06-26 05:18:28 +0000
+++ b/storage/maria/Makefile.am 2009-10-23 16:48:54 +0000
@@ -32,7 +32,7 @@ SUBDIRS = . unittest
EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_test_big.sh \
ma_ft_stem.c CMakeLists.txt plug.in ma_test_recovery
-pkgdata_DATA = ma_test_all ma_test_all.res ma_test_recovery
+pkgdata_DATA =
pkglib_LIBRARIES = libmaria.a
bin_PROGRAMS = maria_chk maria_pack maria_ftdump maria_read_log \
maria_dump_log
=== modified file 'storage/myisam/Makefile.am'
--- a/storage/myisam/Makefile.am 2007-02-28 16:50:51 +0000
+++ b/storage/myisam/Makefile.am 2009-10-23 16:48:54 +0000
@@ -28,7 +28,7 @@ LDADD =
DEFS = @DEFS@
EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in
-pkgdata_DATA = mi_test_all mi_test_all.res
+pkgdata_DATA =
pkglib_LIBRARIES = libmyisam.a
bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
=== modified file 'support-files/Makefile.am'
--- a/support-files/Makefile.am 2009-02-24 16:54:03 +0000
+++ b/support-files/Makefile.am 2009-10-23 16:48:54 +0000
@@ -53,7 +53,9 @@ pkgsupp_DATA = my-small.cnf \
ndb-config-2-node.ini
pkgsupp_SCRIPTS = mysql.server \
- mysqld_multi.server
+ mysqld_multi.server \
+ binary-configure \
+ mysql-log-rotate
aclocaldir = $(datadir)/aclocal
aclocal_DATA = mysql.m4
=== modified file 'support-files/config.huge.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/config.medium.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/config.small.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/mysql.server.sh'
--- a/support-files/mysql.server.sh 2009-10-16 06:15:30 +0000
+++ b/support-files/mysql.server.sh 2009-10-23 19:26:26 +0000
@@ -77,7 +77,12 @@ else
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
- libexecdir="$basedir/libexec"
+ if test -f "$basedir/bin/mysqld"
+ then
+ libexecdir="$basedir/bin"
+ else
+ libexecdir="$basedir/libexec"
+ fi
fi
# datadir_set is used to determine if datadir was set (and so should be
@@ -126,6 +131,12 @@ parse_server_arguments() {
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
+ if test -f "$basedir/bin/mysqld"
+ then
+ libexecdir="$basedir/bin"
+ else
+ libexecdir="$basedir/libexec"
+ fi
libexecdir="$basedir/libexec"
;;
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
1
0
[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2791)
by Michael Widenius 23 Oct '09
by Michael Widenius 23 Oct '09
23 Oct '09
#At lp:maria based on revid:monty@askmonty.org-20091020233221-bbcl5rwjhurvogjw
2791 Michael Widenius 2009-10-23
Fixes for binary distribution in tar file
- mysql_install_db doesn't require --basedir option anymore
- Fix that mysql_install_db mysqld_safe mysql_fix_privilege_tables has right paths for tar binary install
- Move some files from share/mysql to where they have always been (1.0 - 5.0)
- Move scripts used when installing MariaDB to the scripts directory (Added symlinks in old place for compatibility)
- Move man files to 'man' (from 'share/man')
- Ensure that all scripts are executable
mysql_secure_installation.sh
- Added support for --basedir flag
- Don't assume that the mysql binary is in the path
Other:
- Fixed crash when one got kill signal during bootstrap
modified:
Docs/INSTALL-BINARY
Docs/mysql.info
README
configure.in
libmysql/libmysql.c
scripts/make_binary_distribution.sh
scripts/mysql_secure_installation.sh
sql/mysqld.cc
storage/maria/Makefile.am
storage/myisam/Makefile.am
support-files/Makefile.am
support-files/config.huge.ini.sh*
support-files/config.medium.ini.sh*
support-files/config.small.ini.sh*
support-files/mysql.server.sh
per-file messages:
Docs/INSTALL-BINARY
Change references from MySQL to MariaDB
Docs/mysql.info
Change references from MySQL to MariaDB
README
Removed duplicate row
configure.in
Change references from MySQL to MariaDB
libmysql/libmysql.c
Assume that if version string contains '-maria-' we are also using MariaDB
scripts/make_binary_distribution.sh
Fix that mysql_install_db mysqld_safe mysql_fix_privilege_tables has right paths for tar binary install
Remove some files that should not be part of a MariaDB binary install
Move some files from share/mysql to where they have always been (1.0 - 5.0)
Move man files to 'man' (from 'share/man')
Move scripts used when installing MariaDB to the scripts directory (Added symlinks in old place for compatibility)
Removed generation of 'netware/init_db.sql', as it was never used
Remove old reference to bk tree
scripts/mysql_secure_installation.sh
Added support for --basedir flag
Don't assume that the mysql binary is in the path
Use .my.cnf files
Removed a lot of useless 'echo' rows
sql/mysqld.cc
Fixed crash when one got kill signal during bootstrap
storage/maria/Makefile.am
Don't add internal test files to binary distributions
storage/myisam/Makefile.am
Don't add internal test files to binary distributions
support-files/Makefile.am
Make scripts executable
support-files/config.huge.ini.sh
Removed execution bit
support-files/config.medium.ini.sh
Removed execution bit
support-files/config.small.ini.sh
Removed execution bit
support-files/mysql.server.sh
Ensure this works also mysqld is in the 'bin' directory
=== modified file 'Docs/INSTALL-BINARY'
--- a/Docs/INSTALL-BINARY 2009-09-16 12:03:18 +0000
+++ b/Docs/INSTALL-BINARY 2009-10-23 16:48:54 +0000
@@ -1,25 +1,20 @@
+MariaDB and MySQL have identical install methods. In this document we
+describe how to install MariaDB; However all documentation at www.mysql.com
+also applies.
-2.9. Installing MySQL from tar.gz Packages on Other Unix-Like Systems
- This section covers the installation of MySQL binary distributions
- that are provided for various platforms in the form of compressed
- tar files (files with a .tar.gz extension). See Section 2.1.2.4,
- "MySQL Binaries Compiled by Sun Microsystems, Inc.," for a
- detailed list.
+2.9. Installing MariaDB from tar.gz Packages on Other Unix-Like Systems
- To obtain MySQL, see Section 2.1.3, "How to Get MySQL."
+ This section covers the installation of MariaDB binary distributions
+ that are provided for various platforms in the form of compressed
+ tar files (files with a .tar.gz extension).
- MySQL tar file binary distributions have names of the form
- mysql-VERSION-OS.tar.gz, where VERSION is a number (for example,
+ MariaDB tar file binary distributions have names of the form
+ mariadb-VERSION-OS.tar.gz, where VERSION is a number (for example,
5.1.39), and OS indicates the type of operating system for which
the distribution is intended (for example, pc-linux-i686).
- In addition to these generic packages, we also offer binaries in
- platform-specific package formats for selected platforms. See
- Section 2.2, "Standard MySQL Installation Using a Binary
- Distribution," for more information on how to install these.
-
- You need the following tools to install a MySQL tar file binary
+ You need the following tools to install a MariaDB tar file binary
distribution:
* GNU gunzip to uncompress the distribution.
@@ -33,11 +28,14 @@
program. On other systems with a deficient tar, you should
install GNU tar first.
- If you run into problems and need to file a bug report, please use
- the instructions in Section 1.6, "How to Report Bugs or Problems."
+ If you run into problems and need to file a bug report,
+ please report them to: http://bugs.launchpad.net/maria
+
+ See the instructions in Section 1.6, "How to Report Bugs or Problems."
The basic commands that you must execute to install and use a
- MySQL binary distribution are:
+ MariaDB binary distribution are:
+
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
@@ -53,7 +51,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
- This procedure does not set up any passwords for MySQL accounts.
+ This procedure does not set up any passwords for MariaDB accounts.
After following the procedure, proceed to Section 2.11,
"Post-Installation Setup and Testing."
@@ -80,8 +78,8 @@ shell> useradd -g mysql mysql
shell> cd /usr/local
3. Obtain a distribution file using the instructions in Section
- 2.1.3, "How to Get MySQL." For a given release, binary
- distributions for all platforms are built from the same MySQL
+ 2.1.3, "How to Get MariaDB." For a given release, binary
+ distributions for all platforms are built from the same MariaDB
source distribution.
4. Unpack the distribution, which creates the installation
@@ -106,7 +104,7 @@ shell> cd mysql
+ The bin directory contains client programs and the
server. You should add the full path name of this
directory to your PATH environment variable so that your
- shell finds the MySQL programs properly. See Section
+ shell finds the MariaDB programs properly. See Section
2.14, "Environment Variables."
+ The scripts directory contains the mysql_install_db
@@ -126,8 +124,8 @@ shell> chgrp -R mysql .
the mysql user. The second changes the group attribute to the
mysql group.
- 7. If you have not installed MySQL before, you must create the
- MySQL data directory and initialize the grant tables:
+ 7. If you have not installed MariaDB before, you must create the
+ MariaDB data directory and initialize the grant tables:
shell> scripts/mysql_install_db --user=mysql
If you run the command as root, include the --user option as
shown. If you run the command while logged in as that user,
@@ -137,25 +135,26 @@ shell> scripts/mysql_install_db --user=m
After creating or updating the grant tables, you need to
restart the server manually.
- 8. Most of the MySQL installation can be owned by root if you
+ 8. Most of the MariaDB installation can be owned by root if you
like. The exception is that the data directory must be owned
by mysql. To accomplish this, run the following commands as
root in the installation directory:
+
shell> chown -R root .
shell> chown -R mysql data
- 9. If you want MySQL to start automatically when you boot your
+ 9. If you want MariaDB to start automatically when you boot your
machine, you can copy support-files/mysql.server to the
location where your system has its startup files. More
information can be found in the support-files/mysql.server
script itself and in Section 2.11.2.2, "Starting and Stopping
- MySQL Automatically."
+ MariaDB Automatically."
10. You can set up new accounts using the bin/mysql_setpermission
script if you install the DBI and DBD::mysql Perl modules. See
Section 4.6.14, "mysql_setpermission --- Interactively Set
Permissions in Grant Tables." For Perl module installation
instructions, see Section 2.15, "Perl Installation Notes."
- 11. If you would like to use mysqlaccess and have the MySQL
+ 11. If you would like to use mysqlaccess and have the MariaDB
distribution in some nonstandard location, you must change the
location where mysqlaccess expects to find the mysql client.
Edit the bin/mysqlaccess script at approximately line 18.
@@ -166,7 +165,7 @@ $MYSQL = '/usr/local/bin/mysql';
error will occur when you run mysqlaccess.
After everything has been unpacked and installed, you should test
- your distribution. To start the MySQL server, use the following
+ your distribution. To start the MariaDB server, use the following
command:
shell> bin/mysqld_safe --user=mysql &
@@ -185,7 +184,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
- The accounts that are listed in the MySQL grant tables initially
+ The accounts that are listed in the MariaDB grant tables initially
have no passwords. After starting the server, you should set up
passwords for them using the instructions in Section 2.11,
"Post-Installation Setup and Testing."
=== modified file 'Docs/mysql.info'
--- a/Docs/mysql.info 2007-11-02 11:29:13 +0000
+++ b/Docs/mysql.info 2009-10-23 16:48:54 +0000
@@ -1,3 +1,10 @@
+MariaDB is in most aspects identical to MySQL.
+
+Differences between MySQL and MariaDB can be found at:
+http://askmonty.org/wiki/index.php/MariaDB_versus_MySQL
+
+The MariaDB references manual can be found at:
+http://askmonty.org/wiki/index.php/Manual
The MySQL Reference Manual is available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
=== modified file 'README'
--- a/README 2009-09-15 10:46:35 +0000
+++ b/README 2009-10-23 16:48:54 +0000
@@ -1,5 +1,4 @@
This is a release of MariaDB, a branch of MySQL.
-MySQL is brought to you by the MySQL team at Sun Microsystems, Inc.
MariaDB is a drop-in replacement of MySQL, with more features, less
bugs and better performance.
=== modified file 'configure.in'
--- a/configure.in 2009-10-08 09:43:31 +0000
+++ b/configure.in 2009-10-23 16:48:54 +0000
@@ -2897,13 +2897,11 @@ AC_CONFIG_COMMANDS_POST(ac_configure_arg
AC_OUTPUT
echo
-echo "MySQL has a Web site at http://www.mysql.com/ which carries details on the"
-echo "latest release, upcoming features, and other information to make your"
-echo "work or play with MySQL more productive. There you can also find"
-echo "information about mailing lists for MySQL discussion."
+echo "You can find information about MariaDB at"
+echo http://askmonty.org/wiki/index.php/MariaDB
echo
echo "Remember to check the platform specific part of the reference manual for"
-echo "hints about installing MySQL on your platform. Also have a look at the"
+echo "hints about installing MariaDB on your platform. Also have a look at the"
echo "files in the Docs directory."
echo
@@ -2922,5 +2920,5 @@ echo "---"
# The following text is checked in ./Do-compile to verify that configure
# ended sucessfully - don't remove it.
-echo "Thank you for choosing MySQL!"
+echo "Thank you for choosing MariaDB!"
echo
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2009-10-02 10:36:28 +0000
+++ b/libmysql/libmysql.c 2009-10-23 16:48:54 +0000
@@ -1432,7 +1432,8 @@ mysql_get_server_info(MYSQL *mysql)
my_bool STDCALL mariadb_connection(MYSQL *mysql)
{
- return strinstr(mysql->server_version, "MariaDB") != 0;
+ return (strinstr(mysql->server_version, "MariaDB") != 0 ||
+ strinstr(mysql->server_version, "-maria-") != 0);
}
const char * STDCALL
=== modified file 'scripts/make_binary_distribution.sh'
--- a/scripts/make_binary_distribution.sh 2009-10-20 23:32:21 +0000
+++ b/scripts/make_binary_distribution.sh 2009-10-23 16:48:54 +0000
@@ -239,8 +239,8 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
# ----------------------------------------------------------------------
cd scripts
- rm -f mysql_install_db
- @MAKE@ mysql_install_db \
+ rm -f mysql_install_db mysqld_safe mysql_fix_privilege_tables
+ @MAKE@ mysql_install_db mysqld_safe mysql_fix_privilege_tables \
prefix=. \
bindir=./bin \
sbindir=./bin \
@@ -257,7 +257,7 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
sbindir=./bin \
scriptdir=./bin \
libexecdir=./bin \
- pkgdatadir=@pkgdatadir@
+ pkgdatadir=./share
cd ..
# ----------------------------------------------------------------------
@@ -320,6 +320,33 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; t
mkdir $DEST/data $DEST/data/mysql $DEST/data/test
chmod o-rwx $DEST/data $DEST/data/mysql $DEST/data/test
+ # Remove not needed files
+ rm $DEST/share/mysql/errmsg.txt
+
+ # Remove NDB files
+ rm -f $DEST/share/mysql/ndb-config-2-node.ini \
+ $DEST/share/mysql/config*
+
+ #
+ # Move things to make them easier to find in tar installation
+ #
+ mv $DEST/libexec/* $DEST/bin
+ mv $DEST/share/man $DEST
+ mv $DEST/share/mysql/binary-configure $DEST/configure
+ mv $DEST/share/mysql/*.sql $DEST/share
+ mv $DEST/share/mysql/*.cnf $DEST/share/mysql/*.server $DEST/share/mysql/mysql-log-rotate $DEST/support-files
+ rmdir $DEST/libexec
+
+ #
+ # Move some scripts that are only run once to 'scripts' directory
+ # but add symbolic links instead to old place for compatibility
+ #
+ for i in mysql_secure_installation mysql_fix_extensions mysql_fix_privilege_tables
+ do
+ mv $DEST/bin/$i $DEST/scripts
+ ln -s "../scripts/$i" $DEST/bin/$i
+ done
+
# ----------------------------------------------------------------------
# Create the result tar file
# ----------------------------------------------------------------------
@@ -496,12 +523,21 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in
$BASE/bin/mysql_install_db $BASE/bin/make_binary_distribution \
$BASE/bin/make_win_* \
$BASE/bin/setsomevars $BASE/support-files/Makefile* \
- $BASE/support-files/*.sh
+ $BASE/support-files/*.sh \
+ $BASE/share/mysql/errmsg.txt
+
+# Remove NDB files
+rm -f $BASE/share/ndb-config-2-node.ini \
+ $BASE/share/mysql/config*
#
-# Copy system dependent files
+# Move things to make things easier to find in tar installation
#
-./scripts/fill_help_tables < ./Docs/manual.texi >> ./netware/init_db.sql
+
+mv $BASE/share/man $BASE
+mv $BASE/share/mysql/binary-configure $BASE/configure
+mv $BASE/share/mysql/*.sql $BASE/share
+mv $BASE/share/mysql/*.cnf $BASE/share/mysql/*.server $BASE/share/mysql/mysql-log-rotate $BASE/support-files
#
# Remove system dependent files
@@ -515,12 +551,6 @@ rm -f $BASE/support-files/magic \
$BASE/support-files/MySQL-shared-compat.spec \
$BASE/INSTALL-BINARY
-# Clean up if we did this from a bk tree
-if [ -d $BASE/sql-bench/SCCS ] ; then
- find $BASE/share -name SCCS -print | xargs rm -rf
- find $BASE/sql-bench -name SCCS -print | xargs rm -rf
-fi
-
BASE2=$TMP/$NEW_NAME
rm -rf $BASE2
mv $BASE $BASE2
=== modified file 'scripts/mysql_secure_installation.sh'
--- a/scripts/mysql_secure_installation.sh 2007-01-01 04:31:23 +0000
+++ b/scripts/mysql_secure_installation.sh 2009-10-23 16:48:54 +0000
@@ -23,6 +23,157 @@ trap "interrupt" 2
rootpass=""
echo_n=
echo_c=
+basedir=
+bindir=
+
+parse_arg()
+{
+ echo "$1" | sed -e 's/^[^=]*=//'
+}
+
+parse_arguments()
+{
+ # We only need to pass arguments through to the server if we don't
+ # handle them here. So, we collect unrecognized options (passed on
+ # the command line) into the args variable.
+ pick_args=
+ if test "$1" = PICK-ARGS-FROM-ARGV
+ then
+ pick_args=1
+ shift
+ fi
+
+ for arg
+ do
+ case "$arg" in
+ --basedir=*) basedir=`parse_arg "$arg"` ;;
+ --no-defaults|--defaults-file=*|--defaults-extra-file=*)
+ defaults="$arg" ;;
+ *)
+ if test -n "$pick_args"
+ then
+ # This sed command makes sure that any special chars are quoted,
+ # so the arg gets passed exactly to the server.
+ # XXX: This is broken; true fix requires using eval and proper
+ # quoting of every single arg ($basedir, $ldata, etc.)
+ #args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
+ args="$args $arg"
+ fi
+ ;;
+ esac
+ done
+}
+
+# Try to find a specific file within --basedir which can either be a binary
+# release or installed source directory and return the path.
+find_in_basedir()
+{
+ return_dir=
+ case "$1" in
+ --dir)
+ return_dir=1; shift
+ ;;
+ esac
+
+ file=$1; shift
+
+ for dir in "$@"
+ do
+ if test -f "$basedir/$dir/$file"
+ then
+ if test -n "$return_dir"
+ then
+ echo "$basedir/$dir"
+ else
+ echo "$basedir/$dir/$file"
+ fi
+ break
+ fi
+ done
+}
+
+cannot_find_file()
+{
+ echo
+ echo "FATAL ERROR: Could not find $1"
+
+ shift
+ if test $# -ne 0
+ then
+ echo
+ echo "The following directories were searched:"
+ echo
+ for dir in "$@"
+ do
+ echo " $dir"
+ done
+ fi
+
+ echo
+ echo "If you compiled from source, you need to run 'make install' to"
+ echo "copy the software into the correct location ready for operation."
+ echo
+ echo "If you are using a binary release, you must either be at the top"
+ echo "level of the extracted archive, or pass the --basedir option"
+ echo "pointing to that location."
+ echo
+}
+
+# Ok, let's go. We first need to parse arguments which are required by
+# my_print_defaults so that we can execute it first, then later re-parse
+# the command line to add any extra bits that we need.
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+#
+# We can now find my_print_defaults. This script supports:
+#
+# --srcdir=path pointing to compiled source tree
+# --basedir=path pointing to installed binary location
+#
+# or default to compiled-in locations.
+#
+
+if test -n "$basedir"
+then
+ print_defaults=`find_in_basedir my_print_defaults bin extra`
+ echo "print: $print_defaults"
+ if test -z "$print_defaults"
+ then
+ cannot_find_file my_print_defaults $basedir/bin $basedir/extra
+ exit 1
+ fi
+else
+ print_defaults="@bindir@/my_print_defaults"
+fi
+
+if test ! -x "$print_defaults"
+then
+ cannot_find_file "$print_defaults"
+ exit 1
+fi
+
+# Now we can get arguments from the group [client]
+# in the my.cfg file, then re-run to merge with command line arguments.
+parse_arguments `$print_defaults $defaults client`
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+# Configure paths to support files
+if test -n "$basedir"
+then
+ bindir="$basedir/bin"
+elif test -f "./bin/mysql"
+ then
+ bindir="./bin"
+else
+ bindir="@bindir@"
+fi
+
+mysql_command=`find_in_basedir mysql $bindir`
+if test -z "$print_defaults"
+then
+ cannot_find_file mysql $bindir
+ exit 1
+fi
set_echo_compat() {
case `echo "testing\c"`,`echo -n testing` in
@@ -39,7 +190,7 @@ prepare() {
do_query() {
echo $1 >$command
- mysql --defaults-file=$config <$command
+ $bindir/mysql --defaults-file=$config <$command
return $?
}
@@ -185,14 +336,9 @@ prepare
set_echo_compat
echo
-echo
-echo
-echo
echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL"
echo " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!"
echo
-echo
-
echo "In order to log into MySQL to secure it, we'll need the current"
echo "password for the root user. If you've just installed MySQL, and"
echo "you haven't set the root password yet, the password will be blank,"
@@ -310,13 +456,8 @@ echo
cleanup
echo
-echo
-echo
echo "All done! If you've completed all of the above steps, your MySQL"
echo "installation should now be secure."
echo
echo "Thanks for using MySQL!"
-echo
-echo
-
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-10-16 15:44:58 +0000
+++ b/sql/mysqld.cc 2009-10-23 16:48:54 +0000
@@ -4560,7 +4560,13 @@ we force server id to 2, but this MySQL
{
select_thread_in_use= 0; // Allow 'kill' to work
bootstrap(stdin);
- unireg_abort(bootstrap_error ? 1 : 0);
+ if (!kill_in_progress)
+ unireg_abort(bootstrap_error ? 1 : 0);
+ else
+ {
+ sleep(2); // Wait for kill
+ exit(0);
+ }
}
if (opt_init_file)
{
=== modified file 'storage/maria/Makefile.am'
--- a/storage/maria/Makefile.am 2008-06-26 05:18:28 +0000
+++ b/storage/maria/Makefile.am 2009-10-23 16:48:54 +0000
@@ -32,7 +32,7 @@ SUBDIRS = . unittest
EXTRA_DIST = ma_test_all.sh ma_test_all.res ma_test_big.sh \
ma_ft_stem.c CMakeLists.txt plug.in ma_test_recovery
-pkgdata_DATA = ma_test_all ma_test_all.res ma_test_recovery
+pkgdata_DATA =
pkglib_LIBRARIES = libmaria.a
bin_PROGRAMS = maria_chk maria_pack maria_ftdump maria_read_log \
maria_dump_log
=== modified file 'storage/myisam/Makefile.am'
--- a/storage/myisam/Makefile.am 2007-02-28 16:50:51 +0000
+++ b/storage/myisam/Makefile.am 2009-10-23 16:48:54 +0000
@@ -28,7 +28,7 @@ LDADD =
DEFS = @DEFS@
EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in
-pkgdata_DATA = mi_test_all mi_test_all.res
+pkgdata_DATA =
pkglib_LIBRARIES = libmyisam.a
bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
=== modified file 'support-files/Makefile.am'
--- a/support-files/Makefile.am 2009-02-24 16:54:03 +0000
+++ b/support-files/Makefile.am 2009-10-23 16:48:54 +0000
@@ -53,7 +53,9 @@ pkgsupp_DATA = my-small.cnf \
ndb-config-2-node.ini
pkgsupp_SCRIPTS = mysql.server \
- mysqld_multi.server
+ mysqld_multi.server \
+ binary-configure \
+ mysql-log-rotate
aclocaldir = $(datadir)/aclocal
aclocal_DATA = mysql.m4
=== modified file 'support-files/config.huge.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/config.medium.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/config.small.ini.sh' (properties changed: +x to -x)
=== modified file 'support-files/mysql.server.sh'
--- a/support-files/mysql.server.sh 2009-07-02 13:18:12 +0000
+++ b/support-files/mysql.server.sh 2009-10-23 16:48:54 +0000
@@ -77,7 +77,12 @@ else
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
- libexecdir="$basedir/libexec"
+ if test -f "$basedir/bin/mysqld"
+ then
+ libexecdir="$basedir/bin"
+ else
+ libexecdir="$basedir/libexec"
+ fi
fi
# datadir_set is used to determine if datadir was set (and so should be
@@ -126,6 +131,12 @@ parse_server_arguments() {
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
+ if test -f "$basedir/bin/mysqld"
+ then
+ libexecdir="$basedir/bin"
+ else
+ libexecdir="$basedir/libexec"
+ fi
libexecdir="$basedir/libexec"
;;
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
1
0
[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2791)
by knielsenï¼ knielsen-hq.org 23 Oct '09
by knielsenï¼ knielsen-hq.org 23 Oct '09
23 Oct '09
#At lp:maria
2791 knielsen(a)knielsen-hq.org 2009-10-23 [merge]
Merge Peter Lieverdink's fixes:
- configtest target in rc script.
- type fix usefull -> useful.
modified:
Docs/myisam.txt
configure.in
mysql-test/mysql-stress-test.pl
mysys/safemalloc.c
sql/mysqld.cc
sql/sql_select.cc
sql/udf_example.c
support-files/mysql.server.sh
=== modified file 'Docs/myisam.txt'
--- a/Docs/myisam.txt 2000-07-31 19:29:14 +0000
+++ b/Docs/myisam.txt 2009-09-30 23:40:51 +0000
@@ -868,7 +868,7 @@ Space compression makes the index file s
Prefix compression helps if there are many strings with an identical prefix.
In memory table characteristics
-HEAP tables only exists in memory so they are lost if `mysqld' is taken down or crashes. But since they are *very* fast they are usefull as anyway.
+HEAP tables only exists in memory so they are lost if `mysqld' is taken down or crashes. But since they are *very* fast they are useful as anyway.
The *MySQL* internal HEAP tables uses 100% dynamic hashing without overflow areas and don't have problems with delete.
=== modified file 'configure.in'
--- a/configure.in 2009-10-08 09:43:31 +0000
+++ b/configure.in 2009-10-16 06:18:37 +0000
@@ -2847,7 +2847,7 @@ do
done
AC_SUBST(sql_union_dirs)
-# Some usefull subst
+# Some useful subst
AC_SUBST(CC)
AC_SUBST(GXX)
=== modified file 'mysql-test/mysql-stress-test.pl'
--- a/mysql-test/mysql-stress-test.pl 2006-03-03 18:15:01 +0000
+++ b/mysql-test/mysql-stress-test.pl 2009-09-30 23:40:51 +0000
@@ -1100,7 +1100,7 @@ mysql-stress-test.pl --stress-basedir=<d
they specified in the list file.
--sleep-time=<time in seconds>
- Delay between test execution. Could be usefull in continued testsing
+ Delay between test execution. Could be useful in continued testsing
when one of instance of stress script perform periodical cleanup or
recreating of some database objects
@@ -1109,7 +1109,7 @@ mysql-stress-test.pl --stress-basedir=<d
--check-tests-file
Check file with list of tests. If file was modified it will force to
- reread list of tests. Could be usefull in continued testing for
+ reread list of tests. Could be useful in continued testing for
adding/removing tests without script interruption
--mysqltest=/path/to/mysqltest binary
=== modified file 'mysys/safemalloc.c'
--- a/mysys/safemalloc.c 2009-09-07 20:50:10 +0000
+++ b/mysys/safemalloc.c 2009-09-30 23:40:51 +0000
@@ -436,7 +436,7 @@ void TERMINATE(FILE *file, uint flag)
/*
Report where a piece of memory was allocated
- This is usefull to call from withing a debugger
+ This is useful to call from withing a debugger
*/
void sf_malloc_report_allocated(void *memory)
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-10-16 15:44:58 +0000
+++ b/sql/mysqld.cc 2009-10-23 11:43:17 +0000
@@ -6630,7 +6630,7 @@ log and this option does nothing anymore
0, 0, 0, 0, 0},
{"test-ignore-wrong-options", OPT_TEST_IGNORE_WRONG_OPTIONS,
- "Ignore wrong enums values in command line arguments. Usefull only for test scripts",
+ "Ignore wrong enums values in command line arguments. Useful only for test scripts",
(uchar**) &opt_ignore_wrong_options, (uchar**) &opt_ignore_wrong_options,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"timed_mutexes", OPT_TIMED_MUTEXES,
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2009-09-15 10:46:35 +0000
+++ b/sql/sql_select.cc 2009-09-30 23:40:51 +0000
@@ -11812,7 +11812,7 @@ join_read_const_table(JOIN_TAB *tab, POS
{
#if !defined(DBUG_OFF) && defined(NOT_USING_ITEM_EQUAL)
/*
- This test could be very usefull to find bugs in the optimizer
+ This test could be very useful to find bugs in the optimizer
where we would call this function with an expression that can't be
evaluated yet. We can't have this enabled by default as long as
have items like Item_equal, that doesn't report they are const but
=== modified file 'sql/udf_example.c'
--- a/sql/udf_example.c 2009-04-25 10:05:32 +0000
+++ b/sql/udf_example.c 2009-09-30 23:40:51 +0000
@@ -205,7 +205,7 @@ char *is_const(UDF_INIT *initid, UDF_ARG
** try to keep the error message less than 80 bytes long!
**
** This function should return 1 if something goes wrong. In this case
-** message should contain something usefull!
+** message should contain something useful!
**************************************************************************/
#define MAXMETAPH 8
=== modified file 'support-files/mysql.server.sh'
--- a/support-files/mysql.server.sh 2009-07-02 13:18:12 +0000
+++ b/support-files/mysql.server.sh 2009-10-16 06:15:30 +0000
@@ -434,9 +434,36 @@ case "$mode" in
fi
fi
;;
- *)
+ 'configtest')
+ # Safeguard (relative paths, core dumps..)
+ cd $basedir
+ echo $echo_n "Testing MySQL configuration syntax"
+ daemon=$bindir/mysqld
+ if test -x $libexecdir/mysqld
+ then
+ daemon=$libexecdir/mysqld
+ elif test -x $sbindir/mysqld
+ then
+ daemon=$sbindir/mysqld
+ elif test -x `which mysqld`
+ then
+ daemon=`which mysqld`
+ else
+ log_failure_msg "Unable to locate the mysqld binary!"
+ exit 1
+ fi
+ help_out=`$daemon --help 2>&1`; r=$?
+ if test "$r" != 0 ; then
+ log_failure_msg "$help_out"
+ log_failure_msg "There are syntax errors in the server configuration. Please fix them!"
+ else
+ log_success_msg "Syntax OK"
+ fi
+ exit $r
+ ;;
+ *)
# usage
- echo "Usage: $0 {start|stop|restart|reload|force-reload|status} [ MySQL server options ]"
+ echo "Usage: $0 {start|stop|restart|reload|force-reload|status|configtest} [ MySQL server options ]"
exit 1
;;
esac
1
0
[Maria-developers] bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (monty:2727)
by Michael Widenius 23 Oct '09
by Michael Widenius 23 Oct '09
23 Oct '09
#At lp:maria/5.2 based on revid:monty@askmonty.org-20091019171448-rkr7tyitt2m544h9
2727 Michael Widenius 2009-10-23
Fixed version number
modified:
configure.in
=== modified file 'configure.in'
--- a/configure.in 2009-10-19 17:14:48 +0000
+++ b/configure.in 2009-10-23 07:54:38 +0000
@@ -15,7 +15,7 @@ AC_CANONICAL_SYSTEM
# MySQL version number.
#
# Note: the following line must be parseable by win/configure.js:GetVersion()
-AM_INIT_AUTOMAKE(mysql, 5.1.38-maria-beta)
+AM_INIT_AUTOMAKE(mysql, 5.2.0-alpha)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
1
0
[Maria-developers] Updated (by Monty): Improve the show statistics (60)
by worklog-noreplyï¼ askmonty.org 22 Oct '09
by worklog-noreplyï¼ askmonty.org 22 Oct '09
22 Oct '09
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Improve the show statistics
CREATION DATE..: Thu, 22 Oct 2009, 17:42
SUPERVISOR.....: Monty
IMPLEMENTOR....: Bothorsen
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 60 (http://askmonty.org/worklog/?tid=60)
VERSION........: WorkLog-3.4
STATUS.........: Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 0 (hours remain)
ORIG. ESTIMATE.: 0
PROGRESS NOTES:
-=-=(Monty - Thu, 22 Oct 2009, 18:38)=-=-
High Level Description modified.
--- /tmp/wklog.60.old.17258 2009-10-22 15:38:47.000000000 +0000
+++ /tmp/wklog.60.new.17258 2009-10-22 15:38:47.000000000 +0000
@@ -1,12 +1,17 @@
In the MariaDB 5.2 branch, some new parts to show statistics have been added.
Monty wants these to be improved upon.
-1) Change "show table_statistics" to "show table statistics"
+1)
+Change "show [table|index|user|client]_statistics" to
+"show [table|index|user|client] statistics"
-2) Add a "flush statistics" that flushes all statistics to the current "flush
-table statistics"
+Do the same change to the flush command
-3) Add where and like clauses to show statistics.
+2)
+Add a "flush statistics" as a synonym for
+flush table_statistics, index statistics..."
+
+3) Add where and like clauses to show XXXX_statistics.
(only like: match most important column)
This will be done as a patch to the 5.2 tree.
DESCRIPTION:
In the MariaDB 5.2 branch, some new parts to show statistics have been added.
Monty wants these to be improved upon.
1)
Change "show [table|index|user|client]_statistics" to
"show [table|index|user|client] statistics"
Do the same change to the flush command
2)
Add a "flush statistics" as a synonym for
flush table_statistics, index statistics..."
3) Add where and like clauses to show XXXX_statistics.
(only like: match most important column)
This will be done as a patch to the 5.2 tree.
Interesting files for this patch are: sql_show.cc, sql_yacc.yy and lex.h.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v3.5.9)
1
0