uu直播快3平台_UU快3直播官方

MySQL · 引擎特性 · InnoDB崩溃恢复

时间:2020-02-13 23:59:17 出处:uu直播快3平台_UU快3直播官方

执行完了redo前滚数据库,数据库的所有数据页将会所处一致的情况表,undo回滚数据库就都能不能安全的执行了。数据库崩溃的以前将会有某些没有提交的事务将会将会提交的事务,类事以前就前要决定是是不是提交。主要分为三步,首先是扫描undo日志,重新建立起undo日志链表,接着是,土辦法 上一步建立起的链表,重建崩溃前的事务,即恢复当时事务的情况表。最后,我希望土辦法 事务的不同情况表,进行回滚将会提交。

undo日志回滚数据库

检查点: 英文名为checkpoint。数据库为了提高性能,数据页在内存修改后并前要每次总要刷到磁盘上。checkpoint以前的数据页保证一定落盘了,从前以前的日志就没有用了(将会InnoDB redolog日志循环使用,这时这每段日志就都能不能被覆盖),checkpoint以前的数据页有将会落盘,前要将会没有落盘,什么都有checkpoint以前的日志在崩溃恢复的以前还是前要被使用的。InnoDB会土辦法 脏页的刷新情况表,定期推进checkpoint,从而减少数据库崩溃恢复的时间。检查点的信息在第还还有一个 日志文件的头部。

