Binlog 由事件(event)组成,请注意是事件(event)不是事务(transaction),一个事务可以包含多个事件。事件描述对数据库的修改内容。
现在我们已经了解了 Binlog 的结构,我们可以试着修改 Binlog 里的数据。例如前面举例的 Binlog 删除了一条记录,我们可以试着把这条记录恢复,Binlog 里面有个删除行(DELETE_ROWS_EVENT)的事件,就是这个事件删除了记录,这个事件和写行(WRITE_ROWS_EVENT)的事件的数据结构是完全一样的,只是删除行事件的类型是 32,写行事件的类型是 30,我们把对应的 Binlog 位置的 32 改成 30 即可把已经删除的记录再插入回去。从前面的 “show binlog events” 里面可看到这个 DELETE_ROWS_EVENT 是从位置 378 开始的,这里的位置就是 Binlog 文件的实际位置(以字节为单位)。从事件(event)的结构里面可以看到 type_code 是在 event 的第 5 个字节,我们写个 Python 小程序把把第383(378+5=383)字节改成 30 即可。当然您也可以用二进制编辑工具来改。
找出 Binlog 中的大事务
由于 ROW 模式的 Binlog 是每一个变更都记录一条日志,因此一个简单的 SQL,在 Binlog 里可能会产生一个巨无霸的事务,例如一个不带 where 的 update 或 delete 语句,修改了全表里面的所有记录,每条记录都在 Binlog 里面记录一次,结果是一个巨大的事务记录。这样的大事务经常是产生麻烦的根源。我的一个客户有一次向我抱怨,一个 Binlog 前滚,滚了两天也没有动静,我把那个 Binlog 解析了一下,发现里面有个事务产生了 1.4G 的记录,修改了 66 万条记录!下面是一个简单的找出 Binlog 中大事务的 Python 小程序,我们知道用 mysqlbinlog 解析的 Binlog,每个事务都是以 BEGIN 开头,以 COMMIT 结束。我们找出 BENGIN 前面的 “# at” 的位置,检查 COMMIT 后面的 “# at” 位置,这两个位置相减即可计算出这个事务的大小,下面是这个 Python 程序的例子。
切割 Binlog 中的大事务
对于大的事务,MySQL 会把它分解成多个事件(注意一个是事务 TRANSACTION,另一个是事件 EVENT),事件的大小由参数 binlog-row-event-max-size 决定,这个参数默认是 8K。因此我们可以把若干个事件切割成一个单独的略小的事务
ROW 模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,这个行为是 binlog_row_image 参数控制的,这个参数有 3 个值,默认为 FULL,也就是记录列的所有修改,即使字段没有发生变更也会记录。这样我们就可以实现类似 Oracle 的 flashback 的功能,我个人估计 MySQL 未来的版本从可能会基于 Binlog 推出这样的功能。
了解了 Binlog 的结构,再加上 Python 这把瑞士军刀,我们还可以实现很多功能,例如我们可以统计哪个表被修改地最多?我们还可以把 Binlog 切割成一段一段的,然后再重组,可以灵活地进行 MySQL 数据库的修改和迁移等工作。
① 请求消息处理线程负责端口监听,如果有新连接进入则验证连接合法性,如果成功则加入连接池,连接池只能容纳一定量的连接
监听连接池中所有连接是否有消息输入,如果有则读取请求消息
处理连接非协议性关闭(如断电)
② 将请求消息写入消息队列
这时必须换过消息格式,在原来的消息头中加入进队列的时间戳和所属连接。
③ 通知连接无法处理请求
由于消息队列可容纳的消息个数有限,并且消息队列是循环可丢弃型的,只有在消息处理线程组太忙而客户又有大量请求进来时才须要抛弃最旧的消息。在抛弃最旧消息时查一下时间戳,如果未超时则可产生一个‘系统太忙未处理请求’的结果消息加到结果队列去。
如果消息队列已满,可以考虑动态增加处理线程的个数,但处理线程组的个数必须是有限的。
错误日志包含mysqld启动和关闭的时间信息,还包含诊断消息,如服务器启动和关闭期间以及服务器运行时出现的错误、警告和其他需要注意的信息。例如:如果mysqld检测到某个表需要检查或修复,会写入错误日志。
根据错误日志配置,错误消息还可能填充performance_schema.error_log表,以便为日志提供SQL接口,使错误日志能够查询。
如果用mysqld_safe启动mysqld,mysqld_safe会将消息写入错误日志。例如,当mysqld_safe注意到mysqld异常退出时,它会重新启动mysqld,并将mysqld重新启动的消息写入错误日志。
在MySQL 8.0中,错误日志使用MySQL组件(component) 架构。错误日志系统由执行日志事件过滤和写出组件以及系统变量组成,该系统变量配置启用哪些组件来实现所需的日志记录。
基于组件的错误日志记录提供了以下功能:
log_error_services系统变量控制为错误记录启用哪些日志组件。多个组件用逗号或分号分隔,日志系统按照此顺序依次执行。组件分过滤filter和写出sink两类。filter类组件过滤错误日志信息,sink类组件将错误日志写到不同的位置。
过滤器组件 过滤依据 相关系统变量 log_filter_internal 错误事件的优先级及错误代码 log_error_verbosity
log_error_suppression_listlog_filter_dragnet 用户定义的规则 dragnet.log_error_filter_rules
系统变量log_error指定错误日志的缺省目的地,日志组件根据该系统变量决定自己的日志输出目的地。
sink类日志组件 log_error值 目的地 log_sink_internal(缺省) file_name file_name log_sink_internal stderr 控制台log_sink_json stderr 控制台log_sink_json file_name file_name .00.json
file_name .01.jsonlog_sink_test stderr 控制台log_sink_test file_name file_name log_sink_syseventlog stderr 系统日志log_sink_syseventlog file_name 系统日志
安装sink组件log_sink_json,修改log_error_services参数增加log_sink_json写出组件。
目标:配置log_sink_internal组件只记录ERROR类信息。
方法:修改启动参数文件,调整log_error_verbosity参数。
目标:配置log_sink_internal记录ERROR, WARNING, INFORMATION类错误,将 WARNING, INFORMATION中错误号MY-010001,MY-10002过滤掉。
方法:修改启动参数文件,调整log_error_verbosity和log_error_suppression_list参数
目标:配置过滤器,按照用户定义的规则过滤错误日志信息。
方法:使用log_filter_dragnet,配置变量dragnet.log_error_filter_rules添加过滤规则。
目标:将MySQL的错误日志写入Linux系统日志。
方法:使用log_sink_syseventlog组件,将错误日志写入Linux系统日志。
目标:保留原错误日志,让MySQL开始一个新的错误日志。
方法:使用FLUSH ERROR LOGS 或 FLUSH LOGS 或 mysqladmin flush-logs都可以关闭错误日志,然后重新创建错误日志,在此之前应该手工将错误日志改名或备份。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)