MySQL 용 Microsoft의 "SQL Server Profiler"와 같은 도구가 있습니까? [닫은]


43

MySQL에서 개발하는 동안 프로파일 러를 실행할 수 없었습니다. 내가 찾을 수 SQLyog에가 쿼리 분석기에 대한 충분한 대체하지만 도구를 발견하지 않은 SQL 프로파일 러처럼 작동합니다.

Microsoft의 SQL 프로파일 러를 보지 못한 MySQL 사용자의 경우 스크린 샷이 있습니다.

프로파일 러 SQL

이전 작업에서 우리는 SQL 프로파일 러 보다 우월한 도구를 사용 했으며 심지어 스택 추적을 제공했습니다.

알티리스 프로파일 러

누구든지 MySQL에서 작동하는 언급 한 도구와 같은 도구를 알고 있습니까?

(참고로 Altiris Profiler를 MySQL과 함께 사용할 수는 있지만 실제로 Symantec Sku가 아닌 Windows를 실행해야하므로 라이센스가 까다로워집니다)

답변:


17

MySQL은 쿼리 프로파일 링을 제안하지 않았습니다. MySQL이 Oracle에 의해 손 대어지고 있기 때문에 이것이 계속 될 것이라는 것을 알고 있습니다.

그러나 모든 희망이 사라지지는 않습니다.

2007 년부터 Percona는 Query Profiling을 포함하여 개발자와 DBA가 원하는 모든 것을위한 절대적으로 놀라운 도구를 개발했습니다.

MAATKIT로 알려진 Percona의 첫 번째 도구 세트 는 MySQL을 진지하게 사용하는 사용자를위한 영역을 만들었습니다. 다음 과 같은 많은 기능이 있습니다 .

  • 쿼리 프로파일 링
  • 복제 하트 비트
  • 복제 슬레이브 관리
  • 테이블 체크섬 및 동기화

Percona는 최근 MAATKIT를 오늘날 Percona Toolkit 으로 알려진 최신 도구 세트에 포함 시켰습니다 . 이 도구들은 심각한 MySQL 사용자의 활동 영역을 확장하여 MAATKIT가 중단 한 곳에서 찾아 냈습니다.

  • 외래 키 오류 확인
  • 온라인 스키마 변경
  • 시각적 설명 계획
  • 그리고 더 ...

원래 질문으로 돌아가서 쿼리 프로파일 링을위한 도구는 다음과 같습니다.

다음은 이러한 도구 중 하나를 사용하여 얻을 수있는 풍부한 정보의 예입니다.

클라이언트가 mk-query-digest를 구현하여 20 분마다 20 개의 최악의 쿼리를보고하도록 도와주었습니다. 이 YouTube 비디오에서 아이디어를 얻었습니다 . 클라이언트는 잘못된 쿼리의 출력을 memcached로 이동하여 쿼리가 데이터베이스에 영향을 미치는 빈도를 줄입니다.

다음은 mk-query-digest를 호출하기 위해 만든 스크립트입니다 (프로세스 목록 만 검사).

#!/bin/sh

RUNFILE=/tmp/QueriesAreBeingDigested.txt
if [ -f ${RUNFILE} ] ; then exit ; fi

MKDQ=/usr/local/sbin/mk-query-digest
RUNTIME=${1}
COPIES_TO_KEEP=${2}
DBVIP=${3}

WHICH=/usr/bin/which
DATE=`${WHICH} date`
ECHO=`${WHICH} echo`
HEAD=`${WHICH} head`
TAIL=`${WHICH} tail`
AWK=`${WHICH} awk`
SED=`${WHICH} sed`
CAT=`${WHICH} cat`
WC=`${WHICH} wc`
RM=`${WHICH} rm | ${TAIL} -1 | ${AWK} '{print $1}'`
LS=`${WHICH} ls | ${TAIL} -1 | ${AWK} '{print $1}'`

HAS_THE_DBVIP=`/sbin/ip addr show | grep "scope global secondary" | grep -c "${DBVIP}"`
if [ ${HAS_THE_DBVIP} -eq 1 ] ; then exit ; fi

DT=`${DATE} +"%Y%m%d_%H%M%S"`
UNIQUETAG=`${ECHO} ${SSH_CLIENT}_${SSH_CONNECTION}_${DT} | ${SED} 's/\./ /g' | ${SED} 's/ //g'`

