系列
- MySQL · 案例分析 · 主从复制中断
- MySQL · 案例分析 · 磁盘空间不足
- MySQL · 案例分析 · information_schema.tables 与 count(*) 查询数不一致
数据库连接失败
问题现象
项目经理火急火燎的反馈,说数据库连接不上了,请求排查问题原因。
原因分析
测试
Navicate
是否能够连上数据库 ?登录服务器,查看
mysqld
进程是否存在,如果进程不存在,可能是服务器断电导致进程未自启动。
1 | $ ssh -p 2222 01510886@10.138.16.192 |
- 登录
mysql
,查看线程状态,查看是否有锁占用,或者线程大量阻塞情况。
1 | $ mysql -S /data/mysql/mysql.sock -usre -p'sre@@p$i' |
解决方法
- 如果是第一种原因,启动
mysql
进程
1 | $ cd /etc/init.d |
- 如果是第二种原因,删除正在执行的锁表线程
1 | # 杀掉ID为1的线程, 关闭连接 |
备份夯住
现象描述
据备份供应商反映,昨天晚上 22:00 XX系统
,从库备份失败,使用的备份工具是 mysqldump
,请求协助定位备份失败原因。
原因分析
(1)检查从库两个线程 Slave_IO_Running
和 Slave_SQL_Running
均是 Yes,说明主从复制链路正常,但是 Seconds_Behind_Master
不断增大,且主从数据延迟有不断扩大的趋势。
1 | mysql> show slave status\G |
(2)检查当前数据库线程状态,未发现有明显异常。
1 | mysql> show processlist; |
(3)检查当前正在使用的表:show open tables where In_use=1;
发现有一张表一直处于 In_use
状态。
1 | mysql> show open tables where In_use=1; |
(4)根据 Relay_Log_Pos
解析 relay-log.000004
,查看当时正在执行的操作是 Delete_rows
,操作的表是 tdmetl
.odsepg_zrfc_zco_zzfymx_sw
。
1 | # mysqlbinlog -vv --base64-output=decode-rows relay-log.000004 --start-position=169851605 | more |
1 | # at 169851605 |
(5)检查表结构,发现该表数据量很大且无主键。由此基本确定其问题根本原因:对无主键的表进行删除或者更新,导致从库夯住。该表数据量:77961221条。
解决方法
(1)表添加自增主键。
1 | ALTER TABLE 'xxxx' ADD id int UNSIGNED primary key AUTO_INCREMENT; |
(2)大表删除使用 truncate
命令。
建议
- 避免无
where
条件的delete
或update
操作大表,如果需要全表删除,使用truncate
操作。 - 在
binlog row
模式下表结构最好能有主键。
主从复制中断
问题现象
监控系统,检测到xx项目
主从复制中断,并发送了告警
原因分析
1)登录所报告警数据库,查看复制状态
1 | ssh haieradmin@10.138.8.216 |
经检查 Slave_SQL_Running
为 No,原因一般都很明显,记录在 Last_Error
,根据报错原因选择合适地解决方法,最常用的解决办法是跳过这一条正在执行的 SQL。
解决方法
(1)登陆 10.133.0.53
(2)执行下面操作
1 | pt-slave-restart -h 'x.x.x.x' -u'xx' -p'xx' -P 3306 |
1 | mysql> show slave status\G |
1 | Slave_IO_Running: No |
1 | [root@hop02 mzjh]# ll | grep mysql-bin |
从库在主库找不到 binlog 文件
原因
该错误发生在从库的io进程从主库拉取日志时,发现主库的mysql_bin.index文件中第一个文件不存在。出现此类报错可能是由于你的slave 由于某种原因停止了好长一段是时间,当你重启slave 复制的时候,在主库上找不到相应的binlog ,会报此类错误。或者是由于某些设置主库上的binlog被删除了,导致从库获取不到对应的binglog file。
表碎片
表碎片是 MySQL
运维过程中比较常见的问题,碎片的存在十分影响数据库的性能。
判断方法
MySQL 的碎片是否产生,通过查看
1 | show table status from table_name\G; |
这个命令中 Data_free
字段,如果该字段不为 0,则产生了数据碎片。
产生原因
1. 经常进行 delete 操作
经常进行 delete
操作,产生空白空间,如果进行新的插入操作,MySQL 将尝试利用这些留空的区域,但仍然无法将其彻底占用,久而久之就产生了碎片;
2. update 更新
update
更新可变长度的字段(例如:varchar
类型),将长的字符串更新成短的。之前存储的内容长,后来存储是短的,即使后来插入新数据,那么有一些空白区域还是没能有效利用的。
产生影响
由于碎片空间是不连续的,导致这些空间不能充分被利用;
由于碎片的存在,导致数据库的磁盘
I/O
操作变成离散随机读写,加重了磁盘I/O
的负担。
清理办法
MyISAM:
optimize table
表名;(OPTIMIZE 可以整理数据文件,并重排索引)InnoDB:
(1)重建表存储引擎:
ALTER TABLE tablename ENGINE = InnoDB;
(2)进行一次数据的导入导出
碎片清理的性能对比:
引用我之前一个生产库的数据,对比一下清理前后的 SQL 执行速度差异:
1 | select count(*) from test.twitter_11; |
总结
通过对比,可以看到碎片清理前后,节省了很多空间,SQL执行效率更快。所以,在日常运维工作中,应该对表碎片进行定期清理,保证数据库有稳定的性能。
触发器创建失败
问题现象
创建触发器,报错提示”1419”
1 | ERROR 1419 (HY000): You do not have the SUPER privilege and |
原因分析
有些操作要禁止掉对 SUPER 权限的要求,要处理可以设置 log_bin_trust_routine_creators
全局系统变量为 1
,默认地,这个变量值为 0
。
解决方法
直接在数据库进行修改,也可以在启动服务器之时用 --log-bin-trust-routine-creators
选项来设置允许这个变量。
1 | mysql> SET GLOBAL log_bin_trust_routine_creators = 1; |