MYSQL中InnoDB和ROW_FORMAT=COMPACT

Advertisement

去掉:ROW_FORMAT
ALTER TABLE table_name ROW_FORMAT = DEFAULT

MYSQL中InnoDB是什么?
一种表驱动,除了innodb还有其它的,例如isam,myisam等.

innodb的特色在于支持并发与表间引用 MySQL支持多种存储引擎,用户可以方便的选用不同的存储引擎来支持自己的应用,每种不同的存储引擎都有其自己的特性

Innodb是其中的一种存储引擎,它的特性是支持事务,并且采用多版本并发控制的方式来提高并发度主要是事务表,当一个事务全部完成,才会执行update.如果一段代码没有完成(及一个事务操作没有完成)它是不会update的,例如:银行转帐,一 笔业务没有完成的时候,突然的断电,或是,网络,系统的原因使你无法完成此交易的话,这个事务是要回滚的此交易之前的状态的,没有完成交易,你银行的 money是不会减少的!缺点是,innoDB的表执行起来速度较慢,但是安全!bbs的表要求的是速度,用的都是myisam的表!不知这样通俗的说, 你是否理解?
----------------------------------------------------------------------
翻译一段MySQL关于Innodb的物理行结构的官方文档:

Records in InnoDB ROW_FORMAT=COMPACT tables have the following characteristics:

InnoDB ROW_FORMAT=COMPACT 的表,其中的记录有如下特点:

Each index record contains a five-byte header that may be preceded by a variable-length header. The header is used to link together consecutive records, and also in row-level locking.

每个索引记录包含一个五字节的头,在它之前还有一个变长的头。这个头是用来连接连续的记录,也用于行级锁。

The record header contains a bit vector for indicating NULL columns. The bit vector occupies (n_nullable+7)/8 bytes. Columns that are NULL will not occupy other space than the bit in this vector.

记录头包含一个位向量,用来指明空列。位向量占用了(可空的列数+7)/8字节。值为空的列不会再占用此位向量以外的空间。

For each non-NULL variable-length field, the record header contains the length of the column in one or two bytes. Two bytes will only be needed if part of the column is stored externally or the maximum length exceeds 255 bytes and the actual length exceeds 127 bytes.

对于每个非空的变长字段,记录头使用一或两个字节包含了列的长度。只有如下情况才会用到两个字节:字段的值保存在外部;或者字段的最大长度走过了255,并且实际的字段值超过了127字节。

The record header is followed by the data contents of the columns. Columns that are NULL are omitted.

记录头的后面是字段的内容,其中空字段被忽略。

Records in the clustered index contain fields for all user-defined columns. In addition, there is a six-byte field for the transaction ID and a seven-byte field for the roll pointer.

clustered索引的记录包含了所有用户定义的列。此外,还有一个六字节的区域保存事务ID,一个七字节的的区域保存roll pointer(回滚指针?)

If no primary key was defined for a table, each clustered index record also contains a six-byte row ID field.

如果没有定义主键,每个clusterd索引也会包含一个六字节的row ID区域。

Each secondary index record contains also all the fields defined for the clustered index key.

每个副索引(非clustered索引)也包含所有clustered索引键列。

Internally, InnoDB stores fixed-length, fixed-width character columns such as CHAR(10) in a fixed-length format. InnoDB truncates trailing spaces from VARCHAR columns.

内部地,InnoDB用定长的格式存储定长的字符列,如CHAR(10)。InnoDB会去掉VARCHAR列两侧的空格。

Internally, InnoDB attempts to store UTF-8 CHAR(n) columns in n bytes by trimming trailing spaces. In ROW_FORMAT=REDUNDANT, such columns occupy 3*n bytes. The motivation behind reserving the minimum space n is that it in many cases enables an update of the column to be done in place without causing fragmentation of the index page.

