针对binlog MIXED格式对表的增删改统计分析

本文深入探讨了SQL命令在数据库操作中的应用,特别是从ROW格式过渡到MIXED格式的过程。通过使用mysqlbinlog命令进行数据解析,并结合awk进行文本处理,实现对数据库更新、插入、删除操作的高效分析与优化。

我书里的那个命令是针对ROW格式的,下面增加一个MIXED格式的。

mysqlbinlog --no-defaults --base64-output=decode-rows -vv mysql-bin.004177 | 
awk '{IGNORECASE=1}/UPDATE|INSERT|DELETE/{gsub("###","");gsub("INSERT.*INTO","INSERT");
gsub("DELETE.*FROM","DELETE");
count[$1" "$2]++}END{for(i in count)print i,"\t",count[i]}' |sort -k3nr|head -n 20

wKioL1Rq-ELBDxtsAAQlmU9gFe4565.jpg



<think>我们使用Python捕获MySQL的binlog日志并解析增删改事件,通常需要使用第三方库。一个常用的库是`python-mysql-replication`(也称为PyMySQLReplication)。下面将逐步说明如何操作。###步骤1:安装必要的库首先,安装`pymysql`和`mysql-replication`库:```bashpipinstallpymysqlmysql-replication```###步骤2:配置MySQL服务器在MySQL服务器上,需要启用binlog并设置binlog格式为ROW,因为ROW格式会记录每行数据的变更细节,便于解析。1.修改MySQL配置文件(通常是my.cnf或my.ini),添加以下配置:```ini[mysqld]server-id=1log-bin=mysql-binbinlog_format=ROW```2.重启MySQL服务使配置生效。3.确保用于连接MySQL的用户具有`REPLICATIONSLAVE`和`REPLICATIONCLIENT`权限。例如:```sqlCREATEUSER'repl_user'@'%'IDENTIFIEDBY'password';GRANTREPLICATIONSLAVE,REPLICATIONCLIENTON*.*TO'repl_user'@'%';FLUSHPRIVILEGES;```###步骤3:使用Python捕获binlog下面是一个示例代码,展示如何连接到MySQL服务器并捕获binlog事件,特别是增删改事件(对应WriteRowsEvent、UpdateRowsEvent、DeleteRowsEvent)。```pythonfrompymysqlreplicationimportBinLogStreamReaderfrompymysqlreplication.row_eventimport(WriteRowsEvent,UpdateRowsEvent,DeleteRowsEvent)#MySQL连接配置MYSQL_SETTINGS={"host":"localhost","port":3306,"user":"repl_user","passwd":"password"}#创建BinLogStreamReader对象stream=BinLogStreamReader(connection_settings=MYSQL_SETTINGS,server_id=100,#唯一标识这个连接,避免和MySQL主从复制冲突blocking=True,#持续监听新事件resume_stream=True,#从上次断开的位置继续only_events=[WriteRowsEvent,UpdateRowsEvent,DeleteRowsEvent]#只监听增删改事件)#循环读取事件forbinlogeventinstream:#获取事件所属的数据库和db=binlogevent.schematable=binlogevent.table#根据事件类型处理ifisinstance(binlogevent,WriteRowsEvent):print(f"Inserteventin{db}.{table}")forrowinbinlogevent.rows:print("Insertedrow:",row["values"])elifisinstance(binlogevent,UpdateRowsEvent):print(f"Updateeventin{db}.{table}")forrowinbinlogevent.rows:#注意:UpdateRowsEvent的rows是一个字典,包含'before'和'after'print("Before:",row["before_values"])print("After:",row["after_values"])elifisinstance(binlogevent,DeleteRowsEvent):print(f"Deleteeventin{db}.{table}")forrowinbinlogevent.rows:print("Deletedrow:",row["values"])#关闭连接stream.close()```###说明:1.`BinLogStreamReader`:用于读取binlog事件流。2.事件类型:-`WriteRowsEvent`:插入事件(对应INSERT操作)-`UpdateRowsEvent`:更新事件(对应UPDATE操作)-`DeleteRowsEvent`:删除事件(对应DELETE操作)3.在ROW格式下,每个事件包含具体的行数据。对于更新事件,会同时提供更新前和更新后的数据。4.参数`resume_stream=True`会从上次读取的位置继续,位置信息会保存在`stream.log_file`和`stream.log_pos`中。你也可以指定`log_file`和`log_pos`参数来从特定位置开始。###注意事项:-确保网络连接通畅,因为`blocking=True`会让程序持续监听。-生产环境中需要考虑异常处理和断点续传。-如果需要处理大事务,注意内存使用,因为整个事务的事件会一起加载到内存。###其他方法:使用`mysqlbinlog`命令除了使用Python库,还可以通过调用`mysqlbinlog`命令并解析其输出来捕获binlog。但这种方法需要处理文本解析,不如上述方法直接。###参考引用:-关于MySQLbinlog格式的官方文档:[MySQL::MySQL5.7ReferenceManual::5.4.4.1BinaryLogFormats](https://dev.mysql.com/doc/refman/5.7/en/binary-log-formats.html)[^1]-`python-mysql-replication`库文档:[GitHub-noplay/python-mysql-replication](https://github.com/noplay/python-mysql-replication)[^2]§§相关问题§§1.如何确保binlog事件捕获的可靠性(比如断网重连)?2.除了增删改事件,还有其他哪些binlog事件类型?3.如何处理大型事务以避免内存溢出?4.如何将捕获的事件同步到其他存储(如Elasticsearch或Kafka)?</think>### Python捕获MySQL Binlog日志并解析增删改事件 以下是完整的实现方案,使用Python捕获MySQL的Binlog日志并解析增删改事件: #### 前置条件 1. **MySQL配置**: - 启用Binlog并设置为ROW模式(在my.cnf中添加): ```ini [mysqld] server-id = 1 log-bin = mysql-bin binlog_format = ROW # 关键:ROW格式记录行级变更 ``` - 创建专用账号: ```sql CREATE USER 'binlog_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'binlog_user'@'%'; FLUSH PRIVILEGES; ``` 2. **Python库安装**: ```bash pip install mysql-replication pymysql ``` #### 代码实现 ```python from pymysqlreplication import BinLogStreamReader from pymysqlreplication.row_event import ( WriteRowsEvent, UpdateRowsEvent, DeleteRowsEvent ) # MySQL连接配置 mysql_settings = { "host": "localhost", "port": 3306, "user": "binlog_user", "passwd": "password", "charset": "utf8mb4" } # 创建Binlog流读取器 stream = BinLogStreamReader( connection_settings=mysql_settings, server_id=100, # 唯一ID(非MySQL server-id) blocking=True, # 持续监听 resume_stream=True, # 断点续传 only_events=[WriteRowsEvent, UpdateRowsEvent, DeleteRowsEvent] # 仅监听增删改 ) # 事件处理 for binlogevent in stream: event_type = type(binlogevent).__name__ print(f"事件类型: {event_type}") print(f"数据库: {binlogevent.schema}, : {binlogevent.table}") # 处理插入事件 if isinstance(binlogevent, WriteRowsEvent): for row in binlogevent.rows: print(f"[INSERT] 新增行: {row['values']}") # 处理更新事件 elif isinstance(binlogevent, UpdateRowsEvent): for row in binlogevent.rows: print(f"[UPDATE] 变更前: {row['before_values']}") print(f"[UPDATE] 变更后: {row['after_values']}") # 处理删除事件 elif isinstance(binlogevent, DeleteRowsEvent): for row in binlogevent.rows: print(f"[DELETE] 删除行: {row['values']}") print("=" * 50) # 关闭连接(通常不会执行到此处) stream.close() ``` #### 关键说明 1. **事件类型解析**: - `WriteRowsEvent`:INSERT操作 - `UpdateRowsEvent`:UPDATE操作(包含变更前后数据) - `DeleteRowsEvent`:DELETE操作 2. **ROW模式优势**: - 记录具体行数据变更,而非SQL语句 - 避免触发器/函数导致的歧义[^1] 3. **断点续传机制**: - `resume_stream=True` 自动记录binlog位置 - 位置信息保存在`stream.log_file`和`stream.log_pos` #### 高级配置 ```python # 指定起始位置(binlog文件名+位置) stream = BinLogStreamReader( ... log_file='mysql-bin.000001', log_pos=107, only_schemas=['your_database'] # 过滤指定数据库 ) ``` #### 注意事项 1. **权限要求**: - `REPLICATION CLIENT`:查看master状态 - `REPLICATION SLAVE`:读取binlog流[^1] 2. **性能影响**: - 持续监听可能消耗网络资源 - 生产环境建议配合消息队列(如Kafka) 3. **时区问题**: - 确保Python和MySQL时区一致 - 可在连接参数添加`use_tz=True` ### 引用说明 [^1]: 需要`REPLICATION SLAVE`权限来读取binlog流,这是MySQL复制机制的基础权限。 [^2]: ROW格式binlog直接记录行数据变更,比STATEMENT格式更精确,避免了函数、触发器执行结果不一致的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值