提高篇:
1.MySQL是怎么保证主备一致的:
主备切换流程:
在状态 1 中,客户端的读写都直接访问节点 A,而节点 B 是 A 的备库,只是将 A 的更新都同步过来,到本地执行。这样可以保持节点 B 和 A 的数据是相同的。当需要切换的时候,就切成状态 2。这时候客户端读写访问的都是节点 B,而节点 A 是 B的备库。在状态 1 中,虽然节点 B 没有被直接访问,但是我依然建议你把节点 B(也就是备库)设置成只读(readonly)模式。这样做,有以下几个考虑:
有时候一些运营类的查询语句会被放到备库上去查,设置为只读可以防止误操作;
防止切换逻辑有 bug,比如切换过程中出现双写,造成主备不一致;
可以用 readonly 状态,来判断节点的角色。需要注意的一点就是,将备库设置成了只读,对超级 (super) 权限用户是无效的,而用于同步更新的线程,就拥有超级权限
节点 A 到 B 这条线的内部流程是什么样的:
在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及 要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。
在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。
主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog,发给 B。
备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)。
sql_thread 读取中转日志,解析出日志里的命令,并执行。
binlog三种格式对比:一些资料上讲binlog 有两种格式,一种是 statement,一种是row。可能你在其他资料上还会看到有第三种格式,叫作 mixed,其实它就是前两种格式的混合
binlog_format=statement 时,binlog 里面记录的就是 SQL 语句的原文。 但是statement 格式的 binlog 可能会导致主备不一致。
row 格式的 binlog 里没有了 SQL 语句的原文,而是替换成了两个 event:Table_map 和 Delete_rows , Table_map event,用于说明接下来要操作的表是 test 库的表 t; Delete_rows event,用于定义删除的行为(将binlog格式设置row, 我们在解决数据库幻读的时候使用过)当 binlog_format 使用 row 格式的时候,binlog 里面记录了真实删除行的主键 id,这样 binlog 传到备库去的时候,不会有主备删除不同行的问题。
第三种形式mixed:为什么会有 mixed 这种 binlog 格式?因为 statement 格式的 binlog 可能会导致主备不一致 ,所以要使用 row 格式。但 row 格式的缺点是,很占空间,同时写 binlog 也要耗费 IO 资源,影响执行速度 ,于是就是使用折中的方法,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用row 格式,否则就用 statement 格式 ,这就是mixed格式 。(mixed 格式 和 statement格式都是不常用的,常用就是row格式方便恢复数据)
2. join的使用和优化:
能不能使用 join 语句?
如果可以使用 Index Nested-Loop Join 算法,也就是说可以用上被驱动表上的索引,其实是没问题的;
如果使用 Block Nested-Loop Join 算法,扫描行数就会过多。尤其是在大表上的 join操作,这样可能要扫描被驱动表很多次,,比较次数等于两个表参与 join 的行数的乘积,会占用大量的系统资源。所以这种 join 尽量不要用。所以你在判断要不要使用 join 语句时,就是看 explain 结果里面,Extra 字段里面有没有出现“Block Nested Loop”字样。
如果要使用 join,应该选择大表做驱动表还是选择小表做驱动表?
如果是 Index Nested-Loop Join 算法,应该选择小表做驱动表;
如果是 Block Nested-Loop Join 算法:在 join_buffer_size 足够大的时候,是一样的;在 join_buffer_size 不够大的时候(这种情况更常见),应该选择小表做驱动表。所以,这个问题的结论就是,总是应该使用小表做驱动表。
什么是小表:在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表
3. 自增主键为什么不连续:
自增主键出现不连续的原因:
唯一键冲突是导致自增主键 id 不连续的第一种原因
,事务回滚也会产生类似的现象,这就是第二种原因。
为什么上面的两种原因会出现自增主键不连续的问题:
首先MySQL 这么设计是为了提升性能,要是先判断表中是否是存在这个id,存在就跳过的话,成本非常的高,需要去主键引树上判断 id 是否存在,会影响性能。
把自增 id 的锁范围扩大,必须等到一个事务执行完成并提交,下一个事务才能再申请自增 id。这个方法的问题,就是锁的粒度太大,系统并发能力大大下降,也会影响性能。
相关文章:
2021-08-05
2021-07-20
2021-06-07
2021-05-30
2021-11-13
2021-11-29
2022-02-05
2022-01-01
猜你喜欢
2021-11-19
2022-12-23
2022-02-09
2022-03-08
2022-12-23
2022-12-23
相关资源
下载
2023-01-10
下载
2022-11-30
下载
2023-01-19