您好,欢迎访问一九零五行业门户网

mysql日志文件undo log和redo log怎么设置

1 undo1.1 undo是什么undo日志用于存放数据修改被修改前的值,假设修改 tba 表中 id=2的行数据,把name='b' 修改为name = 'b2' ,那么undo日志就会用来存放name='b'的记录,如果这个修改出现异常,可以使用undo日志来实现回滚操作,保证事务的一致性。
对数据的变更操作,主要来自 insert update delete,而undo log中分为两种类型,一种是 insert_undo(insert操作),记录插入的唯一键值;一种是 update_undo(包含update及delete操作),记录修改的唯一键值以及old column记录。
id name
1 a
2 b
3 c
4 d
1.2 undo参数mysql跟undo有关的参数设置有这些:
mysql> show global variables like '%undo%';+--------------------------+------------+| variable_name | value |+--------------------------+------------+| innodb_max_undo_log_size | 1073741824 || innodb_undo_directory | ./ || innodb_undo_log_truncate | off || innodb_undo_logs | 128 || innodb_undo_tablespaces | 3 |+--------------------------+------------+mysql> show global variables like '%truncate%';+--------------------------------------+-------+| variable_name | value |+--------------------------------------+-------+| innodb_purge_rseg_truncate_frequency | 128 || innodb_undo_log_truncate | off |+--------------------------------------+-------+
innodb_max_undo_log_size
    控制最大undo tablespace文件的大小,当启动了innodb_undo_log_truncate 时,undo tablespace 超过innodb_max_undo_log_size 阀值时才会去尝试truncate。该值默认大小为1g,truncate后的大小默认为10m。
innodb_undo_tablespaces 
设置undo独立表空间个数,范围为0-128, 默认为0,0表示表示不开启独立undo表空间 且 undo日志存储在ibdata文件中。该参数只能在最开始初始化mysql实例的时候指定,如果实例已创建,这个参数是不能变动的,如果在数据库配置文 件 .cnf 中指定innodb_undo_tablespaces 的个数大于实例创建时的指定个数,则会启动失败,提示该参数设置有误。
如果设置了该参数为n(n>0),那么就会在undo目录下创建n个undo文件(undo001,undo002 ...... undo n),每个文件默认大小为10m.
什么时候需要来设置这个参数呢?
当db写压力较大时,可以设置独立undo表空间,把undo log从ibdata文件中分离开来,指定 innodb_undo_directory目录存放,可以制定到高速磁盘上,加快undo log 的读写性能。
innodb_undo_log_truncate
innodb的purge线程,根据innodb_undo_log_truncate设置开启或关闭、innodb_max_undo_log_size的参数值,以及truncate的频率来进行空间回收和 undo file 的重新初始化。
 该参数生效的前提是,已设置独立表空间且独立表空间个数大于等于2个。
