MySQL Innodb Engine--DML操作时先生成Undo Log还是先生成Redo Log
时间:2021-07-13
本文章向大家介绍MySQL Innodb Engine--DML操作时先生成Undo Log还是先生成Redo Log,主要包括MySQL Innodb Engine--DML操作时先生成Undo Log还是先生成Redo Log使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
问题总结
问题:DML操作时先生成Undo Log是Redo Log?
答案:先生成Undo Log,再生成Redo Log。
在生成Undo Log并写入到Undo Space时,会产生Redo Log。
在故障恢复时,可以通过Redo Log来恢复Undo Log,再通过Undo Log来回滚事务。
代码瞎猜
函数btr_cur_optimistic_insert用来实现插入记录操作,其中代码为:
/** Tries to perform an insert to a page in an index tree, next to cursor.
It is assumed that mtr holds an x-latch on the page. The operation does
not succeed if there is too little space on the page. If there is just
one record on the page, the insert will always succeed; this is to
prevent trying to split a page with just one record.
@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
dberr_t btr_cur_optimistic_insert()
{
/* Now, try the insert */
{
const rec_t *page_cursor_rec = page_cur_get_rec(page_cursor);
/* 判断表是否为临时表(is_intrinsic) */
if (index->table->is_intrinsic()) {
/* 临时表不需要生产UNDO LOG */
index->rec_cache.rec_size = rec_size;
*rec = page_cur_tuple_direct_insert(page_cursor, entry, index, mtr);
} else {
/* Check locks and write to the undo log,if specified */
err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, mtr, &inherit);
if (err != DB_SUCCESS) {
goto fail_err;
}
/* 向数据页中插入记录,插入过程会产生UNDO LOG */
*rec = page_cur_tuple_insert(page_cursor, entry, index, offsets, heap, mtr);
}
reorg = page_cursor_rec != page_cur_get_rec(page_cursor);
}
}
函数btr_cur_optimistic_update用于更新记录,其中代码为:
/** Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
so that tree compression is recommended. We assume here that the ordering
fields of the record do not change.
@return error code, including
@retval DB_SUCCESS on success
@retval DB_OVERFLOW if the updated record does not fit
@retval DB_UNDERFLOW if the page would become too empty
@retval DB_ZIP_OVERFLOW if there is not enough space left
on the compressed page (IBUF_BITMAP_FREE was reset outside mtr) */
dberr_t btr_cur_optimistic_update()
{
/* Do lock checking and undo logging */
err = btr_cur_upd_lock_and_undo(flags, cursor, *offsets, update, cmpl_info,
thr, mtr, &roll_ptr);
/* 更新adaptive hash index*/
btr_search_update_hash_on_delete(cursor);
/* 删除记录 */
page_cur_delete_rec(page_cursor, index, *offsets, mtr);
page_cur_move_to_prev(page_cursor);
if (!(flags & BTR_KEEP_SYS_FLAG) && !index->table->is_intrinsic()) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, roll_ptr);
row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID, trx_id);
}
/* There are no externally stored columns in new_entry */
/* 插入记录 */
rec = btr_cur_insert_if_possible(cursor, new_entry, offsets, heap, mtr);
ut_a(rec); /* <- We calculated above the insert would fit */
/* Restore the old explicit lock state on the record */
if (!dict_table_is_locking_disabled(index->table)) {
lock_rec_restore_from_page_infimum(block, rec, block);
}
page_cur_move_to_next(page_cursor);
ut_ad(err == DB_SUCCESS);
}
Mini-transaction的日志类型
每条InnoDB存储引擎产生的Redo Log都包含下面信息:
- type:Redo Log的类型,使用1字节来存放。
- space:表空间ID
- offset:数据页在表空间上的偏移量
- body:存放Redo Log的日志数据
针对DML中增删改产生的Redo Log有如下类型:
/** Record insert */
MLOG_REC_INSERT = 9,
/*!< Delete a record from a page */
MLOG_REC_DELETE = 14,
/** update of a record, preserves record field sizes */
MLOG_REC_UPDATE_IN_PLACE = 13,
/** update of a compact record, preserves record field sizes */
MLOG_COMP_REC_UPDATE_IN_PLACE = 41,
/** delete a compact record from a page */
MLOG_COMP_REC_DELETE = 42,
/** compact record insert */
MLOG_COMP_REC_INSERT = 38,
/** delete a compact record from a page */
MLOG_COMP_REC_DELETE = 42,
针对Undo Log产生的Redo Log有如下类型:
/** Insert entry in an undo log */
MLOG_UNDO_INSERT = 20,
/** erase an undo log page end */
MLOG_UNDO_ERASE_END = 21,
/** initialize a page in an undo log */
MLOG_UNDO_INIT = 22,
/** reuse an insert undo log header */
MLOG_UNDO_HDR_REUSE = 24,
/** create an undo log header */
MLOG_UNDO_HDR_CREATE = 25,
Mini-transaction的日志类型:
/** Logging modes for a mini-transaction */
enum mtr_log_t {
/** Default mode: log all operations modifying disk-based data */
MTR_LOG_ALL = 0,
/** Log no operations and dirty pages are not added to the flush list */
MTR_LOG_NONE = 1,
/** Don't generate REDO log but add dirty pages to flush list */
MTR_LOG_NO_REDO = 2,
/** Inserts are logged in a shorter form */
MTR_LOG_SHORT_INSERTS = 3,
/** Last element */
MTR_LOG_MODE_MAX = 4
};
/** @name Log item types
The log items are declared 'byte' so that the compiler can warn if val
and type parameters are switched in a call to mlog_write_ulint. NOTE!
For 1 - 8 bytes, the flag value must give the length also! @{ */
enum mlog_id_t {
/** if the mtr contains only one log record for one page,
i.e., write_initial_log_record has been called only once,
this flag is ORed to the type of that first log record */
MLOG_SINGLE_REC_FLAG = 128,
/** one byte is written */
MLOG_1BYTE = 1,
/** 2 bytes ... */
MLOG_2BYTES = 2,
/** 4 bytes ... */
MLOG_4BYTES = 4,
/** 8 bytes ... */
MLOG_8BYTES = 8,
/** Record insert */
MLOG_REC_INSERT = 9,
/** Mark clustered index record deleted */
MLOG_REC_CLUST_DELETE_MARK = 10,
/** Mark secondary index record deleted */
MLOG_REC_SEC_DELETE_MARK = 11,
/** update of a record, preserves record field sizes */
MLOG_REC_UPDATE_IN_PLACE = 13,
/*!< Delete a record from a page */
MLOG_REC_DELETE = 14,
/** Delete record list end on index page */
MLOG_LIST_END_DELETE = 15,
/** Delete record list start on index page */
MLOG_LIST_START_DELETE = 16,
/** Copy record list end to a new created index page */
MLOG_LIST_END_COPY_CREATED = 17,
/** Reorganize an index page in ROW_FORMAT=REDUNDANT */
MLOG_PAGE_REORGANIZE = 18,
/** Create an index page */
MLOG_PAGE_CREATE = 19,
/** Insert entry in an undo log */
MLOG_UNDO_INSERT = 20,
/** erase an undo log page end */
MLOG_UNDO_ERASE_END = 21,
/** initialize a page in an undo log */
MLOG_UNDO_INIT = 22,
/** reuse an insert undo log header */
MLOG_UNDO_HDR_REUSE = 24,
/** create an undo log header */
MLOG_UNDO_HDR_CREATE = 25,
/** mark an index record as the predefined minimum record */
MLOG_REC_MIN_MARK = 26,
/** initialize an ibuf bitmap page */
MLOG_IBUF_BITMAP_INIT = 27,
#ifdef UNIV_LOG_LSN_DEBUG
/** Current LSN */
MLOG_LSN = 28,
#endif /* UNIV_LOG_LSN_DEBUG */
/** this means that a file page is taken into use and the prior
contents of the page should be ignored: in recovery we must not
trust the lsn values stored to the file page.
Note: it's deprecated because it causes crash recovery problem
in bulk create index, and actually we don't need to reset page
lsn in recv_recover_page_func() now. */
MLOG_INIT_FILE_PAGE = 29,
/** write a string to a page */
MLOG_WRITE_STRING = 30,
/** If a single mtr writes several log records, this log
record ends the sequence of these records */
MLOG_MULTI_REC_END = 31,
/** dummy log record used to pad a log block full */
MLOG_DUMMY_RECORD = 32,
/** log record about creating an .ibd file, with format */
MLOG_FILE_CREATE = 33,
/** rename a tablespace file that starts with (space_id,page_no) */
MLOG_FILE_RENAME = 34,
/** delete a tablespace file that starts with (space_id,page_no) */
MLOG_FILE_DELETE = 35,
/** mark a compact index record as the predefined minimum record */
MLOG_COMP_REC_MIN_MARK = 36,
/** create a compact index page */
MLOG_COMP_PAGE_CREATE = 37,
/** compact record insert */
MLOG_COMP_REC_INSERT = 38,
/** mark compact clustered index record deleted */
MLOG_COMP_REC_CLUST_DELETE_MARK = 39,
/** mark compact secondary index record deleted; this log
record type is redundant, as MLOG_REC_SEC_DELETE_MARK is
independent of the record format. */
MLOG_COMP_REC_SEC_DELETE_MARK = 40,
/** update of a compact record, preserves record field sizes */
MLOG_COMP_REC_UPDATE_IN_PLACE = 41,
/** delete a compact record from a page */
MLOG_COMP_REC_DELETE = 42,
/** delete compact record list end on index page */
MLOG_COMP_LIST_END_DELETE = 43,
/*** delete compact record list start on index page */
MLOG_COMP_LIST_START_DELETE = 44,
/** copy compact record list end to a new created index page */
MLOG_COMP_LIST_END_COPY_CREATED = 45,
/** reorganize an index page */
MLOG_COMP_PAGE_REORGANIZE = 46,
/** write the node pointer of a record on a compressed
non-leaf B-tree page */
MLOG_ZIP_WRITE_NODE_PTR = 48,
/** write the BLOB pointer of an externally stored column
on a compressed page */
MLOG_ZIP_WRITE_BLOB_PTR = 49,
/** write to compressed page header */
MLOG_ZIP_WRITE_HEADER = 50,
/** compress an index page */
MLOG_ZIP_PAGE_COMPRESS = 51,
/** compress an index page without logging it's image */
MLOG_ZIP_PAGE_COMPRESS_NO_DATA = 52,
/** reorganize a compressed page */
MLOG_ZIP_PAGE_REORGANIZE = 53,
/** Create a R-Tree index page */
MLOG_PAGE_CREATE_RTREE = 57,
/** create a R-tree compact page */
MLOG_COMP_PAGE_CREATE_RTREE = 58,
/** this means that a file page is taken into use.
We use it to replace MLOG_INIT_FILE_PAGE. */
MLOG_INIT_FILE_PAGE2 = 59,
/** Table is being truncated. (Marked only for file-per-table) */
/* MLOG_TRUNCATE = 60, Disabled for WL6378 */
/** notify that an index tree is being loaded without writing
redo log about individual pages */
MLOG_INDEX_LOAD = 61,
/** log for some persistent dynamic metadata change */
MLOG_TABLE_DYNAMIC_META = 62,
/** create a SDI index page */
MLOG_PAGE_CREATE_SDI = 63,
/** create a SDI compact page */
MLOG_COMP_PAGE_CREATE_SDI = 64,
/** Extend the space */
MLOG_FILE_EXTEND = 65,
/** Used in tests of redo log. It must never be used outside unit tests. */
MLOG_TEST = 66,
/** biggest value (used in assertions) */
MLOG_BIGGEST_TYPE = MLOG_TEST
};
原文地址:https://www.cnblogs.com/gaogao67/p/15008294.html
- CTreeCtrl 控件使用总结
- 高盛成立交易部门,涉足比特币和加密货币交易
- WordPress主题开发:添加主题更新提醒功能
- WordPress主题开发:添加主题更新提醒功能
- ASP.NET2.0应用中定制安全凭证之实践篇
- Kaggle大神带你上榜单Top2%:点击预测大赛纪实(下)
- WordPress主题后台选项开发框架 Options Framework 介绍
- vc++ 在程序中运行另一个程序的方法
- 为Options Framework主题后台框架添加后台侧边栏
- ClistCtrl用法及总结(由怎样隐藏ListCtrl列表头的排序小三角形这个bug学习到的知识)
- 弹出式模态窗体选择文本控件
- zookeeper 分布式锁服务
- QT Creator 快速入门教程 读书笔记(三)
- WordPress中添加自定义评论表情包的方法(附三套表情包下载)
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- PHP JWT初识及其简单示例
- PHP正则判断一个变量是否为正整数的方法
- php5.5使用PHPMailer-5.2发送邮件的完整步骤
- 详细对比php中类继承和接口继承
- 解决Keras的自定义lambda层去reshape张量时model保存出错问题
- 解决Keras中Embedding层masking与Concatenate层不可调和的问题
- 浅谈keras使用预训练模型vgg16分类,损失和准确度不变
- 关于tf.matmul() 和tf.multiply() 的区别说明
- python中执行smtplib失败的处理方法
- PHP+Ajax简单get验证操作示例
- Python matplotlib读取excel数据并用for循环画多个子图subplot操作
- python转化excel数字日期为标准日期操作
- thinkPHP框架通过Redis实现增删改查操作的方法详解
- PHP中引用类型和值类型功能与用法示例
- PHP文件上传小程序 适合初学者学习!