《Mysql技术内幕》札记(上)

第一章   MYSQL体系结构和存储引擎

一、数据库的概念

数据库:数据库文件类型的集合,以frm与ibd结尾等。

数据库实例:数据库后台的进程/线程 以及共享内存组成,实例操作数据库文件
数据库与实例一一对应,一个实例对应一个数据库
Mysql是单进程多线程,这就意味着一个实例一个进程

MYSQL架构

   SQL接口组件   查询分析器组件    优化器组件    缓存
                      插件式存储引擎(基于表)
                          物理文件

二、不同引擎

Innodb存储引擎

事务应用的特点:行锁,外键,非锁定读 
高性能功能:1.写入方面:插入缓冲,二次写 2.查询方面:自适应哈希索引,预读 
Myisam引擎
Myisam由myd和myi文件组成。myd数据文件和myi索引文件

三、连接mysql

连接进程是mysql连接进程和数据库实例进行通信,本质上是进程的通信。

通信方式一般有:TCP/IP,unix套接字等 
1.在网络中MYSQL连接是通过用TCP/IP套接字方式 
##TCP/IP套接字方式时,实例在连接时会检查权限表user,用来判断连接是否被允许。 
2. Unix套接字连接,适用于客户端与服务器在同一台服务器。用--socket=**** 来连接。可以通过ps -ef|grep ‘mysql‘查询套接字以及配置文件

第一章   innodb存储引擎

一、Innodb后台线程

后台线程有7个 
4个io thread 1个master线程 1个锁线程 1个错误监控

io四个线程:

Insert buffer thread
Log thread
Write thread
Read thread

show engine innodb status;
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insertbuffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (writethread)

二、内存

内存由以下组成:缓冲池,重做日志缓冲池,额外内存池。 
缓冲池大小查看:

show variables like ‘%buffer%‘;

+------------------------------+------------+

| Variable_name          | Value      |

+------------------------------+------------+

| innodb_buffer_pool_size    | 6442450944 |

| innodb_log_buffer_size     | 33554432   |

+------------------------------+------------+

缓冲池

缓冲池的数据页:数据页,索引页 ,undo页,插入缓冲,自适应哈希索引,锁信息和数据字典 
数据按页读到缓冲池,将最近最多使用的数据页留在缓冲池,只要数据文件需要修改就更新缓存池的页,然后缓冲池的脏页会按照一定的频率刷到文件

缓存池具体使用情况:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 6593445888; in additional poolallocated 0
Dictionary memory allocated 9473932
Buffer pool size  393215 一共**缓冲帧(每个帧页为16k)
Free buffers      0     空闲缓冲帧
Database pages    381113  已使用的缓冲帧
Old database pages 140664    最近没有被访问的页(会被替换出去)
Modified db pages 0   表示脏页

Old database pages 解释:http://www.orczhou.com/index.php/2010/05/innodb-plugin-make-buffer-cache-scan-resistant/

当数据页被替换到内存时,为了避免数据污染(热数据被全部替换)将在不热的数据队列进行读取,过一定的时间还有读取才会替换最热的缓存。

##show engine innodb status 统计的数据不是实时
=====================================
151106 14:20:53 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 17 seconds 
(此数据库服务器统计的数据是前17秒的数据)

日志缓冲数据一般情况下每一秒将刷新到磁盘,所以日志缓冲区大小不需要太大
额外内存池:数据结构分配内存时使用

三、线程

