MySQL数据库体系结构

DDL:数据定义语言 data Definition language,
eg:create、drop、alter;
DML:数据操控语言 data Manipulation language,
eg:insert、update、delete;(要commit!)
DCL:数据控制语言 (管理用户权限)data Control language,
eg:grant、deny、revoke;
DQL:数据查询语言 data Query language,
eg:select。

innodb存储引擎内存结构

这里写图片描述


1.软件
安装:rpm;make install;yum localinstall rpm*

mysql 的软件存放的位置(每个人不一样),

软件存放的位置:show variables like ‘%base%’;
数据存放的位置:show variables like ‘%data%’;

2.通过这个软件可以管理很多数据:表
insert
delete
update
select

数据区的特点:

  • 1.占用空间很大;
  • 2.主要放的是表数据,索引数据
  • 3.数据区由很多数据文件组成
  • 4.数据文件特点:被格式化成一个个的数据块(数据页)(data page),默认16K
  • 5.表数据放在数据页中,以行的形式存放

数据库启动,在ram中划出一块很大的内存区;
对数据行的访问:

  • 1.数据行所在的数据页在内存中,直接产生内存读,将数据行从内存中读取出来,发送给用户;
  • 2.数据行所在的数据页不在内存时,产生物理读(physical read),然后通过内存读读取数据。

用户线程:
- 每一个用户连接都会产生一个线程;
- 每一个用户线程会分配一个工作区。

数据缓冲区:(innodb_buffer_pool

  • 物理内存的:50%~80%
  • 数据缓冲区是共享内存区

select * from t where id<5 order by ‘name’

执行SQL时:

  • 1.建立一个用户连接、建立一个用户线程,分配一个用户空间(最经典的就是sort_buffer_size (256K))(每个用户线程都会分配一个sort_buffer)(256K指的是每个线程分配这么大);
  • 2.执行sql,例select、insert、update、delete;
  • 3.访问数据页,select、dml;在内存-》内存读;不在内存–》物理读+内存读。

物理读:

  • 用户线程发出读请求,具体物理读这个动作是由专门的读线程执行的;
  • 用户写线程负责将脏数据(已修改,但未提交的数据)写给磁盘,这个动作是由写线程来完成的,而不是用户线程来完成。

小知识:mysql里,增删改查都叫 query!!

SQL的执行时间:内存查找+物理读+内存读+…… 执行完成,留下一个脏数据块(修改了,但是没有写到磁盘上!)。

其中,物理写不计算在SQL执行时间里面,物理写也叫作后台写!


知道数据库的状态:(eg:读线程数、写线程数)
show engine innodb status G (没有分号!)

数据文件
show variables like ‘%file%’;得到:
redo logfile:2个,每个50M
log buffer size:8M

这里写图片描述

这里写图片描述

dml:修改/增加/删除 数据行;
dml会产生redo log
redo的格式: 数据页的地址、数据行、具体动作、动作内容

redo log:日志本身
log buffer:日志缓存
log file:日志文件本身

进行DML操作,就会产生redo log(数据页的地址、数据行、具体动作、动作内容),redo log 就会往log buffer写,就算没提交,也会每隔一段时间不断的写,然后log buffer再写到磁盘的logfile里。
redo log会给人感觉修改了N多数据后,提交的时候,非常快!原因:其实只是把redo log写到了磁盘的logfile里,而大量的脏数据其实还没有写到磁盘里,而是在后台慢慢写,但我们并不用担心,因为redo log已经写到logfile里了!!!
(没有commit的数据是可以丢的,不违背mysql的承诺!!)
redo log 详细的记录了对每一个数据页里面的数据行的修改!
修改前的数据页+redo log–》可以构造出来脏页!

eg:delete from t where id<10000;
删除一万行数据,至少会产生1000个redo log。
1.可能会非常大,增长很快
2.可以构造脏块

mysql有一个承诺: 只要提交成功的sql,mysql保证这个sql修改的数据会被永久保存!
dml
commit;

commit;
mysql会做一件事情,将log buffer(内存里)里面的日志写入到 logfile里去!
(PS:数据库崩溃之后,都会有自己的崩溃机制!)


PS:

  • logfile是物理文件,是log存在的场所。一般数据库下的数据文件中有三个日志文件。
  • redo log重做日志,记录着数据库所发生的变化,进行一条DML语句时,如果提交会先写入重做日志里。如果数据库出问题了,也可以根据重做日志来进行恢复。

完整的描述sql工作过程中产生的

用户线程建立、工作区分配、
内存读、物理读、
commit、redo log(日志写)(用户空间)
物理写(为什么说是后台物理写)协同工作!

这里写图片描述

这里写图片描述

首先用户执行一条输入一条dml,之后产生脏页,redo日志,undo日志,redo日志首先存在于用户空间中,之后到logbuffer中,最后通过commit到磁盘的log.file中,这时候数据脏页还没有到磁盘之中,仅仅存在于内存里,可视redolog已经存在于写缓存中,这样系统就会告诉用户已经已经写成功了,但脏页依旧没有进入磁盘,但只要有redolog在,就可以构建脏块,所以不怕没写入的脏块丢失,之后脏块通过后台写线程慢慢的写入写缓存,之后进入磁盘,完成整个操作,但这个时间不计算在写时间,仅仅在后台进行。
【达到1/2的时候、每隔1s钟写一次、commit的时候,都会把sort_buffer写到log_buffer,log buffer往logfile写。】
【所以,log_buffer里,只有很小的数据,基本不会超过4M(一共8M)】
(sort_buffer虽然只有256K,但是是给每个线程分配256K,而线程很多时,就大了。)

存储中的闪存和缓存

sql执行速度要想更快:

  • 1.内存要足够大(从内存读的速度是从磁盘读的几万倍);
  • 2.物理读的速度要足够快(万一产生物理读,得能节省时间);
  • 3.redo log 写入速度要足够快。

cache缓存:
读缓存:对读操作原理上是有性能的提升,但是对于数据库系统来说,性能提升不是很明显,特别是系统稳定以后;对于写操作没有性能的提升(写的时候还是直接写到存储中…)
这里写图片描述

写缓存:对写性能有显著提升;对读性能基本上和读缓存差不多。

这里写图片描述
(写缓存原理)
存储里面,主要是写缓存!

存储的写功能是很强大的,如果写缓存失效,则是因为电池导致写cache被关闭:

  • 1.电池确实坏了;
  • 2.电池生命周期结束(倒计时到了);
  • 3.存储对电池有一个周期性的充放电,自动校正功能。

在充放电期间,存储关闭写缓存。(一般3个月一次)
为什么要充放电?
因为cache要知道电池能给自己充多长时间的电啊~

闪存

现代存储的工作机制:
读数据先到内存(128G)找–》到缓存(20G)找–》到闪存(4T)–》到磁盘,然后在磁盘找到时,直接读到内存。

这里写图片描述

网络上的方案:
在闪存里单独划出一块空间,给logfile。能够提升写缓存的速度。(错)

  • 1.有个前提:写cache坏了,才能提升写缓存的速度;
  • 2.而且,万一闪存坏了,那么logfile就没了,数据就没了。
原文地址:https://www.cnblogs.com/lpeng94/p/12546468.html