MySQL日志记录每个操作详情(mysql下日志)
MySQL日志:记录每个操作详情
在MySQL数据库中,日志是一个非常重要的概念。当我们需要追踪某些SQL语句的执行情况,或者需要恢复意外删除的数据时,日志起到了至关重要的作用。MySQL中提供了多种日志模式,如二进制日志、慢查询日志、错误日志等。其中,二进制日志是最为常用的日志模式,本文将会介绍如何记录MySQL的每个操作详情。
一、启用二进制日志
要启用MySQL的二进制日志,我们需要在MySQL配置文件my.cnf中加入以下内容:
[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
其中log-bin指定了二进制日志文件记录的位置和文件名。一旦启用了二进制日志,MySQL会记录所有数据的更改,包括数据表的添加、删除和修改、数据记录值的添加、删除和修改等所有操作,并将这些操作以二进制文件形式写到log-bin文件中。
启动MySQL服务后,可以使用以下命令查看当前是否启用了二进制日志:
mysql> show variables like 'log_bin';
二、查看二进制日志
我们可以使用mysqlbinlog命令来查看MySQL的二进制日志。例如,使用以下命令查看从2021年8月1日到今天的二进制日志:
mysqlbinlog --start-datetime='2021-08-01' /var/log/mysql/mysql-bin.log
这将显示在2021年8月1日到今天之间所有的二进制操作,包括添加、删除和修改数据。
三、解析二进制日志
二进制日志是以二进制格式存储的,不能直接查看其中记录的操作内容,需要通过解析才能得到有用的信息。
MySQL提供了自带的binary log解析库,即mysqlbinlog,可以用来解析二进制日志。另外,我们还可以使用第三方的工具,例如Binlogpaser、Canal等。
以下是使用python脚本解析MySQL二进制日志的示例:
“`python
import pymysql
import os
import struct
class BinlogParser:
def __init__(self, host, port, user, password, log_file):
self.log_file = log_file
self.log_pos = 4
self.conn = pymysql.connect(host=host, port=port, user=user, password=password)
self.cursor = conn.cursor()
def __del__(self):
self.cursor.close()
self.conn.close()
def read_event(self):
“”” 读取一个二进制事件 “””
self.cursor.execute(‘SELECT LOAD_FILE(“{}”)’.format(self.log_file))
data = self.cursor.fetchone()[0]
event_header = struct.unpack(‘
event_body = data[self.log_pos+19:self.log_pos+event_header[0]]
self.log_pos += event_header[0]
return (event_header, event_body)
def parse_event(self):
“”” 解析二进制事件 “””
header, body = self.read_event()
event_type = header[4]
if event_type == 19:
“”” Table_map_event “””
table_id = struct.unpack(‘
table_name_len = body[8]
table_name = body[9:9+table_name_len].decode(‘utf-8’)
table_column_count = body[9+table_name_len+1]
table_column_types = body[9+table_name_len+2:]
column_types = [table_column_types[i] for i in range(0, len(table_column_types), 2)]
# 将解析结果返回
return {
‘event_type’: ‘Table_map_event’,
‘table_id’: table_id,
‘table_name’: table_name,
‘column_types’: column_types
}
elif event_type == 33:
“”” Write_rows_event “””
pass
# TODO 解析 Write_rows_event 的内容
elif event_type == 30:
“”” Update_rows_event “””
pass
# TODO 解析 Update_rows_event 的内容
elif event_type == 31:
“”” Delete_rows_event “””
pass
# TODO 解析 Delete_rows_event 的内容
else:
pass
# TODO 解析其它类型的事件
if __name__ == ‘__mn__’:
parser = BinlogParser(‘localhost’, 3306, ‘root’, ‘password’, ‘/var/log/mysql/mysql-bin.000001’)
while True:
event = parser.parse_event()
if not event:
break
# 处理 Table_map_event 事件
if event[‘event_type’] == ‘Table_map_event’:
print(‘Table_map_event: table_id={}, table_name={}, column_types={}’.format(
event[‘table_id’], event[‘table_name’], event[‘column_types’]))
上面的示例代码可以解析table_map_event类型的二进制事件,读者可以参考MySQL的官方文档和协议,自行解析其它类型的二进制事件。