中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何讀取mysql binlog開始和結束時間

發布時間:2021-10-13 14:21:13 來源:億速云 閱讀:274 作者:柒染 欄目:數據庫

本篇文章給大家分享的是有關如何讀取mysql binlog開始和結束時間,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

mysql binlog 記錄了所有可能涉及更新的操作,可以用來作為增量備份的一種選擇。為了管理binlog ,需要讀取每個binlog 文件的準確的開始和結束時間。用mysqlbinlog 工具可以解析binlog 文件,所以也可以通過分析輸出結果來獲取。但是mysqlbinlog 只能順序讀取記錄,如果只是分析開始時間還好,要分析結束時間,就必須等它把整個binlog 處理完。在binlog 文件體積大的時候,代價就大了些。好在mysql 對binlog 文件的格式是公開的,所以我們可以直接通過解析文件自己實現。
 
binlog 文件的格式在http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log 可以找到。每個binlog 文件都有相同的開頭:0xfe 0×62 0×69 0x6e 。也就是0xfe 后面加上bin 。之后,就是一個個事件數據。binlog 的事件類型有很多種,但每個binlog 文件的第一個事件一定是格式描述事件(format description event),描述了binlog 文件格式版本信息;最后一個時間一定是輪轉事件(rotate event),記錄了下一個binlog 的文件名和事件開始偏移位置。每個事件都有一個一致的事件頭,其中就有事件的時間戳、事件類型等。讀取第一個事件和最后一個事件的信息就可以獲取binlog 文件的準確開始和結束時間了。
 
讀取第一個事件format description event 要容易一些,seek 跳過文件頭,讀取事件頭就行了。讀取最后一個事件的時間要稍麻煩些。因為事件的長度是不固定的。對于輪轉事件來說,除了事件頭以外,后面還有一個64位整數的開始位置偏移量以及下一個binlog 的文件名。長度不確定的部分就是最后的文件名部分。好在那個偏移量是一個固定的值:4(也就是跳過文件頭),所以可以從后往前讀取,用它來作為標記,檢查是否讀完了文件名。然后就可以跳過文件名和偏移量,讀取最后一個事件的事件頭了。
 
代碼如下:
 
<?php
/**
 * read binlog info
 *
 * A  binlog file is begin with a head "\xfebin" and then log evnets. The
 * first event is a format description event, the last event is a rotate event.
 *
 * For more infomation about mysql binlog format, see http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log
 */
class BinlogInfo {
    const EVENT_HEAD_SIZE = 19;
    const FORMAT_DESCRIPTION_EVENT_DATA_SIZE = 59;
    const BINLOG_HEAD = "\xfebin";
    const FORMAT_DESCRIPTION_EVENT = 15;
    const ROTATE_EVENT = 4;
 
    private $eventHeadPackStr = '';
    private $formatDescriptionEventDataPackStr = '';
 
    function __construct() {
        $this->eventHeadPackStr = $this->eventHeadPackStr();
        $this->formatDescriptionEventDataPackStr = $this->formatDescriptionEventDataPackStr();
    }
 
    protected function eventHeadPackStr() {
        $event_header_struct = array(
            'timestamp' => 'l',
            'type_code' => 'c',
            'server_id' => 'l',
            'event_length' => 'l',
            'next_position' => 'l',
            'flags' => 's',
        );
        return $this->toPackStr($event_header_struct);
    }
 
    protected function formatDescriptionEventDataPackStr() {
        $format_description_event_data_struct = array(
            'binlog_version' => 's',
            'server_version' => 'a50',
            'create_timestamp' => 'l',
            'head_length' => 'c'
        );
        return $this->toPackStr($format_description_event_data_struct);
    }
 
    protected function toPackStr($arr) {
        $ret = '';
        foreach ($arr as $k=>$v) {
            $ret.= '/'.$v.$k;
        }
        $ret = substr($ret, 1);
        return $ret;
    }
 
    /**
     * @param resource $file
     *
     * Mysql binlog file begin with a 4 bytes head: "\xfebin".
     */
    protected function isBinlog($file) {
        rewind($file);
        $head = fread($file, strlen(self::BINLOG_HEAD));
        return $head == self::BINLOG_HEAD;
    }
 
    /**
     * @param resource $file
     *
     * Format description event is the first event of a binlog file
     */
    protected function readFormatDescriptionEvent($file) {
        fseek($file, strlen(self::BINLOG_HEAD), SEEK_SET);
        $head_str = fread($file, self::EVENT_HEAD_SIZE);
        $head = unpack($this->eventHeadPackStr, $head_str);
        if ($head['type_code'] != self::FORMAT_DESCRIPTION_EVENT) {
            return null;
        }
        $data_str= fread($file, self::FORMAT_DESCRIPTION_EVENT_DATA_SIZE);
        $data = unpack($this->formatDescriptionEventDataPackStr, $data_str);
 
        return array('head'=>$head, 'data'=>$data);
    }
 
    /**
     * @param resource $file
     *
     * Rotate event is the last event of a binglog.
     * After event header, there is a 64bit int indicate the first event
     * position of next binlog file and next binlog file name without  at end.
     * The position is always be 4 (hex: 0400000000000000).
     *
     */
    protected function readRotateEvent($file)
    {
        /**
         * Rotate event size is 19(head size) + 8(pos) + len(filename).
         * 100 bytes can contain a filename which length less than 73 bytes and
         * it is short than the length of format description event so filesize -
         * bufsize will never be negative.
         */
        $bufsize = 100;
        $size_pos = 8;
        fseek($file, -$bufsize, SEEK_END);
        $buf = fread($file, $bufsize);
        $min_begin = strlen(self::BINLOG_HEAD) + self::EVENT_HEAD_SIZE + $size_pos;
        $ok = false;
        for ($i = $bufsize - 1; $i > $min_begin; $i--) {
            if ($buf[$i] == "") {
                $ok = true;
                break;
            }
        }
        if (!$ok) {
            return null;
        }
        $next_filename = substr($buf, $i + 1);
 
        $head_str = substr($buf, $i + 1 - $size_pos - self::EVENT_HEAD_SIZE, self::EVENT_HEAD_SIZE);
        $head = unpack($this->eventHeadPackStr, $head_str);
        if ($head['type_code'] != self::ROTATE_EVENT) {
            return null;
        }
        return array('head'=>$head, 'nextFile'=>$next_filename);
    }
 
    /**
     * @param string $path path to binlog file
     */
    function read($path) {
        $file = fopen($path, 'r');
        if (!$file) {
            return null;
        }
        if (!$this->isBinlog($file)) {
            fclose($file);
            return null;
        }
 
        $fde = $this->readFormatDescriptionEvent($file);
        $re = $this->readRotateEvent($file);
        fclose($file);
        return array(
            'beginAt' => $fde['head']['timestamp'],
            'endAt' => $re['head']['timestamp'],
            'nextFile' => $re['nextFile'],
            'serverVersion' => $fde['data']['server_version'],
        );
    }
}

以上就是如何讀取mysql binlog開始和結束時間,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

嵊州市| 临安市| 乡宁县| 北辰区| 虞城县| 浠水县| 常州市| 喜德县| 望城县| 南皮县| 丘北县| 通河县| 栾城县| 阿城市| 宿松县| 武陟县| 文昌市| 富宁县| 江孜县| 且末县| 湘西| 莎车县| 宝坻区| 调兵山市| 郸城县| 清流县| 楚雄市| 筠连县| 望城县| 濉溪县| 金华市| 隆林| 镇巴县| 吴川市| 沅江市| 正阳县| 阜阳市| 西青区| 正安县| 胶州市| 陕西省|