MySQL日志详解
错误日志
MySQL的错误信息是在data目录下的
错误日志本身所定义的内容本身是可以定义的
编辑配置文件,定义错误日志:
log-error=/path/to/xx.err #定义是否启动错误日志的功能
log-warnings={1|0} #定义是否将警告信息也记录在错误日志中
而默认情况下错误日志也记录以下几个方面的消息:
1、服务器启动和关闭过程中的信息
未必是错误信息,比如mysql是如何去初始化存储引擎的过程记录在错误日志里等等
2、服务器运行过程中的错误信息
比如sock文件找不到,无法加载mysql数据库的数据文件,如果忘记初始化mysql或data dir路径找不到,或权限不正确等 都会记录在此
3、事件调度器运行一个事件时产生的信息
一旦mysql调度启动一个计划任务的时候,它也会将相关信息记录在错误日志中
4、在从服务器上启动从服务器进程时产生的信息
在复制环境下,从服务器进程的信息也会被记录进错误日志
一般情况下错误日志不会特别大,可以放心安全的开启,对于诊断服务器故障或问题也是非常有帮助的
如何定义mysql服务器错误日志相关功能:
mysql> showglobal variables like '%log%';
+-----------------------------------------+---------------------------------+
|Variable_name |Value |
+-----------------------------------------+---------------------------------+
| back_log | 50 |
|binlog_cache_size |32768 |
|binlog_direct_non_transactional_updates | OFF |
|binlog_format |MIXED |
|binlog_stmt_cache_size |32768 |
|expire_logs_days |0 |
| general_log | OFF |
|general_log_file |/mydata/data/localhost.log |
|innodb_flush_log_at_trx_commit |1 |
| innodb_locks_unsafe_for_binlog | OFF |
|innodb_log_buffer_size |8388608 |
|innodb_log_file_size |5242880 |
|innodb_log_files_in_group | 2 |
|innodb_log_group_home_dir |./ |
|innodb_mirrored_log_groups |1 |
| log | OFF |
| log_bin | ON |
|log_bin_trust_function_creators |OFF |
|log_error |/mydata/data/localhost.err |
| log_output | FILE |
|log_queries_not_using_indexes |OFF |
|log_slave_updates |OFF |
|log_slow_queries | OFF |
|log_warnings |1 |
|max_binlog_cache_size |18446744073709547520 |
|max_binlog_size |1073741824 |
|max_binlog_stmt_cache_size |18446744073709547520 |
|max_relay_log_size |0 |
| relay_log | |
|relay_log_index | |
|relay_log_info_file |relay-log.info |
|relay_log_purge |ON |
| relay_log_recovery | OFF |
|relay_log_space_limit |0 |
|slow_query_log |OFF |
|slow_query_log_file | /mydata/data/localhost-slow.log |
| sql_log_bin | ON |
| sql_log_off | OFF |
| sync_binlog | 0 |
|sync_relay_log |0 |
|sync_relay_log_info |0 |
+-----------------------------------------+---------------------------------+
41 rows in set(0.00 sec)
日志保存路径,默认路径为当前路径下的hostname.err
| log_error |/mydata/data/localhost.err |
将服务数据库服务的警告信息写入localhost.err里
| log_warnings | 1 |
通常errlog的配置参数一般是
log_error =/path/to/somefie
log_warnings ={1|0}
日志的相关功能是全局的,有些功能是静态定义的
[root@localhostdata]# pwd
/mydata/data
[root@localhostdata]# hostname
localhost
[root@localhostdata]# ll | grep err
-rw-r----- 1 mysqlroot 6220 Mar 31 14:32 localhost.err
-rw-r----- 1 mysqlroot 68129 Feb 26 09:30 test3.err
查看错误日志:
首先重启一下mysql服务进程,并观察错误日志:
[root@localhostdata]# tail -20 localhost.err
140331 14:32:02[Note] /usr/local/mysql/bin/mysqld: Shutdown complete
140331 14:32:02mysqld_safe mysqld from pid file /mydata/data/localhost.pid ended
140331 14:32:02mysqld_safe Starting mysqld daemon with databases from /mydata/data
140331 14:32:03[Note] Plugin 'FEDERATED' is disabled. #初始化存储引擎
140331 14:32:03InnoDB: The InnoDB memory heap is disabled #innodb禁用了堆功能
140331 14:32:03InnoDB: Mutexes and rw_locks use GCC atomic builtins #互斥量和行级锁是GCC编制的
140331 14:32:03InnoDB: Compressed tables use zlib 1.2.3
140331 14:32:03InnoDB: Using Linux native AIO
140331 14:32:03InnoDB: Initializing buffer pool, size = 128.0M #innodb存储引擎的缓冲池(buff poll)一般需要改的,而且需要改的特别大,一般8G内存分配给其5G都不足为过(专用于mysql场景)
因此可以观察此文件来观察缓冲池到底占用多少内存
140331 14:32:03InnoDB: Completed initialization of buffer pool
140331 14:32:03InnoDB: highest supported file format is Barracuda.
140331 14:32:03 InnoDB: Waiting for the background threads tostart
140331 14:32:04InnoDB: 5.5.33 started; log sequence number 2856278
140331 14:32:04[Note] Server hostname (bind-address): '0.0.0.0'; port: 3306 #服务已经运行并监听在本地0.0.0.0的 3306端口
140331 14:32:04[Note] - '0.0.0.0' resolves to'0.0.0.0'; #0.0.0.0反解失败
140331 14:32:04[Note] Server socket created on IP: '0.0.0.0'.
140331 14:32:04[Note] Event Scheduler: Loaded 0 events #时间调度器没有进行任何调度
140331 14:32:04[Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version:'5.5.33-log' socket:'/tmp/mysql.sock' port: 3306 MySQL Community Server (GPL) #mysql已经启动并在/tmp/目录下生成mysql.sock文件
查询日志
查询日志一般情况下mysql是没有启用的,因为mysql本身为关系型数据库,用户连接进数据库的时候,用户的一切行为 增删查改都会生成查询日志
insert查询为了避免数据冲突,如果此前插入过数据,而如果跟主键或唯一键的数据重复那肯定会报错
update时也会查询因为更新的时候很可能会更新某一块数据
delete查询,只删除符合条件的数据
因此都会产生日志,在并发操作非常多的场景下,查询信息会非常多,那么如果都记录下来会导致IO非常大 影响mysql性能,因此如果不是在调试环境下,是不建议开启查询日志功能的
mysql> showglobal variables like '%log%';
+-----------------------------------------+---------------------------------+
|Variable_name |Value |
+-----------------------------------------+---------------------------------+
| back_log | 50 |
| binlog_cache_size | 32768 |
|binlog_direct_non_transactional_updates | OFF |
|binlog_format |MIXED |
|binlog_stmt_cache_size | 32768 |
|expire_logs_days |0 |
| general_log | OFF |
|general_log_file |/mydata/data/localhost.log |
|innodb_flush_log_at_trx_commit |1 |
|innodb_locks_unsafe_for_binlog |OFF |
|innodb_log_buffer_size |8388608 |
|innodb_log_file_size |5242880 |
|innodb_log_files_in_group |2 |
|innodb_log_group_home_dir |./ |
|innodb_mirrored_log_groups |1 |
|log |OFF |
| log_bin | ON |
|log_bin_trust_function_creators |OFF |
| log_error |/mydata/data/localhost.err |
|log_output |FILE |
|log_queries_not_using_indexes |OFF |
|log_slave_updates |OFF |
|log_slow_queries |OFF |
| log_warnings | 1 |
| max_binlog_cache_size | 18446744073709547520 |
|max_binlog_size |1073741824 |
|max_binlog_stmt_cache_size |18446744073709547520 |
|max_relay_log_size | 0 |
| relay_log | |
|relay_log_index | |
|relay_log_info_file |relay-log.info |
|relay_log_purge |ON |
|relay_log_recovery |OFF |
|relay_log_space_limit |0 |
|slow_query_log |OFF |
|slow_query_log_file |/mydata/data/localhost-slow.log |
| sql_log_bin | ON |
| sql_log_off | OFF |
| sync_binlog | 0 |
|sync_relay_log |0 |
|sync_relay_log_info | 0 |
+-----------------------------------------+---------------------------------+
41 rows in set(0.30 sec)
查询日志保存路径
|general_log_file |/mydata/data/localhost.log |
是否开启日志功能,这里我们没有开启
| log | OFF |
定义日志输出保存位置,可以保存在文件中"FILE" 为保存在general_log_file文件上
也可以将其保存在表中TABLE (默认保存在mysql库中的general_log)
| log_output | FILE |
mysql> usemysql;
Database changed
mysql> showtables;
+---------------------------+
|Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| event |
| func |
| general_log |
|help_category |
| help_keyword |
|help_relation |
| help_topic |
| host |
|ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| proxies_priv |
| servers |
| slow_log |
| tables_priv |
| time_zone |
|time_zone_leap_second |
|time_zone_name |
|time_zone_transition |
|time_zone_transition_type |
| user |
+---------------------------+
24 rows in set(0.00 sec)
这两个值可以同时保存在文件和表中
总结:
查询日志就是记录了查询语句以及启动时间
涉及参数如下
log
log_out_putFILE,TABLE
general_log OFF
general_log_file/mydata/data/mysql.log
慢查询日志
慢查询日志中记录了市场,明确说明了哪个时间段执行和结束,中间执行了多长时间
对于非常繁忙的服务器,如果中途出现了查询速度非常慢的场景中,通常需要启动慢查询日志功能,慢查询日志对性能的影响微乎其微,但是可以详细记录了服务器上的慢查询,因此可以去定位服务器的瓶颈
涉及参数:
是否开启慢查询日志功能,建议开启,改为ON
slow_query_log OFF
保存慢查询日志的位置
slow_query_log_file /mydata/data/localhost-slow.log
mysql> showglobal variables like '%slow_quer%';
+---------------------+---------------------------------+
|Variable_name | Value |
+---------------------+---------------------------------+
|log_slow_queries | OFF |
|slow_query_log | OFF |
|slow_query_log_file | /mydata/data/localhost-slow.log |
+---------------------+---------------------------------+
3 rows in set (0.00sec)
查看并设置慢查询时间周期
mysql> showglobal variables like 'long%';
+-----------------+-----------+
|Variable_name | Value |
+-----------------+-----------+
| long_query_time |10.000000 |
+-----------------+-----------+
1 row in set (0.00sec)
单位为秒,默认时间超过十秒都叫做慢查询,我们可以修改这个值来定义慢查询的查询时长
语句执行超过十秒(无论是由于其他资源征用而导致被阻塞查询过程时间还是其他原因都被称为慢查询)
慢查询的时长:取决于命令从启动开始到执行结束,中途无论是因为什么原因,都是慢查询,并不是轮到语句执行超过X秒,哪怕没轮到它执行被阻塞
单位为秒,可以精确到微秒
将慢查询日志时间设置为毫秒级并执行操作语句,再去查看慢查询日志
开启慢查询:
mysql> setglobal slow_query_log=1;
Query OK, 0 rowsaffected (0.17 sec)
mysql> showglobal variables like '%slow_qu%';
+---------------------+---------------------------------+
|Variable_name | Value |
+---------------------+---------------------------------+
|log_slow_queries | ON |
|slow_query_log | ON |
|slow_query_log_file | /mydata/data/localhost-slow.log |
+---------------------+---------------------------------+
3 rows in set (0.00sec)
设置慢查询时间
mysql> setglobal long_query_time=0.000001;
Query OK, 0 rowsaffected (0.00 sec)
新建会话,并进行简单操作
[root@localhost ~]#mysql
mysql> showdatabases;
mysql> usetest1;
mysql> showtables;
由于调整的时间间隔极小,所以mysql认为每个操作都是慢查询,都一一记录了我们的操作过程,如下所示:
[root@localhost data]#tail -F localhost-slow.log
# Time: 14033115:50:21
# User@Host:root[root] @ localhost []
# Query_time:0.000093 Lock_time: 0.000000 Rows_sent:1 Rows_examined: 0
SETtimestamp=1396252221;
select@@version_comment limit 1;
# Time: 14033115:50:28
# User@Host:root[root] @ localhost []
# Query_time:0.030523 Lock_time: 0.029807 Rows_sent:10 Rows_examined: 10
SETtimestamp=1396252228;
show databases;
# Time: 14033115:50:59
# User@Host:root[root] @ localhost []
# Query_time:0.000084 Lock_time: 0.000000 Rows_sent:1 Rows_examined: 0
SETtimestamp=1396252259;
SELECT DATABASE();
# User@Host:root[root] @ localhost []
# Query_time:0.000029 Lock_time: 0.000000 Rows_sent:1 Rows_examined: 0
use test1;
SETtimestamp=1396252259;
# administrator command:Init DB;
# Time: 14033115:51:22
# User@Host:root[root] @ localhost []
# Query_time:0.000290 Lock_time: 0.000087 Rows_sent:1 Rows_examined: 1
SETtimestamp=1396252282;
show tables;
我们在数据库进行了4次操作,都一一被记录到日志里
[root@localhostdata]# grep 'Time' localhost-slow.log |wc -l
4
在配置文件配置慢查询
long_query_time = #
#如果服务器非常繁忙,经常会产生慢查询的话,那么日志量会非常大,那么需要手工去设置日志滚动功能
事物日志
事物日志是innodb专用功能,这里只考虑innod存储引擎
相关参数:
在事物提交时,innodb是否将缓冲到文件中同步,只要提交则立刻同步,同时又不会保证每个语句都同步,因此性能不会有特别大的影响
1 表示事物提交后同步,一般是每间隔1秒钟同步一次,就算有事物丢失那么最多就丢失1秒钟的数据 ,但是定义为1对mysql的性能影响特别大的,因为不管事物是否提交,每隔1秒钟都会去在同步一次数据,意味着每1秒就消耗一次IO 2一般只有事物提交才同步,尤其是事物量非常大的时候,性能是非常明显的,但是如果出现问题会丢失整个事物
|innodb_flush_log_at_trx_commit |1 |
| innodb_locks_unsafe_for_binlog |OFF |
定义内存空间的大小,万一都写在buffer里面,如果进程崩溃,也会丢失事物,因此避免这种情况,一旦事物提交了,那么需要立即同步到磁盘中,而不是间断同步,需要定义以下的参数:
|innodb_log_buffer_size |8388608 |
每个日志的单位大小为5MB,如果有些大数据的话,则需要将其调大,否则恢复起来会比较慢,但是太大了也会导致恢复比较慢
|innodb_log_file_size |5242880 |
在每个组里面提供2个文件,上面有提到过
|innodb_log_files_in_group |2 |
定义事物日志组的位置,一般来讲会有2个日志,一个写满后会重建立文件(达到轮询功能,写满后会同步到磁盘并将其清空)一般来讲,日志文件大小是固定的,凡是mysql已启动日志空间会在磁盘上立即分配,因为他们的主要功能是将随机IO转为顺序IO ,默认大小是每个文件为5MB,明确说明事物日志的路径保存在./ 表示在当前路径下
|innodb_log_group_home_dir |./ |
同一个日志文件对日志组做镜像,当然,需要存放在不同的磁盘上
|innodb_mirrored_log_groups |1 |
二进制日志 (binlog)
修改数据或有可能引起数据改变的mysql操作语句(select 等不会保存的)
mysql>show global variables like '%binlog%';
+-----------------------------------------+----------------------+
|Variable_name |Value |
+-----------------------------------------+----------------------+
|binlog_cache_size |32768 |
|binlog_direct_non_transactional_updates | OFF |
|binlog_format |MIXED |
|binlog_stmt_cache_size |32768 |
|innodb_locks_unsafe_for_binlog |OFF |
|max_binlog_cache_size |18446744073709547520 |
|max_binlog_size |1073741824 |
|max_binlog_stmt_cache_size | 18446744073709547520 |
|sync_binlog |0 |
+-----------------------------------------+----------------------+
9 rowsin set (0.00 sec)
|log_bin | ON |
显示为on 但是没有定义文件名和位置,表示其保存在默认路径下:
[root@localhost~]# cd /mydata/data/
[root@localhostdata]# ll -th | grep bin
-rw-rw----1 mysql mysql 7.3K Mar 31 16:20 mysql-bin.000056
-rw-rw----1 mysql mysql 133 Mar 31 14:32mysql-bin.index #索引文件
-rw-rw----1 mysql mysql 90K Mar 31 14:32 mysql-bin.000055
-rw-rw----1 mysql mysql 3.9K Mar 27 11:20 mysql-bin.000054
-rw-rw----1 mysql mysql 6.9K Mar 27 10:30 mysql-bin.000053
--------------------------------略---------------------------
查看文件类型,如下所示,明确显示了这是mysql服务的二进制文件
[root@localhostdata]# file mysql-bin.000056
mysql-bin.000056:MySQL replication log
再来看索引文件
[root@localhostdata]# file mysql-bin.index
mysql-bin.index: ASCII text
索引文件内包含的全都为二进制文件的当前路径
[root@localhostdata]# tail mysql-bin.index
./mysql-bin.000050
./mysql-bin.000051
./mysql-bin.000052
./mysql-bin.000053
./mysql-bin.000054
./mysql-bin.000055
./mysql-bin.000056
只要重启了mysql服务器它都会滚动
mysqldrestart
再次查看
[root@localhostdata]# tail -3 mysql-bin.index
./mysql-bin.000055
./mysql-bin.000056
./mysql-bin.000057
也可以在mysql里手动使其滚动
mysql>flush logs;
QueryOK, 0 rows affected (0.09 sec)
[root@localhostdata]# tail -3 mysql-bin.index
./mysql-bin.000056
./mysql-bin.000057
./mysql-bin.000058
所以二进制日志会不时的发生变化,并且越来越多,而且量也会越来越大,其主要作用是记录修改数据或有可能引起数据改变的mysql操作语句
对于非确定的数据纯粹记录语句会带来问题,因此2进制日志记录的格式有以下几种:
1、语句:默认记录就是语句本身
2、行 :以行数据方式记录
3、混合格式交替使用行和语句,如果语句不会产生错误信息,那么就使用混合格式,如果出现错误则使用行,至于使用哪种格式由mysql自行判断
基于行的记录方式数据量大,但是精确
基于语句记录方式很可能出现错误,比如使用mysql内置时间函数等
显示二进制日志文件有哪些
mysql>show binary logs;
+------------------+-----------+
|Log_name | File_size |
+------------------+-----------+
|mysql-bin.000050 | 1898 |
|mysql-bin.000051 | 18952 |
|mysql-bin.000052 | 14040 |
|mysql-bin.000053 | 6990 |
|mysql-bin.000054 | 3936 |
|mysql-bin.000055 | 91841 |
|mysql-bin.000056 | 7896 |
|mysql-bin.000057 | 150 |
|mysql-bin.000058 | 537 |
+------------------+-----------+
9 rowsin set (0.00 sec)
或者使用show master logs 与上面的效果是一样的
那么这么多二进制文件,我们不知道使用的是哪一个(一般最后一个)我们可以使用show master status 来查看当前二进制文件
mysql>show master status;
+------------------+----------+--------------+------------------+
|File | Position |Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
|mysql-bin.000058 | 537 | | |
+------------------+----------+--------------+------------------+
1 rowin set (0.01 sec)
#mysql-bin.000058 为当前使用的二进制日志文件
#537 为当前处于什么位置
日志位置
文件被打开之后,会将其记录很多信息,而每个语句在记录的时候为了告知主机在读取日志文件的时候,语句在什么时候执行什么时候结束以及语句的长度,每个记录下的信息,称为一个我二进制日志事件-Binary log event每个事件都有很多元数据信息(mata data),以及当前大小以及占据的空间,每个字节都有特定的位置,因此对于整个文件来讲,每个事件开始都有一个具体位置,很显然如果再记录一个事件,那么下一个事件也有了开头字节数了,而下一个事件有可能比上一个事件或长或短都是有可能的,因此每一次记录的时候所记录的位置都是上一个事件结束的位置,那么这个位置就是position,我们记录的position为537因此下一个就是537+1=538开始
每个事件都有开始的位置,每个事件在执行的时候都有执行时间,而这些元数据中也包含有当前时间等记录信息
查看记录了哪些事件
mysql>create database test2;
Query OK, 1 row affected (0.02 sec)
mysql> use test2
Database changed
mysql>create table tb1 (id INT);
QueryOK, 0 rows affected (0.06 sec)
mysql>insert into tb1 values (1);
Query OK, 1 row affected (0.00 sec)
再次查看
mysql>show master status;
+------------------+----------+--------------+------------------+
|File | Position |Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
|mysql-bin.000059 | 467 | | |
+------------------+----------+--------------+------------------+
1 rowin set (0.00 sec)
467就是意味着下次开始的时候以467的位置开始
显示binlog中事件
语法:SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,]row_count]
mysql>show binlog events in 'mysql-bin.000059';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------+
|Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------+
|mysql-bin.000059 | 4 | Format_desc| 1 | 107 | Server ver: 5.5.33-log, Binlogver: 4 |
|mysql-bin.000059 | 107 | Query | 1 | 192 | create database test2 |
|mysql-bin.000059 | 192 | Query | 1 | 281 | use `test2`; create table tb1(id INT) |
|mysql-bin.000059 | 281 | Query | 1 | 350 | BEGIN |
|mysql-bin.000059 | 350 | Query | 1 | 440 | use `test2`; insert into tb1values (1) |
|mysql-bin.000059 | 440 | Xid | 1 | 467 | COMMIT /* xid=22 */ |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------+
6 rowsin set (0.00 sec)
在位置000059中有以下几个事件:
|mysql-bin.000059 | 4 | Format_desc| 1 | 107 | Server ver: 5.5.33-log, Binlogver: 4 |
在第4个位置开始到第106个位置为头部信息
从位置107到191记录了第一个事件操作createdatabase test2
在位置192开始记录了第二个操作use `test2`; create table tb1(id INT)
位置281begin了一个事件
所以每个语句执行结束后都会向日志记录的,因此如果数据量非常庞大的话会影响性能下降的
也可以明确说明从哪个位置开始
比如从位置192开始并且显示2行,如下所示:
mysql>show binlog events in 'mysql-bin.000059' from 192 limit 2;
+------------------+-----+------------+-----------+-------------+----------------------------------------+
|Log_name | Pos | Event_type |Server_id | End_log_pos | Info |
+------------------+-----+------------+-----------+-------------+----------------------------------------+
| mysql-bin.000059| 192 | Query | 1 | 281 | use `test2`; create table tb1(id INT) |
|mysql-bin.000059 | 281 | Query | 1 | 350 | BEGIN |
+------------------+-----+------------+-----------+-------------+----------------------------------------+
2 rowsin set (0.00 sec)
(flush logs一般只会滚动中继日志和二进制日志i)
一般默认文件大小上限: 1G ,日志容量到达1G的时候会自动回滚日志
清除二进制日志的安全方法:
可以使用PURGE命令来删除之前的二进制日志(binlog)
PURGEBINARY LOGS TO 'mysql-bin.xxxxx;
PURGE BINARY LOGS BEFORE '20xx-0x-02 22:46:26';
备份之前必须将日志文件备份,备份完毕后再次确认,如果确实可以删除则使用以上命令进行删除
假设binglog备份文件已经备份到日志服务器中,当前本地的数据库日志已经确保无误可以删除
如下所示:
备份
[root@localhostdata]# cp mysql-bin.0000* /tmp/
备份数据库:
mysqldump-u root -p'123456' -A > /tmp/bak.sql
接下来就可以清除无用的日志了
[root@localhost data]# tail -5 mysql-bin.index
./mysql-bin.000056
./mysql-bin.000057
./mysql-bin.000058
./mysql-bin.000059
./mysql-bin.000060
删除000056之前的二进制文件
mysql>purge binary logs to 'mysql-bin.000056';
QueryOK, 0 rows affected (0.01 sec)
再次查看
[root@localhostdata]# cat mysql-bin.index
./mysql-bin.000056
./mysql-bin.000057
./mysql-bin.000058
./mysql-bin.000059
./mysql-bin.000060
删除某一事件之前的信息
mysql>show binlog events in 'mysql-bin.000060' limit 10;
先来看10行,可以看到有很多的事件信息,我们可以根据其事件时间来进行删除
定义二进制格式日志:
#设置二进制存储路径,不需要加后缀,有了这个参数之后 mysql数据库会自动为我们日志信息加后缀并且按照增量的方式命名,比如some_file001那么下次回滚就是some_file002.. ..以此类推
log-bin= /path/to/some_log_file
#设置二进制日志格式,指定mixed
|binlog_format | MIXED |
# binlog基于语句的格式缓存大小 ,默认值为32768
|binlog_stmt_cache_size |32768 |
#设置日志过期时间,能够自动清除二进制格式,比如expire_logs_days = 100 那么自动清除100天之前的二进制格式,如果确定x天之前的日志没有用 则可以清除,否则需要保留因为2进制日志十分重要
|expire_logs_days |0 |
#刚开始启动必要功能的时候直接分配32768的内存空间,由binlog_cache_size参数进行定义,如果需要更大的话,那么18446744073709547520 则为最大上限空间
|max_binlog_cache_size |18446744073709547520 |
#设置日志文件大小,一个日志文件一旦达到这个数值则自动滚动,比如500mb 则使用500*1024*104最后得出值
|max_binlog_size | 1073741824 |
#设置实时将缓存中数据同步到硬盘中,在事物提交时是否将事件从缓存刷新至磁盘中,建议开启此功能,但对服务器可导致性能略微下降,但是更能够保证二进制日志中数据的安全,一般这种代价是无论如何都值得的
|sync_binlog
#设置会话级别的变量,当前用户执行操作不想记录二进制可以使用此参数将其关闭,其作用为控制会话级别二进制功能的开启或关闭
|sql_log_bin | ON |
#setsession sql_log_bin=0
然后插入数据或创建表,并执行show binlog events in 'mysql-bin.0000x' 查看是否存在日志
mysqlbinlog 命令
mysqlbinlog直接在命令行直接去操作二进制文件
建议对日志操作之前先将其flush logs 滚动一次再对其进行编辑
查看二进制日志内容信息
[root@localhostdata]# mysqlbinlog mysql-bin.000060 |more
#文件头
/*!50530SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019SET @@session.max_insert_delayed_threads=0*/;
/*!50003SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER/*!*/;
#初始化版本信息
#用户通过mysql服务器进行通告
# at 4 #结束的位置
#14033116:07:45 server id 1 end_log_pos 107 Start: binlog v 4, server v 5.5.33-log created140331 16:07:45 at startup
#Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG'
USI5Uw8BAAAAZwAAAGsAAAABAAQANS41LjMzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABRIjlTEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA==
'/*!*/;
#真正的事件是从107开始的
# at107 #开始处,表明了上一个事件结束的时候开始
#14033116:10:01 server id 1 end_log_pos 177Querythread_id=1exec_time=0error_code=0
#server id : 用在复制场景中避免循环复制而设定的,任何服务器只是从其复制读取非自己服务器的事,#因此每个mysql server都有自己的server id 每个server id 都为1
#end_log_pos 177: 结束的位置,显示的结束位置是下个事件开始的位置
#Query : 查询语句
thread_id=1: 会话线程创建的语句
exec_time=0 : 执行时长,单位为秒
error_code=0: 错误代码 0为没有错误
#环境预设再下面就是sql语句了
SETTIMESTAMP=1396253401/*!*/;
SET@@session.pseudo_thread_id=1/*!*/;
SET@@session.foreign_key_checks=1, @@session.sql_auto_is_null=0,@@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET@@session.sql_mode=0/*!*/;
SET@@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\Clatin1 *//*!*/;
SET@@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET@@session.lc_time_names=0/*!*/;
SET@@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
#到176处结束,并在177位置处开始信的事件
# at177
#14033116:10:01 server id 1 end_log_pos 205 Intvar
SETINSERT_ID=2606/*!*/;
# at205
以二进制日志文件对其删除数据并进行简单的恢复
首先刷新日志信息,以一个新的二进制日志位置开始方便我们实验
mysql>flush logs;
QueryOK, 0 rows affected (0.00 sec)
查看二进制日志位置
mysql>show master status;
+------------------+----------+--------------+------------------+
|File | Position |Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
|mysql-bin.000061 | 1023 | | |
+------------------+----------+--------------+------------------+
1 rowin set (0.00 sec)
新建数据库并插入表
mysql>create database test3;
QueryOK, 1 row affected (0.01 sec)
mysql>use test3;
Databasechanged
mysql>create table tb1(id INT);
QueryOK, 0 rows affected (0.02 sec)
mysql> insert into tb1 values (1);
QueryOK, 1 row affected (0.00 sec)
查看数据库,并将我们新建立的数据库删除
mysql>show databases;
+--------------------+
|Database |
+--------------------+
|information_schema |
|Syslog |
|mydb |
|mydb2 |
|mydbl |
|mysql |
|performance_schema |
|test |
|test1 |
| test2 |
| test3 |
|wpdb |
+--------------------+
12 rowsin set (0.00 sec)
mysql>drop database test3;
QueryOK, 1 row affected (0.31 sec)
恢复:
恢复之前最好让日志再次刷新一次 方便我们操作
mysql>show master status;
+------------------+----------+--------------+------------------+
|File | Position |Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
|mysql-bin.000061 | 8579 | | |
+------------------+----------+--------------+------------------+
1 rowin set (0.00 sec)
mysql>flush logs;
QueryOK, 0 rows affected (0.01 sec)
mysql>show master status;
+------------------+----------+--------------+------------------+
|File | Position |Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
|mysql-bin.000062 | 565 | | |
+------------------+----------+--------------+------------------+
1 rowin set (0.00 sec)
使用mysqlbinlog命令将二进制日志文件转为sql语句方式并编辑
[root@localhostdata]# mysqlbinlog mysql-bin.000061 > ./huifu.sql
在位置6206我们看到刚才执行的删除操作:
# at6206
#14033117:11:47 server id 1 end_log_pos6289 Query thread_id=3 exec_time=1 error_code=0
SETTIMESTAMP=1396257107/*!*/;
dropdatabase test3
/*!*/;
接下来将此条信息删除并保存
导入数据库
mysql>source /mydata/data/huifu.sql
再次查看数据库
mysql>show databases;
+--------------------+
|Database |
+--------------------+
|information_schema |
|Syslog |
|mydb |
|mydb2 |
|mydbl |
|mysql |
|performance_schema |
|test |
|test1 |
|test2 |
| test3 |
|wpdb |
+--------------------+
12 rowsin set (0.01 sec)
进入数据库查看表是否存在
mysql>show tables;
+-----------------+
|Tables_in_test3 |
+-----------------+
|tb1 |
+-----------------+
1 rowin set (0.00 sec)
查看数据是否存在
mysql>select * from tb1;
+------+
|id |
+------+
| 1 |
+------+
1 rowin set (0.00 sec)