cd /root/QueryDigest
OUTFILE=QP_${DT}.txt
HOSTADDR=${DBVIP}
${MKDQ} --processlist h=${HOSTADDR},u=queryprofiler,p=queryprofiler --run-time=${RUNTIME} > ${OUTFILE}

#
# Rotate out Old Copies
#

QPFILES=QPFiles.txt
QPFILES2ZAP=QPFiles2Zap.txt
${LS} QP_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9].txt > ${QPFILES}

LINECOUNT=`${WC} -l < ${QPFILES}`
if [ ${LINECOUNT} -gt ${COPIES_TO_KEEP} ]
then
        (( DIFF = LINECOUNT - COPIES_TO_KEEP ))
        ${HEAD} -${DIFF} < ${QPFILES} > ${QPFILES2ZAP}
        for QPFILETOZAP in `${CAT} ${QPFILES2ZAP}`
        do
                ${RM} ${QPFILETOZAP}
        done
fi

rm -f ${QPFILES2ZAP}
rm -f ${QPFILES}
rm -f ${RUNFILE}

mk-query-digest를 사용하여 mysql에 연결 한 사용자는 다음과 같습니다.

GRANT PROCESS ON *.* TO 'queryprofiler'@'%' IDENTIFIED BY 'queryprofiler';

다음은 마지막 144 개 사본 (프로파일 링 48 시간)을 유지하면서 20 분마다 (10 초 미만) 실행 한 crontab입니다.

*/20 * * * * /root/QueryDigest/ExecQueryDigest.sh 1190s 144 10.1.1.8

놀라운 부분 : mk-query-digest의 출력

다음은 1190 초 (20 분 10 초) 동안 2011-12-28 11:20:00에 실행 된 프로필입니다.

마지막 22 줄

# Rank Query ID           Response time    Calls   R/Call     Item
# ==== ================== ================ ======= ========== ====
#    1 0x5E994008E9543B29    40.3255 11.2%     101   0.399263 SELECT schedule_occurrence schedule_eventschedule schedule_event schedule_eventtype schedule_event schedule_eventtype schedule_occurrence.start
#    2 0x392F6DA628C7FEBD    33.9181  9.4%      17   1.995184 SELECT mt_entry mt_objecttag
#    3 0x6C6318E56E149036    26.4695  7.3%     102   0.259505 SELECT schedule_occurrence schedule_eventschedule schedule_event schedule_eventtype schedule_event schedule_eventtype schedule_occurrence.start
#    4 0x00F66961DAE6FFB2    25.5472  7.1%      55   0.464495 SELECT mt_entry mt_placement mt_category
#    5 0x99E13015BFF1E75E    22.3618  6.2%     199   0.112371 SELECT mt_entry mt_objecttag
#    6 0x84DD09F0FC444677    22.3516  6.2%      39   0.573118 SELECT mt_entry
#    7 0x440EBDBCEDB88725    21.1817  5.9%      36   0.588380 SELECT mt_entry
#    8 0x8D258C584B858811    17.2402  4.8%      37   0.465951 SELECT mt_entry mt_placement mt_category
#    9 0x4E2CB0F4CAFD1400    16.9768  4.7%      40   0.424419 SELECT mt_entry mt_placement mt_category
#   10 0x377E0D0898266FDD    16.6979  4.6%     150   0.111319 SELECT polls_pollquestion mt_category
#   11 0x3B9686D98BB8E054    16.2089  4.5%      32   0.506529 SELECT mt_entry mt_objecttag mt_tag
#   12 0x97F670B604A85608    15.6158  4.3%      34   0.459287 SELECT mt_entry mt_placement mt_category
#   13 0x3F5557DA231225EB    14.4309  4.0%      36   0.400859 SELECT mt_entry mt_placement mt_category
#   14 0x191D660A10738896    13.1220  3.6%      31   0.423290 SELECT mt_entry mt_placement mt_category
#   15 0xF88F7421DD88036D    12.1261  3.4%      61   0.198788 SELECT mt_entry mt_blog mt_objecttag mt_tag mt_author
#   16 0xA909BF76E7051792    10.3971  2.9%      53   0.196172 SELECT mt_entry mt_objecttag mt_tag
#   17 0x3D42D07A335ED983     9.1424  2.5%      20   0.457121 SELECT mt_entry mt_placement mt_category
#   18 0x59F43B57DD43F2BD     9.0533  2.5%      21   0.431111 SELECT mt_entry mt_placement mt_category
#   19 0x7961BD4C76277EB7     8.5564  2.4%      47   0.182052 INSERT UNION UPDATE UNION mt_session
#   20 0x173EB4903F3B6DAC     8.5394  2.4%      22   0.388153 SELECT mt_entry mt_placement mt_category

