二进制日志

Posted youzhongmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二进制日志相关的知识,希望对你有一定的参考价值。

二进制日志

  二进制日志基本介绍

    二进制日志文件只是保存了对数据库的变更,对没有变更的数据操作不会记录到二进制日志。

    二进制日志的内容如下图所示:

    技术分享图片

    二进制日志中的字段如下:

    Event_Type:用来设置数据的操作类型。如Query、Update。

    Server_id:服务器的id

    Log_name:用来表明该事件保存的二进制日志文件名称

‘    Pos:事件的开始位置

    End_log_pos:事件的结束位置

    info:事件信息的可读文本

   二进制文件的结构

    技术分享图片

    主要包含二进制文件和二进制文件的索引文件,二进制日志文件以格式描述事件开始,以日志轮换事件结束。

    格式描述事件主要包括服务器版本号、服务器信息和二进制文件信息等。

    日志轮换事件’主要包括事件在记录到的下一个日志文件名称。

    查看二进制日志的指令:

    show  binlog  events    //用以查看第一个日志文件的第一条事件的信息。

    show  binlog  events  in "文件名"  //用以查看指定二进制日志的事件信息

    show  master  status   //通过主服务器查看当前正在写入的二进制日志

  记录语句

   对数据的更新语句在master上执行,并写入二进制文件,slave会同步master的语句并执行。

   在有主从同步的数据库模式中尽量避免以下几种操作,因为在master和slave上的数据可能会导致不一致。例如当前数据库、用户自定义变量的值、RAND函数的种子、当前时间、AUTO_INCREMENT插入值、调用LAST_INCRET_ID的返回值和线程ID等。

  二进制日志的过滤器

  在设置过滤器时,可以在主库上设置,也可以在备库上设置。

  binlog-do-db=dbname     //该参数会设置将该数据库的变化保存到二进制日志中,将该数据库的变化同步到备库。

  binlog-ignore-db=dbname   //该参数会忽略该数据库的变化不会保存到二进制日志中,由于该数据库的二进制日志没有保存,所以在系统崩溃后,重新启动时,无法恢复该数据库。

  binlog-do-table=tablename   //该参数会设置将该数据库表的变化保存到二进制日志中,将该数据库表的变化同步到备库。

  binlog-ignore-table=tablename   //该参数会忽略该数据库表的变化不会保存到二进制日志中,由于该数据库表的二进制日志没有保存,所以在系统崩溃后,重新启动时,无法恢复该数据库表。

  replicat-do-db=dbname     //该参数会设置将该数据库的变化同步到中继日志中,将该数据库的变化在备库上执行。

  replicate-ignore-db=dbname   //该参数会忽略该数据库的变化不会保存到中继日志中。

  replicate-do-table=tablename   //该参数会设置将该数据库表的变化保存到中继日志中,将该数据库表的变化在备库上执行。

  replicate-ignore-table=tablename   //该参数会忽略该数据库表的变化不会保存到中继日志中。

  注意:1、binlog-ignore-db和binlog-ignore-table参数会过滤对该数据库和表的操作保存到二进制日志中,所以在数据恢复时,导致数据丢失,一般不建议在主库上设置该参数,

      可以在备库上进行过滤。    

     2、在同时使用binlog-do-db和binlog-ignore-db时,只对binlog-do-db参数有效。

  触发器、存储过程、存储函数和事件

  1、触发器

   在master上创建一个触发器:

      create database test;
     use test;
     create table t (id int);
     create table t_log (id int, dd date);
     create trigger tri_t  after insert on t for each row  insert into t_log values (new.id,now());
     在master和slave上查看是否存在数据库:show triggers from test;
   技术分享图片
   以上查询结果均在master和slave上显示,说明触发器会同步到slave上。
   当在master上插入一条数据,调用触发器时,查看trigger是否都在master和slave上执行: insert into t values (1);
   通过指令select * from t_log;查看到master和slave上均有该条数据,说明触发器在主从上都能创建并一同出发。
   结论:
    1 主从都存在trigger时,主库会记录下所有的操作,包含trigger的操作,从库上数据和主库一致.
    2 主有trigger,从库上没有trigger时,依然不影响主从同步
    3 主上无trigger,从上有trigger时 ,主从数据依然一致,从库上的trigger没有被触发
  2、存储过程
  在master上创建存储过程:
  CREATE procedure p1 (IN name varchar(10),IN age int)
   BEGIN
   insert into test.t1 values(name,age);
  END//
  会在master和slave上看到都会存在该存储过程。也就是说存储过程会在主从上保持一致。
  在执行存储过程时,只会讲存储过程执行的语句写入二进制日志,并将该语句同步到slave上。
  3、存储函数
   在master上创建函数:
  CREATE FUNCTION f1 (string VARCHAR(5))
  RETURNS VARCHAR(20) DETERMINISTIC
  RETURN CONCAT(‘f1‘,string);
  在查看二进制日志文件时可以看到,创建的过程保存在了文件中,如下图:
  