前滚数据库,主要分为两阶段,首先是日志扫描阶段,扫描阶段按照数据页的space_id和page_no分发redo日志到hash_table中,保证同还还有一个 数据页的日志被分发到同还还有一个 哈希桶中,且按照lsn大小从小到大排序。扫描以前,再遍历整个哈希表,依次应用每个数据页的日志,应用以前,在数据页的情况表上离米 恢复到了崩溃以前的情况表。亲们来完整篇 分析一下代码。 首先,打开所有的ibdata文件(open_or_create_data_files)(ibdata都能不能有多个),每个ibdata文件有个flush_lsn在头部,计算出什么文件中的max_flush_lsn和min_flush_lsn,将会ibdata前要将会有数据没写完整篇 ,前要恢复,后续(recv_recovery_from_checkpoint_start_func)通过比较checkpoint_lsn和类事个 值来挑选是是不是前要对ibdata前滚。 接着,打开系统表空间和日志表空间的所有文件(fil_open_log_and_system_tablespace_files),防止老出文件句柄严重不足,清空buffer pool(buf_pool_invalidate)。接下来就进入最最核心的函数: (recv_recovery_from_checkpoint_start_func),注意,即使数据库是正常关闭的,也会进入。 真是recv_recovery_from_checkpoint_start_func看后去很冗长,因此什么都有代码前要为了LOG_ARCHIVE特征而编写的,真正数据崩溃恢复的代码真是不必 。 首先,初始化某些变量,查看srv_force_recovery类事变量,将会用户设置跳过前滚阶段,函数直接返回。 接着,初始化recv_sys特征,分配hash_table的大小,并肩初始化flush list rbtree。recv_sys特征主要在崩溃恢复前滚阶段使用。hash_table我希望以前说的用来存不同数据页日志的哈希表,哈希表的大小被初始化为buffer_size_in_bytes/512, 类事是哈希表最大的长度,超过就存不下了,幸运的是,前要恢复的数据页的个数不必超过类事值,将会buffer poll最多(数据库崩溃以前脏页的上线)没有存放buffer_size_in_bytes/16KB个数据页,即使考虑压缩页,最多也没有buffer_size_in_bytes/1KB个,此外关于类事哈希表内存分配的大小,都能不能参考bug#53122。flush list rbtree类事主我希望为了加入插入脏页列表,InnoDB的flush list前要按照数据页的最老修改lsn(oldest_modifcation)从小到大排序,在数据库正常运行时,都能不能通过log_sys->mutex和log_sys->log_flush_order_mutex保证顺序,在崩溃恢复则没有类事保证,应用数据的以前,是从第还还有一个 元素现在现在刚开始遍历哈希表,没有保证数据页按照最老修改lsn(oldest_modifcation)从小到大排序,从前就前要线性遍历flush_list来寻找插入位置,带宽太低,因此引入红黑树,加快查找插入的位置。 接着,从ib_logfile0的头中读取checkpoint信息,主要包括checkpoint_lsn和checkpoint_no。将会InnoDB日志是循环使用的,且离米 要有还还有一个 ,什么都有ib_logfile0一定所处,把checkpoint信息所处后边很安全,不必担心被删除。checkpoint信息真是会写在文件头的还还有一个 地方,还还有一个 checkpoint域轮流写。为什么会要还还有一个 地方轮流写呢?假设没有还还有一个 checkpoint域,无缘无故更新类事域,而checkpoint域有512字节(OS_FILE_LOG_BLOCK_SIZE),将会刚好在写类事512字节的以前,数据库挂了,服务器也挂了(先不考虑硬件的原子写特征,早期的硬件没有类事特征),类事512字节将会只写了一半,是因为整个checkpoint域不可用。从前数据库将无法做崩溃恢复,从而无法启动。将会有还还有一个 checkpoint域,没有即使还还有一个 写坏了,还都能不能用另外还还有一个 尝试恢复,真是有将会类事以前日志将会被覆盖,因此离米 提高了恢复成功的概率。还还有一个 checkpoint域轮流写,才能减少磁盘扇区故障带来的影响。checkpoint_lsn以前的数据页都将会落盘,不前要前滚,以前的数据页将会还没落盘,前要重新恢复出来,即使将会落盘也没关系,将会redo日志是幂等的,应用一次和应用两次都一样(底层实现: 将会数据页上的lsn大于等于当前redo日志的lsn,就不应用,因此应用。checkpoint_no都能不能理解为checkpoint域写盘的次数,每次刷盘递增1,并肩类事值取模2都能不能用来实现checkpoint_no域的轮流写。正常逻辑下,挑选checkpoint_no值大的作为最终的checkpoint信息,用来做后续崩溃恢复扫描的起始点。 接着,使用checkpoint域的信息初始化recv_sys特征体的某些信息后,就进入日志解析的核心函数recv_group_scan_log_recs,类事函数后续亲们再分析,主要作用我希望解析redo日志,将会内存严重不足了,就直接调用应用(recv_apply_hashed_log_recs)日志,因此再接着解析。将会前要应用的日志很少,就仅仅解析分发日志,到recv_recovery_from_checkpoint_finish函数中在应用日志。 接着,土辦法 当前刷盘的数据页情况表做一次checkpoint,将会在recv_group_scan_log_recs里将会将会应用每段日志了。至此recv_recovery_from_checkpoint_start_func函数现在现在刚开始。 在recv_recovery_from_checkpoint_finish函数中,将会srv_force_recovery设置正确,就现在现在刚开始调用函数recv_apply_hashed_log_recs应用日志,因此等待时间刷脏的应用多多线程 退出(应用多多线程 是崩溃恢复是临时启动的),最后释放recv_sys的相关资源以及hash_table占用的内存。 至此,数据库前滚现在现在刚开始。接下来,亲们完整篇 分析一下redo日志解析函数以及redo日志应用函数的实现细节。

解析函数的最上层是recv_group_scan_log_recs,类事函数调用底层函数(log_group_read_log_seg),按照RECV_SCAN_SIZE(64KB)大小分批读取。读取出来后,首先通过block_no和lsn之间的关系以及日志checksum判断是是不是读到了日志最后(什么都有都能不能看出,并没还还有一个 标记在日志头标记日志的有效位置,完前要按照上述还还有一个 条件判断是是不是到达了日志尾部),将会读到最后则返回(以前说了,即使数据库是正常关闭的,也要走崩溃恢复逻辑,没有在这里就返回了,将会正常关闭的checkpoint值一定是指向日志最后),因此则把日志去头掐尾放到 还还有一个 recv_sys->buf中,日志头后边存了某些控制信息和checksum值,我希望用来校验和定位,在真正的应用中没有用。在放到 recv_sys->buf以前,前要检验一下recv_sys->buf有没有满(RECV_PARSING_BUF_SIZE,2M),满了就报错(将会上一批解析有不完整篇 的日志,日志解析函数不必分发,我希望把什么不完整篇 的日志留在recv_sys->buf中,直到解析到完整篇 的日志)。接下的事情我希望从recv_sys->buf中解析日志(recv_parse_log_recs)。日志分一种生活:single_rec和multi_rec,前者表示只对还还有一个 数据页进行一种生活操作,后者表示对还还有一个 将会多个数据页进行多种操作。日志中还包括对应数据页的space_id,page_no,操作的type以及操作的内容(recv_parse_log_rec)。解蒸发掉相应的日志后,按照space_id和page_no进行哈希(将会对应的表空间在内存中不所处,则表示表将会被删除了),放到 hash_table后边(日志真正存放的位置依然在buffer pool)即可,等待时间后续应用。这里有几块点值得注意:

