Example #1
0
 def print_rollback_sql(self, fin):
     '''print rollback sql from tmpfile'''
     with open(fin) as ftmp:
         sleepInterval = 1000
         i = 0
         for line in reversed_lines(ftmp):
             print line.rstrip()
             if i >= sleepInterval:
                 print 'SELECT SLEEP(1);'
                 i = 0
             else:
                 i += 1
Example #2
0
    def process_binlog(self):
        stream = BinLogStreamReader(connection_settings=self.connectionSettings, server_id=self.serverId,
                                    log_file=self.startFile, log_pos=self.startPos, only_schemas=self.only_schemas,
                                    only_tables=self.only_tables, resume_stream=True)

        cur = self.connection.cursor()
        tmpFile = create_unique_file('%s.%s' % (self.connectionSettings['host'],self.connectionSettings['port'])) # to simplify code, we do not use file lock for tmpFile.
        ftmp = open(tmpFile ,"w")
        flagLastEvent = False
        eStartPos, lastPos = stream.log_pos, stream.log_pos
        try:
            for binlogevent in stream:
                if not self.stopnever:
                    if (stream.log_file == self.endFile and stream.log_pos == self.endPos) or (stream.log_file == self.eofFile and stream.log_pos == self.eofPos):
                        flagLastEvent = True
                    elif datetime.datetime.fromtimestamp(binlogevent.timestamp) < self.startTime:
                        if not (isinstance(binlogevent, RotateEvent) or isinstance(binlogevent, FormatDescriptionEvent)):
                            lastPos = binlogevent.packet.log_pos
                        continue
                    elif (stream.log_file not in self.binlogList) or (self.endPos and stream.log_file == self.endFile and stream.log_pos > self.endPos) or (stream.log_file == self.eofFile and stream.log_pos > self.eofPos) or (datetime.datetime.fromtimestamp(binlogevent.timestamp) >= self.stopTime):
                        break
                    # else:
                    #     raise ValueError('unknown binlog file or position')

                if isinstance(binlogevent, QueryEvent) and binlogevent.query == 'BEGIN':
                    eStartPos = lastPos

                if isinstance(binlogevent, QueryEvent):
                    sql = concat_sql_from_binlogevent(cursor=cur, binlogevent=binlogevent, flashback=self.flashback, nopk=self.nopk)
                    if sql:
                        print sql
                elif isinstance(binlogevent, WriteRowsEvent) or isinstance(binlogevent, UpdateRowsEvent) or isinstance(binlogevent, DeleteRowsEvent):
                    for row in binlogevent.rows:
                        sql = concat_sql_from_binlogevent(cursor=cur, binlogevent=binlogevent, row=row , flashback=self.flashback, nopk=self.nopk, eStartPos=eStartPos)
                        if self.flashback:
                            ftmp.write(sql + '\n')
                        else:
                            print sql

                if not (isinstance(binlogevent, RotateEvent) or isinstance(binlogevent, FormatDescriptionEvent)):
                    lastPos = binlogevent.packet.log_pos
                if flagLastEvent:
                    break
            ftmp.close()
            if self.flashback:
                with open(tmpFile) as ftmp:
                    for line in reversed_lines(ftmp):
                        print line.rstrip()
        finally:
            os.remove(tmpFile)
        cur.close()
        stream.close()
        return True
Example #3
0
 def print_rollback_sql(self, filename):
     """print rollback sql from tmp_file"""
     with open(filename, "rb") as f_tmp:
         batch_size = 1000
         i = 0
         for line in reversed_lines(f_tmp):
             print(line.rstrip())
             if i >= batch_size:
                 i = 0
                 if self.back_interval:
                     print('SELECT SLEEP(%s);' % self.back_interval)
             else:
                 i += 1
Example #4
0
    def process_binlog(self):
        stream = BinLogStreamReader(connection_settings=self.conn_setting,
                                    server_id=self.server_id,
                                    log_file=self.start_file,
                                    log_pos=self.start_pos,
                                    only_schemas=self.only_schemas,
                                    only_tables=self.only_tables,
                                    resume_stream=True,
                                    blocking=True)

        flag_last_event = False
        e_start_pos, last_pos = stream.log_pos, stream.log_pos
        # to simplify code, we do not use flock for tmp_file.
        tmp_file = create_unique_file(
            '%s.%s' % (self.conn_setting['host'], self.conn_setting['port']))
        try:
            with temp_open(tmp_file, "w") as f_tmp, self.connection as cursor:
                count = 0
                for binlog_event in stream:
                    if count >= self.countnum:
                        break
                    if not self.stop_never:
                        try:
                            event_time = datetime.datetime.fromtimestamp(
                                binlog_event.timestamp)
                        except OSError:
                            event_time = datetime.datetime(1980, 1, 1, 0, 0)
                        if (stream.log_file == self.end_file and stream.log_pos == self.end_pos) or \
                                (stream.log_file == self.eof_file and stream.log_pos == self.eof_pos):
                            flag_last_event = True  #解析道文件尾
                        elif event_time < self.start_time:
                            if not (isinstance(binlog_event, RotateEvent)
                                    or isinstance(binlog_event,
                                                  FormatDescriptionEvent)):
                                last_pos = binlog_event.packet.log_pos
                            continue
                        elif (stream.log_file not in self.binlogList) or \
                                (self.end_pos and stream.log_file == self.end_file and stream.log_pos > self.end_pos) or \
                                (stream.log_file == self.eof_file and stream.log_pos > self.eof_pos) or \
                                (event_time >= self.stop_time):
                            break
                        # else:
                        #     raise ValueError('unknown binlog file or position')

                    if isinstance(
                            binlog_event,
                            QueryEvent) and binlog_event.query == 'BEGIN':
                        e_start_pos = last_pos

                    if isinstance(binlog_event,
                                  QueryEvent) and not self.only_dml:
                        sql = concat_sql_from_binlog_event(
                            cursor=cursor,
                            binlog_event=binlog_event,
                            flashback=self.flashback,
                            no_pk=self.no_pk)

                        if sql:
                            count = count + 1
                            self.sqllist.append(sql)
                            print(sql)
                    elif is_dml_event(binlog_event) and event_type(
                            binlog_event) in self.sql_type:
                        for row in binlog_event.rows:
                            sql = concat_sql_from_binlog_event(
                                cursor=cursor,
                                binlog_event=binlog_event,
                                no_pk=self.no_pk,
                                row=row,
                                flashback=self.flashback,
                                e_start_pos=e_start_pos)
                            if self.flashback:
                                f_tmp.write(sql + '\n')
                            else:
                                self.sqllist.append(sql)
                                print(sql)
                            count = count + 1
                    if not (isinstance(binlog_event, RotateEvent) or
                            isinstance(binlog_event, FormatDescriptionEvent)):
                        last_pos = binlog_event.packet.log_pos
                    if flag_last_event:
                        break

                stream.close()
                f_tmp.close()
                if self.flashback:
                    with open(tmp_file) as ftmp:
                        for line in reversed_lines(ftmp):
                            self.sqllist.append(line.rstrip())
                    self.print_rollback_sql(filename=tmp_file)
        finally:
            os.remove(tmp_file)
        return True