master thread,线程优先级最高,由主循环,后台循环,刷新循环,暂停循环构成。
主循环分两个:每秒操作以及每10秒操作 
每秒操作操作:
1.日志缓冲刷新到磁盘(总是)即使没有提交,很好解释commit为什么很快
2.合并插入缓冲(可能)io小于5次
3.至多刷新100个innodb的缓冲池的脏数据到磁盘(可能)脏数据数据到达脏页比例(innodb_max_dirty_pages_pct,可以在线修改)
4.切换到后台循环 当前没有活动
每10秒操作: 
1.合并至多5个插入缓存 (总是)
2.刷新100个或者10个脏页到磁盘(总是)如果脏页超过70%,刷新100个脏页,不到70%,刷新10%的脏页
3.删除undo无用页(总是)  原已经删除但是行版本问题还存在的页 
4.产生一个检查点 (总是) 将最老的日志序列写入磁盘
5.没有用户活动时切到background :loop删除无用undo页,合并20个插入缓存,刷新100个页

6.跳到flush loop(可能,容易切换suspend_loop,将Master thread挂起)
show engine innodb status;

show engine innodbstatus;
-----------------
BACKGROUND THREAD
-----------------
srv_master_threadloops: 13146906 1_second, 13146039 sleeps, 1314246 10_second, 17451 background,17451 flush
srv_master_threadlog flush and writes: 13182400

主循环一秒的操作13146906,每秒休眠次数13146039,每10秒的操作1314246,后台循环17451,刷新循环17451

一秒的操作与每秒休眠次数越相等说明服务器压力越小
数据量大时大量数据不在磁盘宕机后恢复时间长 100页写入磁盘还行吗?
innodb_adaptive_flushing适应性的刷新通过参考日志的写入速度,调整每次刷新到磁盘的页数。这时没到innodb_max_dirty_pages_pct比例也会有脏数据被刷新到磁盘。

四、关键特性

插入缓冲:插入聚集索引一般是顺序的,不需要随机读,非聚集索引需要按照索引建查找,此时离散读降低性能,所以引入插入缓冲

插入缓冲使用条件:
1.索引是辅助索引
2.索引不唯一 
辅助索引唯一,就避免了离散读,插入缓冲就没了意义。通常多个插入合并到一个操作,提高了插入和修改操作。

show engine innodbstatus;
-------------------------------------
INSERT BUFFER ANDADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, freelist len 41069, seg size 41071, 172271 merges
merged operations:
 insert 133199, delete mark 9111330, delete717755
discardedoperations:
 insert 348, delete mark 0, delete 0
Hash table size50999537, node heap has 70273 buffer(s)
3330.12 hashsearches/s, 946.55 non-hash searches/s

seg size当前插入缓冲页41071,free list len空闲队列长度41069 ,insert插入的记录数133199。

写操作密集的情况下插入缓冲占缓冲过大影响其他操作

二次写:当宕机时,数据库正在写一个页,然而这个页只写了磁盘一部分(部分写失效),导致部分数据丢失。然而重做日志无法恢复,因为重做日志是记录对页的物理操作,然而页已经损坏。因此在重做日之前,需要一个页的副本。

Doublewrite两部分组成:内存中的Doublebuffer(大小为2M)和物理磁盘上的共享表空间连续的两个区。当缓冲池脏数据刷新时,不是直接写到磁盘,而是先写到二次写缓冲区,然后再分两次写到两次写磁盘区,最后将脏数据从缓冲区直接刷新到磁盘。(二次写都是顺序写,速度快,减少了随机写时间长引起的宕机写失效的风险)。

宕机后的恢复,在共享空间中读取二次写改页的副本,拷贝到表空间文件,在做重做日志。
如果有多台从库,innodb_doublewrite 功能可以不启动。

自适应哈希索引:哈希是一种非常快的查找方法,常用于连接操作。Innodb根据访问的频率为某些也建立哈希索引。读写可以提高2倍的速度,连接可以提高5倍。哈希索引只能用于等值查询。

-------------------------------------
INSERT BUFFER ANDADAPTIVE HASH INDEX
-------------------------------------
3330.12 hashsearches/s, 946.55 non-hash searches/s

可以看出使用和没使用哈希索引的效率

五、启动关闭恢复

