— 1 —
mysql
1、实例CPU使用率过高
a、通过命令行,或者sql平台登录数据库执行如下sql:
代码语言:javascript复制select /*gtt*/ count(*) '并发数',max(time)'最长执行时间',concat(SUBSTR(REPLACE(REPLACE(REPLACE(info, CHAR(10), ''), CHAR(13), ''),' ',' ' )FROM 1 FOR 30),'||', REPLACE(REPLACE(substr(info,LOCATE('from',info) 4,30), CHAR(10), ''), CHAR(13), '')) 'sql格式化展示' from information_schema.PROCESSLIST where info is not null and id not in( select connection_id() ) group by concat(SUBSTR(REPLACE(REPLACE(REPLACE(info, CHAR(10), ''), CHAR(13), ''),' ',' ' )FROM 1 FOR 30),'||', REPLACE(REPLACE(substr(info,LOCATE('from',info) 4,30), CHAR(10), ''), CHAR(13), '')) order by 1;
b、通过下面的sql 查看具体的每一个进程情况:
代码语言:javascript复制select * from information_schema.PROCESSLIST where info is not null order by time,info ;
如果并发进程量大(>实例所承载的进程量),最长执行时间比较大(>1s)可从云平台或者grafana的监控上总体对比数据库前后时间段的压力情况(主要从tps,qps,网络流量,连接数),
同时和运维、开发人员沟通是否有推送,新上线,业务请求量增大等情况,
推送:可以先设置innodb_thread_concurrency参数控制最大并发
业务请求量增大:升级数据库配置
恶意攻击:修改数据库账号权限,ip访问白名单,修改数据库密码等
如果并发量特别大,进程数>数据库实例所承载的进程数,数据库处于hang的状态可以协商进行数据库主备切换(此操作业务时候肯定是受损.对比业务不可用,快速恢复数据库变成可用这个时候是DBA最要考虑的事情)
c、通过下面的sql,输入过滤条件,查询出满足条件的进程列表,执行查询结果 kill 进程
代码语言:javascript复制select concat('kill ',id,';') 'kill',USER,host,db,COMMAND,time ,STATE from information_schema.PROCESSLIST where info is not null and TIME>0 and info like '%过滤条件%';
并发量不大,进程执行时间比较长超100s,可以先kill进程,后续再优化sql
2、实例内存使用率过高
紧急情况:数据库主备切换并告知开发,一般业务都有自动重连机制影响不大
非紧急情况:登录数据库,使用performance_schema下面的memory_summary_by_xxx表分析内存使用分布情况
3、实例磁盘iops使用率过高
kill长时间运行的sql,及优化慢sql(控制台-日志-慢日志明显)
4、实例连接数使用率过高
释放长时间的空闲连接:
- kill sleep进程直接释放
- 调整超时timeout参数
5、实例磁盘空间使用率过高
扩容磁盘 (业务低风期 扩容)
清理表碎片(analyze table 会锁表 要注意) 根据上面的sql查询占用磁盘空间大的表,及碎片
代码语言:javascript复制SELECT table_schema,table_name,sum(round( round( data_length index_length ) / (1024 *1024*1024) , 2 )) total_size_G ,round(sum(DATA_FREE)/1024/1024/1024,2) FROM information_schema.TABLES group by table_schema,table_name HAVING sum(round( round( data_length index_length ) / (1024 *1024*1024) , 2 ))>1 order by total_size_G desc ;
清理归档废弃数据
— 2 —
redis
1、 监控大盘上整体查看redis(推荐使用 grafana prometheus)
所有数据库都需要对区域、维度、重要级别 有不同的应级方案
所有数据库都需要对区域、维度、重要级别 有不同的应级方案
所有数据库都需要对区域、维度、重要级别 有不同的应级方案
2、查看慢操作:
代码语言:javascript复制slowlog get N
3、内存使用率分析:
redis-analyzer
代码语言:javascript复制go get github.com/lanfang/redis-analyzer
cd go/bin/
./redis-analyzer parse-rdb --rdb-file=mess.rdb
redis-rdb-tools
代码语言:javascript复制git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
python setup.py install
rdb -c memory 30.rdb > memory2.csv
从源码安装
代码语言:javascript复制 python setup.py install
rdb -c memory 30.rdb > memory2.csv
分析内存快照
SQLite 是一款轻型的数据库。我们可以将前面生成的 csv 导入到数据库中之后,就可以利用 sql 语句很方便的对 Redis 的内存数据进行各种分析了。 导入方法:
代码语言:javascript复制sqlite3 30.db
create table memory30(database int,type varchar(128),key varchar(128),size_in_bytes int,encoding varchar(128),num_elements int,len_largest_element varchar(128),expiry varchar(128));
.mode csv
.import memory.csv memory2018070420320
数据导入以后,接下来想怎么分析就怎么分析了,举几个简单的例子: 查询key个数
代码语言:javascript复制select count(*) from memory30;
查询总的内存占用
代码语言:javascript复制select sum(size_in_bytes)/1024/1024 from memory30 where key like 'xxx_detail%';
查询内存占用最高的10个 key
代码语言:javascript复制select * from memory20180704203207 order by size_in_bytes desc limit 10;
查询成员个数1000个以上的 list
代码语言:javascript复制select * from memory20180704203207 where type='list' and num_elements > 1000
3、实时分析redis实例:
代码语言:javascript复制git clone https://github.com/Instagram/redis-faina.git
代码语言:javascript复制redis-cli -h 0.0.0.0 -a passwd -p 6379 MONITOR | head -n 10000 | ./redis-faina.py |more
代码语言:javascript复制Overall Stats
========================================
Lines Processed 10000 --采样的数目
Commands/Sec 31718.97 --TPS 单实例tps可以达到8-10w
Top Prefixes --热点key前缀
========================================
vivashow 8526 (85.26%)
v 275 (2.75%)
vid 102 (1.02%)
n 70 (0.70%)
vids 10 (0.10%)
Top Keys --热点key
========================================
vivashow:f:v:i~lock 559 (5.59%)
vivashow:v:i~lock 395 (3.95%)
Top Commands --热点命令
========================================
EXISTS 4817 (48.17%)
GET 2943 (29.43%)
SET 368 (3.68%)
Command Time (microsecs)--命令耗时
========================================
Median 20.0
75% 217.25
90% 585.75
99% 1184.0
Heaviest Commands (microsecs)--最重的命令
========================================
GET 100961.5
SET 44970.0
EXISTS 38443.25
Slowest Calls --最慢的调用
========================================
1519.75 "EXISTS" "xxxxxx:user:info:36833133"
— 3 —
mongodb
1、数据库常用命令
代码语言:javascript复制db.currentOp() ---查看数据库当前正在执行的操作
db.killOp(opid) ---直接终止该操作
db.userInfo.find({name: /mongo/}) —-模糊查询
db.user_message_feed_index.createIndex( { created_at:1}, {expireAfterSeconds:2592000,background: true} ) —-添加索引
2、日常使用的慢日志(system.profile)查询 a、返回最近的10条记录
代码语言:javascript复制db.system.profile.find().limit(10).sort({ ts : -1 }).pretty()
b、返回所有的操作,除command类型的
代码语言:javascript复制db.system.profile.find( { op: { $ne : 'insert' } }).pretty()
c、返回特定集合
代码语言:javascript复制db.system.profile.find( { ns : ‘mydb.test‘ } ).pretty()
d、返回大于5毫秒慢的操作
代码语言:javascript复制db.system.profile.find({ millis : { $gt : 100 } } ).pretty()
3、分片集 mongodb常用命令
a、db启用shard
代码语言:javascript复制sh.enableSharding('xxxashow')
b、对集合分片:
代码语言:javascript复制sh.shardCollection("xxx.notification",{"receiverId":"hashed"})
c、查看是否发生了迁移与分割:
代码语言:javascript复制use config
db.changelog.find({what: "split"}).sort({time:-1})
db.changelog.find({what: "moveChunk.commit"}).sort({time:-1})
写到尾声:赠送故障时 3大操作 让你快速恢复数据库
1、快速对数据库进行主备切换!数据业务不重要可以恢复到某个时间来保证数据库能正常使用
2、快速联系云厂商要求帮助协助问题!(网络 DNS 宿主机本身)
3、升级数据库配置!
以上3条操作 ,遇到比较大故障第1条优先处理!(如删除会话等操作无效情况下)
文中部分脚本用同事湍神之前整理mysql脚本