mysql DBA技能

DBA技能mysql

主备

启动slave thread:登陆到sql后运行start slave;
查看主备:show slave status\G

主备切换

发生切换的缘由是ha在固定时间内来测试数据库可否访问,若是数据库在多长时间内一直不能访问才会发生主备切换
因此主备切换的缘由是必定时间内数据库没法访问,缘由可能有qps过大或慢sql rt太高致使数据库堵住,或线程池满数据库没法访问,链接满拒绝访问

数据

1.max_connections:容许全部用户的最大链接数,包括root除了(‘root’@‘127.0.0.1’和’root’@’localhost’),满了报错too many connections,错误号1040
2.max_user_connections:单个用户容许的最大链接数,包括root除了(‘root’@‘127.0.0.1’和’root’@’localhost’),满了报错User root already has more than 'max_user_connections' active connections,错误号1203
3.数据库线程池:32   thread_pool_size=32,thread_pool_oversubscribe=10;线程池大小为32*(10+1)=352,加上其它后台线程也不过400

指标解读

rt:经过调用tcprstat来监控MySQL的响应时间,单位us,rt高就是mysql的响应时间高,就是有慢sql
load average:是 CPU的Load,它所包含的信息不是CPU的使用率情况,而是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,
    也就是CPU使用队列的长度的统计信息。Load Average却从另外一个角度来展示对于CPU使用状态的描述,
    Load Average越高说明对于CPU资源的竞争越激烈,CPU资源比较短缺,由于cpu执行快io执行慢,load高通常是有执行慢的io操做使得cpu等待。
    Load Average是与机器内核数有关的。以一个单核的机器为例,load=0.5表示CPU还有一半的资源能够处理其余的线程请求,load=1表示CPU全部的资源都在处理请求,没有剩余的资源能够利用了,而load=2则表示CPU已经超负荷运做,另外还有一倍的线程正在等待处理。因此,对于单核机器来讲,理想状态下,Load Average要小于1。同理,对于双核处理器来讲,Load Average要小于2。结论是:多核处理器中,你的Load Average不该该高于处理器核心的总数量。
cpu利用率:是对一个时间段内CPU使用情况的统计,经过这个指标能够看出在某一个时间段内CPU被占用的状况
qps:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
tps:Transactions Per Second(每秒传输的事物处理个数)
    即服务器每秒处理的事务数。TPS包括一条消息入和一条消息出,加上一次用户数据库访问。(业务TPS = CAPS × 每一个呼叫平均TPS)
    TPS是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求而后服务器作出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。

加权限

磁盘满了:

