前言

MySqlbinlog一般用于我们对数据的恢复,以及从数据库对主数据库的复制和更新。

假设此时我们有一个需要查询和读取Mysql最近操作DDL的信息,我们需要怎么处理?

聪明的你可能已经想到了,我们可以使用mysqlbinlog工具读取啊!的确,mysqlbinlog对于statement或者mixed格式的binlog文件确实会很方便读取,但是你要知道,从Mysql5.7.7开始,row就是默认的binlog_format,此时我们再要去直接通过肉眼去看,恐怕就不是那么容易了。

即使我们在通过mysqlbinlog解析时加上-v参数,也只能显示出这样的效果:

于是,我写了一个binlog2sql的初级版本,来实现sql语句的转换。

实现

实现过程不是很复杂,主要是通过mysqlbinlog来提取我们需要的DDL语句,然后我们再通过我们的方法来把这些语句转化为我们可以识别的sql语句。

核心代码:

/**
* @return $this
*/
protected function selectFromBinLog()
{
$fillFile = Util::getFile(__DIR__ . '/data/file.sql');
file_put_contents($fillFile, "");
exec("mysqlbinlog -v --database='" . Conf::__DATABASE__ . "' $this->_binlog_basename/$this->_binlog_file | grep -E -i '###|UPDATE|INSERT|DELETE' >> $fillFile");
return $this;
} /**
* @return $this
*/
protected function parseSql()
{
$fillFileHandler = fopen(__DIR__ . '/data/file.sql', 'r');
$sqlArr = [];
if ($this->_type == 'ROW') {
$match = NULL;
$sqlStr = "";
while (($sql = fgets($fillFileHandler)) !== false) {
if (($match = preg_match('/UPDATE|INSERT|DELETE/', $sql)) || strrpos($sql, 'end_log_pos') !== false) {
# 如果有指定表
if ($match && $this->_table && strpos($sql, $this->_table) === false) continue;
$sqlStr == '' || array_push($sqlArr, $sqlStr);
$sqlStr = $match ? trim(substr($sql, 3, -1)) . " " : "";
} elseif (strpos($sql, '@') !== false || strpos($sql, 'SET')) {
$sqlStr .= trim(substr($sql, 3, -1)) . " ";
}
}
$sqlStr == '' || array_push($sqlArr, $sqlStr);
} else {
# statement 和 mixed格式一样
while (($sql = fgets($fillFileHandler)) !== false) {
$sql = trim($sql);
if (preg_match('/(UPDATE|INSERT|DELETE)\s+/', $sql)) {
array_push($sqlArr, $sql);
}
}
}
$sqlArr = array_map(function ($value) {
return preg_replace_callback('/(@(\d+))/', function ($matches) use ($value) {
$parts = explode('.', $value);
return $this->getTableColumns(explode('`', array_pop($parts))[1])[$matches[2] - 1];
}, $value);
}, $sqlArr); $mysqlFile = Util::getFile(__DIR__ . '/data/mysql.sql'); array_map(function ($value) use ($mysqlFile) {
file_put_contents($mysqlFile, $value . PHP_EOL, FILE_APPEND);
}, $sqlArr);
fclose($fillFileHandler); return $this;
} /**
* @param $table
* @return array
*/
protected function getTableColumns($table)
{
if (array_key_exists($table, $this->_tableColumns))
return $this->_tableColumns[$table];
$tableInfo = $this->select("show full columns from $table");
if (empty($tableInfo)) Util::dd("$table 不存在");
return $this->_tableColumns[$table] = array_column($tableInfo, 'Field');
}

其中有三个主要的方法,selectFromBinLog用于执行mysqlbinlog,用于提取我们所需要的DDLparseSql用于解析我们提取出来的sqlgetTableColumns用于获取表的字段(主要是针对row模式下的@1,@2之类)。

当我们执行Binlog.phpstart方法之后,就可以把DDL写入到'./data/mysql.sql'中了,非常方便。

