阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

UNDO类型日志系统浅浅理解

368次阅读
没有评论

共计 2603 个字符,预计需要花费 7 分钟才能阅读完成。

日志系统是保证数据库管理系统正确执行事务的基本机制。根据作用的不同,日志系统分为 UNDO 和 REDO 两种,本文对 UNDO 类型日志的原理进行简单模拟说明。

1 UNDO 日志要求

  • 日志记录了数据修改之前的旧值;
  • 数据刷盘之前,把日志刷盘;(一致性)
  • 数据刷盘之后,把日志 COMMIT 刷盘。(持久性)

2 UNDO 日志缺陷

UNDO 日志提供了足够的信息可以保证事务的一致性和持久性。但是,为了保持一致性,采取的是被动保守的策略,即:用旧值覆盖不能确保成功的事务。 未成功的事务不能重新执行,只能恢复到事务之前的一致状态。

2 模拟代码

只是模拟了数据写入的过程,没有模拟数据恢复过程,待以后有时间补充。

/* UNDO 类型日志基本流程模拟 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>

/* 日志文件, 基本格式:
 * T1_START
 * A=100
 * B=100
 * T1_COMMIT
 */

#define LOG_FILE "test.log"

/* 数据文件, 基本格式: 每行一个键值对,长度固定为 1024,右侧用空格填充。* A=100     (padding)
 * B=100     (padding)
 */
#define DATA_FILE "test.data"

#define LINE_MAX 1024

/* 键值对 */
typedef struct KV KV;
struct KV
{char* key;
    char* value;
};

/* 从硬盘读取名为 k 的数据 */
static int fread_kv(char* k, char* v, FILE* fp)
{rewind(fp);
    char line[LINE_MAX+1]={0};
    int lineNo = 0;
    while(fread(line, 1, LINE_MAX, fp)==LINE_MAX){int i=0;
        while(k[i] && line[i]!='='){if(k[i] != line[i]){break;
            }
            i++;
        }
        if(line[i] == '='){strcpy(v, &line[i+1]);
            return lineNo;
                                                                                                                                                                    1,1           Top        }
        lineNo ++;
    }
    return -1;
}
/* 把数据刷入硬盘 */
static void fwrite_kv(char* k,  char* v, FILE* fp)
{int lineNo = -1;
    char newLine[LINE_MAX];
    sprintf(newLine, "%s=%s", k, v);
    int offset = 0;
    if((lineNo=fread_kv(k,v,fp))<0)  /* insert */
    {offset = fseek(fp, 0, SEEK_END);
    }else{/* update */
        offset = fseek(fp, LINE_MAX * lineNo, 0);
    }

    fprintf(fp, "%-1023s\n", newLine);
    fflush(fp);
}


int main(int argc, char** argv)
{FILE* fpLog = fopen(LOG_FILE, "r+");
    FILE* fpData = fopen(DATA_FILE, "r+");

    if(!(fpLog && fpData)){perror(NULL);
    }

    /* 开始一个事务 */
    char log[1024] = "T1 START\n";

    /* 在内存中执行事务操作 */
    char v[LINE_MAX];
    fread_kv("A", v, fpData);
    int A = atoi(v);

    fread_kv("B", v, fpData);
    int B = atoi(v);

    char logA[1024];
    sprintf(logA, "T1:A=%d\n", A); /* 在日志中记录旧值 */
    strcat(log, logA);
    A -= 50;

    char logB[1024];
    sprintf(logB, "T1:B=%d\n", B); /* 在日志中记录旧值 */
    strcat(log, logB);
    B += 50;

    /************** 如果此时发生故障,日志和数据均尚未写出到硬盘上, 事务丢失,但保持数据库一致性.*************/
    /* 数据刷盘之前,先把日志刷入硬盘 */
    fputs(log, fpLog);
    fflush(fpLog);

    /************* 如果此时发生故障,日志旧值已经被写出到硬盘上,数据尚未写入,恢复时需要把旧值恢复.(随然数据未刷盘,但并不可知)********/
    /* 把数据新值刷入硬盘 */
    sprintf(v, "%d", A);
    fwrite_kv("A", v, fpData);
    /************* 如果此时发生故障,日志旧值已经被写出到硬盘上,数据尚未写入,恢复时需要把旧值恢复.********/

    abort(); /* 模拟故障 */

    sprintf(v, "%d", B);
    fwrite_kv("B", v, fpData);
    /************* 如果此时发生故障,日志旧值已经被写出到硬盘上,数据已经写入硬盘,但是 COMMIT 日志未写出,也需要恢复旧值.(虽然数据已完整刷盘,但并不可知)********/

    /* 数据刷盘之后,把提交日志刷入硬盘 */
    fputs("T1 COMMIT\n", fpLog);
    fflush(fpLog);
    /************* 如果此时发生故障,日志 COMMIT 已刷盘,能够确保数据也已经刷盘成功。无需恢复 ********/

    fclose(fpLog);
    fclose(fpData);
    return 0;
}

代码执行之前:
数据文件内容如下:

A=100
B=100

上述代码执行后:
数据文件内容如下:

A=50
B=100

日志文件内容如下:

T1 START
T1:A=100
T1:B=100

根据日志文件,由于没有找到 T1 COMMIT,所以断定事务 T1 未能成功,数据可能处于不一致状态,需要数据恢复。进而根据日志文件,可以得到事务 T1 执行之前的数据旧值 A =100,B=100,恢复也就很容易了,只要把 A,B 的值都更新为其对应的旧值就可以了。

恢复之后的数据文件:

A=100
B=100

更多 Oracle 相关信息见 Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-07/133709.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2603字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19350
评论数
4
阅读量
7885642
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-2:飞牛配置RAID磁盘阵列

星哥带你玩飞牛NAS-2:飞牛配置RAID磁盘阵列

星哥带你玩飞牛 NAS-2:飞牛配置 RAID 磁盘阵列 前言 大家好,我是星哥之前星哥写了《星哥带你玩飞牛 ...
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你 为什么要用宝塔跑分? 宝塔跑分其实就是对 CPU、内存、磁盘、IO 做...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统 大家好,我是星哥。公司的项目文档存了一堆 ...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛 NAS 硬件 02:某鱼 6 张左右就可拿下 5 盘位的飞牛圣体 NAS 前言 大家好,我是星...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛NAS-8:有了NAS你可以干什么?软件汇总篇

星哥带你玩飞牛 NAS-8:有了 NAS 你可以干什么?软件汇总篇 前言 哈喽各位玩友!我是是星哥,不少朋友私...
浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍 前言 在 AI 自动化快速发展的当下,浏览器早已不再只是...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...