彻底挖掘mysqlbinlog数据内容

标签: mysqlbinlog 数据 | 发表时间:2013-11-21 23:05 | 作者:GuaiShuiJue
出处:http://blog.csdn.net

平时工作需要查询mysqlbinlog里面哪个库,哪个表在什么时间更新了什么数据,而通过mysqlbinlog转义过来的文件里面数据太乱,很多注释,而且也没有表结构相关字段,都用@1,@2等类似的方式显示,就想到通过python开发一个这样的功能。

先说下脚本的原理:

  1. 先通过mysqlbinlog转义二进制日志binlog文件,保存为一份临时文件(执行完后删除)
  2. 脚本连接数据库,查出对应的表结构和字段,然后替换掉对应的@1,@2等字段
  3. 过滤掉大部分注释的语句
  4. 然后...就没有然后了
    __author__ = 'chunyang.wu'
    # -*- coding: utf-8 -*-
    #!/usr/bin/env python
    import MySQLdb
    import re
    import os
    import sys
    
    mysql_config = {
        'host':'192.168.1.197',\
        'user':'root',\
        'passwd':'123456',\
        'port':3306,\
        'db':'mydb'
    }
    
    class Deal_binlog:
        def __init_db(self):
            self.mysql_db = MySQLdb.connect(host=self.host,user=self.user,passwd=self.passwd,port=self.port,db=self.db)
            self.mysql_cur=self.mysql_db.cursor()
    
        def __init__(self):
            self.host = mysql_config['host']
            self.user = mysql_config['user']
            self.passwd = mysql_config['passwd']
            self.port = mysql_config['port']
            self.db = mysql_config['db']
            self.sql_file = sys.argv[2]
            self.input_binlog_file = sys.argv[1]
            self.tmp_binlog_file = 'tmp_binlog_file'
            self.field = []
            self.tb_name = ''
            self.where = []
            self.update = []
            self.delete = []
            self.patt = re.compile("/* .* */")
            self.__init_db()
    
        def _release_db(self):
            self.mysql_cur.close()
            self.mysql_db.close()
    
        def _write_data(self,data):
            print data
            data = str(data)+"\n"
            f = open(self.data_file,'a+')
            f.write(data)
            f.close()
    
        def _get_table_name(self,line):
            try:
                if line.find('Table_map:')!=-1:
                    l = line.index('Table_map')
    #                print  line[l::].split(' ')
                    self.tb_name = line[l::].split(' ')[1].replace('`','')
    #                return table
            except Exception,ex:
                print ex
    
        def _get_table_structure(self,tb):
            desc_sql = 'desc %s' %tb
    #        print desc_sql
            self.field = []
            self.mysql_cur.execute(desc_sql)
            res = self.mysql_cur.fetchall()
            for j in res:
                self.field.append(j[0])
    
        def _do(self):
            '''先把mysql二进制的binlog解析成可识别文件,在从里面提取需要的数据'''
            if os.path.exists(self.sql_file):
                os.remove(self.sql_file)
            os.popen('mysqlbinlog -v -v --base64-output=DECODE-ROWS %s>%s' %(self.input_binlog_file,self.tmp_binlog_file))
            with open(self.tmp_binlog_file,"r") as infile:
                for line in infile:
                    if line.rstrip('\n')=='BEGIN':
                        line = line.replace('BEGIN','')
                    elif line.find('Table_map:')!=-1:
                        self._get_table_name(line)
                        self._get_table_structure(self.tb_name)
                    elif line.find('###   @')!=-1:
    #                    print line.replace('###   @','')
                        i = line.replace('###   @','').split('=')[0]
    #                    print line,i
                        line = line.replace('###   @'+str(i),self.field[int(i)-1])
                        if(int(i)== len(self.field)):
                            line = self.patt.sub(' ',line)
                        else:
                            line = self.patt.sub(',',line)
                    elif line.find('###')!=-1:
                        line = line.replace('###','')
                    else:
                        line = ''
                    if line.rstrip('\n')!= '':
                        print line.rstrip('\n')
                        f = open(self.sql_file,'a+')
                        f.write(line)
                        f.close()
            os.remove(self.tmp_binlog_file)
    
    def usage():
        print "python deal_binlog.py mysql_binlog_file out_put_sql_file"
        print "  tag: "
        print "  1. change mysql_config dict"
        print "  2. need MySQLdb"
        print "  3. need your mysql server desc table privileges"
    
    def main():
        p = Deal_binlog()
        p._do()
        p._release_db()
    
    if __name__=="__main__":
        if len(sys.argv) ==3:
            main()
        else:
            usage()

    脚本的执行方式:python deal_binlog.py mysql_binlog_file out_put_sql_file
    操作系统需要安装MySQLdb模块,且需要有权限连接到对应的数据库,脚本的执行可以不在mysql服务器上面(copy一份binlog文件即可)
    执行时需要把该脚本和复制的binlog放在同一个目录下,下面贴上一份解析后的结果图:
    可以看到哪个时间点,数据库更新了什么数据,我的目的这就达到了(update、delete语句不是标准sql语法,这里如果以后有需要在改了)

