10、binlog
binlog (归档日志):与刚才两个日志不同,它是 Server 层生成的日志,所有存储引擎都可以使用;它用于记录表结构和表数据的改动(也就是**记录 MySQL 上的所有变化 **并以二进制形式保存在磁盘上),所以不会记录查询操作,如SELECT、SHOW
-
binlog是再一条语句执行完了之后才生成的,等事务提交的时候,会将该事物执行过程中产生的 binlog 统一写 入 binlog 文件
-
写入磁盘的过程:
- 事务执行过程中,先把日志写到 binlog cache(Server 层的 cache),事务提交的时候,执行器再把 binlog cache 写到 binlog 文件中,并清空 binlog cache(一个事务的所有binlog,必须要保证一次性写入binlog cache和文件中):
(虽然每个线程有自己 binlog cache,但是最终都写到同一个 binlog 文件
-
MySQL提供一个 sync_binlog 参数来控制数据库的 binlog 刷到磁盘上的频率:
- sync_binlog = 0 (默认),表示每次提交事务都只 write,不 fsync,后续交由操作系统决定何时将数据持久化到磁盘;
- sync_binlog = 1 ,表示每次提交事务都会 write,然后马上执行 fsync;
- sync_binlog =N(N>1) ,表示每次提交事务都 write,但累积 N 个事务后才 fsync。
-
所以,参数为0时 风险最高,N时 风险其次,1 时 风险最低。但是性能:0>1>N。
-
如果能容少量事务的 binlog 日志丢失的风险,为了提高写入的性能,一般会 sync_binlog 设置为 100~1000 中的某个数值
-
易错点:
- **整个数据库的数据被删除了,此时要用 binlog 恢复。**因为binlog的数据是完整的,而由于redo log 文件采用 循环写,因为内存中有一部分脏页已经刷新到磁盘了,所以它们对应的redo log 就被覆盖了,也就是说,被覆盖过的redo log 已经不完整了,不能再还原整个数据库
-
主从复制
主从复制:将 binlog 中的数据从 主库 传输到 从库 上,这个过程是异步的(其他线程不会等它,即主库上执行事务操作的线程不会等待复制 binlog 的线程同步完成),从而让主库和从库的数据一模一样
-
具体过程:
主库:MySQL 主库在收到客户端提交事务的请求之后,会先写入 binlog,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功”的响应。
从库:
- 创建一个专门的 I/O 线程,连接主库的 log dump 线程,来接收主库的 binlog 日志,再把 binlog 信息写入 relay log 的中继日志里,再返回给主库“复制成功”的响应。
- 创建一个用于回放 binlog 的线程,去读 relay log 中继日志,然后 回放 binlog, 更新存储引擎中的数据,最终实现主从的数据一致性。
-
在完成主从复制之后,你就可以在写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执行
-
注意事项:
- 从库不是越多越好,如果从库增多,那么主库上的 log dump 线程 数量就会增多,同时从库连接过来的IO线程也比较多,从而增加对主库资源的消耗(一般,1 套数据库,1 主 2 从 1 备主)
- 除了异步、同步(性能很差)之外,还有一个半同步复制:介于两者之间,事务线程不用等待所有的从库复制成功响应,只要一部分复制成功响应回来就行。它兼顾了异步复制和同步复制的优点,即使出现主库宕机,至少还有一个从库有最新的数据,不存在数据丢失的风险
-