技术分享图片
  在master上执行函数时,同步到slave时分为两种情况一是binlog_format为statement,另一种情况为row。
  binlog_format=statement时,会在同步时,只同步存储函数。
  binlog_format=row时,会在同步时,将同步的存储函数转换为同步的记录数据。
  4、事件
    事件只在master上执行,在slave上不会执行。因为如果在slave上执行事件,那么slave上将执行两次事件,一次来自master,一次来自slave本身。事件的执行语句会保存在二进制日志中,
    同步到slave上进行语句的执行,slave的事件功能是自动进制的。

  记录事务

     1、事务在mysql

      在mysql中执行事务操作主要有一下几种情况:

      使用START  TRANSACTION或者BEGIN指令。

      可以通过SET AUTOCOMMIT=1,来设置系统的事务为自动提交模式,每一条SQL语句都是一个事务。但是在事务中如果存在非事务语句没那么该语句就不会作为事务提交。如操作的是MYISAM的表。

      在将AUTOCOMMIT设置为0时,可以通过COMMIT来提交事务。

      在mysql中有些事务是隐式提交的:

      写文件的语句,例如CREATE、ALTER等,在该部分指令操作时,会将前面的语句做一次隐式提交,在执行完该部分指令后,会做一次隐式提交。

      对mysql数据库表的操作,创建、修改和删除用户账户和权限的语句都是隐式提交,并且不是事务的一部分。

    2、事务缓存

      由于在客户端在提交事务后,可能存在多个事务在不同的线程上执行多个事务,在执行事务时,会将多个事务按照执行顺序放到事务缓存中,并将每个事务作为一个单元按照顺序存储到二进制日志,最后清空事务缓存。

    3、非事务性语句作为事务一部分

      如果某一条语句是事务性语句,则会直接进入事务缓存

      如果某一条语句没有标记为事务性语句,在事务缓存中没有该语句,则直接进入二进制日志。

      如果该条语句没有标记为事务语句,但是在事务缓存中存在,则该语句被写入事务缓存。也就是说在某一个事务中即有事务语句又有非事务语句,就会将所有语句作为整个事务保存到事务缓存。

  二进制日志管理

     1、二级制日志与系统崩溃

     在每一个事务提交后,会将事务从事务缓存中清除并提交到二进制日志,以便于在系统崩溃时,利用恢复工具通过二进制日志对数据进行恢复。何时将缓存中的事务写入二进制日志,可以通过一个参数进行设置sync_binlogsync_binlog=0时,是由操作系统的规则将缓存数据写入二进制日志,sync_binlog=n时,在有n个事务提交后,将缓存中的事务写入二进制日志。要想将安全级别设置为最高,可以设置sync_binlog=1,也就是每一次的事务提交都会写入二进制日志,但是这样会产生部分资源开销。

     2、Binlog文件转换

    二进制日志文件并不是在一个文件中无限增大,在达到一定的条件后,就会写入一个新的二进制日志中:

    当一个二进制文件达到指定的文件大小后,就会在该文件的末尾标记新文件的名字和位置,从而产生新的文件,保证二进制文件具有连贯性。

    当服务器停止后,在重新启动时需要产生一个新的二进制文件

    FLUSG LOGS指令可以产生一个新的二进制文件

    一个事故在服务器上运行时

    当系统发生崩溃时,可能会产生一个二进制文件

    binlong文件的版本发生变化时,也就是说MYSQl的版本发生变化时

    服务器版本发生变化时

 

     4、清除binlog文件

    随着数据库的运行,将产生大量的二进制日志文件,我们可以将部分旧的二进制文件清除,清除文件主要有两种方式:一种是在my.cnf文件中设置expires-logs-days选项来保留有效期内的文件,一种是通过PURGE  BINARY  LOGS指令手动清除文件。

    PURGE  BINARY  LOGS  BEFORE  datetime:删除该时间之前的所有文件

    PURGE  BINARY  LOGS  TO filename:删除该文件之前的所有文件

  二进制日志选项和变量

    在my.cnf文件中可以设置部分变量来控制二进制文件的使用情况:

    expires-logs-days:用来设置保存二进制日志时间的有效期,在超出有效期后,将自动清除。

    log-bin:用来设置二进制日志保存的位置和文件的名称

    log-bin-index:用来设置二进制日志文件索引文件的位置和文件名称

    binlog_cache_size:用来设置二进制文件的存留在缓存中的大小

    max_binlog_cache_size:用来设置二进制文件存留在缓存中的最大值

    max_binlog_size:用来设置二进制文件的大小

    sync_binlog:用来设置执行多少条事务就可以将缓存中的事务写入二进制文件

    read_only:设置该mysql为制度服务










以上是关于二进制日志的主要内容,如果未能解决你的问题,请参考以下文章

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

片段事务中的实例化错误

webstorm代码片段的创建

android.view.InflateException:二进制 XML 文件第 15 行:二进制 XML 文件第 19 行:膨胀类片段时出错

python常用代码片段总结

执行代码时有时不显示对话框片段