innodb_fast_shutdown
0造成所有操作才关
1不需要完成full purge,merge insert buffer操作 缓冲池的数据刷新到磁盘
2表示都不完成 只需写入日志文件 
当数据库设为2或非正常关机 mysql在启动时会对表恢复
innodb_force_recovery
默认0 恢复执行所有所有恢复操作
有时我们知道如何去恢复,不需要Innodb自行回滚 回滚时间很长,我们可以将innodb_force_recovery不设为0,把表删了从备份中将数据导入表
>0不能做dml语句
实例未提交以及killMysql进程,没提交的回滚

2015-11-1616:59:33 13071 [Note] InnoDB: The log sequence numbers 1833451 and 1833451 inibdata files do not match the log sequence number 210684564 in the ib_logfiles!
2015-11-1616:59:33 13071 [Note] InnoDB: Database was not shutdown normally!
2015-11-1616:59:33 13071 [Note] InnoDB: Starting crash recovery.
2015-11-1616:59:33 13071 [Note] InnoDB: Reading tablespace information from the .ibdfiles...
2015-11-1616:59:33 13071 [Note] InnoDB: Restoring possible half-written data pages 
2015-11-1616:59:33 13071 [Note] InnoDB: from the doublewrite buffer...
InnoDB:1 transaction(s) which must be rolled back or cleaned up
InnoDB:in total 2 row operations to undo
InnoDB: Trx idcounter is 184320
InnoDB: Last MySQLbinlog file position 0 137539294, file name mysqlbin.000016
2015-11-1616:59:33 13071 [Note] InnoDB: 128 rollback segment(s) are active.
InnoDB: Startingin background the rollback of uncommitted transactions
2015-11-1616:59:33 7f8863a73700  InnoDB: Rollingback trx with id 183970, 2 rows to undo
2015-11-1616:59:33 13071 [Note] InnoDB: Waiting for purge to start
2015-11-1616:59:33 13071 [Note] InnoDB: Rollback of trx with id 183970 completed

 第三章 文件

一、参数文件与日志文件

查看参数show variables的信息存储在information_schema.GLOBAL_VARIABLES表
参数分动态和静态参数,动态意味着在实例中可以改变
有些参数只能会话修改autocommit,有些整个实例都会生效,但此会话不生效innodb_support_xa,可以会话和实例内都生效read_buffer_size 。
日志文件
错误日志 二进制日志 慢查询日志 查询日志
慢查询 long_query_time查看阀值是大于这个阀直,可以精确到微妙 
log_queries_not_using_indexes 将没走索引的记录记录来

Mysqldumpslow用于慢查询日志解析

mysqldumpslow -sat -t 5 /opt/mysql/3306/data/db-slave-1-11-slow.log 
Reading mysql slowquery log from /opt/mysql/3306/data/db-slave-slow.log
Count: 1  Time=876.78s (876s)  Lock=0.00s (0s)  Rows=0.0 (0), admin[admin]@[192.168.186.32]
  update monitor_2015_07_03 setplayer_lost_cash = (select sum(a.lost_cash_of_day) fromsanguo_11.players_activity_logs a where a.log_date=‘S‘ andmonitor_2015_07_03.player_id=a.player_id)

-s at 按平均时间最长的排序-t 5显示前5位  Count: 1 Time=876.78s (876s) 一共有1条,平均时间为876.78秒
log_output 指定慢查询输出格式可以table也可以file,table模式可以在mysql.slow_log表中查找(被死锁的语句不会写入慢查询日志)

二、二进制日志

max_binlog_size 二进制日志容量多大开始切换新日志
binlog_cache_size 事务未提交时会将其写在cache里,提交写到二进制日志,一个线程一个事务,如果这值太小会将此缓存的数据写入一个临时文件
那多少为适合? Binlog_cache_use 记录了使用二进制日志的次数Binlog_cache_disk_use记录了临时文件写二进制的次数 =0是合适的
Binlog_Do_DB  Binlog_Ignore_DB过滤写入二进制的数据库
Slave有这选项就会拉来这些db但在binlog中不执行和Replicate_Ignore_DB 一个意思。此参数的获取通过show slave/master status获取

