0%

14.6 InnoDB在磁盘上的结构(InnoDB On-Disk Structures)

14.6.1 表(Tables)

14.6.1.1 创建InnoDB表

使用CREATE TABLE语句来创建一个InnoDB表

1
CREATE TABLE t1 (a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoDB;

如果InnoDB是默认的存储引擎的话你不需要特定指定ENGINE=InnoDB,可以使用下面语句检查默认的存储引擎

1
2
3
4
5
6
mysql> SELECT @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| InnoDB |
+--------------------------+
阅读全文 »

问题产生

在线上主从同步的slave数据库中产生了如下的错误:

1
2
ERROR 1787 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and 
DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1.

使用show slave status可以查看从库当前的同步状态,发现I/O状态已经变为NO,尝试使用:

1
set global sql_slave_skip_counter = 1;

之后产生如下的问题:

1
ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction

根据错误说明使用一个空事务来跳过异常,代码如下:

1
2
3
4
5
STOP SLAVE;
SET GTID_NEXT=# binlog中事务的下一个位置;
BEGIN; COMMIT; # 产生一个空事务并提交
SET GTID_NEXT="AUTOMATIC";
START SLAVE;

然而这样会导致主从的数据可能产生不一致的情况,这是我们想要避免的,并且希望主库可以不锁表导出数据即可进行备份.

阅读全文 »

14.3 InnoDB的多版本

InnoDB是一个多版本存储引擎:它会保留关于行变动的旧版本信息用来支持事务特性,例如并发和回滚(rollback).这些信息被称为回滚段(rollback segment),存储在表空间中.InnoDB使用回滚段中的信息来执行事务回滚中所需要的撤销操作.还使用该信息构建早期版本以进行一致的行读取.

在内部,InnoDB为存储在数据库的每一行添加三个字段.一个6位的DB_TRX_ID字段用来标识插入或更新行的最后一个事务.此外,删除在内部被视为更新,行的一个特殊位用来标记是否删除.每一行还包含一个7位的DB_ROLL_PTR字段叫做滚动指针(roll pointer).滚动指针指向写入回滚段的撤消日志记录.如果行被更新了,那么撤消日志记录了用来重建被更新之前的行内容所必要的信息.一个6位的DB_ROW_ID字段包含了一个行ID在插入的时候递增.如果InnoDB自动生成聚簇索引,这个索引会包含行ID的值.否则,DB_ROW_ID列不会出现在任何索引中.

回滚段中的撤销日志分为插入和更新的撤销日志(undo logs).插入的回滚日志只在事务回滚的时候需要并且在事务提交之后可以立即丢弃.更新的撤销日志也被用于一致性读,但是只有在InnoDB没有分配快照的事务之后才能丢弃它们,在一致读取中可能需要更新撤消日志中的信息来构建数据库行的早期版本.

定期提交你的事务,包括那些只有一致性读的事务.否则,InnoDB将不能从更新的撤销日志里丢弃数据使得回滚段变得过大而填满表空间.

回滚段中撤消日志记录的物理大小通常小于相应的插入或更新行.你可以使用此信息计算回滚段所需的空间.

在InnoDB多版本方案中,当你使用sql语句删除行的时候不会马上从数据库中物理删除.InnoDB只在丢弃为删除而写的更新撤销日志的时候才会物理的删除相应的行.这个删除操作叫做清除(purge),它很快,通常采用和sql语句删除时相同的顺序.

如果你在表中以相同的速率执行小批量的插入和删除操作,清除线程可能开始落后,因为那些”死掉”的行,表会变得越来越大,使得一切都受磁盘限制变得很慢.在这种情况下,通过调整innodb_max_purge_lag系统变量来限制新行操作,并为清除线程分配更多资源.

阅读全文 »

14.2 InnoDB 和 ACID 模型

ACID模型是一系列的数据库设计准则,强调对业务数据和关键应用非常重要的可靠性方面.MySQL包括了像InnoDB存储引擎这样遵守ACID模型的组件所以数据不会因为例如软件崩溃和硬件故障这样的意外情况而遭到破坏或者丢失.当你依赖ACID相关特性的时候,你不需要重新发明一致性检查和崩溃恢复机制.如果你有其他附加的软件保障,高可用的硬件或者一个可以容忍小部分数据的丢失或者不一致的话,你可以调整MySQL设置用ACID可靠性来交换更好的性能和吞吐量.

下面讨论MySQL的特性尤其是InnoDB存储引擎是如何与ACID模型关联的.

  • A: 原子性(atomicity).
  • C: 一致性(consistency).
  • I: 隔离性(isolation).
  • D: 持久性(durability).
    阅读全文 »

14.1 InnoDB简介

InnoDB是一个平衡了高可用和高性能的通用存储引擎.在Mysql 5.7中已经作为默认的存储引擎使用.

关键优势:

  • DML操作遵循ACID原则,具有事务的提交,回滚和崩溃恢复能力
  • 行级锁和Oracle风格的一致性读保证了多用户并发和性能
  • InnoDB在硬盘上基于主键来管理数据用来优化查询.每一个InnoDB表都有一个主键索引被称作聚簇索引来组织数据,在主键查找的时候可以最小化I/O.
  • 为了保持数据完整性,InnoDB支持外键约束.在外键作用下,inserts,updates和deletes操作会被检查以确保在不同的表间不会出现数据不一致.
    阅读全文 »

代码整洁之道

整洁代码

要有代码

记住,代码确然是我们最终用来表达需求的那种语言.我们可以创造各种与需求接近的语言.我们可以创造帮助把需求解析和汇整为正式结构的各种工具.然而,我们永远无法抛弃必要的精确性–所以代码永存.

什么是整洁代码

  1. 我喜欢优雅和高效的代码,代码逻辑应当直截了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善错误处理代码;性能调至最优,省得引诱别人做没规矩的优化,搞出一堆混乱来,整洁的代码只做好一件事.
  2. 整洁的代码简单直接,整洁的代码如同优美的散文.整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句
  3. 整洁的代码应当可由作者之外的开发者阅读和增补.它应有单元测试和验收测试.它使用有意义的命名.它只提供一种而非多种做一件事的途径.它只有尽量少的依赖关系,而且要明确地定义和提供清晰,尽量少的API.代码应通过其字面表达含义,因为不同的语言导致并非所有必须信息均可通过代码自身清晰表达.
  4. 我可以列出我留意到的整洁代码的所有特点,但其中有一条是根本性的.整洁的代码总是看起来像是某位特别在意它的人写的.几乎没有改进的余地.作者的代码什么都想到了,如果你企图改进它,它总会回到原点,赞叹某人留给你的代码–全心投入某人留下的代码.
  5. 近年来,我开始研究贝克的简单代码规则,差不多也都琢磨透了.简单代码,依其重要顺序:
    1. 能通过所有测试
    2. 没有重复代码
    3. 体现系统中的全部设计理念
    4. 包括尽量少的实体,比如类,方法,函数等
  6. 如果每个例程都让你感到深和己意,那就是整洁代码,如果代码让编程语言看起来像是专为解决那个问题而存在,就可以称之为漂亮的代码.
    阅读全文 »

开始

首先给出我们要解决的问题:

有 12 枚外表一模一样的硬币,其中一枚是假币,其余都是真币。假币的重量与真币不同,但是更重还是更轻不知道。给你一个没有砝码和刻度的天平,最少称几次才能确保找出假币?

类似的题目的变种也非常的多而且经常会时不时出现在我的面前,但是一法通 万法通,只要掌握了方法这类问题也就变成了有通解的简单数学题而已.以前的我也是这么想的,但是在机缘巧合之下看到了这个硬币的两面,感觉非常有趣便在此记录一下.

离散数学

让我们先从逻辑谓词的角度来看看这个问题.当然如果你对离散学习非常熟悉的话,在看到这个问题的时候应该就能想到:”这不就是纠错码吗?”,没错,离散数学的解决方法就是纠错码.

Hamming Code

汉明码(Hamming Code)是广泛用于内存和磁盘纠错的编码。汉明码不仅可以用来检测转移数据时发生的错误,还可以用来修正错误。(要注意的是,汉明码只能发现和修正一位错误,对于两位或者两位以上的错误无法正确和发现)。

纠错,一位,完美适应我们提出的硬币问题!那么我们就开始吧~

阅读全文 »

开始

之前写完博客需要:

1
2
3
hexo g
hexo d
hexo b

一系列的操作发布到github上之后再备份,这一点都不cooooooooool!,在之前做博客备份的时候就看到过有人使用CI来发布文章的,当时没有觉得很重要,而在经历了一次博客源文件丢失以及换电脑环境之后,才发现能够直接push一篇md就能完成整个流程是这么的美好,下面就记录一下整个配置流程(略有小坑)

Travis CI

这里使用了Travis CI来作为持续集成的工具,当然其他的工具也是同理

登录Travis CI

这里可以直接使用你的github帐号登录Travis CI不做赘述,登录之后执行下面的操作:

阅读全文 »