innodb_force_recovery: 类事参数主要用来控制InnoDB启动以前做什么工作,数值越大,做的工作越少,启动也更加容易,因此数据不一致的风险也越大。当MySQL将会某些不可控的是因为没有启动时,都能不能设置类事参数,从1现在现在刚开始逐步递增,知道MySQL启动,因此使用SELECT INTO OUTFILE把数据导出,尽最大的努力减少数据丢失。 innodb_force_recovery = 0。类事是默认的参数,启动的以总要做所有的事情,包括redo日志应用,undo日志回滚,启动后台master和purge应用多多线程 ,ibuf合并。检测到了数据页损坏了,将会是系统表空间的,则会crash,用户表空间的,则打错误日志。 innodb_force_recovery = 1。将会检测到数据页损坏了,不必crash我希望会报错(buf_page_io_complete),启动的以前我希望会校验表空间第还还有一个 数据页的正确性(fil_check_first_page),表空间无法访问也继续做崩溃恢复(fil_open_single_table_tablespacefil_load_single_table_tablespace),ddl操作没有进行(check_if_supported_inplace_alter),并肩数据库也被没有进行写入操作(row_insert_for_mysqlrow_update_for_mysql等),所有的prepare事务也会被回滚(trx_resurrect_inserttrx_resurrect_update_in_prepared_state)。类事选项还是很常用的,数据页将会是将会磁盘坏了而损坏了,设置为1,能保证数据库正常启动。 innodb_force_recovery = 2。除了设置1以前的操作不必运行,后台的master和purge应用多多线程 就不必启动了(srv_master_threadsrv_purge_coordinator_thread等),当你发现数据库将会类事个 应用多多线程 的是因为而无法启动时,都能不能设置。 innodb_force_recovery = 3。除了设置2以前的操作不必运行,undo回滚数据库我希望会进行,因此回滚段依然会被扫描,undo链表也依然会被创建(trx_sys_init_at_db_start)。srv_read_only_mode会被打开。 innodb_force_recovery = 4。除了设置3以前的操作不必运行,ibuf的操作我希望会运行(ibuf_merge_or_delete_for_page),表信息统计的应用多多线程 我希望会运行(将会还还有一个 坏的索引页会是因为数据库崩溃)(info_lowdict_stats_update等)。从类事选项现在现在刚开始,以前的所有选项,总要损坏数据,慎重使用。 innodb_force_recovery = 5。除了设置4以前的操作不必运行,回滚段我希望会被扫描(recv_recovery_rollback_active),undo链表我希望会被创建,类事主要用在undo日志被写坏的情况表下。 innodb_force_recovery = 6。除了设置5以前的操作不必运行,数据库前滚操作我希望会进行,包括解析和应用(recv_recovery_from_checkpoint_start_func)。

基础知识

数据库系统与文件系统最大的区别在于数据库能保证操作的原子性,还还有一个 操作要么不做要么都做,即使在数据库宕机的情况表下,我希望会老出操作一半的情况表,类事就前要数据库的日志和一套完善的崩溃恢复机制来保证。本文仔细剖析了InnoDB的崩溃恢复流程,代码基于5.6分支。

