补充问题
- socket变成
- 堆排序
- 链表反转
- docker原理 dockerfile编写
- k8s 原理 pod设计
- openstack trove设计模式
一个update到mysql,里面执行的流程是什么。 从庫为什么有延迟,一般怎么处理。 用户抱怨数据库性能差,怎么回复用户,有什么改进,预防的措施。 为什么添加索引会加快查询,加索引有什么注意的地方,mysql为什么会选错索引。 单机和集群是如何保证数据不丢的
sql语句流程
####################################################################################################
客户端
连接器 连接器负责跟客户端建立连接、获取权限、维持和管理连接 和客户端完成TCP握手后 连接器开始认证身份,然后到权限表查询该用户的权限
查询缓存
- 如果能够查询到缓存 直接返回 不建议 失效比较频繁,
- 在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空
- 8.0已经禁掉了
分析器: 对SQL语句做解析
- 负责词法分析, 识别sql语句中的每个字符 字段代表什么
- 语法分析 判断sql语句是否满足mysql语法
优化器: 选择最优的执行方案
- 表里面有多个索引的时候,决定使用哪个索引
- 有多表关联(join)的时候,决定各个表的连接顺序
执行器
- 判断操作的这个表有没有权限 没有就直接返回错误
- 有权限 就打开表继续执行
存储引擎
- 执行器就会根据表的引擎定义,去使用这个引擎提供的接口
update语句流程 #################################################################################################### create table T(ID int primary key, c int); update T set c=c+1 where ID=2;
- 执行器调用innodb的接口 找这一行数据, 如果数据页在内存中 直接返回; 如果不在内存 从磁盘读取到内存
- 执行器拿到接口返回的这行数据, 对数据进行操作 更新完这行数据 再调用接口写入这行新数据
- innodb引擎将这个更新操作记录到redo log, 此时redolog处于prepare状态 告诉执行器更新完成, 随时可以提交事务
- 执行器生成对应的binlog 写入磁盘
- 执行器调用innodb的接口 提交事务, innodb把刚才的redolog状态改为commit
redolog binlog区别? ####################################################################################################
这两种日志有以下三点不同。 redo log 是 InnoDB 引擎特有的; binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
redo log 是物理日志,记录的是“在某个数据页上做了什么修改”; binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
redo log 是循环写的,空间固定会用完; binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
从庫为什么有延迟,一般怎么处理。? #################################################################################################### 主库binlog到备库的操作很快 主备延迟很有可能是在从库重放relay日志慢造成的
-
备库所在机器的性能要比主库所在的机器性能差 备库所在的服务器还有其他的实例 io竞争较大 解决方法: 对称部署
-
主库写操作, 备库读操作, 备库查询压力太大 cpu消耗太大 解决方法: 一主多从 多接几个从库分担压力 binlog 输出到外部系统, 比如 Hadoop 这类系统,让外部系统提供统计类查询的能力
-
大事务 主库执行时间太长 必须等主库提交事务 才把binlog写入
(1)比如一次delete大量的数据 解决方法: 低峰期 分多批次删除
(2)大表ddl 解决方法: 计划内的 DDL,建议使用 gh-ost 方案
- 备库的并行复制能力 mysql5.6 安库并行
为什么添加索引会加快查询,加索引有什么注意的地方,mysql为什么会选错索引。 #################################################################################################### 为什么添加索引会加快查询?
聚集索引:以主键创建的索引;聚集索引的叶子节点存储的是表中的数据; 非聚集索引:非主键创建的索引;非聚集索引在叶子节点存储的是主键和索引列;使用非聚集索引查询数据,会查询到叶子上的主键,再根据主键查到数据(这个过程叫做回表) 怎么解决回表 用覆盖索引
加索引有什么注意的地方?
原则: 频繁使用的列 频繁表连接的列 where语句 where语句中有多个and字段的 可以考虑复合索引 索引的选择要注意区分度 越高越好 优先小的字段, 可以考虑前缀索引 节省空间,但会增加查询扫描次数,并且不能使用覆盖索引; 创建hash字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。
表上的索引不能太多 经常插入、删除、修改的表少建索引 对复合索引,按照字段在查询条件中出现的频度建立索引 删除不再使用,或者很少被使用的索引
mysql为什么会选错索引? 没能准确地判断出扫描行数(analyze table 命令,可以用来重新统计索引信息) (1) 优化器选择基数最大 区分度最高的索引, 因为是采样统计,索引的基数不准确 会有误差 (2) 预计扫描行数 使用普通索引 计算回表的代价
解决方法: (1)force index 强行选择一个索引 (2)order by (3)如果索引没有用 那就删掉误选的索引
事务隔离级别 #################################################################################################### 未提交读:一个事务可以读取到,另外一个事务尚未提交的变更。 已提交读:一个事务提交后,其变更才会被另一个事务读取到。 可重复读:在一个事务执行的过程中所读取到的数据,和事务启动时所看到的一致。 串行化:当操作一行数据时,读写分别都会加锁。当出现读写锁互斥时,会排队串行执行
用户抱怨数据库性能差,怎么回复用户,有什么改进,预防的措施。 ####################################################################################################
预先发现问题? 上线前,在测试环境,把慢查询日志(slow log)打开,并且把 long_query_time 设置成 0,确保每个语句都会被记录入慢查询日志; 在测试表里插入模拟线上的数据,做一遍回归测试; 观察慢查询日志里每类语句的输出,特别留意 Rows_examined 字段是否与预期一致。
单机和集群是如何保证数据不丢的 ####################################################################################################
单机设置双1 binlog写入机制 事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中
sync_binlog选择: sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync; sync_binlog=1 的时候,表示每次提交事务都会执行 fsync; sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。 如果主机发生异常重启,会丢失最近 N 个事务的 binlog 日志
redolog 先写入redo log buffer 在写入redologfile innodb_flush_log_at_trx_commit 参数 设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ; 设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘; 设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到 page cache
索引相关
- 04 | 深入浅出索引(上)
- 05 | 深入浅出索引(下)
- 09 | 普通索引和唯一索引,应该怎么选择?
- 10 | MySQL为什么有时候会选错索引?
- 11 | 怎么给字符串字段加索引?
- 15 | 答疑文章(一):日志和索引相关问题
- 16 | “order by”是怎么工作的?
- 18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?
事务相关
- 03 | 事务隔离:为什么你改了我还看不见?
- 08 | 事务到底是隔离的还是不隔离的?
- 20 | 幻读是什么,幻读有什么问题?
锁相关
- 06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
- 07 | 行锁功过:怎么减少行锁对性能的影响?
- 19 | 为什么我只查一行的语句,也执行这么慢?
- 20 | 幻读是什么,幻读有什么问题?
- 21 | 为什么我只改一行的语句,锁这么多?
- 30 | 答疑文章(二):用动态的观点看加锁
- 40 | insert语句的锁为什么这么多?
日志与主备相关
- 02 | 日志系统:一条SQL更新语句是如何执行的?
- 12 | 为什么我的MySQL会“抖”一下?
- 23 | MySQL是怎么保证数据不丢的?
- 24 | MySQL是怎么保证主备一致的?
- 25 | MySQL是怎么保证高可用的?
- 26 | 备库为什么会延迟好几个小时?
- 27 | 主库出问题了,从库怎么办?
- 28 | 读写分离有哪些坑?
- 29 | 如何判断一个数据库是不是出问题了?
- 31 | 误删数据后除了跑路,还能怎么办?
临时表相关
- 17 | 如何正确地显示随机消息?
- 34 | 到底可不可以使用join?
- 35 | join语句怎么优化?
- 36 | 为什么临时表可以重名?
- 37 | 什么时候会使用内部临时表?
- 43 | 要不要使用分区表?
实用性归类
- 14 | count(*)这么慢,我该怎么办?
- 32 | 为什么还有kill不掉的语句?
- 33 | 我查这么多数据,会不会把数据库内存打爆?
- 41 | 怎么最快地复制一张表?
- 44 | 答疑文章(三):说一说这些好问题
- 45 | 自增id用完怎么办?
- 38 | 都说InnoDB好,那还要不要使用Memory引擎?
红黑树和AVL
B B+
juejin.cn/post/684490… juejin.cn/post/684490… zhuanlan.zhihu.com/p/77383599
111 917
stack由编译器分配和释放 存放函数的参数和局部变量
heap 由程序员分配和释放