MySQL(六)

MySQL总结(六)日志

通用查询日志(General query log)

mysql> show variables like '%general%';
+------------------+---------------------------+
| Variable_name    | Value                     |
+------------------+---------------------------+
| general_log      | OFF                       |
| general_log_file | /var/lib/mysql/Lang01.log |
+------------------+---------------------------+
2 rows in set (0.01 sec)

默认是关闭的。主要记录用户的所有操作 ,包括启动和关闭MySQL服务、所有用户的连接开始时间和截止时间、发给服务器的所有 SQL 指令等。

Time                 Id Command    Argument
2023-07-03T11:39:15.084195Z         9 Query     SELECT * FROM employees
2023-07-03T11:40:43.317476Z         9 Query     SET global  general_log = off
set global general_log = on / off # 开启或关闭

set global general_log_file = 'path' #文件保存位置

慢查询日志(slow query log)

mysql> show variables like '%slow_query%';
+---------------------+--------------------------------+
| Variable_name       | Value                          |
+---------------------+--------------------------------+
| slow_query_log      | OFF                            |
| slow_query_log_file | /var/lib/mysql/Lang01-slow.log |
+---------------------+--------------------------------+
2 rows in set (0.01 sec)

慢查询的阈值

mysql> show variables like '%long_query%';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 | # 10s
+-----------------+-----------+
1 row in set (0.01 sec)
mysql > set global long_query_time = 1; #修改

错误日志(error log)

mysql> show variables like 'log_error%';
+----------------------------+----------------------------------------+
| Variable_name              | Value                                  |
+----------------------------+----------------------------------------+
| log_error                  | /var/log/mysqld.log                    |
| log_error_services         | log_filter_internal; log_sink_internal |
| log_error_suppression_list |                                        |
| log_error_verbosity        | 2                                      |
+----------------------------+----------------------------------------+
4 rows in set (0.01 sec)

可以用vim直接打开

==二进制日志(bin log)==

mysql> show variables like 'log_bin%';
+---------------------------------+-----------------------------+
| Variable_name                   | Value                       |
+---------------------------------+-----------------------------+
| log_bin                         | ON                          |
| log_bin_basename                | /var/lib/mysql/binlog       |
| log_bin_index                   | /var/lib/mysql/binlog.index |
| log_bin_trust_function_creators | OFF                         |
| log_bin_use_v1_row_events       | OFF                         |
+---------------------------------+-----------------------------+
5 rows in set (0.01 sec)

binlog日志的格式

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.01 sec)

一共有三种

Statement:每一条会修改数据的sql都会记录在binlog中。

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。

Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改。

优点:row level 的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题。

Mixed:实际上就是Statement与Row的,自动判断用哪种记录

写入机制

binlog的写入时机也非常简单,事务执行过程中,先把日志写到 binlog cache ,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

我们可以通过binlog_cache_size参数控制单个线程 binlog cache 大小,如果存储内容超过了这个参数,就要暂存到磁盘(Swap)。binlog日志刷盘流程如下:

alt
  • 上图的write,是指把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快
  • 上图的fsync,才是将数据持久化到磁盘的操作

write和fsync的时机,可以由参数 sync_binlog 控制,默认是 0

sync_binlog = 0,每次事务提交就会write(写入page cache)

sync_binlog = 1,表示每次提交事务都会执行fsync

sync_binlog = N(N>1),表示每次提交事务都write,但累积N个事务后才fsync。

binlog 和 redo的区别

  • redo log 它是 物理日志 ,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎层产生的。
  • 而 binlog 是 逻辑日志 ,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于 MySQL Server 层。
  • 虽然它们都属于持久化的保证,但是侧重点不同。
    • redo log让InnoDB存储引擎拥有了崩溃恢复能力。
    • binlog保证了MySQL集群架构的数据一致性。

两阶段提交

先介绍一下,redo log和 binlog的写入时机

redo log 是执行事务时不断写入

binlog 是事务提交后server层写入的

alt

那么就有一个问题?如果redo log 写入了,但是binlog写的时候,服务器出问题了,会发生什么

在主从复制的时候?会有问题

update table set c = 1 where id = 2;写入了redo,但是没有写入binlog,所以主服务器启动后会发现redo的值是 c =1,会改变。但是主服务器的binlog是c = 0,所以从服务器的c = 0。主从不一致

alt

针对这种情况,MySQL对redo采用两阶段提交。PreareCommit

alt

如果这时候,binlog写入时服务器异常,会发生什么?

重启服务器后,发现redo属于prepare阶段,也没有binlog,所以会直接回滚

如果reod log commit的时候异常,会发生什么?

重启服务器后,发现redo属于prepare,有binlog,提交事务

alt

本文由 mdnice 多平台发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值