recv_recovery_from_checkpoint_start_func以前,recv_recovery_from_checkpoint_finish以前,调用了trx_sys_init_at_db_start,类事函数做了上述三步中的前两步。 第一步在函数trx_rseg_array_init中防止,遍历整个undo日志空间(最多TRX_SYS_N_RSEGS(128)个segment),将会发现某个undo segment非空,就进行初始化(trx_rseg_create_instance)。整个每个undo segment,将会发现undo slot非空(最多TRX_RSEG_N_SLOTS(1024)个slot),也就行初始化(trx_undo_lists_init)。在初始化undo slot后,就把不类事型的undo日志放到 不同链表中(trx_undo_mem_create_at_db_start)。undo日志主要分为一种生活:TRX_UNDO_INSERT和TRX_UNDO_UPDATE。前者主我希望提供给insert操作用的,后者是给update和delete操作使用。以前说过,undo日志有一种生活作用,事务回滚以前用和MVCC快照读取以前用。将会insert的数据不前要提供给某些应用多多线程 用,什么都有我希望事务提交,就都能不能删除TRX_UNDO_INSERT类型的undo日志。TRX_UNDO_UPDATE在事务提交后还没有删除,前要保证没有快照使用它的以前,才能通以前台的purge应用多多线程 清理。 第二步在函数trx_lists_init_at_db_start中进行,将会第一步中,将会在内存中建立起了undo_insert_list和undo_update_list(链表每个undo segment独立),什么都有类事步只前要遍历所有链表,重建起事务的情况表(trx_resurrect_inserttrx_resurrect_update)。简单的说,将会undo日志的情况表是TRX_UNDO_ACTIVE,则事务的情况表为TRX_ACTIVE,将会undo日志的情况表是TRX_UNDO_PREPARED,则事务的情况表为TRX_PREPARED。这里前要考虑变量srv_force_recovery的设置,将会类事变量值为非0,所有的事务总要回滚(即事务被设置为TRX_ACTIVE),即使事务的情况表应该为TRX_STATE_PREPARED。重建起事务后,按照事务id加入到trx_sys->trx_list链表中。最后,在函数trx_sys_init_at_db_start中,会统计所有前要回滚的事务(事务情况表为TRX_ACTIVE)一共前要回滚几块行数据,输出到错误日志中,类事:5 transaction(s) which must be rolled back or cleaned up。InnoDB: in total 342232 row operations to undo的字样。 第三步的操作在还还有一个 地方被调用。还还有一个 是在recv_recovery_from_checkpoint_finish的最后,另外还还有一个 是在recv_recovery_rollback_active中。前者主我希望回滚对数据字典的操作,也我希望回滚DDL一句话的操作,后者是回滚DML一句话。前者是在数据库可提供服务以前前要完成,后者则都能不能在数据库提供服务(也即是崩溃恢复现在现在刚开始)以前继续进行(通过新开还还有一个 后台应用多多线程 trx_rollback_or_clean_all_recovered来防止)。将会InnoDB认为数据字典是最重要的,前要要回滚到一致的情况表才行,而用户表的数据都能不能稍微慢某些,对外提供服务后,慢慢恢复即可。因此亲们常常在会发现数据库将会启动起来了,因此错误日志中还在不断的打印回滚事务的信息。事务回滚的核心函数是trx_rollback_or_clean_recovered,逻辑很简单,只前要遍历trx_sys->trx_list,按照事务不同的情况表回滚将会提交即可(trx_rollback_resurrected)。这里要注意的是,将会事务是TRX_STATE_PREPARED情况表,没有在InnoDB层,不做防止,前要在Server层土辦法 binlog的情况表来决定是是不是回滚事务,将会binlog将会写了,事务就提交,将会binlog写了就将会被传到备库,将会主库回滚会是因为主备数据不一致,将会binlog没有写,就回滚事务。

redo日志: 现代数据库都前要写redo日志,类事修改第第一根 数据,首先写redo日志,因此再写数据。在写完redo日志后,就直接给客户端返回成功。从前真是看后去多写了一次盘,因此将会把对磁盘的随机写入(写数据)转加进了顺序的写入(写redo日志),性能有很大幅度的提高。当数据库挂了以前,通过扫描redo日志,就能找出什么没有刷盘的数据页(在崩溃以前将会数据页仅仅在内存中修改了,因此还没来得及写盘),保证数据不丢。

总结