쿼리 응답 시간을 기반으로 한 20 개의 최악의 쿼리 목록을 쿼리를 호출 한 횟수로 나눈 것에 주목하십시오.

쿼리 ID # 1 0x5E994008E9543B29을 보면 출력 파일에서 해당 쿼리 ID를 찾고 다음은 해당 특정 쿼리에 대한 보고서입니다.

# Query 1: 0.09 QPS, 0.03x concurrency, ID 0x5E994008E9543B29 at byte 0 __
# This item is included in the report because it matches --limit.
#              pct   total     min     max     avg     95%  stddev  median
# Count          4     101
# Exec time      7     40s   303ms      1s   399ms   992ms   198ms   293ms
# Lock time      0       0       0       0       0       0       0       0
# Users                  1      mt
# Hosts                101 10.64.95.73:33750 (1), 10.64.95.73:34452 (1), 10.64.95.73:38440 (1)... 97 more
# Databases              1     mt1
# Time range 1325089201 to 1325090385
# bytes          0 273.60k   2.71k   2.71k   2.71k   2.62k       0   2.62k
# id             4 765.11M   7.57M   7.58M   7.58M   7.29M    0.12   7.29M
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms  ################################################################
#    1s  ######
#  10s+
# Tables
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_occurrence'\G
#    SHOW CREATE TABLE `mt1`.`schedule_occurrence`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_eventschedule'\G
#    SHOW CREATE TABLE `mt1`.`schedule_eventschedule`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_event'\G
#    SHOW CREATE TABLE `mt1`.`schedule_event`\G
#    SHOW TABLE STATUS FROM `mt1` LIKE 'schedule_eventtype'\G
#    SHOW CREATE TABLE `mt1`.`schedule_eventtype`\G
#    SHOW TABLE STATUS FROM `schedule_occurrence` LIKE 'start'\G
#    SHOW CREATE TABLE `schedule_occurrence`.`start`\G
# EXPLAIN
SELECT `schedule_occurrence`.`id`, `schedule_occurrence`.`schedule_id`, `schedule_occurrence`.`event_id`, `schedule_occurrence`.`start`, `schedule_occurrence`.`end`, `schedule_occurrence`.`cancelled`, `schedule_occurrence`.`original_start`, `schedule_occurrence`.`original_end`, `schedule_occurrence`.`all_day`, `schedule_occurrence`.`ongoing`, `schedule_occurrence`.`featured`, `schedule_eventschedule`.`id`, `schedule_eventschedule`.`event_id`, `schedule_eventschedule`.`start`, `schedule_eventschedule`.`end`, `schedule_eventschedule`.`all_day`, `schedule_eventschedule`.`ongoing`, `schedule_eventschedule`.`min_date_calculated`, `schedule_eventschedule`.`max_date_calculated`, `schedule_eventschedule`.`rule`, `schedule_eventschedule`.`end_recurring_period`, `schedule_eventschedule`.`textual_description`, `schedule_event`.`id`, `schedule_event`.`title`, `schedule_event`.`slug`, `schedule_event`.`description`, `schedule_event`.`host_id`, `schedule_event`.`cost`, `schedule_event`.`age_restrictions`, `schedule_event`.`more_info`, `schedule_event`.`photo_id`, `schedule_event`.`contact_email`, `schedule_event`.`event_type_id`, `schedule_event`.`featured`, `schedule_event`.`staff_pick`, `schedule_event`.`futuremost`, `schedule_event`.`creator_id`, `schedule_event`.`created_on`, `schedule_event`.`allow_comments`, `schedule_event`.`mt_entry`, `schedule_eventtype`.`id`, `schedule_eventtype`.`parent_id`, `schedule_eventtype`.`name`, `schedule_eventtype`.`slug`, `schedule_eventtype`.`lft`, `schedule_eventtype`.`rght`, `schedule_eventtype`.`tree_id`, `schedule_eventtype`.`level`, T5.`id`, T5.`title`, T5.`slug`, T5.`description`, T5.`host_id`, T5.`cost`, T5.`age_restrictions`, T5.`more_info`, T5.`photo_id`, T5.`contact_email`, T5.`event_type_id`, T5.`featured`, T5.`staff_pick`, T5.`futuremost`, T5.`creator_id`, T5.`created_on`, T5.`allow_comments`, T5.`mt_entry`, T6.`id`, T6.`parent_id`, T6.`name`, T6.`slug`, T6.`lft`, T6.`rght`, T6.`tree_id`, T6.`level` FROM `schedule_occurrence` INNER JOIN `schedule_eventschedule` ON (`schedule_occurrence`.`schedule_id` = `schedule_eventschedule`.`id`) INNER JOIN `schedule_event` ON (`schedule_eventschedule`.`event_id` = `schedule_event`.`id`) INNER JOIN `schedule_eventtype` ON (`schedule_event`.`event_type_id` = `schedule_eventtype`.`id`) INNER JOIN `schedule_event` T5 ON (`schedule_occurrence`.`event_id` = T5.`id`) INNER JOIN `schedule_eventtype` T6 ON (T5.`event_type_id` = T6.`id`) WHERE (EXTRACT(MONTH FROM `schedule_occurrence`.`start`) = 8 AND EXTRACT(DAY FROM `schedule_occurrence`.`start`) = 6 AND `schedule_occurrence`.`start` BETWEEN '2011-01-01 00:00:00' and '2011-12-31 23:59:59.99') ORDER BY `schedule_occurrence`.`ongoing` ASC, `schedule_occurrence`.`all_day` DESC, `schedule_occurrence`.`start` ASC\G