极可能是备份进程,ps -aux |grep xtra查看   
df -h查看磁盘占用
sudo du -sh /u01/* 查看占用详情
查看最大的库最大的表
    sudo du -sh /u01/my*:查看哪一个实例最大
    cd /u01/my3306/data:
    sudo du -sh xxx* |grep G|sort:查看以xxx开头并是G体量的并从小到大排序
    sudo du -sh *.ibd |grep G|sort:查看.ibd结尾的表文件以GB为体量的大小并从小到大排序
    sudo du -sh *.ibd |grep G|wc -l:查看文件个数

锁表 5.6.16.6库

索引有关
    fulltext index会锁表
字段有关
    加AUTO_INCREMENT列
    加列中有隐式的NOT NULL转换时候 (主键列 就算没有指定not null  也会加上这个属性的)
    修改列的数据类型。(扩大长度没问题(可是varchar长度过大会形成锁表,由于长度过大会自动将varchar转换成text),修改数据类型就会锁表varchar到text也算是修改数据类型也会锁表,int到bigint也会锁表,只有修改varchar(1) 到varchar(10)这种扩大长度的才不会锁表)
其余
    删除PrimaryKey
    转换/修改字符集
锁表时间
    2G的表大约锁表几秒钟,主要由IO等资源决定,时间不肯定

mysql online DDL锁

1.,lock=none :支持select和DML在线无锁变动
2.,lock=shared :支持select 不支持DML 
3.,lock=exclusive :不支持select 不支持DML
4.,lock=default : mysql本身选择锁定资源最少的方式

数据库设计

1.表设计
    1)     表必须定义主键,主键建议为整型
    2)     禁止使用外键
    3)     多表中的相同列,必须保证列定义一致
    4)     表默认使用InnoDB,表字符集使用utf8
    5)     表必须包含gmt_create和gmt_modify字段,即表必须包含记录建立时间和修改时间的字段
    6)     单表数据量超过500w或数据容量超过10G考虑分表
2.字段设计
    1)     表被索引列必须定义为not null,并设置default值
    2)     禁止使用float、double类型,建议使用decimal替代
    3)     禁止使用blob、text类型保留大文本、文件、图片,建议使用其余方式存储(TFS),MySQL只保存指针信息
3.其余
    1)     禁止使用:存储过程、触发器、函数、视图、事件等MySQL高级功能
    2)     禁止使用跨库查询
    3)     禁止使用子查询,建议将子查询转换成关联查询
    4)     禁止核心业务流程SQL包含:计算操做、多表关联、表遍历case when等复杂查询,建议拆分红单表简单查询

解析log命令

mysqlbinlog -v --base64-output=decode-rows -d 数据库名字  log名字 > /tmp/mysql-bin.000004.sql
eg:
mysqlbinlog -v --base64-output=decode-rows -d seotools mysql-bin.000004 > /tmp/mysql-bin.000004.sql
mysqlbinlog -v --base64-output=decode-rows --start-position=442183506 --stop-position=453224675 mysql-bin.000970 >>zjk.log

恢复删除数据

rollback

跳过错误,登陆mysql,实际上是跳过一个事务

stop slave;
set global sql_slave_skip_counter=1;
start slave;

smart,登陆mysql

stop slave;
set global slave_exec_mode='smart';
start slave;

stop slave;
set global slave_exec_mode='strict';
start slave;

数据回滚——udc>数据质量>数据回滚

删除/修改数据查询(解析binlog)——udc>数据质量>数据轨迹

解binlog

mysqlbinlog  --help

高低水位限流

1.为threads_running设置一个硬上线,当并发超过此值是,拒绝执行sql,保护MySQL,咱们将这个称之为:高水位限流
2.为mysql server层并发运行线程数目设置一个软上线,当超过此值时,线程自动按照FIFO顺序排队,将并发运行线程控制在必定数目以内,减小context switch及大量线程之间可能的锁竞争,使 MySQL性能可以稳定在较高点,咱们将这个称之为:低水位优化
主要参数包括2个:show variables like "threads_running%";
    threads_running_low_watermark
    threads_running_high_watermark
当系统变量threads_running超过threads_running_low_watermark设置的阀值时,线程进行排队;
超过threads_running_high_watermark设置的值时,直接拒绝该SQL。
建议设置:
    threads_running_high_watermark为1000,threads_running_low_watermark做用不大。
注意:5.6版本启用了线程池,线程池对请求作了排队,所以通常状况下,无需再设置高低水位。
    对于thread_pool_size=32,thread_pool_oversubscribe=10的设置,处理请求的线程只有:
    32*(10+1)=352,加上其它后台线程也不过400,所以threads_running不会达到很高,
    遇到极端状况,线程池满负荷运转,但rt已经不知足需求,能够考虑将threads_running_high_watermark
    设置的更小。

sql限流

查看show variables like 'sql%filter%';
查看sql_delete_filter sql_select_filter  sql_update_filter是否限流
如何限流参考:https://askdba.alibaba-inc.com/libary/control/getArticle.do?articleId=11632
能够指定带有某些字段的select/insert/delete的SQL并发数,超出并发数的查询报错:Query execution was interrupted

启动/关闭实例

my3361
myadm -P3361 -d startup/shutdown/startslave:启动关闭3361实例,或者启动3361的备份进程
myadm startup/shutdown/startslave:启动或者关闭这台机器上的全部实例,或者启动这台机器上的全部备份进程

实例挂了

报警:slave io/sql thread error 或 slave] failed
1.尝试12中的启动实例
2.启动不成功查看alert日志:/u02/my3306/log/alert.log web

重搭备库

数据迁移

数据迁移分为以下几种种状况
1.迁移数据表,且表没有不少的写入,表中数据不算太大
2.迁移整个库且没有太大的写入
待添加
3.迁移整个实例,且没有太大的写入
待添加
4.无论迁移什么,可是有不少的写入
这时候须要全量迁移还要增量迁移,用DTS或者精卫,要在一个写入少的时间里作个切换sql

筛选链接并kill掉

select concat("kill ", id, ";") from information_schema.processlist where user = 'tbdw';

数据库升级 说白了就是实例迁移,但须要开发升级相应依赖

msyql 5.6 tddl 5  jdbc 5.1.18

实例迁移,扩容,都是同样的

慢sql日志

/u02/my3306/log/slow_history/

字符转换

ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8;

查看用户链接数thread_connected

/opt/dbfree-minion/data/          grep threads_connected metric.21.10.2016 | grep 3306  找到对应的时间点的位置
或者查看thread_connected指标

drop table

有风险,严重消耗IO,还会对table cache加锁,全部的操做都会阻塞,
经历两个步骤:1.flush dirty data:删除buffer pool上的数据,会加table_cache的锁,其余查询去不没法执行,2.remove data file:删除物理文件
1.drop table操做须要进行sleep操做,sleep 60,不是解决阻塞,而是缓解
2.对于大表必定创建文件硬链接,缩短第二部的耗时
    一、创建硬连接。
        ln table.ibd table.idb.hdlk
    二、mysql执行drop table操做。(实际上这一步只是删除指向文件的指针)
        drop table if exists tablename;
    三、使用truncate删除物理文件。(这里才是真正的删除数据)
        truncate -s xxxG filename

删除数据

ssh能登录ping不通

交换机故障,此时应用没问题,不须要作什么

ssh不能登录能ping通

RSA/raid卡故障,此时应用其实不能用了,至关于挂了

分配实例

按照 qps计算实例的buffer pool, 取最近15天qps的最大值,若是qps<100, bp=1G; 100<=qps<=1000, bp=10G; 1000<=qps<=2000, bp=35G, qps>2000,保持原来的bp

网卡

千兆网卡:1000Mb   平时说的网络发送接收之类的单位都是MB,换算单位是1000/8=125,可是网卡是双网卡对,因此瓶颈是250左右

动态指定索引(索引存在,但走不到,应用加force index来不及的情景)

语法
Set global sql_hints='+,<schema_name>,<table_name>,<index_name>,<keyword1>~<keyword2>…';
eg:select id from test.heartbeat where a=xxx and b=xxx
set global sql_hints ='+,test,heartbeat,idx_id,select id from~a=~b=';
分表支持,例如heartbeat表是分表
set global sql_hints ='+,test,heartbeat_,idx_id,select id from~a=~b=';
没法支持分库,想要分库必须手动每一个分库上都添加
查看规则
show sql_hints;
移除规则
set global sql_hints=='-,idx_id';
清理全部规则
set global reset_all_sql_hints=1

批量删除大量慢sql

select concat("kill ", id , ";") from information_schema.processlist where time > 10 into outfile 'kill.sql'
source /u01/my3306/data/kill.sql

开启全量sql

source /home/mysql/.bash_profile
for sockets in  `ps -ef|grep mysqld|awk -F "--socket=" '{print $2}'|awk '{print $1}'`;
do
  mysql -uroot -S $sockets -e"uninstall plugin dam_plugin"
  mysql -uroot -S $sockets -e"select version()" | egrep "5.6.16.12-20161009-log|5.6.16.12.3-20161017"
 if [ "$?" -ne 0 ]; then
  echo $sockets, "ignore"
  continue
 fi 
 mysql -uroot -S $sockets -e"set global log_sql_info=ON"
done
service dbfree-dam restart
sleep 10
source /home/mysql/.bash_profile
for sockets in  `ps -ef|grep mysqld|awk -F "--socket=" '{print $2}'|awk '{print $1}'`;
do
  mysql -uroot -S $sockets -e"select version()" | egrep "5.6.16.12-20161009-log|5.6.16.12.3-20161017" 
 if [ "$?" -ne 0 ]; then
  echo $sockets, "ignore 2"
  continue
 fi 
 mysql -uroot -S $sockets -e"set global log_sql_info=ON"
done
echo 'Success'
if not now when,if not me who