purge线程在truncate undo log file的过程中,需要检查该文件上是否还有活动事务,如果没有,需要把该undo log file标记为不可分配,这个时候,undo log 都会记录到其他文件上,所以至少需要2个独立表空间文件,才能进行truncate 操作,标注不可分配后,会创建一个独立的文件undo_14dd8211b5a9bbcc94f64984f0f1e91e_trunc.log,记录现在正在truncate 某个undo log文件,然后开始初始化undo log file到10m,操作结束后,删除表示truncate动作的 undo_14dd8211b5a9bbcc94f64984f0f1e91e_trunc.log 文件,这个文件保证了即使在truncate过程中发生了故障重启数据库服务,重启后,服务发现这个文件,也会继续完成truncate操作,删除文件结束后,标识该undo log file可分配。
innodb_purge_rseg_truncate_frequency
用于控制purge回滚段的频度,默认为128。假设设置为n,则说明,当innodb purge操作的协调线程 purge事务128次时,就会触发一次history purge,检查当前的undo log 表空间状态是否会触发truncate。
1.3 undo空间管理如果需要设置独立表空间,需要在初始化数据库实例的时候,指定独立表空间的数量。
undo内部由多个回滚段组成,即 rollback segment,一共有128个,保存在ibdata系统表空间中,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成。
回滚段(rollback segment)分配如下:
slot 0 ,预留给系统表空间;
slot 1- 32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;
slot33-127,如果有独立表空间,则预留给undo独立表空间;如果没有,则预留给系统表空间;
回滚段中除去32个提供给临时表事务使用,剩下的 128-32=96个回滚段,可执行 96*1024 个并发事务操作,每个事务占用一个 undo segment slot,注意,如果事务中有临时表事务,还会在临时表空间中的 undo segment slot 再占用一个 undo segment slot,即占用2个undo segment slot。如果错误日志中有:cannot find a free slot for an undo log。则说明并发的事务太多了,需要考虑下是否要分流业务。
回滚段(rollback segment )采用 轮询调度的方式来分配使用,如果设置了独立表空间,那么就不会使用系统表空间回滚段中undo segment,而是使用独立表空间的,同时,如果回顾段正在 truncate操作,则不分配。
2 redo2.1 redo是什么当数据库对数据做修改的时候,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为dirty page 脏数据,如果这个时候发生非正常的db服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机io),也就是会发生数据丢失,如果这个时候,能够在有一个文件,当buffer pool 中的data page变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序io),那么当db服务发生crash的情况,恢复db的时候,也可以根据这个文件的记录内容,重新应用到磁盘文件,数据保持一致。
这个文件就是redo log ,用于记录 数据修改后的记录,顺序记录。它可以带来这些好处:
当buffer pool中的dirty page 还没有刷新到磁盘的时候,发生crash,启动服务后,可通过redo log 找到需要重新刷新到磁盘文件的记录;
buffer pool中的数据直接flush到disk file,是一个随机io,效率较差,而把buffer pool中的数据记录到redo log,是一个顺序io,可以提高事务提交的速度;
假设修改 tba 表中 id=2的行数据,把name='b' 修改为name = 'b2' ,那么redo日志就会用来存放name='b2'的记录,如果这个修改在flush 到磁盘文件时出现异常,可以使用redo log实现重做操作,保证事务的持久性。
id name
1 a
2 b
3 c
4 d
这里注意下redo log 跟binary log 的区别,redo log 是存储引擎层产生的,而binary log是数据库层产生的。假设一个大事务,对tba做10万行的记录插入,在这个过程中,一直不断的往redo log顺序记录,而binary log不会记录,知道这个事务提交,才会一次写入到binary log文件中。有三种不同的记录格式可供二进制日志使用,分别是row、statement和mixed,它们之间的记录形式各不相同。
2.2 redo 参数innodb_log_files_in_group
redo log 文件的个数,命名方式如:ib_logfile0,iblogfile1... iblogfilen。默认2个,最大100个。
innodb_log_file_size
文件设置大小,默认值为 48m,最大值为512g,注意最大值指的是整个 redo log系列文件之和,即(innodb_log_files_in_group * innodb_log_file_size )不能大于最大值512g。
innodb_log_group_home_dir
文件存放路径
innodb_log_buffer_size
redo log 缓存区,默认8m,可设置1-8m。延迟事务日志写入磁盘,把redo log 放到该缓冲区,然后根据 innodb_flush_log_at_trx_commit参数的设置,再把日志从buffer 中flush 到磁盘中。
innodb_flush_log_at_trx_commit
innodb_flush_log_at_trx_commit=1,每次commit都会把redo log从redo log buffer写入到system,并fsync刷新到磁盘文件中。
innodb_flush_log_at_trx_commit=2,每次事务提交时mysql会把日志从redo log buffer写入到system,但只写入到file system buffer,由系统内部来fsync到磁盘文件。如果数据库实例crash,不会丢失redo log,但是如果服务器crash,由于file system buffer还来不及fsync到磁盘文件,所以会丢失这一部分的数据。
innodb_flush_log_at_trx_commit=0,事务发生过程,日志一直激励在redo log buffer中,跟其他设置一样,但是在事务提交时,不产生redo 写操作,而是mysql内部每秒操作一次,从redo log buffer,把数据写入到系统中去。如果发生crash,即丢失1s内的事务修改操作。
注意:由于进程调度策略问题,这个“每秒执行一次 flush(刷到磁盘)操作”并不是保证100%的“每秒”。
2.3 redo 空间管理redo log文件以ib_logfile[number]命名,redo log 以顺序的方式写入文件文件,写满时则回溯到第一个文件,进行覆盖写。(但在做redo checkpoint时,也会更新第一个日志文件的头部checkpoint标记,所以严格来讲也不算顺序写)。
事实上,redo日志由两个部分构成:redo日志缓冲区和redo日志文件。buffer pool中把数据修改情况记录到redo log buffer,出现以下情况,再把redo log刷下到redo log file:
redo log buffer空间不足
事务提交(依赖innodb_flush_log_at_trx_commit参数设置)
后台线程
做checkpoint
实例shutdown
binlog切换
3 undo及redo如何记录事务3.1 undo + redo事务的简化过程假设有a、b两个数据,值分别为1,2,开始一个事务,事务的操作内容为:把1修改为3,2修改为4,那么实际的记录如下(简化):
  a.事务开始.
  b.记录a=1到undo log.
  c.修改a=3.
  d.记录a=3到redo log.
  e.记录b=2到undo log.
  f.修改b=4.
  g.记录b=4到redo log.
  h.将redo log写入磁盘。
  i.事务提交
