ToB企服应用市场:ToB评测及商务社交产业平台
标题:
高性能MySQL(第4版) 第一章 MySQL架构 读书笔记
[打印本页]
作者:
大号在练葵花宝典
时间:
2022-11-9 14:35
标题:
高性能MySQL(第4版) 第一章 MySQL架构 读书笔记
这本书去年11月出的,今年中文版也出了,并且直接上了
微信读书
,之后有空就读一读,分享下读书笔记~
原文内容比较充实,建议有时间可以读一下原文.
第一章主要是个概览.
MySQL的逻辑架构
默认情况下,每个客户端连接都会在服务器进程中拥有一个线程,该连接的查询只会在这个单独的线程中执行,该线程驻留在一个内核或者CPU上.
线程池
优化器会向存储引擎询问它的一些功能、某个具体操作的成本,以及表数据的统计信息.
query cache 5.7.20弃用 8.0移除
考虑应用自己在redis中缓存
并发控制
只要有多个查询需要同时修改数据,就会产生并发控制问题
读写锁
处理并发读/写访问的系统通常实现一个由两种锁类型组成的锁系统
这两种锁通常被称为共享锁(shared lock)和排他锁(exclusive lock),也叫读锁(read lock)和写锁(write lock)
锁的粒度
通过降低锁的粒度提高共享资源并发性
只锁定包含需要修改的部分数据
表锁
table lock
最基本 开销最小的锁策略(锁本身的开销 不是指查询/修改性能)
行级锁
row lock
最大程度支持并发处理 最大的锁开销
行级锁是在存储引擎中实现
事务
事务就是一组SQL语句,作为一个工作单元以原子方式进行处理
要么全部执行成功 要么全部执行失败
ACID
隔离级别
这里谈的是ANSI SQL中的定义
READ UNCOMMITTED: 未提交读
在事务中可以查看其他事务中还没有提交的修改
脏读(dirty read): 读取未提交的数据
READ COMMITTED: 已提交读
大多数数据库系统的默认级别
但MySQL不是
一个事务可以看到其他事务在它开始之后提交的修改,但在该事务提交之前,其所做的任何修改对其他事务都是不可见的.
允许不可重复读(nonrepeatable read) 同一个事务中两次执行相同语句 可能看到不同结果
REPEATABLE READ: 可重复读
解决了不可重复读
无法解决幻读(phantom read) 读取范围数据时 如果另一个事务在该范围插入了新的 再次读取会产生换行(phantom row)
InnoDB和XtraDB通过MVCC解决
这也是MySQL默认的隔离级别
SERIALIZABLE: 可串行化
该级别通过强制事务按序执行,使不同事务之间不可能产生冲突,从而解决了前面说的幻读问题.
会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题.
使用场景较少 除非需要严格确保数据安全 并且接收并发性能下降
死锁
两个或多个事务相互持有和请求相同资源上的锁,产生了循环依赖.
当多个事务试图以不同的顺序锁定资源时会导致死锁.
数据库系统实现了各种是说检测和锁超时机制
InnoDB目前处理死锁的方式是将持有最少行级排他锁的事务回滚
锁的行为和顺序和存储引擎相关
console1:
start transaction ;
update user set user_name='cc11' where user_id=1;
update user set user_name='cc22' where user_id=2;
commit ;
复制代码
console2:
start transaction ;
update user set user_name='cc222' where user_id=2;
update user set user_name='cc111' where user_id=1;
commit ;
复制代码
单步执行
[40001][1213] Deadlock found when trying to get lock; try restarting transaction
复制代码
事务日志
事务日志有助于提高事务的效率.存储引擎只需要更改内存中的数据副本,而不用每次修改磁盘中的表,这会非常快.
事务日志只追加 顺序I/O
WAL write-ahead logging 预写日志 修改数据最终要两次磁盘写入
MySQL中的事务
描述的是InnoDB引擎中的事务
理解AUTOCOMMIT
默认开启 单个语句也是包裹在事务中 自动提交
可以通过set autocommit=0/1进行开关
用begin或者start transaction来开启事务
用commit提交 rollback回滚
有一些命令,当在活动的事务中发出时,会导致MySQL在事务的所有语句执行完毕前提交当前事务
比如一些DDL命令 alter table等
可以通过SET TRANSACTION ISOLATION LEVEL改变隔离级别 下一个事务开始时生效
在事务中混合使用存储引擎
MySQL的事务由下层存储引擎实现
在同一个事务中,混合使用多种存储引擎是不可靠的.
隐式锁定和显式锁定
InnoDB使用两阶段锁定协议(two-phase locking protocol).
事务执行期间,随时都可以获取锁,但锁只有在提交或回滚后才会释放,并且所有的锁会同时释放.
前面描述的锁定机制都是隐式的.InnoDB会根据隔离级别自动处理锁.
显式的(不属于SQL规范)
SELECT … FOR SHARE
SELECT … FOR UPDATE
复制代码
MySQL还支持LOCK TABLES和UNLOCK TABLES
这两个命令在服务器级别实现
因为InnoDB支持行级锁 没必要使用
建议: 除了在禁用AUTOCOMMIT的事务中可以使用之外,其他任何时候都不要显式地执行LOCK TABLES,不管使用的是什么存储引擎.
多版本并发控制
MySQL的大多数事务型存储引擎使用的都不是简单的行级锁机制.它们会将行级锁和可以提高并发性能的多版本并发控制(MVCC)技术结合使用.
不同数据库的实现细节不一样
可以认为MVCC是行级锁的一种变种 它在很多情况下避免加锁 因此开销更低
通过数据快照实现
InnoDB为每个事务启动时分配一个事务ID
该事务修改记录时 向Undo log写入一条如何恢复回去的undo记录 事务回滚指针指向该记录
当不同会话读取聚簇主键索引记录时 InnoDB会把记录的事务ID和该会话的读取视图比较 如果更改他的事务未提交 则跟踪undo log直到一个符合可见条件的事务ID
大多数读取通过这种方式不需要获取锁(通过读取快照) 缺点是存储引擎会对每一行存储更多数据 做更多工作
MVCC仅适用于REPEATABLE READ和READ COMMITTED隔离级别.
(可以想象对于可重复读 读取的事务id固定为事务进行中第一次读的可见事务id 对于读已提交 读最新的可见事务id
另外两个因为不需要事务版本(一个是脏读 一个是串行化的) 和MVCC不是很适配(当然要看不同引擎的实现)
复制
Replication
一主多从
数据文件结构
在8.0版本中,MySQL将表的元数据重新设计为一种数据字典,包含在表的.ibd文件中
使得表结构上的信息支持事务和原子级数据定义更改
除了以来information_schema检索表定义和元数据
引入了字典对象缓存 LRU的内存缓存
使得服务器访问表的元数据减少了I/O
每个表的.ibd和.frm文件被替换为已经被序列化的字典信息(.sdi).
InnoDB引擎
为处理大量短期事务而设计 这些事务预期通常是正常提交 很少会被回滚
默认情况下,InnoDB将数据存储在一系列的数据文件中,这些文件统被称为表空间(tablespace)
InnoDB使用MVCC来实现高并发性,并实现了所有4个SQL标准隔离级别.
默认为REPEATABLE READ隔离级别,并且通过间隙锁(next-key locking)策略来防止在这个隔离级别上的幻读:
InnoDB不只锁定在查询中涉及的行,还会对索引结构中的间隙进行锁定,以防止幻行被插入
基于聚簇索引构建
但是,因为二级索引(secondary index,非主键索引)需要包含主键列,如果主键较大,则其他索引也会很大.如果表中的索引较多,主键应当尽量小.
微信读书:
https://weread.qq.com/web/bookDetail/00a32b70813ab746fg018ec7
博客位置:
https://bingowith.me/2022/11/08/high-performance-mysql-4th-ch01-note/
博客:
https://bingowith.me
出处:
http://www.cnblogs.com/fairjm/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4