内部地,InooDB尝试把UTF-8 CHAR(n)列两侧的空格去掉,使此列只占用n字节。在ROW_FORMAT=REDUNDANT时,这样的列要占用3*n字节。这是为了update该列时在索引页不产生碎片。
---------------------------------------------------------------------
InnoDB性能调节提示
  · 如果Unix的top工具或者Windows任务管理器显示,你的数据库的工作负荷的CPU使用率小于70%,则你的工作负荷可能是磁盘绑定的,可能你正生成太多的事务和提交,或者缓冲池太小。使得缓冲池更大一些会有帮助的,但不要设置缓冲池等于或超过物理内存的80%.
  · 把数个修改放在一个事务里。如果事务对数据库修改,InnoDB在该事务提交时必须刷新日志到磁盘。因为磁盘旋转的速度至多167转/秒,如果磁盘没有骗操作系统的话,这就限制提交的数目为同样的每秒167次。
  · 如果你可以接受损失一些最近的已提交事务,你可以设置参数 innodb_flush_log_at_trx_commit 为 0。无论如何InnoDB试着每秒刷新一次日志,尽管刷新不被许可。
  · 使用大的日志文件,甚至让它与缓冲池一样大。当InnoDB写满日志文件时,它不得不在一个检查点把缓冲池已修改的内容写进磁盘。小日志文件导致许多不必要的吸盘写操作。大日志文件的缺点时恢复时间更长。
  · 也让日志缓冲相当大(与8MB相似的数量)。
  · 如果你存储变长字符串,或者列可能包含很多NULL值,则使用VARCHAR列类型而不是CHAR类型。一个CHAR(N)列总是占据N个字节来存储,即使字符串更短或字符串的值是NULL。越小的表越好地适合缓冲池并且减少磁盘I/O。
  当使用row_format=compact (MySQL 5.1中默认的InnoDB记录格式)和可变长度字符集,比如GB2312或sjis,CHAR(N)将占据可变数量的空间,至少为N 字节。
  · 在一些版本的GNU/Linux和Unix上,用Unix的fsync()(InnoDB默认使用的)把文件刷新到磁盘,并且其他相似的方法是惊人的慢。如果你不满意数据库的写性能,你可以试着设置参数 innodb_flush_method 值为 O_DSYNC,虽然 O_DSYNC 在多数系统上看起来更慢。
  · 当在Solaris 10上,为x86_64架构(AMD Opteron)使用InnoDB存储引擎,重要的是使用forcedirectio选项来安装任何为存储与InnoDB相关的文件而使用的数据系统。(默认在Solaris 10/x86_64上不使用这个文件系统安装选项 )。使用forcedirectio 失败会导致InnoDB在这个平台上的速度和性能严重下降。
  · 当导入数据到InnoDB中之时,请确信MySQL没有允许autocommit模式,因为允许autocommit模式会需要每次插入都要刷新日志到磁盘。要在导入操作规程中禁止autocommit模式,用SET AUTOCOMMIT和COMMIT语句来包住导入语句:
  SET AUTOCOMMIT=0;
  /* SQL import statements ... */
  COMMIT;
  · 如果你使用mysqldump 选项--opt,即使不用SET AUTOCOMMIT和COMMIT语句来包裹,你也使得快速的转储文件被导入到InnoDB表中。
  · 小心大宗插入的大回滚:InnoDB在插入中使用插入缓冲来节约磁盘I/O, 但是在相应的回滚中没有使用这样的机制。一个磁盘绑定的回滚可以用相应插入花费时间的30倍来执行。杀掉数据库进程没有是帮助的,因为回滚在服务器启动时会再次启动。除掉一个失控的回滚的唯一方法是增大缓冲池使得回滚变成CPU绑定且跑得快,或者使用专用步骤,请参阅15.2.8.1节,“强制恢复”。
  · 也要小心其它大的磁盘绑定操作。用 DROP TABLE 或 CREATE TABLE 来清空一个表,而不是用 DELETE FROM tbl_name。
  · 如果你需要插入许多行,则使用多行插入语法来减少客户端和服务器之间的通讯开支:
  INSERT INTO yourtable VALUES (1,2), (5,5), ...;
  这个提示对到任何表类型的插入都是合法的,不仅仅是对InnoDB类型。
  · 如果你在第二个键上有UNIQUE约束,你可以在导入会话中暂时关闭唯一性检查以加速表的导入:
  SET UNIQUE_CHECKS=0;
  对于大表,这节约了大量磁盘I/O,因为InnoDB可以使用它的插入缓冲来在一批内写第二个索引记录。
  · 如果你对你的表有FOREIGN KEY约束,你可以在导入会话过程中通过关闭外键检查来提速表的导入:
  SET FOREIGN_KEY_CHECKS=0;
  对于大表,这可以节约大量的磁盘I/O。
  · 如果你经常有对不经常更新的表的重发查询,请使用查询缓存:
  [mysqld]
  query_cache_type = ON
  query_cache_size = 10M