히스토그램은 텍스트를 기반으로하지만 쿼리의 전체 성능을 1 초에 걸쳐 실행하며 대부분 0.01 ~ 0.1 초 사이의 정확한 그림을 제공합니다. 여기에서 쿼리를 리팩터링하고 쿼리 결과를 memcached에 배치하거나 누락되거나 포함 된 인덱스 추가 등을 수행하여 성능 조정을 진행할 수 있습니다.

결론

IMHO Percona가 프로파일 러 도구를 Windows GUI에 배치 한 경우 Microsoft의 SQL Server 프로파일 러와 쉽게 경쟁 할 수 있습니다.

국방 달려라 !!!


IMHO JetProfiler는 Percona Tools가 그래픽으로 결합한 것과 같습니다. 각각 뉘앙스가 있습니다. Linux 사용자와 명령 줄 사용자는 Percona Tools 또는 MAATKIT에 만족할 것입니다. JetProfiler를 사용하면 DB 심도를 높이고 MONyog의 Windows 그래픽 이점을 마음대로 사용할 수 있습니다.
RolandoMySQLDBA


5

아니요, 그러한 도구는 없습니다.


동의했다. 나는 대부분의 MySQL 개발자 / 관리자가 Microsoft SQL Server에 많은 시간을 소비하지 않았으며 MS 스택이 개발에 얼마나 놀라운 지 알지 못했습니다. 내가 본 모든 MySQL 쿼리 도구는 폴링에 의존하지만 SQL Server를 사용하면 데이터베이스에서 발생하는 거의 모든 것을 실시간으로 볼 수 있습니다. MySQL은 단순히 그것을 지원하지 않기 때문에 SQL Server 프로파일 러의 세부 사항에 가까운 것은 없습니다.
Parleer

4

GUI MySQL 도구 와 결합 된 MySQL Query Profiler 는 아마도 SQL Server Profiler 도구에 접근 할 수있는 수준에 가깝습니다.


2
흠, 거기에 GUI가 없습니다 ...
Sam Saffron

더 나쁜 것은 여전히 ​​실제 트래픽 기록을 보여주지는 않습니다. 와우, 마이크로 소프트는 이것에 대해 양말을 날려 버린다!

4

내가 찾은 최고의 아웃 - 오브 - 박스 솔루션은 느린 쿼리 로그의 조합을 (프로파일 러에 비해 짜증)를 사용하고, 단지 어떤 (포트 3306에 Wireshark를 실행 정말 '프로파일 러에 비해 짜증 및 원 연결을 암호화하는 경우 작동하지 않습니다).

SHOW FULL PROCESSLIST도 있습니다. 이는 sys.dm_exec_sessions와 sys.dm_exec_requests (작은 sys.dm_exec_sql_text가 포함 된)의 축소 조합과 같습니다.


4

MySQL에있는 모든 데이터베이스가 아니라 단일 응용 프로그램을 프로파일 링해야하는 경우 Neor Profile SQL이 유용합니다.




당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.