python解析binlog取得MySQL binlog的开始时间和结束时间,pythonbinlog,#!/usr/bin/p
#!/usr/bin/pythonimport osimport time import structimport sys def to_uint8(byts) : retval,= struct.unpack('B' , byts) return retvaldef to_uint16(byts) : retval,= struct.unpack('H' , byts) return retvaldef to_uint32(byts) : retval,= struct.unpack('I' , byts) return retvaldef to_uint64(byts) : retval,= struct.unpack('Q' , byts) return retvaldef to_char(byts) : retval,= struct.unpack('c' , byts) return retvalclass BinFileReader(object) : def __init__(self , bin_filename) : self.stream = open(bin_filename , 'rb') def uint8(self) : buf = self.stream.read(1) if buf is None or buf=='' : raise Exception('End of file.') return to_uint8(buf) def uint16(self) : buf = self.stream.read(2) if buf is None or buf=='' : raise Exception('End of file.') return to_uint16(buf) def uint32(self) : buf = self.stream.read(4) if buf is None or buf=='' : raise Exception('End of file.') return to_uint32(buf) def uint64(self) : buf = self.stream.read(8) if buf is None or buf=='' : raise Exception('End of file.') return to_uint64(buf) def char(self) : buf = self.stream.read(1) if buf is None or buf=='' : raise Exception('End of file.') return to_char(buf) def chars(self , byte_size=1) : buf = self.stream.read(byte_size) if buf is None or buf=='' : raise Exception('End of file.') return buf def close(self) : self.stream.close() def seek(self , p , seek_type=0) : self.stream.seek(p , seek_type)class Constant : BINLOG_HEADER = '\\xfe\\x62\\x69\\x6e' BINLOG_HEADER_LEN = 4 EVENT_HEADER_LEN = 19class EventType : UNKNOWN_EVENT= 0 START_EVENT_V3= 1 QUERY_EVENT= 2 STOP_EVENT= 3 ROTATE_EVENT= 4 INTVAR_EVENT= 5 LOAD_EVENT= 6 SLAVE_EVENT= 7 CREATE_FILE_EVENT= 8 APPEND_BLOCK_EVENT= 9 EXEC_LOAD_EVENT= 10 DELETE_FILE_EVENT= 11 NEW_LOAD_EVENT= 12 RAND_EVENT= 13 USER_VAR_EVENT= 14 FORMAT_DESCRIPTION_EVENT= 15 XID_EVENT= 16 BEGIN_LOAD_QUERY_EVENT= 17 EXECUTE_LOAD_QUERY_EVENT= 18 TABLE_MAP_EVENT = 19 PRE_GA_WRITE_ROWS_EVENT = 20 PRE_GA_UPDATE_ROWS_EVENT = 21 PRE_GA_DELETE_ROWS_EVENT = 22 WRITE_ROWS_EVENT = 23 UPDATE_ROWS_EVENT = 24 DELETE_ROWS_EVENT = 25 INCIDENT_EVENT= 26 HEARTBEAT_LOG_EVENT= 27class ErrCode : ERR_BAD_ARGS = 1 ERR_OPEN_FAILED = 2 ERR_NOT_BINLOG = 3 ERR_READ_FDE_FAILED = 4 ERR_READ_RE_FAILED = 5class EventHeader : EVENT_HEADER_LEN = 19 def __init__(self , reader) : self.timestamp = reader.uint32() self.type_code = reader.uint8() self.server_id = reader.uint32() self.event_length = reader.uint32() self.next_position = reader.uint32() self.flags = reader.uint16() def __repr__(self) : msg = 'EventHeader: Timestamp=%s type_code=%s server_id=%s event_length=%s next_position=%s flags=%s' % \\ (self.timestamp , self.type_code , self.server_id , self.event_length , self.next_position , self.flags) return msg class FormatDescEventData : def __init__(self , reader , event_header) : self.binlog_version = reader.uint16() self.server_version = reader.chars(50) self.create_timestamp = reader.uint32() self.header_length = reader.uint8() # post_header_len is not decoded self.post_header_len = reader.chars(event_header.event_length - 2 - 50 - 4 - 1 -19 -1 ) if reader.char() == '\\x00' : pass def __repr__(self) : msg ='FormatDescEventData: binlog_version=%s server_version=%s create_timestamp=%s header_length=%s' % \\ (self.binlog_version , self.server_version , self.create_timestamp , self.header_length) return msg class RotateEvent : def __init__(self , reader , event_header) : self.position = reader.uint64() self.next_binlog = reader.chars(event_header.event_length - 8 - 19 ) def __repr__(self) : msg = 'Rotate Event : position=%s next_binlog=%s' % (self.position , self.next_binlog ) return msg def get_info(mysql_binlog) : reader = BinFileReader(mysql_binlog) binlog_header = reader.chars(Constant.BINLOG_HEADER_LEN) if binlog_header != Constant.BINLOG_HEADER : raise Exception('It\\'s not a mysql binlog file') last_event_header = None retval = {} try : while True: event_header = EventHeader(reader) last_event_header = event_header if event_header.type_code == EventType.FORMAT_DESCRIPTION_EVENT : event_body = FormatDescEventData(reader , event_header) retval['start_time'] = event_header.timestamp elif event_header.type_code == EventType.ROTATE_EVENT : event_body = RotateEvent(reader , event_header) retval['end_time'] = event_header.timestamp retval['next_binlog'] = event_body.next_binlog break elif event_header.type_code == EventType.STOP_EVENT : event_body = StopEvent(reader , event_header) break else : reader.seek(event_header.event_length - 19 , 1 ) except Exception : if reader.stream.read() == '' : pass else : raise Exception('Error when read mysql binlog,filename is %s '\\ %(mysql_binlog , ) ) finally : reader.close() if not getattr(retval , 'end_time' , None) : retval['end_time'] = event_header.timestamp if not getattr(retval , 'next_binlog' , None) : idx = mysql_binlog.rindex('.') _id = int(mysql_binlog[idx+1:] ) + 1 retval['next_binlog'] = mysql_binlog[:idx] + ('.%06d' % _id ) return retval if __name__ == '__main__' : if len(sys.argv) == 2 : mysql_binlog = sys.argv[1] else : print 'Usage : \\n./readbinlog.py <mysql-bin-log>' exit() info = get_info(mysql_binlog) for (k ,v) in info.items() : print '%s = %s' % (k , v)#该片段来自于http://byrx.net
评论关闭