iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL中binlog有什么用
  • 980
分享到

MySQL中binlog有什么用

2024-04-02 19:04:59 980人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关Mysql中binlog有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 一、binlog文件和文件的逻辑、物理表现形式

这篇文章将为大家详细讲解有关Mysql中binlog有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、binlog文件和文件的逻辑、物理表现形式

1. binlog文件

binlog文件主要包括:

  1. mysql-bin.000001

  2. mysql-bin.index

其中:

mysql-bin.index内保存着server中未purge的binlog文件,以“文本”形式保留的。

2.binlog文件格式

mysql-bin.index没啥可说的,我们专门看一下二进制binlog文件。

binlog文件格式有以下特点:

  1. binlog是由event组成,event是binlog的逻辑最小单元。

  2. 文件头的头四个字节为BINLOG_MAGIC(fe 62 69 6e)

  3. 紧接着这四个字节的是 descriptor event : FORMAT_DESCRIPTioN_EVENT

  4. 文件的末尾是 log-rotation event: ROTATE_EVENT

  5. 这两个event中间是各种不同的event,每个event代表Master上不同的操作。

下面对基本比较关键的概念进行说明:

  • BINLOG_MAGIC

利用hexdump -C 读取mysql-bin.000005的内容,

这里分别以十六进制和ASCII码展示显示,我们可以看到binlog的头四个字节是固定的:fe 62 69 6e,后三个字符ASCII码为bin,指明展示一个binlog文件。这四个字节成为 BINLOG_MAGIC。

  • event

mysqlbinlog -vvv 读取mysql-bin.000011的内容示例:

这里可以看到,第一个event是FORMAT_DESCRIPTION_EVENT,它记录了这个binlog的版本(MySQL 5.0以后binlog 的版本都是4)。最后一个event,是ROTATE_EVENT,它记录了切换到下一个binlog文件的文件名。

在它们两个之间是各种其他的event,目前的event类型有:



enum Log_event_type { 
    UNKNOWN_EVENT= 0, 
    START_EVENT_V3= 1, 
    QUERY_EVENT= 2, 
    STOP_EVENT= 3, 
    ROTATE_EVENT= 4, 
    INTVAR_EVENT= 5, 
    LOAD_EVENT= 6, 
    SLAVE_EVENT= 7, 
    CREATE_FILE_EVENT= 8, 
    APPEND_BLOCK_EVENT= 9, 
    EXEC_LOAD_EVENT= 10, 
    DELETE_FILE_EVENT= 11, 
    NEW_LOAD_EVENT= 12, 
    RAND_EVENT= 13, 
    USER_VAR_EVENT= 14, 
    FORMAT_DESCRIPTION_EVENT= 15, 
    XID_EVENT= 16, 
    BEGIN_LOAD_QUERY_EVENT= 17, 
    EXECUTE_LOAD_QUERY_EVENT= 18, 
    TABLE_MAP_EVENT = 19, 
    PRE_GA_WRITE_ROWS_EVENT = 20, 
    PRE_GA_UPDATE_ROWS_EVENT = 21, 
    PRE_GA_DELETE_ROWS_EVENT = 22, 
    WRITE_ROWS_EVENT = 23, 
    UPDATE_ROWS_EVENT = 24, 
    DELETE_ROWS_EVENT = 25, 
    INCIDENT_EVENT= 26, 
    HEARTBEAT_LOG_EVENT= 27, 
    IGNORABLE_LOG_EVENT= 28,
    ROWS_QUERY_LOG_EVENT= 29,
    WRITE_ROWS_EVENT = 30,
    UPDATE_ROWS_EVENT = 31,
    DELETE_ROWS_EVENT = 32,
    GTID_LOG_EVENT= 33,
    ANONYMOUS_GTID_LOG_EVENT= 34,
    PREVIOUS_GTIDS_LOG_EVENT= 35, 
    ENUM_END_EVENT 
     
  };
  

当然,内部已经有部分event被弃用了,我们不一一列举,这里只简单介绍几个平时经常见到的:

  • QUERY_EVENT :用于具体的SQL文本。如果binlog_format=statement方式下,insert,update,delete等各种SQL都是以Query event记录下来的。

  • WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT : 在binlog_format=row方式下,insert,update,delete操作的行信息分别以这三种event记录下来。

  • GTID_LOG_EVENT:5.6的GTID模式下,每个事务的GTID序号被记录到这种EVENT中。

  • PREVIOUS_GTIDS_LOG_EVENT :5.6的GTID模式下,这个event记录了生成这个binlog之前,MySQL已经执行的所有事务的GTID集合

二、slave io在源码中是怎么连上Master的

这里主要描述源码中的函数调用关系

1. slave如何注册并请求master 的binlog

slave io线程对应的入口函数为sql/rpl_slave.cc:handle_slave_io()

该函数核心主要是做了以下三个事情:

  1. safe_connect(thd, mysql, mi)

  2. reGISter_slave_on_master(mysql, mi, &suppress_warnings)

  3. request_dump(thd, mysql, mi, &suppress_warnings)

  4. event_len= read_event(mysql, mi, &suppress_warnings);

也就是说,它先以标准的连接方式连上master MySQL,然后把自己注册到master上去,接着调用request_dump向master请求binlog数据,最后一个一个event读取并存放到本地relay log中。

  • safe_connect

连接MySQL的标准方式,MySQL c的connector也是用这种方式连接MySQL Server的。

  • register_slave_on_master