log_slave_updates选项,默认不开启情况下slave不将同步操作写进binlog日志的,当需要主从从时,第二个从库需要第一个从库的binlog。所以这时需要启动该选项。
binlog_format为mixed一般用statement,当一些不确定函数如user()当前登录用户,这种动态语句 
Row格式

当insert时

mysql> insertinto q values(20,11);
### INSERT INTO`t1`.`q`
### SET
###   @1=20 /* INT meta=0 nullable=0 is_null=0 */
###   @2=11 /* INT meta=0 nullable=1 is_null=0 */

当delete时

mysql> delete *from a;
### DELETE FROM`t1`.`a`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM`t1`.`a`
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM`t1`.`a`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM`t1`.`a`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM`t1`.`a`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */

三、innodb引擎文件

Frm可以查看视图定义。

create view q1select * from q;
cat/opt/mysql/3306/data/t1/q1.frm
TYPE=VIEW
query=select`t1`.`q`.`id` AS `id`,`t1`.`q`.`b` AS `b` from `t1`.`q`
md5=14285012a6aa421fccda65e5a48c0b93
updatable=1
algorithm=0
definer_user=root
definer_host=localhost
suid=2
with_check_option=0
timestamp=2015-11-1703:04:04
create-version=1
source=select *from q
client_cs_name=utf8
connection_cl_name=utf8_general_ci
view_body_utf8=select `t1`.`q`.`id` AS`id`,`t1`.`q`.`b` AS `b` from `t1`.`q`

ibd路径和大小通过innodb_data_home_dir ,innodb_data_file_path  来定义 。

innodb_data_file_path| ibdata1:1000M;ibdata2:1000M:autoextend
-rw-rw---- 1 mysqlmysql 1000M Nov 17 11:12 ibdata1
-rw-rw---- 1 mysqlmysql  4.6G Nov 17 11:11 ibdata2

可以看到,当是初始化后ibdata1的容量就为1000M,当容量用满时只有ibdata2是自动增长的

innodb_file_per_table,打开后该表空间存数据,索引和插入缓冲信息。其余在共享表空间

重做日志:innodb_log_group_home_dir存储位置,innodb_log_file_size重做日志大小innodb_log_files_in_group组内有多少日志文件 innodb_mirrored_log_groups有多日志文件组,1没有镜像

时间: 2024-11-03 05:37:24

《Mysql技术内幕》札记(上)的相关文章

《mysql技术内幕 InnoDB存储引擎(第二版)》阅读笔记

一.mysql架构 mysql是一个单进程多线程架构的数据库. 二.存储引擎 InnoDB: 支持事务 行锁 读操作无锁 4种隔离级别,默认为repeatable 自适应hash索引 每张表的存储都是按主键的顺序记性存放 支持全文索引(InnoDB1.2.x - mysql5.6) 支持MVCC(多版本并发控制)实现高并发 MyISAM: 不支持事务 表锁 支持全文索引 三.InnoDB体系架构 1.后台线程 Master Thread 负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性 IO

mysql技术内幕InnoDB存储引擎-阅读笔记

mysql技术内幕InnoDB存储引擎这本书断断续续看了近10天左右,应该说作者有比较丰富的开发水平,在源码级别上分析的比较透彻.如果结合高可用mysql和高性能mysql来看或许效果会更好,可惜书太厚,还在啃当中,希望能早点读完……. 应该说与oracle相比,mysql数据库还是相对比简单,以后还是深入学习下oracle去. 搞数据库也比搞应用运维相对单纯,不用知道各种应用架构,不用写各种脚本工具,只要掌握这个软件就足够了.当然希望自己的知识还是全面一些好.

Mysql技术内幕——表&索引算法和锁