如何通过binlog获取我们想要的MySql语句?的更多相关文章

  1. 答:SQLServer DBA 三十问之六:Job信息我们可以通过哪些表获取;系统正在运行的语句可以通过哪些视图获取;如何获取某个T-SQL语句的IO、Time等信息;

    6. Job信息我们可以通过哪些表获取:系统正在运行的语句可以通过哪些视图获取:如何获取某个T-SQL语句的IO.Time等信息: 我的MSDB数据库中有全部的表: sys.all_columns,s ...

  2. PHP获取当前服务器信息的基本语句

    下面是PHP获取当前服务器信息的基本语句. PHP程式版本: <?PHP echo PHP_VERSION; ?> ZEND版本: <?PHP echo zend_version() ...

  3. Yii2获取当前程序执行的sql语句

    1.Yii2获取当前程序执行的sql语句: $query = model::find();         $dataProvider = new ActiveDataProvider([       ...

  4. 如何获取自己想要模拟的APP的相关图片?

    一.首先打开iTunes APP,找到自己想要模拟实现的APP,并下载 二.找到下载的APP在iTunes中的位置 三.选中对应的APP,点击右键选择在Finder中显示,会打开对应的文件窗口,打开对 ...

  5. 百度地图sdk sha1秘钥获取有种想吐的赶脚

    撸代码坐的腰算背疼还只是弄一个不是项目里边需要的升级版本的so 日 需要sha1 指纹秘钥,还有项目包, 才能用百度地图sdk 这个找sha1  获取废了20分钟, 显示全盘找keytool.exe ...

  6. iOS 在不添加库的情况下 通过抽象类来获取自己想要的方法

    #define SYSTEM_VERSION_MORE_THAN_BFDATA(v) ([[[UIDevice currentDevice] systemVersion] compare:v opti ...

  7. 引人遐想,用 Python 获取你想要的 “某个人” 摄像头照片

    仅用来学习,希望给你们有提供到学习上的作用. 1.安装库 需要安装python3.5以上版本,在官网下载即可.然后安装库opencv-python,安装方式为打开终端输入命令行. 2.更改收件人和发件 ...

  8. AFLW如何获取你想要的21点人脸关键点数据

    目前人脸检测和人脸的关键点的数据库根据关键点个数:5,20,21,29,68等.https://blog.csdn.net/XZZPPP/article/details/74939823该网页详细列出 ...

  9. Oracle获取干净的建表DDL语句,不含其它存储、表空间、段属性

    早上一个同事资讯怎么获取到建表语句而且是不带存储那种SQL.Oracle自己提供了一个函数DBMS_METADATA.GET_DDL,但是获取到的建表语句含有存储.表空间.以及一些其他段的属性.如图: ...

随机推荐

  1. [leetcode-551-Student Attendance Record I]

    You are given a string representing an attendance record for a student. The record only contains the ...

  2. 理解oauth2.0【转载】

    原文出处: http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth是一个关于授权(authorization)的开放网络标准,在全世界得 ...

  3. office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行

    office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行 系统:win8 64位 PowerPoint2013 64位 在幻灯片中插入SmartArt图 ...

  4. VB6之WebBrowser控件

    UI短手或者GDI+用烦的童鞋可以借用WebBrowser打造漂亮的程序界面,只需要下载一个好看点的html代码就够了. 引用: Microsoft Html Object Library 部件: M ...

  5. 一只猿:使用flask来做一个小应用

    上周 @萍姐 问我如何抓取天猫上面店铺的评分,看了下挺简单的,于是花了点时间写了个Python脚本,加上web.py做成一个web服务,使用起来还不错,今天来看的时候发现当时为了方便直接用web.py ...

  6. [UWP]浅谈按钮设计

    一时兴起想谈谈UWP按钮的设计. 按钮是UI中最重要的元素之一,可能也是用得最多的交互元素.好的按钮设计可以有效提高用户体验,构造让人眼前一亮的UI.而且按钮通常不会影响布局,小小的按钮无论怎么改也不 ...

  7. wifi扩展设置

    一.主路由器设置 网络参数 LAN口设置查到 MAC地址,用于设置扩展路由器 Bridge功能设置时 AP1的地址 2.无线基本设置,桥的 SSID BSSID 为扩展 3.无线安全设置 二.扩展路由 ...

  8. 如何将notMNIST转成MNIST格式

    相信了解机器学习的对MNIST不会陌生,Google的工程师Yaroslav Bulatov 创建了notMNIST,它和MNIST类似,图像28x28,也有10个Label(A-J). 在Tenso ...

  9. 【Storm】Storm实战之频繁二项集挖掘

    一.前言 针对大叔据实时处理的入门,除了使用WordCount示例之外,还需要相对更深入点的示例来理解Storm,因此,本篇博文利用Storm实现了频繁项集挖掘的案例,以方便更好的入门Storm. 二 ...

  10. 18-EasyNetQ:发生错误的情况

    这一篇文章让我们看看在消息系统中可能发生的各种错误的情况下,看下EasyNetQ如何处理它们. 订阅服务挂了 当你写了一个windows 服务,用来订阅一个NewCustomerMessage消息. ...