slave把自己的slave_id,IP,端口,用户名提交给Master,用于注册自己到Master上去。

  • request_dump

根据GTID来进行判断,如果是GTID模式,那么把本地执行的GTID集合及其他相关信息传给master;如果不是GTID模式,那么就把master log file和Pos传给主库。主库如何根据这些信息来发送binlog的event,参考下节。

  • read_event

read_event调用了cli_safe_read(),cli_safe_read()调用了my_net_read(),等待主库将binlog数据发过来

也就是说,read_event被动的从网络中接受主库发过来的信息。

2. master 如何处理slave的 binlog 请求

MySQL处理各种命令的核心函数为:sql/sql_parse.cc:dispatch_command

该函数会根据用户的请求来确定做什么事情,

  • COM_REGISTER_SLAVE则调用register_slave(thd, (uchar*)packet, packet_length)注册slave

  • COM_BINLOG_DUMP_GTID 则调用com_binlog_dump_gtid(thd, packet, packet_length);

  • COM_BINLOG_DUMP 则调用com_binlog_dump(thd, packet, packet_length);

我们这里以com_binlog_dump为例介绍master怎么发送binlog event给slave的。

com_binlog_dump核心代码为:

  1. kill_zombie_dump_threads(&slave_uuid);

  2. mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, NULL)

kill_zombie_dump_threads()函数:如果新的server_id相同的slave注册上来,master会移除跟该slave的server_id匹配的的binlog dump线程

com_binlog_dump()会调用mysql_binlog_send()来打开文件,将文件指针挪到指定位置,读取文件,将一个个的event按照事件顺序发给slave。

综上

MySQL复制需要slave先注册到Master,再向Master提交binlog和POS,请求发送binlog。Master接收到请求后,先做一系列验证,打开本地binlog文件,按照内部event的顺序,依序发给slave。

三、sql线程在源码中是怎么读取二进制信息,应用到本地MySQL的

sql线程在5.6引入了db级别的并行,所以有两个入口

1

2

handle_slave_worker

  handle_slave_sql

handle_slave_worker线程是主要干活的函数,handle_salve_sql函数作为协调器会启动和分配worker线程。

handle_slave_sql函数主要调用了slave_worker_exec_job。

slave_worker_exec_job的主要功能:

  1. job_item= pop_jobs_item(worker, job_item); ev= static_cast<Log_event*>(job_item->data);

  2. error= ev->do_apply_event_worker(worker);

该函数做到事情其实就是 从handle_salve_sql()获得具体的event(ev),然后调用ev->do_apply_event_worker(worker),利用c++的多态特性,调用真正的event的do_apply_event虚函数,以便将不同的event的操作在本地做一遍。

这里需要大家回顾一下event的概念了,event是binlog的最小单元,所有的event的父类是Log_event(抽象基类),它定义了一系列虚函数,其中就包括我们这里调用的函数:

这里举一个insert语句对应的的Write_rows_log_event例子,简单说明一下数据是怎么应用到本地MySQL的。

Write_rows_log_event,Update_rows_log_event和Delete_rows_log_event的do_apply_event都是调用的它的基类Rows_log_event的do_apply_event。

Rows_log_event的do_apply_event主要功能如下:

  1. m_table= const_cast <relay_log_info* style=”-WEBkit-print-color-adjust: exact;”> (rli)->m_table_map.get_table(m_table_id);

  2. error= (this->*do_apply_row_ptr)(rli);

get_table()先从table map中获得对应的table的信息,然后调用do_apply_row_ptr函数指针指向的函数来将event对应操作应用到本地MySQL。

do_apply_row_ptr函数指针可能指向以下几种不同的函数:

  • do_hash_scan_and_update

  • do_index_scan_and_update

  • do_table_scan_and_update

  • do_apply_row

Write_rows_log_event是insert,不用查找数据,所以它调用的是do_apply_row。

do_apply_row主要的功能就是调用了do_exec_row ….汗

do_exec_row是Write_rows_log_event自己实现的,它的主要功能是调用了 write_row ….汗

write_row也是Write_rows_log_event自己实现的,它的主要功能是:m_table->file->ha_start_bulk_insert(estimated_rows);也就是说,它直接把这一行数据交给了存储引擎,让存储引擎把数据给插进去。

四、binlog_format=ROW 格式下,MySQL是怎么用二进制保存各种不同的数据类型的

在sql/log_event.cc:log_event_print_value()函数中详细描述了MySQL的各种数据类型的二进制表现形式,摘录如下

这里有几个比较有意思的地方:

  1. MYSQL_TYPE_STRING 类型,它的length占用的字节数是不固定的。如果string长度不到大于255,则需要占用2个字节,所以,MySQL在定义String类型的字段时,255是一个坎,如果字段不可能超过255个字节,不建议定义长度的时候超过255,否则MySQL存储数据时会白白浪费一个字节。

  2. MYSQL_TYPE_DATETIME类型。它存储的格式就是把年-月-日 时:分:秒按顺序存储下来的,比如:2015-10-10 22:45:55存储下来就存储为20151010224545。这种存储格式比较浪费,所以字节数相比timestamp占用的也比较多。

关于“MySQL中binlog有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL中binlog有什么用

本文链接: https://www.lsjlt.com/news/62702.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-14
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-14
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-14
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-14
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-14
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-14
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-14
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-14
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作