由于数据库 Blob字段太多,导致从库进行binlog不能正常进行的处理方法

binlog_format为row格式的时候记录的不是简单的sql,而是实际变更的行,一些大的DML操作,会导致binlog量增加很大,消耗额外的IO、网络资源

可以通过设置binlog_row_image=minimal解决

测试:

binlog_row_image默认值是full

对user表进行update

进入binlog里面查看更新记录,binlog日志将所有影响的行都进行了记录

现在将binlog_row_image=minimal

对表中的行进行相同的update操作 再来观察下binlog记录

结论:可以对比发现当binlog_row_image=minimal的时候binlog只记录了影响的那一行记录,有效减少了binlog日志量。

数据库版本:5.6.*

1.row日志image类型

参数binlog_row_image 控制着这种image类型,默认为FULL(log all columns),即记录before&after images。
该参数还有两种,minimal和noblob,minimal表示只记录after更改后的值,并且如果有主键或者非空唯一索引,则只以该字段作为where条件判断;noblob同full,只是不记录blob、text列。

2.binlog日志

对于insert则没有什么好说的,我们主要重点关注一下update和delete操作。

binlog_row_image=full的情况下,对于update和delete所有的表(包含带有主键、非空唯一索引,唯一索引,没有索引)产生的binlog均一致,binlog情况如下:

  1. --建表语句
  2. CREATE TABLE `pk_test`(
  3. `id` bigint(20) NOT NULL,
  4. `username` varchar(30) NOT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  7. insert into pk_test values (1,2);
  8. insert into pk_test values (2,2);
  9. commit;
  10. show master statusG;--记录binlog文件和pos
  11. deletefrom pk_test where id =1;
  12. update pk_test set username=‘3‘;
  13. commit;
  14. mysqlbinlog --no-defaults -v --start-position=637945822/mysqllog/3307/binlog/mysql-bin.000001| more
  15. ### DELETE FROM `baofeng`.`pk_test`
  16. ### WHERE
  17. ### @1=1
  18. ### @2=‘2‘
  19. .....
  20. ### UPDATE `baofeng`.`pk_test`
  21. ### WHERE
  22. ### @1=2
  23. ### @2=‘2‘
  24. ### SET
  25. ### @1=2
  26. ### @2=‘3‘

从上面我们可以看到,在默认为FULL的binlog_row_image下,无论表有没有主键、唯一索引,全部按照全表字段作为条件,且update会更新全部字段。

binlog_row_image=minimal的情况下:

  1. --建表语句
  2. CREATE TABLE `ui_test`(
  3. `id` bigint(20) NOT NULL,
  4. `username` varchar(30) NOT NULL,
  5. UNIQUE (`id`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  7. CREATE TABLE `ui_test_null`(
  8. `id` bigint(20),
  9. `username` varchar(30) NOT NULL,
  10. UNIQUE key (`id`)
  11. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  12. CREATE TABLE `null_test`(
  13. `id` bigint(20),
  14. `username` varchar(30) NOT NULL
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  16. insert into pk_test values (1,2);
  17. insert into ui_test values (1,2);
  18. insert into ui_test_null values (1,2);
  19. insert into null_test values (1,2);
  20. commit;
  21. update pk_test set username=‘4‘;
  22. deletefrom pk_test;
  23. deletefrom ui_test;
  24. deletefrom ui_test_null;
  25. update null_test set username=‘4‘;
  26. deletefrom null_test;
  27. ### UPDATE `baofeng`.`pk_test`
  28. ### WHERE
  29. ### @1=1
  30. ### SET
  31. ### @2=‘4‘
  32. ....
  33. ### DELETE FROM `baofeng`.`pk_test`
  34. ### WHERE
  35. ### @1=1
  36. .....
  37. ### DELETE FROM `baofeng`.`ui_test`
  38. ### WHERE
  39. ### @1=1
  40. .....
  41. ### DELETE FROM `baofeng`.`ui_test_null`
  42. ### WHERE
  43. ### @1=1
  44. ### @2=‘2‘
  45. .....
  46. ### UPDATE `baofeng`.`null_test`
  47. ### WHERE
  48. ### @1=1
  49. ### @2=‘2‘
  50. ### SET
  51. ### @2=‘4‘
  52. .....
  53. ### DELETE FROM `baofeng`.`null_test`
  54. ### WHERE
  55. ### @1=1
  56. ### @2=‘2‘

从上面的例子可以看到,当binlog_row_image=minimal的情况下,where条件只有主键或不为空的唯一索引,且只会更新被改变的字段。

3.总结:

在上面的测试我们可以看到,如果采用minimal格式,将减少主键和非空唯一索引表的before值,以及减少所有表update的after未被改变的值。
从效率上来说,减少了网络传输以及加快了update的效率。

参考资料:
https://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html#sysvar_binlog_row_image

时间: 2024-08-10 19:07:51

由于数据库 Blob字段太多,导致从库进行binlog不能正常进行的处理方法的相关文章

JAVA读取Oracle数据库BLOB字段数据文件并保存到本地文件

******JAVA读取Oracle数据库BLOB字段数据文件并保存到本地文件****** package com.bo.test; import java.io.FileOutputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import

Java读取/更新Oracle数据库blob字段

在写java程序过程中,如何读取Oracle数据库表某类型为blob的字段? 以下是我在写程序的时候一种解决方法.核心语句.(传上来做了修改,格式不要学习,养成良好习惯) 详细请参考: 读取序列ID:http://blog.csdn.net/yzsind/article/details/6918506 BLOB相关:http://jslfl.iteye.com/blog/1771949 http://www.linuxidc.com/Linux/2011-08/40218.htm http://

Oracle数据库BLOB字段的存取

述]     Oracle的Blob字段比较特殊,他比long字段的性能要好很多,可以用来保存例如图片之类的二进制数据. 写入Blob字段和写入其它类型字段的方式非常不同,因为Blob自身有一个cursor,你必须使用cursor对 blob进行操作,因而你在写入Blob之前,必须获得cursor才能进行写入,那么如何获得Blob的cursor呢? 这需要你先插入一个empty的blob,这将创建一个blob的cursor,然后你再把这个empty的blob的cursor 用select查询出来

对oracle数据库Blob字段的操作

java实体类 定义类型 byte[] private byte[] str_blob hibernate映射文件类型oracle.sql.BLOB <property name="str_blob" type="oracle.sql.BLOB"> <column name="STR_BLOB" /> </property> 数据库类型BLOB byte[] b = str.getBytes(); String

把数据库blob字段用FoxitReaderSDK1显示PDF

procedure TAO_EWordPdf.ShowDoc;var   Adapter: iStream;//TStreamAdapter; DataLoader: TMemoryStream;begin if not cdsGetDocDOC_DATA.IsNull then   //判断数据字段不为空  begin DataLoader := TMemoryStream.Create();    DataLoader.Clear;    cdsGetDocDOC_DATA.SaveToSt

springmvc和servlet下的文件上传和下载(存文件目录和存数据库Blob两种方式)

项目中涉及了文件的上传和下载,以前在struts2下做过,今天又用springmvc做了一遍,发现springmvc封装的特别好,基本不用几行代码就完成了,下面把代码贴出来: FileUpAndDown.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"%> <html> <head> <title>using commons Uplo

springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)

参与该项目的文件上传和下载.一旦struts2下完成,今天springmvc再来一遍.发现springmvc特别好包,基本上不具备的几行代码即可完成,下面的代码贴: FileUpAndDown.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"%> <html> <head> <title>using commons Upload to

java 读写Oracle Blob字段

许久没有分享代码了,把这段时间写的一个Java操作Blob字段,有日子没写Java了,就当作笔记记录一下.1. [代码][Java]代码     跳至 [1] [全屏预览]package com.wanmei.meishu;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileReader;import java.io.InputStream;import java.io.OutputS

JSP读取Oracle数据库里的图片Blob字段并显示在页面上&lt;转&gt;

java代码:首先定义一个读取Oracle数据库的Blob字段并把字节写入一个输出流的方法. 1 public static void writeImg(OutputStream os) { 2 Connection con; 3 try { 4 con = ConnectionFactory.getConnection(); 5 Statement stmt = con.createStatement(); 6 ResultSet rs = stmt.executeQuery("select