MySQL实战
2021-12-22 14:14:57 26 举报
AI智能生成
极客时间-《MySQL 实战 45 讲》林晓斌 思维导图笔记
作者其他创作
大纲/内容
慢sql
只查一行也慢
mysql数据库本身被堵住了
网络、系统资源
长时间不返还
等MDL锁
show processlist;
等flush
等行锁
rr下,为了数据一致性,有大量回滚
表中数据导致,回表次数庞大
短连接风暴
关掉占着连接不工作的线程
减少连接过程的消耗
跳过权限验证:重启数据库,并使用-skip-grant-tables参数启动,慎用
查询慢
索引没有设计好
索引没生效
sql语句没写好
query_rewrite
mysql选错了索引
应急方案:force index
QPS突增
如果业务方会下掉业务,从白名单去掉sql
单独数据库用户的话,删掉账户
查询重写成select 1返回,慎用
主备
主备延迟
主备延迟 T3-T1
- 主库A执行完一个事务,写入binlog,记为T1时刻
- 之后传给备库B,备库B接收完这个binlog的时刻记为T2
- 备库B执行完这个事务,这个时刻记为T3
备库 show slave status
seconds_behind_master 表示当前备库延迟了多少秒
每个事务的binlog都有一个时间字段,用于记录主库上写入的时间
备库取出当前正在执行的事务的时间字段的值,计算它与当前系统时间的差值,得到second_behind_master
原因
备库服务器比主机差
主库和从库的参数配置不一样
备库压力大
备库上在进行备份操作
表上无主键的情况
设置的延迟备库
备库空间不足
主库DML语句并发大,从库QPS高
大事务
一次性用delete删除大量数据
大表DDL
建议使用gh-ost方案
备库的并行复制策略
MySQL5.5
按表分发策略
按行分发策略
MySQL5.6
按库分发策略
MariaDB
组提交
- 再一组里面一起提交的事务,有一个相同的commit_id,下一组就是commit_id+1;
- commit_id直接写到binlog里面;
- 传到备库应用的时候,相同commit_id的事务分发到多个worker执行;
- 这一组全部执行完成后,coorinator再去取下一批
MySQL5.7
slave-parallel-type
配置为DATABASE,使用MySQL5.6版本的按库并行策略
配置为LOGICAL_CLOCK,表示使用类似MariaDB的策略
思想
- 同时处于prepare的事务,在备库执行时是可以并行的;
- 处于prepare状态的事务,与处于commit状态的事务之间,在备库执行时也是可以并行的
MySQL5.7.22
基于WRITESET
binlog-transaction-dependency-tracking
COMMIT_ORDER,根据同时进入prepare和commit来判断是否可以并行
WRITESET,对于事务涉及更新的每一行,计算出这行的hash值,组成集合writeset。如果这两个事务没有操作相同的行,也就是它们的writeset没有交集,就可以并行
WRITESET_SESSION,是在WRITESE的基础上多了一个约束,即在主库上同一个线程先后执行的两个事务,在备库执行的时候,要保证相同的先后顺序
双M
循环复制
主库更新事务后用set global server_id=x修改了server_id
三个节点
主备切换
可靠性优先策略
- 判断备库B现在的seconds_behind_master,如果小于某个值,比如5s,继续下一步,否则持续重试这一步;
- 把主库A改成只读状态,即把readonly设置为true;
- 判断备库B的second_behind_master的值,直到这个值变成0为止;
- 把备库B改成可读写状态,也就是把readonly设置成false;
- 把业务请求切到备库B。
可用性优先策略
过期读
强制走主库方案
将必须要拿到最新结果的请求强制发到主库;
将可以读到旧数据的请求发到从库
将可以读到旧数据的请求发到从库
sleep方案
主库更新后,读从库之前先sleep一下,让主从间同步
判断主备无延迟方案
每次从库查询前,先判断seconds_behind_master是否已经为0,如果还不为0,就等待此参数变为0
对比位点确保主备无延迟
show slave status
show slave status
Master_log_File和Read_Master_Log_Pos,表示的是读到的主库的最新位点
Relay_Master_Log_File和Exec_Master_Log_Pos,表示的是备库执行的最新位点
对比GTID集合确保主备无延迟
show slave status
show slave status
Auto_Position=1,表示这对主备关系使用了GTID协议
Retrieved_Gtid_Set,是备库收到的所有日志的GTID集合
Executed_Gtid_Set,是备库所有已经执行完成的GTID集合
配合semi-sync方案
- 事务提交的时候,主库把binlog发给从库;
- 从库收到binlog以后,发回给主库一个ack,表示收到了;
- 主库收到这个ack以后,才能给客户端返回“事务完成”的确认
等主库位点方案
select master_pos_wait(file,pos[,timeout])
在从库执行,参数file和pos是主库上的文件名和位置,timeout参数可选,设置为正整数N表示这个函数最多等待N秒。正常返回结果是一个正整数M,表示从命令开始执行,到应用完file和pos表示的binlog位置,执行了多少事务。如果执行期间备库同步线程发生异常返回NULL,如果等待超过N秒,返回-1,如果刚开始执行的时候,就发现已经执行过这个位置了,则返回0
1、trx1事务更新完成后,马上执行show master status得到当前主库执行到的File和Position;
2、选定一个从库执行查询语句;
3、在从库上执行select master_pos_wait(File,Position1):
4、如果返回值是大于等于0的正整数,则在这个从库执行查询语句;
5、否则,到主库执行查询语句
2、选定一个从库执行查询语句;
3、在从库上执行select master_pos_wait(File,Position1):
4、如果返回值是大于等于0的正整数,则在这个从库执行查询语句;
5、否则,到主库执行查询语句
等GTID方案
select wait_for_executed_gtid_set(gtid_set,1)
等待,直到这个库执行的事务中包含传入的gtid_set,返回0;
超时返回1
超时返回1
1、trx1事务更新完成后,从返回包直接获取这个事务的GTID,记为gtid1;
2、选定一个从库执行查询语句;
3、在从库上执行select wait_for_executed_gtid_set(gtid_set,1)
4、如果返回值是0,则在这个从库执行查询语句;
5、否则,到主库执行查询语句
2、选定一个从库执行查询语句;
3、在从库上执行select wait_for_executed_gtid_set(gtid_set,1)
4、如果返回值是0,则在这个从库执行查询语句;
5、否则,到主库执行查询语句
如何让返回包带GTID?
将参数session_track_gtids设置为OWN_GTID,然后通过API接口mysql_session_track_get_first从返回包中解析出GTID的值即可
误删数据
误删行
Flashback
修改binlog的内容,拿到原库重放。前提是binlog_format=row和binlog_row_imagFULL
误删表/库
全量备份+增量备份
防范
延迟复制备库
账号分离
制定操作规范
把待删除表加后缀做改名,观察一段时间后再删除,并且只能删除特定后缀表
备份脚本
执行脚本
验证脚本
回滚脚本
通过chatrr +i命令给所有重要的文件增加i权限属性
join
如果可以使用被驱动表的索引,join语句还是有其优势
不能使用被驱动表的索引,只能使用Block Nested-Loop Join算法,这样的语句尽量不要使用
在使用join的时候,应该让小表做驱动表
小表做驱动表
小表N行,大表M行
Index Nested-Loop Join
优化
MRR
会在join_buffer进行主键排序,然后去主键索引树上一个个的查找,因为按照主键顺序去主键索引树上查找,性能较高,MRR优化接近顺序读,性能会比较高
BKA
一次取出一批数据的字段到join_buffer中,然后批量join,性能会比较好。依赖MRR,因为批量join找到被驱动表的非聚集索引字段通过MRR去查找行数据。
Simple Nested-Loop Join
Block Nested-Loop Join
问题
可能会多次扫描被驱动表,占用磁盘IO资源
判断join条件需要执行M*N次对比(M、N分别是两张表的行数),如果是大表就会占用非常多的CPU资源
可能会导致Buffer Pool的热数据被淘汰,影响内存命中率
优化
转成BKA,加索引
创建使用临时表
临时表
建表语法是create temporary table...
一个临时表只能被创建它的seesion访问,对其他线程不可见,session结束后会自动删除临时表。
临时表可以与普通表同名
session A内有同名的临时表和普通表的时候,show create语句,以及增上改查语句访问的是临时表
show tables 命令不显示临时表
临时表frm存在临时目标下,#sql{进程id}_{线程id}_序列号.frm,使用select @@tmpdir查看临时文件位置
内存临时表
什么时候使用
- 语句执行过程不可以一边读数据一边直接得到结果,需要额外内存;
- join_buffer是无序数组,sort_buffer是有序数组,临时表是二维表结构;
- 如果执行逻辑需要用到二维表特性,就会优先考虑使用临时表
group by
- 如果对group by的结果没有排序要求,要在语句后面加order by null;
- 尽量让group by过程用上索引,确认方法是explain结果里没有Using temporary和Using filesort;
- 如果group by需要统计的数据量不大,尽量只使用内存临时表,可以通过适当调大tmp_table_size参数来避免用到磁盘临时表;
- 如果数据量大,使用SQL_BIG_RESULT来告诉优化器直接使用排序算法得到group by的结果
自增id
自增id不连续
唯一键冲突
回滚
批量申请自增id,按照1,2,4,8翻倍递增申请,没用到的就会空了
自增id上限
表的自增id达到上限后,再申请时它的值就不会改变,进而导致继续插入数据时报主键冲突的错误
row_id达到上限后,则会归0再重新递增,如果出现相同的row_id,后写的数据会覆盖之前的数据
Xid只需要不在同一个binlog文件中出现重复值即可。虽然理论上会出现重复值,但是概率极小,可以忽略不计
InnoDB的max_trx_id递增值每次MySQL重启都会被保存起
thread_id达到上限后会归0再递增,底层有代码逻辑去判断不冲突使用
逻辑架构
日志系统
Innodb特有日志 redolog
write pos代表当前记录位置,一边写一边后移;checkpoint代表当前要擦除的位置,擦除记录前把记录更新到数据文件,擦除后后移
如果write pos追上checkpoint,就没有记录空间了,需要把checkpoint向后推进擦除一些记录
redo log保证数据库发生异常重启时之前提交的记录不会丢失,这个能力成为crash-safe
物理日志,循环写,记录页做了什么改动
innodb_flush_log_at_trx_commit
0
每次事务提交时都只是把redo log留在redo log buffer中
1
每次事务提交都将redo log直接持久化到磁盘
2
每次事务提交时都只是把redo log写到page cache
Server层日志 binlog
事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中
一个事务的binlog不论多大,都要确保一次性写入,不能被拆分开
系统给每个binlog cache分配一片内存,每个线程一个,binlog_cache_size控制单个线程内binlog cache所占内存大小,若超过参数大小,就暂存到磁盘。
事务提交的时候,执行器把binlog cache里的完整事务写入到binlog中,并清空binlog cache
逻辑日志,追加写
两种模式,statement格式会记录sql语句,row格式记录行的内容,记两条,更新前和更新后
sync_binlog
0
每次提交事务都把日志写到文件系统的page cache,不持久化到磁盘
1
每次提交事务都把日志写到文件系统的page cache,并且持久化到磁盘
N
每次提交事务都把日志写到文件系统的page cache,累积N个事务后持久化到磁盘
binlog组提交
binlog_group_commit_sync_delay
表示延迟多少微秒后才调用fsync
binlog_group_commit_sync_no_delay_count
表示累积多少次以后才调用fsync
XA-2PC (two phase commit, 两阶段提交 )
prepare 阶段
InnoDB Prepare阶段。此时SQL已经成功执行,并生成事务ID(xid)信息及redo和undo的内存日志。此阶段InnoDB会写事务的redo log,但要注意的是,此时redo log只是记录了事务的所有操作日志,并没有记录提交(commit)日志,因此事务此时的状态为Prepare。此阶段对binlog不会有任何操作
commit 阶段
第一步写binlog(先调用write()将binlog内存日志数据写入文件系统缓存,再调用fsync()将binlog文件系统缓存日志数据永久写入磁盘);
第二步完成事务的提交(commit),此时在redo log中记录此事务的提交日志(增加commit 标签)。
崩溃恢复
如果数据库在记录此事务的binlog之前和过程中发生crash。数据库在恢复后认为此事务并没有成功提交,则会回滚此事务的操作。与此同时,因为在binlog中也没有此事务的记录,所以从库也不会有此事务的数据修改。
如果数据库在记录此事务的binlog之后发生crash。此时,即使是redo log中还没有记录此事务的commit 标签,数据库在恢复后也会认为此事务提交成功(因为在上述两阶段过程中,binlog写入成功就认为事务成功提交了)。它会扫描最后一个binlog文件,并提取其中的事务ID(xid),InnoDB会将那些状态为Prepare的事务(redo log没有记录commit 标签)的xid和Binlog中提取的xid做比较,如果在Binlog中存在,则提交该事务,否则回滚该事务。这也就是说,binlog中记录的事务,在恢复时都会被认为是已提交事务,会在redo log中重新写入commit标志,并完成此事务的重做(主库中有此事务的数据修改)。与此同时,因为在binlog中已经有了此事务的记录,所有从库也会有此事务的数据修改。
IO瓶颈
设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count参数,减少binlog的写盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但没有丢失数据的风险。
将sync_binlog设置为大于1的值,比较常见是100-1000。风险是主机掉电时会丢binlog日志
将innodb_flush_log_at_trx_commit设置为2。风险是主机掉电时会丢数据
事务隔离
隔离级别
读未提交
一个事务还没提交时,它做的变更就能被其他事务看到
别人改数据的事务尚未提交,我在我的事务中也能读到
读已提交
一个事务提交后,它做的变更才会被其他事务看到
别人改数据的事务已经提交,我在我的事务中才能读到
可重复读
一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致。
别人改数据的事务已经提交,我在我的事务中也不去读
可重复读的核心是一致性读,开启事务时建立视图,后面读的数据都从视图中读。更新数据都是先读后写,读的是当前值,称为“当前读”。如果当前记录的行锁被其他事务占用的话,就需要进入锁等待
Innodb的行数据有多个版本,每个数据版本有自己的row trx_id,每个事务或者语句有自己的一致性视图。普通查询语句是一致性读,一致性读会根据row trx_id和一致性视图确定数据版本的可见性
对于可重复读,查询只承认在事务启动前就已经提交完成的数据
对于读提交,查询只承认在语句启动前就已经提交完成的数据
串行化
对于同一行记录,写会加写锁,读会加读锁。当读写锁冲突时,后访问的事务必须等前一个事务完成
我的事务尚未提交,别人就别想改数据
示例
读未提交
V1 2,V2 2,V3 2
事务B虽然没提交,但是已经被A看到了
读已提交
V1 1,V2 2,V3 2
事务B的更新在提交后才能被A看到
可重复读
V1 1,V2 1,V3 2
之所以V2还是1,是因为事务在执行期间看到的数据必须前后一致
串行化
V1 1,V2 1,V3 2
在事务B执行将1改成2时,会被锁住。直到事务A提交后事务B才能继续执行,从A角度看V1、V2是1,V3是2
oracle默认rc,mysql默认rr
show variables like 'transaction_isolation'
查看长事务
select * from information_schema.innodb_trx where time_to_sec(timediff(now(),trx_started))>60
Innodb支撑RC和RR隔离级别实现是用的一致性视图(Consistent read view)
事务在启动时会排一个快照,这个快照是基于整个库的
基于整个库的意思是说一个事务内,整个库的修改对该事务都是不可见的。如果在事务内select t表,另外的事务执行了DDL t表,根据发送的时间,要么锁住要么报错
事务是如何实现的MVCC的
每个事务都有一个事务ID,叫做transaction id,严格递增
事务在启动时,找到已提交的最大事务ID记为up_limit_id
事务在更新一条语句时,比如id=1改为id=2,会把id=1和该行之前的row trx_id写到undo log里,并且在数据页上把id的值改为2,并且把修改这条语句的transaction id记到该行行头
再定一个个规矩,一个事务要查看一条数据时,必须先用该事务的up_limit_id<transaction id,则只能去undo log去取,去undo log查找数据的时候,也需要做比对,必须up_limit_id>transaction id,才返回数据
什么是当前读
当前读都是先读后写,只能读当前值,会更新事务内的up_limit_id为该事务的transaction id
为什么RR能实现可重复读而RC不能
快照读的情况下,RR不能更新事务内的up_limit_id,而RC每次都会把up_limit_id更新为快照读之前最新已提交事务的transaction id,则RC不能可重复读
当前读的情况下,RR是利用record + gap lock 来实现的,而RC没有gap,所以RC不能可重复读
索引
索引模型
哈希表
有序数组
搜索树
Innodb使用
索引类型
主键索引
叶子节点存的正行数据,聚簇索引
非主键索引
主键的值,二级索引
索引优化
覆盖索引
select的数据列只用从索引中就能够取得,不必读取数据行
将被查询的字段,建立到联合索引(如果只有一个字段,普通索引也可以)里去。
前缀索引
节省空间
会增加查询成本
select count(distinct email) from user;
select count(distinct left(email,4)),count(distinct left(email,5)),count(distinct left(email,6)) from user;
select count(distinct left(email,4)),count(distinct left(email,5)),count(distinct left(email,6)) from user;
不能使用覆盖索引
索引下推
读取索引记录(不是完整的行记录);
判断WHERE条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;
条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);
唯一索引与普通索引的选择
普通索引和唯一索引在读性能上相差无几,由于普通索引还需要多做一些检索和判断操作,性能稍差,但可忽略,因为大概率这些操作是在内存中的数据页上进行操作的
普通索引和唯一索引在写性能上也相差无几,由于唯一索引要做唯一性校验,性能稍差,并且不能利用changebuffer来优化性能
change buffer
只限于普通索引,适用于写多读少及写后延迟读的场景,如账单类、日志类
如果所有的更新后面都马上伴随着对这个记录的查询,那么应该关闭change buffer
对唯一索引/主键索引不适用,因为它们需要唯一性的判断,需要将数据及时拿到内存中
针对的操作包括增加、修改、删除
记录的是数据操作的历史记录
本质是一个B+树,存在共享表空间中,使用changebuffer后可能导致innodb_buffer_pool的使用内存变大
merge的合并时机
master线程每隔1秒或10秒刷新,随机选取changebuffer的叶子节点进行merge操作
插入changebuffer后,立即执行了读取操作
changebuffer的空间不满足要求时(当检测到插入的数据大于制定叶的容量限度时)
增大区分度
例如身份证号,前缀区分度不明显,后缀明显
倒序存储
使用hash字段
在表上多创建一个字段来保存身份证的校验码,同时在这个字段上创建索引,以增加区分度
缺点:没法范围查找
重建主键索引
alter table T engine=InnoDB
索引失效
条件字段函数操作
select count(*) from tracelog where month(createtime)=7;
隐式类型转换
转换规则
字符串->数字
select * from tracelog where traceid=11011;
traceid是varchar类型
traceid是varchar类型
实际执行select * from tracelog where CAST(traceid AS signed int)=11011;
隐式字符编码转换
select * from trace_detail where CONVERT(traceid USING utf8mb4)=d.traceid;
utf8mb4是utf8的超集,utf8会转utf8mb4。自动转换的时候,为了避免数据在转换过程中由于截断导致数据错误,都是按数据长度增加的方向转换
数据量太少,系统觉得没必要走索引
走索引不比全表扫描代价低
in()中的数量>全表总行数x9.3%
锁
全局锁
全局读锁 Flush Tables with read lock(FTWRL)
场景:全库逻辑备份
表级锁
表锁
lock tables ...read/write
lock tables 语法除了会限制别的线程读写外,也限定了本线程接下来的操作对象
元数据锁MDL
当对一个表做增删改查操作时,加MDL读锁;当对表结构做变更操作时,加MDL写锁
读锁之间不互斥,可以多个线程同时对一张表做增删改查
读写锁之间、写锁之间互斥。
行锁
间隙锁
next-key lock
间隙锁+行锁
前开后闭
抖动
刷脏页
出现的原因
redo log写满了。系统停止所有更新操作,把checkpoint往前推进,给redo log留出空间
系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是脏页,就要先将脏页写到磁盘
MySQL认为系统空闲的时候
MySQL正常关闭的情况。MySQL会把内存的脏页都flush到磁盘上,这样下次MySQL启动的时候,就可以直接从磁盘上读取数据,启动速度会很快。
mysql5.6开始引入了page cleaner线程,专门负责刷脏
innodb_io_capacity
建议设置成磁盘的IOPS
刷盘速度
脏页比例
innodb_max_dirty_pages_pct 脏页比例上限,默认75%
show status like 'Innodb_buffer_pool_pages%';
Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total
innodb_flush_neighbors
InnoDB用来控制buffer pool刷脏页时是否把脏页邻近的其他脏页一起刷到磁盘
如果MySQL服务器磁盘是传统的HDD存储设备,打开该参数,能够减少I/O磁盘寻道的开销,提高性能,而对于SSD设备,寻道时间的性能影响很小,关闭该参数,反而能够分散写操作,提高数据库性能。由于SSD设备的普及,MySQL 8.0 将该参数的默认值由1调整为0。
5.7版本为1, 8.0版本为0
redo log写盘速度
刷脏算法
flush-list(依据时间管理缓冲池中更改页面的列表)
flush-list(依据时间管理缓冲池中更改页面的列表)
LRU-list(用于管理缓冲池中非常用页面的列表)
innodb_file_per_table(独立表空间)
共享表空间
某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下。 默认的文件名为:ibdata1 初始化为10M。
优点:可以将表空间分成多个文件存放到各个磁盘上(表空间文件大小不受表大小的限制,如一个表可以分布在不同的文件上)。数据和文件放在一起方便管理。
缺点:所有的数据和索引存放到一个文件中,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日值系统这类应用最不适合用共享表空间。
独立表空间
每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件。 其中这个文件包括了单独一个表的数据内容以及索引内容,默认情况下它的存储位置也是在表的位置之中。
优点:
1.每个表都有自已独立的表空间。
2.每个表的数据和索引都会存在自已的表空间中。
3.可以实现单表在不同的数据库中移动。
4.空间可以回收(除drop table操作处,表空不能自已回收)
a.Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。
b.对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。
c.对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。
1.每个表都有自已独立的表空间。
2.每个表的数据和索引都会存在自已的表空间中。
3.可以实现单表在不同的数据库中移动。
4.空间可以回收(除drop table操作处,表空不能自已回收)
a.Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。
b.对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。
c.对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。
缺点:单表增加过大,如超过100个G。
共享表空间转化为独立表空间的两种方法
先逻辑备份,然后修改配置文件my.cnf中的参数innodb_file_per_table参数为1,重启服务后将逻辑备份导入即可。
修改配置文件my.cnf中的参数innodb_file_per_table参数为1,重启服务后将需要修改的所有innodb表都执行一遍:alter table table_name engine=innodb;
原来库中的表中的数据会继续存放于ibdata1中,新建的表才会使用独立表空间
事务锁
information_schema.innodb_trx
trx_id as 事务ID,
trx_state as 事务状态,
trx_started as 事务开始时间,
trx_requested_lock_id as 事务需要等待的资源,
trx_wait_started as 事务开始等待时间,
trx_mysql_thread_id as 事务线程id,
trx_query as 具体SQL语句,
trx_operation_state as 事务当前操作状态,
trx_tables_in_use as 使用表数量,
trx_tables_locked as 拥有锁数量,
trx_lock_memory_bytes as 锁住内存大小,
trx_rows_locked as 事务锁住的行数,
trx_rows_modified as 事务更改的行数,
trx_concurrency_tickets as 事务并发票数,
trx_unique_checks as 是否唯一性检查,
trx_foreign_key_checks as 是否外键检查,
trx_last_foreign_key_error as 最后的外键错误
trx_state as 事务状态,
trx_started as 事务开始时间,
trx_requested_lock_id as 事务需要等待的资源,
trx_wait_started as 事务开始等待时间,
trx_mysql_thread_id as 事务线程id,
trx_query as 具体SQL语句,
trx_operation_state as 事务当前操作状态,
trx_tables_in_use as 使用表数量,
trx_tables_locked as 拥有锁数量,
trx_lock_memory_bytes as 锁住内存大小,
trx_rows_locked as 事务锁住的行数,
trx_rows_modified as 事务更改的行数,
trx_concurrency_tickets as 事务并发票数,
trx_unique_checks as 是否唯一性检查,
trx_foreign_key_checks as 是否外键检查,
trx_last_foreign_key_error as 最后的外键错误
information_schema.innodb_locks
lock_id as 锁ID,
lock_trx_id as 拥有锁的事务ID,
lock_mode as 锁模式,
lock_type as 锁类型,
lock_table as 被锁的表,
lock_index as 被锁的索引,
lock_space as 被锁的表空间号,
lock_page as 被锁的页号,
lock_rec as 被锁的记录号,
lock_data as 被锁的数据
lock_trx_id as 拥有锁的事务ID,
lock_mode as 锁模式,
lock_type as 锁类型,
lock_table as 被锁的表,
lock_index as 被锁的索引,
lock_space as 被锁的表空间号,
lock_page as 被锁的页号,
lock_rec as 被锁的记录号,
lock_data as 被锁的数据
information_schema.innodb_lock_waits
requesting_trx_id as 请求锁的事务ID,
requested_lock_id as 请求锁的锁ID,
blocking_trx_id as 当前拥有锁的事务ID,
blocking_lock_id as 当前拥有锁的锁ID
requested_lock_id as 请求锁的锁ID,
blocking_trx_id as 当前拥有锁的事务ID,
blocking_lock_id as 当前拥有锁的锁ID
0 条评论
下一页