基本信息
binary log有两个基本作用:
1/在复制时,将主服务器上的变化提供给从服务器。
2/某些数据进行恢复时需要二进制日志文件。
如果需要打开binary log 功能,只要启动时设置log_bin[=base_name]即可。如果没有指定base_name,那么将会使用pid_file的值作为base_name,如果base_name有扩展名(比如centos.binlog)那么.binlog将默认会被移除,只保留centos。mysqld会追加一串数字到base_name后面,每生成一个文件,这个数字就会加一。有三种情况会生成新的文件,1/打开或者重启,2/flush logs,3/当前binlog的大小达到max_binlog_size。
为了追踪binlog文件使用的情况,mysqld会创建一个与binlog名字一样,但是扩展名是.index的文件。可以使用log_bin_index[=file_name]来修改名称。这不是一个动态参数,不可以在mysqld启动的时候修改。该文件是文本格式。
binlog记录的方式有三种,statement,row,mixed。
statement:基于sql语句的记录。
row:把行的变化记录到日志文件中,这需要表中有主键来确定某个具体的行。
mixed:默认使用statement,遇到以下情况会自动转换成row
1/一个在NDBCLUSTER表上执行的DML语句
2/包括UUID()的函数
3/有自动增长列的表调用存储过程或者触发器。
4/涉及可加载函数的调用
5/当使用FOUND_ROWS() ,ROW_COUNT(), USER(),CURRENT_USER(),CURRENT_USER时(这些是bug)
6/当语句涉及到系统变量时(Bug #31168)
7/涉及到mysql库当中的表时
如果在主从复制进行的过程中修改binlog的记录方式,改变会导致从库使用statement的方式进行记录,主库使用row/mixed的方式记录,这可能导致某些问题。
不可以在运行时修改binlog_format的情况:
1/在存储过程或者触发器内
2/使用了NDB存储引擎
3/基于行复制时,打开了一个临时表
statement的方式可能有些语句没法复制到从库,例如使用limit的update,delete,但是却没有使用order by,还有now()函数,但是row的格式是可以复制到从库的。大部分语句都是可以通过row的格式复制到从库,除了两种情况
1/对于mysql系统库的操作,例如grant,revoke,使用的是基于statement的格式
2/create table … select 语句,create table 使用的是statement的格式,插入数据使用的是row格式
对于临时表,mysql只会用基于语句的方式记录,不会使用基于行的方式记录。如果使用了mixed,一般会用基于语句的的方式记录,如果在加载数据时使用了UUID()函数,则不会记录。
对于不同的存储引擎,大部分存储引擎支持statement格式以及row格式,如果使用innodb表,且事务的隔离级别是READ COMMITED,READ UNCOMMITED,binlog_format只能使用row。如果是example,NDB,则只支持row。
关于 flush logs
其他可以执行flush logs的方法:
mysqladmin flush-logs, mysqladmin refresh, mysqldump —flush-logs, or mysqldump —master-data
如果binlog已经打开了,执行flush logs会关闭当前的binlog文件,并使用下一个序列号重新打开一个binlog文件。
如果打开了一般查询以及慢查询,执行flush logs会关闭当前文件并重新打开。
如果开启了错误日志的记录,执行flush logs会关闭并重新打开错误日志文件。
如果想让general log,slow_log,error_log重新生成新的文件,需要将他们的名字重命名,然后再flush logs。
shell>cd mysql-data-directoryshell>mv mysql.log mysql.log.oldshell>mv mysql-slow.log mysql-slow.log.oldshell>mv err.log err.log.oldshell>mysqladmin flush-logs
如果需要在运行时重命名general_log,slow_log的文件名,需要先禁用general_log,slow_log,然后重命名,最后再打开。
mysql> SET GLOBAL general_log = 'OFF';
mysql> SET GLOBAL slow_query_log = 'OFF';
mysql> set global general_log_file='/data/logs/general.log';
mysql> set global slow_query_log_file='/data/logs/slow.log';
mysql> SET GLOBAL general_log = 'ON';
mysql> SET GLOBAL slow_query_log = 'ON';
管理操作
打开log_bin:
这个变量只能在参数文件中配置,或者在启动时手动添加—log_bin
[mysqld]
log_bin=centos7
设置全局binlog_format:
修改global变量需要SUPER权限
mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';
设置会话binlog_format:
mysql> SET SESSION binlog_format = 'STATEMENT';
mysql> SET SESSION binlog_format = 'ROW';
mysql> SET SESSION binlog_format = 'MIXED';
删除binlog:
1/可以设置expire_logs_days,到期自动删除,如果启动了这个变量,那么需要保证binlog已经被复制到从库
2/使用PURGE BINARY LOGS 手动删除,但是需要BINLOG ADMIN权限,有两种方式删除,一种是指定名称,一种是指定日期。
mysql> PURGE BINARY LOGS TO 'mysql-bin.010'; --删除010之前的所有binlog
mysql> PURGE BINARY LOGS BEFORE '2021-05-26 17:46:26'; --删除到指定日期之前的所有binlog
mysql> show slave status; --查看从库正在使用的binlog
mysql> show binary logs; --主从复制中查看主库正在使用的binlog
删除binlog之前最好备份一下,也要确认要删除的binlog是否在使用。删除binlog时会把binlog文件,以及.index文件中相关的内容都删除。如果删除的时候,.index文件在操作系统端被删除了,那么关于purge的两个语句都会报错。
如果删除的时候.index不在了,可以手工建一个,把相关的binlog都写到.index文件中。然后再执行purge binary logs
[root@centos7 data]# cat centos7.index
./centos7.000002
./centos7.000003
.....
相关参数
max_binlog_size
| Command-Line Format | —max-binlog-size=# |
|---|---|
| System Variable | max_binlog_size |
| Scope | Global |
| Dynamic | Yes |
| Type | Integer |
| Default Value | 1073741824 |
| Minimum Value | 4096 |
| Maximum Value | 1073741824 |
| Block Size | 4096 |
这个变量控制写入到binlog文件的大小。默认是1G。如果有一个大事务,那么这个文件的大小有可能超过一个G。
log_bin_index
| Command-Line Format | —log-bin-index=file_name |
|---|---|
| System Variable | log_bin_index |
| Scope | Global |
| Dynamic | No |
| Type | File name |
设置binlog索引文件的名称。默认情况下是跟log_bin的参数相同,名字相同(后缀不同),路径相同。
sql_log_bin
| System Variable | sql_log_bin |
|---|---|
| Scope | Session |
| Dynamic | Yes |
| Type | Boolean |
| Default Value | ON |
这个变量控制是否将当前会话的二进制日志记录到文件中。
当你不想把某些变化从主库复制到从库时,可以将这个变量临时打开。
不可以在事务或者子查询中设置该变量。
如果使用GTIDs来进行复制,如果开启这个变量,从开启的那一刻开始,事务都会丢失。
global 的sql_log_bin是只读的,不可以改变,这个变量已经弃用,会在以后的版本中删除。
binlog_format
| Command-Line Format | —binlog-format=format |
|---|---|
| System Variable | binlog_format |
| Scope | Global, Session |
| Dynamic | Yes |
| Type | Enumeration |
| Default Value | ROW |
| Valid Values | ROW STATEMENT MIXED |
在5.7.7之前默认值是STATEMENT,5.7.7之后,默认值是ROW。在NDB集群里,默认值是mixed,且不支持statement
expire_logs_days
| Command-Line Format | —expire-logs-days=# |
|---|---|
| System Variable | expire_logs_days |
| Scope | Global |
| Dynamic | Yes |
| Type | Integer |
| Default Value | 0 |
| Minimum Value | 0 |
| Maximum Value | 99 |
这个变量控制多少天后会自动删除binlog。默认是不开启的。
