mysql物理文件
一、日志类
1.binlog MySQL 会将所有修改数据库数据的query(查询) 以二进制形式记录到日志文件中。
当然,日志中并不仅限于query 语句这么简单,还包括每一条query 所执行的时间,所消耗的资源,
以及相关的事务信息,所以binlog是事务安全的。 --log-bin[=file_name]
2.慢查询 slow query log --log-slow-queries[=file_name]
慢查询日志采用的是简单的文本格式,可以通过各种文本编辑器查看其中的内容。其中
记录了语句执行的时刻,执行所消耗的时间,执行用户,连接主机等相关信息。MySQL 还提
供了专门用来分析满查询日志的工具程序mysqlslowdump,用来帮助数据库管理人员解决可
能存在的性能问题。
二、数据文件
MyISAM
.frm
.MYD
.MYI
Innodb
.ibd
ibdata
Replication相关
master.info
relay log
relay log index
relay-log.info
Mysql系统架构
MySQL 可以看成是二层架构,第一层我们通常叫做SQL Layer,在MySQL 数据库系统处理
底层数据之前的所有工作都是在这一层完成的,包括权限判断,sql 解析,执行计划优化,
query cache 的处理等等;第二层就是存储引擎层,我们通常叫做Storage Engine Layer,
也就是底层数据存取操作实现部分,由多种存储引擎共同组成。
mysqldump 完成备份后再取消写入锁定,重新开始提供完整的服务。mysqldump 程
序自己也提供了相关选项如“--lock-tables”和“--lock-all-tables”,在执行之前会锁
定表,执行结束后自动释放锁定
mysql备份策略
1、对于较为核心的在线应用系统,比需要有在线备用主机通过MySQL 的复制进行相
应的备份,复制线程可以一直开启,恢复线程可以每天恢复一次,尽量让备机的数
据延后主机在一定的时间段之内。这个延后的时间多长合适主要是根据实际需求决
定,一般来说延后一天是一个比较常规的做法。
2、对于重要级别稍微低一些的应用,恢复时间要求不是太高的话,为了节约硬件成本,
不必要使用在线的备份主机来单独运行备用MySQL,而是通过每一定的时间周期内
进行一次物理全备份,同时每小时(或者其他合适的时间段)内将产生的二进制日
志进行备份。这样虽然没有第一种备份方法恢复快,但是数据的丢失会比较少。恢
复所需要的时间由全备周期长短所决定。
3、而对于恢复基本没有太多时间要求,但是不希望太多数据丢失的应用场景,则可以
通过每一定时间周期内进行一次逻辑全备份,同时也备份相应的二进制日志。使用
逻辑备份而不使用物理备份的原因是因为逻辑备份实现简单,可以完全在线联机完
成,备份过程不会影响应用提供服务。
4、对于一些搭建临时数据库的备份应用场景,则仅仅只需要通过一个逻辑全备份即可
满足需求,都不需要用二进制日志来进行恢复,因为这样的需求对数据并没有太苛
刻的要求。
下什么样的数据适合通过Cache 技术来提高系统性能:
1. 系统各种配置及规则数据;
由于这些配置信息变动的频率非常低,访问概率又很高,所以非常适合存使用Cache;
2. 活跃用户的基本信息数据;
虽然我们经常会听到某某网站的用户量达到成百上千万,但是很少有系统的活跃用户量能够都
达到这个数量级。也很少有用户每天没事干去将自己的基本信息改来改去。更为重要的一点是
用户的基本信息在应用系统中的访问频率极其频繁。所以用户基本信息的Cache,很容易让整个
应用系统的性能出现一个质的提升。
3. 活跃用户的个性化定制信息数据;
虽然用户个性化定制的数据从访问频率来看,可能并没有用户的基本信息那么的频繁,但相对
于系统整体来说,也占了很大的比例,而且变更皮律一样不会太多。从Ebay 的PayPal 通过
MySQL 的Memory 存储引擎实现用户个性化定制数据的成功案例我们就能看出对这部分信息进行
Cache 的价值了。虽然通过MySQL 的Memory 存储引擎并不像我们传统意义层面的Cache 机制,
但正是对Cache 技术的合理利用和扩充造就了项目整体的成功。
4. 准实时的统计信息数据;
所谓准实时的统计数据,实际上就是基于时间段的统计数据。这种数据不会实时更新,也很少
需要增量更新,只有当达到重新Build 该统计数据的时候需要做一次全量更新操作。虽然这种
数据即使通过数据库来读取效率可能也会比较高,但是执行频率很高之后,同样会消耗不少资
源。既然数据库服务器的资源非常珍贵,我们为什么不能放在应用相关的内存Cache 中呢?
5. 其他一些访问频繁但变更较少的数据;
出了上面这四种数据之外,在我们面对的各种系统环境中肯定还会有各种各样的变更较少但是
访问很频繁的数据。只要合适,我们都可以将对他们的访问从数据库移到Cache 中。
在Master 与Slave 之间的
实现整个复制过程主要由三个线程来完成,其中两个线程(Sql 线程和IO 线程)在Slave 端,
另外一个线程(IO 线程)在Master 端。
要实现MySQL 的Replication ,首先必须打开Master 端的Binary Log(mysqlbin.
xxxxxx)功能,否则无法实现。因为整个复制过程实际上就是Slave 从Master 端获取
该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。打开MySQL 的Binary
Log 可以通过在启动MySQL Server 的过程中使用“―log-bin” 参数选项,或者在my.cnf
配置文件中的mysqld 参数组([mysqld]标识后的参数部分)增加“log-bin” 参数项。
MySQL 复制的基本过程如下:
1. Slave 上面的IO 线程连接上Master,并请求从指定日志文件的指定位置(或者从
最开始的日志)之后的日志内容;
2. Master 接收到来自Slave 的IO 线程的请求后,通过负责复制的IO 线程根据请
求信息读取指定日志指定位置之后的日志信息,返回给Slave 端的IO 线程。返回信
息中除了日志所包含的信息之外,还包括本次返回的信息在Master 端的Binary Log
文件的名称以及在Binary Log 中的位置;
3. Slave 的IO 线程接收到信息后,将接收到的日志内容依次写入到Slave 端的
Relay Log 文件(mysql-relay-bin.xxxxxx)的最末端,并将读取到的Master 端的binlog
的文件名和位置记录到master-info 文件中,以便在下一次读取的时候能够清楚的
高速Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”
4. Slave 的SQL 线程检测到Relay Log 中新增加了内容后,会马上解析该Log 文
件中的内容成为在Master 端真实执行时候的那些可执行的Query 语句,并在自身执
行这些Query。这样,实际上就是在Master 端和Slave 端执行了同样的Query,所
以两端的数据是完全一样的。
实际上,在老版本中,MySQL 的复制实现在Slave 端并不是由SQL 线程和IO 线程
这两个线程共同协作而完成的,而是由单独的一个线程来完成所有的工作。但是MySQL 的
工程师们很快发现,这样做存在很大的风险和性能问题,主要如下:
首先,如果通过一个单一的线程来独立实现这个工作的话,就使复制Master 端的,
Binary Log 日志,以及解析这些日志,然后再在自身执行的这个过程成为一个串行的过程,
性能自然会受到较大的限制,这种架构下的Replication 的延迟自然就比较长了。
其次,Slave 端的这个复制线程从Master 端获取Binary Log 过来之后,需要接着解
析这些内容,还原成Master 端所执行的原始Query,然后在自身执行。在这个过程中,
Master 端很可能又已经产生了大量的变化并生成了大量的Binary Log 信息。如果在这个
阶段Master 端的存储系统出现了无法修复的故障,那么在这个阶段所产生的所有变更都将
永远的丢失,无法再找回来。这种潜在风险在Slave 端压力比较大的时候尤其突出,因为
如果Slave 压力比较大,解析日志以及应用这些日志所花费的时间自然就会更长一些,可
能丢失的数据也就会更多。
Dual Master 复制架构(Master - Master)
有些时候,简单的从一个MySQL 复制到另外一个MySQL 的基本Replication 架构,
可能还会需要在一些特定的场景下进行Master 的切换。如在Master 端需要进行一些特别
的维护操作的时候,可能需要停MySQL 的服务。这时候,为了尽可能减少应用系统写服务
的停机时间,最佳的做法就是将我们的Slave 节点切换成Master 来提供写入的服务。
但是这样一来,我们原来Master 节点的数据就会和实际的数据不一致了。当原Master
启动可以正常提供服务的时候,由于数据的不一致,我们就不得不通过反转原Master -
Slave 关系,重新搭建Replication 环境,并以原Master 作为Slave 来对外提供读的服
务。重新搭建Replication 环境会给我们带来很多额外的工作量,如果没有合适的备份,
可能还会让Replication 的搭建过程非常麻烦。
为了解决这个问题,我们可以通过搭建Dual Master 环境来避免很多的问题。何谓
Dual Master 环境?实际上就是两个MySQL Server 互相将对方作为自己的Master,自己
作为对方的Slave 来进行复制。这样,任何一方所做的变更,都会通过复制应用到另外一
方的数据库中。
可能有些读者朋友会有一个担心,这样搭建复制环境之后,难道不会造成两台MySQL 之
间的循环复制么?实际上MySQL 自己早就想到了这一点,所以在MySQL 的Binary Log 中
记录了当前MySQL 的server-id,而且这个参数也是我们搭建MySQL Replication 的时候
必须明确指定,而且Master 和Slave 的server-id 参数值比需要不一致才能使MySQL
Replication 搭建成功。一旦有了server-id 的值之后,MySQL 就很容易判断某个变更是
从哪一个MySQL Server 最初产生的,所以就很容易避免出现循环复制的情况。而且,如果
我们不打开记录Slave 的Binary Log 的选项(--log-slave-update)的时候,MySQL 根
本就不会记录复制过程中的变更到Binary Log 中,就更不用担心可能会出现循环复制的情
形了。
通过Dual Master 复制架构,我们不仅能够避免因为正常的常规维护操作需要的停机
所带来的重新搭建Replication 环境的操作,因为我们任何一端都记录了自己当前复制到
对方的什么位置了,当系统起来之后,就会自动开始从之前的位置重新开始复制,而不需要
人为去进行任何干预,大大节省了维护成本。
不仅仅如此,Dual Master 复制架构和一些第三方的HA 管理软件结合,还可以在我们
当前正在使用的Master 出现异常无法提供服务之后,非常迅速的自动切换另外一端来提供
相应的服务,减少异常情况下带来的停机时间,并且完全不需要人工干预。
当然,我们搭建成一个Dual Master 环境,并不是为了让两端都提供写的服务。在正
常情况下,我们都只会将其中一端开启写服务,另外一端仅仅只是提供读服务,或者完全不
提供任何服务,仅仅只是作为一个备用的机器存在。为什么我们一般都只开启其中的一端来
提供写服务呢?主要还是为了避免数据的冲突,防止造成数据的不一致性。因为即使在两边
执行的修改有先后顺序,但由于Replication 是异步的实现机制,同样会导致即使晚做的
修改也可能会被早做的修改所覆盖,就像如下情形:
时间点MySQL A MySQL B
1 更新x 表y 记录为10
2 更新x 表y 记录为20
3 获取到A 日志并应用,更新x 表的y 记录为1 0(不符合期望)
4 获取B 日志更新x 表y 记录为20(符合期望)
这中情形下,不仅在B 库上面的数据不是用户所期望的结果,A 和B 两边的数据也出现
了不一致。