3.2  io影响设计undo + redo的主要目的是提高输入输出性能,增加数据库的处理能力。可以看出,b d e g h,均是新增操作,但是b d e g 是缓冲到buffer区,只有g是增加了io操作,为了保证redo log能够有比较好的io性能,innodb 的 redo log的设计有以下几个特点:
b. 尽量确保redo log存储在连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。为了提高性能,redo log会以顺序io的方式进行记录,并且采用逐步添加的方式完成。
  b. 批量写入日志。日志并不是直接写入文件,而是先写入redo log buffer.当需要将日志刷新到磁盘时 (如事务提交),将许多日志一起写入磁盘.
  c. 并发的事务共享redo log的存储空间,它们的redo log按语句的执行顺序,依次交替的记录在一起,以减少日志占用的空间。例如,redo log中的记录内容可能是这样的:
     记录1: bf078c762036cee730ffa75389ae8be7
     记录2: 3f2ec9da89933f241944d5196e3614ba
     记录3: 86791f650287d1f30958866d2e4497cf
     记录4: 34325d79c0b34ef063d5d792ced21635
     记录5: b9a2f5a1fc9cf645058c5a80d062b8c9
  d. 因为c的原因,当一个事务将redo log写入磁盘时,也会将其他未提交的事务的日志写入磁盘。
  e. redo log上只进行顺序追加的操作,当一个事务需要回滚时,它的redo log记录也不会从redo log中删除掉。
3.3 恢复前面说到未提交的事务和回滚了的事务也会记录redo log,因此在进行恢复时,这些事务要进行特殊的的处理。有2种不同的恢复策略:
  a. 进行恢复时,只重做已经提交了的事务。
在进行恢复时,需要重新执行所有事务,包括未提交的和已回滚的事务。然后通过undo log回滚那些
     未提交的事务。
  mysql数据库innodb存储引擎使用了b策略, innodb存储引擎中的恢复机制有几个特点:
  a. 在重做redo log时,并不关心事务性。 恢复时,没有begin,也没有commit,rollback的行为。也不关心每个日志是哪个事务的。尽管事务id等事务相关的内容会记入redo log,这些内容只是被当作要操作的数据的一部分。
  b. 使用b策略就必须要将undo log持久化,而且必须要在写redo log之前将对应的undo log写入磁盘。undo和redo log的这种关联,使得持久化变得复杂起来。为了降低复杂度,innodb将undo log看作数据,因此记录undo log的操作也会记录到redo log中。通过将undo日志缓存在内存中,避免了在写redo日志之前将其写入磁盘的必要性。
     包含undo log操作的redo log,看起来是这样的:
     记录1: 4bd54eb51e19fcca64440c630f9c5dcd>
     记录2: bf078c762036cee730ffa75389ae8be7
     记录3: 69cd2d485aa16a51ad3e317a3c6f1c4e>
     记录4: 3f2ec9da89933f241944d5196e3614ba
     记录5: e9ed01a7a566ba3d4a4b60ea2af079d0>
     记录6: ddb974c11f7d5a2adde734158b4fa210
  c. 到这里,还有一个问题没有弄清楚。既然redo没有事务性,那岂不是会重新执行被回滚了的事务?
     确实是这样。同时innodb也会将事务回滚时的操作也记录到redo log中。在进行回滚操作时,对数据的修改被记录到redo log中,因为回滚操作本质上也是对数据进行修改。
     一个回滚了的事务的redo log,看起来是这样的:
     记录1: c1c53b6e4a5b942f0922376be488b37a>
     记录2: 4322c03ea53f609a1176afa643f64223
     记录3: 02173e28db564862d8469fa20861a424>
     记录4: f3517b20c2e8c01ecfcece9d41c0b650
     记录5: 697b2e07fbcbc01ebfada8903c0d5f7c>
     记录6: 39f2dc01b9bfc67e3a567acb41246eb7
     记录7: 8bd1962a2d772367fdf47a6ed083f8b6
     记录8: 3568b0c61735ee84f8bd4314e312eae7
     记录9: e7eb3a3102ef2ceca4ef016df5465e04
一个被回滚了的事务在恢复时的操作就是先redo再undo,因此不会破坏数据的一致性。
以上就是mysql日志文件undo log和redo log怎么设置的详细内容。
其它类似信息

推荐信息