应用日志的上层函数为recv_apply_hashed_log_recs(应用日志也将会在io_helper函数中进行),主要作用我希望遍历hash_table,从磁盘读取对每个数据页,依次应用哈希桶中的日志。应用完所有的日志后,将会前要则把buffer_pool的页面都刷盘,毕竟空间有限。有以下几点值得注意:

InnoDB实现了一套完善的崩溃恢复机制,保证在任何情况表下(包括在崩溃恢复情况表下)数据库挂了,都能正常恢复,类事是与文件系统最大的差别。此外,崩溃恢复通过redo日志类事物理日志来应用数据页的土辦法 ,给MySQL Replication带来了新的思路,备库是是不是都能不能通过类事应用redo日志的土辦法 来同步数据呢?阿里云RDS MySQL团队在后续的产品中,给亲们带来了类事的特征,敬请期待。

innodb_fast_shutdown: innodb_fast_shutdown = 0。类事表示在MySQL关闭的以前,执行slow shutdown,不但包括日志的刷盘,数据页的刷盘,还包括数据的清理(purge),ibuf的合并,buffer pool dump以及lazy table drop操作(将会表上有未完成的操作,即使执行了drop table且返回成功了,表我希望一定立刻被删除)。 innodb_fast_shutdown = 1。类事是默认值,表示在MySQL关闭的以前,仅仅把日志和数据刷盘。 innodb_fast_shutdown = 2。类事表示关闭的以前,仅仅日志刷盘,某些什么都有要做,就好像MySQL crash了一样。 类事参数值越大,MySQL关闭的带宽很快,因此启动带宽越慢,离米 把关闭以前前要做的工作挪到了崩溃恢复上。另外,将会MySQL要升级,建议使用第一种生活土辦法 进行一次干净的shutdown。

undo日志: 数据库还提供类事归还的功能,当你发现修改错某些数据时,都能不能使用rollback指令回滚以前的操作。类事功能前要undo日志来支持。此外,现代的关系型数据库为了提高并发(同第第一根 记录,不同应用多多线程 的读取不冲突,读写和写读不冲突,没有并肩写才冲突),都实现了类事MVCC的机制,在InnoDB中,类事也依赖undo日志。为了实现统一的管理,与redo日志不同,undo日志在Buffer Pool中含对应的数据页,与普通的数据页并肩管理,土辦法 LRU规则也会被淘汰出内存,后续再从磁盘读取。与普通的数据页一样,对undo页的修改,也前要先写redo日志。

lsn: 都能不能理解为数据库从创建以来产生的redo日志量,类事值越大,说明数据库的更新不必 ,也都能不能理解为更新的时刻。此外,每个数据页上前要还还有一个 lsn,表示最后被修改时的lsn,值越大表示越晚被修改。比如,数据页A的lsn为1000,数据页B的lsn为1000,checkpoint lsn为1000,系统lsn为1000,表示当前系统将会更新到1000,小于1000的数据页将会被刷到磁盘上,因此数据页A的最新数据一定在磁盘上,而数据页B则不一定,有将会还在内存中。

崩溃恢复相关参数解析

前言

redo日志前滚数据库

亲们从源码淬硬层 仔细剖析一下数据库崩溃恢复过程。整个过程前要引擎初始化阶段完成(innobase_init),其中最主要的函数是innobase_start_or_create_for_mysql,innodb通过类事函数完成创建和初始化,包括崩溃恢复。首先来介绍一下数据库的前滚。

崩溃恢复: 用户修改了数据,因此收到了成功的消息,然而对数据库来说,将会类事以前修改后的数据还没有落盘,将会这以前数据库挂了,重启后,数据库前要从日志中把什么修改后的数据给发现龙 来,重新写入磁盘,保证用户的数据不丢。类事从日志中捞数据的过程我希望崩溃恢复的主要任务,也都能不能成为数据库前滚。当然,在崩溃恢复中还前要回滚没有提交的事务,提交没有提交成功的事务。将会回滚操作前要undo日志的支持,undo日志的完整篇 性和可靠性前要redo日志来保证,什么都有崩溃恢复先做redo前滚,因此做undo回滚。

redo日志解析函数

热门

热门标签