一.开启Debug日志
MySQL提供了trace机制方便定位
1.cmake时要开启编译选项-DWITH_DEBUG=1 -DCMAKE_BUILD_TYPE=Debug这两个参数
2.设置trace日志的路径,export MYSQL_DEBUG=d:t:O,/tmp/client.trace。如果不配置,默认保存在tmp/mysql.trace
3.mysql启动的时候,需要增加--debug参数,如:bin/mysqld --defaults-file=../etc/my_8130.cnf --debug
4.由于是处于调试模式,建议一个链接一个线程,即修改配置文件,配置:thread_handling = 0
5.开启trace日志后,可以利用 DBUG_PRINT("info", ("get_first_used_partition:%d",part_id)); 宏来调试输出
二、GDB调试
core文件调试
bt获取到调用堆栈后
f 数字:进入对于的函数堆栈
p 变量:变量如果是指针需要带*,对于this指针,p *this会打印出变量的结构体
打印变量格式化:set print pretty on
attach调试
1.attach pid
2.设置断点,基于原函数 比如:b Item_func_murmurHashCodeAndMod::val_int
3.继续向下执行 c
4.触发断点后,执行bt
5.需要向下单步调试s(或者c直接向下执行)
6.清除所有断点:
先查看所有断点:info break
删除单个断点:delete 1 删除#1断点
删除所有断点:delete break
三.MySQL测试用例集
首先cmake的时候需要增加参数 -DINSTALL_MYSQLTESTDIR=${路径}
这个路径一般都放在和bin目录平级的目录,再cmake install说的时候自动安装拷贝到该目录
./mtr 执行所有的测试用例集
./mtr --suite="tdsql_hide_partitions" 执行suite目录下tdsql_hide_partitions目录下所有的测试集
./mtr --do-test="binlog_xa_prepared_disconnect" 执行t/目录下对于的test文件,如mysql-test/t/binlog_xa_prepared_disconnect.test
./mtr --mysqld="--lock_wait_timeout=100" 指定超时参数
注意:
1.mtr执行的时候可能会遇到result文件和实际执行结果是一样的,但是由于wiondws和unix下的换行编码问题,导致md5不一样,需要对windows下的result文件中的回车做转码处理:sed -i 's/\r//' 文件
2.mtr会在mysql-test/var/log下创建一个msyql临时实例用来测试
q其他参数:
nowarnings:mysql-test执行的时候遇到mysql错误日志中的warnings也会自动停止,所以我们一般要带上--nowarnings参数;
big-test:某些被标记为”big“的测试用例默认是不执行的,所以我们一般也带上参数--big-test;
force:一般情况下,一旦有测试用例失败mtr会自动退出,所以我们一般加上--force参数,发生错误后强制继续向下执行;
mysqld:指定mysqld启动的默认参数: --mysqld="--innodb_buffer_pool_size=3355648"
其他:--max-test-fail=1000 --retry-failure=0 --suite-timeout=600 --retry-failure=1 --testcase-timeout=10这几个参数顾名思义,是增加超时、容错以及重试的,建议也加上。
./mtr --parallel=8 --force --max-test-fail=1000 --retry-failure=0 --suite-timeout=600 --retry-failure=1 --testcase-timeout=10 --big-test --nowarnings --mysqld="--innodb_buffer_pool_size=3355648" --suite="binlog"
./mtr --parallel=8 --force --max-test-fail=1000 --retry-failure=0 --suite-timeout=600 --retry-failure=1 --testcase-timeout=10 --big-test --nowarnings --mysqld="--innodb_buffer_pool_size=3355648" --do-test="binlog_xa_prepared_disconnect"
对于跑失败的用例,分析其输出和r/*.result文件的内容对比,定位失败的原因。
参考资料:
https://www.jianshu.com/p/a2b4ccd14626
https://blog.csdn.net/yunqishequ1/article/details/51882952
https://www.iteye.com/blog/dinglin-804798
四.GDB调试&&官方PATCH定位
一般core问题都会有一个调用堆栈
#0 0x00007f57ac4158ac in pthread_kill () from /lib64/libpthread.so.0
#1 0x000000000078a23b in handle_fatal_signal (sig=11) at /data/home/jenkins/jobs/526/workspace/dev/mariadb-10.1.9/sql/signal_handler.cc:273
#2 <signal handler called>
#3 0x000000000060178c in part_of_refkey (root_cond=<value optimized out>, left_item=<value optimized out>, right_item=0x7f5645107a68)
at /data/home/jenkins/jobs/526/workspace/dev/mariadb-10.1.9/sql/sql_select.cc:20375
#4 test_if_ref (root_cond=<value optimized out>, left_item=<value optimized out>, right_item=0x7f5645107a68)
at /data/home/jenkins/jobs/526/workspace/dev/mariadb-10.1.9/sql/sql_select.cc:20003
一般找到最后一个调用堆栈的函数,搜索比如mysql bug part_of_refkey,或者mariadb bug part_of_refkey,通过google可以找到

找到bug之后,继续寻找patch

这里点开就是github上关于patch的说明,点开链接后查看内容

将url的末尾追加.patch,就是可以直接下载的patch

如果合并patch时报错,观察一下如果是mysqltest问题则可以忽略,如果代码问题则需要看懂patch手动合并。
五.git多个commit合并为一个
内核开发的时候经常会发现第一次commit之后,又发现bug结果多了一次commit,导致别人代码review时非常费劲
因而需要多个commit合并为一个
将前3个commit合并为一个
git rebase -i HEAD~3
之后,会弹出一个vim,从上到下分别是第一次、第二次、第三次提交
将后两个pack改为s,保存vim退出
进入到另外一个日志窗口,会把第一次、第二次、第三次的commit log都list出来,我们可以修改(这里#注释不用管)
最后保存vim退出
git push -f
六.其他
mysql锁依赖关系查询
SELECT
r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
TIMESTAMPDIFF(
SECOND,
r.trx_wait_started,
CURRENT_TIMESTAMP
) wait_time,
r.trx_query waiting_query,
l.lock_table waiting_table_lock,
b.trx_id blocking_trx_id,
b.trx_mysql_thread_id blocking_thread,
SUBSTRING(
p. HOST,
1,
INSTR(p. HOST, ':') - 1
) blocking_host,
SUBSTRING(p. HOST, INSTR(p. HOST, ':') + 1) blocking_port,
IF (p.COMMAND = 'Sleep', p.TIME, 0) idel_in_trx,
b.trx_query blocking_query
FROM
information_schema.INNODB_LOCK_WAITS w
INNER JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id
INNER JOIN information_schema.INNODB_LOCKS l ON w.requested_lock_id = l.lock_id
LEFT JOIN information_schema. PROCESSLIST p ON p.ID = b.trx_mysql_thread_id
ORDER BY
wait_time DESC;
七.常见mysql故障处理以及问题处理
1.数据库强制启动,如果innodb文件损坏,或者遇到其他故障需要强制启动则修改innodb_force_recovery,调整对应的级别数字越大跳过的检查越多。innodb_force_recovery = 6
1(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。
2(SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
3(SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。
4(SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作。
5(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
6(SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。
2.对于文件读写的错误,比较典型的是:InnoDB: File(unknow):'read' returned OS error 122
对于此类错误,一般通过调整innodb_flush_method参数可以解决(注释掉innodb_flush_method = O_DIRECT)
3.数据库输盘参数,对于写压力测试往往IO成为瓶颈,通过调整以下参数可以降低IO的开销
sync_binlog 默认为0,操作系统负责刷新mysql不负责刷新,重启机器会导致binlog丢失。强一致场景设置为1,每次强制刷盘。
innodb_flush_log_at_trx_commit 默认为2,由操作系统刷新,mysql不刷新,重启机器会导致redo丢失。强一致默认为1,每次强制刷盘。
4.对于cpu性能分析,一般比较常用的指令是perf top -p ${pid}
5.自动清理binlog,通过设置参数expire_logs_days=3
6.常用的工具集合
sysben压力测试工具
./sysbench --test=tests/db/oltp.lua --mysql-table-engine=innodb --mysql-engine-trx=yes --oltp-table-size=10000 --mysql-user="${user}" --mysql-password="${password}" --mysql-db=test --mysql-host=${ip} --mysql-port=24002 --oltp_tables_count=10 prepare
./sysbench --test=tests/db/oltp.lua --mysql-table-engine=innodb --mysql-engine-trx=yes --oltp-table-size=500000000 --mysql-user="${user}" --mysql-password="${password}" --mysql-db=test --mysql-host=${ip} --mysql-port=24002 --oltp-test-mode=complex --num-threads=100 --oltp_tables_count=10 --report-interval=5 --max-time=720 --max-requests=0 run
./sysbench --test=tests/db/oltp.lua --mysql-table-engine=innodb --mysql-engine-trx=yes --oltp-table-size=500000000 --mysql-user="${user}" --mysql-password="${password}" --mysql-db=test --mysql-host=${ip} --mysql-port=24002 --oltp_tables_count=10 cleanup
tpcc测试
./tpcc_load ${ip}:${port} tpcctest "${user}" "${password}" 10
./tpcc_start -h${ip} -P${port} -d tpcctest -u "${user}" -p "${password}" -w 10 -c 10 -r 120 -l 120
checksum
./pt-table-checksum --replicate=test.checksum --no-check-binlog-format --socket='/data/tdengine/data/4021/prod/mysql.sock' --user='${user}' --password='${password}'
SELECT db, tbl, CONCAT(db, '.', tbl) AS `table`, chunk, chunk_index, lower_boundary, upper_boundary, COALESCE(this_cnt-master_cnt, 0) AS cnt_diff, COALESCE(this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc), 0) AS crc_diff, this_cnt, master_cnt, this_crc, master_crc FROM test.checksum WHERE master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)
pt-query-digest
./pt-query-digest --since="2016-01-22 00:00:00" --until="2016-01-22 12:00:00" --output=json
mydumper
./mydumper --host=${ip} --port=4020 --user="${user}" --password="${password}" --events --routines --triggers --less-locking --ignore-sysdb=1 --chunk-filesize=512 --complete-insert --db-list=cstsdb --outputdir=./backup_dir
./myloader --user=""${user}"sys_kp_new" --password="4^GAs10Ii0veS&9WaIUv" -h 10.231.136.34 --directory="/tmp/backup" -o --enable-binlog
mysqldump
./mysqldump -q --default-character-set=utf8 --hex-blob --skip-add-locks --skip-add-drop-table --skip-lock-tables -v --master-data=2 --single-transaction=1 --skip-disable-keys -c --skip-extended-insert -u'{user}' -p'{pass}' -h{ip} -P3306 --where"" db table >localfile.sql
pt-online-schema-change
./pt-online-schema-change --user=${user} -p ${password} --socket=/data/4002/prod/mysql.sock --no-check-replication-filters --alter=CHARACTER SET utf8 COLLATE utf8_bin D=seven,t=t --noanalyze-before-swap --critical-load=Threads_running=800 --execute
跳过gtid
stop slave sql_thread;set global gtid_slave_pos = '+1';start slave sql_thread;
SET SESSION GTID_NEXT = '1b0c6d04-b349-11e9-b7ab-6c92bf6285f4:20289131';begin;commit
slave-skip-errors=1053,1146 #跳过指定类型的错误
slave-skip-errors=all #跳过所有错误
跳过权限表
skip-grant-tables
本文详细介绍了MySQL的调试技巧,包括开启Debug日志、使用GDB进行core文件调试、测试用例集的执行以及GDB调试官方PATCH的定位。此外,还分享了如何将多个git commit合并为一个,以及常见MySQL故障的处理方法,如调整innodb_force_recovery参数等。
815

被折叠的 条评论
为什么被折叠?