表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示的定义主键则innodb如按照如下方式选择或者创建主键.首先表中是否有唯一非空索引(unique not null),如果有则该列即为主键.不符合上述条件,innodb存储引擎会自动创建一个6字节大小的指针,rowid(). 4.2.innodb逻辑存储结构 innodb的逻辑存储单元由大到小分别是

MySQL技术内幕-InnoDB存储引擎-读书笔记(二)

MySQL技术内幕-InnoDB存储引擎-读书笔记(二) 作为php开发,使用mysql总是少不了的 系列文章博客链接 http://itsong.net/articles/466.html 第三章 文件 mysql与innodb几个类型的文件 参数文件,配置路径.初始化参数.内存大小等 日志文件,包括错误日志,二进制日志,慢查询日志,查询日志 socket文件,用unix域套接字,unix domain socket来进行连接时需要的文件,这一般是本机连接,比通常tcp快 pid文件,进程id

MySQL技术内幕-InnoDB存储引擎-读书笔记(一)

MySQL技术内幕-InnoDB存储引擎-读书笔记(一) 作为php开发,使用mysql总是少不了的 博客链接 http://itsong.net/articles/466.html 第一章 MySQL体系结构和存储引擎 MySQL被设计为一个单进程多线程架构的数据库 ./mysql --help | grep my.cnf 可以查看mysql数据库实例启动时,它会在哪些位置查找配置文件. 配置文件中有一个datadir参数,指定了数据库所在的路径.默认为/usr/local/mysql/dat

《Mysql技术内幕》札记(中)

 第四章   表 一.innodb逻辑结构 Innodb存储引擎表,每张表都有个主键,如果没有显示的主键,则innodb存储引擎会按如下的方式选择或创建主键. 是否有非空的唯一索引,如果有即为主键 不符合上述条件,innodb自动创建一个6个字节大小的指针 表空间由段,区,页组成. Innodb_file_per_table选项,每张表的表空间内存放的只是数据,索引和插入缓冲.其他类型undo信息,系统事务信息,二次写缓冲等还是存放在原来的共享表空间内.即使在Innodb_file_per_ta

《Mysql技术内幕》札记(下)

第七章 事务 一.redo和undo 当一个事务开始时,会记录这个事务的日志序列号,当此事务执行时,会往日志缓冲池插入数据,当事务提交时,日志缓冲区的数据存入磁盘.(innodb_flush_log_at_trx_commit=1时) show engine innodb status --- LOG --- Log sequence number 1759155   (当前的lsn ) Log flushed up to  1759155(已经被刷新到重做日志lsn ) Last checkp

MySQL技术内幕(SQL编程)-数据类型

一:MySQL存储引擎 MySQL插件式存储引擎可以让存储引擎层的开发人员设计他们希望的存储层(满足事务需求.满足数据放到内存中等),常见的存储引擎如下: InnoDB存储引擎:支持事务,面向联机事务处理的应用.特点是行锁设计.支持外键.默认读取操作不会产生锁.最为常用的引擎,5.5.8版本后的默认存储引擎. MyISAM:表锁设计.支持全文索引.不支持事务,面向OLAP数据库应用,5.5.8版本前曾是默认存储引擎.其缓冲池只缓存索引文件,不缓存数据文件. NDB:集群存储引擎,结构是share

Mysql技术内幕——InnoDB存储引擎

一.mysql体系结构和存储引擎 1.1.数据库和实例的区别 数据库:物理操作系统或其他形式文件类型的集合.在mysql下数据库文件可以是frm,myd,myi,ibd结尾的文件. 数据库实例:由数据库后台进程/线程以及一个共享内存区组成.数据库实例才是真正用来操作数据库文件的. mysql数据库是单进程多线程的程序,与sql server比较类似.也就是说,Mysql数据库实例在系统上的表现就是一个进程. 1.2.mysql的体系结构 mysql由连接池组件.管理服务和工具组件.sql接口组建