Similar Posts:

  • MySQL中Innodb的事务隔离级别和锁的关系的讲解教程

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一次封锁or两段锁?因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会用

  • MySQL中InnoDB和MyISAM的差别

    InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定.下面是已知的两者之间的差别,仅供参考. innodb InnoDB 给 MySQL 提供了具有事务(commit).回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表.InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读

  • MySQL中InnoDB存储引擎的事务隔离级别与事务处理

    1.事务进行中,不得用set transaction命令更改隔离级别.但可以用set {global|session} transaction更改隔离级别.文档上说set transaction可以改变当前会话的下一个事务的隔离级别,实际测试发现不起做用. 2.用set [{global|session}] tx_isolation={READ-COMMITTED|REPEATABLE-READ}改变事务隔离级别. 3.read committed隔离级别,二进制日志必须为row格式,或者不启用

  • MySQL的Innodb中的事务隔离级别和锁的关系

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 本文转载自美团点评技术团队:http://tech.meituan.com/innodb-lock.html #一次封锁or

  • mysql中的row_format

    Mysql的row_format 在mysql中, 若一张表里面不存在varchar.text以及其变形.blob以及其变形的字段的话,那么张这个表其实也叫静态表,即该表的row_format是fixed,就是说每条记录所占用的字节一样.其优点读取快,缺点浪费额外一部分空间. 若一张表里面存在varchar.text以及其变形.blob以及其变形的字段的话,那么张这个表其实也叫动态表,即该表的row_format是dynamic,就是说每条记录所占用的字节是动态的.其优点节省空间,缺点增加读取的

  • mysql的innodb中事务日志ib_logfile

    mysql的innodb中事务日志ib_logfile 事务日志或称redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节 开启几组日志来服务于当前mysql数据库,mysql采用顺序,循环写方式,每开启一个事务时, 会把一些相关信息记录事务日志中(记录对数据文件数据修改的物理位置或叫做偏移量); 作用:在系统崩溃重启时,作事务重做:在系统正常时,每次checkpoint时间点,会将之前写入事务 应用到数据文件中. 引入一个问题:在m/s

  • Mysql中MyISMA和InnoDB的区别

    在该开始学习mysql建立表时,发现了mysql中的的MyISAM和InnoDB两种表类型,于是在网上查找了各种解释,进行了一下总结. MyISAM和InnoDB是在使用Mysql时最常用的两个表类型,这两个表各有优势,视具体应用而定.基本的差别为:MySIAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是表的性能,其执行速度比InnoDB类型要快,但是不提供事务支持,而InnoDB提供事务支持以及外键等高级数据库功能. MyISAM:这是一个默认类型,它基于

  • MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无论存放的是数字.字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 二. varchar和char 的区别: char是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是: char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,M

  • mysql SHOW INNODB STATUS 探秘

    mysql SHOW INNODB STATUS 探秘 原文作者: Peter Zaitsev 原文来源: http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/ 译者:叶金荣(Email:),转载请注明译者和出处,并且不能用于商业用途,违者必究. 很多人让我来阐述一下 SHOW INNODB STATUS 的输出信息, 了解 SHOW INNODB STATUS 都输出了些什么信息,并且我们

  • MySQL中的char与varchar详解

    mysql中char与varchar的区别: char:定长,效率高,一般用于固定长度的表单提交数据存储 :例如:身份证号,手机号,电话,密码等 varchar:不定长,效率偏低 1.varchar类型的变化 MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定).在 MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了