一 如何进行锁等待的排查
1 锁等待分为MDL锁等待和事务锁等待
2 通过show processlist可以观察到事务整体状态的语句
3 通过innodb_trx可以观察所有活动未提交的事务(包括读),这里要注意几点
1 TRX_STARTED 是事务开始的时间
2 TRX_QUERY 是否有具体的sql内容,如果没有具体的sql内容,很可能是长时间未提交的事务
3 TRX_MYSQL_THREAD_ID mysql_thread id,可以根据此进行kill操作
4 TRX_STATE 事务状态 允许的值为 RUNNING, LOCK WAIT, ROLLING BACK, COMMITTING
5 TRX_QUERY 事务保留锁的数量
4 通过innodb_wait_trx 可以观察到具体的等待事务信息(比如等待的事务ID,正在运行的事务ID)默认这里为空.
5 通过5.7的meta_lock的数据可以定位具体的把持mdl的事务
6 kill session的本质是kill mysql_thread_id,这点从show processit-id和innodb_trx的TRX_MYSQL_THREAD_ID 都可以发现
二 innodb_page_cleaners
1 作为mysql后台的线程,周期性的将脏页刷新到磁盘上
2 5.7以后默认参数是4,官方建议设置和buffer_pool_instance一样的个数
3 针对所谓的多线程刷脏对应的是instance实例数量
4 page_cleaner的告警 警告一般是IO能力不足,或者参数不够优化的结果
1 减少每次刷脏的数量 2 升级你的硬盘配置
5 通过pfs库查询到的page_cleaner线程只有一个,暂时不知道为何
三 运维平台进行排查问题的功能
1 收集目标 show processlist innodb_trx innodb_trx_wait
2 统计关键字 MDL锁,SQL执行时间大于5S,针对DB纬度的统计
3 获得信息 1 现在运行的所有事务(事务分成三种 1 长时间运行的事务(比如慢查询) 2 短时间频繁运行的事务 3 长时间未提交的事务(可能导致锁等待),然后针对进行处理
四 mysql 压测相关
1 工具 sysbench1.x oltp.lua
2 具体流程 1 填充数据 2 进行oltp混合测试 3 清理数据环境
3 参数选项 1 并发thread 2 读写混合模式 3 压力总连接数和持续时间 4 样本抽样类型
4 报告分析
1 各类命令统计(dml+其他)2 每秒/总tps——qps
3 time
avg/min/max/count transtaion(包括读事务)
4 errors 错误数量,如果太大,就代表出现了瓶颈
5 sysbench应该配合丰富的监控系统来不断调整压测参数和对数据库进行配置优化,达到最终目的
五 死锁问题
1 lock mode X locks gap before rec insert intention waiting 插入意向锁等待
拆开分析
1 lock_mode X locks gap before rec insert intention->插入意向锁
2 waiting 等待
即一个事务想要获取插入意向锁,如果有其他事务已经加了gap lock或 Next-key lock,则会阻塞,此日志对应INSERT语句
备注 1
- 记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
- 间隙锁(LOCK_GAP): lock_mode X locks gap before rec
- Next-key 锁(LOCK_ORNIDARY): lock_mode X
- 插入意向锁(LOCK_INSERT_INTENTION):
1 lock_mode X locks gap before rec insert intention
2 lock_mode X insert intention(省掉了 locks gap before rec, 出现在supremun record被锁定情况 )
2 如果插入的值超过索引中最大值,锁类型变为X锁,被锁的最大行为supremum pseudo-record,它具有大于所有索引的值,不是真正的索引记录。此时,锁的范围扩大到正无穷。
3 page no关键字 锁定的具体数据页 primary 锁定具体是否是主键
4 需要完整的事务语句
5 是有几率发生还是一定发生
六 insert慢的几种情况
1 磁盘IO负载过高,导致资源征用
2 插入语句等待GAP LOCK,锁资源征用
3 插入语句等待MDL LOCK,锁资源征用
4 表本身的外键检测约束
5 表本身没有主键
6 插入的字段本身包含大字段
7 半同步复制导致的延时提交
8 由于某些原因导致的LRU_MUTEX锁被征用,处于等待状态,可以通过观察SPIN等待状态分析
七 MySQL 内存泄漏
1 在之前的题目中我们说了内存问题的几种情况,然后我们这次具体分析下内存泄漏情况
2 查询具体表
select thread_id,event_name, SUM_NUMBER_OF_BYTES_ALLOC, SUM_NUMBER_OF_BYTES_FREE from performance_schema.memory_summary_by_thread_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 30;
3 我们要注意几点
1 SUM_NUMBER_OF_BYTES_ALLOC 申请的内存量
2 SUM_NUMBER_OF_BYTES_FREE 申请的内存是否已释放,为0时要特别注意
3 thread_id 判断出问题EVENT,根据此查找出对应THREAD线程,进行进一步分析
4 几个常见的问题
0 memory/innodb/mem0mem
1 memory/sql/log_event
5 select thread_id,event_name, CURRENT_NUMBER_OF_BYTES_USED from performance_schema.memory_summary_by_thread_by_event_name order by CURRENT_NUMBER_OF_BYTES_USED desc limit 30;
八 程序连接MYSQL TIMEOUT排查思路
1 程序报错
1 和MYSQL建立连接过程中超时 connect timeout
2 在MYSQL中读取数据时超时 read timed out
2 排查思路
1 查看linux的连接状态,查看连接数的数量和各种状态的统计,关注是否有大量的TIMEOUT
2 查看MYSQL的总体连接数/正在运行的连接数,推测是否因为连接数打满导致的问题
3 查看linux的网卡流量,推测是否因为流量被堵死导致的TCP无法建立连接
4 查看linux的整体负载情况,是否因为服务器压力太大导致响应问题
3 建立程序报错汇总-解决办法 相应体系
九 MHA切换几个关键点
1 当MHA检测到主库不通时,会进行第二检测脚本进行检测,只有当两者都不通时,才会进行切换动作,防止脑裂的情况
2 新主库补全日志需要两份,新主应用延时的RELAY-LOG (默认选择的就是RELAY-LOG应用最新的从库,所以这里并不需要APPLY 对比其他从库) 和 从原主拷贝的BINLOG,
3 当新主补全完所有日志后,就会打开读写,绑定VIP,提供正常服务
4 剩下的从库就会被并行补全新主与从库差异的RELAY-LOG和新主与原主之间差异的binlog,两个日志会进行合并,然后从库进行应用
十 SELECT查询的关键点
1 查询本质是利用索引在INNODB层定位目标数据所在的数据页,然后读取到BUFFER_POOL中进行操作读取
2 索引的条件查询发生在INNODB层,非索引查询定位和指定字段取值发生在SERVER层
3 尽量避免大字段和尽量过滤较多的数据在INNODB层,减少无关数据页的获取到SERVER层
十一 关于LINUX优化的几个参数
1 更改调度算法为NOOP,最大限度磁盘性能
2 更改VM.SWAPNISS值,尽量尽可能的少用SWAP空间,这个值得调整意义是百分比,当所用内存到达总内存的占用百分比时才会使用SWAP
3 关闭NUMA,防止内存泄漏
4 调整文件打开数最大,为65535
十一 网络基础
1 完整流程
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
2 状态解说
LISTEN:服务器在等待进入呼叫
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
TMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
3 关键解释
1 ACK起应答作用 SYN起同步作用 FIN 终止连接通道
2 ACK每次都会累计+1
3 三次握手组合为SYN+ACK 四次断开组合为FIN+ACK
4 主动关闭(FIN_WAIT1,FIN_WAIT2,TIME_WAIT) 被动关闭(CLOSE_WAIT,LAST_ACK,CLOSED)
5 主动申请(SYNC_SENT,ESTABLISHED) 被动接受(SYNC_RECV,ESTABLISHED)
4 TIME_WAIT的危害
1 如果出现大量的TIME_WAIT,将导致大量的SOCKET端口被占用,然而LINUX的端口数量是有限的,可能导致后续的连接无法建立,没有端口可用
解决方式:linux开启TIME_WAIT的端口可重用性和快速回收机制,减少TIME_OUT的持续时间(默认是4MIN 2 * MSL)
十二 innodb_buffer_pool的构成
1 undo页 作用 1 事务提交/回滚支持,保证事务的完整性和一致性 2 进行purge旧版本的删除
2 data page页 作用 包含两种 1种是脏页 一种是正常页,为用户事务提供服务
3 dict info LRU的各种锁信息
4 data dictionary 数据字典信息
5 插入缓冲 作用 合并针对非一性索引的insert/update/delete操作 减少与磁盘IO的交互,针对的是索引页
6 自适应AHI 缓存指定的hash map,加速符合条件查询语句的查询速度
7 index page 索引页
十三 锁的介绍和构成
锁 类型: 表级锁 MDL锁 用户添加的表锁 由server控志
行级锁又分为 记录锁 间隙锁 NEXT-KEY_LOCK 插入意向锁 由innodb引擎负责
next-key-lock 由 记录锁+间隙锁组成,针对某些场景会进行优化,等值条件下 针对唯一性索引,退化成记录锁,针对非唯一性索引,退化成间隙锁,间隙锁锁定记录本身的左右区间,直到遇到符合条件的记录
锁模式: 读锁和写锁
锁行为 人为触发的锁操作显示锁 存储引擎默认加的锁被称为隐形锁
意向锁的目的 是为了让行锁和表锁共存.innodb的意向锁是表锁 可以和行锁共存 目的是增加读写并发性进行预判断
自增锁在事务提价前就被释放 提高并发性
十一 字符集限制
0 MySQL表具有65,535字节的最大行大小限制
1 更改列为 TEXT可以避免MySQL 65,535字节的行大小限制
2 如果包含可变长度列(例如:text)的InnoDB 行超过最大行大小,InnoDB选择可变长度列进行页外存储 5.7.9之前和之后由于row_format的变化,针对标准是不同的,5,6是768,5.7是3000+
3 对于变长类型的计算要+2 对于NULL还要+1,字符集为utf8的要X3,字符集为mb4要X4
十二 MVCC机制
1 多版本并发控制,是现代数据库(包括 MySQL
、Oracle
、PostgreSQL
等)引擎实现中常用的处理读写冲突的手段,目的在于提高数据库高并发场景下的吞吐性能。
2 核心不同的事务在并发过程中,SELECT
操作可以不加锁而是通过 MVCC
机制读取指定的版本历史记录,代替加行锁锁定
3 MVCC机制在RC和RR隔离级别上启动作用 区别在于事务中获得的不同的read-view,RC是每次都重新获得 而RR是事务一开始就只获得一次
4 innodb的每行都隐藏一个最新的trx_id,MVCC通过比较trx_id和READ_VIEW的相关范围实现版本读的控志,undo存放着历史版本
十三 如何构建恢复平台
1 每天对重要实例根据当天凌晨备份构建恢复实例 这样有两个好处 1 是测试备份的有效性 2是能加快数据的恢复 3 是能提供历史场景的数据查询
2 利用relay-log方式加速恢复增量数据
1 从库方式进行同步主库数据直到故障节点前,(推荐)
2 就是利用binlogserver做成伪装master,然后将从库change上去,其思想就是欺骗slave,让slave的io_thread将缺失的binlog拉取过来,sql_thread并行应用binlog event
start slave sql_thread until sql_before_gtids='9e912d2b-92f6-11e8-9747-0050568be82c:9791090' 同步到指定位点前
十四 如何避免微盟事件
1 构建多个节点 比如 一主-N从
2 历史备份数据保存在多地
3 关于历史备份的多地数据权限不能一个人全部有 要实现权限的分层管理 一个DBA管一部分
十五 rdb和aof
1 从文件体积
rdb 过程是生成快照,写到磁盘临时文件再进行覆盖原文件,体积较小,不能直接读取
aof 采用追加执行命令的方式写入aof文件中,会定期进行合并和压缩,体积较大,可以直接读取
2 从数据保存实时性
rdb rdb的数据实时保存有效性取决于如何设置单位时间内keys的变更阈值,在生成rdb期间的变更数据不会保留,所以rdb数据备份有效期取决于开始bgsave的时间 三种触发方式(参数,save,bgsave)
aof aof的数据实时保存有效性取决于如何设置fsync的刷新机制(1 每次命令 2 每秒 3 os周期性flush)
3 从对redis的影响
1 rdb和aof都会占用IO资源,一般IO上升基本都是在备份期间造成的 还有aof压缩命令 2 rdb和aof都是fork独立一个进程进行备份处理的
4 从数据恢复
rdb恢复的速度比aof的速度更快