[Pkg-mysql-commits] r1209 - in trunk: . debian debian/patches
Monty Taylor
mtaylor-guest at alioth.debian.org
Wed Apr 30 03:50:06 UTC 2008
Author: mtaylor-guest
Date: 2008-04-30 03:50:06 +0000 (Wed, 30 Apr 2008)
New Revision: 1209
Added:
trunk/debian/patches/57_fix_mysql_replication.dpatch
trunk/debian/patches/61_microslow.dpatch
Modified:
trunk/
trunk/debian/changelog
trunk/debian/patches/00list
Log:
Merged in changes.
Property changes on: trunk
___________________________________________________________________
Name: bzr:revision-info
- timestamp: 2008-04-19 11:34:46.030999899 -0700
committer: Monty Taylor <monty at inaugust.com>
properties:
branch-nick: trunk
+ timestamp: 2008-04-26 11:15:06.736999989 -0700
committer: Monty Taylor <monty at inaugust.com>
properties:
branch-nick: trunk
Name: bzr:ancestry:v3-trunk0
- svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1093
monty at inaugust.com-20071219005821-v5qtsv9qvi70s0mt
monty at inaugust.com-20071227223102-6uiuykhyivk9r6q9
svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1115
svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1150
+ svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1093
monty at inaugust.com-20071219005821-v5qtsv9qvi70s0mt
monty at inaugust.com-20071227223102-6uiuykhyivk9r6q9
svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1115
svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1150
svn-v3-trunk0:bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:1202
Name: bzr:file-ids
- debian/patches/70_ebay_mysql_heap_dynamic_rows.dpatch 70_ebay_mysql_heap_d-20080419182018-xn5ikjccusouaio5-1
+ debian/patches/57_fix_mysql_replication.dpatch 1198 at bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:debian%2Fpatches%2F57_fix_mysql_replication.dpatch
debian/patches/61_microslow.dpatch 1202 at bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:trunk:debian%2Fpatches%2F61_microslow.dpatch
Name: bzr:revision-id:v3-trunk0
- 588 monty at inaugust.com-20071218115655-e9a3qdeanxkm37q0
589 monty at inaugust.com-20071219010144-z07rx72f4aryuxd5
590 monty at inaugust.com-20071219010251-1xj8ebk20xcavzzz
591 monty at inaugust.com-20071219133703-cfc7gcr1mfrbff5k
594 monty at inaugust.com-20071219160333-4t3d5sm5ou2cnx42
600 monty at inaugust.com-20071227231232-38mmb4bf89bai9tz
601 monty at inaugust.com-20071227231533-6u75bgvr52589l9d
602 monty at inaugust.com-20071227232516-5e1uuemjok6gax36
603 monty at inaugust.com-20071227232613-mvmphhlfm3ucfjre
604 monty at inaugust.com-20071227232728-26ik99mzw0yhq4vi
605 monty at inaugust.com-20071227234930-zlri2er7sq9obnot
606 monty at inaugust.com-20071228004201-2uib1ipksw8yeodu
607 monty at inaugust.com-20080218183922-0rfctqrxnkvqirvz
608 monty at inaugust.com-20080218184224-jq7u016hfc6gvt16
609 monty at inaugust.com-20080218191319-s202z6cpd2wkk6mx
610 monty at inaugust.com-20080218193205-41o5j3pbcsjpnwhp
611 monty at inaugust.com-20080219191434-rk81tk20rs716j21
612 monty at inaugust.com-20080219191453-lt7mlbmdj6vqmv2z
613 monty at inaugust.com-20080219191808-lm6fzgy5dldmgs00
614 monty at inaugust.com-20080219195801-1qsjv2edorbp07gu
615 monty at inaugust.com-20080227185513-vudpt1mtynu6jc4v
616 monty at inaugust.com-20080227193209-cl6e3g7cmlurkc2f
620 monty at inaugust.com-20080301125100-u5yhvmmzuf7g8baz
629 monty at inaugust.com-20080330023953-bpbgyxivz97shb09
630 monty at inaugust.com-20080330024030-0wolpf04aabjsrom
633 monty at inaugust.com-20080401091054-yra08fd5sy0jopl4
635 monty at inaugust.com-20080419183446-d38duis16nygevbi
+ 588 monty at inaugust.com-20071218115655-e9a3qdeanxkm37q0
589 monty at inaugust.com-20071219010144-z07rx72f4aryuxd5
590 monty at inaugust.com-20071219010251-1xj8ebk20xcavzzz
591 monty at inaugust.com-20071219133703-cfc7gcr1mfrbff5k
594 monty at inaugust.com-20071219160333-4t3d5sm5ou2cnx42
600 monty at inaugust.com-20071227231232-38mmb4bf89bai9tz
601 monty at inaugust.com-20071227231533-6u75bgvr52589l9d
602 monty at inaugust.com-20071227232516-5e1uuemjok6gax36
603 monty at inaugust.com-20071227232613-mvmphhlfm3ucfjre
604 monty at inaugust.com-20071227232728-26ik99mzw0yhq4vi
605 monty at inaugust.com-20071227234930-zlri2er7sq9obnot
606 monty at inaugust.com-20071228004201-2uib1ipksw8yeodu
607 monty at inaugust.com-20080218183922-0rfctqrxnkvqirvz
608 monty at inaugust.com-20080218184224-jq7u016hfc6gvt16
609 monty at inaugust.com-20080218191319-s202z6cpd2wkk6mx
610 monty at inaugust.com-20080218193205-41o5j3pbcsjpnwhp
611 monty at inaugust.com-20080219191434-rk81tk20rs716j21
612 monty at inaugust.com-20080219191453-lt7mlbmdj6vqmv2z
613 monty at inaugust.com-20080219191808-lm6fzgy5dldmgs00
614 monty at inaugust.com-20080219195801-1qsjv2edorbp07gu
615 monty at inaugust.com-20080227185513-vudpt1mtynu6jc4v
616 monty at inaugust.com-20080227193209-cl6e3g7cmlurkc2f
620 monty at inaugust.com-20080301125100-u5yhvmmzuf7g8baz
629 monty at inaugust.com-20080330023953-bpbgyxivz97shb09
630 monty at inaugust.com-20080330024030-0wolpf04aabjsrom
633 monty at inaugust.com-20080401091054-yra08fd5sy0jopl4
635 monty at inaugust.com-20080419183446-d38duis16nygevbi
636 monty at inaugust.com-20080426181506-gc9m9zmjme3j0eo1
Name: svk:merge
- bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1093
bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1115
bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1150
+ bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1093
bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1115
bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1150
bb5a2ed9-75f0-0310-a2b8-e46d7b0922c1:/trunk:1202
Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog 2008-04-30 03:50:01 UTC (rev 1208)
+++ trunk/debian/changelog 2008-04-30 03:50:06 UTC (rev 1209)
@@ -1,8 +1,14 @@
mysql-dfsg-5.0 (5.0.51a-5) UNRELEASED; urgency=low
+ [ Norbert Tretkowski ]
+ * New patch 57_fix-mysql-replication.dpatch from 5.0.54 to fix directory for
+ relay logs when using replication.
+ * Add microslow patch from Percona, but don't enable it in default build.
+
+ [ Monty Taylor ]
* Added the eBay patch for variable sized Memory engine rows.
- -- Monty Taylor <mordred at inaugust.com> Sat, 19 Apr 2008 11:21:45 -0700
+ -- Monty Taylor <mordred at inaugust.com> Sat, 26 Apr 2008 11:10:49 -0700
mysql-dfsg-5.0 (5.0.51a-4) unstable; urgency=low
Modified: trunk/debian/patches/00list
===================================================================
--- trunk/debian/patches/00list 2008-04-30 03:50:01 UTC (rev 1208)
+++ trunk/debian/patches/00list 2008-04-30 03:50:06 UTC (rev 1209)
@@ -13,10 +13,13 @@
54_ssl-client-support.dpatch
55_testsuite-2008.dpatch
56_fix_order_by.dpatch
-#60_raise-max-keylength.dpatch
70_ebay_mysql_heap_dynamic_rows.dpatch
86_PATH_MAX.dpatch
88_sphinx_se.dpatch
89_ndb__staticlib.dpatch
90_upstreamdebiandir.dpatch
91_SECURITY_CVE-2007-5925.dpatch
+
+## Patches below are not enabled by default
+#60_raise-max-keylength.dpatch
+#61_microslow.dpatch
Added: trunk/debian/patches/57_fix_mysql_replication.dpatch
===================================================================
--- trunk/debian/patches/57_fix_mysql_replication.dpatch (rev 0)
+++ trunk/debian/patches/57_fix_mysql_replication.dpatch 2008-04-30 03:50:06 UTC (rev 1209)
@@ -0,0 +1,53 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 57_fix_mysql_replication.dpatch by Norbert Tretkowski <nobse at debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: http://bugs.mysql.com/bug.php?id=28597
+
+ at DPATCH@
+diff -Nrup a/mysql-test/t/rpl_dual_pos_advance.test b/mysql-test/t/rpl_dual_pos_advance.test
+--- a/mysql-test/t/rpl_dual_pos_advance.test 2007-03-20 12:15:14 +02:00
++++ b/mysql-test/t/rpl_dual_pos_advance.test 2007-11-05 17:20:08 +02:00
+@@ -106,9 +106,3 @@ connection slave;
+ sync_with_master;
+
+ # End of 4.1 tests
+-
+-# Cleanup
+-# The A->B->A replication causes the master to start writing relay logs
+-# in var/run, remove them
+-remove_file $MYSQLTEST_VARDIR/run/master-relay-bin.000001;
+-remove_file $MYSQLTEST_VARDIR/run/master-relay-bin.index;
+diff -Nrup a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test
+--- a/mysql-test/t/rpl_temporary.test 2007-02-27 15:54:31 +02:00
++++ b/mysql-test/t/rpl_temporary.test 2007-11-05 17:20:08 +02:00
+@@ -211,6 +211,8 @@ select * from t1;
+ connection master;
+ drop table t1;
+
++--remove_file $MYSQLTEST_VARDIR/tmp/bug14157.sql
++
+ # Delete the anonymous users
+ source include/delete_anonymous_users.inc;
+
+diff -Nrup a/sql/log.cc b/sql/log.cc
+--- a/sql/log.cc 2007-07-30 18:27:30 +03:00
++++ b/sql/log.cc 2007-11-05 17:20:08 +02:00
+@@ -448,13 +448,10 @@ const char *MYSQL_LOG::generate_name(con
+ {
+ if (!log_name || !log_name[0])
+ {
+- /*
+- TODO: The following should be using fn_format(); We just need to
+- first change fn_format() to cut the file name if it's too long.
+- */
+- strmake(buff, pidfile_name,FN_REFLEN-5);
+- strmov(fn_ext(buff),suffix);
+- return (const char *)buff;
++ strmake(buff, pidfile_name, FN_REFLEN - strlen(suffix) - 1);
++ return (const char *)
++ fn_format(buff, buff, "", suffix, MYF(MY_REPLACE_EXT|MY_REPLACE_DIR));
++
+ }
+ // get rid of extension if the log is binary to avoid problems
+ if (strip_ext)
Added: trunk/debian/patches/61_microslow.dpatch
===================================================================
--- trunk/debian/patches/61_microslow.dpatch (rev 0)
+++ trunk/debian/patches/61_microslow.dpatch 2008-04-30 03:50:06 UTC (rev 1209)
@@ -0,0 +1,1350 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 61_microslow.dpatch by Norbert Tretkowski <nobse at debian.org>
+
+ at DPATCH@
+diff -r 1cae91646da0 include/my_time.h
+--- a/include/my_time.h Thu Mar 27 11:55:26 2008 +0100
++++ b/include/my_time.h Mon Apr 07 14:28:43 2008 +0200
+@@ -140,7 +140,7 @@
+ int my_date_to_str(const MYSQL_TIME *l_time, char *to);
+ int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
+ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
+-
++ulonglong my_timer(ulonglong *ltime, ulonglong frequency);
+ C_MODE_END
+
+ #endif /* _my_time_h_ */
+diff -r 1cae91646da0 scripts/mysqldumpslow.sh
+--- a/scripts/mysqldumpslow.sh Thu Mar 27 11:55:26 2008 +0100
++++ b/scripts/mysqldumpslow.sh Mon Apr 07 14:28:43 2008 +0200
+@@ -83,8 +83,8 @@
+ s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//;
+ my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('','');
+
+- s/^# Query_time: (\d+) Lock_time: (\d+) Rows_sent: (\d+).*\n//;
+- my ($t, $l, $r) = ($1, $2, $3);
++ s/^# Query_time: (\d+(\.\d+)?) Lock_time: (\d+(\.\d+)?) Rows_sent: (\d+(\.\d+)?).*\n//;
++ my ($t, $l, $r) = ($1, $3, $5);
+ $t -= $l unless $opt{l};
+
+ # remove fluff that mysqld writes to log when it (re)starts:
+diff -r 1cae91646da0 sql-common/my_time.c
+--- a/sql-common/my_time.c Thu Mar 27 11:55:26 2008 +0100
++++ b/sql-common/my_time.c Mon Apr 07 14:28:43 2008 +0200
+@@ -1250,3 +1250,37 @@
+ return 0;
+ }
+
++/*
++ int my_timer(ulonglong *ltime, ulonglong frequency)
++
++ For performance measurement this function returns the number
++ of microseconds since the epoch (SVr4, BSD 4.3, POSIX 1003.1-2001)
++ or system start (Windows platforms).
++
++ For windows platforms frequency value (obtained via
++ QueryPerformanceFrequency) has to be specified. The global frequency
++ value is set in mysqld.cc.
++
++ If Windows platform doesn't support QueryPerformanceFrequency we will
++ obtain the time via GetClockCount, which supports microseconds only.
++*/
++
++ulonglong my_timer(ulonglong *ltime, ulonglong frequency)
++{
++ ulonglong newtime= 0;
++#ifdef __WIN__
++ if (frequency)
++ {
++ QueryPerformanceCounter((LARGE_INTEGER *)&newtime);
++ newtime/= (frequency * 1000000);
++ } else
++ newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
++#else
++ struct timeval t;
++ gettimeofday(&t, NULL);
++ newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
++#endif
++ if (ltime)
++ *ltime= newtime;
++ return newtime;
++}
+diff -r 1cae91646da0 sql/filesort.cc
+--- a/sql/filesort.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/filesort.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -172,6 +172,7 @@
+ {
+ statistic_increment(thd->status_var.filesort_scan_count, &LOCK_status);
+ }
++ thd->query_plan_flags|= QPLAN_FILESORT;
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+@@ -238,6 +239,7 @@
+ }
+ else
+ {
++ thd->query_plan_flags|= QPLAN_FILESORT_DISK;
+ if (!table_sort.buffpek && table_sort.buffpek_len < maxbuffer &&
+ !(table_sort.buffpek=
+ (byte *) read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
+@@ -1059,6 +1061,7 @@
+
+ statistic_increment(current_thd->status_var.filesort_merge_passes,
+ &LOCK_status);
++ current_thd->query_plan_fsort_passes++;
+ if (param->not_killable)
+ {
+ killed= ¬_killable;
+diff -r 1cae91646da0 sql/log.cc
+--- a/sql/log.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/log.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -2037,10 +2037,11 @@
+ */
+
+ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
+- time_t query_start_arg)
++ time_t query_start_arg, ulonglong query_start_timer)
+ {
+ bool error=0;
+ time_t current_time;
++ ulonglong current_timer;
+ if (!is_open())
+ return 0;
+ DBUG_ENTER("MYSQL_LOG::write");
+@@ -2051,7 +2052,8 @@
+ int tmp_errno=0;
+ char buff[80],*end;
+ end=buff;
+- if (!(thd->options & OPTION_UPDATE_LOG))
++ if (!(thd->options & OPTION_UPDATE_LOG) &&
++ !(thd->slave_thread && opt_log_slow_slave_statements))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ DBUG_RETURN(0);
+@@ -2081,22 +2083,69 @@
+ if (my_b_printf(&log_file, "# User at Host: %s[%s] @ %s [%s]\n",
+ sctx->priv_user ?
+ sctx->priv_user : "",
+- sctx->user ? sctx->user : "",
++ sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""),
+ sctx->host ? sctx->host : "",
+ sctx->ip ? sctx->ip : "") ==
+ (uint) -1)
+ tmp_errno=errno;
+ }
+- if (query_start_arg)
++ if (query_start_timer)
+ {
++ char buf[5][20];
++ ulonglong current_timer= my_timer(¤t_timer, frequency);
++ sprintf(buf[0], "%.6f", (current_timer - query_start_timer) / 1000000.0);
++ sprintf(buf[1], "%.6f", (thd->timer_after_lock - query_start_timer) / 1000000.0);
++ if (!query_length)
++ {
++ thd->sent_row_count= thd->examined_row_count= 0;
++ thd->innodb_was_used= FALSE;
++ thd->query_plan_flags= QPLAN_NONE;
++ thd->query_plan_fsort_passes= 0;
++ }
++
+ /* For slow query log */
+ if (my_b_printf(&log_file,
+- "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
+- (ulong) (current_time - query_start_arg),
+- (ulong) (thd->time_after_lock - query_start_arg),
++ "# Thread_id: %lu Schema: %s\n" \
++ "# Query_time: %s Lock_time: %s Rows_sent: %lu Rows_examined: %lu\n",
++ (ulong) thd->thread_id, (thd->db ? thd->db : ""),
++ buf[0], buf[1],
+ (ulong) thd->sent_row_count,
+ (ulong) thd->examined_row_count) == (uint) -1)
+ tmp_errno=errno;
++ if ((thd->variables.log_slow_verbosity & SLOG_V_QUERY_PLAN) &&
++ my_b_printf(&log_file,
++ "# QC_Hit: %s Full_scan: %s Full_join: %s Tmp_table: %s Tmp_table_on_disk: %s\n" \
++ "# Filesort: %s Filesort_on_disk: %s Merge_passes: %lu\n",
++ ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"),
++ thd->query_plan_fsort_passes) == (uint) -1)
++ tmp_errno=errno;
++ if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) && thd->innodb_was_used)
++ {
++ sprintf(buf[2], "%.6f", thd->innodb_io_reads_wait_timer / 1000000.0);
++ sprintf(buf[3], "%.6f", thd->innodb_lock_que_wait_timer / 1000000.0);
++ sprintf(buf[4], "%.6f", thd->innodb_innodb_que_wait_timer / 1000000.0);
++ if (my_b_printf(&log_file,
++ "# InnoDB_IO_r_ops: %lu InnoDB_IO_r_bytes: %lu InnoDB_IO_r_wait: %s\n" \
++ "# InnoDB_rec_lock_wait: %s InnoDB_queue_wait: %s\n" \
++ "# InnoDB_pages_distinct: %lu\n",
++ (ulong) thd->innodb_io_reads,
++ (ulong) thd->innodb_io_read,
++ buf[2], buf[3], buf[4],
++ (ulong) thd->innodb_page_access) == (uint) -1)
++ tmp_errno=errno;
++ }
++ else
++ {
++ if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) &&
++ my_b_printf(&log_file,"# No InnoDB statistics available for this query\n") == (uint) -1)
++ tmp_errno=errno;
++ }
+ }
+ if (thd->db && strcmp(thd->db,db))
+ { // Database changed
+diff -r 1cae91646da0 sql/log_event.cc
+--- a/sql/log_event.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/log_event.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -1905,6 +1905,7 @@
+ /* Execute the query (note that we bypass dispatch_command()) */
+ const char* found_semicolon= NULL;
+ mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
++ log_slow_statement(thd);
+
+ }
+ else
+diff -r 1cae91646da0 sql/my_time.c
+--- a/sql/my_time.c Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/my_time.c Mon Apr 07 14:28:43 2008 +0200
+@@ -1250,3 +1250,37 @@
+ return 0;
+ }
+
++/*
++ int my_timer(ulonglong *ltime, ulonglong frequency)
++
++ For performance measurement this function returns the number
++ of microseconds since the epoch (SVr4, BSD 4.3, POSIX 1003.1-2001)
++ or system start (Windows platforms).
++
++ For windows platforms frequency value (obtained via
++ QueryPerformanceFrequency) has to be specified. The global frequency
++ value is set in mysqld.cc.
++
++ If Windows platform doesn't support QueryPerformanceFrequency we will
++ obtain the time via GetClockCount, which supports microseconds only.
++*/
++
++ulonglong my_timer(ulonglong *ltime, ulonglong frequency)
++{
++ ulonglong newtime= 0;
++#ifdef __WIN__
++ if (frequency)
++ {
++ QueryPerformanceCounter((LARGE_INTEGER *)&newtime);
++ newtime/= (frequency / 1000000);
++ } else
++ newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */
++#else
++ struct timeval t;
++ gettimeofday(&t, NULL);
++ newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
++#endif
++ if (ltime)
++ *ltime= newtime;
++ return newtime;
++}
+diff -r 1cae91646da0 sql/mysql_priv.h
+--- a/sql/mysql_priv.h Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/mysql_priv.h Mon Apr 07 14:28:43 2008 +0200
+@@ -482,6 +482,78 @@
+ #define WEEK_FIRST_WEEKDAY 4
+
+ #define STRING_BUFFER_USUAL_SIZE 80
++
++/* Slow log */
++
++struct msl_opts
++{
++ ulong val;
++ char *name;
++};
++
++#define SLOG_V_MICROTIME 1 << 0
++#define SLOG_V_QUERY_PLAN 1 << 1
++#define SLOG_V_INNODB 1 << 2
++/* ... */
++#define SLOG_V_INVALID 1 << 31
++#define SLOG_V_NONE SLOG_V_MICROTIME
++
++static const struct msl_opts slog_verb[]=
++{
++ /* Basic flags */
++
++ { SLOG_V_MICROTIME, "microtime" },
++ { SLOG_V_QUERY_PLAN, "query_plan" },
++ { SLOG_V_INVALID, "innodb" },
++
++ /* End of baisc flags */
++
++ { 0, "" },
++
++ /* Complex flags */
++
++ { SLOG_V_MICROTIME, "minimal" },
++ { SLOG_V_MICROTIME|SLOG_V_QUERY_PLAN, "standard" },
++ { SLOG_V_INVALID, "full" },
++
++ /* End of complex flags */
++
++ { SLOG_V_INVALID, (char *)0 }
++};
++
++#define QPLAN_NONE 0
++#define QPLAN_QC 1 << 0
++#define QPLAN_QC_NO 1 << 1
++#define QPLAN_FULL_SCAN 1 << 2
++#define QPLAN_FULL_JOIN 1 << 3
++#define QPLAN_TMP_TABLE 1 << 4
++#define QPLAN_TMP_DISK 1 << 5
++#define QPLAN_FILESORT 1 << 6
++#define QPLAN_FILESORT_DISK 1 << 7
++/* ... */
++#define QPLAN_MAX 1 << 31
++
++#define SLOG_F_QC_NO QPLAN_QC_NO
++#define SLOG_F_FULL_SCAN QPLAN_FULL_SCAN
++#define SLOG_F_FULL_JOIN QPLAN_FULL_JOIN
++#define SLOG_F_TMP_TABLE QPLAN_TMP_TABLE
++#define SLOG_F_TMP_DISK QPLAN_TMP_DISK
++#define SLOG_F_FILESORT QPLAN_FILESORT
++#define SLOG_F_FILESORT_DISK QPLAN_FILESORT_DISK
++#define SLOG_F_INVALID 1 << 31
++#define SLOG_F_NONE 0
++
++static const struct msl_opts slog_filter[]=
++{
++ { SLOG_F_QC_NO, "qc_miss" },
++ { SLOG_F_FULL_SCAN, "full_scan" },
++ { SLOG_F_FULL_JOIN, "full_join" },
++ { SLOG_F_TMP_TABLE, "tmp_table" },
++ { SLOG_F_TMP_DISK, "tmp_table_on_disk" },
++ { SLOG_F_FILESORT, "filesort" },
++ { SLOG_F_FILESORT_DISK, "filesort_on_disk" },
++ { SLOG_F_INVALID, (char *)0 }
++};
+
+ enum enum_parsing_place
+ {
+@@ -1324,7 +1396,7 @@
+ 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;
+-extern my_bool opt_log_slow_admin_statements;
++extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
+ extern my_bool sp_automatic_privileges, opt_noacl;
+ extern my_bool opt_old_style_user_limits, trust_function_creators;
+ extern uint opt_crash_binlog_innodb;
+diff -r 1cae91646da0 sql/mysqld.cc
+--- a/sql/mysqld.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/mysqld.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -169,7 +169,6 @@
+ static void getvolumeID(BYTE *volumeName);
+ #endif /* __NETWARE__ */
+
+-
+ #ifdef _AIX41
+ int initgroups(const char *,unsigned int);
+ #endif
+@@ -213,6 +212,7 @@
+ extern "C" int gethostname(char *name, int namelen);
+ #endif
+
++ulonglong frequency= 0;
+
+ /* Constants */
+
+@@ -384,6 +384,7 @@
+ my_bool opt_secure_auth= 0;
+ char* opt_secure_file_priv= 0;
+ my_bool opt_log_slow_admin_statements= 0;
++my_bool opt_log_slow_slave_statements= 0;
+ my_bool lower_case_file_system= 0;
+ my_bool opt_large_pages= 0;
+ uint opt_large_page_size= 0;
+@@ -3490,6 +3491,8 @@
+ unireg_abort(1);
+ }
+ }
++ if (!QueryPerformanceFrequency((LARGE_INTEGER *)&frequency))
++ frequency= 0;
+ #endif /* __WIN__ */
+
+ if (init_common_variables(MYSQL_CONFIG_NAME,
+@@ -4733,7 +4736,7 @@
+ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
+ OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
+ OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
+- OPT_LONG_QUERY_TIME,
++ OPT_LONG_QUERY_TIME, OPT_MIN_EXAMINED_ROW_LIMIT,
+ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
+ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
+ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
+@@ -4824,6 +4827,10 @@
+ OPT_TIMED_MUTEXES,
+ OPT_OLD_STYLE_USER_LIMITS,
+ OPT_LOG_SLOW_ADMIN_STATEMENTS,
++ OPT_LOG_SLOW_SLAVE_STATEMENTS,
++ OPT_LOG_SLOW_RATE_LIMIT,
++ OPT_LOG_SLOW_VERBOSITY,
++ OPT_LOG_SLOW_FILTER,
+ OPT_TABLE_LOCK_WAIT_TIMEOUT,
+ OPT_PORT_OPEN_TIMEOUT,
+ OPT_MERGE,
+@@ -5205,6 +5212,11 @@
+ "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
+ (gptr*) &opt_log_slow_admin_statements,
+ (gptr*) &opt_log_slow_admin_statements,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
++ "Log slow replicated statements to the slow log if it is open.",
++ (gptr*) &opt_log_slow_slave_statements,
++ (gptr*) &opt_log_slow_slave_statements,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-slow-queries", OPT_SLOW_QUERY_LOG,
+ "Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options.",
+@@ -5868,11 +5880,27 @@
+ (gptr*) 0,
+ 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
+ 1, 100, 0, 1, 0},
++ {"log_slow_filter", OPT_LOG_SLOW_FILTER,
++ "Log only the queries that followed certain execution plan. Multiple flags allowed in a comma-separated string. [qc_miss, full_scan, full_join, tmp_table, tmp_table_on_disk, filesort, filesort_on_disk]",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_F_NONE, 0, 0},
++ {"log_slow_rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
++ "Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
++ (gptr*) &global_system_variables.log_slow_rate_limit,
++ (gptr*) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 1, ~0L, 0, 1L, 0},
++ {"log_slow_verbosity", OPT_LOG_SLOW_VERBOSITY,
++ "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [microtime, query_plan]",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_V_MICROTIME, 0, 0},
+ {"long_query_time", OPT_LONG_QUERY_TIME,
+ "Log all queries that have taken more than long_query_time seconds to execute to file.",
+ (gptr*) &global_system_variables.long_query_time,
+ (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG,
+- REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
++ REQUIRED_ARG, 10000000, 0, LONG_TIMEOUT * 1000000, 0, 1, 0},
++ {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
++ "Don't log queries which examine less than min_examined_row_limit rows to file.",
++ (gptr*) &global_system_variables.min_examined_row_limit,
++ (gptr*) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0},
+ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
+ "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system",
+ (gptr*) &lower_case_table_names,
+@@ -6639,7 +6667,9 @@
+ global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
+ max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
+ global_system_variables.old_passwords= 0;
+-
++ global_system_variables.log_slow_verbosity= SLOG_V_MICROTIME;
++ global_system_variables.log_slow_filter= SLOG_F_NONE;
++
+ /*
+ Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
+ when collecting index statistics for MyISAM tables.
+@@ -7100,6 +7130,24 @@
+ case OPT_BOOTSTRAP:
+ opt_noacl=opt_bootstrap=1;
+ break;
++ case OPT_LOG_SLOW_FILTER:
++ if ((global_system_variables.log_slow_filter=
++ msl_flag_resolve_by_name(slog_filter, argument,
++ SLOG_F_NONE, SLOG_F_INVALID)) == SLOG_F_INVALID)
++ {
++ fprintf(stderr,"Invalid argument to log_slow_filter\n");
++ exit(1);
++ }
++ break;
++ case OPT_LOG_SLOW_VERBOSITY:
++ if ((global_system_variables.log_slow_verbosity=
++ msl_flag_resolve_by_name(slog_verb, argument,
++ SLOG_V_NONE, SLOG_V_INVALID)) == SLOG_V_INVALID)
++ {
++ fprintf(stderr,"Invalid argument to log_slow_verbosity\n");
++ exit(1);
++ }
++ break;
+ case OPT_STORAGE_ENGINE:
+ {
+ if ((enum db_type)((global_system_variables.table_type=
+@@ -7422,10 +7470,14 @@
+ if (opt_bdb)
+ sql_print_warning("this binary does not contain BDB storage engine");
+ #endif
+- if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) &&
++ if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
++ opt_log_slow_slave_statements) &&
+ !opt_slow_log)
+- sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
+-
++ {
++ sql_print_warning("options --log-slow-admin-statements, --log-slow-slave-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
++ opt_log_slow_slave_statements= FALSE;
++ }
++
+ if (argc > 0)
+ {
+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv);
+diff -r 1cae91646da0 sql/set_var.cc
+--- a/sql/set_var.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/set_var.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -211,7 +211,7 @@
+ sys_log_queries_not_using_indexes("log_queries_not_using_indexes",
+ &opt_log_queries_not_using_indexes);
+ sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
+-sys_var_thd_ulong sys_long_query_time("long_query_time",
++sys_var_thd_ulonglong sys_long_query_time("long_query_time",
+ &SV::long_query_time);
+ sys_var_thd_bool sys_low_priority_updates("low_priority_updates",
+ &SV::low_priority_updates,
+@@ -276,6 +276,8 @@
+ &SV::max_tmp_tables);
+ sys_var_long_ptr sys_max_write_lock_count("max_write_lock_count",
+ &max_write_lock_count);
++sys_var_thd_ulong sys_min_examined_row_limit("min_examined_row_limit",
++ &SV::min_examined_row_limit);
+ sys_var_thd_ulong sys_multi_range_count("multi_range_count",
+ &SV::multi_range_count);
+ sys_var_long_ptr sys_myisam_data_pointer_size("myisam_data_pointer_size",
+@@ -319,6 +321,20 @@
+ sys_var_bool_ptr sys_relay_log_purge("relay_log_purge",
+ &relay_log_purge);
+ #endif
++sys_var_thd_ulong sys_log_slow_rate_limit("log_slow_rate_limit",
++ &SV::log_slow_rate_limit);
++sys_var_thd_msl_flag sys_log_slow_filter("log_slow_filter",
++ &SV::log_slow_filter,
++ SLOG_F_NONE,
++ SLOG_F_NONE,
++ SLOG_F_INVALID,
++ slog_filter);
++sys_var_thd_msl_flag sys_log_slow_verbosity("log_slow_verbosity",
++ &SV::log_slow_verbosity,
++ SLOG_V_NONE,
++ SLOG_V_MICROTIME,
++ SLOG_V_INVALID,
++ slog_verb);
+ sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+ &rpl_recovery_rank);
+ sys_var_long_ptr sys_query_cache_size("query_cache_size",
+@@ -674,6 +690,9 @@
+ &sys_log_binlog,
+ &sys_log_off,
+ &sys_log_queries_not_using_indexes,
++ &sys_log_slow_filter,
++ &sys_log_slow_rate_limit,
++ &sys_log_slow_verbosity,
+ &sys_log_update,
+ &sys_log_warnings,
+ &sys_long_query_time,
+@@ -697,6 +716,7 @@
+ &sys_max_tmp_tables,
+ &sys_max_user_connections,
+ &sys_max_write_lock_count,
++ &sys_min_examined_row_limit,
+ &sys_multi_range_count,
+ &sys_myisam_data_pointer_size,
+ &sys_myisam_max_sort_file_size,
+@@ -966,6 +986,8 @@
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
+ #endif
+ {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
++ {sys_log_slow_filter.name, (char*) &sys_log_slow_filter, SHOW_SYS},
++ {sys_log_slow_verbosity.name, (char*) &sys_log_slow_verbosity, SHOW_SYS},
+ {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
+ {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS},
+ {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
+@@ -994,6 +1016,7 @@
+ {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
+ {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
+ {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
++ {sys_min_examined_row_limit.name, (char*) &sys_min_examined_row_limit, SHOW_SYS},
+ {sys_multi_range_count.name, (char*) &sys_multi_range_count, SHOW_SYS},
+ {sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS},
+ {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size,
+@@ -1050,6 +1073,7 @@
+ {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS},
+ {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size,
+ SHOW_SYS},
++ {sys_log_slow_rate_limit.name, (char*) &sys_log_slow_rate_limit, SHOW_SYS},
+ {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
+ {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
+ {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
+@@ -1587,6 +1611,53 @@
+ return (byte*) &(thd->variables.*offset);
+ }
+
++void sys_var_thd_microtime::set_default(THD *thd, enum_var_type type)
++{
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset= (ulonglong) option_limits->def_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++bool sys_var_thd_microtime::check(THD *thd, set_var *var)
++{
++ if (var->value->result_type() == DECIMAL_RESULT)
++ var->save_result.ulonglong_value= (ulonglong)(var->value->val_real() * 1000000);
++ else
++ var->save_result.ulonglong_value= (ulonglong)var->value->val_int() * 1000000;
++ return 0;
++}
++
++byte *sys_var_thd_microtime::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ return (byte*) &(global_system_variables.*offset);
++ return (byte*) &(thd->variables.*offset);
++}
++
++bool sys_var_thd_microtime::update(THD *thd, set_var *var)
++{
++ ulonglong tmp= var->save_result.ulonglong_value;
++
++ if (tmp > max_system_variables.*offset)
++ tmp= max_system_variables.*offset;
++
++ if (option_limits)
++ tmp= getopt_ull_limit_value(tmp, option_limits);
++
++ /* Lock is needed to make things safe on 32 bit systems */
++ if (var->type == OPT_GLOBAL)
++ {
++ /* Lock is needed to make things safe on 32 bit systems */
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset= tmp;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= (ulonglong) tmp;
++
++ return 0;
++}
+
+ bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
+ {
+@@ -3398,6 +3469,191 @@
+ #endif
+ }
+
++/* Slow log stuff */
++
++ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len)
++{
++ ulong i;
++
++ for (i=0; opts[i].name; i++)
++ {
++ if (!my_strnncoll(&my_charset_latin1,
++ (const uchar *)name, len,
++ (const uchar *)opts[i].name, strlen(opts[i].name)))
++ return opts[i].val;
++ }
++ return opts[i].val;
++}
++
++ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list,
++ const ulong none_val, const ulong invalid_val)
++{
++ const char *p, *e;
++ ulong val= none_val;
++
++ if (!*names_list)
++ return val;
++
++ for (p= e= names_list; ; e++)
++ {
++ ulong i;
++
++ if (*e != ',' && *e)
++ continue;
++ for (i=0; opts[i].name; i++)
++ {
++ if (!my_strnncoll(&my_charset_latin1,
++ (const uchar *)p, e - p,
++ (const uchar *)opts[i].name, strlen(opts[i].name)))
++ {
++ val= val | opts[i].val;
++ break;
++ }
++ }
++ if (opts[i].val == invalid_val)
++ return invalid_val;
++ if (!*e)
++ break;
++ p= e + 1;
++ }
++ return val;
++}
++
++const char *msl_option_get_name(const struct msl_opts *opts, ulong val)
++{
++ for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
++ {
++ if (opts[i].val == val)
++ return opts[i].name;
++ }
++ return "*INVALID*";
++}
++
++char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val)
++{
++ uint offset= 0;
++
++ *buf= '\0';
++ for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
++ {
++ if (opts[i].val & val)
++ offset+= snprintf(buf+offset, STRING_BUFFER_USUAL_SIZE - offset - 1,
++ "%s%s", (offset ? "," : ""), opts[i].name);
++ }
++ return buf;
++}
++
++/****************************************************************************
++ Functions to handle log_slow_verbosity
++****************************************************************************/
++
++/* Based upon sys_var::check_enum() */
++
++bool sys_var_thd_msl_option::check(THD *thd, set_var *var)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ ulong verb= this->invalid_val;
++ if (!(res=var->value->val_str(&str)) ||
++ (var->save_result.ulong_value=
++ (ulong) (verb= msl_option_resolve_by_name(this->opts, res->ptr(), res->length()))) == this->invalid_val)
++ goto err;
++ return 0;
++ }
++
++err:
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
++ return 1;
++}
++
++byte *sys_var_thd_msl_option::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ ulong val;
++ val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ const char *verbosity= msl_option_get_name(this->opts, val);
++ return (byte *) verbosity;
++}
++
++
++void sys_var_thd_msl_option::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) this->default_val;
++ else
++ thd->variables.*offset= (ulong) (global_system_variables.*offset);
++}
++
++
++bool sys_var_thd_msl_option::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.ulong_value;
++ else
++ thd->variables.*offset= var->save_result.ulong_value;
++ return 0;
++}
++
++/****************************************************************************
++ Functions to handle log_slow_filter
++****************************************************************************/
++
++/* Based upon sys_var::check_enum() */
++
++bool sys_var_thd_msl_flag::check(THD *thd, set_var *var)
++{
++ char buff[2 * STRING_BUFFER_USUAL_SIZE];
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ ulong filter= this->none_val;
++ if (!(res=var->value->val_str(&str)) ||
++ (var->save_result.ulong_value=
++ (ulong) (filter= msl_flag_resolve_by_name(this->flags, res->ptr(), this->none_val,
++ this->invalid_val))) == this->invalid_val)
++ goto err;
++ return 0;
++ }
++
++err:
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
++ return 1;
++}
++
++byte *sys_var_thd_msl_flag::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ ulong val;
++ val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ msl_flag_get_name(this->flags, this->flags_string, val);
++ return (byte *) this->flags_string;
++}
++
++
++void sys_var_thd_msl_flag::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) this->default_val;
++ else
++ thd->variables.*offset= (ulong) (global_system_variables.*offset);
++}
++
++
++bool sys_var_thd_msl_flag::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.ulong_value;
++ else
++ thd->variables.*offset= var->save_result.ulong_value;
++ return 0;
++}
++
+ /****************************************************************************
+ Functions to handle table_type
+ ****************************************************************************/
+diff -r 1cae91646da0 sql/set_var.h
+--- a/sql/set_var.h Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/set_var.h Mon Apr 07 14:28:43 2008 +0200
+@@ -123,6 +123,7 @@
+ };
+
+
++
+ class sys_var_ulonglong_ptr :public sys_var
+ {
+ public:
+@@ -287,7 +288,6 @@
+ }
+ };
+
+-
+ class sys_var_thd_ulong :public sys_var_thd
+ {
+ sys_check_func check_func;
+@@ -307,6 +307,23 @@
+ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ };
+
++class sys_var_thd_microtime :public sys_var_thd
++{
++public:
++ ulonglong SV::*offset;
++ sys_var_thd_microtime(const char *name_arg, ulonglong SV::*offset_arg)
++ :sys_var_thd(name_arg), offset(offset_arg)
++ {}
++ bool update(THD *thd, set_var *var);
++ void set_default(THD *thd, enum_var_type type);
++ SHOW_TYPE type() { return SHOW_MICROTIME; }
++ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
++ bool check(THD *thd, set_var *var);
++ bool check_update_type(Item_result type)
++ {
++ return type != INT_RESULT && type != DECIMAL_RESULT;
++ }
++};
+
+ class sys_var_thd_ha_rows :public sys_var_thd
+ {
+@@ -324,7 +341,6 @@
+ SHOW_TYPE show_type() { return SHOW_HA_ROWS; }
+ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ };
+-
+
+ class sys_var_thd_ulonglong :public sys_var_thd
+ {
+@@ -353,7 +369,6 @@
+ }
+ };
+
+-
+ class sys_var_thd_bool :public sys_var_thd
+ {
+ public:
+@@ -423,6 +438,66 @@
+ ulong *length);
+ };
+
++
++class sys_var_thd_msl_option :public sys_var_thd
++{
++protected:
++ ulong SV::*offset;
++ const ulong none_val;
++ const ulong default_val;
++ const ulong invalid_val;
++ const struct msl_opts *opts;
++public:
++ sys_var_thd_msl_option(const char *name_arg, ulong SV::*offset_arg,
++ const ulong none_val_arg,
++ const ulong default_val_arg,
++ const ulong invalid_val_arg,
++ const struct msl_opts *opts_arg)
++ :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
++ default_val(default_val_arg), invalid_val(invalid_val_arg),
++ opts(opts_arg)
++ {}
++ bool check(THD *thd, set_var *var);
++ SHOW_TYPE show_type() { return SHOW_CHAR; }
++ bool check_update_type(Item_result type)
++ {
++ return type != STRING_RESULT; /* Only accept strings */
++ }
++ void set_default(THD *thd, enum_var_type type);
++ bool update(THD *thd, set_var *var);
++ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
++};
++
++
++class sys_var_thd_msl_flag :public sys_var_thd
++{
++protected:
++ char flags_string[2 * STRING_BUFFER_USUAL_SIZE];
++ ulong SV::*offset;
++ const ulong none_val;
++ const ulong default_val;
++ const ulong invalid_val;
++ const struct msl_opts *flags;
++public:
++ sys_var_thd_msl_flag(const char *name_arg, ulong SV::*offset_arg,
++ const ulong none_val_arg,
++ const ulong default_val_arg,
++ const ulong invalid_val_arg,
++ const struct msl_opts *flags_arg)
++ :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
++ default_val(default_val_arg), invalid_val(invalid_val_arg),
++ flags(flags_arg)
++ {}
++ bool check(THD *thd, set_var *var);
++ SHOW_TYPE show_type() { return SHOW_CHAR; }
++ bool check_update_type(Item_result type)
++ {
++ return type != STRING_RESULT; /* Only accept strings */
++ }
++ void set_default(THD *thd, enum_var_type type);
++ bool update(THD *thd, set_var *var);
++ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
++};
+
+ class sys_var_thd_storage_engine :public sys_var_thd
+ {
+@@ -1018,3 +1093,11 @@
+ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *));
+ void delete_elements(I_List<NAMED_LIST> *list,
+ void (*free_element)(const char*, gptr));
++
++/* Slow log functions */
++
++ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len);
++ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list,
++ const ulong none_val, const ulong invalid_val);
++const char *msl_option_get_name(const struct msl_opts *opts, ulong val);
++char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val);
+diff -r 1cae91646da0 sql/slave.cc
+--- a/sql/slave.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/slave.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -2908,6 +2908,12 @@
+ + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
+ thd->slave_thread = 1;
+ set_slave_thread_options(thd);
++ if (opt_log_slow_slave_statements)
++ {
++ thd->enable_slow_log= TRUE;
++ /* Slave thread is excluded from rate limiting the slow log writes. */
++ thd->write_to_slow_log= TRUE;
++ }
+ thd->client_capabilities = CLIENT_LOCAL_FILES;
+ thd->real_id=pthread_self();
+ pthread_mutex_lock(&LOCK_thread_count);
+diff -r 1cae91646da0 sql/sql_cache.cc
+--- a/sql/sql_cache.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_cache.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -1341,6 +1341,7 @@
+
+ thd->limit_found_rows = query->found_rows();
+ thd->status_var.last_query_cost= 0.0;
++ thd->query_plan_flags|= QPLAN_QC;
+
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(1); // Result sent to client
+@@ -1348,6 +1349,7 @@
+ err_unlock:
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ err:
++ thd->query_plan_flags|= QPLAN_QC_NO;
+ DBUG_RETURN(0); // Query was not cached
+ }
+
+diff -r 1cae91646da0 sql/sql_class.cc
+--- a/sql/sql_class.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_class.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -174,7 +174,7 @@
+ lock_id(&main_lock_id),
+ user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0),
+ transaction_rollback_request(0), is_fatal_sub_stmt_error(0),
+- rand_used(0), time_zone_used(0),
++ rand_used(0), time_zone_used(0), user_timer(0),
+ last_insert_id_used(0), last_insert_id_used_bin_log(0), insert_id_used(0),
+ clear_next_insert_id(0), in_lock_tables(0), bootstrap(0),
+ derived_tables_processing(FALSE), spcont(NULL), m_lip(NULL)
+@@ -2163,6 +2163,12 @@
+ backup->cuted_fields= cuted_fields;
+ backup->client_capabilities= client_capabilities;
+ backup->savepoints= transaction.savepoints;
++ backup->innodb_io_reads= innodb_io_reads;
++ backup->innodb_io_read= innodb_io_read;
++ backup->innodb_io_reads_wait_timer= innodb_io_reads_wait_timer;
++ backup->innodb_lock_que_wait_timer= innodb_lock_que_wait_timer;
++ backup->innodb_innodb_que_wait_timer= innodb_innodb_que_wait_timer;
++ backup->innodb_page_access= innodb_page_access;
+
+ if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
+ options&= ~OPTION_BIN_LOG;
+@@ -2179,7 +2185,13 @@
+ sent_row_count= 0;
+ cuted_fields= 0;
+ transaction.savepoints= 0;
+-
++ innodb_io_reads= 0;
++ innodb_io_read= 0;
++ innodb_io_reads_wait_timer= 0;
++ innodb_lock_que_wait_timer= 0;
++ innodb_innodb_que_wait_timer= 0;
++ innodb_page_access= 0;
++
+ /* Surpress OK packets in case if we will execute statements */
+ net.no_send_ok= TRUE;
+ }
+@@ -2232,6 +2244,12 @@
+ */
+ examined_row_count+= backup->examined_row_count;
+ cuted_fields+= backup->cuted_fields;
++ innodb_io_reads+= backup->innodb_io_reads;
++ innodb_io_read+= backup->innodb_io_read;
++ innodb_io_reads_wait_timer+= backup->innodb_io_reads_wait_timer;
++ innodb_lock_que_wait_timer+= backup->innodb_lock_que_wait_timer;
++ innodb_innodb_que_wait_timer+= backup->innodb_innodb_que_wait_timer;
++ innodb_page_access+= backup->innodb_page_access;
+ }
+
+
+diff -r 1cae91646da0 sql/sql_class.h
+--- a/sql/sql_class.h Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_class.h Mon Apr 07 14:28:43 2008 +0200
+@@ -43,6 +43,13 @@
+ extern char internal_table_name[2];
+ extern char empty_c_string[1];
+ extern const char **errmesg;
++#ifdef __cplusplus
++__BEGIN_DECLS
++#endif
++extern ulonglong frequency;
++#ifdef __cplusplus
++__END_DECLS
++#endif
+
+ #define TC_LOG_PAGE_SIZE 8192
+ #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
+@@ -308,7 +315,7 @@
+ bool write(THD *thd, enum enum_server_command command,
+ const char *format, ...) ATTRIBUTE_FORMAT(printf, 4, 5);
+ bool write(THD *thd, const char *query, uint query_length,
+- time_t query_start=0);
++ time_t query_start=0, ulonglong query_start_timer=0);
+ bool write(Log_event* event_info); // binary log write
+ bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
+
+@@ -514,13 +521,14 @@
+ ulong auto_increment_increment, auto_increment_offset;
+ ulong bulk_insert_buff_size;
+ ulong join_buff_size;
+- ulong long_query_time;
++ ulonglong long_query_time;
+ ulong max_allowed_packet;
+ ulong max_error_count;
+ ulong max_length_for_sort_data;
+ ulong max_sort_length;
+ ulong max_tmp_tables;
+ ulong max_insert_delayed_threads;
++ ulong min_examined_row_limit;
+ ulong multi_range_count;
+ ulong myisam_repair_threads;
+ ulong myisam_sort_buff_size;
+@@ -536,10 +544,13 @@
+ ulong preload_buff_size;
+ ulong profiling_history_size;
+ ulong query_cache_type;
++ ulong log_slow_rate_limit;
+ ulong read_buff_size;
+ ulong read_rnd_buff_size;
+ ulong div_precincrement;
+ ulong sortbuff_size;
++ ulong log_slow_filter;
++ ulong log_slow_verbosity;
+ ulong table_type;
+ ulong tx_isolation;
+ ulong completion_type;
+@@ -1106,6 +1117,12 @@
+ uint in_sub_stmt;
+ bool enable_slow_log, insert_id_used, clear_next_insert_id;
+ bool last_insert_id_used;
++ ulong innodb_io_reads;
++ ulonglong innodb_io_read;
++ ulong innodb_io_reads_wait_timer;
++ ulong innodb_lock_que_wait_timer;
++ ulong innodb_innodb_que_wait_timer;
++ ulong innodb_page_access;
+ my_bool no_send_ok;
+ SAVEPOINT *savepoints;
+ };
+@@ -1162,6 +1179,11 @@
+ class THD :public Statement,
+ public Open_tables_state
+ {
++private:
++ inline ulonglong query_start_timer() { return start_timer; }
++ inline void set_timer() { if (user_timer) start_timer=timer_after_lock=user_timer; else timer_after_lock=my_timer(&start_timer, frequency); }
++ inline void end_timer() { my_timer(&start_timer, frequency); }
++ inline void lock_timer() { my_timer(&timer_after_lock, frequency); }
+ public:
+ /*
+ Constant for THD::where initialization in the beginning of every query.
+@@ -1270,10 +1292,24 @@
+ */
+ const char *where;
+ time_t start_time,time_after_lock,user_time;
++ ulonglong start_timer,timer_after_lock, user_timer;
+ time_t connect_time,thr_create_time; // track down slow pthread_create
+ thr_lock_type update_lock_default;
+ Delayed_insert *di;
+
++ bool write_to_slow_log;
++
++ bool innodb_was_used;
++ ulong innodb_io_reads;
++ ulonglong innodb_io_read;
++ ulong innodb_io_reads_wait_timer;
++ ulong innodb_lock_que_wait_timer;
++ ulong innodb_innodb_que_wait_timer;
++ ulong innodb_page_access;
++
++ ulong query_plan_flags;
++ ulong query_plan_fsort_passes;
++
+ /* <> 0 if we are inside of trigger or stored function. */
+ uint in_sub_stmt;
+
+@@ -1650,11 +1686,11 @@
+ sql_print_information("time() failed with %d", errno);
+ }
+
+- inline time_t query_start() { query_start_used=1; return start_time; }
+- inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }}
+- inline void end_time() { safe_time(&start_time); }
+- inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; }
+- inline void lock_time() { safe_time(&time_after_lock); }
++ inline time_t query_start() { query_start_timer(); query_start_used=1; return start_time; }
++ inline void set_time() { set_timer(); if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }}
++ inline void end_time() { end_timer(); safe_time(&start_time); }
++ inline void set_time(time_t t) { set_timer(); time_after_lock=start_time=user_time=t; }
++ inline void lock_time() { lock_timer(); safe_time(&time_after_lock); }
+ inline void insert_id(ulonglong id_arg)
+ {
+ last_insert_id= id_arg;
+diff -r 1cae91646da0 sql/sql_parse.cc
+--- a/sql/sql_parse.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_parse.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -20,6 +20,7 @@
+ #include <m_ctype.h>
+ #include <myisam.h>
+ #include <my_dir.h>
++#include <my_time.h>
+
+ #ifdef HAVE_INNOBASE_DB
+ #include "ha_innodb.h"
+@@ -1190,6 +1191,15 @@
+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
+ my_net_set_write_timeout(net, thd->variables.net_write_timeout);
+
++ /*
++ If rate limiting of slow log writes is enabled, decide whether to log this
++ new thread's queries or not. Uses extremely simple algorithm. :)
++ */
++ thd->write_to_slow_log= FALSE;
++ if (thd->variables.log_slow_rate_limit <= 1 ||
++ (thd->thread_id % thd->variables.log_slow_rate_limit) == 0)
++ thd->write_to_slow_log= TRUE;
++
+ while (!net->error && net->vio != 0 &&
+ !(thd->killed == THD::KILL_CONNECTION))
+ {
+@@ -2193,27 +2203,53 @@
+ return; // Don't set time for sub stmt
+
+ start_of_query= thd->start_time;
++ ulonglong start_of_query_timer= thd->start_timer;
+ thd->end_time(); // Set start time
++
++
++ /* Follow the slow log filter configuration. */
++ if (thd->variables.log_slow_filter != SLOG_F_NONE &&
++ (!(thd->variables.log_slow_filter & thd->query_plan_flags) ||
++ ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&
++ (thd->query_plan_flags & QPLAN_QC))))
++ return;
++
++ /*
++ Low long_query_time value most likely means user is debugging stuff and even
++ though some thread's queries are not supposed to be logged b/c of the rate
++ limit, if one of them takes long enough (>= 1 second) it will be sensible
++ to make an exception and write to slow log anyway.
++ */
++ if (thd->write_to_slow_log != TRUE && thd->variables.long_query_time < 1000000 &&
++ (ulong) (thd->start_timer - thd->timer_after_lock) >= 1000000)
++ thd->write_to_slow_log= TRUE;
++
++ /* Do not log this thread's queries due to rate limiting. */
++ if (thd->write_to_slow_log != TRUE)
++ return;
+
+ /*
+ Do not log administrative statements unless the appropriate option is
+ set; do not log into slow log if reading from backup.
+ */
+- if (thd->enable_slow_log && !thd->user_time)
++ if (thd->enable_slow_log &&
++ (!thd->user_time || (thd->slave_thread && opt_log_slow_slave_statements))
++ )
+ {
+ thd_proc_info(thd, "logging slow query");
+
+- if ((ulong) (thd->start_time - thd->time_after_lock) >
+- thd->variables.long_query_time ||
+- (thd->server_status &
+- (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
+- opt_log_queries_not_using_indexes &&
+- /* == SQLCOM_END unless this is a SHOW command */
+- thd->lex->orig_sql_command == SQLCOM_END)
++ if (((ulong) (thd->start_timer - thd->timer_after_lock) >=
++ thd->variables.long_query_time ||
++ (thd->server_status &
++ (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
++ opt_log_queries_not_using_indexes &&
++ /* == SQLCOM_END unless this is a SHOW command */
++ thd->lex->orig_sql_command == SQLCOM_END) &&
++ thd->examined_row_count >= thd->variables.min_examined_row_limit)
+ {
+ thd_proc_info(thd, "logging slow query");
+ thd->status_var.long_query_count++;
+- mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
++ mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query, start_of_query_timer);
+ }
+ }
+ }
+@@ -5887,6 +5923,16 @@
+ thd->total_warn_count=0; // Warnings for this query
+ thd->rand_used= 0;
+ thd->sent_row_count= thd->examined_row_count= 0;
++ thd->innodb_was_used= FALSE;
++ thd->innodb_io_reads= 0;
++ thd->innodb_io_read= 0;
++ thd->innodb_io_reads_wait_timer= 0;
++ thd->innodb_lock_que_wait_timer= 0;
++ thd->innodb_innodb_que_wait_timer= 0;
++ thd->innodb_page_access= 0;
++ thd->query_plan_flags= QPLAN_NONE;
++ thd->query_plan_fsort_passes= 0;
++
+ #ifdef ENABLED_PROFILING
+ thd->profiling.reset();
+ #endif
+diff -r 1cae91646da0 sql/sql_select.cc
+--- a/sql/sql_select.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_select.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -6203,8 +6203,11 @@
+ {
+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
+ if (statistics)
++ {
+ statistic_increment(join->thd->status_var.select_scan_count,
+ &LOCK_status);
++ join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
++ }
+ }
+ }
+ else
+@@ -6219,8 +6222,11 @@
+ {
+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
+ if (statistics)
++ {
+ statistic_increment(join->thd->status_var.select_full_join_count,
+ &LOCK_status);
++ join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
++ }
+ }
+ }
+ if (!table->no_keyread)
+@@ -9228,6 +9234,7 @@
+ (ulong) rows_limit,test(group)));
+
+ statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
++ thd->query_plan_flags|= QPLAN_TMP_TABLE;
+
+ if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
+ temp_pool_slot = bitmap_set_next(&temp_pool);
+@@ -10088,6 +10095,7 @@
+ }
+ statistic_increment(table->in_use->status_var.created_tmp_disk_tables,
+ &LOCK_status);
++ table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
+ table->s->db_record_offset= 1;
+ DBUG_RETURN(0);
+ err:
+diff -r 1cae91646da0 sql/sql_show.cc
+--- a/sql/sql_show.cc Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/sql_show.cc Mon Apr 07 14:28:43 2008 +0200
+@@ -1488,6 +1488,9 @@
+ value= ((char *) status_var + (ulonglong) value);
+ case SHOW_LONGLONG:
+ end= longlong10_to_str(*(longlong*) value, buff, 10);
++ break;
++ case SHOW_MICROTIME:
++ end= buff + sprintf(buff, "%.6f", (*(ulonglong*)value) / 1000000.0);
+ break;
+ case SHOW_HA_ROWS:
+ end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
+diff -r 1cae91646da0 sql/structs.h
+--- a/sql/structs.h Thu Mar 27 11:55:26 2008 +0100
++++ b/sql/structs.h Mon Apr 07 14:28:43 2008 +0200
+@@ -168,8 +168,8 @@
+ enum SHOW_TYPE
+ {
+ SHOW_UNDEF,
+- SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
+- SHOW_DOUBLE_STATUS,
++ SHOW_LONG, SHOW_LONGLONG, SHOW_MICROTIME, SHOW_INT, SHOW_CHAR,
++ SHOW_CHAR_PTR, SHOW_DOUBLE_STATUS,
+ SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION,
+ SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
+ SHOW_VARS,
More information about the Pkg-mysql-commits
mailing list