---------------------------------------------------------------------------------------------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
QQ:       380968195
Email:    [email protected]
Blog:     http://blog.csdn.net/selectdb

URL:       http://blog.csdn.net/selectdb/article/details/16861063


作者:GuaiShuiJue 发表于2013-11-21 15:05:02 原文链接
阅读:73 评论:0 查看评论

相关 [mysqlbinlog 数据] 推荐:

彻底挖掘mysqlbinlog数据内容

- - CSDN博客数据库推荐文章
平时工作需要查询mysqlbinlog里面哪个库,哪个表在什么时间更新了什么数据,而通过mysqlbinlog转义过来的文件里面数据太乱,很多注释,而且也没有表结构相关字段,都用@1,@2等类似的方式显示,就想到通过python开发一个这样的功能. 先通过mysqlbinlog转义二进制日志binlog文件,保存为一份临时文件(执行完后删除).

使用MySQLBinlog按时间查询二进制日志时易疏忽的地方

- Eneri - 火丁笔记
使用mysqlbinlog按时间查询二进制日志时,会用到start-datetime和stop-datetime选项. 提示:MySQL二进制日志的名称缺省是HOSTNAME-bin,不过推荐通过log-bin设置,以防止HOSTNAME更改所带来的影响. 二进制日志的目录可以使用如下方法得到:. 假设要查询2010-11-20全天的二进制日志的话,很多人会这么写:.

数据仓库

- Ran - [email protected]
翻译:马少兵、曾怀东、朱翊然、林业. 尽管服务器存储、处理能力得到有效的提高,以及服务器价格的降低,让人们能够负担起大量的服务器,但是商业软件应用和监控工具快速的增加,还是使得人们被大量的数据所困扰. 在数据仓库领域中的许多系统管理员、应用开发者,以及初级数据库管理员发现,他们正在处理“海量数据”-不管你准备与否-都会有好多不熟悉的术语,概念或工具.

数据抽取

- - 数据库 - ITeye博客
转自: http://wiki.mbalib.com/wiki/%E6%95%B0%E6%8D%AE%E6%8A%BD%E5%8F%96#.   数据抽取是指从源数据源系统抽取目的数据源系统需要的. 实际应用中,数据源较多采用的是. 数据迁移或数据复制,它将数据源中的表或视图的数据原封不动的从数 据库中抽取出来,并转换成自己的ETL 工具可以识别的格式.

数据库sharding

- - 数据库 - ITeye博客
当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确地知道需要访问的数据表以及查询参数,借助这些信息可以直接定位到目标shard上,而不必像框架那样需要对SQL进行解析然后再依据配置的规则进行路由. 另一个优势是不会受ORM框架的制约.

数据脱敏

- - IT瘾-bigdata
作者|李呈祥,其中部分内容由十一城补充. 数据脱敏(Data Masking),又称数据漂白、数据去隐私化或数据变形. 百度百科对数据脱敏的定义为:指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据 的可靠保护. 这样,就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集.

数据分析之如何用数据?

- - 互联网分析沙龙
光知道怎么看数据,还是不成,你得熟悉这些数据拿到手上之后怎么去用它,怎么让数据显示出来它本身的威力来. 第一个部分,是看历史数据,发现规律. 以社区中的活动和电商中的促销为例,这些都是常见的活动,活动做得好的话有意想不到的效果. 在做这样的活动,最好是拿到前一个月或者两个月的历史数据. 对电商来说,从这里面要去分析各个品类的销售情况,那个品类销量最大,那个品类销量最小,每月或者每周的平均增长率和符合增长率是多少.

excel数据导入mysql数据库

- - 互联网 - ITeye博客
1、excel另存为txt.       选中将要导出的数据列,然后另存为选择其它格式=>文本文件(制表符分割). E:\项目\fblike\game_code_san.txt. 2、txt导入到mysql数据库. load data infile 'E:\\项目\\fblike\\game_code_san.txt' into table game_code_san(code).

数据批量导入Oracle数据库

- - Oracle - 数据库 - ITeye博客
今天学习了一个新的东西,觉得还挺有意思的,也是从别出COPY 的,. SQL*LOADER是大型数据. 仓库选择使用的加载方法,因为它提供了最快速的途径(DIRECT,PARALLEL). 现在,我们抛开其理论不谈,用实例来使. 您快速掌握SQL*LOADER的使用方法.   首先,我们认识一下SQL*LOADER.

数据分析之如何用数据?

- - 人人都是产品经理
光知道怎么看数据,还是不成,你得熟悉这些数据拿到手上之后怎么去用它,怎么让数据显示出来它本身的威力来. 第一个部分,是看历史数据,发现规律. 以社区中的活动和电商中的促销为例,这些都是常见的活动,活动做得好的话有意想不到的效果. 在做这样的活动,最好是拿到前一个月或者两个月的历史数据. 对电商来说,从这里面要去分析各个品类的销售情况,那个品类销量最大,那个品类销量最小,每月或者每周的平均增长率和符合增长率是多少.